Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Augmentations #1009

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#define PREFERENCE_TAB_BODY_MODIFICATIONS_PREFERENCES 4
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/datum/modpack/augmentation_preferences
name = "Augmentation Preferences"
desc = "Расширенное меню для аугментаций, имплантов, протезов и ампутаций"
author = "gaxeer"
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#include "_augmentation_preferences.dm"

#include "code/body_modifications/body_part/amputations.dm"
#include "code/body_modifications/body_part/prosthetics.dm"
#include "code/body_modifications/_body_modifications_datum.dm"
#include "code/body_modifications/_body_modifications_datum.dm"

Check failure on line 6 in modular_bandastation/augmentation_preferences/_augmentation_preferences.dme

View workflow job for this annotation

GitHub Actions / Run Linters

OD1000: File "modular_bandastation/augmentation_preferences/code/body_modifications/_body_modifications_datum.dm" was already included

Check warning on line 6 in modular_bandastation/augmentation_preferences/_augmentation_preferences.dme

View workflow job for this annotation

GitHub Actions / Run Linters

duplicate #include "modular_bandastation/augmentation_preferences/code/body_modifications/_body_modifications_datum.dm"
#include "code/preferences/body_modification_preference_middleware.dm"
#include "code/preferences/body_modification_preference.dm"
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
GLOBAL_LIST_INIT_TYPED(body_modifications, /datum/body_modification, init_body_modifications())

/datum/body_modification
/// The abstract type of this body modification
var/abstract_type = /datum/body_modification
/// The key used to identify this body modification
var/key = null
/// The name of this body modification
var/name = null
/// Cost in quirk points of thisbody modification
var/cost = 0
/// The list of body modifications incompatible with this body modification
var/list/incompatible_body_modifications = list()

/datum/body_modification/New()
..()
if(isnull(key))
stack_trace("body modification without key: [type]")

if(abstract_type == type)
stack_trace("abstract body modification attempted to be instantiated: [type]")
qdel(src)

/// Apply this set of body modifications to the given mob
/datum/body_modification/proc/apply_to_human(mob/living/carbon/target)
SHOULD_CALL_PARENT(TRUE)

return can_be_applied(target)

/// Returns TRUE if this body modification can be applied
/datum/body_modification/proc/can_be_applied(mob/living/carbon/target)
SHOULD_CALL_PARENT(TRUE)

if(isnull(target))
return FALSE

var/list/applied_body_modifications = target.client?.prefs?.read_preference(/datum/preference/body_modifications)
if(length(applied_body_modifications) == 0)
return TRUE

for(var/incompatible_body_modification in incompatible_body_modifications)
if(incompatible_body_modification in applied_body_modifications)
return FALSE

return TRUE

/// Returns the list of body modifications incompatible with this body modification
/datum/body_modification/proc/get_conflicting_body_modifications(mob/living/carbon/target)
return incompatible_body_modifications && target.client?.prefs?.read_preference(/datum/preference/body_modifications)

/datum/body_modification/proc/get_description()
return "No description yet"

/proc/init_body_modifications()
var/list/body_modifications = list()
for(var/datum/body_modification/body_modification_type as anything in subtypesof(/datum/body_modification))
if(body_modification_type == body_modification_type::abstract_type)
continue

body_modifications[body_modification_type::key] = new body_modification_type()

return body_modifications
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/datum/body_modification/limb_amputation
name = "Body Part Amputation"
abstract_type = /datum/body_modification/limb_amputation
var/limb_body_zone = null

/datum/body_modification/limb_amputation/apply_to_human(mob/living/carbon/target)
. = ..()
if(!.)
return

var/obj/item/bodypart/limb_to_remove = target.get_bodypart(limb_body_zone)
if(!limb_to_remove)
return FALSE

limb_to_remove.drop_limb(special = TRUE)
return TRUE

/datum/body_modification/limb_amputation/arm
abstract_type = /datum/body_modification/limb_amputation/arm

/datum/body_modification/limb_amputation/arm/left
key = "left_arm_amputation"
name = "Ампутация левой руки"
limb_body_zone = BODY_ZONE_L_ARM

/datum/body_modification/limb_amputation/arm/right
key = "right_arm_amputation"
name = "Ампутация правой руки"
limb_body_zone = BODY_ZONE_R_ARM

