diff --git a/code/controllers/subsystem/SSair.dm b/code/controllers/subsystem/SSair.dm
index 435c0766588d..06057844d02f 100644
--- a/code/controllers/subsystem/SSair.dm
+++ b/code/controllers/subsystem/SSair.dm
@@ -417,40 +417,54 @@ SUBSYSTEM_DEF(air)
continue
var/reasons = currentrun[offset + MILLA_INDEX_INTERESTING_REASONS]
- var/x_flow = currentrun[offset + MILLA_INDEX_AIRFLOW_X]
- var/y_flow = currentrun[offset + MILLA_INDEX_AIRFLOW_Y]
- var/milla_tile = currentrun.Copy(offset + 1, offset + 1 + MILLA_TILE_SIZE + 1)
- currentrun.len -= MILLA_INTERESTING_TILE_SIZE
// Bind the MILLA tile we got, if needed.
- if(isnull(T.bound_air))
- bind_turf(T, milla_tile)
- else if(T.bound_air.lastread < milla_tick)
- T.bound_air.copy_from_milla(milla_tile)
- T.bound_air.lastread = milla_tick
- T.bound_air.readonly = null
- T.bound_air.dirty = FALSE
- T.bound_air.synchronized = FALSE
-
if(reasons & MILLA_INTERESTING_REASON_DISPLAY)
+ var/milla_tile = currentrun.Copy(offset + 1, offset + 1 + MILLA_TILE_SIZE + 1)
+ if(isnull(T.bound_air))
+ bind_turf(T, milla_tile)
+ else if(T.bound_air.lastread < milla_tick)
+ T.bound_air.copy_from_milla(milla_tile)
+ T.bound_air.lastread = milla_tick
+ T.bound_air.readonly = null
+ T.bound_air.dirty = FALSE
+ T.bound_air.synchronized = FALSE
+
var/turf/simulated/S = T
if(istype(S))
S.update_visuals()
if(reasons & MILLA_INTERESTING_REASON_HOT)
+ var/temperature = currentrun[offset + MILLA_INDEX_TEMPERATURE]
+ var/fuel_burnt = currentrun[offset + MILLA_INDEX_FUEL_BURNT]
+ var/hotspot_temperature = currentrun[offset + MILLA_INDEX_HOTSPOT_TEMPERATURE]
+ var/hotspot_volume = currentrun[offset + MILLA_INDEX_HOTSPOT_VOLUME]
+
var/turf/simulated/S = T
if(istype(S))
if(isnull(S.active_hotspot))
// Wasn't an active hotspot before, add it.
hotspots += S
-
- var/datum/gas_mixture/air = T.get_readonly_air()
- T.temperature_expose(air.temperature())
+ else
+ S.active_hotspot.temperature = temperature
+ S.active_hotspot.fuel_burnt = fuel_burnt
+ S.active_hotspot.data_tick = milla_tick
+ if(hotspot_volume > 0)
+ S.active_hotspot.temperature = hotspot_temperature
+ S.active_hotspot.volume = hotspot_volume * CELL_VOLUME
+ else
+ S.active_hotspot.temperature = temperature
+ S.active_hotspot.volume = CELL_VOLUME
+
+ T.temperature_expose(temperature)
for(var/atom/movable/item in T)
- item.temperature_expose(air, air.temperature(), CELL_VOLUME)
- T.temperature_expose(air, air.temperature(), CELL_VOLUME)
+ if(item.cares_about_temperature || !isnull(item.reagents))
+ item.temperature_expose(temperature, CELL_VOLUME)
if(reasons & MILLA_INTERESTING_REASON_WIND)
+ var/x_flow = currentrun[offset + MILLA_INDEX_AIRFLOW_X]
+ var/y_flow = currentrun[offset + MILLA_INDEX_AIRFLOW_Y]
+
var/turf/simulated/S = T
if(istype(S))
if(isnull(S.wind_tick))
@@ -461,6 +475,7 @@ SUBSYSTEM_DEF(air)
S.wind_y = y_flow
T.high_pressure_movements(x_flow, y_flow)
+ currentrun.len -= MILLA_INTERESTING_TILE_SIZE
if(MC_TICK_CHECK)
return
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index 78409ed8dfaa..e8f518533c04 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -134,6 +134,9 @@
/// Whether this atom is using the new attack chain.
var/new_attack_chain = FALSE
+ /// Do we care about temperature at all? Saves us a ton of proc calls during big fires.
+ var/cares_about_temperature = FALSE
+
/atom/New(loc, ...)
SHOULD_CALL_PARENT(TRUE)
if(GLOB.use_preloader && (src.type == GLOB._preloader.target_path))//in case the instanciated atom is creating other atoms in New()
diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm
index ef09ebfda5b6..32fd6730f8de 100644
--- a/code/game/machinery/doors/airlock.dm
+++ b/code/game/machinery/doors/airlock.dm
@@ -63,6 +63,7 @@ GLOBAL_LIST_EMPTY(airlock_emissive_underlays)
flags_2 = RAD_PROTECT_CONTENTS_2 | RAD_NO_CONTAMINATE_2
rad_insulation = RAD_MEDIUM_INSULATION
smoothing_groups = list(SMOOTH_GROUP_AIRLOCK)
+ cares_about_temperature = TRUE
var/security_level = 0 //How much are wires secured
var/aiControlDisabled = AICONTROLDISABLED_OFF
var/hackProof = FALSE // if TRUE, this door can't be hacked by the AI
@@ -1680,7 +1681,7 @@ GLOBAL_LIST_EMPTY(airlock_emissive_underlays)
else
return PROCESS_KILL
-/obj/machinery/door/airlock/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
+/obj/machinery/door/airlock/temperature_expose(exposed_temperature, exposed_volume)
..()
if(heat_proof)
return
diff --git a/code/game/machinery/doors/airlock_types.dm b/code/game/machinery/doors/airlock_types.dm
index 96632e6ce7dc..173b8c14553b 100644
--- a/code/game/machinery/doors/airlock_types.dm
+++ b/code/game/machinery/doors/airlock_types.dm
@@ -182,7 +182,7 @@
assemblytype = /obj/structure/door_assembly/door_assembly_plasma
paintable = FALSE
-/obj/machinery/door/airlock/plasma/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
+/obj/machinery/door/airlock/plasma/temperature_expose(exposed_temperature, exposed_volume)
..()
if(exposed_temperature > 300)
PlasmaBurn(exposed_temperature)
diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm
index a09a871ad4ab..d7205cd99256 100644
--- a/code/game/machinery/doors/firedoor.dm
+++ b/code/game/machinery/doors/firedoor.dm
@@ -24,6 +24,7 @@
blocks_emissive = EMISSIVE_BLOCK_GENERIC
armor = list(MELEE = 30, BULLET = 30, LASER = 20, ENERGY = 20, BOMB = 10, RAD = 100, FIRE = 95, ACID = 70)
superconductivity = ZERO_HEAT_TRANSFER_COEFFICIENT
+ cares_about_temperature = TRUE
/// How long does opening by hand take, in deciseconds.
var/manual_open_time = 5 SECONDS
var/can_crush = TRUE
@@ -350,7 +351,7 @@
return FALSE
return ..()
-/obj/machinery/door/firedoor/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
+/obj/machinery/door/firedoor/temperature_expose(exposed_temperature, exposed_volume)
..()
if(exposed_temperature > (T0C + heat_resistance))
take_damage(round(exposed_volume / 100), BURN, 0, 0)
@@ -382,6 +383,7 @@
icon_state = "frame1"
anchored = FALSE
density = TRUE
+ cares_about_temperature = TRUE
var/constructionStep = CONSTRUCTION_NOCIRCUIT
var/reinforced = 0
var/heat_resistance = 1000
@@ -546,7 +548,7 @@
new /obj/machinery/door/firedoor(get_turf(src))
qdel(src)
-/obj/structure/firelock_frame/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
+/obj/structure/firelock_frame/temperature_expose(exposed_temperature, exposed_volume)
..()
if(exposed_temperature > (T0C + heat_resistance))
take_damage(round(exposed_volume / 100), BURN, 0, 0)
diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm
index d1e4dc769203..c22c7ded82f3 100644
--- a/code/game/machinery/doors/windowdoor.dm
+++ b/code/game/machinery/doors/windowdoor.dm
@@ -13,6 +13,7 @@
armor = list(MELEE = 20, BULLET = 50, LASER = 50, ENERGY = 50, BOMB = 10, RAD = 100, FIRE = 70, ACID = 100)
glass = TRUE // Used by polarized helpers. Windoors are always glass.
superconductivity = WINDOW_HEAT_TRANSFER_COEFFICIENT
+ cares_about_temperature = TRUE
var/obj/item/airlock_electronics/electronics
var/base_state = "left"
var/reinf = FALSE
@@ -268,7 +269,7 @@
/obj/machinery/door/window/narsie_act()
color = NARSIE_WINDOW_COLOUR
-/obj/machinery/door/window/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
+/obj/machinery/door/window/temperature_expose(exposed_temperature, exposed_volume)
..()
if(exposed_temperature > T0C + (reinf ? 1600 : 800))
take_damage(round(exposed_volume / 200), BURN, 0, 0)
diff --git a/code/game/machinery/firealarm.dm b/code/game/machinery/firealarm.dm
index 32d9950aa5a6..dcbd732a6b63 100644
--- a/code/game/machinery/firealarm.dm
+++ b/code/game/machinery/firealarm.dm
@@ -24,6 +24,7 @@ FIRE ALARM
active_power_consumption = 6
power_channel = PW_CHANNEL_ENVIRONMENT
resistance_flags = FIRE_PROOF
+ cares_about_temperature = TRUE
light_power = LIGHTING_MINIMUM_POWER
light_range = 7
@@ -107,7 +108,7 @@ FIRE ALARM
playsound(loc, 'sound/effects/sparks4.ogg', 50, TRUE)
return TRUE
-/obj/machinery/firealarm/temperature_expose(datum/gas_mixture/air, temperature, volume)
+/obj/machinery/firealarm/temperature_expose(temperature, volume)
..()
if(!emagged && detecting && temperature > T0C + 200)
alarm() // added check of detector status here
diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm
index b8d369ca0a8b..e84aa61d6aaa 100644
--- a/code/game/mecha/mecha.dm
+++ b/code/game/mecha/mecha.dm
@@ -15,6 +15,7 @@
max_integrity = 300 //max_integrity is base health
armor = list(melee = 20, bullet = 10, laser = 0, energy = 0, bomb = 0, rad = 0, fire = 100, acid = 75)
bubble_icon = "machine"
+ cares_about_temperature = TRUE
var/list/facing_modifiers = list(MECHA_FRONT_ARMOUR = 1.5, MECHA_SIDE_ARMOUR = 1, MECHA_BACK_ARMOUR = 0.5)
var/initial_icon = null //Mech type for resetting icon. Only used for reskinning kits (see custom items)
var/can_move = 0 // time of next allowed movement
@@ -699,7 +700,7 @@
log_message("EMP detected", 1)
check_for_internal_damage(list(MECHA_INT_FIRE, MECHA_INT_TEMP_CONTROL, MECHA_INT_CONTROL_LOST, MECHA_INT_SHORT_CIRCUIT), 1)
-/obj/mecha/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
+/obj/mecha/temperature_expose(exposed_temperature, exposed_volume)
..()
if(exposed_temperature > max_temperature)
log_message("Exposed to dangerous temperature.", 1)
diff --git a/code/game/objects/effects/effect_system/effects_foam.dm b/code/game/objects/effects/effect_system/effects_foam.dm
index cbe122c4d742..19f9237f9230 100644
--- a/code/game/objects/effects/effect_system/effects_foam.dm
+++ b/code/game/objects/effects/effect_system/effects_foam.dm
@@ -10,6 +10,7 @@
gender = PLURAL
layer = OBJ_LAYER + 0.9
animate_movement = NO_STEPS
+ cares_about_temperature = TRUE
/// How many times this one bit of foam can spread around itself
var/spread_amount = 3
/// How long it takes this to initially start spreading after being dispersed
@@ -121,7 +122,7 @@
/obj/effect/particle_effect/foam/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume, global_overlay = TRUE) //Don't heat the reagents inside
return
-/obj/effect/particle_effect/foam/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) // overriden to prevent weird behaviors with heating reagents inside
+/obj/effect/particle_effect/foam/temperature_expose(exposed_temperature, exposed_volume) // overriden to prevent weird behaviors with heating reagents inside
if(prob(max(0, exposed_temperature - 475)))
flick("[icon_state]-disolve", src)
QDEL_IN(src, 0.5 SECONDS)
@@ -155,7 +156,7 @@
M.metal = metal_kind
M.update_state()
-/obj/effect/particle_effect/foam/metal/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
+/obj/effect/particle_effect/foam/metal/temperature_expose(exposed_temperature, exposed_volume)
return
/obj/effect/particle_effect/foam/metal/on_atom_entered(datum/source, atom/movable/entered)
diff --git a/code/game/objects/effects/glowshroom.dm b/code/game/objects/effects/glowshroom.dm
index 4d540b743b44..5fe354697544 100644
--- a/code/game/objects/effects/glowshroom.dm
+++ b/code/game/objects/effects/glowshroom.dm
@@ -11,6 +11,7 @@
base_icon_state = "glowshroom" //replaced in New
layer = ABOVE_NORMAL_TURF_LAYER
max_integrity = 30
+ cares_about_temperature = TRUE
var/floor = 0
var/obj/item/seeds/myseed = /obj/item/seeds/glowshroom
@@ -107,7 +108,7 @@
if(damage_type == BURN && damage_amount)
playsound(src.loc, 'sound/items/welder.ogg', 100, TRUE)
-/obj/structure/glowshroom/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
+/obj/structure/glowshroom/temperature_expose(exposed_temperature, exposed_volume)
..()
if(exposed_temperature > 300)
take_damage(5, BURN, 0, 0)
diff --git a/code/game/objects/effects/spiders.dm b/code/game/objects/effects/spiders.dm
index 9a31bef1b3e5..8a08f0ae9b3b 100644
--- a/code/game/objects/effects/spiders.dm
+++ b/code/game/objects/effects/spiders.dm
@@ -6,6 +6,7 @@
anchored = TRUE
density = FALSE
max_integrity = 15
+ cares_about_temperature = TRUE
var/mob/living/carbon/human/master_commander = null
/obj/structure/spider/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
@@ -26,7 +27,7 @@
master_commander = null
return ..()
-/obj/structure/spider/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
+/obj/structure/spider/temperature_expose(exposed_temperature, exposed_volume)
..()
if(exposed_temperature > 300)
take_damage(5, BURN, 0, 0)
diff --git a/code/game/objects/items/latexballoon.dm b/code/game/objects/items/latexballoon.dm
index 0501b49aa7b8..19a1b3fd1f51 100644
--- a/code/game/objects/items/latexballoon.dm
+++ b/code/game/objects/items/latexballoon.dm
@@ -8,6 +8,7 @@
w_class = WEIGHT_CLASS_TINY
throw_speed = 1
throw_range = 7
+ cares_about_temperature = TRUE
var/state
var/datum/gas_mixture/air_contents = null
@@ -52,7 +53,7 @@
burst()
return ..()
-/obj/item/latexballon/temperature_expose(datum/gas_mixture/air, temperature, volume)
+/obj/item/latexballon/temperature_expose(temperature, volume)
..()
if(temperature > T0C+100)
burst()
diff --git a/code/game/objects/items/stacks/sheets/leather.dm b/code/game/objects/items/stacks/sheets/leather.dm
index 6423b9edd94d..482adb9c3f4d 100644
--- a/code/game/objects/items/stacks/sheets/leather.dm
+++ b/code/game/objects/items/stacks/sheets/leather.dm
@@ -125,6 +125,7 @@ GLOBAL_LIST_INIT(xeno_recipes, list (
icon_state = "sheet-wetleather"
item_state = "sheet-leather"
origin_tech = ""
+ cares_about_temperature = TRUE
var/wetness = 30 //Reduced when exposed to high temperautres
var/drying_threshold_temperature = 500 //Kelvin to start drying
@@ -327,7 +328,7 @@ GLOBAL_LIST_INIT(sinew_recipes, list (
qdel(src)
//Step three - drying
-/obj/item/stack/sheet/wetleather/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
+/obj/item/stack/sheet/wetleather/temperature_expose(exposed_temperature, exposed_volume)
..()
if(exposed_temperature >= drying_threshold_temperature)
wetness--
diff --git a/code/game/objects/structures/aliens.dm b/code/game/objects/structures/aliens.dm
index 1a80c3bac7c2..e53c434b8b8e 100644
--- a/code/game/objects/structures/aliens.dm
+++ b/code/game/objects/structures/aliens.dm
@@ -14,6 +14,7 @@
/obj/structure/alien
icon = 'icons/mob/alien.dmi'
max_integrity = 100
+ cares_about_temperature = TRUE
/obj/structure/alien/run_obj_armor(damage_amount, damage_type, damage_flag = 0, attack_dir)
if(damage_flag == MELEE)
@@ -355,7 +356,7 @@
new /obj/structure/alien/weeds(T, linked_node)
check_surroundings()
-/obj/structure/alien/weeds/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
+/obj/structure/alien/weeds/temperature_expose(exposed_temperature, exposed_volume)
..()
if(exposed_temperature > 300)
take_damage(5, BURN, 0, 0)
@@ -545,7 +546,7 @@
if(status != BURST)
burst(kill = TRUE)
-/obj/structure/alien/egg/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
+/obj/structure/alien/egg/temperature_expose(exposed_temperature, exposed_volume)
..()
if(exposed_temperature > 500)
take_damage(5, BURN, 0, 0)
diff --git a/code/game/objects/structures/door_assembly.dm b/code/game/objects/structures/door_assembly.dm
index 4566e9bbfc26..7c3205e754ec 100644
--- a/code/game/objects/structures/door_assembly.dm
+++ b/code/game/objects/structures/door_assembly.dm
@@ -5,6 +5,7 @@
anchored = FALSE
density = TRUE
max_integrity = 200
+ cares_about_temperature = TRUE
var/overlays_file = 'icons/obj/doors/airlocks/station/overlays.dmi'
var/state = AIRLOCK_ASSEMBLY_NEEDS_WIRES
/// String value. Used in user chat messages
@@ -309,7 +310,7 @@
new /obj/item/shard(T)
qdel(src)
-/obj/structure/door_assembly/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
+/obj/structure/door_assembly/temperature_expose(exposed_temperature, exposed_volume)
..()
if(exposed_temperature > (T0C + heat_resistance))
take_damage(round(exposed_volume / 100), BURN, 0, 0)
diff --git a/code/game/objects/structures/false_walls.dm b/code/game/objects/structures/false_walls.dm
index a056b9930043..a567fc1b7ec9 100644
--- a/code/game/objects/structures/false_walls.dm
+++ b/code/game/objects/structures/false_walls.dm
@@ -287,6 +287,7 @@
smoothing_flags = SMOOTH_BITMASK
smoothing_groups = list(SMOOTH_GROUP_WALLS, SMOOTH_GROUP_PLASMA_WALLS)
canSmoothWith = list(SMOOTH_GROUP_PLASMA_WALLS)
+ cares_about_temperature = TRUE
/obj/structure/falsewall/plasma/attackby__legacy__attackchain(obj/item/W, mob/user, params)
if(W.get_heat() > 300)
diff --git a/code/game/objects/structures/girders.dm b/code/game/objects/structures/girders.dm
index 746c4b9b7263..23148e306bdf 100644
--- a/code/game/objects/structures/girders.dm
+++ b/code/game/objects/structures/girders.dm
@@ -7,6 +7,7 @@
layer = BELOW_OBJ_LAYER
flags_2 = RAD_PROTECT_CONTENTS_2 | RAD_NO_CONTAMINATE_2
rad_insulation = RAD_VERY_LIGHT_INSULATION
+ cares_about_temperature = TRUE
var/state = GIRDER_NORMAL
var/girderpasschance = 20 // percentage chance that a projectile passes through the girder.
max_integrity = 200
@@ -40,7 +41,7 @@
for(var/i=0;i < metalAmount;i++)
new metal_type(get_turf(src))
-/obj/structure/girder/temperature_expose(datum/gas_mixture/air, exposed_temperature)
+/obj/structure/girder/temperature_expose(exposed_temperature)
..()
var/temp_check = exposed_temperature
if(temp_check >= GIRDER_MELTING_TEMP)
diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm
index c4a1b48e218a..ded748b87223 100644
--- a/code/game/objects/structures/grille.dm
+++ b/code/game/objects/structures/grille.dm
@@ -13,6 +13,7 @@
armor = list(MELEE = 50, BULLET = 70, LASER = 70, ENERGY = 100, BOMB = 10, RAD = 100, FIRE = 0, ACID = 0)
max_integrity = 50
integrity_failure = 20
+ cares_about_temperature = TRUE
var/rods_type = /obj/item/stack/rods
var/rods_amount = 2
var/rods_broken = 1
@@ -228,7 +229,7 @@
return FALSE
return FALSE
-/obj/structure/grille/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
+/obj/structure/grille/temperature_expose(exposed_temperature, exposed_volume)
..()
if(!broken)
if(exposed_temperature > T0C + 1500)
diff --git a/code/game/objects/structures/mineral_doors.dm b/code/game/objects/structures/mineral_doors.dm
index e12f73b712df..8d2912757851 100644
--- a/code/game/objects/structures/mineral_doors.dm
+++ b/code/game/objects/structures/mineral_doors.dm
@@ -180,6 +180,7 @@
name = "plasma door"
icon_state = "plasma"
sheetType = /obj/item/stack/sheet/mineral/plasma
+ cares_about_temperature = TRUE
/obj/structure/mineral_door/transparent/plasma/attackby__legacy__attackchain(obj/item/W, mob/user)
if(W.get_heat())
@@ -190,7 +191,7 @@
else
return ..()
-/obj/structure/mineral_door/transparent/plasma/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
+/obj/structure/mineral_door/transparent/plasma/temperature_expose(exposed_temperature, exposed_volume)
..()
if(exposed_temperature > 300)
TemperatureAct(exposed_temperature)
diff --git a/code/game/objects/structures/statues.dm b/code/game/objects/structures/statues.dm
index 8eadb12fe09a..5ca44a56d70b 100644
--- a/code/game/objects/structures/statues.dm
+++ b/code/game/objects/structures/statues.dm
@@ -95,6 +95,7 @@
max_integrity = 200
material_drop_type = /obj/item/stack/sheet/mineral/plasma
desc = "This statue is suitably made from plasma."
+ cares_about_temperature = TRUE
/obj/structure/statue/plasma/scientist
name = "statue of a scientist"
@@ -104,7 +105,7 @@
name = "statue of a xenomorph"
icon_state = "xeno"
-/obj/structure/statue/plasma/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
+/obj/structure/statue/plasma/temperature_expose(exposed_temperature, exposed_volume)
..()
if(exposed_temperature > 300)
PlasmaBurn(exposed_temperature)
diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm
index 4f1862204ec4..da739679edd1 100644
--- a/code/game/objects/structures/window.dm
+++ b/code/game/objects/structures/window.dm
@@ -15,6 +15,7 @@
resistance_flags = ACID_PROOF
armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, RAD = 0, FIRE = 80, ACID = 100)
rad_insulation = RAD_VERY_LIGHT_INSULATION
+ cares_about_temperature = TRUE
var/ini_dir = null
var/state = WINDOW_OUT_OF_FRAME
var/reinf = FALSE
@@ -474,7 +475,7 @@
..()
update_icon(UPDATE_OVERLAYS)
-/obj/structure/window/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
+/obj/structure/window/temperature_expose(exposed_temperature, exposed_volume)
..()
if(exposed_temperature > (T0C + heat_resistance))
take_damage(round(exposed_volume / 100), BURN, 0, 0)
diff --git a/code/game/turfs/simulated/floor.dm b/code/game/turfs/simulated/floor.dm
index a8165ed08823..4b9b76c9118f 100644
--- a/code/game/turfs/simulated/floor.dm
+++ b/code/game/turfs/simulated/floor.dm
@@ -118,7 +118,7 @@ GLOBAL_LIST_INIT(icons_to_ignore_at_floor_init, list("damaged1","damaged2","dama
burnt = TRUE
update_icon()
-/turf/simulated/floor/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
+/turf/simulated/floor/temperature_expose(exposed_temperature, exposed_volume)
if(exposed_temperature > FIRE_MINIMUM_TEMPERATURE_TO_EXIST && prob(1))
burn_tile()
diff --git a/code/game/turfs/simulated/floor/mineral_floors.dm b/code/game/turfs/simulated/floor/mineral_floors.dm
index c7d99f19ddcd..5c376ffd1254 100644
--- a/code/game/turfs/simulated/floor/mineral_floors.dm
+++ b/code/game/turfs/simulated/floor/mineral_floors.dm
@@ -29,7 +29,7 @@
floor_tile = /obj/item/stack/tile/mineral/plasma
icons = list("plasma","plasma_dam")
-/turf/simulated/floor/mineral/plasma/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
+/turf/simulated/floor/mineral/plasma/temperature_expose(exposed_temperature, exposed_volume)
..()
if(exposed_temperature > 300)
PlasmaBurn()
diff --git a/code/game/turfs/simulated/walls_mineral.dm b/code/game/turfs/simulated/walls_mineral.dm
index 1d9d726abd08..c06323761895 100644
--- a/code/game/turfs/simulated/walls_mineral.dm
+++ b/code/game/turfs/simulated/walls_mineral.dm
@@ -135,7 +135,7 @@
ChangeTurf(/turf/simulated/floor)
atmos_spawn_air(LINDA_SPAWN_HEAT | LINDA_SPAWN_TOXINS, 400)
-/turf/simulated/wall/mineral/plasma/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)//Doesn't fucking work because walls don't interact with air :(
+/turf/simulated/wall/mineral/plasma/temperature_expose(exposed_temperature, exposed_volume)//Doesn't fucking work because walls don't interact with air :(
..()
if(exposed_temperature > 300)
PlasmaBurn(exposed_temperature)
diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm
index fcea2b6c6661..79a1dad9b8f6 100644
--- a/code/game/turfs/turf.dm
+++ b/code/game/turfs/turf.dm
@@ -675,11 +675,31 @@
get_turf_air(T).copy_from(air)
/turf/simulated/proc/update_hotspot()
- var/datum/gas_mixture/air = get_readonly_air()
- if(air.fuel_burnt() < 0.001)
- if(isnull(active_hotspot))
- return FALSE
+ // This is a horrible (but fast) way to do this. Don't copy it.
+ // It's only used here because we know we're in safe code and this method is called a ton.
+ var/datum/gas_mixture/air
+ var/fuel_burnt = 0
+ if(isnull(active_hotspot))
+ active_hotspot = new(src)
+ active_hotspot.update_interval = max(1, floor(length(SSair.hotspots) / 1000))
+ active_hotspot.update_tick = rand(0, active_hotspot.update_interval - 1)
+
+ if(active_hotspot.data_tick != SSair.milla_tick)
+ if(isnull(bound_air) || bound_air.lastread < SSair.milla_tick)
+ air = get_readonly_air()
+ else
+ air = bound_air
+ fuel_burnt = air.fuel_burnt()
+ if(air.hotspot_volume() > 0)
+ active_hotspot.temperature = air.hotspot_temperature()
+ active_hotspot.volume = air.hotspot_volume() * CELL_VOLUME
+ else
+ active_hotspot.temperature = air.temperature()
+ active_hotspot.volume = CELL_VOLUME
+ else
+ fuel_burnt = active_hotspot.fuel_burnt
+ if(fuel_burnt < 0.001)
// If it's old, delete it.
if(active_hotspot.death_timer < SSair.milla_tick)
QDEL_NULL(active_hotspot)
@@ -687,18 +707,12 @@
else
return TRUE
- if(isnull(active_hotspot))
- active_hotspot = new(src)
-
active_hotspot.death_timer = SSair.milla_tick + 4
- if(air.hotspot_volume() > 0)
- active_hotspot.temperature = air.hotspot_temperature()
- active_hotspot.volume = air.hotspot_volume() * CELL_VOLUME
- else
- active_hotspot.temperature = air.temperature()
- active_hotspot.volume = CELL_VOLUME
- active_hotspot.update_visuals()
+ if(active_hotspot.update_tick == 0)
+ active_hotspot.update_visuals(active_hotspot.fuel_burnt)
+ active_hotspot.update_interval = max(1, floor(length(SSair.hotspots) / 1000))
+ active_hotspot.update_tick = (active_hotspot.update_tick + 1) % active_hotspot.update_interval
return TRUE
/turf/simulated/proc/update_wind()
@@ -712,7 +726,14 @@
wind_effect.dir = wind_direction(wind_x, wind_y)
- var/datum/gas_mixture/air = get_readonly_air()
+ // This is a horrible (but fast) way to do this. Don't copy it.
+ // It's only used here because we know we're in safe code and this method is called a ton.
+ var/datum/gas_mixture/air
+ if(isnull(bound_air) || bound_air.lastread < SSair.milla_tick)
+ air = get_readonly_air()
+ else
+ air = bound_air
+
var/wind = sqrt(wind_x ** 2 + wind_y ** 2)
var/wind_strength = wind * air.total_moles() / MOLES_CELLSTANDARD
wind_effect.alpha = min(255, 5 + wind_strength * 25)
diff --git a/code/modules/atmospherics/environmental/LINDA_fire.dm b/code/modules/atmospherics/environmental/LINDA_fire.dm
index 234aa4a500d7..54461958b0e7 100644
--- a/code/modules/atmospherics/environmental/LINDA_fire.dm
+++ b/code/modules/atmospherics/environmental/LINDA_fire.dm
@@ -1,6 +1,6 @@
/atom/proc/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
- if(reagents)
+ if(!isnull(reagents))
reagents.temperature_reagents(exposed_temperature)
/turf/simulated/temperature_expose(exposed_temperature)
@@ -32,19 +32,35 @@
var/volume = 125
var/temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST
- // The last tick this hotspot should be alive for.
+ /// 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()
+/obj/effect/hotspot/proc/update_visuals(fuel_burnt)
color = heat2color(temperature)
- set_light(l_color = color)
- var/turf/here = get_turf(src)
- var/datum/gas_mixture/gas = here.get_readonly_air()
- var/fuel_burnt = gas.fuel_burnt()
+ 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)
diff --git a/code/modules/atmospherics/machinery/portable/canister.dm b/code/modules/atmospherics/machinery/portable/canister.dm
index e8023b2a3ba7..0b2c4d46e4a8 100644
--- a/code/modules/atmospherics/machinery/portable/canister.dm
+++ b/code/modules/atmospherics/machinery/portable/canister.dm
@@ -60,6 +60,7 @@ GLOBAL_DATUM_INIT(canister_icon_container, /datum/canister_icons, new())
armor = list(MELEE = 50, BULLET = 50, LASER = 50, ENERGY = 100, BOMB = 10, RAD = 100, FIRE = 80, ACID = 50)
max_integrity = 250
integrity_failure = 100
+ cares_about_temperature = TRUE
var/valve_open = FALSE
var/release_pressure = ONE_ATMOSPHERE
@@ -166,7 +167,7 @@ GLOBAL_DATUM_INIT(canister_icon_container, /datum/canister_icons, new())
else if(current_pressure_appearance == EXTREME_PRESSURE)
. += "can-o3"
-/obj/machinery/atmospherics/portable/canister/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
+/obj/machinery/atmospherics/portable/canister/temperature_expose(exposed_temperature, exposed_volume)
..()
if(exposed_temperature > temperature_resistance)
take_damage(5, BURN, 0)
diff --git a/code/modules/clothing/under/accessories/accessory.dm b/code/modules/clothing/under/accessories/accessory.dm
index ffeb70cda6d7..95c384d877ec 100644
--- a/code/modules/clothing/under/accessories/accessory.dm
+++ b/code/modules/clothing/under/accessories/accessory.dm
@@ -262,8 +262,9 @@
icon_state = "plasma"
item_color = "plasma"
materials = list(MAT_PLASMA = 1000)
+ cares_about_temperature = TRUE
-/obj/item/clothing/accessory/medal/plasma/temperature_expose(datum/gas_mixture/air, temperature, volume)
+/obj/item/clothing/accessory/medal/plasma/temperature_expose(temperature, volume)
..()
if(temperature > T0C + 200)
burn_up()
diff --git a/code/modules/events/spacevine.dm b/code/modules/events/spacevine.dm
index fc2d81c0488f..5cb7f6e964ae 100644
--- a/code/modules/events/spacevine.dm
+++ b/code/modules/events/spacevine.dm
@@ -399,6 +399,7 @@
pass_flags = PASSTABLE | PASSGRILLE
max_integrity = 50
unbuckle_time = 5 SECONDS
+ cares_about_temperature = TRUE
var/energy = 0
var/obj/structure/spacevine_controller/master = null
var/list/mutations = list()
@@ -701,7 +702,7 @@
if(!i && prob(100/severity))
wither()
-/obj/structure/spacevine/temperature_expose(null, temp, volume)
+/obj/structure/spacevine/temperature_expose(temp, volume)
..()
var/override = 0
for(var/SM_type in mutations)
diff --git a/code/modules/mob/living/carbon/alien/special/facehugger.dm b/code/modules/mob/living/carbon/alien/special/facehugger.dm
index 517c7b8ae567..886d2cc1c0cc 100644
--- a/code/modules/mob/living/carbon/alien/special/facehugger.dm
+++ b/code/modules/mob/living/carbon/alien/special/facehugger.dm
@@ -13,6 +13,7 @@
flags_cover = MASKCOVERSMOUTH | MASKCOVERSEYES
layer = MOB_LAYER
max_integrity = 100
+ cares_about_temperature = TRUE
var/stat = CONSCIOUS //UNCONSCIOUS is the idle state in this case
var/sterile = FALSE
@@ -60,7 +61,7 @@
if(sterile)
. += "It looks like the proboscis has been removed."
-/obj/item/clothing/mask/facehugger/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
+/obj/item/clothing/mask/facehugger/temperature_expose(exposed_temperature, exposed_volume)
..()
if(exposed_temperature > 300)
Die()
diff --git a/code/modules/power/lights.dm b/code/modules/power/lights.dm
index b6b1a8f66f5f..0f92a2e59197 100644
--- a/code/modules/power/lights.dm
+++ b/code/modules/power/lights.dm
@@ -238,6 +238,7 @@
idle_power_consumption = 10 //when in low power mode
active_power_consumption = 20 //when in full power mode
power_channel = PW_CHANNEL_LIGHTING //Lights are calc'd via area so they dont need to be in the machine list
+ cares_about_temperature = TRUE
var/base_state = "tube" // Base description and icon_state
/// Is the light on or off?
var/on = FALSE
@@ -943,7 +944,7 @@
// called when on fire
-/obj/machinery/light/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
+/obj/machinery/light/temperature_expose(exposed_temperature, exposed_volume)
..()
if(prob(max(0, exposed_temperature - 673))) //0% at <400C, 100% at >500C
break_light_tube()
diff --git a/code/modules/reagents/reagent_dispenser.dm b/code/modules/reagents/reagent_dispenser.dm
index 55dfca88312e..8c9c7ef4e0bf 100644
--- a/code/modules/reagents/reagent_dispenser.dm
+++ b/code/modules/reagents/reagent_dispenser.dm
@@ -7,6 +7,7 @@
pressure_resistance = 2*ONE_ATMOSPHERE
container_type = DRAINABLE | AMOUNT_VISIBLE
max_integrity = 300
+ cares_about_temperature = TRUE
/// How much this dispenser can hold (In units)
var/tank_volume = 1000
/// The ID of the reagent that the dispenser uses
@@ -49,7 +50,7 @@
if(can_be_unwrenched)
. += "The wheels look like they can be [anchored ? "unlocked" : "locked in place"] with a wrench."
-/obj/structure/reagent_dispensers/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
+/obj/structure/reagent_dispensers/temperature_expose(exposed_temperature, exposed_volume)
..()
if(reagents)
for(var/i in 1 to 8)