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

Arconomy: The bigger balance PR (REVISED EDITION) #65795

Merged
merged 44 commits into from Apr 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
0b53179
Documents economy and bank account variables
ArcaneMusic Jan 18, 2022
08666da
Original Commit: Jobs have had their income equalized, as have produc…
ArcaneMusic Jan 20, 2022
1f9e64a
Briefcase of cash contains 500 credits now. Basically doubles the pla…
ArcaneMusic Feb 20, 2022
e01837a
Merge remote-tracking branch 'upstream/master' into TheEconomicCrashO…
ArcaneMusic Feb 20, 2022
a61b019
Un-changes runtime station
ArcaneMusic Feb 20, 2022
a38a92d
fixes compile
ArcaneMusic Feb 20, 2022
f06d8a1
Merge remote-tracking branch 'upstream/master' into TheEconomicCrashO…
ArcaneMusic Mar 27, 2022
99c59f0
Fixes compile
ArcaneMusic Mar 28, 2022
8c877c2
LATHE CHARGES, PAYMENT CURVE EDITION.
ArcaneMusic Mar 28, 2022
d6490ed
Adjustments
ArcaneMusic Mar 29, 2022
01edebc
Bam
ArcaneMusic Mar 30, 2022
a810a8f
I've been working in matlab for too long
ArcaneMusic Mar 30, 2022
7182982
Merge remote-tracking branch 'upstream/master' into TheEconomicCrashO…
ArcaneMusic Mar 30, 2022
5fef11b
ccost is not a word
ArcaneMusic Mar 30, 2022
8b3a4e7
Merge remote-tracking branch 'upstream/master' into TheEconomicCrashO…
ArcaneMusic Apr 1, 2022
ef71e68
Fixes merge conflict with scanners
ArcaneMusic Apr 1, 2022
5d54396
Conflicts fixed and reviews applied.
ArcaneMusic Apr 1, 2022
2dea71a
Implements ghetto code review edit
ArcaneMusic Apr 1, 2022
f2352c2
Discord indentation am I rite fellas
ArcaneMusic Apr 1, 2022
2adbd27
Potato I fixed the discounts, sorry guys
ArcaneMusic Apr 3, 2022
6490773
First round of changes from the maintainer agreed-upon decision for e…
ArcaneMusic Apr 5, 2022
d5c5d01
I learned something invoke_async
ArcaneMusic Apr 6, 2022
4668945
Merge remote-tracking branch 'upstream/master' into TheEconomicCrashO…
ArcaneMusic Apr 6, 2022
bc91257
WHOOPS APPARENTLY THIS GOT LOST IN MERGE CONFLICTS
ArcaneMusic Apr 6, 2022
5812a4d
Adds some additional, basic logging onto payment component.
ArcaneMusic Apr 9, 2022
d55f357
Fixes a glaring oversight in the differences between protolathes and …
ArcaneMusic Apr 9, 2022
0020d59
Review cleanup
ArcaneMusic Apr 13, 2022
6fad8bd
Revolutions now remove the lathe tax is revs win. Missing early return.
ArcaneMusic Apr 14, 2022
12c1870
attempts to clean up payment component's handling of cash/credits for…
ArcaneMusic Apr 15, 2022
7972637
Early returns on handling with cash.
ArcaneMusic Apr 18, 2022
98524b6
Correctly tweaks the inflation with the new income values
ArcaneMusic Apr 19, 2022
ba4a428
Merge remote-tracking branch 'upstream/master' into TheEconomicCrashO…
ArcaneMusic Apr 19, 2022
d6b6173
Fixes conflicts
ArcaneMusic Apr 19, 2022
fe9d245
Why did I put that out of order. Comments.
ArcaneMusic Apr 19, 2022
cfafec0
Merge remote-tracking branch 'upstream/master' into TheEconomicCrashO…
ArcaneMusic Apr 21, 2022
7e9c5ac
Finishes some documentation that I negelected to do the first time.
ArcaneMusic Apr 21, 2022
6a79fd5
New potato review
ArcaneMusic Apr 23, 2022
0e57fbd
Hand slipped
ArcaneMusic Apr 23, 2022
3c1e50b
Merge remote-tracking branch 'upstream/master' into TheEconomicCrashO…
ArcaneMusic Apr 26, 2022
9200b13
Moves to a signal removal system
ArcaneMusic Apr 26, 2022
3767b59
Moves to a global signal
ArcaneMusic Apr 27, 2022
3c4954d
Tweaks to signal documentation
ArcaneMusic Apr 27, 2022
763177c
You are alone, child. There is only darkness for you, these ancients …
ArcaneMusic Apr 27, 2022
315647e
renames signal string
LemonInTheDark Apr 27, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
30 changes: 15 additions & 15 deletions _maps/map_files/debug/runtimestation.dmm
Expand Up @@ -2103,11 +2103,6 @@
/obj/machinery/door/airlock/shell,
/turf/open/floor/iron/dark,
/area/construction)
"sE" = (
/obj/structure/cable,
/obj/machinery/power/rtg/debug,
/turf/open/floor/plating/airless,
/area/space/nearstation)
"sH" = (
/obj/structure/table,
/obj/item/storage/box/shipping,
Expand Down Expand Up @@ -2235,6 +2230,11 @@
},
/turf/open/floor/engine,
/area/hallway/secondary/entry)
"yN" = (
/obj/structure/cable,
/obj/machinery/power/rtg/debug,
/turf/open/floor/plating/airless,
/area/space/nearstation)
"zo" = (
/obj/machinery/power/apc/auto_name/directional/south,
/obj/structure/cable,
Expand Down Expand Up @@ -6636,11 +6636,11 @@ aa
aa
ae
ab
sE
sE
sE
sE
sE
yN
yN
yN
yN
yN
ab
bv
bI
Expand Down Expand Up @@ -6728,11 +6728,11 @@ aa
aa
ae
ab
sE
yN
an
sE
yN
an
sE
yN
ab
bv
BG
Expand Down Expand Up @@ -6820,11 +6820,11 @@ aa
aa
ae
ab
sE
yN
an
ao
an
sE
yN
ab
bv
bJ
Expand Down
2 changes: 2 additions & 0 deletions code/__DEFINES/dcs/signals/signals_global.dm
Expand Up @@ -68,3 +68,5 @@

/// Global signal sent when a light mechanism is completed (try_id)
#define COMSIG_GLOB_LIGHT_MECHANISM_COMPLETED "!light_mechanism_completed"
///Global Signal sent when the crew wins the revolution (No arguments).
#define COMSIG_GLOB_REVOLUTION_TAX_REMOVAL "!revolution_tax_removal"
31 changes: 18 additions & 13 deletions code/__DEFINES/economy.dm
@@ -1,28 +1,33 @@
/// Number of paychecks jobs start with at the creation of a new bank account for a player (So at shift-start or game join, but not a blank new account.)
#define STARTING_PAYCHECKS 7
#define STARTING_PAYCHECKS 5
/// How much mail the Economy SS will create per minute, regardless of firing time.
#define MAX_MAIL_PER_MINUTE 3
/// Probability of using letters of envelope sprites on all letters.
#define FULL_CRATE_LETTER_ODDS 70

//Experimental change: These are subject to tweaking based on the /tg/ economy overhaul.
//Current design direction: Higher paying jobs are vastly outnumbered by lower paying jobs, so anything above medium hurts inflation, common jobs help inflation
#define PAYCHECK_PRISONER 25
#define PAYCHECK_ASSISTANT 50
#define PAYCHECK_MINIMAL 55
#define PAYCHECK_EASY 60
#define PAYCHECK_MEDIUM 75
#define PAYCHECK_HARD 100
#define PAYCHECK_COMMAND 200

//Current Paycheck values. Altering these changes both the cost of items meant for each paygrade, as well as the passive/starting income of each job.
///Default paygrade for the Unassigned Job/Unpaid job assignments.
#define PAYCHECK_ZERO 0
///Paygrade for Prisoners and Assistants.
#define PAYCHECK_LOWER 25
///Paygrade for all regular crew not belonging to PAYGRADE_LOWER or PAYGRADE_COMMAND.
#define PAYCHECK_CREW 50
///Paygrade for Heads of Staff.
#define PAYCHECK_COMMAND 100

//How many credits a player is charged if they print something from a departmental lathe they shouldn't have access to.
#define LATHE_TAX 10
//How much POWER a borg's cell is taxed if they print something from a departmental lathe.
#define SILICON_LATHE_TAX 2000

#define STATION_TARGET_BUFFER 25


#define STATION_TARGET_BUFFER 40

#define MAX_GRANT_DPT 500

//What should vending machines charge when you buy something in-department.
#define VENDING_DISCOUNT 0.2
#define DEPARTMENT_DISCOUNT 0.2

#define ACCOUNT_CIV "CIV"
#define ACCOUNT_CIV_NAME "Civil Budget"
Expand Down
1 change: 1 addition & 0 deletions code/controllers/subsystem/economy.dm
Expand Up @@ -88,6 +88,7 @@ SUBSYSTEM_DEF(economy)
var/datum/bank_account/bank_account = bank_accounts_by_id[account]
if(bank_account?.account_job && !ispath(bank_account.account_job))
temporary_total += (bank_account.account_job.paycheck * STARTING_PAYCHECKS)
bank_account.payday(1)
station_total += bank_account.account_balance
station_target = max(round(temporary_total / max(bank_accounts_by_id.len * 2, 1)) + station_target_buffer, 1)
if(!HAS_TRAIT(SSeconomy, TRAIT_MARKET_CRASHING))
Expand Down
2 changes: 1 addition & 1 deletion code/controllers/subsystem/persistent_paintings.dm
@@ -1,7 +1,7 @@
#define PAINTINGS_DATA_FORMAT_VERSION 2

// Patronage thresholds for paintings. Different cosmetic frames become available as more credits are spent on the patronage.
#define PATRONAGE_OK_FRAME PAYCHECK_ASSISTANT * 3 // 150 credits, as of early 2022
#define PATRONAGE_OK_FRAME PAYCHECK_CREW * 3 // 150 credits, as of march 2022
#define PATRONAGE_NICE_FRAME PATRONAGE_OK_FRAME * 2.5
#define PATRONAGE_GREAT_FRAME PATRONAGE_NICE_FRAME * 2
#define PATRONAGE_EXCELLENT_FRAME PATRONAGE_GREAT_FRAME * 2
Expand Down
139 changes: 115 additions & 24 deletions code/datums/components/payment.dm
Expand Up @@ -17,62 +17,153 @@
var/transaction_style = "Clinical"
///Who's getting paid?
var/datum/bank_account/target_acc
///Does this payment component respect same-department-discount?
var/department_discount = FALSE
///A static typecache of all the money-based items that can be actively used as currency.
var/static/list/allowed_money = typecacheof(list(
/obj/item/stack/spacecash,
/obj/item/holochip,
/obj/item/coin))

/datum/component/payment/Initialize(_cost, _target, _style)
target_acc = _target
if(!target_acc)
target_acc = SSeconomy.get_dep_account(ACCOUNT_CIV)

cost = _cost
transaction_style = _style
RegisterSignal(parent, COMSIG_OBJ_ATTEMPT_CHARGE, .proc/attempt_charge)
RegisterSignal(parent, COMSIG_OBJ_ATTEMPT_CHARGE_CHANGE, .proc/change_cost)
RegisterSignal(parent, COMSIG_GLOB_REVOLUTION_TAX_REMOVAL, .proc/clean_up)

/datum/component/payment/proc/attempt_charge(datum/source, atom/movable/target, extra_fees = 0)
SIGNAL_HANDLER

if(!cost) //In case a free variant of anything is made it'll skip charging anyone.
if(!cost && !extra_fees) //In case a free variant of anything is made it'll skip charging anyone.
return
var/total_cost = cost + extra_fees
if(!ismob(target))
return COMPONENT_OBJ_CANCEL_CHARGE
var/mob/living/user = target
if(issilicon(user)) //They have evolved beyond the need for mere credits
return
var/obj/item/card/id/card
if(istype(user))
card = user.get_idcard(TRUE)
if(!card)
switch(transaction_style)
if(PAYMENT_FRIENDLY)
to_chat(user, span_warning("ID not detected, sorry [user]!"))
if(PAYMENT_ANGRY)
to_chat(user, span_warning("WHERE IS YOUR GOD DAMN CARD! GOD DAMNIT!"))
if(PAYMENT_CLINICAL)
to_chat(user, span_warning("ID card not present. Aborting."))
return COMPONENT_OBJ_CANCEL_CHARGE
if(!card.registered_account)
if(!card && istype(user.pulling, /obj/item/card/id))
card = user.pulling
if(handle_card(user, card, total_cost))
return //Only breaks here if the card can handle the cost of purchasing with someone's ID.
if(handle_cardless(user, total_cost)) //Here we attempt to handle the purchase physically, with held money first. Otherwise we default to below.
return
return COMPONENT_OBJ_CANCEL_CHARGE

/**
* Proc that changes the base cost of the interaction.
*
* * source: Datum source of the thing changing the cost.
* * new_cost: the int value of the attempted new_cost to replace the cost value.
*/
/datum/component/payment/proc/change_cost(datum/source, new_cost)
SIGNAL_HANDLER

if(!isnum(new_cost))
CRASH("change_cost called with variable new_cost as not a number.")
cost = new_cost

/**
* Attempts to charge the mob, user, an integer number of credits, total_cost, without the use of an ID card to directly draw upon.
*/
/datum/component/payment/proc/handle_cardless(mob/living/user, total_cost)
//Here is all the possible non-ID payment methods.
var/list/counted_money = list()
var/physical_cash_total = 0
for(var/obj/item/credit in typecache_filter_list(user.get_all_contents(), allowed_money)) //Coins, cash, and credits.
if(physical_cash_total > total_cost)
break
physical_cash_total += credit.get_item_credit_value()
counted_money += credit

if(is_type_in_typecache(user.pulling, allowed_money) && (physical_cash_total < total_cost)) //Coins(Pulled).
var/obj/item/counted_credit = user.pulling
physical_cash_total += counted_credit.get_item_credit_value()
counted_money += counted_credit

if(physical_cash_total < total_cost)
var/armless //Suggestions for those with no arms/simple animals.
if(!ishuman(user) && !istype(user, /mob/living/simple_animal/slime))
armless = TRUE
else
var/mob/living/carbon/human/harmless_armless = user
if(!harmless_armless.get_bodypart(BODY_ZONE_L_ARM) && !harmless_armless.get_bodypart(BODY_ZONE_R_ARM))
armless = TRUE

if(armless)
if(!user.pulling || !iscash(user.pulling) && !istype(user.pulling, /obj/item/card/id))
to_chat(user, span_notice("Try pulling a valid ID, space cash, holochip or coin while using \the [parent]!"))
return FALSE
return FALSE

if(physical_cash_total < total_cost)
to_chat(user, span_notice("Insufficient funds. Aborting."))
return FALSE
for(var/obj/cash_object in counted_money)
qdel(cash_object)
physical_cash_total -= total_cost

if(physical_cash_total > 0)
var/obj/item/holochip/holochange = new /obj/item/holochip(user.loc) //Change is made in holocredits exclusively.
holochange.credits = physical_cash_total
holochange.name = "[holochange.credits] credit holochip"
if(istype(user, /mob/living/carbon/human))
var/mob/living/carbon/human/paying_customer = user
if(!INVOKE_ASYNC(paying_customer, /mob.proc/put_in_hands, holochange))
user.pulling = holochange
else
user.pulling = holochange
log_econ("[total_cost] credits were spent on [parent] by [user].")
to_chat(user, span_notice("Purchase completed with held credits."))
playsound(user, 'sound/effects/cashregister.ogg', 20, TRUE)
return TRUE

/**
* Attempts to charge a mob, user, an integer number of credits, total_cost, directly from an ID card/bank account.
*/
/datum/component/payment/proc/handle_card(mob/living/user, obj/item/card/id/idcard, total_cost)
if(!idcard)
return FALSE
if(!idcard?.registered_account)
switch(transaction_style)
if(PAYMENT_FRIENDLY)
to_chat(user, span_warning("There's no account detected on your ID, how mysterious!"))
if(PAYMENT_ANGRY)
to_chat(user, span_warning("ARE YOU JOKING. YOU DON'T HAVE A BANK ACCOUNT ON YOUR ID YOU IDIOT."))
if(PAYMENT_CLINICAL)
to_chat(user, span_warning("ID Card lacks a bank account. Aborting."))
return COMPONENT_OBJ_CANCEL_CHARGE
if(!(card.registered_account.has_money(cost + extra_fees)))
to_chat(user, span_warning("ID Card lacks a bank account. Advancing."))
return FALSE

if(!(idcard.registered_account.has_money(total_cost)))
switch(transaction_style)
if(PAYMENT_FRIENDLY)
to_chat(user, span_warning("I'm so sorry... You don't seem to have enough money."))
if(PAYMENT_ANGRY)
to_chat(user, span_warning("YOU MORON. YOU ABSOLUTE BAFOON. YOU INSUFFERABLE TOOL. YOU ARE POOR."))
if(PAYMENT_CLINICAL)
to_chat(user, span_warning("ID Card lacks funds. Aborting."))
return COMPONENT_OBJ_CANCEL_CHARGE
target_acc.transfer_money(card.registered_account, cost + extra_fees)
card.registered_account.bank_card_talk("[cost + extra_fees] credits deducted from your account.")
user.balloon_alert(user, "Cost: [total_cost] credits.")
return FALSE
target_acc.transfer_money(idcard.registered_account, total_cost)
log_econ("[total_cost] credits were spent on [parent] by [user] via [idcard.registered_account.account_holder]'s card.")
idcard.registered_account.bank_card_talk("[total_cost] credits deducted from your account.")
playsound(src, 'sound/effects/cashregister.ogg', 20, TRUE)
SSeconomy.track_purchase(card.registered_account, cost + extra_fees, parent)
SSeconomy.track_purchase(idcard.registered_account, total_cost, parent)
return TRUE

/datum/component/payment/proc/change_cost(datum/source, new_cost)
/**
* Attempts to remove the payment component, currently when the crew wins a revolution.
* * datum/source: source of the signal.
*/
/datum/component/payment/proc/clean_up(datum/source)
SIGNAL_HANDLER
if(!isnum(new_cost))
CRASH("change_cost called with variable new_cost as not a number.")
cost = new_cost
target_acc = null
qdel(src)
return

1 change: 0 additions & 1 deletion code/game/machinery/autolathe.dm
Expand Up @@ -45,7 +45,6 @@
/obj/machinery/autolathe/Initialize(mapload)
AddComponent(/datum/component/material_container, SSmaterials.materials_by_category[MAT_CATEGORY_ITEM_MATERIAL], 0, MATCONTAINER_EXAMINE, _after_insert = CALLBACK(src, .proc/AfterMaterialInsert))
. = ..()

wires = new /datum/wires/autolathe(src)
stored_research = new /datum/techweb/specialized/autounlocking/autolathe
matching_designs = list()
Expand Down
2 changes: 1 addition & 1 deletion code/game/objects/items/RCD.dm
Expand Up @@ -227,7 +227,7 @@ RLD
worn_icon_state = "RCD"
lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi'
custom_premium_price = PAYCHECK_HARD * 10
custom_premium_price = PAYCHECK_COMMAND * 10
max_matter = 160
slot_flags = ITEM_SLOT_BELT
item_flags = NO_MAT_REDEMPTION | NOBLUDGEON
Expand Down
2 changes: 1 addition & 1 deletion code/game/objects/items/cigs_lighters.dm
Expand Up @@ -669,7 +669,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
heat = 1500
resistance_flags = FIRE_PROOF
grind_results = list(/datum/reagent/iron = 1, /datum/reagent/fuel = 5, /datum/reagent/fuel/oil = 5)
custom_price = PAYCHECK_ASSISTANT * 1.1
custom_price = PAYCHECK_CREW * 1.1
light_system = MOVABLE_LIGHT
light_range = 2
light_power = 0.6
Expand Down
Expand Up @@ -508,7 +508,7 @@
/obj/item/circuitboard/machine/vendor
name = "Custom Vendor (Machine Board)"
desc = "You can turn the \"brand selection\" dial using a screwdriver."
custom_premium_price = PAYCHECK_ASSISTANT * 1.5
custom_premium_price = PAYCHECK_CREW * 1.5
build_path = /obj/machinery/vending/custom
req_components = list(/obj/item/vending_refill/custom = 1)

Expand Down
4 changes: 2 additions & 2 deletions code/game/objects/items/devices/flashlight.dm
@@ -1,7 +1,7 @@
/obj/item/flashlight
name = "flashlight"
desc = "A hand-held emergency light."
custom_price = PAYCHECK_EASY
custom_price = PAYCHECK_CREW
icon = 'icons/obj/lighting.dmi'
icon_state = "flashlight"
inhand_icon_state = "flashlight"
Expand Down Expand Up @@ -450,7 +450,7 @@
/obj/item/flashlight/glowstick
name = "glowstick"
desc = "A military-grade glowstick."
custom_price = PAYCHECK_PRISONER
custom_price = PAYCHECK_LOWER
w_class = WEIGHT_CLASS_SMALL
light_range = 4
light_system = MOVABLE_LIGHT
Expand Down
2 changes: 1 addition & 1 deletion code/game/objects/items/devices/multitool.dm
Expand Up @@ -27,7 +27,7 @@
drop_sound = 'sound/items/handling/multitool_drop.ogg'
pickup_sound = 'sound/items/handling/multitool_pickup.ogg'
custom_materials = list(/datum/material/iron=50, /datum/material/glass=20)
custom_premium_price = PAYCHECK_HARD * 3
custom_premium_price = PAYCHECK_COMMAND * 3
toolspeed = 1
usesound = 'sound/weapons/empty.ogg'
var/obj/machinery/buffer // simple machine buffer for device linkage
Expand Down
2 changes: 1 addition & 1 deletion code/game/objects/items/devices/paicard.dm
Expand Up @@ -8,7 +8,7 @@
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
w_class = WEIGHT_CLASS_SMALL
slot_flags = ITEM_SLOT_BELT
custom_premium_price = PAYCHECK_HARD * 1.25
custom_premium_price = PAYCHECK_COMMAND * 1.25
resistance_flags = FIRE_PROOF | ACID_PROOF | INDESTRUCTIBLE

/// Spam alert prevention
Expand Down
4 changes: 2 additions & 2 deletions code/game/objects/items/devices/portable_chem_mixer.dm
Expand Up @@ -7,8 +7,8 @@
w_class = WEIGHT_CLASS_HUGE
slot_flags = ITEM_SLOT_BELT
equip_sound = 'sound/items/equip/toolbelt_equip.ogg'
custom_price = PAYCHECK_MEDIUM * 10
custom_premium_price = PAYCHECK_MEDIUM * 14
custom_price = PAYCHECK_CREW * 10
custom_premium_price = PAYCHECK_CREW * 14

var/obj/item/reagent_containers/beaker = null ///Creating an empty slot for a beaker that can be added to dispense into
var/amount = 30 ///The amount of reagent that is to be dispensed currently
Expand Down