Slightly refactors adjustCloneLoss() and setCloneLoss() (#20838)

* Fix 0 cloneloss unmutating all organs only 20% of the time

* Clean up the rest of `adjustCloneLoss()`

* Add missing `setCloneLoss()` override for carbons

* Fix setting cloneloss to 0 not unmutating organs

* Fix the code instead

* Someone forgot about this operator

* Sean review; minor cleanup

* Deduplicate mass unmutation

* gnarg
This commit is contained in:
Nathan Winters
2023-04-25 21:13:33 +02:00
committed by GitHub
parent 837e62c4fa
commit efecd97f76
2 changed files with 53 additions and 38 deletions
@@ -24,7 +24,7 @@
if(sponge)
if(dna.species && amount > 0)
if(use_brain_mod)
amount = amount * dna.species.brain_mod
amount *= dna.species.brain_mod
sponge.damage = clamp(sponge.damage + amount, 0, 120)
if(sponge.damage >= 120)
visible_message("<span class='alert'><B>[src]</B> goes limp, [p_their()] facial expression utterly blank.</span>")
@@ -42,7 +42,7 @@
if(sponge)
if(dna.species && amount > 0)
if(use_brain_mod)
amount = amount * dna.species.brain_mod
amount *= dna.species.brain_mod
sponge.damage = clamp(amount, 0, 120)
if(sponge.damage >= 120)
visible_message("<span class='alert'><B>[src]</B> goes limp, [p_their()] facial expression utterly blank.</span>")
@@ -84,7 +84,7 @@
/mob/living/carbon/human/adjustBruteLoss(amount, updating_health = TRUE, damage_source = null, robotic = FALSE)
if(amount > 0)
if(dna.species)
amount = amount * dna.species.brute_mod
amount *= dna.species.brute_mod
take_overall_damage(amount, 0, updating_health, used_weapon = damage_source)
else
heal_overall_damage(-amount, 0, updating_health, FALSE, robotic)
@@ -94,7 +94,7 @@
/mob/living/carbon/human/adjustFireLoss(amount, updating_health = TRUE, damage_source = null, robotic = FALSE)
if(amount > 0)
if(dna.species)
amount = amount * dna.species.burn_mod
amount *= dna.species.burn_mod
take_overall_damage(0, amount, updating_health, used_weapon = damage_source)
else
heal_overall_damage(0, -amount, updating_health, FALSE, robotic)
@@ -106,7 +106,8 @@
/mob/living/carbon/human/proc/adjustBruteLossByPart(amount, organ_name, obj/damage_source = null, updating_health = TRUE)
if(dna.species && amount > 0)
amount = amount * dna.species.brute_mod
amount *= dna.species.brute_mod
if(organ_name in bodyparts_by_name)
var/obj/item/organ/external/O = get_organ(organ_name)
@@ -119,7 +120,7 @@
/mob/living/carbon/human/proc/adjustFireLossByPart(amount, organ_name, obj/damage_source = null, updating_health = TRUE)
if(dna.species && amount > 0)
amount = amount * dna.species.burn_mod
amount *= dna.species.burn_mod
if(organ_name in bodyparts_by_name)
var/obj/item/organ/external/O = get_organ(organ_name)
@@ -131,74 +132,88 @@
O.heal_damage(0, -amount, internal = 0, robo_repair = O.is_robotic(), updating_health = updating_health)
return STATUS_UPDATE_HEALTH
/mob/living/carbon/human/proc/unmutateAllBodyparts()
for(var/obj/item/organ/external/O in bodyparts)
if(O.status & ORGAN_MUTATED)
O.unmutate()
to_chat(src, "<span class='notice'>Your [O.name] is shaped normally again.</span>")
/mob/living/carbon/human/adjustCloneLoss(amount)
if(dna.species && amount > 0)
amount = amount * dna.species.clone_mod
amount *= dna.species.clone_mod
. = ..()
var/heal_prob = max(0, 80 - getCloneLoss())
if(!amount)
return
var/mut_prob = min(80, getCloneLoss() + 10)
if(amount > 0) //cloneloss is being added
if(prob(mut_prob))
var/list/obj/item/organ/external/candidates = list() //TYPECASTED LISTS ARE NOT A FUCKING THING WHAT THE FUCK
for(var/obj/item/organ/external/O in bodyparts)
if(O.is_robotic())
continue
if(!(O.status & ORGAN_MUTATED))
candidates |= O
var/heal_prob = max(0, 80 - getCloneLoss())
if(candidates.len)
var/obj/item/organ/external/O = pick(candidates)
O.mutate()
to_chat(src, "<span class='notice'>Something is not right with your [O.name]...</span>")
O.add_autopsy_data("Mutation", amount)
return
if(!getCloneLoss()) // All cloneloss was purged - fix all organs
unmutateAllBodyparts()
return
else //cloneloss is being subtracted
if(prob(heal_prob))
for(var/obj/item/organ/external/O in bodyparts)
if(O.status & ORGAN_MUTATED)
O.unmutate()
to_chat(src, "<span class='notice'>Your [O.name] is shaped normally again.</span>")
return
if(amount > 0) // Cloneloss was inflicted - chance to mutate an organ
if(!prob(mut_prob))
return
var/list/candidates = list()
for(var/obj/item/organ/external/O in bodyparts)
if(!O.is_robotic() && !(O.status & ORGAN_MUTATED))
candidates |= O
if(length(candidates))
var/obj/item/organ/external/O = pick(candidates)
O.mutate()
to_chat(src, "<span class='notice'>Something is not right with your [O.name]...</span>")
O.add_autopsy_data("Mutation", amount)
else // Cloneloss was partially healed - chance to unmutate an organ
if(!prob(heal_prob))
return
if(getCloneLoss() < 1) //no cloneloss, fixes organs
for(var/obj/item/organ/external/O in bodyparts)
if(O.status & ORGAN_MUTATED)
O.unmutate()
to_chat(src, "<span class='notice'>Your [O.name] is shaped normally again.</span>")
return
/mob/living/carbon/human/setCloneLoss(amount)
if(dna.species && amount > 0)
amount *= dna.species.clone_mod
. = ..()
if(!amount) // Cloneloss was set to 0 - fix all organs
unmutateAllBodyparts()
// Defined here solely to take species flags into account without having to recast at mob/living level.
/mob/living/carbon/human/adjustOxyLoss(amount)
if(dna.species && amount > 0)
amount = amount * dna.species.oxy_mod
amount *= dna.species.oxy_mod
. = ..()
/mob/living/carbon/human/setOxyLoss(amount)
if(dna.species && amount > 0)
amount = amount * dna.species.oxy_mod
amount *= dna.species.oxy_mod
. = ..()
/mob/living/carbon/human/adjustToxLoss(amount)
if(dna.species && amount > 0)
amount = amount * dna.species.tox_mod
amount *= dna.species.tox_mod
. = ..()
/mob/living/carbon/human/setToxLoss(amount)
if(dna.species && amount > 0)
amount = amount * dna.species.tox_mod
amount *= dna.species.tox_mod
. = ..()
/mob/living/carbon/human/adjustStaminaLoss(amount, updating = TRUE)
if(dna.species && amount > 0)
amount = amount * dna.species.stamina_mod
amount *= dna.species.stamina_mod
. = ..()
/mob/living/carbon/human/setStaminaLoss(amount, updating = TRUE)
if(dna.species && amount > 0)
amount = amount * dna.species.stamina_mod
amount *= dna.species.stamina_mod
. = ..()
////////////////////////////////////////////
@@ -156,10 +156,10 @@
/datum/reagent/medicine/rezadone/on_mob_life(mob/living/M)
var/update_flags = STATUS_UPDATE_NONE
update_flags |= M.setCloneLoss(0, FALSE) //Rezadone is almost never used in favor of cryoxadone. Hopefully this will change that.
update_flags |= M.adjustCloneLoss(-1, FALSE) //What? We just set cloneloss to 0. Why? Simple; this is so external organs properly unmutate. // why don't you fix the code instead
update_flags |= M.setCloneLoss(0, FALSE) // Rezadone is almost never used in favor of cryoxadone. Hopefully this will change that.
update_flags |= M.adjustBruteLoss(-1, FALSE)
update_flags |= M.adjustFireLoss(-1, FALSE)
if(ishuman(M))
var/mob/living/carbon/human/H = M
var/obj/item/organ/external/head/head = H.get_organ("head")