Merge branch 'necrosis' into bleeding-edge-freeze

This commit is contained in:
Chinsky
2013-02-22 23:46:54 +04:00
14 changed files with 125 additions and 128 deletions

View File

@@ -66,6 +66,7 @@ var/global/list/backbaglist = list("Nothing", "Backpack", "Satchel", "Satchel Al
for(var/T in paths)
var/datum/surgery_step/S = new T
surgery_steps += S
sort_surgeries()
/* // Uncomment to debug chemical reaction list.
/client/verb/debug_chemical_list()

View File

@@ -31,6 +31,7 @@
var/status = 0
var/open = 0
var/stage = 0
var/cavity = 0
var/obj/item/hidden = null
var/list/implants = list()
@@ -239,25 +240,65 @@
// process wounds, doing healing etc., only do this every 4 ticks to save processing power
if(owner.life_tick % wound_update_accuracy == 0)
update_wounds()
//Dismemberment
if(status & ORGAN_DESTROYED)
if(!destspawn && config.limbs_can_break)
droplimb()
return
if(!(status & ORGAN_BROKEN))
perma_injury = 0
if(parent)
if(parent.status & ORGAN_DESTROYED)
status |= ORGAN_DESTROYED
owner.update_body(1)
return
//Bone fracurtes
if(config.bones_can_break && brute_dam > min_broken_damage * config.organ_health_multiplier && !(status & ORGAN_ROBOT))
src.fracture()
if(germ_level > 0)
for(var/datum/wound/W in wounds) if(!W.bandaged && !W.salved)
W.germ_level = max(W.germ_level, germ_level)
if(!(status & ORGAN_BROKEN))
perma_injury = 0
update_germs()
update_icon()
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
/datum/organ/external/proc/update_germs()
if(germ_level > 0 && owner.bodytemperature >= 170) //cryo stops germs from moving and doing their bad stuffs
//Syncing germ levels with external wounds
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++
if(germ_level > GANGREN_LEVEL_ONE && prob(round(germ_level/100)))
germ_level++
owner.adjustToxLoss(1)
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)
*/
//Updating wounds. Handles wound natural healing, internal bleedings and infections
/datum/organ/external/proc/update_wounds()
for(var/datum/wound/W in wounds)
@@ -281,14 +322,12 @@
// amount of healing is spread over all the wounds
W.heal_damage((wound_update_accuracy * amount * W.amount * config.organ_regeneration_multiplier) / (20*owner.number_wounds+1))
if(W.germ_level > 100 && prob(10))
owner.adjustToxLoss(1 * wound_update_accuracy)
if(W.germ_level > 1000)
owner.adjustToxLoss(1 * wound_update_accuracy)
// Salving also helps against infection
if(W.germ_level > 0 && W.salved && prob(2))
W.germ_level = 0
W.disinfected = 1
// sync the organ's damage with its wounds
src.update_damages()

View File

@@ -96,6 +96,23 @@
else if(damage_type == BURN)
return salved
// 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)
return 0
if (disinfected)
return 0
var/dam_coef = round(damage/10)
switch (damage_type)
if (BRUISE)
return prob(dam_coef*5) && bleeding() //bruises only infectable if bleeding
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

View File

@@ -920,3 +920,31 @@
E.ruptured_lungs = 1
/mob/living/carbon/human/verb/simulate()
set name = "sim"
set background = 1
var/damage = input("Wound damage","Wound damage") as num
var/germs = 0
var/tdamage = 0
var/ticks = 0
while (germs < 2501 && ticks < 100000 && round(damage/10)*20)
diary << "VIRUS TESTING: [ticks] : germs [germs] tdamage [tdamage] prob [round(damage/10)*20]"
ticks++
if (prob(round(damage/10)*20))
germs++
if (germs == 100)
world << "Reached stage 1 in [ticks] ticks"
if (germs > 100)
if (prob(10))
damage++
germs++
if (germs == 1000)
world << "Reached stage 2 in [ticks] ticks"
if (germs > 1000)
damage++
germs++
if (germs == 2500)
world << "Reached stage 3 in [ticks] ticks"
world << "Mob took [tdamage] tox damage"

View File

@@ -222,6 +222,7 @@ proc/get_damage_icon_part(damage_state, body_part)
var/husk_color_mod = rgb(96,88,80)
var/hulk_color_mod = rgb(48,224,40)
var/plant_color_mod = rgb(144,224,144)
var/necrosis_color_mod = rgb(10,50,0)
var/husk = (HUSK in src.mutations) //100% unnecessary -Agouri //nope, do you really want to iterate through src.mutations repeatedly? -Pete
var/fat = (FAT in src.mutations)
@@ -283,6 +284,9 @@ proc/get_damage_icon_part(damage_state, body_part)
temp = new /icon(icobase, "[part.icon_name]")
if(part.status & ORGAN_ROBOT)
temp.GrayScale()
if(part.status & ORGAN_DEAD)
temp.ColorTone(necrosis_color_mod)
temp.SetIntensity(0.7)
else if(!skeleton)
if(husk)
temp.ColorTone(husk_color_mod)

View File

@@ -4,6 +4,7 @@
//////////////////////////////////////////////////////////////////
/datum/surgery_step/appendectomy/
priority = 2
can_infect = 1
blood_level = 1
can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)

