Merge pull request #2539 from comma/organ

Organ code restructuring
This commit is contained in:
Christian Bielert
2013-03-16 07:10:40 -07:00
17 changed files with 1353 additions and 1385 deletions

View File

@@ -166,11 +166,6 @@
#include "code\datums\helper_datums\global_iterator.dm" #include "code\datums\helper_datums\global_iterator.dm"
#include "code\datums\helper_datums\teleport.dm" #include "code\datums\helper_datums\teleport.dm"
#include "code\datums\helper_datums\topic_input.dm" #include "code\datums\helper_datums\topic_input.dm"
#include "code\datums\organs\organ.dm"
#include "code\datums\organs\organ_external.dm"
#include "code\datums\organs\organ_internal.dm"
#include "code\datums\organs\pain.dm"
#include "code\datums\organs\wound.dm"
#include "code\datums\spells\area_teleport.dm" #include "code\datums\spells\area_teleport.dm"
#include "code\datums\spells\conjure.dm" #include "code\datums\spells\conjure.dm"
#include "code\datums\spells\dumbfire.dm" #include "code\datums\spells\dumbfire.dm"
@@ -508,6 +503,7 @@
#include "code\game\objects\items\robot\robot_parts.dm" #include "code\game\objects\items\robot\robot_parts.dm"
#include "code\game\objects\items\robot\robot_upgrades.dm" #include "code\game\objects\items\robot\robot_upgrades.dm"
#include "code\game\objects\items\stacks\medical.dm" #include "code\game\objects\items\stacks\medical.dm"
#include "code\game\objects\items\stacks\nanopaste.dm"
#include "code\game\objects\items\stacks\rods.dm" #include "code\game\objects\items\stacks\rods.dm"
#include "code\game\objects\items\stacks\stack.dm" #include "code\game\objects\items\stacks\stack.dm"
#include "code\game\objects\items\stacks\sheets\glass.dm" #include "code\game\objects\items\stacks\sheets\glass.dm"
@@ -1029,6 +1025,12 @@
#include "code\modules\mob\new_player\preferences_setup.dm" #include "code\modules\mob\new_player\preferences_setup.dm"
#include "code\modules\mob\new_player\skill.dm" #include "code\modules\mob\new_player\skill.dm"
#include "code\modules\mob\new_player\sprite_accessories.dm" #include "code\modules\mob\new_player\sprite_accessories.dm"
#include "code\modules\organs\blood.dm"
#include "code\modules\organs\organ.dm"
#include "code\modules\organs\organ_external.dm"
#include "code\modules\organs\organ_internal.dm"
#include "code\modules\organs\pain.dm"
#include "code\modules\organs\wound.dm"
#include "code\modules\paperwork\clipboard.dm" #include "code\modules\paperwork\clipboard.dm"
#include "code\modules\paperwork\filingcabinet.dm" #include "code\modules\paperwork\filingcabinet.dm"
#include "code\modules\paperwork\folders.dm" #include "code\modules\paperwork\folders.dm"

View File

@@ -1,20 +0,0 @@
/datum/organ
var/name = "organ"
var/mob/living/carbon/human/owner = null
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
///datum/organ/proc/process()
// return 0
///datum/organ/proc/receive_chem(chemical as obj)
// return 0
proc/process()
return 0
proc/receive_chem(chemical as obj)
return 0

View File

@@ -84,7 +84,7 @@
if(istype(src.beaker, /obj/item/weapon/reagent_containers/blood)) if(istype(src.beaker, /obj/item/weapon/reagent_containers/blood))
// speed up transfer on blood packs // speed up transfer on blood packs
transfer_amount = 4 transfer_amount = 4
src.beaker.reagents.trans_to(src.attached, transfer_amount) attached.inject_blood(beaker,transfer_amount)
update_icon() update_icon()
// Take blood // Take blood
@@ -99,52 +99,23 @@
var/mob/living/carbon/human/T = attached var/mob/living/carbon/human/T = attached
if(!istype(T)) return if(!istype(T)) return
var/datum/reagent/B
for(var/datum/reagent/blood/Blood in beaker.reagents.reagent_list)
if(Blood.data && Blood.data["blood_type"]==T.dna.b_type)
B = Blood
break
if(!B) B = new /datum/reagent/blood
if(!T.dna) if(!T.dna)
return return
if(NOCLONE in T.mutations) if(NOCLONE in T.mutations)
return return
// If the human is losing too much blood, beep. // If the human is losing too much blood, beep.
if(T.vessel.get_reagent_amount("blood") < BLOOD_VOLUME_SAFE) if(prob(5)) if(T.vessel.get_reagent_amount("blood") < BLOOD_VOLUME_SAFE) if(prob(5))
visible_message("\The [src] beeps loudly.") visible_message("\The [src] beeps loudly.")
if(T.vessel.get_reagent_amount("blood") < amount)
return
B.holder = beaker
B.volume += amount
//set reagent data
B.data["donor"] = T
if(T.virus2) var/datum/reagent/B = T.take_blood(beaker,amount)
B.data["virus2"] = T.virus2.getcopy()
B.data["blood_DNA"] = copytext(T.dna.unique_enzymes,1,0) if (B)
if(T.resistances && T.resistances.len) beaker.reagents.reagent_list |= B
if(B.data["resistances"]) beaker.reagents.update_total()
B.data["resistances"] |= T.resistances.Copy() beaker.on_reagent_change()
else beaker.reagents.handle_reactions()
B.data["resistances"] = T.resistances.Copy() update_icon()
B.data["blood_type"] = copytext(T.dna.b_type,1,0)
var/list/temp_chem = list()
for(var/datum/reagent/R in T.reagents.reagent_list)
temp_chem += R.name
temp_chem[R.name] = R.volume
B.data["trace_chem"] = list2params(temp_chem)
B.data["antibodies"] |= T.antibodies
T.vessel.remove_reagent("blood",amount) // Removes blood if human
beaker.reagents.reagent_list |= B
beaker.reagents.update_total()
beaker.on_reagent_change()
beaker.reagents.handle_reactions()
update_icon()
/obj/machinery/iv_drip/attack_hand(mob/user as mob) /obj/machinery/iv_drip/attack_hand(mob/user as mob)
if(src.beaker) if(src.beaker)

View File

