From d6dc38e64d183a3e5098bf5a77ea5d6cb33e936b Mon Sep 17 00:00:00 2001 From: LT3 <83487515+lessthnthree@users.noreply.github.com> Date: Fri, 16 Jan 2026 10:42:03 -0800 Subject: [PATCH] Cargo export gate can change payment accounts (#5121) ## About The Pull Request Allows the cargo export gate to be configured to pay out cargo techs, customs agents, and the QM based on the preference of the crew. ## Proof of Testing ## image ## Why It's Good For The Game Allows QM and Customs Agent to get a share of the bounty cube tips if desired. ## Changelog :cl: LT3 add: Customs agent and quartermaster accounts can receive a share of export gate payments if desired /:cl: --- code/__DEFINES/~~bubber_defines/machines.dm | 11 +++ .../modules/cargo/code/export_gate.dm | 96 +++++++++++++++++-- 2 files changed, 97 insertions(+), 10 deletions(-) diff --git a/code/__DEFINES/~~bubber_defines/machines.dm b/code/__DEFINES/~~bubber_defines/machines.dm index 5b1454283e3..30ac3515340 100644 --- a/code/__DEFINES/~~bubber_defines/machines.dm +++ b/code/__DEFINES/~~bubber_defines/machines.dm @@ -7,3 +7,14 @@ #define SCRAM_DIVINE_INTERVENTION "divine_intervention" /// how long from roundstart the scram is functional #define SCRAM_TIME_RESTRICTION (1 * 30 MINUTES) + +// Export gate settings +#define EX_CARGO_TECHNICIAN (1<<0) +#define EX_CUSTOMS_AGENT (1<<1) +#define EX_QUARTERMASTER (1<<2) + +DEFINE_BITFIELD(payment_mode, list( + "EX_CARGO_TECHNICIAN" = EX_CARGO_TECHNICIAN, + "EX_CUSTOMS_AGENT" = EX_CUSTOMS_AGENT, + "EX_QUARTERMASTER" = EX_QUARTERMASTER, +)) diff --git a/modular_skyrat/modules/cargo/code/export_gate.dm b/modular_skyrat/modules/cargo/code/export_gate.dm index 91381377a43..f1ade8d3ab3 100644 --- a/modular_skyrat/modules/cargo/code/export_gate.dm +++ b/modular_skyrat/modules/cargo/code/export_gate.dm @@ -20,6 +20,8 @@ icon = 'icons/obj/machines/scangate.dmi' icon_state = "scangate_black" circuit = /obj/item/circuitboard/machine/export_gate + /// Used to secure changing of payment mode + req_one_access = list(ACCESS_QM, ACCESS_ALL_PERSONAL_LOCKERS) /// Cooldown on the scanner's beep COOLDOWN_DECLARE(scanner_beep) /// Cooldown on payout calculation @@ -30,7 +32,9 @@ var/locked = FALSE /// The holding bank account used for the export gate var/datum/bank_account/holding_account - /// List of crew accounts who split the scanned bounties + /// Which crew members receive a share of the scanned bounties + var/payment_mode = EX_CARGO_TECHNICIAN | EX_CUSTOMS_AGENT + /// List of crew accounts associated with the current payment mode var/list/payment_accounts ///Our internal radio var/obj/item/radio/radio @@ -107,9 +111,11 @@ . += span_notice("The status display reads:") . += span_info("Income last cycle: [income_previous] cr.") . += span_info("Share per account last cycle: [income_share] cr.") + . += span_info("Payment mode: [display_payment_mode()].") . += span_info("Registered crew accounts last cycle: [LAZYLEN(payment_accounts)]") . += span_info("Total cubes registered: [cubes_registered]") . += span_info("Total income: [income_total] cr.") + . += span_notice("The payment mode can be changed by swiping an authorized command ID card.") /obj/machinery/export_gate/wrench_act(mob/living/user, obj/item/tool) default_unfasten_wrench(user, tool) @@ -176,22 +182,81 @@ cube.AddComponent(/datum/component/pricetag, holding_account, cube.handler_tip, FALSE) cube.bounty_handler_account = holding_account cubes_registered += 1 - var/message = "Cube value of [cube_value ? "+[floor(cube_value * cube.handler_tip)]+ credits " : ""]successfully registered." + var/message = "Cube value of [cube_value ? "[floor(cube_value * cube.handler_tip)] credits " : ""]successfully registered." say(message) for(var/datum/bank_account/tech_account as anything in payment_accounts) tech_account.bank_card_talk(message) -/obj/machinery/export_gate/proc/refresh_payment_accounts() - var/list/manifest_accounts = list() - var/list/cargo_tech_accounts = SSeconomy.bank_accounts_by_job[/datum/job/cargo_technician] - if(isnull(cargo_tech_accounts)) +#define MODE_CARGO_TECH "Cargo Technician" +#define MODE_CUSTOMS_AGENT "Cargo Technician / Customs Agent" +#define MODE_QUARTERMASTER "Cargo Technician / Customs Agent / Quartermaster" + +/obj/machinery/export_gate/proc/set_payment_mode(mob/user, obj/item/card/id/id_card) + var/list/payment_modes = list(MODE_CARGO_TECH, MODE_CUSTOMS_AGENT, MODE_QUARTERMASTER) + var/selected_mode = tgui_input_list(user, "Set bounty payment mode:", src.name, payment_modes) + if(!selected_mode) return - for(var/datum/bank_account/tech_account as anything in cargo_tech_accounts) - if(tech_account.off_duty_check()) - continue + switch(selected_mode) + if(MODE_CARGO_TECH) + payment_mode = EX_CARGO_TECHNICIAN + if(MODE_CUSTOMS_AGENT) + payment_mode = EX_CARGO_TECHNICIAN | EX_CUSTOMS_AGENT + if(MODE_QUARTERMASTER) + payment_mode = EX_CARGO_TECHNICIAN | EX_CUSTOMS_AGENT | EX_QUARTERMASTER - LAZYADD(manifest_accounts, tech_account) + log_econ("[src.name] payment mode changed by [user] ([id_card.registered_name]) to [display_payment_mode()].") + radio.talk_into(src, "Payment mode set to [display_payment_mode()] by authorized ID [id_card.registered_name].", RADIO_CHANNEL_SUPPLY) + +/obj/machinery/export_gate/proc/display_payment_mode() + if(payment_mode & EX_QUARTERMASTER) + return MODE_QUARTERMASTER + if(payment_mode & EX_CUSTOMS_AGENT) + return MODE_CUSTOMS_AGENT + else + return MODE_CARGO_TECH + +#undef MODE_CARGO_TECH +#undef MODE_CUSTOMS_AGENT +#undef MODE_QUARTERMASTER + +/obj/machinery/export_gate/proc/refresh_payment_accounts(retry = FALSE) + LAZYINITLIST(payment_accounts) + var/list/manifest_accounts = list() + var/list/CT_accounts = SSeconomy.bank_accounts_by_job[/datum/job/cargo_technician] + var/list/CA_accounts = SSeconomy.bank_accounts_by_job[/datum/job/customs_agent] + var/list/QM_accounts = SSeconomy.bank_accounts_by_job[/datum/job/quartermaster] + if(isnull(CT_accounts) && isnull(CA_accounts) && isnull(QM_accounts)) + return + + if(payment_mode & EX_CARGO_TECHNICIAN) + for(var/datum/bank_account/CT_account as anything in CT_accounts) + if(CT_account.off_duty_check()) + continue + + manifest_accounts += CT_account + + if(payment_mode & EX_CUSTOMS_AGENT) + for(var/datum/bank_account/CA_account as anything in CA_accounts) + if(CA_account.off_duty_check()) + continue + + manifest_accounts += CA_account + + if(payment_mode & EX_QUARTERMASTER) + for(var/datum/bank_account/QM_account as anything in QM_accounts) + if(QM_account.off_duty_check()) + continue + + manifest_accounts += QM_account + + // If there's nobody to pay, fallback to paying everyone + if(LAZYLEN(manifest_accounts) == 0 && !retry) + payment_mode = EX_CARGO_TECHNICIAN | EX_CUSTOMS_AGENT | EX_QUARTERMASTER + log_econ("[src.name] payment mode falling back to [display_payment_mode()] due to lack of crew") + radio.talk_into(src, "Payment mode falling back to [display_payment_mode()] due to lack of crew.", RADIO_CHANNEL_SUPPLY) + refresh_payment_accounts(retry = TRUE) + return payment_accounts = manifest_accounts @@ -221,6 +286,17 @@ else stack_trace("[src.name] attempted to perform a bounty cube export payment to [payout_account.account_holder], but it failed!") +/obj/machinery/export_gate/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + update_last_used(user) + var/obj/item/card/id/id_card = tool.GetID() + if(istype(id_card)) + if(check_access(id_card)) + set_payment_mode(user, id_card) + return ITEM_INTERACT_SUCCESS + else + user.balloon_alert(user, "insufficient access!") + return ITEM_INTERACT_BLOCKING + /datum/controller/subsystem/economy/issue_paydays() for(var/obj/machinery/export_gate/payout_gate as anything in SSmachines.get_machines_by_type_and_subtypes(/obj/machinery/export_gate)) payout_gate.disperse_earnings()