Collapsed all organs into one object type. Added more interesting amputation. Added dislocation. WIP.

This commit is contained in:
Zuhayr
2015-03-11 21:17:51 +10:30
parent 9c30024ca0
commit e0f23aead5
115 changed files with 1295 additions and 1372 deletions

View File

@@ -65,7 +65,7 @@ var/const/BLOOD_VOLUME_SURVIVE = 122
// Damaged heart virtually reduces the blood volume, as the blood isn't
// being pumped properly anymore.
if(species && species.has_organ["heart"])
var/datum/organ/internal/heart/heart = internal_organs_by_name["heart"]
var/obj/item/organ/heart/heart = internal_organs_by_name["heart"]
if(!heart)
blood_volume = 0
@@ -127,7 +127,7 @@ var/const/BLOOD_VOLUME_SURVIVE = 122
//Bleeding out
var/blood_max = 0
for(var/datum/organ/external/temp in organs)
for(var/obj/item/organ/external/temp in organs)
if(!(temp.status & ORGAN_BLEEDING) || temp.status & ORGAN_ROBOT)
continue
for(var/datum/wound/W in temp.wounds) if(W.bleeding())

View File

@@ -1,26 +1,152 @@
/datum/organ
var/name = "organ"
var/list/organ_cache = list()
/obj/item/organ
name = "organ"
var/mob/living/carbon/human/owner = null
var/status = 0
var/vital //Lose a vital limb, die immediately.
var/damage = 0 // amount of damage to the organ
var/min_bruised_damage = 10
var/min_broken_damage = 30
var/max_damage
var/organ_tag = "organ"
var/parent_organ = "chest"
var/robotic = 0 //For being a robot
var/rejecting // Is this organ already being rejected?
var/list/transplant_data
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
germ_level = 0
var/germ_level = 0 // INTERNAL germs inside the organ, this is BAD if it's greater than INFECTION_LEVEL_ONE
/obj/item/organ/New(var/newloc, var/mob/living/carbon/holder)
..(newloc)
proc/process()
return 0
create_reagents(5)
proc/receive_chem(chemical as obj)
return 0
if(!max_damage) max_damage = min_broken_damage * 2
/datum/organ/proc/get_icon(var/icon/race_icon, var/icon/deform_icon)
return icon('icons/mob/human.dmi',"blank")
if(istype(holder))
holder.internal_organs |= src
src.owner = holder
var/mob/living/carbon/human/H = holder
if(istype(H))
var/obj/item/organ/external/E = H.organs_by_name[src.parent_organ]
if(E.internal_organs == null)
E.internal_organs = list()
E.internal_organs |= src
/obj/item/organ/proc/die()
name = "dead [initial(name)]"
health = 0
processing_objects -= src
//TODO: Grey out the icon state.
//TODO: Inject an organ with peridaxon to make it alive again.
/obj/item/organ/process()
// Don't process if we're in a freezer, an MMI or a stasis bag. //TODO: ambient temperature?
if(istype(loc,/obj/item/device/mmi) || istype(loc,/obj/item/bodybag/cryobag) || istype(loc,/obj/structure/closet/crate/freezer))
return
//Process infections
if (robotic >= 2 || (owner.species && owner.species.flags & IS_PLANT))
germ_level = 0
return
if(!owner)
var/datum/reagent/blood/B = locate(/datum/reagent/blood) in reagents.reagent_list
if(B && prob(40))
reagents.remove_reagent("blood",0.1)
blood_splatter(src,B,1)
health -= rand(1,3)
if(health <= 0)
die()
else if(owner.bodytemperature >= 170) //cryo stops germs from moving and doing their bad stuffs
//** Handle antibiotics and curing infections
handle_antibiotics()
handle_rejection()
handle_germ_effects()
/obj/item/organ/proc/handle_germ_effects()
//** 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_ONE)
var/fever_temperature = (owner.species.heat_level_1 - owner.species.body_temperature - 5)* min(germ_level/INFECTION_LEVEL_TWO, 1) + owner.species.body_temperature
owner.bodytemperature += between(0, (fever_temperature - T20C)/BODYTEMP_COLD_DIVISOR + 1, fever_temperature - owner.bodytemperature)
if (germ_level >= INFECTION_LEVEL_TWO)
var/obj/item/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))
/obj/item/organ/proc/handle_rejection()
// Process unsuitable transplants. TODO: consider some kind of
// immunosuppressant that changes transplant data to make it match.
if(transplant_data)
if(!rejecting && prob(20) && owner.dna && blood_incompatible(transplant_data["blood_type"],owner.dna.b_type,owner.species,transplant_data["species"]))
rejecting = 1
else
rejecting++ //Rejection severity increases over time.
if(rejecting % 10 == 0) //Only fire every ten rejection ticks.
switch(rejecting)
if(1 to 50)
take_damage(1)
if(51 to 200)
owner.reagents.add_reagent("toxin", 1)
take_damage(1)
if(201 to 500)
take_damage(rand(2,3))
owner.reagents.add_reagent("toxin", 2)
if(501 to INFINITY)
take_damage(4)
owner.reagents.add_reagent("toxin", rand(3,5))
/obj/item/organ/proc/receive_chem(chemical as obj)
return 0
/obj/item/organ/proc/get_icon(var/image/supplied)
var/key = "internal-[icon_state]"
var/image/I
if(organ_cache[key])
I = organ_cache[key]
else
I = image(icon, "[icon_state]")
return I
/obj/item/organ/proc/rejuvenate()
damage = 0
/obj/item/organ/proc/is_damaged()
return damage > 0
/obj/item/organ/proc/is_bruised()
return damage >= min_bruised_damage
/obj/item/organ/proc/is_broken()
return (damage >= min_broken_damage || (status & ORGAN_CUT_AWAY) || ((status & ORGAN_BROKEN) && !(status & ORGAN_SPLINTED)))
//Germs
/datum/organ/proc/handle_antibiotics()
/obj/item/organ/proc/handle_antibiotics()
var/antibiotics = owner.reagents.get_reagent_amount("spaceacillin")
if (!germ_level || antibiotics < 5)
@@ -33,15 +159,8 @@
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.
for(var/datum/reagent/A in reagents.reagent_list)
var/datum/organ/O = pick(organs)
O.trace_chemicals[A.name] = 100
//Adds autopsy data for used_weapon.
/datum/organ/proc/add_autopsy_data(var/used_weapon, var/damage)
/obj/item/organ/proc/add_autopsy_data(var/used_weapon, var/damage)
var/datum/autopsy_data/W = autopsy_data[used_weapon]
if(!W)
W = new()
@@ -52,88 +171,153 @@
W.damage += damage
W.time_inflicted = world.time
/mob/living/carbon/human/var/list/organs = list()
/mob/living/carbon/human/var/list/organs_by_name = list() // map organ names to organs
/mob/living/carbon/human/var/list/internal_organs_by_name = list() // so internal organs have less ickiness too
/obj/item/organ/proc/take_damage(amount, var/silent=0)
if(src.robotic == 2)
src.damage += (amount * 0.8)
else
src.damage += amount
// Takes care of organ related updates, such as broken and missing limbs
/mob/living/carbon/human/proc/handle_organs()
var/obj/item/organ/external/parent = owner.get_organ(parent_organ)
if (!silent)
owner.custom_pain("Something inside your [parent.display_name] hurts a lot.", 1)
number_wounds = 0
var/force_process = 0
var/damage_this_tick = getBruteLoss() + getFireLoss() + getToxLoss()
if(damage_this_tick > last_dam)
force_process = 1
last_dam = damage_this_tick
if(force_process)
bad_external_organs.Cut()
for(var/datum/organ/external/Ex in organs)
bad_external_organs += Ex
/obj/item/organ/proc/robotize() //Being used to make robutt hearts, etc
robotic = 2
src.status &= ~ORGAN_BROKEN
src.status &= ~ORGAN_BLEEDING
src.status &= ~ORGAN_SPLINTED
src.status &= ~ORGAN_CUT_AWAY
src.status &= ~ORGAN_ATTACHABLE
src.status &= ~ORGAN_DESTROYED
src.status |= ORGAN_ROBOT
src.status |= ORGAN_ASSISTED
//processing internal organs is pretty cheap, do that first.
for(var/datum/organ/internal/I in internal_organs)
I.process()
/obj/item/organ/proc/mechassist() //Used to add things like pacemakers, etc
robotize()
src.status &= ~ORGAN_ROBOT
robotic = 1
min_bruised_damage = 15
min_broken_damage = 35
//losing a limb stops it from processing, so this has to be done separately
handle_stance()
/obj/item/organ/emp_act(severity)
switch(robotic)
if(0)
return
if(1)
switch (severity)
if (1.0)
take_damage(20,0)
return
if (2.0)
take_damage(7,0)
return
if(3.0)
take_damage(3,0)
return
if(2)
switch (severity)
if (1.0)
take_damage(40,0)
return
if (2.0)
take_damage(15,0)
return
if(3.0)
take_damage(10,0)
return
if(!force_process && !bad_external_organs.len)
/obj/item/organ/proc/removed(var/mob/living/carbon/human/target,var/mob/living/user)
if(!istype(target))
return
for(var/datum/organ/external/E in bad_external_organs)
if(!E)
continue
if(!E.need_process())
bad_external_organs -= E
continue
else
E.process()
number_wounds += E.number_wounds
target.internal_organs_by_name[organ_tag] = null
target.internal_organs_by_name -= organ_tag
target.internal_organs -= src
if (!lying && world.time - l_move_time < 15)
//Moving around with fractured ribs won't do you any good
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))
var/obj/item/organ/external/affected = target.get_organ(parent_organ)
affected.internal_organs -= src
//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
loc = target.loc
rejecting = null
var/datum/reagent/blood/organ_blood = locate(/datum/reagent/blood) in reagents.reagent_list
if(!organ_blood || !organ_blood.data["blood_DNA"])
target.vessel.trans_to(src, 5, 1, 1)
/mob/living/carbon/human/proc/handle_stance()
// Don't need to process any of this if they aren't standing anyways
// unless their stance is damaged, and we want to check if they should stay down
if (!stance_damage && (lying || resting) && (life_tick % 4) == 0)
return
stance_damage = 0
// Buckled to a bed/chair. Stance damage is forced to 0 since they're sitting on something solid
if (istype(buckled, /obj/structure/bed))
if(target && user && vital)
user.attack_log += "\[[time_stamp()]\]<font color='red'> removed a vital organ ([src]) from [target.name] ([target.ckey]) (INTENT: [uppertext(user.a_intent)])</font>"
target.attack_log += "\[[time_stamp()]\]<font color='orange'> had a vital organ ([src]) removed by [user.name] ([user.ckey]) (INTENT: [uppertext(user.a_intent)])</font>"
msg_admin_attack("[user.name] ([user.ckey]) removed a vital organ ([src]) from [target.name] ([target.ckey]) (INTENT: [uppertext(user.a_intent)]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)")
target.death()
/obj/item/organ/proc/replaced(var/mob/living/carbon/human/target,var/obj/item/organ/external/affected)
if(!istype(target)) return
var/datum/reagent/blood/transplant_blood = locate(/datum/reagent/blood) in reagents.reagent_list
transplant_data = list()
if(!transplant_blood)
transplant_data["species"] = target.species.name
transplant_data["blood_type"] = target.dna.b_type
transplant_data["blood_DNA"] = target.dna.unique_enzymes
else
transplant_data["species"] = transplant_blood.data["species"]
transplant_data["blood_type"] = transplant_blood.data["blood_type"]
transplant_data["blood_DNA"] = transplant_blood.data["blood_DNA"]
owner = target
target.internal_organs |= src
affected.internal_organs |= src
target.internal_organs_by_name[organ_tag] = src
status |= ORGAN_CUT_AWAY
del(src)
/obj/item/organ/eyes/replaced(var/mob/living/carbon/human/target)
// Apply our eye colour to the target.
if(istype(target) && eye_colour)
target.r_eyes = eye_colour[1]
target.g_eyes = eye_colour[2]
target.b_eyes = eye_colour[3]
target.update_body()
..()
/obj/item/organ/proc/bitten(mob/user)
if(robotic)
return
for (var/organ in list("l_leg","l_foot","r_leg","r_foot"))
var/datum/organ/external/E = organs_by_name[organ]
if (E.status & ORGAN_DESTROYED)
stance_damage += 2 // let it fail even if just foot&leg
else if (E.is_malfunctioning() || (E.is_broken() && !(E.status & ORGAN_SPLINTED)) || !E.is_usable())
stance_damage += 1
// Canes and crutches help you stand (if the latter is ever added)
// One cane mitigates a broken leg+foot, or a missing foot.
// Two canes are needed for a lost leg. If you are missing both legs, canes aren't gonna help you.
if (istype(l_hand, /obj/item/weapon/cane))
stance_damage -= 2
if (istype(l_hand, /obj/item/weapon/cane))
stance_damage -= 2
user << "\blue You take an experimental bite out of \the [src]."
var/datum/reagent/blood/B = locate(/datum/reagent/blood) in reagents.reagent_list
blood_splatter(src,B,1)
// standing is poor
if(stance_damage >= 4 || (stance_damage >= 2 && prob(5)))
if(!(lying || resting))
if(species && !(species.flags & NO_PAIN))
emote("scream")
custom_emote(1, "collapses!")
Weaken(5) //can't emote while weakened, apparently.
user.drop_from_inventory(src)
var/obj/item/weapon/reagent_containers/food/snacks/organ/O = new(get_turf(src))
O.name = name
O.icon_state = icon_state
// Pass over the blood.
reagents.trans_to(O, reagents.total_volume)
if(fingerprints) O.fingerprints = fingerprints.Copy()
if(fingerprintshidden) O.fingerprintshidden = fingerprintshidden.Copy()
if(fingerprintslast) O.fingerprintslast = fingerprintslast
user.put_in_active_hand(O)
del(src)
/obj/item/organ/attack_self(mob/user as mob)
// Convert it to an edible form, yum yum.
if(!robotic && user.a_intent == "help" && user.zone_sel.selecting == "mouth")
bitten(user)
return
/obj/item/organ/proc/remove(var/mob/user)
if(user)
src.loc = get_turf(user)
else
src.loc = get_turf(owner)
return src