@@ -0,0 +1,37 @@
/obj/item/stack/nanopaste
name = "nanopaste"
singular_name = "nanite swarm"
desc = "A tube of paste containing swarms of repair nanties. Very effective in repairing robotic machinery."
icon = 'icons/obj/nanopaste.dmi'
icon_state = "tube"
origin_tech = "materials=4;engineering=3"
amount = 10
/obj/item/stack/nanopaste/attack(mob/living/M as mob, mob/user as mob)
if (!istype(M) || !istype(user))
return 0
if (istype(M,/mob/living/silicon/robot)) //Repairing cyborgs
var/mob/living/silicon/robot/R = M
if (R.getBruteLoss() || R.getFireLoss() )
R.adjustBruteLoss(-60)
R.adjustFireLoss(-60)
R.updatehealth()
use(1)
user.visible_message("<span class='notice'>You apply some [src] at [R]'s damaged areas.</span>",\
"<span class='notice'>\The [user] applied some [src] at [R]'s damaged areas.</span>")
else
user << "<span class='notice'>All [R]'s systems are nominal.</span>"
if (istype(M,/mob/living/carbon/human)) //Repairing robolimbs
var/mob/living/carbon/human/H = M
var/datum/organ/external/S = H.get_organ(user.zone_sel.selecting)
if (S && (S.status & ORGAN_ROBOT))
if(S.get_damage())
S.heal_damage(30, 30, robo_repair = 1)
H.updatehealth()
use(1)
user.visible_message("<span class='notice'>You apply some nanite paste at [user == M ? "your" : "[M]'s"] [S.display_name]</span>",\
"<span class='notice'>\The [user] applies some nanite paste at[user != M ? " \the [M]'s" : " \the"][S.display_name] with \the [src]</span>")
else
user << "<span class='notice'>Nothing to fix here.</span>"

View File

@@ -5,10 +5,6 @@
icon = 'icons/mob/human.dmi' icon = 'icons/mob/human.dmi'
icon_state = "body_m_s" icon_state = "body_m_s"
var/datum/reagents/vessel
// TODO: make this actually affect the way the mob is rendered
var/pale = 0
/mob/living/carbon/human/dummy /mob/living/carbon/human/dummy
real_name = "Test Dummy" real_name = "Test Dummy"
@@ -24,78 +20,14 @@
if(!dna) if(!dna)
dna = new /datum/dna(null) dna = new /datum/dna(null)
//initialise organs
organs = list()
organs_by_name["chest"] = new/datum/organ/external/chest()
organs_by_name["groin"] = new/datum/organ/external/groin(organs_by_name["chest"])
organs_by_name["head"] = new/datum/organ/external/head(organs_by_name["chest"])
organs_by_name["l_arm"] = new/datum/organ/external/l_arm(organs_by_name["chest"])
organs_by_name["r_arm"] = new/datum/organ/external/r_arm(organs_by_name["chest"])
organs_by_name["r_leg"] = new/datum/organ/external/r_leg(organs_by_name["groin"])
organs_by_name["l_leg"] = new/datum/organ/external/l_leg(organs_by_name["groin"])
organs_by_name["l_hand"] = new/datum/organ/external/l_hand(organs_by_name["l_arm"])
organs_by_name["r_hand"] = new/datum/organ/external/r_hand(organs_by_name["r_arm"])
organs_by_name["l_foot"] = new/datum/organ/external/l_foot(organs_by_name["l_leg"])
organs_by_name["r_foot"] = new/datum/organ/external/r_foot(organs_by_name["r_leg"])
new/datum/organ/internal/heart(src)
new/datum/organ/internal/lungs(src)
new/datum/organ/internal/liver(src)
new/datum/organ/internal/kidney(src)
new/datum/organ/internal/brain(src)
for(var/name in organs_by_name)
organs += organs_by_name[name]
for(var/datum/organ/external/O in organs)
O.owner = src
..() ..()
if(dna) if(dna)
dna.real_name = real_name dna.real_name = real_name
prev_gender = gender // Debug for plural genders prev_gender = gender // Debug for plural genders
make_organs()
make_blood()
vessel = new/datum/reagents(600)
vessel.my_atom = src
vessel.add_reagent("blood",560)
spawn(1)
fixblood()
/mob/living/carbon/human/proc/drip(var/amt as num)
if(!amt)
return
var/amm = 0.1 * amt
var/turf/T = get_turf(src)
var/list/obj/effect/decal/cleanable/blood/drip/nums = list()
var/list/iconL = list("1","2","3","4","5")
vessel.remove_reagent("blood",amm)
for(var/obj/effect/decal/cleanable/blood/drip/G in T)
nums += G
iconL.Remove(G.icon_state)
if (nums.len < 5)
var/obj/effect/decal/cleanable/blood/drip/this = new(T)
this.icon_state = pick(iconL)
this.blood_DNA = list()
this.blood_DNA[dna.unique_enzymes] = dna.b_type
else
for(var/obj/effect/decal/cleanable/blood/drip/G in nums)
del G
T.add_blood(src)
/mob/living/carbon/human/proc/fixblood()
for(var/datum/reagent/blood/B in vessel.reagent_list)
if(B.id == "blood")
B.data = list("donor"=src,"viruses"=null,"blood_DNA"=dna.unique_enzymes,"blood_type"=dna.b_type,"resistances"=null,"trace_chem"=null, "virus2" = null, "antobodies" = null)
/mob/living/carbon/human/Bump(atom/movable/AM as mob|obj, yes) /mob/living/carbon/human/Bump(atom/movable/AM as mob|obj, yes)
if ((!( yes ) || now_pushing)) if ((!( yes ) || now_pushing))

View File

@@ -47,9 +47,6 @@
var/icon/stand_icon = null var/icon/stand_icon = null
var/icon/lying_icon = null var/icon/lying_icon = null
var/list/organs = list() //Gets filled up in the constructor (human.dm, New() proc, line 24. I'm sick and tired of missing comments. -Agouri
var/list/organs_by_name = list() // map organ names to organs
var/miming = null //Toggle for the mime's abilities. var/miming = null //Toggle for the mime's abilities.
var/special_voice = "" // For changing our voice. Used by a symptom. var/special_voice = "" // For changing our voice. Used by a symptom.

View File

