[MIRROR] Reworks burning objects to be a component [MDB IGNORE] (#20543)

* Reworks burning objects to be a component (#74688)

## About The Pull Request

Title.

## Why It's Good For The Game

Simply put, allows for atoms which are not /obj but use atom_integrity
to burn up too, which is nice and good.
But also, it allows for neat behavior like burning particle effects
(only structures use that right now to spawn smoke)

![image](https://user-images.githubusercontent.com/82850673/231595051-2a8d0574-33cc-4cd9-9d61-65566decf4ef.png)

## Changelog

🆑
add: Burning structures spawn smoke particles. Sick.
/🆑

---------

Co-authored-by: MrMelbert <51863163+MrMelbert@ users.noreply.github.com>

* Reworks burning objects to be a component

* modular

---------

Co-authored-by: ChungusGamer666 <82850673+ChungusGamer666@users.noreply.github.com>
Co-authored-by: MrMelbert <51863163+MrMelbert@ users.noreply.github.com>
Co-authored-by: Tom <8881105+tf-4@users.noreply.github.com>
This commit is contained in:
SkyratBot
2023-04-14 23:44:14 +01:00
committed by GitHub
co-authored by MrMelbert ChungusGamer666 Tom
parent bf9de0161c
commit 327ebcb31c
25 changed files with 134 additions and 79 deletions
@@ -24,6 +24,8 @@
#define COMSIG_ATOM_FIX "atom_fix"
/// from base of [/atom/proc/atom_destruction]: (damage_flag)
#define COMSIG_ATOM_DESTRUCTION "atom_destruction"
/// from base of [/atom/proc/extinguish]
#define COMSIG_ATOM_EXTINGUISH "atom_extinguish"
///from base of [/atom/proc/update_integrity]: (old_value, new_value)
#define COMSIG_ATOM_INTEGRITY_CHANGED "atom_integrity_changed"
///from base of [/atom/proc/take_damage]: (damage_amount, damage_type, damage_flag, sound_effect, attack_dir, aurmor_penetration)
+2
View File
@@ -168,7 +168,9 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204
#define LAVA_PROOF (1<<0)
/// 100% immune to fire damage (but not necessarily to lava or heat)
#define FIRE_PROOF (1<<1)
/// atom is flammable and can have the burning component
#define FLAMMABLE (1<<2)
/// currently burning
#define ON_FIRE (1<<3)
/// acid can't even appear on it, let alone melt it.
#define UNACIDABLE (1<<4)
+1 -1
View File
@@ -214,7 +214,7 @@
#define FIRE_PRIOTITY_SMOOTHING 35
#define FIRE_PRIORITY_OBJ 40
#define FIRE_PRIORITY_ACID 40
#define FIRE_PRIOTITY_BURNING 40
#define FIRE_PRIORITY_BURNING 40
#define FIRE_PRIORITY_DEFAULT 50
#define FIRE_PRIORITY_PARALLAX 65
#define FIRE_PRIORITY_INSTRUMENTS 80
@@ -1,40 +0,0 @@
SUBSYSTEM_DEF(fire_burning)
name = "Fire Burning"
priority = FIRE_PRIOTITY_BURNING
flags = SS_NO_INIT|SS_BACKGROUND
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
var/list/currentrun = list()
var/list/processing = list()
/datum/controller/subsystem/fire_burning/stat_entry(msg)
msg = "P:[length(processing)]"
return ..()
/datum/controller/subsystem/fire_burning/fire(resumed = 0)
if (!resumed)
src.currentrun = processing.Copy()
//cache for sanic speed (lists are references anyways)
var/list/currentrun = src.currentrun
var/seconds_per_tick = wait * 0.1
while(currentrun.len)
var/obj/O = currentrun[currentrun.len]
currentrun.len--
if (!O || QDELETED(O))
processing -= O
if (MC_TICK_CHECK)
return
continue
if(O.resistance_flags & ON_FIRE) //in case an object is extinguished while still in currentrun
if(!(O.resistance_flags & FIRE_PROOF))
O.take_damage(10 * seconds_per_tick, BURN, FIRE, 0)
else
O.extinguish()
if (MC_TICK_CHECK)
return
@@ -0,0 +1,6 @@
/// The subsystem used to tick [/datum/component/burning] instances.
PROCESSING_SUBSYSTEM_DEF(fire_burning)
name = "Fire Burning"
priority = FIRE_PRIORITY_BURNING
flags = SS_NO_INIT|SS_BACKGROUND
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
+2
View File
@@ -1,3 +1,5 @@
GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/effects/effects.dmi', "acid"))
/** Component representing acid applied to an object.
*
* Must be attached to an atom.
+70
View File
@@ -0,0 +1,70 @@
GLOBAL_DATUM_INIT(fire_overlay, /mutable_appearance, mutable_appearance('icons/effects/fire.dmi', "fire", appearance_flags = RESET_COLOR))
/**
* Component representing an atom being on fire.
* Should not be used on mobs, they use the fire stacks system.
*/
/datum/component/burning
/// Fire overlay appearance we apply
var/fire_overlay
/// Particle holder for fire particles, if any
var/obj/effect/abstract/particle_holder/particle_effect
/datum/component/burning/Initialize(fire_overlay, fire_particles)
if(!isatom(parent))
return COMPONENT_INCOMPATIBLE
var/atom/atom_parent = parent
if(!atom_parent.uses_integrity)
stack_trace("Tried to add /datum/component/burning to an atom ([atom_parent]) that does not use atom_integrity!")
return COMPONENT_INCOMPATIBLE
// only flammable atoms should have this component, but it's not really an error if we try to apply this to a non flammable one
if(!(atom_parent.resistance_flags & FLAMMABLE) || (atom_parent.resistance_flags & FIRE_PROOF))
qdel(src)
return
src.fire_overlay = fire_overlay
if(fire_particles)
particle_effect = new(atom_parent, fire_particles)
atom_parent.resistance_flags |= ON_FIRE
START_PROCESSING(SSfire_burning, src)
/datum/component/burning/RegisterWithParent()
. = ..()
RegisterSignal(parent, COMSIG_ATOM_UPDATE_OVERLAYS, PROC_REF(on_update_overlays))
RegisterSignal(parent, COMSIG_ATOM_EXTINGUISH, PROC_REF(on_extinguish))
var/atom/atom_parent = parent
atom_parent.update_appearance(UPDATE_ICON)
/datum/component/burning/UnregisterFromParent()
. = ..()
UnregisterSignal(parent, list(COMSIG_ATOM_UPDATE_OVERLAYS, COMSIG_ATOM_EXTINGUISH))
/datum/component/burning/Destroy(force, silent)
STOP_PROCESSING(SSfire_burning, src)
if(particle_effect)
QDEL_NULL(particle_effect)
var/atom/atom_parent = parent
if(!QDELING(atom_parent) && (atom_parent.resistance_flags & ON_FIRE))
atom_parent.resistance_flags &= ~ON_FIRE
atom_parent.update_appearance(UPDATE_ICON)
return ..()
/datum/component/burning/process(seconds_per_tick)
var/atom/atom_parent = parent
// Check if the parent somehow became fireproof
if(atom_parent.resistance_flags & FIRE_PROOF)
atom_parent.extinguish()
return
atom_parent.take_damage(10 * seconds_per_tick, BURN, FIRE, FALSE)
/// Maintains the burning overlay on the parent atom
/datum/component/burning/proc/on_update_overlays(atom/source, list/overlays)
SIGNAL_HANDLER
if(fire_overlay)
overlays += fire_overlay
/// Deletes the component when the atom gets extinguished
/datum/component/burning/proc/on_extinguish(atom/source, list/overlays)
SIGNAL_HANDLER
qdel(src)
+16
View File
@@ -140,3 +140,19 @@
/// A cut-out proc for [/atom/proc/bullet_act] so living mobs can have their own armor behavior checks without causing issues with needing their own on_hit call
/atom/proc/check_projectile_armor(def_zone, obj/projectile/impacting_projectile, is_silent)
return 0
/**
* Should be called when the atom is destroyed by fire
* This proc is terrible. I do not know why it exists.
* Please remove it at some point.
*/
/atom/proc/burn()
return
/**
* Sends COMSIG_ATOM_EXTINGUISH signal which properly removes burning component.
* Can be hooked onto for extra behavior.
*/
/atom/proc/extinguish()
SHOULD_CALL_PARENT(TRUE)
return SEND_SIGNAL(src, COMSIG_ATOM_EXTINGUISH)
@@ -14,6 +14,9 @@
gravity = list(0, 0.95)
grow = 0.05
/particles/smoke/burning
position = list(0, 0, 0)
/particles/smoke/steam
icon_state = list("steam_1" = 1, "steam_2" = 1, "steam_3" = 2)
fade = 1.5 SECONDS
-2
View File
@@ -1,5 +1,3 @@
GLOBAL_DATUM_INIT(fire_overlay, /mutable_appearance, mutable_appearance('icons/effects/fire.dmi', "fire", appearance_flags = RESET_COLOR))
/// Anything you can pick up and hold.
/obj/item
name = "item"
+3
View File
@@ -78,6 +78,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
STOP_PROCESSING(SSobj, src)
/obj/item/match/extinguish()
. = ..()
matchburnout()
/obj/item/match/dropped(mob/user)
@@ -304,6 +305,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
M.update_held_items()
/obj/item/clothing/mask/cigarette/extinguish()
. = ..()
if(!lit)
return
attack_verb_continuous = null
@@ -792,6 +794,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
update_appearance()
/obj/item/lighter/extinguish()
. = ..()
set_lit(FALSE)
/obj/item/lighter/attack_self(mob/living/user)
@@ -350,9 +350,9 @@
. = ..() //SKYRAT EDIT - MODULAR PARENT PROC
/obj/item/flashlight/flare/extinguish()
if(fuel != INFINITY && can_be_extinguished)
. = ..()
if((fuel != INFINITY) && can_be_extinguished)
turn_off()
return ..()
/obj/item/flashlight/flare/update_brightness()
..()
+4 -16
View File
@@ -96,8 +96,6 @@
///// ACID
GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/effects/effects.dmi', "acid"))
///the obj's reaction when touched by acid
/obj/acid_act(acidpwr, acid_volume)
. = ..()
@@ -123,25 +121,15 @@ GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/e
if(exposed_temperature && !(resistance_flags & FIRE_PROOF))
take_damage(clamp(0.02 * exposed_temperature, 0, 20), BURN, FIRE, 0)
if(!(resistance_flags & ON_FIRE) && (resistance_flags & FLAMMABLE) && !(resistance_flags & FIRE_PROOF))
resistance_flags |= ON_FIRE
SSfire_burning.processing[src] = src
update_appearance()
return 1
AddComponent(/datum/component/burning, custom_fire_overlay || GLOB.fire_overlay, burning_particles)
return TRUE
return ..()
///called when the obj is destroyed by fire
/obj/proc/burn()
if(resistance_flags & ON_FIRE)
SSfire_burning.processing -= src
/obj/burn()
. = ..()
deconstruct(FALSE)
///Called when the obj is no longer on fire.
/obj/proc/extinguish()
if(resistance_flags & ON_FIRE)
resistance_flags &= ~ON_FIRE
update_appearance()
SSfire_burning.processing -= src
///Called when the obj is hit by a tesla bolt.
/obj/zap_act(power, zap_flags)
if(QDELETED(src))
+3 -1
View File
@@ -35,8 +35,10 @@
/// Example: If req_one_access = list(ACCESS_ENGINE, ACCESS_CE)- then the user must have either ACCESS_ENGINE or ACCESS_CE in order to use the object.
var/list/req_one_access
/// Custom fire overlay icon
/// Custom fire overlay icon, will just use the default overlay if this is null
var/custom_fire_overlay
/// Particles this obj uses when burning, if any
var/burning_particles
var/renamedByPlayer = FALSE //set when a player uses a pen on a renamable object
+2 -1
View File
@@ -9,8 +9,9 @@
receive_ricochet_chance_mod = 0.6
pass_flags_self = PASSSTRUCTURE
blocks_emissive = EMISSIVE_BLOCK_GENERIC
var/broken = FALSE
armor_type = /datum/armor/obj_structure
burning_particles = /particles/smoke/burning
var/broken = FALSE
/datum/armor/obj_structure
fire = 50
+8 -6
View File
@@ -166,12 +166,14 @@
bonfire_burn(seconds_per_tick)
/obj/structure/bonfire/extinguish()
if(burning)
icon_state = "bonfire"
burning = FALSE
set_light(0)
QDEL_NULL(particles)
STOP_PROCESSING(SSobj, src)
. = ..()
if(!burning)
return
icon_state = "bonfire"
burning = FALSE
set_light(0)
QDEL_NULL(particles)
STOP_PROCESSING(SSobj, src)
/obj/structure/bonfire/buckle_mob(mob/living/buckled_mob, force = FALSE, check_loc = TRUE)
if(..())
+1 -1
View File
@@ -118,12 +118,12 @@
adjust_light()
/obj/structure/fireplace/extinguish()
. = ..()
if(lit)
var/fuel = burn_time_remaining()
flame_expiry_timer = 0
put_out()
adjust_fuel_timer(fuel)
. = ..()
/obj/structure/fireplace/proc/adjust_fuel_timer(amount)
if(lit)
@@ -232,7 +232,7 @@
return ..() //You don't get to do it for free
/obj/structure/blob/extinguish()
..()
. = ..()
if(overmind)
overmind.blobstrain.extinguish_reaction(src)
@@ -130,9 +130,9 @@
if(to_be_destroyed && exposed_temperature >= max_fire_temperature_sustained)
max_fire_temperature_sustained = min(exposed_temperature, max_fire_temperature_sustained + heat_capacity / 4) //Ramp up to 100% yeah?
if(to_be_destroyed && !changing_turf)
burn()
burn_turf()
/turf/proc/burn()
/turf/proc/burn_turf()
burn_tile()
var/chance_of_deletion
if (heat_capacity) //beware of division by zero
@@ -76,6 +76,7 @@
icon_state = "firepit"
/obj/structure/firepit/extinguish()
. = ..()
if(active)
active = FALSE
toggleFirepit()
-4
View File
@@ -325,10 +325,6 @@
return
. += span_warning("You cannot read it!")
/obj/item/paper/extinguish()
..()
update_appearance()
/obj/item/paper/ui_status(mob/user,/datum/ui_state/state)
// Are we on fire? Hard to read if so
if(resistance_flags & ON_FIRE)
+1
View File
@@ -231,6 +231,7 @@
update_icon()
/obj/item/burner/extinguish()
. = ..()
set_lit(FALSE)
/obj/item/burner/attack_self(mob/living/user)
@@ -143,9 +143,9 @@
start()
/obj/structure/chem_separator/extinguish()
. = ..()
if(burning)
stop()
return ..()
/// Ignite the burner to start the separation process
/obj/structure/chem_separator/proc/start()
@@ -112,6 +112,7 @@
return total_burn_power
/obj/effect/abstract/liquid_turf/extinguish()
. = ..()
if(fire_state)
set_fire_state(LIQUID_FIRE_STATE_NONE)
+2 -1
View File
@@ -640,7 +640,6 @@
#include "code\controllers\subsystem\eigenstate.dm"
#include "code\controllers\subsystem\events.dm"
#include "code\controllers\subsystem\explosions.dm"
#include "code\controllers\subsystem\fire_burning.dm"
#include "code\controllers\subsystem\fluids.dm"
#include "code\controllers\subsystem\garbage.dm"
#include "code\controllers\subsystem\icon_smooth.dm"
@@ -719,6 +718,7 @@
#include "code\controllers\subsystem\processing\clock_component.dm"
#include "code\controllers\subsystem\processing\conveyors.dm"
#include "code\controllers\subsystem\processing\fastprocess.dm"
#include "code\controllers\subsystem\processing\fire_burning.dm"
#include "code\controllers\subsystem\processing\greyscale.dm"
#include "code\controllers\subsystem\processing\instruments.dm"
#include "code\controllers\subsystem\processing\obj.dm"
@@ -944,6 +944,7 @@
#include "code\datums\components\bloodysoles.dm"
#include "code\datums\components\boomerang.dm"
#include "code\datums\components\bumpattack.dm"
#include "code\datums\components\burning.dm"
#include "code\datums\components\butchering.dm"
#include "code\datums\components\caltrop.dm"
#include "code\datums\components\chasm.dm"