From 9b0c40756bd070896e5be2b5c0dfac0835aea2bd Mon Sep 17 00:00:00 2001 From: SkyMarshal Date: Thu, 4 Apr 2013 01:29:23 -0700 Subject: [PATCH] Fixed fire. --- code/ZAS/Fire.dm | 189 +++++++++++++++++++++++++++--------------- code/ZAS/ZAS_Zones.dm | 6 +- 2 files changed, 123 insertions(+), 72 deletions(-) diff --git a/code/ZAS/Fire.dm b/code/ZAS/Fire.dm index bdd9859ccd8..c94c18837d9 100644 --- a/code/ZAS/Fire.dm +++ b/code/ZAS/Fire.dm @@ -40,10 +40,10 @@ turf/simulated/hotspot_expose(exposed_temperature, exposed_volume, soh) if(locate(/obj/fire) in src) return 1 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.calculate_firelevel(liquid) > vsc.IgnitionLevel && (fuel || liquid || air_contents.toxins > 0.1)) + var/obj/liquid_fuel/liquid = locate() in src + if(air_contents.calculate_firelevel(liquid) > vsc.IgnitionLevel && (fuel || liquid || air_contents.toxins > 0.5)) igniting = 1 - if(air_contents.oxygen < 0.1) + if(air_contents.oxygen < 0.5) return 0 if(! (locate(/obj/fire) in src)) @@ -63,7 +63,7 @@ obj anchored = 1 mouse_opacity = 0 - luminosity = 3 + //luminosity = 3 icon = 'fire.dmi' icon_state = "1" @@ -79,70 +79,73 @@ obj process() . = 1 - var/turf/simulated/floor/S = loc - if(!S.zone) del src //Cannot exist where zones are broken. + if(firelevel > vsc.IgnitionLevel) - if(istype(S,/turf/simulated/floor)) - var - datum/gas_mixture/air_contents = S.return_air() - //Get whatever trace fuels are in the area - datum/gas/volatile_fuel/fuel = locate(/datum/gas/volatile_fuel/) in air_contents.trace_gases - //Also get liquid fuels on the ground. - obj/effect/decal/cleanable/liquid_fuel/liquid = locate() in S + var/turf/simulated/floor/S = loc + if(!S.zone) del src //Cannot exist where zones are broken. - 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. + if(istype(S,/turf/simulated/floor)) + var + datum/gas_mixture/air_contents = S.return_air() + //Get whatever trace fuels are in the area + datum/gas/volatile_fuel/fuel = locate(/datum/gas/volatile_fuel/) in air_contents.trace_gases + //Also get liquid fuels on the ground. + obj/liquid_fuel/liquid = locate() in S - firelevel = air_contents.calculate_firelevel(liquid) + 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. - //Ensure that there is an appropriate amount of fuel and O2 here. - if(firelevel > 0.25 && flow.oxygen > 0.1 && (air_contents.toxins || fuel || liquid)) + firelevel = air_contents.calculate_firelevel(liquid) - for(var/direction in cardinal) - if(S.air_check_directions&direction) //Grab all valid bordering tiles + //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)) - var/turf/simulated/enemy_tile = get_step(S, direction) + for(var/direction in cardinal) + if(S.air_check_directions&direction) //Grab all valid bordering tiles - 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 + var/turf/simulated/enemy_tile = get_step(S, direction) - //Spread the fire. - if(!(locate(/obj/fire) in enemy_tile)) - if( prob( firelevel*10 ) ) - new/obj/fire(enemy_tile,firelevel) + 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 - if(flow) + //Spread the fire. + if(!(locate(/obj/fire) in enemy_tile)) + if( prob( firelevel*10 ) ) + new/obj/fire(enemy_tile,firelevel) - //Ensure adequate oxygen and fuel. - if(flow.oxygen > 0.1 && (flow.toxins || fuel || liquid)) + 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) - //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.2,flow.temperature) - - //Burn the gas mixture. - if(!flow.zburn(liquid)) del src + + S.assume_air(flow) //Then put it back where you found it. + else - del src - - - S.assume_air(flow) //Then put it back where you found it. - else del src else @@ -174,12 +177,67 @@ obj ..() +obj/liquid_fuel + //Liquid fuel is used for things that used to rely on volatile fuels or plasma being contained to a couple tiles. + icon = 'icons/effects/effects.dmi' + icon_state = "fuel" + layer = TURF_LAYER+0.2 + anchored = 1 + var/amount = 1 //Basically moles. + + New(newLoc,amt=1) + src.amount = amt + + //Be absorbed by any other liquid fuel in the tile. + for(var/obj/liquid_fuel/other in newLoc) + if(other != src) + other.amount += src.amount + spawn other.Spread() + del src + + Spread() + . = ..() + + proc/Spread() + //Allows liquid fuels to sometimes flow into other tiles. + if(amount < 0.5) return + var/turf/simulated/S = loc + if(!istype(S)) return + for(var/d in cardinal) + if(S.air_check_directions & d) + if(rand(25)) + var/turf/simulated/O = get_step(src,d) + if(!locate(/obj/liquid_fuel) in O) + new/obj/liquid_fuel(O,amount*0.25) + amount *= 0.75 + + flamethrower_fuel + icon_state = "mustard" + anchored = 0 + New(newLoc, amt = 1, d = 0) + dir = d //Setting this direction means you won't get torched by your own flamethrower. + . = ..() + Spread() + //The spread for flamethrower fuel is much more precise, to create a wide fire pattern. + if(amount < 0.1) return + var/turf/simulated/S = loc + if(!istype(S)) return + + for(var/d in list(turn(dir,90),turn(dir,-90))) + if(S.air_check_directions & d) + var/turf/simulated/O = get_step(S,d) + new/obj/liquid_fuel/flamethrower_fuel(O,amount*0.25,d) + O.hotspot_expose((T20C*2) + 380,500) //Light flamethrower fuel on fire immediately. + + amount *= 0.5 + + turf/simulated/var/fire_protection = 0 //Protects newly extinguished tiles from being overrun again. 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) +datum/gas_mixture/proc/zburn(obj/liquid_fuel/liquid) //This proc is similar to fire(), but uses a simple logarithm to calculate temp, and is thus more stable with ZAS. if(temperature > PLASMA_MINIMUM_BURN_TEMPERATURE) var @@ -188,16 +246,16 @@ datum/gas_mixture/proc/zburn(obj/effect/decal/cleanable/liquid_fuel/liquid) datum/gas/volatile_fuel/fuel = locate() in trace_gases if(fuel) - //Volatile Fuel + //Volatile Fuel if(fuel.moles < 0.01) trace_gases.Remove(fuel) - del fuel + fuel = null else total_fuel += fuel.moles fuel_sources++ if(liquid) - //Liquid Fuel + //Liquid Fuel if(liquid.amount <= 0) del liquid else @@ -205,16 +263,14 @@ datum/gas_mixture/proc/zburn(obj/effect/decal/cleanable/liquid_fuel/liquid) fuel_sources++ //Toxins - if(toxins > 0.1) fuel_sources++ + if(toxins > 0.3) fuel_sources++ if(!fuel_sources) return 0 //If there's no fuel, there's no burn. Can't divide by zero anyway. - if(oxygen > 0.1) + if(oxygen > 0.3) //Calculate the firelevel. var/firelevel = calculate_firelevel(liquid) - if(firelevel < 0.01) - return 0 //Reaches a maximum practical temperature of around 4500. @@ -222,7 +278,7 @@ datum/gas_mixture/proc/zburn(obj/effect/decal/cleanable/liquid_fuel/liquid) temperature = max( 1700*log(0.4*firelevel + 1.23) , temperature ) //Consume some gas. - var/consumed_gas = min(oxygen,firelevel * 50,total_fuel) / fuel_sources + var/consumed_gas = min(oxygen,0.05*firelevel,total_fuel) / fuel_sources oxygen = max(0,oxygen-consumed_gas) @@ -243,24 +299,19 @@ datum/gas_mixture/proc/zburn(obj/effect/decal/cleanable/liquid_fuel/liquid) return 0 -datum/gas_mixture/proc/calculate_firelevel(obj/effect/decal/cleanable/liquid_fuel/liquid) +datum/gas_mixture/proc/calculate_firelevel(obj/liquid_fuel/liquid) //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 - fuel_concentration = 0 oxy_concentration = oxygen / volume tox_concentration = toxins / volume + fuel_concentration = 0 if(fuel) fuel_concentration = (fuel.moles) / volume if(liquid) liquid_concentration = (liquid.amount*15) / volume - - var/final = tox_concentration + liquid_concentration + fuel_concentration - if(final > oxy_concentration) - final = oxy_concentration - - return final * 100 + return (oxy_concentration + tox_concentration + liquid_concentration + fuel_concentration)*100 /mob/living/carbon/human/proc/FireBurn(mx as num) //Burns mobs due to fire. Respects heat transfer coefficients on various body parts. @@ -273,7 +324,7 @@ datum/gas_mixture/proc/calculate_firelevel(obj/effect/decal/cleanable/liquid_fue arms_exposure = 1 //Get heat transfer coefficients for clothing. - //skytodo: different handling of temp with tg //Jesus, mate. Don't ask me. I have no diea how their crap works, and Aryn wrote this proc. + //skytodo: different handling of temp with tg /*for(var/obj/item/clothing/C in src) if(l_hand == C || r_hand == C) continue if(C.body_parts_covered & HEAD) diff --git a/code/ZAS/ZAS_Zones.dm b/code/ZAS/ZAS_Zones.dm index 903cc156ad5..f1a3a57bd52 100644 --- a/code/ZAS/ZAS_Zones.dm +++ b/code/ZAS/ZAS_Zones.dm @@ -388,11 +388,11 @@ proc/ShareSpace(datum/gas_mixture/A, list/unsimulated_tiles) plasma_avg = unsim_plasma//(full_plasma + unsim_plasma) / (size + share_size) //WOOT WOOT TOUCH THIS AND YOU ARE A RETARD - if(sharing_lookup_table.len >= connecting_tiles) //6 or more interconnecting tiles will max at 42% of air moved per tick. - ratio = sharing_lookup_table[connecting_tiles] + if(sharing_lookup_table.len >= unsimulated_tiles.len) //6 or more interconnecting tiles will max at 42% of air moved per tick. + ratio = sharing_lookup_table[unsimulated_tiles.len] ratio *= 2 //WOOT WOOT TOUCH THIS AND YOU ARE A RETARD - + A.oxygen = max(0, (A.oxygen - oxy_avg) * (1-ratio) + oxy_avg ) A.nitrogen = max(0, (A.nitrogen - nit_avg) * (1-ratio) + nit_avg ) A.carbon_dioxide = max(0, (A.carbon_dioxide - co2_avg) * (1-ratio) + co2_avg )