View File

@@ -4,6 +4,7 @@
//////////////////////////////////////////////////////////////////
/datum/surgery_step/glue_bone
priority = 2
required_tool = /obj/item/weapon/bonegel
allowed_tools = list(/obj/item/weapon/screwdriver)
can_infect = 1

View File

@@ -4,6 +4,7 @@
//////////////////////////////////////////////////////////////////
/datum/surgery_step/brain/
priority = 2
blood_level = 1
can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
return target_zone == "head" && hasorgans(target)

View File

@@ -4,6 +4,7 @@
//////////////////////////////////////////////////////////////////
/datum/surgery_step/eye
priority = 2
can_infect = 1
can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
if (!hasorgans(target))

View File

@@ -4,6 +4,7 @@
//////////////////////////////////////////////////////////////////
/datum/surgery_step/face
priority = 2
can_infect = 0
can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
if (!hasorgans(target))

View File

@@ -5,6 +5,7 @@
/datum/surgery_step/fix_vein
priority = 2
required_tool = /obj/item/weapon/FixOVein
allowed_tools = list(/obj/item/weapon/cable_coil)
can_infect = 1
@@ -45,120 +46,3 @@
user.visible_message("\red [user]'s hand slips, smearing [tool] in the incision in [target]'s [affected.display_name]!" , \
"\red Your hand slips, smearing [tool] in the incision in [target]'s [affected.display_name]!")
affected.take_damage(5, 0)
//////////////////////////////////////////////////////////////////
// IMPLANT REMOVAL SURGERY //
//////////////////////////////////////////////////////////////////
/datum/surgery_step/implant_removal
required_tool = /obj/item/weapon/hemostat
allowed_tools = list(/obj/item/weapon/wirecutters, /obj/item/weapon/kitchen/utensil/fork)
min_duration = 80
max_duration = 100
can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/datum/organ/external/affected = target.get_organ(target_zone)
return affected.open == 2 && !(affected.status & ORGAN_BLEEDING)
begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/datum/organ/external/affected = target.get_organ(target_zone)
user.visible_message("[user] starts poking around inside the incision on [target]'s [affected.display_name] with \the [tool].", \
"You start poking around inside the incision on [target]'s [affected.display_name] with \the [tool]" )
target.custom_pain("The pain in your chest is living hell!",1)
..()
end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/datum/organ/external/chest/affected = target.get_organ(target_zone)
var/find_prob = 0
if (affected.implants.len)
var/obj/item/weapon/implant/imp = affected.implants[1]
if (imp.islegal())
find_prob +=60
else
find_prob +=40
if (isright(tool))
find_prob +=20
if (prob(find_prob))
user.visible_message("\blue [user] takes something out of incision on [target]'s [affected.display_name] with \the [tool].", \
"\blue You take something out of incision on [target]'s [affected.display_name]s with \the [tool]." )
affected.implants -= imp
imp.loc = get_turf(target)
imp.imp_in = null
imp.implanted = 0
else if (affected.hidden)
user.visible_message("\blue [user] takes something out of incision on [target]'s [affected.display_name] with \the [tool].", \
"\blue You take something out of incision on [target]'s [affected.display_name]s with \the [tool]." )
affected.hidden.loc = get_turf(target)
if(!affected.hidden.blood_DNA)
affected.hidden.blood_DNA = list()
affected.hidden.blood_DNA[target.dna.unique_enzymes] = target.dna.b_type
affected.hidden.update_icon()
affected.hidden = null
else
user.visible_message("\blue [user] could not find anything inside [target]'s [affected.display_name], and pulls \the [tool] out.", \
"\blue You could not find anything inside [target]'s [affected.display_name]." )
fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/datum/organ/external/chest/affected = target.get_organ(target_zone)
user.visible_message("\red [user]'s hand slips, scraping tissue inside [target]'s [affected.display_name] with \the [tool]!", \
"\red Your hand slips, scraping tissue inside [target]'s [affected.display_name] with \the [tool]!")
affected.createwound(CUT, 20)
if (affected.implants.len)
var/fail_prob = 10
if (!isright(tool))
fail_prob += 30
if (prob(fail_prob))
var/obj/item/weapon/implant/imp = affected.implants[1]
user.visible_message("\red Something beeps inside [target]'s [affected.display_name]!")
playsound(imp.loc, 'sound/items/countdown.ogg', 75, 1, -3)
spawn(25)
imp.activate()
//////////////////////////////////////////////////////////////////
// ITEM PLACEMENT SURGERY //
//////////////////////////////////////////////////////////////////
/datum/surgery_step/item_place
required_tool = /obj/item
min_duration = 80
max_duration = 100
var/max_size = 2 //maximum w_class of item that fits.
can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/datum/organ/external/affected = target.get_organ(target_zone)
if (affected.name in list("chest","groin","head"))
max_size = 3
else
max_size = 2
return affected.open == 2 && !(affected.status & ORGAN_BLEEDING) && tool.w_class <= max_size && !affected.hidden
begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/datum/organ/external/affected = target.get_organ(target_zone)
user.visible_message("[user] starts putting [tool] inside the incision on [target]'s [affected.display_name].", \
"You start putting [tool] inside the incision on [target]'s [affected.display_name]." )
target.custom_pain("The pain in your chest is living hell!",1)
..()
end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/datum/organ/external/chest/affected = target.get_organ(target_zone)
user.visible_message("\blue [user] puts [tool] inside [target]'s [affected.display_name].", \
"\blue You put [tool] inside [target]'s [affected.display_name]." )
if (tool.w_class > max_size/2 && prob(50))
user << "\red You tear some vessels trying to fit such big object in this cavity."
var/datum/wound/internal_bleeding/I = new (15)
affected.wounds += I
affected.owner.custom_pain("You feel something rip in your [affected.display_name]!", 1)
user.drop_item()
affected.hidden = tool
tool.loc = target
fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/datum/organ/external/chest/affected = target.get_organ(target_zone)
user.visible_message("\red [user]'s hand slips, scraping tissue inside [target]'s [affected.display_name] with \the [tool]!", \
"\red Your hand slips, scraping tissue inside [target]'s [affected.display_name] with \the [tool]!")
affected.createwound(CUT, 20)