View File

@@ -1,35 +1,30 @@
//DIONA ORGANS.
/datum/organ/internal/diona
removed_type = /obj/item/organ/diona
/datum/organ/internal/diona/process()
/obj/item/organ/diona/process()
return
/datum/organ/internal/diona/strata
/obj/item/organ/diona/strata
name = "neural strata"
parent_organ = "chest"
/datum/organ/internal/diona/bladder
/obj/item/organ/diona/bladder
name = "gas bladder"
parent_organ = "head"
/datum/organ/internal/diona/polyp
/obj/item/organ/diona/polyp
name = "polyp segment"
parent_organ = "groin"
/datum/organ/internal/diona/ligament
/obj/item/organ/diona/ligament
name = "anchoring ligament"
parent_organ = "groin"
/datum/organ/internal/diona/node
/obj/item/organ/diona/node
name = "receptor node"
parent_organ = "head"
removed_type = /obj/item/organ/diona/node
/datum/organ/internal/diona/nutrients
/obj/item/organ/diona/nutrients
name = "nutrient vessel"
parent_organ = "chest"
removed_type = /obj/item/organ/diona/nutrients
/obj/item/organ/diona
name = "diona nymph"
@@ -78,13 +73,12 @@
return
//CORTICAL BORER ORGANS.
/datum/organ/internal/borer
/obj/item/organ/borer
name = "cortical borer"
parent_organ = "head"
removed_type = /obj/item/organ/borer
vital = 1
/datum/organ/internal/borer/process()
/obj/item/organ/borer/process()
// Borer husks regenerate health, feel no pain, and are resistant to stuns and brainloss.
for(var/chem in list("tricordrazine","tramadol","hyperzine","alkysine"))
@@ -126,46 +120,41 @@
del(src)
//XENOMORPH ORGANS
/datum/organ/internal/xenos/eggsac
/obj/item/organ/xenos/eggsac
name = "egg sac"
parent_organ = "groin"
removed_type = /obj/item/organ/xenos/eggsac
/datum/organ/internal/xenos/plasmavessel
/obj/item/organ/xenos/plasmavessel
name = "plasma vessel"
parent_organ = "chest"
removed_type = /obj/item/organ/xenos/plasmavessel
var/stored_plasma = 0
var/max_plasma = 500
/datum/organ/internal/xenos/plasmavessel/queen
/obj/item/organ/xenos/plasmavessel/queen
name = "bloated plasma vessel"
stored_plasma = 200
max_plasma = 500
/datum/organ/internal/xenos/plasmavessel/sentinel
/obj/item/organ/xenos/plasmavessel/sentinel
stored_plasma = 100
max_plasma = 250
/datum/organ/internal/xenos/plasmavessel/hunter
/obj/item/organ/xenos/plasmavessel/hunter
name = "tiny plasma vessel"
stored_plasma = 100
max_plasma = 150
/datum/organ/internal/xenos/acidgland
/obj/item/organ/xenos/acidgland
name = "acid gland"
parent_organ = "head"
removed_type = /obj/item/organ/xenos/acidgland
/datum/organ/internal/xenos/hivenode
/obj/item/organ/xenos/hivenode
name = "hive node"
parent_organ = "chest"
removed_type = /obj/item/organ/xenos/hivenode
/datum/organ/internal/xenos/resinspinner
/obj/item/organ/xenos/resinspinner
name = "resin spinner"
parent_organ = "head"
removed_type = /obj/item/organ/xenos/resinspinner
/obj/item/organ/xenos
name = "xeno organ"
@@ -198,32 +187,28 @@
organ_tag = "resin spinner"
//VOX ORGANS.
/datum/organ/internal/stack
/obj/item/organ/stack
name = "cortical stack"
removed_type = /obj/item/organ/stack
parent_organ = "head"
robotic = 2
vital = 1
var/backup_time = 0
var/datum/mind/backup
/datum/organ/internal/stack/process()
/obj/item/organ/stack/process()
if(owner && owner.stat != 2 && !is_broken())
backup_time = world.time
if(owner.mind) backup = owner.mind
/datum/organ/internal/stack/vox
removed_type = /obj/item/organ/stack/vox
/obj/item/organ/stack/vox
/datum/organ/internal/stack/vox/stack
/obj/item/organ/stack/vox/stack
/obj/item/organ/stack
name = "cortical stack"
icon_state = "brain-prosthetic"
organ_tag = "stack"
robotic = 2
prosthetic_name = null
prosthetic_icon = null
/obj/item/organ/stack/vox
name = "vox cortical stack"