@@ -21,11 +21,6 @@
#define COLD_GAS_DAMAGE_LEVEL_2 1.5 //Amount of damage applied when the current breath's temperature passes the 200K point #define COLD_GAS_DAMAGE_LEVEL_2 1.5 //Amount of damage applied when the current breath's temperature passes the 200K point
#define COLD_GAS_DAMAGE_LEVEL_3 3 //Amount of damage applied when the current breath's temperature passes the 120K point #define COLD_GAS_DAMAGE_LEVEL_3 3 //Amount of damage applied when the current breath's temperature passes the 120K point
var/const/BLOOD_VOLUME_SAFE = 501
var/const/BLOOD_VOLUME_OKAY = 336
var/const/BLOOD_VOLUME_BAD = 224
var/const/BLOOD_VOLUME_SURVIVE = 122
/mob/living/carbon/human /mob/living/carbon/human
var/oxygen_alert = 0 var/oxygen_alert = 0
var/toxins_alert = 0 var/toxins_alert = 0
@@ -133,98 +128,6 @@ var/const/BLOOD_VOLUME_SURVIVE = 122
/mob/living/carbon/human /mob/living/carbon/human
proc/handle_blood()
// take care of blood and blood loss
if(stat < 2 && bodytemperature >= 170)
var/blood_volume = round(vessel.get_reagent_amount("blood"))
if(blood_volume < 560 && blood_volume)
var/datum/reagent/blood/B = locate() in vessel.reagent_list //Grab some blood
if(B) // Make sure there's some blood at all
if(B.data["donor"] != src) //If it's not theirs, then we look for theirs
for(var/datum/reagent/blood/D in vessel.reagent_list)
if(D.data["donor"] == src)
B = D
break
var/datum/reagent/nutriment/F = locate() in reagents.reagent_list
if(F != null)
if(F.volume >= 1)
// nutriment speeds it up quite a bit
B.volume += 0.4
F.volume -= 0.1
else
//At this point, we dun care which blood we are adding to, as long as they get more blood.
B.volume = B.volume + 0.1 // regenerate blood VERY slowly
// Damaged heart virtually reduces the blood volume, as the blood isn't
// being pumped properly anymore.
var/datum/organ/internal/heart/heart = internal_organs["heart"]
switch(heart.damage)
if(5 to 10)
blood_volume *= 0.8
if(11 to 20)
blood_volume *= 0.5
if(21 to INFINITY)
blood_volume *= 0.3
switch(blood_volume)
if(BLOOD_VOLUME_SAFE to 10000)
if(pale)
pale = 0
update_body()
if(BLOOD_VOLUME_OKAY to BLOOD_VOLUME_SAFE)
if(!pale)
pale = 1
update_body()
var/word = pick("dizzy","woosey","faint")
src << "\red You feel [word]"
if(prob(1))
var/word = pick("dizzy","woosey","faint")
src << "\red You feel [word]"
if(oxyloss < 20)
// hint that they're getting close to suffocation
oxyloss += 3
if(BLOOD_VOLUME_BAD to BLOOD_VOLUME_OKAY)
if(!pale)
pale = 1
update_body()
eye_blurry += 6
if(oxyloss < 50)
oxyloss += 10
oxyloss += 1
if(prob(15))
Paralyse(rand(1,3))
var/word = pick("dizzy","woosey","faint")
src << "\red You feel extremely [word]"
if(BLOOD_VOLUME_SURVIVE to BLOOD_VOLUME_BAD)
oxyloss += 5
toxloss += 5
if(prob(15))
var/word = pick("dizzy","woosey","faint")
src << "\red You feel extremely [word]"
if(0 to BLOOD_VOLUME_SURVIVE)
// There currently is a strange bug here. If the mob is not below -100 health
// when death() is called, apparently they will be just fine, and this way it'll
// spam deathgasp. Adjusting toxloss ensures the mob will stay dead.
toxloss += 300 // just to be safe!
death()
// Without enough blood you slowly go hungry.
if(blood_volume < BLOOD_VOLUME_SAFE)
if(nutrition >= 300)
nutrition -= 10
else if(nutrition >= 200)
nutrition -= 3
var/blood_max = 0
for(var/datum/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())
blood_max += W.damage / 4
if(temp.status & ORGAN_DESTROYED && !(temp.status & ORGAN_GAUZED) && !temp.amputated)
blood_max += 20 //Yer missing a fucking limb.
drip(blood_max)
proc/handle_disabilities() proc/handle_disabilities()
if (disabilities & EPILEPSY) if (disabilities & EPILEPSY)
if ((prob(1) && paralysis < 1)) if ((prob(1) && paralysis < 1))
@@ -291,108 +194,6 @@ var/const/BLOOD_VOLUME_SURVIVE = 122
src << "\red Your legs won't respond properly, you fall down." src << "\red Your legs won't respond properly, you fall down."
lying = 1 lying = 1
proc/handle_organs()
// take care of organ related updates, such as broken and missing limbs
// recalculate number of wounds
number_wounds = 0
for(var/datum/organ/external/E in organs)
if(!E)
world << name
continue
number_wounds += E.number_wounds
var/leg_tally = 2
var/canstand_l = 1 //Can stand on left leg
var/canstand_r = 1 //Can stand on right leg
var/hasleg_l = 1 //Have left leg
var/hasleg_r = 1 //Have right leg
var/hasarm_l = 1 //Have left arm
var/hasarm_r = 1 //Have right arm
for(var/datum/organ/external/E in organs)
E.process()
if(E.status & ORGAN_ROBOT && prob(E.brute_dam + E.burn_dam))
if(E.name == "l_hand" || E.name == "l_arm")
if(hand && equipped())
drop_item()
emote("me", 1, "drops what they were holding, their [E.display_name?"[E.display_name]":"[E]"] malfunctioning!")
var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread()
spark_system.set_up(5, 0, src)
spark_system.attach(src)
spark_system.start()
spawn(10)
del(spark_system)
else if(E.name == "r_hand" || E.name == "r_arm")
if(!hand && equipped())
drop_item()
emote("me", 1, "drops what they were holding, their [E.display_name?"[E.display_name]":"[E]"] malfunctioning!")
var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread()
spark_system.set_up(5, 0, src)
spark_system.attach(src)
spark_system.start()
spawn(10)
del(spark_system)
else if(E.name == "l_leg" || E.name == "l_foot" \
|| E.name == "r_leg" || E.name == "r_foot" && !lying)
leg_tally-- // let it fail even if just foot&leg
if(E.status & ORGAN_BROKEN || (E.status & ORGAN_DESTROYED && !E.amputated))
if(E.name == "l_hand" || E.name == "l_arm")
if(hand && equipped())
if(E.status & ORGAN_SPLINTED && prob(10))
drop_item()
emote("scream")
else
drop_item()
emote("scream")
else if(E.name == "r_hand" || E.name == "r_arm")
if(!hand && equipped())
if(E.status & ORGAN_SPLINTED && prob(10))
drop_item()
emote("scream")
else
drop_item()
emote("scream")
else if(E.name == "l_leg" || E.name == "l_foot" \
|| E.name == "r_leg" || E.name == "r_foot" && !lying)
if(!(E.status & ORGAN_SPLINTED))
leg_tally-- // let it fail even if just foot&leg
// standing is poor
if(leg_tally <= 0 && !paralysis && !(lying || resting) && prob(5))
emote("scream")
emote("collapse")
paralysis = 10
//Check arms and legs for existence
var/datum/organ/external/E
E = get_organ("l_leg")
if(E.status & ORGAN_DESTROYED && !(E.status & ORGAN_SPLINTED))
canstand_l = 0
hasleg_l = 0
E = get_organ("r_leg")
if(E.status & ORGAN_DESTROYED && !(E.status & ORGAN_SPLINTED))
canstand_r = 0
hasleg_r = 0
E = get_organ("l_foot")
if(E.status & ORGAN_DESTROYED && !(E.status & ORGAN_SPLINTED))
canstand_l = 0
E = get_organ("r_foot")
if(E.status & ORGAN_DESTROYED && !(E.status & ORGAN_SPLINTED))
canstand_r = 0
E = get_organ("l_arm")
if(E.status & ORGAN_DESTROYED && !(E.status & ORGAN_SPLINTED))
hasarm_l = 0
E = get_organ("r_arm")
if(E.status & ORGAN_DESTROYED && !(E.status & ORGAN_SPLINTED))
hasarm_r = 0
// Can stand if have at least one full leg (with leg and foot parts present)
// Has limbs to move around if at least one arm or leg is at least partially there
can_stand = canstand_l||canstand_r
has_limbs = hasleg_l||hasleg_r||hasarm_l||hasarm_r
proc/handle_mutations_and_radiation() proc/handle_mutations_and_radiation()
if(getFireLoss()) if(getFireLoss())
if((COLD_RESISTANCE in mutations) || (prob(1))) if((COLD_RESISTANCE in mutations) || (prob(1)))
@@ -455,20 +256,14 @@ var/const/BLOOD_VOLUME_SURVIVE = 122
if(reagents.has_reagent("lexorin")) return if(reagents.has_reagent("lexorin")) return
if(istype(loc, /obj/machinery/atmospherics/unary/cryo_cell)) return if(istype(loc, /obj/machinery/atmospherics/unary/cryo_cell)) return
var/lung_ruptured = is_lung_ruptured() var/datum/organ/internal/lungs/L = internal_organs["lungs"]
L.process()
if(lung_ruptured && prob(2))
spawn emote("me", 1, "coughs up blood!")
src.drip(10)
var/datum/gas_mixture/environment = loc.return_air() var/datum/gas_mixture/environment = loc.return_air()
var/datum/gas_mixture/breath var/datum/gas_mixture/breath
// HACK NEED CHANGING LATER // HACK NEED CHANGING LATER
if(health < 0) if(health < 0)
losebreath++ losebreath++
if(lung_ruptured && prob(4))
spawn emote("me", 1, "gasps for air!")
losebreath += 5
if(losebreath>0) //Suffocating so do not take a breath if(losebreath>0) //Suffocating so do not take a breath
losebreath-- losebreath--
if (prob(10)) //Gasp per 10 ticks? Sounds about right. if (prob(10)) //Gasp per 10 ticks? Sounds about right.
@@ -498,7 +293,7 @@ var/const/BLOOD_VOLUME_SURVIVE = 122
breath = loc.remove_air(breath_moles) breath = loc.remove_air(breath_moles)
if(!lung_ruptured) if(!is_lung_ruptured())
if(!breath || breath.total_moles < BREATH_MOLES / 5 || breath.total_moles > BREATH_MOLES * 5) if(!breath || breath.total_moles < BREATH_MOLES / 5 || breath.total_moles > BREATH_MOLES * 5)
if(prob(5)) if(prob(5))
rupture_lung() rupture_lung()
@@ -1061,34 +856,10 @@ var/const/BLOOD_VOLUME_SURVIVE = 122
dizziness = max(0, dizziness - 3) dizziness = max(0, dizziness - 3)
jitteriness = max(0, jitteriness - 3) jitteriness = max(0, jitteriness - 3)
handle_trace_chems()
if(life_tick % 10 == 0) var/datum/organ/internal/liver/liver = internal_organs["liver"]
// handle trace chemicals for autopsy liver.process()
for(var/datum/organ/O in organs)
for(var/chemID in O.trace_chemicals)
O.trace_chemicals[chemID] = O.trace_chemicals[chemID] - 1
if(O.trace_chemicals[chemID] <= 0)
O.trace_chemicals.Remove(chemID)
for(var/datum/reagent/A in reagents.reagent_list)
// add chemistry traces to a random organ
var/datum/organ/O = pick(organs)
O.trace_chemicals[A.name] = 100
var/damaged_liver_process_accuracy = 10
if(life_tick % damaged_liver_process_accuracy == 0)
// Damaged liver means some chemicals are very dangerous
var/datum/organ/internal/liver/liver = internal_organs["liver"]
if(liver.damage >= liver.min_bruised_damage)
for(var/datum/reagent/R in src.reagents.reagent_list)
// Ethanol and all drinks are bad
if(istype(R, /datum/reagent/ethanol))
adjustToxLoss(0.1 * damaged_liver_process_accuracy)
// Can't cope with toxins at all
for(var/toxin in list("toxin", "plasma", "sacid", "pacid", "cyanide", "lexorin", "amatoxin", "chloralhydrate", "carpotoxin", "zombiepowder", "mindbreaker"))
if(src.reagents.has_reagent(toxin))
adjustToxLoss(0.3 * damaged_liver_process_accuracy)
updatehealth() updatehealth()

