mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-01-11 01:51:51 +00:00
* CI change * world.dm * .dme world.dm * subsystem renaming * .dme for subsystems * ai_laws.dm * armor.dm * emote.dm * logging.dm * spell.dm * air_alarm.dm * crew.dm * decal.dm * emissive_blocker.dm * footstep.dm * spawner.dm * fire.dm * carbon.dm * living.dm * mob.dm * movement.dm * thermal_drill.dm * plasmamen.dm * lavaland.dm * chaplain.dm * lightning.dm * magnet.dm * mimic.dm * wizard.dm * morph.dm * vampire.dm * click.dm * self.dm * radiation_storm.dm * airlock.dm * autolathe.dm * mulebot.dm * nuclearbomb.dm * particle_accelerator.dm * smartfridge.dm * syndicatebomb.dm * vending.dm * wires.dm * sound.dm * mining.dm * syndicate_space_base.dm * monkey.dm * guardian.dm * bomb.dm * standard.dm * nuclear.dm * pinpointer.dm * access.dm * departments.dm * job.dm * science.dm * buttons.dm * cloning.dm * igniter.dm * wishgranter.dm * atmos_control.dm * message.dm * power_monitor.dm * mecha.dm * combat.dm * mining_tools.dm * meteors.dm * spiders.dm * contraband.dm * aliens.dm * uplinks.dm * voice.dm * intercom.dm * lights.dm * robot_items.dm * mineral.dm * dice.dm * extinguisher.dm * paint.dm * signs.dm * staff.dm * smokebomb.dm * boxes.dm * random.dm * janicart.dm * statue.dm * cargo.dm * asteroid.dm * headslug.dm * fulton.dm * atmospherics.dm * pump.dm * corpse.dm * oldstation.dm * gps.dm * preferences.dm * clothing.dm * ears.dm * glasses.dm * boxing.dm * color.dm * renames ninja gear files * recipes.dm * error_handler.dm * anomaly.dm * floorcluwne.dm * undead.dm * overmind.dm * shield.dm * bottle.dm * organ.dm * piano.dm * plasma_fist.dm * language.dm * mob_defines.dm * mob_helpers.dm * damage_procs.dm * _defines.dm * empress.dm and queen.dm * brain.dm * organ file renaming * subsystems.dm * constructs.dm * bot.dm * pet.dm * nature.dm * magic.dm * colors.dm * drugs.dm * medicine.dm * toxins.dm * shuttle.dm * surgery.dm * moves a bunch of define files * traits.dm * names.dm * other_mobs.dm * flags.dm * some final define files * well turns out contractor_pinpointer.dm was taken * I forgot to remove this file * how in the hell did this get unticked * I DID INCLUDE IT, but there was a "w" there * swaps the world definitions * camera renamed to SScamera * examine -> alien_examine
309 lines
12 KiB
Plaintext
309 lines
12 KiB
Plaintext
SUBSYSTEM_DEF(economy)
|
|
name = "Economy"
|
|
flags = SS_BACKGROUND
|
|
init_order = INIT_ORDER_ECONOMY //needs to init AFTER SSjobs
|
|
wait = 30 SECONDS
|
|
runlevels = RUNLEVEL_GAME
|
|
offline_implications = "Crew wont get their paychecks. No immediate action is needed." // money go down
|
|
cpu_display = SS_CPUDISPLAY_LOW
|
|
///List of all money account databases existing in the round
|
|
var/list/money_account_databases = list()
|
|
///Total amount of account created during the round, neccesary for generating unique account ids
|
|
var/account_counter = 0
|
|
|
|
///The absolute total amount of space cash (not to be confused with credits) in the round, does not count space credits in money accounts
|
|
var/total_space_cash = 0
|
|
///The absolute total amount of space credits in various economy systems, does not count space cash
|
|
var/total_space_credits = 0
|
|
///The amount of space credits that have been irreversibly deleted/removed from the round
|
|
var/space_credits_destroyed = 0
|
|
///The amount of space credits that have been created out of thin air, does not include credits created at round-start
|
|
var/space_credits_created = 0
|
|
///The amount of transfers (that are worth more than a few credits) that have been accepted during the round
|
|
var/total_credit_transfers = 0
|
|
///the amount of venor purchases during the round
|
|
var/total_vendor_transactions = 0
|
|
///amount of money spent in this 15 minute slot during the round
|
|
var/current_10_minute_spending = 0
|
|
|
|
///list of vars that will be tracked throughout the round (a new entry for each key list will be added every 15 minutes)
|
|
var/list/economy_data = list(
|
|
"totalcash" = list(), //how much space cash is in circulation
|
|
"totalcredits" = list(), //How many space credits are in circulation
|
|
"creditsdestroyed" = list(), //How many space credits have been removed from the round
|
|
"totaltransfers" = list(), //How many transfers have been accped (above $4) this round
|
|
"moneyvelocity" = list(), //What is the money velocity of this 10 minute period GDP/MS
|
|
"totalvends" = list(), //How many purchases have been made from vendors this round
|
|
"stagnant_accounts" = list(), //How many accounts have not made any transactions this round
|
|
"stagnant_cash" = list(), //How many credits are sitting in stagnant accounts this round
|
|
"non_stagnant_cash" = list() //How many credits are in active accounts this round
|
|
)
|
|
///time to next stats check
|
|
var/next_data_check = 0
|
|
|
|
|
|
//////CARGO VARIABLES/////
|
|
///the department account tethered to this supply console, we keep a ref here for shuttle operations
|
|
var/datum/money_account/cargo_account
|
|
///Current Order number
|
|
var/ordernum = 1
|
|
|
|
/// points gained per slip returned
|
|
var/credits_per_manifest = 5
|
|
/// points gained per intel returned
|
|
var/credits_per_intel = 750
|
|
/// points gained per plasma returned
|
|
var/credits_per_plasma = 10
|
|
/// points gained per research design returned
|
|
var/credits_per_design = 20
|
|
|
|
/// Remarks from Centcom on how well you checked the last order.
|
|
var/centcom_message
|
|
/// Typepaths for unusual plants we've already sent CentComm, associated with their potencies
|
|
var/list/discovered_plants = list()
|
|
var/list/tech_levels = list()
|
|
var/list/research_designs = list()
|
|
|
|
///Requested crates, waiting for approval by department heads
|
|
var/list/request_list = list()
|
|
///Approved Crates, waiting to be delivered
|
|
var/list/shopping_list = list()
|
|
///Crates that will be on next shuttle
|
|
var/list/delivery_list = list()
|
|
|
|
///Full list of all available supply packs to purchase
|
|
var/list/supply_packs = list()
|
|
var/sold_atoms = ""
|
|
|
|
var/list/all_supply_groups = list(
|
|
SUPPLY_EMERGENCY,
|
|
SUPPLY_SECURITY,
|
|
SUPPLY_ENGINEER,
|
|
SUPPLY_MEDICAL,
|
|
SUPPLY_SCIENCE,
|
|
SUPPLY_ORGANIC,
|
|
SUPPLY_MATERIALS,
|
|
SUPPLY_MISC,
|
|
SUPPLY_VEND
|
|
)
|
|
|
|
//////Paycheck Variables/////
|
|
/// time to next payday
|
|
var/next_paycheck_delay = 0
|
|
/// total paydays this round
|
|
var/payday_count = 0
|
|
|
|
var/global_paycheck_bonus = 0
|
|
var/global_paycheck_deduction = 0
|
|
|
|
/datum/controller/subsystem/economy/vv_edit_var(var_name, var_value)
|
|
switch(var_name)
|
|
//These are all things that admins should not be touching during production, these are either used for logging
|
|
//or economy critical things that should not be touched
|
|
if("payday_count")
|
|
return FALSE //fuck off, used for logging
|
|
if("sold_atoms")
|
|
return FALSE //fuck off, used for logging
|
|
if("cargo_account")
|
|
if(!istype(var_value, /datum/money_account))
|
|
return FALSE //really fuck off, you're vv editing something to a value that will break the economy
|
|
return ..()
|
|
|
|
/datum/controller/subsystem/economy/Initialize()
|
|
///create main station accounts
|
|
if(!GLOB.current_date_string)
|
|
GLOB.current_date_string = "[time2text(world.timeofday, "DD Month")], [GLOB.game_year]"
|
|
if(GLOB.station_money_database)
|
|
populate_station_database()
|
|
cargo_account = GLOB.station_money_database.get_account_by_department(DEPARTMENT_SUPPLY)
|
|
if(!cargo_account)
|
|
WARNING("SSeconomy could not locate the supply department account")
|
|
//need to set this back to 0 due to how this is tracked (and so we have a clean slate for roundstart)
|
|
current_10_minute_spending = 0
|
|
ordernum = rand(1, 9000)
|
|
|
|
for(var/typepath in subtypesof(/datum/supply_packs))
|
|
var/datum/supply_packs/P = typepath
|
|
if(initial(P.name) == "HEADER")
|
|
continue // To filter out group headers
|
|
P = new typepath()
|
|
supply_packs["[P.type]"] = P
|
|
|
|
centcom_message = "<center>---[station_time_timestamp()]---</center><br>Remember to stamp and send back the supply manifests.<hr>"
|
|
|
|
next_paycheck_delay = 30 MINUTES + world.time
|
|
|
|
/datum/controller/subsystem/economy/fire()
|
|
if(next_paycheck_delay <= world.time)
|
|
next_paycheck_delay = 30 MINUTES + world.time
|
|
payday()
|
|
if(next_data_check <= world.time)
|
|
next_data_check = 10 MINUTES + world.time
|
|
record_economy_data()
|
|
process_job_tasks()
|
|
|
|
/datum/controller/subsystem/economy/proc/record_economy_data()
|
|
economy_data["totalcash"] += total_space_cash
|
|
economy_data["totalcredits"] += total_space_credits
|
|
economy_data["creditsdestroyed"] += space_credits_destroyed - listgetindex(economy_data["creditsdestroyed"], length(economy_data["creditsdestroyed"]))
|
|
economy_data["totaltransfers"] += total_credit_transfers - listgetindex(economy_data["totaltransfers"], length(economy_data["totaltransfers"]))
|
|
economy_data["totalvends"] += total_vendor_transactions - listgetindex(economy_data["totalvends"], length(economy_data["totalvends"]))
|
|
economy_data["moneyvelocity"] += round((current_10_minute_spending / total_space_cash), 0.001)
|
|
var/stagnant_count = 0
|
|
var/stagnant_cash = 0
|
|
for(var/datum/money_account/account as anything in GLOB.station_money_database.user_accounts)
|
|
if(length(account.account_log) <= payday_count)
|
|
stagnant_count++
|
|
stagnant_cash += account.credit_balance
|
|
economy_data["stagnant_accounts"] += stagnant_count
|
|
economy_data["stagnant_cash"] = stagnant_cash
|
|
economy_data["non_stagnant_cash"] = total_space_credits - stagnant_cash
|
|
current_10_minute_spending = 0
|
|
/*
|
|
* # generate_account_number()
|
|
*
|
|
* SS proc that will generate a mostly random seven digit account number.
|
|
* This will allow up to 1000 guaranteed unique account numbers
|
|
*/
|
|
/datum/controller/subsystem/economy/proc/generate_account_number()
|
|
account_counter++
|
|
return (rand(1000, 9999) * 1000) + account_counter
|
|
|
|
/datum/controller/subsystem/economy/proc/populate_station_database()
|
|
var/datum/money_account_database/main_station/station_db = GLOB.station_money_database
|
|
money_account_databases += station_db
|
|
for(var/datum/station_department/department as anything in SSjobs.station_departments)
|
|
station_db.create_department_account(department.department_name, department.account_base_pay, department.account_starting_balance)
|
|
department.department_account = station_db.get_account_by_department(department.department_name)
|
|
//some crates ordered outside of cargo members still need QM explicit approval
|
|
station_db.create_vendor_account()
|
|
|
|
////////////////////////////
|
|
/// Supply Stuff /////////
|
|
////////////////////////
|
|
|
|
/datum/controller/subsystem/economy/proc/generate_supply_order(packID, orderedby, occupation, comment)
|
|
if(!packID)
|
|
return FALSE
|
|
var/datum/supply_packs/pack = locateUID(packID)
|
|
if(!pack)
|
|
return FALSE
|
|
|
|
var/datum/supply_order/order = new()
|
|
order.ordernum = ordernum++
|
|
order.object = pack
|
|
order.orderedby = orderedby
|
|
order.orderedbyRank = occupation
|
|
order.comment = comment
|
|
|
|
return order
|
|
|
|
/datum/controller/subsystem/economy/proc/process_supply_order(datum/supply_order/order, paid_for)
|
|
if(!order)
|
|
CRASH("process_supply_order() called with a null datum/supply_order")
|
|
|
|
if(!paid_for && !(order in request_list))
|
|
request_list += order //submit a request but do not finalize it
|
|
return TRUE
|
|
|
|
if(order.requires_head_approval || order.requires_cargo_approval)
|
|
return TRUE
|
|
|
|
//if purchaser has already paid it means it's fully approved, finalize order
|
|
if(paid_for)
|
|
finalize_supply_order(order) //if payment was succesful, add order to shoppinglist
|
|
return TRUE
|
|
log_debug("process_supply_order() called on Crate [order.ordernum] ordered by [order.orderedby] but isn't paid for and doesn't need approval, deleting")
|
|
qdel(order) //only the strong will survive
|
|
return FALSE
|
|
|
|
/datum/controller/subsystem/economy/proc/finalize_supply_order(datum/supply_order/order)
|
|
if(!order)
|
|
CRASH("finalize_supply_order() called with a null datum/supply_order")
|
|
if(order in request_list)
|
|
request_list -= order
|
|
|
|
if(SSshuttle.supply.getDockedId() == "supply_away" && SSshuttle.supply.mode == SHUTTLE_IDLE)
|
|
delivery_list += order
|
|
else
|
|
shopping_list += order
|
|
|
|
////////////////////////////
|
|
/// Paycheck Stuff /////////
|
|
////////////////////////
|
|
|
|
/datum/controller/subsystem/economy/proc/payday()
|
|
payday_count++
|
|
var/total_payout = 0
|
|
var/total_accounts = 0
|
|
var/datum/money_account_database/main_station/station_db = GLOB.station_money_database
|
|
var/list/all_station_accounts = station_db.user_accounts + station_db.get_all_department_accounts()
|
|
for(var/datum/money_account/account in all_station_accounts)
|
|
var/amount_to_pay = account.payday_amount + global_paycheck_bonus - global_paycheck_deduction
|
|
if(LAZYLEN(account.pay_check_bonuses))
|
|
for(var/bonus in account.pay_check_bonuses)
|
|
amount_to_pay += bonus
|
|
account.pay_check_bonuses = null
|
|
for(var/deduction in account.pay_check_deductions)
|
|
amount_to_pay -= deduction
|
|
amount_to_pay = max(amount_to_pay, 0)
|
|
account.pay_check_deductions = null
|
|
station_db.credit_account(account, amount_to_pay, "Payday", "NAS Trurl Payroll", FALSE)
|
|
if(account.account_type == ACCOUNT_TYPE_PERSONAL)
|
|
if(LAZYLEN(account.associated_nanobank_programs))
|
|
for(var/datum/data/pda/app/nanobank/program as anything in account.associated_nanobank_programs)
|
|
program.announce_payday(amount_to_pay)
|
|
total_accounts++
|
|
total_payout += amount_to_pay
|
|
|
|
//reset global paycheck modifiers to 0
|
|
global_paycheck_bonus = 0
|
|
global_paycheck_deduction = 0
|
|
//update space credit statistics
|
|
space_credits_created += total_payout
|
|
total_space_credits += total_payout
|
|
//alert admins and c*ders alike
|
|
log_debug("Payday Count: [payday_count] - [total_payout] credits paid out to [total_accounts] accounts")
|
|
|
|
|
|
//Called by the gameticker
|
|
/datum/controller/subsystem/economy/proc/process_job_tasks()
|
|
for(var/mob/M in GLOB.player_list) //why not just make a global list of players with job objectives???? someone else fix this ~sirryan
|
|
if(!M.mind)
|
|
continue
|
|
for(var/datum/job_objective/objective as anything in M.mind.job_objectives)
|
|
if(objective.completed && objective.payout_given)
|
|
continue //objective is completed and we've already given out award
|
|
if(!objective.is_completed())
|
|
continue //object is not completed, do not proceed
|
|
if(objective.completion_payment == 0)
|
|
objective.payout_given = TRUE
|
|
continue //objective doesn't giveout payout
|
|
|
|
if(objective.owner_account)
|
|
objective.owner_account.modify_payroll(objective.completion_payment, TRUE, "Job Objective \"[objective.objective_name]\" completed, award will be included in next paycheck")
|
|
objective.payout_given = TRUE
|
|
break
|
|
|
|
//
|
|
// The NanoCoin Economy is booming
|
|
// My Parabuck Stocks are Rising
|
|
// God Bless John Nanotrasen
|
|
//
|
|
// __-----__
|
|
// ..;;;--'~~~`--;;;..
|
|
// /; -~IN NANOTRASEN ;.
|
|
// // WE TRUST~- \\
|
|
// // ,-------, \\
|
|
// .// | ;;; ~ \ \\.
|
|
// || |;;;( /.| ||
|
|
// || |;; _\ ||
|
|
// || '. '=== ||
|
|
// || PROFIT | ''\ ;;;/ ||
|
|
// \\ ,| '\ '|><| 2223 //
|
|
// \\ | | \ AD//
|
|
// `;.,|. | '\.-'/
|
|
// ~~;;;,._|___.,-;;;~'
|
|
// ''=--'
|
|
//
|