diff --git a/code/ZAS/Fire.dm b/code/ZAS/Fire.dm
index 501c49ae556..dba966e9fb9 100644
--- a/code/ZAS/Fire.dm
+++ b/code/ZAS/Fire.dm
@@ -1,13 +1,9 @@
/*
Making Bombs with ZAS:
-Make burny fire with lots of burning
-Draw off 5000K gas from burny fire
-Separate gas into oxygen and phoron components
-Obtain phoron and oxygen tanks filled up about 50-75% with normal-temp gas
-Fill rest with super hot gas from separated canisters, they should be about 125C now.
-Attach to transfer valve and open. BOOM.
-
+Get gas to react in an air tank so that it gains pressure. If it gains enough pressure, it goes boom.
+The more pressure, the more boom.
+If it gains pressure too slowly, it may leak or just rupture instead of exploding.
*/
//#define FIREDBG
@@ -268,16 +264,16 @@ turf/proc/hotspot_expose(exposed_temperature, exposed_volume, soh = 0)
//determine how far the reaction can progress
var/reaction_limit = min(total_oxidizers*(FIRE_REACTION_FUEL_AMOUNT/FIRE_REACTION_OXIDIZER_AMOUNT), total_fuel) //stoichiometric limit
- //calculate the firelevel.
- var/firelevel = calculate_firelevel(total_fuel, total_oxidizers, reaction_limit)
- var/firelevel_ratio = firelevel / vsc.fire_firelevel_multiplier
-
//vapour fuels are extremely volatile! The reaction progress is a percentage of the total fuel (similar to old zburn).)
+ var/gas_firelevel = calculate_firelevel(gas_fuel, total_oxidizers, reaction_limit, volume*group_multiplier) / vsc.fire_firelevel_multiplier
var/min_burn = 0.30*volume*group_multiplier/CELL_VOLUME //in moles - so that fires with very small gas concentrations burn out fast
- var/gas_reaction_progress = min(max(min_burn, firelevel_ratio*gas_fuel)*FIRE_GAS_BURNRATE_MULT, gas_fuel)
+ var/gas_reaction_progress = min(max(min_burn, gas_firelevel*gas_fuel)*FIRE_GAS_BURNRATE_MULT, gas_fuel)
//liquid fuels are not as volatile, and the reaction progress depends on the size of the area that is burning. Limit the burn rate to a certain amount per area.
- var/liquid_reaction_progress = min((firelevel_ratio*0.2 + 0.05)*fuel_area*FIRE_LIQUID_BURNRATE_MULT, liquid_fuel)
+ var/liquid_firelevel = calculate_firelevel(liquid_fuel, total_oxidizers, reaction_limit, 0) / vsc.fire_firelevel_multiplier
+ var/liquid_reaction_progress = min((liquid_firelevel*0.2 + 0.05)*fuel_area*FIRE_LIQUID_BURNRATE_MULT, liquid_fuel)
+
+ var/firelevel = (gas_fuel*gas_firelevel + liquid_fuel*liquid_firelevel)/total_fuel
var/total_reaction_progress = gas_reaction_progress + liquid_reaction_progress
var/used_fuel = min(total_reaction_progress, reaction_limit)
@@ -286,7 +282,7 @@ turf/proc/hotspot_expose(exposed_temperature, exposed_volume, soh = 0)
#ifdef FIREDBG
log_debug("gas_fuel = [gas_fuel], liquid_fuel = [liquid_fuel], total_oxidizers = [total_oxidizers]")
log_debug("fuel_area = [fuel_area], total_fuel = [total_fuel], reaction_limit = [reaction_limit]")
- log_debug("firelevel -> [firelevel] / [vsc.fire_firelevel_multiplier]")
+ log_debug("firelevel -> [firelevel] (gas: [gas_firelevel], liquid: [liquid_firelevel])")
log_debug("liquid_reaction_progress = [liquid_reaction_progress]")
log_debug("gas_reaction_progress = [gas_reaction_progress]")
log_debug("total_reaction_progress = [total_reaction_progress]")
@@ -315,13 +311,13 @@ turf/proc/hotspot_expose(exposed_temperature, exposed_volume, soh = 0)
//calculate the energy produced by the reaction and then set the new temperature of the mix
temperature = (starting_energy + vsc.fire_fuel_energy_release * (used_gas_fuel + used_liquid_fuel)) / heat_capacity()
+ update_values()
#ifdef FIREDBG
log_debug("used_gas_fuel = [used_gas_fuel]; used_liquid_fuel = [used_liquid_fuel]; total = [used_fuel]")
- log_debug("new temperature = [temperature]")
+ log_debug("new temperature = [temperature]; new pressure = [return_pressure()]")
#endif
-
- update_values()
+
return firelevel
datum/gas_mixture/proc/check_recombustability(list/fuel_objs)
@@ -363,27 +359,31 @@ datum/gas_mixture/proc/check_recombustability(list/fuel_objs)
break
//returns a value between 0 and vsc.fire_firelevel_multiplier
-/datum/gas_mixture/proc/calculate_firelevel(total_fuel, total_oxidizers, reaction_limit)
+/datum/gas_mixture/proc/calculate_firelevel(total_fuel, total_oxidizers, reaction_limit, gas_volume)
//Calculates the firelevel based on one equation instead of having to do this multiple times in different areas.
var/firelevel = 0
var/total_combustables = (total_fuel + total_oxidizers)
+ var/active_combustables = (FIRE_REACTION_OXIDIZER_AMOUNT/FIRE_REACTION_FUEL_AMOUNT + 1)*reaction_limit
if(total_combustables > 0)
//slows down the burning when the concentration of the reactants is low
- var/dampening_multiplier = min(1, reaction_limit / (total_moles/group_multiplier))
+ var/damping_multiplier = min(1, active_combustables / (total_moles/group_multiplier))
+
+ //weight the damping mult so that it only really brings down the firelevel when the ratio is closer to 0
+ damping_multiplier = 2*damping_multiplier - (damping_multiplier*damping_multiplier)
//calculates how close the mixture of the reactants is to the optimum
- //fires burn better when there is more oxidizer -- too much fuel will choke them out a bit, reducing firelevel.
+ //fires burn better when there is more oxidizer -- too much fuel will choke the fire out a bit, reducing firelevel.
var/mix_multiplier = 1 / (1 + (5 * ((total_fuel / total_combustables) ** 2)))
#ifdef FIREDBG
- ASSERT(dampening_multiplier <= 1)
+ ASSERT(damping_multiplier <= 1)
ASSERT(mix_multiplier <= 1)
#endif
//toss everything together -- should produce a value between 0 and fire_firelevel_multiplier
- firelevel = vsc.fire_firelevel_multiplier * mix_multiplier * dampening_multiplier
+ firelevel = vsc.fire_firelevel_multiplier * mix_multiplier * damping_multiplier
return max( 0, firelevel)
diff --git a/code/ZAS/Variable Settings.dm b/code/ZAS/Variable Settings.dm
index 674be3fc5ea..7e91a26b3f2 100644
--- a/code/ZAS/Variable Settings.dm
+++ b/code/ZAS/Variable Settings.dm
@@ -9,7 +9,8 @@ var/global/vs_control/vsc = new
var/fire_firelevel_multiplier_NAME = "Fire - Firelevel Constant"
var/fire_firelevel_multiplier_DESC = "Multiplied by the equation for firelevel, affects mainly the extingiushing of fires."
- var/fire_fuel_energy_release = 397000
+ //Note that this parameter and the phoron heat capacity have a significant impact on TTV yield.
+ var/fire_fuel_energy_release = 866000 //J/mol. Adjusted to compensate for fire energy release being fixed, was 397000
var/fire_fuel_energy_release_NAME = "Fire - Fuel energy release"
var/fire_fuel_energy_release_DESC = "The energy in joule released when burning one mol of a burnable substance"
diff --git a/code/__defines/atmos.dm b/code/__defines/atmos.dm
index e93bf450859..668178abfce 100644
--- a/code/__defines/atmos.dm
+++ b/code/__defines/atmos.dm
@@ -59,15 +59,15 @@
//These control the speed at which fire burns
#define FIRE_GAS_BURNRATE_MULT 1
-#define FIRE_LIQUID_BURNRATE_MULT 1
+#define FIRE_LIQUID_BURNRATE_MULT 0.225
//If the fire is burning slower than this rate then the reaction is going too slow to be self sustaining and the fire burns itself out.
//This ensures that fires don't grind to a near-halt while still remaining active forever.
#define FIRE_GAS_MIN_BURNRATE 0.01
-#define FIRE_LIQUD_MIN_BURNRATE 0.01
+#define FIRE_LIQUD_MIN_BURNRATE 0.0025
//How many moles of fuel are contained within one solid/liquid fuel volume unit
-#define LIQUIDFUEL_AMOUNT_TO_MOL 1 //mol/volume unit
+#define LIQUIDFUEL_AMOUNT_TO_MOL 0.45 //mol/volume unit
// XGM gas flags.
#define XGM_GAS_FUEL 1
diff --git a/code/defines/gases.dm b/code/defines/gases.dm
index 1f8c871ad3f..659bd2e21ae 100644
--- a/code/defines/gases.dm
+++ b/code/defines/gases.dm
@@ -21,6 +21,9 @@
/decl/xgm_gas/phoron
id = "phoron"
name = "Phoron"
+
+ //Note that this has a significant impact on TTV yield.
+ //Because it is so high, any leftover phoron soaks up a lot of heat and drops the yield pressure.
specific_heat = 200 // J/(mol*K)
//Hypothetical group 14 (same as carbon), period 8 element.
diff --git a/code/game/objects/effects/spawners/bombspawner.dm b/code/game/objects/effects/spawners/bombspawner.dm
index 547931a5118..fb4716043f1 100644
--- a/code/game/objects/effects/spawners/bombspawner.dm
+++ b/code/game/objects/effects/spawners/bombspawner.dm
@@ -105,27 +105,61 @@
qdel(src)
*/
+/client/proc/spawn_tanktransferbomb()
+ set category = "Debug"
+ set desc = "Spawn a tank transfer valve bomb"
+ set name = "Instant TTV"
+
+ if(!check_rights(R_SPAWN)) return
+
+ var/obj/effect/spawner/newbomb/proto = /obj/effect/spawner/newbomb/radio/custom
+
+ var/p = input("Enter phoron amount (mol):","Phoron", initial(proto.phoron_amt)) as num|null
+ if(p == null) return
+
+ var/o = input("Enter oxygen amount (mol):","Oxygen", initial(proto.oxygen_amt)) as num|null
+ if(o == null) return
+
+ var/c = input("Enter carbon dioxide amount (mol):","Carbon Dioxide", initial(proto.carbon_amt)) as num|null
+ if(c == null) return
+
+ new /obj/effect/spawner/newbomb/radio/custom(get_turf(mob), p, o, c)
+
/obj/effect/spawner/newbomb
- name = "bomb"
+ name = "TTV bomb"
icon = 'icons/mob/screen1.dmi'
icon_state = "x"
- var/btype = 0 // 0=radio, 1=prox, 2=time
+
+ var/assembly_type = /obj/item/device/assembly/signaler
+
+ //Note that the maximum amount of gas you can put in a 70L air tank at 1013.25 kPa and 519K is 16.44 mol.
+ var/phoron_amt = 10.96
+ var/oxygen_amt = 16.44
+ var/carbon_amt = 0.0
- timer
- btype = 2
+/obj/effect/spawner/newbomb/timer
+ name = "TTV bomb - timer"
+ assembly_type = /obj/item/device/assembly/timer
- syndicate
+/obj/effect/spawner/newbomb/timer/syndicate
+ name = "TTV bomb - merc"
+ //High yield bombs. Yes, it is possible to make these with toxins
+ phoron_amt = 15.66
+ oxygen_amt = 24.66
- proximity
- btype = 1
+/obj/effect/spawner/newbomb/proximity
+ name = "TTV bomb - proximity"
+ assembly_type = /obj/item/device/assembly/prox_sensor
- radio
- btype = 0
-
-
-/obj/effect/spawner/newbomb/New()
+/obj/effect/spawner/newbomb/radio/custom/New(var/newloc, ph, ox, co)
+ if(ph != null) phoron_amt = ph
+ if(ox != null) oxygen_amt = ox
+ if(co != null) carbon_amt = co
..()
+/obj/effect/spawner/newbomb/New(newloc)
+ ..(newloc)
+
var/obj/item/device/transfer_valve/V = new(src.loc)
var/obj/item/weapon/tank/phoron/PT = new(V)
var/obj/item/weapon/tank/oxygen/OT = new(V)
@@ -137,28 +171,15 @@
OT.master = V
PT.air_contents.temperature = PHORON_FLASHPOINT
- PT.air_contents.adjust_multi("phoron", 12, "carbon_dioxide", 8)
+ PT.air_contents.gas["phoron"] = phoron_amt
+ PT.air_contents.gas["carbon_dioxide"] = carbon_amt
+ PT.air_contents.update_values()
OT.air_contents.temperature = PHORON_FLASHPOINT
- OT.air_contents.adjust_gas("oxygen", 20)
+ OT.air_contents.gas["oxygen"] = oxygen_amt
+ OT.air_contents.update_values()
- var/obj/item/device/assembly/S
-
- switch (src.btype)
- // radio
- if (0)
-
- S = new/obj/item/device/assembly/signaler(V)
-
- // proximity
- if (1)
-
- S = new/obj/item/device/assembly/prox_sensor(V)
-
- // timer
- if (2)
-
- S = new/obj/item/device/assembly/timer(V)
+ var/obj/item/device/assembly/S = new assembly_type(V)
V.attached_device = S
diff --git a/code/game/objects/items/devices/transfer_valve.dm b/code/game/objects/items/devices/transfer_valve.dm
index 4135dda5f7c..88b53bd342d 100644
--- a/code/game/objects/items/devices/transfer_valve.dm
+++ b/code/game/objects/items/devices/transfer_valve.dm
@@ -100,17 +100,9 @@
if (src.loc != usr)
return 0
if(tank_one && href_list["tankone"])
- split_gases()
- valve_open = 0
- tank_one.loc = get_turf(src)
- tank_one = null
- update_icon()
+ remove_tank(tank_one)
else if(tank_two && href_list["tanktwo"])
- split_gases()
- valve_open = 0
- tank_two.loc = get_turf(src)
- tank_two = null
- update_icon()
+ remove_tank(tank_two)
else if(href_list["open"])
toggle_valve()
else if(attached_device)
@@ -149,20 +141,43 @@
if(attached_device)
overlays += "device"
+/obj/item/device/transfer_valve/proc/remove_tank(obj/item/weapon/tank/T)
+ if(tank_one == T)
+ split_gases()
+ tank_one = null
+ else if(tank_two == T)
+ split_gases()
+ tank_two = null
+ else
+ return
+
+ T.loc = get_turf(src)
+ update_icon()
+
/obj/item/device/transfer_valve/proc/merge_gases()
+ if(valve_open)
+ return
tank_two.air_contents.volume += tank_one.air_contents.volume
var/datum/gas_mixture/temp
temp = tank_one.air_contents.remove_ratio(1)
tank_two.air_contents.merge(temp)
+ valve_open = 1
/obj/item/device/transfer_valve/proc/split_gases()
- if (!valve_open || !tank_one || !tank_two)
+ if(!valve_open)
return
+
+ valve_open = 0
+
+ if(deleted(tank_one) || deleted(tank_two))
+ return
+
var/ratio1 = tank_one.air_contents.volume/tank_two.air_contents.volume
var/datum/gas_mixture/temp
temp = tank_two.air_contents.remove_ratio(ratio1)
tank_one.air_contents.merge(temp)
tank_two.air_contents.volume -= tank_one.air_contents.volume
+
/*
Exadv1: I know this isn't how it's going to work, but this was just to check
@@ -170,8 +185,7 @@
*/
/obj/item/device/transfer_valve/proc/toggle_valve()
- if(valve_open==0 && (tank_one && tank_two))
- valve_open = 1
+ if(!valve_open && (tank_one && tank_two))
var/turf/bombturf = get_turf(src)
var/area/A = get_area(bombturf)
@@ -197,16 +211,11 @@
message_admins(log_str, 0, 1)
log_game(log_str)
merge_gases()
- spawn(20) // In case one tank bursts
- for (var/i=0,i<5,i++)
- src.update_icon()
- sleep(10)
- src.update_icon()
else if(valve_open==1 && (tank_one && tank_two))
split_gases()
- valve_open = 0
- src.update_icon()
+
+ src.update_icon()
// this doesn't do anything but the timer etc. expects it to be here
// eventually maybe have it update icon to show state (timer, prox etc.) like old bombs
diff --git a/code/game/objects/items/weapons/tanks/tanks.dm b/code/game/objects/items/weapons/tanks/tanks.dm
index a0340c1cd2c..b131e03ee45 100644
--- a/code/game/objects/items/weapons/tanks/tanks.dm
+++ b/code/game/objects/items/weapons/tanks/tanks.dm
@@ -41,6 +41,10 @@
processing_objects.Remove(src)
+ if(istype(loc, /obj/item/device/transfer_valve))
+ var/obj/item/device/transfer_valve/TTV = loc
+ TTV.remove_tank(src)
+
..()
/obj/item/weapon/tank/examine(mob/user)
@@ -249,7 +253,10 @@
qdel(src)
else if(pressure > TANK_RUPTURE_PRESSURE)
- //world << "[x],[y] tank is rupturing: [pressure] kPa, integrity [integrity]"
+ #ifdef FIREDBG
+ log_debug("\blue[x],[y] tank is rupturing: [pressure] kPa, integrity [integrity]")
+ #endif
+
if(integrity <= 0)
var/turf/simulated/T = get_turf(src)
if(!T)
@@ -261,7 +268,10 @@
integrity--
else if(pressure > TANK_LEAK_PRESSURE)
- //world << "[x],[y] tank is leaking: [pressure] kPa, integrity [integrity]"
+ #ifdef FIREDBG
+ log_debug("\blue[x],[y] tank is leaking: [pressure] kPa, integrity [integrity]")
+ #endif
+
if(integrity <= 0)
var/turf/simulated/T = get_turf(src)
if(!T)
diff --git a/code/modules/admin/verbs/mapping.dm b/code/modules/admin/verbs/mapping.dm
index bd3c4be0d92..29d2b95d88e 100644
--- a/code/modules/admin/verbs/mapping.dm
+++ b/code/modules/admin/verbs/mapping.dm
@@ -162,6 +162,7 @@ var/list/debug_verbs = list (
,/client/proc/testZAScolors_remove
,/client/proc/setup_supermatter_engine
,/client/proc/atmos_toggle_debug
+ ,/client/proc/spawn_tanktransferbomb
)
diff --git a/html/changelogs/HarpyEagle-ttv.yml b/html/changelogs/HarpyEagle-ttv.yml
new file mode 100644
index 00000000000..67d426e234e
--- /dev/null
+++ b/html/changelogs/HarpyEagle-ttv.yml
@@ -0,0 +1,21 @@
+################################
+# Valid Prefixes:
+# bugfix
+# wip (For works in progress)
+# tweak
+# soundadd
+# sounddel
+# rscadd (general adding of nice things)
+# rscdel (general deleting of nice things)
+# imageadd
+# imagedel
+# maptweak
+# spellcheck (typo fixes)
+# experiment
+#################################
+
+author: HarpyEagle
+delete-after: True
+changes:
+ - bugfix: "Fixed a couple of bugs causing phoron gas fires to burn cooler and slower than they were supposed to."
+ - bugfix: "Merc bombs are now appropriately explosive again. Same goes for bombs made by toxins."