fire update

enabled fire to destroy floors and objects
also tweaked the behaviour of glass to enable glasslocks against fire
also made fire extingiushers stop being useless
This commit is contained in:
LordBraindead
2013-07-14 21:20:45 +02:00
parent b777ae4bac
commit 08d2e22220
13 changed files with 264 additions and 227 deletions

View File

@@ -30,7 +30,7 @@ turf/simulated/hotspot_expose(exposed_temperature, exposed_volume, soh)
var/igniting = 0
var/obj/effect/decal/cleanable/liquid_fuel/liquid = locate() in src
if(air_contents.check_combustability(liquid))
igniting = 1
@@ -55,28 +55,87 @@ obj
icon = 'fire.dmi'
icon_state = "1"
layer = TURF_LAYER
layer = TURF_LAYER + 0.2
var
firelevel = 10000 //Calculated by gas_mixture.calculate_firelevel()
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
//get scorchmarks
var/obj/effect/decal/cleanable/scorchmark/scorch = locate() in S
//check if it found a scorchmark and add one if there isnt one already
if (!scorch)
scorch = new/obj/effect/decal/cleanable/scorchmark(S,0)
//try to burn the floor
//initialize the temperature needed for burning the floor
//initialize the fuel gained by burning this floor
//initialize the speed modifier for the floor to catch on fire
var/floor_target_temp = 0
var/floor_fuel = 1
var/floor_speed_modifier = 1
if(S.is_plasteel_floor())
floor_target_temp = 800
else if (S.is_light_floor())
floor_target_temp = 600
else if (S.is_grass_floor())
floor_target_temp = 500
floor_fuel = 2
floor_speed_modifier = 1.5
else if (S.is_wood_floor())
floor_target_temp = 500
floor_fuel = 3
floor_speed_modifier = 1.25
else if (S.is_carpet_floor())
floor_target_temp = 500
floor_fuel = 3
floor_speed_modifier = 1.5
else
floor_target_temp = 1200
floor_speed_modifier = 0.8
//check if the floor is burnable
if(floor_target_temp > 0)
//calculate a random factor for the equation
var/turf_burn_random = max( min(floor_speed_modifier * 5 * ( ( max(air_contents.temperature - floor_target_temp,0) / floor_target_temp )^2 ), 100), 0)
//check if the random check is passed
if (prob(turf_burn_random))
//check if the tile has already been damaged once
if (S.burnt || S.broken)
//check if the tile is plating, if not break it and release some fuel, also some randomness to slow down the process
if (!S.is_plating() && prob(10))
scorch.amount += floor_fuel
S.break_tile_to_plating()
//damage it and release fuel
else
scorch.amount += floor_fuel
S.burn_tile()
//now burn some items!
for(var/obj/o in loc)
if(o.fire_min_burn_temp)
var/obj_burn_random = max( min(o.fire_burn_multiplier * 5 * ( ( max(air_contents.temperature - o.fire_min_burn_temp,0) / o.fire_min_burn_temp )^2 ), 100), 0)
if(prob(obj_burn_random))
scorch.amount += fire_fuel_worth
o.fire_burn()
//since the air is processed in fractions, we need to make sure not to have any minuscle residue or
//the amount of moles might get to low for some functions to catch them and thus result in wonky behaviour
if(air_contents.oxygen < 0.001)
@@ -86,29 +145,29 @@ obj
if(fuel)
if(fuel.moles < 0.001)
air_contents.trace_gases.Remove(fuel)
//check if there is something to combust
if(!air_contents.check_combustability(liquid))
if(!air_contents.check_combustability(liquid,scorch))
del src
//get a firelevel and set the icon
firelevel = air_contents.calculate_firelevel(liquid)
if(firelevel > 6)
firelevel = air_contents.calculate_firelevel(liquid,scorch)
if(firelevel > 3)
icon_state = "3"
SetLuminosity(7)
else if(firelevel > 2.5)
else if(firelevel > 2)
icon_state = "2"
SetLuminosity(5)
else
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!
//spread!
for(var/direction in cardinal)
if(S.air_check_directions&direction) //Grab all valid bordering tiles
@@ -118,7 +177,7 @@ obj
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)
if(prob( 100 * (1 - min( max( ( (world.time - 30) - enemy_tile.fire_protection ), 0 ) / 30, 1) ) ) )
firelevel -= 1.5
continue
@@ -126,29 +185,29 @@ obj
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))
if(flow.check_combustability(liquid,scorch))
//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)
flow.zburn(liquid,scorch,1)
//merge the air back
S.assume_air(flow)
///////////////////////////////// FLOW HAS BEEN REMERGED /// feel free to delete the fire again from here on //////////////////////////////////////////////////////////////////
New(newLoc,fl)
..()
@@ -178,15 +237,15 @@ turf/simulated/apply_fire_protection()
fire_protection = world.time
datum/gas_mixture/proc/zburn(obj/effect/decal/cleanable/liquid_fuel/liquid,force_burn)
datum/gas_mixture/proc/zburn(obj/effect/decal/cleanable/liquid_fuel/liquid, obj/effect/decal/cleanable/scorchmark/scorch, force_burn)
var/value = 0
if((temperature > PLASMA_MINIMUM_BURN_TEMPERATURE || force_burn) && check_combustability(liquid) )
var/total_fuel = 0
if((temperature > PLASMA_MINIMUM_BURN_TEMPERATURE || force_burn) && check_combustability(liquid,scorch) )
var/total_fuel = 0
var/datum/gas/volatile_fuel/fuel = locate() in trace_gases
total_fuel += toxins
if(fuel)
//Volatile Fuel
total_fuel += fuel.moles
@@ -198,8 +257,12 @@ datum/gas_mixture/proc/zburn(obj/effect/decal/cleanable/liquid_fuel/liquid,force
else
total_fuel += liquid.amount
if(scorch)
//fuel created by destroying objects and turfs
total_fuel += scorch.amount
//Calculate the firelevel.
var/firelevel = calculate_firelevel(liquid)
var/firelevel = calculate_firelevel(liquid, scorch)
//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
@@ -207,7 +270,7 @@ datum/gas_mixture/proc/zburn(obj/effect/decal/cleanable/liquid_fuel/liquid,force
//determine the amount of oxygen used
var/total_oxygen = min(oxygen, 2 * total_fuel)
//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
@@ -232,33 +295,39 @@ datum/gas_mixture/proc/zburn(obj/effect/decal/cleanable/liquid_fuel/liquid,force
liquid.amount -= liquid.amount * used_fuel_ratio * used_reactants_ratio
if(liquid.amount <= 0) del liquid
if(scorch)
scorch.amount -= min(scorch.amount, scorch.amount * used_fuel_ratio * used_reactants_ratio)
//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()
update_values()
value = total_reactants * used_reactants_ratio
return value
datum/gas_mixture/proc/check_combustability(obj/effect/decal/cleanable/liquid_fuel/liquid)
datum/gas_mixture/proc/check_combustability(obj/effect/decal/cleanable/liquid_fuel/liquid, obj/effect/decal/cleanable/scorchmark/scorch)
//this check comes up very often and is thus centralized here to ease adding stuff
var/datum/gas/volatile_fuel/fuel = locate() in trace_gases
var/datum/gas/volatile_fuel/fuel = locate() in trace_gases
var/value = 0
if(oxygen && (toxins || fuel || liquid))
value = 1
else if (scorch)
if (oxygen && scorch.amount > 0)
value = 1
return value
datum/gas_mixture/proc/calculate_firelevel(obj/effect/decal/cleanable/liquid_fuel/liquid)
datum/gas_mixture/proc/calculate_firelevel(obj/effect/decal/cleanable/liquid_fuel/liquid, obj/effect/decal/cleanable/scorchmark/scorch)
//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
var/total_fuel = 0
var/firelevel = 0
if(check_combustability(liquid))
total_fuel += toxins
if(liquid)
@@ -267,17 +336,20 @@ datum/gas_mixture/proc/calculate_firelevel(obj/effect/decal/cleanable/liquid_fue
if(fuel)
total_fuel += fuel.moles
if(scorch)
total_fuel += scorch.amount
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)
@@ -323,6 +395,4 @@ datum/gas_mixture/proc/calculate_firelevel(obj/effect/decal/cleanable/liquid_fue
apply_damage(0.6*mx*legs_exposure, BURN, "l_leg", 0, 0, "Fire")
apply_damage(0.6*mx*legs_exposure, BURN, "r_leg", 0, 0, "Fire")
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()
apply_damage(0.4*mx*arms_exposure, BURN, "r_arm", 0, 0, "Fire")

View File

@@ -80,7 +80,17 @@
var/name = t.fields["name"]
var/rank = t.fields["rank"]
var/real_rank = t.fields["real_rank"]
isactive[name] = t.fields["p_stat"]
var/active = 0
for(var/mob/M in player_list) if(M.name == name)
// For dead ones, have a chance to get their status wrong
if(M.stat == 2)
active = M.x % 2 // Should be good enough, avoids their status flipping constantly
break
else if(M.client && M.client.inactivity <= 10 * 60 * 10)
active = 1
break
isactive[name] = active ? "Active" : "SSD"
//world << "[name]: [rank]"

View File

@@ -0,0 +1,15 @@
obj/effect/decal/cleanable/scorchmark
//this is used as an additional visual result of fire and as a reagent holder for fuel created by burning of turfs and items.
icon = 'icons/effects/scorchmark.dmi'
name = "Soot"
icon_state = "1"
layer = TURF_LAYER+0.1
anchored = 1
var/amount = 0 //starts always empty and is filled by procs called by fire
New(newLoc,start_amount=0)
..()
icon_state = pick("1","2","3","4","5","6","7","8","9")
dir = pick(cardinal)
amount = start_amount

View File

@@ -39,25 +39,25 @@ would spawn and follow the beaker, even if it is carried or thrown.
/obj/effect/effect/water/New()
..()
//var/turf/T = src.loc
//if (istype(T, /turf))
// T.firelevel = 0 //TODO: FIX
var/turf/simulated/floor/T = src.loc
if (istype(T, /turf/simulated/floor))
T.fire_protection = world.time
spawn( 70 )
delete()
return
return
/obj/effect/effect/water/Del()
//var/turf/T = src.loc
//if (istype(T, /turf))
// T.firelevel = 0 //TODO: FIX
var/turf/simulated/floor/T = src.loc
if (istype(T, /turf/simulated/floor))
T.fire_protection = world.time
..()
return
/obj/effect/effect/water/Move(turf/newloc)
//var/turf/T = src.loc
//if (istype(T, /turf))
// T.firelevel = 0 //TODO: FIX
var/turf/simulated/floor/T = src.loc
if (istype(T, /turf/simulated/floor))
T.fire_protection = world.time
if (--src.life < 1)
//SN src = null
delete()

View File

@@ -103,6 +103,9 @@ var/global/list/datum/stack_recipe/uranium_recipes = list ( \
origin_tech = "plasmatech=2;materials=2"
perunit = 2000
sheettype = "plasma"
fire_min_burn_temp = 500
fire_burn_multiplier = 3 //made of burnium
fire_fuel_worth = 0
var/global/list/datum/stack_recipe/plasma_recipes = list ( \
new/datum/stack_recipe("plasma door", /obj/structure/mineral_door/transparent/plasma, 10, one_per_turf = 1, on_floor = 1), \
@@ -114,6 +117,18 @@ var/global/list/datum/stack_recipe/plasma_recipes = list ( \
pixel_y = rand(0,4)-4
..()
/obj/item/stack/sheet/mineral/plasma/fire_burn()
//get location and check if it is in a proper ZAS zone
var/turf/simulated/floor/S = loc
if(S.zone)
var/datum/gas_mixture/air_contents = S.return_air()
if(air_contents)
air_contents.toxins += 20
air_contents.update_values()
amount -= 1
if(amount <= 0)
del src
/obj/item/stack/sheet/mineral/plastic
name = "Plastic"
icon_state = "sheet-plastic"
@@ -124,6 +139,7 @@ var/global/list/datum/stack_recipe/plasma_recipes = list ( \
throw_range = 3
origin_tech = "materials=3"
perunit = 2000
sheettype = "plastic"
var/global/list/datum/stack_recipe/plastic_recipes = list ( \
new/datum/stack_recipe("plastic crate", /obj/structure/closet/pcrate, 10, one_per_turf = 1, on_floor = 1), \

View File

@@ -20,6 +20,10 @@
var/construction_cost = list("metal"=750,"glass"=75)
var/construction_time=100
fire_min_burn_temp = 1000
fire_burn_multiplier = 0.75
fire_fuel_worth = 0
suicide_act(mob/user)
viewers(user) << "\red <b>[user] is licking the electrodes of the [src.name]! It looks like \he's trying to commit suicide.</b>"
return (FIRELOSS)
@@ -111,4 +115,12 @@
maxcharge = 10000
maxcharge = 10000
m_amt = 0
g_amt = 0
g_amt = 0
/obj/item/weapon/cell/fire_burn()
viewers(src) << "\red <b>Charge: [src.charge]</b>"
var/radius = round( (sqrt(charge)/30)+0.5, 1 )
viewers(src) << "\red <b>Radius: [radius]</b>"
if (radius >= 1)
explosion(src.loc,0,0,radius)
..()

View File

@@ -16,6 +16,11 @@
var/integrity = 3
var/volume = 70
m_amt = 3750
fire_min_burn_temp = 800
fire_burn_multiplier = 0.75
fire_fuel_worth = 0
/obj/item/weapon/tank/New()
..()
@@ -261,4 +266,11 @@
integrity--
else if(integrity < 3)
integrity++
integrity++
/obj/item/weapon/tank/fire_burn()
//get location and check if it is in a proper ZAS zone
var/turf/simulated/floor/S = loc
if(S.zone)
S.assume_air(air_contents)
..()

View File

@@ -76,11 +76,19 @@
icon_state = "wooden_chair"
name = "wooden chair"
desc = "Old is never too old to not be in fashion."
fire_min_burn_temp = 500
fire_burn_multiplier = 1.25
fire_fuel_worth = 5
m_amt = 0
/obj/structure/stool/bed/chair/wood/wings
icon_state = "wooden_chair_wings"
name = "wooden chair"
desc = "Old is never too old to not be in fashion."
fire_min_burn_temp = 500
fire_burn_multiplier = 1.25
fire_fuel_worth = 5
m_amt = 0
/obj/structure/stool/bed/chair/wood/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(istype(W, /obj/item/weapon/wrench))
@@ -93,6 +101,9 @@
/obj/structure/stool/bed/chair/comfy
name = "comfy chair"
desc = "It looks comfy."
fire_min_burn_temp = 500
fire_burn_multiplier = 1.25
fire_fuel_worth = 4
/obj/structure/stool/bed/chair/comfy/brown
icon_state = "comfychair_brown"

View File

@@ -6,6 +6,10 @@
anchored = 1.0
flags = FPRINT
pressure_resistance = 15
m_amt = 3750
fire_min_burn_temp = 600
fire_burn_multiplier = 1
fire_fuel_worth = 2
/obj/structure/stool/ex_act(severity)
switch(severity)

View File

@@ -373,8 +373,9 @@
return
/obj/structure/window/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(exposed_temperature > T0C + 800)
hit(round(exposed_volume / 100), 0)
//Since glasslocks are the only thing you can do to prevent spreading atmos issues, this was disabled for the time being
//if(exposed_temperature > T0C + 800)
// hit(round(exposed_volume / 100), 0)
..()

View File

@@ -1,5 +1,3 @@
/obj/structure/reagent_dispensers
name = "Dispenser"
desc = "..."
@@ -66,12 +64,6 @@
new /obj/effect/effect/water(src.loc)
del(src)
//Dispensers
/obj/structure/reagent_dispensers/watertank
name = "watertank"
@@ -79,10 +71,39 @@
icon = 'icons/obj/objects.dmi'
icon_state = "watertank"
amount_per_transfer_from_this = 10
m_amt = 7500
g_amt = 3750
fire_min_burn_temp = 800
fire_burn_multiplier = 0.75
fire_fuel_worth = 0
New()
..()
reagents.add_reagent("water",1000)
/obj/structure/reagent_dispensers/watertank/fire_burn()
src.reagents.update_total()
var/number_of_gusts = src.reagents.total_volume / 50
for(var/a=0, a < number_of_gusts , a++)
var/obj/effect/effect/water/W = new /obj/effect/effect/water( get_turf(src) )
var/turf/my_target = get_step(get_step(get_step(get_step(get_step(get_turf(src),pick(cardinal)),pick(cardinal)),pick(cardinal)),pick(cardinal)),pick(cardinal))
var/datum/reagents/R = new/datum/reagents(50)
if(!W) return
W.reagents = R
R.my_atom = W
if(!W || !src) return
src.reagents.trans_to(W,50)
for(var/b=0, b<5, b++)
step_towards(W,my_target)
if(!W) return
W.reagents.reaction(get_turf(W))
for(var/atom/atm in get_turf(W))
if(!W) return
W.reagents.reaction(atm)
if(W.loc == my_target) break
..()
/obj/structure/reagent_dispensers/fueltank
name = "fueltank"
desc = "A fueltank"
@@ -91,6 +112,13 @@
amount_per_transfer_from_this = 10
var/modded = 0
var/obj/item/device/assembly_holder/rig = null
m_amt = 7500
g_amt = 3750
fire_min_burn_temp = 800
fire_burn_multiplier = 1
fire_fuel_worth = 0
New()
..()
reagents.add_reagent("fuel",1000)
@@ -164,6 +192,11 @@
if(src)
del(src)
/obj/structure/reagent_dispensers/fueltank/fire_burn()
src.reagents.update_total()
new/obj/effect/decal/cleanable/liquid_fuel(src.loc, src.reagents.total_volume)
..()
/obj/structure/reagent_dispensers/peppertank
name = "Pepper Spray Refiller"
desc = "Refill pepper spray canisters."
@@ -214,4 +247,4 @@
New()
..()
reagents.add_reagent("virusfood", 1000)
reagents.add_reagent("virusfood", 1000)