From e4cd90631f13f7bee61d4531cca84b4654f70cff Mon Sep 17 00:00:00 2001 From: ynot01 Date: Wed, 8 Jan 2025 01:32:46 -0500 Subject: [PATCH 1/2] pay our doctors --- code/game/objects/items/cards_ids.dm | 28 ++-- code/modules/economy/healthcare.dm | 155 +++++++++++++++++++ tgui/packages/tgui/interfaces/Healthcare.tsx | 86 ++++++++++ yogstation.dme | 1 + 4 files changed, 256 insertions(+), 14 deletions(-) create mode 100644 code/modules/economy/healthcare.dm create mode 100644 tgui/packages/tgui/interfaces/Healthcare.tsx diff --git a/code/game/objects/items/cards_ids.dm b/code/game/objects/items/cards_ids.dm index 7e91ff0ec0bb..737394c9b1e8 100644 --- a/code/game/objects/items/cards_ids.dm +++ b/code/game/objects/items/cards_ids.dm @@ -108,7 +108,7 @@ . = ..() var/atom/A = target if(!proximity && prox_check) - return + return if(charges < 1) to_chat(user, span_danger("\The [src] is still recharging!")) return @@ -206,7 +206,7 @@ /obj/item/card/cmag/afterattack(atom/target, mob/user, proximity) . = ..() if(!proximity && prox_check) - return + return if(charges < 1) to_chat(user, span_danger("\The [src] is still recharging!")) return @@ -285,7 +285,7 @@ cyborg.SetStun(60) // Gives you time to run if needed. cyborg.module.transform_to(/obj/item/robot_module/clown) // No law change, but they get to clown around instead. return - + cyborg.SetStun(60) // Standard stun like from emagging. cyborg.lawupdate = FALSE cyborg.set_connected_ai(null) @@ -314,7 +314,7 @@ cyborg.laws = new /datum/ai_laws/pranksimov cyborg.laws.associate(cyborg) - + cyborg.update_icons() return @@ -426,7 +426,7 @@ else to_chat(user, span_notice("You insert [I] into [src], adding [cash_money] credits to the linked account.")) - to_chat(user, span_notice("The linked account now reports a balance of $[registered_account.account_balance].")) + to_chat(user, span_notice("The linked account now reports a [registered_account.account_balance >= 0 ? "balance" : "debt"] of $[registered_account.account_balance].")) qdel(I) @@ -527,11 +527,11 @@ . += "There's [mining_points] mining equipment redemption point\s loaded onto this card." if(registered_account) - . += "The account linked to the ID belongs to '[registered_account.account_holder]' and reports a balance of $[registered_account.account_balance]." + . += "The account linked to the ID belongs to '[registered_account.account_holder]' and reports a [registered_account.account_balance >= 0 ? "balance" : "debt"] of $[registered_account.account_balance]." if(registered_account.account_job) var/datum/bank_account/D = SSeconomy.get_dep_account(registered_account.account_job.paycheck_department) if(D) - . += "The [D.account_holder] reports a balance of $[D.account_balance]." + . += "The [D.account_holder] reports a [D.account_balance >= 0 ? "balance" : "debt"] of $[D.account_balance]." . += span_info("Alt-Click the ID to pull money from the linked account in the form of holochips.") . += span_info("You can insert credits into the linked account by pressing holochips, cash, or coins against the ID.") if(registered_account.account_holder == user.real_name) @@ -1111,11 +1111,11 @@ update_label("John Doe", "Clowny") department_name = ACCOUNT_SEC_NAME /*** - * - * + * + * * HERETIC ID SECTION (SORRY) - * - * + * + * */ /obj/effect/knock_portal @@ -1141,7 +1141,7 @@ update_label("John Doe", "Clowny") if(target) our_airlock = target RegisterSignal(target, COMSIG_QDELETING, PROC_REF(delete_on_door_delete)) - + var/static/list/loc_connections = list( COMSIG_ATOM_ENTERED = PROC_REF(on_entered), ) @@ -1231,7 +1231,7 @@ update_label("John Doe", "Clowny") /obj/item/card/id/syndicate/heretic/proc/clear_portals() QDEL_NULL(portal_one) - QDEL_NULL(portal_two) + QDEL_NULL(portal_two) ///Clears portal references /obj/item/card/id/syndicate/heretic/proc/clear_portal_refs() @@ -1245,7 +1245,7 @@ update_label("John Doe", "Clowny") if(portal_one || portal_two) clear_portals() message += ", previous cleared" - + portal_one = new(get_turf(door2), door2) portal_two = new(get_turf(door1), door1) portal_one.destination = portal_two diff --git a/code/modules/economy/healthcare.dm b/code/modules/economy/healthcare.dm new file mode 100644 index 000000000000..5ec0a8767d35 --- /dev/null +++ b/code/modules/economy/healthcare.dm @@ -0,0 +1,155 @@ +#define CARE_BASIC_CHECKUP "Basic Checkup" +#define CARE_VACCINATION "Vaccination" +#define CARE_MINOR_SURGERY "Minor Surgery" +#define CARE_MAJOR_SURGERY "Major Surgery" +#define CARE_EMERGENCY "Emergency Care" +#define CARE_PRESCRIPTION "Prescription" +#define CARE_MENTAL "Mental Health Consultataion" + +/// This machine is designed to encourage medical staff to charge patients exorbitant prices for basic care +/obj/machinery/healthcare_computer + name = "healthcare computer" + desc = "A convenient and user-friendly computer interface for all of your healthcare needs." + icon = 'yogstation/icons/obj/register.dmi' + icon_state = "register" + clicksound = "keyboard" + anchored = TRUE + density = TRUE + resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF // death & taxes + flags_1 = NODECONSTRUCT_1 + var/obj/item/radio/radio + var/current_price = 0 + var/list/selected_care + var/static/list/available_care + var/department_tax = 0.08 + +/obj/machinery/healthcare_computer/Initialize(mapload) + . = ..() + radio = new(src) + radio.keyslot = new /obj/item/encryptionkey/headset_med + radio.subspace_transmission = TRUE + radio.listening = FALSE + radio.recalculateChannels() + + if(available_care && islist(available_care)) + return + + available_care = list( + CARE_BASIC_CHECKUP = floor(50 * (1.0 + department_tax)), + CARE_VACCINATION = floor(75 * (1.0 + department_tax)), + CARE_MINOR_SURGERY = floor(150 * (1.0 + department_tax)), + CARE_MAJOR_SURGERY = floor(300 * (1.0 + department_tax)), + CARE_EMERGENCY = floor(200 * (1.0 + department_tax)), + CARE_PRESCRIPTION = floor(100 * (1.0 + department_tax)), + CARE_MENTAL = floor(100 * (1.0 + department_tax)), + ) + +/obj/machinery/healthcare_computer/attack_hand(mob/living/user, list/modifiers) + . = ..() + if(.) + return + if(!user.combat_mode && user.stat == CONSCIOUS) + ui_interact(user) + return . + return + +/obj/machinery/healthcare_computer/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!is_operational()) + return + if (!ui) + ui = new(user, src, "Healthcare", name) + ui.open() + +/obj/machinery/healthcare_computer/ui_data(mob/user) + . = ..() + var/payee = "none" + var/obj/item/card/id/card = user.get_idcard(TRUE) + if(card?.registered_account?.account_holder) + payee = card.registered_account.account_holder + .["payee"] = payee + .["current_price"] = current_price + .["selected_care"] = selected_care + .["available_care"] = available_care + +/obj/machinery/healthcare_computer/ui_act(action, list/params) + if(..()) + return TRUE + if(!is_operational()) + return + + switch(action) + if("toggle_care") + var/care_name = params["care"] + if(!istext(care_name)) + return + if(!available_care[care_name]) + return + if(!selected_care) + selected_care = list() + if(care_name in selected_care) + selected_care -= care_name + current_price -= available_care[care_name] + else + selected_care |= care_name + current_price += available_care[care_name] + return TRUE + if("pay_for_care") + var/card = usr.get_idcard(TRUE) + if(!card) + return + if(!charge_card(card)) + return + return TRUE + +/obj/machinery/healthcare_computer/proc/charge_card(obj/item/card/id/victim) + if(!victim.registered_account) + return FALSE + if(current_price <= 0) + return FALSE + if(!selected_care || !islist(selected_care) || selected_care.len == 0) + return FALSE + if(!victim || !istype(victim)) + return FALSE + + victim.registered_account._adjust_money(-current_price) // can't pay? it's ok, you'll just go into debt + . = TRUE + + var/list/datum/bank_account/payouts = list() + var/m_staff_amt = 0 + for(var/datum/bank_account/account_id as anything in SSeconomy.bank_accounts) + var/datum/bank_account/account = SSeconomy.bank_accounts[account_id] + if(account.account_job && (account.account_job.title in GLOB.medical_positions)) + payouts += account + m_staff_amt += 1 + + var/datum/bank_account/med_account = SSeconomy.get_dep_account(ACCOUNT_MED) + med_account.adjust_money(floor(current_price * department_tax)) + var/after_tax = current_price * (1.0 - department_tax) + + var/payout_amt = floor(after_tax / m_staff_amt) + for(var/datum/bank_account/medical_staff as anything in payouts) + medical_staff.adjust_money(payout_amt) + + var/care = selected_care.Join(", ") + radio.talk_into(src, "[victim.registered_account.account_holder] has paid for [care]. Medical staff have been paid [payout_amt]cr each.", RADIO_CHANNEL_MEDICAL) + + current_price = 0 + selected_care = null + + say("Thank you for your patronage, [victim.registered_account.account_holder]! Medical staff have been paid and notified. You are entitled to the following: [care]") + + if(!victim.registered_account.has_money(-950)) // fraud prevention. id is shredded, debt remains on account + victim.registered_account.bank_card_talk("Severe debt fraud detected! This ID will now self-destruct. Please contact a member of command to be issued a new ID.", TRUE) + qdel(victim) + playsound(src.loc, 'sound/items/pshred.ogg', 75, TRUE) + else + playsound(src.loc, 'sound/effects/cashregister.ogg', 20, TRUE) + +#undef CARE_BASIC_CHECKUP +#undef CARE_VACCINATION +#undef CARE_MINOR_SURGERY +#undef CARE_MAJOR_SURGERY +#undef CARE_EMERGENCY +#undef CARE_PRESCRIPTION +#undef CARE_MENTAL diff --git a/tgui/packages/tgui/interfaces/Healthcare.tsx b/tgui/packages/tgui/interfaces/Healthcare.tsx new file mode 100644 index 000000000000..269f170a072b --- /dev/null +++ b/tgui/packages/tgui/interfaces/Healthcare.tsx @@ -0,0 +1,86 @@ +import { useBackend } from '../backend'; +import { Button, Box, Table, Section } from '../components'; +import { Window } from '../layouts'; + +type HealthcareData = { + payee: string; + current_price: number; + selected_care: string[] | null; + available_care: any; +}; +// https://i.imgur.com/AQlT2gV.png +export const Healthcare = (props, context) => { + const { act, data } = useBackend(context); + return ( + + +
+ + {data.selected_care?.map((val, idx) => ( + + + {val} + + + {data.available_care[val]+'cr'} + + + ))} + + + Total + + + { + (data.selected_care === null || data.selected_care.length === 0) ? '0' : + ( + data.selected_care.length === 1 ? data.available_care[data.selected_care[0]] : + ( + data.selected_care?.reduce( + (acc, curr) => + ( + ((acc in data.available_care) ? data.available_care[acc] : acc) + data.available_care[curr] + ) + ) + ) + ) + }cr + + + + act('pay_for_care')} /> + +
+
+
+ {Object.entries(data.available_care).map((key, idx) => ( +
+
+
+ ); +}; diff --git a/yogstation.dme b/yogstation.dme index 3d2cdc363ce1..2a67d5c5bead 100644 --- a/yogstation.dme +++ b/yogstation.dme @@ -2415,6 +2415,7 @@ #include "code\modules\discord\manipulation.dm" #include "code\modules\economy\_economy.dm" #include "code\modules\economy\account.dm" +#include "code\modules\economy\healthcare.dm" #include "code\modules\economy\pay_stand.dm" #include "code\modules\emoji\emoji_parse.dm" #include "code\modules\error_handler\error_handler.dm" From a103250782bbdca38e11da28611af2d3b58495e1 Mon Sep 17 00:00:00 2001 From: ynot01 Date: Wed, 8 Jan 2025 01:40:38 -0500 Subject: [PATCH 2/2] move fraud check up --- code/modules/economy/healthcare.dm | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/code/modules/economy/healthcare.dm b/code/modules/economy/healthcare.dm index 5ec0a8767d35..7d39c5c705d8 100644 --- a/code/modules/economy/healthcare.dm +++ b/code/modules/economy/healthcare.dm @@ -112,6 +112,12 @@ if(!victim || !istype(victim)) return FALSE + if(!victim.registered_account.has_money(-1050)) + victim.registered_account.bank_card_talk("Severe debt fraud detected! This ID will now self-destruct. Please contact a member of command to be issued a new ID.", TRUE) + qdel(victim) + playsound(src.loc, 'sound/items/pshred.ogg', 75, TRUE) + return + victim.registered_account._adjust_money(-current_price) // can't pay? it's ok, you'll just go into debt . = TRUE @@ -138,13 +144,7 @@ selected_care = null say("Thank you for your patronage, [victim.registered_account.account_holder]! Medical staff have been paid and notified. You are entitled to the following: [care]") - - if(!victim.registered_account.has_money(-950)) // fraud prevention. id is shredded, debt remains on account - victim.registered_account.bank_card_talk("Severe debt fraud detected! This ID will now self-destruct. Please contact a member of command to be issued a new ID.", TRUE) - qdel(victim) - playsound(src.loc, 'sound/items/pshred.ogg', 75, TRUE) - else - playsound(src.loc, 'sound/effects/cashregister.ogg', 20, TRUE) + playsound(src.loc, 'sound/effects/cashregister.ogg', 20, TRUE) #undef CARE_BASIC_CHECKUP #undef CARE_VACCINATION