diff --git a/code/ZAS/Fire.dm b/code/ZAS/Fire.dm index 501c49ae55..dba966e9fb 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/Gas.dm b/code/ZAS/Gas.dm index 0f3faa09b4..20dd67bf34 100644 --- a/code/ZAS/Gas.dm +++ b/code/ZAS/Gas.dm @@ -21,6 +21,9 @@ /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/ZAS/Variable Settings.dm b/code/ZAS/Variable Settings.dm index c152159b7a..7700fee2bb 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/game/objects/effects/spawners/bombspawner.dm b/code/game/objects/effects/spawners/bombspawner.dm index 547931a511..fb4716043f 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 36c3b3d11f..e44f759547 100644 --- a/code/game/objects/items/devices/transfer_valve.dm +++ b/code/game/objects/items/devices/transfer_valve.dm @@ -99,17 +99,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) @@ -148,20 +140,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 @@ -169,8 +184,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) @@ -196,16 +210,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 68e4ad84dd..dec27ed60a 100644 --- a/code/game/objects/items/weapons/tanks/tanks.dm +++ b/code/game/objects/items/weapons/tanks/tanks.dm @@ -36,6 +36,10 @@ qdel(air_contents) processing_objects.Remove(src) + + if(istype(loc, /obj/item/device/transfer_valve)) + var/obj/item/device/transfer_valve/TTV = loc + TTV.remove_tank(src) ..() @@ -272,7 +276,10 @@ qdel(src) else if(pressure > TANK_RUPTURE_PRESSURE) - //world << "\blue[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) @@ -284,7 +291,10 @@ integrity-- else if(pressure > TANK_LEAK_PRESSURE) - //world << "\blue[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 bd3c4be0d9..29d2b95d88 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/code/setup.dm b/code/setup.dm index be0989b191..8371ca3cdd 100644 --- a/code/setup.dm +++ b/code/setup.dm @@ -142,15 +142,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 #define T0C 273.15 // 0.0 degrees celcius #define T20C 293.15 // 20.0 degrees celcius diff --git a/html/changelogs/HarpyEagle-ttv.yml b/html/changelogs/HarpyEagle-ttv.yml new file mode 100644 index 0000000000..67d426e234 --- /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."