mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-07-23 05:47:24 +01:00
9b5f89a717
Adds turf fires (ported from Baystation, which ported them from Shiptest), which are now used instead of ZAS fires for fuel decals and flamethrowers. They also supplement ZAS fires in especially bad atmos fires. This makes flamethrowers and related objects more suitable for AOE denial, rather than cooking the room (including yourself). They still do the latter, but less so than a gaseous fire. To make flamethrowers actually useful against them, simple mobs now take brute damage when on fire. ### Asset Licenses The following assets that **have not** been created by myself are included in this PR: | Path | Original Author | License | | --- | --- | --- | | sound/weapons/flamethrower/flamethrower1.ogg | [rye-rice](https://github.com/rye-rice) (Shiptest) | CC-BY-SA 3.0 | | sound/weapons/flamethrower/flamethrower2.ogg | [rye-rice](https://github.com/rye-rice) (Shiptest) | CC-BY-SA 3.0 | | sound/weapons/flamethrower/flamethrower3.ogg | [rye-rice](https://github.com/rye-rice) (Shiptest) | CC-BY-SA 3.0 | | sound/weapons/flamethrower/flamethrower_empty.ogg | [rye-rice](https://github.com/rye-rice) (Shiptest) | CC-BY-SA 3.0 | | icons/effects/particles/smoke.dmi | [rye-rice](https://github.com/shiptest-ss13/Shiptest/commits?author=rye-rice) (Shiptest) | CC-BY-SA 3.0 | | icons/effects/turf_fire.dmi | CM Dev (cmss13) | CC-BY-SA 3.0 |
237 lines
7.1 KiB
Plaintext
237 lines
7.1 KiB
Plaintext
#define TURF_FIRE_REQUIRED_TEMP (T0C+10)
|
|
#define TURF_FIRE_TEMP_BASE (T0C+100)
|
|
#define TURF_FIRE_POWER_LOSS_ON_LOW_TEMP 3.5
|
|
#define TURF_FIRE_TEMP_INCREMENT_PER_POWER 3
|
|
#define TURF_FIRE_POWER_LOSS_BASE 0.5
|
|
#define TURF_FIRE_VOLUME 150
|
|
#define TURF_FIRE_MAX_POWER 50
|
|
|
|
#define TURF_FIRE_ENERGY_PER_BURNED_OXY_MOL 12000
|
|
#define TURF_FIRE_BURN_RATE_BASE 0.06
|
|
#define TURF_FIRE_BURN_RATE_PER_POWER 0.02
|
|
#define TURF_FIRE_BURN_MINIMUM_OXYGEN_REQUIRED 0.5
|
|
#define TURF_FIRE_BURN_PLAY_SOUND_EFFECT_CHANCE 6
|
|
|
|
#define TURF_FIRE_STATE_SMALL 1
|
|
#define TURF_FIRE_STATE_MEDIUM 2
|
|
#define TURF_FIRE_STATE_LARGE 3
|
|
#define TURF_FIRE_STATE_MAX 4
|
|
|
|
/obj/turf_fire
|
|
icon = 'icons/effects/turf_fire.dmi'
|
|
layer = BELOW_DOOR_LAYER
|
|
anchored = TRUE
|
|
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
|
/// How much power have we got. This is treated like fuel, be it flamethrower liquid or any random thing you could come up with
|
|
var/fire_power = 20
|
|
/// If false, it does not interact with atmos.
|
|
var/interact_with_atmos = TRUE
|
|
|
|
/// If false, it will not lose power by itself. Mainly for adminbus events or mapping.
|
|
var/passive_loss = TRUE
|
|
|
|
/// Visual state of the fire. Kept track to not do too many updates.
|
|
var/current_fire_state
|
|
|
|
light_color = COLOR_ORANGE
|
|
|
|
///All the subtypes are for adminbussery and or mapping
|
|
/obj/turf_fire/magical
|
|
interact_with_atmos = FALSE
|
|
passive_loss = FALSE
|
|
color = COLOR_LIGHT_CYAN
|
|
|
|
/obj/turf_fire/small
|
|
fire_power = 10
|
|
|
|
/obj/turf_fire/small/magical
|
|
interact_with_atmos = FALSE
|
|
passive_loss = FALSE
|
|
color = COLOR_SPRING_GREEN
|
|
|
|
/obj/turf_fire/inferno
|
|
fire_power = 30
|
|
|
|
/obj/turf_fire/inferno/magical
|
|
interact_with_atmos = FALSE
|
|
passive_loss = FALSE
|
|
color = COLOR_VIOLET
|
|
|
|
/obj/turf_fire/Initialize(mapload, power, fire_color)
|
|
. = ..()
|
|
var/turf/open_turf = loc
|
|
if(open_turf.turf_fire)
|
|
return INITIALIZE_HINT_QDEL
|
|
|
|
if(fire_color && ((color != fire_color) && isnull(color))) //Take colour from proc unless base colour was already custom
|
|
color = fire_color
|
|
if(color != null)
|
|
set_color(color)
|
|
|
|
particles = new /particles/smoke/turf_fire
|
|
|
|
var/static/list/loc_connections = list(
|
|
COMSIG_ATOM_ENTERED = PROC_REF(on_entered),
|
|
)
|
|
|
|
AddElement(/datum/element/connect_loc, loc_connections)
|
|
|
|
open_turf.turf_fire = src
|
|
SSturf_fire.fires += src
|
|
if(power)
|
|
fire_power = min(TURF_FIRE_MAX_POWER, power)
|
|
UpdateFireState()
|
|
|
|
/obj/turf_fire/Destroy()
|
|
var/turf/T = loc
|
|
T.turf_fire = null
|
|
SSturf_fire.fires -= src
|
|
return ..()
|
|
|
|
//Approximates colour. It will not change value or saturation, just hue.
|
|
/obj/turf_fire/proc/set_color(_color)
|
|
light_color = _color
|
|
var/base = rgb2num(COLOR_ORANGE, COLORSPACE_HSV) //Base sprite is red fire, but maybe other fires want to be different
|
|
var/target = rgb2num(_color, COLORSPACE_HSV)
|
|
var/baseAngle = base[1]
|
|
var/targetAngle= target[1]
|
|
|
|
var/angle = (targetAngle - baseAngle)
|
|
filters = filter(type = "color", color = list(1,0,0,0,
|
|
0,1,0,0,
|
|
0,0,1,0,
|
|
0,0,0,1,
|
|
angle/360,0,0,0), space = FILTER_COLOR_HSV)
|
|
color = null //The actual colour should remain white so transform makes sense
|
|
|
|
/obj/turf_fire/proc/process_waste(seconds_per_tick)
|
|
var/total_oxidizer = 0
|
|
var/turf/T = loc
|
|
var/datum/gas_mixture/env = T.return_air()
|
|
for (var/g in env.gas)
|
|
if(gas_data.flags[g] & XGM_GAS_OXIDIZER)
|
|
total_oxidizer += env.gas[g]
|
|
if (total_oxidizer < TURF_FIRE_BURN_MINIMUM_OXYGEN_REQUIRED)
|
|
return FALSE
|
|
var/burn_rate = (TURF_FIRE_BURN_RATE_BASE * seconds_per_tick) + fire_power * TURF_FIRE_BURN_RATE_PER_POWER
|
|
if(burn_rate > total_oxidizer)
|
|
burn_rate = total_oxidizer
|
|
|
|
env.remove_by_flag(XGM_GAS_OXIDIZER, burn_rate)
|
|
|
|
env.adjust_gas(GAS_CO2, burn_rate)
|
|
|
|
var/energy_released = burn_rate * TURF_FIRE_ENERGY_PER_BURNED_OXY_MOL
|
|
env.add_thermal_energy(energy_released)
|
|
SSair.mark_for_update(T)
|
|
return TRUE
|
|
|
|
/obj/turf_fire/process(seconds_per_tick)
|
|
var/turf/simulated/T = get_turf(src)
|
|
if(!T || T.density)
|
|
qdel(src)
|
|
return
|
|
if(prob(TURF_FIRE_BURN_PLAY_SOUND_EFFECT_CHANCE))
|
|
playsound(T, SFX_FIRE, 40, TRUE)
|
|
if(T.hotspot) //If we have an active hotspot, let it do the damage instead and lets not loose power
|
|
return
|
|
if(interact_with_atmos && !process_waste(seconds_per_tick))
|
|
qdel(src)
|
|
return
|
|
if(passive_loss)
|
|
if(T.air?.temperature < TURF_FIRE_REQUIRED_TEMP)
|
|
fire_power -= TURF_FIRE_POWER_LOSS_ON_LOW_TEMP * seconds_per_tick
|
|
fire_power -= TURF_FIRE_POWER_LOSS_BASE * seconds_per_tick
|
|
if(fire_power <= 0)
|
|
qdel(src)
|
|
return
|
|
var/effective_temperature = TURF_FIRE_TEMP_BASE + (TURF_FIRE_TEMP_INCREMENT_PER_POWER * fire_power)
|
|
T.hotspot_expose(effective_temperature)
|
|
//Nearby turfs may also trigger a fire (will only start fires if there's fuel, currently)
|
|
//Guaranteed fire spread in the last tick
|
|
if(prob(50 + fire_power) || fire_power == 1)
|
|
for(var/direction in GLOB.cardinals)
|
|
var/turf/simulated/other_tile = get_step(T, direction)
|
|
|
|
// Exit the loop early if the checked tile is not a valid direction for the fire to spread.
|
|
if(!istype(other_tile) || (T.open_directions & direction) || other_tile.hotspot || other_tile.turf_fire) //Grab all valid bordering tiles
|
|
continue
|
|
|
|
other_tile.hotspot_expose(effective_temperature)
|
|
|
|
for(var/atom/movable/burning_atom as anything in T)
|
|
burning_atom.fire_act(exposed_temperature = effective_temperature, exposed_volume = TURF_FIRE_VOLUME)
|
|
|
|
UpdateFireState()
|
|
if(!interact_with_atmos || prob(fire_power) || !istype(T, /turf/simulated/floor))
|
|
return
|
|
|
|
var/turf/simulated/floor/F = T
|
|
F.burn_tile(effective_temperature)
|
|
|
|
/obj/turf_fire/proc/on_entered(datum/source, atom/movable/arrived, atom/old_loc, list/atom/old_locs)
|
|
SIGNAL_HANDLER
|
|
|
|
if(!istype(arrived))
|
|
return
|
|
|
|
var/turf/T = loc
|
|
if(T.hotspot) //If we have an active hotspot, let it do the damage instead
|
|
return
|
|
|
|
arrived.fire_act(exposed_temperature = TURF_FIRE_TEMP_BASE + (TURF_FIRE_TEMP_INCREMENT_PER_POWER*fire_power), exposed_volume = TURF_FIRE_VOLUME)
|
|
|
|
return
|
|
|
|
/obj/turf_fire/proc/AddPower(power)
|
|
fire_power = min(TURF_FIRE_MAX_POWER, fire_power + power)
|
|
UpdateFireState()
|
|
|
|
/obj/turf_fire/proc/UpdateFireState()
|
|
var/new_state
|
|
switch(fire_power)
|
|
if(0 to 10)
|
|
new_state = TURF_FIRE_STATE_SMALL
|
|
if(11 to 24)
|
|
new_state = TURF_FIRE_STATE_MEDIUM
|
|
if(25 to 39)
|
|
new_state = TURF_FIRE_STATE_LARGE
|
|
if(40 to INFINITY)
|
|
new_state = TURF_FIRE_STATE_MAX
|
|
|
|
if(new_state == current_fire_state)
|
|
return
|
|
current_fire_state = new_state
|
|
|
|
switch(current_fire_state)
|
|
if(TURF_FIRE_STATE_SMALL)
|
|
icon_state = "small"
|
|
set_light(1.5, 0.5)
|
|
if(TURF_FIRE_STATE_MEDIUM)
|
|
icon_state = "medium"
|
|
set_light(2, 0.5)
|
|
if(TURF_FIRE_STATE_LARGE)
|
|
icon_state = "big"
|
|
set_light(2, 0.6)
|
|
if(TURF_FIRE_STATE_MAX)
|
|
icon_state = "max"
|
|
set_light(3, 0.7)
|
|
|
|
#undef TURF_FIRE_REQUIRED_TEMP
|
|
#undef TURF_FIRE_TEMP_BASE
|
|
#undef TURF_FIRE_POWER_LOSS_ON_LOW_TEMP
|
|
#undef TURF_FIRE_TEMP_INCREMENT_PER_POWER
|
|
#undef TURF_FIRE_VOLUME
|
|
#undef TURF_FIRE_MAX_POWER
|
|
|
|
#undef TURF_FIRE_ENERGY_PER_BURNED_OXY_MOL
|
|
#undef TURF_FIRE_BURN_RATE_BASE
|
|
#undef TURF_FIRE_BURN_RATE_PER_POWER
|
|
#undef TURF_FIRE_BURN_MINIMUM_OXYGEN_REQUIRED
|
|
#undef TURF_FIRE_BURN_PLAY_SOUND_EFFECT_CHANCE
|
|
|
|
#undef TURF_FIRE_STATE_SMALL
|
|
#undef TURF_FIRE_STATE_MEDIUM
|
|
#undef TURF_FIRE_STATE_LARGE
|
|
#undef TURF_FIRE_STATE_MAX
|