Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simple fires #11044

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions beestation.dme
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,7 @@
#include "code\controllers\subsystem\processing\ai_controllers.dm"
#include "code\controllers\subsystem\processing\clock_component.dm"
#include "code\controllers\subsystem\processing\digital_clock.dm"
#include "code\controllers\subsystem\processing\effects.dm"
#include "code\controllers\subsystem\processing\fastprocess.dm"
#include "code\controllers\subsystem\processing\fields.dm"
#include "code\controllers\subsystem\processing\fluids.dm"
Expand Down Expand Up @@ -1223,6 +1224,7 @@
#include "code\game\objects\effects\overlays.dm"
#include "code\game\objects\effects\portals.dm"
#include "code\game\objects\effects\proximity.dm"
#include "code\game\objects\effects\simple_fire.dm"
#include "code\game\objects\effects\spiders.dm"
#include "code\game\objects\effects\step_triggers.dm"
#include "code\game\objects\effects\wanted_poster.dm"
Expand Down
38 changes: 32 additions & 6 deletions code/__HELPERS/heap.dm
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
/datum/heap/proc/insert(atom/A)

L.Add(A)
swim(length(L))
return swim(length(L))

//removes and returns the first element of the heap
//(i.e the max or the min dependant on the comparison function)
Expand All @@ -37,6 +37,19 @@
if(length(L))
sink(1)

/datum/heap/proc/delete_at(index)
if (index <= 0)
CRASH("Attempted to delete from heap where index is less than 0. This is an error.")
if (index > length(L))
CRASH("Attempted to delete from a heap outside of the bounds of the heap.")
var/deleted = L[index]
L.Swap(index, length(L))
L.len--
// Edge case where we remove the sole element of the heap
if (index <= L.len)
swim(index)
return deleted

//Get a node up to its right position in the heap
/datum/heap/proc/swim(index)
var/parent = round(index * 0.5)
Expand All @@ -45,6 +58,7 @@
L.Swap(index,parent)
index = parent
parent = round(index * 0.5)
return index

//Get a node down to its right position in the heap
/datum/heap/proc/sink(index)
Expand All @@ -55,19 +69,25 @@
index = g_child
g_child = get_greater_child(index)

#define parent_index(index) (index == 1 ? index : index / 2)

#define left_child_index(index) (index * 2)

#define right_child_index(index) (index * 2 + 1)

//Returns the greater (relative to the comparison proc) of a node children
//or 0 if there's no child
/datum/heap/proc/get_greater_child(index)
if(index * 2 > length(L))
if(left_child_index(index) > length(L))
return 0

if(index * 2 + 1 > length(L))
return index * 2
if(right_child_index(index) > length(L))
return left_child_index(index)

if(call(cmp)(L[index * 2],L[index * 2 + 1]) < 0)
return index * 2 + 1
return left_child_index(index)
else
return index * 2
return right_child_index(index)

//Replaces a given node so it verify the heap condition
/datum/heap/proc/resort(atom/A)
Expand All @@ -78,3 +98,9 @@

/datum/heap/proc/List()
. = L.Copy()

#undef parent_index

#undef left_child_index

#undef right_child_index
2 changes: 1 addition & 1 deletion code/__HELPERS/path.dm
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@
/datum/pathfind/New(atom/movable/caller, atom/goal, id, max_distance, mintargetdist, simulated_only, avoid, avoid_mobs)
src.caller = caller
end = get_turf(goal)
open = new /datum/heap(/proc/HeapPathWeightCompare)
open = new /datum/heap(GLOBAL_PROC_REF(HeapPathWeightCompare))
sources = new()
src.id = id
src.max_distance = max_distance
Expand Down
1 change: 1 addition & 0 deletions code/controllers/subsystem/async_map_generator.dm
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ SUBSYSTEM_DEF(async_map_generator)
current_run_length = length(executing_generators)
//Split the tick
MC_SPLIT_TICK_INIT(current_run_length)
MC_SPLIT_TICK
//Start processing
while (current_run_index <= current_run_length)
//Get current action
Expand Down
1 change: 1 addition & 0 deletions code/controllers/subsystem/enumeration.dm
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ SUBSYSTEM_DEF(enumeration)

