mirror of
https://github.com/KabKebab/GS13.git
synced 2026-07-09 07:02:15 +01:00
whew
This commit is contained in:
@@ -99,6 +99,7 @@
|
||||
#define NOEYES 16
|
||||
#define MARKINGS 17
|
||||
|
||||
//organ slots
|
||||
#define ORGAN_SLOT_BRAIN "brain"
|
||||
#define ORGAN_SLOT_APPENDIX "appendix"
|
||||
#define ORGAN_SLOT_RIGHT_ARM_AUG "r_arm_device"
|
||||
@@ -122,3 +123,7 @@
|
||||
#define ORGAN_SLOT_BRAIN_ANTISTUN "brain_antistun"
|
||||
#define ORGAN_SLOT_TAIL "tail"
|
||||
#define ORGAN_SLOT_PENIS "penis"
|
||||
////organ defines
|
||||
#define STANDARD_ORGAN_THRESHOLD 100
|
||||
#define STANDARD_ORGAN_HEALING 0.001
|
||||
#define STANDARD_ORGAN_DECAY 0.00222 //designed to fail organs when left to decay for ~15 minutes
|
||||
@@ -10,6 +10,8 @@
|
||||
#define CHECK_BITFIELD(variable, flag) (variable & (flag))
|
||||
#define TOGGLE_BITFIELD(variable, flag) (variable ^= (flag))
|
||||
|
||||
#define CHECK_MULTIPLE_BITFIELDS(flagvar, flags) (((flagvar) & (flags)) == (flags))
|
||||
|
||||
GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768))
|
||||
|
||||
// for /datum/var/datum_flags
|
||||
|
||||
@@ -314,7 +314,7 @@ GLOBAL_LIST_INIT(pda_reskins, list(PDA_SKIN_CLASSIC = 'icons/obj/pda.dmi', PDA_S
|
||||
#define MAP_MAXZ 6
|
||||
|
||||
// Defib stats
|
||||
#define DEFIB_TIME_LIMIT 120
|
||||
#define DEFIB_TIME_LIMIT 960
|
||||
#define DEFIB_TIME_LOSS 60
|
||||
|
||||
// Diagonal movement
|
||||
|
||||
@@ -203,9 +203,6 @@
|
||||
|
||||
#define MAX_CHICKENS 50
|
||||
|
||||
#define UNHEALING_EAR_DAMAGE 100
|
||||
|
||||
|
||||
#define INCORPOREAL_MOVE_BASIC 1
|
||||
#define INCORPOREAL_MOVE_SHADOW 2 // leaves a trail of shadows
|
||||
#define INCORPOREAL_MOVE_JAUNT 3 // is blocked by holy water/salt
|
||||
@@ -256,6 +253,9 @@
|
||||
|
||||
#define MAX_QUIRKS 6 //The maximum amount of quirks one character can have at roundstart
|
||||
|
||||
#define MAX_REVIVE_FIRE_DAMAGE 180
|
||||
#define MAX_REVIVE_BRUTE_DAMAGE 180
|
||||
|
||||
// AI Toggles
|
||||
#define AI_CAMERA_LUMINOSITY 5
|
||||
#define AI_VOX // Comment out if you don't want VOX to be enabled and have players download the voice sounds.
|
||||
|
||||
@@ -38,3 +38,12 @@
|
||||
#define THICKMATERIAL (1<<5) //prevents syringes, parapens and hypos if the external suit or helmet (if targeting head) has this flag. Example: space suits, biosuit, bombsuits, thick suits that cover your body.
|
||||
#define VOICEBOX_TOGGLABLE (1<<6) // The voicebox in this clothing can be toggled.
|
||||
#define VOICEBOX_DISABLED (1<<7) // The voicebox is currently turned off.
|
||||
|
||||
// Flags for the organ_flags var on /obj/item/organ
|
||||
|
||||
#define ORGAN_SYNTHETIC (1<<0) //Synthetic organs, or cybernetic organs. Reacts to EMPs and don't deteriorate or heal
|
||||
#define ORGAN_FROZEN (1<<1) //Frozen organs, don't deteriorate
|
||||
#define ORGAN_FAILING (1<<2) //Failing organs perform damaging effects until replaced or fixed
|
||||
#define ORGAN_EXTERNAL (1<<3) //Was this organ implanted/inserted/etc, if true will not be removed during species change.
|
||||
#define ORGAN_VITAL (1<<4) //Currently only the brain
|
||||
#define ORGAN_NO_SPOIL (1<<5) //Currently only the brain
|
||||
@@ -8,6 +8,9 @@
|
||||
#define UNCONSCIOUS 2
|
||||
#define DEAD 3
|
||||
|
||||
//Maximum healthiness an individual can have
|
||||
#define MAX_SATIETY 600
|
||||
|
||||
// bitflags for machine stat variable
|
||||
#define BROKEN (1<<0)
|
||||
#define NOPOWER (1<<1)
|
||||
|
||||
@@ -159,6 +159,43 @@
|
||||
processing_list.Cut(1, 2)
|
||||
processing_list += A.contents
|
||||
|
||||
/** recursive_organ_check
|
||||
* inputs: O (object to start with)
|
||||
* outputs:
|
||||
* description: A pseudo-recursive loop based off of the recursive mob check, this check looks for any organs held
|
||||
* within 'O', toggling their frozen flag. This check excludes items held within other safe organ
|
||||
* storage units, so that only the lowest level of container dictates whether we do or don't decompose
|
||||
*/
|
||||
/proc/recursive_organ_check(atom/O)
|
||||
|
||||
var/list/processing_list = list(O)
|
||||
var/list/processed_list = list()
|
||||
var/index = 1
|
||||
var/obj/item/organ/found_organ
|
||||
|
||||
while(index <= length(processing_list))
|
||||
|
||||
var/atom/A = processing_list[index]
|
||||
|
||||
if(istype(A, /obj/item/organ))
|
||||
found_organ = A
|
||||
found_organ.organ_flags ^= ORGAN_FROZEN
|
||||
|
||||
else if(istype(A, /mob/living/carbon))
|
||||
var/mob/living/carbon/Q = A
|
||||
for(var/organ in Q.internal_organs)
|
||||
found_organ = organ
|
||||
found_organ.organ_flags ^= ORGAN_FROZEN
|
||||
|
||||
for(var/atom/B in A) //objects held within other objects are added to the processing list, unless that object is something that can hold organs safely
|
||||
if(!processed_list[B] && !istype(B, /obj/structure/closet/crate/freezer) && !istype(B, /obj/structure/closet/secure_closet/freezer))
|
||||
processing_list+= B
|
||||
|
||||
index++
|
||||
processed_list[A] = A
|
||||
|
||||
return
|
||||
|
||||
// Better recursive loop, technically sort of not actually recursive cause that shit is retarded, enjoy.
|
||||
//No need for a recursive limit either
|
||||
/proc/recursive_mob_check(atom/O,client_check=1,sight_check=1,include_radio=1)
|
||||
|
||||
@@ -177,4 +177,14 @@ GLOBAL_LIST_INIT(bitfields, list(
|
||||
"CAN_CARRY" = CAN_CARRY,
|
||||
"CAN_RESIST" = CAN_RESIST
|
||||
),
|
||||
))
|
||||
|
||||
"organ_flags" = list(
|
||||
"ORGAN_SYNTHETIC" = ORGAN_SYNTHETIC,
|
||||
"ORGAN_FROZEN" = ORGAN_FROZEN,
|
||||
"ORGAN_FAILING" = ORGAN_FAILING,
|
||||
"ORGAN_EXTERNAL" = ORGAN_EXTERNAL,
|
||||
"ORGAN_VITAL" = ORGAN_VITAL,
|
||||
"ORGAN_NO_SPOIL" = ORGAN_NO_SPOIL
|
||||
),
|
||||
))
|
||||
@@ -294,7 +294,7 @@ Versioning
|
||||
var/lakey = L.lastattackerckey
|
||||
var/sqlbrute = L.getBruteLoss()
|
||||
var/sqlfire = L.getFireLoss()
|
||||
var/sqlbrain = L.getBrainLoss()
|
||||
var/sqlbrain = L.getOrganLoss(ORGAN_SLOT_BRAIN)
|
||||
var/sqloxy = L.getOxyLoss()
|
||||
var/sqltox = L.getToxLoss()
|
||||
var/sqlclone = L.getCloneLoss()
|
||||
@@ -308,7 +308,7 @@ Versioning
|
||||
|
||||
if(!SSdbcore.Connect())
|
||||
return
|
||||
|
||||
|
||||
sqlname = sanitizeSQL(sqlname)
|
||||
sqlkey = sanitizeSQL(sqlkey)
|
||||
sqljob = sanitizeSQL(sqljob)
|
||||
|
||||
@@ -26,5 +26,5 @@
|
||||
if(!HAS_TRAIT(wearer, TRAIT_DEAF))
|
||||
var/obj/item/organ/ears/ears = wearer.getorganslot(ORGAN_SLOT_EARS)
|
||||
if (ears)
|
||||
ears.deaf = max(ears.deaf - 1, (ears.ear_damage < UNHEALING_EAR_DAMAGE ? 0 : 1)) // Do not clear deafness while above the unhealing ear damage threshold
|
||||
ears.ear_damage = max(ears.ear_damage - 0.1, 0)
|
||||
ears.deaf = max(ears.deaf - 1, (ears.damage < ears.maxHealth ? 0 : 1)) // Do not clear deafness if our ears are too damaged
|
||||
ears.damage = max(ears.damage - 0.1, 0)
|
||||
|
||||
@@ -94,10 +94,23 @@
|
||||
TOXIN:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=toxin' id='toxin'>[M.getToxLoss()]</a>
|
||||
OXY:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=oxygen' id='oxygen'>[M.getOxyLoss()]</a>
|
||||
CLONE:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=clone' id='clone'>[M.getCloneLoss()]</a>
|
||||
BRAIN:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=brain' id='brain'>[M.getBrainLoss()]</a>
|
||||
BRAIN:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=brain' id='brain'>[M.getOrganLoss(ORGAN_SLOT_BRAIN)]</a>
|
||||
STAMINA:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=stamina' id='stamina'>[M.getStaminaLoss()]</a>
|
||||
AROUSAL:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=arousal' id='arousal'>[M.getArousalLoss()]</a>
|
||||
</font>
|
||||
"}
|
||||
if(GLOB.Debug2)
|
||||
atomsnowflake += {"
|
||||
HEART:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=heart' id='heart'>[M.getOrganLoss(ORGAN_SLOT_HEART)]</a>
|
||||
LIVER:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=liver' id='liver'>[M.getOrganLoss(ORGAN_SLOT_LIVER)]</a>
|
||||
LUNGS:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=lungs' id='lungs'>[M.getOrganLoss(ORGAN_SLOT_LUNGS)]</a>
|
||||
EYES:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=eye_sight' id='eye_sight'>[M.getOrganLoss(ORGAN_SLOT_EYES)]</a>
|
||||
EARS:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=ears' id='ears'>[M.getOrganLoss(ORGAN_SLOT_EARS)]</a>
|
||||
STOMACH:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=stomach' id='stomach'>[M.getOrganLoss(ORGAN_SLOT_STOMACH)]</a>
|
||||
TONGUE:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=tongue' id='tongue'>[M.getOrganLoss(ORGAN_SLOT_TONGUE)]</a>
|
||||
APPENDIX:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=appendix' id='appendix'>[M.getOrganLoss(ORGAN_SLOT_APPENDIX)]</a>
|
||||
"}
|
||||
atomsnowflake += {"
|
||||
</font>
|
||||
"}
|
||||
else
|
||||
atomsnowflake += "<a href='?_src_=vars;[HrefToken()];datumedit=[refid];varnameedit=name'><b id='name'>[D]</b></a>"
|
||||
@@ -1334,8 +1347,8 @@
|
||||
L.adjustOxyLoss(amount)
|
||||
newamt = L.getOxyLoss()
|
||||
if("brain")
|
||||
L.adjustBrainLoss(amount)
|
||||
newamt = L.getBrainLoss()
|
||||
L.adjustOrganLoss(ORGAN_SLOT_BRAIN, amount)
|
||||
newamt = L.getOrganLoss(ORGAN_SLOT_BRAIN)
|
||||
if("clone")
|
||||
L.adjustCloneLoss(amount)
|
||||
newamt = L.getCloneLoss()
|
||||
@@ -1345,6 +1358,30 @@
|
||||
if("arousal")
|
||||
L.adjustArousalLoss(amount)
|
||||
newamt = L.getArousalLoss()
|
||||
if("heart")
|
||||
L.adjustOrganLoss(ORGAN_SLOT_HEART, amount)
|
||||
newamt = L.getOrganLoss(ORGAN_SLOT_HEART)
|
||||
if("liver")
|
||||
L.adjustOrganLoss(ORGAN_SLOT_LIVER, amount)
|
||||
newamt = L.getOrganLoss(ORGAN_SLOT_LIVER)
|
||||
if("lungs")
|
||||
L.adjustOrganLoss(ORGAN_SLOT_LUNGS, amount)
|
||||
newamt = L.getOrganLoss(ORGAN_SLOT_LUNGS)
|
||||
if("eye_sight")
|
||||
L.adjustOrganLoss(ORGAN_SLOT_EYES, amount)
|
||||
newamt = L.getOrganLoss(ORGAN_SLOT_EYES)
|
||||
if("ears")
|
||||
L.adjustOrganLoss(ORGAN_SLOT_EARS, amount)
|
||||
newamt = L.getOrganLoss(ORGAN_SLOT_EARS)
|
||||
if("stomach")
|
||||
L.adjustOrganLoss(ORGAN_SLOT_STOMACH, amount)
|
||||
newamt = L.getOrganLoss(ORGAN_SLOT_STOMACH)
|
||||
if("tongue")
|
||||
L.adjustOrganLoss(ORGAN_SLOT_TONGUE, amount)
|
||||
newamt = L.getOrganLoss(ORGAN_SLOT_TONGUE)
|
||||
if("appendix")
|
||||
L.adjustOrganLoss(ORGAN_SLOT_APPENDIX, amount)
|
||||
newamt = L.getOrganLoss(ORGAN_SLOT_APPENDIX)
|
||||
else
|
||||
to_chat(usr, "You caused an error. DEBUG: Text:[Text] Mob:[L]")
|
||||
return
|
||||
|
||||
@@ -144,5 +144,5 @@ Bonus
|
||||
/datum/symptom/asphyxiation/proc/Asphyxiate_death(mob/living/M, datum/disease/advance/A)
|
||||
var/get_damage = rand(25,35) * power
|
||||
M.adjustOxyLoss(get_damage)
|
||||
M.adjustBrainLoss(get_damage/2)
|
||||
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, get_damage/2)
|
||||
return 1
|
||||
|
||||
@@ -55,7 +55,7 @@ Bonus
|
||||
to_chat(M, "<span class='userdanger'>You can't think straight!</span>")
|
||||
M.confused = min(100 * power, M.confused + 8)
|
||||
if(brain_damage)
|
||||
M.adjustBrainLoss(3 * power, 80)
|
||||
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 3 * power, 80)
|
||||
M.updatehealth()
|
||||
|
||||
return
|
||||
|
||||
@@ -50,9 +50,9 @@ Bonus
|
||||
if(5)
|
||||
if(power > 2)
|
||||
var/obj/item/organ/ears/ears = M.getorganslot(ORGAN_SLOT_EARS)
|
||||
if(istype(ears) && ears.ear_damage < UNHEALING_EAR_DAMAGE)
|
||||
if(istype(ears) && ears.damage < ears.maxHealth)
|
||||
to_chat(M, "<span class='userdanger'>Your ears pop painfully and start bleeding!</span>")
|
||||
ears.ear_damage = max(ears.ear_damage, UNHEALING_EAR_DAMAGE)
|
||||
ears.damage = max(ears.damage, ears.maxHealth)
|
||||
M.emote("scream")
|
||||
else
|
||||
to_chat(M, "<span class='userdanger'>Your ears pop and begin ringing loudly!</span>")
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
M.hallucination = max(0, M.hallucination - 10)
|
||||
|
||||
if(A.stage >= 5)
|
||||
M.adjustBrainLoss(-3)
|
||||
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, -3)
|
||||
if(trauma_heal_mild && iscarbon(M))
|
||||
var/mob/living/carbon/C = M
|
||||
if(prob(10))
|
||||
@@ -100,8 +100,8 @@
|
||||
else if(M.eye_blind || M.eye_blurry)
|
||||
M.set_blindness(0)
|
||||
M.set_blurriness(0)
|
||||
else if(eyes.eye_damage > 0)
|
||||
M.adjust_eye_damage(-1)
|
||||
else if(eyes.damage > 0)
|
||||
eyes.applyOrganDamage(-1)
|
||||
else
|
||||
if(prob(base_message_chance))
|
||||
to_chat(M, "<span class='notice'>[pick("Your eyes feel great.","You feel like your eyes can focus more clearly.", "You don't feel the need to blink.","Your ears feel great.","Your healing feels more acute.")]</span>")
|
||||
@@ -45,7 +45,7 @@ Bonus
|
||||
return
|
||||
var/mob/living/carbon/M = A.affected_mob
|
||||
var/obj/item/organ/eyes/eyes = M.getorganslot(ORGAN_SLOT_EYES)
|
||||
if(istype(eyes))
|
||||
if(eyes)
|
||||
switch(A.stage)
|
||||
if(1, 2)
|
||||
if(prob(base_message_chance) && !suppress_warning)
|
||||
@@ -53,20 +53,20 @@ Bonus
|
||||
if(3, 4)
|
||||
to_chat(M, "<span class='warning'><b>Your eyes burn!</b></span>")
|
||||
M.blur_eyes(10)
|
||||
M.adjust_eye_damage(1)
|
||||
eyes.applyOrganDamage(1)
|
||||
else
|
||||
M.blur_eyes(20)
|
||||
M.adjust_eye_damage(5)
|
||||
if(eyes.eye_damage >= 10)
|
||||
eyes.applyOrganDamage(5)
|
||||
if(eyes.damage >= 10)
|
||||
M.become_nearsighted(EYE_DAMAGE)
|
||||
if(prob(eyes.eye_damage - 10 + 1))
|
||||
if(prob(eyes.damage - 10 + 1))
|
||||
if(!remove_eyes)
|
||||
if(!HAS_TRAIT(M, TRAIT_BLIND))
|
||||
to_chat(M, "<span class='userdanger'>You go blind!</span>")
|
||||
M.become_blind(EYE_DAMAGE)
|
||||
eyes.applyOrganDamage(eyes.maxHealth)
|
||||
else
|
||||
M.visible_message("<span class='warning'>[M]'s eyes fall off their sockets!</span>", "<span class='userdanger'>Your eyes fall off their sockets!</span>")
|
||||
eyes.Remove(M)
|
||||
eyes.forceMove(get_turf(M))
|
||||
else
|
||||
to_chat(M, "<span class='userdanger'>Your eyes burn horrifically!</span>")
|
||||
to_chat(M, "<span class='userdanger'>Your eyes burn horrifically!</span>")
|
||||
|
||||
@@ -27,8 +27,10 @@
|
||||
A.update_icon()
|
||||
if(prob(3))
|
||||
to_chat(affected_mob, "<span class='warning'>You feel a stabbing pain in your abdomen!</span>")
|
||||
affected_mob.adjustOrganLoss(ORGAN_SLOT_APPENDIX, 5)
|
||||
affected_mob.Stun(rand(40,60))
|
||||
affected_mob.adjustToxLoss(1)
|
||||
if(3)
|
||||
if(prob(1))
|
||||
affected_mob.vomit(95)
|
||||
affected_mob.adjustOrganLoss(ORGAN_SLOT_APPENDIX, 15)
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
if(prob(2))
|
||||
to_chat(affected_mob, "<span class='danger'>You don't feel like yourself.</span>")
|
||||
if(prob(5))
|
||||
affected_mob.adjustBrainLoss(1, 170)
|
||||
affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 1, 170)
|
||||
affected_mob.updatehealth()
|
||||
if(3)
|
||||
if(prob(2))
|
||||
@@ -32,7 +32,7 @@
|
||||
if(prob(2))
|
||||
affected_mob.emote("drool")
|
||||
if(prob(10))
|
||||
affected_mob.adjustBrainLoss(2, 170)
|
||||
affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 2, 170)
|
||||
affected_mob.updatehealth()
|
||||
if(prob(2))
|
||||
to_chat(affected_mob, "<span class='danger'>Your try to remember something important...but can't.</span>")
|
||||
@@ -43,7 +43,7 @@
|
||||
if(prob(2))
|
||||
affected_mob.emote("drool")
|
||||
if(prob(15))
|
||||
affected_mob.adjustBrainLoss(3, 170)
|
||||
affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 3, 170)
|
||||
affected_mob.updatehealth()
|
||||
if(prob(2))
|
||||
to_chat(affected_mob, "<span class='danger'>Strange buzzing fills your head, removing all thoughts.</span>")
|
||||
|
||||
@@ -79,7 +79,7 @@
|
||||
"<span class='userdanger'>[A] kicks your head, knocking you out!</span>")
|
||||
playsound(get_turf(A), 'sound/weapons/genhit1.ogg', 50, 1, -1)
|
||||
D.SetSleeping(300)
|
||||
D.adjustBrainLoss(15, 150)
|
||||
D.adjustOrganLoss(ORGAN_SLOT_BRAIN, 15, 150)
|
||||
return TRUE
|
||||
|
||||
/datum/martial_art/cqc/proc/Pressure(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
D.apply_damage(rand(5,10), BRUTE, BODY_ZONE_HEAD)
|
||||
A.apply_damage(rand(5,10), BRUTE, BODY_ZONE_HEAD)
|
||||
if(!istype(D.head,/obj/item/clothing/head/helmet/) && !istype(D.head,/obj/item/clothing/head/hardhat))
|
||||
D.adjustBrainLoss(5)
|
||||
D.adjustOrganLoss(ORGAN_SLOT_BRAIN, 5)
|
||||
A.Stun(rand(10,45))
|
||||
D.Knockdown(rand(5,30))//CIT CHANGE - makes stuns from martial arts always use Knockdown instead of Stun for the sake of consistency
|
||||
if(5,6)
|
||||
|
||||
@@ -224,7 +224,7 @@
|
||||
H.visible_message("<span class='warning'>[user] delivers a heavy hit to [H]'s head, knocking [H.p_them()] out cold!</span>", \
|
||||
"<span class='userdanger'>[user] knocks you unconscious!</span>")
|
||||
H.SetSleeping(600)
|
||||
H.adjustBrainLoss(15, 150)
|
||||
H.adjustOrganLoss(ORGAN_SLOT_BRAIN, 15, 150)
|
||||
else
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -520,7 +520,7 @@
|
||||
itemUser.adjustToxLoss(-1.5, forced = TRUE) //Because Slime People are people too
|
||||
itemUser.adjustOxyLoss(-1.5)
|
||||
itemUser.adjustStaminaLoss(-1.5)
|
||||
itemUser.adjustBrainLoss(-1.5)
|
||||
itemUser.adjustOrganLoss(ORGAN_SLOT_BRAIN, -1.5)
|
||||
itemUser.adjustCloneLoss(-0.5) //Becasue apparently clone damage is the bastion of all health
|
||||
//Heal all those around you, unbiased
|
||||
for(var/mob/living/L in view(7, owner))
|
||||
@@ -532,7 +532,7 @@
|
||||
L.adjustToxLoss(-3.5, forced = TRUE) //Because Slime People are people too
|
||||
L.adjustOxyLoss(-3.5)
|
||||
L.adjustStaminaLoss(-3.5)
|
||||
L.adjustBrainLoss(-3.5)
|
||||
L.adjustOrganLoss(ORGAN_SLOT_BRAIN, -3.5)
|
||||
L.adjustCloneLoss(-1) //Becasue apparently clone damage is the bastion of all health
|
||||
else if(issilicon(L))
|
||||
L.adjustBruteLoss(-3.5)
|
||||
|
||||
@@ -119,7 +119,7 @@
|
||||
medical_record_text = "Patient has a tumor in their brain that is slowly driving them to brain death."
|
||||
|
||||
/datum/quirk/brainproblems/on_process()
|
||||
quirk_holder.adjustBrainLoss(0.2)
|
||||
quirk_holder.adjustOrganLoss(ORGAN_SLOT_BRAIN, 0.2)
|
||||
|
||||
/datum/quirk/nearsighted //t. errorage
|
||||
name = "Nearsighted"
|
||||
@@ -345,9 +345,12 @@
|
||||
gain_text = "<span class='danger'>You find yourself unable to speak!</span>"
|
||||
lose_text = "<span class='notice'>You feel a growing strength in your vocal chords.</span>"
|
||||
medical_record_text = "Functionally mute, patient is unable to use their voice in any capacity."
|
||||
var/datum/brain_trauma/severe/mute/mute
|
||||
|
||||
/datum/quirk/mute/add()
|
||||
var/mob/living/carbon/human/H = quirk_holder
|
||||
mute = new
|
||||
H.gain_trauma(mute, TRAUMA_RESILIENCE_SURGERY)
|
||||
H.gain_trauma(TRAIT_MUTE, TRAUMA_RESILIENCE_SURGERY)
|
||||
|
||||
/datum/quirk/mute/on_process()
|
||||
|
||||
@@ -146,7 +146,7 @@
|
||||
data["occupant"]["toxLoss"] = mob_occupant.getToxLoss()
|
||||
data["occupant"]["fireLoss"] = mob_occupant.getFireLoss()
|
||||
data["occupant"]["cloneLoss"] = mob_occupant.getCloneLoss()
|
||||
data["occupant"]["brainLoss"] = mob_occupant.getBrainLoss()
|
||||
data["occupant"]["brainLoss"] = mob_occupant.getOrganLoss(ORGAN_SLOT_BRAIN)
|
||||
data["occupant"]["reagents"] = list()
|
||||
if(mob_occupant.reagents && mob_occupant.reagents.reagent_list.len)
|
||||
for(var/datum/reagent/R in mob_occupant.reagents.reagent_list)
|
||||
|
||||
@@ -241,13 +241,15 @@
|
||||
var/obj/item/I = pick_n_take(unattached_flesh)
|
||||
if(isorgan(I))
|
||||
var/obj/item/organ/O = I
|
||||
O.organ_flags &= ~ORGAN_FROZEN
|
||||
O.Insert(mob_occupant)
|
||||
else if(isbodypart(I))
|
||||
var/obj/item/bodypart/BP = I
|
||||
BP.attach_limb(mob_occupant)
|
||||
|
||||
//Premature clones may have brain damage.
|
||||
mob_occupant.adjustBrainLoss(-((speed_coeff / 2) * dmg_mult))
|
||||
mob_occupant.adjustOrganLoss(ORGAN_SLOT_BRAIN, -((speed_coeff / 2) * dmg_mult))
|
||||
|
||||
|
||||
use_power(7500) //This might need tweaking.
|
||||
|
||||
@@ -261,6 +263,7 @@
|
||||
for(var/i in unattached_flesh)
|
||||
if(isorgan(i))
|
||||
var/obj/item/organ/O = i
|
||||
O.organ_flags &= ~ORGAN_FROZEN
|
||||
O.Insert(mob_occupant)
|
||||
else if(isbodypart(i))
|
||||
var/obj/item/bodypart/BP = i
|
||||
@@ -344,6 +347,9 @@
|
||||
if(mess) //Clean that mess and dump those gibs!
|
||||
for(var/obj/fl in unattached_flesh)
|
||||
fl.forceMove(T)
|
||||
if(istype(fl, /obj/item/organ))
|
||||
var/obj/item/organ/O = fl
|
||||
O.organ_flags &= ~ORGAN_FROZEN
|
||||
unattached_flesh.Cut()
|
||||
mess = FALSE
|
||||
new /obj/effect/gibspawner/generic(get_turf(src))
|
||||
@@ -440,7 +446,7 @@
|
||||
unattached_flesh.Cut()
|
||||
|
||||
H.setCloneLoss(CLONE_INITIAL_DAMAGE) //Yeah, clones start with very low health, not with random, because why would they start with random health
|
||||
H.setBrainLoss(CLONE_INITIAL_DAMAGE)
|
||||
//H.setOrganLoss(ORGAN_SLOT_BRAIN, CLONE_INITIAL_DAMAGE)
|
||||
// In addition to being cellularly damaged and having barely any
|
||||
|
||||
// brain function, they also have no limbs or internal organs.
|
||||
@@ -456,8 +462,9 @@
|
||||
|
||||
for(var/o in H.internal_organs)
|
||||
var/obj/item/organ/organ = o
|
||||
if(!istype(organ) || organ.vital)
|
||||
if(!istype(organ) || (organ.organ_flags & ORGAN_VITAL))
|
||||
continue
|
||||
organ.organ_flags |= ORGAN_FROZEN
|
||||
organ.Remove(H, special=TRUE)
|
||||
organ.forceMove(src)
|
||||
unattached_flesh += organ
|
||||
|
||||
@@ -166,7 +166,7 @@
|
||||
<font color="[patient.getToxLoss() < 60 ? "#3d5bc3" : "#c51e1e"]"><b>Toxin Content:</b> [patient.getToxLoss()]%</font><br />
|
||||
<font color="[patient.getFireLoss() < 60 ? "#3d5bc3" : "#c51e1e"]"><b>Burn Severity:</b> [patient.getFireLoss()]%</font><br />
|
||||
<span class='danger'>[patient.getCloneLoss() ? "Subject appears to have cellular damage." : ""]</span><br />
|
||||
<span class='danger'>[patient.getBrainLoss() ? "Significant brain damage detected." : ""]</span><br />
|
||||
<span class='danger'>[patient.getOrganLoss(ORGAN_SLOT_BRAIN) ? "Significant brain damage detected." : ""]</span><br />
|
||||
<span class='danger'>[length(patient.get_traumas()) ? "Brain Traumas detected." : ""]</span><br />
|
||||
"}
|
||||
|
||||
|
||||
@@ -513,12 +513,12 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
|
||||
|
||||
log_combat(user, M, "attacked", "[src.name]", "(INTENT: [uppertext(user.a_intent)])")
|
||||
|
||||
M.adjust_blurriness(3)
|
||||
M.adjust_eye_damage(rand(2,4))
|
||||
var/obj/item/organ/eyes/eyes = M.getorganslot(ORGAN_SLOT_EYES)
|
||||
if (!eyes)
|
||||
return
|
||||
if(eyes.eye_damage >= 10)
|
||||
M.adjust_blurriness(3)
|
||||
eyes.applyOrganDamage(rand(2,4))
|
||||
if(eyes.damage >= 10)
|
||||
M.adjust_blurriness(15)
|
||||
if(M.stat != DEAD)
|
||||
to_chat(M, "<span class='danger'>Your eyes start to bleed profusely!</span>")
|
||||
@@ -532,7 +532,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
|
||||
M.adjust_blurriness(10)
|
||||
M.Unconscious(20)
|
||||
M.Knockdown(40)
|
||||
if (prob(eyes.eye_damage - 10 + 1))
|
||||
if (prob(eyes.damage - 10 + 1))
|
||||
M.become_blind(EYE_DAMAGE)
|
||||
to_chat(M, "<span class='danger'>You go blind!</span>")
|
||||
|
||||
|
||||
@@ -17,26 +17,27 @@
|
||||
/obj/item/organ/body_egg/Insert(var/mob/living/carbon/M, special = 0)
|
||||
..()
|
||||
ADD_TRAIT(owner, TRAIT_XENO_HOST, TRAIT_GENERIC)
|
||||
START_PROCESSING(SSobj, src)
|
||||
owner.med_hud_set_status()
|
||||
INVOKE_ASYNC(src, .proc/AddInfectionImages, owner)
|
||||
|
||||
/obj/item/organ/body_egg/Remove(var/mob/living/carbon/M, special = 0)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
if(owner)
|
||||
REMOVE_TRAIT(owner, TRAIT_XENO_HOST, TRAIT_GENERIC)
|
||||
owner.med_hud_set_status()
|
||||
INVOKE_ASYNC(src, .proc/RemoveInfectionImages, owner)
|
||||
..()
|
||||
|
||||
/obj/item/organ/body_egg/process()
|
||||
/obj/item/organ/body_egg/on_death()
|
||||
. = ..()
|
||||
if(!owner)
|
||||
return
|
||||
if(!(src in owner.internal_organs))
|
||||
Remove(owner)
|
||||
return
|
||||
egg_process()
|
||||
|
||||
/obj/item/organ/body_egg/on_life()
|
||||
. = ..()
|
||||
egg_process()
|
||||
|
||||
|
||||
/obj/item/organ/body_egg/proc/egg_process()
|
||||
return
|
||||
|
||||
|
||||
@@ -407,6 +407,7 @@
|
||||
/obj/machinery/smartfridge/food = "food",
|
||||
/obj/machinery/smartfridge/drinks = "drinks",
|
||||
/obj/machinery/smartfridge/extract = "slimes",
|
||||
/obj/machinery/smartfridge/organ = "organs",
|
||||
/obj/machinery/smartfridge/chemistry = "chems",
|
||||
/obj/machinery/smartfridge/chemistry/virology = "viruses",
|
||||
/obj/machinery/smartfridge/disks = "disks")
|
||||
|
||||
@@ -140,12 +140,10 @@
|
||||
return ..()
|
||||
|
||||
/obj/item/defibrillator/emag_act(mob/user)
|
||||
if(safety)
|
||||
safety = FALSE
|
||||
to_chat(user, "<span class='warning'>You silently disable [src]'s safety protocols with the cryptographic sequencer.</span>")
|
||||
else
|
||||
safety = TRUE
|
||||
to_chat(user, "<span class='notice'>You silently enable [src]'s safety protocols with the cryptographic sequencer.</span>")
|
||||
. = ..()
|
||||
safety = !safety
|
||||
to_chat(user, "<span class='warning'>You silently [safety ? "enable" : "disable"] [src]'s safety protocols with the cryptographic sequencer.</span>")
|
||||
return TRUE
|
||||
|
||||
/obj/item/defibrillator/emp_act(severity)
|
||||
. = ..()
|
||||
@@ -442,9 +440,20 @@
|
||||
|
||||
do_help(H, user)
|
||||
|
||||
/obj/item/twohanded/shockpaddles/proc/can_defib(mob/living/carbon/H)
|
||||
/obj/item/twohanded/shockpaddles/proc/can_defib(mob/living/carbon/H) //Our code here is different than tg, if it breaks in testing; BUG_PROBABLE_CAUSE
|
||||
var/obj/item/organ/heart = H.getorgan(/obj/item/organ/heart)
|
||||
if(H.suiciding || H.hellbound || HAS_TRAIT(H, TRAIT_HUSK))
|
||||
return
|
||||
if((world.time - H.timeofdeath) > tlimit)
|
||||
return
|
||||
if((H.getBruteLoss() >= MAX_REVIVE_BRUTE_DAMAGE) || (H.getFireLoss() >= MAX_REVIVE_FIRE_DAMAGE))
|
||||
return
|
||||
if(!heart || (heart.organ_flags & ORGAN_FAILING))
|
||||
return
|
||||
var/obj/item/organ/brain/BR = H.getorgan(/obj/item/organ/brain)
|
||||
return (!H.suiciding && !(HAS_TRAIT(H, TRAIT_NOCLONE)) && !H.hellbound && ((world.time - H.timeofdeath) < tlimit) && (H.getBruteLoss() < 180) && (H.getFireLoss() < 180) && H.getorgan(/obj/item/organ/heart) && BR && !BR.damaged_brain)
|
||||
if(QDELETED(BR) || BR.brain_death || (BR.organ_flags & ORGAN_FAILING) || H.suiciding)
|
||||
return
|
||||
return TRUE
|
||||
|
||||
/obj/item/twohanded/shockpaddles/proc/shock_touching(dmg, mob/H)
|
||||
if(req_defib)
|
||||
@@ -559,14 +568,12 @@
|
||||
if(do_after(user, primetimer, target = H)) //beginning to place the paddles on patient's chest to allow some time for people to move away to stop the process
|
||||
user.visible_message("<span class='notice'>[user] places [src] on [H]'s chest.</span>", "<span class='warning'>You place [src] on [H]'s chest.</span>")
|
||||
playsound(src, 'sound/machines/defib_charge.ogg', 75, 0)
|
||||
var/tplus = world.time - H.timeofdeath
|
||||
// past this much time the patient is unrecoverable
|
||||
// (in deciseconds)
|
||||
// brain damage starts setting in on the patient after
|
||||
// some time left rotting
|
||||
// patients rot when they are killed, and die when they are dead
|
||||
var/tplus = world.time - H.timeofdeath //length of time spent dead
|
||||
var/tloss = deathtimer
|
||||
var/total_burn = 0
|
||||
var/total_brute = 0
|
||||
var/obj/item/organ/heart = H.getorgan(/obj/item/organ/heart)
|
||||
if(do_after(user, primetimer2, target = H)) //placed on chest and short delay to shock for dramatic effect, revive time is 5sec total
|
||||
for(var/obj/item/carried_item in H.contents)
|
||||
if(istype(carried_item, /obj/item/clothing/suit/space))
|
||||
@@ -591,16 +598,26 @@
|
||||
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>"
|
||||
else if (tplus > tlimit)
|
||||
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))
|
||||
else if (!heart)
|
||||
failed = "<span class='warning'>[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Patient's heart is missing.</span>"
|
||||
else if (heart.organ_flags & ORGAN_FAILING)
|
||||
failed = "<span class='warning'>[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Patient's heart too damaged.</span>"
|
||||
else if(total_burn >= 180 || total_brute >= 180)
|
||||
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>"
|
||||
else
|
||||
var/obj/item/organ/brain/BR = H.getorgan(/obj/item/organ/brain)
|
||||
if(!BR || BR.damaged_brain)
|
||||
failed = "<span class='warning'>[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Patient's brain is missing or damaged beyond point of no return. Further attempts futile.</span>"
|
||||
if(BR) //BUG_PROBABLE_CAUSE - slight difference between us and tg
|
||||
if(BR.organ_flags & ORGAN_FAILING)
|
||||
failed = "<span class='warning'>[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Patient's brain tissue is damaged making recovery of patient impossible via defibrillator. Further attempts futile.</span>"
|
||||
if(BR.brain_death)
|
||||
failed = "<span class='warning'>[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Patient's brain damaged beyond point of no return. Further attempts futile.</span>"
|
||||
if(H.suiciding || BR.brainmob?.suiciding)
|
||||
failed = "<span class='warning'>[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - No intelligence pattern can be detected in patient's brain. Further attempts futile.</span>"
|
||||
else
|
||||
failed = "<span class='warning'>[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Patient's brain is missing. Further attempts futile.</span>"
|
||||
|
||||
|
||||
if(failed)
|
||||
user.visible_message(failed)
|
||||
@@ -625,7 +642,7 @@
|
||||
H.Jitter(100)
|
||||
SEND_SIGNAL(H, COMSIG_LIVING_MINOR_SHOCK)
|
||||
if(tplus > tloss)
|
||||
H.adjustBrainLoss( max(0, min(99, ((tlimit - tplus) / tlimit * 100))), 150)
|
||||
H.adjustOrganLoss(ORGAN_SLOT_BRAIN, max(0, min(99, ((tlimit - tplus) / tlimit * 100))), 150)
|
||||
log_combat(user, H, "revived", defib)
|
||||
if(req_defib)
|
||||
if(defib.healdisk)
|
||||
@@ -643,7 +660,11 @@
|
||||
playsound(src, 'sound/machines/defib_failed.ogg', 50, 0)
|
||||
else if(H.undergoing_cardiac_arrest())
|
||||
H.set_heartattack(FALSE)
|
||||
user.visible_message("<span class='notice'>[req_defib ? "[defib]" : "[src]"] pings: Patient's heart is now beating again.</span>")
|
||||
if(!(heart.organ_flags & ORGAN_FAILING))
|
||||
H.set_heartattack(FALSE)
|
||||
user.visible_message("<span class='notice'>[req_defib ? "[defib]" : "[src]"] pings: Patient's heart is now beating again.</span>")
|
||||
else
|
||||
user.visible_message("<span class='warning'>[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed, heart damage detected.</span>")
|
||||
playsound(src, 'sound/machines/defib_zap.ogg', 50, 1, -1)
|
||||
|
||||
|
||||
|
||||
@@ -211,7 +211,7 @@
|
||||
data["occupant"]["toxLoss"] = mob_occupant.getToxLoss()
|
||||
data["occupant"]["fireLoss"] = mob_occupant.getFireLoss()
|
||||
data["occupant"]["cloneLoss"] = mob_occupant.getCloneLoss()
|
||||
data["occupant"]["brainLoss"] = mob_occupant.getBrainLoss()
|
||||
data["occupant"]["brainLoss"] = mob_occupant.getOrganLoss(ORGAN_SLOT_BRAIN)
|
||||
data["occupant"]["reagents"] = list()
|
||||
if(mob_occupant.reagents.reagent_list.len)
|
||||
for(var/datum/reagent/R in mob_occupant.reagents.reagent_list)
|
||||
|
||||
@@ -135,7 +135,7 @@ SLIME SCANNER
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(H.undergoing_cardiac_arrest() && H.stat != DEAD)
|
||||
to_chat(user, "<span class='danger'>Subject suffering from heart attack: Apply defibrillation or other electric shock immediately!</span>")
|
||||
if(H.undergoing_liver_failure() && H.stat != DEAD)
|
||||
if(H.undergoing_liver_failure() && H.stat != DEAD) //might be depreciated BUG_PROBABLE_CAUSE
|
||||
to_chat(user, "<span class='danger'>Subject is suffering from liver failure: Apply Corazone and begin a liver transplant immediately!</span>")
|
||||
|
||||
var/msg = "<span class='info'>*---------*\nAnalyzing results for [M]:\n\tOverall status: [mob_status]\n"
|
||||
@@ -157,12 +157,8 @@ SLIME SCANNER
|
||||
msg += "\t<span class='alert'>Subject appears to have [M.getCloneLoss() > 30 ? "Severe" : "Minor"] cellular damage.</span>\n"
|
||||
if(advanced)
|
||||
msg += "\t<span class='info'>Cellular Damage Level: [M.getCloneLoss()].</span>\n"
|
||||
if (M.getBrainLoss() >= 200 || !M.getorgan(/obj/item/organ/brain))
|
||||
msg += "\t<span class='alert'>Subject's brain function is non-existent.</span>\n"
|
||||
else if (M.getBrainLoss() >= 120)
|
||||
msg += "\t<span class='alert'>Severe brain damage detected. Subject likely to have mental traumas.</span>\n"
|
||||
else if (M.getBrainLoss() >= 45)
|
||||
msg += "\t<span class='alert'>Brain damage detected.</span>\n"
|
||||
if (!M.getorgan(/obj/item/organ/brain))
|
||||
to_chat(user, "\t<span class='alert'>Subject lacks a brain.</span>") //Unsure how this won't proc for 50% of the cit playerbase (This is a joke everyone on cit a cute.)
|
||||
if(ishuman(M) && advanced) // Should I make this not advanced?
|
||||
var/mob/living/carbon/human/H = M
|
||||
var/obj/item/organ/liver/L = H.getorganslot("liver")
|
||||
@@ -194,6 +190,14 @@ SLIME SCANNER
|
||||
if(Br.cached_size>5)
|
||||
msg += "\t<span class='info'>Subject has a sizeable bosom with a [Br.size] cup.</span>\n"
|
||||
|
||||
if (M.getOrganLoss(ORGAN_SLOT_BRAIN) >= 200 || !M.getorgan(/obj/item/organ/brain))
|
||||
msg += "\t<span class='alert'>Subject's brain function is non-existent.</span>\n"
|
||||
else if (M.getOrganLoss(ORGAN_SLOT_BRAIN) >= 120)
|
||||
msg += "\t<span class='alert'>Severe brain damage detected. Subject likely to have mental traumas.</span>\n"
|
||||
else if (M.getOrganLoss(ORGAN_SLOT_BRAIN) >= 45)
|
||||
msg += "\t<span class='alert'>Brain damage detected.</span>\n"
|
||||
|
||||
if(iscarbon(M))
|
||||
var/mob/living/carbon/C = M
|
||||
if(LAZYLEN(C.get_traumas()))
|
||||
var/list/trauma_text = list()
|
||||
@@ -212,11 +216,10 @@ SLIME SCANNER
|
||||
if(C.roundstart_quirks.len)
|
||||
msg += "\t<span class='info'>Subject has the following physiological traits: [C.get_trait_string()].</span>\n"
|
||||
if(advanced)
|
||||
msg += "\t<span class='info'>Brain Activity Level: [(200 - M.getBrainLoss())/2]%.</span>\n"
|
||||
msg += "\t<span class='info'>Brain Activity Level: [(200 - M.getOrganLoss(ORGAN_SLOT_BRAIN))/2]%.</span>\n"
|
||||
if(M.radiation)
|
||||
msg += "\t<span class='alert'>Subject is irradiated.</span>\n"
|
||||
if(advanced)
|
||||
msg += "\t<span class='info'>Radiation Level: [M.radiation]%.</span>\n"
|
||||
msg += "\t<span class='info'>Radiation Level: [M.radiation] rad</span>\n"
|
||||
|
||||
if(advanced && M.hallucinating())
|
||||
msg += "\t<span class='info'>Subject is hallucinating.</span>\n"
|
||||
@@ -247,11 +250,11 @@ SLIME SCANNER
|
||||
healthy = FALSE
|
||||
msg += "\t<span class='alert'>Subject is deaf.</span>\n"
|
||||
else
|
||||
if(ears.ear_damage)
|
||||
msg += "\t<span class='alert'>Subject has [ears.ear_damage > UNHEALING_EAR_DAMAGE? "permanent ": "temporary "]hearing damage.</span>\n"
|
||||
if(ears.damage)
|
||||
to_chat(user, "\t<span class='alert'>Subject has [ears.damage > ears.maxHealth ? "permanent ": "temporary "]hearing damage.</span>")
|
||||
healthy = FALSE
|
||||
if(ears.deaf)
|
||||
msg += "\t<span class='alert'>Subject is [ears.ear_damage > UNHEALING_EAR_DAMAGE ? "permanently ": "temporarily "] deaf.</span>\n"
|
||||
to_chat(user, "\t<span class='alert'>Subject is [ears.damage > ears.maxHealth ? "permanently ": "temporarily "] deaf.</span>")
|
||||
healthy = FALSE
|
||||
if(healthy)
|
||||
msg += "\t<span class='info'>Healthy.</span>\n"
|
||||
@@ -267,13 +270,13 @@ SLIME SCANNER
|
||||
if(HAS_TRAIT(C, TRAIT_NEARSIGHT))
|
||||
msg += "\t<span class='alert'>Subject is nearsighted.</span>\n"
|
||||
healthy = FALSE
|
||||
if(eyes.eye_damage > 30)
|
||||
if(eyes.damage > 30)
|
||||
msg += "\t<span class='alert'>Subject has severe eye damage.</span>\n"
|
||||
healthy = FALSE
|
||||
else if(eyes.eye_damage > 20)
|
||||
else if(eyes.damage > 20)
|
||||
msg += "\t<span class='alert'>Subject has significant eye damage.</span>\n"
|
||||
healthy = FALSE
|
||||
else if(eyes.eye_damage)
|
||||
else if(eyes.damage)
|
||||
msg += "\t<span class='alert'>Subject has minor eye damage.</span>\n"
|
||||
healthy = FALSE
|
||||
if(healthy)
|
||||
@@ -297,6 +300,59 @@ SLIME SCANNER
|
||||
for(var/obj/item/bodypart/org in damaged)
|
||||
msg += "\t\t<span class='info'>[capitalize(org.name)]: [(org.brute_dam > 0) ? "<font color='red'>[org.brute_dam]</font></span>" : "<font color='red'>0</font>"]-[(org.burn_dam > 0) ? "<font color='#FF8000'>[org.burn_dam]</font>" : "<font color='#FF8000'>0</font>"]\n"
|
||||
|
||||
//Organ damages report
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
var/minor_damage
|
||||
var/major_damage
|
||||
var/max_damage
|
||||
var/report_organs = FALSE
|
||||
|
||||
//Piece together the lists to be reported
|
||||
for(var/O in H.internal_organs)
|
||||
var/obj/item/organ/organ = O
|
||||
if(organ.organ_flags & ORGAN_FAILING)
|
||||
report_organs = TRUE //if we report one organ, we report all organs, even if the lists are empty, just for consistency
|
||||
if(max_damage)
|
||||
max_damage += ", " //prelude the organ if we've already reported an organ
|
||||
max_damage += organ.name //this just slaps the organ name into the string of text
|
||||
else
|
||||
max_damage = "\t<span class='alert'>Non-Functional Organs: " //our initial statement
|
||||
max_damage += organ.name
|
||||
else if(organ.damage > organ.high_threshold)
|
||||
report_organs = TRUE
|
||||
if(major_damage)
|
||||
major_damage += ", "
|
||||
major_damage += organ.name
|
||||
else
|
||||
major_damage = "\t<span class='info'>Severely Damaged Organs: "
|
||||
major_damage += organ.name
|
||||
else if(organ.damage > organ.low_threshold)
|
||||
report_organs = TRUE
|
||||
if(minor_damage)
|
||||
minor_damage += ", "
|
||||
minor_damage += organ.name
|
||||
else
|
||||
minor_damage = "\t<span class='info'>Mildly Damaged Organs: "
|
||||
minor_damage += organ.name
|
||||
|
||||
if(report_organs) //we either finish the list, or set it to be empty if no organs were reported in that category
|
||||
if(!max_damage)
|
||||
max_damage = "\t<span class='alert'>Non-Functional Organs: </span>"
|
||||
else
|
||||
max_damage += "</span>"
|
||||
if(!major_damage)
|
||||
major_damage = "\t<span class='info'>Severely Damaged Organs: </span>"
|
||||
else
|
||||
major_damage += "</span>"
|
||||
if(!minor_damage)
|
||||
minor_damage = "\t<span class='info'>Mildly Damaged Organs: </span>"
|
||||
else
|
||||
minor_damage += "</span>"
|
||||
msg += "[minor_damage]"
|
||||
msg += "[major_damage]"
|
||||
msg += "[max_damage]"
|
||||
|
||||
|
||||
// Species and body temperature
|
||||
if(ishuman(M))
|
||||
@@ -385,7 +441,7 @@ SLIME SCANNER
|
||||
if(M.reagents.reagent_list.len)
|
||||
var/list/datum/reagent/reagents = list()
|
||||
for(var/datum/reagent/R in M.reagents.reagent_list)
|
||||
if(R.invisible)
|
||||
if(R.chemical_flags & REAGENT_INVISIBLE)
|
||||
continue
|
||||
reagents += R
|
||||
|
||||
@@ -404,6 +460,21 @@ SLIME SCANNER
|
||||
msg += "<span class='danger'>[R.name]</span>\n"
|
||||
else
|
||||
msg += "<span class='notice'>Subject is not addicted to any reagents.</span>\n"
|
||||
|
||||
if(M.reagents.has_reagent("fermiTox"))
|
||||
var/datum/reagent/fermiTox = M.reagents.has_reagent("fermiTox")
|
||||
switch(fermiTox.volume)
|
||||
if(5 to 10)
|
||||
msg += "<span class='notice'>Subject contains a low amount of toxic isomers.</span>\n"
|
||||
if(10 to 25)
|
||||
msg += "<span class='danger'>Subject contains toxic isomers.</span>\n"
|
||||
if(25 to 50)
|
||||
msg += "<span class='danger'>Subject contains a substantial amount of toxic isomers.</span>\n"
|
||||
if(50 to 95)
|
||||
msg += "<span class='danger'>Subject contains a high amount of toxic isomers.</span>\n"
|
||||
if(95 to INFINITY)
|
||||
msg += "<span class='danger'>Subject contains a extremely dangerous amount of toxic isomers.</span>\n"
|
||||
|
||||
msg += "*---------*</span>"
|
||||
to_chat(user, msg)
|
||||
|
||||
|
||||
@@ -254,7 +254,7 @@
|
||||
to_chat(user, "<span class='warning'>The MMI indicates that their mind is currently inactive; it might change!</span>")
|
||||
return
|
||||
|
||||
if(BM.stat == DEAD || (M.brain && M.brain.damaged_brain))
|
||||
if(BM.stat == DEAD || (M.brain && M.brain.organ_flags & ORGAN_FAILING))
|
||||
to_chat(user, "<span class='warning'>Sticking a dead brain into the frame would sort of defeat the purpose!</span>")
|
||||
return
|
||||
|
||||
|
||||
@@ -140,7 +140,7 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "bible",
|
||||
else if(iscarbon(M))
|
||||
var/mob/living/carbon/C = M
|
||||
if(!istype(C.head, /obj/item/clothing/head))
|
||||
C.adjustBrainLoss(10, 80)
|
||||
C.adjustOrganLoss(ORGAN_SLOT_BRAIN, 10, 80)
|
||||
to_chat(C, "<span class='danger'>You feel dumber.</span>")
|
||||
|
||||
if(smack)
|
||||
|
||||
@@ -304,7 +304,7 @@
|
||||
|
||||
var/obj/item/bodypart/head/myhead = user.get_bodypart(BODY_ZONE_HEAD)//stole from chainsaw code
|
||||
var/obj/item/organ/brain/B = user.getorganslot(ORGAN_SLOT_BRAIN)
|
||||
B.vital = FALSE//this cant possibly be a good idea
|
||||
B.organ_flags &= ~ORGAN_VITAL //this cant possibly be a good idea
|
||||
var/randdir
|
||||
for(var/i in 1 to 24)//like a headless chicken!
|
||||
if(user.is_holding(src))
|
||||
|
||||
@@ -2,6 +2,24 @@
|
||||
icon_state = "freezer"
|
||||
var/jones = FALSE
|
||||
|
||||
/obj/structure/closet/secure_closet/freezer/Destroy()
|
||||
recursive_organ_check(src)
|
||||
..()
|
||||
|
||||
/obj/structure/closet/secure_closet/freezer/Initialize()
|
||||
..()
|
||||
recursive_organ_check(src)
|
||||
|
||||
/obj/structure/closet/secure_closet/freezer/open(mob/living/user)
|
||||
if(opened || !can_open(user)) //dupe check just so we don't let the organs decay when someone fails to open the locker
|
||||
return FALSE
|
||||
recursive_organ_check(src)
|
||||
return ..()
|
||||
|
||||
/obj/structure/closet/secure_closet/freezer/close(mob/living/user)
|
||||
if(..()) //if we actually closed the locker
|
||||
recursive_organ_check(src)
|
||||
|
||||
/obj/structure/closet/secure_closet/freezer/ex_act()
|
||||
if(!jones)
|
||||
jones = TRUE
|
||||
|
||||
@@ -31,6 +31,7 @@ GLOBAL_LIST_EMPTY(bodycontainers) //Let them act as spawnpoints for revenants an
|
||||
/obj/structure/bodycontainer/Initialize()
|
||||
. = ..()
|
||||
GLOB.bodycontainers += src
|
||||
recursive_organ_check(src)
|
||||
|
||||
/obj/structure/bodycontainer/Destroy()
|
||||
GLOB.bodycontainers -= src
|
||||
@@ -101,6 +102,7 @@ GLOBAL_LIST_EMPTY(bodycontainers) //Let them act as spawnpoints for revenants an
|
||||
|
||||
/obj/structure/bodycontainer/deconstruct(disassembled = TRUE)
|
||||
new /obj/item/stack/sheet/metal (loc, 5)
|
||||
recursive_organ_check(src)
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/bodycontainer/container_resist(mob/living/user)
|
||||
@@ -120,6 +122,7 @@ GLOBAL_LIST_EMPTY(bodycontainers) //Let them act as spawnpoints for revenants an
|
||||
open()
|
||||
|
||||
/obj/structure/bodycontainer/proc/open()
|
||||
recursive_organ_check(src)
|
||||
playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1)
|
||||
playsound(src, 'sound/effects/roll.ogg', 5, 1)
|
||||
var/turf/T = get_step(src, dir)
|
||||
@@ -134,6 +137,7 @@ GLOBAL_LIST_EMPTY(bodycontainers) //Let them act as spawnpoints for revenants an
|
||||
for(var/atom/movable/AM in connected.loc)
|
||||
if(!AM.anchored || AM == connected)
|
||||
AM.forceMove(src)
|
||||
recursive_organ_check(src)
|
||||
update_icon()
|
||||
|
||||
/obj/structure/bodycontainer/get_remote_view_fullscreens(mob/user)
|
||||
|
||||
@@ -458,7 +458,7 @@
|
||||
SSblackbox.record_feedback("nested tally", "admin_secrets_fun_used", 1, list("Mass Braindamage"))
|
||||
for(var/mob/living/carbon/human/H in GLOB.player_list)
|
||||
to_chat(H, "<span class='boldannounce'>You suddenly feel stupid.</span>")
|
||||
H.adjustBrainLoss(60, 80)
|
||||
H.adjustOrganLoss(ORGAN_SLOT_BRAIN, 60, 80)
|
||||
message_admins("[key_name_admin(usr)] made everybody retarded")
|
||||
|
||||
if("eagles")//SCRAW
|
||||
|
||||
@@ -1752,7 +1752,7 @@
|
||||
if(DEAD)
|
||||
status = "<font color='red'><b>Dead</b></font>"
|
||||
health_description = "Status = [status]"
|
||||
health_description += "<BR>Oxy: [L.getOxyLoss()] - Tox: [L.getToxLoss()] - Fire: [L.getFireLoss()] - Brute: [L.getBruteLoss()] - Clone: [L.getCloneLoss()] - Brain: [L.getBrainLoss()] - Stamina: [L.getStaminaLoss()]"
|
||||
health_description += "<BR>Oxy: [L.getOxyLoss()] - Tox: [L.getToxLoss()] - Fire: [L.getFireLoss()] - Brute: [L.getBruteLoss()] - Clone: [L.getCloneLoss()] - Brain: [L.getOrganLoss(ORGAN_SLOT_BRAIN)] - Stamina: [L.getStaminaLoss()]"
|
||||
else
|
||||
health_description = "This mob type has no health to speak of."
|
||||
|
||||
|
||||
@@ -1264,7 +1264,7 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
|
||||
target.electrocution_animation(40)
|
||||
to_chat(target, "<span class='userdanger'>The gods have punished you for your sins!</span>")
|
||||
if(ADMIN_PUNISHMENT_BRAINDAMAGE)
|
||||
target.adjustBrainLoss(199, 199)
|
||||
target.adjustOrganLoss(ORGAN_SLOT_BRAIN, 199, 199)
|
||||
if(ADMIN_PUNISHMENT_GIB)
|
||||
target.gib(FALSE)
|
||||
if(ADMIN_PUNISHMENT_BSA)
|
||||
|
||||
@@ -151,7 +151,7 @@
|
||||
if(2)
|
||||
to_chat(H, "<span class='warning'>You hear an annoying buzz in your head.</span>")
|
||||
H.confused += 15
|
||||
H.adjustBrainLoss(10, 160)
|
||||
H.adjustOrganLoss(ORGAN_SLOT_BRAIN, 10, 160)
|
||||
if(3)
|
||||
H.hallucination += 60
|
||||
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
if(istype(C))
|
||||
var/obj/item/organ/brain/B = C.getorganslot(ORGAN_SLOT_BRAIN)
|
||||
if(B && (B.decoy_override != initial(B.decoy_override)))
|
||||
B.vital = TRUE
|
||||
B.organ_flags |= ORGAN_VITAL
|
||||
B.decoy_override = FALSE
|
||||
remove_changeling_powers()
|
||||
. = ..()
|
||||
@@ -340,7 +340,7 @@
|
||||
if(istype(C))
|
||||
var/obj/item/organ/brain/B = C.getorganslot(ORGAN_SLOT_BRAIN)
|
||||
if(B)
|
||||
B.vital = FALSE
|
||||
B.organ_flags &= ~ORGAN_VITAL
|
||||
B.decoy_override = TRUE
|
||||
update_changeling_icons_added()
|
||||
return
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
B = new C.dna.species.mutant_brain()
|
||||
else
|
||||
B = new()
|
||||
B.vital = FALSE
|
||||
B.organ_flags &= ~ORGAN_VITAL
|
||||
B.decoy_override = TRUE
|
||||
B.Insert(C)
|
||||
if(ishuman(user))
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
to_chat(user, "<span class='userdanger'>The helmet tries to drive a spike through your head as you scramble to remove it!</span>")
|
||||
user.emote("scream")
|
||||
user.apply_damage(30, BRUTE, BODY_ZONE_HEAD)
|
||||
user.adjustBrainLoss(30)
|
||||
user.adjustOrganLoss(ORGAN_SLOT_BRAIN, 30)
|
||||
addtimer(CALLBACK(user, /mob/living.proc/dropItemToGround, src, TRUE), 1) //equipped happens before putting stuff on(but not before picking items up), 1). thus, we need to wait for it to be on before forcing it off.
|
||||
|
||||
/obj/item/clothing/head/helmet/clockwork/mob_can_equip(mob/M, mob/equipper, slot, disable_warning = 0)
|
||||
|
||||
@@ -80,6 +80,7 @@
|
||||
desc = "Still it beats furiously, emanating an aura of utter hate."
|
||||
icon = 'icons/obj/surgery.dmi'
|
||||
icon_state = "demon_heart-on"
|
||||
decay_factor = 0
|
||||
|
||||
/obj/item/organ/heart/demon/update_icon()
|
||||
return //always beating visually
|
||||
|
||||
@@ -144,6 +144,13 @@
|
||||
else
|
||||
O.forceMove(src)
|
||||
return TRUE
|
||||
|
||||
///Really simple proc, just moves the object "O" into the hands of mob "M" if able, done so I could modify the proc a little for the organ fridge
|
||||
/obj/machinery/smartfridge/proc/dispense(obj/item/O, var/mob/M)
|
||||
if(!M.put_in_hands(O))
|
||||
O.forceMove(drop_location())
|
||||
adjust_item_drop_location(O)
|
||||
|
||||
|
||||
/obj/machinery/smartfridge/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
@@ -197,9 +204,7 @@
|
||||
if(desired == 1 && Adjacent(usr) && !issilicon(usr))
|
||||
for(var/obj/item/O in src)
|
||||
if(O.name == params["name"])
|
||||
if(!usr.put_in_hands(O))
|
||||
O.forceMove(drop_location())
|
||||
adjust_item_drop_location(O)
|
||||
dispense(O, usr)
|
||||
break
|
||||
if (visible_contents)
|
||||
update_icon()
|
||||
@@ -209,8 +214,7 @@
|
||||
if(desired <= 0)
|
||||
break
|
||||
if(O.name == params["name"])
|
||||
O.forceMove(drop_location())
|
||||
adjust_item_drop_location(O)
|
||||
dispense(O, usr)
|
||||
desired--
|
||||
if (visible_contents)
|
||||
update_icon()
|
||||
@@ -378,6 +382,44 @@
|
||||
/obj/machinery/smartfridge/extract/preloaded
|
||||
initial_contents = list(/obj/item/slime_scanner = 2)
|
||||
|
||||
// ------------------------- You think you're better than Chem, huh?
|
||||
// Organ Surgery Smartfridge
|
||||
// ------------------------- Just wait till Tamiorgans
|
||||
/obj/machinery/smartfridge/organ
|
||||
name = "smart organ storage"
|
||||
desc = "A refrigerated storage unit for organ storage."
|
||||
max_n_of_items = 20 //vastly lower to prevent processing too long
|
||||
var/repair_rate = 0
|
||||
|
||||
/obj/machinery/smartfridge/organ/accept_check(obj/item/O)
|
||||
if(istype(O, /obj/item/organ))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/smartfridge/organ/load(obj/item/O)
|
||||
. = ..()
|
||||
if(!.) //if the item loads, clear can_decompose
|
||||
return
|
||||
var/obj/item/organ/organ = O
|
||||
organ.organ_flags |= ORGAN_FROZEN
|
||||
|
||||
/obj/machinery/smartfridge/organ/RefreshParts()
|
||||
for(var/obj/item/stock_parts/matter_bin/B in component_parts)
|
||||
max_n_of_items = 20 * B.rating
|
||||
repair_rate = max(0, STANDARD_ORGAN_HEALING * (B.rating - 1))
|
||||
|
||||
/obj/machinery/smartfridge/organ/process()
|
||||
for(var/organ in contents)
|
||||
var/obj/item/organ/O = organ
|
||||
if(!istype(O))
|
||||
return
|
||||
O.applyOrganDamage(-repair_rate)
|
||||
|
||||
/obj/machinery/smartfridge/organ/Exited(obj/item/organ/AM, atom/newLoc)
|
||||
. = ..()
|
||||
if(istype(AM))
|
||||
AM.organ_flags &= ~ORGAN_FROZEN
|
||||
|
||||
// -----------------------------
|
||||
// Chemistry Medical Smartfridge
|
||||
// -----------------------------
|
||||
@@ -399,7 +441,7 @@
|
||||
return TRUE
|
||||
if(!O.reagents || !O.reagents.reagent_list.len) // other empty containers not accepted
|
||||
return FALSE
|
||||
if(istype(O, /obj/item/reagent_containers/syringe) || istype(O, /obj/item/reagent_containers/glass/bottle) || istype(O, /obj/item/reagent_containers/glass/beaker) || istype(O, /obj/item/reagent_containers/spray) || istype(O, /obj/item/reagent_containers/medspray)|| istype(O, /obj/item/reagent_containers/chem_pack))
|
||||
if(istype(O, /obj/item/reagent_containers/syringe) || istype(O, /obj/item/reagent_containers/glass/bottle) || istype(O, /obj/item/reagent_containers/glass/beaker) || istype(O, /obj/item/reagent_containers/spray) || istype(O, /obj/item/reagent_containers/medspray))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@ Chaplain
|
||||
B.name = "Guys Gone Wild"
|
||||
if("lol", "wtf", "gay", "penis", "ass", "poo", "badmin", "shitmin", "deadmin", "cock", "cocks", "meme", "memes")
|
||||
B.name = pick("Woodys Got Wood: The Aftermath", "War of the Cocks", "Sweet Bro and Hella Jef: Expanded Edition")
|
||||
H.adjustBrainLoss(100) // starts off retarded as fuck
|
||||
H.adjustOrganLoss(ORGAN_SLOT_BRAIN, 100) // starts off retarded as fuck
|
||||
if("science")
|
||||
B.name = pick("Principle of Relativity", "Quantum Enigma: Physics Encounters Consciousness", "Programming the Universe", "Quantum Physics and Theology", "String Theory for Dummies", "How To: Build Your Own Warp Drive", "The Mysteries of Bluespace", "Playing God: Collector's Edition")
|
||||
else
|
||||
|
||||
@@ -50,8 +50,8 @@
|
||||
if(U.job in list("Curator")) // the curator is both faster, and more accurate than normal crew members at research
|
||||
speed = 100
|
||||
correctness = 100
|
||||
correctness -= U.getBrainLoss() *0.5 //Brain damage makes researching hard.
|
||||
speed += U.getBrainLoss() * 3
|
||||
correctness -= U.getOrganLoss(ORGAN_SLOT_BRAIN) *0.5 //Brain damage makes researching hard.
|
||||
speed += U.getOrganLoss(ORGAN_SLOT_BRAIN) * 3
|
||||
if(do_after(user, speed, 0, user))
|
||||
var/usedName = devilName
|
||||
if(!prob(correctness))
|
||||
|
||||
@@ -57,13 +57,14 @@
|
||||
newbrain.brainmob = null
|
||||
brainmob.forceMove(src)
|
||||
brainmob.container = src
|
||||
if(!newbrain.damaged_brain) // the brain organ hasn't been beaten to death.
|
||||
if(!(newbrain.organ_flags & ORGAN_FAILING)) // the brain organ hasn't been beaten to death.
|
||||
brainmob.stat = CONSCIOUS //we manually revive the brain mob
|
||||
GLOB.dead_mob_list -= brainmob
|
||||
GLOB.alive_mob_list += brainmob
|
||||
|
||||
brainmob.reset_perspective()
|
||||
brain = newbrain
|
||||
brain.organ_flags |= ORGAN_FROZEN
|
||||
|
||||
name = "Man-Machine Interface: [brainmob.real_name]"
|
||||
update_icon()
|
||||
@@ -100,6 +101,7 @@
|
||||
user.put_in_hands(brain) //puts brain in the user's hand or otherwise drops it on the user's turf
|
||||
else
|
||||
brain.forceMove(get_turf(src))
|
||||
brain.organ_flags &= ~ORGAN_FROZEN
|
||||
brain = null //No more brain in here
|
||||
|
||||
|
||||
|
||||
@@ -7,11 +7,19 @@
|
||||
layer = ABOVE_MOB_LAYER
|
||||
zone = BODY_ZONE_HEAD
|
||||
slot = ORGAN_SLOT_BRAIN
|
||||
vital = TRUE
|
||||
organ_flags = ORGAN_VITAL
|
||||
attack_verb = list("attacked", "slapped", "whacked")
|
||||
///The brain's organ variables are significantly more different than the other organs, with half the decay rate for balance reasons, and twice the maxHealth
|
||||
decay_factor = STANDARD_ORGAN_DECAY / 4 //30 minutes of decaying to result in a fully damaged brain, since a fast decay rate would be unfun gameplay-wise
|
||||
|
||||
maxHealth = BRAIN_DAMAGE_DEATH
|
||||
low_threshold = 45
|
||||
high_threshold = 120
|
||||
var/mob/living/brain/brainmob = null
|
||||
var/damaged_brain = FALSE //whether the brain organ is damaged.
|
||||
var/brain_death = FALSE //if the brainmob was intentionally killed by attacking the brain after removal, or by severe braindamage
|
||||
var/decoy_override = FALSE //I apologize to the security players, and myself, who abused this, but this is going to go.
|
||||
//two variables necessary for calculating whether we get a brain trauma or not
|
||||
var/damage_delta = 0
|
||||
|
||||
var/list/datum/brain_trauma/traumas = list()
|
||||
|
||||
@@ -34,7 +42,7 @@
|
||||
if(brainmob.mind)
|
||||
brainmob.mind.transfer_to(C)
|
||||
else
|
||||
C.key = brainmob.key
|
||||
brainmob.transfer_ckey(C)
|
||||
|
||||
QDEL_NULL(brainmob)
|
||||
|
||||
@@ -90,22 +98,89 @@
|
||||
if(brainmob)
|
||||
O.attack(brainmob, user) //Oh noooeeeee
|
||||
|
||||
/obj/item/organ/brain/examine(mob/user)
|
||||
..()
|
||||
if(istype(O, /obj/item/organ_storage)) //BUG_PROBABLE_CAUSE
|
||||
return //Borg organ bags shouldn't be killing brains
|
||||
|
||||
if(brainmob)
|
||||
if(brainmob.client)
|
||||
if(brainmob.health <= HEALTH_THRESHOLD_DEAD)
|
||||
to_chat(user, "It's lifeless and severely damaged.")
|
||||
if((organ_flags & ORGAN_FAILING) && O.is_drainable() && O.reagents.has_reagent("neurine")) //Neurine fixes dead brains
|
||||
. = TRUE //don't do attack animation.
|
||||
var/cached_Bdamage = brainmob?.health
|
||||
var/datum/reagent/medicine/neurine/N = reagents.has_reagent("neurine")
|
||||
var/datum/reagent/medicine/mannitol/M1 = reagents.has_reagent("mannitol")
|
||||
|
||||
if(O.reagents.has_reagent("mannitol"))//Just a quick way to bolster the effects if someone mixes up a batch.
|
||||
N.volume *= (M1.volume*0.5)
|
||||
|
||||
if(!O.reagents.has_reagent("neurine", 10))
|
||||
to_chat(user, "<span class='warning'>There's not enough neurine in [O] to restore [src]!</span>")
|
||||
return
|
||||
|
||||
user.visible_message("<span class='notice'>[user] starts to pour the contents of [O] onto [src].</span>", "<span class='notice'>You start to slowly pour the contents of [O] onto [src].</span>")
|
||||
if(!do_after(user, 60, TRUE, src))
|
||||
to_chat(user, "<span class='warning'>You failed to pour [O] onto [src]!</span>")
|
||||
return
|
||||
|
||||
user.visible_message("<span class='notice'>[user] pours the contents of [O] onto [src], causing it to reform its original shape and turn a slightly brighter shade of pink.</span>", "<span class='notice'>You pour the contents of [O] onto [src], causing it to reform its original shape and turn a slightly brighter shade of pink.</span>")
|
||||
setOrganDamage((damage - (0.10 * maxHealth)*(N.volume/10))) //heals a small amount, and by using "setorgandamage", we clear the failing variable if that was up
|
||||
O.reagents.clear_reagents()
|
||||
|
||||
if(cached_Bdamage <= HEALTH_THRESHOLD_DEAD) //Fixing dead brains yeilds a trauma
|
||||
if((cached_Bdamage <= HEALTH_THRESHOLD_DEAD) && (brainmob.health > HEALTH_THRESHOLD_DEAD))
|
||||
if(prob(80))
|
||||
gain_trauma_type(BRAIN_TRAUMA_MILD)
|
||||
else if(prob(50))
|
||||
gain_trauma_type(BRAIN_TRAUMA_SEVERE)
|
||||
else
|
||||
gain_trauma_type(BRAIN_TRAUMA_SPECIAL)
|
||||
return
|
||||
|
||||
if((organ_flags & ORGAN_FAILING) && O.is_drainable() && O.reagents.has_reagent("mannitol")) //attempt to heal the brain
|
||||
. = TRUE //don't do attack animation.
|
||||
var/datum/reagent/medicine/mannitol/M = reagents.has_reagent("mannitol")
|
||||
if(brain_death || brainmob?.health <= HEALTH_THRESHOLD_DEAD) //if the brain is fucked anyway, do nothing
|
||||
to_chat(user, "<span class='warning'>[src] is far too damaged, you'll have to use neurine on it!</span>")
|
||||
return
|
||||
|
||||
if(!O.reagents.has_reagent("mannitol", 10))
|
||||
to_chat(user, "<span class='warning'>There's not enough mannitol in [O] to restore [src]!</span>")
|
||||
return
|
||||
|
||||
user.visible_message("<span class='notice'>[user] starts to pour the contents of [O] onto [src].</span>", "<span class='notice'>You start to slowly pour the contents of [O] onto [src].</span>")
|
||||
if(!do_after(user, 60, TRUE, src))
|
||||
to_chat(user, "<span class='warning'>You failed to pour [O] onto [src]!</span>")
|
||||
return
|
||||
|
||||
user.visible_message("<span class='notice'>[user] pours the contents of [O] onto [src], causing it to reform its original shape and turn a slightly brighter shade of pink.</span>", "<span class='notice'>You pour the contents of [O] onto [src], causing it to reform its original shape and turn a slightly brighter shade of pink.</span>")
|
||||
setOrganDamage((damage - (0.05 * maxHealth)*(M.volume/10))) //heals a small amount, and by using "setorgandamage", we clear the failing variable if that was up
|
||||
O.reagents.clear_reagents()
|
||||
return
|
||||
|
||||
|
||||
|
||||
/obj/item/organ/brain/examine(mob/user)//BUG_PROBABLE_CAUSE to_chats changed to . +=
|
||||
. = ..()
|
||||
|
||||
if(user.suiciding)
|
||||
. += "<span class='info'>It's started turning slightly grey. They must not have been able to handle the stress of it all.</span>"
|
||||
else if(brainmob)
|
||||
if(brainmob.get_ghost(FALSE, TRUE))
|
||||
if(brain_death || brainmob.health <= HEALTH_THRESHOLD_DEAD)
|
||||
. += "<span class='info'>It's lifeless and severely damaged, only the strongest of chems will save it.</span>"
|
||||
else if(organ_flags & ORGAN_FAILING)
|
||||
. += "<span class='info'>It seems to still have a bit of energy within it, but it's rather damaged... You may be able to restore it with some <b>mannitol</b>.</span>"
|
||||
else
|
||||
to_chat(user, "You can feel the small spark of life still left in this one.")
|
||||
. += "<span class='info'>You can feel the small spark of life still left in this one.</span>"
|
||||
else if(organ_flags & ORGAN_FAILING)
|
||||
. += "<span class='info'>It seems particularly lifeless and is rather damaged... You may be able to restore it with some <b>mannitol</b> incase it becomes functional again later.</span>"
|
||||
else
|
||||
to_chat(user, "This one seems particularly lifeless. Perhaps it will regain some of its luster later.")
|
||||
. += "<span class='info'>This one seems particularly lifeless. Perhaps it will regain some of its luster later.</span>"
|
||||
else
|
||||
if(decoy_override)
|
||||
to_chat(user, "This one seems particularly lifeless. Perhaps it will regain some of its luster later.")
|
||||
if(organ_flags & ORGAN_FAILING)
|
||||
. += "<span class='info'>It seems particularly lifeless and is rather damaged... You may be able to restore it with some <b>mannitol</b> incase it becomes functional again later.</span>"
|
||||
else
|
||||
. += "<span class='info'>This one seems particularly lifeless. Perhaps it will regain some of its luster later.</span>"
|
||||
else
|
||||
to_chat(user, "This one is completely devoid of life.")
|
||||
. += "<span class='info'>This one is completely devoid of life.</span>"
|
||||
|
||||
/obj/item/organ/brain/attack(mob/living/carbon/C, mob/user)
|
||||
if(!istype(C))
|
||||
@@ -141,7 +216,7 @@
|
||||
Insert(C)
|
||||
else
|
||||
..()
|
||||
|
||||
/* TO BE REMOVED, KEPT IN CASE OF BUGS
|
||||
/obj/item/organ/brain/proc/get_brain_damage()
|
||||
var/brain_damage_threshold = max_integrity * BRAIN_DAMAGE_INTEGRITY_MULTIPLIER
|
||||
var/offset_integrity = obj_integrity - (max_integrity - brain_damage_threshold)
|
||||
@@ -165,6 +240,54 @@
|
||||
else if(adjusted_amount <= -DAMAGE_PRECISION)
|
||||
obj_integrity = min(max_integrity, obj_integrity-adjusted_amount)
|
||||
. = adjusted_amount
|
||||
*/
|
||||
|
||||
/obj/item/organ/brain/on_life()
|
||||
if(damage >= BRAIN_DAMAGE_DEATH) //rip
|
||||
to_chat(owner, "<span class='userdanger'>The last spark of life in your brain fizzles out...</span>")
|
||||
owner.death()
|
||||
brain_death = TRUE
|
||||
|
||||
/obj/item/organ/brain/on_death()
|
||||
if(damage <= BRAIN_DAMAGE_DEATH) //rip
|
||||
brain_death = FALSE
|
||||
applyOrganDamage(maxHealth * decay_factor)
|
||||
|
||||
|
||||
/obj/item/organ/brain/applyOrganDamage(var/d, var/maximum = maxHealth)
|
||||
..()
|
||||
|
||||
|
||||
/obj/item/organ/brain/check_damage_thresholds(mob/M)
|
||||
. = ..()
|
||||
//if we're not more injured than before, return without gambling for a trauma
|
||||
if(damage <= prev_damage)
|
||||
return
|
||||
damage_delta = damage - prev_damage
|
||||
if(damage > BRAIN_DAMAGE_MILD)
|
||||
if(prob(damage_delta * (1 + max(0, (damage - BRAIN_DAMAGE_MILD)/100)))) //Base chance is the hit damage; for every point of damage past the threshold the chance is increased by 1% //learn how to do your bloody math properly goddamnit
|
||||
gain_trauma_type(BRAIN_TRAUMA_MILD)
|
||||
if(damage > BRAIN_DAMAGE_SEVERE)
|
||||
if(prob(damage_delta * (1 + max(0, (damage - BRAIN_DAMAGE_SEVERE)/100)))) //Base chance is the hit damage; for every point of damage past the threshold the chance is increased by 1%
|
||||
if(prob(20))
|
||||
gain_trauma_type(BRAIN_TRAUMA_SPECIAL)
|
||||
else
|
||||
gain_trauma_type(BRAIN_TRAUMA_SEVERE)
|
||||
|
||||
if (owner)
|
||||
if(owner.stat < UNCONSCIOUS) //conscious or soft-crit
|
||||
var/brain_message
|
||||
if(prev_damage < BRAIN_DAMAGE_MILD && damage >= BRAIN_DAMAGE_MILD)
|
||||
brain_message = "<span class='warning'>You feel lightheaded.</span>"
|
||||
else if(prev_damage < BRAIN_DAMAGE_SEVERE && damage >= BRAIN_DAMAGE_SEVERE)
|
||||
brain_message = "<span class='warning'>You feel less in control of your thoughts.</span>"
|
||||
else if(prev_damage < (BRAIN_DAMAGE_DEATH - 20) && damage >= (BRAIN_DAMAGE_DEATH - 20))
|
||||
brain_message = "<span class='warning'>You can feel your mind flickering on and off...</span>"
|
||||
|
||||
if(.)
|
||||
. += "\n[brain_message]"
|
||||
else
|
||||
return brain_message
|
||||
|
||||
/obj/item/organ/brain/Destroy() //copypasted from MMIs.
|
||||
if(brainmob)
|
||||
@@ -200,6 +323,10 @@
|
||||
return FALSE
|
||||
if(!resilience)
|
||||
resilience = initial(trauma.resilience)
|
||||
if(!owner)
|
||||
return FALSE
|
||||
if(owner.stat == DEAD)
|
||||
return FALSE
|
||||
|
||||
var/resilience_tier_count = 0
|
||||
for(var/X in traumas)
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
else if(istype(loc, /obj/item/organ/brain))
|
||||
BR = loc
|
||||
if(BR)
|
||||
BR.damaged_brain = 1 //beaten to a pulp
|
||||
BR.brain_death = TRUE
|
||||
|
||||
/mob/living/brain/proc/handle_emp_damage()
|
||||
if(emp_damage)
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
return S
|
||||
|
||||
/obj/item/organ/body_egg/alien_embryo/on_life()
|
||||
.=..()
|
||||
switch(stage)
|
||||
if(2, 3)
|
||||
if(prob(2))
|
||||
|
||||
@@ -814,7 +814,7 @@
|
||||
reagents.clear_reagents()
|
||||
var/obj/item/organ/brain/B = getorgan(/obj/item/organ/brain)
|
||||
if(B)
|
||||
B.damaged_brain = FALSE
|
||||
B.brain_death = FALSE
|
||||
for(var/thing in diseases)
|
||||
var/datum/disease/D = thing
|
||||
if(D.severity != DISEASE_SEVERITY_POSITIVE)
|
||||
|
||||
@@ -405,16 +405,16 @@
|
||||
|
||||
if(istype(ears) && (deafen_pwr || damage_pwr))
|
||||
var/ear_damage = damage_pwr * effect_amount
|
||||
var/deaf = max(ears.deaf, deafen_pwr * effect_amount)
|
||||
var/deaf = deafen_pwr * effect_amount
|
||||
adjustEarDamage(ear_damage,deaf)
|
||||
|
||||
if(ears.ear_damage >= 15)
|
||||
if(ears.damage >= 15)
|
||||
to_chat(src, "<span class='warning'>Your ears start to ring badly!</span>")
|
||||
if(prob(ears.ear_damage - 5))
|
||||
if(prob(ears.damage - 5))
|
||||
to_chat(src, "<span class='userdanger'>You can't hear anything!</span>")
|
||||
ears.ear_damage = min(ears.ear_damage, UNHEALING_EAR_DAMAGE)
|
||||
ears.damage = min(ears.damage, ears.maxHealth)
|
||||
// you need earmuffs, inacusiate, or replacement
|
||||
else if(ears.ear_damage >= 5)
|
||||
else if(ears.damage >= 5)
|
||||
to_chat(src, "<span class='warning'>Your ears start to ring!</span>")
|
||||
SEND_SOUND(src, sound('sound/weapons/flash_ring.ogg',0,1,0,250))
|
||||
return effect_amount //how soundbanged we are
|
||||
|
||||
@@ -47,7 +47,6 @@
|
||||
adjustArousalLoss(damage * hit_percent)
|
||||
return TRUE
|
||||
|
||||
|
||||
//These procs fetch a cumulative total damage from all bodyparts
|
||||
/mob/living/carbon/getBruteLoss()
|
||||
var/amount = 0
|
||||
@@ -63,7 +62,6 @@
|
||||
amount += BP.burn_dam
|
||||
return amount
|
||||
|
||||
|
||||
/mob/living/carbon/adjustBruteLoss(amount, updating_health = TRUE, forced = FALSE)
|
||||
if(!forced && (status_flags & GODMODE))
|
||||
return FALSE
|
||||
@@ -113,6 +111,50 @@
|
||||
return
|
||||
adjustStaminaLoss(diff, updating, forced)
|
||||
|
||||
/** adjustOrganLoss
|
||||
* inputs: slot (organ slot, like ORGAN_SLOT_HEART), amount (damage to be done), and maximum (currently an arbitrarily large number, can be set so as to limit damage)
|
||||
* outputs:
|
||||
* description: If an organ exists in the slot requested, and we are capable of taking damage (we don't have GODMODE on), call the damage proc on that organ.
|
||||
*/
|
||||
/mob/living/carbon/adjustOrganLoss(slot, amount, maximum)
|
||||
var/obj/item/organ/O = getorganslot(slot)
|
||||
if(O && !(status_flags & GODMODE))
|
||||
if(!maximum)
|
||||
maximum = O.maxHealth
|
||||
O.applyOrganDamage(amount, maximum)
|
||||
O.onDamage(amount, maximum)
|
||||
|
||||
/** setOrganLoss
|
||||
* inputs: slot (organ slot, like ORGAN_SLOT_HEART), amount(damage to be set to)
|
||||
* outputs:
|
||||
* description: If an organ exists in the slot requested, and we are capable of taking damage (we don't have GODMODE on), call the set damage proc on that organ, which can
|
||||
* set or clear the failing variable on that organ, making it either cease or start functions again, unlike adjustOrganLoss.
|
||||
*/
|
||||
/mob/living/carbon/setOrganLoss(slot, amount)
|
||||
var/obj/item/organ/O = getorganslot(slot)
|
||||
if(O && !(status_flags & GODMODE))
|
||||
O.setOrganDamage(amount)
|
||||
O.onSetDamage(amount)
|
||||
|
||||
/** getOrganLoss
|
||||
* inputs: slot (organ slot, like ORGAN_SLOT_HEART)
|
||||
* outputs: organ damage
|
||||
* description: If an organ exists in the slot requested, return the amount of damage that organ has
|
||||
*/
|
||||
/mob/living/carbon/getOrganLoss(slot)
|
||||
var/obj/item/organ/O = getorganslot(slot)
|
||||
if(O)
|
||||
return O.damage
|
||||
|
||||
/mob/living/carbon/proc/adjustAllOrganLoss(amount, maximum)
|
||||
for(var/obj/item/organ/O in internal_organs)
|
||||
if(O && !(status_flags & GODMODE))
|
||||
continue
|
||||
if(!maximum)
|
||||
maximum = O.maxHealth
|
||||
O.applyOrganDamage(amount, maximum)
|
||||
O.onDamage(amount, maximum)
|
||||
|
||||
////////////////////////////////////////////
|
||||
|
||||
//Returns a list of damaged bodyparts
|
||||
@@ -213,24 +255,25 @@
|
||||
update_damage_overlays()
|
||||
update_stamina()
|
||||
|
||||
/mob/living/carbon/getBrainLoss()
|
||||
/* TO_REMOVE
|
||||
/mob/living/carbon/getOrganLoss(ORGAN_SLOT_BRAIN)
|
||||
. = 0
|
||||
var/obj/item/organ/brain/B = getorganslot(ORGAN_SLOT_BRAIN)
|
||||
if(B)
|
||||
. = B.get_brain_damage()
|
||||
|
||||
//Some sources of brain damage shouldn't be deadly
|
||||
/mob/living/carbon/adjustBrainLoss(amount, maximum = BRAIN_DAMAGE_DEATH)
|
||||
/mob/living/carbon/adjustOrganLoss(ORGAN_SLOT_BRAIN, amount, maximum = BRAIN_DAMAGE_DEATH)
|
||||
if(status_flags & GODMODE)
|
||||
return FALSE
|
||||
var/prev_brainloss = getBrainLoss()
|
||||
var/prev_brainloss = getOrganLoss(ORGAN_SLOT_BRAIN)
|
||||
var/obj/item/organ/brain/B = getorganslot(ORGAN_SLOT_BRAIN)
|
||||
if(!B)
|
||||
return
|
||||
B.adjust_brain_damage(amount, maximum)
|
||||
if(amount <= 0) //cut this early
|
||||
return
|
||||
var/brainloss = getBrainLoss()
|
||||
var/brainloss = getOrganLoss(ORGAN_SLOT_BRAIN)
|
||||
if(brainloss > BRAIN_DAMAGE_MILD)
|
||||
if(prob(amount * ((2 * (100 + brainloss - BRAIN_DAMAGE_MILD)) / 100))) //Base chance is the hit damage; for every point of damage past the threshold the chance is increased by 2%
|
||||
gain_trauma_type(BRAIN_TRAUMA_MILD)
|
||||
|
||||
@@ -348,10 +348,15 @@
|
||||
if(temp)
|
||||
var/update = 0
|
||||
var/dmg = rand(M.force/2, M.force)
|
||||
var/atom/throw_target = get_edge_target_turf(src, M.dir)
|
||||
switch(M.damtype)
|
||||
if("brute")
|
||||
if(M.force > 20)
|
||||
Unconscious(20)
|
||||
if(M.force > 35) // durand and other heavy mechas
|
||||
Knockdown(50)
|
||||
src.throw_at(throw_target, rand(1,5), 7)
|
||||
else if(M.force >= 20 && !IsKnockdown()) // lightweight mechas like gygax
|
||||
Knockdown(30)
|
||||
src.throw_at(throw_target, rand(1,3), 7)
|
||||
update |= temp.receive_damage(dmg, 0)
|
||||
playsound(src, 'sound/weapons/punch4.ogg', 50, 1)
|
||||
if("fire")
|
||||
@@ -746,9 +751,54 @@
|
||||
if(0 to NUTRITION_LEVEL_STARVING)
|
||||
to_send += "<span class='danger'>You're starving!</span>\n"
|
||||
|
||||
|
||||
//TODO: Convert these messages into vague messages, thereby encouraging actual dignosis.
|
||||
//Compiles then shows the list of damaged organs and broken organs
|
||||
var/list/broken = list()
|
||||
var/list/damaged = list()
|
||||
var/broken_message
|
||||
var/damaged_message
|
||||
var/broken_plural
|
||||
var/damaged_plural
|
||||
//Sets organs into their proper list
|
||||
for(var/O in internal_organs)
|
||||
var/obj/item/organ/organ = O
|
||||
if(organ.organ_flags & ORGAN_FAILING)
|
||||
if(broken.len)
|
||||
broken += ", "
|
||||
broken += organ.name
|
||||
else if(organ.damage > organ.low_threshold)
|
||||
if(damaged.len)
|
||||
damaged += ", "
|
||||
damaged += organ.name
|
||||
//Checks to enforce proper grammar, inserts words as necessary into the list
|
||||
if(broken.len)
|
||||
if(broken.len > 1)
|
||||
broken.Insert(broken.len, "and ")
|
||||
broken_plural = TRUE
|
||||
else
|
||||
var/holder = broken[1] //our one and only element
|
||||
if(holder[lentext(holder)] == "s")
|
||||
broken_plural = TRUE
|
||||
//Put the items in that list into a string of text
|
||||
for(var/B in broken)
|
||||
broken_message += B
|
||||
to_chat(src, "<span class='warning'> Your [broken_message] [broken_plural ? "are" : "is"] non-functional!</span>")
|
||||
if(damaged.len)
|
||||
if(damaged.len > 1)
|
||||
damaged.Insert(damaged.len, "and ")
|
||||
damaged_plural = TRUE
|
||||
else
|
||||
var/holder = damaged[1]
|
||||
if(holder[lentext(holder)] == "s")
|
||||
damaged_plural = TRUE
|
||||
for(var/D in damaged)
|
||||
damaged_message += D
|
||||
to_chat(src, "<span class='info'>Your [damaged_message] [damaged_plural ? "are" : "is"] hurt.</span>")
|
||||
|
||||
if(roundstart_quirks.len)
|
||||
to_send += "<span class='notice'>You have these quirks: [get_trait_string()].</span>\n"
|
||||
|
||||
|
||||
to_chat(src, to_send)
|
||||
else
|
||||
if(wear_suit)
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
else if(eye_blurry) //blurry eyes heal slowly
|
||||
adjust_blurriness(-1)
|
||||
|
||||
if (getBrainLoss() >= 30) //Citadel change to make memes more often.
|
||||
if (getOrganLoss(ORGAN_SLOT_BRAIN) >= 30) //Citadel change to make memes more often.
|
||||
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "brain_damage", /datum/mood_event/brain_damage)
|
||||
if(prob(3))
|
||||
if(prob(25))
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// This code handles different species in the game.
|
||||
|
||||
GLOBAL_LIST_EMPTY(roundstart_races)
|
||||
GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
|
||||
/datum/species
|
||||
var/id // if the game needs to manually check your race to do something not included in a proc here, it will use this
|
||||
@@ -8,13 +9,35 @@ GLOBAL_LIST_EMPTY(roundstart_races)
|
||||
var/name // this is the fluff name. these will be left generic (such as 'Lizardperson' for the lizard race) so servers can change them to whatever
|
||||
var/default_color = "#FFF" // if alien colors are disabled, this is the color that will be used by that race
|
||||
|
||||
var/sexes = 1 // whether or not the race has sexual characteristics. at the moment this is only 0 for skeletons and shadows
|
||||
var/sexes = 1 // whether or not the race has sexual characteristics. at the moment this is only 0 for skeletons and shadows
|
||||
|
||||
var/list/offset_features = list(OFFSET_UNIFORM = list(0,0), OFFSET_ID = list(0,0), OFFSET_GLOVES = list(0,0), OFFSET_GLASSES = list(0,0), OFFSET_EARS = list(0,0), OFFSET_SHOES = list(0,0), OFFSET_S_STORE = list(0,0), OFFSET_FACEMASK = list(0,0), OFFSET_HEAD = list(0,0), OFFSET_FACE = list(0,0), OFFSET_BELT = list(0,0), OFFSET_BACK = list(0,0), OFFSET_SUIT = list(0,0), OFFSET_NECK = list(0,0))
|
||||
//Species Icon Drawing Offsets - Pixel X, Pixel Y, Aka X = Horizontal and Y = Vertical, from bottom left corner
|
||||
var/list/offset_features = list(
|
||||
OFFSET_UNIFORM = list(0,0),
|
||||
OFFSET_ID = list(0,0),
|
||||
OFFSET_GLOVES = list(0,0),
|
||||
OFFSET_GLASSES = list(0,0),
|
||||
OFFSET_EARS = list(0,0),
|
||||
OFFSET_SHOES = list(0,0),
|
||||
OFFSET_S_STORE = list(0,0),
|
||||
OFFSET_FACEMASK = list(0,0),
|
||||
OFFSET_HEAD = list(0,0),
|
||||
OFFSET_EYES = list(0,0),
|
||||
OFFSET_LIPS = list(0,0),
|
||||
OFFSET_BELT = list(0,0),
|
||||
OFFSET_BACK = list(0,0),
|
||||
OFFSET_HAIR = list(0,0),
|
||||
OFFSET_FHAIR = list(0,0),
|
||||
OFFSET_SUIT = list(0,0),
|
||||
OFFSET_NECK = list(0,0),
|
||||
OFFSET_MUTPARTS = list(0,0)
|
||||
)
|
||||
|
||||
var/hair_color // this allows races to have specific hair colors... if null, it uses the H's hair/facial hair colors. if "mutcolor", it uses the H's mutant_color
|
||||
var/hair_alpha = 255 // the alpha used by the hair. 255 is completely solid, 0 is transparent.
|
||||
|
||||
var/horn_color //specific horn colors, because why not?
|
||||
|
||||
var/use_skintones = 0 // does it use skintones or not? (spoiler alert this is only used by humans)
|
||||
var/exotic_blood = "" // If your race wants to bleed something other than bog standard blood, change this to reagent id.
|
||||
var/exotic_bloodtype = "" //If your race uses a non standard bloodtype (A+, O-, AB-, etc)
|
||||
@@ -79,7 +102,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
|
||||
var/fixed_mut_color3 = ""
|
||||
var/whitelisted = 0 //Is this species restricted to certain players?
|
||||
var/whitelist = list() //List the ckeys that can use this species, if it's whitelisted.: list("John Doe", "poopface666", "SeeALiggerPullTheTrigger") Spaces & capitalization can be included or ignored entirely for each key as it checks for both.
|
||||
|
||||
var/should_draw_citadel = FALSE
|
||||
|
||||
///////////
|
||||
// PROCS //
|
||||
@@ -98,6 +121,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
|
||||
var/datum/species/S = new I
|
||||
if(S.check_roundstart_eligible())
|
||||
GLOB.roundstart_races += S.id
|
||||
GLOB.roundstart_race_names["[S.name]"] = S.id
|
||||
qdel(S)
|
||||
if(!GLOB.roundstart_races.len)
|
||||
GLOB.roundstart_races += "human"
|
||||
@@ -129,10 +153,10 @@ GLOBAL_LIST_EMPTY(roundstart_races)
|
||||
return
|
||||
|
||||
//Please override this locally if you want to define when what species qualifies for what rank if human authority is enforced.
|
||||
/datum/species/proc/qualifies_for_rank(rank, list/features)
|
||||
if(rank in GLOB.command_positions)
|
||||
return 0
|
||||
return 1
|
||||
/datum/species/proc/qualifies_for_rank(rank, list/features) //SPECIES JOB RESTRICTIONS
|
||||
//if(rank in GLOB.command_positions) Left as an example: The format qualifies for rank takes.
|
||||
// return 0 //It returns false when it runs the proc so they don't get jobs from the global list.
|
||||
return 1 //It returns 1 to say they are a-okay to continue.
|
||||
|
||||
//Will regenerate missing organs
|
||||
/datum/species/proc/regenerate_organs(mob/living/carbon/C,datum/species/old_species,replace_current=TRUE)
|
||||
@@ -260,7 +284,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
|
||||
C.hud_used.update_locked_slots()
|
||||
|
||||
// this needs to be FIRST because qdel calls update_body which checks if we have DIGITIGRADE legs or not and if not then removes DIGITIGRADE from species_traits
|
||||
if(("legs" in C.dna.species.mutant_bodyparts) && C.dna.features["legs"] == "Digitigrade Legs")
|
||||
if(("legs" in C.dna.species.mutant_bodyparts) && (C.dna.features["legs"] == "Digitigrade" || C.dna.features["legs"] == "Avian"))
|
||||
species_traits += DIGITIGRADE
|
||||
if(DIGITIGRADE in species_traits)
|
||||
C.Digitigrade_Leg_Swap(FALSE)
|
||||
@@ -294,8 +318,6 @@ GLOBAL_LIST_EMPTY(roundstart_races)
|
||||
for(var/datum/disease/A in C.diseases)
|
||||
A.cure(FALSE)
|
||||
|
||||
SEND_SIGNAL(C, COMSIG_SPECIES_GAIN, src, old_species)
|
||||
|
||||
//CITADEL EDIT
|
||||
if(NOAROUSAL in species_traits)
|
||||
C.canbearoused = FALSE
|
||||
@@ -306,6 +328,11 @@ GLOBAL_LIST_EMPTY(roundstart_races)
|
||||
var/mob/living/carbon/human/H = C
|
||||
if(NOGENITALS in H.dna.species.species_traits)
|
||||
H.give_genitals(TRUE) //call the clean up proc to delete anything on the mob then return.
|
||||
if("meat_type" in default_features) //I can't believe it's come to the meat
|
||||
H.type_of_meat = GLOB.meat_types[H.dna.features["meat_type"]]
|
||||
|
||||
SEND_SIGNAL(C, COMSIG_SPECIES_GAIN, src, old_species)
|
||||
|
||||
|
||||
// EDIT ENDS
|
||||
|
||||
@@ -317,6 +344,11 @@ GLOBAL_LIST_EMPTY(roundstart_races)
|
||||
for(var/X in inherent_traits)
|
||||
REMOVE_TRAIT(C, X, SPECIES_TRAIT)
|
||||
|
||||
if("meat_type" in default_features)
|
||||
C.type_of_meat = GLOB.meat_types[C.dna.features["meat_type"]]
|
||||
else
|
||||
C.type_of_meat = initial(meat)
|
||||
|
||||
SEND_SIGNAL(C, COMSIG_SPECIES_LOSS, src)
|
||||
|
||||
/datum/species/proc/handle_hair(mob/living/carbon/human/H, forced_colour)
|
||||
@@ -389,6 +421,10 @@ GLOBAL_LIST_EMPTY(roundstart_races)
|
||||
|
||||
facial_overlay.alpha = hair_alpha
|
||||
|
||||
if(OFFSET_FHAIR in H.dna.species.offset_features)
|
||||
facial_overlay.pixel_x += H.dna.species.offset_features[OFFSET_FHAIR][1]
|
||||
facial_overlay.pixel_y += H.dna.species.offset_features[OFFSET_FHAIR][2]
|
||||
|
||||
standing += facial_overlay
|
||||
|
||||
if(H.head)
|
||||
@@ -446,9 +482,11 @@ GLOBAL_LIST_EMPTY(roundstart_races)
|
||||
else
|
||||
hair_overlay.color = forced_colour
|
||||
hair_overlay.alpha = hair_alpha
|
||||
if(OFFSET_FACE in H.dna.species.offset_features)
|
||||
hair_overlay.pixel_x += H.dna.species.offset_features[OFFSET_FACE][1]
|
||||
hair_overlay.pixel_y += H.dna.species.offset_features[OFFSET_FACE][2]
|
||||
|
||||
if(OFFSET_HAIR in H.dna.species.offset_features)
|
||||
hair_overlay.pixel_x += H.dna.species.offset_features[OFFSET_HAIR][1]
|
||||
hair_overlay.pixel_y += H.dna.species.offset_features[OFFSET_HAIR][2]
|
||||
|
||||
if(hair_overlay.icon)
|
||||
standing += hair_overlay
|
||||
|
||||
@@ -469,9 +507,11 @@ GLOBAL_LIST_EMPTY(roundstart_races)
|
||||
if(H.lip_style && (LIPS in species_traits))
|
||||
var/mutable_appearance/lip_overlay = mutable_appearance('icons/mob/human_face.dmi', "lips_[H.lip_style]", -BODY_LAYER)
|
||||
lip_overlay.color = H.lip_color
|
||||
if(OFFSET_FACE in H.dna.species.offset_features)
|
||||
lip_overlay.pixel_x += H.dna.species.offset_features[OFFSET_FACE][1]
|
||||
lip_overlay.pixel_y += H.dna.species.offset_features[OFFSET_FACE][2]
|
||||
|
||||
if(OFFSET_LIPS in H.dna.species.offset_features)
|
||||
lip_overlay.pixel_x += H.dna.species.offset_features[OFFSET_LIPS][1]
|
||||
lip_overlay.pixel_y += H.dna.species.offset_features[OFFSET_LIPS][2]
|
||||
|
||||
standing += lip_overlay
|
||||
|
||||
// eyes
|
||||
@@ -484,9 +524,11 @@ GLOBAL_LIST_EMPTY(roundstart_races)
|
||||
eye_overlay = mutable_appearance('icons/mob/human_face.dmi', "eyes", -BODY_LAYER)
|
||||
if((EYECOLOR in species_traits) && has_eyes)
|
||||
eye_overlay.color = "#" + H.eye_color
|
||||
if(OFFSET_FACE in H.dna.species.offset_features)
|
||||
eye_overlay.pixel_x += H.dna.species.offset_features[OFFSET_FACE][1]
|
||||
eye_overlay.pixel_y += H.dna.species.offset_features[OFFSET_FACE][2]
|
||||
|
||||
if(OFFSET_EYES in H.dna.species.offset_features)
|
||||
eye_overlay.pixel_x += H.dna.species.offset_features[OFFSET_EYES][1]
|
||||
eye_overlay.pixel_y += H.dna.species.offset_features[OFFSET_EYES][2]
|
||||
|
||||
standing += eye_overlay
|
||||
|
||||
//Underwear, Undershirts & Socks
|
||||
@@ -529,7 +571,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
|
||||
var/digilegs = (DIGITIGRADE in species_traits) ? "_d" : ""
|
||||
var/mutable_appearance/MA = mutable_appearance(S.icon, "[S.icon_state][digilegs]", -BODY_LAYER)
|
||||
if(UNDIE_COLORABLE(S))
|
||||
MA.color = "[H.socks_color]"
|
||||
MA.color = "#[H.socks_color]"
|
||||
standing += MA
|
||||
|
||||
if(standing.len)
|
||||
@@ -612,6 +654,10 @@ GLOBAL_LIST_EMPTY(roundstart_races)
|
||||
else if ("wings" in mutant_bodyparts)
|
||||
bodyparts_to_add -= "wings_open"
|
||||
|
||||
if("insect_fluff" in mutant_bodyparts)
|
||||
if(!H.dna.features["insect_fluff"] || H.dna.features["insect_fluff"] == "None" || H.wear_suit && (H.wear_suit.flags_inv & HIDEJUMPSUIT))
|
||||
bodyparts_to_add -= "insect_fluff"
|
||||
|
||||
//CITADEL EDIT
|
||||
//Race specific bodyparts:
|
||||
//Xenos
|
||||
@@ -715,12 +761,14 @@ GLOBAL_LIST_EMPTY(roundstart_races)
|
||||
S = GLOB.wings_list[H.dna.features["wings"]]
|
||||
if("wingsopen")
|
||||
S = GLOB.wings_open_list[H.dna.features["wings"]]
|
||||
if("deco_wings")
|
||||
S = GLOB.deco_wings_list[H.dna.features["deco_wings"]]
|
||||
if("legs")
|
||||
S = GLOB.legs_list[H.dna.features["legs"]]
|
||||
if("moth_wings")
|
||||
S = GLOB.moth_wings_list[H.dna.features["moth_wings"]]
|
||||
if("moth_markings")
|
||||
S = GLOB.moth_markings_list[H.dna.features["moth_markings"]]
|
||||
if("insect_wings")
|
||||
S = GLOB.insect_wings_list[H.dna.features["insect_wings"]]
|
||||
if("insect_fluff")
|
||||
S = GLOB.insect_fluffs_list[H.dna.features["insect_fluff"]]
|
||||
if("caps")
|
||||
S = GLOB.caps_list[H.dna.features["caps"]]
|
||||
if("ipc_screen")
|
||||
@@ -817,6 +865,8 @@ GLOBAL_LIST_EMPTY(roundstart_races)
|
||||
accessory_overlay.color = "#[H.facial_hair_color]"
|
||||
if(EYECOLOR)
|
||||
accessory_overlay.color = "#[H.eye_color]"
|
||||
if(HORNCOLOR)
|
||||
accessory_overlay.color = "#[H.horn_color]"
|
||||
else
|
||||
accessory_overlay.color = forced_colour
|
||||
else
|
||||
@@ -833,6 +883,11 @@ GLOBAL_LIST_EMPTY(roundstart_races)
|
||||
for(var/index=1, index<=husklist.len, index++)
|
||||
husklist[index] = husklist[index]/255
|
||||
accessory_overlay.color = husklist
|
||||
|
||||
if(OFFSET_MUTPARTS in H.dna.species.offset_features)
|
||||
accessory_overlay.pixel_x += H.dna.species.offset_features[OFFSET_MUTPARTS][1]
|
||||
accessory_overlay.pixel_y += H.dna.species.offset_features[OFFSET_MUTPARTS][2]
|
||||
|
||||
standing += accessory_overlay
|
||||
|
||||
if(S.hasinner)
|
||||
@@ -845,6 +900,10 @@ GLOBAL_LIST_EMPTY(roundstart_races)
|
||||
if(S.center)
|
||||
inner_accessory_overlay = center_image(inner_accessory_overlay, S.dimension_x, S.dimension_y)
|
||||
|
||||
if(OFFSET_MUTPARTS in H.dna.species.offset_features)
|
||||
inner_accessory_overlay.pixel_x += H.dna.species.offset_features[OFFSET_MUTPARTS][1]
|
||||
inner_accessory_overlay.pixel_y += H.dna.species.offset_features[OFFSET_MUTPARTS][2]
|
||||
|
||||
standing += inner_accessory_overlay
|
||||
|
||||
if(S.extra) //apply the extra overlay, if there is one
|
||||
@@ -882,6 +941,14 @@ GLOBAL_LIST_EMPTY(roundstart_races)
|
||||
extra_accessory_overlay.color = "#[H.facial_hair_color]"
|
||||
if(EYECOLOR)
|
||||
extra_accessory_overlay.color = "#[H.eye_color]"
|
||||
|
||||
if(HORNCOLOR)
|
||||
extra_accessory_overlay.color = "#[H.horn_color]"
|
||||
|
||||
if(OFFSET_MUTPARTS in H.dna.species.offset_features)
|
||||
extra_accessory_overlay.pixel_x += H.dna.species.offset_features[OFFSET_MUTPARTS][1]
|
||||
extra_accessory_overlay.pixel_y += H.dna.species.offset_features[OFFSET_MUTPARTS][2]
|
||||
|
||||
standing += extra_accessory_overlay
|
||||
|
||||
if(S.extra2) //apply the extra overlay, if there is one
|
||||
@@ -914,6 +981,13 @@ GLOBAL_LIST_EMPTY(roundstart_races)
|
||||
extra2_accessory_overlay.color = "#[H.dna.features["mcolor"]]"
|
||||
else
|
||||
extra2_accessory_overlay.color = "#[H.hair_color]"
|
||||
if(HORNCOLOR)
|
||||
extra2_accessory_overlay.color = "#[H.horn_color]"
|
||||
|
||||
if(OFFSET_MUTPARTS in H.dna.species.offset_features)
|
||||
extra2_accessory_overlay.pixel_x += H.dna.species.offset_features[OFFSET_MUTPARTS][1]
|
||||
extra2_accessory_overlay.pixel_y += H.dna.species.offset_features[OFFSET_MUTPARTS][2]
|
||||
|
||||
standing += extra2_accessory_overlay
|
||||
|
||||
|
||||
@@ -1198,9 +1272,14 @@ GLOBAL_LIST_EMPTY(roundstart_races)
|
||||
if(mood && mood.sanity > SANITY_DISTURBED)
|
||||
hunger_rate *= max(0.5, 1 - 0.002 * mood.sanity) //0.85 to 0.75
|
||||
|
||||
if(H.satiety > 0)
|
||||
// Whether we cap off our satiety or move it towards 0
|
||||
if(H.satiety > MAX_SATIETY)
|
||||
H.satiety = MAX_SATIETY
|
||||
else if(H.satiety > 0)
|
||||
H.satiety--
|
||||
if(H.satiety < 0)
|
||||
else if(H.satiety < -MAX_SATIETY)
|
||||
H.satiety = -MAX_SATIETY
|
||||
else if(H.satiety < 0)
|
||||
H.satiety++
|
||||
if(prob(round(-H.satiety/40)))
|
||||
H.Jitter(5)
|
||||
@@ -1316,9 +1395,9 @@ GLOBAL_LIST_EMPTY(roundstart_races)
|
||||
if(!istype(J) && istype(C))
|
||||
J = C.jetpack
|
||||
if(istype(J) && J.full_speed && J.allow_thrust(0.01, H)) //Prevents stacking
|
||||
. -= 2
|
||||
. -= 0.4
|
||||
else if(istype(T) && T.allow_thrust(0.01, H))
|
||||
. -= 2
|
||||
. -= 0.4
|
||||
|
||||
if(!ignoreslow && gravity)
|
||||
if(H.wear_suit)
|
||||
@@ -1685,7 +1764,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
|
||||
if(BODY_ZONE_HEAD)
|
||||
if(!I.is_sharp() && armor_block < 50)
|
||||
if(prob(I.force))
|
||||
H.adjustBrainLoss(20)
|
||||
H.adjustOrganLoss(ORGAN_SLOT_BRAIN, 20)
|
||||
if(H.stat == CONSCIOUS)
|
||||
H.visible_message("<span class='danger'>[H] has been knocked senseless!</span>", \
|
||||
"<span class='userdanger'>[H] has been knocked senseless!</span>")
|
||||
@@ -1694,11 +1773,11 @@ GLOBAL_LIST_EMPTY(roundstart_races)
|
||||
if(prob(10))
|
||||
H.gain_trauma(/datum/brain_trauma/mild/concussion)
|
||||
else
|
||||
H.adjustBrainLoss(I.force * 0.2)
|
||||
H.adjustOrganLoss(ORGAN_SLOT_BRAIN, I.force * 0.2)
|
||||
|
||||
if(H.stat == CONSCIOUS && H != user && prob(I.force + ((100 - H.health) * 0.5))) // rev deconversion through blunt trauma.
|
||||
var/datum/antagonist/rev/rev = H.mind.has_antag_datum(/datum/antagonist/rev)
|
||||
var/datum/antagonist/gang/gang = H.mind.has_antag_datum(/datum/antagonist/gang/)
|
||||
var/datum/antagonist/gang/gang = H.mind.has_antag_datum(/datum/antagonist/gang && !/datum/antagonist/gang/boss)
|
||||
if(rev)
|
||||
rev.remove_revolutionary(FALSE, user)
|
||||
if(gang)
|
||||
@@ -1734,6 +1813,130 @@ GLOBAL_LIST_EMPTY(roundstart_races)
|
||||
H.forcesay(GLOB.hit_appends) //forcesay checks stat already.
|
||||
return TRUE
|
||||
|
||||
/datum/species/proc/alt_spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H, datum/martial_art/attacker_style)
|
||||
if(!istype(M))
|
||||
return TRUE
|
||||
CHECK_DNA_AND_SPECIES(M)
|
||||
CHECK_DNA_AND_SPECIES(H)
|
||||
|
||||
if(!istype(M)) //sanity check for drones.
|
||||
return TRUE
|
||||
if(M.mind)
|
||||
attacker_style = M.mind.martial_art
|
||||
if((M != H) && M.a_intent != INTENT_HELP && H.check_shields(M, 0, M.name, attack_type = UNARMED_ATTACK))
|
||||
log_combat(M, H, "attempted to touch")
|
||||
H.visible_message("<span class='warning'>[M] attempted to touch [H]!</span>")
|
||||
return TRUE
|
||||
switch(M.a_intent)
|
||||
if(INTENT_HELP)
|
||||
if(M == H)
|
||||
althelp(M, H, attacker_style)
|
||||
return TRUE
|
||||
return FALSE
|
||||
if(INTENT_DISARM)
|
||||
altdisarm(M, H, attacker_style)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/species/proc/althelp(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style)
|
||||
if(user == target && istype(user))
|
||||
if(user.getStaminaLoss() >= STAMINA_SOFTCRIT)
|
||||
to_chat(user, "<span class='warning'>You're too exhausted for that.</span>")
|
||||
return
|
||||
if(!user.resting)
|
||||
to_chat(user, "<span class='notice'>You can only force yourself up if you're on the ground.</span>")
|
||||
return
|
||||
user.visible_message("<span class='notice'>[user] forces [p_them()]self up to [p_their()] feet!</span>", "<span class='notice'>You force yourself up to your feet!</span>")
|
||||
user.resting = 0
|
||||
user.update_canmove()
|
||||
user.adjustStaminaLossBuffered(user.stambuffer) //Rewards good stamina management by making it easier to instantly get up from resting
|
||||
playsound(user, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
|
||||
/datum/species/proc/altdisarm(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style)
|
||||
if(user.getStaminaLoss() >= STAMINA_SOFTCRIT)
|
||||
to_chat(user, "<span class='warning'>You're too exhausted.</span>")
|
||||
return FALSE
|
||||
if(target.check_block())
|
||||
target.visible_message("<span class='warning'>[target] blocks [user]'s shoving attempt!</span>")
|
||||
return FALSE
|
||||
if(attacker_style && attacker_style.disarm_act(user,target))
|
||||
return TRUE
|
||||
if(user.resting)
|
||||
return FALSE
|
||||
else
|
||||
if(user == target)
|
||||
return
|
||||
user.do_attack_animation(target, ATTACK_EFFECT_DISARM)
|
||||
user.adjustStaminaLossBuffered(4)
|
||||
playsound(target, 'sound/weapons/thudswoosh.ogg', 50, TRUE, -1)
|
||||
|
||||
if(target.w_uniform)
|
||||
target.w_uniform.add_fingerprint(user)
|
||||
SEND_SIGNAL(target, COMSIG_HUMAN_DISARM_HIT, user, user.zone_selected)
|
||||
|
||||
if(!target.resting)
|
||||
target.adjustStaminaLoss(5)
|
||||
|
||||
if(target.is_shove_knockdown_blocked())
|
||||
return
|
||||
|
||||
var/turf/target_oldturf = target.loc
|
||||
var/shove_dir = get_dir(user.loc, target_oldturf)
|
||||
var/turf/target_shove_turf = get_step(target.loc, shove_dir)
|
||||
var/mob/living/carbon/human/target_collateral_human
|
||||
var/shove_blocked = FALSE //Used to check if a shove is blocked so that if it is knockdown logic can be applied
|
||||
|
||||
//Thank you based whoneedsspace
|
||||
target_collateral_human = locate(/mob/living/carbon/human) in target_shove_turf.contents
|
||||
if(target_collateral_human && !target_collateral_human.resting)
|
||||
shove_blocked = TRUE
|
||||
else
|
||||
target_collateral_human = null
|
||||
target.Move(target_shove_turf, shove_dir)
|
||||
if(get_turf(target) == target_oldturf)
|
||||
shove_blocked = TRUE
|
||||
|
||||
if(shove_blocked && !target.buckled)
|
||||
var/directional_blocked = !target.Adjacent(target_shove_turf)
|
||||
var/targetatrest = target.resting
|
||||
if((directional_blocked || !(target_collateral_human || target_shove_turf.shove_act(target, user))) && !targetatrest)
|
||||
target.Knockdown(SHOVE_KNOCKDOWN_SOLID)
|
||||
user.visible_message("<span class='danger'>[user.name] shoves [target.name], knocking them down!</span>",
|
||||
"<span class='danger'>You shove [target.name], knocking them down!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
log_combat(user, target, "shoved", "knocking them down")
|
||||
else if(target_collateral_human && !targetatrest)
|
||||
target.Knockdown(SHOVE_KNOCKDOWN_HUMAN)
|
||||
target_collateral_human.Knockdown(SHOVE_KNOCKDOWN_COLLATERAL)
|
||||
user.visible_message("<span class='danger'>[user.name] shoves [target.name] into [target_collateral_human.name]!</span>",
|
||||
"<span class='danger'>You shove [target.name] into [target_collateral_human.name]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
log_combat(user, target, "shoved", "into [target_collateral_human.name]")
|
||||
|
||||
else
|
||||
user.visible_message("<span class='danger'>[user.name] shoves [target.name]!</span>",
|
||||
"<span class='danger'>You shove [target.name]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
var/target_held_item = target.get_active_held_item()
|
||||
var/knocked_item = FALSE
|
||||
if(!is_type_in_typecache(target_held_item, GLOB.shove_disarming_types))
|
||||
target_held_item = null
|
||||
if(!target.has_movespeed_modifier(SHOVE_SLOWDOWN_ID))
|
||||
target.add_movespeed_modifier(SHOVE_SLOWDOWN_ID, multiplicative_slowdown = SHOVE_SLOWDOWN_STRENGTH)
|
||||
if(target_held_item)
|
||||
target.visible_message("<span class='danger'>[target.name]'s grip on \the [target_held_item] loosens!</span>",
|
||||
"<span class='danger'>Your grip on \the [target_held_item] loosens!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
addtimer(CALLBACK(target, /mob/living/carbon/human/proc/clear_shove_slowdown), SHOVE_SLOWDOWN_LENGTH)
|
||||
else if(target_held_item)
|
||||
target.dropItemToGround(target_held_item)
|
||||
knocked_item = TRUE
|
||||
target.visible_message("<span class='danger'>[target.name] drops \the [target_held_item]!!</span>",
|
||||
"<span class='danger'>You drop \the [target_held_item]!!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
var/append_message = ""
|
||||
if(target_held_item)
|
||||
if(knocked_item)
|
||||
append_message = "causing them to drop [target_held_item]"
|
||||
else
|
||||
append_message = "loosening their grip on [target_held_item]"
|
||||
log_combat(user, target, "shoved", append_message)
|
||||
|
||||
/datum/species/proc/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked, mob/living/carbon/human/H)
|
||||
var/hit_percent = (100-(blocked+armor))/100
|
||||
hit_percent = (hit_percent * (100-H.physiology.damage_resistance))/100
|
||||
@@ -1783,14 +1986,13 @@ GLOBAL_LIST_EMPTY(roundstart_races)
|
||||
if(CLONE)
|
||||
H.adjustCloneLoss(damage * hit_percent * H.physiology.clone_mod)
|
||||
if(STAMINA)
|
||||
H.stamdamageoverlaytemp = 20
|
||||
if(BP)
|
||||
if(damage > 0 ? BP.receive_damage(0, 0, damage * hit_percent * H.physiology.stamina_mod) : BP.heal_damage(0, 0, abs(damage * hit_percent * H.physiology.stamina_mod), only_robotic = FALSE, only_organic = FALSE))
|
||||
H.update_stamina()
|
||||
else
|
||||
H.adjustStaminaLoss(damage * hit_percent * H.physiology.stamina_mod)
|
||||
if(BRAIN)
|
||||
H.adjustBrainLoss(damage * hit_percent * H.physiology.brain_mod)
|
||||
H.adjustOrganLoss(ORGAN_SLOT_BRAIN, damage * hit_percent * H.physiology.brain_mod)
|
||||
if(AROUSAL) //Citadel edit - arousal
|
||||
H.adjustArousalLoss(damage * hit_percent)
|
||||
return 1
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
|
||||
/obj/item/organ/brain/dullahan
|
||||
decoy_override = TRUE
|
||||
vital = FALSE
|
||||
organ_flags = 0
|
||||
|
||||
/obj/item/organ/tongue/dullahan
|
||||
zone = "abstract"
|
||||
|
||||
@@ -102,6 +102,7 @@
|
||||
color = "#1C1C1C"
|
||||
var/respawn_progress = 0
|
||||
var/obj/item/light_eater/blade
|
||||
decay_factor = 0
|
||||
|
||||
|
||||
/obj/item/organ/heart/nightmare/attack(mob/M, mob/living/carbon/user, obj/target)
|
||||
@@ -122,10 +123,8 @@
|
||||
if(special != HEART_SPECIAL_SHADOWIFY)
|
||||
blade = new/obj/item/light_eater
|
||||
M.put_in_hands(blade)
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/item/organ/heart/nightmare/Remove(mob/living/carbon/M, special = 0)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
respawn_progress = 0
|
||||
if(blade && special != HEART_SPECIAL_SHADOWIFY)
|
||||
QDEL_NULL(blade)
|
||||
@@ -138,9 +137,8 @@
|
||||
/obj/item/organ/heart/nightmare/update_icon()
|
||||
return //always beating visually
|
||||
|
||||
/obj/item/organ/heart/nightmare/process()
|
||||
if(QDELETED(owner) || owner.stat != DEAD)
|
||||
respawn_progress = 0
|
||||
/obj/item/organ/heart/nightmare/on_death()
|
||||
if(!owner)
|
||||
return
|
||||
var/turf/T = get_turf(owner)
|
||||
if(istype(T))
|
||||
|
||||
@@ -9,9 +9,10 @@
|
||||
stamdamageoverlaytemp = 0
|
||||
update_damage_hud()
|
||||
|
||||
|
||||
if(!IsInStasis())
|
||||
if(stat != DEAD) //Reagent processing needs to come before breathing, to prevent edge cases.
|
||||
handle_organs()
|
||||
//Reagent processing needs to come before breathing, to prevent edge cases.
|
||||
handle_organs()
|
||||
|
||||
. = ..()
|
||||
|
||||
@@ -49,8 +50,22 @@
|
||||
|
||||
//Start of a breath chain, calls breathe()
|
||||
/mob/living/carbon/handle_breathing(times_fired)
|
||||
if((times_fired % 4) == 2 || failed_last_breath)
|
||||
breathe() //Breathe per 4 ticks, unless suffocating
|
||||
var/next_breath = 4
|
||||
var/obj/item/organ/lungs/L = getorganslot(ORGAN_SLOT_LUNGS)
|
||||
var/obj/item/organ/heart/H = getorganslot(ORGAN_SLOT_HEART)
|
||||
if(L)
|
||||
if(L.damage > L.high_threshold)
|
||||
next_breath--
|
||||
if(H)
|
||||
if(H.damage > H.high_threshold)
|
||||
next_breath--
|
||||
|
||||
if((times_fired % next_breath) == 0 || failed_last_breath)
|
||||
breathe() //Breathe per 4 ticks if healthy, down to 2 if our lungs or heart are damaged, unless suffocating
|
||||
if(failed_last_breath)
|
||||
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "suffocation", /datum/mood_event/suffocation)
|
||||
else
|
||||
SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "suffocation")
|
||||
else
|
||||
if(istype(loc, /obj/))
|
||||
var/obj/location_as_object = loc
|
||||
@@ -58,6 +73,7 @@
|
||||
|
||||
//Second link in a breath chain, calls check_breath()
|
||||
/mob/living/carbon/proc/breathe()
|
||||
var/obj/item/organ/lungs = getorganslot(ORGAN_SLOT_LUNGS)
|
||||
if(reagents.has_reagent("lexorin"))
|
||||
return
|
||||
if(istype(loc, /obj/machinery/atmospherics/components/unary/cryo_cell))
|
||||
@@ -76,7 +92,7 @@
|
||||
var/datum/gas_mixture/breath
|
||||
|
||||
if(!getorganslot(ORGAN_SLOT_BREATHING_TUBE))
|
||||
if(health <= HEALTH_THRESHOLD_FULLCRIT || (pulledby && pulledby.grab_state >= GRAB_KILL))
|
||||
if(health <= HEALTH_THRESHOLD_FULLCRIT || (pulledby && pulledby.grab_state >= GRAB_KILL) || lungs.organ_flags & ORGAN_FAILING)
|
||||
losebreath++ //You can't breath at all when in critical or when being choked, so you're going to miss a breath
|
||||
|
||||
else if(health <= crit_threshold)
|
||||
@@ -128,7 +144,7 @@
|
||||
if((status_flags & GODMODE))
|
||||
return
|
||||
|
||||
var/lungs = getorganslot(ORGAN_SLOT_LUNGS)
|
||||
var/obj/item/organ/lungs = getorganslot(ORGAN_SLOT_LUNGS)
|
||||
if(!lungs)
|
||||
adjustOxyLoss(2)
|
||||
|
||||
@@ -368,9 +384,18 @@
|
||||
. |= BP.on_life()
|
||||
|
||||
/mob/living/carbon/proc/handle_organs()
|
||||
for(var/V in internal_organs)
|
||||
var/obj/item/organ/O = V
|
||||
O.on_life()
|
||||
if(stat != DEAD)
|
||||
for(var/V in internal_organs)
|
||||
var/obj/item/organ/O = V
|
||||
if(O)
|
||||
O.on_life()
|
||||
else
|
||||
for(var/V in internal_organs)
|
||||
var/obj/item/organ/O = V
|
||||
if(O)
|
||||
O.on_death() //Needed so organs decay while inside the body.
|
||||
|
||||
|
||||
|
||||
/mob/living/carbon/handle_diseases()
|
||||
for(var/thing in diseases)
|
||||
@@ -615,7 +640,7 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put
|
||||
to_chat(src, "<span class='warning'>Maybe you should lie down for a bit...</span>")
|
||||
|
||||
if(drunkenness >= 91)
|
||||
adjustBrainLoss(0.4, 60)
|
||||
adjustOrganLoss(ORGAN_SLOT_BRAIN, 0.4, 60)
|
||||
if(prob(20) && !stat)
|
||||
if(SSshuttle.emergency.mode == SHUTTLE_DOCKED && is_station_level(z)) //QoL mainly
|
||||
to_chat(src, "<span class='warning'>You're so tired... but you can't miss that shuttle...</span>")
|
||||
@@ -649,8 +674,8 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put
|
||||
if((!dna && !liver) || (NOLIVER in dna.species.species_traits))
|
||||
return
|
||||
if(liver)
|
||||
if(liver.damage >= liver.maxHealth)
|
||||
liver.failing = TRUE
|
||||
if(liver.damage < liver.maxHealth)
|
||||
liver.organ_flags |= ORGAN_FAILING
|
||||
liver_failure()
|
||||
else
|
||||
liver_failure()
|
||||
@@ -689,13 +714,6 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put
|
||||
var/datum/brain_trauma/BT = T
|
||||
BT.on_life()
|
||||
|
||||
if(getBrainLoss() >= BRAIN_DAMAGE_DEATH) //rip
|
||||
to_chat(src, "<span class='userdanger'>The last spark of life in your brain fizzles out...<span>")
|
||||
death()
|
||||
var/obj/item/organ/brain/B = getorganslot(ORGAN_SLOT_BRAIN)
|
||||
if(B)
|
||||
B.damaged_brain = TRUE
|
||||
|
||||
/////////////////////////////////////
|
||||
//MONKEYS WITH TOO MUCH CHOLOESTROL//
|
||||
/////////////////////////////////////
|
||||
@@ -704,7 +722,7 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put
|
||||
if(!needs_heart())
|
||||
return FALSE
|
||||
var/obj/item/organ/heart/heart = getorganslot(ORGAN_SLOT_HEART)
|
||||
if(!heart || heart.synthetic)
|
||||
if(!heart || (heart.organ_flags & ORGAN_SYNTHETIC))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
|
||||
@@ -25,8 +25,6 @@
|
||||
adjustCloneLoss(damage * hit_percent)
|
||||
if(STAMINA)
|
||||
adjustStaminaLoss(damage * hit_percent)
|
||||
if(BRAIN)
|
||||
adjustBrainLoss(damage * hit_percent)
|
||||
return 1
|
||||
|
||||
/mob/living/proc/apply_damage_type(damage = 0, damagetype = BRUTE) //like apply damage except it always uses the damage procs
|
||||
@@ -43,8 +41,6 @@
|
||||
return adjustCloneLoss(damage)
|
||||
if(STAMINA)
|
||||
return adjustStaminaLoss(damage)
|
||||
if(BRAIN)
|
||||
return adjustBrainLoss(damage)
|
||||
|
||||
/mob/living/proc/get_damage_amount(damagetype = BRUTE)
|
||||
switch(damagetype)
|
||||
@@ -60,9 +56,6 @@
|
||||
return getCloneLoss()
|
||||
if(STAMINA)
|
||||
return getStaminaLoss()
|
||||
if(BRAIN)
|
||||
return getBrainLoss()
|
||||
|
||||
|
||||
/mob/living/proc/apply_damages(brute = 0, burn = 0, tox = 0, oxy = 0, clone = 0, def_zone = null, blocked = FALSE, stamina = 0, brain = 0)
|
||||
if(blocked >= 100)
|
||||
@@ -218,13 +211,13 @@
|
||||
updatehealth()
|
||||
return amount
|
||||
|
||||
/mob/living/proc/getBrainLoss()
|
||||
. = 0
|
||||
|
||||
/mob/living/proc/adjustBrainLoss(amount, maximum = BRAIN_DAMAGE_DEATH)
|
||||
/mob/living/proc/adjustOrganLoss(slot, amount, maximum)
|
||||
return
|
||||
|
||||
/mob/living/proc/setBrainLoss(amount)
|
||||
/mob/living/proc/setOrganLoss(slot, amount, maximum)
|
||||
return
|
||||
|
||||
/mob/living/proc/getOrganLoss(slot)
|
||||
return
|
||||
|
||||
/mob/living/proc/getStaminaLoss()
|
||||
|
||||
@@ -255,7 +255,7 @@
|
||||
H.Knockdown(20)
|
||||
else
|
||||
message_param = "<span class='userdanger'>bumps [user.p_their()] head on the ground</span> trying to motion towards %t."
|
||||
H.adjustBrainLoss(5)
|
||||
H.adjustOrganLoss(ORGAN_SLOT_BRAIN, 5)
|
||||
..()
|
||||
|
||||
/datum/emote/living/pout
|
||||
|
||||
@@ -473,7 +473,6 @@
|
||||
setToxLoss(0, 0) //zero as second argument not automatically call updatehealth().
|
||||
setOxyLoss(0, 0)
|
||||
setCloneLoss(0, 0)
|
||||
setBrainLoss(0)
|
||||
setStaminaLoss(0, 0)
|
||||
SetUnconscious(0, FALSE)
|
||||
set_disgust(0)
|
||||
@@ -500,6 +499,13 @@
|
||||
QDEL_LIST_ASSOC_VAL(mood.mood_events)
|
||||
mood.sanity = SANITY_GREAT
|
||||
mood.update_mood()
|
||||
//Heal all organs
|
||||
if(iscarbon(src))
|
||||
var/mob/living/carbon/C = src
|
||||
if(C.internal_organs)
|
||||
for(var/organ in C.internal_organs)
|
||||
var/obj/item/organ/O = organ
|
||||
O.setOrganDamage(0)
|
||||
|
||||
|
||||
//proc called by revive(), to check if we can actually ressuscitate the mob (we don't want to revive him and have him instantly die again)
|
||||
|
||||
@@ -35,8 +35,8 @@
|
||||
/mob/living/silicon/setStaminaLoss(amount, updating_stamina = 1)
|
||||
return FALSE
|
||||
|
||||
/mob/living/silicon/adjustBrainLoss(amount)
|
||||
/mob/living/silicon/adjustOrganLoss(slot, amount, maximum = 500)
|
||||
return FALSE
|
||||
|
||||
/mob/living/silicon/setBrainLoss(amount)
|
||||
/mob/living/silicon/setOrganLoss(slot, amount)
|
||||
return FALSE
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
/mob/living/silicon/pai/adjustStaminaLoss(amount)
|
||||
take_holo_damage(amount & 0.25)
|
||||
|
||||
/mob/living/silicon/pai/adjustBrainLoss(amount)
|
||||
/mob/living/silicon/pai/adjustOrganLoss(slot, amount, maximum = 500) //I kept this in, unlike tg
|
||||
Knockdown(amount * 0.2)
|
||||
|
||||
/mob/living/silicon/pai/getBruteLoss()
|
||||
@@ -102,18 +102,12 @@
|
||||
/mob/living/silicon/pai/getCloneLoss()
|
||||
return FALSE
|
||||
|
||||
/mob/living/silicon/pai/getBrainLoss()
|
||||
return FALSE
|
||||
|
||||
/mob/living/silicon/pai/getStaminaLoss()
|
||||
return FALSE
|
||||
|
||||
/mob/living/silicon/pai/setCloneLoss()
|
||||
return FALSE
|
||||
|
||||
/mob/living/silicon/pai/setBrainLoss()
|
||||
return FALSE
|
||||
|
||||
/mob/living/silicon/pai/setStaminaLoss()
|
||||
return FALSE
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
.=..()
|
||||
if ((from.pH > 12.5) || (from.pH < 1.5))
|
||||
to_chat(src, "<span class='warning'>You taste chemical burns!</span>")
|
||||
T.adjustTongueLoss(src, 4)
|
||||
T.applyOrganDamage(5)
|
||||
if(istype(T, /obj/item/organ/tongue/cybernetic))
|
||||
to_chat(src, "<span class='notice'>Your tongue moves on it's own in response to the liquid.</span>")
|
||||
say("The pH is appropriately [round(from.pH, 1)].")
|
||||
@@ -52,13 +52,13 @@
|
||||
switch(from.pH)
|
||||
if(11.5 to INFINITY)
|
||||
to_chat(src, "<span class='warning'>You taste a strong alkaline flavour!</span>")
|
||||
T.adjustTongueLoss(src, 1)
|
||||
T.applyOrganDamage(1)
|
||||
if(8.5 to 11.5)
|
||||
to_chat(src, "<span class='notice'>You taste a sort of soapy tone in the mixture.</span>")
|
||||
if(2.5 to 5.5)
|
||||
to_chat(src, "<span class='notice'>You taste a sort of acid tone in the mixture.</span>")
|
||||
if(-INFINITY to 2.5)
|
||||
to_chat(src, "<span class='warning'>You taste a strong acidic flavour!</span>")
|
||||
T.adjustTongueLoss(src, 1)
|
||||
T.applyOrganDamage(1)
|
||||
|
||||
#undef DEFAULT_TASTE_SENSITIVITY
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
O.setOxyLoss(getOxyLoss(), 0)
|
||||
O.setCloneLoss(getCloneLoss(), 0)
|
||||
O.adjustFireLoss(getFireLoss(), 0)
|
||||
O.setBrainLoss(getBrainLoss(), 0)
|
||||
O.setOrganLoss(ORGAN_SLOT_BRAIN, getOrganLoss(ORGAN_SLOT_BRAIN), 0)
|
||||
O.adjustStaminaLoss(getStaminaLoss(), 0)//CIT CHANGE - makes monkey transformations inherit stamina
|
||||
O.updatehealth()
|
||||
O.radiation = radiation
|
||||
@@ -236,7 +236,7 @@
|
||||
O.setOxyLoss(getOxyLoss(), 0)
|
||||
O.setCloneLoss(getCloneLoss(), 0)
|
||||
O.adjustFireLoss(getFireLoss(), 0)
|
||||
O.setBrainLoss(getBrainLoss(), 0)
|
||||
O.setOrganLoss(ORGAN_SLOT_BRAIN, getOrganLoss(ORGAN_SLOT_BRAIN), 0)
|
||||
O.adjustStaminaLoss(getStaminaLoss(), 0)//CIT CHANGE - makes monkey transformations inherit stamina
|
||||
O.updatehealth()
|
||||
O.radiation = radiation
|
||||
|
||||
@@ -5,5 +5,5 @@
|
||||
. = ..()
|
||||
if(ishuman(target))
|
||||
var/mob/living/carbon/human/M = target
|
||||
M.adjustBrainLoss(20)
|
||||
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 20)
|
||||
M.hallucination += 30
|
||||
|
||||
@@ -550,6 +550,10 @@
|
||||
if (multiplier == 0)
|
||||
fermiEnd()
|
||||
return
|
||||
for(var/P in C.required_catalysts)
|
||||
if(!has_reagent(P))
|
||||
fermiEnd()
|
||||
return
|
||||
for(var/P in cached_results)
|
||||
targetVol = cached_results[P]*multiplier
|
||||
|
||||
@@ -676,7 +680,7 @@
|
||||
STOP_PROCESSING(SSprocessing, src)
|
||||
return 0
|
||||
|
||||
C.FermiCreate(src)//proc that calls when step is done
|
||||
C.FermiCreate(src, addChemAmmount, purity)//proc that calls when step is done
|
||||
|
||||
//Apply pH changes and thermal output of reaction to beaker
|
||||
chem_temp = round(cached_temp + (C.ThermicConstant * addChemAmmount))
|
||||
|
||||
@@ -1373,6 +1373,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
|
||||
|
||||
/datum/reagent/consumable/ethanol/neurotoxin
|
||||
name = "Neurotoxin"
|
||||
id = "neurotoxin"
|
||||
description = "A strong neurotoxin that puts the subject into a death-like state."
|
||||
color = "#2E2E61" // rgb: 46, 46, 97
|
||||
boozepwr = 50
|
||||
@@ -1382,6 +1383,10 @@ All effects don't start immediately, but rather get worse over time; the rate is
|
||||
glass_icon_state = "neurotoxinglass"
|
||||
glass_name = "Neurotoxin"
|
||||
glass_desc = "A drink that is guaranteed to knock you silly."
|
||||
//SplitChem = TRUE
|
||||
impure_chem = "neuroweak"
|
||||
inverse_chem_val = 0.5 //Clear conversion
|
||||
inverse_chem = "neuroweak"
|
||||
|
||||
/datum/reagent/consumable/ethanol/neurotoxin/proc/pickt()
|
||||
return (pick(TRAIT_PARALYSIS_L_ARM,TRAIT_PARALYSIS_R_ARM,TRAIT_PARALYSIS_R_LEG,TRAIT_PARALYSIS_L_LEG))
|
||||
@@ -1389,18 +1394,18 @@ All effects don't start immediately, but rather get worse over time; the rate is
|
||||
/datum/reagent/consumable/ethanol/neurotoxin/on_mob_life(mob/living/carbon/M)
|
||||
M.set_drugginess(50)
|
||||
M.dizziness +=2
|
||||
M.adjustBrainLoss(1*REM, 150)
|
||||
if(prob(20))
|
||||
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 1*REM, 150)
|
||||
if(prob(20) && !holder.has_reagent("neuroweak"))
|
||||
M.adjustStaminaLoss(10)
|
||||
M.drop_all_held_items()
|
||||
to_chat(M, "<span class='notice'>You cant feel your hands!</span>")
|
||||
if(current_cycle > 5)
|
||||
if(prob(20))
|
||||
if(prob(20) && !holder.has_reagent("neuroweak"))
|
||||
var/t = pickt()
|
||||
ADD_TRAIT(M, t, type)
|
||||
M.adjustStaminaLoss(10)
|
||||
if(current_cycle > 30)
|
||||
M.adjustBrainLoss(2*REM)
|
||||
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 2*REM)
|
||||
if(current_cycle > 50 && prob(15))
|
||||
if(!M.undergoing_cardiac_arrest() && M.can_heartattack())
|
||||
M.set_heartattack(TRUE)
|
||||
@@ -1417,6 +1422,25 @@ All effects don't start immediately, but rather get worse over time; the rate is
|
||||
M.adjustStaminaLoss(10)
|
||||
..()
|
||||
|
||||
/datum/reagent/consumable/ethanol/neuroweak
|
||||
name = "Neuro-Smash"
|
||||
id = "neuroweak"
|
||||
description = "A mostly safe alcoholic drink for the true daredevils. Counteracts Neurotoxins."
|
||||
boozepwr = 60
|
||||
pH = 8
|
||||
|
||||
/datum/reagent/consumable/ethanol/neuroweak/on_mob_life(mob/living/carbon/M)
|
||||
if(holder.has_reagent("neurotoxin"))
|
||||
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, -1*REM, 150)
|
||||
M.reagents.remove_reagent("neurotoxin", 1.5 * REAGENTS_METABOLISM, FALSE)
|
||||
if(holder.has_reagent("fentanyl"))
|
||||
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, -1*REM, 150)
|
||||
M.reagents.remove_reagent("fentanyl", 0.75 * REAGENTS_METABOLISM, FALSE)
|
||||
else
|
||||
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, -0.5*REM, 150)
|
||||
M.dizziness +=2
|
||||
..()
|
||||
|
||||
/datum/reagent/consumable/ethanol/hippies_delight
|
||||
name = "Hippie's Delight"
|
||||
id = "hippiesdelight"
|
||||
@@ -2122,6 +2146,29 @@ All effects don't start immediately, but rather get worse over time; the rate is
|
||||
glass_name = "Planet Cracker"
|
||||
glass_desc = "Although historians believe the drink was originally created to commemorate the end of an important conflict in man's past, its origins have largely been forgotten and it is today seen more as a general symbol of human supremacy."
|
||||
|
||||
/datum/reagent/consumable/ethanol/commander_and_chief
|
||||
name = "Commander and Chief"
|
||||
id = "commander_and_chief"
|
||||
description = "A cocktail for the captain on the go."
|
||||
color = "#ffffc9"
|
||||
boozepwr = 50
|
||||
quality = DRINK_FANTASTIC
|
||||
taste_description = "Tastes like...duty and responsibility?"
|
||||
glass_icon_state = "commander_and_chief"
|
||||
glass_name = "Commander and Chief"
|
||||
glass_desc = "The gems of this majestic chalice represent the departments and their Heads."
|
||||
|
||||
/datum/reagent/consumable/ethanol/commander_and_chief/on_mob_life(mob/living/carbon/M)
|
||||
if(M.mind && HAS_TRAIT(M.mind, TRAIT_CAPTAIN_METABOLISM))
|
||||
M.heal_bodypart_damage(2,2,2)
|
||||
M.adjustBruteLoss(-3.5,0)
|
||||
M.adjustOxyLoss(-3.5,0)
|
||||
M.adjustFireLoss(-3.5,0)
|
||||
M.adjustToxLoss(-3.5,0)
|
||||
M.radiation = max(M.radiation - 25, 0)
|
||||
. = 1
|
||||
return ..()
|
||||
|
||||
/datum/reagent/consumable/ethanol/fruit_wine
|
||||
name = "Fruit Wine"
|
||||
id = "fruit_wine"
|
||||
|
||||
@@ -80,14 +80,14 @@
|
||||
. = 1
|
||||
|
||||
/datum/reagent/drug/crank/overdose_process(mob/living/M)
|
||||
M.adjustBrainLoss(2*REM)
|
||||
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 2*REM)
|
||||
M.adjustToxLoss(2*REM, 0)
|
||||
M.adjustBruteLoss(2*REM, 0)
|
||||
..()
|
||||
. = 1
|
||||
|
||||
/datum/reagent/drug/crank/addiction_act_stage1(mob/living/M)
|
||||
M.adjustBrainLoss(5*REM)
|
||||
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 5*REM)
|
||||
..()
|
||||
|
||||
/datum/reagent/drug/crank/addiction_act_stage2(mob/living/M)
|
||||
@@ -101,7 +101,7 @@
|
||||
. = 1
|
||||
|
||||
/datum/reagent/drug/crank/addiction_act_stage4(mob/living/M)
|
||||
M.adjustBrainLoss(3*REM)
|
||||
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 3*REM)
|
||||
M.adjustToxLoss(5*REM, 0)
|
||||
M.adjustBruteLoss(5*REM, 0)
|
||||
..()
|
||||
@@ -125,13 +125,13 @@
|
||||
..()
|
||||
|
||||
/datum/reagent/drug/krokodil/overdose_process(mob/living/M)
|
||||
M.adjustBrainLoss(0.25*REM)
|
||||
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 0.25*REM)
|
||||
M.adjustToxLoss(0.25*REM, 0)
|
||||
..()
|
||||
. = 1
|
||||
|
||||
/datum/reagent/drug/krokodil/addiction_act_stage1(mob/living/M)
|
||||
M.adjustBrainLoss(2*REM)
|
||||
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 2*REM)
|
||||
M.adjustToxLoss(2*REM, 0)
|
||||
..()
|
||||
. = 1
|
||||
@@ -192,7 +192,7 @@
|
||||
if(jitter)
|
||||
M.Jitter(2)
|
||||
if(brain_damage)
|
||||
M.adjustBrainLoss(rand(1,4))
|
||||
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, rand(1,4))
|
||||
M.heal_overall_damage(2, 2)
|
||||
if(prob(5))
|
||||
M.emote(pick("twitch", "shiver"))
|
||||
@@ -210,7 +210,7 @@
|
||||
M.drop_all_held_items()
|
||||
..()
|
||||
M.adjustToxLoss(1, 0)
|
||||
M.adjustBrainLoss(pick(0.5, 0.6, 0.7, 0.8, 0.9, 1))
|
||||
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, pick(0.5, 0.6, 0.7, 0.8, 0.9, 1))
|
||||
. = 1
|
||||
|
||||
/datum/reagent/drug/methamphetamine/addiction_act_stage1(mob/living/M)
|
||||
@@ -289,7 +289,7 @@
|
||||
if(prob(5))
|
||||
to_chat(M, "<span class='notice'>[high_message]</span>")
|
||||
M.adjustStaminaLoss(-5, 0)
|
||||
M.adjustBrainLoss(4)
|
||||
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 4)
|
||||
M.hallucination += 5
|
||||
if(M.canmove && !ismovableatom(M.loc))
|
||||
step(M, pick(GLOB.cardinals))
|
||||
@@ -314,7 +314,7 @@
|
||||
for(var/i = 0, i < 8, i++)
|
||||
step(M, pick(GLOB.cardinals))
|
||||
M.Jitter(5)
|
||||
M.adjustBrainLoss(10)
|
||||
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 10)
|
||||
if(prob(20))
|
||||
M.emote(pick("twitch","drool","moan"))
|
||||
..()
|
||||
@@ -326,7 +326,7 @@
|
||||
step(M, pick(GLOB.cardinals))
|
||||
M.Jitter(10)
|
||||
M.Dizzy(10)
|
||||
M.adjustBrainLoss(10)
|
||||
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 10)
|
||||
if(prob(30))
|
||||
M.emote(pick("twitch","drool","moan"))
|
||||
..()
|
||||
@@ -338,7 +338,7 @@
|
||||
step(M, pick(GLOB.cardinals))
|
||||
M.Jitter(15)
|
||||
M.Dizzy(15)
|
||||
M.adjustBrainLoss(10)
|
||||
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 10)
|
||||
if(prob(40))
|
||||
M.emote(pick("twitch","drool","moan"))
|
||||
..()
|
||||
@@ -351,7 +351,7 @@
|
||||
M.Jitter(50)
|
||||
M.Dizzy(50)
|
||||
M.adjustToxLoss(5, 0)
|
||||
M.adjustBrainLoss(10)
|
||||
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 10)
|
||||
if(prob(50))
|
||||
M.emote(pick("twitch","drool","moan"))
|
||||
..()
|
||||
@@ -401,7 +401,7 @@
|
||||
M.jitteriness = 0
|
||||
M.confused = 0
|
||||
M.disgust = 0
|
||||
M.adjustBrainLoss(0.2)
|
||||
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 0.2)
|
||||
..()
|
||||
. = 1
|
||||
|
||||
@@ -418,7 +418,7 @@
|
||||
if(3)
|
||||
M.emote("frown")
|
||||
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "happiness_drug", /datum/mood_event/happiness_drug_bad_od)
|
||||
M.adjustBrainLoss(0.5)
|
||||
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 0.5)
|
||||
..()
|
||||
. = 1
|
||||
|
||||
@@ -490,7 +490,7 @@
|
||||
H.dna.species.punchdamagehigh *= 0.2
|
||||
|
||||
/datum/reagent/drug/skooma/on_mob_life(mob/living/carbon/M)
|
||||
M.adjustBrainLoss(1*REM)
|
||||
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 1*REM)
|
||||
M.adjustToxLoss(1*REM)
|
||||
if(prob(10))
|
||||
M.adjust_blurriness(2)
|
||||
@@ -522,7 +522,7 @@
|
||||
M.Dizzy(50)
|
||||
M.adjust_blurriness(10)
|
||||
if(prob(50)) //This proc will be called about 200 times and the adjustbrainloss() below only has to be called 40 times to kill. This will make surviving skooma addiction pretty rare without mannitol usage.
|
||||
M.adjustBrainLoss(5)
|
||||
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 5)
|
||||
if(prob(40))
|
||||
M.emote(pick("twitch","drool","moan"))
|
||||
..()
|
||||
|
||||
@@ -684,7 +684,7 @@
|
||||
. = 1
|
||||
if(prob(20))
|
||||
M.losebreath += 4
|
||||
M.adjustBrainLoss(2*REM, 150)
|
||||
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 2*REM, 150)
|
||||
M.adjustToxLoss(3*REM,0)
|
||||
M.adjustStaminaLoss(10*REM,0)
|
||||
M.blur_eyes(5)
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
M.heal_bodypart_damage(5,5)
|
||||
M.adjustToxLoss(-5, 0, TRUE)
|
||||
M.hallucination = 0
|
||||
M.setBrainLoss(0)
|
||||
M.setOrganLoss(ORGAN_SLOT_BRAIN, 0)
|
||||
REMOVE_TRAITS_NOT_IN(M, list(SPECIES_TRAIT, ROUNDSTART_TRAIT, ORGAN_TRAIT))
|
||||
M.set_blurriness(0)
|
||||
M.set_blindness(0)
|
||||
@@ -64,6 +64,10 @@
|
||||
if(M.blood_volume < (BLOOD_VOLUME_NORMAL*M.blood_ratio))
|
||||
M.blood_volume = (BLOOD_VOLUME_NORMAL*M.blood_ratio)
|
||||
|
||||
for(var/organ in M.internal_organs)
|
||||
var/obj/item/organ/O = organ
|
||||
O.setOrganDamage(0)
|
||||
|
||||
for(var/thing in M.diseases)
|
||||
var/datum/disease/D = thing
|
||||
if(D.severity == DISEASE_SEVERITY_POSITIVE)
|
||||
@@ -852,10 +856,16 @@
|
||||
if(M.notify_ghost_cloning(source = M))
|
||||
spawn (100) //so the ghost has time to re-enter
|
||||
return
|
||||
|
||||
else
|
||||
M.adjustOxyLoss(-20, 0)
|
||||
M.adjustToxLoss(-20, 0)
|
||||
var/mob/living/carbon/H = M
|
||||
for(var/organ in H.internal_organs)
|
||||
var/obj/item/organ/O = organ
|
||||
O.setOrganDamage(0)
|
||||
M.updatehealth()
|
||||
|
||||
if(M.revive())
|
||||
M.emote("gasp")
|
||||
log_combat(M, M, "revived", src)
|
||||
@@ -875,7 +885,7 @@
|
||||
pH = 10.4
|
||||
|
||||
/datum/reagent/medicine/mannitol/on_mob_life(mob/living/carbon/C)
|
||||
C.adjustBrainLoss(-2*REM)
|
||||
C.adjustOrganLoss(ORGAN_SLOT_BRAIN, -2*REM)
|
||||
if(prob(10))
|
||||
C.cure_trauma_type(resilience = TRAUMA_RESILIENCE_BASIC)
|
||||
..()
|
||||
@@ -1130,7 +1140,7 @@
|
||||
M.adjustFireLoss(-5*REM, 0)
|
||||
M.adjustOxyLoss(-15, 0)
|
||||
M.adjustToxLoss(-5*REM, 0)
|
||||
M.adjustBrainLoss(-15*REM)
|
||||
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, -15*REM)
|
||||
M.adjustCloneLoss(-3*REM, 0)
|
||||
M.adjustStaminaLoss(-20*REM,0)
|
||||
..()
|
||||
@@ -1175,9 +1185,9 @@
|
||||
M.adjustFireLoss(-3 * REM, 0)
|
||||
M.adjustOxyLoss(-15 * REM, 0)
|
||||
M.adjustToxLoss(-3 * REM, 0, TRUE) //Heals TOXINLOVERS
|
||||
M.adjustBrainLoss(2 * REM, 150) //This does, after all, come from ambrosia, and the most powerful ambrosia in existence, at that!
|
||||
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 2 * REM, 150) //This does, after all, come from ambrosia, and the most powerful ambrosia in existence, at that!
|
||||
M.adjustCloneLoss(-1 * REM, 0)
|
||||
M.adjustStaminaLoss(-30 * REM, 0)
|
||||
M.adjustStaminaLoss(-13 * REM, 0)
|
||||
M.jitteriness = min(max(0, M.jitteriness + 3), 30)
|
||||
M.druggy = min(max(0, M.druggy + 10), 15) //See above
|
||||
..()
|
||||
@@ -1207,7 +1217,7 @@
|
||||
if (M.hallucination >= 5)
|
||||
M.hallucination -= 5
|
||||
if(prob(20))
|
||||
M.adjustBrainLoss(1*REM, 50)
|
||||
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 1*REM, 50)
|
||||
M.adjustStaminaLoss(2.5*REM, 0)
|
||||
..()
|
||||
return TRUE
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
name = "Blood"
|
||||
id = "blood"
|
||||
color = "#C80000" // rgb: 200, 0, 0
|
||||
description = "Blood from a human, or otherwise."
|
||||
metabolization_rate = 5 //fast rate so it disappears fast.
|
||||
taste_description = "iron"
|
||||
taste_mult = 1.3
|
||||
@@ -200,22 +201,20 @@
|
||||
pH = 7.5 //God is alkaline
|
||||
|
||||
/datum/reagent/water/holywater/on_mob_metabolize(mob/living/L)
|
||||
..()
|
||||
. = ..()
|
||||
ADD_TRAIT(L, TRAIT_HOLY, id)
|
||||
|
||||
if(is_servant_of_ratvar(L))
|
||||
to_chat(L, "<span class='userdanger'>A fog spreads through your mind, purging the Justiciar's influence!</span>")
|
||||
else if(iscultist(L))
|
||||
to_chat(L, "<span class='userdanger'>A fog spreads through your mind, weakening your connection to the veil and purging Nar-sie's influence</span>")
|
||||
|
||||
/datum/reagent/water/holywater/on_mob_end_metabolize(mob/living/L)
|
||||
REMOVE_TRAIT(L, TRAIT_HOLY, id)
|
||||
..()
|
||||
|
||||
/datum/reagent/water/holywater/reaction_mob(mob/living/M, method=TOUCH, reac_volume)
|
||||
if(is_servant_of_ratvar(M))
|
||||
to_chat(M, "<span class='userdanger'>A fog spreads through your mind, purging the Justiciar's influence!</span>")
|
||||
..()
|
||||
|
||||
/datum/reagent/water/holywater/reaction_mob(mob/living/M, method=TOUCH, reac_volume)
|
||||
if(iscultist(M))
|
||||
to_chat(M, "<span class='userdanger'>A fog spreads through your mind, weakening your connection to the veil and purging Nar-sie's influence</span>")
|
||||
..()
|
||||
if(iscultist(L))
|
||||
for(var/datum/action/innate/cult/blood_magic/BM in L.actions)
|
||||
BM.holy_dispel = FALSE
|
||||
return ..()
|
||||
|
||||
/datum/reagent/water/holywater/on_mob_life(mob/living/carbon/M)
|
||||
if(!data)
|
||||
@@ -224,9 +223,11 @@
|
||||
M.jitteriness = min(M.jitteriness+4,10)
|
||||
if(iscultist(M))
|
||||
for(var/datum/action/innate/cult/blood_magic/BM in M.actions)
|
||||
to_chat(M, "<span class='cultlarge'>Your blood rites falter as holy water scours your body!</span>")
|
||||
for(var/datum/action/innate/cult/blood_spell/BS in BM.spells)
|
||||
qdel(BS)
|
||||
if(!BM.holy_dispel)
|
||||
BM.holy_dispel = TRUE
|
||||
to_chat(M, "<span class='cultlarge'>Your blood rites falter as holy water scours your body!</span>")
|
||||
for(var/datum/action/innate/cult/blood_spell/BS in BM.spells)
|
||||
qdel(BS)
|
||||
if(data >= 25) // 10 units, 45 seconds @ metabolism 0.4 units & tick rate 1.8 sec
|
||||
if(!M.stuttering)
|
||||
M.stuttering = 1
|
||||
@@ -296,7 +297,7 @@
|
||||
if(ishuman(M) && M.blood_volume < (BLOOD_VOLUME_NORMAL*M.blood_ratio))
|
||||
M.blood_volume += 3
|
||||
else // Will deal about 90 damage when 50 units are thrown
|
||||
M.adjustBrainLoss(3, 150)
|
||||
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 3, 150)
|
||||
M.adjustToxLoss(2, 0)
|
||||
M.adjustFireLoss(2, 0)
|
||||
M.adjustOxyLoss(2, 0)
|
||||
@@ -315,7 +316,7 @@
|
||||
M.IgniteMob() //Only problem with igniting people is currently the commonly availible fire suits make you immune to being on fire
|
||||
M.adjustToxLoss(1, 0)
|
||||
M.adjustFireLoss(1, 0) //Hence the other damages... ain't I a bastard?
|
||||
M.adjustBrainLoss(5, 150)
|
||||
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 5, 150)
|
||||
holder.remove_reagent(id, 1)
|
||||
pH = 0.1
|
||||
|
||||
@@ -536,12 +537,12 @@
|
||||
race = /datum/species/fly
|
||||
mutationtext = "<span class='danger'>The pain subsides. You feel... buzzy.</span>"
|
||||
|
||||
/datum/reagent/mutationtoxin/moth
|
||||
name = "Moth Mutation Toxin"
|
||||
/datum/reagent/mutationtoxin/insect
|
||||
name = "Insect Mutation Toxin"
|
||||
id = "mothmutationtoxin"
|
||||
description = "A glowing toxin."
|
||||
color = "#5EFF3B" //RGB: 94, 255, 59
|
||||
race = /datum/species/moth
|
||||
race = /datum/species/insect
|
||||
mutationtext = "<span class='danger'>The pain subsides. You feel... attracted to light.</span>"
|
||||
|
||||
/datum/reagent/mutationtoxin/pod
|
||||
@@ -805,7 +806,7 @@
|
||||
step(M, pick(GLOB.cardinals))
|
||||
if(prob(5))
|
||||
M.emote(pick("twitch","drool","moan"))
|
||||
M.adjustBrainLoss(1)
|
||||
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 1)
|
||||
..()
|
||||
|
||||
/datum/reagent/sulfur
|
||||
@@ -1172,7 +1173,7 @@
|
||||
/datum/reagent/impedrezene/on_mob_life(mob/living/carbon/M)
|
||||
M.jitteriness = max(M.jitteriness-5,0)
|
||||
if(prob(80))
|
||||
M.adjustBrainLoss(2*REM)
|
||||
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 2*REM)
|
||||
if(prob(50))
|
||||
M.drowsyness = max(M.drowsyness, 3)
|
||||
if(prob(10))
|
||||
@@ -1222,7 +1223,7 @@
|
||||
description = "A perfluoronated sulfonic acid that forms a foam when mixed with water."
|
||||
color = "#9E6B38" // rgb: 158, 107, 56
|
||||
taste_description = "metal"
|
||||
pH = 13
|
||||
pH = 11
|
||||
|
||||
/datum/reagent/foaming_agent// Metal foaming agent. This is lithium hydride. Add other recipes (e.g. LiH + H2O -> LiOH + H2) eventually.
|
||||
name = "Foaming agent"
|
||||
@@ -1231,7 +1232,7 @@
|
||||
reagent_state = SOLID
|
||||
color = "#664B63" // rgb: 102, 75, 99
|
||||
taste_description = "metal"
|
||||
pH = 12.5
|
||||
pH = 11.5
|
||||
|
||||
/datum/reagent/smart_foaming_agent //Smart foaming agent. Functions similarly to metal foam, but conforms to walls.
|
||||
name = "Smart foaming agent"
|
||||
@@ -1445,9 +1446,6 @@
|
||||
color = "#FFFFFF" // white
|
||||
random_color_list = list("#FFFFFF") //doesn't actually change appearance at all
|
||||
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////Hydroponics stuff///////////////////////////////
|
||||
|
||||
/datum/reagent/plantnutriment
|
||||
@@ -1489,16 +1487,8 @@
|
||||
tox_prob = 15
|
||||
pH = 1
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// GOON OTHERS
|
||||
|
||||
|
||||
|
||||
/datum/reagent/oil
|
||||
name = "Oil"
|
||||
id = "oil"
|
||||
@@ -1530,20 +1520,6 @@
|
||||
taste_description = "metal"
|
||||
pH = 4.5
|
||||
|
||||
/datum/reagent/carpet
|
||||
name = "Carpet"
|
||||
id = "carpet"
|
||||
description = "For those that need a more creative way to roll out a red carpet."
|
||||
reagent_state = LIQUID
|
||||
color = "#b51d05"
|
||||
taste_description = "carpet" // Your tounge feels furry.
|
||||
|
||||
/datum/reagent/carpet/reaction_turf(turf/T, reac_volume)
|
||||
if(isplatingturf(T) || istype(T, /turf/open/floor/plasteel))
|
||||
var/turf/open/floor/F = T
|
||||
F.PlaceOnTop(/turf/open/floor/carpet)
|
||||
..()
|
||||
|
||||
/datum/reagent/bromine
|
||||
name = "Bromine"
|
||||
id = "bromine"
|
||||
@@ -1676,7 +1652,7 @@
|
||||
reagent_state = LIQUID
|
||||
color = "#FFFFD6" // very very light yellow
|
||||
taste_description = "alkali" //who put ACID for NaOH ????
|
||||
pH = 13
|
||||
pH = 11.9
|
||||
|
||||
/datum/reagent/drying_agent
|
||||
name = "Drying agent"
|
||||
@@ -1697,6 +1673,143 @@
|
||||
qdel(O)
|
||||
new /obj/item/clothing/shoes/galoshes/dry(t_loc)
|
||||
|
||||
// Liquid Carpets
|
||||
/datum/reagent/carpet
|
||||
name = "Liquid Carpet"
|
||||
id = "carpet"
|
||||
description = "For those that need a more creative way to roll out a carpet."
|
||||
reagent_state = LIQUID
|
||||
color = "#b51d05"
|
||||
taste_description = "carpet" // Your tounge feels furry.
|
||||
|
||||
/datum/reagent/carpet/reaction_turf(turf/T, reac_volume)
|
||||
if(isplatingturf(T) || istype(T, /turf/open/floor/plasteel))
|
||||
var/turf/open/floor/F = T
|
||||
F.PlaceOnTop(/turf/open/floor/carpet)
|
||||
..()
|
||||
|
||||
/datum/reagent/carpet/black
|
||||
name = "Liquid Black Carpet"
|
||||
id = "blackcarpet"
|
||||
color = "#363636"
|
||||
|
||||
/datum/reagent/carpet/black/reaction_turf(turf/T, reac_volume)
|
||||
if(isplatingturf(T) || istype(T, /turf/open/floor/plasteel))
|
||||
var/turf/open/floor/F = T
|
||||
F.PlaceOnTop(/turf/open/floor/carpet/black)
|
||||
..()
|
||||
|
||||
/datum/reagent/carpet/blackred
|
||||
name = "Liquid Red Black Carpet"
|
||||
id = "blackredcarpet"
|
||||
color = "#342125"
|
||||
|
||||
/datum/reagent/carpet/blackred/reaction_turf(turf/T, reac_volume)
|
||||
if(isplatingturf(T) || istype(T, /turf/open/floor/plasteel))
|
||||
var/turf/open/floor/F = T
|
||||
F.PlaceOnTop(/turf/open/floor/carpet/blackred)
|
||||
..()
|
||||
|
||||
/datum/reagent/carpet/monochrome
|
||||
name = "Liquid Monochrome Carpet"
|
||||
id = "monochromecarpet"
|
||||
color = "#b4b4b4"
|
||||
|
||||
/datum/reagent/carpet/monochrome/reaction_turf(turf/T, reac_volume)
|
||||
if(isplatingturf(T) || istype(T, /turf/open/floor/plasteel))
|
||||
var/turf/open/floor/F = T
|
||||
F.PlaceOnTop(/turf/open/floor/carpet/monochrome)
|
||||
..()
|
||||
|
||||
/datum/reagent/carpet/blue
|
||||
name = "Liquid Blue Carpet"
|
||||
id = "bluecarpet"
|
||||
color = "#1256ff"
|
||||
|
||||
/datum/reagent/carpet/blue/reaction_turf(turf/T, reac_volume)
|
||||
if(isplatingturf(T) || istype(T, /turf/open/floor/plasteel))
|
||||
var/turf/open/floor/F = T
|
||||
F.PlaceOnTop(/turf/open/floor/carpet/blue)
|
||||
..()
|
||||
|
||||
/datum/reagent/carpet/cyan
|
||||
name = "Liquid Cyan Carpet"
|
||||
id = "cyancarpet"
|
||||
color = "#3acfb9"
|
||||
|
||||
/datum/reagent/carpet/cyan/reaction_turf(turf/T, reac_volume)
|
||||
if(isplatingturf(T) || istype(T, /turf/open/floor/plasteel))
|
||||
var/turf/open/floor/F = T
|
||||
F.PlaceOnTop(/turf/open/floor/carpet/cyan)
|
||||
..()
|
||||
|
||||
/datum/reagent/carpet/green
|
||||
name = "Liquid Green Carpet"
|
||||
id = "greencarpet"
|
||||
color = "#619b62"
|
||||
|
||||
/datum/reagent/carpet/green/reaction_turf(turf/T, reac_volume)
|
||||
if(isplatingturf(T) || istype(T, /turf/open/floor/plasteel))
|
||||
var/turf/open/floor/F = T
|
||||
F.PlaceOnTop(/turf/open/floor/carpet/green)
|
||||
..()
|
||||
|
||||
/datum/reagent/carpet/orange
|
||||
name = "Liquid Orange Carpet"
|
||||
id = "orangecarpet"
|
||||
color = "#cc7900"
|
||||
|
||||
/datum/reagent/carpet/orange/reaction_turf(turf/T, reac_volume)
|
||||
if(isplatingturf(T) || istype(T, /turf/open/floor/plasteel))
|
||||
var/turf/open/floor/F = T
|
||||
F.PlaceOnTop(/turf/open/floor/carpet/orange)
|
||||
..()
|
||||
|
||||
/datum/reagent/carpet/purple
|
||||
name = "Liquid Purple Carpet"
|
||||
id = "purplecarpet"
|
||||
color = "#6d3392"
|
||||
|
||||
/datum/reagent/carpet/purple/reaction_turf(turf/T, reac_volume)
|
||||
if(isplatingturf(T) || istype(T, /turf/open/floor/plasteel))
|
||||
var/turf/open/floor/F = T
|
||||
F.PlaceOnTop(/turf/open/floor/carpet/purple)
|
||||
..()
|
||||
|
||||
/datum/reagent/carpet/red
|
||||
name = "Liquid Red Carpet"
|
||||
id = "redcarpet"
|
||||
color = "#871515"
|
||||
|
||||
/datum/reagent/carpet/red/reaction_turf(turf/T, reac_volume)
|
||||
if(isplatingturf(T) || istype(T, /turf/open/floor/plasteel))
|
||||
var/turf/open/floor/F = T
|
||||
F.PlaceOnTop(/turf/open/floor/carpet/red)
|
||||
..()
|
||||
|
||||
/datum/reagent/carpet/royalblack
|
||||
name = "Liquid Royal Black Carpet"
|
||||
id = "royalblackcarpet"
|
||||
color = "#483d05"
|
||||
|
||||
/datum/reagent/carpet/royalblack/reaction_turf(turf/T, reac_volume)
|
||||
if(isplatingturf(T) || istype(T, /turf/open/floor/plasteel))
|
||||
var/turf/open/floor/F = T
|
||||
F.PlaceOnTop(/turf/open/floor/carpet/royalblack)
|
||||
..()
|
||||
|
||||
/datum/reagent/carpet/royalblue
|
||||
name = "Liquid Royal Blue Carpet"
|
||||
id = "royalbluecarpet"
|
||||
color = "#24227e"
|
||||
|
||||
/datum/reagent/carpet/royalblue/reaction_turf(turf/T, reac_volume)
|
||||
if(isplatingturf(T) || istype(T, /turf/open/floor/plasteel))
|
||||
var/turf/open/floor/F = T
|
||||
F.PlaceOnTop(/turf/open/floor/carpet/royalblue)
|
||||
..()
|
||||
|
||||
|
||||
// Virology virus food chems.
|
||||
|
||||
/datum/reagent/toxin/mutagen/mutagenvirusfood
|
||||
@@ -2003,7 +2116,7 @@
|
||||
can_synth = FALSE
|
||||
var/datum/dna/original_dna
|
||||
var/reagent_ticks = 0
|
||||
invisible = TRUE
|
||||
chemical_flags = REAGENT_INVISIBLE
|
||||
|
||||
/datum/reagent/changeling_string/on_mob_metabolize(mob/living/carbon/C)
|
||||
if(C && C.dna && data["desired_dna"])
|
||||
@@ -2031,3 +2144,25 @@
|
||||
/datum/reagent/changeling_string/Destroy()
|
||||
qdel(original_dna)
|
||||
return ..()
|
||||
|
||||
/datum/reagent/mustardgrind
|
||||
name = "Mustardgrind"
|
||||
id = "mustardgrind"
|
||||
description = "A powerd that is mixed with water and enzymes to make mustard."
|
||||
color = "#BCC740" //RGB: 188, 199, 64
|
||||
taste_description = "plant dust"
|
||||
|
||||
/datum/reagent/pax/catnip
|
||||
name = "catnip"
|
||||
id = "catnip"
|
||||
taste_description = "grass"
|
||||
description = "A colorless liquid that makes people more peaceful and felines more happy."
|
||||
metabolization_rate = 1.75 * REAGENTS_METABOLISM
|
||||
|
||||
/datum/reagent/pax/catnip/on_mob_life(mob/living/carbon/M)
|
||||
if(prob(20))
|
||||
M.emote("nya")
|
||||
if(prob(20))
|
||||
to_chat(M, "<span class = 'notice'>[pick("Headpats feel nice.", "The feeling of a hairball...", "Backrubs would be nice.", "Whats behind those doors?")]</span>")
|
||||
M.adjustArousalLoss(2)
|
||||
..()
|
||||
|
||||
@@ -313,25 +313,6 @@
|
||||
. = 1
|
||||
..()
|
||||
|
||||
/datum/reagent/toxin/chloralhydratedelayed //sedates half as quickly and does not cause toxloss. same name/desc so it doesn't give away sleepypens
|
||||
name = "Chloral Hydrate"
|
||||
id = "chloralhydratedelayed"
|
||||
description = "A powerful sedative that induces confusion and drowsiness before putting its target to sleep."
|
||||
reagent_state = SOLID
|
||||
color = "#000067" // rgb: 0, 0, 103
|
||||
toxpwr = 0
|
||||
metabolization_rate = 1 * REAGENTS_METABOLISM
|
||||
|
||||
/datum/reagent/toxin/chloralhydratedelayed/on_mob_life(mob/living/carbon/M)
|
||||
switch(current_cycle)
|
||||
if(10 to 20)
|
||||
M.confused += 1
|
||||
M.drowsyness += 1
|
||||
M.adjustStaminaLoss(7.5)
|
||||
if(20 to INFINITY)
|
||||
M.Sleeping(40, 0)
|
||||
..()
|
||||
|
||||
/datum/reagent/toxin/fakebeer //disguised as normal beer for use by emagged brobots
|
||||
name = "Beer"
|
||||
id = "fakebeer"
|
||||
@@ -389,12 +370,12 @@
|
||||
id = "tirizene"
|
||||
description = "A nonlethal poison that causes extreme fatigue and weakness in its victim."
|
||||
color = "#6E2828"
|
||||
data = 13
|
||||
data = 15
|
||||
toxpwr = 0
|
||||
|
||||
/datum/reagent/toxin/staminatoxin/on_mob_life(mob/living/carbon/M)
|
||||
M.adjustStaminaLoss(REM * data, 0)
|
||||
data = max(data - 1, 3)
|
||||
data = max(data - 1, 5)
|
||||
..()
|
||||
. = 1
|
||||
|
||||
@@ -490,7 +471,7 @@
|
||||
toxpwr = 0
|
||||
|
||||
/datum/reagent/toxin/fentanyl/on_mob_life(mob/living/carbon/M)
|
||||
M.adjustBrainLoss(3*REM, 150)
|
||||
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 3*REM, 150)
|
||||
if(M.toxloss <= 60)
|
||||
M.adjustToxLoss(1*REM, 0)
|
||||
if(current_cycle >= 18)
|
||||
@@ -969,3 +950,20 @@
|
||||
to_chat(M, "<span class='warning'>Your missing arm aches from wherever you left it.</span>")
|
||||
M.emote("sigh")
|
||||
return ..()
|
||||
|
||||
/datum/reagent/toxin/brainhurtingjuice //oof ouch
|
||||
name = "Brain Hurting Juice"
|
||||
id = "brainhurtingjuice"
|
||||
color = "#AAAAAA77" //RGBA: 170, 170, 170, 77
|
||||
toxpwr = 0
|
||||
taste_description = "brain hurting"
|
||||
metabolization_rate = 5
|
||||
|
||||
/datum/reagent/toxin/brainhurtingjuice/on_mob_life(mob/living/carbon/M)
|
||||
if(prob(50))
|
||||
M.gain_trauma_type(BRAIN_TRAUMA_MILD)
|
||||
else if(prob(50))
|
||||
M.gain_trauma_type(BRAIN_TRAUMA_SEVERE)
|
||||
else
|
||||
M.gain_trauma_type(BRAIN_TRAUMA_SPECIAL)
|
||||
..()
|
||||
|
||||
@@ -68,6 +68,42 @@
|
||||
results = list("synthflesh" = 3)
|
||||
required_reagents = list("blood" = 1, "carbon" = 1, "styptic_powder" = 1)
|
||||
|
||||
/datum/chemical_reaction/synthtissue
|
||||
name = "Synthtissue"
|
||||
id = "synthtissue"
|
||||
results = list("synthtissue" = 0.05)
|
||||
required_reagents = list("synthflesh" = 0.01)
|
||||
required_catalysts = list("nutriment" = 0.1)
|
||||
//FermiChem vars:
|
||||
OptimalTempMin = 305 // Lower area of bell curve for determining heat based rate reactions
|
||||
OptimalTempMax = 315 // Upper end for above
|
||||
ExplodeTemp = 1050 // Temperature at which reaction explodes
|
||||
OptimalpHMin = 8.5 // Lowest value of pH determining pH a 1 value for pH based rate reactions (Plateu phase)
|
||||
OptimalpHMax = 9.5 // Higest value for above
|
||||
ReactpHLim = 2 // How far out pH wil react, giving impurity place (Exponential phase)
|
||||
CatalystFact = 0 // How much the catalyst affects the reaction (0 = no catalyst)
|
||||
CurveSharpT = 1 // How sharp the temperature exponential curve is (to the power of value)
|
||||
CurveSharppH = 2.5 // How sharp the pH exponential curve is (to the power of value)
|
||||
ThermicConstant = 0.01 // Temperature change per 1u produced
|
||||
HIonRelease = 0.015 // pH change per 1u reaction (inverse for some reason)
|
||||
RateUpLim = 0.05 // Optimal/max rate possible if all conditions are perfect
|
||||
FermiChem = TRUE // If the chemical uses the Fermichem reaction mechanics
|
||||
PurityMin = 0
|
||||
|
||||
/datum/chemical_reaction/synthtissue/FermiCreate(datum/reagents/holder, added_volume, added_purity)
|
||||
var/datum/reagent/synthtissue/St = holder.has_reagent("synthtissue")
|
||||
var/datum/reagent/N = holder.has_reagent("nutriment")
|
||||
if(!St)
|
||||
return
|
||||
if(holder.chem_temp > 320)
|
||||
var/temp_ratio = 1-(330 - holder.chem_temp)/10
|
||||
holder.remove_reagent(src.id, added_volume*temp_ratio)
|
||||
if(St.purity < 1)
|
||||
St.volume *= St.purity
|
||||
St.purity = 1
|
||||
N.volume -= 0.002
|
||||
St.data["grown_volume"] = St.data["grown_volume"] + added_volume
|
||||
|
||||
/datum/chemical_reaction/styptic_powder
|
||||
name = "Styptic Powder"
|
||||
id = "styptic_powder"
|
||||
|
||||
@@ -534,6 +534,17 @@
|
||||
category = list("Medical Designs")
|
||||
departmental_flags = DEPARTMENTAL_FLAG_MEDICAL
|
||||
|
||||
/datum/design/cybernetic_heart_u
|
||||
name = "Upgraded Cybernetic Heart"
|
||||
desc = "An upgraded cybernetic heart"
|
||||
id = "cybernetic_heart_u"
|
||||
build_type = PROTOLATHE | MECHFAB
|
||||
construction_time = 50
|
||||
materials = list(MAT_METAL = 500, MAT_GLASS = 500, MAT_SILVER = 500)
|
||||
build_path = /obj/item/organ/heart/cybernetic/upgraded
|
||||
category = list("Misc", "Medical Designs")
|
||||
departmental_flags = DEPARTMENTAL_FLAG_MEDICAL
|
||||
|
||||
/datum/design/cybernetic_liver_u
|
||||
name = "Upgraded Cybernetic Liver"
|
||||
desc = "An upgraded cybernetic liver"
|
||||
@@ -712,6 +723,28 @@
|
||||
category = list("Medical Designs")
|
||||
departmental_flags = DEPARTMENTAL_FLAG_MEDICAL
|
||||
|
||||
/datum/design/cybernetic_ears
|
||||
name = "Cybernetic Ears"
|
||||
desc = "A pair of cybernetic ears."
|
||||
id = "cybernetic_ears"
|
||||
build_type = PROTOLATHE | MECHFAB
|
||||
construction_time = 30
|
||||
materials = list(MAT_METAL = 250, MAT_GLASS = 400)
|
||||
build_path = /obj/item/organ/ears/cybernetic
|
||||
category = list("Misc", "Medical Designs")
|
||||
departmental_flags = DEPARTMENTAL_FLAG_MEDICAL
|
||||
|
||||
/datum/design/cybernetic_ears_u
|
||||
name = "Upgraded Cybernetic Ears"
|
||||
desc = "A pair of upgraded cybernetic ears."
|
||||
id = "cybernetic_ears_u"
|
||||
build_type = PROTOLATHE | MECHFAB
|
||||
construction_time = 40
|
||||
materials = list(MAT_METAL = 500, MAT_GLASS = 500, MAT_SILVER = 500)
|
||||
build_path = /obj/item/organ/ears/cybernetic/upgraded
|
||||
category = list("Misc", "Medical Designs")
|
||||
departmental_flags = DEPARTMENTAL_FLAG_MEDICAL
|
||||
|
||||
/////////////////////
|
||||
///Surgery Designs///
|
||||
/////////////////////
|
||||
|
||||
@@ -72,14 +72,16 @@
|
||||
/datum/nanite_program/brain_heal/check_conditions()
|
||||
if(iscarbon(host_mob))
|
||||
var/mob/living/carbon/C = host_mob
|
||||
if(length(C.get_traumas()))
|
||||
return ..()
|
||||
if(host_mob.getBrainLoss())
|
||||
for(var/X in C.get_traumas())
|
||||
var/datum/brain_trauma/BT = X
|
||||
if(BT.resilience <= TRAUMA_RESILIENCE_BASIC)
|
||||
return ..()
|
||||
if(host_mob.getOrganLoss(ORGAN_SLOT_BRAIN))
|
||||
return ..()
|
||||
return FALSE
|
||||
|
||||
/datum/nanite_program/brain_heal/active_effect()
|
||||
host_mob.adjustBrainLoss(-1, TRUE)
|
||||
host_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, -1, TRUE)
|
||||
if(iscarbon(host_mob) && prob(10))
|
||||
var/mob/living/carbon/C = host_mob
|
||||
C.cure_trauma_type(resilience = TRAUMA_RESILIENCE_BASIC)
|
||||
@@ -193,14 +195,16 @@
|
||||
/datum/nanite_program/brain_heal_advanced/check_conditions()
|
||||
if(iscarbon(host_mob))
|
||||
var/mob/living/carbon/C = host_mob
|
||||
if(length(C.get_traumas()))
|
||||
return ..()
|
||||
if(host_mob.getBrainLoss())
|
||||
for(var/X in C.get_traumas())
|
||||
var/datum/brain_trauma/BT = X
|
||||
if(BT.resilience <= TRAUMA_RESILIENCE_LOBOTOMY)
|
||||
return ..()
|
||||
if(host_mob.getOrganLoss(ORGAN_SLOT_BRAIN))
|
||||
return ..()
|
||||
return FALSE
|
||||
|
||||
|
||||
/datum/nanite_program/brain_heal_advanced/active_effect()
|
||||
host_mob.adjustBrainLoss(-2, TRUE)
|
||||
host_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, -2, TRUE)
|
||||
if(iscarbon(host_mob) && prob(10))
|
||||
var/mob/living/carbon/C = host_mob
|
||||
C.cure_trauma_type(resilience = TRAUMA_RESILIENCE_LOBOTOMY)
|
||||
@@ -232,7 +236,7 @@
|
||||
if(!C.getorgan(/obj/item/organ/heart)) //what are we even shocking
|
||||
return FALSE
|
||||
var/obj/item/organ/brain/BR = C.getorgan(/obj/item/organ/brain)
|
||||
if(QDELETED(BR) || BR.damaged_brain)
|
||||
if(QDELETED(BR) || BR.brain_death || (BR.organ_flags & ORGAN_FAILING) || C.suiciding)
|
||||
return FALSE
|
||||
if(C.get_ghost())
|
||||
return FALSE
|
||||
@@ -252,7 +256,7 @@
|
||||
SEND_SIGNAL(C, COMSIG_LIVING_MINOR_SHOCK)
|
||||
var/tplus = world.time - C.timeofdeath
|
||||
if(tplus > 600)
|
||||
C.adjustBrainLoss( max(0, ((1800 - tplus) / 1800 * 150)), 150)
|
||||
C.adjustOrganLoss(ORGAN_SLOT_BRAIN, max(0, ((1800 - tplus) / 1800 * 150)), 150)
|
||||
log_game("[C] has been successfully defibrillated by nanites.")
|
||||
else
|
||||
playsound(C, 'sound/machines/defib_failed.ogg', 50, 0)
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
/datum/nanite_program/brain_decay/active_effect()
|
||||
if(prob(4))
|
||||
host_mob.hallucination = min(15, host_mob.hallucination)
|
||||
host_mob.adjustBrainLoss(1)
|
||||
host_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 1)
|
||||
|
||||
//Generic brain-affecting programs can also decay into this
|
||||
/datum/nanite_program/brain_misfire
|
||||
|
||||
@@ -526,10 +526,18 @@
|
||||
display_name = "Cybernetic Organs"
|
||||
description = "We have the technology to rebuild him."
|
||||
prereq_ids = list("adv_biotech")
|
||||
design_ids = list("cybernetic_heart", "cybernetic_liver", "cybernetic_liver_u", "cybernetic_lungs", "cybernetic_lungs_u", "cybernetic_tongue")
|
||||
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
|
||||
design_ids = list("cybernetic_ears", "cybernetic_heart", "cybernetic_liver", "cybernetic_lungs", "cybernetic_tongue")
|
||||
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 1000)
|
||||
export_price = 5000
|
||||
|
||||
/datum/techweb_node/cyber_organs_upgraded
|
||||
id = "cyber_organs_upgraded"
|
||||
display_name = "Upgraded Cybernetic Organs"
|
||||
description = "We have the technology to upgrade him."
|
||||
prereq_ids = list("cyber_organs")
|
||||
design_ids = list("cybernetic_ears_u", "cybernetic_heart_u", "cybernetic_liver_u", "cybernetic_lungs_u")
|
||||
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 1500)
|
||||
|
||||
/datum/techweb_node/cyber_implants
|
||||
id = "cyber_implants"
|
||||
display_name = "Cybernetic Implants"
|
||||
|
||||
@@ -119,7 +119,7 @@ Consuming extracts:
|
||||
M.adjustToxLoss(-5, forced=1) //To heal slimepeople.
|
||||
M.adjustOxyLoss(-5)
|
||||
M.adjustCloneLoss(-5)
|
||||
M.adjustBrainLoss(-5)
|
||||
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, -5)
|
||||
|
||||
/obj/item/slimecross/consuming/blue
|
||||
colour = "blue"
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
/datum/surgery_step/clamp_bleeders,
|
||||
/datum/surgery_step/brainwash,
|
||||
/datum/surgery_step/close)
|
||||
|
||||
|
||||
species = list(/mob/living/carbon/human)
|
||||
possible_locs = list(BODY_ZONE_HEAD)
|
||||
/datum/surgery/advanced/brainwashing/can_start(mob/user, mob/living/carbon/target)
|
||||
@@ -56,7 +56,7 @@
|
||||
display_results(user, target, "<span class='warning'>You screw up, bruising the brain tissue!</span>",
|
||||
"<span class='warning'>[user] screws up, causing brain damage!</span>",
|
||||
"[user] completes the surgery on [target]'s brain.")
|
||||
target.adjustBrainLoss(40)
|
||||
target.adjustOrganLoss(ORGAN_SLOT_BRAIN, 40)
|
||||
else
|
||||
user.visible_message("<span class='warning'>[user] suddenly notices that the brain [user.p_they()] [user.p_were()] working on is not there anymore.", "<span class='warning'>You suddenly notice that the brain you were working on is not there anymore.</span>")
|
||||
return FALSE
|
||||
|
||||
@@ -51,11 +51,12 @@
|
||||
return TRUE
|
||||
|
||||
/datum/surgery_step/lobotomize/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
if(target.getorganslot(ORGAN_SLOT_BRAIN))
|
||||
var/obj/item/organ/brain/B = target.getorganslot(ORGAN_SLOT_BRAIN)
|
||||
if(B)
|
||||
display_results(user, target, "<span class='warning'>You remove the wrong part, causing more damage!</span>",
|
||||
"[user] successfully lobotomizes [target]!",
|
||||
"[user] completes the surgery on [target]'s brain.")
|
||||
target.adjustBrainLoss(80)
|
||||
B.applyOrganDamage(80)
|
||||
switch(rand(1,3))
|
||||
if(1)
|
||||
target.gain_trauma_type(BRAIN_TRAUMA_MILD, TRAUMA_RESILIENCE_MAGIC)
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
user.visible_message("...[target] wakes up, alive and aware!", "<span class='notice'><b>IT'S ALIVE!</b></span>")
|
||||
target.visible_message("...[target] wakes up, alive and aware!")
|
||||
target.emote("gasp")
|
||||
target.adjustBrainLoss(50, 199) //MAD SCIENCE
|
||||
target.adjustOrganLoss(ORGAN_SLOT_BRAIN, 50, 199) //MAD SCIENCE
|
||||
return TRUE
|
||||
else
|
||||
user.visible_message("...[target.p_they()] convulses, then lies still.")
|
||||
@@ -75,5 +75,5 @@
|
||||
"[user] send a powerful shock to [target]'s brain with [tool], but [target.p_they()] doesn't react.",
|
||||
"[user] send a powerful shock to [target]'s brain with [tool], but [target.p_they()] doesn't react.")
|
||||
playsound(get_turf(target), 'sound/magic/lightningbolt.ogg', 50, 1)
|
||||
target.adjustBrainLoss(15, 199)
|
||||
target.adjustOrganLoss(ORGAN_SLOT_BRAIN, 15, 199)
|
||||
return FALSE
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
"[user] completes the surgery on [target]'s brain.")
|
||||
if(target.mind && target.mind.has_antag_datum(/datum/antagonist/brainwashed))
|
||||
target.mind.remove_antag_datum(/datum/antagonist/brainwashed)
|
||||
target.adjustBrainLoss(-60)
|
||||
target.setOrganLoss(ORGAN_SLOT_BRAIN, target.getOrganLoss(ORGAN_SLOT_BRAIN) - 60) //we set damage in this case in order to clear the "failing" flag
|
||||
target.cure_all_traumas(TRAUMA_RESILIENCE_SURGERY)
|
||||
return TRUE
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
display_results(user, target, "<span class='warning'>You screw up, causing more damage!</span>",
|
||||
"<span class='warning'>[user] screws up, causing brain damage!</span>",
|
||||
"[user] completes the surgery on [target]'s brain.")
|
||||
target.adjustBrainLoss(60)
|
||||
target.adjustOrganLoss(ORGAN_SLOT_BRAIN, 60)
|
||||
target.gain_trauma_type(BRAIN_TRAUMA_SEVERE, TRAUMA_RESILIENCE_LOBOTOMY)
|
||||
else
|
||||
user.visible_message("<span class='warning'>[user] suddenly notices that the brain [user.p_they()] [user.p_were()] working on is not there anymore.", "<span class='warning'>You suddenly notice that the brain you were working on is not there anymore.</span>")
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
/datum/surgery/coronary_bypass
|
||||
name = "Coronary Bypass"
|
||||
steps = list(/datum/surgery_step/incise, /datum/surgery_step/retract_skin, /datum/surgery_step/saw, /datum/surgery_step/clamp_bleeders,
|
||||
/datum/surgery_step/incise_heart, /datum/surgery_step/coronary_bypass, /datum/surgery_step/close)
|
||||
possible_locs = list(BODY_ZONE_CHEST)
|
||||
|
||||
/datum/surgery/coronary_bypass/can_start(mob/user, mob/living/carbon/target)
|
||||
var/obj/item/organ/heart/H = target.getorganslot(ORGAN_SLOT_HEART)
|
||||
if(H)
|
||||
if(H.damage > 60 && !H.operated)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
|
||||
//an incision but with greater bleed, and a 90% base success chance
|
||||
/datum/surgery_step/incise_heart
|
||||
name = "incise heart"
|
||||
implements = list(/obj/item/scalpel = 90, /obj/item/melee/transforming/energy/sword = 45, /obj/item/kitchen/knife = 45,
|
||||
/obj/item/shard = 25)
|
||||
time = 16
|
||||
|
||||
/datum/surgery_step/incise_heart/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
display_results(user, target, "<span class='notice'>You begin to make an incision in [target]'s heart...</span>",
|
||||
"[user] begins to make an incision in [target]'s heart.",
|
||||
"[user] begins to make an incision in [target]'s heart.")
|
||||
|
||||
/datum/surgery_step/incise_heart/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
if(ishuman(target))
|
||||
var/mob/living/carbon/human/H = target
|
||||
if (!(NOBLOOD in H.dna.species.species_traits))
|
||||
display_results(user, target, "<span class='notice'>Blood pools around the incision in [H]'s heart.</span>",
|
||||
"Blood pools around the incision in [H]'s heart.",
|
||||
"")
|
||||
H.bleed_rate += 10
|
||||
H.adjustBruteLoss(10)
|
||||
return TRUE
|
||||
|
||||
/datum/surgery_step/incise_heart/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
if(ishuman(target))
|
||||
var/mob/living/carbon/human/H = target
|
||||
display_results(user, target, "<span class='warning'>You screw up, cutting too deeply into the heart!</span>",
|
||||
"<span class='warning'>[user] screws up, causing blood to spurt out of [H]'s chest!</span>",
|
||||
"<span class='warning'>[user] screws up, causing blood to spurt out of [H]'s chest!</span>")
|
||||
H.bleed_rate += 20
|
||||
H.adjustOrganLoss(ORGAN_SLOT_HEART, 10)
|
||||
H.adjustBruteLoss(10)
|
||||
|
||||
//grafts a coronary bypass onto the individual's heart, success chance is 90% base again
|
||||
/datum/surgery_step/coronary_bypass
|
||||
name = "graft coronary bypass"
|
||||
implements = list(/obj/item/hemostat = 90, TOOL_WIRECUTTER = 35, /obj/item/stack/packageWrap = 15, /obj/item/stack/cable_coil = 5)
|
||||
time = 90
|
||||
|
||||
/datum/surgery_step/coronary_bypass/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
display_results(user, target, "<span class='notice'>You begin to graft a bypass onto [target]'s heart...</span>",
|
||||
"[user] begins to graft something onto [target]'s heart!",
|
||||
"[user] begins to graft something onto [target]'s heart!")
|
||||
|
||||
/datum/surgery_step/coronary_bypass/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
target.setOrganLoss(ORGAN_SLOT_HEART, 60)
|
||||
var/obj/item/organ/heart/heart = target.getorganslot(ORGAN_SLOT_HEART)
|
||||
if(heart) //slightly worrying if we lost our heart mid-operation, but that's life
|
||||
heart.operated = TRUE
|
||||
display_results(user, target, "<span class='notice'>You successfully graft a bypass onto [target]'s heart.</span>",
|
||||
"[user] finishes grafting something onto [target]'s heart.",
|
||||
"[user] finishes grafting something onto [target]'s heart.")
|
||||
return TRUE
|
||||
|
||||
/datum/surgery_step/coronary_bypass/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
if(ishuman(target))
|
||||
var/mob/living/carbon/human/H = target
|
||||
display_results(user, target, "<span class='warning'>You screw up in attaching the graft, and it tears off, tearing part of the heart!</span>",
|
||||
"<span class='warning'>[user] screws up, causing blood to spurt out of [H]'s chest profusely!</span>",
|
||||
"<span class='warning'>[user] screws up, causing blood to spurt out of [H]'s chest profusely!</span>")
|
||||
H.adjustOrganLoss(ORGAN_SLOT_HEART, 20)
|
||||
H.bleed_rate += 30
|
||||
return FALSE
|
||||
@@ -37,7 +37,7 @@
|
||||
display_results(user, target, "<span class='warning'>You accidentally stab [target] right in the brain!</span>",
|
||||
"<span class='warning'>[user] accidentally stabs [target] right in the brain!</span>",
|
||||
"<span class='warning'>[user] accidentally stabs [target] right in the brain!</span>")
|
||||
target.adjustBrainLoss(70)
|
||||
target.adjustOrganLoss(ORGAN_SLOT_BRAIN, 70)
|
||||
else
|
||||
display_results(user, target, "<span class='warning'>You accidentally stab [target] right in the brain! Or would have, if [target] had a brain.</span>",
|
||||
"<span class='warning'>[user] accidentally stabs [target] right in the brain! Or would have, if [target] had a brain.</span>",
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
//Organ reconstruction, limited to the chest region as most organs in the head have their own repair method (eyes/brain). We require synthflesh for these
|
||||
//steps since fixing internal organs aren't as simple as mending exterior flesh, though in the future it would be neat to add more chems to the viable list.
|
||||
//TBD: Add heart damage, have heart reconstruction seperate from organ reconstruction, and find a better name for this. I can imagine people getting it confused with manipulation.
|
||||
|
||||
/datum/surgery/graft_synthtissue
|
||||
name = "Graft synthtissue"
|
||||
species = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
|
||||
possible_locs = list(BODY_ZONE_CHEST, BODY_ZONE_PRECISE_GROIN, BODY_ZONE_PRECISE_EYES)
|
||||
steps = list(
|
||||
/datum/surgery_step/incise,
|
||||
/datum/surgery_step/retract_skin,
|
||||
/datum/surgery_step/saw,
|
||||
/datum/surgery_step/clamp_bleeders,
|
||||
/datum/surgery_step/incise,
|
||||
/datum/surgery_step/graft_synthtissue,
|
||||
/datum/surgery_step/close
|
||||
)
|
||||
|
||||
//repair organs
|
||||
/datum/surgery_step/graft_synthtissue
|
||||
name = "graft synthtissue"
|
||||
implements = list(/obj/item/hemostat = 100, TOOL_SCREWDRIVER = 35, /obj/item/pen = 15)
|
||||
repeatable = TRUE
|
||||
time = 75
|
||||
chems_needed = list("synthtissue")
|
||||
var/obj/item/organ/chosen_organ
|
||||
var/health_restored = 10
|
||||
|
||||
/datum/surgery_step/graft_synthtissue/preop(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
if(implement_type in implements)
|
||||
var/list/organs = target.getorganszone(target_zone)
|
||||
if(!organs.len)
|
||||
to_chat(user, "<span class='notice'>There are no targetable organs in [target]'s [parse_zone(target_zone)]!</span>")
|
||||
return -1
|
||||
else
|
||||
for(var/obj/item/organ/O in organs)
|
||||
O.on_find(user)
|
||||
organs -= O
|
||||
organs[O.name] = O
|
||||
chosen_organ = input("Target which organ?", "Surgery", null, null) as null|anything in organs
|
||||
chosen_organ = organs[chosen_organ]
|
||||
if(!chosen_organ)
|
||||
return -1
|
||||
if(!target.reagents.has_reagent("synthtissue"))
|
||||
to_chat(user, "<span class='notice'>There's no synthtissue available for use on [chosen_organ]</span>")
|
||||
return -1
|
||||
var/datum/reagent/synthtissue/Sf = locate(/datum/reagent/synthtissue) in target.reagents.reagent_list
|
||||
if(Sf.volume < 10)
|
||||
to_chat(user, "<span class='notice'>There's not enough synthtissue to perform the operation! There needs to be at least 10u.</span>")
|
||||
return -1
|
||||
|
||||
if((chosen_organ.organ_flags & ORGAN_FAILING) && !(Sf.data["grown_volume"] >= 115))
|
||||
to_chat(user, "<span class='notice'>[chosen_organ] is too damaged to graft onto!</span>")
|
||||
return -1
|
||||
|
||||
if(health_restored != 10)
|
||||
health_restored = 10
|
||||
health_restored += (Sf.data["grown_volume"]/10)
|
||||
|
||||
user.visible_message("[user] begins to graft synthtissue onto [chosen_organ].</span>")
|
||||
target.reagents.remove_reagent("synthtissue", 10)
|
||||
|
||||
/datum/surgery_step/graft_synthtissue/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
user.visible_message("[user] successfully repairs part of [chosen_organ].", "<span class='notice'>You succeed in repairing parts of [chosen_organ].</span>")
|
||||
chosen_organ.applyOrganDamage(health_restored)
|
||||
|
||||
/datum/surgery_step/graft_synthtissue/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
user.visible_message("<span class='warning'>[user] accidentally damages part of [chosen_organ]!</span>", "<span class='warning'>You damage [chosen_organ]! Apply more synthtissue if it's run out.</span>")
|
||||
chosen_organ.applyOrganDamage(10)
|
||||
return FALSE
|
||||
@@ -0,0 +1,46 @@
|
||||
/datum/surgery/lobectomy
|
||||
name = "Lobectomy" //not to be confused with lobotomy
|
||||
steps = list(/datum/surgery_step/incise, /datum/surgery_step/retract_skin, /datum/surgery_step/saw, /datum/surgery_step/clamp_bleeders,
|
||||
/datum/surgery_step/lobectomy, /datum/surgery_step/close)
|
||||
possible_locs = list(BODY_ZONE_CHEST)
|
||||
|
||||
/datum/surgery/lobectomy/can_start(mob/user, mob/living/carbon/target)
|
||||
var/obj/item/organ/lungs/L = target.getorganslot(ORGAN_SLOT_LUNGS)
|
||||
if(L)
|
||||
if(L.damage > 60 && !L.operated)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
|
||||
//lobectomy, removes the most damaged lung lobe with a 95% base success chance
|
||||
/datum/surgery_step/lobectomy
|
||||
name = "excise damaged lung node"
|
||||
implements = list(/obj/item/scalpel = 95, /obj/item/melee/transforming/energy/sword = 65, /obj/item/kitchen/knife = 45,
|
||||
/obj/item/shard = 35)
|
||||
time = 42
|
||||
|
||||
/datum/surgery_step/lobectomy/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
display_results(user, target, "<span class='notice'>You begin to make an incision in [target]'s lungs...</span>",
|
||||
"[user] begins to make an incision in [target].",
|
||||
"[user] begins to make an incision in [target].")
|
||||
|
||||
/datum/surgery_step/lobectomy/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
if(ishuman(target))
|
||||
var/mob/living/carbon/human/H = target
|
||||
var/obj/item/organ/lungs/L = H.getorganslot(ORGAN_SLOT_LUNGS)
|
||||
L.operated = TRUE
|
||||
H.setOrganLoss(ORGAN_SLOT_LUNGS, 60)
|
||||
display_results(user, target, "<span class='notice'>You successfully excise [H]'s most damaged lobe.</span>",
|
||||
"Successfully removes a piece of [H]'s lungs.",
|
||||
"")
|
||||
return TRUE
|
||||
|
||||
/datum/surgery_step/lobectomy/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
if(ishuman(target))
|
||||
var/mob/living/carbon/human/H = target
|
||||
display_results(user, target, "<span class='warning'>You screw up, failing to excise [H]'s damaged lobe!</span>",
|
||||
"<span class='warning'>[user] screws up!</span>",
|
||||
"<span class='warning'>[user] screws up!</span>")
|
||||
H.losebreath += 4
|
||||
H.adjustOrganLoss(ORGAN_SLOT_LUNGS, 10)
|
||||
return FALSE
|
||||
@@ -3,7 +3,23 @@
|
||||
icon_state = "appendix"
|
||||
zone = BODY_ZONE_PRECISE_GROIN
|
||||
slot = ORGAN_SLOT_APPENDIX
|
||||
var/inflamed = 0
|
||||
healing_factor = STANDARD_ORGAN_HEALING
|
||||
decay_factor = STANDARD_ORGAN_DECAY
|
||||
|
||||
now_failing = "<span class='warning'>An explosion of pain erupts in your lower right abdomen!</span>"
|
||||
now_fixed = "<span class='info'>The pain in your abdomen has subsided.</span>"
|
||||
|
||||
var/inflamed
|
||||
|
||||
/obj/item/organ/appendix/on_life()
|
||||
..()
|
||||
if(!(organ_flags & ORGAN_FAILING))
|
||||
return
|
||||
var/mob/living/carbon/M = owner
|
||||
if(M)
|
||||
M.adjustToxLoss(4, TRUE, TRUE) //forced to ensure people don't use it to gain tox as slime person
|
||||
|
||||
|
||||
|
||||
/obj/item/organ/appendix/update_icon()
|
||||
if(inflamed)
|
||||
@@ -16,7 +32,7 @@
|
||||
/obj/item/organ/appendix/Remove(mob/living/carbon/M, special = 0)
|
||||
for(var/datum/disease/appendicitis/A in M.diseases)
|
||||
A.cure()
|
||||
inflamed = 1
|
||||
inflamed = TRUE
|
||||
update_icon()
|
||||
..()
|
||||
|
||||
|
||||
@@ -121,7 +121,7 @@
|
||||
playsound(get_turf(owner), 'sound/mecha/mechmove03.ogg', 50, 1)
|
||||
|
||||
/obj/item/organ/cyberimp/arm/ui_action_click()
|
||||
if(crit_fail || (!holder && !contents.len))
|
||||
if(crit_fail || (organ_flags & ORGAN_FAILING) || (!holder && !contents.len))
|
||||
to_chat(owner, "<span class='warning'>The implant doesn't respond. It seems to be broken...</span>")
|
||||
return
|
||||
|
||||
@@ -145,7 +145,7 @@
|
||||
. = ..()
|
||||
if(. & EMP_PROTECT_SELF)
|
||||
return
|
||||
if(prob(30/severity) && owner && !crit_fail)
|
||||
if(prob(30/severity) && owner && !(organ_flags & ORGAN_FAILING))
|
||||
Retract()
|
||||
owner.visible_message("<span class='danger'>A loud bang comes from [owner]\'s [zone == BODY_ZONE_R_ARM ? "right" : "left"] arm!</span>")
|
||||
playsound(get_turf(owner), 'sound/weapons/flashbang.ogg', 100, 1)
|
||||
@@ -154,6 +154,7 @@
|
||||
owner.IgniteMob()
|
||||
owner.adjustFireLoss(25)
|
||||
crit_fail = 1
|
||||
organ_flags |= ORGAN_FAILING
|
||||
|
||||
|
||||
/obj/item/organ/cyberimp/arm/gun/laser
|
||||
|
||||
@@ -144,7 +144,7 @@
|
||||
|
||||
/obj/item/organ/cyberimp/chest/thrusters/proc/toggle(silent = FALSE)
|
||||
if(!on)
|
||||
if(crit_fail)
|
||||
if(crit_fail || (organ_flags & ORGAN_FAILING))
|
||||
if(!silent)
|
||||
to_chat(owner, "<span class='warning'>Your thrusters set seems to be broken!</span>")
|
||||
return 0
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
name = "cybernetic implant"
|
||||
desc = "A state-of-the-art implant that improves a baseline's functionality."
|
||||
status = ORGAN_ROBOTIC
|
||||
organ_flags = ORGAN_SYNTHETIC
|
||||
var/implant_color = "#FFFFFF"
|
||||
var/implant_overlay
|
||||
var/syndicate_implant = FALSE //Makes the implant invisible to health analyzers and medical HUDs.
|
||||
@@ -102,7 +103,7 @@
|
||||
|
||||
/obj/item/organ/cyberimp/brain/anti_stun/on_life()
|
||||
..()
|
||||
if(crit_fail)
|
||||
if(crit_fail || !(organ_flags & ORGAN_FAILING))
|
||||
return
|
||||
owner.adjustStaminaLoss(-3.5) //Citadel edit, makes it more useful in Stamina based combat
|
||||
if(owner.AmountStun() > STUN_SET_AMOUNT)
|
||||
@@ -112,13 +113,15 @@
|
||||
|
||||
/obj/item/organ/cyberimp/brain/anti_stun/emp_act(severity)
|
||||
. = ..()
|
||||
if(crit_fail || . & EMP_PROTECT_SELF)
|
||||
if(crit_fail || (organ_flags & ORGAN_FAILING) || . & EMP_PROTECT_SELF)
|
||||
return
|
||||
crit_fail = TRUE
|
||||
organ_flags |= ORGAN_FAILING
|
||||
addtimer(CALLBACK(src, .proc/reboot), 90 / severity)
|
||||
|
||||
/obj/item/organ/cyberimp/brain/anti_stun/proc/reboot()
|
||||
crit_fail = FALSE
|
||||
organ_flags &= ~ORGAN_FAILING
|
||||
|
||||
|
||||
//[[[[MOUTH]]]]
|
||||
|
||||
@@ -6,6 +6,14 @@
|
||||
slot = ORGAN_SLOT_EARS
|
||||
gender = PLURAL
|
||||
|
||||
healing_factor = STANDARD_ORGAN_HEALING
|
||||
decay_factor = STANDARD_ORGAN_DECAY
|
||||
|
||||
low_threshold_passed = "<span class='info'>Your ears begin to resonate with an internal ring sometimes.</span>"
|
||||
now_failing = "<span class='warning'>You are unable to hear at all!</span>"
|
||||
now_fixed = "<span class='info'>Noise slowly begins filling your ears once more.</span>"
|
||||
low_threshold_cleared = "<span class='info'>The ringing in your ears has died down.</span>"
|
||||
|
||||
// `deaf` measures "ticks" of deafness. While > 0, the person is unable
|
||||
// to hear anything.
|
||||
var/deaf = 0
|
||||
@@ -23,17 +31,26 @@
|
||||
/obj/item/organ/ears/on_life()
|
||||
if(!iscarbon(owner))
|
||||
return
|
||||
..()
|
||||
var/mob/living/carbon/C = owner
|
||||
if((damage < maxHealth) && (organ_flags & ORGAN_FAILING)) //ear damage can be repaired from the failing condition
|
||||
organ_flags &= ~ORGAN_FAILING
|
||||
// genetic deafness prevents the body from using the ears, even if healthy
|
||||
if(HAS_TRAIT(C, TRAIT_DEAF))
|
||||
deaf = max(deaf, 1)
|
||||
else if(ear_damage < UNHEALING_EAR_DAMAGE) // if higher than UNHEALING_EAR_DAMAGE, no natural healing occurs.
|
||||
ear_damage = max(ear_damage - 0.05, 0)
|
||||
else if(!(organ_flags & ORGAN_FAILING)) // if this organ is failing, do not clear deaf stacks.
|
||||
deaf = max(deaf - 1, 0)
|
||||
if(prob(damage / 20) && (damage > low_threshold))
|
||||
adjustEarDamage(0, 4)
|
||||
SEND_SOUND(C, sound('sound/weapons/flash_ring.ogg'))
|
||||
to_chat(C, "<span class='warning'>The ringing in your ears grows louder, blocking out any external noises for a moment.</span>")
|
||||
else if((organ_flags & ORGAN_FAILING) && (deaf == 0))
|
||||
deaf = 1 //stop being not deaf you deaf idiot
|
||||
|
||||
/obj/item/organ/ears/proc/restoreEars()
|
||||
deaf = 0
|
||||
ear_damage = 0
|
||||
organ_flags &= ~ORGAN_FAILING
|
||||
|
||||
var/mob/living/carbon/C = owner
|
||||
|
||||
@@ -99,4 +116,23 @@
|
||||
name = "tin ears"
|
||||
desc = "The robust ears of a bronze golem. "
|
||||
damage_multiplier = 0.1 //STRONK
|
||||
bang_protect = 1 //Fear me weaklings.
|
||||
bang_protect = 1 //Fear me weaklings.
|
||||
|
||||
/obj/item/organ/ears/cybernetic
|
||||
name = "cybernetic ears"
|
||||
icon_state = "ears-c"
|
||||
desc = "a basic cybernetic designed to mimic the operation of ears."
|
||||
damage_multiplier = 0.9
|
||||
organ_flags = ORGAN_SYNTHETIC
|
||||
|
||||
/obj/item/organ/ears/cybernetic/upgraded
|
||||
name = "upgraded cybernetic ears"
|
||||
icon_state = "ears-c-u"
|
||||
desc = "an advanced cybernetic ear, surpassing the performance of organic ears"
|
||||
damage_multiplier = 0.5
|
||||
|
||||
/obj/item/organ/ears/cybernetic/emp_act(severity)
|
||||
. = ..()
|
||||
if(. & EMP_PROTECT_SELF)
|
||||
return
|
||||
damage += 40/severity
|
||||
|
||||
@@ -6,6 +6,19 @@
|
||||
slot = ORGAN_SLOT_EYES
|
||||
gender = PLURAL
|
||||
|
||||
healing_factor = STANDARD_ORGAN_HEALING
|
||||
decay_factor = STANDARD_ORGAN_DECAY
|
||||
maxHealth = 0.5 * STANDARD_ORGAN_THRESHOLD //half the normal health max since we go blind at 30, a permanent blindness at 50 therefore makes sense unless medicine is administered
|
||||
high_threshold = 0.3 * STANDARD_ORGAN_THRESHOLD //threshold at 30
|
||||
low_threshold = 0.15 * STANDARD_ORGAN_THRESHOLD //threshold at 15
|
||||
|
||||
low_threshold_passed = "<span class='info'>Distant objects become somewhat less tangible.</span>"
|
||||
high_threshold_passed = "<span class='info'>Everything starts to look a lot less clear.</span>"
|
||||
now_failing = "<span class='warning'>Darkness envelopes you, as your eyes go blind!</span>"
|
||||
now_fixed = "<span class='info'>Color and shapes are once again perceivable.</span>"
|
||||
high_threshold_cleared = "<span class='info'>Your vision functions passably once more.</span>"
|
||||
low_threshold_cleared = "<span class='info'>Your vision is cleared of any ailment.</span>"
|
||||
|
||||
var/sight_flags = 0
|
||||
var/see_in_dark = 2
|
||||
var/eye_damage = 0
|
||||
@@ -15,9 +28,12 @@
|
||||
var/flash_protect = 0
|
||||
var/see_invisible = SEE_INVISIBLE_LIVING
|
||||
var/lighting_alpha
|
||||
var/damaged = FALSE //damaged indicates that our eyes are undergoing some level of negative effect
|
||||
|
||||
/obj/item/organ/eyes/Insert(mob/living/carbon/M, special = FALSE, drop_if_replaced = FALSE)
|
||||
..()
|
||||
if(damage == initial(damage))
|
||||
clear_eye_trauma()
|
||||
if(ishuman(owner))
|
||||
var/mob/living/carbon/human/HMN = owner
|
||||
old_eye_color = HMN.eye_color
|
||||
@@ -32,7 +48,9 @@
|
||||
M.update_tint()
|
||||
owner.update_sight()
|
||||
|
||||
|
||||
/obj/item/organ/eyes/Remove(mob/living/carbon/M, special = 0)
|
||||
clear_eye_trauma()
|
||||
..()
|
||||
if(ishuman(M) && eye_color)
|
||||
var/mob/living/carbon/human/HMN = M
|
||||
@@ -41,6 +59,34 @@
|
||||
M.update_tint()
|
||||
M.update_sight()
|
||||
|
||||
/obj/item/organ/eyes/on_life()
|
||||
..()
|
||||
var/mob/living/carbon/C = owner
|
||||
//since we can repair fully damaged eyes, check if healing has occurred
|
||||
if((organ_flags & ORGAN_FAILING) && (damage < maxHealth))
|
||||
organ_flags &= ~ORGAN_FAILING
|
||||
C.cure_blind(EYE_DAMAGE)
|
||||
//various degrees of "oh fuck my eyes", from "point a laser at your eye" to "staring at the Sun" intensities
|
||||
if(damage > 20)
|
||||
damaged = TRUE
|
||||
if(organ_flags & ORGAN_FAILING)
|
||||
C.become_blind(EYE_DAMAGE)
|
||||
else if(damage > 30)
|
||||
C.overlay_fullscreen("eye_damage", /obj/screen/fullscreen/impaired, 2)
|
||||
else
|
||||
C.overlay_fullscreen("eye_damage", /obj/screen/fullscreen/impaired, 1)
|
||||
//called once since we don't want to keep clearing the screen of eye damage for people who are below 20 damage
|
||||
else if(damaged)
|
||||
damaged = FALSE
|
||||
C.clear_fullscreen("eye_damage")
|
||||
return
|
||||
|
||||
/obj/item/organ/eyes/proc/clear_eye_trauma()
|
||||
var/mob/living/carbon/C = owner
|
||||
C.clear_fullscreen("eye_damage")
|
||||
C.cure_blind(EYE_DAMAGE)
|
||||
damaged = FALSE
|
||||
|
||||
/obj/item/organ/eyes/night_vision
|
||||
name = "shadow eyes"
|
||||
desc = "A spooky set of eyes that can see in the dark."
|
||||
@@ -71,6 +117,7 @@
|
||||
/obj/item/organ/eyes/night_vision/zombie
|
||||
name = "undead eyes"
|
||||
desc = "Somewhat counterintuitively, these half-rotten eyes actually have superior vision to those of a living human."
|
||||
sight_flags = SEE_MOBS
|
||||
|
||||
/obj/item/organ/eyes/night_vision/nightmare
|
||||
name = "burning red eyes"
|
||||
@@ -88,15 +135,17 @@
|
||||
icon_state = "cybernetic_eyeballs"
|
||||
desc = "Your vision is augmented."
|
||||
status = ORGAN_ROBOTIC
|
||||
organ_flags = ORGAN_SYNTHETIC
|
||||
|
||||
/obj/item/organ/eyes/robotic/emp_act(severity)
|
||||
. = ..()
|
||||
if(!owner || . & EMP_PROTECT_SELF)
|
||||
return
|
||||
if(prob(10 * severity))
|
||||
return
|
||||
to_chat(owner, "<span class='warning'>Static obfuscates your vision!</span>")
|
||||
owner.flash_act(visual = 1)
|
||||
if(severity == EMP_HEAVY)
|
||||
owner.adjustOrganLoss(ORGAN_SLOT_EYES, 20)
|
||||
|
||||
|
||||
/obj/item/organ/eyes/robotic/xray
|
||||
name = "\improper X-ray eyes"
|
||||
@@ -137,7 +186,7 @@
|
||||
M.become_blind("flashlight_eyes")
|
||||
|
||||
|
||||
/obj/item/organ/eyes/robotic/flashlight/Remove(var/mob/living/carbon/M, var/special = 0)
|
||||
/obj/item/organ/eyes/robotic/flashlight/Remove(var/mob/living/carbon/M, special = FALSE)
|
||||
eye.on = FALSE
|
||||
eye.update_brightness(M)
|
||||
eye.forceMove(src)
|
||||
@@ -321,7 +370,7 @@
|
||||
if(!istype(parent))
|
||||
return INITIALIZE_HINT_QDEL
|
||||
|
||||
/obj/item/organ/eyes/moth
|
||||
name = "moth eyes"
|
||||
/obj/item/organ/eyes/insect
|
||||
name = "insect eyes"
|
||||
desc = "These eyes seem to have increased sensitivity to bright light, with no improvement to low light vision."
|
||||
flash_protect = -1
|
||||
|
||||
@@ -4,12 +4,24 @@
|
||||
icon_state = "heart-on"
|
||||
zone = BODY_ZONE_CHEST
|
||||
slot = ORGAN_SLOT_HEART
|
||||
|
||||
healing_factor = STANDARD_ORGAN_HEALING
|
||||
decay_factor = 4 * STANDARD_ORGAN_DECAY //designed to fail about 5 minutes after death
|
||||
|
||||
low_threshold_passed = "<span class='info'>Prickles of pain appear then die out from within your chest...</span>"
|
||||
high_threshold_passed = "<span class='warning'>Something inside your chest hurts, and the pain isn't subsiding. You notice yourself breathing far faster than before.</span>"
|
||||
now_fixed = "<span class='info'>Your heart begins to beat again.</span>"
|
||||
high_threshold_cleared = "<span class='info'>The pain in your chest has died down, and your breathing becomes more relaxed.</span>"
|
||||
|
||||
// Heart attack code is in code/modules/mob/living/carbon/human/life.dm
|
||||
var/beating = 1
|
||||
var/icon_base = "heart"
|
||||
attack_verb = list("beat", "thumped")
|
||||
var/beat = BEAT_NONE//is this mob having a heatbeat sound played? if so, which?
|
||||
|
||||
var/failed = FALSE //to prevent constantly running failing code
|
||||
var/operated = FALSE //whether the heart's been operated on to fix some of its damages
|
||||
|
||||
/obj/item/organ/heart/update_icon()
|
||||
if(beating)
|
||||
icon_state = "[icon_base]-on"
|
||||
@@ -50,6 +62,7 @@
|
||||
|
||||
/obj/item/organ/heart/on_life()
|
||||
if(owner.client && beating)
|
||||
failed = FALSE
|
||||
var/sound/slowbeat = sound('sound/health/slowbeat.ogg', repeat = TRUE)
|
||||
var/sound/fastbeat = sound('sound/health/fastbeat.ogg', repeat = TRUE)
|
||||
var/mob/living/carbon/H = owner
|
||||
@@ -70,11 +83,18 @@
|
||||
H.stop_sound_channel(CHANNEL_HEARTBEAT)
|
||||
beat = BEAT_NONE
|
||||
|
||||
if(organ_flags & ORGAN_FAILING) //heart broke, stopped beating, death imminent
|
||||
if(owner.stat == CONSCIOUS)
|
||||
owner.visible_message("<span class='userdanger'>[owner] clutches at [owner.p_their()] chest as if [owner.p_their()] heart is stopping!</span>")
|
||||
owner.set_heartattack(TRUE)
|
||||
failed = TRUE
|
||||
|
||||
/obj/item/organ/heart/cursed
|
||||
name = "cursed heart"
|
||||
desc = "A heart that, when inserted, will force you to pump it manually."
|
||||
icon_state = "cursedheart-off"
|
||||
icon_base = "cursedheart"
|
||||
decay_factor = 0
|
||||
actions_types = list(/datum/action/item_action/organ_action/cursed_heart)
|
||||
var/last_pump = 0
|
||||
var/add_colour = TRUE //So we're not constantly recreating colour datums
|
||||
@@ -153,18 +173,48 @@
|
||||
name = "cybernetic heart"
|
||||
desc = "An electronic device designed to mimic the functions of an organic human heart. Offers no benefit over an organic heart other than being easy to make."
|
||||
icon_state = "heart-c"
|
||||
synthetic = TRUE
|
||||
organ_flags = ORGAN_SYNTHETIC
|
||||
|
||||
/obj/item/organ/heart/cybernetic/emp_act()
|
||||
/obj/item/organ/heart/cybernetic/emp_act(severity)
|
||||
. = ..()
|
||||
if(. & EMP_PROTECT_SELF)
|
||||
return
|
||||
Stop()
|
||||
addtimer(CALLBACK(src, .proc/Restart), 20/severity SECONDS)
|
||||
damage += 100/severity
|
||||
|
||||
/obj/item/organ/heart/cybernetic/upgraded
|
||||
name = "upgraded cybernetic heart"
|
||||
desc = "An electronic device designed to mimic the functions of an organic human heart. Also holds an emergency dose of epinephrine, used automatically after facing severe trauma. This upgraded model can regenerate its dose after use."
|
||||
icon_state = "heart-c-u"
|
||||
maxHealth = 2 * STANDARD_ORGAN_THRESHOLD
|
||||
|
||||
//I put it on upgraded for now.
|
||||
var/dose_available = TRUE
|
||||
var/rid = /datum/reagent/medicine/epinephrine
|
||||
var/ramount = 10
|
||||
|
||||
obj/item/organ/heart/cybernetic/upgraded/on_life()
|
||||
. = ..()
|
||||
if(dose_available && owner.health <= owner.crit_threshold && !owner.reagents.has_reagent(rid))
|
||||
owner.reagents.add_reagent(rid, ramount)
|
||||
used_dose()
|
||||
if(ramount < 10) //eats your nutrition to regen epinephrine
|
||||
var/regen_amount = owner.nutrition/2000
|
||||
owner.nutrition -= regen_amount
|
||||
ramount += regen_amount
|
||||
|
||||
/obj/item/organ/heart/cybernetic/upgraded/proc/used_dose()
|
||||
. = ..()
|
||||
addtimer(VARSET_CALLBACK(src, dose_available, TRUE), 5 MINUTES)
|
||||
ramount = 0
|
||||
|
||||
|
||||
|
||||
/obj/item/organ/heart/freedom
|
||||
name = "heart of freedom"
|
||||
desc = "This heart pumps with the passion to give... something freedom."
|
||||
synthetic = TRUE //the power of freedom prevents heart attacks
|
||||
organ_flags = ORGAN_SYNTHETIC //the power of freedom prevents heart attacks
|
||||
var/min_next_adrenaline = 0
|
||||
|
||||
/obj/item/organ/heart/freedom/on_life()
|
||||
|
||||
@@ -10,10 +10,13 @@
|
||||
zone = BODY_ZONE_CHEST
|
||||
slot = ORGAN_SLOT_LIVER
|
||||
desc = "Pairing suggestion: chianti and fava beans."
|
||||
var/damage = 0 //liver damage, 0 is no damage, damage=maxHealth causes liver failure
|
||||
|
||||
maxHealth = STANDARD_ORGAN_THRESHOLD
|
||||
healing_factor = STANDARD_ORGAN_HEALING
|
||||
decay_factor = STANDARD_ORGAN_DECAY
|
||||
|
||||
var/alcohol_tolerance = ALCOHOL_RATE//affects how much damage the liver takes from alcohol
|
||||
var/failing //is this liver failing?
|
||||
var/maxHealth = LIVER_DEFAULT_HEALTH
|
||||
var/toxTolerance = LIVER_DEFAULT_TOX_TOLERANCE//maximum amount of toxins the liver can just shrug off
|
||||
var/toxLethality = LIVER_DEFAULT_TOX_LETHALITY//affects how much damage toxins do to the liver
|
||||
var/filterToxins = TRUE //whether to filter toxins
|
||||
@@ -24,7 +27,7 @@
|
||||
var/mob/living/carbon/C = owner
|
||||
|
||||
if(istype(C))
|
||||
if(!failing)//can't process reagents with a failing liver
|
||||
if(!(organ_flags & ORGAN_FAILING))//can't process reagents with a failing liver
|
||||
//slowly heal liver damage
|
||||
damage = max(0, damage - 0.1)
|
||||
|
||||
@@ -69,7 +72,7 @@
|
||||
if(moveCalc == cachedmoveCalc)//reduce calculations
|
||||
return
|
||||
if(prob(5))
|
||||
to_chat(owner, "<span class='notice'>You feel a stange ache in your side, almost like a sitch. This pain is affecting your movements and making you feel lightheaded.</span>")
|
||||
to_chat(owner, "<span class='notice'>You feel a stange ache in your side, almost like a stitch. This pain is affecting your movements and making you feel lightheaded.</span>")
|
||||
var/mob/living/carbon/human/H = owner
|
||||
H.add_movespeed_modifier(LIVER_SWELLING_MOVE_MODIFY, TRUE, 100, NONE, override = TRUE, multiplicative_slowdown = moveCalc)
|
||||
H.AdjustBloodVol(moveCalc/3)
|
||||
@@ -97,14 +100,15 @@
|
||||
name = "cybernetic liver"
|
||||
icon_state = "liver-c"
|
||||
desc = "An electronic device designed to mimic the functions of a human liver. It has no benefits over an organic liver, but is easy to produce."
|
||||
synthetic = TRUE
|
||||
organ_flags = ORGAN_SYNTHETIC
|
||||
maxHealth = 1.1 * STANDARD_ORGAN_THRESHOLD
|
||||
|
||||
/obj/item/organ/liver/cybernetic/upgraded
|
||||
name = "upgraded cybernetic liver"
|
||||
icon_state = "liver-c-u"
|
||||
desc = "An upgraded version of the cybernetic liver, designed to improve upon organic livers. It is resistant to alcohol poisoning and is very robust at filtering toxins."
|
||||
alcohol_tolerance = 0.001
|
||||
maxHealth = 200 //double the health of a normal liver
|
||||
maxHealth = 2 * STANDARD_ORGAN_THRESHOLD
|
||||
toxTolerance = 15 //can shrug off up to 15u of toxins
|
||||
toxLethality = 0.008 //20% less damage than a normal liver
|
||||
|
||||
|
||||
@@ -8,6 +8,19 @@
|
||||
gender = PLURAL
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
|
||||
var/failed = FALSE
|
||||
var/operated = FALSE //whether we can still have our damages fixed through surgery
|
||||
|
||||
//health
|
||||
maxHealth = LUNGS_MAX_HEALTH
|
||||
|
||||
healing_factor = STANDARD_ORGAN_HEALING
|
||||
decay_factor = STANDARD_ORGAN_DECAY
|
||||
|
||||
high_threshold_passed = "<span class='warning'>You feel some sort of constriction around your chest as your breathing becomes shallow and rapid.</span>"
|
||||
now_fixed = "<span class='warning'>Your lungs seem to once again be able to hold air.</span>"
|
||||
high_threshold_cleared = "<span class='info'>The constriction around your chest loosens as your breathing calms down.</span>"
|
||||
|
||||
//Breath damage
|
||||
|
||||
var/safe_oxygen_min = 16 // Minimum safe partial pressure of O2, in kPa
|
||||
@@ -56,36 +69,35 @@
|
||||
|
||||
var/crit_stabilizing_reagent = "epinephrine"
|
||||
|
||||
//health
|
||||
var/maxHealth = LUNGS_MAX_HEALTH
|
||||
var/damage = 0
|
||||
|
||||
|
||||
//TODO: lung health affects lung function
|
||||
/obj/item/organ/lungs/proc/adjustLungLoss(damage_mod, mob/living/carbon/M) //damage might be too low atm.
|
||||
/obj/item/organ/lungs/onDamage(damage_mod) //damage might be too low atm.
|
||||
var/cached_damage = damage
|
||||
if (maxHealth == INFINITY)
|
||||
return
|
||||
if(damage+damage_mod < 0)
|
||||
damage = 0
|
||||
if(cached_damage+damage_mod < 0)
|
||||
cached_damage = 0
|
||||
return
|
||||
|
||||
damage += damage_mod
|
||||
if ((damage / maxHealth) > 1)
|
||||
to_chat(M, "<span class='userdanger'>You feel your lungs collapse within your chest as you gasp for air, unable to inflate them anymore!</span>")
|
||||
M.emote("gasp")
|
||||
cached_damage += damage_mod
|
||||
if ((cached_damage/ maxHealth) > 1)
|
||||
to_chat(owner, "<span class='userdanger'>You feel your lungs collapse within your chest as you gasp for air, unable to inflate them anymore!</span>")
|
||||
owner.emote("gasp")
|
||||
SSblackbox.record_feedback("tally", "fermi_chem", 1, "Lungs lost")
|
||||
qdel(src)
|
||||
else if ((damage / maxHealth) > 0.75)
|
||||
to_chat(M, "<span class='warning'>It's getting really hard to breathe!!</span>")
|
||||
M.emote("gasp")
|
||||
M.Dizzy(3)
|
||||
else if ((damage / maxHealth) > 0.5)
|
||||
M.Dizzy(2)
|
||||
to_chat(M, "<span class='notice'>Your chest is really starting to hurt.</span>")
|
||||
M.emote("cough")
|
||||
else if ((damage / maxHealth) > 0.2)
|
||||
to_chat(M, "<span class='notice'>You feel an ache within your chest.</span>")
|
||||
M.emote("cough")
|
||||
M.Dizzy(1)
|
||||
//qdel(src) - Handled elsewhere for now.
|
||||
else if ((cached_damage / maxHealth) > 0.75)
|
||||
to_chat(owner, "<span class='warning'>It's getting really hard to breathe!!</span>")
|
||||
owner.emote("gasp")
|
||||
owner.Dizzy(3)
|
||||
else if ((cached_damage / maxHealth) > 0.5)
|
||||
owner.Dizzy(2)
|
||||
to_chat(owner, "<span class='notice'>Your chest is really starting to hurt.</span>")
|
||||
owner.emote("cough")
|
||||
else if ((cached_damage / maxHealth) > 0.2)
|
||||
to_chat(owner, "<span class='notice'>You feel an ache within your chest.</span>")
|
||||
owner.emote("cough")
|
||||
owner.Dizzy(1)
|
||||
|
||||
/obj/item/organ/lungs/proc/check_breath(datum/gas_mixture/breath, mob/living/carbon/human/H)
|
||||
//TODO: add lung damage = less oxygen gains
|
||||
@@ -289,7 +301,7 @@
|
||||
H.hallucination += 10
|
||||
H.reagents.add_reagent("bz_metabolites",5)
|
||||
if(prob(33))
|
||||
H.adjustBrainLoss(3, 150)
|
||||
H.adjustOrganLoss(ORGAN_SLOT_BRAIN, 3, 150)
|
||||
|
||||
else if(bz_pp > 0.01)
|
||||
H.hallucination += 5
|
||||
@@ -405,13 +417,13 @@
|
||||
var/cold_modifier = H.dna.species.coldmod
|
||||
if(breath_temperature < cold_level_3_threshold)
|
||||
H.apply_damage_type(cold_level_3_damage*cold_modifier, cold_damage_type)
|
||||
adjustLungLoss((cold_level_3_damage*cold_modifier*2), H)
|
||||
H.adjustOrganLoss(ORGAN_SLOT_LUNGS, (cold_level_3_damage*cold_modifier*2))
|
||||
if(breath_temperature > cold_level_3_threshold && breath_temperature < cold_level_2_threshold)
|
||||
H.apply_damage_type(cold_level_2_damage*cold_modifier, cold_damage_type)
|
||||
adjustLungLoss((cold_level_2_damage*cold_modifier*2), H)
|
||||
H.adjustOrganLoss(ORGAN_SLOT_LUNGS, (cold_level_2_damage*cold_modifier*2))
|
||||
if(breath_temperature > cold_level_2_threshold && breath_temperature < cold_level_1_threshold)
|
||||
H.apply_damage_type(cold_level_1_damage*cold_modifier, cold_damage_type)
|
||||
adjustLungLoss((cold_level_1_damage*cold_modifier*2), H)
|
||||
H.adjustOrganLoss(ORGAN_SLOT_LUNGS, (cold_level_1_damage*cold_modifier*2))
|
||||
if(breath_temperature < cold_level_1_threshold)
|
||||
if(prob(20))
|
||||
to_chat(H, "<span class='warning'>You feel [cold_message] in your [name]!</span>")
|
||||
@@ -420,17 +432,29 @@
|
||||
var/heat_modifier = H.dna.species.heatmod
|
||||
if(breath_temperature > heat_level_1_threshold && breath_temperature < heat_level_2_threshold)
|
||||
H.apply_damage_type(heat_level_1_damage*heat_modifier, heat_damage_type)
|
||||
adjustLungLoss((heat_level_1_damage*heat_modifier*2), H)
|
||||
H.adjustOrganLoss(ORGAN_SLOT_LUNGS, (heat_level_1_damage*heat_modifier*2))
|
||||
if(breath_temperature > heat_level_2_threshold && breath_temperature < heat_level_3_threshold)
|
||||
H.apply_damage_type(heat_level_2_damage*heat_modifier, heat_damage_type)
|
||||
adjustLungLoss((heat_level_2_damage*heat_modifier*2), H)
|
||||
H.adjustOrganLoss(ORGAN_SLOT_LUNGS, (heat_level_2_damage*heat_modifier*2))
|
||||
if(breath_temperature > heat_level_3_threshold)
|
||||
H.apply_damage_type(heat_level_3_damage*heat_modifier, heat_damage_type)
|
||||
adjustLungLoss((heat_level_3_damage*heat_modifier*2), H)
|
||||
H.adjustOrganLoss(ORGAN_SLOT_LUNGS, (heat_level_3_damage*heat_modifier*2))
|
||||
if(breath_temperature > heat_level_1_threshold)
|
||||
if(prob(20))
|
||||
to_chat(H, "<span class='warning'>You feel [hot_message] in your [name]!</span>")
|
||||
|
||||
|
||||
/obj/item/organ/lungs/on_life()
|
||||
..()
|
||||
if((!failed) && ((organ_flags & ORGAN_FAILING)))
|
||||
if(owner.stat == CONSCIOUS)
|
||||
owner.visible_message("<span class='danger'>[owner] grabs [owner.p_their()] throat, struggling for breath!</span>", \
|
||||
"<span class='userdanger'>You suddenly feel like you can't breathe!</span>")
|
||||
failed = TRUE
|
||||
else if(!(organ_flags & ORGAN_FAILING))
|
||||
failed = FALSE
|
||||
return
|
||||
|
||||
/obj/item/organ/lungs/prepare_eat()
|
||||
var/obj/S = ..()
|
||||
S.reagents.add_reagent("salbutamol", 5)
|
||||
@@ -451,14 +475,16 @@
|
||||
name = "cybernetic lungs"
|
||||
desc = "A cybernetic version of the lungs found in traditional humanoid entities. It functions the same as an organic lung and is merely meant as a replacement."
|
||||
icon_state = "lungs-c"
|
||||
synthetic = TRUE
|
||||
organ_flags = ORGAN_SYNTHETIC
|
||||
maxHealth = 400
|
||||
safe_oxygen_min = 13
|
||||
|
||||
/obj/item/organ/lungs/cybernetic/emp_act()
|
||||
. = ..()
|
||||
if(. & EMP_PROTECT_SELF)
|
||||
return
|
||||
owner.losebreath = 20
|
||||
owner.adjustOrganLoss(ORGAN_SLOT_LUNGS, 25)
|
||||
|
||||
|
||||
/obj/item/organ/lungs/cybernetic/upgraded
|
||||
@@ -495,8 +521,24 @@
|
||||
|
||||
safe_toxins_max = 0 //We breathe this to gain POWER.
|
||||
|
||||
cold_level_1_threshold = 285 // Remember when slimes used to be succeptable to cold? Well....
|
||||
cold_level_2_threshold = 260
|
||||
cold_level_3_threshold = 230
|
||||
|
||||
maxHealth = 250
|
||||
|
||||
/obj/item/organ/lungs/slime/check_breath(datum/gas_mixture/breath, mob/living/carbon/human/H)
|
||||
. = ..()
|
||||
if (breath && breath.gases[/datum/gas/plasma])
|
||||
var/plasma_pp = breath.get_breath_partial_pressure(breath.gases[/datum/gas/plasma])
|
||||
owner.blood_volume += (0.2 * plasma_pp) // 10/s when breathing literally nothing but plasma, which will suffocate you.
|
||||
|
||||
/obj/item/organ/lungs/yamerol
|
||||
name = "Yamerol lungs"
|
||||
desc = "A temporary pair of lungs made from self assembling yamerol molecules."
|
||||
maxHealth = 200
|
||||
color = "#68e83a"
|
||||
|
||||
/obj/item/organ/lungs/yamerol/on_life()
|
||||
..()
|
||||
damage += 2 //Yamerol lungs are temporary
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
#define STANDARD_ORGAN_THRESHOLD 100
|
||||
#define STANDARD_ORGAN_HEALING 0.001
|
||||
|
||||
/obj/item/organ
|
||||
name = "organ"
|
||||
icon = 'icons/obj/surgery.dmi'
|
||||
@@ -8,11 +11,23 @@
|
||||
var/zone = BODY_ZONE_CHEST
|
||||
var/slot
|
||||
// DO NOT add slots with matching names to different zones - it will break internal_organs_slot list!
|
||||
var/vital = 0
|
||||
//Was this organ implanted/inserted/etc, if true will not be removed during species change.
|
||||
var/external = FALSE
|
||||
var/synthetic = FALSE // To distinguish between organic and synthetic organs
|
||||
var/organ_flags = 0
|
||||
var/maxHealth = STANDARD_ORGAN_THRESHOLD
|
||||
var/damage = 0 //total damage this organ has sustained
|
||||
///Healing factor and decay factor function on % of maxhealth, and do not work by applying a static number per tick
|
||||
var/healing_factor = 0 //fraction of maxhealth healed per on_life(), set to 0 for generic organs
|
||||
var/decay_factor = 0 //same as above but when without a living owner, set to 0 for generic organs
|
||||
var/high_threshold = STANDARD_ORGAN_THRESHOLD * 0.45 //when severe organ damage occurs
|
||||
var/low_threshold = STANDARD_ORGAN_THRESHOLD * 0.1 //when minor organ damage occurs
|
||||
|
||||
///Organ variables for determining what we alert the owner with when they pass/clear the damage thresholds
|
||||
var/prev_damage = 0
|
||||
var/low_threshold_passed
|
||||
var/high_threshold_passed
|
||||
var/now_failing
|
||||
var/now_fixed
|
||||
var/high_threshold_cleared
|
||||
var/low_threshold_cleared
|
||||
|
||||
/obj/item/organ/proc/Insert(mob/living/carbon/M, special = 0, drop_if_replaced = TRUE)
|
||||
if(!iscarbon(M) || owner == M)
|
||||
@@ -33,31 +48,53 @@
|
||||
for(var/X in actions)
|
||||
var/datum/action/A = X
|
||||
A.Grant(M)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
|
||||
//Special is for instant replacement like autosurgeons
|
||||
/obj/item/organ/proc/Remove(mob/living/carbon/M, special = 0)
|
||||
/obj/item/organ/proc/Remove(mob/living/carbon/M, special = FALSE)
|
||||
owner = null
|
||||
if(M)
|
||||
M.internal_organs -= src
|
||||
if(M.internal_organs_slot[slot] == src)
|
||||
M.internal_organs_slot.Remove(slot)
|
||||
if(vital && !special && !(M.status_flags & GODMODE))
|
||||
if((organ_flags & ORGAN_VITAL) && !special && !(M.status_flags & GODMODE))
|
||||
M.death()
|
||||
for(var/X in actions)
|
||||
var/datum/action/A = X
|
||||
A.Remove(M)
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
|
||||
/obj/item/organ/proc/on_find(mob/living/finder)
|
||||
return
|
||||
|
||||
/obj/item/organ/proc/on_life()
|
||||
return
|
||||
/obj/item/organ/process()
|
||||
on_death() //Kinda hate doing it like this, but I really don't want to call process directly.
|
||||
|
||||
/obj/item/organ/proc/on_death() //runs decay when outside of a person
|
||||
if(organ_flags & (ORGAN_SYNTHETIC | ORGAN_FROZEN | ORGAN_NO_SPOIL))
|
||||
return
|
||||
applyOrganDamage(maxHealth * decay_factor)
|
||||
|
||||
/obj/item/organ/proc/on_life() //repair organ damage if the organ is not failing
|
||||
if(!(organ_flags & ORGAN_FAILING))
|
||||
///Damage decrements by a percent of its maxhealth
|
||||
var/healing_amount = -(maxHealth * healing_factor)
|
||||
///Damage decrements again by a percent of its maxhealth, up to a total of 4 extra times depending on the owner's health
|
||||
healing_amount -= owner.satiety > 0 ? 4 * healing_factor * owner.satiety / MAX_SATIETY : 0
|
||||
applyOrganDamage(healing_amount) //to FERMI_TWEAK
|
||||
//Make it so each threshold is stuck.
|
||||
|
||||
/obj/item/organ/examine(mob/user)
|
||||
..()
|
||||
if(status == ORGAN_ROBOTIC && crit_fail)
|
||||
to_chat(user, "<span class='warning'>[src] seems to be broken!</span>")
|
||||
. = ..()
|
||||
if(!organ_flags & ORGAN_FAILING)
|
||||
if(status == ORGAN_ROBOTIC)
|
||||
. += "<span class='warning'>[src] seems to be broken!</span>"
|
||||
return
|
||||
. += "<span class='warning'>[src] has decayed for too long, and has turned a sickly color! It doesn't look like it will work anymore!</span>"
|
||||
return
|
||||
if(damage > high_threshold)
|
||||
. += "<span class='warning'>[src] is starting to look discolored.</span>"
|
||||
|
||||
|
||||
/obj/item/organ/proc/prepare_eat()
|
||||
@@ -78,6 +115,10 @@
|
||||
foodtype = RAW | MEAT | GROSS
|
||||
|
||||
|
||||
/obj/item/organ/Initialize()
|
||||
. = ..()
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/item/organ/Destroy()
|
||||
if(owner)
|
||||
// The special flag is important, because otherwise mobs can die
|
||||
@@ -100,13 +141,64 @@
|
||||
/obj/item/organ/item_action_slot_check(slot,mob/user)
|
||||
return //so we don't grant the organ's action to mobs who pick up the organ.
|
||||
|
||||
///Adjusts an organ's damage by the amount "d", up to a maximum amount, which is by default max damage
|
||||
/obj/item/organ/proc/applyOrganDamage(var/d, var/maximum = maxHealth) //use for damaging effects
|
||||
if(!d) //Micro-optimization.
|
||||
return
|
||||
if(maximum < damage)
|
||||
return
|
||||
damage = CLAMP(damage + d, 0, maximum)
|
||||
var/mess = check_damage_thresholds(owner)
|
||||
prev_damage = damage
|
||||
if(mess && owner)
|
||||
to_chat(owner, mess)
|
||||
|
||||
///SETS an organ's damage to the amount "d", and in doing so clears or sets the failing flag, good for when you have an effect that should fix an organ if broken
|
||||
/obj/item/organ/proc/setOrganDamage(var/d) //use mostly for admin heals
|
||||
applyOrganDamage(d - damage)
|
||||
|
||||
/** check_damage_thresholds
|
||||
* input: M (a mob, the owner of the organ we call the proc on)
|
||||
* output: returns a message should get displayed.
|
||||
* description: By checking our current damage against our previous damage, we can decide whether we've passed an organ threshold.
|
||||
* If we have, send the corresponding threshold message to the owner, if such a message exists.
|
||||
*/
|
||||
/obj/item/organ/proc/check_damage_thresholds(var/M)
|
||||
if(damage == prev_damage)
|
||||
return
|
||||
var/delta = damage - prev_damage
|
||||
if(delta > 0)
|
||||
if(damage >= maxHealth)
|
||||
organ_flags |= ORGAN_FAILING
|
||||
return now_failing
|
||||
if(damage > high_threshold && prev_damage <= high_threshold)
|
||||
return high_threshold_passed
|
||||
if(damage > low_threshold && prev_damage <= low_threshold)
|
||||
return low_threshold_passed
|
||||
else
|
||||
organ_flags &= ~ORGAN_FAILING
|
||||
if(prev_damage > low_threshold && damage <= low_threshold)
|
||||
return low_threshold_cleared
|
||||
if(prev_damage > high_threshold && damage <= high_threshold)
|
||||
return high_threshold_cleared
|
||||
if(prev_damage == maxHealth)
|
||||
return now_fixed
|
||||
|
||||
//Runs some code on the organ when damage is taken/healed
|
||||
/obj/item/organ/proc/onDamage(var/d, var/maximum = maxHealth)
|
||||
return
|
||||
|
||||
//Runs some code on the organ when damage is taken/healed
|
||||
/obj/item/organ/proc/onSetDamage(var/d, var/maximum = maxHealth)
|
||||
return
|
||||
|
||||
//Looking for brains?
|
||||
//Try code/modules/mob/living/carbon/brain/brain_item.dm
|
||||
|
||||
/mob/living/proc/regenerate_organs()
|
||||
return 0
|
||||
|
||||
/mob/living/carbon/regenerate_organs()
|
||||
/mob/living/carbon/regenerate_organs(only_one = FALSE)
|
||||
var/breathes = TRUE
|
||||
var/blooded = TRUE
|
||||
if(dna && dna.species)
|
||||
@@ -125,6 +217,8 @@
|
||||
else
|
||||
LI = new()
|
||||
LI.Insert(src)
|
||||
if(only_one)
|
||||
return TRUE
|
||||
|
||||
if(has_stomach && !getorganslot(ORGAN_SLOT_STOMACH))
|
||||
var/obj/item/organ/stomach/S
|
||||
@@ -134,14 +228,20 @@
|
||||
else
|
||||
S = new()
|
||||
S.Insert(src)
|
||||
if(only_one)
|
||||
return TRUE
|
||||
|
||||
if(breathes && !getorganslot(ORGAN_SLOT_LUNGS))
|
||||
var/obj/item/organ/lungs/L = new()
|
||||
L.Insert(src)
|
||||
if(only_one)
|
||||
return TRUE
|
||||
|
||||
if(blooded && !getorganslot(ORGAN_SLOT_HEART))
|
||||
var/obj/item/organ/heart/H = new()
|
||||
H.Insert(src)
|
||||
if(only_one)
|
||||
return TRUE
|
||||
|
||||
if(!getorganslot(ORGAN_SLOT_TONGUE))
|
||||
var/obj/item/organ/tongue/T
|
||||
@@ -153,7 +253,10 @@
|
||||
|
||||
// if they have no mutant tongues, give them a regular one
|
||||
T.Insert(src)
|
||||
else
|
||||
if(only_one)
|
||||
return TRUE
|
||||
|
||||
else if (!only_one)
|
||||
var/obj/item/organ/tongue/oT = getorganslot(ORGAN_SLOT_TONGUE)
|
||||
if(oT.name == "fluffy tongue")
|
||||
var/obj/item/organ/tongue/T
|
||||
@@ -174,6 +277,8 @@
|
||||
else
|
||||
E = new()
|
||||
E.Insert(src)
|
||||
if(only_one)
|
||||
return TRUE
|
||||
|
||||
if(!getorganslot(ORGAN_SLOT_EARS))
|
||||
var/obj/item/organ/ears/ears
|
||||
@@ -183,9 +288,13 @@
|
||||
ears = new
|
||||
|
||||
ears.Insert(src)
|
||||
if(only_one)
|
||||
return TRUE
|
||||
|
||||
if(!getorganslot(ORGAN_SLOT_TAIL))
|
||||
var/obj/item/organ/tail/tail
|
||||
if(dna && dna.species && dna.species.mutanttail)
|
||||
tail = new dna.species.mutanttail
|
||||
tail.Insert(src)
|
||||
if(only_one)
|
||||
return TRUE
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user