mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-24 04:27:35 +01:00
Prevents limb regeneration when changing species (#19945)
* Prevents clings from quick regenerating bodyparts * Clarify a comment * Reworks to work with monkeys and other sources as well * qdel organ if it doesn't get inserted * Use initial instead of creating and qdeling * Revert unnecessary cast
This commit is contained in:
@@ -1243,7 +1243,7 @@
|
||||
|
||||
/mob/living/carbon/human/proc/change_dna(datum/dna/new_dna, include_species_change = FALSE, keep_flavor_text = FALSE)
|
||||
if(include_species_change)
|
||||
set_species(new_dna.species.type, retain_damage = TRUE, transformation = TRUE)
|
||||
set_species(new_dna.species.type, retain_damage = TRUE, transformation = TRUE, keep_missing_bodyparts = TRUE)
|
||||
dna = new_dna.Clone()
|
||||
if (include_species_change) //We have to call this after new_dna.Clone() so that species actions don't get overwritten
|
||||
dna.species.on_species_gain(src)
|
||||
@@ -1258,7 +1258,19 @@
|
||||
sec_hud_set_ID()
|
||||
|
||||
|
||||
/mob/living/carbon/human/proc/set_species(datum/species/new_species, use_default_color = FALSE, delay_icon_update = FALSE, skip_same_check = FALSE, retain_damage = FALSE, transformation = FALSE)
|
||||
/**
|
||||
* Change a mob's species.
|
||||
*
|
||||
* Arguments:
|
||||
* * new_species - The user's new species.
|
||||
* * use_default_color - If true, use the species' default color for the new mob.
|
||||
* * delay_icon_update - If true, UpdateAppearance() won't be called in this proc.
|
||||
* * skip_same_check - If true, don't bail out early if we would be changing to our current species and run through everything anyway.
|
||||
* * retain_damage - If true, damage on the mob will be re-applied post-transform. Otherwise, the mob will have its organs healed.
|
||||
* * transformation - If true, don't apply new species traits to the mob. A false value should be used when creating a new mob instead of transforming into a new species.
|
||||
* * keep_missing_bodyparts - If true, any bodyparts (legs, head, etc.) that were missing on the mob before species change will be missing post-change as well.
|
||||
*/
|
||||
/mob/living/carbon/human/proc/set_species(datum/species/new_species, use_default_color = FALSE, delay_icon_update = FALSE, skip_same_check = FALSE, retain_damage = FALSE, transformation = FALSE, keep_missing_bodyparts = FALSE)
|
||||
if(!skip_same_check)
|
||||
if(dna.species.name == initial(new_species.name))
|
||||
return
|
||||
@@ -1316,9 +1328,16 @@
|
||||
if(!transformation) //Distinguish between creating a mob and switching species
|
||||
dna.species.on_species_gain(src)
|
||||
|
||||
var/list/missing_bodyparts = list() // should line up here to pop out only what's missing
|
||||
if(keep_missing_bodyparts)
|
||||
for(var/organ_name as anything in bodyparts_by_name)
|
||||
if(isnull(bodyparts_by_name[organ_name]))
|
||||
missing_bodyparts |= organ_name
|
||||
|
||||
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 as anything in bodyparts)
|
||||
if(E.brute_dam == 0 && E.burn_dam == 0 && !(E.status & ORGAN_INT_BLEEDING)) //If there's no damage we don't bother remembering it.
|
||||
@@ -1342,7 +1361,7 @@
|
||||
internal_damages += list(stats)
|
||||
|
||||
//Create the new organs for the species change
|
||||
dna.species.create_organs(src)
|
||||
dna.species.create_organs(src, missing_bodyparts)
|
||||
|
||||
//Apply relevant damages and variables to the new organs.
|
||||
for(var/obj/item/organ/external/E as anything in bodyparts)
|
||||
@@ -1377,7 +1396,7 @@
|
||||
qdel(part)
|
||||
|
||||
else
|
||||
dna.species.create_organs(src)
|
||||
dna.species.create_organs(src, missing_bodyparts)
|
||||
|
||||
for(var/obj/item/thing in kept_items)
|
||||
var/equipped = equip_to_slot_if_possible(thing, kept_items[thing])
|
||||
|
||||
@@ -190,7 +190,15 @@
|
||||
var/datum/language/species_language = GLOB.all_languages[language]
|
||||
return species_language.get_random_name(gender)
|
||||
|
||||
/datum/species/proc/create_organs(mob/living/carbon/human/H) //Handles creation of mob organs.
|
||||
|
||||
/**
|
||||
* Handles creation of mob organs.
|
||||
*
|
||||
* Arguments:
|
||||
* * H: The human to create organs inside of
|
||||
* * bodyparts_to_omit: Any bodyparts in this list (and organs within them) should not be added.
|
||||
*/
|
||||
/datum/species/proc/create_organs(mob/living/carbon/human/H, list/bodyparts_to_omit) //Handles creation of mob organs.
|
||||
QDEL_LIST_CONTENTS(H.internal_organs)
|
||||
QDEL_LIST_CONTENTS(H.bodyparts)
|
||||
|
||||
@@ -198,21 +206,29 @@
|
||||
LAZYREINITLIST(H.bodyparts_by_name)
|
||||
LAZYREINITLIST(H.internal_organs)
|
||||
|
||||
for(var/limb_type in has_limbs)
|
||||
var/list/organ_data = has_limbs[limb_type]
|
||||
for(var/limb_name in has_limbs)
|
||||
if(bodyparts_to_omit && (limb_name in bodyparts_to_omit))
|
||||
H.bodyparts_by_name[limb_name] = null // Null it out, but leave the name here so it's still "there"
|
||||
continue
|
||||
var/list/organ_data = has_limbs[limb_name]
|
||||
var/limb_path = organ_data["path"]
|
||||
var/obj/item/organ/O = new limb_path(H)
|
||||
organ_data["descriptor"] = O.name
|
||||
|
||||
for(var/index in has_organ)
|
||||
var/organ = has_organ[index]
|
||||
// organ new code calls `insert` on its own
|
||||
new organ(H)
|
||||
var/obj/item/organ/internal/organ_path = has_organ[index]
|
||||
if(initial(organ_path.parent_organ) in bodyparts_to_omit)
|
||||
continue
|
||||
|
||||
var/obj/item/organ/internal/org = new organ_path()
|
||||
org.insert(H)
|
||||
|
||||
create_mutant_organs(H)
|
||||
|
||||
for(var/name in H.bodyparts_by_name)
|
||||
H.bodyparts |= H.bodyparts_by_name[name]
|
||||
var/part_type = H.bodyparts_by_name[name]
|
||||
if(!isnull(part_type))
|
||||
H.bodyparts |= part_type // we do not want nulls here, even though it's alright to have them in bodyparts_by_name
|
||||
|
||||
for(var/obj/item/organ/external/E as anything in H.bodyparts)
|
||||
E.owner = H
|
||||
@@ -221,10 +237,15 @@
|
||||
/datum/species/proc/create_mutant_organs(mob/living/carbon/human/H)
|
||||
var/obj/item/organ/internal/ears/ears = H.get_int_organ(/obj/item/organ/internal/ears)
|
||||
if(ears)
|
||||
if(istype(ears, mutantears))
|
||||
// if they're the same, just heal them and don't bother replacing them
|
||||
ears.rejuvenate()
|
||||
return
|
||||
qdel(ears)
|
||||
|
||||
if(mutantears)
|
||||
ears = new mutantears(H)
|
||||
if(mutantears && !isnull(H.bodyparts_by_name[initial(mutantears.parent_organ)]))
|
||||
var/obj/item/organ/internal/ears/new_ears = new mutantears()
|
||||
new_ears.insert(H)
|
||||
|
||||
/datum/species/proc/breathe(mob/living/carbon/human/H)
|
||||
if(HAS_TRAIT(H, TRAIT_NOBREATH))
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/mob/living/carbon/human/proc/monkeyize()
|
||||
var/mob/H = src
|
||||
H.dna.SetSEState(GLOB.monkeyblock,1)
|
||||
H.dna.SetSEState(GLOB.monkeyblock, 1)
|
||||
singlemutcheck(H, GLOB.monkeyblock, MUTCHK_FORCED)
|
||||
|
||||
/mob/new_player/AIize()
|
||||
|
||||
Reference in New Issue
Block a user