Extinguisher + Container Reworks (#4793)

Reworked how slipping on tiles work. If there is too much lube/water on one tile, it will spread to all adjacent tiles.

Fixed a potential bug where spilling copious amounts of water on a tile will turn it to ice.

Containers are much more saner now. They all share a standard system, unless specified.

You can drink from any open holdable container using help intent. You can splash the contents of the container on anything via harm intent.

Sinks are more saner, you can refill or empty them easier with various refill amounts.

Removed silly exclusive cyborg limb checking for hyposprays.

Added a new chemsprayer, the "Xenoblaster" which is a significantly weaker chem sprayer. Two can be found in xenobiology.

Large reagent containers (beer kegs, water tanks, fuel tanks) now share a system together. Both can leak their reagents via harm intent with a wrench, and bother can accept any sort of reagent, with exception to the fuel tank.

Large reagent container leaking happens over time as opposed to just leaking every time it moves.

New chemical, Monoammonium phosphate. Monoammonium phosphate is a fertilizer and also a potent fire extinguishing and preventing chemical. It can be made with 1 part ammonia, 1 part sulfuric acid, 1 part sodium, 1 part phosphorus.

All extinguishers now have monoammonium phosphate in them instead of water.

Extinguishers can hold any reagent, however they must be filled using an extinguisher refiller cartridge. These can be ordered or found in atmospherics.

Nerfed the extinguisher range so it only sprays in a 3x3 radius.

Mini-extinguishers spray in a 1x1 radius.

Adds Monoammonium phosphate containers across the station.

Most watertanks are replaced with Monoammonium phosphate containers.
This commit is contained in:
BurgerLUA
2018-08-05 20:14:00 +03:00
committed by Erki
parent 4cd7b99e43
commit 1620d81661
54 changed files with 820 additions and 523 deletions
+2 -2
View File
@@ -22,8 +22,8 @@
if (istype(src.loc.loc, /obj/structure/reagent_dispensers/fueltank/))
var/obj/structure/reagent_dispensers/fueltank/tank = src.loc.loc
if (tank && tank.modded)
tank.explode()
tank.ex_act(3.0)
spark(src, 4, cardinal)
return 1
+1 -1
View File
@@ -23,7 +23,7 @@
/mob/abstract/conveyor_act()
return
/mob/abstract/ex_act()
/mob/abstract/ex_act(var/severity = 2.0)
return
/mob/abstract/singularity_act()
@@ -141,7 +141,7 @@
if(M.a_intent == I_HURT)
set_flee_target(M)
/mob/living/simple_animal/cat/ex_act()
/mob/living/simple_animal/cat/ex_act(var/severity = 2.0)
. = ..()
set_flee_target(src.loc)
@@ -289,7 +289,7 @@
if (health < healthbefore)
instant_aggro()
/mob/living/simple_animal/hostile/bear/ex_act()
/mob/living/simple_animal/hostile/bear/ex_act(var/severity = 2.0)
var/healthbefore = health
..()
spawn(1)
+1 -1
View File
@@ -283,7 +283,7 @@
qdel(src)
return TRUE
/obj/item/projectile/ex_act()
/obj/item/projectile/ex_act(var/severity = 2.0)
return //explosions probably shouldn't delete projectiles
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -182,7 +182,7 @@
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.temperature = max(lowertemp.temperature-2000, lowertemp.temperature / 2, 0)
lowertemp.react()
T.assume_air(lowertemp)
qdel(hotspot)
@@ -194,7 +194,7 @@
T.visible_message("<span class='warning'>The water sizzles as it lands on \the [T]!</span>")
else if(volume >= 10)
T.wet_floor(1)
T.wet_floor(WET_TYPE_WATER,volume)
/datum/reagent/water/touch_obj(var/obj/O)
if(istype(O))
@@ -288,7 +288,7 @@
*/
if(volume >= 3)
T.wet_floor(2)
T.wet_floor(WET_TYPE_LUBE,volume)
/datum/reagent/nutriment/triglyceride/oil/initialize_data(var/newdata) // Called when the reagent is created.
..()
@@ -366,7 +366,7 @@
if(!istype(T))
return
if(volume >= 1)
T.wet_floor(2)
T.wet_floor(WET_TYPE_LUBE,volume)
/datum/reagent/silicate
name = "Silicate"
@@ -259,6 +259,51 @@
name = "Robust Harvest"
id = "robustharvest"
/datum/reagent/toxin/fertilizer/monoammoniumphosphate
name = "Monoammonium Phosphate"
id = "monoammoniumphosphate"
strength = 0.25
description = "Commonly found in fire extinguishers, also works as a fertilizer."
reagent_state = SOLID
color = "#CCCCCC"
taste_description = "salty dirt"
metabolism = REM * 2
/datum/reagent/toxin/fertilizer/monoammoniumphosphate/touch_turf(var/turf/simulated/T)
if(!istype(T))
return
var/hotspot = (locate(/obj/fire) in T)
if(hotspot && !istype(T, /turf/space))
var/datum/gas_mixture/lowertemp = T.return_air()
lowertemp.temperature = max(min(lowertemp.temperature-2000, lowertemp.temperature / 2), 0)
lowertemp.react()
qdel(hotspot)
var/amount_to_remove = max(1,round(volume * 0.5))
new /obj/effect/decal/cleanable/foam(T, amount_to_remove)
remove_self(amount_to_remove)
return
/datum/reagent/toxin/fertilizer/monoammoniumphosphate/touch_mob(var/mob/living/L, var/amount)
if(istype(L))
L.adjust_fire_stacks(-amount)
if(L.fire_stacks <= 0 )
L.fire_stacks = 0
L.ExtinguishMob()
/datum/reagent/toxin/fertilizer/monoammoniumphosphate/affect_touch(var/mob/living/carbon/slime/S, var/alien, var/removed)
if(istype(S))
S.adjustToxLoss(8 * removed)
if(!S.client && S.Target)
S.Target = null
++S.Discipline
if(dose == removed)
S.visible_message("<span class='warning'>[S]'s flesh sizzles where the liquid touches it!</span>", "<span class='danger'>Your flesh burns in the liquid!</span>")
/datum/reagent/toxin/plantbgone
name = "Plant-B-Gone"
id = "plantbgone"
@@ -537,6 +537,13 @@
required_reagents = list("cardox" = 0.1, "phoron" = 1)
result_amount = 0
/datum/chemical_reaction/monoammoniumphosphate
name = "Monoammoniumphosphate"
id = "monoammoniumphosphate"
result = "monoammoniumphosphate"
required_reagents = list("ammonia" = 1, "sacid" = 1, "sodium" = 1, "phosphorus" = 1)
result_amount = 4
/datum/chemical_reaction/koispasteclean
name = "Filtered K'ois"
id = "koispasteclean"
+66 -14
View File
@@ -8,6 +8,35 @@
var/possible_transfer_amounts = list(5,10,15,25,30)
var/volume = 30
var/accuracy = 1
var/can_be_placed_into = list(
/obj/machinery/chem_master,
/obj/machinery/chemical_dispenser,
/obj/structure/reagent_dispensers,
/obj/machinery/reagentgrinder,
/obj/structure/table,
/obj/structure/closet,
/obj/structure/sink,
/obj/item/weapon/storage,
/obj/machinery/atmospherics/unary/cryo_cell,
/obj/machinery/dna_scannernew,
/obj/item/weapon/grenade/chem_grenade,
/mob/living/bot/medbot,
/obj/machinery/computer/pandemic,
/obj/item/weapon/storage/secure/safe,
/obj/machinery/iv_drip,
/obj/machinery/disease2/incubator,
/obj/machinery/disposal,
/mob/living/simple_animal/cow,
/mob/living/simple_animal/hostile/retaliate/goat,
/obj/machinery/computer/centrifuge,
/obj/machinery/sleeper,
/obj/machinery/smartfridge,
/obj/machinery/biogenerator,
/obj/machinery/constructable_frame,
/obj/machinery/radiocarbon_spectrometer,
/obj/item/weapon/storage/part_replacer
)
//The above list a misnomer. This basically means that anything in this list has their own way of handling reagent transfers and should be ignored in afterattack.
/obj/item/weapon/reagent_containers/verb/set_APTFT() //set amount_per_transfer_from_this
set name = "Set transfer amount"
@@ -27,19 +56,29 @@
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))
return
if(can_operate(M) && do_surgery(M, user, src))
return
/obj/item/weapon/reagent_containers/afterattack(obj/target, mob/user, flag)
return
/obj/item/weapon/reagent_containers/afterattack(var/obj/target, var/mob/user, var/proximity)
if(!proximity || !is_open_container())
return
if(is_type_in_list(target,can_be_placed_into))
return
if(standard_splash_mob(user, target))
return
if(standard_feed_mob(user,target))
return
if(standard_pour_into(user, target))
return
if(standard_splash_obj(user, target))
return
/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
/obj/item/weapon/reagent_containers/proc/standard_dispenser_refill(var/mob/user, var/obj/structure/reagent_dispensers/target)
if(!istype(target))
return 0
@@ -51,14 +90,29 @@
user << "<span class='notice'>[src] is full.</span>"
return 1
var/trans = target.reagents.trans_to_obj(src, target:amount_per_transfer_from_this)
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_obj(var/mob/user, var/target)
if(user.a_intent != I_HURT)
return
if(!reagents || !reagents.total_volume)
return
user.visible_message("<span class='danger'>\The [target] has been splashed with something by \the [user]!</span>", "<span class = 'warning'>You splash the solution onto \the [target].</span>")
reagents.splash(target, reagents.total_volume)
return
/obj/item/weapon/reagent_containers/proc/standard_splash_mob(var/mob/user, var/mob/target) // This goes into afterattack
if(!istype(target))
return
if(user.a_intent != I_HURT)
return
if(!reagents || !reagents.total_volume)
user << "<span class='notice'>[src] is empty.</span>"
return 1
@@ -67,15 +121,13 @@
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>)",ckey=key_name(user),ckey_target=key_name(target))
user.visible_message("<span class='danger'>[target] has been splashed with something by [user]!</span>", "<span class = 'notice'>You splash the solution onto [target].</span>")
reagents.splash(target, reagents.total_volume)
user.visible_message("<span class='danger'>\The [target] has been splashed with something by \the [user]!</span>", "<span class = 'warning'>You splash the solution onto \the [target].</span>")
reagents.splash(target, min(120,reagents.total_volume) ) //Splash Limit
if (istype(target, /mob/living/silicon/robot))
var/mob/living/silicon/robot/R = target
@@ -84,7 +136,7 @@
return 1
/obj/item/weapon/reagent_containers/proc/self_feed_message(var/mob/user)
user << "<span class='notice'>You eat \the [src]</span>"
user.visible_message("<span class='notice'>\The [user] drinks from \the [src]</span>","<span class='notice'>You drink from \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]!</span>")
@@ -93,7 +145,7 @@
user.visible_message("<span class='warning'>[user] has fed [target] \the [src]!</span>")
/obj/item/weapon/reagent_containers/proc/feed_sound(var/mob/user)
return
playsound(user.loc, 'sound/items/drink.ogg', rand(10, 50), 1)
/obj/item/weapon/reagent_containers/proc/standard_feed_mob(var/mob/user, var/mob/target) // This goes into attack
if(!istype(target))
@@ -121,7 +173,7 @@
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) //puts a limit on how fast people can eat/drink things
self_feed_message(user)
reagents.trans_to_mob(user, amount_per_transfer_from_this, CHEM_INGEST)
reagents.trans_to_mob(user, min(10,amount_per_transfer_from_this), CHEM_INGEST) //A sane limiter. So you don't go drinking 300u all at once.
feed_sound(user)
return 1
else
@@ -51,34 +51,38 @@
reagent_volumes[T] = min(reagent_volumes[T] + 5, volume)
return 1
/obj/item/weapon/reagent_containers/borghypo/attack(var/mob/living/M, var/mob/user)
if(!istype(M))
/obj/item/weapon/reagent_containers/borghypo/afterattack(var/mob/living/M, var/mob/user, proximity)
if(!proximity)
return
if(!istype(M))
return ..()
if(!reagent_volumes[reagent_ids[mode]])
user << "<span class='warning'>The injector is empty.</span>"
to_chat(user,"<span class='warning'>The injector is empty.</span>")
return
var/mob/living/carbon/human/H = M
if(istype(H))
var/obj/item/organ/external/affected = H.get_organ(user.zone_sel.selecting)
if(!affected)
user << "<span class='danger'>\The [H] is missing that limb!</span>"
to_chat(user,"<span class='danger'>\The [H] is missing that limb!</span>")
return
else if(affected.status & ORGAN_ROBOT)
user << "<span class='danger'>You cannot inject a robotic limb.</span>"
to_chat(user,"<span class='danger'>You cannot inject a robotic limb.</span>")
return
if (M.can_inject(user, 1))
visible_message("<span class='notice'>[user] injects [M] with their hypospray!</span>", "<span class='notice'>You inject [M] with your hypospray!</span>")
M << "<span class='notice'>You feel a tiny prick!</span>"
to_chat(M,"<span class='notice'>You feel a tiny prick!</span>")
if(M.reagents)
var/t = min(amount_per_transfer_from_this, reagent_volumes[reagent_ids[mode]])
M.reagents.add_reagent(reagent_ids[mode], t)
reagent_volumes[reagent_ids[mode]] -= t
admin_inject_log(user, M, src, reagent_ids[mode], t)
user << "<span class='notice'>[t] units injected. [reagent_volumes[reagent_ids[mode]]] units remaining.</span>"
to_chat(user,"<span class='notice'>[t] units injected. [reagent_volumes[reagent_ids[mode]]] units remaining.</span>")
return
/obj/item/weapon/reagent_containers/borghypo/attack_self(mob/user as mob) //Change the mode
@@ -35,5 +35,7 @@
pixel_x = (CELLSIZE * (0.5 + cell_x)) - center_of_mass["x"]
pixel_y = (CELLSIZE * (0.5 + cell_y)) - center_of_mass["y"]
. = ..()
#undef CELLS
#undef CELLSIZE
@@ -29,26 +29,6 @@
if(!proximity)
return
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(!target.reagents.get_free_space())
user << "<span class='notice'>You can't add more condiment to \the [target].</span>"
return
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>"
/obj/item/weapon/reagent_containers/food/condiment/feed_sound(var/mob/user)
playsound(user.loc, 'sound/items/drink.ogg', rand(10, 50), 1)
/obj/item/weapon/reagent_containers/food/condiment/self_feed_message(var/mob/user)
user << "<span class='notice'>You swallow some of contents of \the [src].</span>"
@@ -116,11 +96,7 @@
desc = "Garlic sauce, perfect for spicing up a plate of garlic."
center_of_mass = list("x"=16, "y"=6)
else
name = "misc condiment bottle"
if (reagents.reagent_list.len==1)
desc = "Looks like it is [reagents.get_master_reagent_name()], but you are not sure."
else
desc = "A mixture of various condiments. [reagents.get_master_reagent_name()] is one of them."
desc = "A mixture of various condiments. [reagents.get_master_reagent_name()] is one of them."
icon_state = "mixedcondiments"
center_of_mass = list("x"=16, "y"=6)
else
@@ -41,21 +41,8 @@
/obj/item/weapon/reagent_containers/food/drinks/attack(mob/M as mob, mob/user as mob, def_zone)
if(force && !(flags & NOBLUDGEON) && user.a_intent == I_HURT)
return ..()
if(standard_feed_mob(user, M))
return
return 0
/obj/item/weapon/reagent_containers/food/drinks/afterattack(obj/target, mob/user, proximity)
if(!proximity)
return
if(standard_dispenser_refill(user, target))
return
if(standard_pour_into(user, target))
return
return ..()
/obj/item/weapon/reagent_containers/food/drinks/standard_feed_mob(var/mob/user, var/mob/target)
if(!is_open_container())
user << "<span class='notice'>You need to open [src]!</span>"
@@ -74,12 +61,6 @@
return 1
return ..()
/obj/item/weapon/reagent_containers/food/drinks/self_feed_message(var/mob/user)
user << "<span class='notice'>You swallow a gulp from \the [src].</span>"
/obj/item/weapon/reagent_containers/food/drinks/feed_sound(var/mob/user)
playsound(user.loc, 'sound/items/drink.ogg', rand(10, 50), 1)
/obj/item/weapon/reagent_containers/food/drinks/examine(mob/user)
if(!..(user, 1))
return
@@ -19,34 +19,6 @@
var/label_text = ""
var/list/can_be_placed_into = list(
/obj/machinery/chem_master/,
/obj/machinery/chemical_dispenser,
/obj/machinery/reagentgrinder,
/obj/structure/table,
/obj/structure/closet,
/obj/structure/sink,
/obj/item/weapon/storage,
/obj/machinery/atmospherics/unary/cryo_cell,
/obj/machinery/dna_scannernew,
/obj/item/weapon/grenade/chem_grenade,
/mob/living/bot/medbot,
/obj/machinery/computer/pandemic,
/obj/item/weapon/storage/secure/safe,
/obj/machinery/iv_drip,
/obj/machinery/disease2/incubator,
/obj/machinery/disposal,
/mob/living/simple_animal/cow,
/mob/living/simple_animal/hostile/retaliate/goat,
/obj/machinery/computer/centrifuge,
/obj/machinery/sleeper,
/obj/machinery/smartfridge/,
/obj/machinery/biogenerator,
/obj/machinery/constructable_frame,
/obj/machinery/radiocarbon_spectrometer,
/obj/item/weapon/storage/part_replacer
)
/obj/item/weapon/reagent_containers/glass/Initialize()
. = ..()
base_name = name
@@ -78,26 +50,6 @@
/obj/item/weapon/reagent_containers/glass/AltClick(var/mob/user)
set_APTFT()
/obj/item/weapon/reagent_containers/glass/afterattack(var/obj/target, var/mob/user, var/flag)
if(!is_open_container() || !flag)
return
for(var/type in can_be_placed_into)
if(istype(target, type))
return
if(standard_splash_mob(user, target))
return
if(standard_dispenser_refill(user, target))
return
if(standard_pour_into(user, target))
return
if(reagents && reagents.total_volume)
user << "<span class='notice'>You splash the solution onto [target].</span>"
reagents.splash(target, reagents.total_volume)
return
/obj/item/weapon/reagent_containers/glass/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(istype(W,/obj/item/weapon/storage/part_replacer))
if(!reagents || !reagents.total_volume)
@@ -15,43 +15,35 @@
flags = OPENCONTAINER
slot_flags = SLOT_BELT
///obj/item/weapon/reagent_containers/hypospray/Initialize() //comment this to make hypos start off empty
// . = ..()
// reagents.add_reagent("tricordrazine", 30)
// return
/obj/item/weapon/reagent_containers/hypospray/attack(mob/living/M as mob, mob/user as mob, var/target_zone)
if(!reagents.total_volume)
user << "<span class='warning'>[src] is empty.</span>"
return
if (!istype(M))
return
/obj/item/weapon/reagent_containers/hypospray/attack(var/mob/M, var/mob/user, target_zone)
. = ..()
var/mob/living/carbon/human/H = M
if(istype(H))
var/obj/item/organ/external/affected = H.get_organ(target_zone)
if(!affected)
user << "<span class='danger'>\The [H] is missing that limb!</span>"
return
else if(affected.status & ORGAN_ROBOT)
user << "<span class='danger'>You cannot inject a robotic limb.</span>"
return
user.visible_message("<span class='warning'>[user] is trying to inject [M] with [src]!</span>","<span class='notice'>You are trying to inject [M] with [src].</span>")
user.visible_message("<span class='warning'>[user] is trying to inject \the [M] with \the [src]!</span>","<span class='notice'>You are trying to inject \the [M] with \the [src].</span>")
if(H.run_armor_check(target_zone,"melee",0,"Your armor slows down the injection!","Your armor slows down the injection!"))
if(!do_mob(user, M, 60))
return
/obj/item/weapon/reagent_containers/hypospray/afterattack(var/mob/M, var/mob/user, proximity)
if (!istype(M))
return ..()
if(!reagents.total_volume)
to_chat(user,"<span class='warning'>\The [src] is empty.</span>")
return
user.setClickCooldown(DEFAULT_QUICK_COOLDOWN)
user.do_attack_animation(M)
M << "<span class='notice'>You feel a tiny prick!</span>"
to_chat(user,"<span class='notice'>You inject [M] with [src].</span>")
to_chat(M,"<span class='notice'>You feel a tiny prick!</span>")
playsound(src, 'sound/items/hypospray.ogg',25)
if(M.reagents)
var/contained = reagentlist()
var/trans = reagents.trans_to_mob(M, amount_per_transfer_from_this, CHEM_BLOOD)
admin_inject_log(user, M, src, contained, trans)
user << "<span class='notice'>[trans] units injected. [reagents.total_volume] units remaining in \the [src].</span>"
to_chat(user,"<span class='notice'>[trans] units injected. [reagents.total_volume] units remaining in \the [src].</span>")
return
@@ -96,10 +88,10 @@
amount_per_transfer_from_this = 20
/obj/item/weapon/reagent_containers/hypospray/autoinjector/stimpack/Initialize()
. = ..()
reagents.add_reagent("hyperzine", 12)
reagents.add_reagent("tramadol", 8)
update_icon()
. = ..()
reagents.add_reagent("hyperzine", 12)
reagents.add_reagent("tramadol", 8)
update_icon()
/obj/item/weapon/reagent_containers/hypospray/autoinjector/survival
name = "survival autoinjector"
@@ -108,13 +100,13 @@
amount_per_transfer_from_this = 35
/obj/item/weapon/reagent_containers/hypospray/autoinjector/survival/Initialize()
. = ..()
reagents.add_reagent("tricordrazine", 15)
reagents.add_reagent("inaprovaline", 5)
reagents.add_reagent("dexalinp", 5)
reagents.add_reagent("oxycodone", 5)
reagents.add_reagent("methylphenidate", 5)
update_icon()
. = ..()
reagents.add_reagent("tricordrazine", 15)
reagents.add_reagent("inaprovaline", 5)
reagents.add_reagent("dexalinp", 5)
reagents.add_reagent("oxycodone", 5)
reagents.add_reagent("methylphenidate", 5)
update_icon()
/obj/item/weapon/reagent_containers/hypospray/combat
name = "combat hypospray"
@@ -129,5 +121,4 @@
reagents.add_reagent("synaptizine", 5)
reagents.add_reagent("hyperzine", 5)
reagents.add_reagent("arithrazine", 5)
return
update_icon()
@@ -14,26 +14,24 @@
flags = OPENCONTAINER
slot_flags = SLOT_BELT
/obj/item/weapon/reagent_containers/inhaler/attack(mob/living/M as mob, mob/user as mob)
/obj/item/weapon/reagent_containers/inhaler/afterattack(var/mob/living/carbon/human/H, var/mob/user, proximity)
if (!istype(H))
return ..()
if(!reagents.total_volume)
to_chat(user,"<span class='warning'>\The [src] is empty.</span>")
return
var/mob/living/carbon/human/H = M
if (!istype(H))
return
if ( ((CLUMSY in user.mutations) || (DUMB in user.mutations)) && prob(10))
to_chat(user,"<span class='danger'>Your hand slips from clumsiness!</span>")
eyestab(M,user)
if(M.reagents)
eyestab(H,user)
if(H.reagents)
var/contained = reagentlist()
var/trans = reagents.trans_to_mob(M, amount_per_transfer_from_this, CHEM_TOUCH)
admin_inject_log(user, M, src, contained, trans)
var/trans = reagents.trans_to_mob(H, amount_per_transfer_from_this, CHEM_TOUCH)
admin_inject_log(user, H, src, contained, trans)
playsound(src.loc, 'sound/items/stimpack.ogg', 50, 1)
user.visible_message("<span class='notice'>[user] accidentally sticks the [src] in [M]'s eyes!</span>","<span class='notice'>You accidentally stick the [src] in [M]'s eyes!</span>")
user.visible_message("<span class='notice'>[user] accidentally sticks the [src] in [H]'s eyes!</span>","<span class='notice'>You accidentally stick the [src] in [H]'s eyes!</span>")
to_chat(user,"<span class='notice'>[trans] units injected. [reagents.total_volume] units remaining in \the [src].</span>")
return
@@ -41,30 +39,30 @@
to_chat(user,"<span class='warning'>You don't have the dexterity to do this!</span>")
return
if(user == M)
if(!M.can_eat(src))
if(user == H)
if(!H.can_eat(src))
return
else
if(!M.can_force_feed(user, src))
if(!H.can_force_feed(user, src))
return
user.setClickCooldown(DEFAULT_QUICK_COOLDOWN)
user.do_attack_animation(M)
user.do_attack_animation(H)
if(user == M)
if(user == H)
user.visible_message("<span class='notice'>[user] injects themselves with the [src]</span>","<span class='notice'>You stick the [src] in your mouth and press the injection button.</span>")
else
user.visible_message("<span class='warning'>[user] attempts to administer \the [src] to [M]...</span>","<span class='notice'>You attempt to administer \the [src] to [M]...</span>")
if (!do_after(user, 1 SECONDS, act_target = M))
user.visible_message("<span class='warning'>[user] attempts to administer \the [src] to [H]...</span>","<span class='notice'>You attempt to administer \the [src] to [H]...</span>")
if (!do_after(user, 1 SECONDS, act_target = H))
to_chat(user,"<span class='notice'>You and the target need to be standing still in order to inject \the [src].</span>")
return
user.visible_message("<span class='notice'>[user] injects [M] with the [src].</span>","<span class='notice'>You stick the [src] in [M]'s mouth and press the injection button.</span>")
user.visible_message("<span class='notice'>[user] injects [H] with the [src].</span>","<span class='notice'>You stick the [src] in [H]'s mouth and press the injection button.</span>")
if(M.reagents)
if(H.reagents)
var/contained = reagentlist()
var/trans = reagents.trans_to_mob(M, amount_per_transfer_from_this, CHEM_BREATHE, bypass_mask = TRUE)
admin_inject_log(user, M, src, contained, trans)
var/trans = reagents.trans_to_mob(H, amount_per_transfer_from_this, CHEM_BREATHE, bypass_mask = TRUE)
admin_inject_log(user, H, src, contained, trans)
playsound(src.loc, 'sound/items/stimpack.ogg', 50, 1)
to_chat(user,"<span class='notice'>[trans] units injected. [reagents.total_volume] units remaining in \the [src].</span>")
@@ -26,11 +26,16 @@
if(!usr || usr.stat || usr.lying || usr.restrained() || !Adjacent(usr)) return
safety = !safety
playsound(src.loc, 'sound/weapons/empty.ogg', 50, 1)
usr << "<span class = 'notice'>You twist the locking cap on the end of the nozzle, the spraybottle is now [safety ? "locked" : "unlocked"].</span>"
usr << "<span class = 'notice'>You twist the locking cap on the end of the nozzle. \The [src] is now [safety ? "locked" : "unlocked"].</span>"
/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/reagent_containers))
. = ..()
return
if(is_type_in_list(A,can_be_placed_into))
return
if(istype(A, /mob))
@@ -58,8 +63,6 @@
playsound(src.loc, 'sound/effects/spray2.ogg', 50, 1, -6)
if(reagents.has_reagent("sacid"))
message_admins("[key_name_admin(user)] fired sulphuric acid from \a [src].")
log_game("[key_name(user)] fired sulphuric acid from \a [src].",ckey=key_name(user))
@@ -199,7 +202,7 @@
var/turf/T2 = get_step(T,turn(direction, -90))
var/list/the_targets = list(T, T1, T2)
for(var/a = 1 to 3)
for(var/a = 1 to spray_size)
spawn(0)
if(reagents.total_volume < 1) break
var/obj/effect/effect/water/chempuff/D = new/obj/effect/effect/water/chempuff(get_turf(src))
@@ -212,6 +215,19 @@
D.set_up(my_target, rand(6, 8), 2)
return
/obj/item/weapon/reagent_containers/spray/chemsprayer/xenobiology
name = "xenoblaster"
desc = "A child's plastic watergun repurposed for the use in pacifying slimes. Has an adjustable nozzle that controls precision as well as strength."
icon = 'icons/obj/gun.dmi'
icon_state = "xenoblaster"
item_state = "xenoblaster"
origin_tech = list(TECH_MATERIAL = 1, TECH_ENGINEERING = 1)
volume = 200
spray_size = 3
spray_sizes = list(1,3)
amount_per_transfer_from_this = 5
possible_transfer_amounts = list(5,15)
/obj/item/weapon/reagent_containers/spray/plantbgone
name = "Plant-B-Gone"
desc = "Kills those pesky weeds!"
+131 -118
View File
@@ -1,93 +1,130 @@
/obj/structure/reagent_dispensers
name = "Dispenser"
desc = "..."
name = "Strange dispenser"
desc = "What the fuck is this?"
icon = 'icons/obj/objects.dmi'
icon_state = "watertank"
density = 1
anchored = 0
var/accept_any_reagent = TRUE
var/amount_per_transfer_from_this = 10
var/possible_transfer_amounts = list(10,25,50,100)
var/possible_transfer_amounts = list(5,10,15,25,30,50,60,100,120,250,300)
var/capacity = 1000
attackby(obj/item/weapon/W as obj, mob/user as mob)
var/can_tamper = TRUE
var/is_leaking = FALSE
/obj/structure/reagent_dispensers/Initialize()
. = ..()
create_reagents(capacity)
if (!possible_transfer_amounts)
src.verbs -= /obj/structure/reagent_dispensers/verb/set_APTFT
/obj/structure/reagent_dispensers/examine(mob/user)
if(!..(user, 2))
return
to_chat(user,"<span class='notice'>It contains [reagents.total_volume] units of reagents.</span>")
New()
var/datum/reagents/R = new/datum/reagents(capacity)
reagents = R
R.my_atom = src
if (!possible_transfer_amounts)
src.verbs -= /obj/structure/reagent_dispensers/verb/set_APTFT
..()
/obj/structure/reagent_dispensers/verb/set_APTFT() //set amount_per_transfer_from_this
set name = "Set transfer amount"
set category = "Object"
set src in view(1)
var/N = input("Amount per transfer from this:","[src]") as null|anything in possible_transfer_amounts
if (N)
amount_per_transfer_from_this = N
examine(mob/user)
if(!..(user, 2))
return
user << "<span class='notice'>It contains:</span>"
if(reagents && reagents.reagent_list.len)
for(var/datum/reagent/R in reagents.reagent_list)
user << "<span class='notice'>[R.volume] units of [R.name]</span>"
/obj/structure/reagent_dispensers/ex_act(severity)
reagents.splash_turf(get_turf(src), reagents.total_volume)
visible_message(span("danger", "\The [src] bursts open, spreading reagents all over the area!"))
qdel(src)
/obj/structure/reagent_dispensers/attackby(obj/item/O as obj, mob/user as mob)
var/obj/item/weapon/reagent_containers/RG = O
if (istype(RG) && RG.is_open_container())
var/atype
if(accept_any_reagent)
atype = alert(user, "Do you want to fill or empty \the [RG] at \the [src]?", "Fill or Empty", "Fill", "Empty", "Cancel")
else
user << "<span class='notice'>Nothing.</span>"
atype = alert(user, "Do you want to fill \the [RG] at \the [src]?", "Fill", "Fill", "Cancel")
verb/set_APTFT() //set amount_per_transfer_from_this
set name = "Set transfer amount"
set category = "Object"
set src in view(1)
var/N = input("Amount per transfer from this:","[src]") as null|anything in possible_transfer_amounts
if (N)
amount_per_transfer_from_this = N
if(!user.Adjacent(src)) return
if(RG.loc != user) return
ex_act(severity)
switch(severity)
if(1.0)
qdel(src)
return
if(2.0)
if (prob(50))
new /obj/effect/effect/water(src.loc)
qdel(src)
return
if(3.0)
if (prob(5))
new /obj/effect/effect/water(src.loc)
qdel(src)
return
else
switch(atype)
if ("Fill")
RG.standard_dispenser_refill(user,src)
if ("Empty")
if(is_open_container())
RG.standard_pour_into(user,src)
else
to_chat(user,"<span class='notice'>The top cap is wrenched on tight!</span>")
return
if (iswrench(O))
if(can_tamper && user.a_intent == I_HURT)
user.visible_message("<span class='warning'>\The [user] wrenches \the [src]'s faucet [is_leaking ? "closed" : "open"].</span>","<span class='warning'>You wrench \the [src]'s faucet [is_leaking ? "closed" : "open"]</span>")
is_leaking = !is_leaking
if (is_leaking)
message_admins("[key_name_admin(user)] wrench opened \the [src] at [loc.loc.name] ([loc.x],[loc.y],[loc.z]), leaking reagents. (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[loc.x];Y=[loc.y];Z=[loc.z]'>JMP</a>)")
log_game("[key_name(user)] opened \the [src] at [loc.loc.name] ([loc.x],[loc.y],[loc.z]), leaking reagents.",ckey=key_name(user))
START_PROCESSING(SSprocessing,src)
else if(accept_any_reagent)
var/is_closed = flags & OPENCONTAINER
var/verb01 = is_closed ? "unwrenches" : "wrenches"
var/verb02 = (is_closed ? "open" : "shut")
user.visible_message("<span class='notice'>[user] [verb01] the top cap [verb02] from \the [src].</span>", "<span class='notice'>You [verb01] the top cap [verb02] from \the [src].</span>")
flags ^= OPENCONTAINER
return
/obj/structure/reagent_dispensers/process()
if(!is_leaking || reagents.total_volume <= 0)
STOP_PROCESSING(SSprocessing,src)
return
var/splash_amount = min(amount_per_transfer_from_this,60) //Hard limit of 60 per process
reagents.trans_to_turf(get_turf(src),splash_amount)
//Dispensers
/obj/structure/reagent_dispensers/watertank
name = "watertank"
name = "water tank"
desc = "A tank filled with water."
icon = 'icons/obj/objects.dmi'
icon_state = "watertank"
amount_per_transfer_from_this = 10
New()
..()
reagents.add_reagent("water",capacity)
/obj/structure/reagent_dispensers/watertank/Initialize()
. = ..()
reagents.add_reagent("water",capacity)
/obj/structure/reagent_dispensers/extinguisher
name = "extinguisher tank"
desc = "A tank filled with extinguisher fluid."
icon = 'icons/obj/objects.dmi'
icon_state = "extinguisher_tank"
amount_per_transfer_from_this = 10
/obj/structure/reagent_dispensers/extinguisher/Initialize()
. = ..()
reagents.add_reagent("monoammoniumphosphate",capacity)
/obj/structure/reagent_dispensers/fueltank
name = "fuel tank"
desc = "A tank filled with welding fuel."
icon = 'icons/obj/objects.dmi'
icon_state = "weldtank"
accept_any_reagent = FALSE
amount_per_transfer_from_this = 10
var/modded = 0
var/defuse = 0
var/armed = 0
var/obj/item/device/assembly_holder/rig = null
New()
..()
reagents.add_reagent("fuel",capacity)
/obj/structure/reagent_dispensers/fueltank/Initialize()
. = ..()
reagents.add_reagent("fuel",capacity)
/obj/structure/reagent_dispensers/fueltank/examine(mob/user)
if(!..(user, 2))
@@ -97,25 +134,17 @@
if(rig)
user << "<span class='notice'>There is some kind of device rigged to the tank.</span>"
/obj/structure/reagent_dispensers/fueltank/attack_hand()
/obj/structure/reagent_dispensers/fueltank/attack_hand(mob/user)
if (rig)
usr.visible_message("[usr] begins to detach [rig] from \the [src].", "You begin to detach [rig] from \the [src]")
if(do_after(usr, 20))
usr.visible_message("<span class='notice'>[usr] detaches [rig] from \the [src].</span>", "<span class='notice'>You detach [rig] from \the [src]</span>")
rig.forceMove(get_turf(usr))
user.visible_message("[user] begins to detach [rig] from \the [src].", "You begin to detach [rig] from \the [src]")
if(do_after(user, 20))
user.visible_message("<span class='notice'>[user] detaches [rig] from \the [src].</span>", "<span class='notice'>You detach [rig] from \the [src]</span>")
rig.forceMove(get_turf(user))
rig = null
overlays = new/list()
/obj/structure/reagent_dispensers/fueltank/attackby(obj/item/weapon/W as obj, mob/user as mob)
src.add_fingerprint(user)
if (iswrench(W))
user.visible_message("[user] wrenches [src]'s faucet [modded ? "closed" : "open"].", \
"You wrench [src]'s faucet [modded ? "closed" : "open"]")
modded = modded ? 0 : 1
if (modded)
message_admins("[key_name_admin(user)] opened fueltank at [loc.loc.name] ([loc.x],[loc.y],[loc.z]), leaking fuel. (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[loc.x];Y=[loc.y];Z=[loc.z]'>JMP</a>)")
log_game("[key_name(user)] opened fueltank at [loc.loc.name] ([loc.x],[loc.y],[loc.z]), leaking fuel.",ckey=key_name(user))
leak_fuel(amount_per_transfer_from_this)
if (istype(W,/obj/item/device/assembly_holder))
if (rig)
user << "<span class='warning'>There is another device in the way.</span>"
@@ -158,12 +187,10 @@
log_game("[key_name(Proj.firer)] shot fueltank at [loc.loc.name] ([loc.x],[loc.y],[loc.z]).",ckey=key_name(Proj.firer))
if(!istype(Proj ,/obj/item/projectile/beam/lastertag) && !istype(Proj ,/obj/item/projectile/beam/practice) )
explode()
ex_act(2.0)
/obj/structure/reagent_dispensers/fueltank/ex_act()
explode()
/obj/structure/reagent_dispensers/fueltank/ex_act(var/severity = 3.0)
/obj/structure/reagent_dispensers/fueltank/proc/explode()
if (QDELETED(src))
return
@@ -173,31 +200,19 @@
explosion(src.loc,0,1,3)
else if (reagents.total_volume > 50)
explosion(src.loc,-1,1,2)
if(src)
qdel(src)
..()
/obj/structure/reagent_dispensers/fueltank/fire_act(datum/gas_mixture/air, temperature, volume)
if (modded)
explode()
ex_act(2.0)
else if (temperature > T0C+500)
explode()
ex_act(2.0)
return ..()
/obj/structure/reagent_dispensers/fueltank/tesla_act()
..()
explode()
/obj/structure/reagent_dispensers/fueltank/Move()
if (..() && modded)
leak_fuel(amount_per_transfer_from_this/10.0)
/obj/structure/reagent_dispensers/fueltank/proc/leak_fuel(amount)
if (reagents.total_volume == 0)
return
amount = min(amount, reagents.total_volume)
reagents.remove_reagent("fuel",amount)
new /obj/effect/decal/cleanable/liquid_fuel(src.loc, amount,1)
ex_act(2.0)
/obj/structure/reagent_dispensers/peppertank
name = "Pepper Spray Refiller"
@@ -207,10 +222,11 @@
anchored = 1
density = 0
amount_per_transfer_from_this = 45
New()
..()
reagents.add_reagent("condensedcapsaicin",capacity)
can_tamper = FALSE
/obj/structure/reagent_dispensers/peppertank/Initialize()
. = ..()
reagents.add_reagent("condensedcapsaicin",capacity)
/obj/structure/reagent_dispensers/water_cooler
name = "Water-Cooler"
@@ -220,12 +236,15 @@
icon_state = "water_cooler"
possible_transfer_amounts = null
anchored = 1
New()
..()
reagents.add_reagent("water",500)
capacity = 500
can_tamper = FALSE
/obj/structure/reagent_dispensers/water_cooler/Initialize()
. = ..()
reagents.add_reagent("water",capacity)
/obj/structure/reagent_dispensers/water_cooler/attackby(obj/item/weapon/W as obj, mob/user as mob)
if (iswrench(W))
if (isscrewdriver(W))
src.add_fingerprint(user)
playsound(src.loc, 'sound/items/Ratchet.ogg', 100, 1)
if(do_after(user, 20))
@@ -233,22 +252,22 @@
switch (anchored)
if (0)
anchored = 1
user.visible_message("\The [user] tightens the bolts securing \the [src] to the floor.", "You tighten the bolts securing \the [src] to the floor.")
user.visible_message("\The [user] tightens the screws securing \the [src] to the floor.", "You tighten the screws securing \the [src] to the floor.")
if (1)
user.visible_message("\The [user] unfastens the bolts securing \the [src] to the floor.", "You unfasten the bolts securing \the [src] to the floor.")
user.visible_message("\The [user] unfastens the screws securing \the [src] to the floor.", "You unfasten the screws securing \the [src] to the floor.")
anchored = 0
return
/obj/structure/reagent_dispensers/beerkeg
name = "beer keg"
desc = "A beer keg"
icon = 'icons/obj/objects.dmi'
icon_state = "beertankTEMP"
amount_per_transfer_from_this = 10
New()
..()
reagents.add_reagent("beer",capacity)
/obj/structure/reagent_dispensers/beerkeg/Initialize()
. = ..()
reagents.add_reagent("beer",capacity)
/obj/structure/reagent_dispensers/xuizikeg
name = "xuizi juice keg"
@@ -256,9 +275,10 @@
icon = 'icons/obj/objects.dmi'
icon_state = "keg_xuizi"
amount_per_transfer_from_this = 10
New()
..()
reagents.add_reagent("xuizijuice",capacity)
/obj/structure/reagent_dispensers/xuizikeg/Initialize()
. = ..()
reagents.add_reagent("xuizijuice",capacity)
/obj/structure/reagent_dispensers/virusfood
name = "Virus Food Dispenser"
@@ -268,10 +288,11 @@
amount_per_transfer_from_this = 10
anchored = 1
density = 0
can_tamper = FALSE
New()
..()
reagents.add_reagent("virusfood", capacity)
/obj/structure/reagent_dispensers/virusfood/Initialize()
. = ..()
reagents.add_reagent("virusfood", capacity)
/obj/structure/reagent_dispensers/acid
name = "Sulphuric Acid Dispenser"
@@ -281,11 +302,11 @@
amount_per_transfer_from_this = 10
anchored = 1
density = 0
can_tamper = FALSE
New()
..()
reagents.add_reagent("sacid", capacity)
/obj/structure/reagent_dispensers/acid/Initialize()
. = ..()
reagents.add_reagent("sacid", capacity)
//Cooking oil refill tank
/obj/structure/reagent_dispensers/cookingoil
@@ -302,12 +323,4 @@
/obj/structure/reagent_dispensers/cookingoil/bullet_act(var/obj/item/projectile/Proj)
if(Proj.get_structure_damage())
explode()
/obj/structure/reagent_dispensers/cookingoil/ex_act()
explode()
/obj/structure/reagent_dispensers/cookingoil/proc/explode()
reagents.splash_area(get_turf(src), 3)
visible_message(span("danger", "The [src] bursts open, spreading oil all over the area."))
qdel(src)
ex_act(2.0)
@@ -4,16 +4,17 @@
icon = 'icons/obj/objects.dmi'
icon_state = "coolanttank"
amount_per_transfer_from_this = 10
New()
..()
reagents.add_reagent("coolant",1000)
/obj/structure/reagent_dispensers/coolanttank/Initialize()
. = ..()
reagents.add_reagent("coolant",1000)
/obj/structure/reagent_dispensers/coolanttank/bullet_act(var/obj/item/projectile/Proj)
if(Proj.get_structure_damage())
if(!istype(Proj ,/obj/item/projectile/beam/lastertag) && !istype(Proj ,/obj/item/projectile/beam/practice) )
explode()
/obj/structure/reagent_dispensers/coolanttank/ex_act()
/obj/structure/reagent_dispensers/coolanttank/ex_act(var/severity = 2.0)
explode()
/obj/structure/reagent_dispensers/coolanttank/proc/explode()
+1 -1
View File
@@ -96,7 +96,7 @@
/obj/machinery/computer/shuttle_control/bullet_act(var/obj/item/projectile/Proj)
visible_message("\The [Proj] ricochets off \the [src]!")
/obj/machinery/computer/shuttle_control/ex_act()
/obj/machinery/computer/shuttle_control/ex_act(var/severity = 2.0)
return
/obj/machinery/computer/shuttle_control/emp_act()
+1 -1
View File
@@ -21,7 +21,7 @@
carried = null
return ..()
/obj/item/projectile/spell_projectile/ex_act()
/obj/item/projectile/spell_projectile/ex_act(var/severity = 2.0)
return
/obj/item/projectile/spell_projectile/before_move()