mirror of
https://github.com/PolarisSS13/Polaris.git
synced 2025-12-26 18:13:11 +00:00
Merge branch 'dev' into ofChemistryAndStuff
Conflicts: code/modules/mob/living/carbon/carbon.dm code/modules/organs/organ_internal.dm code/modules/organs/organ_objects.dm code/modules/reagents/Chemistry-Reagents.dm code/modules/reagents/reagent_containers/syringes.dm
This commit is contained in:
@@ -61,7 +61,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
|
||||
@@ -123,7 +123,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())
|
||||
|
||||
@@ -1,26 +1,154 @@
|
||||
/datum/organ
|
||||
var/name = "organ"
|
||||
var/list/organ_cache = list()
|
||||
|
||||
/obj/item/organ
|
||||
name = "organ"
|
||||
icon = 'icons/obj/surgery.dmi'
|
||||
|
||||
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/proc/update_health()
|
||||
return
|
||||
|
||||
proc/process()
|
||||
return 0
|
||||
/obj/item/organ/New(var/mob/living/carbon/holder, var/internal)
|
||||
..(holder)
|
||||
create_reagents(5)
|
||||
if(!max_damage)
|
||||
max_damage = min_broken_damage * 2
|
||||
if(istype(holder))
|
||||
src.owner = holder
|
||||
var/mob/living/carbon/human/H = holder
|
||||
if(istype(H))
|
||||
if(internal)
|
||||
var/obj/item/organ/external/E = H.organs_by_name[src.parent_organ]
|
||||
if(E)
|
||||
if(E.internal_organs == null)
|
||||
E.internal_organs = list()
|
||||
E.internal_organs |= src
|
||||
if(H.dna)
|
||||
if(!blood_DNA)
|
||||
blood_DNA = list()
|
||||
blood_DNA[H.dna.unique_enzymes] = H.dna.b_type
|
||||
if(internal)
|
||||
holder.internal_organs |= src
|
||||
|
||||
proc/receive_chem(chemical as obj)
|
||||
return 0
|
||||
/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.
|
||||
|
||||
/datum/organ/proc/get_icon(var/icon/race_icon, var/icon/deform_icon)
|
||||
return icon('icons/mob/human.dmi',"blank")
|
||||
/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 && owner.species && (owner.species.flags & IS_PLANT)))
|
||||
germ_level = 0
|
||||
return
|
||||
|
||||
if(loc != owner)
|
||||
owner = null
|
||||
|
||||
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/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 +161,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 +173,147 @@
|
||||
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.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/user)
|
||||
|
||||
if(!istype(owner))
|
||||
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
|
||||
owner.internal_organs_by_name[organ_tag] = null
|
||||
owner.internal_organs_by_name -= organ_tag
|
||||
owner.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 = owner.get_organ(parent_organ)
|
||||
if(affected) 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 = owner.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"])
|
||||
owner.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(owner && vital)
|
||||
if(user)
|
||||
user.attack_log += "\[[time_stamp()]\]<font color='red'> removed a vital organ ([src]) from [owner.name] ([owner.ckey]) (INTENT: [uppertext(user.a_intent)])</font>"
|
||||
owner.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 [owner.name] ([owner.ckey]) (INTENT: [uppertext(user.a_intent)]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)")
|
||||
owner.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
|
||||
|
||||
@@ -1,51 +1,6 @@
|
||||
//DIONA ORGANS.
|
||||
/datum/organ/internal/diona
|
||||
removed_type = /obj/item/organ/diona
|
||||
|
||||
/datum/organ/internal/diona/process()
|
||||
return
|
||||
|
||||
/datum/organ/internal/diona/strata
|
||||
name = "neural strata"
|
||||
parent_organ = "chest"
|
||||
|
||||
/datum/organ/internal/diona/bladder
|
||||
name = "gas bladder"
|
||||
parent_organ = "head"
|
||||
|
||||
/datum/organ/internal/diona/polyp
|
||||
name = "polyp segment"
|
||||
parent_organ = "groin"
|
||||
|
||||
/datum/organ/internal/diona/ligament
|
||||
name = "anchoring ligament"
|
||||
parent_organ = "groin"
|
||||
|
||||
/datum/organ/internal/diona/node
|
||||
name = "receptor node"
|
||||
parent_organ = "head"
|
||||
removed_type = /obj/item/organ/diona/node
|
||||
|
||||
/datum/organ/internal/diona/nutrients
|
||||
name = "nutrient vessel"
|
||||
parent_organ = "chest"
|
||||
removed_type = /obj/item/organ/diona/nutrients
|
||||
|
||||
/obj/item/organ/diona
|
||||
name = "diona nymph"
|
||||
icon = 'icons/obj/objects.dmi'
|
||||
icon_state = "nymph"
|
||||
organ_tag = "special" // Turns into a nymph instantly, no transplanting possible.
|
||||
|
||||
/obj/item/organ/diona/removed(var/mob/living/target,var/mob/living/user)
|
||||
|
||||
..()
|
||||
var/mob/living/carbon/human/H = target
|
||||
if(!istype(target))
|
||||
del(src)
|
||||
|
||||
if(!H.internal_organs.len)
|
||||
H.death()
|
||||
/proc/spawn_diona_nymph_from_organ(var/obj/item/organ/organ)
|
||||
if(!istype(organ))
|
||||
return
|
||||
|
||||
//This is a terrible hack and I should be ashamed.
|
||||
var/datum/seed/diona = plant_controller.seeds["diona"]
|
||||
@@ -53,10 +8,180 @@
|
||||
del(src)
|
||||
|
||||
spawn(1) // So it has time to be thrown about by the gib() proc.
|
||||
var/mob/living/carbon/alien/diona/D = new(get_turf(src))
|
||||
var/mob/living/carbon/alien/diona/D = new(get_turf(organ))
|
||||
diona.request_player(D)
|
||||
del(organ)
|
||||
|
||||
/obj/item/organ/external/diona
|
||||
name = "tendril"
|
||||
cannot_break = 1
|
||||
amputation_point = "branch"
|
||||
joint = "structural ligament"
|
||||
dislocated = -1
|
||||
|
||||
/obj/item/organ/external/diona/chest
|
||||
name = "core trunk"
|
||||
limb_name = "chest"
|
||||
icon_name = "torso"
|
||||
health = 200
|
||||
min_broken_damage = 50
|
||||
body_part = UPPER_TORSO
|
||||
vital = 1
|
||||
cannot_amputate = 1
|
||||
parent_organ = null
|
||||
|
||||
/obj/item/organ/external/diona/groin
|
||||
name = "fork"
|
||||
limb_name = "groin"
|
||||
icon_name = "groin"
|
||||
health = 100
|
||||
min_broken_damage = 50
|
||||
body_part = LOWER_TORSO
|
||||
parent_organ = "chest"
|
||||
|
||||
/obj/item/organ/external/diona/arm
|
||||
name = "left upper tendril"
|
||||
limb_name = "l_arm"
|
||||
icon_name = "l_arm"
|
||||
health = 35
|
||||
min_broken_damage = 20
|
||||
body_part = ARM_LEFT
|
||||
parent_organ = "chest"
|
||||
can_grasp = 1
|
||||
|
||||
/obj/item/organ/external/diona/arm/right
|
||||
name = "right upper tendril"
|
||||
limb_name = "r_arm"
|
||||
icon_name = "r_arm"
|
||||
body_part = ARM_RIGHT
|
||||
|
||||
/obj/item/organ/external/diona/leg
|
||||
name = "left lower tendril"
|
||||
limb_name = "l_leg"
|
||||
icon_name = "l_leg"
|
||||
health = 35
|
||||
min_broken_damage = 20
|
||||
body_part = LEG_LEFT
|
||||
icon_position = LEFT
|
||||
parent_organ = "groin"
|
||||
can_stand = 1
|
||||
|
||||
/obj/item/organ/external/diona/leg/right
|
||||
name = "right lower tendril"
|
||||
limb_name = "r_leg"
|
||||
icon_name = "r_leg"
|
||||
body_part = LEG_RIGHT
|
||||
icon_position = RIGHT
|
||||
|
||||
/obj/item/organ/external/diona/foot
|
||||
name = "left foot"
|
||||
limb_name = "l_foot"
|
||||
icon_name = "l_foot"
|
||||
health = 20
|
||||
min_broken_damage = 10
|
||||
body_part = FOOT_LEFT
|
||||
icon_position = LEFT
|
||||
parent_organ = "l_leg"
|
||||
can_stand = 1
|
||||
|
||||
/obj/item/organ/external/diona/foot/right
|
||||
name = "right foot"
|
||||
limb_name = "r_foot"
|
||||
icon_name = "r_foot"
|
||||
body_part = FOOT_RIGHT
|
||||
icon_position = RIGHT
|
||||
parent_organ = "r_leg"
|
||||
joint = "right ankle"
|
||||
amputation_point = "right ankle"
|
||||
|
||||
/obj/item/organ/external/diona/hand
|
||||
name = "left grasper"
|
||||
limb_name = "l_hand"
|
||||
icon_name = "l_hand"
|
||||
health = 30
|
||||
min_broken_damage = 15
|
||||
body_part = HAND_LEFT
|
||||
parent_organ = "l_arm"
|
||||
can_grasp = 1
|
||||
|
||||
/obj/item/organ/external/diona/hand/right
|
||||
name = "right grasper"
|
||||
limb_name = "r_hand"
|
||||
icon_name = "r_hand"
|
||||
body_part = HAND_RIGHT
|
||||
parent_organ = "r_arm"
|
||||
|
||||
/obj/item/organ/external/diona/head
|
||||
limb_name = "head"
|
||||
icon_name = "head"
|
||||
name = "head"
|
||||
health = 50
|
||||
min_broken_damage = 25
|
||||
body_part = HEAD
|
||||
parent_organ = "chest"
|
||||
|
||||
/obj/item/organ/external/diona/head/removed()
|
||||
if(owner)
|
||||
owner.u_equip(owner.head)
|
||||
owner.u_equip(owner.l_ear)
|
||||
..()
|
||||
|
||||
//DIONA ORGANS.
|
||||
/obj/item/organ/external/diona/removed()
|
||||
..()
|
||||
if(!istype(owner))
|
||||
del(src)
|
||||
|
||||
if(!owner.organs.len)
|
||||
owner.death()
|
||||
|
||||
if(prob(50))
|
||||
spawn_diona_nymph_from_organ(src)
|
||||
|
||||
/obj/item/organ/diona/process()
|
||||
return
|
||||
|
||||
/obj/item/organ/diona/strata
|
||||
name = "neural strata"
|
||||
parent_organ = "chest"
|
||||
|
||||
/obj/item/organ/diona/bladder
|
||||
name = "gas bladder"
|
||||
parent_organ = "head"
|
||||
|
||||
/obj/item/organ/diona/polyp
|
||||
name = "polyp segment"
|
||||
parent_organ = "groin"
|
||||
|
||||
/obj/item/organ/diona/ligament
|
||||
name = "anchoring ligament"
|
||||
parent_organ = "groin"
|
||||
|
||||
/obj/item/organ/diona/node
|
||||
name = "receptor node"
|
||||
parent_organ = "head"
|
||||
|
||||
/obj/item/organ/diona/nutrients
|
||||
name = "nutrient vessel"
|
||||
parent_organ = "chest"
|
||||
|
||||
/obj/item/organ/diona
|
||||
name = "diona nymph"
|
||||
icon = 'icons/obj/objects.dmi'
|
||||
icon_state = "nymph"
|
||||
organ_tag = "special" // Turns into a nymph instantly, no transplanting possible.
|
||||
|
||||
/obj/item/organ/diona/removed(var/mob/living/user)
|
||||
|
||||
..()
|
||||
if(!istype(owner))
|
||||
del(src)
|
||||
|
||||
if(!owner.internal_organs.len)
|
||||
owner.death()
|
||||
|
||||
spawn_diona_nymph_from_organ(src)
|
||||
|
||||
// These are different to the standard diona organs as they have a purpose in other
|
||||
// species (absorbing radiation and light respectively)
|
||||
/obj/item/organ/diona/nutrients
|
||||
@@ -78,13 +203,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"))
|
||||
@@ -113,59 +237,54 @@
|
||||
organ_tag = "brain"
|
||||
desc = "A disgusting space slug."
|
||||
|
||||
/obj/item/organ/borer/removed(var/mob/living/target,var/mob/living/user)
|
||||
/obj/item/organ/borer/removed(var/mob/living/user)
|
||||
|
||||
..()
|
||||
|
||||
var/mob/living/simple_animal/borer/B = target.has_brain_worms()
|
||||
var/mob/living/simple_animal/borer/B = owner.has_brain_worms()
|
||||
if(B)
|
||||
B.leave_host()
|
||||
B.ckey = target.ckey
|
||||
B.ckey = owner.ckey
|
||||
|
||||
spawn(0)
|
||||
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 +317,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"
|
||||
File diff suppressed because it is too large
Load Diff
111
code/modules/organs/organ_icon.dm
Normal file
111
code/modules/organs/organ_icon.dm
Normal file
@@ -0,0 +1,111 @@
|
||||
var/global/list/limb_icon_cache = list()
|
||||
|
||||
/obj/item/organ/external/set_dir()
|
||||
return
|
||||
|
||||
/obj/item/organ/external/proc/compile_icon()
|
||||
overlays.Cut()
|
||||
get_icon()
|
||||
// This is a kludge, only one icon has more than one generation of children though.
|
||||
for(var/obj/item/organ/external/organ in contents)
|
||||
if(organ.children && organ.children.len)
|
||||
for(var/obj/item/organ/external/child in organ.children)
|
||||
overlays += child.get_icon()
|
||||
overlays += organ.get_icon()
|
||||
|
||||
/obj/item/organ/external/proc/sync_colour_to_human(var/mob/living/carbon/human/human)
|
||||
s_tone = null
|
||||
s_col = null
|
||||
if(human.s_tone && (human.species.flags & HAS_SKIN_TONE))
|
||||
s_tone = human.s_tone
|
||||
if(human.species.flags & HAS_SKIN_COLOR)
|
||||
s_col = list(human.r_skin, human.g_skin, human.b_skin)
|
||||
|
||||
/obj/item/organ/external/proc/get_icon(var/skeletal)
|
||||
|
||||
var/gender
|
||||
if(force_icon)
|
||||
mob_icon = new /icon(force_icon, "[icon_name]")
|
||||
else
|
||||
if(!owner)
|
||||
mob_icon = new /icon('icons/mob/human_races/r_human.dmi', "[icon_name][gendered_icon ? "_f" : ""]")
|
||||
else
|
||||
|
||||
if(gendered_icon)
|
||||
if(owner.gender == FEMALE)
|
||||
gender = "f"
|
||||
else
|
||||
gender = "m"
|
||||
|
||||
if(skeletal)
|
||||
mob_icon = new /icon('icons/mob/human_races/r_skeleton.dmi', "[icon_name][gender ? "_[gender]" : ""]")
|
||||
else if ((status & ORGAN_ROBOT) && !(owner.species && owner.species.flags & IS_SYNTHETIC))
|
||||
mob_icon = new /icon('icons/mob/human_races/robotic.dmi', "[icon_name][gender ? "_[gender]" : ""]")
|
||||
else
|
||||
if (status & ORGAN_MUTATED)
|
||||
mob_icon = new /icon(owner.species.deform, "[icon_name][gender ? "_[gender]" : ""]")
|
||||
else
|
||||
mob_icon = new /icon(owner.species.icobase, "[icon_name][gender ? "_[gender]" : ""]")
|
||||
|
||||
if(status & ORGAN_DEAD)
|
||||
mob_icon.ColorTone(rgb(10,50,0))
|
||||
mob_icon.SetIntensity(0.7)
|
||||
|
||||
if(!isnull(s_tone))
|
||||
if(s_tone >= 0)
|
||||
mob_icon.Blend(rgb(s_tone, s_tone, s_tone), ICON_ADD)
|
||||
else
|
||||
mob_icon.Blend(rgb(-s_tone, -s_tone, -s_tone), ICON_SUBTRACT)
|
||||
else if(s_col && s_col.len >= 3)
|
||||
mob_icon.Blend(rgb(s_col[1], s_col[2], s_col[3]), ICON_ADD)
|
||||
|
||||
dir = EAST
|
||||
icon = mob_icon
|
||||
|
||||
return mob_icon
|
||||
|
||||
/obj/item/organ/external/head/get_icon(var/skeletal)
|
||||
|
||||
if(skeletal || !owner)
|
||||
return
|
||||
|
||||
..()
|
||||
|
||||
if(owner.species.has_organ["eyes"])
|
||||
var/obj/item/organ/eyes/eyes = owner.internal_organs_by_name["eyes"]
|
||||
if(eyes && owner.species.eyes)
|
||||
var/icon/eyes_icon = new/icon('icons/mob/human_face.dmi', owner.species.eyes)
|
||||
eyes_icon.Blend(rgb(eyes.eye_colour[1], eyes.eye_colour[2], eyes.eye_colour[3]), ICON_ADD)
|
||||
mob_icon.Blend(eyes_icon, ICON_OVERLAY)
|
||||
|
||||
if(owner.lip_style && (owner.species && (owner.species.flags & HAS_LIPS)))
|
||||
mob_icon.Blend(new/icon('icons/mob/human_face.dmi', "lips_[owner.lip_style]_s"), ICON_OVERLAY)
|
||||
|
||||
if(owner.f_style)
|
||||
var/datum/sprite_accessory/facial_hair_style = facial_hair_styles_list[owner.f_style]
|
||||
if(facial_hair_style)
|
||||
var/icon/facial = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_s")
|
||||
if(facial_hair_style.do_colouration)
|
||||
facial.Blend(rgb(owner.r_facial, owner.g_facial, owner.b_facial), ICON_ADD)
|
||||
mob_icon.Blend(facial, ICON_OVERLAY)
|
||||
|
||||
if(owner.h_style && !(owner.head && (owner.head.flags & BLOCKHEADHAIR)))
|
||||
var/datum/sprite_accessory/hair_style = hair_styles_list[owner.h_style]
|
||||
if(hair_style)
|
||||
var/icon/hair = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s")
|
||||
if(hair_style.do_colouration)
|
||||
hair.Blend(rgb(owner.r_hair, owner.g_hair, owner.b_hair), ICON_ADD)
|
||||
|
||||
mob_icon.Blend(hair, ICON_OVERLAY)
|
||||
|
||||
icon = mob_icon
|
||||
return mob_icon
|
||||
|
||||
// new damage icon system
|
||||
// adjusted to set damage_state to brute/burn code only (without r_name0 as before)
|
||||
/obj/item/organ/external/update_icon()
|
||||
var/n_is = damage_state_text()
|
||||
if (n_is != damage_state)
|
||||
damage_state = n_is
|
||||
return 1
|
||||
return 0
|
||||
@@ -1,288 +1,183 @@
|
||||
#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 processing.
|
||||
if(owner.chem_effects[CE_ALCOHOL_TOXIC])
|
||||
if(filter_effect < 3)
|
||||
owner.adjustToxLoss(owner.chem_effects[CE_ALCOHOL_TOXIC] * 0.1 * PROCESS_ACCURACY)
|
||||
else
|
||||
take_damage(owner.chem_effects[CE_ALCOHOL_TOXIC] * 0.1 * PROCESS_ACCURACY, prob(1)) // Chance to warn them
|
||||
|
||||
/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/list/eye_colour = list(0,0,0)
|
||||
|
||||
/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/New()
|
||||
..()
|
||||
if(owner)
|
||||
eye_colour = list(
|
||||
owner.r_eyes ? owner.r_eyes : 0,
|
||||
owner.g_eyes ? owner.g_eyes : 0,
|
||||
owner.b_eyes ? owner.b_eyes : 0
|
||||
)
|
||||
|
||||
/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 processing.
|
||||
if(owner.chem_effects[CE_ALCOHOL_TOXIC])
|
||||
if(filter_effect < 3)
|
||||
owner.adjustToxLoss(owner.chem_effects[CE_ALCOHOL_TOXIC] * 0.1 * PROCESS_ACCURACY)
|
||||
else
|
||||
take_damage(owner.chem_effects[CE_ALCOHOL_TOXIC] * 0.1 * PROCESS_ACCURACY, prob(1)) // Chance to warn them
|
||||
|
||||
/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()
|
||||
|
||||
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 owner.viruses)
|
||||
inflamed = 1
|
||||
appendicitis.cure()
|
||||
owner.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"
|
||||
|
||||
24
code/modules/organs/organ_stump.dm
Normal file
24
code/modules/organs/organ_stump.dm
Normal file
@@ -0,0 +1,24 @@
|
||||
/obj/item/organ/external/stump
|
||||
name = "limb stump"
|
||||
icon_name = ""
|
||||
dislocated = -1
|
||||
cannot_amputate = 1
|
||||
|
||||
/obj/item/organ/external/stump/New(var/mob/living/carbon/holder, var/internal, var/obj/item/organ/external/limb)
|
||||
if(istype(limb))
|
||||
limb_name = limb.limb_name
|
||||
body_part = limb.body_part
|
||||
amputation_point = limb.amputation_point
|
||||
joint = limb.joint
|
||||
parent_organ = limb.parent_organ
|
||||
wounds = limb.wounds
|
||||
..(holder, internal)
|
||||
if(istype(limb))
|
||||
max_damage = limb.max_damage
|
||||
|
||||
/obj/item/organ/external/stump/is_stump()
|
||||
return 1
|
||||
|
||||
/obj/item/organ/external/stump/removed()
|
||||
..()
|
||||
del(src)
|
||||
@@ -77,10 +77,8 @@ mob/living/carbon/human/proc/handle_pain()
|
||||
if(analgesic > 70)
|
||||
return
|
||||
var/maxdam = 0
|
||||
var/datum/organ/external/damaged_organ = null
|
||||
for(var/datum/organ/external/E in organs)
|
||||
// amputated limbs don't cause pain
|
||||
if(E.amputated) continue
|
||||
var/obj/item/organ/external/damaged_organ = null
|
||||
for(var/obj/item/organ/external/E in organs)
|
||||
if(E.status & ORGAN_DEAD) continue
|
||||
var/dam = E.get_damage()
|
||||
// make the choice of the organ depend on damage,
|
||||
@@ -89,13 +87,13 @@ mob/living/carbon/human/proc/handle_pain()
|
||||
damaged_organ = E
|
||||
maxdam = dam
|
||||
if(damaged_organ)
|
||||
pain(damaged_organ.display_name, maxdam, 0)
|
||||
pain(damaged_organ.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)
|
||||
src.custom_pain("You feel a sharp pain in your [parent.display_name]", 1)
|
||||
var/obj/item/organ/external/parent = get_organ(I.parent_organ)
|
||||
src.custom_pain("You feel a sharp pain in your [parent.name]", 1)
|
||||
|
||||
var/toxDamageMessage = null
|
||||
var/toxMessageProb = 1
|
||||
|
||||
37
code/modules/organs/robolimbs.dm
Normal file
37
code/modules/organs/robolimbs.dm
Normal file
@@ -0,0 +1,37 @@
|
||||
var/global/list/all_robolimbs = list()
|
||||
var/global/list/chargen_robolimbs = list()
|
||||
var/global/datum/robolimb/basic_robolimb
|
||||
|
||||
/proc/populate_robolimb_list()
|
||||
basic_robolimb = new()
|
||||
for(var/limb_type in typesof(/datum/robolimb))
|
||||
var/datum/robolimb/R = new limb_type()
|
||||
all_robolimbs[R.company] = R
|
||||
if(!R.unavailable_at_chargen)
|
||||
chargen_robolimbs[R.company] = R
|
||||
|
||||
/datum/robolimb
|
||||
var/company = "Unbranded" // Shown when selecting the limb.
|
||||
var/desc = "A generic unbranded robotic prosthesis." // Seen when examining a limb.
|
||||
var/icon = 'icons/mob/human_races/robotic.dmi' // Icon base to draw from.
|
||||
var/unavailable_at_chargen // If set, not available at chargen.
|
||||
|
||||
/datum/robolimb/bishop
|
||||
company = "Bishop Cybernetics"
|
||||
desc = "This limb has a white polymer casing with blue holo-displays."
|
||||
icon = 'icons/mob/human_races/cyberlimbs/bishop.dmi'
|
||||
|
||||
/datum/robolimb/hesphaistos
|
||||
company = "Hesphiastos Industries"
|
||||
desc = "This limb has a militaristic black and green casing with gold stripes."
|
||||
icon = 'icons/mob/human_races/cyberlimbs/hesphaistos.dmi'
|
||||
|
||||
/datum/robolimb/zenghu
|
||||
company = "Zeng-Hu Pharmaceuticals"
|
||||
desc = "This limb has a rubbery fleshtone covering with visible seams."
|
||||
icon = 'icons/mob/human_races/cyberlimbs/zenghu.dmi'
|
||||
|
||||
/datum/robolimb/xion
|
||||
company = "Xion Manufacturing Group"
|
||||
desc = "This limb has a minimalist black and red casing."
|
||||
icon = 'icons/mob/human_races/cyberlimbs/xion.dmi'
|
||||
Reference in New Issue
Block a user