View File

@@ -0,0 +1,213 @@
/****************************************************
BLOOD SYSTEM
****************************************************/
//Blood levels
var/const/BLOOD_VOLUME_SAFE = 501
var/const/BLOOD_VOLUME_OKAY = 336
var/const/BLOOD_VOLUME_BAD = 224
var/const/BLOOD_VOLUME_SURVIVE = 122
/mob/living/carbon/human/var/datum/reagents/vessel //Container for blood and BLOOD ONLY. Do not transfer other chems here.
/mob/living/carbon/human/var/var/pale = 0 //Should affect how mob sprite is drawn, but currently doesn't.
//Initializes blood vessels
/mob/living/carbon/human/proc/make_blood()
if (vessel)
return
vessel = new/datum/reagents(600)
vessel.my_atom = src
vessel.add_reagent("blood",560)
spawn(1)
fixblood()
//Resets blood data
/mob/living/carbon/human/proc/fixblood()
for(var/datum/reagent/blood/B in vessel.reagent_list)
if(B.id == "blood")
B.data = list( "donor"=src,"viruses"=null,"blood_DNA"=dna.unique_enzymes,"blood_type"=dna.b_type, \
"resistances"=null,"trace_chem"=null, "virus2" = null, "antobodies" = null)
// Takes care blood loss and regeneration
/mob/living/carbon/human/proc/handle_blood()
if(stat != DEAD && bodytemperature >= 170) //Dead or cryosleep people do not pump the blood.
var/blood_volume = round(vessel.get_reagent_amount("blood"))
//Blood regeneration if there is some space
if(blood_volume < 560 && blood_volume)
var/datum/reagent/blood/B = locate() in vessel.reagent_list //Grab some blood
if(B) // Make sure there's some blood at all
if(B.data["donor"] != src) //If it's not theirs, then we look for theirs
for(var/datum/reagent/blood/D in vessel.reagent_list)
if(D.data["donor"] == src)
B = D
break
B.volume += 0.1 // regenerate blood VERY slowly
if (reagents.has_reagent("nutriment")) //Getting food speeds it up
B.volume += 0.4
reagents.remove_reagent("nutriment", 0.1)
if (reagents.has_reagent("iron")) //Hematogen candy anyone?
B.volume += 0.8
reagents.remove_reagent("iron", 0.1)
// Damaged heart virtually reduces the blood volume, as the blood isn't
// being pumped properly anymore.
var/datum/organ/internal/heart/heart = internal_organs["heart"]
switch(heart.damage)
if(5 to 10)
blood_volume *= 0.8
if(11 to 20)
blood_volume *= 0.5
if(21 to INFINITY)
blood_volume *= 0.3
//Effects of bloodloss
switch(blood_volume)
if(BLOOD_VOLUME_SAFE to 10000)
if(pale)
pale = 0
update_body()
if(BLOOD_VOLUME_OKAY to BLOOD_VOLUME_SAFE)
if(!pale)
pale = 1
update_body()
var/word = pick("dizzy","woosey","faint")
src << "\red You feel [word]"
if(prob(1))
var/word = pick("dizzy","woosey","faint")
src << "\red You feel [word]"
if(oxyloss < 20)
oxyloss += 3
if(BLOOD_VOLUME_BAD to BLOOD_VOLUME_OKAY)
if(!pale)
pale = 1
update_body()
eye_blurry += 6
if(oxyloss < 50)
oxyloss += 10
oxyloss += 1
if(prob(15))
Paralyse(rand(1,3))
var/word = pick("dizzy","woosey","faint")
src << "\red You feel extremely [word]"
if(BLOOD_VOLUME_SURVIVE to BLOOD_VOLUME_BAD)
oxyloss += 5
toxloss += 5
if(prob(15))
var/word = pick("dizzy","woosey","faint")
src << "\red You feel extremely [word]"
if(0 to BLOOD_VOLUME_SURVIVE)
// There currently is a strange bug here. If the mob is not below -100 health
// when death() is called, apparently they will be just fine, and this way it'll
// spam deathgasp. Adjusting toxloss ensures the mob will stay dead.
toxloss += 300 // just to be safe!
death()
// Without enough blood you slowly go hungry.
if(blood_volume < BLOOD_VOLUME_SAFE)
if(nutrition >= 300)
nutrition -= 10
else if(nutrition >= 200)
nutrition -= 3
//Bleeding out
var/blood_max = 0
for(var/datum/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())
blood_max += W.damage / 4
if(temp.status & ORGAN_DESTROYED && !(temp.status & ORGAN_GAUZED) && !temp.amputated)
blood_max += 20 //Yer missing a fucking limb.
if (temp.open)
blood_max += 2 //Yer stomach is cut open
drip(blood_max)
//Makes a blood drop, leaking certain amount of blood from the mob
/mob/living/carbon/human/proc/drip(var/amt as num)
if(!amt)
return
var/amm = 0.1 * amt
var/turf/T = get_turf(src)
var/list/obj/effect/decal/cleanable/blood/drip/nums = list()
var/list/iconL = list("1","2","3","4","5")
vessel.remove_reagent("blood",amm)
for(var/obj/effect/decal/cleanable/blood/drip/G in T)
nums += G
iconL.Remove(G.icon_state)
if (nums.len < 5)
var/obj/effect/decal/cleanable/blood/drip/this = new(T)
this.icon_state = pick(iconL)
this.blood_DNA = list()
this.blood_DNA[dna.unique_enzymes] = dna.b_type
else
for(var/obj/effect/decal/cleanable/blood/drip/G in nums)
del G
T.add_blood(src)
/****************************************************
BLOOD TRANSFERS
****************************************************/
//Gets blood from mob to the container, preserving all data in it.
/mob/living/carbon/proc/take_blood(obj/item/weapon/reagent_containers/container, var/amount)
var/datum/reagent/B = get_blood(container.reagents)
if(!B) B = new /datum/reagent/blood
B.holder = container
B.volume += amount
//set reagent data
B.data["donor"] = src
if(src.virus2)
B.data["virus2"] = src.virus2.getcopy()
B.data["antibodies"] |= src.antibodies
B.data["blood_DNA"] = copytext(src.dna.unique_enzymes,1,0)
if(src.resistances && src.resistances.len)
if(B.data["resistances"])
B.data["resistances"] |= src.resistances.Copy()
else
B.data["resistances"] = src.resistances.Copy()
B.data["blood_type"] = copytext(src.dna.b_type,1,0)
var/list/temp_chem = list()
for(var/datum/reagent/R in src.reagents.reagent_list)
temp_chem += R.name
temp_chem[R.name] = R.volume
B.data["trace_chem"] = list2params(temp_chem)
return B
//For humans, blood does not appear from blue, it comes from vessels.
/mob/living/carbon/human/take_blood(obj/item/weapon/reagent_containers/container, var/amount)
if(vessel.get_reagent_amount("blood") < amount)
return null
. = ..()
vessel.remove_reagent("blood",amount) // Removes blood if human
//Transfers blood from container ot vessels, respecting blood types compatability.
/mob/living/carbon/human/proc/inject_blood(obj/item/weapon/reagent_containers/container, var/amount)
var/datum/reagent/blood/our = get_blood(vessel)
var/datum/reagent/blood/injected = get_blood(container.reagents)
if(blood_incompatible(injected.data["blood_type"],our.data["blood_type"]) )
reagents.add_reagent("toxin",amount * 0.5)
reagents.update_total()
else
vessel.add_reagent("blood", amount)
vessel.update_total()
container.reagents.remove_reagent("blood", amount)
//Gets human's own blood.
/mob/living/carbon/proc/get_blood(datum/reagents/container)
var/datum/reagent/blood/res = locate() in container.reagent_list //Grab some blood
if(res) // Make sure there's some blood at all
if(res.data["donor"] != src) //If it's not theirs, then we look for theirs
for(var/datum/reagent/blood/D in container.reagent_list)
if(D.data["donor"] == src)
return D
return res

