mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-11 02:34:00 +00:00
Merge branch 'necrosis' into bleeding-edge-freeze
This commit is contained in:
@@ -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()
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user