From 01534749dd1681a2989159f9d0eaa2fdb4aae37d Mon Sep 17 00:00:00 2001 From: Tim Date: Thu, 16 Jul 2026 09:04:44 -0500 Subject: [PATCH] Modular computers (PDAs) now shutdown when out of power (#96932) ## About The Pull Request This PR refactors modular computers (PDAs) so that they actually respect their power cells and shut down when they hit 0% charge. Previously, PDA power mechanics were essentially non-functional. While the flashlight would drain more power, it would never actually turn off when the battery died. Additionally, there was broken code intended to make the messenger program immune to power requirements. That immunity code was so buggy that it made all the power mechanics get ignored. To fix this, I gutted the broken immunity code. The marginal power draw of the messenger program is so tiny that it doesn't need exceptions. Now, when a modular computer runs out of power, everything, including the flashlight, shuts off completely. ## Why It's Good For The Game Right now, the power mechanics for modular computers are effectively LARP that does nothing. Players now have a tangible reason to conserve power and seek out upgraded power cells if they plan on heavily utilizing their PDA's features. It's balanced so that you'd have to be quite careless with the flashlight to completely drain a standard battery. It adds consequence without being overly punishing to the average crewmember. ## Changelog :cl: balance: Modular computers (PDAs) now shutdown when out of power fix: PDA flashlights now turn off when out of power sound: Added a terminal off switch sound to PDAs when power runs out /:cl: --- code/__DEFINES/modular_computer.dm | 4 +--- .../modular_computers/computers/item/computer.dm | 1 + .../computers/item/computer_power.dm | 13 +++---------- .../modular_computers/file_system/computer_file.dm | 2 -- .../modular_computers/file_system/program.dm | 2 +- .../programs/messenger/messenger_program.dm | 2 +- 6 files changed, 7 insertions(+), 17 deletions(-) diff --git a/code/__DEFINES/modular_computer.dm b/code/__DEFINES/modular_computer.dm index e80d91f4bb4..f8bd39e2b3d 100644 --- a/code/__DEFINES/modular_computer.dm +++ b/code/__DEFINES/modular_computer.dm @@ -26,10 +26,8 @@ #define PROGRAM_UNIQUE_COPY (1<<3) ///The program is a header and will show up at the top of the ModPC's UI. #define PROGRAM_HEADER (1<<4) -///The program will run despite the ModPC not having any power in it. -#define PROGRAM_RUNS_WITHOUT_POWER (1<<5) ///The circuit ports of this program can be triggered even if the program is not open -#define PROGRAM_CIRCUITS_RUN_WHEN_CLOSED (1<<6) +#define PROGRAM_CIRCUITS_RUN_WHEN_CLOSED (1<<5) //Program categories #define PROGRAM_CATEGORY_DEVICE "Device Tools" diff --git a/code/modules/modular_computers/computers/item/computer.dm b/code/modules/modular_computers/computers/item/computer.dm index 1a6cb5013a2..f02176d50b1 100644 --- a/code/modules/modular_computers/computers/item/computer.dm +++ b/code/modules/modular_computers/computers/item/computer.dm @@ -796,6 +796,7 @@ if(looping_sound) soundloop.stop() if(physical && loud) + playsound(src, 'sound/machines/terminal/terminal_off.ogg', 25, FALSE) physical.visible_message(span_notice("\The [src] shuts down.")) enabled = FALSE update_appearance() diff --git a/code/modules/modular_computers/computers/item/computer_power.dm b/code/modules/modular_computers/computers/item/computer_power.dm index 5cfc6580342..2dd51d3ab2a 100644 --- a/code/modules/modular_computers/computers/item/computer_power.dm +++ b/code/modules/modular_computers/computers/item/computer_power.dm @@ -6,20 +6,14 @@ /obj/item/modular_computer/proc/use_energy(amount = 0, check_programs = TRUE) if(check_power_override(amount)) return TRUE - if(!internal_cell) return FALSE if(!amount || internal_cell.use(amount)) return TRUE if(!check_programs) return FALSE - internal_cell.use(min(amount, internal_cell.charge)) //drain it anyways. - if(active_program?.program_flags & PROGRAM_RUNS_WITHOUT_POWER) - return TRUE + INVOKE_ASYNC(src, PROC_REF(close_all_programs)) - for(var/datum/computer_file/program/programs as anything in stored_files) - if((programs.program_flags & PROGRAM_RUNS_WITHOUT_POWER) && open_program(program = programs)) - return TRUE return FALSE /obj/item/modular_computer/proc/give_power(amount) @@ -37,7 +31,7 @@ set_light_on(FALSE) for(var/datum/computer_file/program/programs as anything in idle_threads) programs.event_powerfailure() - shutdown_computer(loud = FALSE) + shutdown_computer() ///Takes the charge necessary from the Computer, shutting it off if it's unable to provide it. ///Charge depends on whether the PC is on, and what programs are running/idle on it. @@ -59,9 +53,8 @@ return FALSE ///Returns TRUE if the PC should not be using any power, FALSE otherwise. -///Checks to see if the current app allows to be ran without power, if so we'll run with it. /obj/item/modular_computer/proc/check_power_override(amount) - return !amount && !internal_cell?.charge && (active_program?.program_flags & PROGRAM_RUNS_WITHOUT_POWER) + return !amount && !internal_cell?.charge //Integrated (Silicon) tablets don't drain power, because the tablet is required to state laws, so it being disabled WILL cause problems. /obj/item/modular_computer/pda/silicon/check_power_override() diff --git a/code/modules/modular_computers/file_system/computer_file.dm b/code/modules/modular_computers/file_system/computer_file.dm index 768b2c29ebb..a13618c17b9 100644 --- a/code/modules/modular_computers/file_system/computer_file.dm +++ b/code/modules/modular_computers/file_system/computer_file.dm @@ -87,8 +87,6 @@ * * background - Whether the app is running in the background. */ /datum/computer_file/program/proc/event_powerfailure() - if(program_flags & PROGRAM_RUNS_WITHOUT_POWER) - return kill_program() /** diff --git a/code/modules/modular_computers/file_system/program.dm b/code/modules/modular_computers/file_system/program.dm index 215849b02c1..84e3c78aa84 100644 --- a/code/modules/modular_computers/file_system/program.dm +++ b/code/modules/modular_computers/file_system/program.dm @@ -8,7 +8,7 @@ /// (PROGRAM_ALL | PROGRAM_CONSOLE | PROGRAM_LAPTOP | PROGRAM_PDA) var/can_run_on_flags = PROGRAM_ALL /// Program-specific bitflags that tells the ModPC what the app is able to do special. - /// (PROGRAM_REQUIRES_NTNET|PROGRAM_ON_NTNET_STORE|PROGRAM_ON_SYNDINET_STORE|PROGRAM_UNIQUE_COPY|PROGRAM_HEADER|PROGRAM_RUNS_WITHOUT_POWER) + /// (PROGRAM_REQUIRES_NTNET|PROGRAM_ON_NTNET_STORE|PROGRAM_ON_SYNDINET_STORE|PROGRAM_UNIQUE_COPY|PROGRAM_HEADER) var/program_flags = PROGRAM_ON_NTNET_STORE ///How much power running this program costs. var/power_cell_use = PROGRAM_BASIC_CELL_USE diff --git a/code/modules/modular_computers/file_system/programs/messenger/messenger_program.dm b/code/modules/modular_computers/file_system/programs/messenger/messenger_program.dm index e393ff2a60f..9096314200c 100644 --- a/code/modules/modular_computers/file_system/programs/messenger/messenger_program.dm +++ b/code/modules/modular_computers/file_system/programs/messenger/messenger_program.dm @@ -14,7 +14,7 @@ size = 0 undeletable = TRUE // It comes by default in tablets, can't be downloaded, takes no space and should obviously not be able to be deleted. power_cell_use = NONE - program_flags = PROGRAM_HEADER | PROGRAM_RUNS_WITHOUT_POWER | PROGRAM_CIRCUITS_RUN_WHEN_CLOSED + program_flags = PROGRAM_HEADER | PROGRAM_CIRCUITS_RUN_WHEN_CLOSED can_run_on_flags = PROGRAM_PDA ui_header = "ntnrc_idle.gif" tgui_id = "NtosMessenger"