Files
VOREStation/maps/tether/tether_phoronlock.dm
T
Kashargul e956d13a6b jobs, access and radio to defines (#18297)
* jobs, access and radio to defines

* .

* .

* urg

* .

* .

* finish the radio freqs

* why

* .

* .

* ticker initial

* eh

---------

Co-authored-by: Cameron Lennox <killer65311@gmail.com>
2025-08-31 01:32:36 +02:00

274 lines
10 KiB
Plaintext

//
// Objects for making phoron airlocks work
// Instructions: Choose a base tag, and include equipment with tags as follows:
// Phoron Lock Controller (/obj/machinery/embedded_controller/radio/airlock/phoron), id_tag = "[base]"
// Don't set any other tag vars, they will be auto-populated
// Internal Sensor (obj/machinery/airlock_sensor/phoron), id_tag = "[base]_sensor"
// Make sure it is actually located inside the airlock, not on a wall turf. use pixel_x/y
// Exterior doors: (obj/machinery/door/airlock), id_tag = "[base]_outer"
// Interior doors: (obj/machinery/door/airlock), id_tag = "[base]_inner"
// Exterior access button: (obj/machinery/access_button/airlock_exterior), master_tag = "[base]"
// Interior access button: (obj/machinery/access_button/airlock_interior), master_tag = "[base]"
// Srubbers: (obj/machinery/portable_atmospherics/powered/scrubber/huge/stationary), frequency = AIRLOCK_FREQ, scrub_id = "[base]_scrubber"
// Pumps: (obj/machinery/atmospherics/unary/vent_pump/high_volume), frequency = AIRLOCK_FREQ id_tag = "[base]_pump"
//
/obj/machinery/airlock_sensor/phoron
icon = 'icons/obj/airlock_machines.dmi'
icon_state = "airlock_sensor_off"
name = "phoronlock sensor"
var/previousPhoron
/obj/machinery/airlock_sensor/phoron/process()
if(on)
var/datum/gas_mixture/air_sample = return_air()
var/pressure = round(air_sample.return_pressure(), 0.1)
var/phoron = (GAS_PHORON in air_sample.gas) ? round(air_sample.gas[GAS_PHORON], 0.1) : 0
if(abs(pressure - previousPressure) > 0.1 || previousPressure == null || abs(phoron - previousPhoron) > 0.1 || previousPhoron == null)
var/datum/signal/signal = new
signal.transmission_method = TRANSMISSION_RADIO //radio signal
signal.data["tag"] = id_tag
signal.data["timestamp"] = world.time
signal.data["pressure"] = num2text(pressure)
signal.data[GAS_PHORON] = num2text(phoron)
radio_connection.post_signal(src, signal, range = AIRLOCK_CONTROL_RANGE, radio_filter = RADIO_AIRLOCK)
previousPressure = pressure
previousPhoron = phoron
alert = (pressure < ONE_ATMOSPHERE*0.8) || (phoron > 0.5)
update_icon()
/obj/machinery/airlock_sensor/phoron/airlock_interior
command = "cycle_interior"
/obj/machinery/airlock_sensor/phoron/airlock_exterior
command = "cycle_exterior"
// Radio remote control
/obj/machinery/portable_atmospherics/powered/scrubber/huge/stationary
var/frequency = ZERO_FREQ
var/datum/radio_frequency/radio_connection
/obj/machinery/portable_atmospherics/powered/scrubber/huge/stationary/Initialize(mapload)
. = ..()
if(frequency)
set_frequency(frequency)
/obj/machinery/portable_atmospherics/powered/scrubber/huge/stationary/proc/set_frequency(new_frequency)
SSradio.remove_object(src, frequency)
frequency = new_frequency
if(frequency)
radio_connection = SSradio.add_object(src, frequency, radio_filter = RADIO_ATMOSIA)
/obj/machinery/portable_atmospherics/powered/scrubber/huge/stationary/receive_signal(datum/signal/signal)
if(!signal.data["tag"] || (signal.data["tag"] != scrub_id) || (signal.data["sigtype"] != "command"))
return 0
if(signal.data["power"])
on = text2num(signal.data["power"]) ? TRUE : FALSE
if("power_toggle" in signal.data)
on = !on
if(signal.data["status"])
spawn(2)
broadcast_status()
return //do not update_icon
spawn(2)
broadcast_status()
update_icon()
return
/obj/machinery/portable_atmospherics/powered/scrubber/huge/stationary/proc/broadcast_status()
if(!radio_connection)
return 0
var/datum/signal/signal = new
signal.transmission_method = TRANSMISSION_RADIO
signal.source = src
signal.data = list(
"tag" = scrub_id,
"power" = on,
"sigtype" = "status"
)
radio_connection.post_signal(src, signal, radio_filter = RADIO_AIRLOCK)
return 1
/obj/machinery/portable_atmospherics/powered/scrubber/huge/stationary/phoronlock //Special scrubber with bonus inbuilt heater
volume_rate = 40000
active_power_usage = 2000
var/target_temp = T20C
var/heating_power = 150000
/obj/machinery/portable_atmospherics/powered/scrubber/huge/stationary/phoronlock/process()
..()
if(on)
var/datum/gas_mixture/env = loc.return_air()
if(env && abs(env.temperature - target_temp) > 0.1)
var/datum/gas_mixture/removed = env.remove_ratio(0.99)
if(removed)
var/heat_transfer = removed.get_thermal_energy_change(target_temp)
removed.add_thermal_energy(min(heating_power,heat_transfer))
env.merge(removed)
var/transfer_moles = min(1, volume_rate/env.volume)*env.total_moles
for(var/i=1 to 3) //Scrubs 4 times as fast
scrub_gas(src, scrubbing_gas, env, air_contents, transfer_moles, active_power_usage)
//
// PHORON LOCK CONTROLLER
//
/obj/machinery/embedded_controller/radio/airlock/phoron
var/tag_scrubber
/obj/machinery/embedded_controller/radio/airlock/phoron/Initialize(mapload)
. = ..()
program = new/datum/embedded_program/airlock/phoron(src)
//Advanced airlock controller for when you want a more versatile airlock controller - useful for turning simple access control rooms into airlocks
/obj/machinery/embedded_controller/radio/airlock/phoron
name = "Phoron Lock Controller"
valid_actions = list("cycle_ext", "cycle_int", "force_ext", "force_int", "abort", "secure")
/obj/machinery/embedded_controller/radio/airlock/phoron/tgui_data(mob/user)
. = list(
"chamber_pressure" = program.memory["chamber_sensor_pressure"],
"chamber_phoron" = program.memory["chamber_sensor_phoron"],
"exterior_status" = program.memory["exterior_status"],
"interior_status" = program.memory["interior_status"],
"processing" = program.memory["processing"],
"internalTemplateName" = "AirlockConsolePhoron",
)
//
// PHORON LOCK CONTROLLER PROGRAM
//
//Handles the control of airlocks
// Airlocks
#define STATE_IDLE 0
#define STATE_PREPARE 1
#define STATE_CLEAN 16
#define STATE_PRESSURIZE 17
#define TARGET_NONE 0
#define TARGET_INOPEN -1
#define TARGET_OUTOPEN -2
/datum/embedded_program/airlock/phoron
var/tag_scrubber
/datum/embedded_program/airlock/phoron/New(var/obj/machinery/embedded_controller/M)
..(M)
memory["chamber_sensor_phoron"] = 0
memory["external_sensor_pressure"] = VIRGO3B_ONE_ATMOSPHERE
memory["external_sensor_phoron"] = VIRGO3B_MOL_PHORON
memory["internal_sensor_phoron"] = 0
memory["scrubber_status"] = "unknown"
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/embedded_program/airlock/phoron/receive_signal(datum/signal/signal, receive_method, receive_param)
var/receive_tag = signal.data["tag"]
if(!receive_tag) return
if(..()) return 1
if(receive_tag==tag_chamber_sensor)
memory["chamber_sensor_phoron"] = text2num(signal.data[GAS_PHORON])
memory["chamber_sensor_pressure"] = text2num(signal.data["pressure"])
else if(receive_tag==tag_exterior_sensor)
memory["external_sensor_phoron"] = text2num(signal.data[GAS_PHORON])
else if(receive_tag==tag_interior_sensor)
memory["internal_sensor_phoron"] = text2num(signal.data[GAS_PHORON])
else if(receive_tag==tag_scrubber)
if(signal.data["power"])
memory["scrubber_status"] = "on"
else
memory["scrubber_status"] = "off"
// Note: This code doesn't wait for pumps and scrubbers to be offline like other code does
// The idea is to make the doors open and close faster, since there isn't much harm really.
// But lets evaluate how it actually works in the game.
/datum/embedded_program/airlock/phoron/process()
switch(state)
if(STATE_IDLE)
if(target_state == TARGET_INOPEN)
// TODO - Check if okay to just open immediately
close_doors()
state = STATE_PREPARE
else if(target_state == TARGET_OUTOPEN)
close_doors()
state = STATE_PREPARE
// else if(memory["scrubber_status"] != "off")
// signalScrubber(tag_scrubber, 0) // Keep scrubbers off while idle
// else if(memory["pump_status"] != "off")
// signalPump(tag_airpump, 0) // Keep vent pump off while idle
if(STATE_PREPARE)
if (check_doors_secured())
if(target_state == TARGET_INOPEN)
playsound(master, 'sound/AI/airlockin.ogg', 100, 0)
if(memory["chamber_sensor_phoron"] > memory["target_phoron"])
state = STATE_CLEAN
signalScrubber(tag_scrubber, 1) // Start cleaning
signalPump(tag_airpump, 1, 1, memory["target_pressure"]) // And pressurizng to offset losses
else // We can go directly to pressurize
state = STATE_PRESSURIZE
signalPump(tag_airpump, 1, 1, memory["target_pressure"]) // Send a signal to start pressurizing
// We must be cycling outwards! Shut down the pumps and such!
else if(memory["scrubber_status"] != "off")
signalScrubber(tag_scrubber, 0)
else if(memory["pump_status"] != "off")
signalPump(tag_airpump, 0)
else
playsound(master, 'sound/AI/airlockout.ogg', 100, 0)
cycleDoors(target_state)
state = STATE_IDLE
target_state = TARGET_NONE
if(STATE_CLEAN)
playsound(master, 'sound/machines/2beep.ogg', 100, 0)
if(!check_doors_secured())
//the airlock will not allow itself to continue to cycle when any of the doors are forced open.
stop_cycling()
else if(memory["chamber_sensor_phoron"] <= memory["target_phoron"])
// Okay, we reached target phoron! Turn off the scrubber
signalScrubber(tag_scrubber, 0)
// And proceed to finishing pressurization
state = STATE_PRESSURIZE
if(STATE_PRESSURIZE)
playsound(master, 'sound/machines/2beep.ogg', 100, 0)
if(!check_doors_secured())
//the airlock will not allow itself to continue to cycle when any of the doors are forced open.
stop_cycling()
else if(memory["chamber_sensor_pressure"] >= memory["target_pressure"] * 0.95)
signalPump(tag_airpump, 0) // send a signal to stop pumping. No need to wait for it tho.
cycleDoors(target_state)
playsound(master, 'sound/AI/airlockdone.ogg', 100, 0)
state = STATE_IDLE
target_state = TARGET_NONE
memory["processing"] = (state != target_state)
return 1
/datum/embedded_program/airlock/phoron/stop_cycling()
state = STATE_IDLE
target_state = TARGET_NONE
signalPump(tag_airpump, 0)
signalScrubber(tag_scrubber, 0)
/datum/embedded_program/airlock/phoron/proc/signalScrubber(var/tag, var/power)
var/datum/signal/signal = new
signal.data = list(
"tag" = tag,
"sigtype" = "command",
"power" = "[power]",
)
post_signal(signal)