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?)
This commit is contained in:
ChungusGamer666
2023-07-05 15:28:24 -03:00
committed by GitHub
parent 95298fb99d
commit c97f2e73ad
11 changed files with 42 additions and 26 deletions
+6
View File
@@ -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
@@ -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)
@@ -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)
@@ -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)
@@ -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
+1 -2
View File
@@ -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
+2 -2
View File
@@ -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 ..()