Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds a heatpump that works between utility pipe and environment #6297

Merged
merged 8 commits into from
Feb 5, 2024
1 change: 1 addition & 0 deletions citadel.dme
Original file line number Diff line number Diff line change
Expand Up @@ -2278,6 +2278,7 @@
#include "code\modules\atmospherics\machinery\components\trinary_devices\trinary_base.dm"
#include "code\modules\atmospherics\machinery\components\trinary_devices\tvalve.dm"
#include "code\modules\atmospherics\machinery\components\unary\cold_sink.dm"
#include "code\modules\atmospherics\machinery\components\unary\env_heat_pump.dm"
#include "code\modules\atmospherics\machinery\components\unary\generator_input.dm"
#include "code\modules\atmospherics\machinery\components\unary\heat_exchanger.dm"
#include "code\modules\atmospherics\machinery\components\unary\heat_source.dm"
Expand Down
14 changes: 6 additions & 8 deletions code/game/machinery/doors/airlock/phoronlocks.dm
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,6 @@
/obj/machinery/embedded_controller/radio/airlock/phoron
name = "Phoron Lock Controller"
valid_actions = list("cycle_ext", "cycle_int", "force_ext", "force_int", "abort", "secure")
var/tag_scrubber

/obj/machinery/embedded_controller/radio/airlock/phoron/ui_data(mob/user, datum/tgui/ui)
. = list(
Expand All @@ -124,8 +123,8 @@

//Handles the control of airlocks

/datum/computer/file/embedded_program/airlock/phoron
var/tag_scrubber
//datum/computer/file/embedded_program/airlock/phoron


/datum/computer/file/embedded_program/airlock/phoron/New(var/obj/machinery/embedded_controller/M)
..(M)
Expand All @@ -140,10 +139,6 @@
memory["target_phoron"] = 0.1
memory["secure"] = 1

if (istype(M, /obj/machinery/embedded_controller/radio/airlock/phoron)) //if our controller is an airlock controller than we can auto-init our tags
var/obj/machinery/embedded_controller/radio/airlock/phoron/controller = M
tag_scrubber = controller.tag_scrubber ? controller.tag_scrubber : "[id_tag]_scrubber"

/datum/computer/file/embedded_program/airlock/phoron/receive_signal(datum/signal/signal, receive_method, receive_param)
var/receive_tag = signal.data["tag"]
if(!receive_tag) return
Expand Down Expand Up @@ -191,7 +186,7 @@
signalPump(tag_airpump, 1, 1, memory["target_pressure"]) // And pressurizng to offset losses
memory["processing"] = TRUE
else if(fuzzy_smaller_check(memory["chamber_sensor_temperature"], memory["target_temperature"]))
signalScrubber(tag_scrubber, 1)//the scrubbers also work as heats because fuck making sense
signalTemperatureAdjuster(tag_temperature_adjuster, 1, memory["target_temperature"])
memory["processing"] = TRUE
else if(fuzzy_smaller_check(memory["chamber_sensor_pressure"], memory["internal_sensor_pressure"]))
signalScrubber(tag_scrubber, 0) // stop cleaning
Expand All @@ -200,10 +195,12 @@
else // both phoron and pressure levels are acceptable
toggleDoor(memory["interior_status"],tag_interior_door, 1, "open")
signalScrubber(tag_scrubber, 0)
signalTemperatureAdjuster(tag_temperature_adjuster, 0, memory["target_temperature"])
signalPump(tag_airpump, 0, 1, memory["external_sensor_pressure"])//Turn the pump off
state = STATE_OPEN_IN
memory["processing"] = FALSE
if(STATE_CYCLING_OUT)
signalTemperatureAdjuster(tag_temperature_adjuster, 0, memory["target_temperature"])
if(memory["interior_status"]["state"] == "open")
toggleDoor(memory["interior_status"],tag_interior_door, 1, "close")
else if((memory["chamber_sensor_pressure"] - memory["external_sensor_pressure"]) > 1 )
Expand Down Expand Up @@ -231,4 +228,5 @@
/datum/computer/file/embedded_program/airlock/phoron/stop_everything()
. = ..()
signalScrubber(tag_scrubber, 0)//Turn off scrubbers
signalTemperatureAdjuster(tag_temperature_adjuster, 0, memory["target_temperature"])

Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
var/tag_interior_sensor
var/tag_airlock_mech_sensor
var/tag_shuttle_mech_sensor
var/tag_scrubber
var/tag_temperature_adjuster
var/tag_secure = 0
var/list/dummy_terminals = list()
var/cycle_to_external_air = 0
Expand Down
15 changes: 15 additions & 0 deletions code/game/machinery/embedded_controller/airlock_program.dm
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
var/tag_interior_sensor
var/tag_airlock_mech_sensor
var/tag_shuttle_mech_sensor
var/tag_scrubber
var/tag_temperature_adjuster

var/state = STATE_CLOSED

Expand Down Expand Up @@ -42,6 +44,8 @@
tag_interior_sensor = controller.tag_interior_sensor || "[id_tag]_interior_sensor"
tag_airlock_mech_sensor = controller.tag_airlock_mech_sensor? controller.tag_airlock_mech_sensor : "[id_tag]_airlock_mech"
tag_shuttle_mech_sensor = controller.tag_shuttle_mech_sensor? controller.tag_shuttle_mech_sensor : "[id_tag]_shuttle_mech"
tag_scrubber = controller.tag_scrubber ? controller.tag_scrubber : "[id_tag]_scrubber"
tag_temperature_adjuster = controller.tag_temperature_adjuster? controller.tag_temperature_adjuster : "[id_tag]_chamber_temperature"
memory["secure"] = controller.tag_secure

spawn(10)
Expand Down Expand Up @@ -209,6 +213,17 @@
)
post_signal(signal)

