diff --git a/code/game/gamemodes/changeling/changeling_power.dm b/code/game/gamemodes/changeling/changeling_power.dm index da5c31fc092..387e7ce9d61 100644 --- a/code/game/gamemodes/changeling/changeling_power.dm +++ b/code/game/gamemodes/changeling/changeling_power.dm @@ -87,7 +87,7 @@ if(!D) return - H.set_species(D.species.type) + H.set_species(D.species.type, retain_damage = TRUE) H.dna = D.Clone() H.real_name = D.real_name domutcheck(H, null, MUTCHK_FORCED) //Ensures species that get powers by the species proc handle_dna keep them diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 80ff83b7d21..fd72a50bca1 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -1272,7 +1272,7 @@ else to_chat(usr, "[self ? "Your" : "[src]'s"] pulse is [src.get_pulse(GETPULSE_HAND)].") -/mob/living/carbon/human/proc/set_species(datum/species/new_species, default_colour, delay_icon_update = FALSE, skip_same_check = FALSE) +/mob/living/carbon/human/proc/set_species(datum/species/new_species, default_colour, delay_icon_update = FALSE, skip_same_check = FALSE, retain_damage = FALSE) if(!skip_same_check) if(dna.species.name == initial(new_species.name)) return @@ -1325,7 +1325,69 @@ if(I) kept_items[I] = thing - dna.species.create_organs(src) + if(retain_damage) + //Create a list of body parts which are damaged by burn or brute and save them to apply after new organs are generated. First we just handle external organs. + var/bodypart_damages = list() + //Loop through all external organs and save the damage states for brute and burn + for(var/obj/item/organ/external/E in bodyparts) + if(E.brute_dam == 0 && E.burn_dam == 0 && E.internal_bleeding == FALSE) //If there's no damage we don't bother remembering it. + continue + var/brute = E.brute_dam + var/burn = E.burn_dam + var/IB = E.internal_bleeding + var/obj/item/organ/external/OE = new E.type() + var/stats = list(OE, brute, burn, IB) + bodypart_damages += list(stats) + + //Now we do the same for internal organs via the same proceedure. + var/internal_damages = list() + for(var/obj/item/organ/internal/I in internal_organs) + if(I.damage == 0) + continue + var/obj/item/organ/internal/OI = new I.type() + var/damage = I.damage + var/broken = I.is_broken() + var/stats = list(OI, damage, broken) + internal_damages += list(stats) + + //Create the new organs for the species change + dna.species.create_organs(src) + + //Apply relevant damages and variables to the new organs. + for(var/B in bodyparts) + var/obj/item/organ/external/E = B + for(var/list/part in bodypart_damages) + var/obj/item/organ/external/OE = part[1] + if((E.type == OE.type)) // Type has to be explicit, as right limbs are a child of left ones etc. + var/brute = part[2] + var/burn = part[3] + var/IB = part[4] + //Deal the damage to the new organ and then delete the entry to prevent duplicate checks + E.receive_damage(brute, burn, ignore_resists = TRUE) + E.internal_bleeding = IB + qdel(part) + + for(var/O in internal_organs) + var/obj/item/organ/internal/I = O + for(var/list/part in internal_damages) + var/obj/item/organ/internal/OI = part[1] + var/organ_type + + if(OI.parent_type == /obj/item/organ/internal) //Dealing with species organs + organ_type = OI.type + else + organ_type = OI.parent_type + + if(istype(I, organ_type)) + var/damage = part[2] + var/broken = part[3] + I.receive_damage(damage, 1) + if(broken && !(I.status & ORGAN_BROKEN)) + I.status |= ORGAN_BROKEN + qdel(part) + + else + dna.species.create_organs(src) for(var/thing in kept_items) equip_to_slot_if_possible(thing, kept_items[thing], redraw_mob = 0)