View File

@@ -0,0 +1,148 @@
/datum/organ
var/name = "organ"
var/mob/living/carbon/human/owner = null
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
proc/process()
return 0
proc/receive_chem(chemical as obj)
return 0
//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)
var/datum/autopsy_data/W = autopsy_data[used_weapon]
if(!W)
W = new()
W.weapon = used_weapon
autopsy_data[used_weapon] = W
W.hits += 1
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
//Creates and initializes and connects external and internal organs
/mob/living/carbon/human/proc/make_organs()
organs = list()
organs_by_name["chest"] = new/datum/organ/external/chest()
organs_by_name["groin"] = new/datum/organ/external/groin(organs_by_name["chest"])
organs_by_name["head"] = new/datum/organ/external/head(organs_by_name["chest"])
organs_by_name["l_arm"] = new/datum/organ/external/l_arm(organs_by_name["chest"])
organs_by_name["r_arm"] = new/datum/organ/external/r_arm(organs_by_name["chest"])
organs_by_name["r_leg"] = new/datum/organ/external/r_leg(organs_by_name["groin"])
organs_by_name["l_leg"] = new/datum/organ/external/l_leg(organs_by_name["groin"])
organs_by_name["l_hand"] = new/datum/organ/external/l_hand(organs_by_name["l_arm"])
organs_by_name["r_hand"] = new/datum/organ/external/r_hand(organs_by_name["r_arm"])
organs_by_name["l_foot"] = new/datum/organ/external/l_foot(organs_by_name["l_leg"])
organs_by_name["r_foot"] = new/datum/organ/external/r_foot(organs_by_name["r_leg"])
new/datum/organ/internal/heart(src)
new/datum/organ/internal/lungs(src)
new/datum/organ/internal/liver(src)
new/datum/organ/internal/kidney(src)
new/datum/organ/internal/brain(src)
for(var/name in organs_by_name)
organs += organs_by_name[name]
for(var/datum/organ/external/O in organs)
O.owner = src
// Takes care of organ related updates, such as broken and missing limbs
/mob/living/carbon/human/proc/handle_organs()
number_wounds = 0
var/leg_tally = 2
for(var/datum/organ/external/E in organs)
if(!E)
continue
E.process()
number_wounds += E.number_wounds
//Robotic limb malfunctions
var/malfunction = 0
if (E.status & ORGAN_ROBOT && prob(E.brute_dam + E.burn_dam))
malfunction = 1
//Broken limbs hurt too
var/broken = 0
if(E.status & ORGAN_BROKEN && !(E.status & ORGAN_SPLINTED && prob(10)) )
broken = 1
//Special effects for limbs.
if(E.name in list("l_hand","l_arm","r_hand","r_arm"))
var/obj/item/c_hand //Getting what's in this hand
if(E.name == "l_hand" || E.name == "l_arm")
c_hand = l_hand
if(E.name == "r_hand" || E.name == "r_arm")
c_hand = r_hand
if (c_hand)
if (broken||malfunction)
u_equip(c_hand)
if(broken)
emote("me", 1, "screams in pain and drops what they were holding in their [E.display_name?"[E.display_name]":"[E]"]!")
if(malfunction)
emote("me", 1, "drops what they were holding, their [E.display_name?"[E.display_name]":"[E]"] malfunctioning!")
var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread()
spark_system.set_up(5, 0, src)
spark_system.attach(src)
spark_system.start()
spawn(10)
del(spark_system)
else if(E.name in list("l_leg","l_foot","r_leg","r_foot") && !lying)
if (E.status & ORGAN_DESTROYED || malfunction || (broken && !(E.status & ORGAN_SPLINTED)))
leg_tally-- // let it fail even if just foot&leg
// standing is poor
if(leg_tally <= 0 && !paralysis && !(lying || resting) && prob(5))
emote("scream")
emote("collapse")
paralysis = 10
//Check arms and legs for existence
var/canstand_l = 1 //Can stand on left leg
var/canstand_r = 1 //Can stand on right leg
var/hasleg_l = 1 //Have left leg
var/hasleg_r = 1 //Have right leg
var/hasarm_l = 1 //Have left arm
var/hasarm_r = 1 //Have right arm
var/datum/organ/external/E
E = get_organ("l_leg")
if(E.status & ORGAN_DESTROYED && !(E.status & ORGAN_SPLINTED))
canstand_l = 0
hasleg_l = 0
E = get_organ("r_leg")
if(E.status & ORGAN_DESTROYED && !(E.status & ORGAN_SPLINTED))
canstand_r = 0
hasleg_r = 0
E = get_organ("l_foot")
if(E.status & ORGAN_DESTROYED && !(E.status & ORGAN_SPLINTED))
canstand_l = 0
E = get_organ("r_foot")
if(E.status & ORGAN_DESTROYED && !(E.status & ORGAN_SPLINTED))
canstand_r = 0
E = get_organ("l_arm")
if(E.status & ORGAN_DESTROYED && !(E.status & ORGAN_SPLINTED))
hasarm_l = 0
E = get_organ("r_arm")
if(E.status & ORGAN_DESTROYED && !(E.status & ORGAN_SPLINTED))
hasarm_r = 0
// Can stand if have at least one full leg (with leg and foot parts present)
// Has limbs to move around if at least one arm or leg is at least partially there
can_stand = canstand_l||canstand_r
has_limbs = hasleg_l||hasleg_r||hasarm_l||hasarm_r

