Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pay our doctors [Healthcare Computer] #22948

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 14 additions & 14 deletions code/game/objects/items/cards_ids.dm
Original file line number Diff line number Diff line change
@@ -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" : "<b>debt</b>"] 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" : "<b>debt</b>"] 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" : "<b>debt</b>"] 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
155 changes: 155 additions & 0 deletions code/modules/economy/healthcare.dm
Original file line number Diff line number Diff line change
@@ -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

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

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]")
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
86 changes: 86 additions & 0 deletions tgui/packages/tgui/interfaces/Healthcare.tsx
Original file line number Diff line number Diff line change
@@ -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<HealthcareData>(context);
return (
<Window
width={400}
height={500}>
<Window.Content>
<Section title="Order" height={28}>
<Table>
{data.selected_care?.map((val, idx) => (
<Table.Row key={idx} style={{
'border': '2px solid',
'border-color': '#4d4d4d',
'background-color': '#007cb2',
}}>
<Table.Cell px={1} py={1}>
{val}
</Table.Cell>
<Table.Cell bold collapsing minWidth={5}>
{data.available_care[val]+'cr'}
</Table.Cell>
</Table.Row>
))}
<Table.Row style={{
'border': '2px solid',
'border-color': '#4d4d4d',
'background-color': '#39888a',
}}>
<Table.Cell bold px={2} py={2}>
Total
</Table.Cell>
<Table.Cell bold collapsing minWidth={5}>
{
(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
</Table.Cell>
</Table.Row>
<Table.Row>
<Button.Confirm
mx={1}
my={1}
px={1}
py={1}
disabled={data.selected_care === null || data.selected_care.length === 0}
content='Checkout'
onClick={() => act('pay_for_care')} />
</Table.Row>
</Table>
</Section>
<Section title="Select Care">
{Object.entries(data.available_care).map((key, idx) => (
<Button
key={idx}
content={key[0]}
color={(data.selected_care || []).includes(key[0]) ? 'good' : 'bad'}
onClick={() => act('toggle_care', {
care: key[0],
})} />
))}
</Section>
</Window.Content>
</Window>
);
};
1 change: 1 addition & 0 deletions yogstation.dme
Original file line number Diff line number Diff line change
@@ -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"