/datum/controller/subsystem/enumeration/fire()
MC_SPLIT_TICK_INIT(length(tick_enumerations))
MC_SPLIT_TICK
//No need to copy the list, so use indexing enumeration isntead
//Go backwards to prevent concurrent modification issues
for (var/i in length(tick_enumerations) to 1 step -1)
Expand Down
2 changes: 1 addition & 1 deletion code/controllers/subsystem/explosion.dm
Original file line number Diff line number Diff line change
Expand Up @@ -555,7 +555,7 @@ SUBSYSTEM_DEF(explosions)
for(var/thing in flame_turf)
if(thing)
var/turf/T = thing
new /obj/effect/hotspot(T) //Mostly for ambience!
new /obj/effect/simple_fire(T) //Mostly for ambience!
cost_flameturf = MC_AVERAGE(cost_flameturf, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))

if (low_turf.len || med_turf.len || high_turf.len)
Expand Down
4 changes: 4 additions & 0 deletions code/controllers/subsystem/processing/effects.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
PROCESSING_SUBSYSTEM_DEF(effects)
name = "Effects"
wait = 0.2 SECONDS
stat_tag = "EFFECTS"
1 change: 1 addition & 0 deletions code/datums/components/chasm.dm
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
/obj/effect/portal,
/obj/effect/abstract,
/obj/effect/hotspot,
/obj/effect/simple_fire,
/obj/effect/landmark,
/obj/effect/temp_visual,
/obj/effect/light_emitter/tendril,
Expand Down
8 changes: 2 additions & 6 deletions code/datums/status_effects/debuffs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -521,7 +521,7 @@
var/curse_flags = NONE
var/effect_last_activation = 0
var/effect_cooldown = 100
var/obj/effect/temp_visual/curse/wasting_effect = new
var/obj/effect/curse/wasting_effect = new

/datum/status_effect/necropolis_curse/on_creation(mob/living/new_owner, set_curse)
. = ..()
Expand Down Expand Up @@ -585,13 +585,9 @@
C.preparePixelProjectile(ownerloc, spawn_turf)
C.fire()

/obj/effect/temp_visual/curse
/obj/effect/curse
icon_state = "curse"

/obj/effect/temp_visual/curse/Initialize(mapload)
. = ..()
deltimer(timerid)

/datum/status_effect/gonbolaPacify
id = "gonbolaPacify"
status_type = STATUS_EFFECT_MULTIPLE
Expand Down
2 changes: 1 addition & 1 deletion code/game/objects/effects/decals/cleanable/robots.dm
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@
visible_message("<span class='danger'>[src] catches fire!</span>")
var/turf/T = get_turf(src)
qdel(src)
new /obj/effect/hotspot(T)
new /obj/effect/simple_fire(T)

/obj/effect/decal/cleanable/oil/streak
icon_state = "streak1"
Expand Down
5 changes: 5 additions & 0 deletions code/game/objects/effects/effect_system/effects_foam.dm
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@
if(G.return_temperature() > T20C)
G.set_temperature(max(G.return_temperature()/2,T20C))
T.air_update_turf()
var/obj/effect/simple_fire/simple_fire = locate() in T
if (simple_fire)
qdel(simple_fire)

/obj/effect/particle_effect/foam/firefighting/kill_foam()
STOP_PROCESSING(SSfastprocess, src)
Expand Down Expand Up @@ -336,6 +339,8 @@
G.set_temperature(293.15)
for(var/obj/effect/hotspot/H in O)
qdel(H)
for(var/obj/effect/simple_fire/H in O)
qdel(H)
for(var/I in G.get_gases())
if(I == GAS_O2 || I == GAS_N2)
continue
Expand Down
2 changes: 2 additions & 0 deletions code/game/objects/effects/effect_system/effects_smoke.dm
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,8 @@
T.air_update_turf()
for(var/obj/effect/hotspot/H in T)
qdel(H)
for(var/obj/effect/simple_fire/H in T)
qdel(H)
if(G.get_moles(GAS_PLASMA))
G.adjust_moles(GAS_N2, G.get_moles(GAS_PLASMA))
G.set_moles(GAS_PLASMA, 0)
Expand Down
105 changes: 105 additions & 0 deletions code/game/objects/effects/simple_fire.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
#define INSUFFICIENT(path) (location.air.get_moles(path) < 0.5)

Check failure on line 1 in code/game/objects/effects/simple_fire.dm

View workflow job for this annotation

GitHub Actions / Run Linters

Define Sanity

