mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-24 13:38:41 +01:00
Turns TRAIT_NOCLONE into TRAIT_BADDNA for consistency (#41819)
cl XDTM balance: DNA-damaging methods (changeling draining, mainly) no longer prevent alternative revival methods, but can no longer be circumvented by upgrading DNA scanners. balance: Any source of husking now prevents cloning on unupgraded cloning scanners, instead of only husking caused by changelings. balance: Husking now fully prevents revival from several non-cloning methods, including defibrillation, surgery, and strange reagent. /cl Why? Consistency! Also, the removal of prescanning/autocloning really simplifies this. Changeling draining effectively prevents cloning until you transfer the brain to an intact body.
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
#define TRAIT_NEARSIGHT "nearsighted"
|
||||
#define TRAIT_FAT "fat"
|
||||
#define TRAIT_HUSK "husk"
|
||||
#define TRAIT_NOCLONE "noclone"
|
||||
#define TRAIT_BADDNA "baddna"
|
||||
#define TRAIT_CLUMSY "clumsy"
|
||||
#define TRAIT_DUMB "dumb"
|
||||
#define TRAIT_MONKEYLIKE "monkeylike" //sets IsAdvancedToolUser to FALSE
|
||||
|
||||
@@ -504,8 +504,12 @@
|
||||
scantemp = "<font class='bad'>Subject's brain is not responding to scanning stimuli.</font>"
|
||||
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
|
||||
return
|
||||
if((mob_occupant.has_trait(TRAIT_NOCLONE)) && (scanner.scan_level < 2))
|
||||
scantemp = "<font class='bad'>Subject no longer contains the fundamental materials required to create a living clone.</font>"
|
||||
if((mob_occupant.has_trait(TRAIT_HUSK)) && (src.scanner.scan_level < 2))
|
||||
scantemp = "<font class='bad'>Subject's body is too damaged to scan properly.</font>"
|
||||
playsound(src, 'sound/machines/terminal_alert.ogg', 50, 0)
|
||||
return
|
||||
if(mob_occupant.has_trait(TRAIT_BADDNA))
|
||||
scantemp = "<font class='bad'>Subject's DNA is damaged beyond any hope of recovery.</font>"
|
||||
playsound(src, 'sound/machines/terminal_alert.ogg', 50, 0)
|
||||
return
|
||||
if (isnull(mob_occupant.mind))
|
||||
|
||||
@@ -101,7 +101,7 @@
|
||||
if(connected && connected.is_operational())
|
||||
if(connected.occupant) //set occupant_status message
|
||||
viable_occupant = connected.occupant
|
||||
if(viable_occupant.has_dna() && !viable_occupant.has_trait(TRAIT_RADIMMUNE) && !viable_occupant.has_trait(TRAIT_NOCLONE) || (connected.scan_level == 3)) //occupant is viable for dna modification
|
||||
if(viable_occupant.has_dna() && !viable_occupant.has_trait(TRAIT_RADIMMUNE) && !viable_occupant.has_trait(TRAIT_BADDNA) || (connected.scan_level == 3)) //occupant is viable for dna modification
|
||||
occupant_status += "[viable_occupant.name] => "
|
||||
switch(viable_occupant.stat)
|
||||
if(CONSCIOUS)
|
||||
@@ -778,7 +778,7 @@
|
||||
var/mob/living/carbon/viable_occupant = null
|
||||
if(connected)
|
||||
viable_occupant = connected.occupant
|
||||
if(!istype(viable_occupant) || !viable_occupant.dna || viable_occupant.has_trait(TRAIT_RADIMMUNE) || viable_occupant.has_trait(TRAIT_NOCLONE))
|
||||
if(!istype(viable_occupant) || !viable_occupant.dna || viable_occupant.has_trait(TRAIT_RADIMMUNE) || viable_occupant.has_trait(TRAIT_BADDNA))
|
||||
viable_occupant = null
|
||||
return viable_occupant
|
||||
|
||||
|
||||
@@ -100,7 +100,6 @@
|
||||
|
||||
..(user)
|
||||
|
||||
|
||||
// DNA manipulators cannot operate on severed heads or brains
|
||||
if(iscarbon(occupant))
|
||||
var/obj/machinery/computer/scan_consolenew/console = locate_computer(/obj/machinery/computer/scan_consolenew)
|
||||
|
||||
@@ -270,8 +270,12 @@
|
||||
scantemp = "<font class='bad'>Unable to locate valid genetic data.</font>"
|
||||
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
|
||||
return
|
||||
if((mob_occupant.has_trait(TRAIT_NOCLONE)) && (src.scanner.scan_level < 2))
|
||||
scantemp = "<font class='bad'>Subject no longer contains the fundamental materials required to create a living clone.</font>"
|
||||
if((mob_occupant.has_trait(TRAIT_HUSK)) && (src.scanner.scan_level < 2))
|
||||
scantemp = "<font class='bad'>Subject's body is too damaged to scan properly.</font>"
|
||||
playsound(src, 'sound/machines/terminal_alert.ogg', 50, 0)
|
||||
return
|
||||
if(mob_occupant.has_trait(TRAIT_BADDNA))
|
||||
scantemp = "<font class='bad'>Subject's DNA is damaged beyond any hope of recovery.</font>"
|
||||
playsound(src, 'sound/machines/terminal_alert.ogg', 50, 0)
|
||||
return
|
||||
|
||||
|
||||
@@ -437,7 +437,7 @@
|
||||
do_help(H, user)
|
||||
|
||||
/obj/item/twohanded/shockpaddles/proc/can_defib(mob/living/carbon/H)
|
||||
if(H.suiciding || H.has_trait(TRAIT_NOCLONE) || H.hellbound)
|
||||
if(H.suiciding || H.hellbound || H.has_trait(TRAIT_HUSK))
|
||||
return
|
||||
if((world.time - H.timeofdeath) > tlimit)
|
||||
return
|
||||
@@ -569,7 +569,7 @@
|
||||
shock_touching(30, H)
|
||||
var/failed
|
||||
|
||||
if (H.suiciding || (H.has_trait(TRAIT_NOCLONE)))
|
||||
if (H.suiciding)
|
||||
failed = "<span class='warning'>[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Recovery of patient impossible. Further attempts futile.</span>"
|
||||
else if (H.hellbound)
|
||||
failed = "<span class='warning'>[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Patient's soul appears to be on another plane of existence. Further attempts futile.</span>"
|
||||
@@ -577,7 +577,7 @@
|
||||
failed = "<span class='warning'>[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Body has decayed for too long. Further attempts futile.</span>"
|
||||
else if (!H.getorgan(/obj/item/organ/heart))
|
||||
failed = "<span class='warning'>[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Patient's heart is missing.</span>"
|
||||
else if(total_burn >= MAX_REVIVE_FIRE_DAMAGE || total_brute >= MAX_REVIVE_BRUTE_DAMAGE)
|
||||
else if(total_burn >= MAX_REVIVE_FIRE_DAMAGE || total_brute >= MAX_REVIVE_BRUTE_DAMAGE || H.has_trait(TRAIT_HUSK))
|
||||
failed = "<span class='warning'>[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Severe tissue damage makes recovery of patient impossible via defibrillator. Further attempts futile.</span>"
|
||||
else if(H.get_ghost())
|
||||
failed = "<span class='warning'>[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - No activity in patient's brain. Further attempts may be successful.</span>"
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
return attack_hand(user)
|
||||
|
||||
/obj/item/dnainjector/proc/inject(mob/living/carbon/M, mob/user)
|
||||
if(M.has_dna() && !M.has_trait(TRAIT_RADIMMUNE) && !M.has_trait(TRAIT_NOCLONE))
|
||||
if(M.has_dna() && !M.has_trait(TRAIT_RADIMMUNE) && !M.has_trait(TRAIT_BADDNA))
|
||||
M.radiation += rand(20/(damage_coeff ** 2),50/(damage_coeff ** 2))
|
||||
var/log_msg = "[key_name(user)] injected [key_name(M)] with the [name]"
|
||||
for(var/HM in remove_mutations)
|
||||
@@ -304,7 +304,7 @@
|
||||
to_chat(user, "<span class='notice'>You can't modify [M]'s DNA while [M.p_theyre()] dead.</span>")
|
||||
return FALSE
|
||||
|
||||
if(M.has_dna() && !(M.has_trait(TRAIT_NOCLONE)))
|
||||
if(M.has_dna() && !(M.has_trait(TRAIT_BADDNA)))
|
||||
M.radiation += rand(20/(damage_coeff ** 2),50/(damage_coeff ** 2))
|
||||
var/log_msg = "[key_name(user)] injected [key_name(M)] with the [name]"
|
||||
var/endtime = world.time+duration
|
||||
@@ -364,7 +364,7 @@
|
||||
var/doitanyway = FALSE
|
||||
|
||||
/obj/item/dnainjector/activator/inject(mob/living/carbon/M, mob/user)
|
||||
if(M.has_dna() && !M.has_trait(TRAIT_RADIMMUNE) && !M.has_trait(TRAIT_NOCLONE))
|
||||
if(M.has_dna() && !M.has_trait(TRAIT_RADIMMUNE) && !M.has_trait(TRAIT_BADDNA))
|
||||
M.radiation += rand(20/(damage_coeff ** 2),50/(damage_coeff ** 2))
|
||||
var/log_msg = "[key_name(user)] injected [key_name(M)] with the [name]"
|
||||
for(var/mutation in add_mutations)
|
||||
|
||||
@@ -184,7 +184,7 @@ GLOBAL_LIST_EMPTY(bodycontainers) //Let them act as spawnpoints for revenants an
|
||||
|
||||
for(var/mob/living/M in compiled)
|
||||
var/mob/living/mob_occupant = get_mob_or_brainmob(M)
|
||||
if(mob_occupant.client && !mob_occupant.suiciding && !(mob_occupant.has_trait(TRAIT_NOCLONE)) && !mob_occupant.hellbound)
|
||||
if(mob_occupant.client && !mob_occupant.suiciding && !(mob_occupant.has_trait(TRAIT_BADDNA)) && !mob_occupant.hellbound)
|
||||
icon_state = "morgue4" // Cloneable
|
||||
if(mob_occupant.stat == DEAD && beeper)
|
||||
if(world.time > next_beep)
|
||||
|
||||
@@ -240,10 +240,14 @@
|
||||
if(verbose)
|
||||
to_chat(user, "<span class='warning'>[target] is not compatible with our biology.</span>")
|
||||
return
|
||||
if((target.has_trait(TRAIT_NOCLONE)) || (target.has_trait(TRAIT_NOCLONE)))
|
||||
if(target.has_trait(TRAIT_BADDNA))
|
||||
if(verbose)
|
||||
to_chat(user, "<span class='warning'>DNA of [target] is ruined beyond usability!</span>")
|
||||
return
|
||||
if(target.has_trait(TRAIT_HUSK))
|
||||
if(verbose)
|
||||
to_chat(user, "<span class='warning'>[target]'s body is ruined beyond usability!</span>")
|
||||
return
|
||||
if(!ishuman(target))//Absorbing monkeys is entirely possible, but it can cause issues with transforming. That's what lesser form is for anyway!
|
||||
if(verbose)
|
||||
to_chat(user, "<span class='warning'>We could gain no benefit from absorbing a lesser creature.</span>")
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
|
||||
/mob/living/carbon/monkey/handle_blood()
|
||||
if(bodytemperature >= TCRYO && !(has_trait(TRAIT_NOCLONE))) //cryosleep or husked people do not pump the blood.
|
||||
if(bodytemperature >= TCRYO && !(has_trait(TRAIT_HUSK))) //cryosleep or husked people do not pump the blood.
|
||||
//Blood regeneration if there is some space
|
||||
if(blood_volume < BLOOD_VOLUME_NORMAL)
|
||||
blood_volume += 0.1 // regenerate blood VERY slowly
|
||||
@@ -30,7 +30,7 @@
|
||||
bleed_rate = 0
|
||||
return
|
||||
|
||||
if(bodytemperature >= TCRYO && !(has_trait(TRAIT_NOCLONE))) //cryosleep or husked people do not pump the blood.
|
||||
if(bodytemperature >= TCRYO && !(has_trait(TRAIT_HUSK))) //cryosleep or husked people do not pump the blood.
|
||||
|
||||
//Blood regeneration if there is some space
|
||||
if(blood_volume < BLOOD_VOLUME_NORMAL && !has_trait(TRAIT_NOHUNGER))
|
||||
@@ -209,13 +209,15 @@
|
||||
return "blood"
|
||||
|
||||
/mob/living/carbon/monkey/get_blood_id()
|
||||
if(!(has_trait(TRAIT_NOCLONE)))
|
||||
if(!(has_trait(TRAIT_HUSK)))
|
||||
return "blood"
|
||||
|
||||
/mob/living/carbon/human/get_blood_id()
|
||||
if(has_trait(TRAIT_HUSK))
|
||||
return
|
||||
if(dna.species.exotic_blood)
|
||||
return dna.species.exotic_blood
|
||||
else if((NOBLOOD in dna.species.species_traits) || (has_trait(TRAIT_NOCLONE)))
|
||||
else if((NOBLOOD in dna.species.species_traits))
|
||||
return
|
||||
return "blood"
|
||||
|
||||
|
||||
@@ -78,8 +78,8 @@
|
||||
if(!brainmob.stored_dna)
|
||||
brainmob.stored_dna = new /datum/dna/stored(brainmob)
|
||||
C.dna.copy_dna(brainmob.stored_dna)
|
||||
if(L.has_trait(TRAIT_NOCLONE))
|
||||
brainmob.status_traits[TRAIT_NOCLONE] = L.status_traits[TRAIT_NOCLONE]
|
||||
if(L.has_trait(TRAIT_BADDNA))
|
||||
brainmob.status_traits[TRAIT_BADDNA] = L.status_traits[TRAIT_BADDNA]
|
||||
var/obj/item/organ/zombie_infection/ZI = L.getorganslot(ORGAN_SLOT_ZOMBIE)
|
||||
if(ZI)
|
||||
brainmob.set_species(ZI.old_species) //For if the brain is cloned
|
||||
|
||||
@@ -54,6 +54,6 @@
|
||||
|
||||
/mob/living/carbon/proc/Drain()
|
||||
become_husk(CHANGELING_DRAIN)
|
||||
add_trait(TRAIT_NOCLONE, CHANGELING_DRAIN)
|
||||
add_trait(TRAIT_BADDNA, CHANGELING_DRAIN)
|
||||
blood_volume = 0
|
||||
return 1
|
||||
|
||||
@@ -768,7 +768,7 @@
|
||||
/obj/structure/cloth_pile/proc/revive()
|
||||
if(QDELETED(src) || QDELETED(cloth_golem)) //QDELETED also checks for null, so if no cloth golem is set this won't runtime
|
||||
return
|
||||
if(cloth_golem.suiciding || cloth_golem.has_trait(TRAIT_NOCLONE))
|
||||
if(cloth_golem.suiciding || cloth_golem.hellbound)
|
||||
QDEL_NULL(cloth_golem)
|
||||
return
|
||||
|
||||
|
||||
@@ -558,7 +558,7 @@ Difficulty: Very Hard
|
||||
H.regenerate_limbs()
|
||||
H.regenerate_organs()
|
||||
H.revive(1,0)
|
||||
H.add_trait(TRAIT_NOCLONE, MAGIC_TRAIT) //Free revives, but significantly limits your options for reviving except via the crystal
|
||||
H.add_trait(TRAIT_BADDNA, MAGIC_TRAIT) //Free revives, but significantly limits your options for reviving except via the crystal
|
||||
H.grab_ghost(force = TRUE)
|
||||
|
||||
/obj/machinery/anomalous_crystal/helpers //Lets ghost spawn as helpful creatures that can only heal people slightly. Incredibly fragile and they can't converse with humans
|
||||
|
||||
@@ -790,11 +790,11 @@
|
||||
|
||||
/datum/reagent/medicine/strange_reagent/reaction_mob(mob/living/carbon/human/M, method=TOUCH, reac_volume)
|
||||
if(M.stat == DEAD)
|
||||
if(M.getBruteLoss() >= 100 || M.getFireLoss() >= 100)
|
||||
if(M.getBruteLoss() >= 100 || M.getFireLoss() >= 100 || M.has_trait(TRAIT_HUSK))
|
||||
M.visible_message("<span class='warning'>[M]'s body convulses a bit, and then falls still once more.</span>")
|
||||
return
|
||||
M.visible_message("<span class='warning'>[M]'s body convulses a bit.</span>")
|
||||
if(!M.suiciding && !(M.has_trait(TRAIT_NOCLONE)) && !M.hellbound)
|
||||
if(!M.suiciding && !M.hellbound)
|
||||
if(!M)
|
||||
return
|
||||
if(M.notify_ghost_cloning(source = M))
|
||||
|
||||
@@ -215,7 +215,7 @@
|
||||
if(!iscarbon(host_mob)) //nonstandard biology
|
||||
return FALSE
|
||||
var/mob/living/carbon/C = host_mob
|
||||
if(C.suiciding || C.has_trait(TRAIT_NOCLONE) || C.hellbound) //can't revive
|
||||
if(C.suiciding || C.hellbound || C.has_trait(TRAIT_HUSK)) //can't revive
|
||||
return FALSE
|
||||
if((world.time - C.timeofdeath) > 1800) //too late
|
||||
return FALSE
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
return FALSE
|
||||
if(target.stat != DEAD)
|
||||
return FALSE
|
||||
if(target.suiciding || target.has_trait(TRAIT_NOCLONE) || target.hellbound)
|
||||
if(target.suiciding || target.hellbound || target.has_trait(TRAIT_HUSK))
|
||||
return FALSE
|
||||
var/obj/item/organ/brain/B = target.getorganslot(ORGAN_SLOT_BRAIN)
|
||||
if(!B)
|
||||
|
||||
Reference in New Issue
Block a user