/datum/body_modification/limb_amputation/leg
abstract_type = /datum/body_modification/limb_amputation/leg

/datum/body_modification/limb_amputation/leg/left
key = "left_leg_amputation"
name = "Ампутация левой ноги"
limb_body_zone = BODY_ZONE_L_LEG

/datum/body_modification/limb_amputation/leg/right
key = "right_leg_amputation"
name = "Ампутация правой ноги"
limb_body_zone = BODY_ZONE_R_LEG
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/datum/body_modification/bodypart_prosthesis
name = "Body Part Prosthesis"
abstract_type = /datum/body_modification/bodypart_prosthesis
var/replacement_bodypart_type = null

/datum/body_modification/bodypart_prosthesis/apply_to_human(mob/living/carbon/target)
. = ..()
if(!.)
return

var/obj/item/bodypart/replacement_bodypart = new replacement_bodypart_type()
replacement_bodypart.replace_limb(target, TRUE)
return TRUE

/datum/body_modification/bodypart_prosthesis/arm
abstract_type = /datum/body_modification/bodypart_prosthesis/arm

/datum/body_modification/bodypart_prosthesis/arm/left
key = "left_arm_prosthetic"
name = "Протез левой руки"
replacement_bodypart_type = /obj/item/bodypart/arm/left/robot

/datum/body_modification/bodypart_prosthesis/arm/right
key = "right_arm_prosthesis"
name = "Протез правой руки"
replacement_bodypart_type = /obj/item/bodypart/arm/right/robot

/datum/body_modification/bodypart_prosthesis/leg
abstract_type = /datum/body_modification/bodypart_prosthesis/leg

/datum/body_modification/bodypart_prosthesis/leg/left
key = "left_leg_prosthesis"
name = "Протез левой ноги"
replacement_bodypart_type = /obj/item/bodypart/leg/left/robot

/datum/body_modification/bodypart_prosthesis/leg/right
key = "right_leg_prosthesis"
name = "Протез правой ноги"
replacement_bodypart_type = /obj/item/bodypart/leg/right/robot
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/datum/preference/body_modifications
savefile_key = "body_modifications"
savefile_identifier = PREFERENCE_CHARACTER
priority = PREFERENCE_PRIORITY_BODYPARTS
can_randomize = FALSE

/datum/preference/body_modifications/is_valid(value)
if(!islist(value))
return FALSE

var/list/values = value
for(var/body_modification_key in values)
if(isnull(GLOB.body_modifications[body_modification_key]))
return FALSE

return TRUE

/datum/preference/body_modifications/apply_to_human(mob/living/carbon/human/target, value)
if(!islist(value))
return

var/list/body_modifications = value
for(var/body_modification_key in body_modifications)
GLOB.body_modifications[body_modification_key].apply_to_human(target)

/datum/preference/body_modifications/deserialize(input, datum/preferences/preferences)
if(!islist(input))
return list()

var/list/body_modifications = input
var/list/valid_body_modification_keys = list()
for(var/body_modification_key in body_modifications)
if(!GLOB.body_modifications[body_modification_key])
continue

valid_body_modification_keys[body_modification_key] = TRUE

return valid_body_modification_keys

/datum/preference/body_modifications/serialize(input)
if(!islist(input))
return list()

var/list/body_modifications = input
var/list/valid_body_modification_keys = list()
for(var/body_modification_key in body_modifications)
if(!GLOB.body_modifications[body_modification_key])
continue

valid_body_modification_keys |= body_modification_key

return valid_body_modification_keys

/datum/preference/body_modifications/create_default_value()
return list()
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/datum/preference_middleware/body_modifications
action_delegations = list(
"apply_body_modification" = PROC_REF(apply_body_modification),
"remove_body_modification" = PROC_REF(remove_body_modification),
)

/// Append all of these into ui_data
/datum/preference_middleware/body_modifications/get_ui_data(mob/user)
var/list/data = list()
data["applied_body_modifications"] = get_applied_body_modifications()
data["incomptable_body_modifications"] = get_incomptable_body_modifications(user)
return data

