From c97f2e73adcd32e1bcf18c4bdcc2434ff4af0c1a Mon Sep 17 00:00:00 2001 From: ChungusGamer666 <82850673+ChungusGamer666@users.noreply.github.com> Date: Wed, 5 Jul 2023 15:28:24 -0300 Subject: [PATCH] Fixes carbon bodytypes not always being synchronized with bodyparts (#76522) Fixes https://github.com/tgstation/tgstation/issues/76481 TLDR /mob/living/carbon/human/species subtypes were NOT updating their bodytypes on spawn due to absurd and wacky carbon bodypart creation code that meant try_attach_limb() never got called (What the FUCK?) --- code/__DEFINES/mobs.dm | 6 +++--- code/_globalvars/bitfields.dm | 21 ++++++++++++++++--- code/modules/mob/living/carbon/carbon.dm | 6 ++++++ .../mob/living/carbon/human/_species.dm | 3 +++ .../carbon/human/{monkey => }/monkey.dm | 0 .../carbon/human/species_types/monkeys.dm | 3 --- .../surgery/bodyparts/dismemberment.dm | 12 ----------- code/modules/surgery/bodyparts/helpers.dm | 8 +++++++ code/modules/surgery/bodyparts/parts.dm | 3 +-- .../organs/external/_external_organ.dm | 4 ++-- tgstation.dme | 2 +- 11 files changed, 42 insertions(+), 26 deletions(-) rename code/modules/mob/living/carbon/human/{monkey => }/monkey.dm (100%) diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index 6414638e5d0..bb17412a2da 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -72,10 +72,10 @@ #define BODYTYPE_ROBOTIC (1<<1) ///The limb fits the human mold. This is not meant to be literal, if the sprite "fits" on a human, it is "humanoid", regardless of origin. #define BODYTYPE_HUMANOID (1<<2) -///The limb is digitigrade. -#define BODYTYPE_DIGITIGRADE (1<<3) ///The limb fits the monkey mold. -#define BODYTYPE_MONKEY (1<<4) +#define BODYTYPE_MONKEY (1<<3) +///The limb is digitigrade. +#define BODYTYPE_DIGITIGRADE (1<<4) ///The limb is snouted. #define BODYTYPE_SNOUTED (1<<5) ///A placeholder bodytype for xeno larva, so their limbs cannot be attached to anything. diff --git a/code/_globalvars/bitfields.dm b/code/_globalvars/bitfields.dm index 99f90c88e86..29e2a791229 100644 --- a/code/_globalvars/bitfields.dm +++ b/code/_globalvars/bitfields.dm @@ -373,12 +373,27 @@ DEFINE_BITFIELD(reaction_flags, list( )) DEFINE_BITFIELD(bodytype, list( - "BODYTYPE_DIGITIGRADE" = BODYTYPE_DIGITIGRADE, - "BODYTYPE_HUMANOID" = BODYTYPE_HUMANOID, - "BODYTYPE_MONKEY" = BODYTYPE_MONKEY, "BODYTYPE_ORGANIC" = BODYTYPE_ORGANIC, "BODYTYPE_ROBOTIC" = BODYTYPE_ROBOTIC, + "BODYTYPE_HUMANOID" = BODYTYPE_HUMANOID, + "BODYTYPE_MONKEY" = BODYTYPE_MONKEY, + "BODYTYPE_DIGITIGRADE" = BODYTYPE_DIGITIGRADE, "BODYTYPE_SNOUTED" = BODYTYPE_SNOUTED, + "BODYTYPE_LARVA_PLACEHOLDER" = BODYTYPE_LARVA_PLACEHOLDER, + "BODYTYPE_ALIEN" = BODYTYPE_ALIEN, + "BODYTYPE_GOLEM" = BODYTYPE_GOLEM, +)) + +DEFINE_BITFIELD(acceptable_bodytype, list( + "BODYTYPE_ORGANIC" = BODYTYPE_ORGANIC, + "BODYTYPE_ROBOTIC" = BODYTYPE_ROBOTIC, + "BODYTYPE_HUMANOID" = BODYTYPE_HUMANOID, + "BODYTYPE_MONKEY" = BODYTYPE_MONKEY, + "BODYTYPE_DIGITIGRADE" = BODYTYPE_DIGITIGRADE, + "BODYTYPE_SNOUTED" = BODYTYPE_SNOUTED, + "BODYTYPE_LARVA_PLACEHOLDER" = BODYTYPE_LARVA_PLACEHOLDER, + "BODYTYPE_ALIEN" = BODYTYPE_ALIEN, + "BODYTYPE_GOLEM" = BODYTYPE_GOLEM, )) DEFINE_BITFIELD(bodypart_flags, list( diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index e6fe4ddbf21..fb2fa8951f9 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -995,11 +995,15 @@ if(!new_bodypart.bodypart_disabled) set_usable_hands(usable_hands + 1) + synchronize_bodytypes() + ///Proc to hook behavior on bodypart removals. Do not directly call. You're looking for [/obj/item/bodypart/proc/drop_limb()]. /mob/living/carbon/proc/remove_bodypart(obj/item/bodypart/old_bodypart) SHOULD_NOT_OVERRIDE(TRUE) + old_bodypart.on_removal() bodyparts -= old_bodypart + switch(old_bodypart.body_part) if(LEG_LEFT, LEG_RIGHT) set_num_legs(num_legs - 1) @@ -1010,6 +1014,8 @@ if(!old_bodypart.bodypart_disabled) set_usable_hands(usable_hands - 1) + synchronize_bodytypes() + ///Updates the bodypart speed modifier based on our bodyparts. /mob/living/carbon/proc/update_bodypart_speed_modifier() var/final_modification = 0 diff --git a/code/modules/mob/living/carbon/human/_species.dm b/code/modules/mob/living/carbon/human/_species.dm index 48b410e8711..ea4830e3e4d 100644 --- a/code/modules/mob/living/carbon/human/_species.dm +++ b/code/modules/mob/living/carbon/human/_species.dm @@ -449,6 +449,7 @@ GLOBAL_LIST_EMPTY(features_by_species) C.mob_biotypes = inherent_biotypes C.mob_respiration_type = inherent_respiration_type + C.butcher_results = knife_butcher_results?.Copy() if(old_species.type != type) replace_body(C, src) @@ -499,8 +500,10 @@ GLOBAL_LIST_EMPTY(features_by_species) */ /datum/species/proc/on_species_loss(mob/living/carbon/human/C, datum/species/new_species, pref_load) SHOULD_CALL_PARENT(TRUE) + C.butcher_results = null for(var/X in inherent_traits) REMOVE_TRAIT(C, X, SPECIES_TRAIT) + for(var/obj/item/organ/external/organ in C.organs) organ.Remove(C) qdel(organ) diff --git a/code/modules/mob/living/carbon/human/monkey/monkey.dm b/code/modules/mob/living/carbon/human/monkey.dm similarity index 100% rename from code/modules/mob/living/carbon/human/monkey/monkey.dm rename to code/modules/mob/living/carbon/human/monkey.dm 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 838065b3439..495299574fb 100644 --- a/code/modules/mob/living/carbon/human/species_types/monkeys.dm +++ b/code/modules/mob/living/carbon/human/species_types/monkeys.dm @@ -50,15 +50,12 @@ /datum/species/monkey/on_species_gain(mob/living/carbon/human/H, datum/species/old_species) . = ..() H.pass_flags |= PASSTABLE - H.butcher_results = knife_butcher_results H.dna.add_mutation(/datum/mutation/human/race, MUT_NORMAL) H.dna.activate_mutation(/datum/mutation/human/race) - /datum/species/monkey/on_species_loss(mob/living/carbon/C) . = ..() C.pass_flags = initial(C.pass_flags) - C.butcher_results = null C.dna.remove_mutation(/datum/mutation/human/race) /datum/species/monkey/spec_unarmedattack(mob/living/carbon/human/user, atom/target, modifiers) diff --git a/code/modules/surgery/bodyparts/dismemberment.dm b/code/modules/surgery/bodyparts/dismemberment.dm index e341ecbf587..c722ea43987 100644 --- a/code/modules/surgery/bodyparts/dismemberment.dm +++ b/code/modules/surgery/bodyparts/dismemberment.dm @@ -133,7 +133,6 @@ organ.transfer_to_limb(src, phantom_owner) update_icon_dropped() - synchronize_bodytypes(phantom_owner) phantom_owner.update_health_hud() //update the healthdoll phantom_owner.update_body() phantom_owner.update_body_parts() @@ -359,7 +358,6 @@ // Bodyparts need to be sorted for leg masking to be done properly. It also will allow for some predictable // behavior within said bodyparts list. We sort it here, as it's the only place we make changes to bodyparts. new_limb_owner.bodyparts = sort_list(new_limb_owner.bodyparts, GLOBAL_PROC_REF(cmp_bodypart_by_body_part_asc)) - synchronize_bodytypes(new_limb_owner) new_limb_owner.updatehealth() new_limb_owner.update_body() new_limb_owner.update_damage_overlays() @@ -411,16 +409,6 @@ new_head_owner.update_body() new_head_owner.update_damage_overlays() -///Makes sure that the owner's bodytype flags match the flags of all of it's parts. -/obj/item/bodypart/proc/synchronize_bodytypes(mob/living/carbon/carbon_owner) - var/all_limb_flags - for(var/obj/item/bodypart/limb as anything in carbon_owner.bodyparts) - for(var/obj/item/organ/external/ext_organ as anything in limb.external_organs) - all_limb_flags = all_limb_flags | ext_organ.external_bodytypes - all_limb_flags = all_limb_flags | limb.bodytype - - carbon_owner.bodytype = all_limb_flags - /mob/living/carbon/proc/regenerate_limbs(list/excluded_zones = list()) SEND_SIGNAL(src, COMSIG_CARBON_REGENERATE_LIMBS, excluded_zones) var/list/zone_list = list(BODY_ZONE_HEAD, BODY_ZONE_CHEST, BODY_ZONE_R_ARM, BODY_ZONE_L_ARM, BODY_ZONE_R_LEG, BODY_ZONE_L_LEG) diff --git a/code/modules/surgery/bodyparts/helpers.dm b/code/modules/surgery/bodyparts/helpers.dm index 96a67e848d4..5b1c13f76e0 100644 --- a/code/modules/surgery/bodyparts/helpers.dm +++ b/code/modules/surgery/bodyparts/helpers.dm @@ -168,7 +168,15 @@ if(new_bodypart) new_bodypart.update_limb(is_creating = TRUE) +/// Makes sure that the owner's bodytype flags match the flags of all of it's parts and organs +/mob/living/carbon/proc/synchronize_bodytypes() + var/all_limb_flags = NONE + for(var/obj/item/bodypart/limb as anything in bodyparts) + for(var/obj/item/organ/external/ext_organ as anything in limb.external_organs) + all_limb_flags |= ext_organ.external_bodytypes + all_limb_flags |= limb.bodytype + bodytype = all_limb_flags /proc/skintone2hex(skin_tone) . = 0 diff --git a/code/modules/surgery/bodyparts/parts.dm b/code/modules/surgery/bodyparts/parts.dm index 47900ab5356..65b3a7062fb 100644 --- a/code/modules/surgery/bodyparts/parts.dm +++ b/code/modules/surgery/bodyparts/parts.dm @@ -326,13 +326,12 @@ max_damage = 100 should_draw_greyscale = FALSE -/// Parent Type for arms, should not appear in game. +/// Parent Type for legs, should not appear in game. /obj/item/bodypart/leg name = "leg" desc = "This item shouldn't exist. Talk about breaking a leg. Badum-Tss!" attack_verb_continuous = list("kicks", "stomps") attack_verb_simple = list("kick", "stomp") - bodytype = BODYTYPE_HUMANOID | BODYTYPE_MONKEY | BODYTYPE_ORGANIC max_damage = 50 body_damage_coeff = 0.75 can_be_disabled = TRUE diff --git a/code/modules/surgery/organs/external/_external_organ.dm b/code/modules/surgery/organs/external/_external_organ.dm index e682a5098b2..5c00a73532c 100644 --- a/code/modules/surgery/organs/external/_external_organ.dm +++ b/code/modules/surgery/organs/external/_external_organ.dm @@ -86,7 +86,7 @@ add_to_limb(ownerlimb) if(external_bodytypes) - limb.synchronize_bodytypes(receiver) + receiver.synchronize_bodytypes() receiver.update_body_parts() @@ -123,7 +123,7 @@ ownerlimb.external_organs -= src ownerlimb.remove_bodypart_overlay(bodypart_overlay) if(ownerlimb.owner && external_bodytypes) - ownerlimb.synchronize_bodytypes(ownerlimb.owner) + ownerlimb.owner.synchronize_bodytypes() ownerlimb = null return ..() diff --git a/tgstation.dme b/tgstation.dme index 32d4571a16e..8e6552bb017 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -4147,10 +4147,10 @@ #include "code\modules\mob\living\carbon\human\inventory.dm" #include "code\modules\mob\living\carbon\human\life.dm" #include "code\modules\mob\living\carbon\human\login.dm" +#include "code\modules\mob\living\carbon\human\monkey.dm" #include "code\modules\mob\living\carbon\human\physiology.dm" #include "code\modules\mob\living\carbon\human\status_procs.dm" #include "code\modules\mob\living\carbon\human\suicides.dm" -#include "code\modules\mob\living\carbon\human\monkey\monkey.dm" #include "code\modules\mob\living\carbon\human\species_types\abductors.dm" #include "code\modules\mob\living\carbon\human\species_types\abominations.dm" #include "code\modules\mob\living\carbon\human\species_types\android.dm"