View File

@@ -1,7 +1,7 @@
/****************************************************
EXTERNAL ORGANS
****************************************************/
/datum/organ/external
/obj/item/organ/external
name = "external"
var/icon_name = null
var/body_part = null
@@ -10,7 +10,6 @@
var/damage_state = "00"
var/brute_dam = 0
var/burn_dam = 0
var/max_damage = 0
var/max_size = 0
var/last_dam = -1
@@ -21,13 +20,12 @@
var/tmp/perma_injury = 0
var/tmp/destspawn = 0 //Has it spawned the broken limb?
var/tmp/amputated = 0 //Whether this has been cleanly amputated, thus causing no pain
var/min_broken_damage = 30
var/datum/organ/external/parent
var/list/datum/organ/external/children
var/obj/item/organ/external/parent
var/list/obj/item/organ/external/children
// Internal organs of this body part
var/list/datum/organ/internal/internal_organs
var/list/obj/item/organ/internal_organs
var/damage_msg = "\red You feel an intense pain"
var/broken_description
@@ -44,8 +42,14 @@
// how often wounds should be updated, a higher number means less often
var/wound_update_accuracy = 1
var/joint = "joint" // Descriptive string used in dislocation.
var/amputation_point // Descriptive string used in amputation.
var/dislocated = 0 // If you target a joint, you can dislocate the limb, causing temporary damage to the organ.
/datum/organ/external/New(var/datum/organ/external/P)
min_broken_damage = 30
max_damage = 0
/obj/item/organ/external/New(var/newloc, var/mob/living/carbon/holder, var/obj/item/organ/external/P)
if(P)
parent = P
if(!parent.children)
@@ -57,20 +61,7 @@
DAMAGE PROCS
****************************************************/
/datum/organ/external/proc/emp_act(severity)
if(!(status & ORGAN_ROBOT)) //meatbags do not care about EMP
return
var/probability = 30
var/damage = 15
if(severity == 2)
probability = 1
damage = 3
if(prob(probability))
droplimb(1)
else
take_damage(damage, 0, 1, 1, used_weapon = "EMP")
/datum/organ/external/proc/take_damage(brute, burn, sharp, edge, used_weapon = null, list/forbidden_limbs = list())
/obj/item/organ/external/take_damage(brute, burn, sharp, edge, used_weapon = null, list/forbidden_limbs = list())
if((brute <= 0) && (burn <= 0))
return 0
@@ -93,7 +84,7 @@
// High brute damage or sharp objects may damage internal organs
if(internal_organs && ( (sharp && brute >= 5) || brute >= 10) && prob(5))
// Damage an internal organ
var/datum/organ/internal/I = pick(internal_organs)
var/obj/item/organ/I = pick(internal_organs)
I.take_damage(brute / 2)
brute -= brute / 2
@@ -141,7 +132,7 @@
droplimb(1) //Robot limbs just kinda fail at full damage.
else
//List organs we can pass it to
var/list/datum/organ/external/possible_points = list()
var/list/obj/item/organ/external/possible_points = list()
if(parent)
possible_points += parent
if(children)
@@ -150,7 +141,7 @@
possible_points -= forbidden_limbs
if(possible_points.len)
//And pass the pain around
var/datum/organ/external/target = pick(possible_points)
var/obj/item/organ/external/target = pick(possible_points)
target.take_damage(brute, burn, sharp, edge, used_weapon, forbidden_limbs + src)
// sync the organ's damage with its wounds
@@ -168,7 +159,7 @@
var/result = update_icon()
return result
/datum/organ/external/proc/heal_damage(brute, burn, internal = 0, robo_repair = 0)
/obj/item/organ/external/proc/heal_damage(brute, burn, internal = 0, robo_repair = 0)
if(status & ORGAN_ROBOT && !robo_repair)
return
@@ -197,7 +188,7 @@
/*
This function completely restores a damaged organ to perfect condition.
*/
/datum/organ/external/proc/rejuvenate()
/obj/item/organ/external/rejuvenate()
damage_state = "00"
if(status & 128) //Robotic organs stay robotic. Fix because right click rejuvinate makes IPC's organs organic.
status = 128
@@ -211,7 +202,7 @@ This function completely restores a damaged organ to perfect condition.
number_wounds = 0
// handle internal organs
for(var/datum/organ/internal/current_organ in internal_organs)
for(var/obj/item/organ/current_organ in internal_organs)
current_organ.rejuvenate()
// remove embedded objects and drop them on the floor
@@ -223,7 +214,7 @@ This function completely restores a damaged organ to perfect condition.
owner.updatehealth()
/datum/organ/external/proc/createwound(var/type = CUT, var/damage)
/obj/item/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 (because of the return)
@@ -274,7 +265,7 @@ 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()
/obj/item/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.
@@ -290,7 +281,7 @@ This function completely restores a damaged organ to perfect condition.
return 1
return 0
/datum/organ/external/process()
/obj/item/organ/external/process()
//Dismemberment
if(status & ORGAN_DESTROYED)
if(!destspawn && config.limbs_can_break)
@@ -341,7 +332,7 @@ INFECTION_LEVEL_THREE above this germ level the player will take additional toxi
Note that amputating the affected organ does in fact remove the infection from the player's body.
*/
/datum/organ/external/proc/update_germs()
/obj/item/organ/external/proc/update_germs()
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
@@ -357,7 +348,7 @@ Note that amputating the affected organ does in fact remove the infection from t
//** Handle the effects of infections
handle_germ_effects()
/datum/organ/external/proc/handle_germ_sync()
/obj/item/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
@@ -371,29 +362,17 @@ Note that amputating the affected organ does in fact remove the infection from t
germ_level++
break //limit increase to a maximum of one per second
/datum/organ/external/proc/handle_germ_effects()
/obj/item/organ/external/handle_germ_effects()
if(germ_level < INFECTION_LEVEL_TWO)
return ..()
var/antibiotics = owner.reagents.get_reagent_amount("spaceacillin")
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)
if(germ_level >= INFECTION_LEVEL_TWO)
//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)
var/obj/item/organ/target_organ = null //make internal organs become infected one at a time instead of all at once
for (var/obj/item/organ/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
@@ -401,7 +380,7 @@ Note that amputating the affected organ does in fact remove the infection from t
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)
for (var/obj/item/organ/I in internal_organs)
if (I.germ_level < germ_level)
candidate_organs += I
if (candidate_organs.len)
@@ -412,7 +391,7 @@ Note that amputating the affected organ does in fact remove the infection from t
//spread the infection to child and parent organs
if (children)
for (var/datum/organ/external/child in children)
for (var/obj/item/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++
@@ -432,7 +411,7 @@ Note that amputating the affected organ does in fact remove the infection from t
owner.adjustToxLoss(1)
//Updating wounds. Handles wound natural I had some free spachealing, internal bleedings and infections
/datum/organ/external/proc/update_wounds()
/obj/item/organ/external/proc/update_wounds()
if((status & ORGAN_ROBOT)) //Robotic limbs don't heal or get worse.
return
@@ -485,7 +464,7 @@ Note that amputating the affected organ does in fact remove the infection from t
owner.UpdateDamageIcon(1)
//Updates brute_damn and burn_damn from wound damages. Updates BLEEDING status.
/datum/organ/external/proc/update_damages()
/obj/item/organ/external/proc/update_damages()
number_wounds = 0
brute_dam = 0
burn_dam = 0
@@ -517,7 +496,7 @@ Note that amputating the affected organ does in fact remove the infection from t
// new damage icon system
// adjusted to set damage_state to brute/burn code only (without r_name0 as before)
/datum/organ/external/proc/update_icon()
/obj/item/organ/external/update_icon()
var/n_is = damage_state_text()
if (n_is != damage_state)
damage_state = n_is
@@ -526,7 +505,7 @@ Note that amputating the affected organ does in fact remove the infection from t
// new damage icon system
// returns just the brute/burn damage code
/datum/organ/external/proc/damage_state_text()
/obj/item/organ/external/proc/damage_state_text()
if(status & ORGAN_DESTROYED)
return "--"
@@ -557,13 +536,13 @@ Note that amputating the affected organ does in fact remove the infection from t
****************************************************/
//Recursive setting of all child organs to amputated
/datum/organ/external/proc/setAmputatedTree()
for(var/datum/organ/external/O in children)
/obj/item/organ/external/proc/setAmputatedTree()
for(var/obj/item/organ/external/O in children)
O.amputated=amputated
O.setAmputatedTree()
//Handles dismemberment
/datum/organ/external/proc/droplimb(var/override = 0,var/no_explode = 0,var/amputation=0)
/obj/item/organ/external/proc/droplimb(var/override = 0,var/no_explode = 0,var/amputation=0)
if(destspawn) return
if(override)
status |= ORGAN_DESTROYED
@@ -581,7 +560,7 @@ Note that amputating the affected organ does in fact remove the infection from t
germ_level = 0
// If any organs are attached to this, destroy them
for(var/datum/organ/external/O in children)
for(var/obj/item/organ/external/O in children)
O.droplimb(1, no_explode, amputation)
//Replace all wounds on that arm with one wound on parent organ.
@@ -596,53 +575,37 @@ Note that amputating the affected organ does in fact remove the infection from t
parent.update_damages()
update_damages()
var/obj/organ //Dropped limb object
var/list/dropped_items
switch(body_part)
if(HEAD)
organ = new /obj/item/weapon/organ/head(owner.loc, owner)
dropped_items = list(owner.glasses, owner.head, owner.l_ear, owner.r_ear, owner.wear_mask)
if(ARM_RIGHT)
if(status & ORGAN_ROBOT)
organ = new /obj/item/robot_parts/r_arm(owner.loc)
else
organ= new /obj/item/weapon/organ/r_arm(owner.loc, owner)
if(ARM_LEFT)
if(status & ORGAN_ROBOT)
organ= new /obj/item/robot_parts/l_arm(owner.loc)
else
organ= new /obj/item/weapon/organ/l_arm(owner.loc, owner)
if(LEG_RIGHT)
if(status & ORGAN_ROBOT)
organ = new /obj/item/robot_parts/r_leg(owner.loc)
else
organ= new /obj/item/weapon/organ/r_leg(owner.loc, owner)
if(LEG_LEFT)
if(status & ORGAN_ROBOT)
organ = new /obj/item/robot_parts/l_leg(owner.loc)
else
organ= new /obj/item/weapon/organ/l_leg(owner.loc, owner)
if(HAND_RIGHT)
if(!(status & ORGAN_ROBOT))
organ= new /obj/item/weapon/organ/r_hand(owner.loc, owner)
dropped_items = list(owner.gloves) //should probably make it so that you can still wear gloves if you have one hand
if(HAND_LEFT)
if(!(status & ORGAN_ROBOT))
organ= new /obj/item/weapon/organ/l_hand(owner.loc, owner)
dropped_items = list(owner.gloves)
if(FOOT_RIGHT)
if(!(status & ORGAN_ROBOT))
organ= new /obj/item/weapon/organ/r_foot/(owner.loc, owner)
dropped_items = list(owner.shoes)
if(FOOT_LEFT)
if(!(status & ORGAN_ROBOT))
organ = new /obj/item/weapon/organ/l_foot(owner.loc, owner)
dropped_items = list(owner.shoes)
if(dropped_items)
for(var/obj/O in dropped_items)
owner.remove_from_mob(O)
removed(owner)
destspawn = 1
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
if(istype(owner.loc,/turf))
step(src,pick(cardinal))
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()
if(vital)
owner.death()
//Robotic limbs explode if sabotaged.
if(status & ORGAN_ROBOT && !no_explode && sabotaged)
owner.visible_message("\red \The [owner]'s [display_name] explodes violently!",\
@@ -655,28 +618,14 @@ Note that amputating the affected organ does in fact remove the infection from t
spark_system.start()
spawn(10)
del(spark_system)
del(src)
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
if(istype(owner.loc,/turf) && organ)
step(organ,pick(cardinal))
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()
if(vital)
owner.death()
/****************************************************
HELPERS
****************************************************/
/datum/organ/external/proc/release_restraints()
/obj/item/organ/external/proc/release_restraints()
if (owner.handcuffed && body_part in list(ARM_LEFT, ARM_RIGHT, HAND_LEFT, HAND_RIGHT))
owner.visible_message(\
"\The [owner.handcuffed.name] falls off of [owner.name].",\
@@ -691,7 +640,7 @@ Note that amputating the affected organ does in fact remove the infection from t
owner.drop_from_inventory(owner.legcuffed)
/datum/organ/external/proc/bandage()
/obj/item/organ/external/proc/bandage()
var/rval = 0
src.status &= ~ORGAN_BLEEDING
for(var/datum/wound/W in wounds)
@@ -700,7 +649,7 @@ Note that amputating the affected organ does in fact remove the infection from t
W.bandaged = 1
return rval
/datum/organ/external/proc/disinfect()
/obj/item/organ/external/proc/disinfect()
var/rval = 0
for(var/datum/wound/W in wounds)
if(W.internal) continue
@@ -709,7 +658,7 @@ Note that amputating the affected organ does in fact remove the infection from t
W.germ_level = 0
return rval
/datum/organ/external/proc/clamp()
/obj/item/organ/external/proc/clamp()
var/rval = 0
src.status &= ~ORGAN_BLEEDING
for(var/datum/wound/W in wounds)
@@ -718,14 +667,14 @@ Note that amputating the affected organ does in fact remove the infection from t
W.clamped = 1
return rval
/datum/organ/external/proc/salve()
/obj/item/organ/external/proc/salve()
var/rval = 0
for(var/datum/wound/W in wounds)
rval |= !W.salved
W.salved = 1
return rval
/datum/organ/external/proc/fracture()
/obj/item/organ/external/proc/fracture()
if(status & ORGAN_BROKEN)
return
@@ -765,7 +714,7 @@ Note that amputating the affected organ does in fact remove the infection from t
suit.supporting_limbs |= src
return
/datum/organ/external/proc/mend_fracture()
/obj/item/organ/external/proc/mend_fracture()
if(status & ORGAN_ROBOT)
return 0 //ORGAN_BROKEN doesn't have the same meaning for robot limbs
if(brute_dam > min_broken_damage * config.organ_health_multiplier)
@@ -774,37 +723,31 @@ Note that amputating the affected organ does in fact remove the infection from t
status &= ~ORGAN_BROKEN
return 1
/datum/organ/external/proc/robotize()
src.status &= ~ORGAN_BROKEN
src.status &= ~ORGAN_BLEEDING
src.status &= ~ORGAN_SPLINTED
src.status &= ~ORGAN_CUT_AWAY
src.status &= ~ORGAN_ATTACHABLE
src.status &= ~ORGAN_DESTROYED
src.status |= ORGAN_ROBOT
/obj/item/organ/external/robotize()
..()
src.destspawn = 0
for (var/datum/organ/external/T in children)
for (var/obj/item/organ/external/T in children)
if(T)
T.robotize()
/datum/organ/external/proc/mutate()
/obj/item/organ/external/proc/mutate()
src.status |= ORGAN_MUTATED
owner.update_body()
/datum/organ/external/proc/unmutate()
/obj/item/organ/external/proc/unmutate()
src.status &= ~ORGAN_MUTATED
owner.update_body()
/datum/organ/external/proc/get_damage() //returns total damage
/obj/item/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/has_infected_wound()
/obj/item/organ/external/proc/has_infected_wound()
for(var/datum/wound/W in wounds)
if(W.germ_level > INFECTION_LEVEL_ONE)
return 1
return 0
/datum/organ/external/get_icon(var/icon/race_icon, var/icon/deform_icon,gender="")
/obj/item/organ/external/get_icon(var/icon/race_icon, var/icon/deform_icon,gender="")
if (status & ORGAN_ROBOT && !(owner.species && owner.species.flags & IS_SYNTHETIC))
return new /icon('icons/mob/human_races/robotic.dmi', "[icon_name][gender ? "_[gender]" : ""]")
@@ -814,17 +757,14 @@ Note that amputating the affected organ does in fact remove the infection from t
return new /icon(race_icon, "[icon_name][gender ? "_[gender]" : ""]")
/datum/organ/external/proc/is_usable()
/obj/item/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()
/obj/item/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)
/obj/item/organ/external/proc/process_grasp(var/obj/item/c_hand, var/hand_name)
if (!c_hand)
return
@@ -842,7 +782,7 @@ Note that amputating the affected organ does in fact remove the infection from t
spawn(10)
del(spark_system)
/datum/organ/external/proc/embed(var/obj/item/weapon/W, var/silent = 0)
/obj/item/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
@@ -858,7 +798,7 @@ Note that amputating the affected organ does in fact remove the infection from t
ORGAN DEFINES
****************************************************/
/datum/organ/external/chest
/obj/item/organ/external/chest
name = "chest"
icon_name = "torso"
display_name = "chest"
@@ -867,8 +807,11 @@ Note that amputating the affected organ does in fact remove the infection from t
body_part = UPPER_TORSO
vital = 1
encased = "ribcage"
amputation_point = "spines"
joint = "neck"
dislocated = -1
/datum/organ/external/groin
/obj/item/organ/external/groin
name = "groin"
icon_name = "groin"
display_name = "groin"
@@ -876,20 +819,25 @@ Note that amputating the affected organ does in fact remove the infection from t
min_broken_damage = 30
body_part = LOWER_TORSO
vital = 1
amputation_point = "lumbar"
joint = "hip"
dislocated = -1
/datum/organ/external/l_arm
/obj/item/organ/external/l_arm
name = "l_arm"
display_name = "left arm"
icon_name = "l_arm"
max_damage = 50
min_broken_damage = 20
body_part = ARM_LEFT
joint = "left elbow"
amputation_point = "left shoulder"
process()
..()
process_grasp(owner.l_hand, "left hand")
/obj/item/organ/external/l_arm/process()
..()
process_grasp(owner.l_hand, "left hand")
/datum/organ/external/l_leg
/obj/item/organ/external/l_leg
name = "l_leg"
display_name = "left leg"
icon_name = "l_leg"
@@ -897,20 +845,24 @@ Note that amputating the affected organ does in fact remove the infection from t
min_broken_damage = 20
body_part = LEG_LEFT
icon_position = LEFT
joint = "left knee"
amputation_point = "left hip"
/datum/organ/external/r_arm
/obj/item/organ/external/r_arm
name = "r_arm"
display_name = "right arm"
icon_name = "r_arm"
max_damage = 50
min_broken_damage = 20
body_part = ARM_RIGHT
joint = "right elbow"
amputation_point = "right shoulder"
process()
/obj/item/organ/external/r_arm/process()
..()
process_grasp(owner.r_hand, "right hand")
/datum/organ/external/r_leg
/obj/item/organ/external/r_leg
name = "r_leg"
display_name = "right leg"
icon_name = "r_leg"
@@ -918,8 +870,10 @@ Note that amputating the affected organ does in fact remove the infection from t
min_broken_damage = 20
body_part = LEG_RIGHT
icon_position = RIGHT
joint = "right knee"
amputation_point = "right hip"
/datum/organ/external/l_foot
/obj/item/organ/external/l_foot
name = "l_foot"
display_name = "left foot"
icon_name = "l_foot"
@@ -927,8 +881,9 @@ Note that amputating the affected organ does in fact remove the infection from t
min_broken_damage = 15
body_part = FOOT_LEFT
icon_position = LEFT
amputation_point = "left ankle"
/datum/organ/external/r_foot
/obj/item/organ/external/r_foot
name = "r_foot"
display_name = "right foot"
icon_name = "r_foot"
@@ -936,32 +891,35 @@ Note that amputating the affected organ does in fact remove the infection from t
min_broken_damage = 15
body_part = FOOT_RIGHT
icon_position = RIGHT
amputation_point = "right ankle"
/datum/organ/external/r_hand
/obj/item/organ/external/r_hand
name = "r_hand"
display_name = "right hand"
icon_name = "r_hand"
max_damage = 30
min_broken_damage = 15
body_part = HAND_RIGHT
amputation_point = "right wrist"
process()
..()
process_grasp(owner.r_hand, "right hand")
/obj/item/organ/external/r_hand/process()
..()
process_grasp(owner.r_hand, "right hand")
/datum/organ/external/l_hand
/obj/item/organ/external/l_hand
name = "l_hand"
display_name = "left hand"
icon_name = "l_hand"
max_damage = 30
min_broken_damage = 15
body_part = HAND_LEFT
amputation_point = "left wrist"
process()
..()
process_grasp(owner.l_hand, "left hand")
/obj/item/organ/external/l_hand/process()
..()
process_grasp(owner.l_hand, "left hand")
/datum/organ/external/head
/obj/item/organ/external/head
name = "head"
icon_name = "head"
display_name = "head"
@@ -971,8 +929,10 @@ Note that amputating the affected organ does in fact remove the infection from t
var/disfigured = 0
vital = 1
encased = "skull"
joint = "jaw"
amputation_point = "neck"
/datum/organ/external/head/get_icon(var/icon/race_icon, var/icon/deform_icon)
/obj/item/organ/external/head/get_icon(var/icon/race_icon, var/icon/deform_icon)
if (!owner)
return ..()
var/g = "m"
@@ -982,7 +942,7 @@ Note that amputating the affected organ does in fact remove the infection from t
else
. = new /icon(race_icon, "[icon_name]_[g]")
/datum/organ/external/head/take_damage(brute, burn, sharp, edge, used_weapon = null, list/forbidden_limbs = list())
/obj/item/organ/external/head/take_damage(brute, burn, sharp, edge, used_weapon = null, list/forbidden_limbs = list())
..(brute, burn, sharp, edge, used_weapon, forbidden_limbs)
if (!disfigured)
if (brute_dam > 40)
@@ -991,7 +951,7 @@ Note that amputating the affected organ does in fact remove the infection from t
if (burn_dam > 40)
disfigure("burn")
/datum/organ/external/head/proc/disfigure(var/type = "brute")
/obj/item/organ/external/head/proc/disfigure(var/type = "brute")
if (disfigured)
return
if(type == "brute")
@@ -1008,12 +968,12 @@ Note that amputating the affected organ does in fact remove the infection from t
EXTERNAL ORGAN ITEMS
****************************************************/
obj/item/weapon/organ
/obj/item/organ
icon = 'icons/mob/human_races/r_human.dmi'
var/op_stage = 0
var/list/organs_internal = list()
obj/item/weapon/organ/New(loc, mob/living/carbon/human/H)
/obj/item/organ/New(loc, mob/living/carbon/human/H)
..(loc)
if(!istype(H))
return
@@ -1023,14 +983,13 @@ obj/item/weapon/organ/New(loc, mob/living/carbon/human/H)
blood_DNA[H.dna.unique_enzymes] = H.dna.b_type
// Transferring over organs from the host.
for(var/datum/organ/internal/I in H.internal_organs)
for(var/obj/item/organ/I in H.internal_organs)
if(I.parent_organ != name)
continue
var/obj/item/organ/current_organ = I.remove()
current_organ.removed(H)
current_organ.loc = src
if(current_organ.organ_data)
organs_internal |= current_organ.organ_data
organs_internal |= current_organ
// Forming icon for the limb
// Setting base icon for this mob's race
@@ -1062,35 +1021,35 @@ obj/item/weapon/organ/New(loc, mob/living/carbon/human/H)
EXTERNAL ORGAN ITEMS DEFINES
****************************************************/
obj/item/weapon/organ/l_arm
/obj/item/organ/l_arm
name = "left arm"
icon_state = "l_arm"
obj/item/weapon/organ/l_foot
/obj/item/organ/l_foot
name = "left foot"
icon_state = "l_foot"
obj/item/weapon/organ/l_hand
/obj/item/organ/l_hand
name = "left hand"
icon_state = "l_hand"
obj/item/weapon/organ/l_leg
/obj/item/organ/l_leg
name = "left leg"
icon_state = "l_leg"
obj/item/weapon/organ/r_arm
/obj/item/organ/r_arm
name = "right arm"
icon_state = "r_arm"
obj/item/weapon/organ/r_foot
/obj/item/organ/r_foot
name = "right foot"
icon_state = "r_foot"
obj/item/weapon/organ/r_hand
/obj/item/organ/r_hand
name = "right hand"
icon_state = "r_hand"
obj/item/weapon/organ/r_leg
/obj/item/organ/r_leg
name = "right leg"
icon_state = "r_leg"
obj/item/weapon/organ/head
/obj/item/organ/head
name = "head"
icon_state = "head_m"
obj/item/weapon/organ/head/New(loc, mob/living/carbon/human/H)
/obj/item/organ/head/New(loc, mob/living/carbon/human/H)
if(istype(H))
src.icon_state = H.gender == MALE? "head_m" : "head_f"
..()
@@ -1116,7 +1075,7 @@ obj/item/weapon/organ/head/New(loc, mob/living/carbon/human/H)
name = "[H.real_name]'s head"
H.regenerate_icons()
obj/item/weapon/organ/attackby(obj/item/weapon/W as obj, mob/user as mob)
/obj/item/organ/attackby(obj/item/weapon/W as obj, mob/user as mob)
switch(op_stage)
if(0)
if(istype(W,/obj/item/weapon/scalpel))
@@ -1137,9 +1096,35 @@ obj/item/weapon/organ/attackby(obj/item/weapon/W as obj, mob/user as mob)
user.put_in_hands(removing)
if(istype(removing,/obj/item/organ))
var/obj/item/organ/removed_organ = removing
organs_internal -= removed_organ.organ_data
organs_internal -= removed_organ
user.visible_message("<span class='danger'><b>[user]</b> extracts [removing] from [src] with [W]!")
else
user.visible_message("<span class='danger'><b>[user]</b> fishes around fruitlessly in [src] with [W].")
return
..()
..()
/obj/item/organ/external/proc/is_dislocated()
if(dislocated)
return 1
if(parent)
return parent.is_dislocated()
return 0
/obj/item/organ/external/proc/dislocate(var/primary)
if(dislocated != -1)
if(primary)
dislocated = 2
else
dislocated = 1
if(children && children.len)
for(var/obj/item/organ/external/child in children)
child.dislocate()
/obj/item/organ/external/proc/undislocate()
if(dislocated != -1)
dislocated = 0
if(children && children.len)
for(var/obj/item/organ/external/child in children)
child.undislocate()
if(owner)
owner.shock_stage += 20

View File

@@ -1,296 +1,182 @@
#define PROCESS_ACCURACY 10
/****************************************************
INTERNAL ORGANS
****************************************************/
/mob/living/carbon/var/list/internal_organs = list()
/datum/organ/internal
var/damage = 0 // amount of damage to the organ
var/min_bruised_damage = 10
var/min_broken_damage = 30
var/parent_organ = "chest"
var/robotic = 0 //For being a robot
var/removed_type //When removed, forms this object.
var/rejecting // Is this organ already being rejected?
var/obj/item/organ/organ_holder // If not in a body, held in this item.
var/list/transplant_data
/datum/organ/internal/proc/rejuvenate()
damage=0
/datum/organ/internal/proc/is_bruised()
return damage >= min_bruised_damage
/datum/organ/internal/proc/is_broken()
return damage >= min_broken_damage || status & ORGAN_CUT_AWAY
/datum/organ/internal/New(mob/living/carbon/M)
..()
if(M && istype(M))
M.internal_organs |= src
src.owner = M
var/mob/living/carbon/human/H = M
if(istype(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
/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))
// Process unsuitable transplants. TODO: consider some kind of
// immunosuppressant that changes transplant data to make it match.
if(transplant_data)
if(!rejecting && prob(20) && owner.dna && blood_incompatible(transplant_data["blood_type"],owner.dna.b_type,owner.species,transplant_data["species"]))
rejecting = 1
else
rejecting++ //Rejection severity increases over time.
if(rejecting % 10 == 0) //Only fire every ten rejection ticks.
switch(rejecting)
if(1 to 50)
take_damage(1)
if(51 to 200)
owner.reagents.add_reagent("toxin", 1)
take_damage(1)
if(201 to 500)
take_damage(rand(2,3))
owner.reagents.add_reagent("toxin", 2)
if(501 to INFINITY)
take_damage(4)
owner.reagents.add_reagent("toxin", rand(3,5))
/datum/organ/internal/proc/take_damage(amount, var/silent=0)
if(src.robotic == 2)
src.damage += (amount * 0.8)
else
src.damage += amount
var/datum/organ/external/parent = owner.get_organ(parent_organ)
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)
return
if(1)
switch (severity)
if (1.0)
take_damage(20,0)
return
if (2.0)
take_damage(7,0)
return
if(3.0)
take_damage(3,0)
return
if(2)
switch (severity)
if (1.0)
take_damage(40,0)
return
if (2.0)
take_damage(15,0)
return
if(3.0)
take_damage(10,0)
return
/datum/organ/internal/proc/mechanize() //Being used to make robutt hearts, etc
robotic = 2
/datum/organ/internal/proc/mechassist() //Used to add things like pacemakers, etc
robotic = 1
min_bruised_damage = 15
min_broken_damage = 35
/****************************************************
INTERNAL ORGANS DEFINES
****************************************************/
/datum/organ/internal/heart // This is not set to vital because death immediately occurs in blood.dm if it is removed.
// Brain is defined in brain_item.dm.
/obj/item/organ/heart
name = "heart"
icon_state = "heart-on"
organ_tag = "heart"
parent_organ = "chest"
removed_type = /obj/item/organ/heart
/datum/organ/internal/lungs
/obj/item/organ/lungs
name = "lungs"
icon_state = "lungs"
gender = PLURAL
organ_tag = "lungs"
parent_organ = "chest"
removed_type = /obj/item/organ/lungs
process()
..()
if (germ_level > INFECTION_LEVEL_ONE)
if(prob(5))
owner.emote("cough") //respitory tract infection
/obj/item/organ/lungs/process()
..()
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 += 15
if(!owner)
return
/datum/organ/internal/liver
name = "liver"
parent_organ = "chest"
removed_type = /obj/item/organ/liver
if (germ_level > INFECTION_LEVEL_ONE)
if(prob(5))
owner.emote("cough") //respitory tract infection
process()
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 += 15
..()
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)
//High toxins levels are dangerous
if(owner.getToxLoss() >= 60 && !owner.reagents.has_reagent("anti_toxin"))
//Healthy liver suffers on its own
if (src.damage < min_broken_damage)
src.damage += 0.2 * PROCESS_ACCURACY
//Damaged one shares the fun
else
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"))
src.damage -= 0.2 * PROCESS_ACCURACY
if(src.damage < 0)
src.damage = 0
// Get the effectiveness of the liver.
var/filter_effect = 3
if(is_bruised())
filter_effect -= 1
if(is_broken())
filter_effect -= 2
// Do some reagent filtering/processing.
for(var/datum/reagent/R in owner.reagents.reagent_list)
// Damaged liver means some chemicals are very dangerous
// The liver is also responsible for clearing out alcohol and toxins.
// Ethanol and all drinks are bad.K
if(istype(R, /datum/reagent/ethanol))
if(filter_effect < 3)
owner.adjustToxLoss(0.1 * PROCESS_ACCURACY)
owner.reagents.remove_reagent(R.id, R.custom_metabolism*filter_effect)
// Can't cope with toxins at all
else if(istype(R, /datum/reagent/toxin))
if(filter_effect < 3)
owner.adjustToxLoss(0.3 * PROCESS_ACCURACY)
owner.reagents.remove_reagent(R.id, ALCOHOL_METABOLISM*filter_effect)
/datum/organ/internal/kidney
/obj/item/organ/kidneys
name = "kidneys"
icon_state = "kidneys"
gender = PLURAL
organ_tag = "kidneys"
parent_organ = "groin"
removed_type = /obj/item/organ/kidneys
process()
/obj/item/organ/kidney/process()
..()
..()
// Coffee is really bad for you with busted kidneys.
// This should probably be expanded in some way, but fucked if I know
// what else kidneys can process in our reagent list.
var/datum/reagent/coffee = locate(/datum/reagent/drink/coffee) in owner.reagents.reagent_list
if(coffee)
if(is_bruised())
owner.adjustToxLoss(0.1 * PROCESS_ACCURACY)
else if(is_broken())
owner.adjustToxLoss(0.3 * PROCESS_ACCURACY)
if(!owner)
return
/datum/organ/internal/brain
name = "brain"
parent_organ = "head"
removed_type = /obj/item/organ/brain
vital = 1
/datum/organ/internal/brain/xeno
removed_type = /obj/item/organ/brain/xeno
/datum/organ/internal/brain/golem
name = "golem chem"
removed_type = /obj/item/organ/brain/golem
/datum/organ/internal/brain/slime
name = "slime core"
removed_type = /obj/item/organ/brain/slime
/datum/organ/internal/eyes
name = "eyes"
parent_organ = "head"
removed_type = /obj/item/organ/eyes
process() //Eye damage replaces the old eye_stat var.
..()
// Coffee is really bad for you with busted kidneys.
// This should probably be expanded in some way, but fucked if I know
// what else kidneys can process in our reagent list.
var/datum/reagent/coffee = locate(/datum/reagent/drink/coffee) in owner.reagents.reagent_list
if(coffee)
if(is_bruised())
owner.eye_blurry = 20
owner.adjustToxLoss(0.1 * PROCESS_ACCURACY)
else if(is_broken())
owner.adjustToxLoss(0.3 * PROCESS_ACCURACY)
/obj/item/organ/eyes
name = "eyeballs"
icon_state = "eyes"
gender = PLURAL
organ_tag = "eyes"
parent_organ = "head"
var/eye_colour
/obj/item/organ/eyes/process() //Eye damage replaces the old eye_stat var.
..()
if(!owner)
return
if(is_bruised())
owner.eye_blurry = 20
if(is_broken())
owner.eye_blind = 20
/obj/item/organ/eyes/removed(var/mob/living/target,var/mob/living/user)
if(!eye_colour)
eye_colour = list(0,0,0)
..() //Make sure target is set so we can steal their eye colour for later.
var/mob/living/carbon/human/H = target
if(istype(H))
eye_colour = list(
H.r_eyes ? H.r_eyes : 0,
H.g_eyes ? H.g_eyes : 0,
H.b_eyes ? H.b_eyes : 0
)
// Leave bloody red pits behind!
H.r_eyes = 128
H.g_eyes = 0
H.b_eyes = 0
H.update_body()
/obj/item/organ/liver
name = "liver"
icon_state = "liver"
organ_tag = "liver"
parent_organ = "chest"
/obj/item/organ/liver/process()
..()
if(!owner)
return
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)
//High toxins levels are dangerous
if(owner.getToxLoss() >= 60 && !owner.reagents.has_reagent("anti_toxin"))
//Healthy liver suffers on its own
if (src.damage < min_broken_damage)
src.damage += 0.2 * PROCESS_ACCURACY
//Damaged one shares the fun
else
var/obj/item/organ/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"))
src.damage -= 0.2 * PROCESS_ACCURACY
if(src.damage < 0)
src.damage = 0
// Get the effectiveness of the liver.
var/filter_effect = 3
if(is_bruised())
filter_effect -= 1
if(is_broken())
owner.eye_blind = 20
filter_effect -= 2
/datum/organ/internal/appendix
// Do some reagent filtering/processing.
for(var/datum/reagent/R in owner.reagents.reagent_list)
// Damaged liver means some chemicals are very dangerous
// The liver is also responsible for clearing out alcohol and toxins.
// Ethanol and all drinks are bad.K
if(istype(R, /datum/reagent/ethanol))
if(filter_effect < 3)
owner.adjustToxLoss(0.1 * PROCESS_ACCURACY)
owner.reagents.remove_reagent(R.id, R.custom_metabolism*filter_effect)
// Can't cope with toxins at all
else if(istype(R, /datum/reagent/toxin))
if(filter_effect < 3)
owner.adjustToxLoss(0.3 * PROCESS_ACCURACY)
owner.reagents.remove_reagent(R.id, ALCOHOL_METABOLISM*filter_effect)
/obj/item/organ/appendix
name = "appendix"
icon_state = "appendix"
parent_organ = "groin"
removed_type = /obj/item/organ/appendix
/datum/organ/internal/proc/remove(var/mob/user)
/obj/item/organ/appendix/removed(var/mob/living/target,var/mob/living/user)
if(!removed_type) return 0
..()
var/turf/target_loc
if(user)
target_loc = get_turf(user)
else
target_loc = get_turf(owner)
var/inflamed = 0
for(var/datum/disease/appendicitis/appendicitis in target.viruses)
inflamed = 1
appendicitis.cure()
target.resistances += appendicitis
var/obj/item/organ/removed_organ = new removed_type(target_loc)
if(istype(removed_organ))
removed_organ.organ_data = src
removed_organ.update()
organ_holder = removed_organ
return removed_organ
if(inflamed)
icon_state = "appendixinflamed"
name = "inflamed appendix"

