From c681cee6059ceff2dff37424e8f371a5edc40a0a Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Thu, 8 Dec 2022 18:41:31 +0100 Subject: [PATCH] [MIRROR] Fixes DNA Infuser's brain swapping, a little bit of qol, ui reworked [MDB IGNORE] (#17844) * Fixes DNA Infuser's brain swapping, a little bit of qol, ui reworked * conflicts * fix the bad Co-authored-by: tralezab <40974010+tralezab@users.noreply.github.com> Co-authored-by: Tom <8881105+tf-4@users.noreply.github.com> --- code/__HELPERS/_lists.dm | 10 ++ .../game/machinery/dna_infuser/dna_infuser.dm | 44 ++++++- .../machinery/dna_infuser/infuser_entries.dm | 11 +- .../dna_infuser/organ_sets/carp_organs.dm | 17 +-- .../antagonists/nightmare/nightmare_organs.dm | 2 +- .../modules/client/preferences/_preference.dm | 2 + .../preferences/species_features/basic.dm | 4 +- .../preferences/species_features/felinid.dm | 4 +- .../preferences/species_features/lizard.dm | 6 +- .../preferences/species_features/moth.dm | 4 + .../preferences/species_features/pod.dm | 4 +- .../mob/dead/new_player/sprite_accessories.dm | 7 +- .../mob/living/carbon/human/species.dm | 5 + .../carbon/human/species_types/monkeys.dm | 2 +- .../modules/client/preferences/_preference.dm | 2 +- .../modules/client/preferences/genitals.dm | 2 +- .../species_features/digitigrade_legs.dm | 2 +- .../modules/surgery/organs/ipc.dm | 2 +- tgui/packages/tgui/interfaces/InfuserBook.tsx | 119 +++++++++++++++--- 19 files changed, 198 insertions(+), 51 deletions(-) diff --git a/code/__HELPERS/_lists.dm b/code/__HELPERS/_lists.dm index f58b89ca971..27ea724166f 100644 --- a/code/__HELPERS/_lists.dm +++ b/code/__HELPERS/_lists.dm @@ -831,6 +831,16 @@ UNTYPED_LIST_ADD(keys, key) return keys +/// Turns an associative list into a flat list of keys, but for sprite accessories, respecting the locked variable +/proc/assoc_to_keys_features(list/input) + var/list/keys = list() + for(var/key in input) + var/datum/sprite_accessory/value = input[key] + if(value?.locked) + continue + UNTYPED_LIST_ADD(keys, key) + return keys + ///compare two lists, returns TRUE if they are the same /proc/compare_list(list/l,list/d) if(!islist(l) || !islist(d)) diff --git a/code/game/machinery/dna_infuser/dna_infuser.dm b/code/game/machinery/dna_infuser/dna_infuser.dm index d5b616c9c5d..8fc8d96353b 100644 --- a/code/game/machinery/dna_infuser/dna_infuser.dm +++ b/code/game/machinery/dna_infuser/dna_infuser.dm @@ -18,6 +18,8 @@ var/atom/movable/infusing_from ///what we're turning into var/datum/infuser_entry/infusing_into + ///a message for relaying that the machine is locked if someone tries to leave while it's active + COOLDOWN_DECLARE(message_cooldown) /obj/machinery/dna_infuser/Initialize(mapload) . = ..() @@ -38,11 +40,13 @@ . += span_notice("Missing [span_bold("an infusion source")].") else . += span_notice("[span_bold(infusing_from.name)] is in the infusion slot.") + . += span_notice("To operate: Obtain dead creature. Depending on size, drag or drop into the infuser slot.") + . += span_notice("Subject enters the chamber, someone activates the machine. Voila! One of your organs has... changed!") . += span_notice("Alt-click to eject the infusion source, if one is inside.") /obj/machinery/dna_infuser/interact(mob/user) if(user == occupant) - balloon_alert(user, "can't reach!") + toggle_open(user) return if(infusing) balloon_alert(user, "not while it's on!") @@ -64,6 +68,7 @@ if(!infusing_into) //no valid recipe, so you get a fly mutation infusing_into = GLOB.infuser_entries[1] + playsound(src, 'sound/machines/blender.ogg', 50, TRUE) to_chat(hoccupant, span_danger("Little needles repeatedly prick you! And with each prick, you feel yourself becoming more... [infusing_into.infusion_desc]?")) hoccupant.take_overall_damage(10) Shake(15, 15, INFUSING_TIME) @@ -93,7 +98,16 @@ if(potential_new_organs.len) var/obj/item/organ/new_organ = pick(potential_new_organs) new_organ = new new_organ() - new_organ.Insert(target, special = TRUE, drop_if_replaced = FALSE) + if(istype(new_organ, /obj/item/organ/internal/brain)) + // brains REALLY like ghosting people. we need special tricks to avoid that, namely removing the old brain with no_id_transfer + var/obj/item/organ/internal/brain/new_brain = new_organ + var/obj/item/organ/internal/brain/old_brain = target.getorganslot(ORGAN_SLOT_BRAIN) + if(old_brain) + old_brain.Remove(target, special = TRUE, no_id_transfer = TRUE) + qdel(old_brain) + new_brain.Insert(target, special = TRUE, drop_if_replaced = FALSE, no_id_transfer = TRUE) + else + new_organ.Insert(target, special = TRUE, drop_if_replaced = FALSE) infusing_into = null QDEL_NULL(infusing_from) @@ -147,6 +161,21 @@ add_infusion_item(used, user) return ..() +/obj/machinery/dna_infuser/relaymove(mob/living/user, direction) + if(user.stat) + if(COOLDOWN_FINISHED(src, message_cooldown)) + COOLDOWN_START(src, message_cooldown, 4 SECONDS) + to_chat(user, span_warning("[src]'s door won't budge!")) + return + if(infusing) + if(COOLDOWN_FINISHED(src, message_cooldown)) + COOLDOWN_START(src, message_cooldown, 4 SECONDS) + to_chat(user, span_danger("[src]'s door won't budge while all the needles are infusing you!")) + return + open_machine(drop = FALSE) + //we set drop to false to manually call it with an allowlist + dump_inventory_contents(list(occupant)) + // mostly good for dead mobs that turn into items like dead mice (smack to add) /obj/machinery/dna_infuser/proc/add_infusion_item(obj/item/target, mob/user) if(!is_valid_infusion(target, user)) @@ -163,6 +192,11 @@ if(user.stat != CONSCIOUS || HAS_TRAIT(user, TRAIT_UI_BLOCKED) || !Adjacent(user) || !user.Adjacent(target) || !ISADVANCEDTOOLUSER(user)) return + if(iscarbon(target)) + if(ishuman(target)) + close_machine(target) + return + if(!is_valid_infusion(target, user)) return @@ -170,6 +204,7 @@ infusing_from.forceMove(src) /obj/machinery/dna_infuser/proc/is_valid_infusion(atom/movable/target, mob/user) + var/datum/component/edible/food_comp = IS_EDIBLE(target) if(infusing_from) balloon_alert(user, "empty the machine first!") return FALSE @@ -178,9 +213,8 @@ if(living_target.stat != DEAD) balloon_alert(user, "only dead creatures!") return FALSE - else if(istype(target, /obj/item/food)) - var/obj/item/food/food_target = target - if(!(food_target.foodtypes & GORE)) + else if(food_comp) + if(!(food_comp.foodtypes & GORE)) balloon_alert(user, "only creatures!") return FALSE else diff --git a/code/game/machinery/dna_infuser/infuser_entries.dm b/code/game/machinery/dna_infuser/infuser_entries.dm index b685597daa2..1f9309585c1 100644 --- a/code/game/machinery/dna_infuser/infuser_entries.dm +++ b/code/game/machinery/dna_infuser/infuser_entries.dm @@ -1,6 +1,9 @@ /// A list of all infuser entries GLOBAL_LIST_INIT(infuser_entries, prepare_entries()) +/// just clarifying that no threshold does some special stuff, since only meme mutants have it +#define NO_THRESHOLD "" + /proc/prepare_entries() var/list/entries = list() //regardless of names we want the failed mutant case to show first @@ -24,7 +27,7 @@ GLOBAL_LIST_INIT(infuser_entries, prepare_entries()) var/infuse_mob_name = "rejected creature" /// general desc var/desc = "For whatever reason, when the body rejects DNA, the DNA goes sour, ending up as some kind of fly-like DNA jumble." - /// desc of what passing the threshold gets you + /// desc of what passing the threshold gets you. if this is empty, there is no threshold, so this is also really a tally of whether this is a "meme" mutant or not var/threshold_desc = "the DNA mess takes over, and you become a full-fledged flyperson." /// various little bits var/list/qualities = list( @@ -96,11 +99,13 @@ GLOBAL_LIST_INIT(infuser_entries, prepare_entries()) ) infusion_desc = "nomadic" +// just some meme entries, these basically encourage killing staff pets but do not play with the organ bonus system + /datum/infuser_entry/felinid name = "Cat" infuse_mob_name = "feline" desc = "EVERYONE CALM DOWN! I'm not implying anything with this entry. Are we really so surprised that felinids are humans with mixed feline DNA?" - threshold_desc = "nothing happens. I guess this is why it's a big genetic craze, feline DNA is notably stable." + threshold_desc = NO_THRESHOLD qualities = list( "oh, let me guess, you're a big fan of those japanese tourist bots", ) @@ -117,7 +122,7 @@ GLOBAL_LIST_INIT(infuser_entries, prepare_entries()) name = "Fox" infuse_mob_name = "vulpini" desc = "Foxes are now quite rare because of the \"fox ears\" craze back in 2555. I mean, also because we're spacefarers who destroyed foxes' natural habitats ages ago, but that applies to most animals." - threshold_desc = "nothing happens. Stable DNA." + threshold_desc = NO_THRESHOLD qualities = list( "oh come on really", "you bring SHAME to all geneticists", diff --git a/code/game/machinery/dna_infuser/organ_sets/carp_organs.dm b/code/game/machinery/dna_infuser/organ_sets/carp_organs.dm index 00ea11cb3e0..fdc71555518 100644 --- a/code/game/machinery/dna_infuser/organ_sets/carp_organs.dm +++ b/code/game/machinery/dna_infuser/organ_sets/carp_organs.dm @@ -23,8 +23,7 @@ /obj/item/organ/internal/lungs/carp name = "mutated carp-lungs" desc = "Carp DNA infused into what was once some normal lungs." - safe_oxygen_max = 16 - safe_oxygen_min = 0 + safe_oxygen_min = 0 //we don't breathe this! icon = 'icons/obj/medical/organs/infuser_organs.dmi' icon_state = "lungs" @@ -54,10 +53,9 @@ return var/mob/living/carbon/human/human_receiver = tongue_owner var/datum/species/rec_species = human_receiver.dna.species - if(!(rec_species.no_equip_flags & ITEM_SLOT_MASK)) - rec_species.no_equip_flags += ITEM_SLOT_MASK + rec_species.update_no_equip_flags(tongue_owner, rec_species.no_equip_flags | ITEM_SLOT_MASK) var/obj/item/bodypart/head/head = human_receiver.get_bodypart(BODY_ZONE_HEAD) - head.unarmed_damage_low = 10 // Yeah, biteing is pretty weak, blame the monkey super-nerf + head.unarmed_damage_low = 10 head.unarmed_damage_high = 15 head.unarmed_stun_threshold = 15 @@ -67,8 +65,7 @@ return var/mob/living/carbon/human/human_receiver = tongue_owner var/datum/species/rec_species = human_receiver.dna.species - if(!(initial(rec_species.no_equip_flags) & ITEM_SLOT_MASK)) - rec_species.no_equip_flags -= ITEM_SLOT_MASK + rec_species.update_no_equip_flags(tongue_owner, initial(rec_species.no_equip_flags)) var/obj/item/bodypart/head/head = human_receiver.get_bodypart(BODY_ZONE_HEAD) head.unarmed_damage_low = initial(head.unarmed_damage_low) head.unarmed_damage_high = initial(head.unarmed_damage_high) @@ -76,7 +73,7 @@ /obj/item/organ/internal/tongue/carp/on_life(delta_time, times_fired) . = ..() - if(!prob(1)) + if(owner.stat != CONSCIOUS || !prob(0.1)) return owner.emote("cough") var/turf/tooth_fairy = get_turf(owner) @@ -147,4 +144,8 @@ AddElement(/datum/element/noticable_organ, "skin has small patches of scales growing...") AddElement(/datum/element/organ_set_bonus, /datum/status_effect/organ_set_bonus/carp) +#undef CARP_ORGAN_COLOR +#undef CARP_SCLERA_COLOR +#undef CARP_PUPIL_COLOR + #undef CARP_COLORS diff --git a/code/modules/antagonists/nightmare/nightmare_organs.dm b/code/modules/antagonists/nightmare/nightmare_organs.dm index 3fcb01f3e1a..6e7e4117ded 100644 --- a/code/modules/antagonists/nightmare/nightmare_organs.dm +++ b/code/modules/antagonists/nightmare/nightmare_organs.dm @@ -11,7 +11,7 @@ icon_state = "brain-x-d" var/datum/action/cooldown/spell/jaunt/shadow_walk/our_jaunt -/obj/item/organ/internal/brain/shadow/nightmare/Insert(mob/living/carbon/M, special = FALSE, drop_if_replaced = TRUE) +/obj/item/organ/internal/brain/shadow/nightmare/Insert(mob/living/carbon/M, special = FALSE, drop_if_replaced = TRUE, no_id_transfer = FALSE) . = ..() if(M.dna.species.id != SPECIES_NIGHTMARE) M.set_species(/datum/species/shadow/nightmare) diff --git a/code/modules/client/preferences/_preference.dm b/code/modules/client/preferences/_preference.dm index 752ecf6e25b..98366cbcafa 100644 --- a/code/modules/client/preferences/_preference.dm +++ b/code/modules/client/preferences/_preference.dm @@ -469,6 +469,8 @@ GLOBAL_LIST_INIT(preference_entries_by_key, init_preference_entries_by_key()) for (var/name in sprite_accessories) var/datum/sprite_accessory/sprite_accessory = sprite_accessories[name] + if(sprite_accessory.locked) + continue var/icon/final_icon diff --git a/code/modules/client/preferences/species_features/basic.dm b/code/modules/client/preferences/species_features/basic.dm index c9a4410e44c..878adee82a1 100644 --- a/code/modules/client/preferences/species_features/basic.dm +++ b/code/modules/client/preferences/species_features/basic.dm @@ -92,7 +92,7 @@ relevant_species_trait = FACEHAIR /datum/preference/choiced/facial_hair_gradient/init_possible_values() - return assoc_to_keys(GLOB.facial_hair_gradients_list) + return assoc_to_keys_features(GLOB.facial_hair_gradients_list) /datum/preference/choiced/facial_hair_gradient/apply_to_human(mob/living/carbon/human/target, value) LAZYSETLEN(target.grad_style, GRADIENTS_LEN) @@ -155,7 +155,7 @@ relevant_species_trait = HAIR /datum/preference/choiced/hair_gradient/init_possible_values() - return assoc_to_keys(GLOB.hair_gradients_list) + return assoc_to_keys_features(GLOB.hair_gradients_list) /datum/preference/choiced/hair_gradient/apply_to_human(mob/living/carbon/human/target, value) LAZYSETLEN(target.grad_style, GRADIENTS_LEN) diff --git a/code/modules/client/preferences/species_features/felinid.dm b/code/modules/client/preferences/species_features/felinid.dm index 8779cc46c28..037615ee809 100644 --- a/code/modules/client/preferences/species_features/felinid.dm +++ b/code/modules/client/preferences/species_features/felinid.dm @@ -7,7 +7,7 @@ relevant_external_organ = /obj/item/organ/external/tail/cat /datum/preference/choiced/tail_human/init_possible_values() - return assoc_to_keys(GLOB.sprite_accessories["tail"]) + return assoc_to_keys_features(GLOB.tails_list_human) /datum/preference/choiced/tail_human/apply_to_human(mob/living/carbon/human/target, value) target.dna.features["tail_cat"] = value @@ -24,7 +24,7 @@ relevant_mutant_bodypart = "ears" /datum/preference/choiced/ears/init_possible_values() - return GLOB.sprite_accessories["ears"] + return assoc_to_keys_features(GLOB.ears_list) /datum/preference/choiced/ears/apply_to_human(mob/living/carbon/human/target, value) target.dna.features["ears"] = value diff --git a/code/modules/client/preferences/species_features/lizard.dm b/code/modules/client/preferences/species_features/lizard.dm index e0c9ce9764a..1d5d0f22af6 100644 --- a/code/modules/client/preferences/species_features/lizard.dm +++ b/code/modules/client/preferences/species_features/lizard.dm @@ -98,7 +98,7 @@ relevant_mutant_bodypart = "legs" /datum/preference/choiced/lizard_legs/init_possible_values() - return assoc_to_keys(GLOB.legs_list) + return assoc_to_keys_features(GLOB.legs_list) /datum/preference/choiced/lizard_legs/apply_to_human(mob/living/carbon/human/target, value) target.dna.features["legs"] = value @@ -123,7 +123,7 @@ relevant_mutant_bodypart = "spines" /datum/preference/choiced/lizard_spines/init_possible_values() - return assoc_to_keys(GLOB.spines_list) + return assoc_to_keys_features(GLOB.spines_list) /datum/preference/choiced/lizard_spines/apply_to_human(mob/living/carbon/human/target, value) target.dna.features["spines"] = value @@ -135,7 +135,7 @@ relevant_external_organ = /obj/item/organ/external/tail/lizard /datum/preference/choiced/lizard_tail/init_possible_values() - return assoc_to_keys(GLOB.tails_list_lizard) + return assoc_to_keys_features(GLOB.tails_list_lizard) /datum/preference/choiced/lizard_tail/apply_to_human(mob/living/carbon/human/target, value) target.dna.features["tail_lizard"] = value diff --git a/code/modules/client/preferences/species_features/moth.dm b/code/modules/client/preferences/species_features/moth.dm index 2be78cc31d0..fac52d29bde 100644 --- a/code/modules/client/preferences/species_features/moth.dm +++ b/code/modules/client/preferences/species_features/moth.dm @@ -14,6 +14,8 @@ for (var/antennae_name in GLOB.moth_antennae_list) var/datum/sprite_accessory/antennae = GLOB.moth_antennae_list[antennae_name] + if(antennae.locked) + continue var/icon/icon_with_antennae = new(moth_head) icon_with_antennae.Blend(icon(antennae.icon, "m_moth_antennae_[antennae.icon_state]_FRONT"), ICON_OVERLAY) @@ -57,6 +59,8 @@ for (var/markings_name in GLOB.moth_markings_list) var/datum/sprite_accessory/markings = GLOB.moth_markings_list[markings_name] + if(markings.locked) + continue var/icon/icon_with_markings = new(moth_body) if (markings_name != "None") diff --git a/code/modules/client/preferences/species_features/pod.dm b/code/modules/client/preferences/species_features/pod.dm index 7bfcddc40bb..f2534ac7105 100644 --- a/code/modules/client/preferences/species_features/pod.dm +++ b/code/modules/client/preferences/species_features/pod.dm @@ -12,6 +12,8 @@ for (var/pod_name in GLOB.pod_hair_list) var/datum/sprite_accessory/pod_hair = GLOB.pod_hair_list[pod_name] + if(pod_hair.locked) + continue var/icon/icon_with_hair = new(pod_head) var/icon/icon_adj = icon(pod_hair.icon, "m_pod_hair_[pod_hair.icon_state]_ADJ") @@ -27,7 +29,7 @@ return values /datum/preference/choiced/pod_hair/create_default_value() - return pick(GLOB.pod_hair_list) + return pick(assoc_to_keys_features(GLOB.pod_hair_list)) /datum/preference/choiced/pod_hair/apply_to_human(mob/living/carbon/human/target, value) target.dna.features["pod_hair"] = value diff --git a/code/modules/mob/dead/new_player/sprite_accessories.dm b/code/modules/mob/dead/new_player/sprite_accessories.dm index b023d622d05..9a45c6a4abb 100644 --- a/code/modules/mob/dead/new_player/sprite_accessories.dm +++ b/code/modules/mob/dead/new_player/sprite_accessories.dm @@ -16,7 +16,7 @@ from doing this unless you absolutely know what you are doing, and have defined a conversion in savefile.dm */ -/proc/init_sprite_accessory_subtypes(prototype, list/L, list/male, list/female,roundstart = FALSE, add_blank)//Roundstart argument builds a specific list for roundstart parts where some parts may be locked +/proc/init_sprite_accessory_subtypes(prototype, list/L, list/male, list/female, add_blank)//Roundstart argument builds a specific list for roundstart parts where some parts may be locked if(!istype(L)) L = list() if(!istype(male)) @@ -25,10 +25,6 @@ female = list() for(var/path in subtypesof(prototype)) - if(roundstart) - var/datum/sprite_accessory/P = path - if(initial(P.locked)) - continue var/datum/sprite_accessory/D = new path() if(D.icon_state) @@ -1863,6 +1859,7 @@ icon_state = "fox" hasinner = TRUE color_src = HAIR + locked = TRUE /datum/sprite_accessory/wings/none name = "None" diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index 080482033cf..d38b461a4d0 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -433,6 +433,11 @@ GLOBAL_LIST_EMPTY(features_by_species) if(!equipped_item.mob_can_equip(wearer, equipped_item_slot, bypass_equip_delay_self = TRUE, ignore_equipped = TRUE)) wearer.dropItemToGround(equipped_item) +/datum/species/proc/update_no_equip_flags(mob/living/carbon/wearer, new_flags) + no_equip_flags = new_flags + wearer.hud_used?.update_locked_slots() + worn_items_fit_body_check(wearer) + /** * Proc called when a carbon becomes this species. * diff --git a/code/modules/mob/living/carbon/human/species_types/monkeys.dm b/code/modules/mob/living/carbon/human/species_types/monkeys.dm index eb024c0d4c9..a99218b2264 100644 --- a/code/modules/mob/living/carbon/human/species_types/monkeys.dm +++ b/code/modules/mob/living/carbon/human/species_types/monkeys.dm @@ -230,7 +230,7 @@ UpdateButtons() -/obj/item/organ/internal/brain/primate/Insert(mob/living/carbon/primate, special = FALSE, drop_if_replaced = FALSE) +/obj/item/organ/internal/brain/primate/Insert(mob/living/carbon/primate, special = FALSE, drop_if_replaced = FALSE, no_id_transfer = FALSE) . = ..() RegisterSignal(primate, COMSIG_MOVABLE_CROSS, PROC_REF(on_crossed), TRUE) diff --git a/modular_skyrat/master_files/code/modules/client/preferences/_preference.dm b/modular_skyrat/master_files/code/modules/client/preferences/_preference.dm index 55ecdd5a272..04ef3e9233a 100644 --- a/modular_skyrat/master_files/code/modules/client/preferences/_preference.dm +++ b/modular_skyrat/master_files/code/modules/client/preferences/_preference.dm @@ -103,7 +103,7 @@ return (passed_initial_check || overriding) && part_enabled /datum/preference/choiced/mutant_choice/init_possible_values() - return assoc_to_keys(GLOB.sprite_accessories[relevant_mutant_bodypart]) + return assoc_to_keys_features(GLOB.sprite_accessories[relevant_mutant_bodypart]) /datum/preference/choiced/mutant_choice/create_default_value() return initial(default_accessory_type?.name) || "None" diff --git a/modular_skyrat/master_files/code/modules/client/preferences/genitals.dm b/modular_skyrat/master_files/code/modules/client/preferences/genitals.dm index cbc786b3328..8064cba2489 100644 --- a/modular_skyrat/master_files/code/modules/client/preferences/genitals.dm +++ b/modular_skyrat/master_files/code/modules/client/preferences/genitals.dm @@ -68,7 +68,7 @@ return initial(default_accessory_type?.name) || "None" /datum/preference/choiced/genital/init_possible_values() - return assoc_to_keys(GLOB.sprite_accessories[relevant_mutant_bodypart]) + return assoc_to_keys_features(GLOB.sprite_accessories[relevant_mutant_bodypart]) /datum/preference/toggle/genital_skin_tone category = PREFERENCE_CATEGORY_SECONDARY_FEATURES diff --git a/modular_skyrat/master_files/code/modules/client/preferences/species_features/digitigrade_legs.dm b/modular_skyrat/master_files/code/modules/client/preferences/species_features/digitigrade_legs.dm index 56a65ed36aa..ff9ef9c0945 100644 --- a/modular_skyrat/master_files/code/modules/client/preferences/species_features/digitigrade_legs.dm +++ b/modular_skyrat/master_files/code/modules/client/preferences/species_features/digitigrade_legs.dm @@ -11,7 +11,7 @@ /datum/preference/choiced/digitigrade_legs/init_possible_values() - return assoc_to_keys(GLOB.sprite_accessories["legs"]) + return assoc_to_keys_features(GLOB.sprite_accessories["legs"]) /datum/preference/choiced/digitigrade_legs/is_accessible(datum/preferences/preferences) return ..() && is_usable(preferences) diff --git a/modular_skyrat/modules/customization/modules/surgery/organs/ipc.dm b/modular_skyrat/modules/customization/modules/surgery/organs/ipc.dm index dc5c16c5e9d..326863fc181 100644 --- a/modular_skyrat/modules/customization/modules/surgery/organs/ipc.dm +++ b/modular_skyrat/modules/customization/modules/surgery/organs/ipc.dm @@ -12,7 +12,7 @@ #define SYNTH_EMP_BRAIN_DAMAGE_LIGHT 12 #define SYNTH_EMP_BRAIN_DAMAGE_MAXIMUM 75 -/obj/item/organ/internal/brain/ipc_positron/Insert(mob/living/carbon/user, special = 0, drop_if_replaced = TRUE) +/obj/item/organ/internal/brain/ipc_positron/Insert(mob/living/carbon/user, special = FALSE, drop_if_replaced = TRUE, no_id_transfer = FALSE) ..() if(user.stat == DEAD && ishuman(user)) var/mob/living/carbon/human/user_human = user diff --git a/tgui/packages/tgui/interfaces/InfuserBook.tsx b/tgui/packages/tgui/interfaces/InfuserBook.tsx index d1716499e53..4818652a1e4 100644 --- a/tgui/packages/tgui/interfaces/InfuserBook.tsx +++ b/tgui/packages/tgui/interfaces/InfuserBook.tsx @@ -1,6 +1,7 @@ -import { useBackend } from '../backend'; -import { BlockQuote, Box, Section, Stack } from '../components'; +import { useBackend, useLocalState } from '../backend'; +import { BlockQuote, Box, Button, Section, Stack } from '../components'; import { Window } from '../layouts'; +import { multiline } from 'common/string'; type Entry = { name: string; @@ -17,40 +18,126 @@ type DnaInfuserData = { export const InfuserBook = (props, context) => { const { data } = useBackend(context); const { entries } = data; + const [entryIndex, setEntryIndex] = useLocalState(context, 'entry', 0); + + const wrapEntries = (newIndex) => { + if (newIndex < 0) { + newIndex = entries.length - 1; + } else if (newIndex > entries.length - 1) { + newIndex = 0; + } + setEntryIndex(newIndex); + }; + return ( - - + + - {entries.map((entry) => { - return ( - - + + + + + + + + + + - ); - })} + +
+ Entry {entryIndex + 1}/{entries.length} +
+
+ + + +
+
); }; +export const InfuserInstructions = (props, context) => { + return ( +
+ + What does it do? + + DNA Infusion is the practice of integrating dead creature DNA into + yourself, mutating one of your organs into a genetic slurry that sits + somewhere between being yours or the creature's. While this does + bring you further away from being human, and gives a slew of... + unfortunate side effects, it also grants new capabilities.{' '} + + Above all else, you have to understand that gene-mutants are usually + very good at specific things, especially with their threshold + bonuses. + + + I'm sold! How do I do it? + + 1. Load a dead creature into the machine. This is what you're + infusing from. +
+ 2. Enter the machine, like you would the DNA scanner. +
+ 3. Have someone activate the machine externally. +
+ + And you're done! Note that the infusion source will be + obliterated in the process. + +
+
+
+ ); +}; type InfuserEntryProps = { entry: Entry; }; const InfuserEntry = (props: InfuserEntryProps, context) => { const { entry } = props; + const isLesser = !entry.threshold_desc; + const lesserDesc = multiline` + Lesser Mutants usually have a smaller list of potential mutations, and + do not have bonuses for infusing many organs. + `; + const greaterDesc = multiline` + Greater Mutants have more upsides and downsides in their organs, more organs + to infuse overall, and come with special bonuses for infusing enough DNA + into yourself. + `; return ( -
- - {entry.name} Mutant +
+ {isLesser ? 'Lesser' : 'Greater'} Mutant + + }> +
- {entry.desc} If a subject infuses with enough DNA,{' '} - {entry.threshold_desc} + {entry.desc}{' '} + {!isLesser && ( + <>If a subject infuses with enough DNA, {entry.threshold_desc} + )}
- + Qualities: {entry.qualities.map((quality) => { return (