/// Append all of these into ui_static_data
/datum/preference_middleware/body_modifications/get_constant_data(mob/user)
var/list/data = list()
for(var/body_modification_key in GLOB.body_modifications)
var/datum/body_modification/body_modification = GLOB.body_modifications[body_modification_key]
data += list(
list(
"key" = body_modification.key,
"name" = body_modification.name,
"description" = body_modification.get_description(),
"cost" = body_modification.cost
)
)

return data

/datum/preference_middleware/body_modifications/proc/get_applied_body_modifications()
PRIVATE_PROC(TRUE)

var/list/applied_body_modifications = preferences.read_preference(/datum/preference/body_modifications)
var/list/modifications = list()
for(var/body_modification_key in applied_body_modifications)
modifications += body_modification_key

return modifications

/datum/preference_middleware/body_modifications/proc/get_incomptable_body_modifications(mob/user)
PRIVATE_PROC(TRUE)

var/list/incompatible_body_modifications = list()
for(var/body_modification_key in GLOB.body_modifications)
if(GLOB.body_modifications[body_modification_key].can_be_applied(user))
continue

incompatible_body_modifications += body_modification_key

return incompatible_body_modifications

/datum/preference_middleware/body_modifications/proc/apply_body_modification(list/params, mob/user)
var/body_modification_key = params["body_modification_key"]
if(!body_modification_key)
return FALSE

var/datum/body_modification/body_modification_prototype = GLOB.body_modifications[body_modification_key]
if(isnull(body_modification_prototype) || !body_modification_prototype.can_be_applied(user))
return FALSE

var/list/body_modifications = preferences.read_preference(/datum/preference/body_modifications)
if(body_modifications[body_modification_key])
return FALSE

body_modifications[body_modification_key] = TRUE
preferences.update_preference(GLOB.preference_entries[/datum/preference/body_modifications], body_modifications)
return TRUE

/datum/preference_middleware/body_modifications/proc/remove_body_modification(list/params, mob/user)
var/body_modification_key = params["body_modification_key"]
if(!body_modification_key)
return FALSE

var/list/body_modifications = preferences.read_preference(/datum/preference/body_modifications)
if(!body_modifications[body_modification_key])
return FALSE

body_modifications -= body_modification_key
preferences.update_preference(GLOB.preference_entries[/datum/preference/body_modifications], body_modifications)
return TRUE
1 change: 1 addition & 0 deletions modular_bandastation/modular_bandastation.dme
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "aesthetics_sounds/_aesthetics_sounds.dme"
#include "automapper/_automapper.dme"
#include "ai_laws/_ai_laws.dme"
#include "augmentation_preferences/_augmentation_preferences.dme"
#include "announcers/_announcers.dme"
#include "autohiss/_autohiss.dme"
#include "balance/_balance.dme"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { useBackend } from '../../backend';
import { Button, NoticeBox, Stack } from '../../components';
import { BodyModification, PreferencesMenuData, ServerData } from './data';
import { ServerPreferencesFetcher } from './ServerPreferencesFetcher';

export const BodyModificationsPage = () => {
return (
<ServerPreferencesFetcher
render={(serverData: ServerData) => {
if (!serverData) {
return <NoticeBox>Loading...</NoticeBox>;
}
return (
<BodyModificationsPageInner
bodyModification={serverData.body_modifications}
/>
);
}}
/>
);
};

const BodyModificationsPageInner = (props: {
bodyModification: BodyModification[];
}) => {
return (
<Stack height={'100%'} vertical>
{props.bodyModification.map((bodyModification) => (
<Stack.Item key={bodyModification.key}>
<BodyModificationRow bodyModification={bodyModification} />
</Stack.Item>
))}
</Stack>
);
};

const BodyModificationRow = (props: { bodyModification: BodyModification }) => {
const { act, data } = useBackend<PreferencesMenuData>();
const { applied_body_modifications } = data;
return (
<Stack>
<Stack.Item>{props.bodyModification.name}</Stack.Item>
<Stack.Item>
{props.bodyModification.key in applied_body_modifications ? (
<Button
onClick={() =>
act('remove_body_modification', {
body_modification_key: props.bodyModification.key,
})
}
>
Remove
</Button>
) : (
<Button
onClick={() =>
act('apply_body_modification', {
body_modification_key: props.bodyModification.key,
})
}
>
Apply
</Button>
)}
</Stack.Item>
</Stack>
);
};
Loading
Loading