From 2922a655c327c58b54979c9809209ff1a4a6e37d Mon Sep 17 00:00:00 2001 From: gaxeer Date: Sun, 22 Dec 2024 21:43:54 +0200 Subject: [PATCH 1/3] body modifications start --- .../_defines220/code/defines/preferenced.dm | 1 + .../_augmentation_preferences.dm | 4 ++ .../_augmentation_preferences.dme | 3 + .../code/body_modification_preferences.dm | 65 +++++++++++++++++++ .../_body_modifications_datum.dm | 44 +++++++++++++ .../body_part/amputations.dm | 42 ++++++++++++ .../body_part/prosthetics.dm | 49 ++++++++++++++ .../code/body_modifications/implants.dm | 0 .../code/preferences.dm | 3 + 9 files changed, 211 insertions(+) create mode 100644 modular_bandastation/_defines220/code/defines/preferenced.dm create mode 100644 modular_bandastation/augmentation_preferences/_augmentation_preferences.dm create mode 100644 modular_bandastation/augmentation_preferences/_augmentation_preferences.dme create mode 100644 modular_bandastation/augmentation_preferences/code/body_modification_preferences.dm create mode 100644 modular_bandastation/augmentation_preferences/code/body_modifications/_body_modifications_datum.dm create mode 100644 modular_bandastation/augmentation_preferences/code/body_modifications/body_part/amputations.dm create mode 100644 modular_bandastation/augmentation_preferences/code/body_modifications/body_part/prosthetics.dm create mode 100644 modular_bandastation/augmentation_preferences/code/body_modifications/implants.dm create mode 100644 modular_bandastation/augmentation_preferences/code/preferences.dm diff --git a/modular_bandastation/_defines220/code/defines/preferenced.dm b/modular_bandastation/_defines220/code/defines/preferenced.dm new file mode 100644 index 0000000000000..29eb79057088a --- /dev/null +++ b/modular_bandastation/_defines220/code/defines/preferenced.dm @@ -0,0 +1 @@ +#define PREFERENCE_TAB_BODY_MODIFICATIONS_PREFERENCES 4 diff --git a/modular_bandastation/augmentation_preferences/_augmentation_preferences.dm b/modular_bandastation/augmentation_preferences/_augmentation_preferences.dm new file mode 100644 index 0000000000000..755f833b1b5da --- /dev/null +++ b/modular_bandastation/augmentation_preferences/_augmentation_preferences.dm @@ -0,0 +1,4 @@ +/datum/modpack/augmentation_preferences + name = "Augmentation Preferences" + desc = "Расширенное меню для аугментаций, имплантов, протезов и ампутаций" + author = "gaxeer" diff --git a/modular_bandastation/augmentation_preferences/_augmentation_preferences.dme b/modular_bandastation/augmentation_preferences/_augmentation_preferences.dme new file mode 100644 index 0000000000000..722fdd9c7fb8c --- /dev/null +++ b/modular_bandastation/augmentation_preferences/_augmentation_preferences.dme @@ -0,0 +1,3 @@ +#include "_augmentation_preferences.dm" + +#include "code/augmentation_preferences.dm" diff --git a/modular_bandastation/augmentation_preferences/code/body_modification_preferences.dm b/modular_bandastation/augmentation_preferences/code/body_modification_preferences.dm new file mode 100644 index 0000000000000..17ac8e3580e3e --- /dev/null +++ b/modular_bandastation/augmentation_preferences/code/body_modification_preferences.dm @@ -0,0 +1,65 @@ +/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) + return preferences.body_modifications + +/// Append all of these into ui_static_data +/datum/preference_middleware/body_modifications/get_ui_static_data(mob/user) + var/list/body_modifications = get_all_body_modifications() + var/list/data = list() + for(var/body_modification_key in body_modifications) + var/datum/body_modification/body_modification = 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/apply_body_modification(list/params, mob/user) + var/body_modification_key = params["body_modification_key"] + if(!body_modification_key) + return FALSE + + var/list/all_body_modifications = get_all_body_modifications() + var/datum/body_modification/body_modification = all_body_modifications[body_modification_key] + + + + + +/datum/preference_middleware/body_modifications/proc/remove_body_modification(list/params, mob/user) + var/body_modification_key = params["body_modification_key"] + if(!references.body_modifications[body_modification_key]) + return FALSE + + preferences.body_modifications -= body_modification_key + return TRUE + +// /// Called when a character is changed. +// /datum/preference_middleware/body_modifications/on_new_character(mob/user) +// return + +/datum/preference_middleware/body_modifications/proc/get_all_body_modifications() + var/static/list/body_modifications = null + if(isnull(body_modifications)) + 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 + + var/datum/body_modification/body_modification_prototype = new body_modification_type() + body_modifications[body_modification_prototype.key] = body_modification_prototype + + + return body_modifications diff --git a/modular_bandastation/augmentation_preferences/code/body_modifications/_body_modifications_datum.dm b/modular_bandastation/augmentation_preferences/code/body_modifications/_body_modifications_datum.dm new file mode 100644 index 0000000000000..b9dc5868d8326 --- /dev/null +++ b/modular_bandastation/augmentation_preferences/code/body_modifications/_body_modifications_datum.dm @@ -0,0 +1,44 @@ +/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(abstract_type == type) + stack_trace("cannot create body modification [type] with abstract type [abstract_type]") + qdel(src) + +/// Apply this set of body modifications to the given mob +/datum/body_modification/proc/apply_to_carbon(mob/living/carbon/target) + SHOULD_CALL_PARENT(TRUE) + + return can_be_applied() + +/// Remove this set of body modifications from the given mob +/datum/body_modification/proc/remove_from_carbon(mob/living/carbon/target) + return TRUE + +/// Returns TRUE if the preview should be updated +/datum/body_modification/proc/should_update_preview(mob/living/carbon/target) + return TRUE + +/// Returns TRUE if this body modification can be applied +/datum/body_modification/proc/can_be_applied(mob/living/carbon/target) + SHOULD_CALL_PARENT(TRUE) + + return !isnull(target) && length(incompatible_body_modifications && target.client?.prefs?.body_modifications) + +/// 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?.body_modifications + +/datum/body_modification/proc/get_description() + return null diff --git a/modular_bandastation/augmentation_preferences/code/body_modifications/body_part/amputations.dm b/modular_bandastation/augmentation_preferences/code/body_modifications/body_part/amputations.dm new file mode 100644 index 0000000000000..6ba167eccb98a --- /dev/null +++ b/modular_bandastation/augmentation_preferences/code/body_modifications/body_part/amputations.dm @@ -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_carbon(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 diff --git a/modular_bandastation/augmentation_preferences/code/body_modifications/body_part/prosthetics.dm b/modular_bandastation/augmentation_preferences/code/body_modifications/body_part/prosthetics.dm new file mode 100644 index 0000000000000..f54fd096ac93b --- /dev/null +++ b/modular_bandastation/augmentation_preferences/code/body_modifications/body_part/prosthetics.dm @@ -0,0 +1,49 @@ +/datum/body_modification/bodypart_prosthetics + name = "Body Part Prosthetics" + abstract_type = /datum/body_modification/bodypart_prosthetics + var/replacement_bodypart_type = null + +/datum/body_modification/bodypart_prosthetics/apply_to_carbon(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_prosthetics/head + key = "head_prosthetics" + name = "Протез головы" + replacement_bodypart = /obj/item/bodypart/head/robot + +/datum/body_modification/bodypart_prosthetics/chest + key = "chest_prosthetics" + name = "Протез торса" + replacement_bodypart = /obj/item/bodypart/chest/robot + +/datum/body_modification/bodypart_prosthetics/arm + abstract_type = /datum/body_modification/bodypart_prosthetics/arm + +/datum/body_modification/bodypart_prosthetics/arm/left + key = "left_arm_amputation" + name = "Протез левой руки" + replacement_bodypart = /obj/item/bodypart/arm/left/robot + +/datum/body_modification/bodypart_prosthetics/arm/right + key = "right_arm_amputation" + name = "Протез правой руки" + replacement_bodypart = /obj/item/bodypart/arm/right/robot + +/datum/body_modification/bodypart_prosthetics/leg + abstract_type = /datum/body_modification/bodypart_prosthetics/leg + +/datum/body_modification/bodypart_prosthetics/leg/left + key = "left_leg_amputation" + name = "Протез левой ноги" + replacement_bodypart = /obj/item/bodypart/leg/left/robot + +/datum/body_modification/bodypart_prosthetics/leg/right + key = "right_leg_amputation" + name = "Протез правой ноги" + replacement_bodypart = /obj/item/bodypart/leg/right/robot diff --git a/modular_bandastation/augmentation_preferences/code/body_modifications/implants.dm b/modular_bandastation/augmentation_preferences/code/body_modifications/implants.dm new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/modular_bandastation/augmentation_preferences/code/preferences.dm b/modular_bandastation/augmentation_preferences/code/preferences.dm new file mode 100644 index 0000000000000..7b6fb3590b686 --- /dev/null +++ b/modular_bandastation/augmentation_preferences/code/preferences.dm @@ -0,0 +1,3 @@ +/datum/preferences + /// The list of body modifications + var/list/body_modifications = list() From 862fecc2cbbbe40374160e844e09907b690fc039 Mon Sep 17 00:00:00 2001 From: gaxeer Date: Mon, 23 Dec 2024 23:24:20 +0200 Subject: [PATCH 2/3] prepare back-end --- .../_augmentation_preferences.dme | 7 +- .../code/body_modification_preferences.dm | 65 --------------- .../_body_modifications_datum.dm | 33 +++++--- .../body_part/amputations.dm | 10 +-- .../body_part/prosthetics.dm | 52 ++++++------ .../code/preferences.dm | 3 - .../body_modification_preference.dm | 44 ++++++++++ ...body_modification_preference_middleware.dm | 80 +++++++++++++++++++ modular_bandastation/modular_bandastation.dme | 1 + 9 files changed, 182 insertions(+), 113 deletions(-) delete mode 100644 modular_bandastation/augmentation_preferences/code/body_modification_preferences.dm delete mode 100644 modular_bandastation/augmentation_preferences/code/preferences.dm create mode 100644 modular_bandastation/augmentation_preferences/code/preferences/body_modification_preference.dm create mode 100644 modular_bandastation/augmentation_preferences/code/preferences/body_modification_preference_middleware.dm diff --git a/modular_bandastation/augmentation_preferences/_augmentation_preferences.dme b/modular_bandastation/augmentation_preferences/_augmentation_preferences.dme index 722fdd9c7fb8c..f898dc4d3a1be 100644 --- a/modular_bandastation/augmentation_preferences/_augmentation_preferences.dme +++ b/modular_bandastation/augmentation_preferences/_augmentation_preferences.dme @@ -1,3 +1,8 @@ #include "_augmentation_preferences.dm" -#include "code/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" +#include "code/preferences/body_modification_preference_middleware.dm" +#include "code/preferences/body_modification_preference.dm" diff --git a/modular_bandastation/augmentation_preferences/code/body_modification_preferences.dm b/modular_bandastation/augmentation_preferences/code/body_modification_preferences.dm deleted file mode 100644 index 17ac8e3580e3e..0000000000000 --- a/modular_bandastation/augmentation_preferences/code/body_modification_preferences.dm +++ /dev/null @@ -1,65 +0,0 @@ -/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) - return preferences.body_modifications - -/// Append all of these into ui_static_data -/datum/preference_middleware/body_modifications/get_ui_static_data(mob/user) - var/list/body_modifications = get_all_body_modifications() - var/list/data = list() - for(var/body_modification_key in body_modifications) - var/datum/body_modification/body_modification = 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/apply_body_modification(list/params, mob/user) - var/body_modification_key = params["body_modification_key"] - if(!body_modification_key) - return FALSE - - var/list/all_body_modifications = get_all_body_modifications() - var/datum/body_modification/body_modification = all_body_modifications[body_modification_key] - - - - - -/datum/preference_middleware/body_modifications/proc/remove_body_modification(list/params, mob/user) - var/body_modification_key = params["body_modification_key"] - if(!references.body_modifications[body_modification_key]) - return FALSE - - preferences.body_modifications -= body_modification_key - return TRUE - -// /// Called when a character is changed. -// /datum/preference_middleware/body_modifications/on_new_character(mob/user) -// return - -/datum/preference_middleware/body_modifications/proc/get_all_body_modifications() - var/static/list/body_modifications = null - if(isnull(body_modifications)) - 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 - - var/datum/body_modification/body_modification_prototype = new body_modification_type() - body_modifications[body_modification_prototype.key] = body_modification_prototype - - - return body_modifications diff --git a/modular_bandastation/augmentation_preferences/code/body_modifications/_body_modifications_datum.dm b/modular_bandastation/augmentation_preferences/code/body_modifications/_body_modifications_datum.dm index b9dc5868d8326..82ba6e4be80db 100644 --- a/modular_bandastation/augmentation_preferences/code/body_modifications/_body_modifications_datum.dm +++ b/modular_bandastation/augmentation_preferences/code/body_modifications/_body_modifications_datum.dm @@ -1,3 +1,5 @@ +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 @@ -12,33 +14,38 @@ /datum/body_modification/New() ..() + if(isnull(key)) + stack_trace("body modification without key: [type]") + if(abstract_type == type) - stack_trace("cannot create body modification [type] with abstract type [abstract_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_carbon(mob/living/carbon/target) +/datum/body_modification/proc/apply_to_human(mob/living/carbon/target) SHOULD_CALL_PARENT(TRUE) return can_be_applied() -/// Remove this set of body modifications from the given mob -/datum/body_modification/proc/remove_from_carbon(mob/living/carbon/target) - return TRUE - -/// Returns TRUE if the preview should be updated -/datum/body_modification/proc/should_update_preview(mob/living/carbon/target) - return TRUE - /// Returns TRUE if this body modification can be applied /datum/body_modification/proc/can_be_applied(mob/living/carbon/target) SHOULD_CALL_PARENT(TRUE) - return !isnull(target) && length(incompatible_body_modifications && target.client?.prefs?.body_modifications) + return !isnull(target) && length(incompatible_body_modifications && target.client?.prefs?.read_preference(/datum/preference/body_modifications)) /// 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?.body_modifications + return incompatible_body_modifications && target.client?.prefs?.read_preference(/datum/preference/body_modifications) /datum/body_modification/proc/get_description() - return null + 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 diff --git a/modular_bandastation/augmentation_preferences/code/body_modifications/body_part/amputations.dm b/modular_bandastation/augmentation_preferences/code/body_modifications/body_part/amputations.dm index 6ba167eccb98a..1ad66267dfe9b 100644 --- a/modular_bandastation/augmentation_preferences/code/body_modifications/body_part/amputations.dm +++ b/modular_bandastation/augmentation_preferences/code/body_modifications/body_part/amputations.dm @@ -3,7 +3,7 @@ abstract_type = /datum/body_modification/limb_amputation var/limb_body_zone = null -/datum/body_modification/limb_amputation/apply_to_carbon(mob/living/carbon/target) +/datum/body_modification/limb_amputation/apply_to_human(mob/living/carbon/target) . = ..() if(!.) return @@ -19,12 +19,12 @@ abstract_type = /datum/body_modification/limb_amputation/arm /datum/body_modification/limb_amputation/arm/left - key = "left arm amputation" + key = "left_arm_amputation" name = "Ампутация левой руки" limb_body_zone = BODY_ZONE_L_ARM /datum/body_modification/limb_amputation/arm/right - key = "right arm amputation" + key = "right_arm_amputation" name = "Ампутация правой руки" limb_body_zone = BODY_ZONE_R_ARM @@ -32,11 +32,11 @@ abstract_type = /datum/body_modification/limb_amputation/leg /datum/body_modification/limb_amputation/leg/left - key = "left leg amputation" + key = "left_leg_amputation" name = "Ампутация левой ноги" limb_body_zone = BODY_ZONE_L_LEG /datum/body_modification/limb_amputation/leg/right - key = "Right leg amputation" + key = "right_leg_amputation" name = "Ампутация правой ноги" limb_body_zone = BODY_ZONE_R_LEG diff --git a/modular_bandastation/augmentation_preferences/code/body_modifications/body_part/prosthetics.dm b/modular_bandastation/augmentation_preferences/code/body_modifications/body_part/prosthetics.dm index f54fd096ac93b..a8a08f5cd07b0 100644 --- a/modular_bandastation/augmentation_preferences/code/body_modifications/body_part/prosthetics.dm +++ b/modular_bandastation/augmentation_preferences/code/body_modifications/body_part/prosthetics.dm @@ -1,9 +1,9 @@ -/datum/body_modification/bodypart_prosthetics - name = "Body Part Prosthetics" - abstract_type = /datum/body_modification/bodypart_prosthetics +/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_prosthetics/apply_to_carbon(mob/living/carbon/target) +/datum/body_modification/bodypart_prosthesis/apply_to_human(mob/living/carbon/target) . = ..() if(!.) return @@ -12,38 +12,38 @@ replacement_bodypart.replace_limb(target, TRUE) return TRUE -/datum/body_modification/bodypart_prosthetics/head - key = "head_prosthetics" +/datum/body_modification/bodypart_prosthesis/head + key = "head_prosthesis" name = "Протез головы" - replacement_bodypart = /obj/item/bodypart/head/robot + replacement_bodypart_type = /obj/item/bodypart/head/robot -/datum/body_modification/bodypart_prosthetics/chest - key = "chest_prosthetics" +/datum/body_modification/bodypart_prosthesis/chest + key = "chest_prosthesis" name = "Протез торса" - replacement_bodypart = /obj/item/bodypart/chest/robot + replacement_bodypart_type = /obj/item/bodypart/chest/robot -/datum/body_modification/bodypart_prosthetics/arm - abstract_type = /datum/body_modification/bodypart_prosthetics/arm +/datum/body_modification/bodypart_prosthesis/arm + abstract_type = /datum/body_modification/bodypart_prosthesis/arm -/datum/body_modification/bodypart_prosthetics/arm/left - key = "left_arm_amputation" +/datum/body_modification/bodypart_prosthesis/arm/left + key = "left_arm_prosthetic" name = "Протез левой руки" - replacement_bodypart = /obj/item/bodypart/arm/left/robot + replacement_bodypart_type = /obj/item/bodypart/arm/left/robot -/datum/body_modification/bodypart_prosthetics/arm/right - key = "right_arm_amputation" +/datum/body_modification/bodypart_prosthesis/arm/right + key = "right_arm_prosthesis" name = "Протез правой руки" - replacement_bodypart = /obj/item/bodypart/arm/right/robot + replacement_bodypart_type = /obj/item/bodypart/arm/right/robot -/datum/body_modification/bodypart_prosthetics/leg - abstract_type = /datum/body_modification/bodypart_prosthetics/leg +/datum/body_modification/bodypart_prosthesis/leg + abstract_type = /datum/body_modification/bodypart_prosthesis/leg -/datum/body_modification/bodypart_prosthetics/leg/left - key = "left_leg_amputation" +/datum/body_modification/bodypart_prosthesis/leg/left + key = "left_leg_prosthesis" name = "Протез левой ноги" - replacement_bodypart = /obj/item/bodypart/leg/left/robot + replacement_bodypart_type = /obj/item/bodypart/leg/left/robot -/datum/body_modification/bodypart_prosthetics/leg/right - key = "right_leg_amputation" +/datum/body_modification/bodypart_prosthesis/leg/right + key = "right_leg_prosthesis" name = "Протез правой ноги" - replacement_bodypart = /obj/item/bodypart/leg/right/robot + replacement_bodypart_type = /obj/item/bodypart/leg/right/robot diff --git a/modular_bandastation/augmentation_preferences/code/preferences.dm b/modular_bandastation/augmentation_preferences/code/preferences.dm deleted file mode 100644 index 7b6fb3590b686..0000000000000 --- a/modular_bandastation/augmentation_preferences/code/preferences.dm +++ /dev/null @@ -1,3 +0,0 @@ -/datum/preferences - /// The list of body modifications - var/list/body_modifications = list() diff --git a/modular_bandastation/augmentation_preferences/code/preferences/body_modification_preference.dm b/modular_bandastation/augmentation_preferences/code/preferences/body_modification_preference.dm new file mode 100644 index 0000000000000..3d35669fe043a --- /dev/null +++ b/modular_bandastation/augmentation_preferences/code/preferences/body_modification_preference.dm @@ -0,0 +1,44 @@ +/datum/preference/body_modifications + savefile_key = "body_modifications" + savefile_identifier = PREFERENCE_CHARACTER + priority = PREFERENCE_PRIORITY_BODYPARTS + can_randomize = FALSE + +/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() diff --git a/modular_bandastation/augmentation_preferences/code/preferences/body_modification_preference_middleware.dm b/modular_bandastation/augmentation_preferences/code/preferences/body_modification_preference_middleware.dm new file mode 100644 index 0000000000000..a402092706069 --- /dev/null +++ b/modular_bandastation/augmentation_preferences/code/preferences/body_modification_preference_middleware.dm @@ -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 diff --git a/modular_bandastation/modular_bandastation.dme b/modular_bandastation/modular_bandastation.dme index 24d327b88b3ad..d91871a902a37 100644 --- a/modular_bandastation/modular_bandastation.dme +++ b/modular_bandastation/modular_bandastation.dme @@ -10,6 +10,7 @@ #include "aesthetics_sounds/_aesthetics_sounds.dme" #include "automapper/_automapper.dme" #include "ai_laws/_ai_laws.dme" +#include "augmentation_preferences/_augmentation_preferences.dme" #include "autohiss/_autohiss.dme" #include "balance/_balance.dme" #include "barsigns/_barsigns.dme" From aec0ba76d10bf9f25e387654bdfe701cf4591d2e Mon Sep 17 00:00:00 2001 From: gaxeer Date: Tue, 24 Dec 2024 17:25:35 +0200 Subject: [PATCH 3/3] front end setup, back-end fixes --- .../_body_modifications_datum.dm | 15 +++- .../body_part/prosthetics.dm | 10 --- .../body_modification_preference.dm | 11 +++ .../PreferencesMenu/BodyModificationsPage.tsx | 68 +++++++++++++++++++ .../CharacterPreferenceWindow.tsx | 21 +++++- .../tgui/interfaces/PreferencesMenu/data.ts | 23 +++++-- 6 files changed, 129 insertions(+), 19 deletions(-) create mode 100644 tgui/packages/tgui/interfaces/PreferencesMenu/BodyModificationsPage.tsx diff --git a/modular_bandastation/augmentation_preferences/code/body_modifications/_body_modifications_datum.dm b/modular_bandastation/augmentation_preferences/code/body_modifications/_body_modifications_datum.dm index 82ba6e4be80db..1a3d7a25dc250 100644 --- a/modular_bandastation/augmentation_preferences/code/body_modifications/_body_modifications_datum.dm +++ b/modular_bandastation/augmentation_preferences/code/body_modifications/_body_modifications_datum.dm @@ -25,13 +25,24 @@ GLOBAL_LIST_INIT_TYPED(body_modifications, /datum/body_modification, init_body_m /datum/body_modification/proc/apply_to_human(mob/living/carbon/target) SHOULD_CALL_PARENT(TRUE) - return can_be_applied() + 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) - return !isnull(target) && length(incompatible_body_modifications && target.client?.prefs?.read_preference(/datum/preference/body_modifications)) + 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) diff --git a/modular_bandastation/augmentation_preferences/code/body_modifications/body_part/prosthetics.dm b/modular_bandastation/augmentation_preferences/code/body_modifications/body_part/prosthetics.dm index a8a08f5cd07b0..d5d1166bfcc2a 100644 --- a/modular_bandastation/augmentation_preferences/code/body_modifications/body_part/prosthetics.dm +++ b/modular_bandastation/augmentation_preferences/code/body_modifications/body_part/prosthetics.dm @@ -12,16 +12,6 @@ replacement_bodypart.replace_limb(target, TRUE) return TRUE -/datum/body_modification/bodypart_prosthesis/head - key = "head_prosthesis" - name = "Протез головы" - replacement_bodypart_type = /obj/item/bodypart/head/robot - -/datum/body_modification/bodypart_prosthesis/chest - key = "chest_prosthesis" - name = "Протез торса" - replacement_bodypart_type = /obj/item/bodypart/chest/robot - /datum/body_modification/bodypart_prosthesis/arm abstract_type = /datum/body_modification/bodypart_prosthesis/arm diff --git a/modular_bandastation/augmentation_preferences/code/preferences/body_modification_preference.dm b/modular_bandastation/augmentation_preferences/code/preferences/body_modification_preference.dm index 3d35669fe043a..c55009e9b9160 100644 --- a/modular_bandastation/augmentation_preferences/code/preferences/body_modification_preference.dm +++ b/modular_bandastation/augmentation_preferences/code/preferences/body_modification_preference.dm @@ -4,6 +4,17 @@ 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 diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/BodyModificationsPage.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/BodyModificationsPage.tsx new file mode 100644 index 0000000000000..d83c3d02ef5d1 --- /dev/null +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/BodyModificationsPage.tsx @@ -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 ( + { + if (!serverData) { + return Loading...; + } + return ( + + ); + }} + /> + ); +}; + +const BodyModificationsPageInner = (props: { + bodyModification: BodyModification[]; +}) => { + return ( + + {props.bodyModification.map((bodyModification) => ( + + + + ))} + + ); +}; + +const BodyModificationRow = (props: { bodyModification: BodyModification }) => { + const { act, data } = useBackend(); + const { applied_body_modifications } = data; + return ( + + {props.bodyModification.name} + + {props.bodyModification.key in applied_body_modifications ? ( + + ) : ( + + )} + + + ); +}; diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/CharacterPreferenceWindow.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/CharacterPreferenceWindow.tsx index 55bfac0db0e71..59f26782fae95 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/CharacterPreferenceWindow.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/CharacterPreferenceWindow.tsx @@ -5,6 +5,7 @@ import { useBackend } from '../../backend'; import { Button, Stack } from '../../components'; import { Window } from '../../layouts'; import { AntagsPage } from './AntagsPage'; +import { BodyModificationsPage } from './BodyModificationsPage'; // BANDASTATION EDIT ADD - TTS import { PreferencesMenuData } from './data'; import { JobsPage } from './JobsPage'; import { LoadoutPage } from './loadout/index'; @@ -21,8 +22,10 @@ enum Page { Species, Quirks, Loadout, - // BANDASTATION EDIT ADD - TTS + // BANDASTATION ADD START Voice, + BodyModifications, + // BANDASTATION ADD END } const CharacterProfiles = (props: { @@ -83,10 +86,14 @@ export const CharacterPreferenceWindow = (props) => { case Page.Loadout: pageContents = ; break; - // BANDASTATION EDIT ADD - TTS + // BANDASTATION ADD START case Page.Voice: pageContents = ; break; + case Page.BodyModifications: + pageContents = ; + break; + // BANDASTATION ADD END default: exhaustiveCheck(currentPage); } @@ -169,6 +176,16 @@ export const CharacterPreferenceWindow = (props) => { + + + Body Modifications + + + {Boolean(data.tts_enabled) && ( // BANDASTATION EDIT - TTS ; jobs: Record;