Fixes the tram's schrodinger-like power consumption (#81122)

## About The Pull Request

Fixes https://github.com/tgstation/tgstation/issues/81106. The tram's
dynamic power use does not get recalculated when leaving an area because
the powernet between areas is made for static loads, This leads to APCs
being drained quickly consuming too much power, or consuming negative
energy leading to an APC being charged.

The amount of times use_power is called on tram crossing signals during
processing also leads to unexpected power consumption.

This moves tram power to a rectifier machinery object in each area,
controlled by signals from the tram. Tram crossing signals are fixed in
how they consume power, changing between power use states instead of
consuming during processing, and moved from the transport subsystem to
fastprocess because they don't need to be running at 20fps.

## Why It's Good For The Game

Tram draining an APC in a matter of seconds is bad. Tram having negative
power draw at other times is also bad.


![image](https://github.com/tgstation/tgstation/assets/83487515/e49cbabe-1b21-4af2-b940-c3ab9fcdbcda)

## Changelog

🆑 LT3
fix: Tram power consumption will no longer will randomly drain APCs
fix: Tram power moved to area based rectifiers
/🆑

---------

Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com>
This commit is contained in:
lessthanthree
2024-01-31 00:05:58 +01:00
committed by GitHub
co-authored by Ghom
parent 27ff720217
commit 1c0c0805a2
9 changed files with 138 additions and 20 deletions
+18 -2
View File
@@ -19967,6 +19967,9 @@
/obj/effect/decal/cleanable/dirt,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/transport/power_rectifier{
configured_transport_id = "bird_2"
},
/turf/open/floor/iron,
/area/station/maintenance/department/medical/central)
"hic" = (
@@ -38174,6 +38177,13 @@
"nCH" = (
/turf/closed/wall/r_wall,
/area/station/security)
"nCL" = (
/obj/effect/mapping_helpers/broken_floor,
/obj/machinery/transport/power_rectifier{
configured_transport_id = "bird_2"
},
/turf/open/floor/iron,
/area/station/maintenance/port/aft)
"nCR" = (
/obj/effect/decal/cleanable/dirt,
/obj/effect/turf_decal/stripes/line,
@@ -39094,6 +39104,12 @@
/obj/machinery/camera/autoname/directional/south,
/turf/open/floor/iron,
/area/station/hallway/secondary/dock)
"nTy" = (
/obj/machinery/transport/power_rectifier{
configured_transport_id = "bird_1"
},
/turf/open/floor/plating,
/area/station/security/tram)
"nTz" = (
/obj/effect/turf_decal/tile/yellow/anticorner/contrasted,
/obj/machinery/chem_dispenser{
@@ -86835,7 +86851,7 @@ dwa
dBr
eWB
lzM
aFR
nTy
mnb
cDt
xpV
@@ -91471,7 +91487,7 @@ trp
trp
trp
trp
nFu
nCL
xqd
xul
trp
+27 -5
View File
@@ -4436,6 +4436,7 @@
/obj/effect/turf_decal/siding/thinplating/corner{
dir = 4
},
/obj/machinery/airalarm/directional/north,
/turf/open/floor/iron,
/area/station/hallway/primary/tram/center)
"aEn" = (
@@ -25158,6 +25159,16 @@
},
/turf/open/floor/glass/reinforced,
/area/station/science/genetics)
"hXW" = (
/obj/effect/turf_decal/trimline/red/filled/line{
dir = 1
},
/obj/effect/turf_decal/trimline/neutral/filled/warning{
dir = 1
},
/obj/machinery/transport/power_rectifier,
/turf/open/floor/iron,
/area/station/hallway/primary/tram/right)
"hYd" = (
/obj/structure/lattice/catwalk,
/obj/machinery/atmospherics/pipe/smart/simple/green/visible,
@@ -48464,6 +48475,7 @@
"qfQ" = (
/obj/structure/cable,
/obj/machinery/power/apc/auto_name/directional/east,
/obj/machinery/transport/power_rectifier,
/turf/open/floor/catwalk_floor,
/area/station/hallway/primary/tram/right)
"qfS" = (
@@ -52307,6 +52319,16 @@
},
/turf/open/floor/iron,
/area/station/commons/dorms)
"rxI" = (
/obj/effect/turf_decal/trimline/neutral/filled/line{
dir = 1
},
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/transport/power_rectifier,
/turf/open/floor/iron,
/area/station/hallway/primary/tram/left)
"rxN" = (
/obj/machinery/photocopier,
/obj/structure/extinguisher_cabinet/directional/north,
@@ -58208,7 +58230,7 @@
/obj/effect/turf_decal/trimline/neutral/filled/line{
dir = 1
},
/obj/machinery/airalarm/directional/north,
/obj/machinery/transport/power_rectifier,
/turf/open/floor/iron,
/area/station/hallway/primary/tram/center)
"tBa" = (
@@ -154215,7 +154237,7 @@ aQO
aQO
aQO
aQO
qhM
rxI
nYq
yiM
cFs
@@ -167835,7 +167857,7 @@ izU
izU
izU
izU
hce
izU
tAL
sOD
izU
@@ -170405,7 +170427,7 @@ izU
izU
izU
izU
izU
hce
aEm
gnK
izU
@@ -180943,7 +180965,7 @@ jnJ
ged
whL
vUE
aEz
hXW
yeB
ipC
seR
@@ -128,6 +128,7 @@
/datum/transport_controller/linear/tram/Destroy()
paired_cabinet = null
set_status_code(SYSTEM_FAULT, TRUE)
SEND_SIGNAL(SStransport, COMSIG_TRANSPORT_ACTIVE, src, FALSE, controller_status, travel_direction, destination_platform)
tram_registration.active = FALSE
SSblackbox.record_feedback("amount", "tram_destroyed", 1)
SSpersistence.save_tram_history(specific_transport_id)
@@ -528,6 +529,7 @@
paired_cabinet = null
log_transport("TC: [specific_transport_id] received QDEL from controller cabinet.")
set_status_code(SYSTEM_FAULT, TRUE)
send_transport_active_signal()
/**
* Tram malfunction random event. Set comm error, increase tram lethality.
@@ -686,8 +688,8 @@
integrity_failure = 0.25
layer = SIGN_LAYER
req_access = list(ACCESS_TCOMMS)
idle_power_usage = BASE_MACHINE_IDLE_CONSUMPTION * 4.8
active_power_usage = BASE_MACHINE_ACTIVE_CONSUMPTION * 4.8
idle_power_usage = BASE_MACHINE_IDLE_CONSUMPTION * 0.25
power_channel = AREA_USAGE_ENVIRON
var/datum/transport_controller/linear/tram/controller_datum
/// If the cover is open
var/cover_open = FALSE
@@ -742,6 +744,9 @@
return CONTEXTUAL_SCREENTIP_SET
/obj/machinery/transport/tram_controller/update_current_power_usage()
return // We get power from area rectifiers
/obj/machinery/transport/tram_controller/examine(mob/user)
. = ..()
. += span_notice("The door appears to be [cover_locked ? "locked. Swipe an ID card to unlock" : "unlocked. Swipe an ID card to lock"].")
@@ -9,6 +9,8 @@
density = FALSE
max_integrity = 400
integrity_failure = 0.1
power_channel = AREA_USAGE_ENVIRON
idle_power_usage = BASE_MACHINE_IDLE_CONSUMPTION * 0.25
armor_type = /datum/armor/transport_machinery
circuit = /obj/item/circuitboard/computer/tram_controls
light_color = COLOR_BLUE_LIGHT
@@ -64,6 +66,9 @@
if(tram)
RegisterSignal(SStransport, COMSIG_TRANSPORT_ACTIVE, PROC_REF(update_display))
/obj/machinery/computer/tram_controls/update_current_power_usage()
return // We get power from area rectifiers
/**
* Finds the tram from the console
*
+73
View File
@@ -0,0 +1,73 @@
/obj/machinery/transport/power_rectifier
name = "tram power rectifier"
desc = "An electrical device that converts alternating current (AC) to direct current (DC) for powering the tram."
icon = 'icons/obj/tram/tram_controllers.dmi'
icon_state = "rectifier"
idle_power_usage = BASE_MACHINE_IDLE_CONSUMPTION * 11.4
active_power_usage = BASE_MACHINE_ACTIVE_CONSUMPTION * 114
power_channel = AREA_USAGE_ENVIRON
anchored = TRUE
density = FALSE
armor_type = /datum/armor/transport_module
resistance_flags = LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
max_integrity = 750
pixel_y = 32
/// The tram platform we're connected to and providing power
var/obj/effect/landmark/transport/nav_beacon/tram/platform/connected_platform
/obj/machinery/transport/power_rectifier/Initialize(mapload)
. = ..()
return INITIALIZE_HINT_LATELOAD
/obj/machinery/transport/power_rectifier/LateInitialize(mapload)
. = ..()
RegisterSignal(SStransport, COMSIG_TRANSPORT_ACTIVE, PROC_REF(power_tram))
find_platform()
/**
* The mapper should have placed the rectifier in the area containing the station, the object will search for a landmark within
* its control area and set its idle position.
*/
/obj/machinery/transport/power_rectifier/proc/find_platform()
var/area/my_area = get_area(src)
for(var/obj/effect/landmark/transport/nav_beacon/tram/platform/candidate_platform in SStransport.nav_beacons[configured_transport_id])
if(get_area(candidate_platform) == my_area)
connected_platform = candidate_platform
RegisterSignal(connected_platform, COMSIG_QDELETING, PROC_REF(on_landmark_qdel))
log_transport("[id_tag]: Power rectifier linked to landmark [connected_platform.name]")
return
/obj/machinery/transport/power_rectifier/proc/power_tram(datum/source, datum/transport_controller/linear/tram/controller, controller_active, controller_status, travel_direction, obj/effect/landmark/transport/nav_beacon/tram/platform/destination_platform)
SIGNAL_HANDLER
if(controller_active && destination_platform == connected_platform)
update_use_power(ACTIVE_POWER_USE)
else
update_use_power(IDLE_POWER_USE)
update_appearance()
/**
* Update the lights based on the rectifier status.
*/
/obj/machinery/transport/power_rectifier/update_overlays()
. = ..()
if(machine_stat & NOPOWER)
. += mutable_appearance(icon, "rec-power-0")
. += emissive_appearance(icon, "rec-power-0", src, alpha = src.alpha)
return
. += mutable_appearance(icon, "rec-power-1")
. += emissive_appearance(icon, "rec-power-1", src, alpha = src.alpha)
var/is_active = use_power == ACTIVE_POWER_USE
. += mutable_appearance(icon, "rec-active-[is_active]")
. += emissive_appearance(icon, "rec-active-[is_active]", src, alpha = src.alpha)
/**
* Clear reference to the connected landmark if it gets destroyed.
*/
/obj/machinery/transport/power_rectifier/proc/on_landmark_qdel()
log_transport("[id_tag]: Power rectifier received QDEL from landmark [connected_platform.name]")
connected_platform = null
+7 -9
View File
@@ -10,13 +10,13 @@
integrity_failure = 0.25
light_range = 2
light_power = 0.7
idle_power_usage = BASE_MACHINE_IDLE_CONSUMPTION * 2.4
active_power_usage = BASE_MACHINE_ACTIVE_CONSUMPTION * 0.48
idle_power_usage = BASE_MACHINE_IDLE_CONSUMPTION * 3.6
active_power_usage = BASE_MACHINE_ACTIVE_CONSUMPTION * 0.72
anchored = TRUE
density = FALSE
circuit = /obj/item/circuitboard/machine/crossing_signal
// pointless if it only takes 2 seconds to cross but updates every 2 seconds
subsystem_type = /datum/controller/subsystem/processing/transport
subsystem_type = /datum/controller/subsystem/processing/fastprocess
light_color = LIGHT_COLOR_BABY_BLUE
/// green, amber, or red for tram, blue if it's emag, tram missing, etc.
var/signal_state = XING_STATE_MALF
@@ -74,8 +74,7 @@
layer = TRAM_SIGNAL_LAYER
max_integrity = 250
integrity_failure = 0.25
idle_power_usage = BASE_MACHINE_IDLE_CONSUMPTION * 2.4
active_power_usage = BASE_MACHINE_ACTIVE_CONSUMPTION * 0.74
idle_power_usage = BASE_MACHINE_IDLE_CONSUMPTION * 3.6
anchored = TRUE
density = FALSE
light_range = 1.5
@@ -308,13 +307,14 @@
* Returns whether we are still processing.
*/
/obj/machinery/transport/crossing_signal/proc/update_operating()
use_power(idle_power_usage)
update_appearance()
// Immediately process for snappy feedback
var/should_process = process() != PROCESS_KILL
if(should_process)
update_use_power(ACTIVE_POWER_USE)
begin_processing()
return
update_use_power(IDLE_POWER_USE)
end_processing()
/obj/machinery/transport/crossing_signal/process()
@@ -328,8 +328,6 @@
set_signal_state(XING_STATE_MALF, force = !is_operational)
return PROCESS_KILL
use_power(active_power_usage)
var/obj/structure/transport/linear/tram_part = tram.return_closest_platform_to(src)
if(QDELETED(tram_part))
@@ -499,7 +497,7 @@
icon_state = "sensor-base"
desc = "Uses an infrared beam to detect passing trams. Works when paired with a sensor on the other side of the track."
layer = TRAM_RAIL_LAYER
use_power = 0
use_power = NO_POWER_USE
circuit = /obj/item/circuitboard/machine/guideway_sensor
/// Sensors work in a married pair
var/datum/weakref/paired_sensor
@@ -931,8 +931,6 @@
addtimer(CALLBACK(src, PROC_REF(clear_turfs), turfs, iterations), 1)
/obj/structure/transport/linear/tram/proc/estop_throw(throw_direction)
if(prob(50))
do_sparks(2, FALSE, src)
for(var/mob/living/passenger in transport_contents)
to_chat(passenger, span_userdanger("The tram comes to a sudden, grinding stop!"))
var/throw_target = get_edge_target_turf(src, throw_direction)
Binary file not shown.

Before

Width:  |  Height:  |  Size: 800 B

After

Width:  |  Height:  |  Size: 1.3 KiB

+1
View File
@@ -5816,6 +5816,7 @@
#include "code\modules\transport\tram\tram_doors.dm"
#include "code\modules\transport\tram\tram_floors.dm"
#include "code\modules\transport\tram\tram_machinery.dm"
#include "code\modules\transport\tram\tram_power.dm"
#include "code\modules\transport\tram\tram_remote.dm"
#include "code\modules\transport\tram\tram_signals.dm"
#include "code\modules\transport\tram\tram_structures.dm"