/datum/computer/file/embedded_program/airlock/proc/signalTemperatureAdjuster(var/tag, var/power, var/temperature)
signalScrubber(tag_scrubber, power)//Temporary hack so mapping changes arent part of this PR
var/datum/signal/signal = new
signal.data = list(
"tag" = tag,
"sigtype" = "command",
"power" = "[power]",
"target_temperature" = "[temperature]",
)
post_signal(signal)

/datum/computer/file/embedded_program/airlock/proc/signal_mech_sensor(command, sensor)
var/datum/signal/signal = new
signal.data["tag"] = sensor
Expand Down
7 changes: 7 additions & 0 deletions code/game/machinery/embedded_controller/mapping_helpers.dm
Original file line number Diff line number Diff line change
Expand Up @@ -133,11 +133,18 @@ Any frequency works, it's self-setting, but it seems like people have decided 13
icon_state = "pumpdout"
tag_addon = "_pump_out_external"

/obj/map_helper/airlock/atmos/chamber_temperature_adjuster
name = "chamber temperature adjuster"
icon_state = "temp"
tag_addon = "_chamber_temperature"
my_device_type = /obj/machinery/atmospherics/component/unary/env_heat_pump

/obj/map_helper/airlock/atmos/scrubber
name = "chamber scrubber"
my_device_type = /obj/machinery/atmospherics/component/unary/vent_scrubber
icon_state = "scrubber"
tag_addon = "_scrubber"

/*
Sensors - did you know they function as buttons? You don't also need a button.
*/
Expand Down
143 changes: 143 additions & 0 deletions code/modules/atmospherics/machinery/components/unary/env_heat_pump.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@




/obj/machinery/atmospherics/component/unary/env_heat_pump
name = "Room heat exchanger"
icon = 'icons/obj/atmos.dmi'
icon_state = "env_heat_pump"
density = 1
anchored = 1
use_power = USE_POWER_OFF
idle_power_usage = 5 // 5 Watts for thermostat related circuitry
pipe_flags = PIPING_ONE_PER_TURF
connect_types = CONNECT_TYPE_AUX
var/env_temp

var/frequency = 1439
var/datum/radio_frequency/radio_connection
var/id_tag

power_rating = 30000 // standard for machinery (including normal pumps) is 7500, heatpumps have 15000

var/target_temp = T20C
efficiency_multiplier = 1.5 //Bigger device probably works a bit better than the small cramped one

/obj/machinery/atmospherics/component/unary/env_heat_pump/Initialize(mapload)
. = ..()
START_MACHINE_PROCESSING(src)

/obj/machinery/atmospherics/component/unary/env_heat_pump/atmos_init()
. = ..()
if(frequency)
var/radio_filter_in = frequency==1439?(RADIO_FROM_AIRALARM):null
radio_connection = register_radio(src, frequency, frequency, radio_filter_in)
src.broadcast_status()

