mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-13 08:03:43 +01:00
b0463d3c83
* spanish? * aaaagain * keep maptext * Update robot_items.dm * Update span_defines.dm * compiles * Update silicon_mob.dm * compile
265 lines
7.2 KiB
Plaintext
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
|