Files
kyunkyunkyun b0463d3c83 Convert most spans to defines (#31080)
* spanish?

* aaaagain

* keep maptext

* Update robot_items.dm

* Update span_defines.dm

* compiles

* Update silicon_mob.dm

* compile
2025-12-13 23:55:48 +00:00

265 lines
7.2 KiB
Plaintext

/atom/proc/temperature_expose(exposed_temperature, exposed_volume)
if(!isnull(reagents))
reagents.temperature_reagents(exposed_temperature)
/turf/simulated/temperature_expose(exposed_temperature, exposed_volume)
if(reagents)
reagents.temperature_reagents(exposed_temperature, 10, 300)
/turf/proc/hotspot_expose(exposed_temperature, exposed_volume)
return
/turf/simulated/hotspot_expose(exposed_temperature, exposed_volume)
var/datum/milla_safe/make_hotspot/milla = new()
milla.invoke_async(src, exposed_temperature, exposed_volume)
/datum/milla_safe/make_hotspot
/datum/milla_safe/make_hotspot/on_run(turf/simulated/tile, exposed_temperature, exposed_volume)
create_hotspot(tile, exposed_temperature, exposed_volume)
//This is the icon for fire on turfs.
/obj/effect/hotspot
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
icon = 'icons/goonstation/effects/fire.dmi'
icon_state = "1"
layer = MASSIVE_OBJ_LAYER
alpha = 250
blend_mode = BLEND_ADD
light_range = 2
var/volume = 125
var/temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST
/// The last tick this hotspot should be alive for.
var/death_timer = 0
/// How much fuel did we burn this tick?
var/fuel_burnt = 0
/// Which tick did we last load data at?
var/data_tick = 0
/// Which update tick are we on?
var/update_tick = 0
/// How often do we update?
var/update_interval = 1
/obj/effect/hotspot/New()
..()
dir = pick(GLOB.cardinal)
/obj/effect/hotspot/proc/update_visuals(fuel_burnt)
color = heat2color(temperature)
var/list/rgb = rgb2num(color)
if(isnull(light_color))
light_color = color
set_light(l_color = color)
else
var/list/light_rgb = rgb2num(light_color)
var/r_delta = abs(rgb[1] - light_rgb[1])
var/g_delta = abs(rgb[2] - light_rgb[2])
var/b_delta = abs(rgb[3] - light_rgb[3])
if(r_delta > 10 || g_delta > 10 || b_delta)
set_light(l_color = color)
if(fuel_burnt > 1)
icon_state = "3"
else if(fuel_burnt > 0.1)
icon_state = "2"
else
icon_state = "1"
/obj/effect/hotspot/Initialize(mapload)
. = ..()
var/static/list/loc_connections = list(
COMSIG_ATOM_ENTERED = PROC_REF(on_atom_entered),
)
AddElement(/datum/element/connect_loc, loc_connections)
// Garbage collect itself by nulling reference to it
/obj/effect/hotspot/Destroy()
set_light(0)
var/turf/simulated/T = loc
if(istype(T) && T.active_hotspot == src)
T.active_hotspot = null
return ..()
/obj/effect/hotspot/proc/recolor()
color = heat2color(temperature)
set_light(l_color = color)
// TODO: Vestigal, kept temporarily to avoid a merge conflict.
/obj/effect/hotspot/proc/DestroyTurf()
if(issimulatedturf(loc))
var/turf/simulated/T = loc
if(T.to_be_destroyed && !T.changing_turf)
var/chance_of_deletion
if(T.heat_capacity) //beware of division by zero
chance_of_deletion = T.max_fire_temperature_sustained / T.heat_capacity * 8 //there is no problem with prob(23456), min() was redundant --rastaf0
else
chance_of_deletion = 100
if(prob(chance_of_deletion))
T.ChangeTurf(T.baseturf)
else
T.to_be_destroyed = 0
T.max_fire_temperature_sustained = 0
/obj/effect/hotspot/proc/on_atom_entered(datum/source, mob/living/entered)
SIGNAL_HANDLER // COMSIG_ATOM_ENTERED
if(istype(entered))
entered.fire_act()
/obj/effect/hotspot/singularity_pull()
return
/// Largely for the fireflash procs below
/obj/effect/hotspot/fake
var/burn_time = 3 SECONDS
/obj/effect/hotspot/fake/New()
..()
if(burn_time)
QDEL_IN(src, burn_time)
/proc/fireflash(atom/center, radius, temp)
if(!temp)
temp = rand(2800, 3200)
for(var/turf/T in view(radius, get_turf(center)))
if(isspaceturf(T))
continue
if(locate(/obj/effect/hotspot) in T)
continue
if(!can_line(get_turf(center), T, radius + 1))
continue
var/obj/effect/hotspot/fake/H = new(T)
H.temperature = temp
H.volume = 400
H.recolor()
T.hotspot_expose(H.temperature, H.volume)
for(var/atom/A in T)
if(isliving(A))
continue
if(A != H)
A.fire_act(null, H.temperature, H.volume)
if(isfloorturf(T))
var/turf/simulated/floor/F = T
F.burn_tile()
for(var/mob/living/L in T)
L.adjust_fire_stacks(3)
L.IgniteMob()
if(ishuman(L))
var/mob/living/carbon/human/M = L
var/heatBlockPercent = 1 - M.get_heat_protection(temp)
M.bodytemperature += (temp - M.bodytemperature) * heatBlockPercent / 3
else
L.bodytemperature = (2 * L.bodytemperature + temp) / 3
/proc/fireflash_s(atom/center, radius, temp, falloff)
if(temp < T0C + 60)
return list()
var/list/open = list()
var/list/affected = list()
var/list/closed = list()
var/turf/Ce = get_turf(center)
var/max_dist = radius
if(falloff)
max_dist = min((temp - (T0C + 60)) / falloff, radius)
open[Ce] = 0
while(length(open))
var/turf/T = open[1]
var/dist = open[T]
open -= T
closed[T] = TRUE
if(isspaceturf(T))
continue
if(dist > max_dist)
continue
if(!ff_cansee(Ce, T))
continue
var/obj/effect/hotspot/existing_hotspot = locate(/obj/effect/hotspot) in T
var/prev_temp = 0
var/need_expose = 0
var/expose_temp = 0
if(!existing_hotspot)
var/obj/effect/hotspot/fake/H = new(T)
need_expose = TRUE
H.temperature = temp - dist * falloff
expose_temp = H.temperature
H.volume = 400
H.recolor()
existing_hotspot = H
else if(existing_hotspot.temperature < temp - dist * falloff)
expose_temp = (temp - dist * falloff) - existing_hotspot.temperature
prev_temp = existing_hotspot.temperature
if(expose_temp > prev_temp * 3)
need_expose = TRUE
existing_hotspot.temperature = temp - dist * falloff
existing_hotspot.recolor()
affected[T] = existing_hotspot.temperature
if(need_expose && expose_temp)
T.hotspot_expose(expose_temp, existing_hotspot.volume)
for(var/atom/A in T)
if(isliving(A))
continue
if(A != existing_hotspot)
A.fire_act(null, expose_temp, existing_hotspot.volume)
if(isfloorturf(T))
var/turf/simulated/floor/F = T
F.burn_tile()
for(var/mob/living/L in T)
L.adjust_fire_stacks(3)
L.IgniteMob()
if(ishuman(L))
var/mob/living/carbon/human/M = L
var/heatBlockPercent = 1 - M.get_heat_protection(temp)
M.bodytemperature += (temp - M.bodytemperature) * heatBlockPercent / 3
else
L.bodytemperature = (2 * L.bodytemperature + temp) / 3
if(T.density)
continue
if(dist == max_dist)
continue
for(var/direction in GLOB.cardinal)
var/turf/link = get_step(T, direction)
if(!link)
continue
// Check if it wasn't already visited and if you can get to that turf
if(!closed[link] && T.CanAtmosPass(direction) && link.CanAtmosPass(turn(direction, 180)))
var/dx = link.x - Ce.x
var/dy = link.y - Ce.y
var/target_dist = max((dist + 1 + sqrt(dx * dx + dy * dy)) / 2, dist)
if(link in open)
if(open[link] > target_dist)
open[link] = target_dist
else
open[link] = target_dist
return affected
/proc/fireflash_sm(atom/center, radius, temp, falloff, capped = TRUE, bypass_rng = FALSE)
var/list/affected = fireflash_s(center, radius, temp, falloff)
for(var/turf/simulated/T in affected)
var/mytemp = affected[T]
var/melt = 1643.15 // default steel melting point
var/divisor = melt
if(mytemp >= melt * 2)
var/chance = mytemp / divisor
if(capped)
chance = min(chance, 30)
if(prob(chance) || bypass_rng)
T.visible_message(SPAN_WARNING("[T] melts!"))
T.burn_down()
return affected