diff --git a/code/game/machinery/spaceheater.dm b/code/game/machinery/spaceheater.dm
index 1c69dbecb7e..af6221d8921 100644
--- a/code/game/machinery/spaceheater.dm
+++ b/code/game/machinery/spaceheater.dm
@@ -2,7 +2,7 @@
#define HEATER_MODE_HEAT "heat"
#define HEATER_MODE_COOL "cool"
#define HEATER_MODE_AUTO "auto"
-#define BASE_HEATING_ENERGY (STANDARD_CELL_RATE * 4)
+#define BASE_HEATING_ENERGY (40 KILO JOULES)
/obj/machinery/space_heater
anchored = FALSE
@@ -32,7 +32,7 @@
///How much heat/cold we can deliver
var/heating_energy = BASE_HEATING_ENERGY
///How efficiently we can deliver that heat/cold (higher indicates less cell consumption)
- var/efficiency = 200
+ var/efficiency = 20 MEGA JOULES / STANDARD_CELL_CHARGE
///The amount of degrees above and below the target temperature for us to change mode to heater or cooler
var/temperature_tolerance = 1
///What's the middle point of our settable temperature (30 °C)
@@ -176,7 +176,7 @@
for(var/datum/stock_part/capacitor/capacitor in component_parts)
cap += capacitor.tier
- heating_energy = laser * BASE_HEATING_ENERGY
+ heating_energy = laser * initial(heating_energy)
settable_temperature_range = cap * initial(settable_temperature_range)
efficiency = (cap + 1) * initial(efficiency) * 0.5
@@ -295,7 +295,14 @@
on = !on
mode = HEATER_MODE_STANDBY
if(!isnull(user))
- balloon_alert(user, "turned [on ? "on" : "off"]")
+ if(QDELETED(cell))
+ balloon_alert(user, "no cell!")
+ else if(!cell.charge())
+ balloon_alert(user, "no charge!")
+ else if(!is_operational)
+ balloon_alert(user, "not operational!")
+ else
+ balloon_alert(user, "turned [on ? "on" : "off"]")
update_appearance()
if(on)
SSair.start_processing_machine(src)
@@ -310,11 +317,18 @@
//We inherit the cell from the heater prior
cell = null
interaction_flags_click = FORBID_TELEKINESIS_REACH
+ display_panel = FALSE
+ settable_temperature_range = 50
///The beaker within the heater
var/obj/item/reagent_containers/beaker = null
- ///How powerful the heating is, upgrades with parts. (ala chem_heater.dm's method, basically the same level of heating, but this is restricted)
- var/chem_heating_power = 1
- display_panel = FALSE
+ /// How quickly it delivers heat to the reagents. In watts per joule of the thermal energy difference of the reagent from the temperature difference of the current and target temperatures.
+ var/beaker_conduction_power = 0.1
+ /// The subsystem we're being processed by.
+ var/datum/controller/subsystem/processing/our_subsystem
+
+/obj/machinery/space_heater/improvised_chem_heater/Initialize(mapload)
+ our_subsystem = locate(subsystem_type) in Master.subsystems
+ . = ..()
/obj/machinery/space_heater/improvised_chem_heater/Destroy()
. = ..()
@@ -322,11 +336,10 @@
/obj/machinery/space_heater/improvised_chem_heater/heating_examine()
. = ..()
-
- var/power_mod = 0.1 * chem_heating_power
- if(set_mode == HEATER_MODE_AUTO)
- power_mod *= 0.5
- . += span_notice("Heating power for beaker: [display_power(heating_energy * power_mod, convert = TRUE)]")
+ // Conducted energy per joule of thermal energy difference in a tick.
+ var/conduction_energy = beaker_conduction_power * (set_mode == HEATER_MODE_AUTO ? 0.5 : 1) * our_subsystem.wait / (1 SECONDS)
+ // This accounts for the timestep inaccuracy.
+ . += span_notice("Reagent conduction power: [conduction_energy < 1 ? display_power(-log(1 - conduction_energy) SECONDS / our_subsystem.wait, convert = FALSE) : "∞W"]/J")
/obj/machinery/space_heater/improvised_chem_heater/toggle_power(user)
. = ..()
@@ -341,10 +354,10 @@
return PROCESS_KILL
if(beaker.reagents.total_volume)
- var/power_mod = 0.1 * chem_heating_power
+ var/conduction_modifier = beaker_conduction_power
switch(set_mode)
if(HEATER_MODE_AUTO)
- power_mod *= 0.5
+ conduction_modifier *= 0.5
if(HEATER_MODE_HEAT)
if(target_temperature < beaker.reagents.chem_temp)
return
@@ -352,7 +365,7 @@
if(target_temperature > beaker.reagents.chem_temp)
return
- var/required_energy = abs(target_temperature - beaker.reagents.chem_temp) * power_mod * seconds_per_tick * beaker.reagents.heat_capacity()
+ var/required_energy = abs(target_temperature - beaker.reagents.chem_temp) * conduction_modifier * seconds_per_tick * beaker.reagents.heat_capacity()
required_energy = min(required_energy, heating_energy, cell.charge * efficiency)
if(required_energy < 1)
return
@@ -468,16 +481,17 @@
for(var/datum/stock_part/capacitor/capacitor in component_parts)
capacitors_rating += capacitor.tier
- heating_energy = lasers_rating * BASE_HEATING_ENERGY
+ heating_energy = lasers_rating * initial(heating_energy)
- settable_temperature_range = capacitors_rating * 50 //-20 - 80 at base
- efficiency = (capacitors_rating + 1) * 10
+ settable_temperature_range = capacitors_rating * initial(settable_temperature_range) //-20 - 80 at base
+ efficiency = (capacitors_rating + 1) * initial(efficiency) * 0.5
target_temperature = clamp(target_temperature,
max(settable_temperature_median - settable_temperature_range, TCMB),
settable_temperature_median + settable_temperature_range)
- chem_heating_power = efficiency / 20
+ // No time integration is used, so we should clamp this to prevent being able to overshoot if there was a subtype with a high initial value.
+ beaker_conduction_power = min((capacitors_rating + 1) * 0.5 * initial(beaker_conduction_power), 1 SECONDS / our_subsystem.wait)
#undef HEATER_MODE_STANDBY
#undef HEATER_MODE_HEAT