SPREAD_FIRE_POWER is defined locally in code/game/objects/effects/simple_fire.dm but not undefined locally!

Check failure on line 1 in code/game/objects/effects/simple_fire.dm

View workflow job for this annotation

GitHub Actions / Run Linters

Define Sanity

DEFAULT_FIRE_POWER is defined locally in code/game/objects/effects/simple_fire.dm but not undefined locally!
#define SPREAD_FIRE_POWER 5 SECONDS
#define DEFAULT_FIRE_POWER 3 SECONDS

/**
* Simple atmospheric fire that requires oxygen, but doesn't consume it.
* Will die out after a set amount of time.
* Intended for non-atmospheric fires which shouldn't be tied to atmospherics.
*/
/obj/effect/simple_fire
anchored = TRUE
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
icon = 'icons/effects/fire.dmi'
icon_state = "2"
layer = GASFIRE_LAYER
blend_mode = BLEND_ADD
light_system = MOVABLE_LIGHT
light_range = LIGHT_RANGE_FIRE
// increase power for more bloom
light_power = 4
light_color = LIGHT_COLOR_FIRE
// Fire loses 1 power per second as it dies down
var/fire_power = DEFAULT_FIRE_POWER
var/last_fire = 0

/obj/effect/simple_fire/Initialize(mapload, power)
if (!isnull(power))
fire_power = power
// Try a proper ignition
var/turf/location = loc
if (istype(location))
location.hotspot_expose(FIRE_MINIMUM_TEMPERATURE_TO_EXIST)
// Can't set on fire if something is already there
if (locate(/obj/effect/hotspot) in loc)
return INITIALIZE_HINT_QDEL
// Merge with other fires
for (var/obj/effect/simple_fire/other_fire in loc)
if (other_fire == src)
continue
other_fire.fire_power = fire_power + other_fire.fire_power
return INITIALIZE_HINT_QDEL
. = ..()
setDir(pick(GLOB.cardinals))
// Process to die out
START_PROCESSING(SSeffects, src)
// When someone enters, they burn
var/static/list/loc_connections = list(
COMSIG_ATOM_ENTERED = PROC_REF(on_entered),
)
AddElement(/datum/element/connect_loc, loc_connections)

/obj/effect/simple_fire/process(delta_time)
var/turf/open/location = loc
if(!istype(location))
qdel(src)
return
// Fire dires out
if(fire_power <= 0)
qdel(src)
return
// These can exist without any actual gas, although will ignite gas
if(!location.air || location.air.get_oxidation_power() < 0.5)
qdel(src)
return
fire_power -= delta_time * 1 SECONDS
switch (fire_power)
if (3 SECONDS to INFINITY)
icon_state = "3"
if (1 SECONDS to 3 SECONDS)
icon_state = "2"
else
icon_state = "1"
// Fire at a rate of 1 per-second
if (last_fire + 1 SECONDS > world.time)
return
last_fire = world.time
// Spread the fire, so that it burns out quicker but makes a bigger effect
if (fire_power > SPREAD_FIRE_POWER)
var/turf/adjacent = get_step(src, pick(GLOB.cardinals))
if (isopenturf(adjacent))
new /obj/effect/simple_fire(adjacent, fire_power * 0.5)
fire_power *= 0.5
location.hotspot_expose(FIRE_MINIMUM_TEMPERATURE_TO_EXIST)
location.burn_tile()
// Burn things in this place
for(var/A in location)
var/atom/AT = A
// Stop if another fire starts here
if (istype(AT, /obj/effect/hotspot))
qdel(src)
return
if(!QDELETED(AT) && AT != src) // It's possible that the item is deleted in temperature_expose
AT.fire_act(FIRE_MINIMUM_TEMPERATURE_TO_EXIST, 125)

/obj/effect/simple_fire/proc/on_entered(datum/source, atom/movable/arrived, atom/old_loc, list/atom/old_locs)
SIGNAL_HANDLER

if(isliving(arrived))
var/mob/living/immolated = arrived
immolated.fire_act(FIRE_MINIMUM_TEMPERATURE_TO_EXIST, 125)

/obj/effect/simple_fire/singularity_pull(S, current_size)
return

#undef INSUFFICIENT
2 changes: 1 addition & 1 deletion code/game/objects/structures/traps.dm
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@

