Space heater power and heating tweaks (#82344)

## About The Pull Request
- Fixes #82342
- Space heater computes total power for heating adjacent turfs and uses
cell energy once rather multiple times per turf
- Improvised space heater actually works & uses beaker heat capacity and
not a constant of 200 for heating beaker contents

## Changelog 
🆑 SyncIt21,Pickle-Coding
fix: space heater(including improvised) turns off when cell is drained
fix: optimized power usage for both improvised and main space heater.
Improvised heater now works & uses beaker heat capacity
/🆑
This commit is contained in:
SyncIt21
2024-04-01 17:21:15 +02:00
committed by GitHub
parent b3f1c44db3
commit 6d889fac5e
2 changed files with 58 additions and 46 deletions
+3 -2
View File
@@ -159,10 +159,11 @@
* Args:
* - power: The value of power to format.
* - convert: Whether to convert this from joules.
* - datum/controller/subsystem/scheduler: used in the conversion
* Returns: The string containing the formatted power.
*/
/proc/display_power(power, convert = TRUE)
power = convert ? energy_to_power(power) : power
/proc/display_power(power, convert = TRUE, datum/controller/subsystem/scheduler = SSmachines)
power = convert ? energy_to_power(power, scheduler) : power
return siunit(power, "W", 3)
/**
+55 -44
View File
@@ -2,6 +2,7 @@
#define HEATER_MODE_HEAT "heat"
#define HEATER_MODE_COOL "cool"
#define HEATER_MODE_AUTO "auto"
#define BASE_HEATING_ENERGY (40 KILO JOULES)
/obj/machinery/space_heater
anchored = FALSE
@@ -27,10 +28,8 @@
var/set_mode = HEATER_MODE_AUTO
///The temperature we trying to get to
var/target_temperature = T20C
///How much heat/cold we can deliver per tier
var/base_heating_power = 40 KILO JOULES
///How much heat/cold we can deliver
var/heating_power = 40 KILO JOULES
var/heating_energy = 40 KILO JOULES
///How efficiently we can deliver that heat/cold (higher indicates less cell consumption)
var/efficiency = 20
///The amount of degrees above and below the target temperature for us to change mode to heater or cooler
@@ -97,12 +96,16 @@
else
. += span_warning("There is no power cell installed.")
if(in_range(user, src) || isobserver(user))
var/target_temp = round(target_temperature - T0C, 1)
var/min_temp = max(settable_temperature_median - settable_temperature_range, TCMB) - T0C
var/max_temp = settable_temperature_median + settable_temperature_range - T0C
. += span_info("The status display reads:<br>Heating power: <b>[siunit(heating_power, "W", 1)] at [(efficiency / 20) * 100]% efficiency.</b><br>Target temperature: <b>[target_temp]°C \[[min_temp]°C - [max_temp]°C]</b>") // Base efficiency 100%, higher with upgraded components
. += heating_examine()
. += span_notice("<b>Right-click</b> to toggle [on ? "off" : "on"].")
///Returns the heating power of this machine as an examine
/obj/machinery/space_heater/proc/heating_examine()
var/target_temp = round(target_temperature - T0C, 1)
var/min_temp = max(settable_temperature_median - settable_temperature_range, TCMB) - T0C
var/max_temp = settable_temperature_median + settable_temperature_range - T0C
return span_notice("The status display reads:<br>Heating power: <b>[display_power(heating_energy, convert = TRUE, scheduler = SSair)] at [(efficiency / 20) * 100]% efficiency.</b><br>Target temperature: <b>[target_temp]°C [min_temp]°C - [max_temp]°C]</b>\n")
/obj/machinery/space_heater/update_icon_state()
. = ..()
icon_state = "[base_icon_state]-[on ? mode : "off"]"
@@ -117,14 +120,10 @@
return ..()
/obj/machinery/space_heater/process_atmos()
if(!on || !is_operational)
if(!on || !is_operational || QDELETED(cell) || cell.charge <= 1)
if (on) // If it's broken, turn it off too
on = FALSE
return PROCESS_KILL
if(!cell || cell.charge <= 1)
on = FALSE
update_appearance()
update_appearance()
return PROCESS_KILL
var/turf/local_turf = loc
@@ -149,25 +148,23 @@
if(mode == HEATER_MODE_STANDBY)
return
var/heat_capacity = enviroment.heat_capacity()
var/required_energy = abs(enviroment.temperature - target_temperature) * heat_capacity
required_energy = min(required_energy, heating_power)
var/list/turfs = (local_turf.atmos_adjacent_turfs || list()) + local_turf
var/required_energy = abs(enviroment.temperature - target_temperature) * enviroment.heat_capacity()
required_energy = min(required_energy, heating_energy, (cell.charge * efficiency) / length(turfs))
if(required_energy < 1)
return
var/delta_temperature = required_energy / heat_capacity
var/delta_energy = required_energy
if(mode == HEATER_MODE_COOL)
delta_temperature *= -1
if(delta_temperature == 0)
delta_energy *= -1
if(delta_energy == 0)
return
for(var/turf/open/turf in ((local_turf.atmos_adjacent_turfs || list()) + local_turf))
for(var/turf/open/turf in turfs)
var/datum/gas_mixture/turf_gasmix = turf.return_air()
turf_gasmix.temperature += delta_temperature
turf_gasmix.temperature += delta_energy / turf_gasmix.heat_capacity()
air_update_turf(FALSE, FALSE)
cell.use(required_energy / efficiency)
cell.use((required_energy * length(turfs)) / efficiency, force = TRUE)
/obj/machinery/space_heater/RefreshParts()
. = ..()
@@ -178,7 +175,7 @@
for(var/datum/stock_part/capacitor/capacitor in component_parts)
cap += capacitor.tier
heating_power = laser * base_heating_power
heating_energy = laser * BASE_HEATING_ENERGY
settable_temperature_range = cap * 30
efficiency = (cap + 1) * 10
@@ -321,38 +318,52 @@
. = ..()
QDEL_NULL(beaker)
/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: <b>[display_power(heating_energy * power_mod, convert = TRUE)]</b>")
/obj/machinery/space_heater/improvised_chem_heater/toggle_power(user)
. = ..()
if(on)
begin_processing()
/obj/machinery/space_heater/improvised_chem_heater/process(seconds_per_tick)
if(!on)
update_appearance()
if(!on || !is_operational || QDELETED(cell) || cell.charge <= 1 || QDELETED(beaker))
if (on) // If it's broken, turn it off too
on = FALSE
update_appearance()
return PROCESS_KILL
if(!is_operational || !cell || cell.charge <= 0)
on = FALSE
update_appearance()
return PROCESS_KILL
if(!beaker)//No beaker to heat
update_appearance()
return
if(beaker.reagents.total_volume)
var/power_mod = 0.1 * chem_heating_power
switch(set_mode)
if(HEATER_MODE_AUTO)
power_mod *= 0.5
beaker.reagents.adjust_thermal_energy((target_temperature - beaker.reagents.chem_temp) * power_mod * seconds_per_tick * SPECIFIC_HEAT_DEFAULT * beaker.reagents.total_volume)
beaker.reagents.handle_reactions()
if(HEATER_MODE_HEAT)
if(target_temperature < beaker.reagents.chem_temp)
return
beaker.reagents.adjust_thermal_energy((target_temperature - beaker.reagents.chem_temp) * power_mod * seconds_per_tick * SPECIFIC_HEAT_DEFAULT * beaker.reagents.total_volume)
if(HEATER_MODE_COOL)
if(target_temperature > beaker.reagents.chem_temp)
return
beaker.reagents.adjust_thermal_energy((target_temperature - beaker.reagents.chem_temp) * power_mod * seconds_per_tick * SPECIFIC_HEAT_DEFAULT * beaker.reagents.total_volume)
var/required_energy = heating_power * seconds_per_tick * (power_mod * 4)
cell.use(required_energy / efficiency)
var/required_energy = abs(target_temperature - beaker.reagents.chem_temp) * power_mod * seconds_per_tick * beaker.reagents.heat_capacity()
required_energy = min(required_energy, heating_energy, cell.charge * efficiency)
if(required_energy < 1)
return
var/delta_energy = required_energy
if(mode == HEATER_MODE_COOL)
delta_energy *= -1
if(delta_energy == 0)
return
beaker.reagents.adjust_thermal_energy(delta_energy)
beaker.reagents.handle_reactions()
cell.use(required_energy / efficiency, force = TRUE)
update_appearance()
/obj/machinery/space_heater/improvised_chem_heater/ui_data()
@@ -403,7 +414,6 @@
item.afterattack(beaker, user, 1)
return
/obj/machinery/space_heater/improvised_chem_heater/on_deconstruction(disassembled = TRUE)
. = ..()
if(disassembled)
@@ -458,7 +468,7 @@
for(var/datum/stock_part/capacitor/capacitor in component_parts)
capacitors_rating += capacitor.tier
heating_power = lasers_rating * 20000
heating_energy = lasers_rating * 20000
settable_temperature_range = capacitors_rating * 50 //-20 - 80 at base
efficiency = (capacitors_rating + 1) * 10
@@ -473,3 +483,4 @@
#undef HEATER_MODE_HEAT
#undef HEATER_MODE_COOL
#undef HEATER_MODE_AUTO
#undef BASE_HEATING_ENERGY