View File

@@ -3,6 +3,7 @@
// GENERIC RIBCAGE SURGERY //
//////////////////////////////////////////////////////////////////
/datum/surgery_step/ribcage
priority = 2
can_infect = 1
blood_level = 1
can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
@@ -195,4 +196,4 @@
var/datum/organ/external/chest/affected = target.get_organ("chest")
user.visible_message("\red [user]'s hand slips, slicing an artery inside [target]'s chest with \the [tool]!", \
"\red Your hand slips, slicing an artery inside [target]'s chest with \the [tool]!")
affected.createwound(CUT, 20)
affected.createwound(CUT, 20)

View File

@@ -1,6 +1,7 @@
/* SURGERY STEPS */
/datum/surgery_step
var/priority = 0 //steps with higher priority would be attempted first
// type path referencing the required tool for this step
var/required_tool = null
@@ -78,6 +79,22 @@ proc/do_surgery(mob/living/M, mob/living/user, obj/item/tool)
return 1 //don't want to do weapony things after surgery
return 0
proc/sort_surgeries()
var/gap = surgery_steps.len
var/swapped = 1
while (gap > 1 || swapped)
swapped = 0
if(gap > 1)
gap = round(gap / 1.247330950103979)
if(gap < 1)
gap = 1
for(var/i = 1; gap + i <= surgery_steps.len; i++)
var/datum/surgery_step/l = surgery_steps[i] //Fucking hate
var/datum/surgery_step/r = surgery_steps[gap+i] //how lists work here
if(l.priority < r.priority)
surgery_steps.Swap(i, gap + i)
swapped = 1
/datum/surgery_status/
var/eyes = 0
var/face = 0

View File

@@ -580,6 +580,7 @@ var/list/TAGGERLOCATIONS = list("Disposals",
#define ORGAN_ROBOT 128
#define ORGAN_SPLINTED 256
#define SALVED 512
#define ORGAN_DEAD 1024
#define ROUNDSTART_LOGOUT_REPORT_TIME 6000 //Amount of time (in deciseconds) after the rounds starts, that the player disconnect report is issued.