/obj/structure/trap/fire/flare()
..()
new /obj/effect/hotspot(get_turf(src))
new /obj/effect/simple_fire(get_turf(src))


/obj/structure/trap/chill
Expand Down
2 changes: 1 addition & 1 deletion code/modules/antagonists/blob/blobstrains/blazing_oil.dm
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
for(var/turf/open/T in RANGE_TURFS(1, B))
var/obj/structure/blob/C = locate() in T
if(!(C?.overmind && C.overmind.blobstrain.type == B.overmind.blobstrain.type) && prob(80))
new /obj/effect/hotspot(T)
new /obj/effect/simple_fire(T)
if(damage_flag == FIRE)
return 0
return ..()
Expand Down
2 changes: 1 addition & 1 deletion code/modules/antagonists/cult/runes.dm
Original file line number Diff line number Diff line change
Expand Up @@ -847,7 +847,7 @@ structure_check() searches for nearby cultist structures required for the invoca
if(QDELETED(src))
return
do_area_burn(T, 1.5)
new /obj/effect/hotspot(T)
new /obj/effect/simple_fire(T)
qdel(src)

/obj/effect/rune/blood_boil/proc/do_area_burn(turf/T, multiplier)
Expand Down
6 changes: 3 additions & 3 deletions code/modules/antagonists/heretic/magic/ash_ascension.dm
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
return

for(var/turf/nearby_turf as anything in RANGE_TURFS(1, current_user))
new /obj/effect/hotspot(nearby_turf)
new /obj/effect/simple_fire(nearby_turf)
nearby_turf.hotspot_expose(750, 25 * delta_time, 1)
for(var/mob/living/fried_living in nearby_turf.contents - current_user)
fried_living.adjustFireLoss(2.5 * delta_time)
Expand All @@ -65,7 +65,7 @@
var/current_range = 1
for(var/i in 0 to max_range)
for(var/turf/nearby_turf as anything in spiral_range_turfs(current_range, centre))
new /obj/effect/hotspot(nearby_turf)
new /obj/effect/simple_fire(nearby_turf)
nearby_turf.hotspot_expose(750, 50, 1)
for(var/mob/living/fried_living in nearby_turf.contents - centre)
fried_living.adjustFireLoss(5)
Expand Down Expand Up @@ -133,7 +133,7 @@
L.adjustFireLoss(20)
to_chat(L, "<span class='userdanger'>You're hit by [source]'s eldritch flames!</span>")

new /obj/effect/hotspot(T)
new /obj/effect/simple_fire(T)
T.hotspot_expose(700,50,1)
// deals damage to mechs
for(var/obj/vehicle/sealed/mecha/M in T.contents)
Expand Down
2 changes: 1 addition & 1 deletion code/modules/food_and_drinks/drinks/drinks/bottle.dm
Original file line number Diff line number Diff line change
Expand Up @@ -539,7 +539,7 @@
break
if(firestarter && active)
hit_atom.fire_act()
new /obj/effect/hotspot(get_turf(hit_atom))
new /obj/effect/simple_fire(get_turf(hit_atom), 400)
..()

/obj/item/reagent_containers/food/drinks/bottle/molotov/attackby(obj/item/I, mob/user, params)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ Difficulty: Medium
for(var/turf/T in turfs)
if(istype(T, /turf/closed))
break
new /obj/effect/hotspot(T)
new /obj/effect/simple_fire(T)
T.hotspot_expose(700,50,1)
for(var/mob/living/L in T.contents)
if(L in hit_list || L == source)
Expand Down Expand Up @@ -541,7 +541,7 @@ Difficulty: Medium
var/turf/closed/mineral/M = T
M.gets_drilled()
playsound(T, "explosion", 80, 1)
new /obj/effect/hotspot(T)
new /obj/effect/simple_fire(T)
T.hotspot_expose(700, 50, 1)
for(var/mob/living/L in T.contents)
if(istype(L, /mob/living/simple_animal/hostile/megafauna/dragon))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@
/mob/living/simple_animal/hostile/space_dragon/proc/dragon_fire_line(turf/T)
var/list/hit_list = list()
hit_list += src
new /obj/effect/hotspot(T)
new /obj/effect/simple_fire(T)
T.hotspot_expose(700,50,1)
for(var/mob/living/L in T.contents)
if(L.faction_check_mob(src) && L != src)
Expand Down
Loading
Loading