diff --git a/code/WorkInProgress/explosion_particles.dm b/code/WorkInProgress/explosion_particles.dm index 9cf81b27ae..11e2cc4f01 100644 --- a/code/WorkInProgress/explosion_particles.dm +++ b/code/WorkInProgress/explosion_particles.dm @@ -1,5 +1,5 @@ /obj/effect/expl_particles - name = "fire" + name = "explosive particles" icon = 'icons/effects/effects.dmi' icon_state = "explosion_particle" opacity = 1 @@ -9,7 +9,7 @@ /obj/effect/expl_particles/New() ..() spawn (15) - del(src) + src.loc = null return /obj/effect/expl_particles/Move() @@ -37,7 +37,7 @@ step(expl,direct) /obj/effect/explosion - name = "fire" + name = "explosive particles" icon = 'icons/effects/96x96.dmi' icon_state = "explosion" opacity = 1 @@ -49,7 +49,7 @@ /obj/effect/explosion/New() ..() spawn (10) - del(src) + src.loc = null return /datum/effect/system/explosion diff --git a/code/ZAS/FEA_gas_mixture.dm b/code/ZAS/FEA_gas_mixture.dm index 89259c281b..a4bdb02206 100644 --- a/code/ZAS/FEA_gas_mixture.dm +++ b/code/ZAS/FEA_gas_mixture.dm @@ -57,6 +57,8 @@ What are the archived variables for? var/tmp/graphic_archived = 0 var/tmp/fuel_burnt = 0 + var/reacting = 0 + //FOR THE LOVE OF GOD PLEASE USE THIS PROC //Call it with negative numbers to remove gases. @@ -207,14 +209,13 @@ What are the archived variables for? //Inputs: None //Outputs: If a fire occured - var/reacting = 0 //set to 1 if a notable reaction occured (used by pipe_network) + //set to 1 if a notable reaction occured (used by pipe_network) - if(temperature > FIRE_MINIMUM_TEMPERATURE_TO_EXIST) - if(zburn(null) > 0) - reacting = 1 + zburn(null) return reacting +/* /datum/gas_mixture/proc/fire() //Purpose: Calculating any fire reactions. //Called by: react() (See above) @@ -223,7 +224,7 @@ What are the archived variables for? return zburn(null) - /*var/energy_released = 0 + var/energy_released = 0 var/old_heat_capacity = heat_capacity() var/datum/gas/volatile_fuel/fuel_store = locate(/datum/gas/volatile_fuel) in trace_gases diff --git a/code/ZAS/Fire.dm b/code/ZAS/Fire.dm index d057bad4c3..0adc394715 100644 --- a/code/ZAS/Fire.dm +++ b/code/ZAS/Fire.dm @@ -11,6 +11,8 @@ Attach to transfer valve and open. BOOM. */ + + //Some legacy definitions so fires can be started. atom/proc/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) return null @@ -19,145 +21,164 @@ atom/proc/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed turf/proc/hotspot_expose(exposed_temperature, exposed_volume, soh = 0) + turf/simulated/hotspot_expose(exposed_temperature, exposed_volume, soh) - if(fire_protection > world.time-300) + if(fire_protection > world.time-300) return + var/datum/gas_mixture/air_contents = return_air(1) + if(!air_contents) return 0 + + /*if(active_hotspot) + if(soh) + if(air_contents.toxins > 0.5 && air_contents.oxygen > 0.5) + if(active_hotspot.temperature < exposed_temperature) + active_hotspot.temperature = exposed_temperature + if(active_hotspot.volume < exposed_volume) + active_hotspot.volume = exposed_volume + return 1*/ + var/igniting = 0 if(locate(/obj/fire) in src) return 1 - var/datum/gas_mixture/air_contents = return_air() - if(!air_contents || exposed_temperature < PLASMA_MINIMUM_BURN_TEMPERATURE) - return 0 - - var/igniting = 0 + var/datum/gas/volatile_fuel/fuel = locate() in air_contents.trace_gases var/obj/effect/decal/cleanable/liquid_fuel/liquid = locate() in src - - if(air_contents.check_combustability(liquid)) + if(air_contents.calculate_firelevel(liquid) > vsc.IgnitionLevel && (fuel || liquid || air_contents.toxins > 0.5)) igniting = 1 + if(air_contents.oxygen < 0.5) + return 0 if(! (locate(/obj/fire) in src)) - - new /obj/fire(src,1000) + var/obj/fire/F = new(src,1000) + F.temperature = exposed_temperature + F.volume = CELL_VOLUME //active_hotspot.just_spawned = (current_cycle < air_master.current_cycle) //remove just_spawned protection if no longer processing this cell return igniting -/obj/fire - //Icon for fire on turfs. +obj + fire + //Icon for fire on turfs. - anchored = 1 - mouse_opacity = 0 + anchored = 1 + mouse_opacity = 0 - //luminosity = 3 + //luminosity = 3 - icon = 'icons/effects/fire.dmi' - icon_state = "1" - - layer = TURF_LAYER - - var/firelevel = 10000 //Calculated by gas_mixture.calculate_firelevel() - -/obj/fire/process() - . = 1 - - //get location and check if it is in a proper ZAS zone - var/turf/simulated/floor/S = loc - if(!S.zone) - del src - - if(!istype(S)) - del src - - var/datum/gas_mixture/air_contents = S.return_air() - //get liquid fuels on the ground. - var/obj/effect/decal/cleanable/liquid_fuel/liquid = locate() in S - //and the volatile stuff from the air - //var/datum/gas/volatile_fuel/fuel = locate() in air_contents.trace_gases - - //check if there is something to combust - if(!air_contents.check_combustability(liquid)) - del src - - //get a firelevel and set the icon - firelevel = air_contents.calculate_firelevel(liquid) - - if(firelevel > 6) - icon_state = "3" - SetLuminosity(7) - else if(firelevel > 2.5) - icon_state = "2" - SetLuminosity(5) - else + icon = 'icons/effects/fire.dmi' icon_state = "1" - SetLuminosity(3) - //im not sure how to implement a version that works for every creature so for now monkeys are firesafe - for(var/mob/living/carbon/human/M in loc) - M.FireBurn(firelevel, air_contents.temperature, air_contents.return_pressure() ) //Burn the humans! + var + volume = CELL_VOLUME + temperature = PLASMA_MINIMUM_BURN_TEMPERATURE + firelevel = 10000 //Calculated by gas_mixture.calculate_firelevel() + archived_firelevel = 0 + + process() + . = 1 + + if(firelevel > vsc.IgnitionLevel) + + var/turf/simulated/floor/S = loc + if(!S.zone) src.gc_del() //Cannot exist where zones are broken. + + if(istype(S)) + var + datum/gas_mixture/air_contents = S.return_air() + //Get whatever trace fuels are in the area + datum/gas/volatile_fuel/fuel = locate() in air_contents.trace_gases + //Also get liquid fuels on the ground. + obj/effect/decal/cleanable/liquid_fuel/liquid = locate() in S + + var/datum/gas_mixture/flow = air_contents.remove_ratio(0.25) + //The reason we're taking a part of the air instead of all of it is so that it doesn't jump to + //the fire's max temperature instantaneously. + + firelevel = air_contents.calculate_firelevel(liquid) + + //Ensure that there is an appropriate amount of fuel and O2 here. + if(firelevel > 0.25 && flow.oxygen > 0.3 && (air_contents.toxins || fuel || liquid)) + + for(var/direction in cardinal) + if(S.air_check_directions&direction) //Grab all valid bordering tiles + + var/turf/simulated/enemy_tile = get_step(S, direction) + + if(istype(enemy_tile)) + //If extinguisher mist passed over the turf it's trying to spread to, don't spread and + //reduce firelevel. + if(enemy_tile.fire_protection > world.time-30) + firelevel -= 1.5 + continue + + //Spread the fire. + if(!(locate(/obj/fire) in enemy_tile)) + if( prob( firelevel*10 ) && S.CanPass(null, enemy_tile, 0,0) && enemy_tile.CanPass(null, S, 0,0)) + new/obj/fire(enemy_tile,firelevel) + + if(flow) + + //Ensure adequate oxygen and fuel. + if(flow.oxygen > 0.3 && (flow.toxins || fuel || liquid)) + + //Change icon depending on the fuel, and thus temperature. + if(firelevel > 6) + icon_state = "3" + else if(firelevel > 2.5) + icon_state = "2" + else + icon_state = "1" + + //Ensure flow temperature is higher than minimum fire temperatures. + flow.temperature = max(PLASMA_MINIMUM_BURN_TEMPERATURE+0.1,flow.temperature) + + //Burn the gas mixture. + flow.zburn(liquid) + if(fuel && fuel.moles <= 0.00001) + del fuel + + else + + src.gc_del() - //spread! - for(var/direction in cardinal) - if(S.air_check_directions&direction) //Grab all valid bordering tiles + S.assume_air(flow) //Then put it back where you found it. - var/turf/simulated/enemy_tile = get_step(S, direction) - - if(istype(enemy_tile)) - //If extinguisher mist passed over the turf it's trying to spread to, don't spread and - //reduce firelevel. - if(enemy_tile.fire_protection > world.time-30) - firelevel -= 1.5 - continue - - //Spread the fire. - if(!(locate(/obj/fire) in enemy_tile)) - if( prob( 50 + 50 * (firelevel/vsc.fire_firelevel_multiplier) ) && S.CanPass(null, enemy_tile, 0,0) && enemy_tile.CanPass(null, S, 0,0)) - new/obj/fire(enemy_tile,firelevel) - - //seperate part of the present gas - //this is done to prevent the fire burning all gases in a single pass - var/datum/gas_mixture/flow = air_contents.remove_ratio(vsc.fire_consuption_rate) - -///////////////////////////////// FLOW HAS BEEN CREATED /// DONT DELETE THE FIRE UNTIL IT IS MERGED BACK OR YOU WILL DELETE AIR /////////////////////////////////////////////// - - if(flow) - if(flow.check_combustability(liquid)) - //Ensure flow temperature is higher than minimum fire temperatures. - //this creates some energy ex nihilo but is necessary to get a fire started - //lets just pretend this energy comes from the ignition source and dont mention this again - //flow.temperature = max(PLASMA_MINIMUM_BURN_TEMPERATURE+0.1,flow.temperature) - - //burn baby burn! - flow.zburn(liquid,1) - - //merge the air back - S.assume_air(flow) - -///////////////////////////////// FLOW HAS BEEN REMERGED /// feel free to delete the fire again from here on ////////////////////////////////////////////////////////////////// + else + src.gc_del() + else + src.gc_del() + else + src.gc_del() -/obj/fire/New(newLoc,fl) - ..() - - if(!istype(loc, /turf)) - del src - - dir = pick(cardinal) - SetLuminosity(3) - firelevel = fl - air_master.active_hotspots.Add(src) + for(var/mob/living/carbon/human/M in loc) + M.FireBurn(temperature, min(max(0.1,firelevel / 20),10)) //Burn the humans! -/obj/fire/Del() - if (istype(loc, /turf/simulated)) - SetLuminosity(0) + New(newLoc,fl) + ..() - loc = null - air_master.active_hotspots.Remove(src) + if(!istype(loc, /turf)) + src.gc_del() - ..() + dir = pick(cardinal) + //sd_SetLuminosity(3,2,0) + firelevel = fl + air_master.active_hotspots.Add(src) + proc/gc_del() + loc = null + air_master.active_hotspots.Remove(src) + + Del() + if (istype(loc, /turf/simulated)) + //sd_SetLuminosity(0) + + loc = null + air_master.active_hotspots.Remove(src) + + ..() turf/simulated/var/fire_protection = 0 //Protects newly extinguished tiles from being overrun again. @@ -165,19 +186,22 @@ turf/proc/apply_fire_protection() turf/simulated/apply_fire_protection() fire_protection = world.time +datum/gas_mixture/proc/zburn(obj/effect/decal/cleanable/liquid_fuel/liquid) + //This proc is similar to fire(), but uses a simple logarithm to calculate temp, and is thus more stable with ZAS. -datum/gas_mixture/proc/zburn(obj/effect/decal/cleanable/liquid_fuel/liquid,force_burn) - var/value = 0 + if(temperature > PLASMA_FLASHPOINT && !reacting) + reacting = 1 - if((temperature > PLASMA_MINIMUM_BURN_TEMPERATURE || force_burn) && check_combustability(liquid) ) - var/total_fuel = 0 - var/datum/gas/volatile_fuel/fuel = locate() in trace_gases - - total_fuel += toxins + if(temperature > PLASMA_MINIMUM_BURN_TEMPERATURE && reacting) + var + total_fuel = toxins + fuel_sources = 0 //We'll divide by this later so that fuel is consumed evenly. + datum/gas/volatile_fuel/fuel = locate() in trace_gases if(fuel) //Volatile Fuel total_fuel += fuel.moles + fuel_sources++ if(liquid) //Liquid Fuel @@ -185,94 +209,65 @@ datum/gas_mixture/proc/zburn(obj/effect/decal/cleanable/liquid_fuel/liquid,force del liquid else total_fuel += liquid.amount + fuel_sources++ - //Calculate the firelevel. - var/firelevel = calculate_firelevel(liquid) + //Toxins + if(toxins > 0.3) fuel_sources++ - //get the current inner energy of the gas mix - //this must be taken here to prevent the addition or deletion of energy by a changing heat capacity - var/starting_energy = temperature * heat_capacity() + if(!fuel_sources) return 0 //If there's no fuel, there's no burn. Can't divide by zero anyway. - //determine the amount of oxygen used - var/total_oxygen = min(oxygen, 2 * total_fuel) + if(oxygen > 0.3) - //determine the amount of fuel actually used - var/used_fuel_ratio = min(oxygen / 2 , total_fuel) / total_fuel - total_fuel = total_fuel * used_fuel_ratio + //Calculate the firelevel. + var/firelevel = calculate_firelevel(liquid) - var/total_reactants = total_fuel + total_oxygen + //Reaches a maximum practical temperature of around 4500. - //determine the amount of reactants actually reacting - var/used_reactants_ratio = min( max(total_reactants * firelevel / vsc.fire_firelevel_multiplier, 0.2), total_reactants) / total_reactants + //Increase temperature. + temperature = max( 1700*log(0.4*firelevel + 1.23) , temperature ) - //remove and add gasses as calculated - oxygen -= min(oxygen, total_oxygen * used_reactants_ratio ) + //Consume some gas. + var/consumed_gas = min(oxygen,0.05*firelevel,total_fuel) / fuel_sources - toxins -= min(toxins, toxins * used_fuel_ratio * used_reactants_ratio ) + oxygen = max(0,oxygen-consumed_gas) - carbon_dioxide += max(2 * total_fuel, 0) + toxins = max(0,toxins-consumed_gas) - if(fuel) - fuel.moles -= fuel.moles * used_fuel_ratio * used_reactants_ratio - if(fuel.moles <= 0) del fuel + carbon_dioxide += consumed_gas*2 - if(liquid) - liquid.amount -= liquid.amount * used_fuel_ratio * used_reactants_ratio - if(liquid.amount <= 0) del liquid + if(fuel) + fuel.moles -= consumed_gas + if(fuel.moles <= 0) del fuel - //calculate the energy produced by the reaction and then set the new temperature of the mix - temperature = (starting_energy + vsc.fire_fuel_energy_release * total_fuel) / heat_capacity() + if(liquid) + liquid.amount -= consumed_gas + if(liquid.amount <= 0) del liquid - update_values() - value = total_reactants * used_reactants_ratio - return value + update_values() + return consumed_gas*fuel_sources -datum/gas_mixture/proc/check_combustability(obj/effect/decal/cleanable/liquid_fuel/liquid) - //this check comes up very often and is thus centralized here to ease adding stuff + else + reacting = 0 - var/datum/gas/volatile_fuel/fuel = locate() in trace_gases - var/value = 0 + return 0 - if(oxygen > 0.01 && (toxins > 0.01 || (fuel && fuel.moles > 0.01) || liquid)) - value = 1 - - return value datum/gas_mixture/proc/calculate_firelevel(obj/effect/decal/cleanable/liquid_fuel/liquid) - //Calculates the firelevel based on one equation instead of having to do this multiple times in different areas. + //Calculates the firelevel based on one equation instead of having to do this multiple times in different areas. + var + datum/gas/volatile_fuel/fuel = locate() in trace_gases + liquid_concentration = 0 - var/datum/gas/volatile_fuel/fuel = locate() in trace_gases - var/total_fuel = 0 - var/firelevel = 0 + oxy_concentration = oxygen / volume + tox_concentration = toxins / volume + fuel_concentration = 0 - if(check_combustability(liquid)) + if(fuel) fuel_concentration = (fuel.moles) / volume + if(liquid) liquid_concentration = (liquid.amount*15) / volume + return (oxy_concentration + tox_concentration + liquid_concentration + fuel_concentration)*100 - total_fuel += toxins - - if(liquid) - total_fuel += liquid.amount - - if(fuel) - total_fuel += fuel.moles - - var/total_combustables = (total_fuel + oxygen) - - if(total_fuel > 0 && oxygen > 0) - - //slows down the burning when the concentration of the reactants is low - var/dampening_multiplier = total_combustables / (total_combustables + nitrogen + carbon_dioxide) - //calculates how close the mixture of the reactants is to the optimum - var/mix_multiplier = 1 / (1 + (5 * ((oxygen / total_combustables) ** 2))) - //toss everything together - firelevel = vsc.fire_firelevel_multiplier * mix_multiplier * dampening_multiplier - - return max( 0, firelevel) - - -/mob/living/carbon/human/proc/FireBurn(var/firelevel, var/last_temperature, var/pressure) -// mostly using the old proc from Sky until I can think of something better +/mob/living/carbon/human/proc/FireBurn(last_temperature, mx as num) //Burns mobs due to fire. Respects heat transfer coefficients on various body parts. - //Due to TG reworking how fireprotection works, this is kinda less meaningful. var head_exposure = 1 @@ -281,12 +276,8 @@ datum/gas_mixture/proc/calculate_firelevel(obj/effect/decal/cleanable/liquid_fue legs_exposure = 1 arms_exposure = 1 - //determine the multiplier - //minimize this for low-pressure enviroments - var/mx = 5 * firelevel/vsc.fire_firelevel_multiplier * min(pressure / ONE_ATMOSPHERE, 1) - //Get heat transfer coefficients for clothing. - //skytodo: kill anyone who breaks things then orders me to fix them + for(var/obj/item/clothing/C in src) if(l_hand == C || r_hand == C) continue @@ -313,4 +304,4 @@ datum/gas_mixture/proc/calculate_firelevel(obj/effect/decal/cleanable/liquid_fue apply_damage(0.4*mx*arms_exposure, BURN, "l_arm", 0, 0, "Fire") apply_damage(0.4*mx*arms_exposure, BURN, "r_arm", 0, 0, "Fire") - //flash_pain() + //flash_pain() \ No newline at end of file diff --git a/code/ZAS/Variable Settings.dm b/code/ZAS/Variable Settings.dm index 743eadd317..e73d989aff 100644 --- a/code/ZAS/Variable Settings.dm +++ b/code/ZAS/Variable Settings.dm @@ -1,7 +1,7 @@ var/global/vs_control/vsc = new /vs_control - var/fire_consuption_rate = 0.25 +/* var/fire_consuption_rate = 0.25 var/fire_consuption_rate_NAME = "Fire - Air Consumption Ratio" var/fire_consuption_rate_DESC = "Ratio of air removed and combusted per tick." @@ -12,7 +12,10 @@ var/global/vs_control/vsc = new var/fire_fuel_energy_release = 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" +*/ + var/IgnitionLevel = 0.5 + var/IgnitionLevel_DESC = "Determines point at which fire can ignite" var/airflow_lightest_pressure = 20 var/airflow_lightest_pressure_NAME = "Airflow - Small Movement Threshold %" diff --git a/code/setup.dm b/code/setup.dm index da3ff22273..06c4711b45 100644 --- a/code/setup.dm +++ b/code/setup.dm @@ -107,6 +107,7 @@ //Must be between 0 and 1. Values closer to 1 equalize temperature faster //Should not exceed 0.4 else strange heat flow occur +/* #define FIRE_MINIMUM_TEMPERATURE_TO_SPREAD 150+T0C #define FIRE_MINIMUM_TEMPERATURE_TO_EXIST 100+T0C #define FIRE_SPREAD_RADIOSITY_SCALE 0.85 @@ -114,7 +115,7 @@ #define FIRE_PLASMA_ENERGY_RELEASED 3000000 //Amount of heat released per mole of burnt plasma into the tile #define FIRE_GROWTH_RATE 40000 //For small fires -//#define WATER_BOIL_TEMP 393 +#define WATER_BOIL_TEMP 393 */ // Fire Damage #define CARBON_LIFEFORM_FIRE_RESISTANCE 200+T0C @@ -132,7 +133,8 @@ #define T20C 293.15 // 20degC #define TCMB 2.7 // -270.3degC -var/turf/space/Space_Tile = locate(/turf/space) // A space tile to reference when atmos wants to remove excess heat. +//Used to be used by FEA +//var/turf/space/Space_Tile = locate(/turf/space) // A space tile to reference when atmos wants to remove excess heat. #define TANK_LEAK_PRESSURE (30.*ONE_ATMOSPHERE) // Tank starts leaking #define TANK_RUPTURE_PRESSURE (40.*ONE_ATMOSPHERE) // Tank spills all contents into atmosphere