From 6996e46ed4276a20cbcc5e3cd35dba26c01d0baa Mon Sep 17 00:00:00 2001 From: Mechoid Date: Sun, 13 Feb 2022 20:45:30 -0800 Subject: [PATCH] Reagent Geysers, Pump Fixing, Puddles. (#8268) * Reagent Geysers, Pump Fixing, Puddles. * blah blah blah, CI fixes, linting, requested changes --- code/game/objects/effects/chem/puddle.dm | 107 ++++++++++++ code/modules/assembly/igniter.dm | 8 +- code/modules/materials/materials/plastic.dm | 3 +- code/modules/power/tesla/tesla_act.dm | 4 +- code/modules/reagents/holder/holder.dm | 27 ++- .../machinery/dispenser/reagent_tank.dm | 155 +++++++++++------- code/modules/reagents/machinery/pump.dm | 2 +- .../reactions/distilling/distilling.dm | 15 +- .../reagents/reactions/instant/instant.dm | 8 + code/modules/reagents/reagents/_reagents.dm | 3 + code/modules/reagents/reagents/core.dm | 4 + code/modules/reagents/reagents/other.dm | 1 + code/modules/reagents/reagents/toxins.dm | 26 ++- code/modules/reagents/structures/geyser.dm | 117 +++++++++++++ code/modules/tools/tools/weldingtool.dm | 14 +- icons/effects/chempuddle.dmi | Bin 0 -> 6087 bytes icons/obj/machines/reagent.dmi | Bin 6662 -> 8323 bytes polaris.dme | 2 + 18 files changed, 417 insertions(+), 79 deletions(-) create mode 100644 code/game/objects/effects/chem/puddle.dm create mode 100644 code/modules/reagents/structures/geyser.dm create mode 100644 icons/effects/chempuddle.dmi 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 0000000000000000000000000000000000000000..76b06ba74863e24cd2dd0e9a3241ef8c55e40fd0 GIT binary patch literal 6087 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 WqCfmew2f8f0Tl&x`D)0Uu>S%6upJWs literal 0 HcmV?d00001 diff --git a/icons/obj/machines/reagent.dmi b/icons/obj/machines/reagent.dmi index 7a284942bc945dcf1652c1bf487394cd338ac452..4744d75e539e1400a794ade7020756a9670241a7 100644 GIT binary patch literal 8323 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 aZtW$V+QHiq>;?b108o-wds!|E3-~YEUG3=r literal 6662 zcmb_hWmr_*w?E8K(hAb0ASEzJi^LETO1FfAf^ov zVa(WHE$zAH2>lYq1>MOM0pwEJ#4c;P7Oan8-MzzQwedFeCNr8MweL~*bv_=_U&{I& z^xJf7lPK*rO+L2wqpM!2YRl64aqgoHUhStRa#qUs#_7e0-%oTQOuq)RmTO2qb>-5j zb=N=2_4rM4Fb3%8l4!5iK8 zSpifHw$Z{JexEy3c>cH=DhnR7M{zAnmaJ=Ye?L{rwW|@$lMN{JQWP%FJA3e6XYP`s zQOZxF`@%})??!@Cs-yVo=qXKo#87THZW`+?n5&@q<(J1T0H7~WQLOgzeHbmX zgoimz(8m7sNx$WXKAAnaXw(yxlq3!j;?r71;^Ajd0RFe zM7C$EYQp-lSRsU-9<*rWO?WsV(7LN0@%~@2__XaI|9 zlY95?fBIWzA;iO6#C7#bO&J>f_U+<$x#jBGTJYQshTbf&g$;1s9KRQEviwofbsnxs zmk;VO-s4Ajd^qLe3-}ykGm8^GeE0wXytbzc9^tOktm}Cc>^xI{=WKR*nv9(`T1G|& zc#=C*4KjUyxL%^As`ql)eq$NV(*712@s+8xW>PwoYgKKt&mw$}teRqQP8&D2FI`m7@Ij>bNd}d~* zamJa5id0DXvy)59c@3ZZmAG|1_IPK3EmX#vhBvt}X!J)=Gahx1+*CbHmSE zGhO-`J8i&%tMLKph$)&!okk;~w6wIVH-Wp{X{sg%IaTA-0Y2!Mo0m*}E0I8EVKZ(% zMbbggcFUn%~dCD}}YS^~>h`gTk^`-*&bC zgpTf>#Dr|d&&&89!qs3uS6A~3IokZze=H1Aj2Y~%(CujEPby{~oW#7zaszhtt#((7 zK{;Jq%6@wf!(EW~ZCT=Iu#<7+1Qr{vv21ebRj?U2jcIw}2F~mXbzIqa;SmwOK>ItT zt_Ze3`lFLRiMi<0Gh4Oizo5GR0IvAvGylWQ>ySs$b$p@27Xt%228OTJ3bbg%8OY-V zKhkQ!AE!otSZjDW0IK6?bpY}7^0GGYcvSL`_n%YR>~+Q0dEKv1+}NS_ErJcXuX5jo0^B8XN67VATbF*Kdkt#{6Uqj!|P7wv>OKM-r5ottl zk&(+lslvm_;Pi~bz%$z(;8o_W{|7?+!DpZ6$bo@@cu(Fq5E#)giqub^c9pYrUUfX< z7Zij5CZ?vbRz(Hxi;T+r=;-LmD=Ka~KJdY2aN+cC-X@(5JatN6s;hHaUS3|^-X1+G zdC$Vaa&~ckD#B`{qZ52`a+0&f!NFmt;kx`iF=yVAS;|AzojN)u#y5L_C#O`NlvC>*ie}yIADt5yvTSV^WW@Rb-wXw3o*VEH$cOydh@oqox zYLIzBDl9JkM`Xz>)_yx?dh)^zC@$R1qHmX6mE@gd5KC$gf2<)3kcX1stLep`C+i4z+c%av3$-l zx8q+^oyDu-1N|5FX@aM-)FrbPk-zdw3yma+|+O`O6j%&77BNnd;i;QQJ;s}x{@In4g|yD$D1Bf<-U7= zic56_xe~5{5uPFfI)^-Bsd1TmJ2`1$Tw*xxC~npq@C2zbf-#;y+q99R-W~>7@7}%3 z!^eC2&!sp_ZEpN z7Z;z?(9x|hp8-@PVKgkTkq#&jDWmjqh>hKPH9kJRZoa{Ng~DrRmOP>(_<{E}PrY)k zS%a6x-w6)Jn8mIbrY}=l`K6_X1_@*tsF9J894C8xIrg%k^!PPRicYfIE0Xs>TL>SQ zB3j-iCo_V!H61t^M$Ne9_=V};4-!Pk`j7UZ??cHbD3+^_6pJZ=vZl{XfglbLW@gN_ z8YS~a?VFqYvZtGs#VsvCmw^){8qcwP7>rF~VQ+48Gb@1Ypp+w?s&Slvr1XWat=VzD zZOWJb^+7jV*LPtdV%HW_bcq;gz@~+H8XiQ!Kp0P=Hy@L1Vc(ASLo8{#fKl}O?PIp>VEG@GO zlkYRIvw6>|<4lNxZXa#WbmXA}3vqL4PB3kAbMrr;K;{D-Y3I0}^V6g2WQ00;dZ8>2 zye#bOu3h5BT7)DdBErJLic7VwE#gVq2(Cb#9_?7ZcyY(2 zQl1igv~qRrCj|@)3_vfxg6@!(TuG!X1Dwm`=omZ(4^PjVo*o|9pyLiUpV2VhK%q0x zLT_&5sXNZpiwP1`OgMt@t8-flUtD<;MF;bvWRdbvn!cfLV6d>3hb9EnH8gxT*4ITv z+UMsp#+G)Oug|TGjgD&T>fWeDXlMwxN(JZg{ls4!Ue@t@KZx2K?~ItzpVC_ZJ-4xO zQ-GIOjie$t7!SsNnfZVzIVGiSudy~ipGOT5^(g~ju$W=rPSK*%hGmVap>W^g7*rvs8sk(~uYIE7j0P)^0KUroQ!s5V< zwMoBd_E>Y)f#F>>IOnfljm(Y6o@B;8XhZq&_P4g8YOAXcR10x(nc6)LwNqju?Pq6=wOLtbGI)e0H{v3Zh<(Dd_MUB zUco}4GMKs!z zn}xXEszKNx0}b|rDCd#T4FmyJ?*wPZ7LxnvLEE^ zdcKml*3E#@kbaa(3ug6K_a{y`(S-U%vU0lb-~7}^BgD?&YDo>s; zoCOAb7oIRNRI|h|t^LW}YZNb{9x24ciU1Y)n6l&x40-8gqwu*T6jXKrG`q@o#;vh3 zgo=Yh(IRPLR65~sgRI=zMmC!b%KvCvjg6Bpq2!JqqxKH&ET=3sFcr^C@MD}-?mtu} zZHkj(j23Qkqnp9P%gb=}uet%3>6X#(>wzJZ-`EN_61l%bHoteWNb%u+Z_{=2S>%g~ zYU59s{{L`x;pz5OKLg26uXEZ*bPo14diJp+tQ8+&wbntQEo=u*mn z%in{>1e)?VM4;+_d)9^rpkxgXu_Y>vT{_UvXvA3^oDk@*NiwPC#ToS*{eG{V-Mw~+zWHds_5R1 zLZuZ-aAyOy`a<^NP3%nOa(X2B)y=6}&liSa`N)= zN!@+{FUfnBZ-7Pw5E<%%eska}r(j0X`Se|?eU-Phbyv}H)D5tQYi#h^dQ^Z>F039j z%9d?8rYNogk-1V@CQ1->H(E?gY&k|bJFXDZTwlN5ggh1Z+M3LL0tmuj{v7edIm%g4 zQBh587D6x=J~fFOzWb{>=`yx>1rC3?+qa))Y7>K5T6Jtm9(OXNRY>+xa#`Mt%XIzb zp}mN#>^8x>F{r-2enwrL@zHlz6A;PgXX}qYsL-XfI*MD)H6y`;?={6n9(=+Z2^7;5 zv^BqS|2(Z7BCu6TRN?-&U#cK;T^qb}F_`=KBn2u@<*RV$peu)4Qh(Qp&cTinVl=1>qb5ux&)^2y;To zw@Wjulsmh1zHgUCAHMnHwz5DpFIbqEh;R0SCjbh<4PZXT3T8F5-9_;?i?)*7wA2)(}PjnV)7ab0u$S_+NrR2 zVhgVH;NfsX<|%Uv8>0_Dr$ zq@<+8grVTj1jVP^uZz}Yzb(+w(Q)?GeZ}<{`wS=t9Bgf=AezyV$G_4Z5CH+DT>U0! zGI-B(a5@8bycqfY+v@vLNLz;MrgA?wl**2Qh2>khWq1G35VU0ueXkBI+kkm+R&)IK z2h450HQ2L63j-)AH=iGxvc3-Tc9(ke_%R*;mhk$^4DiQDMq&=(m$-eq{iCDoygZ`Z z+*}1z*{^@ZV<;#qi}jCW!5%LUM|Ymv*8(PM33#uoz|w42 z*ITb;j!l9palPT|TM~y7ttPmV$-h$rIL#7R&V%!UKPfI<$Usr5#68jf1)$~Sx1g_m>RellnU5n| z8DRn)3r9()x|Y_SX^rDTULM$H@7SlwnZx2t7&~##6m#KV)7Ln(rUX`edV17Z1Nqnn z%*v93gM&d3&*xT{V}&@pd85N+q9QDaX7%0aH!cf-koUJf=j9DC-YI9&Z)6!JH*vLk zfeILlu<^ctv!fy-Bj0z+NQHY#r3t0=EWdJZHcx&k8+E% zz9DPf#(@L4cLxhDvyHv(%n`G*Pe-DKWMulZ)YUTz3e?6&Cnu9VF2MSll}a4|6q2pP zQ+&}FqVh<4hXllSlZ)-@&lk0)0tFjBS%YSc;A8ZoAlh=xxEFvSI&Dc(R8(}nGm={E zU;+%N;2^@=TLKaclvyKvx;i^wSz)2~^n|EI#l#lc!${j@^M-nLbE;N==UiXvXD)kX zD{TOhi+0YXcdBm4!_JR1K>z(=pTS-;(FrSEV|l^m0;d~|bGpWNXOZ?hsR1(nRV}n^%!d!OXKPwP3f|teSy2r1^z&ff#WQ^}k!E_vjI|9K z>?zCN5P1QMWxm4c?wc=x^O4+qecwbWw3B*-fg;T8*jU8TtUsl5?E@#|VRN%=-Hh`$ zx}}$2--WRGq;@x$2`2SfyB&STmSI*D_4E=pBbGe^Sl_-OR~CVj(m&}q<1Y(37%{>F z6crV1?d;^iK!Q6x9T*(E{k~{>V!@Yk{88p#s z7RvVe;G~kRCdM%ICRc?iVCX-v<+TJ0Iw8g3aQKP<6$H(aAg~5W+Olkt+QfSj(;y4y zXjA6Q#>-i+92*`6e9YqZ|MaEg7Zp(-RxXWzMh|0b6MVR+`o-st@ssQ{!VVIuC(vi8 zz=MSYb~H!ZFli2~q6=@om=diuuDa9S-+x)*bjo?S;cE9v*-8{Od$6#lQOMp>)p6&( z+S~E*9!BD!2H5~vHM&)k>2qF!K{`J<6uvH3Ki|PE=<1JflN+C4JQxXzOUi_Oi`l=S TNn+stJAm3lO{G!=i;({Upoje) 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"