View File

@@ -1,120 +1,83 @@
/**************************************************** /****************************************************
INTERNAL ORGANS INTERNAL ORGANS
****************************************************/ ****************************************************/
/* /mob/living/carbon/human/var/list/internal_organs = list()
/datum/organ/internal
name = "internal" /datum/organ/internal
var/damage = 0 // amount of damage to the organ
var/max_damage = 100 var/damage = 0
var/min_bruised_damage = 10
/datum/organ/internal/skeleton var/min_broken_damage = 30
name = "spooky scary skeleton" var/parent_organ = "chest"
max_damage = 200
/datum/organ/internal/proc/is_bruised()
/datum/organ/internal/skin return damage >= min_bruised_damage
name = "skin"
max_damage = 100 /datum/organ/internal/proc/is_broken()
return damage >= min_broken_damage
/datum/organ/internal/blood_vessels
name = "blood vessels"
var/heart = null /datum/organ/internal/New(mob/living/carbon/human/H)
var/lungs = null ..()
var/kidneys = null var/datum/organ/external/E = H.organs_by_name[src.parent_organ]
if(E.internal_organs == null)
/datum/organ/internal/brain E.internal_organs = list()
name = "brain" E.internal_organs += src
var/head = null H.internal_organs[src.name] = src
src.owner = H
/datum/organ/internal/excretory
name = "excretory" /datum/organ/internal/proc/take_damage(amount)
var/excretory = 7.0 src.damage += amount
var/blood_vessels = null
var/datum/organ/external/parent = owner.get_organ(parent_organ)
/datum/organ/internal/heart owner.custom_pain("Something inside your [parent.display_name] hurts a lot.", 1)
name = "heart"
/****************************************************
/datum/organ/internal/immune_system INTERNAL ORGANS DEFINES
name = "immune system" ****************************************************/
var/blood_vessels = null
var/isys = null /datum/organ/internal/heart
name = "heart"
/datum/organ/internal/intestines parent_organ = "chest"
name = "intestines"
var/intestines = 3.0
var/blood_vessels = null /datum/organ/internal/lungs
name = "lungs"
/datum/organ/internal/liver parent_organ = "chest"
name = "liver"
var/intestines = null process()
var/blood_vessels = null if(is_bruised())
if(prob(2))
/datum/organ/internal/lungs spawn owner.emote("me", 1, "coughs up blood!")
name = "lungs" owner.drip(10)
var/lungs = 3.0 if(prob(4))
var/throat = null spawn owner.emote("me", 1, "gasps for air!")
var/blood_vessels = null owner.losebreath += 5
/datum/organ/internal/stomach /datum/organ/internal/liver
name = "stomach" name = "liver"
var/intestines = null parent_organ = "chest"
var/process_accuracy = 10
/datum/organ/internal/throat
name = "throat" process()
var/lungs = null if(owner.life_tick % process_accuracy == 0)
var/stomach = null // Damaged liver means some chemicals are very dangerous
if(src.damage >= src.min_bruised_damage)
*/ for(var/datum/reagent/R in owner.reagents.reagent_list)
// Ethanol and all drinks are bad
/mob/living/carbon/human/var/list/internal_organs = list() if(istype(R, /datum/reagent/ethanol))
owner.adjustToxLoss(0.1 * process_accuracy)
/datum/organ/internal
// amount of damage to the organ // Can't cope with toxins at all
var/damage = 0 for(var/toxin in list("toxin", "plasma", "sacid", "pacid", "cyanide", "lexorin", "amatoxin", "chloralhydrate", "carpotoxin", "zombiepowder", "mindbreaker"))
var/min_bruised_damage = 10 if(owner.reagents.has_reagent(toxin))
var/min_broken_damage = 30 owner.adjustToxLoss(0.3 * process_accuracy)
var/parent_organ = "chest"
/datum/organ/internal/kidney
/datum/organ/internal/proc/is_bruised() name = "kidney"
return damage >= min_bruised_damage parent_organ = "chest"
/datum/organ/internal/proc/is_broken() /datum/organ/internal/brain
return damage >= min_broken_damage name = "brain"
/datum/organ/internal/New(mob/living/carbon/human/H)
..()
var/datum/organ/external/E = H.organs_by_name[src.parent_organ]
if(E.internal_organs == null)
E.internal_organs = list()
E.internal_organs += src
H.internal_organs[src.name] = src
src.owner = H
/datum/organ/internal/proc/take_damage(amount)
src.damage += amount
var/datum/organ/external/parent = owner.get_organ(parent_organ)
owner.custom_pain("Something inside your [parent.display_name] hurts a lot.", 1)
/datum/organ/internal/heart
name = "heart"
parent_organ = "chest"
/datum/organ/internal/lungs
name = "lungs"
parent_organ = "chest"
/datum/organ/internal/liver
name = "liver"
parent_organ = "chest"
/datum/organ/internal/kidney
name = "kidney"
parent_organ = "chest"
/datum/organ/internal/brain
name = "brain"
parent_organ = "head" parent_organ = "head"

