Merge with dev.

This commit is contained in:
Zuhayr
2015-05-15 23:22:48 +09:30
86 changed files with 3562 additions and 5272 deletions
+4 -2
View File
@@ -33,6 +33,7 @@
#include "code\__HELPERS\type2type.dm"
#include "code\__HELPERS\unsorted.dm"
#include "code\__HELPERS\vector.dm"
#include "code\_defines\chemical_effects.dm"
#include "code\_onclick\adjacent.dm"
#include "code\_onclick\ai.dm"
#include "code\_onclick\click.dm"
@@ -509,7 +510,6 @@
#include "code\game\objects\weapons.dm"
#include "code\game\objects\effects\aliens.dm"
#include "code\game\objects\effects\bump_teleporter.dm"
#include "code\game\objects\effects\chemsmoke.dm"
#include "code\game\objects\effects\effect_system.dm"
#include "code\game\objects\effects\explosion_particles.dm"
#include "code\game\objects\effects\gibs.dm"
@@ -522,6 +522,9 @@
#include "code\game\objects\effects\portals.dm"
#include "code\game\objects\effects\spiders.dm"
#include "code\game\objects\effects\step_triggers.dm"
#include "code\game\objects\effects\chem\chemsmoke.dm"
#include "code\game\objects\effects\chem\foam.dm"
#include "code\game\objects\effects\chem\water.dm"
#include "code\game\objects\effects\decals\cleanable.dm"
#include "code\game\objects\effects\decals\contraband.dm"
#include "code\game\objects\effects\decals\crayon.dm"
@@ -1475,7 +1478,6 @@
#include "code\modules\reagents\reagent_containers\glass.dm"
#include "code\modules\reagents\reagent_containers\hypospray.dm"
#include "code\modules\reagents\reagent_containers\pill.dm"
#include "code\modules\reagents\reagent_containers\robodropper.dm"
#include "code\modules\reagents\reagent_containers\spray.dm"
#include "code\modules\reagents\reagent_containers\syringes.dm"
#include "code\modules\reagents\reagent_containers\food\cans.dm"
+7
View File
@@ -0,0 +1,7 @@
#define CE_STABLE "stable" // Inaprovaline
#define CE_ANTIBIOTIC "antibiotic" // Spaceacilin
#define CE_BLOODRESTORE "bloodrestore" // Iron/nutriment
#define CE_PAINKILLER "painkiller"
#define CE_ALCOHOL "alcohol" // Liver filtering
#define CE_ALCOHOL_TOXIC "alcotoxic" // Liver damage
#define CE_SPEEDBOOST "gofast" // Hyperzine
+2 -2
View File
@@ -94,7 +94,7 @@
/datum/recipe/proc/make(var/obj/container as obj)
var/obj/result_obj = new result(container)
for (var/obj/O in (container.contents-result_obj))
O.reagents.trans_to(result_obj, O.reagents.total_volume)
O.reagents.trans_to_obj(result_obj, O.reagents.total_volume)
qdel(O)
container.reagents.clear_reagents()
return result_obj
@@ -109,7 +109,7 @@
if (O.reagents)
O.reagents.del_reagent("nutriment")
O.reagents.update_total()
O.reagents.trans_to(result_obj, O.reagents.total_volume)
O.reagents.trans_to_obj(result_obj, O.reagents.total_volume)
qdel(O)
container.reagents.clear_reagents()
return result_obj
+1 -2
View File
@@ -598,8 +598,7 @@
inject_amount = 0
if (inject_amount > 50)
inject_amount = 50
connected.beaker.reagents.trans_to(connected.occupant, inject_amount)
connected.beaker.reagents.reaction(connected.occupant)
connected.beaker.reagents.trans_to_mob(connected.occupant, inject_amount, CHEM_BLOOD)
return 1 // return 1 forces an update to all Nano uis attached to src
////////////////////////////////////////////////////////
+2 -2
View File
@@ -191,10 +191,10 @@
if(beaker.reagents.total_volume < beaker.reagents.maximum_volume)
var/pumped = 0
for(var/datum/reagent/x in src.occupant.reagents.reagent_list)
src.occupant.reagents.trans_to(beaker, 3)
src.occupant.reagents.trans_to_obj(beaker, 3)
pumped++
if (ishuman(src.occupant))
src.occupant.vessel.trans_to(beaker, pumped + 1)
src.occupant.vessel.trans_to_obj(beaker, pumped + 1)
src.updateUsrDialog()
return
+1 -2
View File
@@ -232,8 +232,7 @@
var/has_clonexa = occupant.reagents.get_reagent_amount("clonexadone") >= 1
var/has_cryo_medicine = has_cryo || has_clonexa
if(beaker && !has_cryo_medicine)
beaker.reagents.trans_to(occupant, 1, 10)
beaker.reagents.reaction(occupant)
beaker.reagents.trans_to_mob(occupant, 1, CHEM_BLOOD, 10)
/obj/machinery/atmospherics/unary/cryo_cell/proc/heat_gas_contents()
if(air_contents.total_moles < 1)
+2 -2
View File
@@ -82,11 +82,11 @@
// Give blood
if(mode)
if(src.beaker.volume > 0)
var/transfer_amount = REAGENTS_METABOLISM
var/transfer_amount = REM
if(istype(src.beaker, /obj/item/weapon/reagent_containers/blood))
// speed up transfer on blood packs
transfer_amount = 4
src.beaker.reagents.trans_to(src.attached, transfer_amount)
src.beaker.reagents.trans_to_mob(src.attached, transfer_amount, CHEM_BLOOD)
update_icon()
// Take blood
+1 -1
View File
@@ -209,7 +209,7 @@
new_meat.reagents.add_reagent("nutriment",slab_nutrition)
if(src.occupant.reagents)
src.occupant.reagents.trans_to(new_meat, round(occupant.reagents.total_volume/slab_count,1))
src.occupant.reagents.trans_to_obj(new_meat, round(occupant.reagents.total_volume/slab_count,1))
src.occupant.attack_log += "\[[time_stamp()]\] Was gibbed by <b>[user]/[user.ckey]</b>" //One shall not simply gib a mob unnoticed!
user.attack_log += "\[[time_stamp()]\] Gibbed <b>[src.occupant]/[src.occupant.ckey]</b>"
@@ -443,7 +443,7 @@
var/turf/trg = get_turf(target)
var/obj/item/weapon/reagent_containers/syringe/S = syringes[1]
S.forceMove(get_turf(chassis))
reagents.trans_to(S, min(S.volume, reagents.total_volume))
reagents.trans_to_obj(S, min(S.volume, reagents.total_volume))
syringes -= S
S.icon = 'icons/obj/chemical.dmi'
S.icon_state = "syringeproj"
@@ -462,7 +462,7 @@
if(M)
S.icon_state = initial(S.icon_state)
S.icon = initial(S.icon)
S.reagents.trans_to(M, S.reagents.total_volume)
S.reagents.trans_to_mob(M, S.reagents.total_volume, CHEM_BLOOD)
M.take_organ_damage(2)
S.visible_message("<span class=\"attack\"> [M] was hit by the syringe!</span>")
break
@@ -591,7 +591,7 @@
if(!(D.CanPass(S,src.loc)))
occupant_message("Unable to load syringe.")
return 0
S.reagents.trans_to(src, S.reagents.total_volume)
S.reagents.trans_to_obj(src, S.reagents.total_volume)
S.forceMove(src)
syringes += S
occupant_message("Syringe loaded.")
+20 -25
View File
@@ -200,9 +200,9 @@
set_ready_state(0)
if(do_after_cooldown(target))
if( istype(target, /obj/structure/reagent_dispensers/watertank) && get_dist(chassis,target) <= 1)
var/obj/o = target
var/amount = o.reagents.trans_to(src, 200)
occupant_message("<span class='notice'>[amount] units transferred into internal tank.</span>")
var/obj/o = target
var/amount = o.reagents.trans_to_obj(src, 200)
occupant_message("<span class='notice'>[amount] units transferred into internal tank.</span>")
playsound(chassis, 'sound/effects/refill.ogg', 50, 1, -6)
return
@@ -220,29 +220,24 @@
var/list/the_targets = list(T,T1,T2)
for(var/a=0, a<5, a++)
spawn(0)
for(var/a = 1 to 5)
spawn(0)
var/obj/effect/effect/water/W = PoolOrNew(/obj/effect/effect/water, get_turf(chassis))
var/turf/my_target = pick(the_targets)
var/datum/reagents/R = new/datum/reagents(5)
if(!W) return
W.reagents = R
R.my_atom = W
if(!W || !src) return
src.reagents.trans_to(W,1)
for(var/b=0, b<5, b++)
step_towards(W,my_target)
if(!W || !W.reagents) return
W.reagents.reaction(get_turf(W))
for(var/atom/atm in get_turf(W))
if(!W)
return
if(!W.reagents)
break
W.reagents.reaction(atm)
if(W.loc == my_target) break
sleep(2)
qdel(W)
var/turf/my_target
if(a == 1)
my_target = T
else if(a == 2)
my_target = T1
else if(a == 3)
my_target = T2
else
my_target = pick(the_targets)
W.create_reagents(5)
if(!W || !src)
return
reagents.trans_to_obj(W, spray_amount)
W.set_color()
W.set_up(my_target)
return 1
get_equip_info()
@@ -5,13 +5,11 @@
icon = 'icons/effects/chemsmoke.dmi'
opacity = 0
time_to_live = 300
pass_flags = PASSTABLE | PASSGRILLE | PASSGLASS //PASSGLASS is fine here, it's just so the visual effect can "flow" around glass
pass_flags = PASSTABLE | PASSGRILLE | PASSGLASS //PASSGLASS is fine here, it's just so the visual effect can "flow" around glass
/obj/effect/effect/smoke/chem/New()
..()
var/datum/reagents/R = new/datum/reagents(500)
reagents = R
R.my_atom = src
create_reagents(500)
return
/datum/effect/effect/system/smoke_spread/chem
@@ -37,21 +35,16 @@
/datum/effect/effect/system/smoke_spread/chem/New()
..()
chemholder = new/obj()
var/datum/reagents/R = new/datum/reagents(500)
chemholder.reagents = R
R.my_atom = chemholder
chemholder.create_reagents(500)
//------------------------------------------
//Sets up the chem smoke effect
//
// Calculates the max range smoke can travel, then gets all turfs in that view range.
// Culls the selected turfs to a (roughly) circle shape, then calls smokeFlow() to make
// sure the smoke can actually path to the turfs. This culls any turfs it can't reach.
//------------------------------------------
/datum/effect/effect/system/smoke_spread/chem/set_up(var/datum/reagents/carry = null, n = 10, c = 0, loca, direct)
range = n * 0.3
cardinals = c
carry.copy_to(chemholder, carry.total_volume)
carry.trans_to_obj(chemholder, carry.total_volume, copy = 1)
if(istype(loca, /turf/))
location = loca
@@ -62,28 +55,19 @@
targetTurfs = new()
//build affected area list
for(var/turf/T in view(range, location))
//cull turfs to circle
if(cheap_pythag(T.x - location.x, T.y - location.y) <= range)
for(var/turf/T in view(range, location)) //build affected area list
if(cheap_pythag(T.x - location.x, T.y - location.y) <= range) //cull turfs to circle
targetTurfs += T
//make secondary list for reagents that affect walls
if(chemholder.reagents.has_reagent("thermite") || chemholder.reagents.has_reagent("plantbgone"))
wallList = new()
wallList = new()
//pathing check
smokeFlow(location, targetTurfs, wallList)
smokeFlow() //pathing check
//set the density of the cloud - for diluting reagents
density = max(1, targetTurfs.len / 4) //clamp the cloud density minimum to 1 so it cant multiply the reagents
density = max(1, targetTurfs.len / 4) //clamp the cloud density minimum to 1 so it cant multiply the reagents
//Admin messaging
var/contained = ""
for(var/reagent in carry.reagent_list)
contained += " [reagent] "
if(contained)
contained = "\[[contained]\]"
var/contained = carry.get_reagents()
var/area/A = get_area(location)
var/where = "[A.name] | [location.x], [location.y]"
@@ -101,61 +85,27 @@
message_admins("A chemical smoke reaction has taken place in ([whereLink]). No associated key.", 0, 1)
log_game("A chemical smoke reaction has taken place in ([where])[contained]. No associated key.")
//------------------------------------------
//Runs the chem smoke effect
//
// Spawns damage over time loop for each reagent held in the cloud.
// Applies reagents to walls that affect walls (only thermite and plant-b-gone at the moment).
// Also calculates target locations to spawn the visual smoke effect on, so the whole area
// is covered fairly evenly.
//------------------------------------------
/datum/effect/effect/system/smoke_spread/chem/start()
if(!location) //kill grenade if it somehow ends up in nullspace
if(!location)
return
//reagent application - only run if there are extra reagents in the smoke
if(chemholder.reagents.reagent_list.len)
for(var/datum/reagent/R in chemholder.reagents.reagent_list)
var/proba = 100
var/runs = 5
if(chemholder.reagents.reagent_list.len) //reagent application - only run if there are extra reagents in the smoke
for(var/turf/T in wallList)
chemholder.reagents.touch_turf(T)
for(var/turf/T in targetTurfs)
chemholder.reagents.touch_turf(T)
for(var/atom/A in T.contents)
if(istype(A, /obj/effect/effect/smoke/chem) || istype(A, /mob))
continue
else if(isobj(A) && !A.simulated)
chemholder.reagents.touch_obj(A)
//dilute the reagents according to cloud density
R.volume /= density
chemholder.reagents.update_total()
//apply wall affecting reagents to walls
if(R.id in list("thermite", "plantbgone"))
for(var/turf/T in wallList)
R.reaction_turf(T, R.volume)
//reagents that should be applied to turfs in a random pattern
if(R.id == "carbon")
proba = 75
else if(R.id in list("blood", "radium", "uranium"))
proba = 25
spawn(0)
for(var/i = 0, i < runs, i++)
for(var/turf/T in targetTurfs)
if(prob(proba))
R.reaction_turf(T, R.volume)
for(var/atom/A in T.contents)
if(istype(A, /obj/effect/effect/smoke/chem)) //skip the item if it is chem smoke
continue
else if(istype(A, /mob))
var/dist = cheap_pythag(T.x - location.x, T.y - location.y)
if(!dist)
dist = 1
R.reaction_mob(A, volume = R.volume / dist)
else if(istype(A, /obj) && !A.simulated)
R.reaction_obj(A, R.volume)
sleep(30)
//build smoke icon
var/color = chemholder.reagents.get_color()
var/color = chemholder.reagents.get_color() //build smoke icon
var/icon/I
if(color)
I = icon('icons/effects/chemsmoke.dmi')
@@ -163,13 +113,9 @@
else
I = icon('icons/effects/96x96.dmi', "smoke")
var/const/arcLength = 2.3559 //distance between each smoke cloud
//distance between each smoke cloud
var/const/arcLength = 2.3559
//calculate positions for smoke coverage - then spawn smoke
for(var/i = 0, i < range, i++)
for(var/i = 0, i < range, i++) //calculate positions for smoke coverage - then spawn smoke
var/radius = i * 1.5
if(!radius)
spawn(0)
@@ -207,12 +153,12 @@
smoke = PoolOrNew(/obj/effect/effect/smoke/chem, location)
if(chemholder.reagents.reagent_list.len)
chemholder.reagents.copy_to(smoke, chemholder.reagents.total_volume / dist, safety = 1) //copy reagents to the smoke so mob/breathe() can handle inhaling the reagents
chemholder.reagents.trans_to_obj(smoke, chemholder.reagents.total_volume / dist, copy = 1) //copy reagents to the smoke so mob/breathe() can handle inhaling the reagents
smoke.icon = I
smoke.layer = 6
smoke.set_dir(pick(cardinal))
smoke.pixel_x = -32 + rand(-8,8)
smoke.pixel_y = -32 + rand(-8,8)
smoke.pixel_x = -32 + rand(-8, 8)
smoke.pixel_y = -32 + rand(-8, 8)
walk_to(smoke, T)
smoke.opacity = 1 //switching opacity on after the smoke has spawned, and then
sleep(150+rand(0,20)) // turning it off before it is deleted results in cleaner
@@ -225,10 +171,7 @@
spores.name = "cloud of [seed.seed_name] [seed.seed_noun]"
..(T, I, dist, spores)
//------------------------------------------
// Fades out the smoke smoothly using it's alpha variable.
//------------------------------------------
/datum/effect/effect/system/smoke_spread/chem/proc/fadeOut(var/atom/A, var/frames = 16)
/datum/effect/effect/system/smoke_spread/chem/proc/fadeOut(var/atom/A, var/frames = 16) // Fades out the smoke smoothly using it's alpha variable.
if(A.alpha == 0) //Handle already transparent case
return
if(frames == 0)
@@ -239,11 +182,8 @@
sleep(world.tick_lag)
return
//------------------------------------------
// Smoke pathfinder. Uses a flood fill method based on zones to
// quickly check what turfs the smoke (airflow) can actually reach.
//------------------------------------------
/datum/effect/effect/system/smoke_spread/chem/proc/smokeFlow()
/datum/effect/effect/system/smoke_spread/chem/proc/smokeFlow() // Smoke pathfinder. Uses a flood fill method based on zones to quickly check what turfs the smoke (airflow) can actually reach.
var/list/pending = new()
var/list/complete = new()
+184
View File
@@ -0,0 +1,184 @@
// Foam
// Similar to smoke, but spreads out more
// metal foams leave behind a foamed metal wall
/obj/effect/effect/foam
name = "foam"
icon_state = "foam"
opacity = 0
anchored = 1
density = 0
layer = OBJ_LAYER + 0.9
mouse_opacity = 0
animate_movement = 0
var/amount = 3
var/expand = 1
var/metal = 0
/obj/effect/effect/foam/New(var/loc, var/ismetal = 0)
..(loc)
icon_state = "[ismetal? "m" : ""]foam"
metal = ismetal
playsound(src, 'sound/effects/bubbles2.ogg', 80, 1, -3)
spawn(3 + metal * 3)
process()
checkReagents()
spawn(120)
processing_objects.Remove(src)
sleep(30)
if(metal)
var/obj/structure/foamedmetal/M = new(src.loc)
M.metal = metal
M.updateicon()
flick("[icon_state]-disolve", src)
sleep(5)
qdel(src)
return
/obj/effect/effect/foam/proc/checkReagents() // transfer any reagents to the floor
if(!metal && reagents)
var/turf/T = get_turf(src)
reagents.touch_turf(T)
/obj/effect/effect/foam/process()
if(--amount < 0)
return
for(var/direction in cardinal)
var/turf/T = get_step(src, direction)
if(!T)
continue
if(!T.Enter(src))
continue
var/obj/effect/effect/foam/F = locate() in T
if(F)
continue
F = new(T, metal)
F.amount = amount
if(!metal)
F.create_reagents(10)
if(reagents)
for(var/datum/reagent/R in reagents.reagent_list)
F.reagents.add_reagent(R.id, 1, safety = 1) //added safety check since reagents in the foam have already had a chance to react
/obj/effect/effect/foam/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume) // foam disolves when heated, except metal foams
if(!metal && prob(max(0, exposed_temperature - 475)))
flick("[icon_state]-disolve", src)
spawn(5)
qdel(src)
/obj/effect/effect/foam/Crossed(var/atom/movable/AM)
if(metal)
return
if(istype(AM, /mob/living))
var/mob/living/M = AM
M.slip("the foam", 6)
/datum/effect/effect/system/foam_spread
var/amount = 5 // the size of the foam spread.
var/list/carried_reagents // the IDs of reagents present when the foam was mixed
var/metal = 0 // 0 = foam, 1 = metalfoam, 2 = ironfoam
/datum/effect/effect/system/foam_spread/set_up(amt=5, loca, var/datum/reagents/carry = null, var/metalfoam = 0)
amount = round(sqrt(amt / 3), 1)
if(istype(loca, /turf/))
location = loca
else
location = get_turf(loca)
carried_reagents = list()
metal = metalfoam
// bit of a hack here. Foam carries along any reagent also present in the glass it is mixed with (defaults to water if none is present). Rather than actually transfer the reagents, this makes a list of the reagent ids and spawns 1 unit of that reagent when the foam disolves.
if(carry && !metal)
for(var/datum/reagent/R in carry.reagent_list)
carried_reagents += R.id
/datum/effect/effect/system/foam_spread/start()
spawn(0)
var/obj/effect/effect/foam/F = locate() in location
if(F)
F.amount += amount
return
F = PoolOrNew(/obj/effect/effect/foam, list(location, metal))
F.amount = amount
if(!metal) // don't carry other chemicals if a metal foam
F.create_reagents(10)
if(carried_reagents)
for(var/id in carried_reagents)
F.reagents.add_reagent(id, 1, safety = 1) //makes a safety call because all reagents should have already reacted anyway
else
F.reagents.add_reagent("water", 1, safety = 1)
// wall formed by metal foams, dense and opaque, but easy to break
/obj/structure/foamedmetal
icon = 'icons/effects/effects.dmi'
icon_state = "metalfoam"
density = 1
opacity = 1 // changed in New()
anchored = 1
name = "foamed metal"
desc = "A lightweight foamed metal wall."
var/metal = 1 // 1 = aluminum, 2 = iron
/obj/structure/foamedmetal/New()
..()
update_nearby_tiles(1)
/obj/structure/foamedmetal/Destroy()
density = 0
update_nearby_tiles(1)
..()
/obj/structure/foamedmetal/proc/updateicon()
if(metal == 1)
icon_state = "metalfoam"
else
icon_state = "ironfoam"
/obj/structure/foamedmetal/ex_act(severity)
qdel(src)
/obj/structure/foamedmetal/blob_act()
qdel(src)
/obj/structure/foamedmetal/bullet_act()
if(metal == 1 || prob(50))
qdel(src)
/obj/structure/foamedmetal/attack_hand(var/mob/user)
if ((HULK in user.mutations) || (prob(75 - metal * 25)))
user.visible_message("<span class='warning'>[user] smashes through the foamed metal.</span>", "<span class='notice'>You smash through the metal foam wall.</span>")
qdel(src)
else
user << "<span class='notice'>You hit the metal foam but bounce off it.</span>"
return
/obj/structure/foamedmetal/attackby(var/obj/item/I, var/mob/user)
if(istype(I, /obj/item/weapon/grab))
var/obj/item/weapon/grab/G = I
G.affecting.loc = src.loc
visible_message("<span class='warning'>[G.assailant] smashes [G.affecting] through the foamed metal wall.</span>")
qdel(I)
qdel(src)
return
if(prob(I.force * 20 - metal * 25))
user.visible_message("<span class='warning'>[user] smashes through the foamed metal.</span>", "<span class='notice'>You smash through the foamed metal with \the [I].</span>")
qdel(src)
else
user << "<span class='notice'>You hit the metal foam to no effect.</span>"
/obj/structure/foamedmetal/CanPass(atom/movable/mover, turf/target, height=1.5, air_group = 0)
if(air_group)
return 0
return !density
+50
View File
@@ -0,0 +1,50 @@
/obj/effect/effect/water
name = "water"
icon = 'icons/effects/effects.dmi'
icon_state = "extinguish"
mouse_opacity = 0
/obj/effect/effect/water/New(loc)
..()
spawn(150) // In case whatever made it forgets to delete it
if(src)
qdel(src)
/obj/effect/effect/water/proc/set_color() // Call it after you move reagents to it
icon += reagents.get_color()
/obj/effect/effect/water/proc/set_up(var/turf/target, var/step_count = 5, var/delay = 5)
if(!target)
return
for(var/i = 1 to step_count)
step_towards(src, target)
var/turf/T = get_turf(src)
reagents.touch_turf(T)
var/mob/M = locate() in T
if(M)
reagents.splash_mob(M, reagents.total_volume)
break
for(var/atom/A in T)
reagents.touch(A)
if(T == get_turf(target))
break
sleep(delay)
sleep(10)
qdel(src)
/obj/effect/effect/water/Move(turf/newloc)
if(newloc.density)
return 0
. = ..()
/obj/effect/effect/water/Bump(atom/A)
if(reagents)
reagents.touch(A)
return ..()
//Used by spraybottles.
/obj/effect/effect/water/chempuff
name = "chemicals"
icon = 'icons/obj/chempuff.dmi'
icon_state = ""
pass_flags = PASSTABLE | PASSGRILLE
+1 -7
View File
@@ -11,10 +11,4 @@
/obj/effect/decal/spraystill
density = 0
anchored = 1
layer = 50
//Used by spraybottles.
/obj/effect/decal/chempuff
name = "chemicals"
icon = 'icons/obj/chempuff.dmi'
pass_flags = PASSTABLE | PASSGRILLE
layer = 50
+3 -248
View File
@@ -13,35 +13,11 @@ would spawn and follow the beaker, even if it is carried or thrown.
unacidable = 1//So effect are not targeted by alien acid.
pass_flags = PASSTABLE | PASSGRILLE
/obj/effect/effect/water
name = "water"
icon = 'icons/effects/effects.dmi'
icon_state = "extinguish"
var/life = 15.0
mouse_opacity = 0
/obj/effect/Destroy()
/obj/effect/Destroy()
if(reagents)
reagents.delete()
return ..()
/obj/effect/effect/water/Move(turf/newloc)
//var/turf/T = src.loc
//if (istype(T, /turf))
// T.firelevel = 0 //TODO: FIX
if (--src.life < 1)
//SN src = null
qdel(src)
if(newloc.density)
return 0
.=..()
/obj/effect/effect/water/Bump(atom/A)
if(reagents)
reagents.reaction(A)
return ..()
/datum/effect/effect/system
var/number = 3
var/cardinals = 0
@@ -479,228 +455,7 @@ steam.start() -- spawns the effect
proc/stop()
src.processing = 0
src.on = 0
// Foam
// Similar to smoke, but spreads out more
// metal foams leave behind a foamed metal wall
/obj/effect/effect/foam
name = "foam"
icon_state = "foam"
opacity = 0
anchored = 1
density = 0
layer = OBJ_LAYER + 0.9
mouse_opacity = 0
var/amount = 3
var/expand = 1
animate_movement = 0
var/metal = 0
/obj/effect/effect/foam/New(loc, var/ismetal=0)
..(loc)
icon_state = "[ismetal ? "m":""]foam"
metal = ismetal
playsound(src, 'sound/effects/bubbles2.ogg', 80, 1, -3)
spawn(3 + metal*3)
process()
checkReagents()
spawn(120)
processing_objects.Remove(src)
sleep(30)
if(metal)
var/obj/structure/foamedmetal/M = PoolOrNew(/obj/structure/foamedmetal, src.loc)
M.metal = metal
M.updateicon()
flick("[icon_state]-disolve", src)
sleep(5)
qdel(src)
return
// transfer any reagents to the floor
/obj/effect/effect/foam/proc/checkReagents()
if(!metal && reagents)
for(var/atom/A in src.loc.contents)
if(A == src)
continue
reagents.reaction(A, 1, 1)
/obj/effect/effect/foam/process()
if(--amount < 0)
return
for(var/direction in cardinal)
var/turf/T = get_step(src,direction)
if(!T)
continue
if(!T.Enter(src))
continue
var/obj/effect/effect/foam/F = locate() in T
if(F)
continue
F = PoolOrNew(/obj/effect/effect/foam, list(T, metal))
F.amount = amount
if(!metal)
F.create_reagents(10)
if (reagents)
for(var/datum/reagent/R in reagents.reagent_list)
F.reagents.add_reagent(R.id, 1, safety = 1) //added safety check since reagents in the foam have already had a chance to react
// foam disolves when heated
// except metal foams
/obj/effect/effect/foam/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(!metal && prob(max(0, exposed_temperature - 475)))
flick("[icon_state]-disolve", src)
spawn(5)
qdel(src)
/obj/effect/effect/foam/Crossed(var/atom/movable/AM)
if(metal)
return
if(istype(AM, /mob/living))
var/mob/living/M = AM
M.slip("the foam",6)
/datum/effect/effect/system/foam_spread
var/amount = 5 // the size of the foam spread.
var/list/carried_reagents // the IDs of reagents present when the foam was mixed
var/metal = 0 // 0=foam, 1=metalfoam, 2=ironfoam
set_up(amt=5, loca, var/datum/reagents/carry = null, var/metalfoam = 0)
amount = round(sqrt(amt / 3), 1)
if(istype(loca, /turf/))
location = loca
else
location = get_turf(loca)
carried_reagents = list()
metal = metalfoam
// bit of a hack here. Foam carries along any reagent also present in the glass it is mixed
// with (defaults to water if none is present). Rather than actually transfer the reagents,
// this makes a list of the reagent ids and spawns 1 unit of that reagent when the foam disolves.
if(carry && !metal)
for(var/datum/reagent/R in carry.reagent_list)
carried_reagents += R.id
start()
spawn(0)
var/obj/effect/effect/foam/F = locate() in location
if(F)
F.amount += amount
return
F = PoolOrNew(/obj/effect/effect/foam, list(src.location, metal))
F.amount = amount
if(!metal) // don't carry other chemicals if a metal foam
F.create_reagents(10)
if(carried_reagents)
for(var/id in carried_reagents)
F.reagents.add_reagent(id, 1, null, 1) //makes a safety call because all reagents should have already reacted anyway
else
F.reagents.add_reagent("water", 1, safety = 1)
// wall formed by metal foams
// dense and opaque, but easy to break
/obj/structure/foamedmetal
icon = 'icons/effects/effects.dmi'
icon_state = "metalfoam"
density = 1
opacity = 1 // changed in New()
anchored = 1
name = "foamed metal"
desc = "A lightweight foamed metal wall."
var/metal = 1 // 1=aluminum, 2=iron
New()
..()
update_nearby_tiles(1)
Destroy()
density = 0
update_nearby_tiles(1)
..()
proc/updateicon()
if(metal == 1)
icon_state = "metalfoam"
else
icon_state = "ironfoam"
ex_act(severity)
qdel(src)
blob_act()
qdel(src)
bullet_act()
if(metal==1 || prob(50))
qdel(src)
attack_hand(var/mob/user)
if ((HULK in user.mutations) || (prob(75 - metal*25)))
user << "\blue You smash through the metal foam wall."
for(var/mob/O in oviewers(user))
if ((O.client && !( O.blinded )))
O << "\red [user] smashes through the foamed metal."
qdel(src)
else
user << "\blue You hit the metal foam but bounce off it."
return
attackby(var/obj/item/I, var/mob/user)
if (istype(I, /obj/item/weapon/grab))
var/obj/item/weapon/grab/G = I
G.affecting.loc = src.loc
for(var/mob/O in viewers(src))
if (O.client)
O << "\red [G.assailant] smashes [G.affecting] through the foamed metal wall."
qdel(I)
qdel(src)
return
if(prob(I.force*20 - metal*25))
user << "\blue You smash through the foamed metal with \the [I]."
for(var/mob/O in oviewers(user))
if ((O.client && !( O.blinded )))
O << "\red [user] smashes through the foamed metal."
qdel(src)
else
user << "\blue You hit the metal foam to no effect."
CanPass(atom/movable/mover, turf/target, height=1.5, air_group = 0)
if(air_group) return 0
return !density
/datum/effect/effect/system/reagents_explosion
var/amount // TNT equivalent
var/flashing = 0 // does explosion creates flash effect?
+10 -10
View File
@@ -47,7 +47,7 @@
/obj/item/toy/balloon/afterattack(atom/A as mob|obj, mob/user as mob, proximity)
if(!proximity) return
if (istype(A, /obj/structure/reagent_dispensers/watertank) && get_dist(src,A) <= 1)
A.reagents.trans_to(src, 10)
A.reagents.trans_to_obj(src, 10)
user << "\blue You fill the balloon with the contents of [A]."
src.desc = "A translucent balloon with some form of liquid sloshing around in it."
src.update_icon()
@@ -60,22 +60,22 @@
user << "The [O] is empty."
else if(O.reagents.total_volume >= 1)
if(O.reagents.has_reagent("pacid", 1))
user << "The acid chews through the balloon!"
O.reagents.reaction(user)
qdel(src)
user << "The acid chews through the balloon!"
O.reagents.splash_mob(user, reagents.total_volume)
qdel(src)
else
src.desc = "A translucent balloon with some form of liquid sloshing around in it."
user << "\blue You fill the balloon with the contents of [O]."
O.reagents.trans_to(src, 10)
O.reagents.trans_to_obj(src, 10)
src.update_icon()
return
/obj/item/toy/balloon/throw_impact(atom/hit_atom)
if(src.reagents.total_volume >= 1)
src.visible_message("\red The [src] bursts!","You hear a pop and a splash.")
src.reagents.reaction(get_turf(hit_atom))
src.reagents.touch_turf(get_turf(hit_atom))
for(var/atom/A in get_turf(hit_atom))
src.reagents.reaction(A)
src.reagents.touch(A)
src.icon_state = "burst"
spawn(5)
if(src)
@@ -456,15 +456,15 @@
D.icon = 'icons/obj/chemical.dmi'
D.icon_state = "chempuff"
D.create_reagents(5)
src.reagents.trans_to(D, 1)
src.reagents.trans_to_obj(D, 1)
playsound(src.loc, 'sound/effects/spray3.ogg', 50, 1, -6)
spawn(0)
for(var/i=0, i<1, i++)
step_towards(D,A)
D.reagents.reaction(get_turf(D))
D.reagents.touch_turf(get_turf(D))
for(var/atom/T in get_turf(D))
D.reagents.reaction(T)
D.reagents.touch(T)
if(ismob(T) && T:client)
T:client << "\red [user] has sprayed you with water!"
sleep(4)
@@ -114,10 +114,9 @@ CIGARETTE PACKETS ARE IN FANCY.DM
if(H.species.flags & IS_SYNTHETIC)
return
reagents.trans_to(C, REAGENTS_METABOLISM, 0.2) // Most of it is not inhaled... balance reasons.
reagents.reaction(C)
reagents.trans_to_mob(C, REM, CHEM_INGEST, 0.2) // Most of it is not inhaled... balance reasons.
else // else just remove some of the reagents
reagents.remove_any(REAGENTS_METABOLISM)
reagents.remove_any(REM)
/obj/item/clothing/mask/smokable/proc/light(var/flavor_text = "[usr] lights the [name].")
if(!src.lit)
@@ -232,7 +231,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
if(!proximity)
return
if(istype(glass)) //you can dip cigarettes into beakers
var/transfered = glass.reagents.trans_to(src, chem_volume)
var/transfered = glass.reagents.trans_to_obj(src, chem_volume)
if(transfered) //if reagents were transfered, show the message
user << "<span class='notice'>You dip \the [src] into \the [glass].</span>"
else //if not, either the beaker was empty, or the cigarette was full
@@ -377,7 +376,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
return
smoketime = 1000
if(G.reagents)
G.reagents.trans_to(src, G.reagents.total_volume)
G.reagents.trans_to_obj(src, G.reagents.total_volume)
name = "[G.name]-packed [initial(name)]"
qdel(G)
+38 -51
View File
@@ -31,15 +31,11 @@
w_class = 2.0
force = 3.0
max_water = 60
spray_particles = 6
spray_amount = 2
sprite_name = "miniFE"
/obj/item/weapon/extinguisher/New()
var/datum/reagents/R = new/datum/reagents(max_water)
reagents = R
R.my_atom = src
R.add_reagent("water", max_water)
create_reagents(max_water)
reagents.add_reagent("water", max_water)
/obj/item/weapon/extinguisher/examine(mob/user)
if(..(user, 0))
@@ -53,19 +49,19 @@
user << "The safety is [safety ? "on" : "off"]."
return
/obj/item/weapon/extinguisher/afterattack(atom/target, mob/user , flag)
/obj/item/weapon/extinguisher/afterattack(var/atom/target, var/mob/user, var/flag)
//TODO; Add support for reagents in water.
if( istype(target, /obj/structure/reagent_dispensers/watertank) && get_dist(src,target) <= 1)
if( istype(target, /obj/structure/reagent_dispensers/watertank) && flag)
var/obj/o = target
var/amount = o.reagents.trans_to(src, 50)
user << "\blue You fill [src] with [amount] units of the contents of [target]."
var/amount = o.reagents.trans_to_obj(src, 50)
user << "<span class='notice'>You fill [src] with [amount] units of the contents of [target].</span>"
playsound(src.loc, 'sound/effects/refill.ogg', 50, 1, -6)
return
if (!safety)
if (src.reagents.total_volume < 1)
usr << "\red \The [src] is empty."
usr << "<span class='notice'>\The [src] is empty.</span>"
return
if (world.time < src.last_use + 20)
@@ -77,35 +73,35 @@
var/direction = get_dir(src,target)
if(usr.buckled && isobj(usr.buckled) && !usr.buckled.anchored )
if(user.buckled && isobj(user.buckled) && !user.buckled.anchored )
spawn(0)
var/obj/structure/bed/chair/C = null
if(istype(usr.buckled, /obj/structure/bed/chair))
C = usr.buckled
var/obj/B = usr.buckled
if(istype(user.buckled, /obj/structure/bed/chair))
C = user.buckled
var/obj/B = user.buckled
var/movementdirection = turn(direction,180)
if(C) C.propelled = 4
B.Move(get_step(usr,movementdirection), movementdirection)
B.Move(get_step(user,movementdirection), movementdirection)
sleep(1)
B.Move(get_step(usr,movementdirection), movementdirection)
B.Move(get_step(user,movementdirection), movementdirection)
if(C) C.propelled = 3
sleep(1)
B.Move(get_step(usr,movementdirection), movementdirection)
B.Move(get_step(user,movementdirection), movementdirection)
sleep(1)
B.Move(get_step(usr,movementdirection), movementdirection)
B.Move(get_step(user,movementdirection), movementdirection)
if(C) C.propelled = 2
sleep(2)
B.Move(get_step(usr,movementdirection), movementdirection)
B.Move(get_step(user,movementdirection), movementdirection)
if(C) C.propelled = 1
sleep(2)
B.Move(get_step(usr,movementdirection), movementdirection)
B.Move(get_step(user,movementdirection), movementdirection)
if(C) C.propelled = 0
sleep(3)
B.Move(get_step(usr,movementdirection), movementdirection)
B.Move(get_step(user,movementdirection), movementdirection)
sleep(3)
B.Move(get_step(usr,movementdirection), movementdirection)
B.Move(get_step(user,movementdirection), movementdirection)
sleep(3)
B.Move(get_step(usr,movementdirection), movementdirection)
B.Move(get_step(user,movementdirection), movementdirection)
var/turf/T = get_turf(target)
var/turf/T1 = get_step(T,turn(direction, 90))
@@ -113,33 +109,24 @@
var/list/the_targets = list(T,T1,T2)
for(var/a=0, a < spray_particles, a++)
spawn(0)
var/obj/effect/effect/water/W = PoolOrNew(/obj/effect/effect/water, get_turf(src))
var/turf/my_target = pick(the_targets)
var/datum/reagents/R = new/datum/reagents(spray_amount)
if(!W) return
W.reagents = R
R.my_atom = W
if(!W || !src) return
src.reagents.trans_to(W, spray_amount)
for(var/b=0, b<5, b++)
step_towards(W,my_target)
if(!W || !W.reagents) return
W.reagents.reaction(get_turf(W))
for(var/atom/atm in get_turf(W))
if(!W)
return
if(!W.reagents)
break
W.reagents.reaction(atm)
if(isliving(atm)) //For extinguishing mobs on fire
var/mob/living/M = atm
M.ExtinguishMob()
if(W.loc == my_target) break
sleep(2)
qdel(W)
for(var/a = 1 to spray_particles)
spawn(0)
var/obj/effect/effect/water/W = PoolOrNew(new /obj/effect/effect/water, get_turf(src))
var/turf/my_target
if(a == 1)
my_target = T
else if(a == 2)
my_target = T1
else if(a == 3)
my_target = T2
else
my_target = pick(the_targets)
W.create_reagents(spray_amount)
if(!src)
return
reagents.trans_to_obj(W, spray_amount)
W.set_color()
W.set_up(my_target)
if((istype(usr.loc, /turf/space)) || (usr.lastarea.has_gravity == 0))
user.inertia_dir = get_dir(target, user)
@@ -158,7 +158,7 @@
for(var/atom/A in view(affected_area, src.loc))
if( A == src ) continue
src.reagents.reaction(A, 1, 10)
src.reagents.touch(A)
if(istype(loc, /mob/living/carbon)) //drop dat grenade if it goes off in your hand
var/mob/living/carbon/C = loc
@@ -291,7 +291,7 @@ the implant may become unstable and either pre-maturely inject the subject or si
activate(var/cause)
if((!cause) || (!src.imp_in)) return 0
var/mob/living/carbon/R = src.imp_in
src.reagents.trans_to(R, cause)
src.reagents.trans_to_mob(R, cause, CHEM_BLOOD)
R << "You hear a faint *beep*."
if(!src.reagents.total_volume)
R << "You hear a faint click from your chest."
@@ -38,7 +38,7 @@
user << "\red [src] is full."
else
spawn(5)
I.reagents.trans_to(src.imp, 5)
I.reagents.trans_to_mob(src.imp, 5)
user << "\blue You inject 5 units of the solution. The syringe now contains [I.reagents.total_volume] units."
else if (istype(I, /obj/item/weapon/implanter))
var/obj/item/weapon/implanter/M = I
+1 -1
View File
@@ -49,7 +49,7 @@
return ..()
if (reagents.total_volume > 0)
reagents.trans_to_ingest(M, reagents.total_volume)
reagents.trans_to_mob(M, reagents.total_volume, CHEM_INGEST)
if(M == user)
for(var/mob/O in viewers(M, null))
O.show_message(text("\blue [] eats some [] from \the [].", user, loaded, src), 1)
+1 -3
View File
@@ -25,9 +25,7 @@
for(var/obj/effect/O in src)
if(istype(O,/obj/effect/rune) || istype(O,/obj/effect/decal/cleanable) || istype(O,/obj/effect/overlay))
qdel(O)
source.reagents.reaction(src, TOUCH, 10) //10 is the multiplier for the reaction effect. probably needed to wet the floor properly.
source.reagents.remove_any(1) //reaction() doesn't use up the reagents
source.reagents.trans_to_turf(src, 1, 10) //10 is the multiplier for the reaction effect. probably needed to wet the floor properly.
/obj/item/weapon/mop/afterattack(atom/A, mob/user, proximity)
if(!proximity) return
+2 -5
View File
@@ -20,11 +20,8 @@ var/global/list/cached_icons = list()
afterattack(turf/simulated/target, mob/user, proximity)
if(!proximity) return
if(istype(target) && reagents.total_volume > 5)
for(var/mob/O in viewers(user))
O.show_message("\red \The [target] has been splashed with something by [user]!", 1)
spawn(5)
reagents.reaction(target, TOUCH)
reagents.remove_any(5)
user.visible_message("<span class='warning'>\The [target] has been splashed with something by [user]!</span>")
reagents.trans_to_turf(target, 5)
else
return ..()
@@ -158,7 +158,7 @@
/obj/item/weapon/storage/fancy/cigarettes/remove_from_storage(obj/item/W as obj, atom/new_location)
var/obj/item/clothing/mask/smokable/cigarette/C = W
if(!istype(C)) return // what
reagents.trans_to(C, (reagents.total_volume/contents.len))
reagents.trans_to_obj(C, (reagents.total_volume/contents.len))
..()
/obj/item/weapon/storage/fancy/cigarettes/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
@@ -167,7 +167,7 @@
if(M == user && user.zone_sel.selecting == "mouth" && contents.len > 0 && !user.wear_mask)
var/obj/item/clothing/mask/smokable/cigarette/W = new /obj/item/clothing/mask/smokable/cigarette(user)
reagents.trans_to(W, (reagents.total_volume/contents.len))
reagents.trans_to_obj(W, (reagents.total_volume/contents.len))
user.equip_to_slot_if_possible(W, slot_wear_mask)
reagents.maximum_volume = 15 * contents.len
contents.len--
@@ -213,7 +213,7 @@
/obj/item/weapon/storage/fancy/cigar/remove_from_storage(obj/item/W as obj, atom/new_location)
var/obj/item/clothing/mask/smokable/cigarette/cigar/C = W
if(!istype(C)) return
reagents.trans_to(C, (reagents.total_volume/contents.len))
reagents.trans_to_obj(C, (reagents.total_volume/contents.len))
..()
/obj/item/weapon/storage/fancy/cigar/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
@@ -222,7 +222,7 @@
if(M == user && user.zone_sel.selecting == "mouth" && contents.len > 0 && !user.wear_mask)
var/obj/item/clothing/mask/smokable/cigarette/cigar/W = new /obj/item/clothing/mask/smokable/cigarette/cigar(user)
reagents.trans_to(W, (reagents.total_volume/contents.len))
reagents.trans_to_obj(W, (reagents.total_volume/contents.len))
user.equip_to_slot_if_possible(W, slot_wear_mask)
reagents.maximum_volume = 15 * contents.len
contents.len--
+1 -1
View File
@@ -247,7 +247,7 @@
/obj/item/weapon/weldingtool/afterattack(obj/O as obj, mob/user as mob, proximity)
if(!proximity) return
if (istype(O, /obj/structure/reagent_dispensers/fueltank) && get_dist(src,O) <= 1 && !src.welding)
O.reagents.trans_to(src, max_fuel)
O.reagents.trans_to_obj(src, max_fuel)
user << "\blue Welder refueled"
playsound(src.loc, 'sound/effects/refill.ogg', 50, 1, -6)
return
@@ -27,7 +27,7 @@
else
if(T.welding)
user << "\red That was close!"
src.reagents.trans_to(W, T.max_fuel)
src.reagents.trans_to_obj(W, T.max_fuel)
user << "\blue Welder refilled!"
playsound(src.loc, 'sound/effects/refill.ogg', 50, 1, -6)
return
@@ -38,7 +38,7 @@
if(!proximity) // this replaces and improves the get_dist(src,O) <= 1 checks used previously
return
if (istype(O, /obj/structure/reagent_dispensers/fueltank) && src.reagents.total_volume < max_fuel)
O.reagents.trans_to(src, max_fuel)
O.reagents.trans_to_obj(src, max_fuel)
user << "\blue You crack the cap off the top of the pack and fill it back up again from the tank."
playsound(src.loc, 'sound/effects/refill.ogg', 50, 1, -6)
return
@@ -286,8 +286,8 @@
New()
..()
new /obj/item/weapon/reagent_containers/ld50_syringe/choral(src)
new /obj/item/weapon/reagent_containers/ld50_syringe/choral(src)
new /obj/item/weapon/reagent_containers/syringe/ld50_syringe/choral(src)
new /obj/item/weapon/reagent_containers/syringe/ld50_syringe/choral(src)
return
+2 -2
View File
@@ -39,7 +39,7 @@
if(reagents.total_volume < 1)
user << "[src] is out of water!</span>"
else
reagents.trans_to(I, 5) //
reagents.trans_to_obj(I, 5) //
user << "<span class='notice'>You wet [I] in [src].</span>"
playsound(loc, 'sound/effects/slosh.ogg', 25, 1)
return
@@ -186,7 +186,7 @@
/obj/structure/bed/chair/janicart/attackby(obj/item/I, mob/user)
if(istype(I, /obj/item/weapon/mop))
if(reagents.total_volume > 1)
reagents.trans_to(I, 2)
reagents.trans_to_obj(I, 2)
user << "<span class='notice'>You wet [I] in the [callme].</span>"
playsound(loc, 'sound/effects/slosh.ogg', 25, 1)
else
+1 -1
View File
@@ -22,6 +22,6 @@
if(reagents.total_volume < 1)
user << "[src] is out of water!</span>"
else
reagents.trans_to(I, 5)
reagents.trans_to_obj(I, 5)
user << "<span class='notice'>You wet [I] in [src].</span>"
playsound(loc, 'sound/effects/slosh.ogg', 25, 1)
@@ -31,8 +31,7 @@
/obj/item/weapon/reagent_containers/glass/rag/attack(atom/target as obj|turf|area, mob/user as mob , flag)
if(ismob(target) && target.reagents && reagents.total_volume)
user.visible_message("\red \The [target] has been smothered with \the [src] by \the [user]!", "\red You smother \the [target] with \the [src]!", "You hear some struggling and muffled cries of surprise")
src.reagents.reaction(target, TOUCH)
spawn(5) src.reagents.clear_reagents()
reagents.trans_to_mob(target, reagents.total_volume, CHEM_INGEST)
return
else
..()
@@ -3,7 +3,7 @@
// Handle nearby smoke if any.
for(var/obj/effect/effect/smoke/chem/smoke in view(1, src))
if(smoke.reagents.total_volume)
smoke.reagents.copy_to(src, 5)
smoke.reagents.trans_to_obj(src, 5, copy = 1)
//Do this even if we're not ready for a plant cycle.
process_reagents()
+1 -2
View File
@@ -103,8 +103,7 @@
update_icons()
if(do_mob(src, H, 30))
if(t == 1)
reagent_glass.reagents.trans_to(H, injection_amount)
reagent_glass.reagents.reaction(H, 2)
reagent_glass.reagents.trans_to_mob(H, injection_amount, CHEM_BLOOD)
else
H.reagents.add_reagent(t, injection_amount)
visible_message("<span class='warning'>[src] injects [H] with the syringe!</span>")
@@ -23,10 +23,6 @@
verbs += /mob/living/proc/ventcrawl
verbs += /mob/living/proc/hide
var/datum/reagents/R = new/datum/reagents(100)
reagents = R
R.my_atom = src
name = "[initial(name)] ([rand(1, 1000)])"
real_name = name
regenerate_icons()
+12 -1
View File
@@ -105,7 +105,18 @@
proc/handle_chemicals_in_body()
if(reagents) reagents.metabolize(src)
chem_effects.Cut()
analgesic = 0
if(touching)
touching.metabolize(0, CHEM_TOUCH)
if(ingested)
ingested.metabolize(0, CHEM_INGEST)
if(reagents)
reagents.metabolize(0, CHEM_BLOOD)
if(CE_PAINKILLER in chem_effects)
analgesic = chem_effects[CE_PAINKILLER]
confused = max(0, confused - 1)
// decrement dizziness counter, clamped to 0
+4 -6
View File
@@ -7,7 +7,7 @@
var/datum/gas_mixture/breath = null
//First, check if we can breathe at all
if(health < config.health_threshold_crit && !reagents.has_reagent("inaprovaline")) //crit aka circulatory shock
if(health < config.health_threshold_crit && !(CE_STABLE in chem_effects)) //crit aka circulatory shock
losebreath++
if(losebreath>0) //Suffocating so do not take a breath
@@ -65,11 +65,9 @@
for(var/obj/effect/effect/smoke/chem/smoke in view(1, src))
if(smoke.reagents.total_volume)
smoke.reagents.reaction(src, INGEST)
spawn(5)
if(smoke)
//maybe check air pressure here or something to see if breathing in smoke is even possible.
smoke.reagents.copy_to(src, 10) // I dunno, maybe the reagents enter the blood stream through the lungs?
smoke.reagents.trans_to_mob(src, 10, CHEM_INGEST, copy = 1)
//maybe check air pressure here or something to see if breathing in smoke is even possible.
// I dunno, maybe the reagents enter the blood stream through the lungs?
break // If they breathe in the nasty stuff once, no need to continue checking
/mob/living/carbon/proc/handle_breath(datum/gas_mixture/breath)
+18 -2
View File
@@ -1,3 +1,13 @@
/mob/living/carbon/New()
create_reagents(1000)
var/datum/reagents/R1 = new/datum/reagents(1000)
var/datum/reagents/R2 = new/datum/reagents(1000)
ingested = R1
touching = R2
R1.my_atom = src
R2.my_atom = src
..()
/mob/living/carbon/Life()
..()
@@ -442,11 +452,17 @@
Stun(stun_duration)
Weaken(Floor(stun_duration/2))
return 1
/mob/living/carbon/proc/add_chemical_effect(var/effect, var/magnitude = 1)
if(effect in chem_effects)
chem_effects[effect] += magnitude
else
chem_effects[effect] = magnitude
/mob/living/carbon/get_default_language()
if(default_language)
return default_language
if(!species)
return null
return species.default_language ? all_languages[species.default_language] : null
return species.default_language ? all_languages[species.default_language] : null
@@ -17,5 +17,8 @@
var/datum/surgery_status/op_stage = new/datum/surgery_status
//Active emote/pose
var/pose = null
var/list/chem_effects = list()
var/datum/reagents/ingested = null
var/datum/reagents/touching = null
var/pulse = PULSE_NORM //current pulse level
@@ -19,17 +19,13 @@
set_species(new_species,1)
else
set_species()
if(species)
real_name = species.get_random_name(gender)
name = real_name
if(mind)
mind.name = real_name
var/datum/reagents/R = new/datum/reagents(1000)
reagents = R
R.my_atom = src
hud_list[HEALTH_HUD] = image('icons/mob/hud.dmi', src, "hudhealth100")
hud_list[STATUS_HUD] = image('icons/mob/hud.dmi', src, "hudhealthy")
hud_list[LIFE_HUD] = image('icons/mob/hud.dmi', src, "hudhealthy")
@@ -10,9 +10,8 @@
if(embedded_flag)
handle_embedded_objects() //Moving with objects stuck in you can cause bad times.
if(reagents.has_reagent("hyperzine")) return -1
if(reagents.has_reagent("nuka_cola")) return -1
if(CE_SPEEDBOOST in chem_effects)
return -1
var/health_deficiency = (100 - health)
if(health_deficiency >= 40) tally += (health_deficiency / 25)
+9 -6
View File
@@ -859,10 +859,16 @@
proc/handle_chemicals_in_body()
if(reagents && !(species.flags & IS_SYNTHETIC)) //Synths don't process reagents.
chem_effects.Cut()
analgesic = 0
var/alien = 0
if(species && species.reagent_tag)
alien = species.reagent_tag
reagents.metabolize(src,alien)
touching.metabolize(alien, CHEM_TOUCH)
ingested.metabolize(alien, CHEM_INGEST)
reagents.metabolize(alien, CHEM_BLOOD)
if(CE_PAINKILLER in chem_effects)
analgesic = chem_effects[CE_PAINKILLER]
var/total_phoronloss = 0
for(var/obj/item/I in src)
@@ -951,9 +957,6 @@
silent = 0
return 1
// the analgesic effect wears off slowly
analgesic = max(0, analgesic - 1)
//UNCONSCIOUS. NO-ONE IS HOME
if( (getOxyLoss() > 50) || (config.health_threshold_crit > health) )
Paralyse(3)
@@ -1257,7 +1260,7 @@
see_invisible = SEE_INVISIBLE_LIVING
if(healths)
if (analgesic)
if (analgesic > 100)
healths.icon_state = "health_health_numb"
else
switch(hal_screwyhud)
@@ -1449,7 +1452,7 @@
handle_shock()
..()
if(status_flags & GODMODE) return 0 //godmode
if(analgesic || (species && species.flags & NO_PAIN)) return // analgesic avoids all traumatic shock temporarily
if(species && species.flags & NO_PAIN) return
if(health < config.health_threshold_softcrit)// health 0 makes you immediately collapse
shock_stage = max(shock_stage, 61)
+11 -1
View File
@@ -82,8 +82,18 @@
return temp_change
/mob/living/carbon/slime/proc/handle_chemicals_in_body()
chem_effects.Cut()
analgesic = 0
if(reagents) reagents.metabolize(src)
if(touching)
touching.metabolize(0, CHEM_TOUCH)
if(ingested)
ingested.metabolize(0, CHEM_INGEST)
if(reagents)
reagents.metabolize(0, CHEM_BLOOD)
if(CE_PAINKILLER in chem_effects)
analgesic = chem_effects[CE_PAINKILLER]
src.updatehealth()
@@ -61,8 +61,6 @@
verbs += /mob/living/proc/ventcrawl
create_reagents(100)
src.colour = colour
number = rand(1, 1000)
name = "[colour] [is_adult ? "adult" : "baby"] slime ([number])"
@@ -410,14 +408,6 @@
adjustToxLoss(-10)
nutrition = max(nutrition, get_max_nutrition())
/mob/living/carbon/slime/proc/apply_water(var/amount)
adjustToxLoss(15 + amount)
if (!client)
if (Target) // Like cats
Target = null
++Discipline
return
/mob/living/carbon/slime/can_use_vents()
if(Victim)
return "You cannot ventcrawl while feeding."
+2 -15
View File
@@ -13,24 +13,11 @@
1.5 * src.getFireLoss() + \
1.2 * src.getBruteLoss() + \
1.7 * src.getCloneLoss() + \
2 * src.halloss
2 * src.halloss + \
-1 * src.analgesic
if(reagents.has_reagent("alkysine"))
src.traumatic_shock -= 10
if(reagents.has_reagent("inaprovaline"))
src.traumatic_shock -= 25
if(reagents.has_reagent("synaptizine"))
src.traumatic_shock -= 40
if(reagents.has_reagent("paracetamol"))
src.traumatic_shock -= 50
if(reagents.has_reagent("tramadol"))
src.traumatic_shock -= 80
if(reagents.has_reagent("oxycodone"))
src.traumatic_shock -= 200
if(src.slurring)
src.traumatic_shock -= 20
if(src.analgesic)
src.traumatic_shock = 0
// broken or ripped off organs will add quite a bit of pain
if(istype(src,/mob/living/carbon/human))
@@ -230,7 +230,7 @@ var/global/list/robot_modules = list(
src.modules += new /obj/item/roller_holder(src)
src.modules += new /obj/item/weapon/reagent_containers/borghypo/crisis(src)
src.modules += new /obj/item/weapon/reagent_containers/glass/beaker/large(src)
src.modules += new /obj/item/weapon/reagent_containers/robodropper(src)
src.modules += new /obj/item/weapon/reagent_containers/dropper/industrial(src)
src.modules += new /obj/item/weapon/reagent_containers/syringe(src)
src.modules += new /obj/item/weapon/extinguisher/mini(src)
src.emag = new /obj/item/weapon/reagent_containers/spray(src)
@@ -494,7 +494,7 @@ var/global/list/robot_modules = list(
M.stored_matter = 30
src.modules += M
src.modules += new /obj/item/weapon/reagent_containers/robodropper(src)
src.modules += new /obj/item/weapon/reagent_containers/dropper/industrial(src)
var/obj/item/weapon/flame/lighter/zippo/L = new /obj/item/weapon/flame/lighter/zippo(src)
L.lit = 1
+6 -15
View File
@@ -55,12 +55,8 @@ var/const/BLOOD_VOLUME_SURVIVE = 122
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)
if(CE_BLOODRESTORE in chem_effects)
B.volume += chem_effects[CE_BLOODRESTORE]
// Damaged heart virtually reduces the blood volume, as the blood isn't
// being pumped properly anymore.
@@ -200,9 +196,8 @@ var/const/BLOOD_VOLUME_SURVIVE = 122
vessel.remove_reagent("blood",amount) // Removes blood if human
//Transfers blood from container ot vessels
/mob/living/carbon/proc/inject_blood(obj/item/weapon/reagent_containers/container, var/amount)
var/datum/reagent/blood/injected = get_blood(container.reagents)
if (!injected)
/mob/living/carbon/proc/inject_blood(var/datum/reagent/blood/injected, var/amount)
if (!injected || !istype(injected))
return
var/list/sniffles = virus_copylist(injected.data["virus2"])
for(var/ID in sniffles)
@@ -216,12 +211,8 @@ var/const/BLOOD_VOLUME_SURVIVE = 122
src.reagents.add_reagent(C, (text2num(chems[C]) / 560) * amount)//adds trace chemicals to owner's blood
reagents.update_total()
container.reagents.remove_reagent("blood", amount)
//Transfers blood from container ot vessels, respecting blood types compatability.
/mob/living/carbon/human/inject_blood(obj/item/weapon/reagent_containers/container, var/amount)
var/datum/reagent/blood/injected = get_blood(container.reagents)
//Transfers blood from reagents to vessel, respecting blood types compatability.
/mob/living/carbon/human/inject_blood(var/datum/reagent/blood/injected, var/amount)
if(species && species.flags & NO_BLOOD)
reagents.add_reagent("blood", amount, injected.data)
+7 -16
View File
@@ -135,20 +135,12 @@
if(is_broken())
filter_effect -= 2
// Do some reagent filtering/processing.
for(var/datum/reagent/R in owner.reagents.reagent_list)
// Damaged liver means some chemicals are very dangerous
// The liver is also responsible for clearing out alcohol and toxins.
// Ethanol and all drinks are bad.K
if(istype(R, /datum/reagent/ethanol))
if(filter_effect < 3)
owner.adjustToxLoss(0.1 * PROCESS_ACCURACY)
owner.reagents.remove_reagent(R.id, R.custom_metabolism*filter_effect)
// Can't cope with toxins at all
else if(istype(R, /datum/reagent/toxin))
if(filter_effect < 3)
owner.adjustToxLoss(0.3 * PROCESS_ACCURACY)
owner.reagents.remove_reagent(R.id, ALCOHOL_METABOLISM*filter_effect)
// 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"
@@ -157,7 +149,6 @@
organ_tag = "appendix"
/obj/item/organ/appendix/removed()
if(owner)
var/inflamed = 0
for(var/datum/disease/appendicitis/appendicitis in owner.viruses)
@@ -167,4 +158,4 @@
if(inflamed)
icon_state = "appendixinflamed"
name = "inflamed appendix"
..()
..()
+2 -12
View File
@@ -9,13 +9,7 @@ mob/var/next_pain_time = 0
// amount is a num from 1 to 100
mob/living/carbon/proc/pain(var/partname, var/amount, var/force, var/burning = 0)
if(stat >= 2) return
if(reagents.has_reagent("paracetamol"))
return
if(reagents.has_reagent("tramadol"))
return
if(reagents.has_reagent("oxycodone"))
return
if(analgesic)
if(analgesic > 40)
return
if(world.time < next_pain_time && !force)
return
@@ -80,11 +74,7 @@ mob/living/carbon/human/proc/handle_pain()
if(species && species.flags & NO_PAIN) return
if(stat >= 2) return
if(reagents.has_reagent("tramadol"))
return
if(reagents.has_reagent("oxycodone"))
return
if(analgesic)
if(analgesic > 70)
return
var/maxdam = 0
var/obj/item/organ/external/damaged_organ = null
+2 -2
View File
@@ -76,7 +76,7 @@
return
..()
if(reagents.total_volume)
if(M.reagents) reagents.trans_to(M, 50) //used to be 150
if(M.reagents) reagents.trans_to_mob(M, 50, CHEM_BLOOD) //used to be 150
return
@@ -99,7 +99,7 @@
if(M.can_inject(user,1))
if(reagents.total_volume)
if(M.reagents) reagents.trans_to(M, 50)
if(M.reagents) reagents.trans_to_mob(M, 50, CHEM_BLOOD)
return
@@ -52,8 +52,7 @@
//unfortuately we don't know where the dart will actually hit, since that's done by the parent.
if(L.can_inject())
if(syringe.reagents)
syringe.reagents.trans_to(L, 15)
syringe.reagents.trans_to_mob(L, 15, CHEM_BLOOD)
syringe.break_syringe(iscarbon(hit_atom)? hit_atom : null)
syringe.update_icon()
@@ -17,7 +17,7 @@
if(blocked < 2 && isliving(target))
var/mob/living/L = target
if(L.can_inject(target_zone=def_zone))
reagents.trans_to(L, reagent_amount)
reagents.trans_to_mob(L, reagent_amount, CHEM_BLOOD)
/obj/item/ammo_casing/chemdart
name = "chemical dart"
@@ -125,7 +125,7 @@
if(mixing.len)
var/mix_amount = dart.reagent_amount/mixing.len
for(var/obj/item/weapon/reagent_containers/glass/beaker/B in mixing)
B.reagents.trans_to(dart, mix_amount)
B.reagents.trans_to_obj(dart, mix_amount)
/obj/item/weapon/gun/projectile/dartgun/attack_self(mob/user)
user.set_machine(src)
+350 -544
View File
@@ -1,27 +1,23 @@
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
var/const/TOUCH = 1
var/const/INGEST = 2
///////////////////////////////////////////////////////////////////////////////////
/datum/reagents
var/list/datum/reagent/reagent_list = new/list()
var/list/datum/reagent/reagent_list = list()
var/total_volume = 0
var/maximum_volume = 100
var/atom/my_atom = null
var/reacting = 0 // Reacting right now
/datum/reagents/New(maximum=100)
maximum_volume = maximum
/datum/reagents/New(var/max = 100)
maximum_volume = max
//I dislike having these here but map-objects are initialised before world/New() is called. >_>
if(!chemical_reagents_list)
//Chemical Reagents - Initialises all /datum/reagent into a list indexed by reagent id
var/paths = typesof(/datum/reagent) - /datum/reagent
chemical_reagents_list = list()
for(var/path in paths)
var/datum/reagent/D = new path()
var/datum/reagent/D = new path()
if(!D.name)
continue
chemical_reagents_list[D.id] = D
if(!chemical_reactions_list)
//Chemical Reactions - Initialises all /datum/chemical_reaction into a list
// It is filtered into multiple lists within a list.
@@ -44,43 +40,27 @@ var/const/INGEST = 2
for(var/id in reaction_ids)
if(!chemical_reactions_list[id])
chemical_reactions_list[id] = list()
chemical_reactions_list[id] += D
break // Don't bother adding ourselves to other reagent ids, it is redundant.
/datum/reagents/Destroy()
..()
for(var/datum/reagent/R in reagent_list)
qdel(R)
reagent_list.Cut()
reagent_list = null
if(my_atom && my_atom.reagents == src)
chemical_reactions_list[id] += D
break // Don't bother adding ourselves to other reagent ids, it is redundant.
/datum/reagents/Destroy()
..()
for(var/datum/reagent/R in reagent_list)
qdel(R)
reagent_list.Cut()
reagent_list = null
if(my_atom && my_atom.reagents == src)
my_atom.reagents = null
/datum/reagents/proc/remove_any(var/amount=1)
var/total_transfered = 0
var/current_list_element = 1
/* Internal procs */
current_list_element = rand(1,reagent_list.len)
/datum/reagents/proc/get_free_space() // Returns free space.
return maximum_volume - total_volume
while(total_transfered != amount)
if(total_transfered >= amount) break
if(total_volume <= 0 || !reagent_list.len) break
if(current_list_element > reagent_list.len) current_list_element = 1
var/datum/reagent/current_reagent = reagent_list[current_list_element]
src.remove_reagent(current_reagent.id, 1)
current_list_element++
total_transfered++
src.update_total()
handle_reactions()
return total_transfered
/datum/reagents/proc/get_master_reagent()
/datum/reagents/proc/get_master_reagent() // Returns reference to the reagent with the biggest volume.
var/the_reagent = null
var/the_volume = 0
for(var/datum/reagent/A in reagent_list)
if(A.volume > the_volume)
the_volume = A.volume
@@ -88,7 +68,7 @@ var/const/INGEST = 2
return the_reagent
/datum/reagents/proc/get_master_reagent_name()
/datum/reagents/proc/get_master_reagent_name() // Returns the name of the reagent with the biggest volume.
var/the_name = null
var/the_volume = 0
for(var/datum/reagent/A in reagent_list)
@@ -98,7 +78,7 @@ var/const/INGEST = 2
return the_name
/datum/reagents/proc/get_master_reagent_id()
/datum/reagents/proc/get_master_reagent_id() // Returns the id of the reagent with the biggest volume.
var/the_id = null
var/the_volume = 0
for(var/datum/reagent/A in reagent_list)
@@ -108,522 +88,348 @@ var/const/INGEST = 2
return the_id
/datum/reagents/proc/trans_to(var/obj/target, var/amount=1, var/multiplier=1, var/preserve_data=1)//if preserve_data=0, the reagents data will be lost. Usefull if you use data for some strange stuff and don't want it to be transferred.
if (!target )
return
if (!target.reagents || src.total_volume<=0)
return
var/datum/reagents/R = target.reagents
amount = min(min(amount, src.total_volume), R.maximum_volume-R.total_volume)
var/part = amount / src.total_volume
var/trans_data = null
for (var/datum/reagent/current_reagent in src.reagent_list)
if (!current_reagent)
continue
if (current_reagent.id == "blood" && ishuman(target))
var/mob/living/carbon/human/H = target
H.inject_blood(my_atom, amount)
continue
var/current_reagent_transfer = current_reagent.volume * part
if(preserve_data)
trans_data = copy_data(current_reagent)
R.add_reagent(current_reagent.id, (current_reagent_transfer * multiplier), trans_data, safety = 1) //safety checks on these so all chemicals are transferred
src.remove_reagent(current_reagent.id, current_reagent_transfer, safety = 1) // to the target container before handling reactions
src.update_total()
R.update_total()
R.handle_reactions()
src.handle_reactions()
return amount
/datum/reagents/proc/trans_to_ingest(var/obj/target, var/amount=1, var/multiplier=1, var/preserve_data=1)//For items ingested. A delay is added between ingestion and addition of the reagents
if (!target )
return
if (!target.reagents || src.total_volume<=0)
return
/*var/datum/reagents/R = target.reagents
var/obj/item/weapon/reagent_containers/glass/beaker/noreact/B = new /obj/item/weapon/reagent_containers/glass/beaker/noreact //temporary holder
amount = min(min(amount, src.total_volume), R.maximum_volume-R.total_volume)
var/part = amount / src.total_volume
var/trans_data = null
for (var/datum/reagent/current_reagent in src.reagent_list)
if (!current_reagent)
continue
//if (current_reagent.id == "blood" && ishuman(target))
// var/mob/living/carbon/human/H = target
// H.inject_blood(my_atom, amount)
// continue
var/current_reagent_transfer = current_reagent.volume * part
if(preserve_data)
trans_data = current_reagent.data
B.add_reagent(current_reagent.id, (current_reagent_transfer * multiplier), trans_data, safety = 1) //safety checks on these so all chemicals are transferred
src.remove_reagent(current_reagent.id, current_reagent_transfer, safety = 1) // to the target container before handling reactions
src.update_total()
B.update_total()
B.handle_reactions()
src.handle_reactions()*/
var/obj/item/weapon/reagent_containers/glass/beaker/noreact/B = new /obj/item/weapon/reagent_containers/glass/beaker/noreact //temporary holder
B.volume = 1000
var/datum/reagents/BR = B.reagents
var/datum/reagents/R = target.reagents
amount = min(min(amount, src.total_volume), R.maximum_volume-R.total_volume)
src.trans_to(B, amount)
spawn(95)
BR.reaction(target, INGEST)
spawn(5)
BR.trans_to(target, BR.total_volume)
qdel(B)
return amount
/datum/reagents/proc/copy_to(var/obj/target, var/amount=1, var/multiplier=1, var/preserve_data=1, var/safety = 0)
if(!target)
return
if(!target.reagents || src.total_volume<=0)
return
var/datum/reagents/R = target.reagents
amount = min(min(amount, src.total_volume), R.maximum_volume-R.total_volume)
var/part = amount / src.total_volume
var/trans_data = null
for (var/datum/reagent/current_reagent in src.reagent_list)
var/current_reagent_transfer = current_reagent.volume * part
if(preserve_data)
trans_data = copy_data(current_reagent)
R.add_reagent(current_reagent.id, (current_reagent_transfer * multiplier), trans_data, safety = 1) //safety check so all chemicals are transferred before reacting
src.update_total()
R.update_total()
if(!safety)
R.handle_reactions()
src.handle_reactions()
return amount
/datum/reagents/proc/trans_id_to(var/obj/target, var/reagent, var/amount=1, var/preserve_data=1)//Not sure why this proc didn't exist before. It does now! /N
if (!target)
return
if (!target.reagents || src.total_volume<=0 || !src.get_reagent_amount(reagent))
return
var/datum/reagents/R = target.reagents
if(src.get_reagent_amount(reagent)<amount)
amount = src.get_reagent_amount(reagent)
amount = min(amount, R.maximum_volume-R.total_volume)
var/trans_data = null
for (var/datum/reagent/current_reagent in src.reagent_list)
if(current_reagent.id == reagent)
if(preserve_data)
trans_data = copy_data(current_reagent)
R.add_reagent(current_reagent.id, amount, trans_data)
src.remove_reagent(current_reagent.id, amount, 1)
break
src.update_total()
R.update_total()
R.handle_reactions()
//src.handle_reactions() Don't need to handle reactions on the source since you're (presumably isolating and) transferring a specific reagent.
return amount
/*
if (!target) return
var/total_transfered = 0
var/current_list_element = 1
var/datum/reagents/R = target.reagents
var/trans_data = null
//if(R.total_volume + amount > R.maximum_volume) return 0
current_list_element = rand(1,reagent_list.len) //Eh, bandaid fix.
while(total_transfered != amount)
if(total_transfered >= amount) break //Better safe than sorry.
if(total_volume <= 0 || !reagent_list.len) break
if(R.total_volume >= R.maximum_volume) break
if(current_list_element > reagent_list.len) current_list_element = 1
var/datum/reagent/current_reagent = reagent_list[current_list_element]
if(preserve_data)
trans_data = current_reagent.data
R.add_reagent(current_reagent.id, (1 * multiplier), trans_data)
src.remove_reagent(current_reagent.id, 1)
current_list_element++
total_transfered++
src.update_total()
R.update_total()
R.handle_reactions()
handle_reactions()
return total_transfered
*/
/datum/reagents/proc/metabolize(var/mob/M,var/alien)
for(var/A in reagent_list)
var/datum/reagent/R = A
if(M && R)
R.on_mob_life(M,alien)
update_total()
/datum/reagents/proc/conditional_update_move(var/atom/A, var/Running = 0)
for(var/datum/reagent/R in reagent_list)
R.on_move (A, Running)
update_total()
/datum/reagents/proc/conditional_update(var/atom/A, )
for(var/datum/reagent/R in reagent_list)
R.on_update (A)
update_total()
/datum/reagents/proc/handle_reactions()
if(my_atom.flags & NOREACT) return //Yup, no reactions here. No siree.
var/reaction_occured = 0
do
reaction_occured = 0
for(var/datum/reagent/R in reagent_list) // Usually a small list
for(var/reaction in chemical_reactions_list[R.id]) // Was a big list but now it should be smaller since we filtered it with our reagent id
if(!reaction)
continue
var/datum/chemical_reaction/C = reaction
//check if this recipe needs to be heated to mix
if(C.requires_heating)
if(istype(my_atom.loc, /obj/machinery/bunsen_burner))
if(!my_atom.loc:heated)
continue
else
continue
var/total_required_reagents = C.required_reagents.len
var/total_matching_reagents = 0
var/total_required_catalysts = C.required_catalysts.len
var/total_matching_catalysts= 0
var/matching_container = 0
var/matching_other = 0
var/list/multipliers = new/list()
for(var/B in C.required_reagents)
if(!has_reagent(B, C.required_reagents[B])) break
total_matching_reagents++
multipliers += round(get_reagent_amount(B) / C.required_reagents[B])
for(var/B in C.required_catalysts)
if(!has_reagent(B, C.required_catalysts[B])) break
total_matching_catalysts++
if(!C.required_container)
matching_container = 1
else
if(my_atom.type == C.required_container)
matching_container = 1
if(!C.required_other)
matching_other = 1
else
/*if(istype(my_atom, /obj/item/slime_core))
var/obj/item/slime_core/M = my_atom
if(M.POWERFLAG == C.required_other && M.Uses > 0) // added a limit to slime cores -- Muskets requested this
matching_other = 1*/
if(istype(my_atom, /obj/item/slime_extract))
var/obj/item/slime_extract/M = my_atom
if(M.Uses > 0) // added a limit to slime cores -- Muskets requested this
matching_other = 1
if(total_matching_reagents == total_required_reagents && total_matching_catalysts == total_required_catalysts && matching_container && matching_other)
var/multiplier = min(multipliers)
var/preserved_data = null
for(var/B in C.required_reagents)
if(!preserved_data)
preserved_data = get_data(B)
remove_reagent(B, (multiplier * C.required_reagents[B]), safety = 1)
var/created_volume = C.result_amount*multiplier
if(C.result)
feedback_add_details("chemical_reaction","[C.result]|[C.result_amount*multiplier]")
multiplier = max(multiplier, 1) //this shouldnt happen ...
if(!isnull(C.resultcolor)) //paints
add_reagent(C.result, C.result_amount*multiplier, C.resultcolor)
else
add_reagent(C.result, C.result_amount*multiplier)
set_data(C.result, preserved_data)
//add secondary products
for(var/S in C.secondary_results)
add_reagent(S, C.result_amount * C.secondary_results[S] * multiplier)
var/list/seen = viewers(4, get_turf(my_atom))
for(var/mob/M in seen)
M << "\blue \icon[my_atom] The solution begins to bubble."
/* if(istype(my_atom, /obj/item/slime_core))
var/obj/item/slime_core/ME = my_atom
ME.Uses--
if(ME.Uses <= 0) // give the notification that the slime core is dead
for(var/mob/M in viewers(4, get_turf(my_atom)) )
M << "\blue \icon[my_atom] The innards begin to boil!"
*/
if(istype(my_atom, /obj/item/slime_extract))
var/obj/item/slime_extract/ME2 = my_atom
ME2.Uses--
if(ME2.Uses <= 0) // give the notification that the slime core is dead
for(var/mob/M in seen)
M << "\blue \icon[my_atom] The [my_atom]'s power is consumed in the reaction."
ME2.name = "used slime extract"
ME2.desc = "This extract has been used up."
playsound(get_turf(my_atom), 'sound/effects/bubbles.ogg', 80, 1)
C.on_reaction(src, created_volume)
reaction_occured = 1
break
while(reaction_occured)
update_total()
return 0
/datum/reagents/proc/isolate_reagent(var/reagent)
for(var/A in reagent_list)
var/datum/reagent/R = A
if (R.id != reagent)
del_reagent(R.id)
update_total()
/datum/reagents/proc/del_reagent(var/reagent)
for(var/A in reagent_list)
var/datum/reagent/R = A
if (R.id == reagent)
reagent_list -= A
qdel(A)
update_total()
my_atom.on_reagent_change()
return 0
return 1
/datum/reagents/proc/update_total()
/datum/reagents/proc/update_total() // Updates volume.
total_volume = 0
for(var/datum/reagent/R in reagent_list)
if(R.volume < 0.1)
if(R.volume < MINIMUM_CHEMICAL_VOLUME)
del_reagent(R.id)
else
total_volume += R.volume
return 0
/datum/reagents/proc/clear_reagents()
for(var/datum/reagent/R in reagent_list)
del_reagent(R.id)
return 0
/datum/reagents/proc/reaction(var/atom/A, var/method=TOUCH, var/volume_modifier=0)
if(!istype(A) || !A.simulated)
return
switch(method)
if(TOUCH)
for(var/datum/reagent/R in reagent_list)
if(ismob(A))
spawn(0)
if(!R) return
else R.reaction_mob(A, TOUCH, R.volume+volume_modifier)
if(isturf(A))
spawn(0)
if(!R) return
else R.reaction_turf(A, R.volume+volume_modifier)
if(isobj(A))
spawn(0)
if(!R) return
else R.reaction_obj(A, R.volume+volume_modifier)
if(INGEST)
for(var/datum/reagent/R in reagent_list)
if(ismob(A) && R)
spawn(0)
if(!R) return
else R.reaction_mob(A, INGEST, R.volume+volume_modifier)
if(isturf(A) && R)
spawn(0)
if(!R) return
else R.reaction_turf(A, R.volume+volume_modifier)
if(isobj(A) && R)
spawn(0)
if(!R) return
else R.reaction_obj(A, R.volume+volume_modifier)
return
/datum/reagents/proc/add_reagent(var/reagent, var/amount, var/data=null, var/safety = 0)
if(!isnum(amount)) return 1
update_total()
if(total_volume + amount > maximum_volume) amount = (maximum_volume - total_volume) //Doesnt fit in. Make it disappear. Shouldnt happen. Will happen.
for(var/A in reagent_list)
var/datum/reagent/R = A
if (R.id == reagent)
R.on_merge(data, amount)
R.volume += amount
update_total()
if(!safety)
handle_reactions()
my_atom.on_reagent_change()
return 0
var/datum/reagent/D = chemical_reagents_list[reagent]
if(D)
var/datum/reagent/R = new D.type()
reagent_list += R
R.holder = src
R.volume = amount
if(reagent == "paint")
R.color = data
else
SetViruses(R, data) // Includes setting data for blood
//debug
//world << "Adding data"
//for(var/D in R.data)
// world << "Container data: [D] = [R.data[D]]"
//debug
update_total()
my_atom.on_reagent_change()
if(!safety)
handle_reactions()
return 0
else
warning("[my_atom] attempted to add a reagent called '[reagent]' which doesn't exist. ([usr])")
if(!safety)
handle_reactions()
return 1
/datum/reagents/proc/remove_reagent(var/reagent, var/amount, var/safety = 0)//Added a safety check for the trans_id_to
if(!isnum(amount)) return 1
for(var/A in reagent_list)
var/datum/reagent/R = A
if (R.id == reagent)
R.volume -= amount
update_total()
if(!safety)//So it does not handle reactions when it need not to
handle_reactions()
my_atom.on_reagent_change()
return 0
return 1
/datum/reagents/proc/has_reagent(var/reagent, var/amount = -1)
for(var/A in reagent_list)
var/datum/reagent/R = A
if (R.id == reagent)
if(!amount) return R
else
if(R.volume >= amount) return R
else return 0
return 0
/datum/reagents/proc/get_reagent_amount(var/reagent)
for(var/A in reagent_list)
var/datum/reagent/R = A
if (R.id == reagent)
return R.volume
return 0
/datum/reagents/proc/get_reagents()
var/res = ""
for(var/datum/reagent/A in reagent_list)
if (res != "") res += ","
res += A.name
return res
/datum/reagents/proc/remove_all_type(var/reagent_type, var/amount, var/strict = 0, var/safety = 1) // Removes all reagent of X type. @strict set to 1 determines whether the childs of the type are included.
if(!isnum(amount)) return 1
var/has_removed_reagent = 0
for(var/datum/reagent/R in reagent_list)
var/matches = 0
// Switch between how we check the reagent type
if(strict)
if(R.type == reagent_type)
matches = 1
else
if(istype(R, reagent_type))
matches = 1
// We found a match, proceed to remove the reagent. Keep looping, we might find other reagents of the same type.
if(matches)
// Have our other proc handle removement
has_removed_reagent = remove_reagent(R.id, amount, safety)
return has_removed_reagent
//two helper functions to preserve data across reactions (needed for xenoarch)
/datum/reagents/proc/get_data(var/reagent_id)
for(var/datum/reagent/D in reagent_list)
if(D.id == reagent_id)
//world << "proffering a data-carrying reagent ([reagent_id])"
return D.data
/datum/reagents/proc/set_data(var/reagent_id, var/new_data)
for(var/datum/reagent/D in reagent_list)
if(D.id == reagent_id)
//world << "reagent data set ([reagent_id])"
D.data = new_data
/datum/reagents/proc/delete()
for(var/datum/reagent/R in reagent_list)
R.holder = null
if(my_atom)
my_atom.reagents = null
/datum/reagents/proc/copy_data(var/datum/reagent/current_reagent)
if (current_reagent.id == "paint") return current_reagent.color
if (!current_reagent || !current_reagent.data) return null
if (!istype(current_reagent.data, /list)) return current_reagent.data
/datum/reagents/proc/handle_reactions()
if(!my_atom) // No reactions in temporary holders
return
if(my_atom.flags & NOREACT) // No reactions here
return
var/list/trans_data = current_reagent.data.Copy()
var/reaction_occured = 0
do
reaction_occured = 0
for(var/datum/reagent/R in reagent_list)
for(var/datum/chemical_reaction/C in chemical_reactions_list[R.id])
var/reagents_suitable = 1
for(var/B in C.required_reagents)
if(!has_reagent(B, C.required_reagents[B]))
reagents_suitable = 0
for(var/B in C.catalysts)
if(!has_reagent(B, C.catalysts[B]))
reagents_suitable = 0
for(var/B in C.inhibitors)
if(has_reagent(B, C.inhibitors[B]))
reagents_suitable = 0
// We do this so that introducing a virus to a blood sample
// doesn't automagically infect all other blood samples from
// the same donor.
//
// Technically we should probably copy all data lists, but
// that could possibly eat up a lot of memory needlessly
// if most data lists are read-only.
if (trans_data["virus2"])
var/list/v = trans_data["virus2"]
trans_data["virus2"] = v.Copy()
if(!reagents_suitable || !C.can_happen(src))
continue
return trans_data
var/use = -1
for(var/B in C.required_reagents)
if(use == -1)
use = get_reagent_amount(B) / C.required_reagents[B]
else
use = min(use, get_reagent_amount(B) / C.required_reagents[B])
///////////////////////////////////////////////////////////////////////////////////
var/newdata = C.send_data(src) // We need to get it before reagents are removed. See blood paint.
for(var/B in C.required_reagents)
remove_reagent(B, use * C.required_reagents[B], safety = 1)
if(C.result)
add_reagent(C.result, C.result_amount * use, newdata)
// Convenience proc to create a reagents holder for an atom
// Max vol is maximum volume of holder
/atom/proc/create_reagents(var/max_vol)
if(!ismob(my_atom) && C.mix_message)
var/list/seen = viewers(4, get_turf(my_atom))
for(var/mob/M in seen)
M << "<span class='notice'>\icon[my_atom] [C.mix_message]</span>"
playsound(get_turf(my_atom), 'sound/effects/bubbles.ogg', 80, 1)
C.on_reaction(src, C.result_amount * use)
reaction_occured = 1
while(reaction_occured)
update_total()
return
/* Holder-to-chemical */
/datum/reagents/proc/add_reagent(var/id, var/amount, var/data = null, var/safety = 0)
if(!isnum(amount))
return 0
update_total()
amount = min(amount, get_free_space())
for(var/datum/reagent/current in reagent_list)
if(current.id == id)
current.volume += amount
update_total()
if(!isnull(data)) // For all we know, it could be zero or empty string and meaningful
current.mix_data(data, amount)
if(!safety)
handle_reactions()
if(my_atom)
my_atom.on_reagent_change()
return 1
var/datum/reagent/D = chemical_reagents_list[id]
if(D)
var/datum/reagent/R = new D.type()
reagent_list += R
R.holder = src
R.volume = amount
update_total()
R.initialize_data(data)
if(!safety)
handle_reactions()
if(my_atom)
my_atom.on_reagent_change()
return 1
else
warning("[my_atom] attempted to add a reagent called '[id]' which doesn't exist. ([usr])")
return 0
/datum/reagents/proc/remove_reagent(var/id, var/amount, var/safety = 0)
if(!isnum(amount))
return 0
for(var/datum/reagent/current in reagent_list)
if(current.id == id)
current.volume -= amount // It can go negative, but it doesn't matter
update_total() // Because this proc will delete it then
if(!safety)
handle_reactions()
if(my_atom)
my_atom.on_reagent_change()
return 1
return 0
/datum/reagents/proc/del_reagent(var/id)
for(var/datum/reagent/current in reagent_list)
if (current.id == id)
reagent_list -= current
qdel(current)
update_total()
if(my_atom)
my_atom.on_reagent_change()
return 0
/datum/reagents/proc/has_reagent(var/id, var/amount = 0)
for(var/datum/reagent/current in reagent_list)
if(current.id == id)
if(current.volume >= amount)
return 1
else
return 0
return 0
/datum/reagents/proc/clear_reagents()
for(var/datum/reagent/current in reagent_list)
del_reagent(current.id)
return
/datum/reagents/proc/get_reagent_amount(var/id)
for(var/datum/reagent/current in reagent_list)
if(current.id == id)
return current.volume
return 0
/datum/reagents/proc/get_data(var/id)
for(var/datum/reagent/current in reagent_list)
if(current.id == id)
return current.get_data()
return 0
/datum/reagents/proc/get_reagents()
var/res = ""
for(var/datum/reagent/current in reagent_list)
if (res != "") res += ","
res += "[current.id]([current.volume])"
return res
/* Holder-to-holder and similar procs */
/datum/reagents/proc/remove_any(var/amount = 1) // Removes up to [amount] of reagents from [src]. Returns actual amount removed.
amount = min(amount, total_volume)
if(!amount)
return
var/part = amount / total_volume
for(var/datum/reagent/current in reagent_list)
var/amount_to_remove = current.volume * part
remove_reagent(current.id, amount_to_remove, 1)
update_total()
handle_reactions()
return amount
/datum/reagents/proc/trans_to_holder(var/datum/reagents/target, var/amount = 1, var/multiplier = 1, var/copy = 0) // Transfers [amount] reagents from [src] to [target], multiplying them by [multiplier]. Returns actual amount removed from [src] (not amount transferred to [target]).
if(!target || !istype(target))
return
amount = min(amount, total_volume, target.get_free_space() / multiplier)
if(!amount)
return
var/part = amount / total_volume
for(var/datum/reagent/current in reagent_list)
var/amount_to_transfer = current.volume * part
target.add_reagent(current.id, amount_to_transfer * multiplier, current.get_data(), safety = 1) // We don't react until everything is in place
if(!copy)
remove_reagent(current.id, amount_to_transfer, 1)
if(!copy)
handle_reactions()
target.handle_reactions()
return amount
/* Holder-to-atom and similar procs */
/datum/reagents/proc/touch(var/atom/target) // This picks the appropriate reaction. Reagents are not guaranteed to transfer to the target.
if(ismob(target))
touch_mob(target)
if(isturf(target))
touch_turf(target)
if(isobj(target))
touch_obj(target)
return
/datum/reagents/proc/touch_mob(var/mob/target)
if(!target || !istype(target))
return
for(var/datum/reagent/current in reagent_list)
current.touch_mob(target)
update_total()
/datum/reagents/proc/touch_turf(var/turf/target)
if(!target || !istype(target))
return
for(var/datum/reagent/current in reagent_list)
current.touch_turf(target)
update_total()
/datum/reagents/proc/touch_obj(var/obj/target)
if(!target || !istype(target))
return
for(var/datum/reagent/current in reagent_list)
current.touch_obj(target)
update_total()
/datum/reagents/proc/trans_to(var/atom/target, var/amount = 1, var/multiplier = 1, var/copy = 0)
if(ismob(target))
//warning("[my_atom] is trying to transfer reagents to [target], which is a mob, using trans_to()")
//return trans_to_mob(target, amount, multiplier, copy)
return splash_mob(target, amount)
if(isturf(target))
return trans_to_turf(target, amount, multiplier, copy)
if(isobj(target))
return trans_to_obj(target, amount, multiplier, copy)
return 0
/datum/reagents/proc/trans_id_to(var/atom/target, var/id, var/amount = 1)
if (!target || !target.reagents)
return
amount = min(amount, get_reagent_amount(id))
if(!amount)
return
var/datum/reagents/F = new /datum/reagents(amount)
var/tmpdata = get_data(id)
F.add_reagent(id, amount, tmpdata)
remove_reagent(id, amount)
return F.trans_to(target, amount) // Let this proc check the atom's type
/datum/reagents/proc/splash_mob(var/mob/target, var/amount = 1, var/clothes = 1)
var/perm = 0
var/list/L = list("head" = THERMAL_PROTECTION_HEAD, "upper_torso" = THERMAL_PROTECTION_UPPER_TORSO, "lower_torso" = THERMAL_PROTECTION_LOWER_TORSO, "legs" = THERMAL_PROTECTION_LEG_LEFT + THERMAL_PROTECTION_LEG_RIGHT, "feet" = THERMAL_PROTECTION_FOOT_LEFT + THERMAL_PROTECTION_FOOT_RIGHT, "arms" = THERMAL_PROTECTION_ARM_LEFT + THERMAL_PROTECTION_ARM_RIGHT, "hands" = THERMAL_PROTECTION_HAND_LEFT + THERMAL_PROTECTION_HAND_RIGHT)
if(clothes)
for(var/obj/item/clothing/C in target.get_equipped_items())
if(C.permeability_coefficient == 1 || C.body_parts_covered == 0)
continue
if(C.body_parts_covered & HEAD)
L["head"] *= C.permeability_coefficient
if(C.body_parts_covered & UPPER_TORSO)
L["upper_torso"] *= C.permeability_coefficient
if(C.body_parts_covered & LOWER_TORSO)
L["lower_torso"] *= C.permeability_coefficient
if(C.body_parts_covered & LEGS)
L["legs"] *= C.permeability_coefficient
if(C.body_parts_covered & FEET)
L["feet"] *= C.permeability_coefficient
if(C.body_parts_covered & ARMS)
L["arms"] *= C.permeability_coefficient
if(C.body_parts_covered & HANDS)
L["hands"] *= C.permeability_coefficient
for(var/t in L)
perm += L[t]
return trans_to_mob(target, amount, CHEM_TOUCH, perm)
/datum/reagents/proc/trans_to_mob(var/mob/target, var/amount = 1, var/type = CHEM_BLOOD, var/multiplier = 1, var/copy = 0) // Transfer after checking into which holder...
if(!target || !istype(target))
return
if(iscarbon(target))
var/mob/living/carbon/C = target
if(type == CHEM_BLOOD)
var/datum/reagents/R = C.reagents
return trans_to_holder(R, amount, multiplier, copy)
if(type == CHEM_INGEST)
var/datum/reagents/R = C.ingested
return trans_to_holder(R, amount, multiplier, copy)
if(type == CHEM_TOUCH)
var/datum/reagents/R = C.touching
return trans_to_holder(R, amount, multiplier, copy)
else
var/datum/reagents/R = new /datum/reagents(amount)
. = trans_to_holder(R, amount, multiplier, copy)
R.touch_mob(target)
/datum/reagents/proc/trans_to_turf(var/turf/target, var/amount = 1, var/multiplier = 1, var/copy = 0) // Turfs don't have any reagents (at least, for now). Just touch it.
if(!target)
return
var/datum/reagents/R = new /datum/reagents(maximum_volume)
. = trans_to_holder(R, amount, multiplier, copy)
R.touch_turf(target)
return
/datum/reagents/proc/trans_to_obj(var/turf/target, var/amount = 1, var/multiplier = 1, var/copy = 0) // Objects may or may not; if they do, it's probably a beaker or something and we need to transfer properly; otherwise, just touch.
if(!target)
return
if(!target.reagents)
var/datum/reagents/R = new /datum/reagents(maximum_volume)
. = trans_to_holder(R, amount, multiplier, copy)
R.touch_obj(target)
return
return trans_to_holder(target.reagents, amount, multiplier, copy)
/datum/reagents/proc/metabolize(var/alien, var/location)
if(!iscarbon(my_atom))
return
var/mob/living/carbon/C = my_atom
if(!C || !istype(C))
return
for(var/datum/reagent/current in reagent_list)
current.on_mob_life(C, alien, location)
update_total()
/* Atom reagent creation - use it all the time */
/atom/proc/create_reagents(var/max_vol)
reagents = new/datum/reagents(max_vol)
reagents.my_atom = src
reagents.my_atom = src
+3 -3
View File
@@ -189,7 +189,7 @@
P.pixel_x = rand(-7, 7) //random position
P.pixel_y = rand(-7, 7)
P.icon_state = "pill"+pillsprite
reagents.trans_to(P,amount_per_pill)
reagents.trans_to_obj(P,amount_per_pill)
if(src.loaded_pill_bottle)
if(loaded_pill_bottle.contents.len < loaded_pill_bottle.storage_slots)
P.loc = loaded_pill_bottle
@@ -204,11 +204,11 @@
P.pixel_x = rand(-7, 7) //random position
P.pixel_y = rand(-7, 7)
P.icon_state = bottlesprite
reagents.trans_to(P,60)
reagents.trans_to_obj(P,60)
P.update_icon()
else
var/obj/item/weapon/reagent_containers/food/condiment/P = new/obj/item/weapon/reagent_containers/food/condiment(src.loc)
reagents.trans_to(P,50)
reagents.trans_to_obj(P,50)
else if(href_list["change_pill"])
#define MAX_PILL_SPRITE 20 //max icon state of the pill sprites
var/dat = "<table>"
+76 -71
View File
@@ -1,106 +1,111 @@
#define SOLID 1
#define LIQUID 2
#define GAS 3
#define REAGENTS_OVERDOSE 30
#define REM REAGENTS_EFFECT_MULTIPLIER
//The reaction procs must ALWAYS set src = null, this detaches the proc from the object (the reagent)
//so that it can continue working when the reagent is deleted while the proc is still active.
/datum/reagent
var/name = "Reagent"
var/id = "reagent"
var/description = ""
var/description = "A non-descript chemical."
var/datum/reagents/holder = null
var/reagent_state = SOLID
var/list/data = null
var/volume = 0
var/nutriment_factor = 0
var/custom_metabolism = REAGENTS_METABOLISM
var/volume = 0
var/metabolism = REM // This would be 0.2 normally
var/ingest_met = 0
var/touch_met = 0
var/dose = 0
var/max_dose = 0
var/overdose = 0
var/overdose_dam = 1
var/scannable = 0 //shows up on health analyzers
var/scannable = 0 // Shows up on health analyzers.
var/affects_dead = 0
var/glass_icon_state = null
var/glass_name = null
var/glass_desc = null
var/glass_center_of_mass = null
//var/list/viruses = list()
var/color = "#000000" // rgb: 0, 0, 0, 0 - supports alpha channels
var/glass_center_of_mass = null
var/color = "#000000"
var/color_weight = 1
/datum/reagent/proc/reaction_mob(var/mob/M, var/method=TOUCH, var/volume) //By default we have a chance to transfer some
if(!istype(M, /mob/living)) return 0
var/datum/reagent/self = src
src = null //of the reagent to the mob on TOUCHING it.
/datum/reagent/proc/remove_self(var/amount) // Shortcut
holder.remove_reagent(id, amount)
if(self.holder) //for catching rare runtimes
if(!istype(self.holder.my_atom, /obj/effect/effect/smoke/chem))
// If the chemicals are in a smoke cloud, do not try to let the chemicals "penetrate" into the mob's system (balance station 13) -- Doohl
if(method == TOUCH)
var/chance = 1
var/block = 0
for(var/obj/item/clothing/C in M.get_equipped_items())
if(C.permeability_coefficient < chance) chance = C.permeability_coefficient
if(istype(C, /obj/item/clothing/suit/bio_suit))
// bio suits are just about completely fool-proof - Doohl
// kind of a hacky way of making bio suits more resistant to chemicals but w/e
if(prob(75))
block = 1
if(istype(C, /obj/item/clothing/head/bio_hood))
if(prob(75))
block = 1
chance = chance * 100
if(prob(chance) && !block)
if(M.reagents)
M.reagents.add_reagent(self.id,self.volume/2)
return 1
/datum/reagent/proc/reaction_obj(var/obj/O, var/volume) //By default we transfer a small part of the reagent to the object
src = null //if it can hold reagents. nope!
//if(O.reagents)
// O.reagents.add_reagent(id,volume/3)
/datum/reagent/proc/touch_mob(var/mob/M) // This doesn't apply to being splashed - this is for, e.g. extinguishers and sprays. The difference is that reagent is not on the mob - it's in another object.
return
/datum/reagent/proc/reaction_turf(var/turf/T, var/volume)
src = null
/datum/reagent/proc/touch_obj(var/obj/O) // Acid melting, cleaner cleaning, etc
return
/datum/reagent/proc/on_mob_life(var/mob/living/M as mob, var/alien)
if(!istype(M, /mob/living))
return //Noticed runtime errors from pacid trying to damage ghosts, this should fix. --NEO
if( (overdose > 0) && (volume >= overdose))//Overdosing, wooo
M.adjustToxLoss(overdose_dam)
holder.remove_reagent(src.id, custom_metabolism) //By default it slowly disappears.
/datum/reagent/proc/touch_turf(var/turf/T) // Cleaner cleaning, lube lubbing, etc, all go here
return
/datum/reagent/proc/on_move(var/mob/M)
/datum/reagent/proc/on_mob_life(var/mob/living/carbon/M, var/alien, var/location) // Currently, on_mob_life is called on carbons. Any interaction with non-carbon mobs (lube) will need to be done in touch_mob.
if(!istype(M))
return
if(!affects_dead && M.stat == DEAD)
return
if(overdose && (location == CHEM_BLOOD))
overdose(M, alien)
var/removed = metabolism
if(ingest_met && (location == CHEM_INGEST))
removed = ingest_met
if(touch_met && (location == CHEM_TOUCH))
removed = touch_met
removed = min(removed, volume)
max_dose = max(volume, max_dose)
dose = min(dose + removed, max_dose)
if(removed >= (metabolism * 0.1) || removed >= 0.1) // If there's too little chemical, don't affect the mob, just remove it
switch(location)
if(CHEM_BLOOD)
affect_blood(M, alien, removed)
if(CHEM_INGEST)
affect_ingest(M, alien, removed)
if(CHEM_TOUCH)
affect_touch(M, alien, removed)
remove_self(removed)
return
// Called after add_reagents creates a new reagent.
/datum/reagent/proc/on_new(var/data)
/datum/reagent/proc/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
return
// Called when two reagents of the same are mixing. <-- Blatant lies
/datum/reagent/proc/on_merge(var/newdata, var/newamount)
/datum/reagent/proc/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed)
affect_blood(M, alien, removed * 0.5)
return
/datum/reagent/proc/on_update(var/atom/A)
/datum/reagent/proc/affect_touch(var/mob/living/carbon/M, var/alien, var/removed)
return
/datum/reagent/proc/overdose(var/mob/living/carbon/M, var/alien) // Overdose effect. Doesn't happen instantly.
M.adjustToxLoss(REM)
return
/datum/reagent/proc/initialize_data(var/newdata) // Called when the reagent is created.
if(!isnull(newdata))
data = newdata
return
/datum/reagent/proc/mix_data(var/newdata, var/newamount) // You have a reagent with data, and new reagent with its own data get added, how do you deal with that?
return
/datum/reagent/proc/get_data() // Just in case you have a reagent that handles data differently.
if(data && istype(data, /list))
return data.Copy()
else if(data)
return data
return null
/datum/reagent/Destroy() // This should only be called by the holder, so it's already handled clearing its references
..()
holder = null
holder = null
/* DEPRECATED - TODO: REMOVE EVERYWHERE */
/datum/reagent/proc/reaction_turf(var/turf/target)
touch_turf(target)
/datum/reagent/proc/reaction_obj(var/obj/target)
touch_obj(target)
/datum/reagent/proc/reaction_mob(var/mob/target)
touch_mob(target)
/datum/reagent/woodpulp
name = "Wood Pulp"
id = "woodpulp"
description = "A mass of wood fibers."
reagent_state = LIQUID
color = "#B97A57"
color = "#B97A57"
@@ -1,119 +1,98 @@
/datum/reagent/blood
data = new/list("donor"=null,"viruses"=null,"species"="Human","blood_DNA"=null,"blood_type"=null,"blood_colour"= "#A10808","resistances"=null,"trace_chem"=null, "antibodies" = list())
data = new/list("donor" = null, "viruses" = null, "species" = "Human", "blood_DNA" = null, "blood_type" = null, "blood_colour" = "#A10808", "resistances" = null, "trace_chem" = null, "antibodies" = list())
name = "Blood"
id = "blood"
reagent_state = LIQUID
color = "#C80000" // rgb: 200, 0, 0
metabolism = REM * 5
color = "#C80000"
glass_icon_state = "glass_red"
glass_name = "glass of tomato juice"
glass_desc = "Are you sure this is tomato juice?"
/datum/reagent/blood/reaction_mob(var/mob/M, var/method=TOUCH, var/volume)
var/datum/reagent/blood/self = src
src = null
if(self.data && self.data["viruses"])
for(var/datum/disease/D in self.data["viruses"])
//var/datum/disease/virus = new D.type(0, D, 1)
// We don't spread.
if(D.spread_type == SPECIAL || D.spread_type == NON_CONTAGIOUS) continue
if(method == TOUCH)
M.contract_disease(D)
else //injected
M.contract_disease(D, 1, 0)
if(self.data && self.data["virus2"] && istype(M, /mob/living/carbon))//infecting...
var/list/vlist = self.data["virus2"]
if (vlist.len)
for (var/ID in vlist)
var/datum/disease2/disease/V = vlist[ID]
if(method == TOUCH)
infect_virus2(M,V.getcopy())
else
infect_virus2(M,V.getcopy(),1) //injected, force infection!
if(self.data && self.data["antibodies"] && istype(M, /mob/living/carbon))//... and curing
var/mob/living/carbon/C = M
C.antibodies |= self.data["antibodies"]
/datum/reagent/blood/on_merge(var/newdata, var/newamount)
if(!data || !newdata)
return
if(newdata["blood_colour"])
color = newdata["blood_colour"]
if(data && newdata)
if(data["viruses"] || newdata["viruses"])
var/list/mix1 = data["viruses"]
var/list/mix2 = newdata["viruses"]
// Stop issues with the list changing during mixing.
var/list/to_mix = list()
for(var/datum/disease/advance/AD in mix1)
to_mix += AD
for(var/datum/disease/advance/AD in mix2)
to_mix += AD
var/datum/disease/advance/AD = Advance_Mix(to_mix)
if(AD)
var/list/preserve = list(AD)
for(var/D in data["viruses"])
if(!istype(D, /datum/disease/advance))
preserve += D
data["viruses"] = preserve
return ..()
/datum/reagent/blood/on_update(var/atom/A)
if(data["blood_colour"])
/datum/reagent/blood/initialize_data(var/newdata)
..()
if(data && data["blood_colour"])
color = data["blood_colour"]
return ..()
/datum/reagent/blood/reaction_turf(var/turf/simulated/T, var/volume)//splash the blood all over the place
if(!istype(T)) return
var/datum/reagent/blood/self = src
src = null
if(!(volume >= 3)) return
if(!self.data["donor"] || istype(self.data["donor"], /mob/living/carbon/human))
blood_splatter(T,self,1)
else if(istype(self.data["donor"], /mob/living/carbon/alien))
var/obj/effect/decal/cleanable/blood/B = blood_splatter(T,self,1)
if(B) B.blood_DNA["UNKNOWN DNA STRUCTURE"] = "X*"
if(volume >= 5 && !istype(T.loc, /area/chapel)) //blood desanctifies non-chapel tiles
T.holy = 0
return
/* Must check the transfering of reagents and their data first. They all can point to one disease datum.
/datum/reagent/blood/get_data() // Just in case you have a reagent that handles data differently.
var/t = data.Copy()
if(t["virus2"])
var/list/v = t["virus2"]
t["virus2"] = v.Copy()
return t
/datum/reagent/blood/Destroy()
if(src.data["virus"])
var/datum/disease/D = src.data["virus"]
D.cure(0)
..()
*/
/datum/reagent/blood/mix_data(var/newdata, var/newamount) // You have a reagent with data, and new reagent with its own data get added, how do you deal with that?
if(data["viruses"] || newdata["viruses"])
var/list/mix1 = data["viruses"]
var/list/mix2 = newdata["viruses"]
var/list/to_mix = list() // Stop issues with the list changing during mixing.
for(var/datum/disease/advance/AD in mix1)
to_mix += AD
for(var/datum/disease/advance/AD in mix2)
to_mix += AD
var/datum/disease/advance/AD = Advance_Mix(to_mix)
if(AD)
var/list/preserve = list(AD)
for(var/D in data["viruses"])
if(!istype(D, /datum/disease/advance))
preserve += D
data["viruses"] = preserve
/datum/reagent/blood/touch_turf(var/turf/simulated/T)
if(!istype(T) || volume < 3)
return
if(!data["donor"] || istype(data["donor"], /mob/living/carbon/human))
blood_splatter(T, src, 1)
else if(istype(data["donor"], /mob/living/carbon/alien))
var/obj/effect/decal/cleanable/blood/B = blood_splatter(T, src, 1)
if(B)
B.blood_DNA["UNKNOWN DNA STRUCTURE"] = "X*"
/datum/reagent/blood/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed)
if(dose > 5)
M.adjustToxLoss(removed)
if(dose > 15)
M.adjustToxLoss(removed)
/datum/reagent/blood/affect_touch(var/mob/living/carbon/M, var/alien, var/removed)
if(data && data["viruses"])
for(var/datum/disease/D in data["viruses"])
if(D.spread_type == SPECIAL || D.spread_type == NON_CONTAGIOUS)
continue
M.contract_disease(D)
if(data && data["virus2"])
var/list/vlist = data["virus2"]
if(vlist.len)
for(var/ID in vlist)
var/datum/disease2/disease/V = vlist[ID]
infect_virus2(M, V.getcopy())
if(data && data["antibodies"])
M.antibodies |= data["antibodies"]
/datum/reagent/blood/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
M.inject_blood(src, volume)
remove_self(volume)
/datum/reagent/vaccine
//data must contain virus type
name = "Vaccine"
id = "vaccine"
reagent_state = LIQUID
color = "#C81040" // rgb: 200, 16, 64
color = "#C81040"
/datum/reagent/vaccine/reaction_mob(var/mob/M, var/method=TOUCH, var/volume)
var/datum/reagent/vaccine/self = src
src = null
if(self.data&&method == INGEST)
/datum/reagent/vaccine/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
if(data)
for(var/datum/disease/D in M.viruses)
if(istype(D, /datum/disease/advance))
var/datum/disease/advance/A = D
if(A.GetDiseaseID() == self.data)
if(A.GetDiseaseID() == data)
D.cure()
else
if(D.type == self.data)
if(D.type == data)
D.cure()
M.resistances += self.data
M.resistances += data
return
#define WATER_LATENT_HEAT 19000 // How much heat is removed when applied to a hot turf, in J/unit (19000 makes 120 u of water roughly equivalent to 4L)
@@ -122,29 +101,37 @@
id = "water"
description = "A ubiquitous chemical substance that is composed of hydrogen and oxygen."
reagent_state = LIQUID
color = "#0064C877" // rgb: 0, 100, 200
custom_metabolism = 0.01
color = "#0064C877"
metabolism = REM * 10
glass_icon_state = "glass_clear"
glass_name = "glass of water"
glass_desc = "The father of all refreshments."
/datum/reagent/water/reaction_turf(var/turf/simulated/T, var/volume)
if (!istype(T)) return
/datum/reagent/water/touch_turf(var/turf/simulated/T)
if(!istype(T))
return
//If the turf is hot enough, remove some heat
var/datum/gas_mixture/environment = T.return_air()
var/min_temperature = T0C + 100 //100C, the boiling point of water
var/min_temperature = T0C + 100 // 100C, the boiling point of water
if (environment && environment.temperature > min_temperature) //abstracted as steam or something
var/removed_heat = between(0, volume*WATER_LATENT_HEAT, -environment.get_thermal_energy_change(min_temperature))
var/hotspot = (locate(/obj/fire) in T)
if(hotspot && !istype(T, /turf/space))
var/datum/gas_mixture/lowertemp = T.remove_air(T:air:total_moles)
lowertemp.temperature = max(min(lowertemp.temperature-2000, lowertemp.temperature / 2), 0)
lowertemp.react()
T.assume_air(lowertemp)
qdel(hotspot)
if (environment && environment.temperature > min_temperature) // Abstracted as steam or something
var/removed_heat = between(0, volume * WATER_LATENT_HEAT, -environment.get_thermal_energy_change(min_temperature))
environment.add_thermal_energy(-removed_heat)
if (prob(5))
T.visible_message("\red The water sizzles as it lands on \the [T]!")
else //otherwise, the turf gets wet
T.visible_message("<span class='warning'>The water sizzles as it lands on \the [T]!</span>")
else
if(volume >= 3)
if(T.wet >= 1) return
if(T.wet >= 1)
return
T.wet = 1
if(T.wet_overlay)
T.overlays -= T.wet_overlay
@@ -152,74 +139,60 @@
T.wet_overlay = image('icons/effects/water.dmi',T,"wet_floor")
T.overlays += T.wet_overlay
src = null
spawn(800)
if (!istype(T)) return
if(T.wet >= 2) return
spawn(800) // This is terrible and needs to be changed when possible.
if(!T || !istype(T))
return
if(T.wet >= 2)
return
T.wet = 0
if(T.wet_overlay)
T.overlays -= T.wet_overlay
T.wet_overlay = null
//Put out fires.
var/hotspot = (locate(/obj/fire) in T)
if(hotspot)
qdel(hotspot)
if(environment)
environment.react() //react at the new temperature
/datum/reagent/water/reaction_obj(var/obj/O, var/volume)
var/turf/T = get_turf(O)
var/hotspot = (locate(/obj/fire) in T)
if(hotspot && !istype(T, /turf/space))
var/datum/gas_mixture/lowertemp = T.remove_air( T:air:total_moles )
lowertemp.temperature = max( min(lowertemp.temperature-2000,lowertemp.temperature / 2) ,0)
lowertemp.react()
T.assume_air(lowertemp)
qdel(hotspot)
if(istype(O,/obj/item/weapon/reagent_containers/food/snacks/monkeycube))
/datum/reagent/water/touch_obj(var/obj/O)
if(istype(O, /obj/item/weapon/reagent_containers/food/snacks/monkeycube))
var/obj/item/weapon/reagent_containers/food/snacks/monkeycube/cube = O
if(!cube.wrapped)
cube.Expand()
/datum/reagent/water/reaction_mob(var/mob/living/M, var/method=TOUCH, var/volume)
if (istype(M, /mob/living/carbon/slime))
/datum/reagent/water/affect_touch(var/mob/living/carbon/M, var/alien, var/removed)
if(istype(M, /mob/living/carbon/slime))
var/mob/living/carbon/slime/S = M
S.apply_water(volume)
if(method == TOUCH && isliving(M))
S.adjustToxLoss(15 * removed) // Babies have 150 health, adults have 200; So, 10 units and 13.5
if(!S.client)
if(S.Target) // Like cats
S.Target = null
++S.Discipline
if(dose == removed)
S.visible_message("<span class='warning'>[S]'s flesh sizzles where the water touches it!</span>", "<span class='danger'>Your flesh burns in the water!</span>")
var/needed = M.fire_stacks * 10
if(volume > needed)
M.fire_stacks = 0
M.ExtinguishMob()
remove_self(needed)
else
M.adjust_fire_stacks(-(volume / 10))
if(M.fire_stacks <= 0)
M.ExtinguishMob()
return
remove_self(volume)
return
/datum/reagent/fuel
name = "Welding fuel"
id = "fuel"
description = "Required for welders. Flamable."
reagent_state = LIQUID
color = "#660000" // rgb: 102, 0, 0
overdose = REAGENTS_OVERDOSE
color = "#660000"
glass_icon_state = "dr_gibb_glass"
glass_name = "glass of welder fuel"
glass_desc = "Unless you are an industrial tool, this is probably not safe for consumption."
/datum/reagent/fuel/reaction_obj(var/obj/O, var/volume)
var/turf/the_turf = get_turf(O)
if(!the_turf)
return //No sense trying to start a fire if you don't have a turf to set on fire. --NEO
new /obj/effect/decal/cleanable/liquid_fuel(the_turf, volume)
/datum/reagent/fuel/reaction_turf(var/turf/T, var/volume)
/datum/reagent/fuel/touch_turf(var/turf/T)
new /obj/effect/decal/cleanable/liquid_fuel(T, volume)
remove_self(volume)
return
/datum/reagent/fuel/on_mob_life(var/mob/living/M as mob)
if(!M) M = holder.my_atom
M.adjustToxLoss(1)
..()
return
/datum/reagent/fuel/reaction_mob(var/mob/living/M, var/method=TOUCH, var/volume)//Splashing people with welding fuel to make them easy to ignite!
if(!istype(M, /mob/living))
return
if(method == TOUCH)
M.adjust_fire_stacks(volume / 10)
return
/datum/reagent/fuel/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
M.adjustToxLoss(2 * removed)
/datum/reagent/fuel/affect_touch(var/mob/living/carbon/M, var/alien, var/removed) // Splashing people with welding fuel to make them easy to ignite!
M.adjust_fire_stacks(0.1 * removed)
@@ -3,160 +3,144 @@
id = "aluminum"
description = "A silvery white and ductile member of the boron group of chemical elements."
reagent_state = SOLID
color = "#A8A8A8" // rgb: 168, 168, 168
color = "#A8A8A8"
/datum/reagent/carbon
name = "Carbon"
id = "carbon"
description = "A chemical element, the builing block of life."
reagent_state = SOLID
color = "#1C1300" // rgb: 30, 20, 0
color = "#1C1300"
custom_metabolism = 0.01
/datum/reagent/carbon/reaction_turf(var/turf/T, var/volume)
src = null
/datum/reagent/carbon/touch_turf(var/turf/T)
if(!istype(T, /turf/space))
var/obj/effect/decal/cleanable/dirt/dirtoverlay = locate(/obj/effect/decal/cleanable/dirt, T)
if (!dirtoverlay)
dirtoverlay = new/obj/effect/decal/cleanable/dirt(T)
dirtoverlay.alpha = volume*30
dirtoverlay.alpha = volume * 30
else
dirtoverlay.alpha = min(dirtoverlay.alpha+volume*30, 255)
dirtoverlay.alpha = min(dirtoverlay.alpha + volume * 30, 255)
/datum/reagent/chlorine
name = "Chlorine"
id = "chlorine"
description = "A chemical element with a characteristic odour."
reagent_state = GAS
color = "#808080" // rgb: 128, 128, 128
overdose = REAGENTS_OVERDOSE
color = "#808080"
/datum/reagent/chlorine/on_mob_life(var/mob/living/M as mob)
if(!M) M = holder.my_atom
/datum/reagent/chlorine/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
M.take_organ_damage(1*REM, 0)
/datum/reagent/chlorine/affect_touch(var/mob/living/carbon/M, var/alien, var/removed)
M.take_organ_damage(1*REM, 0)
..()
return
/datum/reagent/copper
name = "Copper"
id = "copper"
description = "A highly ductile metal."
color = "#6E3B08" // rgb: 110, 59, 8
custom_metabolism = 0.01
color = "#6E3B08"
/datum/reagent/ethanol
name = "Ethanol" //Parent class for all alcoholic reagents.
id = "ethanol"
description = "A well-known alcohol with a variety of applications."
reagent_state = LIQUID
nutriment_factor = 0 //So alcohol can fill you up! If they want to.
color = "#404030" // rgb: 64, 64, 48
var/boozepwr = 5 //higher numbers mean the booze will have an effect faster.
var/dizzy_adj = 3
var/adj_drowsy = 0
var/adj_sleepy = 0
var/slurr_adj = 3
var/confused_adj = 2
var/slur_start = 90 //amount absorbed after which mob starts slurring
var/confused_start = 150 //amount absorbed after which mob starts confusing directions
var/blur_start = 300 //amount absorbed after which mob starts getting blurred vision
var/pass_out = 400 //amount absorbed after which mob starts passing out
color = "#404030"
var/nutriment_factor = 0
var/strength = 10 // This is, essentially, units between stages - the lower, the stronger. Less fine tuning, more clarity.
var/toxicity = 1
var/druggy = 0
var/adj_temp = 0
var/targ_temp = 310
var/halluci = 0
glass_icon_state = "glass_clear"
glass_name = "glass of ethanol"
glass_desc = "A well-known alcohol with a variety of applications."
/datum/reagent/ethanol/on_mob_life(var/mob/living/M as mob, var/alien)
M:nutrition += nutriment_factor
holder.remove_reagent(src.id, (alien ? FOOD_METABOLISM : ALCOHOL_METABOLISM)) // Catch-all for creatures without livers.
if (adj_drowsy) M.drowsyness = max(0,M.drowsyness + adj_drowsy)
if (adj_sleepy) M.sleeping = max(0,M.sleeping + adj_sleepy)
if(!src.data || (!isnum(src.data) && src.data.len)) data = 1 //if it doesn't exist we set it. if it's a list we're going to set it to 1 as well. This is to
src.data += boozepwr //avoid a runtime error associated with drinking blood mixed in drinks (demon's blood).
var/d = data
// make all the beverages work together
for(var/datum/reagent/ethanol/A in holder.reagent_list)
if(A != src && isnum(A.data)) d += A.data
if(alien && alien == IS_SKRELL) //Skrell get very drunk very quickly.
d*=5
M.dizziness += dizzy_adj.
if(d >= slur_start && d < pass_out)
if (!M:slurring) M:slurring = 1
M:slurring += slurr_adj
if(d >= confused_start && prob(33))
if (!M:confused) M:confused = 1
M.confused = max(M:confused+confused_adj,0)
if(d >= blur_start)
M.eye_blurry = max(M.eye_blurry, 10)
M:drowsyness = max(M:drowsyness, 0)
if(d >= pass_out)
M:paralysis = max(M:paralysis, 20)
M:drowsyness = max(M:drowsyness, 30)
if(ishuman(M))
var/mob/living/carbon/human/H = M
var/obj/item/organ/liver/L = H.internal_organs_by_name["liver"]
if (!L)
H.adjustToxLoss(5)
else if(istype(L))
L.take_damage(0.1, 1)
H.adjustToxLoss(0.1)
..()
/datum/reagent/ethanol/affect_touch(var/mob/living/carbon/M, var/alien, var/removed)
M.adjust_fire_stacks(removed / 15)
return
/datum/reagent/ethanol/reaction_obj(var/obj/O, var/volume)
if(istype(O,/obj/item/weapon/paper))
/datum/reagent/ethanol/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
M.adjustToxLoss(removed * 2 * toxicity)
return
/datum/reagent/ethanol/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed)
M.nutrition += nutriment_factor * removed
var/strength_mod = 1
if(alien == IS_SKRELL)
strength_mod *= 5
if(alien == IS_DIONA)
strength_mod = 0
M.add_chemical_effect(CE_ALCOHOL, 1)
if(dose / strength_mod >= strength) // Early warning
M.make_dizzy(6) // It is decreased at the speed of 3 per tick
if(dose / strength_mod >= strength * 2) // Slurring
M.slurring = max(M.slurring, 30)
if(dose / strength_mod >= strength * 3) // Confusion - walking in random directions
M.confused = max(M.confused, 20)
if(dose / strength_mod >= strength * 4) // Blurry vision
M.eye_blurry = max(M.eye_blurry, 10)
if(dose / strength_mod >= strength * 5) // Drowsyness - periodically falling asleep
M.drowsyness = max(M.drowsyness, 20)
if(dose / strength_mod >= strength * 6) // Toxic dose
M.add_chemical_effect(CE_ALCOHOL_TOXIC, toxicity)
if(dose / strength_mod >= strength * 7) // Pass out
M.paralysis = max(M.paralysis, 20)
M.sleeping = max(M.sleeping, 30)
if(druggy != 0)
M.druggy = max(M.druggy, druggy)
if(adj_temp > 0 && M.bodytemperature < targ_temp) // 310 is the normal bodytemp. 310.055
M.bodytemperature = min(targ_temp, M.bodytemperature + (adj_temp * TEMPERATURE_DAMAGE_COEFFICIENT))
if(adj_temp < 0 && M.bodytemperature > targ_temp)
M.bodytemperature = min(targ_temp, M.bodytemperature - (adj_temp * TEMPERATURE_DAMAGE_COEFFICIENT))
if(halluci)
M.hallucination = max(M.hallucination, halluci)
/datum/reagent/ethanol/touch_obj(var/obj/O)
if(istype(O, /obj/item/weapon/paper))
var/obj/item/weapon/paper/paperaffected = O
paperaffected.clearpaper()
usr << "The solution dissolves the ink on the paper."
if(istype(O,/obj/item/weapon/book))
if(istype(O,/obj/item/weapon/book/tome))
usr << "The solution does nothing. Whatever this is, it isn't normal ink."
return
if(istype(O, /obj/item/weapon/book))
if(volume < 5)
return
if(volume >= 5)
var/obj/item/weapon/book/affectedbook = O
affectedbook.dat = null
usr << "The solution dissolves the ink on the book."
else
usr << "It wasn't enough..."
if(istype(O, /obj/item/weapon/book/tome))
usr << "<span class='notice'>The solution does nothing. Whatever this is, it isn't normal ink.</span>"
return
var/obj/item/weapon/book/affectedbook = O
affectedbook.dat = null
usr << "<span class='notice'>The solution dissolves the ink on the book.</span>"
return
/datum/reagent/ethanol/reaction_mob(var/mob/living/M, var/method=TOUCH, var/volume)//Splashing people with ethanol isn't quite as good as fuel.
if(!istype(M, /mob/living))
return
if(method == TOUCH)
M.adjust_fire_stacks(volume / 15)
return
/datum/reagent/fluorine
name = "Fluorine"
id = "fluorine"
description = "A highly-reactive chemical element."
reagent_state = GAS
color = "#808080" // rgb: 128, 128, 128
overdose = REAGENTS_OVERDOSE
color = "#808080"
/datum/reagent/fluorine/on_mob_life(var/mob/living/M as mob)
if(!M) M = holder.my_atom
M.adjustToxLoss(1*REM)
..()
return
/datum/reagent/fluorine/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
M.adjustToxLoss(removed)
/datum/reagent/fluorine/affect_touch(var/mob/living/carbon/M, var/alien, var/removed)
M.adjustToxLoss(removed)
/datum/reagent/hydrogen
name = "Hydrogen"
id = "hydrogen"
description = "A colorless, odorless, nonmetallic, tasteless, highly combustible diatomic gas."
reagent_state = GAS
color = "#808080" // rgb: 128, 128, 128
custom_metabolism = 0.01
color = "#808080"
/datum/reagent/iron
name = "Iron"
@@ -164,124 +148,100 @@
description = "Pure iron is a metal."
reagent_state = SOLID
color = "#353535"
overdose = REAGENTS_OVERDOSE
/datum/reagent/iron/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed)
if(alien != IS_DIONA)
M.add_chemical_effect(CE_BLOODRESTORE, 8 * removed)
/datum/reagent/lithium
name = "Lithium"
id = "lithium"
description = "A chemical element, used as antidepressant."
reagent_state = SOLID
color = "#808080" // rgb: 128, 128, 128
overdose = REAGENTS_OVERDOSE
color = "#808080"
/datum/reagent/lithium/on_mob_life(var/mob/living/M as mob)
if(!M) M = holder.my_atom
if(M.canmove && !M.restrained() && istype(M.loc, /turf/space))
step(M, pick(cardinal))
if(prob(5)) M.emote(pick("twitch","drool","moan"))
..()
return
/datum/reagent/lithium/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
if(alien != IS_DIONA)
if(M.canmove && !M.restrained() && istype(M.loc, /turf/space))
step(M, pick(cardinal))
if(prob(5))
M.emote(pick("twitch", "drool", "moan"))
/datum/reagent/mercury
name = "Mercury"
id = "mercury"
description = "A chemical element."
reagent_state = LIQUID
color = "#484848" // rgb: 72, 72, 72
overdose = REAGENTS_OVERDOSE
color = "#484848"
/datum/reagent/mercury/on_mob_life(var/mob/living/M as mob)
if(!M) M = holder.my_atom
if(M.canmove && !M.restrained() && istype(M.loc, /turf/space))
step(M, pick(cardinal))
if(prob(5)) M.emote(pick("twitch","drool","moan"))
M.adjustBrainLoss(2)
..()
return
/datum/reagent/mercury/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
if(alien != IS_DIONA)
if(M.canmove && !M.restrained() && istype(M.loc, /turf/space))
step(M, pick(cardinal))
if(prob(5))
M.emote(pick("twitch", "drool", "moan"))
M.adjustBrainLoss(2)
/datum/reagent/nitrogen
name = "Nitrogen"
id = "nitrogen"
description = "A colorless, odorless, tasteless gas."
reagent_state = GAS
color = "#808080" // rgb: 128, 128, 128
color = "#808080"
custom_metabolism = 0.01
/datum/reagent/nitrogen/on_mob_life(var/mob/living/M as mob, var/alien)
if(M.stat == 2) return
if(alien && alien == IS_VOX)
M.adjustOxyLoss(-2*REM)
holder.remove_reagent(src.id, REAGENTS_METABOLISM) //By default it slowly disappears.
return
..()
/datum/reagent/nitrogen/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
if(alien == IS_VOX)
M.adjustOxyLoss(-removed * 3)
/datum/reagent/oxygen
name = "Oxygen"
id = "oxygen"
description = "A colorless, odorless gas."
reagent_state = GAS
color = "#808080" // rgb: 128, 128, 128
color = "#808080"
custom_metabolism = 0.01
/datum/reagent/oxygen/on_mob_life(var/mob/living/M as mob, var/alien)
if(M.stat == 2) return
if(alien && alien == IS_VOX)
M.adjustToxLoss(REAGENTS_METABOLISM)
holder.remove_reagent(src.id, REAGENTS_METABOLISM) //By default it slowly disappears.
return
..()
/datum/reagent/oxygen/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
if(alien == IS_VOX)
M.adjustToxLoss(removed * 3)
/datum/reagent/phosphorus
name = "Phosphorus"
id = "phosphorus"
description = "A chemical element, the backbone of biological energy carriers."
reagent_state = SOLID
color = "#832828" // rgb: 131, 40, 40
custom_metabolism = 0.01
color = "#832828"
/datum/reagent/potassium
name = "Potassium"
id = "potassium"
description = "A soft, low-melting solid that can easily be cut with a knife. Reacts violently with water."
reagent_state = SOLID
color = "#A0A0A0" // rgb: 160, 160, 160
custom_metabolism = 0.01
color = "#A0A0A0"
/datum/reagent/radium
name = "Radium"
id = "radium"
description = "Radium is an alkaline earth metal. It is extremely radioactive."
reagent_state = SOLID
color = "#C7C7C7" // rgb: 199,199,199
color = "#C7C7C7"
/datum/reagent/radium/on_mob_life(var/mob/living/M as mob)
if(!M) M = holder.my_atom
M.apply_effect(2*REM,IRRADIATE,0)
// radium may increase your chances to cure a disease
if(istype(M,/mob/living/carbon)) // make sure to only use it on carbon mobs
var/mob/living/carbon/C = M
if(C.virus2.len)
for (var/ID in C.virus2)
var/datum/disease2/disease/V = C.virus2[ID]
if(prob(5))
C.antibodies |= V.antigen
if(prob(50))
M.radiation += 50 // curing it that way may kill you instead
var/absorbed
var/obj/item/organ/diona/nutrients/rad_organ = locate() in C.internal_organs
if(rad_organ && !rad_organ.is_broken())
absorbed = 1
if(!absorbed)
M.adjustToxLoss(100)
..()
return
/datum/reagent/radium/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
M.apply_effect(10 * removed, IRRADIATE, 0) // Radium may increase your chances to cure a disease
if(M.virus2.len)
for(var/ID in M.virus2)
var/datum/disease2/disease/V = M.virus2[ID]
if(prob(5))
M.antibodies |= V.antigen
if(prob(50))
M.radiation += 50 // curing it that way may kill you instead
var/absorbed = 0
var/obj/item/organ/diona/nutrients/rad_organ = locate() in M.internal_organs
if(rad_organ && !rad_organ.is_broken())
absorbed = 1
if(!absorbed)
M.adjustToxLoss(100)
/datum/reagent/radium/reaction_turf(var/turf/T, var/volume)
src = null
/datum/reagent/radium/touch_turf(var/turf/T)
if(volume >= 3)
if(!istype(T, /turf/space))
var/obj/effect/decal/cleanable/greenglow/glow = locate(/obj/effect/decal/cleanable/greenglow, T)
@@ -289,117 +249,128 @@
new /obj/effect/decal/cleanable/greenglow(T)
return
/datum/reagent/toxin/acid
/datum/reagent/acid
name = "Sulphuric acid"
id = "sacid"
description = "A very corrosive mineral acid with the molecular formula H2SO4."
reagent_state = LIQUID
color = "#DB5008" // rgb: 219, 80, 8
toxpwr = 1
var/meltprob = 10
color = "#DB5008"
metabolism = REM * 2
touch_met = 50 // It's acid!
var/power = 5
var/meltdose = 10 // How much is needed to melt
/datum/reagent/toxin/acid/on_mob_life(var/mob/living/M as mob)
if(!M) M = holder.my_atom
M.take_organ_damage(0, 1*REM)
..()
return
/datum/reagent/acid/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
M.take_organ_damage(0, removed * power * 2)
/datum/reagent/toxin/acid/reaction_mob(var/mob/living/M, var/method=TOUCH, var/volume)//magic numbers everywhere
if(!istype(M, /mob/living))
/datum/reagent/acid/affect_touch(var/mob/living/carbon/M, var/alien, var/removed) // This is the most interesting
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(H.head)
if(H.head.unacidable)
H << "<span class='danger'>Your [H.head] protects you from the acid.</span>"
remove_self(volume)
return
else if(removed > meltdose)
H << "<span class='danger'>Your [H.head] melts away!</span>"
qdel(H.head)
H.update_inv_head(1)
H.update_hair(1)
removed -= meltdose
if(removed <= 0)
return
if(H.wear_mask)
if(H.wear_mask.unacidable)
H << "<span class='danger'>Your [H.wear_mask] protects you from the acid.</span>"
remove_self(volume)
return
else if(removed > meltdose)
H << "<span class='danger'>Your [H.wear_mask] melts away!</span>"
qdel(H.wear_mask)
H.update_inv_wear_mask(1)
H.update_hair(1)
removed -= meltdose
if(removed <= 0)
return
if(H.glasses)
if(H.glasses.unacidable)
H << "<span class='danger'>Your [H.glasses] partially protect you from the acid!</span>"
removed /= 2
else if(removed > meltdose)
H << "<span class='danger'>Your [H.glasses] melt away!</span>"
qdel(H.glasses)
H.update_inv_glasses(1)
removed -= meltdose / 2
if(removed <= 0)
return
if(volume < meltdose) // Not enough to melt anything
M.take_organ_damage(removed * power * 0.2)
return
if(method == TOUCH)
if(ishuman(M))
if(!M.unacidable && removed > 0)
if(istype(M, /mob/living/carbon/human) && volume >= meltdose)
var/mob/living/carbon/human/H = M
var/obj/item/organ/external/affecting = H.get_organ("head")
if(affecting)
if(affecting.take_damage(0, removed * power * 0.1))
H.UpdateDamageIcon()
if(prob(100 * removed / meltdose)) // Applies disfigurement
if (!(H.species && (H.species.flags & NO_PAIN)))
H.emote("scream")
H.status_flags |= DISFIGURED
else
M.take_organ_damage(0, removed * power * 0.1) // Balance. The damage is instant, so it's weaker. 10 units -> 5 damage, double for pacid. 120 units beaker could deal 60, but a) it's burn, which is not as dangerous, b) it's a one-use weapon, c) missing with it will splash it over the ground and d) clothes give some protection, so not everything will hit
if(H.head)
if(prob(meltprob) && !H.head.unacidable)
H << "<span class='danger'>Your headgear melts away but protects you from the acid!</span>"
qdel(H.head)
H.update_inv_head(0)
H.update_hair(0)
else
H << "<span class='warning'>Your headgear protects you from the acid.</span>"
return
if(H.wear_mask)
if(prob(meltprob) && !H.wear_mask.unacidable)
H << "<span class='danger'>Your mask melts away but protects you from the acid!</span>"
qdel (H.wear_mask)
H.update_inv_wear_mask(0)
H.update_hair(0)
else
H << "<span class='warning'>Your mask protects you from the acid.</span>"
return
if(H.glasses) //Doesn't protect you from the acid but can melt anyways!
if(prob(meltprob) && !H.glasses.unacidable)
H << "<span class='danger'>Your glasses melts away!</span>"
qdel (H.glasses)
H.update_inv_glasses(0)
if(!M.unacidable)
if(istype(M, /mob/living/carbon/human) && volume >= 10)
var/mob/living/carbon/human/H = M
var/obj/item/organ/external/affecting = H.get_organ("head")
if(affecting)
if(affecting.take_damage(4*toxpwr, 2*toxpwr))
H.UpdateDamageIcon()
if(prob(meltprob)) //Applies disfigurement
if (!(H.species && (H.species.flags & NO_PAIN)))
H.emote("scream")
H.status_flags |= DISFIGURED
else
M.take_organ_damage(min(6*toxpwr, volume * toxpwr)) // uses min() and volume to make sure they aren't being sprayed in trace amounts (1 unit != insta rape) -- Doohl
else
if(!M.unacidable)
M.take_organ_damage(min(6*toxpwr, volume * toxpwr))
/datum/reagent/toxin/acid/reaction_obj(var/obj/O, var/volume)
if((istype(O,/obj/item) || istype(O,/obj/effect/plant)) && prob(meltprob * 3))
if(!O.unacidable)
var/obj/effect/decal/cleanable/molten_item/I = new/obj/effect/decal/cleanable/molten_item(O.loc)
I.desc = "Looks like this was \an [O] some time ago."
for(var/mob/M in viewers(5, O))
M << "\red \the [O] melts."
qdel(O)
/datum/reagent/acid/touch_obj(var/obj/O)
if(O.unacidable)
return
if((istype(O, /obj/item) || istype(O, /obj/effect/plant)) && (volume > meltdose))
var/obj/effect/decal/cleanable/molten_item/I = new/obj/effect/decal/cleanable/molten_item(O.loc)
I.desc = "Looks like this was \an [O] some time ago."
for(var/mob/M in viewers(5, O))
M << "<span class='warning'>\The [O] melts.</span>"
qdel(O)
remove_self(meltdose) // 10 units of acid will not melt EVERYTHING on the tile
/datum/reagent/silicon
name = "Silicon"
id = "silicon"
description = "A tetravalent metalloid, silicon is less reactive than its chemical analog carbon."
reagent_state = SOLID
color = "#A8A8A8" // rgb: 168, 168, 168
color = "#A8A8A8"
/datum/reagent/sodium
name = "Sodium"
id = "sodium"
description = "A chemical element, readily reacts with water."
reagent_state = SOLID
color = "#808080" // rgb: 128, 128, 128
custom_metabolism = 0.01
color = "#808080"
/datum/reagent/sugar
name = "Sugar"
id = "sugar"
description = "The organic compound commonly known as table sugar and sometimes called saccharose. This white, odorless, crystalline powder has a pleasing, sweet taste."
reagent_state = SOLID
color = "#FFFFFF" // rgb: 255, 255, 255
color = "#FFFFFF"
glass_icon_state = "iceglass"
glass_name = "glass of sugar"
glass_desc = "The organic compound commonly known as table sugar and sometimes called saccharose. This white, odorless, crystalline powder has a pleasing, sweet taste."
/datum/reagent/sugar/on_mob_life(var/mob/living/M as mob)
M.nutrition += 1*REM
..()
return
/datum/reagent/sugar/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
M.nutrition += removed * 3
/datum/reagent/sulfur
name = "Sulfur"
id = "sulfur"
description = "A chemical element with a pungent smell."
reagent_state = SOLID
color = "#BF8C00" // rgb: 191, 140, 0
color = "#BF8C00"
custom_metabolism = 0.01
/datum/reagent/tungsten
name = "Tungsten"
id = "tungsten"
description = "A chemical element, and a strong oxidising agent."
reagent_state = SOLID
color = "#DCDCDC"
File diff suppressed because it is too large Load Diff
@@ -1,197 +1,154 @@
/* General medicine */
/datum/reagent/inaprovaline
name = "Inaprovaline"
id = "inaprovaline"
description = "Inaprovaline is a synaptic stimulant and cardiostimulant. Commonly used to stabilize patients."
reagent_state = LIQUID
color = "#00BFFF" // rgb: 200, 165, 220
overdose = REAGENTS_OVERDOSE*2
color = "#00BFFF"
overdose = REAGENTS_OVERDOSE * 2
metabolism = REM * 0.5
scannable = 1
/datum/reagent/inaprovaline/on_mob_life(var/mob/living/M as mob, var/alien)
if(!M) M = holder.my_atom
if(alien && alien == IS_VOX)
M.adjustToxLoss(REAGENTS_METABOLISM)
else
if(M.losebreath >= 10)
M.losebreath = max(10, M.losebreath-5)
holder.remove_reagent(src.id, 0.5 * REAGENTS_METABOLISM)
return
/datum/reagent/inaprovaline/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
if(alien != IS_DIONA)
M.add_chemical_effect(CE_STABLE)
M.add_chemical_effect(CE_PAINKILLER, 25)
/datum/reagent/bicaridine
name = "Bicaridine"
id = "bicaridine"
description = "Bicaridine is an analgesic medication and can be used to treat blunt trauma."
reagent_state = LIQUID
color = "#BF0000" // rgb: 200, 165, 220
color = "#BF0000"
overdose = REAGENTS_OVERDOSE
scannable = 1
/datum/reagent/bicaridine/on_mob_life(var/mob/living/M as mob, var/alien)
if(M.stat == 2.0)
return
if(!M) M = holder.my_atom
/datum/reagent/bicaridine/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
if(alien != IS_DIONA)
M.heal_organ_damage(2*REM,0)
..()
return
M.heal_organ_damage(6 * removed, 0)
/datum/reagent/kelotane
name = "Kelotane"
id = "kelotane"
description = "Kelotane is a drug used to treat burns."
reagent_state = LIQUID
color = "#FFA800" // rgb: 200, 165, 220
color = "#FFA800"
overdose = REAGENTS_OVERDOSE
scannable = 1
/datum/reagent/kelotane/on_mob_life(var/mob/living/M as mob)
if(M.stat == 2.0)
return
if(!M) M = holder.my_atom
//This needs a diona check but if one is added they won't be able to heal burn damage at all.
M.heal_organ_damage(0,2*REM)
..()
return
/datum/reagent/kelotane/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
if(alien != IS_DIONA)
M.heal_organ_damage(0, 6 * removed)
/datum/reagent/dermaline
name = "Dermaline"
id = "dermaline"
description = "Dermaline is the next step in burn medication. Works twice as good as kelotane and enables the body to restore even the direst heat-damaged tissue."
reagent_state = LIQUID
color = "#FF8000" // rgb: 200, 165, 220
overdose = REAGENTS_OVERDOSE/2
color = "#FF8000"
overdose = REAGENTS_OVERDOSE * 0.5
scannable = 1
/datum/reagent/dermaline/on_mob_life(var/mob/living/M as mob, var/alien)
if(M.stat == 2.0) //THE GUY IS **DEAD**! BEREFT OF ALL LIFE HE RESTS IN PEACE etc etc. He does NOT metabolise shit anymore, god DAMN
return
if(!M) M = holder.my_atom
if(!alien || alien != IS_DIONA)
M.heal_organ_damage(0,3*REM)
..()
return
/datum/reagent/dermaline/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
if(alien != IS_DIONA)
M.heal_organ_damage(0, 12 * removed)
/datum/reagent/anti_toxin
/datum/reagent/dylovene
name = "Dylovene"
id = "anti_toxin"
description = "Dylovene is a broad-spectrum antitoxin."
reagent_state = LIQUID
color = "#00A000" // rgb: 200, 165, 220
color = "#00A000"
scannable = 1
/datum/reagent/anti_toxin/on_mob_life(var/mob/living/M as mob, var/alien)
if(!M) M = holder.my_atom
if(!alien || alien != IS_DIONA)
M.reagents.remove_all_type(/datum/reagent/toxin, 1*REM, 0, 1)
M.drowsyness = max(M.drowsyness-2*REM, 0)
M.hallucination = max(0, M.hallucination - 5*REM)
M.adjustToxLoss(-2*REM)
..()
return
/datum/reagent/dylovene/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
if(alien != IS_DIONA)
M.drowsyness = max(0, M.drowsyness - 6 * removed)
M.hallucination = max(0, M.hallucination - 9 * removed)
M.adjustToxLoss(-4 * removed)
/datum/reagent/dexalin
name = "Dexalin"
id = "dexalin"
description = "Dexalin is used in the treatment of oxygen deprivation."
reagent_state = LIQUID
color = "#0080FF" // rgb: 200, 165, 220
color = "#0080FF"
overdose = REAGENTS_OVERDOSE
scannable = 1
/datum/reagent/dexalin/on_mob_life(var/mob/living/M as mob, var/alien)
if(M.stat == 2.0)
return //See above, down and around. --Agouri
if(!M) M = holder.my_atom
/datum/reagent/dexalin/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
if(alien == IS_VOX)
M.adjustToxLoss(removed * 6)
else if(alien != IS_DIONA)
M.adjustOxyLoss(-15 * removed)
if(alien && alien == IS_VOX)
M.adjustToxLoss(2*REM)
else if(!alien || alien != IS_DIONA)
M.adjustOxyLoss(-2*REM)
holder.remove_reagent("lexorin", 2*REM)
..()
return
holder.remove_reagent("lexorin", 2 * removed)
/datum/reagent/dexalinp
name = "Dexalin Plus"
id = "dexalinp"
description = "Dexalin Plus is used in the treatment of oxygen deprivation. It is highly effective."
reagent_state = LIQUID
color = "#0040FF" // rgb: 200, 165, 220
overdose = REAGENTS_OVERDOSE/2
color = "#0040FF"
overdose = REAGENTS_OVERDOSE * 0.5
scannable = 1
/datum/reagent/dexalinp/on_mob_life(var/mob/living/M as mob, var/alien)
if(M.stat == 2.0)
return
if(!M) M = holder.my_atom
/datum/reagent/dexalinp/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
if(alien == IS_VOX)
M.adjustToxLoss(removed * 9)
else if(alien != IS_DIONA)
M.adjustOxyLoss(-300 * removed)
if(alien && alien == IS_VOX)
M.adjustOxyLoss()
else if(!alien || alien != IS_DIONA)
M.adjustOxyLoss(-M.getOxyLoss())
holder.remove_reagent("lexorin", 2*REM)
..()
return
holder.remove_reagent("lexorin", 3 * removed)
/datum/reagent/tricordrazine
name = "Tricordrazine"
id = "tricordrazine"
description = "Tricordrazine is a highly potent stimulant, originally derived from cordrazine. Can be used to treat a wide range of injuries."
reagent_state = LIQUID
color = "#8040FF" // rgb: 200, 165, 220
color = "#8040FF"
scannable = 1
/datum/reagent/tricordrazine/on_mob_life(var/mob/living/M as mob, var/alien)
if(M.stat == 2.0)
return
if(!M) M = holder.my_atom
if(!alien || alien != IS_DIONA)
if(M.getOxyLoss()) M.adjustOxyLoss(-1*REM)
if(M.getBruteLoss() && prob(80)) M.heal_organ_damage(1*REM,0)
if(M.getFireLoss() && prob(80)) M.heal_organ_damage(0,1*REM)
if(M.getToxLoss() && prob(80)) M.adjustToxLoss(-1*REM)
..()
return
/datum/reagent/tricordrazine/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
if(alien != IS_DIONA)
M.adjustOxyLoss(-6 * removed)
M.heal_organ_damage(3 * removed, 3 * removed)
M.adjustToxLoss(-3 * removed)
/datum/reagent/cryoxadone
name = "Cryoxadone"
id = "cryoxadone"
description = "A chemical mixture with almost magical healing powers. Its main limitation is that the targets body temperature must be under 170K for it to metabolise correctly."
reagent_state = LIQUID
color = "#8080FF" // rgb: 200, 165, 220
color = "#8080FF"
metabolism = REM * 0.5
scannable = 1
/datum/reagent/cryoxadone/on_mob_life(var/mob/living/M as mob)
if(!M) M = holder.my_atom
/datum/reagent/cryoxadone/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
if(M.bodytemperature < 170)
M.adjustCloneLoss(-1)
M.adjustOxyLoss(-1)
M.heal_organ_damage(1,1)
M.adjustToxLoss(-1)
..()
return
M.adjustCloneLoss(-10 * removed)
M.adjustOxyLoss(-10 * removed)
M.heal_organ_damage(10 * removed, 10 * removed)
M.adjustToxLoss(-10 * removed)
/datum/reagent/clonexadone
name = "Clonexadone"
id = "clonexadone"
description = "A liquid compound similar to that used in the cloning process. Can be used to 'finish' the cloning process when used in conjunction with a cryo tube."
reagent_state = LIQUID
color = "#80BFFF" // rgb: 200, 165, 220
color = "#80BFFF"
metabolism = REM * 0.5
scannable = 1
/datum/reagent/clonexadone/on_mob_life(var/mob/living/M as mob)
if(!M) M = holder.my_atom
/datum/reagent/cryoxadone/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
if(M.bodytemperature < 170)
M.adjustCloneLoss(-3)
M.adjustOxyLoss(-3)
M.heal_organ_damage(3,3)
M.adjustToxLoss(-3)
..()
return
M.adjustCloneLoss(-30 * removed)
M.adjustOxyLoss(-3 * removed)
M.heal_organ_damage(30 * removed, 30 * removed)
M.adjustToxLoss(-30 * removed)
/* Painkillers */
/datum/reagent/paracetamol
name = "Paracetamol"
@@ -201,13 +158,14 @@
color = "#C8A5DC"
overdose = 60
scannable = 1
custom_metabolism = 0.025 // Lasts 10 minutes for 15 units
metabolism = 0.02
/datum/reagent/paracetamol/on_mob_life(var/mob/living/M as mob)
if (volume > overdose)
M.hallucination = max(M.hallucination, 2)
/datum/reagent/paracetamol/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
M.add_chemical_effect(CE_PAINKILLER, 50)
/datum/reagent/paracetamol/overdose(var/mob/living/carbon/M, var/alien)
..()
return
M.hallucination = max(M.hallucination, 2)
/datum/reagent/tramadol
name = "Tramadol"
@@ -217,13 +175,14 @@
color = "#CB68FC"
overdose = 30
scannable = 1
custom_metabolism = 0.025 // Lasts 10 minutes for 15 units
metabolism = 0.02
/datum/reagent/tramadol/on_mob_life(var/mob/living/M as mob)
if (volume > overdose)
M.hallucination = max(M.hallucination, 2)
/datum/reagent/tramadol/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
M.add_chemical_effect(CE_PAINKILLER, 80)
/datum/reagent/tramadol/overdose(var/mob/living/carbon/M, var/alien)
..()
return
M.hallucination = max(M.hallucination, 2)
/datum/reagent/oxycodone
name = "Oxycodone"
@@ -232,106 +191,101 @@
reagent_state = LIQUID
color = "#800080"
overdose = 20
custom_metabolism = 0.25 // Lasts 10 minutes for 15 units
metabolism = 0.02
/datum/reagent/oxycodone/on_mob_life(var/mob/living/M as mob)
if (volume > overdose)
M.druggy = max(M.druggy, 10)
M.hallucination = max(M.hallucination, 3)
/datum/reagent/oxycodone/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
M.add_chemical_effect(CE_PAINKILLER, 200)
/datum/reagent/oxycodone/overdose(var/mob/living/carbon/M, var/alien)
..()
return
M.druggy = max(M.druggy, 10)
M.hallucination = max(M.hallucination, 3)
/* Other medicine */
/datum/reagent/synaptizine
name = "Synaptizine"
id = "synaptizine"
description = "Synaptizine is used to treat various diseases."
reagent_state = LIQUID
color = "#99CCFF" // rgb: 200, 165, 220
custom_metabolism = 0.01
color = "#99CCFF"
metabolism = REM * 0.05
overdose = REAGENTS_OVERDOSE
scannable = 1
/datum/reagent/synaptizine/on_mob_life(var/mob/living/M as mob)
if(!M) M = holder.my_atom
M.drowsyness = max(M.drowsyness-5, 0)
/datum/reagent/synaptizine/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
if(alien == IS_DIONA)
return
M.drowsyness = max(M.drowsyness - 5, 0)
M.AdjustParalysis(-1)
M.AdjustStunned(-1)
M.AdjustWeakened(-1)
holder.remove_reagent("mindbreaker", 5)
M.hallucination = max(0, M.hallucination - 10)
if(prob(60)) M.adjustToxLoss(1)
..()
return
M.adjustToxLoss(5 * removed) // It used to be incredibly deadly due to an oversight. Not anymore!
M.add_chemical_effect(CE_PAINKILLER, 40)
/datum/reagent/alkysine
name = "Alkysine"
id = "alkysine"
description = "Alkysine is a drug used to lessen the damage to neurological tissue after a catastrophic injury. Can heal brain tissue."
reagent_state = LIQUID
color = "#FFFF66" // rgb: 200, 165, 220
custom_metabolism = 0.05
color = "#FFFF66"
metabolism = REM * 0.25
overdose = REAGENTS_OVERDOSE
scannable = 1
/datum/reagent/alkysine/on_mob_life(var/mob/living/M as mob)
if(!M) M = holder.my_atom
M.adjustBrainLoss(-3*REM)
..()
return
/datum/reagent/alkysine/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
if(alien == IS_DIONA)
return
M.adjustBrainLoss(-30 * removed)
M.add_chemical_effect(CE_PAINKILLER, 10)
/datum/reagent/imidazoline
name = "Imidazoline"
id = "imidazoline"
description = "Heals eye damage"
reagent_state = LIQUID
color = "#C8A5DC" // rgb: 200, 165, 220
color = "#C8A5DC"
overdose = REAGENTS_OVERDOSE
scannable = 1
/datum/reagent/imidazoline/on_mob_life(var/mob/living/M as mob)
if(!M) M = holder.my_atom
M.eye_blurry = max(M.eye_blurry-5 , 0)
M.eye_blind = max(M.eye_blind-5 , 0)
/datum/reagent/imidazoline/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
M.eye_blurry = max(M.eye_blurry - 5, 0)
M.eye_blind = max(M.eye_blind - 5, 0)
if(ishuman(M))
var/mob/living/carbon/human/H = M
var/obj/item/organ/eyes/E = H.internal_organs_by_name["eyes"]
if(E && istype(E))
if(E.damage > 0)
E.damage = max(E.damage - 1, 0)
..()
return
E.damage = max(E.damage - 5 * removed, 0)
/datum/reagent/peridaxon
name = "Peridaxon"
id = "peridaxon"
description = "Used to encourage recovery of internal organs and nervous systems. Medicate cautiously."
reagent_state = LIQUID
color = "#561EC3" // rgb: 200, 165, 220
color = "#561EC3"
overdose = 10
scannable = 1
/datum/reagent/peridaxon/on_mob_life(var/mob/living/M as mob)
if(!M) M = holder.my_atom
/datum/reagent/peridaxon/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
if(ishuman(M))
var/mob/living/carbon/human/H = M
//Peridaxon heals only non-robotic organs
for(var/obj/item/organ/I in H.internal_organs)
if((I.damage > 0) && (I.robotic != 2))
I.damage = max(I.damage - 0.20, 0)
..()
return
if((I.damage > 0) && (I.robotic != 2)) //Peridaxon heals only non-robotic organs
I.damage = max(I.damage - removed, 0)
/datum/reagent/ryetalyn
name = "Ryetalyn"
id = "ryetalyn"
description = "Ryetalyn can cure all genetic abnomalities via a catalytic process."
reagent_state = SOLID
color = "#004000" // rgb: 200, 165, 220
color = "#004000"
overdose = REAGENTS_OVERDOSE
/datum/reagent/ryetalyn/on_mob_life(var/mob/living/M as mob)
if(!M) M = holder.my_atom
/datum/reagent/ryetalyn/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
var/needs_update = M.mutations.len > 0
M.mutations = list()
@@ -343,261 +297,197 @@
var/mob/living/carbon/human/H = M
H.update_mutations()
..()
return
/datum/reagent/hyperzine
name = "Hyperzine"
id = "hyperzine"
description = "Hyperzine is a highly effective, long lasting, muscle stimulant."
reagent_state = LIQUID
color = "#FF3300" // rgb: 200, 165, 220
custom_metabolism = 0.03
overdose = REAGENTS_OVERDOSE/2
color = "#FF3300"
metabolism = REM * 0.15
overdose = REAGENTS_OVERDOSE * 0.5
/datum/reagent/hyperzine/on_mob_life(var/mob/living/M as mob)
if(!M) M = holder.my_atom
if(prob(5)) M.emote(pick("twitch","blink_r","shiver"))
..()
return
/datum/reagent/hyperzine/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
if(alien == IS_DIONA)
return
if(prob(5))
M.emote(pick("twitch", "blink_r", "shiver"))
M.add_chemical_effect(CE_SPEEDBOOST, 1)
/datum/reagent/ethylredoxrazine // FUCK YOU, ALCOHOL
/datum/reagent/ethylredoxrazine
name = "Ethylredoxrazine"
id = "ethylredoxrazine"
description = "A powerful oxidizer that reacts with ethanol."
reagent_state = SOLID
color = "#605048" // rgb: 96, 80, 72
color = "#605048"
overdose = REAGENTS_OVERDOSE
/datum/reagent/ethylredoxrazine/on_mob_life(var/mob/living/M as mob)
if(!M) M = holder.my_atom
/datum/reagent/ethylredoxrazine/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
if(alien == IS_DIONA)
return
M.dizziness = 0
M.drowsyness = 0
M.stuttering = 0
M.confused = 0
M.reagents.remove_all_type(/datum/reagent/ethanol, 1*REM, 0, 1)
..()
return
if(M.ingested)
for(var/datum/reagent/R in M.ingested)
if(istype(R, /datum/reagent/ethanol))
R.dose = max(R.dose - removed * 5, 0)
/datum/reagent/hyronalin
name = "Hyronalin"
id = "hyronalin"
description = "Hyronalin is a medicinal drug used to counter the effect of radiation poisoning."
reagent_state = LIQUID
color = "#408000" // rgb: 200, 165, 220
custom_metabolism = 0.05
color = "#408000"
metabolism = REM * 0.25
overdose = REAGENTS_OVERDOSE
scannable = 1
/datum/reagent/hyronalin/on_mob_life(var/mob/living/M as mob)
if(!M) M = holder.my_atom
M.radiation = max(M.radiation-3*REM,0)
..()
return
/datum/reagent/hyronalin/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
M.radiation = max(M.radiation - 30 * removed, 0)
/datum/reagent/arithrazine
name = "Arithrazine"
id = "arithrazine"
description = "Arithrazine is an unstable medication used for the most extreme cases of radiation poisoning."
reagent_state = LIQUID
color = "#008000" // rgb: 200, 165, 220
custom_metabolism = 0.05
color = "#008000"
metabolism = REM * 0.25
overdose = REAGENTS_OVERDOSE
scannable = 1
/datum/reagent/arithrazine/on_mob_life(var/mob/living/M as mob)
if(M.stat == 2.0)
return //See above, down and around. --Agouri
if(!M) M = holder.my_atom
M.radiation = max(M.radiation-7*REM,0)
M.adjustToxLoss(-1*REM)
if(prob(15))
M.take_organ_damage(1, 0)
..()
return
/datum/reagent/arithrazine/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
M.radiation = max(M.radiation - 70 * removed, 0)
M.adjustToxLoss(-10 * removed)
if(prob(60))
M.take_organ_damage(4 * removed, 0)
/datum/reagent/spaceacillin
name = "Spaceacillin"
id = "spaceacillin"
description = "An all-purpose antiviral agent."
reagent_state = LIQUID
color = "#C1C1C1" // rgb: 200, 165, 220
custom_metabolism = 0.01
color = "#C1C1C1"
metabolism = REM * 0.05
overdose = REAGENTS_OVERDOSE
scannable = 1
/datum/reagent/spaceacillin/on_mob_life(var/mob/living/M as mob)
..()
return
/datum/reagent/sterilizine
name = "Sterilizine"
id = "sterilizine"
description = "Sterilizes wounds in preparation for surgery."
reagent_state = LIQUID
color = "#C8A5DC" // rgb: 200, 165, 220
color = "#C8A5DC"
touch_met = 5
//makes you squeaky clean
/datum/reagent/sterilizine/reaction_mob(var/mob/living/M, var/method=TOUCH, var/volume)
if (method == TOUCH)
M.germ_level -= min(volume*20, M.germ_level)
/datum/reagent/sterilizine/affect_touch(var/mob/living/carbon/M, var/alien, var/removed)
M.germ_level -= min(removed*20, M.germ_level)
/datum/reagent/sterilizine/reaction_obj(var/obj/O, var/volume)
/datum/reagent/sterilizine/touch_obj(var/obj/O)
O.germ_level -= min(volume*20, O.germ_level)
/datum/reagent/sterilizine/reaction_turf(var/turf/T, var/volume)
/datum/reagent/sterilizine/touch_turf(var/turf/T)
T.germ_level -= min(volume*20, T.germ_level)
/* reaction_mob(var/mob/living/M, var/method=TOUCH, var/volume)
src = null
if (method==TOUCH)
if(istype(M, /mob/living/carbon/human))
if(M.health >= -100 && M.health <= 0)
M.crit_op_stage = 0.0
if (method==INGEST)
usr << "Well, that was stupid."
M.adjustToxLoss(3)
return
on_mob_life(var/mob/living/M as mob)
if(!M) M = holder.my_atom
M.radiation += 3
..()
return
*/
/datum/reagent/leporazine
name = "Leporazine"
id = "leporazine"
description = "Leporazine can be use to stabilize an individuals body temperature."
reagent_state = LIQUID
color = "#C8A5DC" // rgb: 200, 165, 220
color = "#C8A5DC"
overdose = REAGENTS_OVERDOSE
scannable = 1
/datum/reagent/leporazine/on_mob_life(var/mob/living/M as mob)
if(!M) M = holder.my_atom
/datum/reagent/leporazine/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
if(M.bodytemperature > 310)
M.bodytemperature = max(310, M.bodytemperature - (40 * TEMPERATURE_DAMAGE_COEFFICIENT))
else if(M.bodytemperature < 311)
M.bodytemperature = min(310, M.bodytemperature + (40 * TEMPERATURE_DAMAGE_COEFFICIENT))
..()
return
/* Antidepressants */
#define ANTIDEPRESSANT_MESSAGE_DELAY 5*60*10
/datum/reagent/antidepressant/methylphenidate
/datum/reagent/methylphenidate
name = "Methylphenidate"
id = "methylphenidate"
description = "Improves the ability to concentrate."
reagent_state = LIQUID
color = "#BF80BF"
custom_metabolism = 0.01
metabolism = 0.01
data = 0
on_mob_life(var/mob/living/M as mob)
if(!M) M = holder.my_atom
if(src.volume <= 0.1) if(data != -1)
data = -1
M << "\red You lose focus.."
else
if(world.time > data + ANTIDEPRESSANT_MESSAGE_DELAY)
data = world.time
M << "\blue Your mind feels focused and undivided."
..()
/datum/reagent/methylphenidate/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
if(alien == IS_DIONA)
return
if(volume <= 0.1 && data != -1)
data = -1
M << "<span class='warning'>You lose focus...</span>"
else
if(world.time > data + ANTIDEPRESSANT_MESSAGE_DELAY)
data = world.time
M << "<span class='notice'>Your mind feels focused and undivided.</span>"
/datum/chemical_reaction/methylphenidate
name = "Methylphenidate"
id = "methylphenidate"
result = "methylphenidate"
required_reagents = list("mindbreaker" = 1, "hydrogen" = 1)
result_amount = 3
/datum/reagent/antidepressant/citalopram
/datum/reagent/citalopram
name = "Citalopram"
id = "citalopram"
description = "Stabilizes the mind a little."
reagent_state = LIQUID
color = "#FF80FF"
custom_metabolism = 0.01
metabolism = 0.01
data = 0
on_mob_life(var/mob/living/M as mob)
if(!M) M = holder.my_atom
if(src.volume <= 0.1) if(data != -1)
data = -1
M << "\red Your mind feels a little less stable.."
else
if(world.time > data + ANTIDEPRESSANT_MESSAGE_DELAY)
data = world.time
M << "\blue Your mind feels stable.. a little stable."
..()
/datum/reagent/citalopram/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
if(alien == IS_DIONA)
return
if(volume <= 0.1 && data != -1)
data = -1
M << "<span class='warning'>Your mind feels a little less stable...</span>"
else
if(world.time > data + ANTIDEPRESSANT_MESSAGE_DELAY)
data = world.time
M << "<span class='notice'>Your mind feels stable... a little stable.</span>"
/datum/chemical_reaction/citalopram
name = "Citalopram"
id = "citalopram"
result = "citalopram"
required_reagents = list("mindbreaker" = 1, "carbon" = 1)
result_amount = 3
/datum/reagent/antidepressant/paroxetine
/datum/reagent/paroxetine
name = "Paroxetine"
id = "paroxetine"
description = "Stabilizes the mind greatly, but has a chance of adverse effects."
reagent_state = LIQUID
color = "#FF80BF"
custom_metabolism = 0.01
metabolism = 0.01
data = 0
on_mob_life(var/mob/living/M as mob)
if(!M) M = holder.my_atom
if(src.volume <= 0.1) if(data != -1)
data = -1
M << "\red Your mind feels much less stable.."
else
if(world.time > data + ANTIDEPRESSANT_MESSAGE_DELAY)
data = world.time
if(prob(90))
M << "\blue Your mind feels much more stable."
else
M << "\red Your mind breaks apart.."
M.hallucination += 200
..()
/datum/reagent/paroxetine/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
if(alien == IS_DIONA)
return
/datum/chemical_reaction/paroxetine
name = "Paroxetine"
id = "paroxetine"
result = "paroxetine"
required_reagents = list("mindbreaker" = 1, "oxygen" = 1, "inaprovaline" = 1)
result_amount = 3
if(volume <= 0.1 && data != -1)
data = -1
M << "<span class='warning'>Your mind feels much less stable...</span>"
else
if(world.time > data + ANTIDEPRESSANT_MESSAGE_DELAY)
data = world.time
if(prob(90))
M << "<span class='notice'>Your mind feels much more stable.</span>"
else
M << "<span class='warning'>Your mind breaks apart...</span>"
M.hallucination += 200
/datum/reagent/rezadone
name = "Rezadone"
id = "rezadone"
description = "A powder derived from fish toxin, this substance can effectively treat genetic damage in humanoids, though excessive consumption has side effects."
description = "A powder with almost magical properties, this substance can effectively treat genetic damage in humanoids, though excessive consumption has side effects."
reagent_state = SOLID
color = "#669900" // rgb: 102, 153, 0
color = "#669900"
overdose = REAGENTS_OVERDOSE
scannable = 1
/datum/reagent/rezadone/on_mob_life(var/mob/living/M as mob)
if(!M) M = holder.my_atom
if(!data) data = 1
data++
switch(data)
if(1 to 15)
M.adjustCloneLoss(-1)
M.heal_organ_damage(1,1)
if(15 to 35)
M.adjustCloneLoss(-2)
M.heal_organ_damage(2,1)
M.status_flags &= ~DISFIGURED
if(35 to INFINITY)
M.adjustToxLoss(1)
M.make_dizzy(5)
M.make_jittery(5)
..()
return
/datum/reagent/rezadone/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
M.adjustCloneLoss(-20 * removed)
M.adjustOxyLoss(-2 * removed)
M.heal_organ_damage(20 * removed, 20 * removed)
M.adjustToxLoss(-20 * removed)
if(dose > 3)
M.status_flags &= ~DISFIGURED
if(dose > 10)
M.make_dizzy(5)
M.make_jittery(5)
@@ -1,3 +1,5 @@
/* Paint and crayons */
/datum/reagent/crayon_dust
name = "Crayon dust"
id = "crayon_dust"
@@ -52,32 +54,32 @@
description = "This paint will stick to almost any object."
reagent_state = LIQUID
color = "#808080"
overdose = 15
overdose = REAGENTS_OVERDOSE * 0.5
color_weight = 20
/datum/reagent/paint/New()
..()
data = color
/datum/reagent/paint/reaction_turf(var/turf/T, var/volume)
..()
/datum/reagent/paint/touch_turf(var/turf/T)
if(istype(T) && !istype(T, /turf/space))
T.color = color
/datum/reagent/paint/reaction_obj(var/obj/O, var/volume)
..()
if(istype(O,/obj))
/datum/reagent/paint/touch_obj(var/obj/O)
if(istype(O))
O.color = color
/datum/reagent/paint/reaction_mob(var/mob/M, var/method=TOUCH, var/volume)
..()
if(istype(M,/mob) && !istype(M,/mob/dead))
//painting ghosts: not allowed
/datum/reagent/paint/touch_mob(var/mob/M)
if(istype(M) && !istype(M, /mob/dead)) //painting ghosts: not allowed
M.color = color
/datum/reagent/paint/on_merge(var/newdata, var/newamount)
if(!data || !newdata)
return
/datum/reagent/paint/affect_touch(var/mob/living/carbon/M, var/alien, var/removed)
M.color = color
/datum/reagent/paint/get_data()
return color
/datum/reagent/paint/initialize_data(var/newdata)
color = newdata
return
/datum/reagent/paint/mix_data(var/newdata, var/newamount)
var/list/colors = list(0, 0, 0, 0)
var/tot_w = 0
@@ -101,23 +103,26 @@
tot_w += newamount
color = rgb(colors[1] / tot_w, colors[2] / tot_w, colors[3] / tot_w, colors[4] / tot_w)
data = color
return
/* Things that didn't fit anywhere else */
/datum/reagent/adminordrazine //An OP chemical for admins
name = "Adminordrazine"
id = "adminordrazine"
description = "It's magic. We don't have to explain it."
reagent_state = LIQUID
color = "#C8A5DC" // rgb: 200, 165, 220
color = "#C8A5DC"
affects_dead = 1 //This can even heal dead people.
glass_icon_state = "golden_cup"
glass_name = "golden cup"
glass_desc = "It's magic. We don't have to explain it."
/datum/reagent/adminordrazine/on_mob_life(var/mob/living/carbon/M as mob)
if(!M) M = holder.my_atom ///This can even heal dead people.
M.reagents.remove_all_type(/datum/reagent/toxin, 5*REM, 0, 1)
/datum/reagent/adminordrazine/affect_touch(var/mob/living/carbon/M, var/alien, var/removed)
affect_blood(M, alien, removed)
/datum/reagent/adminordrazine/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
M.setCloneLoss(0)
M.setOxyLoss(0)
M.radiation = 0
@@ -144,38 +149,35 @@
D.stage--
if(D.stage < 1)
D.cure()
..()
return
/datum/reagent/gold
name = "Gold"
id = "gold"
description = "Gold is a dense, soft, shiny metal and the most malleable and ductile metal known."
reagent_state = SOLID
color = "#F7C430" // rgb: 247, 196, 48
color = "#F7C430"
/datum/reagent/silver
name = "Silver"
id = "silver"
description = "A soft, white, lustrous transition metal, it has the highest electrical conductivity of any element and the highest thermal conductivity of any metal."
reagent_state = SOLID
color = "#D0D0D0" // rgb: 208, 208, 208
color = "#D0D0D0"
/datum/reagent/uranium
name ="Uranium"
id = "uranium"
description = "A silvery-white metallic chemical element in the actinide series, weakly radioactive."
reagent_state = SOLID
color = "#B8B8C0" // rgb: 184, 184, 192
color = "#B8B8C0"
/datum/reagent/uranium/on_mob_life(var/mob/living/M as mob)
if(!M) M = holder.my_atom
M.apply_effect(1,IRRADIATE,0)
..()
return
/datum/reagent/uranium/affect_touch(var/mob/living/carbon/M, var/alien, var/removed)
affect_ingest(M, alien, removed)
/datum/reagent/uranium/reaction_turf(var/turf/T, var/volume)
src = null
/datum/reagent/uranium/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
M.apply_effect(5 * removed, IRRADIATE, 0)
/datum/reagent/uranium/touch_turf(var/turf/T)
if(volume >= 3)
if(!istype(T, /turf/space))
var/obj/effect/decal/cleanable/greenglow/glow = locate(/obj/effect/decal/cleanable/greenglow, T)
@@ -188,35 +190,32 @@
id = "adrenaline"
description = "Adrenaline is a hormone used as a drug to treat cardiac arrest and other cardiac dysrhythmias resulting in diminished or absent cardiac output."
reagent_state = LIQUID
color = "#C8A5DC" // rgb: 200, 165, 220
color = "#C8A5DC"
/datum/reagent/adrenaline/on_mob_life(var/mob/living/M as mob)
if(!M) M = holder.my_atom
/datum/reagent/adrenaline/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
if(alien == IS_DIONA)
return
M.SetParalysis(0)
M.SetWeakened(0)
M.adjustToxLoss(rand(3))
..()
return
/datum/reagent/water/holywater
name = "Holy Water"
id = "holywater"
description = "An ashen-obsidian-water mix, this solution will alter certain sections of the brain's rationality."
color = "#E0E8EF" // rgb: 224, 232, 239
color = "#E0E8EF"
glass_icon_state = "glass_clear"
glass_name = "glass of holy water"
glass_desc = "An ashen-obsidian-water mix, this solution will alter certain sections of the brain's rationality."
/datum/reagent/water/holywater/on_mob_life(var/mob/living/M as mob)
if(ishuman(M))
/datum/reagent/water/holywater/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed)
..()
if(ishuman(M)) // Any location
if(M.mind && cult.is_antagonist(M.mind) && prob(10))
cult.remove_antagonist(M.mind)
holder.remove_reagent(src.id, 10 * REAGENTS_METABOLISM) //high metabolism to prevent extended uncult rolls.
return
/datum/reagent/water/holywater/reaction_turf(var/turf/T, var/volume)
src = null
/datum/reagent/water/holywater/touch_turf(var/turf/T)
if(volume >= 5)
T.holy = 1
return
@@ -226,142 +225,138 @@
id = "ammonia"
description = "A caustic substance commonly used in fertilizer or household cleaners."
reagent_state = GAS
color = "#404030" // rgb: 64, 64, 48
color = "#404030"
/datum/reagent/diethylamine
name = "Diethylamine"
id = "diethylamine"
description = "A secondary amine, mildly corrosive."
reagent_state = LIQUID
color = "#604030" // rgb: 96, 64, 48
color = "#604030"
/datum/reagent/fluorosurfactant//foam precursor
/datum/reagent/fluorosurfactant // Foam precursor
name = "Fluorosurfactant"
id = "fluorosurfactant"
description = "A perfluoronated sulfonic acid that forms a foam when mixed with water."
reagent_state = LIQUID
color = "#9E6B38" // rgb: 158, 107, 56
color = "#9E6B38"
/datum/reagent/foaming_agent// Metal foaming agent. This is lithium hydride. Add other recipes (e.g. LiH + H2O -> LiOH + H2) eventually.
/datum/reagent/foaming_agent // Metal foaming agent. This is lithium hydride. Add other recipes (e.g. LiH + H2O -> LiOH + H2) eventually.
name = "Foaming agent"
id = "foaming_agent"
description = "A agent that yields metallic foam when mixed with light metal and a strong acid."
reagent_state = SOLID
color = "#664B63" // rgb: 102, 75, 99
color = "#664B63"
/datum/reagent/thermite
name = "Thermite"
id = "thermite"
description = "Thermite produces an aluminothermic reaction known as a thermite reaction. Can be used to melt walls."
reagent_state = SOLID
color = "#673910" // rgb: 103, 57, 16
color = "#673910"
touch_met = 50
/datum/reagent/thermite/reaction_turf(var/turf/T, var/volume)
src = null
/datum/reagent/thermite/touch_turf(var/turf/T)
if(volume >= 5)
if(istype(T, /turf/simulated/wall))
var/turf/simulated/wall/W = T
W.thermite = 1
W.overlays += image('icons/effects/effects.dmi',icon_state = "#673910")
remove_self(5)
return
/datum/reagent/thermite/on_mob_life(var/mob/living/M as mob)
if(!M) M = holder.my_atom
M.adjustFireLoss(1)
..()
/datum/reagent/thermite/affect_touch(var/mob/living/carbon/M, var/alien, var/removed)
M.adjust_fire_stacks(removed * 0.2)
return
/datum/reagent/thermite/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
M.adjustFireLoss(3 * removed)
/datum/reagent/space_cleaner
name = "Space cleaner"
id = "cleaner"
description = "A compound used to clean things. Now with 50% more sodium hypochlorite!"
reagent_state = LIQUID
color = "#A5F0EE" // rgb: 165, 240, 238
overdose = REAGENTS_OVERDOSE
color = "#A5F0EE"
touch_met = 50
/datum/reagent/space_cleaner/reaction_obj(var/obj/O, var/volume)
if(istype(O,/obj/effect/decal/cleanable))
/datum/reagent/space_cleaner/touch_obj(var/obj/O)
if(istype(O, /obj/effect/decal/cleanable))
qdel(O)
else
if(O)
O.clean_blood()
O.clean_blood()
/datum/reagent/space_cleaner/reaction_turf(var/turf/T, var/volume)
/datum/reagent/space_cleaner/touch_turf(var/turf/T)
if(volume >= 1)
if(istype(T, /turf/simulated))
var/turf/simulated/S = T
S.dirt = 0
T.clean_blood()
for(var/obj/effect/decal/cleanable/C in T.contents)
src.reaction_obj(C, volume)
qdel(C)
for(var/mob/living/carbon/slime/M in T)
M.adjustToxLoss(rand(5,10))
M.adjustToxLoss(rand(5, 10))
/datum/reagent/space_cleaner/reaction_mob(var/mob/M, var/method=TOUCH, var/volume)
if(iscarbon(M))
var/mob/living/carbon/C = M
if(C.r_hand)
C.r_hand.clean_blood()
if(C.l_hand)
C.l_hand.clean_blood()
if(C.wear_mask)
if(C.wear_mask.clean_blood())
C.update_inv_wear_mask(0)
if(ishuman(M))
var/mob/living/carbon/human/H = C
if(H.head)
if(H.head.clean_blood())
H.update_inv_head(0)
if(H.wear_suit)
if(H.wear_suit.clean_blood())
H.update_inv_wear_suit(0)
else if(H.w_uniform)
if(H.w_uniform.clean_blood())
H.update_inv_w_uniform(0)
if(H.shoes)
if(H.shoes.clean_blood())
H.update_inv_shoes(0)
else
H.clean_blood(1)
return
M.clean_blood()
/datum/reagent/space_cleaner/affect_touch(var/mob/living/carbon/M, var/alien, var/removed)
if(M.r_hand)
M.r_hand.clean_blood()
if(M.l_hand)
M.l_hand.clean_blood()
if(M.wear_mask)
if(M.wear_mask.clean_blood())
M.update_inv_wear_mask(0)
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(H.head)
if(H.head.clean_blood())
H.update_inv_head(0)
if(H.wear_suit)
if(H.wear_suit.clean_blood())
H.update_inv_wear_suit(0)
else if(H.w_uniform)
if(H.w_uniform.clean_blood())
H.update_inv_w_uniform(0)
if(H.shoes)
if(H.shoes.clean_blood())
H.update_inv_shoes(0)
else
H.clean_blood(1)
return
M.clean_blood()
/datum/reagent/lube
/datum/reagent/lube // TODO: spraying on borgs speeds them up
name = "Space Lube"
id = "lube"
description = "Lubricant is a substance introduced between two moving surfaces to reduce the friction and wear between them. giggity."
reagent_state = LIQUID
color = "#009CA8" // rgb: 0, 156, 168
overdose = REAGENTS_OVERDOSE
color = "#009CA8"
/datum/reagent/lube/reaction_turf(var/turf/simulated/T, var/volume)
if (!istype(T)) return
src = null
/datum/reagent/lube/touch_turf(var/turf/simulated/T)
if(!istype(T))
return
if(volume >= 1)
if(T.wet >= 2) return
if(T.wet >= 2)
return
T.wet = 2
spawn(800)
if (!istype(T)) return
if(!T || !istype(T))
return
T.wet = 0
if(T.wet_overlay)
T.overlays -= T.wet_overlay
T.wet_overlay = null
return
/datum/reagent/silicate
name = "Silicate"
id = "silicate"
description = "A compound that can be used to reinforce glass."
reagent_state = LIQUID
color = "#C7FFFF" // rgb: 199, 255, 255
color = "#C7FFFF"
/datum/reagent/silicate/reaction_obj(var/obj/O, var/volume)
src = null
if(istype(O,/obj/structure/window))
/datum/reagent/silicate/touch_obj(var/obj/O)
if(istype(O, /obj/structure/window))
var/obj/structure/window/W = O
W.apply_silicate(volume)
remove_self(volume)
return
/datum/reagent/glycerol
@@ -369,21 +364,24 @@
id = "glycerol"
description = "Glycerol is a simple polyol compound. Glycerol is sweet-tasting and of low toxicity."
reagent_state = LIQUID
color = "#808080" // rgb: 128, 128, 128
custom_metabolism = 0.01
color = "#808080"
/datum/reagent/nitroglycerin
name = "Nitroglycerin"
id = "nitroglycerin"
description = "Nitroglycerin is a heavy, colorless, oily, explosive liquid obtained by nitrating glycerol."
reagent_state = LIQUID
color = "#808080" // rgb: 128, 128, 128
color = "#808080"
custom_metabolism = 0.01
/datum/reagent/coolant
name = "Coolant"
id = "coolant"
description = "Industrial cooling substance."
reagent_state = LIQUID
color = "#C8A5DC"
/datum/reagent/ultraglue
name = "Ultra Glue"
id = "glue"
description = "An extremely powerful bonding agent."
color = "#FFFFCC" // rgb: 255, 255, 204
color = "#FFFFCC"
@@ -1,49 +1,41 @@
/* Toxins, poisons, venoms */
/datum/reagent/toxin
name = "Toxin"
id = "toxin"
description = "A toxic chemical."
reagent_state = LIQUID
color = "#CF3600" // rgb: 207, 54, 0
var/toxpwr = 0.7 // Toxins are really weak, but without being treated, last very long.
custom_metabolism = 0.1
color = "#CF3600"
metabolism = REM * 0.05 // 0.01 by default. They last a while and slowly kill you.
var/strength = 4 // How much damage it deals per unit
/datum/reagent/toxin/on_mob_life(var/mob/living/M as mob,var/alien)
if(!M) M = holder.my_atom
if(toxpwr)
M.adjustToxLoss(toxpwr*REM)
if(alien) ..() // Kind of a catch-all for aliens without the liver. Because this does not metabolize 'naturally', only removed by the liver.
return
/datum/reagent/toxin/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
if(strength && alien != IS_DIONA)
M.adjustToxLoss(strength * removed)
/datum/reagent/plasticide
/datum/reagent/toxin/plasticide
name = "Plasticide"
id = "plasticide"
description = "Liquid plastic, do not eat."
reagent_state = LIQUID
color = "#CF3600" // rgb: 207, 54, 0
custom_metabolism = 0.01
/datum/reagent/plasticide/on_mob_life(var/mob/living/M as mob)
if(!M) M = holder.my_atom
// Toxins are really weak, but without being treated, last very long.
M.adjustToxLoss(0.2)
..()
return
color = "#CF3600"
strength = 5
/datum/reagent/toxin/amatoxin
name = "Amatoxin"
id = "amatoxin"
description = "A powerful poison derived from certain species of mushroom."
reagent_state = LIQUID
color = "#792300" // rgb: 121, 35, 0
toxpwr = 1
color = "#792300"
strength = 10
/datum/reagent/toxin/carpotoxin
name = "Carpotoxin"
id = "carpotoxin"
description = "A deadly neurotoxin produced by the dreaded space carp."
reagent_state = LIQUID
color = "#003333" // rgb: 0, 51, 51
toxpwr = 2
color = "#003333"
strength = 10
/datum/reagent/toxin/phoron
name = "Phoron"
@@ -51,82 +43,62 @@
description = "Phoron in its liquid form."
reagent_state = LIQUID
color = "#9D14DB"
toxpwr = 3
strength = 30
/datum/reagent/toxin/phoron/on_mob_life(var/mob/living/M as mob)
if(!M) M = holder.my_atom
holder.remove_reagent("inaprovaline", 2*REM)
/datum/reagent/toxin/phoron/affect_touch(var/mob/living/carbon/M, var/alien, var/removed)
..()
return
M.adjust_fire_stacks(removed / 5)
/datum/reagent/toxin/phoron/reaction_obj(var/obj/O, var/volume)
src = null
/*if(istype(O,/obj/item/weapon/reagent_containers/food/snacks/egg/slime))
var/obj/item/weapon/reagent_containers/food/snacks/egg/slime/egg = O
if (egg.grown)
egg.Hatch()*/
if((!O) || (!volume)) return 0
var/turf/the_turf = get_turf(O)
the_turf.assume_gas("volatile_fuel", volume, T20C)
/datum/reagent/toxin/phoron/reaction_turf(var/turf/T, var/volume)
src = null
/datum/reagent/toxin/phoron/touch_turf(var/turf/simulated/T)
if(!istype(T))
return
T.assume_gas("volatile_fuel", volume, T20C)
return
/datum/reagent/toxin/phoron/reaction_mob(var/mob/living/M, var/method=TOUCH, var/volume)//Splashing people with plasma is stronger than fuel!
if(!istype(M, /mob/living))
return
if(method == TOUCH)
M.adjust_fire_stacks(volume / 5)
return
remove_self(volume)
/datum/reagent/toxin/cyanide //Fast and Lethal
name = "Cyanide"
id = "cyanide"
description = "A highly toxic chemical."
reagent_state = LIQUID
color = "#CF3600" // rgb: 207, 54, 0
toxpwr = 4
custom_metabolism = 0.4
color = "#CF3600"
strength = 20
metabolism = REM * 2
/datum/reagent/toxin/cyanide/on_mob_life(var/mob/living/M as mob)
if(!M) M = holder.my_atom
M.adjustOxyLoss(4*REM)
M.sleeping += 1
/datum/reagent/toxin/cyanide/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
..()
return
M.adjustOxyLoss(20 * removed)
M.sleeping += 1
/datum/reagent/toxin/potassium_chloride
name = "Potassium Chloride"
id = "potassium_chloride"
description = "A delicious salt that stops the heart when injected into cardiac muscle."
reagent_state = SOLID
color = "#FFFFFF" // rgb: 255,255,255
toxpwr = 0
overdose = 30
color = "#FFFFFF"
strength = 0
overdose = REAGENTS_OVERDOSE
/datum/reagent/toxin/potassium_chloride/on_mob_life(var/mob/living/carbon/M as mob)
var/mob/living/carbon/human/H = M
if(H.stat != 1)
if (volume >= overdose)
/datum/reagent/toxin/potassium_chloride/overdose(var/mob/living/carbon/M, var/alien)
..()
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(H.stat != 1)
if(H.losebreath >= 10)
H.losebreath = max(10, H.losebreath-10)
H.losebreath = max(10, H.losebreath - 10)
H.adjustOxyLoss(2)
H.Weaken(10)
..()
return
/datum/reagent/toxin/potassium_chlorophoride
name = "Potassium Chlorophoride"
id = "potassium_chlorophoride"
description = "A specific chemical based on Potassium Chloride to stop the heart for surgery. Not safe to eat!"
reagent_state = SOLID
color = "#FFFFFF" // rgb: 255,255,255
toxpwr = 2
color = "#FFFFFF"
strength = 10
overdose = 20
/datum/reagent/toxin/potassium_chlorophoride/on_mob_life(var/mob/living/carbon/M as mob)
/datum/reagent/toxin/potassium_chlorophoride/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
..()
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(H.stat != 1)
@@ -134,41 +106,39 @@
H.losebreath = max(10, M.losebreath-10)
H.adjustOxyLoss(2)
H.Weaken(10)
..()
return
/datum/reagent/toxin/zombiepowder
name = "Zombie Powder"
id = "zombiepowder"
description = "A strong neurotoxin that puts the subject into a death-like state."
reagent_state = SOLID
color = "#669900" // rgb: 102, 153, 0
toxpwr = 0.5
color = "#669900"
metabolism = REM
strength = 3
/datum/reagent/toxin/zombiepowder/on_mob_life(var/mob/living/carbon/M as mob)
if(!M) M = holder.my_atom
/datum/reagent/toxin/zombiepowder/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
..()
if(alien == IS_DIONA)
return
M.status_flags |= FAKEDEATH
M.adjustOxyLoss(0.5*REM)
M.adjustOxyLoss(3 * removed)
M.Weaken(10)
M.silent = max(M.silent, 10)
M.tod = worldtime2text()
..()
return
/datum/reagent/toxin/zombiepowder/Destroy()
if(holder && ismob(holder.my_atom))
if(holder && holder.my_atom && ismob(holder.my_atom))
var/mob/M = holder.my_atom
M.status_flags &= ~FAKEDEATH
..()
//Reagents used for plant fertilizers.
/datum/reagent/toxin/fertilizer
/datum/reagent/toxin/fertilizer //Reagents used for plant fertilizers.
name = "fertilizer"
id = "fertilizer"
description = "A chemical mix good for growing plants with."
reagent_state = LIQUID
toxpwr = 0.2 //It's not THAT poisonous.
color = "#664330" // rgb: 102, 67, 48
strength = 0.5 // It's not THAT poisonous.
color = "#664330"
/datum/reagent/toxin/fertilizer/eznutrient
name = "EZ Nutrient"
@@ -187,11 +157,10 @@
id = "plantbgone"
description = "A harmful toxic mixture to kill plantlife. Do not ingest!"
reagent_state = LIQUID
color = "#49002E" // rgb: 73, 0, 46
toxpwr = 1
color = "#49002E"
strength = 4
// Clear off wallrot fungi
/datum/reagent/toxin/plantbgone/reaction_turf(var/turf/T, var/volume)
/datum/reagent/toxin/plantbgone/touch_turf(var/turf/T)
if(istype(T, /turf/simulated/wall))
var/turf/simulated/wall/W = T
if(locate(/obj/effect/overlay/wallrot) in W)
@@ -199,228 +168,186 @@
qdel(E)
W.visible_message("<span class='notice'>The fungi are completely dissolved by the solution!")
/datum/reagent/toxin/plantbgone/reaction_obj(var/obj/O, var/volume)
if(istype(O,/obj/effect/alien/weeds/))
/datum/reagent/toxin/plantbgone/touch_obj(var/obj/O, var/volume)
if(istype(O, /obj/effect/alien/weeds/))
var/obj/effect/alien/weeds/alien_weeds = O
alien_weeds.health -= rand(15,35) // Kills alien weeds pretty fast
alien_weeds.health -= rand(15, 35)
alien_weeds.healthcheck()
else if(istype(O,/obj/effect/plant))
var/obj/effect/plant/plant = O
plant.die_off()
else if(istype(O,/obj/machinery/portable_atmospherics/hydroponics))
var/obj/machinery/portable_atmospherics/hydroponics/tray = O
else if(istype(O, /obj/effect/plant))
qdel(O)
if(tray.seed)
tray.health -= rand(30,50)
if(tray.pestlevel > 0)
tray.pestlevel -= 2
if(tray.weedlevel > 0)
tray.weedlevel -= 3
tray.toxins += 4
tray.check_level_sanity()
tray.update_icon()
/datum/reagent/toxin/plantbgone/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
..()
if(alien == IS_DIONA)
M.adjustToxLoss(50 * removed)
/datum/reagent/toxin/plantbgone/reaction_mob(var/mob/living/M, var/method=TOUCH, var/volume)
src = null
if(iscarbon(M))
var/mob/living/carbon/C = M
if(!C.wear_mask) // If not wearing a mask
C.adjustToxLoss(2) // 4 toxic damage per application, doubled for some reason
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(H.dna)
if(H.species.flags & IS_PLANT) //plantmen take a LOT of damage
H.adjustToxLoss(50)
/datum/reagent/toxin/plantbgone/affect_touch(var/mob/living/carbon/M, var/alien, var/removed)
..()
if(alien == IS_DIONA)
M.adjustToxLoss(50 * removed)
/datum/reagent/toxin/acid/polyacid
/datum/reagent/acid/polyacid
name = "Polytrinic acid"
id = "pacid"
description = "Polytrinic acid is a an extremely corrosive chemical substance."
reagent_state = LIQUID
color = "#8E18A9" // rgb: 142, 24, 169
toxpwr = 2
meltprob = 30
color = "#8E18A9"
power = 10
meltdose = 4
/datum/reagent/toxin/lexorin
/datum/reagent/lexorin
name = "Lexorin"
id = "lexorin"
description = "Lexorin temporarily stops respiration. Causes tissue damage."
reagent_state = LIQUID
color = "#C8A5DC" // rgb: 200, 165, 220
toxpwr = 0
color = "#C8A5DC"
overdose = REAGENTS_OVERDOSE
/datum/reagent/toxin/lexorin/on_mob_life(var/mob/living/M as mob)
if(M.stat == 2.0)
/datum/reagent/lexorin/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
if(alien == IS_DIONA)
return
if(!M) M = holder.my_atom
if(prob(33))
M.take_organ_damage(1*REM, 0)
M.take_organ_damage(3 * removed, 0)
if(M.losebreath < 15)
M.losebreath++
..()
return
/datum/reagent/toxin/mutagen
/datum/reagent/mutagen
name = "Unstable mutagen"
id = "mutagen"
description = "Might cause unpredictable mutations. Keep away from children."
reagent_state = LIQUID
color = "#13BC5E" // rgb: 19, 188, 94
toxpwr = 0
color = "#13BC5E"
/datum/reagent/toxin/mutagen/reaction_mob(var/mob/living/carbon/M, var/method=TOUCH, var/volume)
if(!..()) return
if(!istype(M) || !M.dna) return //No robots, AIs, aliens, Ians or other mobs should be affected by this.
src = null
if((method==TOUCH && prob(33)) || method==INGEST)
randmuti(M)
if(prob(98)) randmutb(M)
else randmutg(M)
domutcheck(M, null)
M.UpdateAppearance()
return
/datum/reagent/mutagen/affect_touch(var/mob/living/carbon/M, var/alien, var/removed)
if(prob(33))
affect_blood(M, alien, removed)
/datum/reagent/toxin/mutagen/on_mob_life(var/mob/living/carbon/M)
if(!istype(M)) return
if(!M) M = holder.my_atom
M.apply_effect(10,IRRADIATE,0)
..()
return
/datum/reagent/mutagen/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed)
if(prob(67))
affect_blood(M, alien, removed)
/datum/reagent/toxin/slimejelly
/datum/reagent/mutagen/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
if(M.dna)
if(prob(removed * 0.1)) // Approx. one mutation per 10 injected/20 ingested/30 touching units
randmuti(M)
if(prob(98))
randmutb(M)
else
randmutg(M)
domutcheck(M, null)
M.UpdateAppearance()
M.apply_effect(10 * removed, IRRADIATE, 0)
/datum/reagent/slimejelly
name = "Slime Jelly"
id = "slimejelly"
description = "A gooey semi-liquid produced from one of the deadliest lifeforms in existence. SO REAL."
reagent_state = LIQUID
color = "#801E28" // rgb: 128, 30, 40
toxpwr = 0
color = "#801E28"
/datum/reagent/toxin/slimejelly/on_mob_life(var/mob/living/M as mob)
/datum/reagent/slimejelly/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
if(alien == IS_DIONA)
return
if(prob(10))
M << "\red Your insides are burning!"
M.adjustToxLoss(rand(20,60)*REM)
M << "<span class='danger'>Your insides are burning!</span>"
M.adjustToxLoss(rand(100, 300) * removed)
else if(prob(40))
M.heal_organ_damage(5*REM,0)
..()
return
M.heal_organ_damage(25 * removed, 0)
/datum/reagent/toxin/stoxin
/datum/reagent/soporific
name = "Soporific"
id = "stoxin"
description = "An effective hypnotic used to treat insomnia."
reagent_state = LIQUID
color = "#009CA8" // rgb: 232, 149, 204
toxpwr = 0
custom_metabolism = 0.1
color = "#009CA8"
metabolism = REM * 0.5
overdose = REAGENTS_OVERDOSE
/datum/reagent/toxin/stoxin/on_mob_life(var/mob/living/M as mob)
if(!M) M = holder.my_atom
if(!data) data = 1
switch(data)
if(1 to 12)
if(prob(5)) M.emote("yawn")
if(12 to 15)
M.eye_blurry = max(M.eye_blurry, 10)
if(15 to 49)
if(prob(50))
M.Weaken(2)
M.drowsyness = max(M.drowsyness, 20)
if(50 to INFINITY)
M.sleeping = max(M.sleeping, 20)
M.drowsyness = max(M.drowsyness, 60)
data++
..()
return
/datum/reagent/soporific/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
if(alien == IS_DIONA)
return
if(dose < 1)
if(dose == metabolism * 2 || prob(5))
M.emote("yawn")
else if(dose < 1.5)
M.eye_blurry = max(M.eye_blurry, 10)
else if(dose < 5)
if(prob(50))
M.Weaken(2)
M.drowsyness = max(M.drowsyness, 20)
else
M.sleeping = max(M.sleeping, 20)
M.drowsyness = max(M.drowsyness, 60)
/datum/reagent/toxin/chloralhydrate
/datum/reagent/chloralhydrate
name = "Chloral Hydrate"
id = "chloralhydrate"
description = "A powerful sedative."
reagent_state = SOLID
color = "#000067" // rgb: 0, 0, 103
toxpwr = 1
custom_metabolism = 0.1 //Default 0.2
overdose = 15
overdose_dam = 5
color = "#000067"
metabolism = REM * 0.5
overdose = REAGENTS_OVERDOSE * 0.5
/datum/reagent/toxin/chloralhydrate/on_mob_life(var/mob/living/M as mob)
if(!M) M = holder.my_atom
if(!data) data = 1
data++
switch(data)
if(1)
M.confused += 2
M.drowsyness += 2
if(2 to 20)
M.Weaken(30)
M.eye_blurry = max(M.eye_blurry, 10)
if(20 to INFINITY)
M.sleeping = max(M.sleeping, 30)
..()
return
/datum/reagent/chloralhydrate/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
if(alien == IS_DIONA)
return
if(dose == metabolism)
M.confused += 2
M.drowsyness += 2
else if(dose < 2)
M.Weaken(30)
M.eye_blurry = max(M.eye_blurry, 10)
else
M.sleeping = max(M.sleeping, 30)
/datum/reagent/toxin/beer2 //disguised as normal beer for use by emagged brobots
if(dose > 1)
M.adjustToxLoss(removed)
/datum/reagent/chloralhydrate/beer2 //disguised as normal beer for use by emagged brobots
name = "Beer"
id = "beer2"
description = "An alcoholic beverage made from malted grains, hops, yeast, and water. The fermentation appears to be incomplete." //If the players manage to analyze this, they deserve to know something is wrong.
reagent_state = LIQUID
color = "#664300" // rgb: 102, 67, 0
custom_metabolism = 0.15 // Sleep toxins should always be consumed pretty fast
overdose = REAGENTS_OVERDOSE/2
color = "#664300"
glass_icon_state = "beerglass"
glass_name = "glass of beer"
glass_desc = "A freezing pint of beer"
glass_center_of_mass = list("x"=16, "y"=8)
/datum/reagent/toxin/beer2/on_mob_life(var/mob/living/M as mob)
if(!M) M = holder.my_atom
if(!data) data = 1
switch(data)
if(1)
M.confused += 2
M.drowsyness += 2
if(2 to 50)
M.sleeping += 1
if(51 to INFINITY)
M.sleeping += 1
M.adjustToxLoss((data - 50)*REM)
data++
..()
return
/* Drugs */
/datum/reagent/space_drugs
name = "Space drugs"
id = "space_drugs"
description = "An illegal chemical compound used as drug."
reagent_state = LIQUID
color = "#60A584" // rgb: 96, 165, 132
color = "#60A584"
metabolism = REM * 0.5
overdose = REAGENTS_OVERDOSE
/datum/reagent/space_drugs/on_mob_life(var/mob/living/M as mob)
if(!M) M = holder.my_atom
/datum/reagent/space_drugs/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
if(alien == IS_DIONA)
return
M.druggy = max(M.druggy, 15)
if(isturf(M.loc) && !istype(M.loc, /turf/space))
if(M.canmove && !M.restrained())
if(prob(10)) step(M, pick(cardinal))
if(prob(7)) M.emote(pick("twitch","drool","moan","giggle"))
holder.remove_reagent(src.id, 0.5 * REAGENTS_METABOLISM)
return
if(prob(10) && isturf(M.loc) && !istype(M.loc, /turf/space) && M.canmove && !M.restrained())
step(M, pick(cardinal))
if(prob(7))
M.emote(pick("twitch", "drool", "moan", "giggle"))
/datum/reagent/serotrotium
name = "Serotrotium"
id = "serotrotium"
description = "A chemical compound that promotes concentrated production of the serotonin neurotransmitter in humans."
reagent_state = LIQUID
color = "#202040" // rgb: 20, 20, 40
color = "#202040"
metabolism = REM * 0.25
overdose = REAGENTS_OVERDOSE
/datum/reagent/serotrotium/on_mob_life(var/mob/living/M as mob)
if(ishuman(M))
if(prob(7)) M.emote(pick("twitch","drool","moan","gasp"))
holder.remove_reagent(src.id, 0.25 * REAGENTS_METABOLISM)
/datum/reagent/serotrotium/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
if(alien == IS_DIONA)
return
if(prob(7))
M.emote(pick("twitch", "drool", "moan", "gasp"))
return
/datum/reagent/cryptobiolin
@@ -428,165 +355,160 @@
id = "cryptobiolin"
description = "Cryptobiolin causes confusion and dizzyness."
reagent_state = LIQUID
color = "#000055" // rgb: 200, 165, 220
color = "#000055"
metabolism = REM * 0.5
overdose = REAGENTS_OVERDOSE
/datum/reagent/cryptobiolin/on_mob_life(var/mob/living/M as mob)
if(!M) M = holder.my_atom
M.make_dizzy(1)
if(!M.confused) M.confused = 1
/datum/reagent/cryptobiolin/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
if(alien == IS_DIONA)
return
M.make_dizzy(4)
M.confused = max(M.confused, 20)
holder.remove_reagent(src.id, 0.5 * REAGENTS_METABOLISM)
..()
return
/datum/reagent/impedrezene
name = "Impedrezene"
id = "impedrezene"
description = "Impedrezene is a narcotic that impedes one's ability by slowing down the higher brain cell functions."
reagent_state = LIQUID
color = "#C8A5DC" // rgb: 200, 165, 220
color = "#C8A5DC"
overdose = REAGENTS_OVERDOSE
/datum/reagent/impedrezene/on_mob_life(var/mob/living/M as mob)
if(!M) M = holder.my_atom
M.jitteriness = max(M.jitteriness-5,0)
if(prob(80)) M.adjustBrainLoss(1*REM)
if(prob(50)) M.drowsyness = max(M.drowsyness, 3)
if(prob(10)) M.emote("drool")
..()
return
/datum/reagent/impedrezene/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
if(alien == IS_DIONA)
return
M.jitteriness = max(M.jitteriness - 5, 0)
if(prob(80))
M.adjustBrainLoss(3 * removed)
if(prob(50))
M.drowsyness = max(M.drowsyness, 3)
if(prob(10))
M.emote("drool")
/datum/reagent/toxin/mindbreaker
/datum/reagent/mindbreaker
name = "Mindbreaker Toxin"
id = "mindbreaker"
description = "A powerful hallucinogen, it can cause fatal effects in users."
reagent_state = LIQUID
color = "#B31008" // rgb: 139, 166, 233
toxpwr = 0
custom_metabolism = 0.05
color = "#B31008"
metabolism = REM * 0.25
overdose = REAGENTS_OVERDOSE
/datum/reagent/toxin/mindbreaker/on_mob_life(var/mob/living/M)
if(!M) M = holder.my_atom
M.hallucination += 10
..()
return
/datum/reagent/mindbreaker/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
if(alien == IS_DIONA)
return
M.hallucination = max(M.hallucination, 100)
/datum/reagent/psilocybin
name = "Psilocybin"
id = "psilocybin"
description = "A strong psycotropic derived from certain species of mushroom."
color = "#E700E7" // rgb: 231, 0, 231
color = "#E700E7"
overdose = REAGENTS_OVERDOSE
metabolism = REM * 0.5
/datum/reagent/psilocybin/on_mob_life(var/mob/living/M as mob)
if(!M) M = holder.my_atom
/datum/reagent/psilocybin/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
if(alien == IS_DIONA)
return
M.druggy = max(M.druggy, 30)
if(!data) data = 1
switch(data)
if(1 to 5)
if (!M.stuttering) M.stuttering = 1
M.make_dizzy(5)
if(prob(10)) M.emote(pick("twitch","giggle"))
if(5 to 10)
if (!M.stuttering) M.stuttering = 1
M.make_jittery(10)
M.make_dizzy(10)
M.druggy = max(M.druggy, 35)
if(prob(20)) M.emote(pick("twitch","giggle"))
if (10 to INFINITY)
if (!M.stuttering) M.stuttering = 1
M.make_jittery(20)
M.make_dizzy(20)
M.druggy = max(M.druggy, 40)
if(prob(30)) M.emote(pick("twitch","giggle"))
holder.remove_reagent(src.id, 0.2)
data++
..()
return
if(dose < 1)
M.stuttering = max(M.stuttering, 3)
M.make_dizzy(5)
if(prob(10))
M.emote(pick("twitch", "giggle"))
else if(dose < 2)
M.stuttering = max(M.stuttering, 3)
M.make_jittery(10)
M.make_dizzy(10)
M.druggy = max(M.druggy, 35)
if(prob(20))
M.emote(pick("twitch","giggle"))
else
M.stuttering = max(M.stuttering, 3)
M.make_jittery(20)
M.make_dizzy(20)
M.druggy = max(M.druggy, 40)
if(prob(30))
M.emote(pick("twitch", "giggle"))
/datum/reagent/nicotine
name = "Nicotine"
id = "nicotine"
description = "A highly addictive stimulant extracted from the tobacco plant."
reagent_state = LIQUID
color = "#181818" // rgb: 24, 24, 24
color = "#181818"
/* Transformations */
/datum/reagent/slimetoxin
name = "Mutation Toxin"
id = "mutationtoxin"
description = "A corruptive toxin produced by slimes."
reagent_state = LIQUID
color = "#13BC5E" // rgb: 19, 188, 94
overdose = REAGENTS_OVERDOSE
color = "#13BC5E"
/datum/reagent/slimetoxin/on_mob_life(var/mob/living/M as mob)
if(!M) M = holder.my_atom
/datum/reagent/slimetoxin/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
if(ishuman(M))
var/mob/living/carbon/human/human = M
if(human.species.name != "Slime")
var/mob/living/carbon/human/H = M
if(H.species.name != "Slime")
M << "<span class='danger'>Your flesh rapidly mutates!</span>"
human.set_species("Slime")
..()
return
H.set_species("Slime")
/datum/reagent/aslimetoxin
name = "Advanced Mutation Toxin"
id = "amutationtoxin"
description = "An advanced corruptive toxin produced by slimes."
reagent_state = LIQUID
color = "#13BC5E" // rgb: 19, 188, 94
overdose = REAGENTS_OVERDOSE
color = "#13BC5E"
/datum/reagent/aslimetoxin/on_mob_life(var/mob/living/M as mob)
if(!M) M = holder.my_atom
if(istype(M, /mob/living/carbon) && M.stat != DEAD)
M << "\red Your flesh rapidly mutates!"
if(M.monkeyizing) return
M.monkeyizing = 1
M.canmove = 0
M.icon = null
M.overlays.Cut()
M.invisibility = 101
for(var/obj/item/W in M)
if(istype(W, /obj/item/weapon/implant)) //TODO: Carn. give implants a dropped() or something
qdel(W)
continue
W.layer = initial(W.layer)
W.loc = M.loc
W.dropped(M)
var/mob/living/carbon/slime/new_mob = new /mob/living/carbon/slime(M.loc)
new_mob.a_intent = I_HURT
new_mob.universal_speak = 1
if(M.mind)
M.mind.transfer_to(new_mob)
else
new_mob.key = M.key
qdel(M)
..()
return
/datum/reagent/aslimetoxin/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) // TODO: check if there's similar code anywhere else
if(M.monkeyizing)
return
M << "<span class='danger'>Your flesh rapidly mutates!</span>"
M.monkeyizing = 1
M.canmove = 0
M.icon = null
M.overlays.Cut()
M.invisibility = 101
for(var/obj/item/W in M)
if(istype(W, /obj/item/weapon/implant)) //TODO: Carn. give implants a dropped() or something
qdel(W)
continue
W.layer = initial(W.layer)
W.loc = M.loc
W.dropped(M)
var/mob/living/carbon/slime/new_mob = new /mob/living/carbon/slime(M.loc)
new_mob.a_intent = "hurt"
new_mob.universal_speak = 1
if(M.mind)
M.mind.transfer_to(new_mob)
else
new_mob.key = M.key
qdel(M)
/datum/reagent/nanites
name = "Nanomachines"
id = "nanites"
description = "Microscopic construction robots."
reagent_state = LIQUID
color = "#535E66" // rgb: 83, 94, 102
color = "#535E66"
/datum/reagent/nanites/reaction_mob(var/mob/M, var/method=TOUCH, var/volume)
src = null
if( (prob(10) && method==TOUCH) || method==INGEST)
M.contract_disease(new /datum/disease/robotic_transformation(0),1)
/datum/reagent/nanites/affect_touch(var/mob/living/carbon/M, var/alien, var/removed)
if(prob(10))
M.contract_disease(new /datum/disease/robotic_transformation(0), 1)
/datum/reagent/nanites/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
M.contract_disease(new /datum/disease/robotic_transformation(0), 1)
/datum/reagent/xenomicrobes
name = "Xenomicrobes"
id = "xenomicrobes"
description = "Microbes with an entirely alien cellular structure."
reagent_state = LIQUID
color = "#535E66" // rgb: 83, 94, 102
color = "#535E66"
/datum/reagent/xenomicrobes/reaction_mob(var/mob/M, var/method=TOUCH, var/volume)
src = null
if( (prob(10) && method==TOUCH) || method==INGEST)
M.contract_disease(new /datum/disease/xeno_transformation(0),1)
/datum/reagent/xenomicrobes/affect_touch(var/mob/living/carbon/M, var/alien, var/removed)
if(prob(10))
M.contract_disease(new /datum/disease/xeno_transformation(0), 1)
/datum/reagent/xenomicrobes/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
M.contract_disease(new /datum/disease/xeno_transformation(0), 1)
File diff suppressed because it is too large Load Diff
+128 -23
View File
@@ -13,39 +13,144 @@
set category = "Object"
set src in range(0)
var/N = input("Amount per transfer from this:","[src]") as null|anything in possible_transfer_amounts
if (N)
if(N)
amount_per_transfer_from_this = N
/obj/item/weapon/reagent_containers/New()
..()
if (!possible_transfer_amounts)
if(!possible_transfer_amounts)
src.verbs -= /obj/item/weapon/reagent_containers/verb/set_APTFT
var/datum/reagents/R = new/datum/reagents(volume)
reagents = R
R.my_atom = src
create_reagents(volume)
/obj/item/weapon/reagent_containers/attack_self(mob/user as mob)
return
/obj/item/weapon/reagent_containers/attack(mob/M as mob, mob/user as mob, def_zone)
if(can_operate(M)) //Checks if mob is lying down on table for surgery
if(do_surgery(M,user,src))
/obj/item/weapon/reagent_containers/attack(mob/M as mob, mob/user as mob, def_zone)
if(can_operate(M))//Checks if mob is lying down on table for surgery
if(do_surgery(M, user, src))
return
// this prevented pills, food, and other things from being picked up by bags.
// possibly intentional, but removing it allows us to not duplicate functionality.
// -Sayu (storage conslidation)
/*
/obj/item/weapon/reagent_containers/attackby(obj/item/I as obj, mob/user as mob)
return
*/
/obj/item/weapon/reagent_containers/afterattack(obj/target, mob/user , flag)
/obj/item/weapon/reagent_containers/afterattack(obj/target, mob/user, flag)
return
/obj/item/weapon/reagent_containers/proc/reagentlist(var/obj/item/weapon/reagent_containers/snack) //Attack logs for regents in pills
var/data
if(snack.reagents.reagent_list && snack.reagents.reagent_list.len) //find a reagent list if there is and check if it has entries
for (var/datum/reagent/R in snack.reagents.reagent_list) //no reagents will be left behind
data += "[R.id]([R.volume] units); " //Using IDs because SOME chemicals(I'm looking at you, chlorhydrate-beer) have the same names as other chemicals.
return data
else return "No reagents"
/obj/item/weapon/reagent_containers/proc/reagentlist() // For attack logs
if(reagents)
return reagents.get_reagents()
return "No reagent holder"
/obj/item/weapon/reagent_containers/proc/standard_dispenser_refill(var/mob/user, var/obj/structure/reagent_dispensers/target) // This goes into afterattack
if(!istype(target))
return 0
if(!target.reagents || !target.reagents.total_volume)
user << "<span class='notice'>[target] is empty.</span>"
return 1
if(reagents && !reagents.get_free_space())
user << "<span class='notice'>[src] is full.</span>"
return 1
var/trans = target.reagents.trans_to_obj(src, target:amount_per_transfer_from_this)
user << "<span class='notice'>You fill [src] with [trans] units of the contents of [target].</span>"
return 1
/obj/item/weapon/reagent_containers/proc/standard_splash_mob(var/mob/user, var/mob/target) // This goes into afterattack
if(!istype(target))
return
if(!reagents || !reagents.total_volume)
user << "<span class='notice'>[src] is empty.</span>"
return 1
if(target.reagents && !target.reagents.get_free_space())
user << "<span class='notice'>[target] is full.</span>"
return 1
var/contained = reagentlist()
target.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has been splashed with [name] by [user.name] ([user.ckey]). Reagents: [contained]</font>")
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Used the [name] to splash [target.name] ([target.key]). Reagents: [contained]</font>")
msg_admin_attack("[user.name] ([user.ckey]) splashed [target.name] ([target.key]) with [name]. Reagents: [contained] (INTENT: [uppertext(user.a_intent)]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)")
user.visible_message("<span class='danger'>[target] has been splashed with something by [user]!", "<span class = 'notice'>You splash the solution onto [target].</span>")
reagents.splash_mob(target, reagents.total_volume)
return 1
/obj/item/weapon/reagent_containers/proc/self_feed_message(var/mob/user)
user << "<span class='notice'>You eat \the [src]</span>"
/obj/item/weapon/reagent_containers/proc/other_feed_message_start(var/mob/user, var/mob/target)
user.visible_message("<span class='warning'>[user] is trying to feed [target] \the [src]!")
/obj/item/weapon/reagent_containers/proc/other_feed_message_finish(var/mob/user, var/mob/target)
user.visible_message("<span class='warning'>[user] has fed [target] \the [src]!")
/obj/item/weapon/reagent_containers/proc/feed_sound(var/mob/user)
return
/obj/item/weapon/reagent_containers/proc/standard_feed_mob(var/mob/user, var/mob/target) // This goes into attack
if(!istype(target))
return 0
if(!reagents || !reagents.total_volume)
user << "<span class='notice'>\The [src] is empty.</span>"
return 1
if(target == user)
if(istype(user, /mob/living/carbon/human))
var/mob/living/carbon/human/H = user
if(H.species.flags & IS_SYNTHETIC)
H << "<span class='notice'>You have a monitor for a head, where do you think you're going to put that?</span>"
return 1
var/obj/item/blocked = H.check_mouth_coverage()
if(blocked)
user << "<span class='warning'>\The [blocked] is in the way!</span>"
return
self_feed_message(user)
reagents.trans_to_mob(user, amount_per_transfer_from_this, CHEM_INGEST)
feed_sound(user)
return 1
else
if(istype(user, /mob/living/carbon/human))
var/mob/living/carbon/human/H = target
if(H.species.flags & IS_SYNTHETIC)
H << "<span class='notice'>They have a monitor for a head, where do you think you're going to put that?</span>"
return
var/obj/item/blocked = H.check_mouth_coverage()
if(blocked)
user << "<span class='warning'>\The [blocked] is in the way!</span>"
return
other_feed_message_start(user, target)
if(!do_mob(user, target))
return
other_feed_message_finish(user, target)
var/contained = reagentlist()
target.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has been fed [name] by [user.name] ([user.ckey]). Reagents: [contained]</font>")
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Fed [name] by [target.name] ([target.ckey]). Reagents: [contained]</font>")
msg_admin_attack("[key_name(user)] fed [key_name(target)] with [name]. Reagents: [contained] (INTENT: [uppertext(user.a_intent)]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)")
reagents.trans_to_mob(target, amount_per_transfer_from_this, CHEM_INGEST)
feed_sound(user)
return 1
/obj/item/weapon/reagent_containers/proc/standard_pour_into(var/mob/user, var/atom/target) // This goes into afterattack and yes, it's atom-level
if(!target.is_open_container() || !target.reagents)
return 0
if(!reagents || !reagents.total_volume)
user << "<span class='notice'>[src] is empty.</span>"
return 1
if(!target.reagents.get_free_space())
user << "<span class='notice'>[target] is full.</span>"
return 1
var/trans = reagents.trans_to(target, amount_per_transfer_from_this)
user << "<span class='notice'>You transfer [trans] units of the solution to [target].</span>"
return 1
@@ -1,4 +1,3 @@
/obj/item/weapon/reagent_containers/borghypo
name = "Cyborg Hypospray"
desc = "An advanced chemical synthesizer and injection system, designed for heavy-duty medical equipment."
@@ -15,7 +14,6 @@
var/list/datum/reagents/reagent_list = list()
var/list/reagent_ids = list("tricordrazine", "inaprovaline", "spaceacillin")
//var/list/reagent_ids = list("dexalin", "kelotane", "bicaridine", "anti_toxin", "inaprovaline", "spaceacillin")
/obj/item/weapon/reagent_containers/borghypo/surgeon
reagent_ids = list("bicaridine", "inaprovaline", "dexalin")
@@ -40,23 +38,15 @@
if(charge_tick < recharge_time) return 0
charge_tick = 0
if(isrobot(src.loc))
var/mob/living/silicon/robot/R = src.loc
if(isrobot(loc))
var/mob/living/silicon/robot/R = loc
if(R && R.cell)
var/datum/reagents/RG = reagent_list[mode]
if(RG.total_volume < RG.maximum_volume) //Don't recharge reagents and drain power if the storage is full.
R.cell.use(charge_cost) //Take power from borg...
RG.add_reagent(reagent_ids[mode], 5) //And fill hypo with reagent.
//update_icon()
return 1
// Purely for testing purposes I swear~
/*
/obj/item/weapon/reagent_containers/borghypo/verb/add_cyanide()
set src in world
add_reagent("cyanide")
*/
// Use this to add more chemicals for the borghypo to produce.
/obj/item/weapon/reagent_containers/borghypo/proc/add_reagent(var/reagent)
reagent_ids |= reagent
@@ -70,19 +60,18 @@
/obj/item/weapon/reagent_containers/borghypo/attack(mob/living/M as mob, mob/user as mob)
var/datum/reagents/R = reagent_list[mode]
if(!R.total_volume)
user << "\red The injector is empty."
user << "<span class='warning'>The injector is empty.</span>"
return
if (!(istype(M)))
if (!istype(M))
return
if (R.total_volume && M.can_inject(user,1))
user << "\blue You inject [M] with the injector."
M << "\red You feel a tiny prick!"
if (R.total_volume && M.can_inject(user, 1))
user << "<span class='notice'>You inject [M] with the injector.</span>"
M << "<span class='notice'>You feel a tiny prick!</span>"
R.reaction(M, INGEST)
if(M.reagents)
var/trans = R.trans_to(M, amount_per_transfer_from_this)
user << "\blue [trans] units injected. [R.total_volume] units remaining."
var/trans = R.trans_to_mob(M, amount_per_transfer_from_this, CHEM_BLOOD)
user << "<span class='notice'>[trans] units injected. [R.total_volume] units remaining.</span>"
return
/obj/item/weapon/reagent_containers/borghypo/attack_self(mob/user as mob)
@@ -93,7 +82,7 @@
charge_tick = 0 //Prevents wasted chems/cell charge if you're cycling through modes.
var/datum/reagent/R = chemical_reagents_list[reagent_ids[mode]]
user << "\blue Synthesizer is now producing '[R.name]'."
user << "<span class='notice'>Synthesizer is now producing '[R.name]'.</span>"
return
/obj/item/weapon/reagent_containers/borghypo/examine(mob/user)
@@ -105,8 +94,8 @@
for(var/datum/reagents/RS in reagent_list)
var/datum/reagent/R = locate() in RS.reagent_list
if(R)
user << "\blue It currently has [R.volume] units of [R.name] stored."
user << "<span class='notice'>It currently has [R.volume] units of [R.name] stored.</span>"
empty = 0
if(empty)
user << "\blue It is currently empty. Allow some time for the internal syntheszier to produce more."
user << "<span class='notice'>It is currently empty. Allow some time for the internal syntheszier to produce more.</span>"
@@ -10,19 +10,18 @@
possible_transfer_amounts = list(1,2,3,4,5)
w_class = 1
volume = 5
var/filled = 0
afterattack(obj/target, mob/user , flag)
afterattack(var/obj/target, var/mob/user, var/flag)
if(!target.reagents || !flag) return
if(filled)
if(reagents.total_volume)
if(target.reagents.total_volume >= target.reagents.maximum_volume)
user << "\red [target] is full."
if(!target.reagents.get_free_space())
user << "<span class='notice'>[target] is full.</span>"
return
if(!target.is_open_container() && !ismob(target) && !istype(target,/obj/item/weapon/reagent_containers/food) && !istype(target, /obj/item/clothing/mask/smokable/cigarette)) //You can inject humans and food but you cant remove the shit.
user << "\red You cannot directly fill this object."
if(!target.is_open_container() && !ismob(target) && !istype(target, /obj/item/weapon/reagent_containers/food) && !istype(target, /obj/item/clothing/mask/smokable/cigarette)) //You can inject humans and food but you cant remove the shit.
user << "<span class='notice'>You cannot directly fill this object.</span>"
return
var/trans = 0
@@ -30,80 +29,76 @@
if(ismob(target))
var/time = 20 //2/3rds the time of a syringe
for(var/mob/O in viewers(world.view, user))
O.show_message(text("\red <B>[] is trying to squirt something into []'s eyes!</B>", user, target), 1)
user.visible_message("<span class='warning'>[user] is trying to squirt something into [target]'s eyes!")
if(!do_mob(user, target, time)) return
if(!do_mob(user, target, time))
return
if(istype(target , /mob/living/carbon/human))
if(istype(target, /mob/living/carbon/human))
var/mob/living/carbon/human/victim = target
var/obj/item/safe_thing = null
if( victim.wear_mask )
if ( victim.wear_mask.flags & MASKCOVERSEYES )
if(victim.wear_mask)
if (victim.wear_mask.flags & MASKCOVERSEYES)
safe_thing = victim.wear_mask
if( victim.head )
if ( victim.head.flags & MASKCOVERSEYES )
if(victim.head)
if (victim.head.flags & MASKCOVERSEYES)
safe_thing = victim.head
if(victim.glasses)
if ( !safe_thing )
if (!safe_thing)
safe_thing = victim.glasses
if(safe_thing)
if(!safe_thing.reagents)
safe_thing.create_reagents(100)
trans = src.reagents.trans_to(safe_thing, amount_per_transfer_from_this)
for(var/mob/O in viewers(world.view, user))
O.show_message(text("\red <B>[] tries to squirt something into []'s eyes, but fails!</B>", user, target), 1)
spawn(5)
src.reagents.reaction(safe_thing, TOUCH)
user << "\blue You transfer [trans] units of the solution."
if (src.reagents.total_volume<=0)
filled = 0
icon_state = "dropper[filled]"
trans = reagents.trans_to_obj(safe_thing, amount_per_transfer_from_this)
user.visible_message("<span class='warning'>[user] tries to squirt something into [target]'s eyes, but fails!</span>", "<span class='notice'>You transfer [trans] units of the solution.</span>")
return
for(var/mob/O in viewers(world.view, user))
O.show_message(text("\red <B>[] squirts something into []'s eyes!</B>", user, target), 1)
src.reagents.reaction(target, TOUCH)
trans = reagents.trans_to_mob(target, reagents.total_volume, CHEM_INGEST)
user.visible_message("<span class='warning'>[user] squirts something into [target]'s eyes!</span>", "<span class='notice'>You transfer [trans] units of the solution.</span>")
var/mob/living/M = target
var/contained = reagentlist()
M.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has been squirted with [name] by [user.name] ([user.ckey]). Reagents: [contained]</font>")
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Used the [name] to squirt [M.name] ([M.key]). Reagents: [contained]</font>")
msg_admin_attack("[user.name] ([user.ckey]) squirted [M.name] ([M.key]) with [name]. Reagents: [contained] (INTENT: [uppertext(user.a_intent)]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)")
return
var/list/injected = list()
for(var/datum/reagent/R in src.reagents.reagent_list)
injected += R.name
var/contained = english_list(injected)
M.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has been squirted with [src.name] by [user.name] ([user.ckey]). Reagents: [contained]</font>")
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Used the [src.name] to squirt [M.name] ([M.key]). Reagents: [contained]</font>")
msg_admin_attack("[user.name] ([user.ckey]) squirted [M.name] ([M.key]) with [src.name]. Reagents: [contained] (INTENT: [uppertext(user.a_intent)]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)")
else
trans = reagents.trans_to(target, amount_per_transfer_from_this)
user << "<span class='notice'>You transfer [trans] units of the solution.</span>"
trans = src.reagents.trans_to(target, amount_per_transfer_from_this)
user << "\blue You transfer [trans] units of the solution."
if (src.reagents.total_volume<=0)
filled = 0
icon_state = "dropper[filled]"
else
else // Taking from something
if(!target.is_open_container() && !istype(target,/obj/structure/reagent_dispensers))
user << "\red You cannot directly remove reagents from [target]."
user << "<span class='notice'>You cannot directly remove reagents from [target].</span>"
return
if(!target.reagents.total_volume)
user << "\red [target] is empty."
if(!target.reagents || !target.reagents.total_volume)
user << "<span class='notice'>[target] is empty.</span>"
return
var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this)
var/trans = target.reagents.trans_to_obj(src, amount_per_transfer_from_this)
user << "\blue You fill the dropper with [trans] units of the solution."
filled = 1
icon_state = "dropper[filled]"
user << "<span class='notice'>You fill the dropper with [trans] units of the solution.</span>"
return
on_reagent_change()
update_icon()
update_icon()
if(reagents.total_volume)
icon_state = "dropper1"
else
icon_state = "dropper0"
/obj/item/weapon/reagent_containers/dropper/industrial
name = "Industrial Dropper"
desc = "A larger dropper. Transfers 10 units."
amount_per_transfer_from_this = 10
possible_transfer_amounts = list(1,2,3,4,5,6,7,8,9,10)
volume = 10
////////////////////////////////////////////////////////////////////////////////
/// Droppers. END
////////////////////////////////////////////////////////////////////////////////
@@ -1,104 +1,39 @@
/obj/item/weapon/reagent_containers/food/drinks/cans
var canopened = 0
amount_per_transfer_from_this = 5
flags = 0
attack_self(mob/user as mob)
if (canopened == 0)
playsound(src.loc,'sound/effects/canopen.ogg', rand(10,50), 1)
if (!is_open_container())
playsound(loc,'sound/effects/canopen.ogg', rand(10,50), 1)
user << "<span class='notice'>You open the drink with an audible pop!</span>"
canopened = 1
flags |= OPENCONTAINER
else
return
attack(mob/M as mob, mob/user as mob, def_zone)
if (canopened == 0)
if(!is_open_container())
user << "<span class='notice'>You need to open the drink!</span>"
return
var/datum/reagents/R = src.reagents
var/fillevel = gulp_size
if(!R.total_volume || !R)
user << "\red The [src.name] is empty!"
return 0
if(M == user)
M << "\blue You swallow a gulp of [src]."
if(reagents.total_volume)
reagents.trans_to_ingest(M, gulp_size)
reagents.reaction(M, INGEST)
spawn(5)
reagents.trans_to(M, gulp_size)
playsound(M.loc,'sound/items/drink.ogg', rand(10,50), 1)
return 1
else if( istype(M, /mob/living/carbon/human) )
if (canopened == 0)
user << "<span class='notice'>You need to open the drink!</span>"
return
else if (canopened == 1)
for(var/mob/O in viewers(world.view, user))
O.show_message("\red [user] attempts to feed [M] [src].", 1)
if(!do_mob(user, M)) return
for(var/mob/O in viewers(world.view, user))
O.show_message("\red [user] feeds [M] [src].", 1)
M.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has been fed [src.name] by [user.name] ([user.ckey]) Reagents: [reagentlist(src)]</font>")
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Fed [M.name] by [M.name] ([M.ckey]) Reagents: [reagentlist(src)]</font>")
msg_admin_attack("[key_name(user)] fed [key_name(M)] with [src.name] Reagents: [reagentlist(src)] (INTENT: [uppertext(user.a_intent)]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)")
if(reagents.total_volume)
reagents.trans_to_ingest(M, gulp_size)
if(isrobot(user)) //Cyborg modules that include drinks automatically refill themselves, but drain the borg's cell
var/mob/living/silicon/robot/bro = user
bro.cell.use(30)
var/refill = R.get_master_reagent_id()
spawn(600)
R.add_reagent(refill, fillevel)
playsound(M.loc,'sound/items/drink.ogg', rand(10,50), 1)
return 1
return 0
return ..()
afterattack(obj/target, mob/user, proximity)
if(!proximity) return
if(istype(target, /obj/structure/reagent_dispensers)) //A dispenser. Transfer FROM it TO us.
if (canopened == 0)
if(!is_open_container())
user << "<span class='notice'>You need to open the drink!</span>"
return
else if(target.is_open_container()) //Something like a glass. Player probably wants to transfer TO it.
if (canopened == 0)
if(!is_open_container())
user << "<span class='notice'>You need to open the drink!</span>"
return
if (istype(target, /obj/item/weapon/reagent_containers/food/drinks/cans))
var/obj/item/weapon/reagent_containers/food/drinks/cans/cantarget = target
if(cantarget.canopened == 0)
user << "<span class='notice'>You need to open the drink you want to pour into!</span>"
return
return ..()
/* examine(mob/user)
if(!..(user, 1))
return
if(!reagents || reagents.total_volume==0)
user << "\blue \The [src] is empty!"
else if (reagents.total_volume<=src.volume/4)
user << "\blue \The [src] is almost empty!"
else if (reagents.total_volume<=src.volume*0.66)
user << "\blue \The [src] is half full!"
else if (reagents.total_volume<=src.volume*0.90)
user << "\blue \The [src] is almost full!"
else
user << "\blue \The [src] is full!"*/
//DRINKS
/obj/item/weapon/reagent_containers/food/drinks/cans/cola
@@ -15,72 +15,39 @@
center_of_mass = list("x"=16, "y"=6)
volume = 50
attackby(obj/item/weapon/W as obj, mob/user as mob)
return
attack_self(mob/user as mob)
return
attack(mob/M as mob, mob/user as mob, def_zone)
var/datum/reagents/R = src.reagents
if(!R || !R.total_volume)
user << "\red The [src.name] is empty!"
return 0
if(M == user)
M << "\blue You swallow some of contents of the [src]."
if(reagents.total_volume)
reagents.trans_to_ingest(M, 10)
playsound(M.loc,'sound/items/drink.ogg', rand(10,50), 1)
return 1
else if( istype(M, /mob/living/carbon/human) )
for(var/mob/O in viewers(world.view, user))
O.show_message("\red [user] attempts to feed [M] [src].", 1)
if(!do_mob(user, M)) return
for(var/mob/O in viewers(world.view, user))
O.show_message("\red [user] feeds [M] [src].", 1)
M.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has been fed [src.name] by [user.name] ([user.ckey]) Reagents: [reagentlist(src)]</font>")
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Fed [src.name] by [M.name] ([M.ckey]) Reagents: [reagentlist(src)]</font>")
msg_admin_attack("[user.name] ([user.ckey]) fed [M.name] ([M.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)")
if(reagents.total_volume)
reagents.trans_to_ingest(M, 10)
playsound(M.loc,'sound/items/drink.ogg', rand(10,50), 1)
return 1
return 0
attackby(obj/item/I as obj, mob/user as mob)
attackby(var/obj/item/weapon/W as obj, var/mob/user as mob)
return
afterattack(obj/target, mob/user , flag)
if(istype(target, /obj/structure/reagent_dispensers)) //A dispenser. Transfer FROM it TO us.
attack_self(var/mob/user as mob)
return
if(!target.reagents.total_volume)
user << "\red [target] is empty."
attack(var/mob/M as mob, var/mob/user as mob, var/def_zone)
if(standard_feed_mob(user, M))
return
afterattack(var/obj/target, var/mob/user, var/flag)
if(standard_dispenser_refill(user, target))
return
if(standard_pour_into(user, target))
return
if(istype(target, /obj/item/weapon/reagent_containers/food/snacks)) // These are not opencontainers but we can transfer to them
if(!reagents || !reagents.total_volume)
user << "<span class='notice'>There is no condiment left in \the [src].</span>"
return
if(reagents.total_volume >= reagents.maximum_volume)
user << "\red [src] is full."
if(!target.reagents.get_free_space())
user << "<span class='notice'>You can't add more condiment to \the [target].</span>"
return
var/trans = target.reagents.trans_to(src, target:amount_per_transfer_from_this)
user << "\blue You fill [src] with [trans] units of the contents of [target]."
var/trans = reagents.trans_to_obj(target, amount_per_transfer_from_this)
user << "<span class='notice'>You add [trans] units of the condiment to \the [target].</span>"
//Something like a glass or a food item. Player probably wants to transfer TO it.
else if(target.is_open_container() || istype(target, /obj/item/weapon/reagent_containers/food/snacks))
if(!reagents.total_volume)
user << "\red [src] is empty."
return
if(target.reagents.total_volume >= target.reagents.maximum_volume)
user << "\red you can't add anymore to [target]."
return
var/trans = src.reagents.trans_to(target, amount_per_transfer_from_this)
user << "\blue You transfer [trans] units of the condiment to [target]."
feed_sound(var/mob/user)
playsound(user.loc, 'sound/items/drink.ogg', rand(10, 50), 1)
self_feed_message(var/mob/user)
user << "<span class='notice'>You swallow some of contents of \the [src].</span>"
on_reagent_change()
if(icon_state == "saltshakersmall" || icon_state == "peppermillsmall" || icon_state == "flour")
@@ -191,4 +158,4 @@
..()
reagents.add_reagent("flour", 30)
src.pixel_x = rand(-10.0, 10)
src.pixel_y = rand(-10.0, 10)
src.pixel_y = rand(-10.0, 10)
@@ -7,142 +7,63 @@
icon = 'icons/obj/drinks.dmi'
icon_state = null
flags = OPENCONTAINER
var/gulp_size = 5 //This is now officially broken ... need to think of a nice way to fix it.
possible_transfer_amounts = list(5,10,25)
amount_per_transfer_from_this = 5
volume = 50
on_reagent_change()
if (gulp_size < 5) gulp_size = 5
else gulp_size = max(round(reagents.total_volume / 5), 5)
return
attack_self(mob/user as mob)
return
attack(mob/M as mob, mob/user as mob, def_zone)
var/datum/reagents/R = src.reagents
var/fillevel = gulp_size
if(!R.total_volume || !R)
user << "<span class='danger'>The [src.name] is empty!"
return 0
if(M == user)
if(istype(M,/mob/living/carbon/human))
var/mob/living/carbon/human/H = M
if(H.species.flags & IS_SYNTHETIC)
H << "<span class='danger'>You have a monitor for a head, where do you think you're going to put that?</span>"
return
var/obj/item/blocked = H.check_mouth_coverage()
if(blocked)
user << "<span class='warning'>\The [blocked] is in the way!</span>"
return
M << "<span class='notice'>You swallow a gulp from \the [src].</span>"
if(reagents.total_volume)
reagents.trans_to_ingest(M, gulp_size)
playsound(M.loc,'sound/items/drink.ogg', rand(10,50), 1)
return 1
else if( istype(M, /mob/living/carbon/human) )
var/mob/living/carbon/human/H = M
if(H.species.flags & IS_SYNTHETIC)
user << "<span class='danger'>They have a monitor for a head, where do you think you're going to put that?</span>"
return
var/obj/item/blocked = H.check_mouth_coverage()
if(blocked)
user << "<span class='warning'>\The [blocked] is in the way!</span>"
return
user.visible_message("<span class='danger'>[user] attempts to feed [M] [src].</span>")
if(!do_mob(user, M)) return
user.visible_message("<span class='danger'>[user] feeds [M] [src].</span>")
M.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has been fed [src.name] by [user.name] ([user.ckey]) Reagents: [reagentlist(src)]</font>")
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Fed [M.name] by [M.name] ([M.ckey]) Reagents: [reagentlist(src)]</font>")
msg_admin_attack("[key_name(user)] fed [key_name(M)] with [src.name] Reagents: [reagentlist(src)] (INTENT: [uppertext(user.a_intent)]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)")
if(reagents.total_volume)
reagents.trans_to_ingest(M, gulp_size)
if(isrobot(user)) //Cyborg modules that include drinks automatically refill themselves, but drain the borg's cell
var/mob/living/silicon/robot/bro = user
bro.cell.use(30)
var/refill = R.get_master_reagent_id()
spawn(600)
R.add_reagent(refill, fillevel)
playsound(M.loc,'sound/items/drink.ogg', rand(10,50), 1)
return 1
attack(mob/M as mob, mob/user as mob, def_zone)
if(standard_feed_mob(user, M))
robot_refill(user)
return
return 0
afterattack(obj/target, mob/user, proximity)
if(!proximity) return
if(istype(target, /obj/structure/reagent_dispensers)) //A dispenser. Transfer FROM it TO us.
if(!target.reagents.total_volume)
user << "\red [target] is empty."
return
if(reagents.total_volume >= reagents.maximum_volume)
user << "\red [src] is full."
return
var/trans = target.reagents.trans_to(src, target:amount_per_transfer_from_this)
user << "\blue You fill [src] with [trans] units of the contents of [target]."
else if(target.is_open_container()) //Something like a glass. Player probably wants to transfer TO it.
if(!reagents.total_volume)
user << "\red [src] is empty."
return
if(target.reagents.total_volume >= target.reagents.maximum_volume)
user << "\red [target] is full."
return
var/datum/reagent/refill
var/datum/reagent/refillName
if(isrobot(user))
refill = reagents.get_master_reagent_id()
refillName = reagents.get_master_reagent_name()
var/trans = src.reagents.trans_to(target, amount_per_transfer_from_this)
user << "\blue You transfer [trans] units of the solution to [target]."
if(isrobot(user)) //Cyborg modules that include drinks automatically refill themselves, but drain the borg's cell
var/mob/living/silicon/robot/bro = user
var/chargeAmount = max(30,4*trans)
bro.cell.use(chargeAmount)
user << "Now synthesizing [trans] units of [refillName]..."
spawn(300)
reagents.add_reagent(refill, trans)
user << "Cyborg [src] refilled."
if(standard_dispenser_refill(user, target))
return
if(standard_pour_into(user, target))
robot_refill(user)
return
return ..()
proc/robot_refill(var/mob/living/silicon/robot/user)
if(!istype(user))
return 0
user.cell.use(30)
var/refill = reagents.get_master_reagent_id()
user << "Now synthesizing [amount_per_transfer_from_this] units of [refill]..."
spawn(300)
reagents.add_reagent(refill, amount_per_transfer_from_this)
user << "Cyborg [src] refilled."
self_feed_message(var/mob/user)
user << "<span class='notice'>You swallow a gulp from \the [src].</span>"
feed_sound(var/mob/user)
playsound(user.loc, 'sound/items/drink.ogg', rand(10, 50), 1)
examine(mob/user)
if(!..(user, 1))
return
if(!reagents || reagents.total_volume==0)
user << "\blue \The [src] is empty!"
else if (reagents.total_volume<=src.volume/4)
user << "\blue \The [src] is almost empty!"
else if (reagents.total_volume<=src.volume*0.66)
user << "\blue \The [src] is half full!"
else if (reagents.total_volume<=src.volume*0.90)
user << "\blue \The [src] is almost full!"
if(!reagents || reagents.total_volume == 0)
user << "<span class='notice'>\The [src] is empty!</span>"
else if (reagents.total_volume <= volume * 0.25)
user << "<span class='notice'>\The [src] is almost empty!</span>"
else if (reagents.total_volume <= volume * 0.66)
user << "<span class='notice'>\The [src] is half full!</span>"
else if (reagents.total_volume <= volume * 0.90)
user << "<span class='notice'>\The [src] is almost full!</span>"
else
user << "\blue \The [src] is full!"
user << "<span class='notice'>\The [src] is full!</span>"
////////////////////////////////////////////////////////////////////////////////
@@ -1,5 +1,3 @@
///////////////////////////////////////////////Alchohol bottles! -Agouri //////////////////////////
//Functionally identical to regular drinks. The only difference is that the default bottle size is 100. - Darem
//Bottles now weaken and break when smashed on people's heads. - Giacom
@@ -78,10 +76,9 @@
msg_admin_attack("[user.name] ([user.ckey]) attacked [target.name] ([target.ckey]) with a bottle. (INTENT: [uppertext(user.a_intent)]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)")
//The reagents in the bottle splash all over the target, thanks for the idea Nodrak
if(src.reagents)
for(var/mob/O in viewers(user, null))
O.show_message(text("\blue <B>The contents of the [src] splashes all over [target]!</B>"), 1)
src.reagents.reaction(target, TOUCH)
if(reagents)
user.visible_message("<span class='notice'>The contents of the [src] splash all over [target]!</span>")
reagents.splash_mob(target, reagents.total_volume)
//Finally, smash the bottle. This kills (qdel) the bottle.
src.smash(target, user)
@@ -34,7 +34,7 @@
else if(istype(W,/obj/item/weapon/reagent_containers/food/snacks))
user << "\blue You layer [W] over \the [src]."
var/obj/item/weapon/reagent_containers/F = W
F.reagents.trans_to(src, F.reagents.total_volume)
F.reagents.trans_to_obj(src, F.reagents.total_volume)
user.drop_item()
W.loc = src
ingredients += W
@@ -34,7 +34,6 @@
return
/obj/item/weapon/reagent_containers/food/snacks/attack(mob/M as mob, mob/user as mob, def_zone)
if(!reagents.total_volume)
user << "<span class='danger'>None of [src] left!</span>"
user.drop_from_inventory(src)
@@ -102,15 +101,9 @@
playsound(M.loc,'sound/items/eatfood.ogg', rand(10,50), 1)
if(reagents.total_volume)
if(reagents.total_volume > bitesize)
/*
* I totally cannot understand what this code supposed to do.
* Right now every snack consumes in 2 bites, my popcorn does not work right, so I simplify it. -- rastaf0
var/temp_bitesize = max(reagents.total_volume /2, bitesize)
reagents.trans_to(M, temp_bitesize)
*/
reagents.trans_to_ingest(M, bitesize)
reagents.trans_to_mob(M, bitesize, CHEM_INGEST)
else
reagents.trans_to_ingest(M, reagents.total_volume)
reagents.trans_to_mob(M, reagents.total_volume, CHEM_INGEST)
bitecount++
On_Consume(M)
return 1
@@ -157,7 +150,7 @@
I.color = src.filling_color
U.overlays += I
reagents.trans_to(U,min(reagents.total_volume,5))
reagents.trans_to_obj(U, min(reagents.total_volume,5))
if (reagents.total_volume <= 0)
qdel(src)
@@ -193,9 +186,9 @@
var/reagents_per_slice = reagents.total_volume/slices_num
for(var/i=1 to (slices_num-slices_lost))
var/obj/slice = new slice_path (src.loc)
reagents.trans_to(slice,reagents_per_slice)
qdel(src)
var/obj/slice = new slice_path (src.loc)
reagents.trans_to_obj(slice, reagents_per_slice)
qdel(src)
return
/obj/item/weapon/reagent_containers/food/snacks/proc/is_sliceable()
@@ -216,7 +209,7 @@
user.visible_message("<b>[user]</b> nibbles away at \the [src].","You nibble away at \the [src].")
bitecount++
if(reagents && user.reagents)
reagents.trans_to_ingest(user, bitesize)
reagents.trans_to_mob(user, bitesize, CHEM_INGEST)
spawn(5)
if(!src && !user.client)
user.custom_emote(1,"[pick("burps", "cries for more", "burps twice", "looks at the area where the food was")]")
@@ -490,7 +483,7 @@
/obj/item/weapon/reagent_containers/food/snacks/egg/throw_impact(atom/hit_atom)
..()
new/obj/effect/decal/cleanable/egg_smudge(src.loc)
src.reagents.reaction(hit_atom, TOUCH)
src.reagents.trans_to(hit_atom, reagents.total_volume)
src.visible_message("\red [src.name] has been squashed.","\red You hear a smack.")
qdel(src)
@@ -2043,7 +2036,7 @@
New()
..()
reagents.add_reagent("minttoxin", 1)
reagents.add_reagent("mint", 1)
bitesize = 1
/obj/item/weapon/reagent_containers/food/snacks/mushroomsoup
+29 -104
View File
@@ -41,116 +41,71 @@
/obj/machinery/sleeper,
/obj/machinery/smartfridge/,
/obj/machinery/biogenerator,
/obj/machinery/constructable_frame
/obj/machinery/constructable_frame,
/obj/machinery/bunsen_burner,
/obj/machinery/radiocarbon_spectrometer
)
New()
..()
base_name = name
examine(mob/user)
examine(var/mob/user)
if(!..(user, 2))
return
if(reagents && reagents.reagent_list.len)
user << "\blue It contains [src.reagents.total_volume] units of liquid."
user << "<span class='notice'>It contains [reagents.total_volume] units of liquid.</span>"
else
user << "\blue It is empty."
if (!is_open_container())
user << "\blue Airtight lid seals it completely."
user << "<span class='notice'>It is empty.</span>"
if(!is_open_container())
user << "<span class='notice'>Airtight lid seals it completely.</span>"
attack_self()
..()
if (is_open_container())
usr << "<span class = 'notice'>You put the lid on \the [src]."
if(is_open_container())
usr << "<span class = 'notice'>You put the lid on \the [src].</span>"
flags ^= OPENCONTAINER
else
usr << "<span class = 'notice'>You take the lid off \the [src]."
usr << "<span class = 'notice'>You take the lid off \the [src].</span>"
flags |= OPENCONTAINER
update_icon()
afterattack(obj/target, mob/user , flag)
afterattack(var/obj/target, var/mob/user, var/flag)
if (!is_open_container() || !flag)
if(!is_open_container() || !flag)
return
for(var/type in src.can_be_placed_into)
for(var/type in can_be_placed_into)
if(istype(target, type))
return
if(ismob(target) && target.reagents && reagents.total_volume)
user << "\blue You splash the solution onto [target]."
var/mob/living/M = target
var/list/injected = list()
for(var/datum/reagent/R in src.reagents.reagent_list)
injected += R.name
var/contained = english_list(injected)
M.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has been splashed with [src.name] by [user.name] ([user.ckey]). Reagents: [contained]</font>")
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Used the [src.name] to splash [M.name] ([M.key]). Reagents: [contained]</font>")
msg_admin_attack("[user.name] ([user.ckey]) splashed [M.name] ([M.key]) with [src.name]. Reagents: [contained] (INTENT: [uppertext(user.a_intent)]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)")
for(var/mob/O in viewers(world.view, user))
O.show_message(text("\red [] has been splashed with something by []!", target, user), 1)
src.reagents.reaction(target, TOUCH)
spawn(5) src.reagents.clear_reagents()
if(standard_splash_mob(user, target))
return
else if(istype(target, /obj/structure/reagent_dispensers)) //A dispenser. Transfer FROM it TO us.
target.add_fingerprint(user)
if(!target.reagents.total_volume && target.reagents)
user << "\red [target] is empty."
return
if(reagents.total_volume >= reagents.maximum_volume)
user << "\red [src] is full."
return
var/trans = target.reagents.trans_to(src, target:amount_per_transfer_from_this)
user << "\blue You fill [src] with [trans] units of the contents of [target]."
else if(target.is_open_container() && target.reagents) //Something like a glass. Player probably wants to transfer TO it.
if(!reagents.total_volume)
user << "\red [src] is empty."
return
if(target.reagents.total_volume >= target.reagents.maximum_volume)
user << "\red [target] is full."
return
var/trans = src.reagents.trans_to(target, amount_per_transfer_from_this)
user << "\blue You transfer [trans] units of the solution to [target]."
else if(istype(target, /obj/machinery/bunsen_burner))
if(standard_dispenser_refill(user, target))
return
if(standard_pour_into(user, target))
return
else if(istype(target, /obj/machinery/smartfridge))
return
else if(istype(target, /obj/machinery/radiocarbon_spectrometer))
return
else if(reagents.total_volume)
user << "\blue You splash the solution onto [target]."
src.reagents.reaction(target, TOUCH)
spawn(5) src.reagents.clear_reagents()
if(reagents.total_volume)
user << "<span class='notice'>You splash the solution onto [target].</span>"
reagents.trans_to(target, reagents.total_volume)
return
attackby(obj/item/weapon/W as obj, mob/user as mob)
if(istype(W, /obj/item/weapon/pen) || istype(W, /obj/item/device/flashlight/pen))
var/tmp_label = sanitizeSafe(input(user, "Enter a label for [src.name]","Label",src.label_text), MAX_NAME_LEN)
var/tmp_label = sanitizeSafe(input(user, "Enter a label for [name]", "Label", label_text), MAX_NAME_LEN)
if(length(tmp_label) > 10)
user << "\red The label can be at most 10 characters long."
user << "<span class='notice'>The label can be at most 10 characters long.</span>"
else
user << "\blue You set the label to \"[tmp_label]\"."
src.label_text = tmp_label
src.update_name_label()
user << "<span class='notice'>You set the label to \"[tmp_label]\".</span>"
label_text = tmp_label
update_name_label()
proc/update_name_label()
if(src.label_text == "")
src.name = src.base_name
if(label_text == "")
name = base_name
else
src.name = "[src.base_name] ([src.label_text])"
name = "[base_name] ([label_text])"
/obj/item/weapon/reagent_containers/glass/beaker
name = "beaker"
@@ -231,7 +186,6 @@
possible_transfer_amounts = list(5,10,15,25,30,60,120,300)
flags = OPENCONTAINER
/obj/item/weapon/reagent_containers/glass/beaker/vial
name = "vial"
desc = "A small glass vial."
@@ -282,18 +236,6 @@
var/image/lid = image(icon, src, "lid_[initial(icon_state)]")
overlays += lid
// vials are defined twice, what?
/*
/obj/item/weapon/reagent_containers/glass/beaker/vial
name = "vial"
desc = "Small glass vial. Looks fragile."
icon_state = "vial"
g_amt = 500
volume = 15
amount_per_transfer_from_this = 5
possible_transfer_amounts = list(1,5,15)
flags = OPENCONTAINER */
/*
/obj/item/weapon/reagent_containers/glass/blender_jug
name = "Blender Jug"
@@ -324,21 +266,4 @@
amount_per_transfer_from_this = 20
possible_transfer_amounts = list(10,20,30,60)
volume = 120
/obj/item/weapon/reagent_containers/glass/dispenser
name = "reagent glass"
desc = "A reagent glass."
icon = 'icons/obj/chemical.dmi'
icon_state = "beaker0"
amount_per_transfer_from_this = 10
flags = OPENCONTAINER
/obj/item/weapon/reagent_containers/glass/dispenser/surfactant
name = "reagent glass (surfactant)"
icon_state = "liquid"
New()
..()
reagents.add_reagent("fluorosurfactant", 20)
*/
@@ -21,27 +21,22 @@
/obj/item/weapon/reagent_containers/hypospray/attack(mob/M as mob, mob/user as mob)
if(!reagents.total_volume)
user << "\red [src] is empty."
user << "<span class='warning'>[src] is empty.</span>"
return
if (!( istype(M, /mob) ))
if (!istype(M))
return
if (reagents.total_volume)
user << "\blue You inject [M] with [src]."
M << "\red You feel a tiny prick!"
user << "<span class='notice'>You inject [M] with [src].</span>"
M << "<span class='notice'>You feel a tiny prick!</span>"
src.reagents.reaction(M, INGEST)
if(M.reagents)
if(M.reagents)
var/list/injected = list()
for(var/datum/reagent/R in src.reagents.reagent_list)
injected += R.name
var/contained = english_list(injected)
M.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has been injected with [src.name] by [user.name] ([user.ckey]). Reagents: [contained]</font>")
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Used the [src.name] to inject [M.name] ([M.key]). Reagents: [contained]</font>")
msg_admin_attack("[user.name] ([user.ckey]) injected [M.name] ([M.key]) with [src.name]. Reagents: [contained] (INTENT: [uppertext(user.a_intent)]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)")
var/contained = reagentlist()
M.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has been injected with [name] by [user.name] ([user.ckey]). Reagents: [contained]</font>")
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Used the [name] to inject [M.name] ([M.key]). Reagents: [contained]</font>")
msg_admin_attack("[user.name] ([user.ckey]) injected [M.name] ([M.key]) with [name]. Reagents: [contained] (INTENT: [uppertext(user.a_intent)]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)")
var/trans = reagents.trans_to(M, amount_per_transfer_from_this)
user << "\blue [trans] units injected. [reagents.total_volume] units remaining in [src]."
var/trans = reagents.trans_to_mob(M, amount_per_transfer_from_this, CHEM_BLOOD)
user << "<span class='notice'>[trans] units injected. [reagents.total_volume] units remaining in \the [src].</span>"
return
@@ -76,6 +71,6 @@
/obj/item/weapon/reagent_containers/hypospray/autoinjector/examine(mob/user)
..(user)
if(reagents && reagents.reagent_list.len)
user << "\blue It is currently loaded."
user << "<span class='notice'>It is currently loaded.</span>"
else
user << "\blue It is spent."
user << "<span class='notice'>It is spent.</span>"
@@ -14,17 +14,15 @@
New()
..()
if(!icon_state)
icon_state = "pill[rand(1,20)]"
icon_state = "pill[rand(1, 20)]"
attack_self(mob/user as mob)
return
attack(mob/M as mob, mob/user as mob, def_zone)
if(M == user)
if(istype(M, /mob/living/carbon/human))
var/mob/living/carbon/human/H = M
if(H.species.flags & IS_SYNTHETIC)
H << "<span class='danger'>You have a monitor for a head, where do you think you're going to put that?</span>"
H << "<span class='notice'>You have a monitor for a head, where do you think you're going to put that?</span>"
return
var/obj/item/blocked = H.check_mouth_coverage()
@@ -32,44 +30,42 @@
user << "<span class='warning'>\The [blocked] is in the way!</span>"
return
M << "<span class='notice'>You swallow [src].</span>"
M << "<span class='notice'>You swallow \the [src].</span>"
M.drop_from_inventory(src) //icon update
if(reagents.total_volume)
reagents.trans_to_ingest(M, reagents.total_volume)
qdel(src)
else
qdel(src)
reagents.trans_to_mob(M, reagents.total_volume, CHEM_INGEST)
qdel(src)
return 1
else if(istype(M, /mob/living/carbon/human) )
else if(istype(M, /mob/living/carbon/human))
var/mob/living/carbon/human/H = M
if(H.species.flags & IS_SYNTHETIC)
user << "<span class='danger'>They have a monitor for a head, where do you think you're going to put that?</span>"
H << "<span class='notice'>They have a monitor for a head, where do you think you're going to put that?</span>"
return
var/obj/item/blocked = H.check_mouth_coverage()
if(blocked)
user << "<span class='warning'>\The [blocked] is in the way!</span>"
return
user.visible_message("<span class='danger'>[user] attempts to force [M] to swallow [src].</span>")
user.visible_message("<span class='warning'>[user] attempts to force [M] to swallow \the [src].</span>")
if(!do_after(user, 20))
if(!do_mob(user, M))
return
user.drop_from_inventory(src) //icon update
user.visible_message("<span class='danger'>[user] forces [M] to swallow [src].</span>")
user.visible_message("<span class='warning'>[user] forces [M] to swallow \the [src].</span>")
M.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has been fed [src.name] by [user.name] ([user.ckey]) Reagents: [reagentlist(src)]</font>")
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Fed [M.name] by [M.name] ([M.ckey]) Reagents: [reagentlist(src)]</font>")
msg_admin_attack("[user.name] ([user.ckey]) fed [M.name] ([M.ckey]) with [src.name] Reagents: [reagentlist(src)] (INTENT: [uppertext(user.a_intent)]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)")
var/contained = reagentlist()
M.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has been fed [name] by [user.name] ([user.ckey]) Reagents: [contained]</font>")
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Fed [name] by [M.name] ([M.ckey]) Reagents: [contained]</font>")
msg_admin_attack("[user.name] ([user.ckey]) fed [M.name] ([M.ckey]) with [name] Reagents: [contained] (INTENT: [uppertext(user.a_intent)]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)")
if(reagents.total_volume)
reagents.trans_to_ingest(M, reagents.total_volume)
qdel(src)
else
qdel(src)
reagents.trans_to_mob(M, reagents.total_volume, CHEM_INGEST)
qdel(src)
return 1
@@ -78,21 +74,20 @@
afterattack(obj/target, mob/user, proximity)
if(!proximity) return
if(target.is_open_container() != 0 && target.reagents)
if(target.is_open_container() && target.reagents)
if(!target.reagents.total_volume)
user << "\red [target] is empty. Cant dissolve pill."
user << "<span class='notice'>[target] is empty. Can't dissolve \the [src].</span>"
return
user << "\blue You dissolve the pill in [target]"
user << "<span class='notice'>You dissolve \the [src] in [target].</span>"
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Spiked \a [target] with a pill. Reagents: [reagentlist(src)]</font>")
msg_admin_attack("[user.name] ([user.ckey]) spiked \a [target] with a pill. Reagents: [reagentlist(src)] (INTENT: [uppertext(user.a_intent)]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)")
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Spiked \a [target] with a pill. Reagents: [reagentlist()]</font>")
msg_admin_attack("[user.name] ([user.ckey]) spiked \a [target] with a pill. Reagents: [reagentlist()] (INTENT: [uppertext(user.a_intent)]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)")
reagents.trans_to(target, reagents.total_volume)
for(var/mob/O in viewers(2, user))
O.show_message("\red [user] puts something in \the [target].", 1)
O.show_message("<span class='warning'>[user] puts something in \the [target].</span>", 1)
spawn(5)
qdel(src)
qdel(src)
return
@@ -1,98 +0,0 @@
/obj/item/weapon/reagent_containers/robodropper
name = "Industrial Dropper"
desc = "A larger dropper. Transfers 10 units."
icon = 'icons/obj/chemical.dmi'
icon_state = "dropper0"
amount_per_transfer_from_this = 10
possible_transfer_amounts = list(1,2,3,4,5,6,7,8,9,10)
volume = 10
var/filled = 0
afterattack(obj/target, mob/user , flag)
if(!target.reagents) return
if(filled)
if(target.reagents.total_volume >= target.reagents.maximum_volume)
user << "\red [target] is full."
return
if(!target.is_open_container() && !ismob(target) && !istype(target,/obj/item/weapon/reagent_containers/food)) //You can inject humans and food but you cant remove the shit.
user << "\red You cannot directly fill this object."
return
var/trans = 0
if(ismob(target))
if(istype(target , /mob/living/carbon/human))
var/mob/living/carbon/human/victim = target
var/obj/item/safe_thing = null
if( victim.wear_mask )
if ( victim.wear_mask.flags & MASKCOVERSEYES )
safe_thing = victim.wear_mask
if( victim.head )
if ( victim.head.flags & MASKCOVERSEYES )
safe_thing = victim.head
if(victim.glasses)
if ( !safe_thing )
safe_thing = victim.glasses
if(safe_thing)
if(!safe_thing.reagents)
safe_thing.create_reagents(100)
trans = src.reagents.trans_to(safe_thing, amount_per_transfer_from_this)
for(var/mob/O in viewers(world.view, user))
O.show_message(text("\red <B>[] tries to squirt something into []'s eyes, but fails!</B>", user, target), 1)
spawn(5)
src.reagents.reaction(safe_thing, TOUCH)
user << "\blue You transfer [trans] units of the solution."
if (src.reagents.total_volume<=0)
filled = 0
icon_state = "dropper[filled]"
return
for(var/mob/O in viewers(world.view, user))
O.show_message(text("\red <B>[] squirts something into []'s eyes!</B>", user, target), 1)
src.reagents.reaction(target, TOUCH)
var/mob/M = target
var/list/injected = list()
for(var/datum/reagent/R in src.reagents.reagent_list)
injected += R.name
var/contained = english_list(injected)
M.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has been squirted with [src.name] by [user.name] ([user.ckey]). Reagents: [contained]</font>")
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Used the [src.name] to squirt [M.name] ([M.key]). Reagents: [contained]</font>")
msg_admin_attack("[user.name] ([user.ckey]) squirted [M.name] ([M.key]) with [src.name]. Reagents: [contained] (INTENT: [uppertext(user.a_intent)]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)")
trans = src.reagents.trans_to(target, amount_per_transfer_from_this)
user << "\blue You transfer [trans] units of the solution."
if (src.reagents.total_volume<=0)
filled = 0
icon_state = "dropper[filled]"
else
if(!target.is_open_container() && !istype(target,/obj/structure/reagent_dispensers))
user << "\red You cannot directly remove reagents from [target]."
return
if(!target.reagents.total_volume)
user << "\red [target] is empty."
return
var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this)
user << "\blue You fill the dropper with [trans] units of the solution."
filled = 1
icon_state = "dropper[filled]"
return
@@ -16,32 +16,21 @@
var/list/spray_sizes = list(1,3)
volume = 250
/obj/item/weapon/reagent_containers/spray/New()
..()
src.verbs -= /obj/item/weapon/reagent_containers/verb/set_APTFT
/obj/item/weapon/reagent_containers/spray/afterattack(atom/A as mob|obj, mob/user as mob, proximity)
if(istype(A, /obj/item/weapon/storage) || istype(A, /obj/structure/table) || istype(A, /obj/structure/closet) \
|| istype(A, /obj/item/weapon/reagent_containers) || istype(A, /obj/structure/sink) || istype(A, /obj/structure/janitorialcart))
if(istype(A, /obj/item/weapon/storage) || istype(A, /obj/structure/table) || istype(A, /obj/structure/closet) || istype(A, /obj/item/weapon/reagent_containers) || istype(A, /obj/structure/sink) || istype(A, /obj/structure/janitorialcart))
return
if(istype(A, /spell))
return
if(istype(A, /obj/structure/reagent_dispensers) && get_dist(src,A) <= 1) //this block copypasted from reagent_containers/glass, for lack of a better solution
if(!A.reagents.total_volume && A.reagents)
user << "<span class='notice'>\The [A] is empty.</span>"
if(proximity)
if(standard_dispenser_refill(user, A))
return
if(reagents.total_volume >= reagents.maximum_volume)
user << "<span class='notice'>\The [src] is full.</span>"
return
var/trans = A.reagents.trans_to(src, A:amount_per_transfer_from_this)
user << "<span class='notice'>You fill \the [src] with [trans] units of the contents of \the [A].</span>"
return
if(reagents.total_volume < amount_per_transfer_from_this)
user << "<span class='notice'>\The [src] is empty!</span>"
return
@@ -63,38 +52,18 @@
/obj/item/weapon/reagent_containers/spray/proc/Spray_at(atom/A as mob|obj, mob/user as mob, proximity)
if (A.density && proximity)
A.visible_message("[usr] sprays [A] with [src].")
var/obj/D = new/obj()
D.create_reagents(amount_per_transfer_from_this)
reagents.trans_to(D, amount_per_transfer_from_this)
D.icon += D.reagents.get_color()
spawn(0)
D.reagents.reaction(A)
sleep(5)
qdel(D)
A.visible_message("[usr] sprays [A] with [src].")
reagents.trans_to(A, amount_per_transfer_from_this)
else
var/obj/effect/decal/chempuff/D = new/obj/effect/decal/chempuff(get_turf(src))
D.create_reagents(amount_per_transfer_from_this)
reagents.trans_to(D, amount_per_transfer_from_this, 1/spray_size)
D.icon += D.reagents.get_color()
var/turf/A_turf = get_turf(A)//BS12
spawn(0)
for(var/i=0, i<spray_size, i++)
step_towards(D,A)
D.reagents.reaction(get_turf(D))
for(var/atom/T in get_turf(D))
D.reagents.reaction(T)
// When spraying against the wall, also react with the wall, but
// not its contents. BS12
if(get_dist(D, A_turf) == 1 && A_turf.density)
D.reagents.reaction(A_turf)
sleep(2)
sleep(3)
qdel(D)
var/obj/effect/effect/water/chempuff/D = new/obj/effect/effect/water/chempuff(get_turf(src))
var/turf/my_target = get_turf(A)
D.create_reagents(amount_per_transfer_from_this)
if(!src)
return
reagents.trans_to_obj(D, amount_per_transfer_from_this)
D.set_color()
D.set_up(my_target, spray_size, 10)
return
/obj/item/weapon/reagent_containers/spray/attack_self(var/mob/user)
@@ -104,10 +73,9 @@
spray_size = next_in_list(spray_size, spray_sizes)
user << "<span class='notice'>You adjusted the pressure nozzle. You'll now use [amount_per_transfer_from_this] units per spray.</span>"
/obj/item/weapon/reagent_containers/spray/examine(mob/user)
if(..(user, 0) && user==src.loc)
user << "[round(src.reagents.total_volume)] units left."
if(..(user, 0) && loc == user)
user << "[round(reagents.total_volume)] units left."
return
/obj/item/weapon/reagent_containers/spray/verb/empty()
@@ -120,8 +88,7 @@
return
if(isturf(usr.loc))
usr << "<span class='notice'>You empty \the [src] onto the floor.</span>"
reagents.reaction(usr.loc)
spawn(5) src.reagents.clear_reagents()
reagents.trans_to(usr.loc, reagents.total_volume)
//space cleaner
/obj/item/weapon/reagent_containers/spray/cleaner
@@ -135,8 +102,8 @@
/obj/item/weapon/reagent_containers/spray/cleaner/New()
..()
reagents.add_reagent("cleaner", src.volume)
//pepperspray
reagents.add_reagent("cleaner", volume)
/obj/item/weapon/reagent_containers/spray/pepper
name = "pepperspray"
desc = "Manufactured by UhangInc, used to blind and down an opponent quickly."
@@ -147,7 +114,6 @@
volume = 40
var/safety = 1
/obj/item/weapon/reagent_containers/spray/pepper/New()
..()
reagents.add_reagent("condensedcapsaicin", 40)
@@ -166,7 +132,6 @@
return
..()
//water flower
/obj/item/weapon/reagent_containers/spray/waterflower
name = "water flower"
desc = "A seemingly innocent sunflower...with a twist."
@@ -181,7 +146,6 @@
..()
reagents.add_reagent("water", 10)
//chemsprayer
/obj/item/weapon/reagent_containers/spray/chemsprayer
name = "chem sprayer"
desc = "A utility used to spray large amounts of reagent in a given area."
@@ -194,47 +158,27 @@
volume = 600
origin_tech = "combat=3;materials=3;engineering=3"
//this is a big copypasta clusterfuck, but it's still better than it used to be!
/obj/item/weapon/reagent_containers/spray/chemsprayer/Spray_at(atom/A as mob|obj)
var/Sprays[3]
for(var/i=1, i<=3, i++) // intialize sprays
if(src.reagents.total_volume < 1) break
var/obj/effect/decal/chempuff/D = new/obj/effect/decal/chempuff(get_turf(src))
D.create_reagents(amount_per_transfer_from_this)
src.reagents.trans_to(D, amount_per_transfer_from_this)
D.icon += D.reagents.get_color()
Sprays[i] = D
/obj/item/weapon/reagent_containers/spray/chemsprayer/Spray_at(atom/A as mob|obj)
var/direction = get_dir(src, A)
var/turf/T = get_turf(A)
var/turf/T1 = get_step(T,turn(direction, 90))
var/turf/T2 = get_step(T,turn(direction, -90))
var/list/the_targets = list(T,T1,T2)
for(var/i=1, i<=Sprays.len, i++)
spawn()
var/obj/effect/decal/chempuff/D = Sprays[i]
if(!D) continue
// Spreads the sprays a little bit
var/turf/my_target = pick(the_targets)
the_targets -= my_target
for(var/j=1, j<=rand(6,8), j++)
step_towards(D, my_target)
D.reagents.reaction(get_turf(D))
for(var/atom/t in get_turf(D))
D.reagents.reaction(t)
sleep(2)
qdel(D)
var/turf/T2 = get_step(T,turn(direction, -90))
var/list/the_targets = list(T, T1, T2)
for(var/a = 1 to 3)
spawn(0)
if(reagents.total_volume < 1) break
var/obj/effect/effect/water/chempuff/D = new/obj/effect/effect/water/chempuff(get_turf(src))
var/turf/my_target = the_targets[a]
D.create_reagents(amount_per_transfer_from_this)
if(!src)
return
reagents.trans_to_obj(D, amount_per_transfer_from_this)
D.set_color()
D.set_up(my_target, rand(6, 8), 2)
return
// Plant-B-Gone
/obj/item/weapon/reagent_containers/spray/plantbgone // -- Skie
/obj/item/weapon/reagent_containers/spray/plantbgone
name = "Plant-B-Gone"
desc = "Kills those pesky weeds!"
icon = 'icons/obj/hydroponics_machines.dmi'
@@ -242,16 +186,14 @@
item_state = "plantbgone"
volume = 100
/obj/item/weapon/reagent_containers/spray/plantbgone/New()
..()
reagents.add_reagent("plantbgone", 100)
/obj/item/weapon/reagent_containers/spray/plantbgone/afterattack(atom/A as mob|obj, mob/user as mob, proximity)
if(!proximity) return
if (istype(A, /obj/effect/blob)) // blob damage in blob code
if(istype(A, /obj/effect/blob)) // blob damage in blob code
return
..()
@@ -13,12 +13,14 @@
icon_state = "0"
matter = list("glass" = 150)
amount_per_transfer_from_this = 5
possible_transfer_amounts = null //list(5,10,15)
possible_transfer_amounts = null
volume = 15
w_class = 1
sharp = 1
var/mode = SYRINGE_DRAW
var/image/filling //holds a reference to the current filling overlay
var/visible_name = "a syringe"
var/time = 30
on_reagent_change()
update_icon()
@@ -47,18 +49,17 @@
update_icon()
attackby(obj/item/I as obj, mob/user as mob)
return
afterattack(obj/target, mob/user, proximity)
if(!proximity) return
if(!target.reagents) return
if(mode == SYRINGE_BROKEN)
user << "\red This syringe is broken!"
if(!proximity || !target.reagents)
return
if (user.a_intent == I_HURT && ismob(target))
if(mode == SYRINGE_BROKEN)
user << "<span class='warning'>This syringe is broken!</span>"
return
if(user.a_intent == I_HURT && ismob(target))
if((CLUMSY in user.mutations) && prob(50))
target = user
syringestab(target, user)
@@ -68,86 +69,89 @@
switch(mode)
if(SYRINGE_DRAW)
if(reagents.total_volume >= reagents.maximum_volume)
user << "\red The syringe is full."
if(!reagents.get_free_space())
user << "<span class='warning'>The syringe is full.</span>"
mode = SYRINGE_INJECT
return
if(ismob(target))//Blood!
if(istype(target, /mob/living/carbon/slime))
user << "\red You are unable to locate any blood."
if(reagents.has_reagent("blood"))
user << "<span class='notice'>There is already a blood sample in this syringe.</span>"
return
if(src.reagents.has_reagent("blood"))
user << "\red There is already a blood sample in this syringe"
return
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
if(istype(target, /mob/living/carbon))
if(istype(target, /mob/living/carbon/slime))
user << "<span class='warning'>You are unable to locate any blood.</span>"
return
var/amount = reagents.get_free_space()
var/mob/living/carbon/T = target
if(!T.dna)
usr << "You are unable to locate any blood. (To be specific, your target seems to be missing their DNA datum)"
user << "<span class='warning'>You are unable to locate any blood. (To be specific, your target seems to be missing their DNA datum).</span>"
return
if(NOCLONE in T.mutations) //target done been et, no more blood in him
user << "\red You are unable to locate any blood."
user << "<span class='warning'>You are unable to locate any blood.</span>"
return
var/datum/reagent/B
if(istype(T,/mob/living/carbon/human))
if(istype(T, /mob/living/carbon/human))
var/mob/living/carbon/human/H = T
if(H.species && H.species.flags & NO_BLOOD)
H.reagents.trans_to(src,amount)
H.reagents.trans_to_obj(src, amount)
else
B = T.take_blood(src,amount)
B = T.take_blood(src, amount)
else
B = T.take_blood(src,amount)
if (B)
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]"
reagents.reagent_list += B
reagents.update_total()
on_reagent_change()
reagents.handle_reactions()
user << "<span class='notice'>You take a blood sample from [target].</span>"
for(var/mob/O in viewers(4, user))
O.show_message("\red [user] takes a blood sample from [target].", 1)
O.show_message("<span class='notice'>[user] takes a blood sample from [target].</span>", 1)
else //if not mob
if(!target.reagents.total_volume)
user << "\red [target] is empty."
user << "<span class='notice'>[target] is empty.</span>"
return
if(!target.is_open_container() && !istype(target,/obj/structure/reagent_dispensers) && !istype(target,/obj/item/slime_extract))
user << "\red You cannot directly remove reagents from this object."
if(!target.is_open_container() && !istype(target, /obj/structure/reagent_dispensers) && !istype(target, /obj/item/slime_extract))
user << "<span class='notice'>You cannot directly remove reagents from this object.</span>"
return
var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this) // transfer from, transfer to - who cares?
var/trans = target.reagents.trans_to_obj(src, amount_per_transfer_from_this)
user << "<span class='notice'>You fill the syringe with [trans] units of the solution.</span>"
update_icon()
user << "\blue You fill the syringe with [trans] units of the solution."
if (reagents.total_volume >= reagents.maximum_volume)
mode=!mode
if(!reagents.get_free_space())
mode = SYRINGE_INJECT
update_icon()
if(SYRINGE_INJECT)
if(!reagents.total_volume)
user << "\red The syringe is empty."
user << "<span class='notice'>The syringe is empty.</span>"
mode = SYRINGE_DRAW
return
if(istype(target, /obj/item/weapon/implantcase/chem))
return
if(!target.is_open_container() && !ismob(target) && !istype(target, /obj/item/weapon/reagent_containers/food) && !istype(target, /obj/item/slime_extract) && !istype(target, /obj/item/clothing/mask/smokable/cigarette) && !istype(target, /obj/item/weapon/storage/fancy/cigarettes))
user << "\red You cannot directly fill this object."
user << "<span class='notice'>You cannot directly fill this object.</span>"
return
if(target.reagents.total_volume >= target.reagents.maximum_volume)
user << "\red [target] is full."
if(!target.reagents.get_free_space())
user << "<span class='notice'>[target] is full.</span>"
return
if(ismob(target) && target != user)
var/time = 30 //Injecting through a hardsuit takes longer due to needing to find a port.
var/injtime = time //Injecting through a hardsuit takes longer due to needing to find a port.
if(istype(target,/mob/living/carbon/human))
if(istype(target, /mob/living/carbon/human))
var/mob/living/carbon/human/H = target
if(H.wear_suit)
if(istype(H.wear_suit,/obj/item/clothing/suit/space))
time = 60
if(istype(H.wear_suit, /obj/item/clothing/suit/space))
injtime = injtime * 2
else if(!H.can_inject(user, 1))
return
@@ -157,55 +161,43 @@
if(!M.can_inject(user, 1))
return
for(var/mob/O in viewers(world.view, user))
if(time == 30)
O.show_message(text("\red <B>[] is trying to inject []!</B>", user, target), 1)
else
O.show_message(text("\red <B>[] begins hunting for an injection port on []'s suit!</B>", user, target), 1)
if(!do_mob(user, target, time)) return
for(var/mob/O in viewers(world.view, user))
O.show_message(text("\red [] injects [] with the syringe!", user, target), 1)
if(istype(target,/mob/living))
var/mob/living/M = target
var/list/injected = list()
for(var/datum/reagent/R in src.reagents.reagent_list)
injected += R.name
var/contained = english_list(injected)
M.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has been injected with [src.name] by [user.name] ([user.ckey]). Reagents: [contained]</font>")
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Used the [src.name] to inject [M.name] ([M.key]). Reagents: [contained]</font>")
msg_admin_attack("[user.name] ([user.ckey]) injected [M.name] ([M.key]) with [src.name]. Reagents: [contained] (INTENT: [uppertext(user.a_intent)]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)")
src.reagents.reaction(target, INGEST)
if(ismob(target) && target == user)
src.reagents.reaction(target, INGEST)
spawn(5)
var/datum/reagent/blood/B
for(var/datum/reagent/blood/d in src.reagents.reagent_list)
B = d
break
var/trans
if(B && istype(target,/mob/living/carbon))
var/mob/living/carbon/C = target
C.inject_blood(src,5)
if(injtime == time)
user.visible_message("<span class='warning'>[user] is trying to inject [target] with [visible_name]!</span>")
else
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."
if (reagents.total_volume <= 0 && mode==SYRINGE_INJECT)
mode = SYRINGE_DRAW
update_icon()
user.visible_message("<span class='warning'>[user] begins hunting for an injection port on [target]'s suit!</span>")
if(!do_mob(user, target, injtime))
return
user.visible_message("<span class='warning'>[user] injects [target] with the syringe!</span>")
if(istype(target, /mob/living))
var/mob/living/M = target
var/contained = reagentlist()
M.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has been injected with [name] by [user.name] ([user.ckey]). Reagents: [contained]</font>")
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Used the [name] to inject [M.name] ([M.key]). Reagents: [contained]</font>")
msg_admin_attack("[user.name] ([user.ckey]) injected [M.name] ([M.key]) with [name]. Reagents: [contained] (INTENT: [uppertext(user.a_intent)]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)")
var/trans
if(ismob(target))
trans = reagents.trans_to_mob(target, amount_per_transfer_from_this, CHEM_BLOOD)
else
trans = reagents.trans_to(target, amount_per_transfer_from_this)
user << "<span class='notice'>You inject [trans] units of the solution. The syringe now contains [src.reagents.total_volume] units.</span>"
if (reagents.total_volume <= 0 && mode == SYRINGE_INJECT)
mode = SYRINGE_DRAW
update_icon()
return
update_icon()
overlays.Cut()
if(mode == SYRINGE_BROKEN)
icon_state = "broken"
overlays.Cut()
return
var/rounded_vol = round(reagents.total_volume,5)
overlays.Cut()
var/rounded_vol = round(reagents.total_volume, round(reagents.maximum_volume / 3))
if(ismob(loc))
var/injoverlay
switch(mode)
@@ -225,7 +217,6 @@
filling.color = reagents.get_color()
overlays += filling
proc/syringestab(mob/living/carbon/target as mob, mob/living/carbon/user as mob)
user.attack_log += "\[[time_stamp()]\]<font color='red'> Attacked [target.name] ([target.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)])</font>"
@@ -234,8 +225,10 @@
if(istype(target, /mob/living/carbon/human))
var/mob/living/carbon/human/H = target
var/target_zone = ran_zone(check_zone(user.zone_sel.selecting, target))
var/obj/item/organ/external/affecting = target:get_organ(target_zone)
var/obj/item/organ/external/affecting = H.get_organ(target_zone)
if (!affecting || (affecting.status & ORGAN_DESTROYED) || affecting.is_stump())
user << "<span class='danger'>They are missing that limb!</span>"
@@ -243,160 +236,58 @@
var/hit_area = affecting.name
var/mob/living/carbon/human/H = target
if((user != target) && H.check_shields(7, "the [src.name]"))
return
if (target != user && target.getarmor(target_zone, "melee") > 5 && prob(50))
if (target != user && H.getarmor(target_zone, "melee") > 5 && prob(50))
for(var/mob/O in viewers(world.view, user))
O.show_message(text("\red <B>[user] tries to stab [target] in \the [hit_area] with [src.name], but the attack is deflected by armor!</B>"), 1)
user.remove_from_mob(src)
qdel(src)
return
for(var/mob/O in viewers(world.view, user))
O.show_message(text("\red <B>[user] stabs [target] in \the [hit_area] with [src.name]!</B>"), 1)
user.visible_message("<span class='danger'>[user] stabs [target] in \the [hit_area] with [src.name]!</span>")
if(affecting.take_damage(3))
target:UpdateDamageIcon()
H.UpdateDamageIcon()
else
for(var/mob/O in viewers(world.view, user))
O.show_message(text("\red <B>[user] stabs [target] with [src.name]!</B>"), 1)
user.visible_message("<span class='danger'>[user] stabs [target] with [src.name]!</span>")
target.take_organ_damage(3)// 7 is the same as crowbar punch
src.reagents.reaction(target, INGEST)
var/syringestab_amount_transferred = rand(0, (reagents.total_volume - 5)) //nerfed by popular demand
src.reagents.trans_to(target, syringestab_amount_transferred)
src.break_syringe(target, user)
reagents.trans_to_mob(target, syringestab_amount_transferred, CHEM_BLOOD)
break_syringe(target, user)
proc/break_syringe(mob/living/carbon/target, mob/living/carbon/user)
src.desc += " It is broken."
src.mode = SYRINGE_BROKEN
desc += " It is broken."
mode = SYRINGE_BROKEN
if(target)
src.add_blood(target)
add_blood(target)
if(user)
src.add_fingerprint(user)
src.update_icon()
add_fingerprint(user)
update_icon()
/obj/item/weapon/reagent_containers/ld50_syringe
/obj/item/weapon/reagent_containers/syringe/ld50_syringe
name = "Lethal Injection Syringe"
desc = "A syringe used for lethal injections."
icon = 'icons/obj/syringe.dmi'
item_state = "syringe_0"
icon_state = "0"
amount_per_transfer_from_this = 50
possible_transfer_amounts = null //list(5,10,15)
volume = 50
var/mode = SYRINGE_DRAW
visible_name = "a giant syringe"
time = 300
on_reagent_change()
update_icon()
pickup(mob/user)
afterattack(obj/target, mob/user, flag)
if(mode == SYRINGE_DRAW && ismob(target)) // No drawing 50 units of blood at once
user << "<span class='notice'>This needle isn't designed for drawing blood.</span>"
return
if(user.a_intent == "hurt" && ismob(target)) // No instant injecting
user << "<span class='notice'>This syringe is too big to stab someone with it.</span>"
..()
update_icon()
dropped(mob/user)
..()
update_icon()
attack_self(mob/user as mob)
mode = !mode
update_icon()
attack_hand()
..()
update_icon()
attackby(obj/item/I as obj, mob/user as mob)
return
afterattack(obj/target, mob/user , flag)
if(!target.reagents) return
switch(mode)
if(SYRINGE_DRAW)
if(reagents.total_volume >= reagents.maximum_volume)
user << "\red The syringe is full."
return
if(ismob(target))
if(istype(target, /mob/living/carbon))//I Do not want it to suck 50 units out of people
usr << "This needle isn't designed for drawing blood."
return
else //if not mob
if(!target.reagents.total_volume)
user << "\red [target] is empty."
return
if(!target.is_open_container() && !istype(target,/obj/structure/reagent_dispensers))
user << "\red You cannot directly remove reagents from this object."
return
var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this) // transfer from, transfer to - who cares?
user << "\blue You fill the syringe with [trans] units of the solution."
if (reagents.total_volume >= reagents.maximum_volume)
mode=!mode
update_icon()
if(SYRINGE_INJECT)
if(!reagents.total_volume)
user << "\red The Syringe is empty."
return
if(istype(target, /obj/item/weapon/implantcase/chem))
return
if(!target.is_open_container() && !ismob(target) && !istype(target, /obj/item/weapon/reagent_containers/food))
user << "\red You cannot directly fill this object."
return
if(target.reagents.total_volume >= target.reagents.maximum_volume)
user << "\red [target] is full."
return
if(ismob(target) && target != user)
for(var/mob/O in viewers(world.view, user))
O.show_message(text("\red <B>[] is trying to inject [] with a giant syringe!</B>", user, target), 1)
if(!do_mob(user, target, 300)) return
for(var/mob/O in viewers(world.view, user))
O.show_message(text("\red [] injects [] with a giant syringe!", user, target), 1)
src.reagents.reaction(target, INGEST)
if(ismob(target) && target == user)
src.reagents.reaction(target, INGEST)
spawn(5)
var/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."
if (reagents.total_volume >= reagents.maximum_volume && mode==SYRINGE_INJECT)
mode = SYRINGE_DRAW
update_icon()
return
update_icon()
var/rounded_vol = round(reagents.total_volume,50)
if(ismob(loc))
var/mode_t
switch(mode)
if (SYRINGE_DRAW)
mode_t = "d"
if (SYRINGE_INJECT)
mode_t = "i"
icon_state = "[mode_t][rounded_vol]"
else
icon_state = "[rounded_vol]"
item_state = "syringe_[rounded_vol]"
////////////////////////////////////////////////////////////////////////////////
/// Syringes. END
////////////////////////////////////////////////////////////////////////////////
/obj/item/weapon/reagent_containers/syringe/inaprovaline
name = "Syringe (inaprovaline)"
desc = "Contains inaprovaline - used to stabilize patients."
@@ -435,40 +326,9 @@
mode = SYRINGE_INJECT
update_icon()
/obj/item/weapon/reagent_containers/ld50_syringe/choral
/obj/item/weapon/reagent_containers/syringe/ld50_syringe/choral
New()
..()
reagents.add_reagent("chloralhydrate", 50)
mode = SYRINGE_INJECT
update_icon()
//Robot syringes
//Not special in any way, code wise. They don't have added variables or procs.
/obj/item/weapon/reagent_containers/syringe/robot/antitoxin
name = "Syringe (anti-toxin)"
desc = "Contains anti-toxins."
New()
..()
reagents.add_reagent("anti_toxin", 15)
mode = SYRINGE_INJECT
update_icon()
/obj/item/weapon/reagent_containers/syringe/robot/inoprovaline
name = "Syringe (inoprovaline)"
desc = "Contains inaprovaline - used to stabilize patients."
New()
..()
reagents.add_reagent("inaprovaline", 15)
mode = SYRINGE_INJECT
update_icon()
/obj/item/weapon/reagent_containers/syringe/robot/mixed
name = "Syringe (mixed)"
desc = "Contains inaprovaline & anti-toxins."
New()
..()
reagents.add_reagent("inaprovaline", 7)
reagents.add_reagent("anti_toxin", 8)
mode = SYRINGE_INJECT
update_icon()
+1 -1
View File
@@ -66,7 +66,7 @@ using metal and glass, it uses glass and reagents (usually sulfuric acis).
/obj/machinery/r_n_d/circuit_imprinter/dismantle()
for(var/obj/I in component_parts)
if(istype(I, /obj/item/weapon/reagent_containers/glass/beaker))
reagents.trans_to(I, reagents.total_volume)
reagents.trans_to_obj(I, reagents.total_volume)
if(g_amount >= 3750)
var/obj/item/stack/sheet/glass/G = new /obj/item/stack/sheet/glass(loc)
G.amount = round(g_amount / 3750)
+1 -1
View File
@@ -61,7 +61,7 @@ Note: Must be placed west/left of and R&D console to function.
/obj/machinery/r_n_d/protolathe/dismantle()
for(var/obj/I in component_parts)
if(istype(I, /obj/item/weapon/reagent_containers/glass/beaker))
reagents.trans_to(I, reagents.total_volume)
reagents.trans_to_obj(I, reagents.total_volume)
if(m_amount >= 3750)
var/obj/item/stack/sheet/metal/G = new /obj/item/stack/sheet/metal(loc)
G.amount = round(m_amount / G.perunit)
@@ -1,74 +1,5 @@
//chemistry stuff here so that it can be easily viewed/modified
datum
reagent
tungsten
name = "Tungsten"
id = "tungsten"
description = "A chemical element, and a strong oxidising agent."
reagent_state = SOLID
color = "#DCDCDC" // rgb: 220, 220, 220, silver
lithiumsodiumtungstate
name = "Lithium Sodium Tungstate"
id = "lithiumsodiumtungstate"
description = "A reducing agent for geological compounds."
reagent_state = LIQUID
color = "#C0C0C0" // rgb: 192, 192, 192, darker silver
ground_rock
name = "Ground Rock"
id = "ground_rock"
description = "A fine dust made of ground up rock."
reagent_state = SOLID
color = "#A0522D" //rgb: 160, 82, 45, brown
density_separated_sample
name = "Density separated sample"
id = "density_separated_sample"
description = "A watery paste used in chemical analysis, there are some chunks floating in it."
reagent_state = LIQUID
color = "#DEB887" //rgb: 222, 184, 135, light brown
analysis_sample
name = "Analysis liquid"
id = "analysis_sample"
description = "A watery paste used in chemical analysis."
reagent_state = LIQUID
color = "#F5FFFA" //rgb: 245, 255, 250, almost white
chemical_waste
name = "Chemical Waste"
id = "chemical_waste"
description = "A viscous, toxic liquid left over from many chemical processes."
reagent_state = LIQUID
color = "#ADFF2F" //rgb: 173, 255, 47, toxic green
datum
chemical_reaction
lithiumsodiumtungstate //LiNa2WO4, not the easiest chem to mix
name = "Lithium Sodium Tungstate"
id = "lithiumsodiumtungstate"
result = "lithiumsodiumtungstate"
required_reagents = list("lithium" = 1, "sodium" = 2, "tungsten" = 1, "oxygen" = 4)
result_amount = 8
density_separated_liquid
name = "Density separated sample"
id = "density_separated_sample"
result = "density_separated_sample"
secondary_results = list("chemical_waste" = 1)
required_reagents = list("ground_rock" = 1, "lithiumsodiumtungstate" = 2)
result_amount = 2
analysis_liquid
name = "Analysis sample"
id = "analysis_sample"
result = "analysis_sample"
secondary_results = list("chemical_waste" = 1)
required_reagents = list("density_separated_sample" = 5)
result_amount = 4
requires_heating = 1
/obj/item/weapon/reagent_containers/glass/solution_tray
name = "solution tray"
@@ -1,20 +1,3 @@
datum/reagent/coolant
name = "Coolant"
id = "coolant"
description = "Industrial cooling substance."
reagent_state = LIQUID
color = "#C8A5DC" // rgb: 200, 165, 220
datum/chemical_reaction/coolant
name = "Coolant"
id = "coolant"
result = "coolant"
required_reagents = list("tungsten" = 1, "oxygen" = 1, "water" = 1)
result_amount = 3
/obj/structure/reagent_dispensers/coolanttank
name = "coolant tank"
desc = "A tank of industrial coolant"
+2 -4
View File
@@ -144,9 +144,8 @@
var/obj/item/weapon/reagent_containers/container = tool
var/trans = container.reagents.trans_to(target, container.amount_per_transfer_from_this)
var/trans = container.reagents.trans_to_mob(target, container.amount_per_transfer_from_this, CHEM_BLOOD) //technically it's contact, but the reagents are being applied to internal tissue
if (trans > 0)
container.reagents.reaction(target, INGEST) //technically it's contact, but the reagents are being applied to internal tissue
if(container.reagents.has_reagent("peridaxon"))
affected.status &= ~ORGAN_DEAD
@@ -162,8 +161,7 @@
var/obj/item/weapon/reagent_containers/container = tool
var/trans = container.reagents.trans_to(target, container.amount_per_transfer_from_this)
container.reagents.reaction(target, INGEST) //technically it's contact, but the reagents are being applied to internal tissue
var/trans = container.reagents.trans_to_mob(target, container.amount_per_transfer_from_this, CHEM_BLOOD)
user.visible_message("\red [user]'s hand slips, applying [trans] units of the solution to the wrong place in [target]'s [affected.name] with the [tool]!" , \
"\red Your hand slips, applying [trans] units of the solution to the wrong place in [target]'s [affected.name] with the [tool]!")
+2 -2
View File
@@ -55,10 +55,10 @@ datum/reagent/antibodies
reagent_state = LIQUID
color = "#0050F0"
reaction_mob(var/mob/M, var/method=TOUCH, var/volume)
reaction_mob(var/mob/M, var/method=CHEM_TOUCH, var/volume)
if(istype(M,/mob/living/carbon))
var/mob/living/carbon/C = M
if(src.data && method == INGEST)
if(src.data && method == CHEM_INGEST)
//if(C.virus2) if(src.data["antibodies"] & C.virus2.antigen)
// C.virus2.dead = 1
C.antibodies |= src.data["antibodies"]
+1 -1
View File
@@ -134,7 +134,7 @@
if (locate(/datum/reagent/toxin) in beaker.reagents.reagent_list)
for(var/datum/reagent/toxin/T in beaker.reagents.reagent_list)
toxins += max(T.toxpwr,1)
toxins += max(T.strength,1)
beaker.reagents.remove_reagent(T.id,1)
nanomanager.update_uis(src)
+1 -1
View File
@@ -290,7 +290,7 @@
if(c_data)
data = c_data
else
data = pick("bicaridine", "kelotane", "dylovene", "inaprovaline", "space_drugs", "sugar",
data = pick("bicaridine", "kelotane", "anti_toxin", "inaprovaline", "space_drugs", "sugar",
"tramadol", "dexalin", "cryptobiolin", "impedrezene", "hyperzine", "ethylredoxrazine",
"mindbreaker", "nutriment")
var/datum/reagent/R = chemical_reagents_list[data]
+10 -8
View File
@@ -99,9 +99,15 @@
#define DOOR_CRUSH_DAMAGE 10
#define HUNGER_FACTOR 0.05 // Factor of how fast mob nutrition decreases
#define REAGENTS_METABOLISM 0.2 // How many units of reagent are consumed per tick, by default.
#define REAGENTS_EFFECT_MULTIPLIER (REAGENTS_METABOLISM / 0.4) // By defining the effect multiplier this way, it'll exactly adjust
// all effects according to how they originally were with the 0.4 metabolism
#define REM 0.2 // Means 'Reagent Effect Multiplier'. This is how many units of reagent are consumed per tick
#define CHEM_TOUCH 1
#define CHEM_INGEST 2
#define CHEM_BLOOD 3
#define MINIMUM_CHEMICAL_VOLUME 0.01
#define SOLID 1
#define LIQUID 2
#define GAS 3
#define REAGENTS_OVERDOSE 30
#define MINIMUM_AIR_RATIO_TO_SUSPEND 0.05 // Minimum ratio of air that must move to/from a tile to suspend group processing
#define MINIMUM_AIR_TO_SUSPEND (MOLES_CELLSTANDARD * MINIMUM_AIR_RATIO_TO_SUSPEND) // Minimum amount of air that has to move before a group processing can be suspended
@@ -744,10 +750,6 @@ var/list/be_special_flags = list(
#define ATMOS_DEFAULT_VOLUME_MIXER 200 // L.
#define ATMOS_DEFAULT_VOLUME_PIPE 70 // L.
// Reagent metabolism defines.
#define FOOD_METABOLISM 0.4
#define ALCOHOL_METABOLISM 0.1
// Chemistry.
#define CHEM_SYNTH_ENERGY 500 // How much energy does it take to synthesize 1 unit of chemical, in Joules.
@@ -969,4 +971,4 @@ var/list/be_special_flags = list(
#endif
#ifndef CUSTOM_ITEM_MOB
#define CUSTOM_ITEM_MOB 'icons/mob/custom_items_mob.dmi'
#endif
#endif
+7 -7
View File
@@ -221,8 +221,8 @@
"aem" = (/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor,/area/security/main)
"aen" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{dir = 2; icon_state = "redcorner"},/area/security/main)
"aeo" = (/obj/structure/table/rack,/obj/structure/window/reinforced,/obj/machinery/door/window/brigdoor{dir = 1; name = "Weapons locker"; req_access = list(3)},/obj/structure/window/reinforced{dir = 4},/obj/item/clothing/suit/armor/laserproof{pixel_x = 2; pixel_y = 2},/obj/item/clothing/suit/armor/laserproof{pixel_x = -2; pixel_y = -2},/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/security/armoury)
"aep" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor{dir = 8; icon_state = "redcorner"},/area/security/main)
"aeq" = (/obj/structure/table/rack,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/window/brigdoor{dir = 1; name = "Weapons locker"; req_access = list(3)},/obj/item/clothing/suit/armor/bulletproof{pixel_x = 2; pixel_y = 2},/obj/item/clothing/suit/armor/bulletproof{pixel_x = -2; pixel_y = -2},/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/security/armoury)
"aep" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor{dir = 8; icon_state = "redcorner"},/area/security/main)
"aeq" = (/obj/structure/table/rack,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/window/brigdoor{dir = 1; name = "Weapons locker"; req_access = list(3)},/obj/item/clothing/suit/armor/bulletproof{pixel_x = 2; pixel_y = 2},/obj/item/clothing/suit/armor/bulletproof{pixel_x = -2; pixel_y = -2},/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/security/armoury)
"aer" = (/obj/structure/table,/obj/item/weapon/folder/red,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/security/main)
"aes" = (/obj/structure/table,/obj/item/weapon/book/manual/security_space_law,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor,/area/security/main)
"aet" = (/obj/structure/bed/chair/office/dark{dir = 8},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor,/area/security/main)
@@ -268,9 +268,9 @@
"afh" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/security/main)
"afi" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/security/main)
"afj" = (/obj/machinery/firealarm{dir = 4; pixel_x = 24},/turf/simulated/floor,/area/security/main)
"afk" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/security_starboard)
"afl" = (/obj/structure/closet/crate/secure{name = "FOR DISPOSAL"; req_access = list(58)},/obj/item/clothing/glasses/sunglasses/blindfold,/obj/item/clothing/mask/balaclava,/obj/effect/decal/cleanable/cobweb2,/obj/item/clothing/mask/muzzle,/obj/item/weapon/reagent_containers/ld50_syringe/choral,/obj/effect/landmark{name = "blobstart"},/turf/simulated/floor/plating,/area/maintenance/security_port)
"afm" = (/obj/machinery/deployable/barrier,/obj/structure/sign/securearea{name = "\improper ARMORY"; pixel_y = 32},/obj/machinery/camera/network/security{c_tag = "Armoury"},/turf/simulated/floor{icon_state = "delivery"},/area/security/warden)
"afk" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/security_starboard)
"afl" = (/obj/structure/closet/crate/secure{name = "FOR DISPOSAL"; req_access = list(58)},/obj/item/clothing/glasses/sunglasses/blindfold,/obj/item/clothing/mask/balaclava,/obj/effect/decal/cleanable/cobweb2,/obj/item/clothing/mask/muzzle,/obj/item/weapon/reagent_containers/syringe/ld50_syringe/choral,/obj/effect/landmark{name = "blobstart"},/turf/simulated/floor/plating,/area/maintenance/security_port)
"afm" = (/obj/machinery/deployable/barrier,/obj/structure/sign/securearea{name = "\improper ARMORY"; pixel_y = 32},/obj/machinery/camera/network/security{c_tag = "Armoury"},/turf/simulated/floor{icon_state = "delivery"},/area/security/warden)
"afn" = (/turf/simulated/floor/plating,/obj/structure/shuttle/engine/propulsion/burst{dir = 4},/turf/simulated/shuttle/wall{icon_state = "swall_f6"; dir = 2},/area/shuttle/escape_pod3/station)
"afo" = (/turf/simulated/shuttle/wall{icon_state = "swall12"; dir = 2},/area/shuttle/escape_pod3/station)
"afp" = (/turf/simulated/shuttle/wall{icon_state = "swall_s10"; dir = 2},/area/shuttle/escape_pod3/station)
@@ -904,10 +904,10 @@
"art" = (/obj/structure/table,/obj/item/weapon/newspaper,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/security/prison)
"aru" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 1},/turf/simulated/floor,/area/security/prison)
"arv" = (/obj/item/device/radio/intercom{freerange = 1; frequency = 1459; name = "Station Intercom (General)"; pixel_x = -30},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/camera/network/security{c_tag = "Security - Brig West"; dir = 4},/turf/simulated/floor{icon_state = "red"; dir = 8},/area/security/brig)
"arw" = (/obj/structure/table,/obj/machinery/vending/wallmed1{pixel_y = -32},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor,/area/security/prison)
"arw" = (/obj/structure/table,/obj/machinery/vending/wallmed1{pixel_y = -32},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor,/area/security/prison)
"arx" = (/turf/simulated/wall/r_wall,/area/security/lobby)
"ary" = (/obj/machinery/button/remote/airlock{id = "visitdoor"; name = "Visitation Access"; pixel_y = -28},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor{dir = 8; icon_state = "redcorner"},/area/security/lobby)
"arz" = (/obj/machinery/computer/secure_data,/turf/simulated/floor{icon_state = "white"},/area/security/detectives_office)
"arz" = (/obj/machinery/computer/secure_data,/turf/simulated/floor{icon_state = "white"},/area/security/detectives_office)
"arA" = (/turf/simulated/wall/r_wall,/area/hallway/primary/fore)
"arB" = (/obj/structure/cable/yellow{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plating/airless,/area/solar/fore)
"arC" = (/obj/machinery/light,/obj/structure/table,/obj/item/device/mass_spectrometer,/obj/item/device/reagent_scanner,/obj/machinery/camera/network/security{c_tag = "Security - Forensic Office Aft"; dir = 1},/turf/simulated/floor{icon_state = "white"},/area/security/detectives_office)