From efecd97f762e71c4a1e7c73ddbc5f85d721e8946 Mon Sep 17 00:00:00 2001
From: Nathan Winters <100448493+CinnamonSnowball@users.noreply.github.com>
Date: Tue, 25 Apr 2023 21:13:33 +0200
Subject: [PATCH] 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
---
.../mob/living/carbon/human/human_damage.dm | 87 +++++++++++--------
.../reagents/chemistry/reagents/medicine.dm | 4 +-
2 files changed, 53 insertions(+), 38 deletions(-)
diff --git a/code/modules/mob/living/carbon/human/human_damage.dm b/code/modules/mob/living/carbon/human/human_damage.dm
index 8c24e9f9bf2..e369e4e2acb 100644
--- a/code/modules/mob/living/carbon/human/human_damage.dm
+++ b/code/modules/mob/living/carbon/human/human_damage.dm
@@ -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("[src] goes limp, [p_their()] facial expression utterly blank.")
@@ -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("[src] goes limp, [p_their()] facial expression utterly blank.")
@@ -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, "Your [O.name] is shaped normally again.")
+
/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, "Something is not right with your [O.name]...")
- 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, "Your [O.name] is shaped normally again.")
- 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, "Something is not right with your [O.name]...")
+ 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, "Your [O.name] is shaped normally again.")
+ 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
. = ..()
////////////////////////////////////////////
diff --git a/code/modules/reagents/chemistry/reagents/medicine.dm b/code/modules/reagents/chemistry/reagents/medicine.dm
index c520bf1286b..48d5277fc9a 100644
--- a/code/modules/reagents/chemistry/reagents/medicine.dm
+++ b/code/modules/reagents/chemistry/reagents/medicine.dm
@@ -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")