View File

@@ -101,7 +101,7 @@ mob/living/carbon/human/proc/handle_pain()
if(11 to 15) if(11 to 15)
toxMessageProb = 2 toxMessageProb = 2
toxDamageMessage = "Your whole body hurts." toxDamageMessage = "Your whole body hurts."
else if(91 to 10000)
toxMessageProb = 5 toxMessageProb = 5
toxDamageMessage = "Your body aches all over, it's driving you mad." toxDamageMessage = "Your body aches all over, it's driving you mad."

View File

@@ -107,30 +107,9 @@ datum
var/current_reagent_transfer = current_reagent.volume * part var/current_reagent_transfer = current_reagent.volume * part
if(preserve_data) if(preserve_data)
trans_data = current_reagent.data trans_data = current_reagent.data
if(current_reagent.id == "blood" && ishuman(target)) // can never be sure
var/mob/living/carbon/human/H = target
var/datum/reagent/blood/HisBlood = locate() in H.vessel.reagent_list //Grab some blood R.add_reagent(current_reagent.id, (current_reagent_transfer * multiplier), trans_data)
if(HisBlood) // Make sure there's some blood at all src.remove_reagent(current_reagent.id, current_reagent_transfer)
if(HisBlood.data["donor"] != H) //If it's not theirs, then we look for theirs
for(var/datum/reagent/blood/D in H.vessel.reagent_list)
if(D.data["donor"] == H)
HisBlood = D
break
if(HisBlood && HisBlood.data && trans_data)
if(blood_incompatible(trans_data["blood_type"],HisBlood.data["blood_type"]))
H.reagents.add_reagent("toxin",(current_reagent_transfer * multiplier * 0.5))
H.reagents.update_total()
else
H.vessel.add_reagent(current_reagent.id, (current_reagent_transfer * multiplier), trans_data)
H.vessel.update_total()
else
H.vessel.add_reagent(current_reagent.id, (current_reagent_transfer * multiplier), trans_data)
H.vessel.update_total()
src.remove_reagent(current_reagent.id, current_reagent_transfer)
else
R.add_reagent(current_reagent.id, (current_reagent_transfer * multiplier), trans_data)
src.remove_reagent(current_reagent.id, current_reagent_transfer)
src.update_total() src.update_total()
R.update_total() R.update_total()