/obj/machinery/atmospherics/component/unary/env_heat_pump/Destroy()
. = ..()
STOP_MACHINE_PROCESSING(src)

/obj/machinery/atmospherics/component/unary/env_heat_pump/update_icon()
. = ..()
if(use_power)
if(env_temp > target_temp+0.001)//We dont work on such minor
icon_state = "env_heat_pump_cool"
else if(env_temp < target_temp-0.001)
icon_state = "env_heat_pump_heat"
else
if(use_power > 1)
icon_state = "env_heat_pump_on"
else
icon_state = "env_heat_pump"
else
icon_state = "env_heat_pump"

/obj/machinery/atmospherics/component/unary/env_heat_pump/process(delta_time)
. = ..()
update_icon()
if((machine_stat & (NOPOWER|BROKEN)) || !use_power)
use_power = USE_POWER_OFF //We cant operate so we might as well turn off
return

var/datum/gas_mixture/env = return_air()

if(!air_contents || !env || !istype(env))
use_power = USE_POWER_OFF //We cant operate so we might as well turn off
return

//If there is no air_contents or env the temperature is assumed 0 Kelvin which allows for
if((air_contents.temperature < 1) || (env.temperature < 1))
use_power = USE_POWER_OFF //We cant operate so we might as well turn off
return

env_temp = env.temperature

//Now we are at the point where we need to actively pump
var/efficiency = get_thermal_efficiency(air_contents, env) * efficiency_multiplier
CACHE_VSC_PROP(atmos_vsc, /atmos/heatpump/performance_factor, performance_factor)

var/actual_performance_factor = performance_factor*efficiency

var/max_energy_transfer = actual_performance_factor*power_rating

if(abs(env.temperature - target_temp) < 0.001) // don't want wild swings and too much power use
use_power = USE_POWER_IDLE //We cant operate so we might as well turn off
return
//only adds the energy actually removed from air one to air two(- infront of air_contents because energy was removed)
var/energy_transfered = -air_contents.adjust_thermal_energy(-clamp(env.get_thermal_energy_change(target_temp),-max_energy_transfer,max_energy_transfer))
energy_transfered=abs(env.adjust_thermal_energy(energy_transfered))
var/power_draw = abs(energy_transfered/actual_performance_factor)
if (power_draw >= 0)
last_power_draw_legacy = power_draw
use_power(power_draw)
network?.update = 1

/obj/machinery/atmospherics/component/unary/env_heat_pump/proc/get_thermal_efficiency(var/datum/gas_mixture/air1, var/datum/gas_mixture/air2)
if((target_temp < air2.temperature))
return clamp((air2.temperature / air1.temperature), 0, 1)
else if((target_temp > air2.temperature))
return clamp((air1.temperature / air2.temperature), 0, 1)


/obj/machinery/atmospherics/component/unary/env_heat_pump/receive_signal(datum/signal/signal, receive_method, receive_param)
if(machine_stat & (NOPOWER|BROKEN))
return

if(!signal.data["tag"] || (signal.data["tag"] != id_tag) || (signal.data["sigtype"]!="command"))
return 0

if(!isnull(signal.data["power"]))
if(text2num(signal.data["power"]) != 0)
use_power = USE_POWER_ACTIVE
else
use_power = USE_POWER_OFF
if(!isnull(signal.data["target_temperature"]))
target_temp = text2num(signal.data["target_temperature"])
spawn(2)
broadcast_status()
if(signal.data["status"] == null)
update_icon()


/obj/machinery/atmospherics/component/unary/env_heat_pump/proc/broadcast_status()
if(!radio_connection)
return 0

var/datum/signal/signal = new
signal.transmission_method = 1 //radio signal
signal.source = src

signal.data = list(
"device" = "EHP",
"power" = use_power,
"target_temp" = target_temp,
"timestamp" = world.time,
"sigtype" = "status",
"power_draw" = last_power_draw_legacy,
"flow_rate" = last_flow_rate_legacy,
)

radio_connection.post_signal(src, signal, null)

return 1
Binary file modified icons/mapping/helpers/mapping_helpers.dmi
Binary file not shown.
Binary file modified icons/misc/map_helpers.dmi
Binary file not shown.
Binary file modified icons/obj/atmos.dmi
Binary file not shown.
Loading
Loading