diff --git a/code/game/objects/effects/chem/puddle.dm b/code/game/objects/effects/chem/puddle.dm
new file mode 100644
index 0000000000..9d6eafa389
--- /dev/null
+++ b/code/game/objects/effects/chem/puddle.dm
@@ -0,0 +1,107 @@
+
+/obj/effect/decal/cleanable/chempuddle
+ name = "puddle"
+ icon = 'icons/effects/chempuddle.dmi'
+ icon_state = "puddle"
+
+ mouse_opacity = FALSE
+
+/obj/effect/decal/cleanable/chempuddle/Initialize()
+ . = ..()
+
+ create_reagents(100)
+
+ addtimer(CALLBACK(src, .proc/evaporation_pulse), 10 SECONDS)
+
+/obj/effect/decal/cleanable/chempuddle/Destroy()
+ var/turf/T = get_turf(src)
+
+ . = ..()
+
+ for(var/obj/effect/decal/cleanable/chempuddle/CP in range(1, T))
+ CP.update_icon(TRUE)
+
+/obj/effect/decal/cleanable/chempuddle/proc/Spread(exclude=list())
+ if(reagents.total_volume < (25 * reagents.get_viscosity())) return
+ var/turf/simulated/S = get_turf(src)
+ if(!istype(S)) return
+
+ exclude |= S
+
+ var/list/possible_targets = list()
+ for(var/d in cardinal)
+ var/turf/simulated/target = get_step(src,d)
+ var/turf/simulated/origin = get_turf(src)
+ if(!(target in exclude))
+ if((target in origin.AdjacentTurfs()))
+ if(istype(target))
+ possible_targets |= target
+
+ if(LAZYLEN(possible_targets))
+ while(possible_targets.len)
+ var/turf/T = pick(possible_targets) // Don't always go NORTH, please. It's kind of weird.
+ possible_targets -= T
+
+ var/obj/effect/decal/cleanable/chempuddle/other_puddle = locate() in T
+ if(!istype(other_puddle))
+ other_puddle = new(T)
+ reagents.trans_to_holder(other_puddle.reagents, (reagents.total_volume - (25 * reagents.get_viscosity())) * (1 / possible_targets.len))
+ other_puddle.Spread(exclude)
+
+ if(reagents.total_volume)
+ for(var/datum/reagent/current in reagents.reagent_list)
+ current.touch_turf(S, current.volume / 4)
+ reagents.update_total()
+
+ update_icon()
+
+/obj/effect/decal/cleanable/chempuddle/fire_act() // Boil bubble toil and trouble. This will "evaporate" chems, and allow some to do their more dangerous effects, IE Fuel.
+ . = ..()
+ Spread()
+
+/obj/effect/decal/cleanable/chempuddle/Crossed(atom/movable/AM, oldloc)
+ Spread() // Splashing through puddles can disturb them enough to spread them.
+ . = ..()
+
+ if(reagents.total_volume)
+ reagents.touch(AM, max(min(3, reagents.total_volume),reagents.total_volume / 3))
+
+/obj/effect/decal/cleanable/chempuddle/update_icon(var/recursion = FALSE)
+ var/list/cardinals = list(NORTH,SOUTH,EAST,WEST)
+ var/list/present_puddles = list()
+ for(var/dir in cardinals)
+ if(locate(/obj/effect/decal/cleanable/chempuddle) in get_step(src, dir))
+ present_puddles |= dir
+
+ if(LAZYLEN(present_puddles))
+ icon_state = initial(icon_state)
+ for(var/dir in present_puddles)
+ icon_state += "-[dir]"
+
+ if(!recursion)
+ for(var/obj/effect/decal/cleanable/chempuddle/CP in range(1, src))
+ CP.update_icon(TRUE)
+
+ color = reagents.get_color()
+
+/obj/effect/decal/cleanable/chempuddle/proc/evaporation_pulse()
+ set waitfor = FALSE
+ var/turf/T = get_turf(src)
+ var/evaporation_rate = 1
+ if(istype(T, /turf/space))
+ evaporation_rate = 10
+
+ else if(T.outdoors)
+ evaporation_rate = 3
+
+ if(T.temperature > T0C + 10)
+ evaporation_rate *= 2
+
+ reagents.remove_any(evaporation_rate)
+
+ if(reagents.total_volume <= 0)
+ qdel(src)
+ return
+
+ Spread()
+ addtimer(CALLBACK(src, .proc/evaporation_pulse), 10 SECONDS)
diff --git a/code/modules/assembly/igniter.dm b/code/modules/assembly/igniter.dm
index 3349e4df11..56a484b8eb 100644
--- a/code/modules/assembly/igniter.dm
+++ b/code/modules/assembly/igniter.dm
@@ -20,10 +20,10 @@
if(location)
location.hotspot_expose(1000,1000)
if (istype(src.loc,/obj/item/device/assembly_holder))
- 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()
+ if (istype(src.loc.loc, /obj/structure/reagent_dispensers))
+ var/obj/structure/reagent_dispensers/tank = src.loc.loc
+ if (tank && tank.faucet)
+ tank.rupture()
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
s.set_up(3, 1, src)
diff --git a/code/modules/materials/materials/plastic.dm b/code/modules/materials/materials/plastic.dm
index 6cf45fe677..309567cece 100644
--- a/code/modules/materials/materials/plastic.dm
+++ b/code/modules/materials/materials/plastic.dm
@@ -30,7 +30,8 @@
new /datum/stack_recipe("lampshade", /obj/item/weapon/lampshade, 1, time = 1, pass_stack_color = TRUE, recycle_material = "[name]"),
new /datum/stack_recipe("plastic net", /obj/item/weapon/material/fishing_net, 25, time = 1 MINUTE, pass_stack_color = TRUE, recycle_material = "[name]"),
new /datum/stack_recipe("plastic fishtank", /obj/item/glass_jar/fish/plastic, 2, time = 30 SECONDS, recycle_material = "[name]"),
- new /datum/stack_recipe("reagent tubing", /obj/item/stack/hose, 1, 4, 20, pass_stack_color = TRUE, recycle_material = "[name]")
+ new /datum/stack_recipe("reagent tubing", /obj/item/stack/hose, 1, 4, 20, pass_stack_color = TRUE, recycle_material = "[name]"),
+ new /datum/stack_recipe("chemical tank", /obj/structure/reagent_dispensers/empty, 30, time = 15 SECONDS, one_per_turf = 1, on_floor = 1, pass_stack_color = TRUE, recycle_material = "[name]")
)
/datum/material/cardboard
diff --git a/code/modules/power/tesla/tesla_act.dm b/code/modules/power/tesla/tesla_act.dm
index 358e371150..ef8a4e08f4 100644
--- a/code/modules/power/tesla/tesla_act.dm
+++ b/code/modules/power/tesla/tesla_act.dm
@@ -56,9 +56,9 @@
dump_contents()
qdel(src)
-/obj/structure/reagent_dispensers/fueltank/tesla_act()
+/obj/structure/reagent_dispensers/tesla_act()
..() //extend the zap
- explode()
+ rupture()
/obj/mecha/tesla_act(power)
..()
diff --git a/code/modules/reagents/holder/holder.dm b/code/modules/reagents/holder/holder.dm
index cdb602ad70..355bfaad06 100644
--- a/code/modules/reagents/holder/holder.dm
+++ b/code/modules/reagents/holder/holder.dm
@@ -66,6 +66,14 @@
return the_id
+/datum/reagents/proc/get_viscosity() // Returns a multiplier for the mixture's viscosity.
+ . = 0
+ if(total_volume <= 0)
+ return
+ for(var/datum/reagent/A in reagent_list)
+ . += A.viscosity * A.volume
+ . = max(0.1, . / total_volume)
+
/datum/reagents/proc/update_total() // Updates volume.
total_volume = 0
for(var/datum/reagent/R in reagent_list)
@@ -246,6 +254,12 @@
. += "[current.id] ([current.volume])"
return english_list(., "EMPTY", "", ", ", ", ")
+/datum/reagents/proc/has_liquids()
+ for(var/datum/reagent/current in reagent_list)
+ if(current.reagent_state == LIQUID)
+ return TRUE
+ return FALSE
+
/* 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.
@@ -386,7 +400,16 @@
return
for(var/datum/reagent/current in reagent_list)
- current.touch_turf(target, amount)
+ if(!has_liquids() || current.no_puddle)
+ current.touch_turf(target, amount)
+
+
+ if(has_liquids())
+ var/obj/effect/decal/cleanable/chempuddle/CP = locate() in target
+ if(!CP)
+ CP = new(target)
+ trans_to_holder(CP.reagents, amount)
+ CP.Spread()
update_total()
@@ -517,7 +540,7 @@
trans_to(T, total_volume, multiplier, copy)
if (total_volume <= 0)
qdel(src)
-
+
/**
* Calls [/datum/reagent/proc/on_update] on every reagent in this holder
*
diff --git a/code/modules/reagents/machinery/dispenser/reagent_tank.dm b/code/modules/reagents/machinery/dispenser/reagent_tank.dm
index bdae0485f1..e05d54e1c9 100644
--- a/code/modules/reagents/machinery/dispenser/reagent_tank.dm
+++ b/code/modules/reagents/machinery/dispenser/reagent_tank.dm
@@ -10,6 +10,8 @@
anchored = 0
pressure_resistance = 2*ONE_ATMOSPHERE
+ var/faucet = FALSE
+
var/obj/item/hose_connector/input/active/InputSocket
var/obj/item/hose_connector/output/active/OutputSocket
@@ -17,7 +19,23 @@
var/possible_transfer_amounts = list(10,25,50,100)
/obj/structure/reagent_dispensers/attackby(obj/item/weapon/W as obj, mob/user as mob)
- return
+ src.add_fingerprint(user)
+ if (W.get_tool_quality(TOOL_WRENCH))
+ user.visible_message("[user] wrenches [src]'s faucet [faucet ? "closed" : "open"].", \
+ "You wrench [src]'s faucet [faucet ? "closed" : "open"]")
+ faucet = !faucet
+ playsound(src, W.usesound, 75, 1)
+ if (faucet)
+ message_admins("[key_name_admin(user)] opened a reagent tank at [loc.loc.name] ([loc.x],[loc.y],[loc.z]), leaking [LAZYLEN(reagents.reagent_list) ? english_list(reagents.reagent_list) : "nothing"]. (JMP)")
+ log_game("[key_name(user)] opened reagent tank at [loc.loc.name] ([loc.x],[loc.y],[loc.z]), leaking [LAZYLEN(reagents.reagent_list) ? english_list(reagents.reagent_list) : "nothing"].")
+ leak(amount_per_transfer_from_this)
+ return ..()
+
+/obj/structure/reagent_dispensers/examine(mob/user)
+ . = ..()
+ if(get_dist(user, src) <= 2)
+ if(faucet)
+ . += SPAN_WARNING("The faucet is wrenched open, leaking the contents!")
/obj/structure/reagent_dispensers/Destroy()
QDEL_NULL(InputSocket)
@@ -57,6 +75,26 @@
if (N)
amount_per_transfer_from_this = N
+/obj/structure/reagent_dispensers/Move()
+ . = ..()
+ if (. && faucet)
+ leak(amount_per_transfer_from_this / 5 / reagents.get_viscosity())
+
+/obj/structure/reagent_dispensers/proc/leak(amount)
+ if (reagents.total_volume <= 0)
+ return
+
+ amount = min(amount, reagents.total_volume)
+
+ var/turf/T = get_turf(src)
+
+ var/obj/effect/decal/cleanable/chempuddle/CP = locate() in T
+ if(!CP)
+ CP = new(T)
+ reagents.trans_to_holder(CP.reagents, amount)
+ spawn(1)
+ CP.Spread()
+
/obj/structure/reagent_dispensers/ex_act(severity)
switch(severity)
if(1.0)
@@ -75,10 +113,63 @@
else
return
+/obj/structure/reagent_dispensers/bullet_act(var/obj/item/projectile/Proj)
+ if(Proj.get_structure_damage())
+ if(istype(Proj.firer))
+ message_admins("[key_name_admin(Proj.firer)] shot reagent tank at [loc.loc.name] ([loc.x],[loc.y],[loc.z]) (JMP).")
+ log_game("[key_name(Proj.firer)] shot reagent tank at [loc.loc.name] ([loc.x],[loc.y],[loc.z]).")
+
+ if(Proj.sharp || (istype(Proj, /obj/item/projectile/beam) && !Proj.damage))
+ rupture()
+
+/obj/structure/reagent_dispensers/ex_act()
+ rupture()
+
/obj/structure/reagent_dispensers/blob_act()
- qdel(src)
+ rupture()
+/obj/structure/reagent_dispensers/proc/rupture()
+ var/severity = 1
+ var/violent = FALSE
+ if (reagents.total_volume > 500)
+ severity = 3
+ reagents.trans_to_turf(get_turf(src), reagents.total_volume / 5)
+ else if (reagents.total_volume > 100)
+ severity = 2
+ reagents.trans_to_turf(get_turf(src), reagents.total_volume / 3)
+ else if (reagents.total_volume > 50)
+ severity = 1
+ reagents.trans_to_turf(get_turf(src), reagents.total_volume / 2)
+
+ if(reagents.has_any_reagent(list("phoron","fuel","hydrophoron")))
+ violent = TRUE
+
+ if(violent)
+ switch(severity)
+ if(3)
+ explosion(get_turf(src),1,2,4)
+ if(2)
+ explosion(get_turf(src),0,1,3)
+ if(1)
+ explosion(get_turf(src),-1,1,2)
+
+ if(!QDELETED(src))
+ qdel(src)
+
+/obj/structure/reagent_dispensers/fire_act(datum/gas_mixture/air, temperature, volume)
+ if (faucet)
+ rupture()
+ else if (temperature > T0C+500)
+ rupture()
+ return ..()
+
+/obj/structure/reagent_dispensers/empty
+ name = "chemical tank"
+ desc = "A chemical tank."
+ icon = 'icons/obj/machines/reagent.dmi'
+ icon_state = "chemtank"
+ amount_per_transfer_from_this = 10
//Dispensers
/obj/structure/reagent_dispensers/watertank
@@ -107,7 +198,6 @@
icon = 'icons/obj/objects.dmi'
icon_state = "weldtank"
amount_per_transfer_from_this = 10
- var/modded = 0
var/obj/item/device/assembly_holder/rig = null
/obj/structure/reagent_dispensers/fueltank/Initialize()
@@ -117,7 +207,7 @@
/obj/structure/reagent_dispensers/fueltank/examine(mob/user)
. = ..()
if(get_dist(user, src) <= 2)
- if(modded)
+ if(faucet)
. += "Fuel faucet is wrenched open, leaking the fuel!"
if(rig)
. += "There is some kind of device rigged to the tank."
@@ -133,15 +223,7 @@
/obj/structure/reagent_dispensers/fueltank/attackby(obj/item/weapon/W as obj, mob/user as mob)
src.add_fingerprint(user)
- if (W.get_tool_quality(TOOL_WRENCH))
- user.visible_message("[user] wrenches [src]'s faucet [modded ? "closed" : "open"].", \
- "You wrench [src]'s faucet [modded ? "closed" : "open"]")
- modded = modded ? 0 : 1
- playsound(src, W.usesound, 75, 1)
- if (modded)
- message_admins("[key_name_admin(user)] opened fueltank at [loc.loc.name] ([loc.x],[loc.y],[loc.z]), leaking fuel. (JMP)")
- log_game("[key_name(user)] opened fueltank at [loc.loc.name] ([loc.x],[loc.y],[loc.z]), leaking fuel.")
- leak_fuel(amount_per_transfer_from_this)
+
if (istype(W,/obj/item/device/assembly_holder))
if (rig)
to_chat(user, "There is another device in the way.")
@@ -166,51 +248,6 @@
return ..()
-
-/obj/structure/reagent_dispensers/fueltank/bullet_act(var/obj/item/projectile/Proj)
- if(Proj.get_structure_damage())
- if(istype(Proj.firer))
- message_admins("[key_name_admin(Proj.firer)] shot fueltank at [loc.loc.name] ([loc.x],[loc.y],[loc.z]) (JMP).")
- log_game("[key_name(Proj.firer)] shot fueltank at [loc.loc.name] ([loc.x],[loc.y],[loc.z]).")
-
- if(!istype(Proj ,/obj/item/projectile/beam/lasertag) && !istype(Proj ,/obj/item/projectile/beam/practice) )
- explode()
-
-/obj/structure/reagent_dispensers/fueltank/ex_act()
- explode()
-
-/obj/structure/reagent_dispensers/fueltank/blob_act()
- explode()
-
-/obj/structure/reagent_dispensers/fueltank/proc/explode()
- 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)
- if(src)
- qdel(src)
-
-/obj/structure/reagent_dispensers/fueltank/fire_act(datum/gas_mixture/air, temperature, volume)
- if (modded)
- explode()
- else if (temperature > T0C+500)
- explode()
- return ..()
-
-/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)
-
/obj/structure/reagent_dispensers/peppertank
name = "Pepper Spray Refiller"
desc = "Refills pepper spray canisters."
@@ -405,7 +442,7 @@
/obj/structure/reagent_dispensers/acid/Initialize()
. = ..()
reagents.add_reagent("sacid", 1000)
-
+
//Cooking oil refill tank
/obj/structure/reagent_dispensers/cookingoil
name = "cooking oil tank"
diff --git a/code/modules/reagents/machinery/pump.dm b/code/modules/reagents/machinery/pump.dm
index a8767f9fdf..7be78f8dcc 100644
--- a/code/modules/reagents/machinery/pump.dm
+++ b/code/modules/reagents/machinery/pump.dm
@@ -202,4 +202,4 @@
/turf/simulated/floor/water/contaminated/pump_reagents(var/datum/reagents/R, var/volume)
. = ..()
- R.add_reagent("vatstabilizer", round(volume / 2, 0.1))
\ No newline at end of file
+ R.add_reagent("vatstabilizer", round(volume / 2, 0.1))
diff --git a/code/modules/reagents/reactions/distilling/distilling.dm b/code/modules/reagents/reactions/distilling/distilling.dm
index d7c86b46b5..b7d3b5222c 100644
--- a/code/modules/reagents/reactions/distilling/distilling.dm
+++ b/code/modules/reagents/reactions/distilling/distilling.dm
@@ -157,7 +157,7 @@
id = "distill_brutejuice"
result = "berserkmed"
required_reagents = list("biomass" = 1, "hyperzine" = 3, "synaptizine" = 2, "phoron" = 1)
- result_amount = 3
+ result_amount = 5
temp_range = list(T0C + 600, T0C + 700)
temp_shift = 4
@@ -176,7 +176,7 @@
result = "cryoslurry"
required_reagents = list("frostoil" = 7, "enzyme" = 3, "plasticide" = 3, "foaming_agent" = 2)
inhibitors = list("water" = 5)
- result_amount = 1
+ result_amount = 12
temp_range = list(0, 15)
temp_shift = 20
@@ -214,3 +214,14 @@
reaction_rate = HALF_LIFE(20)
temp_range = list(T0C + 90, T0C + 95)
+
+/decl/chemical_reaction/distilling/phoron_plasma
+ name = "Energizing Phoron"
+ id = "energize_phoron"
+ result = "energetic_phoron"
+ required_reagents = list("phoron" = 5)
+ catalysts = list("hydrophoron" = 10)
+
+ result_amount = 4
+
+ temp_range = list(T0C + 100, T0C + 200)
diff --git a/code/modules/reagents/reactions/instant/instant.dm b/code/modules/reagents/reactions/instant/instant.dm
index 910aa07c79..87f1157f7b 100644
--- a/code/modules/reagents/reactions/instant/instant.dm
+++ b/code/modules/reagents/reactions/instant/instant.dm
@@ -1054,6 +1054,14 @@
inhibitors = list("nitrogen" = 1) //So it doesn't mess with lexorin
result_amount = 2
+/decl/chemical_reaction/instant/energized_phoron
+ name = "phoron plasma"
+ id = "inst_energetic_phoron"
+ result = "energetic_phoron"
+ required_reagents = list("phoron" = 1, "hydrophoron" = 3)
+ inhibitors = list("nitrogen" = 1) //So it doesn't mess with hydrophoron
+ result_amount = 3
+
/decl/chemical_reaction/instant/deuterium
name = "Deuterium"
id = "deuterium"
diff --git a/code/modules/reagents/reagents/_reagents.dm b/code/modules/reagents/reagents/_reagents.dm
index 031fe0cd6e..3958c8e36f 100644
--- a/code/modules/reagents/reagents/_reagents.dm
+++ b/code/modules/reagents/reagents/_reagents.dm
@@ -23,6 +23,9 @@
var/can_overdose_touch = FALSE // Can the chemical OD when processing on touch?
var/scannable = 0 // Shows up on health analyzers.
+ var/viscosity = 1 // Resistance to flow.
+ var/no_puddle = FALSE // Prevent the creation of reagent puddles?
+
var/affects_dead = 0 // Does this chem process inside a corpse?
var/affects_robots = 0 // Does this chem process inside a Synth?
diff --git a/code/modules/reagents/reagents/core.dm b/code/modules/reagents/reagents/core.dm
index 64fa18c67e..ddccca1afc 100644
--- a/code/modules/reagents/reagents/core.dm
+++ b/code/modules/reagents/reagents/core.dm
@@ -11,6 +11,8 @@
color = "#C80000"
var/volume_mod = 1 // So if you add different subtypes of blood, you can affect how much vessel blood each unit of reagent adds
+ viscosity = 0.3 // Slightly thicker than water.
+
glass_name = "tomato juice"
glass_desc = "Are you sure this is tomato juice?"
@@ -157,6 +159,8 @@
color = "#0064C877"
metabolism = REM * 10
+ viscosity = 0.2 // For puddle flow, this forms puddles roughly of 5 units. Little bit of water goes a long way.
+
glass_name = "water"
glass_desc = "The father of all refreshments."
diff --git a/code/modules/reagents/reagents/other.dm b/code/modules/reagents/reagents/other.dm
index 7ae039594e..1ae3f447f4 100644
--- a/code/modules/reagents/reagents/other.dm
+++ b/code/modules/reagents/reagents/other.dm
@@ -434,6 +434,7 @@
reagent_state = LIQUID
color = "#A5F0EE"
touch_met = 50
+ no_puddle = TRUE
/datum/reagent/space_cleaner/touch_mob(var/mob/M)
..()
diff --git a/code/modules/reagents/reagents/toxins.dm b/code/modules/reagents/reagents/toxins.dm
index 030ee9450e..503dcdef4e 100644
--- a/code/modules/reagents/reagents/toxins.dm
+++ b/code/modules/reagents/reagents/toxins.dm
@@ -89,6 +89,7 @@
/datum/reagent/toxin/hydrophoron
name = "Hydrophoron"
id = "hydrophoron"
+ reagent_state = SOLID
description = "An exceptionally flammable molecule formed from deuterium synthesis."
strength = 80
var/fire_mult = 30
@@ -122,6 +123,27 @@
spawn(rand(30, 60))
M.IgniteMob()
+/datum/reagent/toxin/energized_phoron
+ name = "phoron plasma"
+ id = "energetic_phoron"
+ description = "A strange, liquid-like form of Phoron."
+ strength = 20
+ affects_robots = TRUE
+
+ var/fire_mult = 4
+
+/datum/reagent/toxin/energized_phoron/affect_touch(var/mob/living/carbon/M, var/alien, var/removed)
+ ..()
+ M.apply_damage(removed * 30, ELECTROCUTE, ran_zone())
+ M.apply_damage(removed * 10, BIOACID, ran_zone())
+ if(prob(10 * fire_mult))
+ M.pl_effects()
+
+/datum/reagent/toxin/energized_phoron/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
+ ..()
+ M.apply_damage(removed * 40, ELECTROCUTE, ran_zone())
+ M.adjust_fire_stacks(removed * 5)
+
/datum/reagent/toxin/lead
name = "lead"
id = "lead"
@@ -139,9 +161,9 @@
/datum/reagent/toxin/phoron
name = "Phoron"
id = "phoron"
- description = "Phoron in its liquid form."
+ description = "Phoron in a powdered form."
taste_mult = 1.5
- reagent_state = LIQUID
+ reagent_state = SOLID
color = "#9D14DB"
strength = 30
touch_met = 5
diff --git a/code/modules/reagents/structures/geyser.dm b/code/modules/reagents/structures/geyser.dm
new file mode 100644
index 0000000000..7f33d1482f
--- /dev/null
+++ b/code/modules/reagents/structures/geyser.dm
@@ -0,0 +1,117 @@
+
+/obj/structure/geyser
+ name = "geothermal vent"
+ desc = "A geothermal vent."
+ description_info = "A geothermal vent capable of being \"mined\" for a reagent via a Reagent Pump.\
+ The reagent is often randomized, but can be guessed via the color of the reagent, or a reagent scanner."
+
+ icon = 'icons/obj/machines/reagent.dmi'
+ icon_state = "geyser"
+
+ density = FALSE
+
+ var/list/reagent_set // The associative list of what reagents this geyser produces. [ID = Amount]
+
+ var/max_reagent_picks = 3
+
+ var/list/allowed_reagents // The associated list of what reagents are allowed to be picked by RNG. [ID = [Min AMT, Max AMT]]
+
+ var/display_reagents = TRUE
+ var/reagent_overlay_state
+
+ var/icon/reagent_overlay_icon
+
+ var/datum/effect_system/smoke_spread/chem/Smoke
+
+/obj/structure/geyser/Initialize()
+ . = ..()
+
+ create_reagents(100)
+ Smoke = new(src)
+ Smoke.show_log = FALSE
+
+ if(display_reagents == TRUE)
+ if(!reagent_overlay_state)
+ reagent_overlay_state = "[icon_state]-reag"
+
+ reagent_overlay_icon = new/icon(icon, reagent_overlay_state)
+
+ var/list/from_reag = get_allowed_reagents()
+
+ if(!LAZYLEN(reagent_set) && LAZYLEN(from_reag))
+ LAZYINITLIST(reagent_set)
+ var/reag_count = rand(1, max_reagent_picks)
+ for(var/count = 1, count <= reag_count, count++)
+ var/targ_reagent = pick(from_reag)
+
+ if(targ_reagent in SSchemistry.chemical_reagents)
+ var/reag_bounds = from_reag[targ_reagent]
+ reagent_set[targ_reagent] = rand(reag_bounds[1],reag_bounds[2])
+
+ if(LAZYLEN(reagent_set))
+ START_PROCESSING(SSobj, src)
+
+/obj/structure/geyser/Destroy()
+ STOP_PROCESSING(SSobj, src)
+ . = ..()
+
+/obj/structure/geyser/update_icon()
+ cut_overlays()
+ if(reagent_overlay_icon && reagents.total_volume)
+ var/list/hextorgb = hex2rgb(reagents.get_color())
+ reagent_overlay_icon.GrayScale()
+
+ reagent_overlay_icon.Blend(rgb(hextorgb[1],hextorgb[2],hextorgb[3]),ICON_MULTIPLY)
+
+ add_overlay(reagent_overlay_icon)
+
+/obj/structure/geyser/process()
+ var/obj/machinery/pump/Pump = locate() in get_turf(src)
+
+ for(var/reag_id in reagent_set)
+ reagents.add_reagent(reag_id, reagent_set[reag_id])
+
+ if(Pump && Pump.anchored)
+ return
+
+ if(reagents.total_volume > 20 && prob(round(reagents.total_volume / 10)))
+ Smoke.set_up(reagents, rand(3,10), 0, get_turf(src))
+ Smoke.start()
+
+ update_icon()
+
+/obj/structure/geyser/proc/get_allowed_reagents()
+ return allowed_reagents
+
+/obj/structure/geyser/planetary
+ desc = "A rocky outcropping."
+
+ allowed_reagents = list(
+ "carbon" = list(1,10),
+ "gold" = list(1,3),
+ "silver" = list(1,5),
+ "hydrogen" = list(3,10),
+ "nitrogen" = list(10,30),
+ "oxygen" = list(5,15),
+ "sacid" = list(1,5),
+ "sulfur" = list(2,10),
+ "phoron" = list(1,1),
+ "fuel" = list(10,30),
+ "mineralizedfluid" = list(1,20)
+ )
+
+/obj/structure/geyser/planetary/phorogenic
+ desc = "An ominous outcropping."
+
+ allowed_reagents = list(
+ "energetic_phoron" = list(5,10)
+ )
+
+/obj/structure/geyser/truerandom
+ name = "strange vent"
+
+/obj/structure/geyser/truerandom/get_allowed_reagents()
+ var/list/allowed_reagents = list()
+ for(var/I = 1, I <= max_reagent_picks, I++)
+ allowed_reagents[pick(SSchemistry.chemical_reagents)] = list(rand(1,5), rand(5,10))
+ return ..()
diff --git a/code/modules/tools/tools/weldingtool.dm b/code/modules/tools/tools/weldingtool.dm
index efa123fc8d..f25c05d3db 100644
--- a/code/modules/tools/tools/weldingtool.dm
+++ b/code/modules/tools/tools/weldingtool.dm
@@ -144,9 +144,11 @@
/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)
+ if (istype(O, /obj/structure/reagent_dispensers) && get_dist(src,O) <= 1)
+ var/obj/structure/reagent_dispensers/tank = O
if(!welding && max_fuel)
O.reagents.trans_to_obj(src, max_fuel)
+ reagents.isolate_reagent("fuel")
to_chat(user, "Welder refueled")
playsound(src, 'sound/effects/refill.ogg', 50, 1, -6)
return
@@ -154,11 +156,11 @@
to_chat(user, "[src] doesn't use fuel.")
return
else
- message_admins("[key_name_admin(user)] triggered a fueltank explosion with a welding tool.")
- log_game("[key_name(user)] triggered a fueltank explosion with a welding tool.")
- to_chat(user, "You begin welding on the fueltank and with a moment of lucidity you realize, this might not have been the smartest thing you've ever done.")
- var/obj/structure/reagent_dispensers/fueltank/tank = O
- tank.explode()
+ if(O.reagents.has_any_reagent(list("phoron","fuel","hydrophoron")))
+ message_admins("[key_name_admin(user)] ruptured a reagent tank with a welding tool, triggering an explosion.")
+ log_game("[key_name(user)] ruptured a reagent tank with a welding tool, triggering an explosion.")
+ to_chat(user, "You begin welding on the reagent tank and with a moment of lucidity you realize, this might not have been the smartest thing you've ever done.")
+ tank.rupture()
return
if (src.welding)
remove_fuel(1)
diff --git a/icons/effects/chempuddle.dmi b/icons/effects/chempuddle.dmi
new file mode 100644
index 0000000000..76b06ba748
Binary files /dev/null and b/icons/effects/chempuddle.dmi differ
diff --git a/icons/obj/machines/reagent.dmi b/icons/obj/machines/reagent.dmi
index 7a284942bc..4744d75e53 100644
Binary files a/icons/obj/machines/reagent.dmi and b/icons/obj/machines/reagent.dmi differ
diff --git a/polaris.dme b/polaris.dme
index d10bbabbc8..15507b4249 100644
--- a/polaris.dme
+++ b/polaris.dme
@@ -897,6 +897,7 @@
#include "code\game\objects\effects\chem\chemsmoke.dm"
#include "code\game\objects\effects\chem\coating.dm"
#include "code\game\objects\effects\chem\foam.dm"
+#include "code\game\objects\effects\chem\puddle.dm"
#include "code\game\objects\effects\chem\water.dm"
#include "code\game\objects\effects\decals\cleanable.dm"
#include "code\game\objects\effects\decals\crayon.dm"
@@ -2937,6 +2938,7 @@
#include "code\modules\reagents\reagents\modifiers.dm"
#include "code\modules\reagents\reagents\other.dm"
#include "code\modules\reagents\reagents\toxins.dm"
+#include "code\modules\reagents\structures\geyser.dm"
#include "code\modules\recycling\conveyor2.dm"
#include "code\modules\recycling\disposal-construction.dm"
#include "code\modules\recycling\disposal.dm"