mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-11 10:43:20 +00:00
Fire Rework (#9669)
This commit is contained in:
147
modular_chomp/code/ZAS/Fire.dm
Normal file
147
modular_chomp/code/ZAS/Fire.dm
Normal file
@@ -0,0 +1,147 @@
|
||||
/turf/proc/lingering_fire(fl)
|
||||
return
|
||||
|
||||
/turf/simulated/lingering_fire(fl)
|
||||
if(istype(src, /turf/space) || istype(src, /turf/simulated/floor/water) || istype(src, /turf/simulated/flesh))
|
||||
return FALSE
|
||||
|
||||
if(istype(src, /turf/simulated/open))
|
||||
var/turf/below = GetBelow(src)
|
||||
if(below)
|
||||
return below.lingering_fire(fl)
|
||||
|
||||
if(!zone)
|
||||
return TRUE
|
||||
|
||||
if(fire)
|
||||
fire.firelevel = max(fl, fire.firelevel)
|
||||
return TRUE
|
||||
|
||||
fire = new /obj/fire/lingering(src, fl)
|
||||
SSair.active_fire_zones |= zone
|
||||
zone.fire_tiles |= src
|
||||
return FALSE
|
||||
|
||||
/turf/proc/feed_lingering_fire(var/amnt)
|
||||
return
|
||||
|
||||
/turf/simulated/feed_lingering_fire(var/amnt)
|
||||
if(fire && istype(fire, /obj/fire/lingering))
|
||||
var/obj/fire/lingering/F = fire
|
||||
F.firelevel += amnt
|
||||
if(F.firelevel > 2) // Allow above 0 if fed
|
||||
F.firelevel = 2
|
||||
F.ultimate_burnout = 0 // Reset
|
||||
zone.fire_tiles |= src
|
||||
// Add C02
|
||||
var/datum/gas_mixture/air_contents = return_air()
|
||||
air_contents.adjust_gas(GAS_CO2, rand(1,5))
|
||||
air_contents.update_values()
|
||||
|
||||
/obj/fire/lingering
|
||||
|
||||
anchored = TRUE // While it would be funny... Sadly no.
|
||||
mouse_opacity = 0
|
||||
|
||||
icon = 'modular_chomp/icons/effects/fire.dmi'
|
||||
icon_state = "fire"
|
||||
light_color = "#ED9200"
|
||||
layer = GASFIRE_LAYER
|
||||
var/ultimate_burnout = 0 // If it reaches 1, begin dying down
|
||||
|
||||
/obj/fire/lingering/Initialize(mapload, fl)
|
||||
if(fl > 1)
|
||||
fl = 1
|
||||
if(fl <= 0)
|
||||
fl = 0.001
|
||||
. = ..(mapload, fl)
|
||||
// USes parent fire init, so let's clear these
|
||||
icon_state = "[initial(icon_state)]-[rand(0, 2)]"
|
||||
color = initial(color)
|
||||
set_light(3, 1, l_color = light_color)
|
||||
SSair.lingering_fires++
|
||||
|
||||
/obj/fire/lingering/process()
|
||||
. = 1
|
||||
|
||||
var/turf/simulated/my_tile = loc
|
||||
if(!istype(my_tile) || !my_tile.zone)
|
||||
if(my_tile && my_tile.fire == src)
|
||||
my_tile.fire = null
|
||||
qdel(src)
|
||||
return TRUE
|
||||
|
||||
// Don't burn forever, eventually we have no more fuel
|
||||
ultimate_burnout += 0.001
|
||||
|
||||
// Spread while burning out oxigen
|
||||
var/datum/gas_mixture/air_contents = my_tile.return_air()
|
||||
var/gas_exchange = rand(0.01, 0.2)
|
||||
air_contents.remove_by_flag(XGM_GAS_OXIDIZER, gas_exchange)
|
||||
air_contents.adjust_gas(GAS_CO2, gas_exchange * 1.5) // Lots of CO2
|
||||
|
||||
var/starting_energy = air_contents.temperature * air_contents.heat_capacity()
|
||||
|
||||
air_contents.temperature = (starting_energy + vsc.fire_fuel_energy_release * (gas_exchange * 1.05)) / air_contents.heat_capacity()
|
||||
air_contents.update_values()
|
||||
|
||||
// Affect contents
|
||||
for(var/mob/living/L in loc)
|
||||
L.FireBurn(firelevel, air_contents.temperature, air_contents.return_pressure()) // Burn the mobs!
|
||||
|
||||
loc.fire_act(air_contents, air_contents.temperature, air_contents.volume)
|
||||
for(var/atom/A in loc)
|
||||
A.fire_act(air_contents, air_contents.temperature, air_contents.volume)
|
||||
|
||||
// Spreading behaviour
|
||||
for(var/direction in shuffle(cardinal))
|
||||
var/turf/simulated/enemy_tile = get_step(my_tile, direction)
|
||||
if(istype(enemy_tile))
|
||||
if(my_tile.open_directions & direction)
|
||||
if(!enemy_tile.zone)
|
||||
continue
|
||||
|
||||
// If extinguisher mist passed over the turf it's trying to spread to, don't spread and end the fire
|
||||
if(enemy_tile.fire_protection > world.time-60)
|
||||
firelevel = 0
|
||||
qdel(src)
|
||||
my_tile.fire = null
|
||||
continue
|
||||
|
||||
if(enemy_tile.fire)
|
||||
if(firelevel > 0.5)
|
||||
// Share with other fires if we have the energy
|
||||
enemy_tile.fire.firelevel += firelevel / 3
|
||||
firelevel /= 2
|
||||
continue
|
||||
|
||||
if(firelevel >= 0.15 && prob(60) && my_tile.CanPass(src, enemy_tile) && enemy_tile.CanPass(src, my_tile))
|
||||
var/splitrate = 0.85
|
||||
enemy_tile.lingering_fire(firelevel * splitrate)
|
||||
firelevel -= (1 - splitrate)
|
||||
|
||||
else if(prob(20))
|
||||
enemy_tile.adjacent_fire_act(loc, air_contents, air_contents.temperature, air_contents.volume)
|
||||
|
||||
var/total_oxidizers = 0
|
||||
for(var/g in air_contents.gas)
|
||||
if(gas_data.flags[g] & XGM_GAS_OXIDIZER)
|
||||
total_oxidizers += air_contents.gas[g]
|
||||
|
||||
var/invalid_fire = total_oxidizers < 1 || air_contents.temperature <= (T0C + 15) || ultimate_burnout >= 1 || my_tile.is_outdoors() || SSair.lingering_fires >= 1000
|
||||
if(prob(30) || invalid_fire)
|
||||
if(total_oxidizers < 10 && prob(10))
|
||||
firelevel *= 0.95
|
||||
else if(invalid_fire)
|
||||
firelevel *= 0.5
|
||||
|
||||
if(firelevel <= 0.01)
|
||||
qdel(src)
|
||||
my_tile.fire = null
|
||||
|
||||
/obj/fire/lingering/ex_act(strength)
|
||||
. = ..()
|
||||
var/turf/T = get_turf(src)
|
||||
if(T)
|
||||
T.fire = null
|
||||
qdel(src)
|
||||
89
modular_chomp/code/ZAS/Fire_acts.dm
Normal file
89
modular_chomp/code/ZAS/Fire_acts.dm
Normal file
@@ -0,0 +1,89 @@
|
||||
#define TRASH_BURN 0.05
|
||||
#define LOW_BURN 0.1
|
||||
#define GOOD_BURN 0.2
|
||||
#define HIGH_BURN 0.5
|
||||
#define SUPER_BURN 0.8
|
||||
#define MEGA_BURN 1
|
||||
|
||||
#define LOW_CHANCE 3
|
||||
#define MED_CHANCE 6
|
||||
#define HIGH_CHANCE 12
|
||||
|
||||
// Additional fire_acts(), macro that assembles a proc that runs every time fire acts on the assigned object path of x.
|
||||
// If it rolls the prob("c"hance) it will feed the lingering fire a 0 to 1 value as "b"urn. Then ex_act(1) the object while leaving ash behind.
|
||||
// With great agony, I wish to report that I feel like I'm coding in C98 with this bullshit - Willbird
|
||||
#define FIREACT_BURNS(x,c,b) x/fire_act(){if(prob(c)){var/turf/T = get_turf(src);T?.feed_lingering_fire(b);new /obj/effect/decal/cleanable/ash(get_turf(src));ex_act(1);}}
|
||||
|
||||
//////////////////////////// TRASH BURN ////////////////////////////
|
||||
FIREACT_BURNS(/obj/item/trash,HIGH_CHANCE,TRASH_BURN)
|
||||
FIREACT_BURNS(/obj/item/paper,HIGH_CHANCE,TRASH_BURN)
|
||||
FIREACT_BURNS(/obj/item/soap,LOW_CHANCE,TRASH_BURN)
|
||||
FIREACT_BURNS(/obj/item/storage/pill_bottle,MED_CHANCE,TRASH_BURN)
|
||||
FIREACT_BURNS(/obj/item/assembly/mousetrap,HIGH_CHANCE,TRASH_BURN)
|
||||
FIREACT_BURNS(/obj/structure/table/standard,LOW_CHANCE,TRASH_BURN)
|
||||
FIREACT_BURNS(/obj/item/deck,LOW_CHANCE,TRASH_BURN)
|
||||
//////////////////////////// LOW BURN ////////////////////////////
|
||||
FIREACT_BURNS(/obj/item/stack/material/plastic,LOW_CHANCE,LOW_BURN)
|
||||
FIREACT_BURNS(/obj/item/paper_bin,HIGH_CHANCE,LOW_BURN)
|
||||
FIREACT_BURNS(/obj/item/bedsheet,HIGH_CHANCE,LOW_BURN)
|
||||
FIREACT_BURNS(/obj/item/book,HIGH_CHANCE,LOW_BURN)
|
||||
FIREACT_BURNS(/obj/item/folder,HIGH_CHANCE,LOW_BURN)
|
||||
FIREACT_BURNS(/obj/item/storage/fancy/cigar,HIGH_CHANCE,LOW_BURN)
|
||||
FIREACT_BURNS(/obj/structure/flora/pottedplant,LOW_CHANCE,LOW_BURN)
|
||||
FIREACT_BURNS(/obj/item/storage/box,MED_CHANCE,LOW_BURN)
|
||||
FIREACT_BURNS(/obj/item/juke_remote,LOW_CHANCE,LOW_BURN)
|
||||
FIREACT_BURNS(/obj/item/mop,LOW_CHANCE,LOW_BURN)
|
||||
FIREACT_BURNS(/obj/item/storage/pouch,LOW_CHANCE,LOW_BURN)
|
||||
FIREACT_BURNS(/obj/item/storage/backpack,LOW_CHANCE,LOW_BURN)
|
||||
FIREACT_BURNS(/obj/item/storage/bag/trash,LOW_CHANCE,LOW_BURN)
|
||||
FIREACT_BURNS(/obj/item/reagent_containers/food,LOW_CHANCE,LOW_BURN)
|
||||
FIREACT_BURNS(/obj/item/packageWrap,HIGH_CHANCE,LOW_BURN)
|
||||
FIREACT_BURNS(/obj/item/tape_roll,LOW_CHANCE,LOW_BURN)
|
||||
FIREACT_BURNS(/obj/structure/sign/christmas,LOW_CHANCE,LOW_BURN) // IT CRIMBO, OH NO IT CRIMBO
|
||||
FIREACT_BURNS(/obj/structure/table/woodentable,MED_CHANCE,LOW_BURN)
|
||||
FIREACT_BURNS(/obj/structure/table/gamblingtable,MED_CHANCE,LOW_BURN)
|
||||
//////////////////////////// GOOD BURN ////////////////////////////
|
||||
FIREACT_BURNS(/obj/item/stack/material/stick,MED_CHANCE,GOOD_BURN)
|
||||
FIREACT_BURNS(/obj/item/stack/material/wax,MED_CHANCE,GOOD_BURN)
|
||||
FIREACT_BURNS(/obj/structure/bookcase,LOW_CHANCE,GOOD_BURN)
|
||||
FIREACT_BURNS(/obj/structure/simple_door/wood,LOW_CHANCE,GOOD_BURN)
|
||||
FIREACT_BURNS(/obj/item/instrument,LOW_CHANCE,GOOD_BURN)
|
||||
FIREACT_BURNS(/obj/item/toy/plushie,MED_CHANCE,GOOD_BURN)
|
||||
FIREACT_BURNS(/obj/item/towel,HIGH_CHANCE,GOOD_BURN)
|
||||
FIREACT_BURNS(/obj/structure/closet/crate/wooden,MED_CHANCE,GOOD_BURN)
|
||||
FIREACT_BURNS(/obj/structure/bed,MED_CHANCE,GOOD_BURN)
|
||||
//////////////////////////// HIGH BURN ////////////////////////////
|
||||
FIREACT_BURNS(/obj/item/stack/material/wood,MED_CHANCE,HIGH_BURN)
|
||||
FIREACT_BURNS(/obj/structure/flora/tree,LOW_CHANCE,HIGH_BURN)
|
||||
//////////////////////////// MEGA BURN ////////////////////////////
|
||||
FIREACT_BURNS(/obj/item/stack/material/phoron,MED_CHANCE,MEGA_BURN)
|
||||
|
||||
// The remaining proc is defined without the macro to give an example of what the macro used above outputs.
|
||||
/obj/item/clothing/fire_act()
|
||||
if(prob(LOW_CHANCE))
|
||||
var/turf/T = get_turf(src)
|
||||
T?.feed_lingering_fire(GOOD_BURN)
|
||||
new /obj/effect/decal/cleanable/ash(get_turf(src))
|
||||
ex_act(1)
|
||||
|
||||
// Suits need special handling to avoid fires destroying rigs
|
||||
/obj/item/clothing/suit/fire_act()
|
||||
return
|
||||
|
||||
// anti-lag ash cleanup
|
||||
/obj/effect/decal/cleanable/ash/fire_act()
|
||||
if(prob(2))
|
||||
qdel(src)
|
||||
|
||||
#undef FIREACT_BURNS
|
||||
|
||||
#undef LOW_CHANCE
|
||||
#undef MED_CHANCE
|
||||
#undef HIGH_CHANCE
|
||||
|
||||
#undef TRASH_BURN
|
||||
#undef LOW_BURN
|
||||
#undef GOOD_BURN
|
||||
#undef HIGH_BURN
|
||||
#undef SUPER_BURN
|
||||
#undef MEGA_BURN
|
||||
Reference in New Issue
Block a user