Files
FabianK3andGitHub 4770cc0739 Storage tanks fill levels (#23005)
# Summary

This PR adds visual fill levels for fuel, extinguisher, water, cooking
oil and lube tanks.
The cooking oil tank now is also persistent and was added to the cargo
order manifest.

Sprites by @alsoandanswer 

## Preview

<img width="404" height="472" alt="image"
src="https://github.com/user-attachments/assets/4ff4a0dd-e790-4a63-bc1a-6e198199ee7c"
/>
2026-08-08 10:22:15 +00:00

668 lines
25 KiB
Plaintext

/obj/structure/reagent_dispensers
name = "strange dispenser"
desc = "What the fuck is this?"
icon = 'icons/obj/reagent_dispensers.dmi'
icon_state = "watertank" // Mapping icon
density = 1
anchored = 0
maxhealth = OBJECT_HEALTH_HIGH
var/accept_any_reagent = TRUE
var/amount_per_transfer_from_this = 10
var/possible_transfer_amounts = list(5,10,15,25,30,50,60,100,120,250,300)
var/capacity = 1000
var/can_tamper = TRUE
var/is_leaking = FALSE
var/has_fill_levels = FALSE // Features base underlay and overlays for 100%, 80%, 60%, 40%, 20% fill levels
var/is_persistent = FALSE
/obj/structure/reagent_dispensers/mechanics_hints(mob/user, distance, is_adjacent)
. += ..()
. += "Use Help intent to fill a container in your hand from this, and use any other intent to empty the container into this."
. += "In the right-click menu, you can set the amount transferred per use."
if(can_tamper)
. += "Using a wrench on this with the Harm intent will open or close the faucet; an open faucet will cause it to continuously leak its contents."
/obj/structure/reagent_dispensers/feedback_hints(mob/user, distance, is_adjacent)
. += ..()
if(distance > 2)
return
. += SPAN_NOTICE("It contains [reagents.total_volume] units of reagents.")
/obj/structure/reagent_dispensers/Initialize()
. = ..()
if(has_fill_levels)
icon_state = "[icon_state]_underlay" // Replace mapping icon with underlay version for fill level overlay
create_reagents(capacity)
if (!possible_transfer_amounts)
src.verbs -= /obj/structure/reagent_dispensers/verb/set_APTFT
if(is_persistent)
SSpersistence.objectsRegisterTrack(src)
update_icon()
/obj/structure/reagent_dispensers/update_icon()
if(!has_fill_levels)
return
ClearOverlays()
var/level = reagents.total_volume / capacity
var/fill_level_overlay = null
if(level <= 1.0)
fill_level_overlay = "_100"
if(level <= 0.8)
fill_level_overlay = "_80"
if(level <= 0.6)
fill_level_overlay = "_60"
if(level <= 0.4)
fill_level_overlay = "_40"
if(level <= 0.2)
fill_level_overlay = "_20"
if(level == 0)
fill_level_overlay = null
if(fill_level_overlay)
AddOverlays("[initial(icon_state)][fill_level_overlay]")
. = ..()
// Debug verb, uncomment if you are in need to adjust a lot of tanks
// /obj/structure/reagent_dispensers/verb/adjust_regeant_total_volume()
// set name = "Set reagent total volume"
// set category = "Object"
// set src in view(1)
// var/x = tgui_input_number(usr, "Select the total reagent amount for this. ", "[src]", capacity, capacity, 0)
// if (x)
// reagents.total_volume = x
// update_icon()
/obj/structure/reagent_dispensers/persistent_objects_get_content()
var/list/content = ..()
content["remaining_volume"] = reagents ? reagents.total_volume : 0
return content
/obj/structure/reagent_dispensers/persistent_objects_apply_content(content, x, y, z)
src.x = x
src.y = y
src.z = z
if(!content["remaining_volume"] || content["remaining_volume"] <= 0)
reagents_to_add = null
return
if(!LAZYLEN(reagents_to_add))
return
// This happens before Initialize, reagents are not generated yet, override to-be-added contents
// Keep ratios the same if multiple reagents are within reagents_to_add
var/scale = content["remaining_volume"] / capacity
for(var/reagent in reagents_to_add)
reagents_to_add[reagent] *= scale
/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 = tgui_input_list(usr, "Select the amount to transfer from this. ", "[src]", possible_transfer_amounts, amount_per_transfer_from_this)
if (N)
amount_per_transfer_from_this = N
/obj/structure/reagent_dispensers/ex_act(severity)
reagents.splash_turf(get_turf(src), reagents.total_volume)
qdel(src)
/obj/structure/reagent_dispensers/attackby(obj/item/attacking_item, mob/user)
var/obj/item/reagent_containers/RG = attacking_item
if (istype(RG))
if(!user.Adjacent(src)) return
if(RG.loc != user && !isrobot(user)) return
if(!(RG.is_open_container()))
to_chat(usr, SPAN_WARNING("The [RG.name]'s lid is on!"))
return
if (usr.a_intent == I_HELP)
RG.standard_dispenser_refill(user,src)
playsound(src.loc, 'sound/machines/reagent_dispense.ogg', 25, 1)
else
if(!accept_any_reagent)
to_chat(user,SPAN_WARNING("You can't refill \the [src]."))
return
if(is_open_container())
RG.standard_pour_into(user,src)
else
to_chat(user,SPAN_NOTICE("The inlet cap on \the [src] is wrenched on tight!"))
update_icon()
if (attacking_item.tool_behaviour == TOOL_WRENCH)
if(use_check(user, USE_DISALLOW_SPECIALS))
to_chat(user, SPAN_WARNING("A strange force prevents you from doing this.")) //there is no way to justify this icly
return
if(can_tamper && user.a_intent == I_HURT)
user.visible_message(SPAN_WARNING("\The [user] wrenches \the [src]'s faucet [is_leaking ? "closed" : "open"]."),
SPAN_WARNING("You wrench \the [src]'s faucet [is_leaking ? "closed" : "open"]"))
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='byond://?_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.")
START_PROCESSING(SSprocessing,src)
else if(accept_any_reagent)
if(atom_flags & ATOM_FLAG_OPEN_CONTAINER)
user.visible_message(SPAN_NOTICE("[user] wrenches the inlet cap on \the [src] shut."),
SPAN_NOTICE("You wrench the inlet cap back on \the [src]."))
else
user.visible_message(SPAN_NOTICE("[user] unwrenches the inlet cap from \the [src]."),
SPAN_NOTICE("You unwrench the inlet cap from \the [src]."))
atom_flags ^= ATOM_FLAG_OPEN_CONTAINER
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)
update_icon()
/obj/structure/reagent_dispensers/on_death(damage, damage_flags, damage_type, armor_penetration, obj/weapon)
if(!should_use_health)
return FALSE
if(reagents.total_volume > 0)
var/splash_area = max(1, round(sqrt(reagents.total_volume / 60.0))) //Splash roughly 60u on every turf.
reagents.splash_area(get_turf(src), splash_area, reagents.total_volume)
visible_message(SPAN_WARNING("As \the [src] is destroyed, it spills [reagents.get_primary_reagent_name()] everywhere!"))
dismantle()
//Fire extinguisher tank
/obj/structure/reagent_dispensers/extinguisher
name = "extinguisher tank"
desc = "A tank filled with extinguisher fluid."
icon_state = "extinguisher_tank"
amount_per_transfer_from_this = 150 // Same volume as extinguisher refillers, quality of life value
reagents_to_add = list(/singleton/reagent/toxin/fertilizer/monoammoniumphosphate = 1000)
has_fill_levels = TRUE
is_persistent = TRUE
// Tanks
/obj/structure/reagent_dispensers/watertank
name = "water tank"
desc = "A tank filled with water."
icon_state = "watertank"
amount_per_transfer_from_this = 300
reagents_to_add = list(/singleton/reagent/water = 1000)
has_fill_levels = TRUE
is_persistent = TRUE
/obj/structure/reagent_dispensers/lube
name = "lube tank"
desc = "A tank filled with a silly amount of lube."
icon_state = "lubetank"
amount_per_transfer_from_this = 30
has_fill_levels = TRUE
reagents_to_add = list(/singleton/reagent/lube = 1000)
/obj/structure/reagent_dispensers/fueltank
name = "fuel tank"
desc = "A tank filled with welding fuel."
icon_state = "weldtank"
accept_any_reagent = FALSE
amount_per_transfer_from_this = 30
var/defuse = 0
var/armed = 0
var/obj/item/assembly_holder/rig = null
reagents_to_add = list(/singleton/reagent/fuel = 1000)
has_fill_levels = TRUE
is_persistent = TRUE
/obj/structure/reagent_dispensers/fueltank/feedback_hints(mob/user, distance, is_adjacent)
. += ..()
if(distance > 2)
return
if (is_leaking)
. += SPAN_WARNING("Fuel faucet is wrenched open, leaking the fuel!")
if(rig)
. += SPAN_NOTICE("There is some kind of device rigged to the tank.")
/obj/structure/reagent_dispensers/fueltank/attack_hand(mob/user)
if (rig)
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_NOTICE("[user] detaches [rig] from \the [src]."),
SPAN_NOTICE("You detach [rig] from \the [src]"))
rig.forceMove(get_turf(user))
rig.detached()
rig = null
overlays = new/list()
/obj/structure/reagent_dispensers/fueltank/attackby(obj/item/attacking_item, mob/user)
src.add_fingerprint(user)
if(istype(attacking_item, /obj/item/wirecutters/bomb) && rig)
user.visible_message(SPAN_WARNING("\The [user] carefully removes \the [rig] from \the [src]."), \
SPAN_NOTICE("You carefully remove \the [rig] from \the [src]."))
rig.forceMove(get_turf(user))
rig.detached()
user.put_in_hands(rig)
rig = null
overlays = new/list()
if (istype(attacking_item,/obj/item/assembly_holder))
if (rig)
to_chat(user, SPAN_WARNING("There is another device in the way."))
return ..()
var/obj/item/assembly_holder/H = attacking_item
if(!H.secured)
to_chat(user, SPAN_WARNING("The assembly must be secured with a screwdriver."))
return TRUE
user.visible_message("[user] begins rigging [attacking_item] to \the [src].", "You begin rigging [attacking_item] to \the [src]")
if(do_after(user, 20))
user.visible_message(SPAN_NOTICE("[user] rigs [attacking_item] to \the [src]."),
SPAN_NOTICE("You rig [attacking_item] to \the [src]"))
if (istype(H.a_left,/obj/item/assembly/igniter) || istype(H.a_right,/obj/item/assembly/igniter))
message_admins("[key_name_admin(user)] rigged fueltank at [loc.loc.name] ([loc.x],[loc.y],[loc.z]) for explosion. (<A href='byond://?_src_=holder;adminplayerobservecoodjump=1;X=[loc.x];Y=[loc.y];Z=[loc.z]'>JMP</a>)")
log_game("[key_name(user)] rigged fueltank at [loc.loc.name] ([loc.x],[loc.y],[loc.z]) for explosion.")
rig = attacking_item
user.drop_from_inventory(attacking_item,src)
var/mutable_appearance/MA = new(attacking_item)
MA.pixel_x += 1
MA.pixel_y += 6
AddOverlays(MA)
return ..()
/obj/structure/reagent_dispensers/fueltank/attack_ghost(mob/user)
if(user.client && user.client.inquisitive_ghost)
examine()
if(!user.client.holder)
return
if(!src.defuse && ((user.client.holder.rights & R_ADMIN) || (user.client.holder.rights & R_MOD)))
src.defuse = 1
message_admins("[key_name_admin(user)] <font color=#00FF00>defused</font> fueltank at ([loc.x],[loc.y],[loc.z]).")
else
if(!src.armed && ((user.client.holder.rights & R_ADMIN) || (user.client.holder.rights & R_MOD)))
src.defuse = 0
message_admins("[key_name_admin(user)] <font color=#FF0000>reset</font> fuse on fueltank at ([loc.x],[loc.y],[loc.z]).")
/obj/structure/reagent_dispensers/fueltank/bullet_act(obj/projectile/hitting_projectile, def_zone, piercing_hit)
. = ..()
if(. != BULLET_ACT_HIT)
return .
if(hitting_projectile.get_structure_damage())
if(istype(hitting_projectile.firer))
log_and_message_admins("shot a welding tank", hitting_projectile.firer)
log_game("[key_name(hitting_projectile.firer)] shot fueltank at [loc.loc.name] ([loc.x],[loc.y],[loc.z]).")
if(!istype(hitting_projectile ,/obj/projectile/beam/laser_tag) && !istype(hitting_projectile ,/obj/projectile/beam/practice) && !istype(hitting_projectile ,/obj/projectile/kinetic))
ex_act(2.0)
/obj/structure/reagent_dispensers/fueltank/ex_act(var/severity = 3.0)
if (QDELETED(src))
return
if (reagents.total_volume > 500)
explosion(src.loc,1,2,4)
else if (reagents.total_volume > 100)
explosion(src.loc,0,1,3)
else if (reagents.total_volume > 50)
explosion(src.loc,-1,1,2)
..()
/obj/structure/reagent_dispensers/fueltank/fire_act(exposed_temperature, exposed_volume)
if (is_leaking)
ex_act(2.0)
else if (exposed_temperature > T0C+500)
ex_act(2.0)
return ..()
/obj/structure/reagent_dispensers/fueltank/tesla_act()
..()
ex_act(2.0)
//Fertilizer tank
/obj/structure/reagent_dispensers/fertilizer
name = "fertilizer tank"
desc = "A tank filled with nutrients for plant growth"
icon_state = "lubetank"
amount_per_transfer_from_this = 30
reagents_to_add = list(/singleton/reagent/toxin/fertilizer = 1000)
//Wall Dispensers
/obj/structure/reagent_dispensers/peppertank
name = "pepper spray refiller"
desc = "Refill pepper spray canisters."
icon_state = "peppertank"
anchored = 1
density = 0
amount_per_transfer_from_this = 45
can_tamper = FALSE
reagents_to_add = list(/singleton/reagent/capsaicin/condensed = 1000)
maxhealth = OBJECT_HEALTH_VERY_LOW //Made of glass.
material = MATERIAL_GLASS
/obj/structure/reagent_dispensers/virusfood
name = "virus food dispenser"
desc = "A dispenser of virus food."
icon_state = "virusfoodtank"
amount_per_transfer_from_this = 10
anchored = 1
density = 0
can_tamper = FALSE
reagents_to_add = list(/singleton/reagent/nutriment/virusfood = 1000)
maxhealth = OBJECT_HEALTH_VERY_LOW //Made of glass.
material = MATERIAL_GLASS
/obj/structure/reagent_dispensers/acid
name = "sulphuric acid dispenser"
desc = "A dispenser of acid for industrial processes."
icon_state = "acidtank"
amount_per_transfer_from_this = 10
anchored = 1
density = 0
can_tamper = FALSE
reagents_to_add = list(/singleton/reagent/acid = 1000)
maxhealth = OBJECT_HEALTH_VERY_LOW //Made of glass.
material = MATERIAL_GLASS
/obj/structure/reagent_dispensers/peppertank/luminol
name = "luminol dispenser"
desc = "A dispenser to refill luminol bottles."
icon_state = "luminoltank"
amount_per_transfer_from_this = 50
reagents_to_add = list(/singleton/reagent/luminol = 1000)
maxhealth = OBJECT_HEALTH_VERY_LOW //Made of glass.
material = MATERIAL_GLASS
/obj/structure/reagent_dispensers/peppertank/spacecleaner
name = "cleaner dispenser"
desc = "A wall-mounted dispenser filled with cleaner. Used to refill cleaner bottles and cleaner tanks."
icon_state = "cleanertank"
amount_per_transfer_from_this = 250
reagents_to_add = list(/singleton/reagent/spacecleaner = 1000)
maxhealth = OBJECT_HEALTH_VERY_LOW //Made of glass.
material = MATERIAL_GLASS
//Water Cooler
/obj/structure/reagent_dispensers/water_cooler
name = "water cooler"
desc = "A machine that dispenses water to drink."
amount_per_transfer_from_this = 5
icon = 'icons/obj/vending.dmi'
icon_state = "water_cooler"
possible_transfer_amounts = null
anchored = 1
capacity = 500
can_tamper = FALSE
reagents_to_add = list(/singleton/reagent/water = 500)
var/cups = 12
var/cup_type = /obj/item/reagent_containers/food/drinks/sillycup
maxhealth = OBJECT_HEALTH_LOW //Made of plastic.
material = MATERIAL_PLASTIC
/obj/structure/reagent_dispensers/water_cooler/attack_hand(var/mob/user)
if(cups > 0)
var/visible_messages = DispenserMessages(user)
visible_message(SPAN_NOTICE(visible_messages[1]), SPAN_NOTICE(visible_messages[2]))
var/cup = new cup_type(loc)
user.put_in_active_hand(cup)
cups--
else
to_chat(user, SPAN_WARNING(RejectionMessage(user)))
/obj/structure/reagent_dispensers/water_cooler/proc/DispenserMessages(var/mob/user)
return list("\The [user] grabs a paper cup from \the [src].", "You grab a paper cup from \the [src]'s cup compartment.")
/obj/structure/reagent_dispensers/water_cooler/proc/RejectionMessage(var/mob/user)
return "[src]'s cup dispenser is empty."
/obj/structure/reagent_dispensers/water_cooler/attackby(obj/item/attacking_item, mob/user)
if (attacking_item.tool_behaviour == TOOL_SCREWDRIVER)
src.add_fingerprint(user)
attacking_item.play_tool_sound(get_turf(src), 100)
if(do_after(user, 20))
if(!src) return
switch (anchored)
if (0)
anchored = 1
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 screws securing \the [src] to the floor.",
"You unfasten the screws securing \the [src] to the floor.")
anchored = 0
return
else
..()
//Beer Kegs
/obj/structure/reagent_dispensers/keg
name = "keg"
desc = "An empty keg."
icon_state = "keg"
amount_per_transfer_from_this = 10
maxhealth = OBJECT_HEALTH_LOW //Made of wood
material = MATERIAL_WOOD
/obj/structure/reagent_dispensers/keg/attackby(obj/item/attacking_item, mob/user)
if (istype(attacking_item, /obj/item/stack/rods))
var/obj/item/stack/rods/R = attacking_item
if(!R.can_use(3)) // like a tripod
to_chat(user, SPAN_NOTICE("You need three rods to make a still!"))
return
if(do_after(user, 20))
if (QDELETED(src))
return
R.use(3)
new /obj/structure/distillery(src.loc)
if(reagents)
to_chat(user, SPAN_NOTICE("As you prop the still up on the rods, the reagents inside are spilled. However, you successfully make the still."))
reagents.trans_to_turf(get_turf(src), reagents.total_volume)
else
to_chat(user, SPAN_NOTICE("You successfully build a still."))
qdel(src)
return
. = ..()
/obj/structure/reagent_dispensers/keg/beerkeg
name = "beer keg"
desc = "A keg full of Virklunder beer, a simple brew from New Gibson."
icon_state = "keg_beer"
reagents_to_add = list(/singleton/reagent/alcohol/beer = 1000)
/obj/structure/reagent_dispensers/keg/beerkeg/rice
name = "rice beer keg"
desc = "A keg full of Ebisu rice beer, a light lagered beer popular on Konyang."
icon_state = "keg_rice"
reagents_to_add = list(/singleton/reagent/alcohol/rice_beer = 1000)
/obj/structure/reagent_dispensers/keg/xuizikeg
name = "xuizi juice keg"
desc = "A keg full of Xuizi juice, blended flower buds from the Moghean Xuizi cactus. The export stamp of the Arizi Guild is imprinted on the side."
icon_state = "keg_xuizi"
reagents_to_add = list(/singleton/reagent/alcohol/butanol/xuizijuice = 1000)
/obj/structure/reagent_dispensers/keg/kvass
name = "\improper Dorshafen kvass keg"
desc = "A keg full of Dorshafen Deluxe kvass, a fermented non-alcoholic mushroom drink. It is a common sight across workers homes in Himeo, and even abroad."
icon_state = "keg_kvass"
reagents_to_add = list(/singleton/reagent/drink/mushroom_kvass = 1000)
/obj/structure/reagent_dispensers/keg/mead
name = "mead barrel"
desc = "A wooden mead barrel."
icon_state = "woodkeg"
reagents_to_add = list(/singleton/reagent/alcohol/messa_mead = 1000)
/obj/structure/reagent_dispensers/keg/sake
name = "sake barrel"
desc = "A wooden sake barrel."
icon_state = "woodkeg"
reagents_to_add = list(/singleton/reagent/alcohol/sake = 1000)
/obj/structure/reagent_dispensers/keg/kvass
name = "kvass keg"
desc = "A keg full of Dorshafen kvass - non-alcoholic, and a common sight in any workers home across Himeo."
icon_state = "keg_kvass"
reagents_to_add = list(/singleton/reagent/drink/mushroom_kvass = 1000)
//Cooking oil tank
/obj/structure/reagent_dispensers/cookingoil
name = "cooking oil tank"
desc = "A tank of commercial-grade corn oil, intended for use in large scale deep fryers. Store in a cool, dark place"
icon_state = "oiltank"
amount_per_transfer_from_this = 120
capacity = 1000
reagents_to_add = list(/singleton/reagent/nutriment/triglyceride/oil/corn = 1000)
has_fill_levels = TRUE
is_persistent = TRUE
/obj/structure/reagent_dispensers/cookingoil/bullet_act(obj/projectile/hitting_projectile, def_zone, piercing_hit)
. = ..()
if(. != BULLET_ACT_HIT)
return .
if(hitting_projectile.get_structure_damage())
ex_act(2.0)
//Coolant tank
/obj/structure/reagent_dispensers/coolanttank
name = "coolant tank"
desc = "A tank of industrial coolant"
icon_state = "coolanttank"
amount_per_transfer_from_this = 10
reagents_to_add = list(/singleton/reagent/coolant = 1000)
/obj/structure/reagent_dispensers/coolanttank/bullet_act(obj/projectile/hitting_projectile, def_zone, piercing_hit)
. = ..()
if(. != BULLET_ACT_HIT)
return .
if(hitting_projectile.get_structure_damage())
if (hitting_projectile.damage_type != DAMAGE_PAIN)
explode()
/obj/structure/reagent_dispensers/coolanttank/ex_act(var/severity = 2.0)
explode()
/obj/structure/reagent_dispensers/coolanttank/proc/explode()
var/datum/effect/effect/system/smoke_spread/S = new /datum/effect/effect/system/smoke_spread
//S.attach(src)
S.set_up(5, 0, src.loc)
playsound(src.loc, 'sound/effects/smoke.ogg', 50, 1, -3)
INVOKE_ASYNC(S, TYPE_PROC_REF(/datum/effect/effect/system/smoke_spread, start))
if(src.loc)
var/datum/gas_mixture/env = src.loc.return_air()
if(env && reagents.total_volume)
env.temperature = max(173, env.temperature - (reagents.total_volume/10))
QDEL_IN(src, 10)
//acid barrel
/obj/structure/reagent_dispensers/acid_barrel
name = "chemical barrel"
desc = "A metal barrel filled with deadly sulfuric acid."
icon_state = "acid_barrel"
amount_per_transfer_from_this = 300
reagents_to_add = list(/singleton/reagent/acid = 1000)
/obj/structure/reagent_dispensers/radioactive_waste
name = "radioactive waste barrel"
desc = "A metal barrel containing radioactive waste."
icon_state = "chemical_barrel"
amount_per_transfer_from_this = 300
reagents_to_add = list(/singleton/reagent/radioactive_waste = 1000)
maxhealth = OBJECT_HEALTH_VERY_HIGH //Made of plasteel, because it's dangerous to break.
material = MATERIAL_PLASTEEL
/obj/structure/reagent_dispensers/antagonist_hints(mob/user, distance, is_adjacent)
. += ..()
if(can_tamper)
. += "Using a wrench on this with the Harm intent will open or close the faucet; an open faucet will cause it to continuously leak its contents."
. += "This hint is being repeated for emphasis. MAKING THIS LEAK WILL CAUSE EVERYONE NEARBY TO HAVE A BAD TIME."
/// Only use this if you want active radiation.
ABSTRACT_TYPE(/obj/structure/reagent_dispensers/radioactive_waste/hazardous)
name = "leaking radioactive waste barrel"
desc = "A metal barrel containing radioactive waste; the seals on this one seem to have failed and noxious fumes are escaping!"
light_range = 2
light_power = 0.6
light_color = "#64C864"
/// Radiation generated by SSradiation.radiate each process() tick.
var/radioactivity
/obj/structure/reagent_dispensers/radioactive_waste/hazardous/antagonist_hints(mob/user, distance, is_adjacent)
. += ..()
. += "Characters directly adjacent to this object will be exposed to <b>[radioactivity] IU/s</b> of radiation. Radiation falls off (approximately) by 75% for every tile away you move."
/obj/structure/reagent_dispensers/radioactive_waste/hazardous/low
radioactivity = RAD_LEVEL_LOW
/obj/structure/reagent_dispensers/radioactive_waste/hazardous/low/antagonist_hints(mob/user, distance, is_adjacent)
. += ..()
. += "Geiger counters will start clicking at ~3 tiles away from this object."
. += "Almost all voidsuits, including softsuits, provide sufficient protection to move safely adjacent to it."
/obj/structure/reagent_dispensers/radioactive_waste/hazardous/medium
radioactivity = RAD_LEVEL_MODERATE
/obj/structure/reagent_dispensers/radioactive_waste/hazardous/medium/antagonist_hints(mob/user, distance, is_adjacent)
. += "Geiger counters will start clicking at ~5 tiles away from this object."
. += "An engineering voidsuit is necessary to move safely adjacent to it."
/obj/structure/reagent_dispensers/radioactive_waste/hazardous/high
/// This is as high as radsuits can absorb! Use with caution.
radioactivity = RAD_LEVEL_HIGH
/obj/structure/reagent_dispensers/radioactive_waste/hazardous/high/antagonist_hints(mob/user, distance, is_adjacent)
. += "Geiger counters will start clicking at ~7 tiles away from this object."
. += "A radsuit is necessary to move safely adjacent to it."
/obj/structure/reagent_dispensers/radioactive_waste/hazardous/very_high
/// This is as high as radsuits can absorb! Use with caution.
radioactivity = RAD_LEVEL_VERY_HIGH
/obj/structure/reagent_dispensers/radioactive_waste/hazardous/very_high/antagonist_hints(mob/user, distance, is_adjacent)
. += "Geiger counters will start clicking at ~11 tiles away from this object."
. += "A radsuit is necessary to move safely adjacent to it."
/obj/structure/reagent_dispensers/radioactive_waste/hazardous/extreme
/// This is higher than radsuits can absorb! Use with caution.
radioactivity = RAD_LEVEL_CATASTROPHIC
/obj/structure/reagent_dispensers/radioactive_waste/hazardous/extreme/antagonist_hints(mob/user, distance, is_adjacent)
. += "Geiger counters will start clicking at ~11 tiles away from this object."
. += "No living thing can safely stand next to this object! Borgs or IPCs only!"
/obj/structure/reagent_dispensers/radioactive_waste/hazardous/Initialize()
. = ..()
if(radioactivity)
START_PROCESSING(SSprocessing, src)
/obj/structure/reagent_dispensers/radioactive_waste/hazardous/process()
if(!is_leaking && reagents.total_volume <= 0)
STOP_PROCESSING(SSprocessing,src)
return
else
if(reagents.total_volume > 0)
SSradiation.radiate(src, radioactivity)
/// The residue probably still isn't very nice.
else
SSradiation.radiate(src, radioactivity / 4)
if(is_leaking && prob(10))
var/splash_amount = min(amount_per_transfer_from_this, rand(2,10))
reagents.trans_to_turf(get_turf(src), splash_amount)
return