Bay Merge 05NOV2014

Known errors:

* A set of errors tied to updating the fire overlays.
* A single error related to a dischephency between new and old slime
code
* A set of errors related to the recharging of stun batons
* A single error due to old machinery code coming from your grav
generator file
* A single error error from your space cooler code, due to old
atmopsherics code
* A playerpanel warning
* An error tied to extinguishing and old atmos code.
This commit is contained in:
skull132
2014-11-05 23:58:05 +02:00
parent b7174a5099
commit 3c04d7199d
535 changed files with 29846 additions and 17593 deletions
+4 -7
View File
@@ -63,7 +63,7 @@ var/const/BLOOD_VOLUME_SURVIVE = 122
// Damaged heart virtually reduces the blood volume, as the blood isn't
// being pumped properly anymore.
var/datum/organ/internal/heart/heart = internal_organs["heart"]
var/datum/organ/internal/heart/heart = internal_organs_by_name["heart"]
if(heart.damage > 1 && heart.damage < heart.min_bruised_damage)
blood_volume *= 0.8
@@ -127,14 +127,12 @@ var/const/BLOOD_VOLUME_SURVIVE = 122
if(!(temp.status & ORGAN_BLEEDING) || temp.status & ORGAN_ROBOT)
continue
for(var/datum/wound/W in temp.wounds) if(W.bleeding())
blood_max += W.damage / 4
if(temp.status & ORGAN_DESTROYED && !(temp.status & ORGAN_GAUZED) && !temp.amputated)
blood_max += 20 //Yer missing a fucking limb.
blood_max += W.damage / 40
if (temp.open)
blood_max += 2 //Yer stomach is cut open
drip(blood_max)
//Makes a blood drop, leaking certain amount of blood from the mob
//Makes a blood drop, leaking amt units of blood from the mob
/mob/living/carbon/human/proc/drip(var/amt as num)
if(species && species.flags & NO_BLOOD) //TODO: Make drips come from the reagents instead.
@@ -143,12 +141,11 @@ var/const/BLOOD_VOLUME_SURVIVE = 122
if(!amt)
return
var/amm = 0.1 * amt
var/turf/T = get_turf(src)
var/list/obj/effect/decal/cleanable/blood/drip/nums = list()
var/list/iconL = list("1","2","3","4","5")
vessel.remove_reagent("blood",amm)
vessel.remove_reagent("blood",amt)
for(var/obj/effect/decal/cleanable/blood/drip/G in T)
nums += G
+33 -52
View File
@@ -5,6 +5,9 @@
var/list/datum/autopsy_data/autopsy_data = list()
var/list/trace_chemicals = list() // traces of chemicals in the organ,
// links chemical IDs to number of ticks for which they'll stay in the blood
var/germ_level = 0 // INTERNAL germs inside the organ, this is BAD if it's greater than INFECTION_LEVEL_ONE
proc/process()
return 0
@@ -14,6 +17,20 @@
/datum/organ/proc/get_icon(var/icon/race_icon, var/icon/deform_icon)
return icon('icons/mob/human.dmi',"blank")
//Germs
/datum/organ/proc/handle_antibiotics()
var/antibiotics = owner.reagents.get_reagent_amount("spaceacillin")
if (!germ_level || antibiotics < 5)
return
if (germ_level < INFECTION_LEVEL_ONE)
germ_level = 0 //cure instantly
else if (germ_level < INFECTION_LEVEL_TWO)
germ_level -= 6 //at germ_level == 500, this should cure the infection in a minute
else
germ_level -= 2 //at germ_level == 1000, this will cure the infection in 5 minutes
//Handles chem traces
/mob/living/carbon/human/proc/handle_trace_chems()
//New are added for reagents to random organs.
@@ -46,13 +63,18 @@
if(damage_this_tick > last_dam)
force_process = 1
last_dam = damage_this_tick
if(!force_process && !bad_external_organs.len)
return
if(force_process)
bad_external_organs.Cut()
for(var/datum/organ/external/Ex in organs)
bad_external_organs += Ex
//processing internal organs is pretty cheap, do that first.
for(var/datum/organ/internal/I in internal_organs)
I.process()
if(!force_process && !bad_external_organs.len)
return
for(var/datum/organ/external/E in bad_external_organs)
if(!E)
continue
@@ -62,63 +84,22 @@
else
E.process()
number_wounds += E.number_wounds
//Robotic limb malfunctions
var/malfunction = 0
if (E.status & ORGAN_ROBOT && prob(E.brute_dam + E.burn_dam))
malfunction = 1
//Broken limbs hurt too
var/broken = 0
if(E.status & ORGAN_BROKEN && !(E.status & ORGAN_SPLINTED) )
broken = 1
if (!lying && world.time - l_move_time < 15)
//Moving around with fractured ribs won't do you any good
if (broken && E.internal_organs && prob(15))
if (!lying && world.timeofday - l_move_time < 15)
if (E.is_broken() && E.internal_organs && prob(15))
var/datum/organ/internal/I = pick(E.internal_organs)
custom_pain("You feel broken bones moving in your [E.display_name]!", 1)
I.take_damage(rand(3,5))
//Special effects for limbs.
if(E.name in list("l_hand","l_arm","r_hand","r_arm"))
var/obj/item/c_hand //Getting what's in this hand
var/hand
if(E.name == "l_hand" || E.name == "l_arm")
c_hand = l_hand
hand = "left hand"
if(E.name == "r_hand" || E.name == "r_arm")
c_hand = r_hand
hand = "right hand"
if (c_hand)
//Moving makes open wounds get infected much faster
if (E.wounds.len)
for(var/datum/wound/W in E.wounds)
if (W.infection_check())
W.germ_level += 1
if(broken)
if(istype(c_hand, /obj/item/weapon/gun/offhand))
var/obj/item/weapon/gun/O = get_inactive_hand()
var/obj/item/weapon/gun/offhand/OH = c_hand
O.unwield()
OH.unwield()
else
u_equip(c_hand)
var/emote_scream = pick("screams in pain and", "let's out a sharp hiss and", "cries out and")
emote("me", 1, "[(species && species.flags & NO_PAIN) ? "" : emote_scream ] drops what they were holding in their [hand]!")
if(malfunction)
if(istype(c_hand, /obj/item/weapon/gun/offhand))
var/obj/item/weapon/gun/O = get_inactive_hand()
var/obj/item/weapon/gun/offhand/OH = c_hand
O.unwield()
OH.unwield()
else
u_equip(c_hand)
emote("me", 1, "drops what they were holding, their [hand] malfunctioning!")
var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread()
spark_system.set_up(5, 0, src)
spark_system.attach(src)
spark_system.start()
spawn(10)
del(spark_system)
else if(E.name in list("l_leg","l_foot","r_leg","r_foot") && !lying)
if (!E.is_usable() || malfunction || (broken && !(E.status & ORGAN_SPLINTED)))
if(E.name in list("l_leg","l_foot","r_leg","r_foot") && !lying)
if (!E.is_usable() || E.is_malfunctioning() || (E.is_broken() && !(E.status & ORGAN_SPLINTED)))
leg_tally-- // let it fail even if just foot&leg
// standing is poor
+267 -121
View File
@@ -32,6 +32,7 @@
var/damage_msg = "\red You feel an intense pain"
var/broken_description
var/vital //Lose a vital limb, die immediately.
var/status = 0
var/open = 0
var/stage = 0
@@ -40,8 +41,6 @@
var/obj/item/hidden = null
var/list/implants = list()
// INTERNAL germs inside the organ, this is BAD if it's greater 0
var/germ_level = 0
// how often wounds should be updated, a higher number means less often
var/wound_update_accuracy = 1
@@ -92,15 +91,8 @@
brute *= brmod //~2/3 damage for ROBOLIMBS
burn *= bumod //~2/3 damage for ROBOLIMBS
//If limb took enough damage, try to cut or tear it off
if(body_part != UPPER_TORSO && body_part != LOWER_TORSO) //as hilarious as it is, getting hit on the chest too much shouldn't effectively gib you.
if(config.limbs_can_break && brute_dam >= max_damage * config.organ_health_multiplier)
if( (edge && prob(5 * brute)) || (brute > 20 && prob(2 * brute)) )
droplimb(1)
return
// High brute damage or sharp objects may damage internal organs
if(internal_organs != null) if( (sharp && brute >= 5) || brute >= 10) if(prob(5))
if(internal_organs && ( (sharp && brute >= 5) || brute >= 10) && prob(5))
// Damage an internal organ
var/datum/organ/internal/I = pick(internal_organs)
I.take_damage(brute / 2)
@@ -163,6 +155,14 @@
// sync the organ's damage with its wounds
src.update_damages()
//If limb took enough damage, try to cut or tear it off
if(body_part != UPPER_TORSO && body_part != LOWER_TORSO) //as hilarious as it is, getting hit on the chest too much shouldn't effectively gib you.
if(config.limbs_can_break && brute_dam >= max_damage * config.organ_health_multiplier)
if( (edge && prob(5 * brute)) || (brute > 20 && prob(2 * brute)) )
droplimb(1)
return
owner.updatehealth()
var/result = update_icon()
@@ -194,18 +194,6 @@
var/result = update_icon()
return result
/datum/organ/external/proc/embed(var/obj/item/weapon/W, var/silent = 0)
if(!silent)
owner.visible_message("<span class='danger'>\The [W] sticks in the wound!</span>")
implants += W
owner.embedded_flag = 1
owner.verbs += /mob/proc/yank_out_object
W.add_blood(owner)
if(ismob(W.loc))
var/mob/living/H = W.loc
H.drop_item()
W.loc = owner
/*
This function completely restores a damaged organ to perfect condition.
*/
@@ -218,6 +206,9 @@ This function completely restores a damaged organ to perfect condition.
perma_injury = 0
brute_dam = 0
burn_dam = 0
germ_level = 0
wounds.Cut()
number_wounds = 0
// handle internal organs
for(var/datum/organ/internal/current_organ in internal_organs)
@@ -235,11 +226,11 @@ This function completely restores a damaged organ to perfect condition.
/datum/organ/external/proc/createwound(var/type = CUT, var/damage)
if(damage == 0) return
//moved this before the open_wound check so that having many small wounds for example doesn't somehow protect you from taking internal damage
//moved this before the open_wound check so that having many small wounds for example doesn't somehow protect you from taking internal damage (because of the return)
//Possibly trigger an internal wound, too.
var/local_damage = brute_dam + burn_dam + damage
if(damage > 15 && type != BURN && local_damage > 30 && prob(damage) && !(status & ORGAN_ROBOT))
var/datum/wound/internal_bleeding/I = new (15)
var/datum/wound/internal_bleeding/I = new (min(damage - 15, 15))
wounds += I
owner.custom_pain("You feel something rip in your [display_name]!", 1)
@@ -277,25 +268,6 @@ This function completely restores a damaged organ to perfect condition.
if(W)
wounds += W
/datum/organ/external/proc/get_wound_type(var/type = CUT, var/damage)
//if you look a the names in the wound's stages list for each wound type you will see the logic behind these values
switch(type)
if(CUT)
if (damage <= 5) return /datum/wound/cut/small
if (damage <= 15) return /datum/wound/cut/deep
if (damage <= 25) return /datum/wound/cut/flesh
if (damage <= 50) return /datum/wound/cut/gaping
if (damage <= 60) return /datum/wound/cut/gaping_big
return /datum/wound/cut/massive
if(BRUISE)
return /datum/wound/bruise
if(BURN)
if (damage <= 5) return /datum/wound/burn/moderate
if (damage <= 15) return /datum/wound/burn/large
if (damage <= 30) return /datum/wound/burn/severe
if (damage <= 40) return /datum/wound/burn/deep
return /datum/wound/burn/carbonised
/****************************************************
PROCESSING & UPDATING
****************************************************/
@@ -303,6 +275,8 @@ This function completely restores a damaged organ to perfect condition.
//Determines if we even need to process this organ.
/datum/organ/external/proc/need_process()
if(destspawn) //Missing limb is missing
return 0
if(status && status != ORGAN_ROBOT) // If it's robotic, that's fine it will have a status.
return 1
if(brute_dam || burn_dam)
@@ -310,21 +284,13 @@ This function completely restores a damaged organ to perfect condition.
if(last_dam != brute_dam + burn_dam) // Process when we are fully healed up.
last_dam = brute_dam + burn_dam
return 1
last_dam = brute_dam + burn_dam
else
last_dam = brute_dam + burn_dam
if(germ_level)
return 1
return 0
/datum/organ/external/process()
// Process wounds, doing healing etc. Only do this every few ticks to save processing power
if(owner.life_tick % wound_update_accuracy == 0)
update_wounds()
//Chem traces slowly vanish
if(owner.life_tick % 10 == 0)
for(var/chemID in trace_chemicals)
trace_chemicals[chemID] = trace_chemicals[chemID] - 1
if(trace_chemicals[chemID] <= 0)
trace_chemicals.Remove(chemID)
//Dismemberment
if(status & ORGAN_DESTROYED)
if(!destspawn && config.limbs_can_break)
@@ -336,56 +302,134 @@ This function completely restores a damaged organ to perfect condition.
owner.update_body(1)
return
// Process wounds, doing healing etc. Only do this every few ticks to save processing power
if(owner.life_tick % wound_update_accuracy == 0)
update_wounds()
//Chem traces slowly vanish
if(owner.life_tick % 10 == 0)
for(var/chemID in trace_chemicals)
trace_chemicals[chemID] = trace_chemicals[chemID] - 1
if(trace_chemicals[chemID] <= 0)
trace_chemicals.Remove(chemID)
//Bone fracurtes
if(config.bones_can_break && brute_dam > min_broken_damage * config.organ_health_multiplier && !(status & ORGAN_ROBOT))
src.fracture()
if(!(status & ORGAN_BROKEN))
perma_injury = 0
//Infections
update_germs()
return
//Updating germ levels. Handles organ germ levels and necrosis.
#define GANGREN_LEVEL_ONE 100
#define GANGREN_LEVEL_TWO 1000
#define GANGREN_LEVEL_TERMINAL 2500
#define GERM_TRANSFER_AMOUNT germ_level/500
/*
The INFECTION_LEVEL values defined in setup.dm control the time it takes to reach the different
infection levels. Since infection growth is exponential, you can adjust the time it takes to get
from one germ_level to another using the rough formula:
desired_germ_level = initial_germ_level*e^(desired_time_in_seconds/1000)
So if I wanted it to take an average of 15 minutes to get from level one (100) to level two
I would set INFECTION_LEVEL_TWO to 100*e^(15*60/1000) = 245. Note that this is the average time,
the actual time is dependent on RNG.
INFECTION_LEVEL_ONE below this germ level nothing happens, and the infection doesn't grow
INFECTION_LEVEL_TWO above this germ level the infection will start to spread to internal and adjacent organs
INFECTION_LEVEL_THREE above this germ level the player will take additional toxin damage per second, and will die in minutes without
antitox. also, above this germ level you will need to overdose on spaceacillin to reduce the germ_level.
Note that amputating the affected organ does in fact remove the infection from the player's body.
*/
/datum/organ/external/proc/update_germs()
if(status & ORGAN_ROBOT|ORGAN_DESTROYED) //Robotic limbs shouldn't be infected, nor should nonexistant limbs.
if(status & (ORGAN_ROBOT|ORGAN_DESTROYED) || (owner.species && owner.species.flags & IS_PLANT)) //Robotic limbs shouldn't be infected, nor should nonexistant limbs.
germ_level = 0
return
if(germ_level > 0 && owner.bodytemperature >= 170) //cryo stops germs from moving and doing their bad stuffs
//Syncing germ levels with external wounds
if(owner.bodytemperature >= 170) //cryo stops germs from moving and doing their bad stuffs
//** Syncing germ levels with external wounds
handle_germ_sync()
//** Handle antibiotics and curing infections
handle_antibiotics()
//** Handle the effects of infections
handle_germ_effects()
/datum/organ/external/proc/handle_germ_sync()
var/antibiotics = owner.reagents.get_reagent_amount("spaceacillin")
for(var/datum/wound/W in wounds)
//Open wounds can become infected
if (owner.germ_level > W.germ_level && W.infection_check())
W.germ_level++
if (antibiotics < 5)
for(var/datum/wound/W in wounds)
if(!W.bandaged && !W.salved)
W.germ_level = max(W.germ_level, germ_level) //Wounds get all the germs
if (W.germ_level > germ_level) //Badly infected wounds raise internal germ levels
germ_level++
//Infected wounds raise the organ's germ level
if (W.germ_level > germ_level)
germ_level++
break //limit increase to a maximum of one per second
if(germ_level > GANGREN_LEVEL_ONE && prob(round(germ_level/100)))
germ_level++
owner.adjustToxLoss(1)
/datum/organ/external/proc/handle_germ_effects()
var/antibiotics = owner.reagents.get_reagent_amount("spaceacillin")
if(germ_level > GANGREN_LEVEL_TWO)
germ_level++
owner.adjustToxLoss(1)
/*
if(germ_level > GANGREN_LEVEL_TERMINAL)
if (!(status & ORGAN_DEAD))
status |= ORGAN_DEAD
owner << "<span class='notice'>You can't feel your [display_name] anymore...</span>"
owner.update_body(1)
if (prob(10)) //Spreading the fun
if (children) //To child organs
for (var/datum/organ/external/child in children)
if (!(child.status & (ORGAN_DEAD|ORGAN_DESTROYED|ORGAN_ROBOT)))
child.germ_level += round(GERM_TRANSFER_AMOUNT)
if (parent)
if (!(parent.status & (ORGAN_DEAD|ORGAN_DESTROYED|ORGAN_ROBOT)))
parent.germ_level += round(GERM_TRANSFER_AMOUNT)
*/
if (germ_level > 0 && germ_level < INFECTION_LEVEL_ONE && prob(60)) //this could be an else clause, but it looks cleaner this way
germ_level-- //since germ_level increases at a rate of 1 per second with dirty wounds, prob(60) should give us about 5 minutes before level one.
if(germ_level >= INFECTION_LEVEL_ONE)
//having an infection raises your body temperature
var/fever_temperature = (owner.species.heat_level_1 - owner.species.body_temperature - 5)* min(germ_level/INFECTION_LEVEL_TWO, 1) + owner.species.body_temperature
//need to make sure we raise temperature fast enough to get around environmental cooling preventing us from reaching fever_temperature
owner.bodytemperature += between(0, (fever_temperature - T20C)/BODYTEMP_COLD_DIVISOR + 1, fever_temperature - owner.bodytemperature)
if(prob(round(germ_level/10)))
if (antibiotics < 5)
germ_level++
if (prob(10)) //adjust this to tweak how fast people take toxin damage from infections
owner.adjustToxLoss(1)
if(germ_level >= INFECTION_LEVEL_TWO && antibiotics < 5)
//spread the infection to internal organs
var/datum/organ/internal/target_organ = null //make internal organs become infected one at a time instead of all at once
for (var/datum/organ/internal/I in internal_organs)
if (I.germ_level > 0 && I.germ_level < min(germ_level, INFECTION_LEVEL_TWO)) //once the organ reaches whatever we can give it, or level two, switch to a different one
if (!target_organ || I.germ_level > target_organ.germ_level) //choose the organ with the highest germ_level
target_organ = I
if (!target_organ)
//figure out which organs we can spread germs to and pick one at random
var/list/candidate_organs = list()
for (var/datum/organ/internal/I in internal_organs)
if (I.germ_level < germ_level)
candidate_organs += I
if (candidate_organs.len)
target_organ = pick(candidate_organs)
if (target_organ)
target_organ.germ_level++
//spread the infection to child and parent organs
if (children)
for (var/datum/organ/external/child in children)
if (child.germ_level < germ_level && !(child.status & ORGAN_ROBOT))
if (child.germ_level < INFECTION_LEVEL_ONE*2 || prob(30))
child.germ_level++
if (parent)
if (parent.germ_level < germ_level && !(parent.status & ORGAN_ROBOT))
if (parent.germ_level < INFECTION_LEVEL_ONE*2 || prob(30))
parent.germ_level++
if(germ_level >= INFECTION_LEVEL_THREE && antibiotics < 30) //overdosing is necessary to stop severe infections
if (!(status & ORGAN_DEAD))
status |= ORGAN_DEAD
owner << "<span class='notice'>You can't feel your [display_name] anymore...</span>"
owner.update_body(1)
germ_level++
owner.adjustToxLoss(1)
//Updating wounds. Handles wound natural I had some free spachealing, internal bleedings and infections
/datum/organ/external/proc/update_wounds()
@@ -401,16 +445,15 @@ This function completely restores a damaged organ to perfect condition.
// let the GC handle the deletion of the wound
// Internal wounds get worse over time. Low temperatures (cryo) stop them.
if(W.internal && !W.is_treated() && owner.bodytemperature >= 170)
if(W.internal && owner.bodytemperature >= 170)
var/bicardose = owner.reagents.get_reagent_amount("bicaridine")
var/inaprovaline = owner.reagents.get_reagent_amount("inaprovaline")
if(!bicardose || !inaprovaline) //bicaridine and inaprovaline stop internal wounds from growing bigger with time, and also stop bleeding
if(!(W.can_autoheal() || (bicardose && inaprovaline))) //bicaridine and inaprovaline stop internal wounds from growing bigger with time, unless it is so small that it is already healing
W.open_wound(0.1 * wound_update_accuracy)
owner.vessel.remove_reagent("blood",0.05 * W.damage * wound_update_accuracy)
if(bicardose >= 30) //overdose of bicaridine begins healing IB
W.damage = max(0, W.damage - 0.2)
owner.vessel.remove_reagent("blood",0.02 * W.damage * wound_update_accuracy)
owner.vessel.remove_reagent("blood", wound_update_accuracy * W.damage/40) //line should possibly be moved to handle_blood, so all the bleeding stuff is in one place.
if(prob(1 * wound_update_accuracy))
owner.custom_pain("You feel a stabbing pain in your [display_name]!",1)
@@ -418,7 +461,7 @@ This function completely restores a damaged organ to perfect condition.
var/heal_amt = 0
// if damage >= 50 AFTER treatment then it's probably too severe to heal within the timeframe of a round.
if (W.is_treated() && W.wound_damage() < 50)
if (W.can_autoheal() && W.wound_damage() < 50)
heal_amt += 0.5
//we only update wounds once in [wound_update_accuracy] ticks so have to emulate realtime
@@ -433,8 +476,8 @@ This function completely restores a damaged organ to perfect condition.
// Salving also helps against infection
if(W.germ_level > 0 && W.salved && prob(2))
W.germ_level = 0
W.disinfected = 1
W.germ_level = 0
// sync the organ's damage with its wounds
src.update_damages()
@@ -525,13 +568,27 @@ This function completely restores a damaged organ to perfect condition.
src.status &= ~ORGAN_BROKEN
src.status &= ~ORGAN_BLEEDING
src.status &= ~ORGAN_SPLINTED
src.status &= ~ORGAN_DEAD
for(var/implant in implants)
del(implant)
germ_level = 0
//Replace all wounds on that arm with one wound on parent organ.
wounds.Cut()
if (parent)
var/datum/wound/W
if(max_damage < 50)
W = new/datum/wound/lost_limb/small(max_damage)
else
W = new/datum/wound/lost_limb(max_damage)
parent.wounds += W
parent.update_damages()
update_damages()
// If any organs are attached to this, destroy them
for(var/datum/organ/external/O in owner.organs)
if(O.parent == src)
O.droplimb(1)
for(var/datum/organ/external/O in children)
O.droplimb(1)
var/obj/organ //Dropped limb object
switch(body_part)
@@ -581,33 +638,37 @@ This function completely restores a damaged organ to perfect condition.
if(!(status & ORGAN_ROBOT))
organ = new /obj/item/weapon/organ/l_foot(owner.loc, owner)
owner.u_equip(owner.shoes)
destspawn = 1
//Robotic limbs explode if sabotaged.
if(status & ORGAN_ROBOT && !no_explode && sabotaged)
owner.visible_message("\red \The [owner]'s [display_name] explodes violently!",\
"\red <b>Your [display_name] explodes!</b>",\
"You hear an explosion followed by a scream!")
explosion(get_turf(owner),-1,-1,2,3)
var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread()
spark_system.set_up(5, 0, owner)
spark_system.attach(owner)
spark_system.start()
spawn(10)
del(spark_system)
owner.visible_message("\red [owner.name]'s [display_name] flies off in an arc.",\
"<span class='moderate'><b>Your [display_name] goes flying off!</b></span>",\
"You hear a terrible sound of ripping tendons and flesh.")
if(organ)
destspawn = 1
//Robotic limbs explode if sabotaged.
if(status & ORGAN_ROBOT && !no_explode && sabotaged)
owner.visible_message("\red \The [owner]'s [display_name] explodes violently!",\
"\red <b>Your [display_name] explodes!</b>",\
"You hear an explosion followed by a scream!")
explosion(get_turf(owner),-1,-1,2,3)
var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread()
spark_system.set_up(5, 0, owner)
spark_system.attach(owner)
spark_system.start()
spawn(10)
del(spark_system)
owner.visible_message("\red [owner.name]'s [display_name] flies off in an arc.",\
"<span class='moderate'><b>Your [display_name] goes flying off!</b></span>",\
"You hear a terrible sound of ripping tendons and flesh.")
//Throw organs around
var/lol = pick(cardinal)
step(organ,lol)
owner.update_body(1)
owner.update_body(1)
// OK so maybe your limb just flew off, but if it was attached to a pair of cuffs then hooray! Freedom!
release_restraints()
// OK so maybe your limb just flew off, but if it was attached to a pair of cuffs then hooray! Freedom!
release_restraints()
if(vital)
owner.death()
/****************************************************
HELPERS
@@ -637,6 +698,15 @@ This function completely restores a damaged organ to perfect condition.
W.bandaged = 1
return rval
/datum/organ/external/proc/disinfect()
var/rval = 0
for(var/datum/wound/W in wounds)
if(W.internal) continue
rval |= !W.disinfected
W.disinfected = 1
W.germ_level = 0
return rval
/datum/organ/external/proc/clamp()
var/rval = 0
src.status &= ~ORGAN_BLEEDING
@@ -654,8 +724,10 @@ This function completely restores a damaged organ to perfect condition.
return rval
/datum/organ/external/proc/fracture()
if(status & ORGAN_BROKEN)
return
owner.visible_message(\
"\red You hear a loud cracking sound coming from \the [owner].",\
"\red <b>Something feels like it shattered in your [display_name]!</b>",\
@@ -672,6 +744,25 @@ This function completely restores a damaged organ to perfect condition.
if (prob(25))
release_restraints()
// This is mostly for the ninja suit to stop ninja being so crippled by breaks.
// TODO: consider moving this to a suit proc or process() or something during
// hardsuit rewrite.
if(!(status & ORGAN_SPLINTED) && istype(owner,/mob/living/carbon/human))
var/mob/living/carbon/human/H = owner
if(H.wear_suit && istype(H.wear_suit,/obj/item/clothing/suit/space))
var/obj/item/clothing/suit/space/suit = H.wear_suit
if(isnull(suit.supporting_limbs))
return
owner << "You feel \the [suit] constrict about your [display_name], supporting it."
status |= ORGAN_SPLINTED
suit.supporting_limbs |= src
return
/datum/organ/external/proc/robotize()
src.status &= ~ORGAN_BROKEN
src.status &= ~ORGAN_BLEEDING
@@ -696,9 +787,9 @@ This function completely restores a damaged organ to perfect condition.
/datum/organ/external/proc/get_damage() //returns total damage
return max(brute_dam + burn_dam - perma_injury, perma_injury) //could use health?
/datum/organ/external/proc/is_infected()
/datum/organ/external/proc/has_infected_wound()
for(var/datum/wound/W in wounds)
if(W.germ_level > 100)
if(W.germ_level > INFECTION_LEVEL_ONE)
return 1
return 0
@@ -715,6 +806,43 @@ This function completely restores a damaged organ to perfect condition.
/datum/organ/external/proc/is_usable()
return !(status & (ORGAN_DESTROYED|ORGAN_MUTATED|ORGAN_DEAD))
/datum/organ/external/proc/is_broken()
return ((status & ORGAN_BROKEN) && !(status & ORGAN_SPLINTED))
/datum/organ/external/proc/is_malfunctioning()
return ((status & ORGAN_ROBOT) && prob(brute_dam + burn_dam))
//for arms and hands
/datum/organ/external/proc/process_grasp(var/obj/item/c_hand, var/hand_name)
if (!c_hand)
return
if(is_broken())
owner.u_equip(c_hand)
var/emote_scream = pick("screams in pain and", "lets out a sharp cry and", "cries out and")
owner.emote("me", 1, "[(owner.species && owner.species.flags & NO_PAIN) ? "" : emote_scream ] drops what they were holding in their [hand_name]!")
if(is_malfunctioning())
owner.u_equip(c_hand)
owner.emote("me", 1, "drops what they were holding, their [hand_name] malfunctioning!")
var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread()
spark_system.set_up(5, 0, owner)
spark_system.attach(owner)
spark_system.start()
spawn(10)
del(spark_system)
/datum/organ/external/proc/embed(var/obj/item/weapon/W, var/silent = 0)
if(!silent)
owner.visible_message("<span class='danger'>\The [W] sticks in the wound!</span>")
implants += W
owner.embedded_flag = 1
owner.verbs += /mob/proc/yank_out_object
W.add_blood(owner)
if(ismob(W.loc))
var/mob/living/H = W.loc
H.drop_item()
W.loc = owner
/****************************************************
ORGAN DEFINES
****************************************************/
@@ -726,7 +854,7 @@ This function completely restores a damaged organ to perfect condition.
max_damage = 75
min_broken_damage = 40
body_part = UPPER_TORSO
vital = 1
/datum/organ/external/groin
name = "groin"
@@ -735,6 +863,7 @@ This function completely restores a damaged organ to perfect condition.
max_damage = 50
min_broken_damage = 30
body_part = LOWER_TORSO
vital = 1
/datum/organ/external/l_arm
name = "l_arm"
@@ -744,6 +873,10 @@ This function completely restores a damaged organ to perfect condition.
min_broken_damage = 20
body_part = ARM_LEFT
process()
..()
process_grasp(owner.l_hand, "left hand")
/datum/organ/external/l_leg
name = "l_leg"
display_name = "left leg"
@@ -761,6 +894,10 @@ This function completely restores a damaged organ to perfect condition.
min_broken_damage = 20
body_part = ARM_RIGHT
process()
..()
process_grasp(owner.r_hand, "right hand")
/datum/organ/external/r_leg
name = "r_leg"
display_name = "right leg"
@@ -796,6 +933,10 @@ This function completely restores a damaged organ to perfect condition.
min_broken_damage = 15
body_part = HAND_RIGHT
process()
..()
process_grasp(owner.r_hand, "right hand")
/datum/organ/external/l_hand
name = "l_hand"
display_name = "left hand"
@@ -804,6 +945,10 @@ This function completely restores a damaged organ to perfect condition.
min_broken_damage = 15
body_part = HAND_LEFT
process()
..()
process_grasp(owner.l_hand, "left hand")
/datum/organ/external/head
name = "head"
icon_name = "head"
@@ -812,6 +957,7 @@ This function completely restores a damaged organ to perfect condition.
min_broken_damage = 40
body_part = HEAD
var/disfigured = 0
vital = 1
/datum/organ/external/head/get_icon(var/icon/race_icon, var/icon/deform_icon)
if (!owner)
+52 -7
View File
@@ -21,15 +21,47 @@
return damage >= min_broken_damage
/datum/organ/internal/New(mob/living/carbon/human/H)
..()
var/datum/organ/external/E = H.organs_by_name[src.parent_organ]
if(E.internal_organs == null)
E.internal_organs = list()
E.internal_organs += src
H.internal_organs[src.name] = src
E.internal_organs |= src
H.internal_organs |= src
src.owner = H
/datum/organ/internal/process()
//Process infections
if (robotic >= 2 || (owner.species && owner.species.flags & IS_PLANT)) //TODO make robotic internal and external organs separate types of organ instead of a flag
germ_level = 0
return
if(owner.bodytemperature >= 170) //cryo stops germs from moving and doing their bad stuffs
//** Handle antibiotics and curing infections
handle_antibiotics()
//** Handle the effects of infections
var/antibiotics = owner.reagents.get_reagent_amount("spaceacillin")
if (germ_level > 0 && germ_level < INFECTION_LEVEL_ONE/2 && prob(30))
germ_level--
if (germ_level >= INFECTION_LEVEL_ONE/2)
//aiming for germ level to go from ambient to INFECTION_LEVEL_TWO in an average of 15 minutes
if(antibiotics < 5 && prob(round(germ_level/6)))
germ_level++
if (germ_level >= INFECTION_LEVEL_TWO)
var/datum/organ/external/parent = owner.get_organ(parent_organ)
//spread germs
if (antibiotics < 5 && parent.germ_level < germ_level && ( parent.germ_level < INFECTION_LEVEL_ONE*2 || prob(30) ))
parent.germ_level++
if (prob(3)) //about once every 30 seconds
take_damage(1,silent=prob(30))
/datum/organ/internal/proc/take_damage(amount, var/silent=0)
if(src.robotic == 2)
src.damage += (amount * 0.8)
@@ -40,7 +72,6 @@
if (!silent)
owner.custom_pain("Something inside your [parent.display_name] hurts a lot.", 1)
/datum/organ/internal/proc/emp_act(severity)
switch(robotic)
if(0)
@@ -90,13 +121,18 @@
parent_organ = "chest"
process()
..()
if (germ_level > INFECTION_LEVEL_ONE)
if(prob(5))
owner.emote("cough") //respitory tract infection
if(is_bruised())
if(prob(2))
spawn owner.emote("me", 1, "coughs up blood!")
owner.drip(10)
if(prob(4))
spawn owner.emote("me", 1, "gasps for air!")
owner.losebreath += 5
owner.losebreath += 15
/datum/organ/internal/liver
name = "liver"
@@ -104,6 +140,14 @@
var/process_accuracy = 10
process()
..()
if (germ_level > INFECTION_LEVEL_ONE)
if(prob(1))
owner << "\red Your skin itches."
if (germ_level > INFECTION_LEVEL_TWO)
if(prob(1))
spawn owner.vomit()
if(owner.life_tick % process_accuracy == 0)
if(src.damage < 0)
src.damage = 0
@@ -115,9 +159,9 @@
src.damage += 0.2 * process_accuracy
//Damaged one shares the fun
else
var/victim = pick(owner.internal_organs)
var/datum/organ/internal/O = owner.internal_organs[victim]
O.damage += 0.2 * process_accuracy
var/datum/organ/internal/O = pick(owner.internal_organs)
if(O)
O.damage += 0.2 * process_accuracy
//Detox can heal small amounts of damage
if (src.damage && src.damage < src.min_bruised_damage && owner.reagents.has_reagent("anti_toxin"))
@@ -146,6 +190,7 @@
parent_organ = "head"
process() //Eye damage replaces the old eye_stat var.
..()
if(is_bruised())
owner.eye_blurry = 20
if(is_broken())
+1 -2
View File
@@ -102,8 +102,7 @@ mob/living/carbon/human/proc/handle_pain()
pain(damaged_organ.display_name, maxdam, 0)
// Damage to internal organs hurts a lot.
for(var/organ_name in internal_organs)
var/datum/organ/internal/I = internal_organs[organ_name]
for(var/datum/organ/internal/I in internal_organs)
if(I.damage > 2) if(prob(2))
var/datum/organ/external/parent = get_organ(I.parent_organ)
src.custom_pain("You feel a sharp pain in your [parent.display_name]", 1)
+98 -28
View File
@@ -7,7 +7,7 @@
var/current_stage = 0
// description of the wound
var/desc = ""
var/desc = "wound" //default in case something borks
// amount of damage this wound causes
var/damage = 0
@@ -31,7 +31,7 @@
var/germ_level = 0
/* These are defined by the wound type and should not be changed */
// stages such as "cut", "deep cut", etc.
var/list/stages
// internal wounds can only be fixed through surgery
@@ -51,7 +51,7 @@
// helper lists
var/tmp/list/desc_list = list()
var/tmp/list/damage_list = list()
New(var/damage)
created = world.time
@@ -65,7 +65,7 @@
src.damage = damage
max_bleeding_stage = src.desc_list.len - max_bleeding_stage
// initialize with the appropriate stage
src.init_stage(damage)
@@ -74,7 +74,7 @@
// returns 1 if there's a next stage, 0 otherwise
proc/init_stage(var/initial_damage)
current_stage = stages.len
while(src.current_stage > 1 && src.damage_list[current_stage-1] <= initial_damage / src.amount)
src.current_stage--
@@ -84,25 +84,26 @@
// the amount of damage per wound
proc/wound_damage()
return src.damage / src.amount
// checks whether the wound has been appropriately treated
// always returns 1 for wounds that are too minor to need treatment
proc/is_treated()
proc/can_autoheal()
if(src.wound_damage() <= autoheal_cutoff)
return 1
return is_treated()
// checks whether the wound has been appropriately treated
proc/is_treated()
if(damage_type == BRUISE || damage_type == CUT)
return bandaged
else if(damage_type == BURN)
return salved
// Checks whether other other can be merged into src.
proc/can_merge(var/datum/wound/other)
if (other.type != src.type) return 0
if (other.current_stage != src.current_stage) return 0
if (other.damage_type != src.damage_type) return 0
if (!(other.is_treated()) != !(src.is_treated())) return 0
if (!(other.can_autoheal()) != !(src.can_autoheal())) return 0
if (!(other.bandaged) != !(src.bandaged)) return 0
if (!(other.clamped) != !(src.clamped)) return 0
if (!(other.salved) != !(src.salved)) return 0
@@ -119,21 +120,29 @@
// checks if wound is considered open for external infections
// untreated cuts (and bleeding bruises) and burns are possibly infectable, chance higher if wound is bigger
proc/can_infect()
if (is_treated() && damage < 10)
proc/infection_check()
if (damage < 10) //small cuts, tiny bruises, and moderate burns shouldn't be infectable.
return 0
if (is_treated() && damage < 25) //anything less than a flesh wound (or equivalent) isn't infectable if treated properly
return 0
if (disinfected)
germ_level = 0 //reset this, just in case
return 0
if (damage_type == BRUISE && !bleeding()) //bruises only infectable if bleeding
return 0
var/dam_coef = round(damage/10)
switch (damage_type)
if (BRUISE)
return prob(dam_coef*5) && bleeding() //bruises only infectable if bleeding
return prob(dam_coef*5)
if (BURN)
return prob(dam_coef*10)
if (CUT)
return prob(dam_coef*20)
return 0
// heal the given amount of damage, and if the given amount of damage was more
// than what needed to be healed, return how much heal was left
// set @heals_internal to also heal internal organ damage
@@ -170,23 +179,71 @@
proc/can_worsen(damage_type, damage)
if (src.damage_type != damage_type)
return 0 //incompatible damage types
if (src.amount > 1)
return 0
//with 1.5*, a shallow cut will be able to carry at most 30 damage,
//37.5 for a deep cut
//52.5 for a flesh wound, etc.
var/max_wound_damage = 1.5*src.damage_list[1]
if (src.damage + damage > max_wound_damage)
return 0
return 1
proc/bleeding()
// internal wounds don't bleed in the sense of this function
return ((wound_damage() > 30 || bleed_timer > 0) && !(bandaged||clamped) && (damage_type == BRUISE && wound_damage() >= 20 || damage_type == CUT && wound_damage() >= 5) && current_stage <= max_bleeding_stage && !src.internal)
if (src.internal)
return 0 // internal wounds don't bleed in the sense of this function
if (current_stage > max_bleeding_stage)
return 0
if (bandaged||clamped)
return 0
if (wound_damage() <= 30 && bleed_timer <= 0)
return 0 //Bleed timer has run out. Wounds with more than 30 damage don't stop bleeding on their own.
return (damage_type == BRUISE && wound_damage() >= 20 || damage_type == CUT && wound_damage() >= 5)
/** WOUND DEFINITIONS **/
//Note that the MINIMUM damage before a wound can be applied should correspond to
//the damage amount for the stage with the same name as the wound.
//e.g. /datum/wound/cut/deep should only be applied for 15 damage and up,
//because in it's stages list, "deep cut" = 15.
/proc/get_wound_type(var/type = CUT, var/damage)
switch(type)
if(CUT)
switch(damage)
if(70 to INFINITY)
return /datum/wound/cut/massive
if(60 to 70)
return /datum/wound/cut/gaping_big
if(50 to 60)
return /datum/wound/cut/gaping
if(25 to 50)
return /datum/wound/cut/flesh
if(15 to 25)
return /datum/wound/cut/deep
if(0 to 15)
return /datum/wound/cut/small
if(BRUISE)
return /datum/wound/bruise
if(BURN)
switch(damage)
if(50 to INFINITY)
return /datum/wound/burn/carbonised
if(40 to 50)
return /datum/wound/burn/deep
if(30 to 40)
return /datum/wound/burn/severe
if(15 to 30)
return /datum/wound/burn/large
if(0 to 15)
return /datum/wound/burn/moderate
return null //no wound
/** CUTS **/
/datum/wound/cut/small
@@ -201,7 +258,7 @@
damage_type = CUT
/datum/wound/cut/flesh
max_bleeding_stage = 3
max_bleeding_stage = 4
stages = list("ugly ripped flesh wound" = 35, "ugly flesh wound" = 30, "flesh wound" = 25, "blood soaked clot" = 15, "large scab" = 5, "fresh skin" = 0)
damage_type = CUT
@@ -230,27 +287,40 @@ datum/wound/cut/massive
/** BURNS **/
/datum/wound/burn/moderate
stages = list("ripped burn" = 10, "moderate burn" = 5, "moderate salved burn" = 2, "fresh skin" = 0)
stages = list("ripped burn" = 10, "moderate burn" = 5, "healing moderate burn" = 2, "fresh skin" = 0)
damage_type = BURN
/datum/wound/burn/large
stages = list("ripped large burn" = 20, "large burn" = 15, "large salved burn" = 5, "fresh skin" = 0)
stages = list("ripped large burn" = 20, "large burn" = 15, "healing large burn" = 5, "fresh skin" = 0)
damage_type = BURN
/datum/wound/burn/severe
stages = list("ripped severe burn" = 35, "severe burn" = 30, "severe salved burn" = 10, "burn scar" = 0)
stages = list("ripped severe burn" = 35, "severe burn" = 30, "healing severe burn" = 10, "burn scar" = 0)
damage_type = BURN
/datum/wound/burn/deep
stages = list("ripped deep burn" = 45, "deep burn" = 40, "deep salved burn" = 15, "large burn scar" = 0)
stages = list("ripped deep burn" = 45, "deep burn" = 40, "healing deep burn" = 15, "large burn scar" = 0)
damage_type = BURN
/datum/wound/burn/carbonised
stages = list("carbonised area" = 50, "treated carbonised area" = 20, "massive burn scar" = 0)
stages = list("carbonised area" = 50, "healing carbonised area" = 20, "massive burn scar" = 0)
damage_type = BURN
/** INTERNAL BLEEDING **/
/datum/wound/internal_bleeding
internal = 1
stages = list("severed vein" = 30, "cut vein" = 20, "damaged vein" = 10, "bruised vein" = 5)
stages = list("severed artery" = 30, "cut artery" = 20, "damaged artery" = 10, "bruised artery" = 5)
autoheal_cutoff = 5
max_bleeding_stage = 0 //all stages bleed. It's called internal bleeding after all.
/** EXTERNAL ORGAN LOSS **/
/datum/wound/lost_limb
damage_type = CUT
stages = list("ripped stump" = 65, "bloody stump" = 50, "clotted stump" = 25, "scarred stump" = 0)
max_bleeding_stage = 3
can_merge(var/datum/wound/other)
return 0 //cannot be merged
/datum/wound/lost_limb/small
stages = list("ripped stump" = 40, "bloody stump" = 30, "clotted stump" = 15, "scarred stump" = 0)