View File

@@ -80,57 +80,20 @@
if(istype(target, /mob/living/carbon))//maybe just add a blood reagent to all mobs. Then you can suck them dry...With hundreds of syringes. Jolly good idea. if(istype(target, /mob/living/carbon))//maybe just add a blood reagent to all mobs. Then you can suck them dry...With hundreds of syringes. Jolly good idea.
var/amount = src.reagents.maximum_volume - src.reagents.total_volume var/amount = src.reagents.maximum_volume - src.reagents.total_volume
var/mob/living/carbon/T = target var/mob/living/carbon/T = target
var/datum/reagent/B = new /datum/reagent/blood
if(!T.dna) if(!T.dna)
usr << "You are unable to locate any blood. (To be specific, your target seems to be missing their DNA datum)" usr << "You are unable to locate any blood. (To be specific, your target seems to be missing their DNA datum)"
return return
if(NOCLONE in T.mutations) //target done been et, no more blood in him if(NOCLONE in T.mutations) //target done been et, no more blood in him
user << "\red You are unable to locate any blood." user << "\red You are unable to locate any blood."
return return
if(ishuman(T))
if(T:vessel.get_reagent_amount("blood") < amount)
return
B.holder = src
B.volume = amount
//set reagent data
B.data["donor"] = T
/*
if(T.virus && T.virus.spread_type != SPECIAL)
B.data["virus"] = new T.virus.type(0)
*/
var/datum/reagent/B = T.take_blood(src,amount)
if (B)
for(var/datum/disease/D in T.viruses) src.reagents.reagent_list += B
if(!B.data["viruses"]) src.reagents.update_total()
B.data["viruses"] = list() src.on_reagent_change()
src.reagents.handle_reactions()
B.data["viruses"] += new D.type(0, D, 1)
if(T.virus2)
B.data["virus2"] = T.virus2.getcopy()
B.data["blood_DNA"] = copytext(T.dna.unique_enzymes,1,0)
if(T.resistances&&T.resistances.len)
B.data["resistances"] = T.resistances.Copy()
if(istype(target, /mob/living/carbon/human))//I wish there was some hasproperty operation...
var/mob/living/carbon/human/HT = target
B.data["blood_type"] = copytext(HT.dna.b_type,1,0)
var/list/temp_chem = list()
for(var/datum/reagent/R in target.reagents.reagent_list)
temp_chem += R.name
temp_chem[R.name] = R.volume
B.data["trace_chem"] = list2params(temp_chem)
B.data["antibodies"] = T.antibodies
if(ishuman(T))
T:vessel.remove_reagent("blood",amount) // Removes blood if human
src.reagents.reagent_list += B
src.reagents.update_total()
src.on_reagent_change()
src.reagents.handle_reactions()
user << "\blue You take a blood sample from [target]" user << "\blue You take a blood sample from [target]"
for(var/mob/O in viewers(4, user)) for(var/mob/O in viewers(4, user))
O.show_message("\red [user] takes a blood sample from [target].", 1) O.show_message("\red [user] takes a blood sample from [target].", 1)
@@ -182,9 +145,7 @@
var/trans var/trans
if(B && ishuman(target)) if(B && ishuman(target))
var/mob/living/carbon/human/H = target var/mob/living/carbon/human/H = target
trans = B.volume > 5? 5 : B.volume H.inject_blood(src,5)
H.vessel.add_reagent("blood",trans,B.data)
src.reagents.remove_reagent("blood",trans)
else else
trans = src.reagents.trans_to(target, amount_per_transfer_from_this) trans = src.reagents.trans_to(target, amount_per_transfer_from_this)
user << "\blue You inject [trans] units of the solution. The syringe now contains [src.reagents.total_volume] units." user << "\blue You inject [trans] units of the solution. The syringe now contains [src.reagents.total_volume] units."

View File

@@ -1321,6 +1321,14 @@ datum/design/synthetic_flash
build_path = "/obj/item/device/flash/synthetic" build_path = "/obj/item/device/flash/synthetic"
category = "Misc" category = "Misc"
datum/design/nanopaste
name = "nanopaste"
desc = "A tube of paste containing swarms of repair nanties. Very effective in repairing robotic machinery."
id = "nanopaste"
req_tech = list("materials" = 4, "engineering" = 3)
build_type = PROTOLATHE
materials = list("$metal" = 7000, "$glass" = 7000)
build_path = "/obj/item/stack/nanopaste"
///////////////////////////////////////// /////////////////////////////////////////
/////////////////Weapons///////////////// /////////////////Weapons/////////////////
///////////////////////////////////////// /////////////////////////////////////////

BIN
icons/obj/nanopaste.dmi Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 311 B