View File

@@ -1,270 +0,0 @@
/obj/item/organ
name = "organ"
desc = "It looks like it probably just plopped out."
icon = 'icons/obj/surgery.dmi'
icon_state = "appendix"
health = 100 // Process() ticks before death.
var/fresh = 3 // Squirts of blood left in it.
var/dead_icon // Icon used when the organ dies.
var/robotic // Is the limb prosthetic?
var/organ_tag // What slot does it go in?
var/organ_type = /datum/organ/internal // Used to spawn the relevant organ data when produced via a machine or spawn().
var/datum/organ/internal/organ_data // Stores info when removed.
var/prosthetic_name = "prosthetic organ" // Flavour string for robotic organ.
var/prosthetic_icon // Icon for robotic organ.
/obj/item/organ/attack_self(mob/user as mob)
// Convert it to an edible form, yum yum.
if(!robotic && user.a_intent == "help" && user.zone_sel.selecting == "mouth")
bitten(user)
return
/obj/item/organ/New()
..()
create_reagents(5)
if(!robotic)
processing_objects += src
spawn(1)
update()
/obj/item/organ/Del()
if(!robotic) processing_objects -= src
..()
/obj/item/organ/process()
if(robotic)
processing_objects -= src
return
// Don't process if we're in a freezer, an MMI or a stasis bag. //TODO: ambient temperature?
if(istype(loc,/obj/item/device/mmi) || istype(loc,/obj/item/bodybag/cryobag) || istype(loc,/obj/structure/closet/crate/freezer))
return
if(fresh && prob(40))
fresh--
var/datum/reagent/blood/B = locate(/datum/reagent/blood) in reagents.reagent_list
blood_splatter(src,B,1)
health -= rand(1,3)
if(health <= 0)
die()
/obj/item/organ/proc/die()
name = "dead [initial(name)]"
if(dead_icon) icon_state = dead_icon
health = 0
processing_objects -= src
//TODO: Grey out the icon state.
//TODO: Inject an organ with peridaxon to make it alive again.
/obj/item/organ/proc/roboticize()
robotic = (organ_data && organ_data.robotic) ? organ_data.robotic : 1
if(prosthetic_name)
name = prosthetic_name
if(prosthetic_icon)
icon_state = prosthetic_icon
else
//TODO: convert to greyscale.
/obj/item/organ/proc/update()
if(!organ_data)
organ_data = new /datum/organ/internal()
if(robotic)
organ_data.robotic = robotic
if(organ_data.robotic >= 2)
roboticize()
// Brain is defined in brain_item.dm.
/obj/item/organ/heart
name = "heart"
icon_state = "heart-on"
prosthetic_name = "circulatory pump"
prosthetic_icon = "heart-prosthetic"
organ_tag = "heart"
fresh = 6 // Juicy.
dead_icon = "heart-off"
/obj/item/organ/lungs
name = "lungs"
icon_state = "lungs"
gender = PLURAL
prosthetic_name = "gas exchange system"
prosthetic_icon = "lungs-prosthetic"
organ_tag = "lungs"
/obj/item/organ/kidneys
name = "kidneys"
icon_state = "kidneys"
gender = PLURAL
prosthetic_name = "prosthetic kidneys"
prosthetic_icon = "kidneys-prosthetic"
organ_tag = "kidneys"
/obj/item/organ/eyes
name = "eyeballs"
icon_state = "eyes"
gender = PLURAL
prosthetic_name = "visual prosthesis"
prosthetic_icon = "eyes-prosthetic"
organ_tag = "eyes"
var/eye_colour
/obj/item/organ/liver
name = "liver"
icon_state = "liver"
prosthetic_name = "toxin filter"
prosthetic_icon = "liver-prosthetic"
organ_tag = "liver"
/obj/item/organ/appendix
name = "appendix"
icon_state = "appendix"
organ_tag = "appendix"
//These are here so they can be printed out via the fabricator.
/obj/item/organ/heart/prosthetic
robotic = 2
/obj/item/organ/lungs/prosthetic
robotic = 2
/obj/item/organ/kidneys/prosthetic
robotic = 2
/obj/item/organ/eyes/prosthetic
robotic = 2
/obj/item/organ/liver/prosthetic
robotic = 2
/obj/item/organ/appendix
name = "appendix"
/obj/item/organ/proc/removed(var/mob/living/carbon/human/target,var/mob/living/user)
if(!istype(target) || !organ_data)
return
target.internal_organs_by_name[organ_tag] = null
target.internal_organs_by_name -= organ_tag
target.internal_organs -= organ_data
var/datum/organ/external/affected = target.get_organ(organ_data.parent_organ)
affected.internal_organs -= organ_data
loc = target.loc
organ_data.rejecting = null
var/datum/reagent/blood/organ_blood = locate(/datum/reagent/blood) in reagents.reagent_list
if(!organ_blood || !organ_blood.data["blood_DNA"])
target.vessel.trans_to(src, 5, 1, 1)
if(target && user && organ_data.vital)
user.attack_log += "\[[time_stamp()]\]<font color='red'> removed a vital organ ([src]) from [target.name] ([target.ckey]) (INTENT: [uppertext(user.a_intent)])</font>"
target.attack_log += "\[[time_stamp()]\]<font color='orange'> had a vital organ ([src]) removed by [user.name] ([user.ckey]) (INTENT: [uppertext(user.a_intent)])</font>"
msg_admin_attack("[user.name] ([user.ckey]) removed a vital organ ([src]) from [target.name] ([target.ckey]) (INTENT: [uppertext(user.a_intent)]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)")
target.death()
/obj/item/organ/appendix/removed(var/mob/living/target,var/mob/living/user)
..()
var/inflamed = 0
for(var/datum/disease/appendicitis/appendicitis in target.viruses)
inflamed = 1
appendicitis.cure()
target.resistances += appendicitis
if(inflamed)
icon_state = "appendixinflamed"
name = "inflamed appendix"
/obj/item/organ/eyes/removed(var/mob/living/target,var/mob/living/user)
if(!eye_colour)
eye_colour = list(0,0,0)
..() //Make sure target is set so we can steal their eye colour for later.
var/mob/living/carbon/human/H = target
if(istype(H))
eye_colour = list(
H.r_eyes ? H.r_eyes : 0,
H.g_eyes ? H.g_eyes : 0,
H.b_eyes ? H.b_eyes : 0
)
// Leave bloody red pits behind!
H.r_eyes = 128
H.g_eyes = 0
H.b_eyes = 0
H.update_body()
/obj/item/organ/proc/replaced(var/mob/living/carbon/human/target,var/datum/organ/external/affected)
if(!istype(target)) return
var/datum/reagent/blood/transplant_blood = locate(/datum/reagent/blood) in reagents.reagent_list
if(!transplant_blood)
organ_data.transplant_data = list()
organ_data.transplant_data["species"] = target.species.name
organ_data.transplant_data["blood_type"] = target.dna.b_type
organ_data.transplant_data["blood_DNA"] = target.dna.unique_enzymes
else
organ_data.transplant_data = list()
organ_data.transplant_data["species"] = transplant_blood.data["species"]
organ_data.transplant_data["blood_type"] = transplant_blood.data["blood_type"]
organ_data.transplant_data["blood_DNA"] = transplant_blood.data["blood_DNA"]
organ_data.organ_holder = null
organ_data.owner = target
target.internal_organs |= organ_data
affected.internal_organs |= organ_data
target.internal_organs_by_name[organ_tag] = organ_data
organ_data.status |= ORGAN_CUT_AWAY
del(src)
/obj/item/organ/eyes/replaced(var/mob/living/carbon/human/target)
// Apply our eye colour to the target.
if(istype(target) && eye_colour)
target.r_eyes = eye_colour[1]
target.g_eyes = eye_colour[2]
target.b_eyes = eye_colour[3]
target.update_body()
..()
/obj/item/organ/proc/bitten(mob/user)
if(robotic)
return
user << "\blue You take an experimental bite out of \the [src]."
var/datum/reagent/blood/B = locate(/datum/reagent/blood) in reagents.reagent_list
blood_splatter(src,B,1)
user.drop_from_inventory(src)
var/obj/item/weapon/reagent_containers/food/snacks/organ/O = new(get_turf(src))
O.name = name
O.icon_state = dead_icon ? dead_icon : icon_state
// Pass over the blood.
reagents.trans_to(O, reagents.total_volume)
if(fingerprints) O.fingerprints = fingerprints.Copy()
if(fingerprintshidden) O.fingerprintshidden = fingerprintshidden.Copy()
if(fingerprintslast) O.fingerprintslast = fingerprintslast
user.put_in_active_hand(O)
del(src)

View File

@@ -87,8 +87,8 @@ mob/living/carbon/human/proc/handle_pain()
if(analgesic)
return
var/maxdam = 0
var/datum/organ/external/damaged_organ = null
for(var/datum/organ/external/E in organs)
var/obj/item/organ/external/damaged_organ = null
for(var/obj/item/organ/external/E in organs)
// amputated limbs don't cause pain
if(E.amputated) continue
if(E.status & ORGAN_DEAD) continue
@@ -102,9 +102,9 @@ mob/living/carbon/human/proc/handle_pain()
pain(damaged_organ.display_name, maxdam, 0)
// Damage to internal organs hurts a lot.
for(var/datum/organ/internal/I in internal_organs)
for(var/obj/item/organ/I in internal_organs)
if(I.damage > 2) if(prob(2))
var/datum/organ/external/parent = get_organ(I.parent_organ)
var/obj/item/organ/external/parent = get_organ(I.parent_organ)
src.custom_pain("You feel a sharp pain in your [parent.display_name]", 1)
var/toxDamageMessage = null