diff --git a/code/__DEFINES/economy.dm b/code/__DEFINES/economy.dm new file mode 100644 index 0000000000..bc9534f527 --- /dev/null +++ b/code/__DEFINES/economy.dm @@ -0,0 +1,35 @@ +#define STARTING_PAYCHECKS 5 + +#define PAYCHECK_ASSISTANT 25 +#define PAYCHECK_MINIMAL 75 +#define PAYCHECK_EASY 125 +#define PAYCHECK_MEDIUM 175 +#define PAYCHECK_HARD 200 +#define PAYCHECK_COMMAND 250 + +#define MAX_GRANT_CIV 2500 +#define MAX_GRANT_ENG 3000 +#define MAX_GRANT_SCI 5000 +#define MAX_GRANT_SECMEDSRV 3000 + +#define ACCOUNT_CIV "CIV" +#define ACCOUNT_CIV_NAME "Civil Budget" +#define ACCOUNT_ENG "ENG" +#define ACCOUNT_ENG_NAME "Engineering Budget" +#define ACCOUNT_SCI "SCI" +#define ACCOUNT_SCI_NAME "Scientific Budget" +#define ACCOUNT_MED "MED" +#define ACCOUNT_MED_NAME "Medical Budget" +#define ACCOUNT_SRV "SRV" +#define ACCOUNT_SRV_NAME "Service Budget" +#define ACCOUNT_CAR "CAR" +#define ACCOUNT_CAR_NAME "Cargo Budget" +#define ACCOUNT_SEC "SEC" +#define ACCOUNT_SEC_NAME "Defense Budget" + +#define NO_FREEBIES "commies go home" + +//ID bank account support defines. +#define ID_NO_BANK_ACCOUNT 0 +#define ID_FREE_BANK_ACCOUNT 1 +#define ID_LOCKED_BANK_ACCOUNT 2 diff --git a/code/__DEFINES/maps.dm b/code/__DEFINES/maps.dm index 73e900226e..8b529859ac 100644 --- a/code/__DEFINES/maps.dm +++ b/code/__DEFINES/maps.dm @@ -38,6 +38,7 @@ require only minor tweaks. #define ZTRAIT_SPACE_RUINS "Space Ruins" #define ZTRAIT_LAVA_RUINS "Lava Ruins" #define ZTRAIT_ISOLATED_RUINS "Isolated Ruins" //Placing ruins on z levels with this trait will use turf reservation instead of usual placement. +#define ZTRAIT_VIRTUAL_REALITY "Virtual Reality" // number - bombcap is multiplied by this before being applied to bombs #define ZTRAIT_BOMBCAP_MULTIPLIER "Bombcap Multiplier" @@ -71,6 +72,7 @@ require only minor tweaks. ZTRAIT_BOMBCAP_MULTIPLIER = 5, \ ZTRAIT_BASETURF = /turf/open/lava/smooth/lava_land_surface) #define ZTRAITS_REEBE list(ZTRAIT_REEBE = TRUE, ZTRAIT_BOMBCAP_MULTIPLIER = 0.5) +#define ZTRAITS_VR list(ZTRAIT_VIRTUAL_REALITY = TRUE, ZTRAIT_AWAY = TRUE) #define DL_NAME "name" #define DL_TRAITS "traits" diff --git a/code/__DEFINES/preferences.dm b/code/__DEFINES/preferences.dm index 06926317ee..84eed5483a 100644 --- a/code/__DEFINES/preferences.dm +++ b/code/__DEFINES/preferences.dm @@ -30,8 +30,9 @@ #define CHAT_GHOSTPDA (1<<8) #define CHAT_GHOSTRADIO (1<<9) #define CHAT_LOOC (1<<10) +#define CHAT_BANKCARD (1<<11) -#define TOGGLES_DEFAULT_CHAT (CHAT_OOC|CHAT_DEAD|CHAT_GHOSTEARS|CHAT_GHOSTSIGHT|CHAT_PRAYER|CHAT_RADIO|CHAT_PULLR|CHAT_GHOSTWHISPER|CHAT_GHOSTPDA|CHAT_GHOSTRADIO|CHAT_LOOC) +#define TOGGLES_DEFAULT_CHAT (CHAT_OOC|CHAT_DEAD|CHAT_GHOSTEARS|CHAT_GHOSTSIGHT|CHAT_PRAYER|CHAT_RADIO|CHAT_PULLR|CHAT_GHOSTWHISPER|CHAT_GHOSTPDA|CHAT_GHOSTRADIO|CHAT_LOOC|CHAT_BANKCARD) #define PARALLAX_INSANE -1 //for show offs #define PARALLAX_HIGH 0 //default. diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm index 5aa0301bf6..104e69706c 100644 --- a/code/__DEFINES/subsystems.dm +++ b/code/__DEFINES/subsystems.dm @@ -65,6 +65,7 @@ #define INIT_ORDER_INSTRUMENTS 53 #define INIT_ORDER_MAPPING 50 #define INIT_ORDER_NETWORKS 45 +#define INIT_ORDER_ECONOMY 40 #define INIT_ORDER_ATOMS 30 #define INIT_ORDER_LANGUAGE 25 #define INIT_ORDER_MACHINES 20 diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index 170d93c31f..679f89f4d2 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -506,6 +506,19 @@ return winset(C, "mainwindow", "flash=5") +//Recursively checks if an item is inside a given type, even through layers of storage. Returns the atom if it finds it. +/proc/recursive_loc_check(atom/movable/target, type) + var/atom/A = target + if(istype(A, type)) + return A + + while(!istype(A.loc, type)) + if(!A.loc) + return + A = A.loc + + return A.loc + /proc/AnnounceArrival(var/mob/living/carbon/human/character, var/rank) if(!SSticker.IsRoundInProgress() || QDELETED(character)) return diff --git a/code/__HELPERS/level_traits.dm b/code/__HELPERS/level_traits.dm index 3e6e88c8fa..c903314da0 100644 --- a/code/__HELPERS/level_traits.dm +++ b/code/__HELPERS/level_traits.dm @@ -12,3 +12,5 @@ #define is_reserved_level(z) SSmapping.level_trait(z, ZTRAIT_RESERVED) #define is_away_level(z) SSmapping.level_trait(z, ZTRAIT_AWAY) + +#define is_vr_level(z) SSmapping.level_trait(z, ZTRAIT_VIRTUAL_REALITY) diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index afa858afb7..5b91afca4c 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -1025,6 +1025,27 @@ B --><-- A /proc/get_random_station_turf() return safepick(get_area_turfs(pick(GLOB.the_station_areas))) +/proc/get_safe_random_station_turf() //excludes dense turfs (like walls) and areas that have valid_territory set to FALSE + for (var/i in 1 to 5) + var/list/L = get_area_turfs(pick(GLOB.the_station_areas)) + var/turf/target + while (L.len && !target) + var/I = rand(1, L.len) + var/turf/T = L[I] + var/area/X = get_area(T) + if(!T.density && X.valid_territory) + var/clear = TRUE + for(var/obj/O in T) + if(O.density) + clear = FALSE + break + if(clear) + target = T + if (!target) + L.Cut(I,I+1) + if (target) + return target + /proc/get_closest_atom(type, list, source) var/closest_atom var/closest_distance @@ -1568,7 +1589,7 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new) /proc/blood_sucking_checks(var/mob/living/carbon/target, check_neck, check_blood) //Bypass this if the target isnt carbon. if(!iscarbon(target)) - return TRUE + return TRUE if(check_neck) if(istype(target.get_item_by_slot(SLOT_NECK), /obj/item/clothing/neck/garlic_necklace)) return FALSE diff --git a/code/_globalvars/lists/flavor_misc.dm b/code/_globalvars/lists/flavor_misc.dm index 968995e81d..8430e690cc 100644 --- a/code/_globalvars/lists/flavor_misc.dm +++ b/code/_globalvars/lists/flavor_misc.dm @@ -221,3 +221,5 @@ GLOBAL_LIST_INIT(numbers_as_words, world.file2list("strings/numbers_as_words.txt GLOBAL_LIST_INIT(station_numerals, greek_letters + phonetic_alphabet + numbers_as_words + generate_number_strings()) GLOBAL_LIST_INIT(admiral_messages, list("Do you know how expensive these stations are?","Stop wasting my time.","I was sleeping, thanks a lot.","Stand and fight you cowards!","You knew the risks coming in.","Stop being paranoid.","Whatever's broken just build a new one.","No.", "null","Error: No comment given.", "It's a good day to die!")) + +GLOBAL_LIST_INIT(redacted_strings, list("\[REDACTED\]", "\[CLASSIFIED\]", "\[ARCHIVED\]", "\[EXPLETIVE DELETED\]", "\[EXPUNGED\]", "\[INFORMATION ABOVE YOUR SECURITY CLEARANCE\]", "\[MOVE ALONG CITIZEN\]", "\[NOTHING TO SEE HERE\]", "\[ACCESS DENIED\]")) diff --git a/code/controllers/configuration/entries/game_options.dm b/code/controllers/configuration/entries/game_options.dm index f11093cba7..63e3f489bd 100644 --- a/code/controllers/configuration/entries/game_options.dm +++ b/code/controllers/configuration/entries/game_options.dm @@ -74,6 +74,8 @@ /datum/config_entry/flag/disable_peaceborg +/datum/config_entry/flag/economy //money money money money money money money money money money money money + /datum/config_entry/number/minimum_secborg_alert //Minimum alert level for secborgs to be chosen. config_entry_value = 3 diff --git a/code/controllers/subsystem/economy.dm b/code/controllers/subsystem/economy.dm new file mode 100644 index 0000000000..078d122aa6 --- /dev/null +++ b/code/controllers/subsystem/economy.dm @@ -0,0 +1,139 @@ +SUBSYSTEM_DEF(economy) + name = "Economy" + wait = 5 MINUTES + init_order = INIT_ORDER_ECONOMY + runlevels = RUNLEVEL_GAME + var/roundstart_paychecks = 5 + var/budget_pool = 35000 + var/list/department_accounts = list(ACCOUNT_CIV = ACCOUNT_CIV_NAME, + ACCOUNT_ENG = ACCOUNT_ENG_NAME, + ACCOUNT_SCI = ACCOUNT_SCI_NAME, + ACCOUNT_MED = ACCOUNT_MED_NAME, + ACCOUNT_SRV = ACCOUNT_SRV_NAME, + ACCOUNT_CAR = ACCOUNT_CAR_NAME, + ACCOUNT_SEC = ACCOUNT_SEC_NAME) + var/list/generated_accounts = list() + var/full_ancap = FALSE // Enables extra money charges for things that normally would be free, such as sleepers/cryo/cloning. + //Take care when enabling, as players will NOT respond well if the economy is set up for low cash flows. + var/alive_humans_bounty = 100 + var/crew_safety_bounty = 1500 + var/monster_bounty = 150 + var/mood_bounty = 100 + var/techweb_bounty = 250 + var/slime_bounty = list("grey" = 10, + // tier 1 + "orange" = 100, + "metal" = 100, + "blue" = 100, + "purple" = 100, + // tier 2 + "dark purple" = 500, + "dark blue" = 500, + "green" = 500, + "silver" = 500, + "gold" = 500, + "yellow" = 500, + "red" = 500, + "pink" = 500, + // tier 3 + "cerulean" = 750, + "sepia" = 750, + "bluespace" = 750, + "pyrite" = 750, + "light pink" = 750, + "oil" = 750, + "adamantine" = 750, + // tier 4 + "rainbow" = 1000) + var/list/bank_accounts = list() //List of normal accounts (not department accounts) + var/list/dep_cards = list() + +/datum/controller/subsystem/economy/Initialize(timeofday) + var/budget_to_hand_out = round(budget_pool / department_accounts.len) + for(var/A in department_accounts) + new /datum/bank_account/department(A, budget_to_hand_out) + return ..() + +/datum/controller/subsystem/economy/fire(resumed = 0) + eng_payout() // Payout based on nothing. What will replace it? Surplus power, powered APC's, air alarms? Who knows. + sci_payout() // Payout based on slimes. + secmedsrv_payout() // Payout based on crew safety, health, and mood. + civ_payout() // Payout based on ??? Profit + car_payout() // Cargo's natural gain in the cash moneys. + for(var/A in bank_accounts) + var/datum/bank_account/B = A + B.payday(1) + + +/datum/controller/subsystem/economy/proc/get_dep_account(dep_id) + for(var/datum/bank_account/department/D in generated_accounts) + if(D.department_id == dep_id) + return D + +/datum/controller/subsystem/economy/proc/eng_payout() + var/engineering_cash = 3000 + var/datum/bank_account/D = get_dep_account(ACCOUNT_ENG) + if(D) + D.adjust_money(engineering_cash) + + +/datum/controller/subsystem/economy/proc/car_payout() + var/cargo_cash = 500 + var/datum/bank_account/D = get_dep_account(ACCOUNT_CAR) + if(D) + D.adjust_money(cargo_cash) + +/datum/controller/subsystem/economy/proc/secmedsrv_payout() + var/crew + var/alive_crew + var/dead_monsters + var/cash_to_grant + for(var/mob/m in GLOB.mob_list) + if(isnewplayer(m)) + continue + if(m.mind) + if(isbrain(m) || iscameramob(m)) + continue + if(ishuman(m)) + var/mob/living/carbon/human/H = m + crew++ + if(H.stat != DEAD) + alive_crew++ + var/datum/component/mood/mood = H.GetComponent(/datum/component/mood) + var/medical_cash = (H.health / H.maxHealth) * alive_humans_bounty + if(mood) + var/datum/bank_account/D = get_dep_account(ACCOUNT_SRV) + if(D) + var/mood_dosh = (mood.mood_level / 9) * mood_bounty + D.adjust_money(mood_dosh) + medical_cash *= (mood.sanity / 100) + + var/datum/bank_account/D = get_dep_account(ACCOUNT_MED) + if(D) + D.adjust_money(medical_cash) + if(ishostile(m)) + var/mob/living/simple_animal/hostile/H = m + if(H.stat == DEAD && (H.z in SSmapping.levels_by_trait(ZTRAIT_STATION))) + dead_monsters++ + CHECK_TICK + var/living_ratio = alive_crew / crew + cash_to_grant = (crew_safety_bounty * living_ratio) + (monster_bounty * dead_monsters) + var/datum/bank_account/D = get_dep_account(ACCOUNT_SEC) + if(D) + D.adjust_money(min(cash_to_grant, MAX_GRANT_SECMEDSRV)) + +/datum/controller/subsystem/economy/proc/sci_payout() + var/science_bounty = 0 + for(var/mob/living/simple_animal/slime/S in GLOB.mob_list) + if(S.stat == DEAD) + continue + science_bounty += slime_bounty[S.colour] + var/datum/bank_account/D = get_dep_account(ACCOUNT_SCI) + if(D) + D.adjust_money(min(science_bounty, MAX_GRANT_SCI)) + +/datum/controller/subsystem/economy/proc/civ_payout() + var/civ_cash = (rand(1,5) * 500) + var/datum/bank_account/D = get_dep_account(ACCOUNT_CIV) + if(D) + D.adjust_money(min(civ_cash, MAX_GRANT_CIV)) diff --git a/code/controllers/subsystem/job.dm b/code/controllers/subsystem/job.dm index 91d0db85d1..7fc3f576de 100644 --- a/code/controllers/subsystem/job.dm +++ b/code/controllers/subsystem/job.dm @@ -477,6 +477,10 @@ SUBSYSTEM_DEF(job) to_chat(M, "[job.custom_spawn_text]") if(CONFIG_GET(number/minimal_access_threshold)) to_chat(M, "As this station was initially staffed with a [CONFIG_GET(flag/jobs_have_minimal_access) ? "full crew, only your job's necessities" : "skeleton crew, additional access may"] have been added to your ID card.") + if(ishuman(H)) + var/mob/living/carbon/human/wageslave = H + to_chat(M, "Your account ID is [wageslave.account_id].") + H.add_memory("Your account ID is [wageslave.account_id].") if(job && H) if(job.dresscodecompliant)// CIT CHANGE - dress code compliance equip_loadout(N, H) // CIT CHANGE - allows players to spawn with loadout items diff --git a/code/controllers/subsystem/mapping.dm b/code/controllers/subsystem/mapping.dm index f13d5a2779..5a1f17e8fb 100644 --- a/code/controllers/subsystem/mapping.dm +++ b/code/controllers/subsystem/mapping.dm @@ -438,9 +438,12 @@ GLOBAL_LIST_EMPTY(the_station_areas) else if(answer in GLOB.potentialRandomZlevels) away_name = answer + var/list/traits = list(ZTRAIT_AWAY = TRUE) + if(answer in GLOB.potentialRandomVRlevels) + traits[ZTRAIT_VIRTUAL_REALITY] = TRUE to_chat(usr,"Loading [away_name]...") var/datum/map_template/template = new(away_name, "Away Mission") - away_level = template.load_new_z() + away_level = template.load_new_z(traits) else return diff --git a/code/controllers/subsystem/shuttle.dm b/code/controllers/subsystem/shuttle.dm index e4a3ff1f9a..b9ec1d647f 100644 --- a/code/controllers/subsystem/shuttle.dm +++ b/code/controllers/subsystem/shuttle.dm @@ -35,10 +35,8 @@ SUBSYSTEM_DEF(shuttle) //supply shuttle stuff var/obj/docking_port/mobile/supply/supply var/ordernum = 1 //order number given to next order - var/points = 5000 //number of trade-points we have var/centcom_message = "" //Remarks from CentCom on how well you checked the last order. var/list/discoveredPlants = list() //Typepaths for unusual plants we've already sent CentCom, associated with their potencies - var/passive_supply_points_per_minute = 125 var/list/supply_packs = list() var/list/shoppinglist = list() @@ -113,9 +111,6 @@ SUBSYSTEM_DEF(shuttle) qdel(T, force=TRUE) CheckAutoEvac() - if(!(times_fired % CEILING(600/wait, 1))) - points += passive_supply_points_per_minute - var/esETA = emergency?.getModeStr() emergency_shuttle_stat_text = "[esETA? "[esETA] [emergency.getTimerStr()]" : ""]" @@ -559,7 +554,6 @@ SUBSYSTEM_DEF(shuttle) centcom_message = SSshuttle.centcom_message ordernum = SSshuttle.ordernum - points = SSshuttle.points emergencyNoEscape = SSshuttle.emergencyNoEscape emergencyCallAmount = SSshuttle.emergencyCallAmount shuttle_purchased = SSshuttle.shuttle_purchased diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 44a891e24a..48518f69c8 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -32,6 +32,9 @@ var/list/filter_data //For handling persistent filters + var/custom_price + var/custom_premium_price + var/datum/component/orbiter/orbiters var/rad_flags = NONE // Will move to flags_1 when i can be arsed to diff --git a/code/game/machinery/Sleeper.dm b/code/game/machinery/Sleeper.dm index 42904383bb..3f2edd7174 100644 --- a/code/game/machinery/Sleeper.dm +++ b/code/game/machinery/Sleeper.dm @@ -26,6 +26,8 @@ var/list/chem_buttons //Used when emagged to scramble which chem is used, eg: antitoxin -> morphine var/scrambled_chems = FALSE //Are chem buttons scrambled? used as a warning var/enter_message = "You feel cool air surround you. You go numb as your senses turn inward." + payment_department = ACCOUNT_MED + fair_market_price = 5 /obj/machinery/sleeper/Initialize() . = ..() @@ -205,6 +207,13 @@ ui = new(user, src, ui_key, "sleeper", name, 550, 700, master_ui, state) ui.open() +/obj/machinery/sleeper/process() + ..() + check_nap_violations() + +/obj/machinery/sleeper/nap_violation(mob/violator) + open_machine() + /obj/machinery/sleeper/ui_data() var/list/data = list() var/chemical_list = list() @@ -250,7 +259,7 @@ data["occupant"]["fireLoss"] = mob_occupant.getFireLoss() data["occupant"]["cloneLoss"] = mob_occupant.getCloneLoss() data["occupant"]["brainLoss"] = mob_occupant.getOrganLoss(ORGAN_SLOT_BRAIN) - + if(mob_occupant.reagents.reagent_list.len) for(var/datum/reagent/R in mob_occupant.reagents.reagent_list) chemical_list += list(list("name" = R.name, "volume" = R.volume)) @@ -290,7 +299,7 @@ if(..()) return var/mob/living/mob_occupant = occupant - + check_nap_violations() switch(action) if("door") if(state_open) diff --git a/code/game/machinery/_machinery.dm b/code/game/machinery/_machinery.dm index 995d11acb7..93121a0753 100644 --- a/code/game/machinery/_machinery.dm +++ b/code/game/machinery/_machinery.dm @@ -121,6 +121,10 @@ Class Procs: var/interaction_flags_machine = INTERACT_MACHINE_WIRES_IF_OPEN | INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OPEN_SILICON | INTERACT_MACHINE_SET_MACHINE + var/fair_market_price = 69 + var/market_verb = "Customer" + var/payment_department = ACCOUNT_ENG + /obj/machinery/Initialize() if(!armor) armor = list("melee" = 25, "bullet" = 10, "laser" = 10, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 70) @@ -248,6 +252,36 @@ Class Procs: return FALSE return TRUE +/obj/machinery/proc/check_nap_violations() + if(!SSeconomy.full_ancap) + return TRUE + if(occupant && !state_open) + if(ishuman(occupant)) + var/mob/living/carbon/human/H = occupant + var/obj/item/card/id/I = H.get_idcard() + if(I) + var/datum/bank_account/insurance = I.registered_account + if(!insurance) + say("[market_verb] NAP Violation: No bank account found.") + nap_violation() + return FALSE + else + if(!insurance.adjust_money(-fair_market_price)) + say("[market_verb] NAP Violation: Unable to pay.") + nap_violation() + return FALSE + var/datum/bank_account/D = SSeconomy.get_dep_account(payment_department) + if(D) + D.adjust_money(fair_market_price) + else + say("[market_verb] NAP Violation: No ID card found.") + nap_violation() + return FALSE + return TRUE + +/obj/machinery/proc/nap_violation(mob/violator) + return + //////////////////////////////////////////////////////////////////////////////////////////// //Return a non FALSE value to interrupt attack_hand propagation to subtypes. diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm index 6fa7fa30c0..e12e4c6cf5 100644 --- a/code/game/machinery/autolathe.dm +++ b/code/game/machinery/autolathe.dm @@ -32,6 +32,8 @@ var/list/datum/design/matching_designs var/selected_category var/screen = 1 + var/base_price = 25 + var/hacked_price = 50 var/list/categories = list( "Tools", diff --git a/code/game/machinery/bank_machine.dm b/code/game/machinery/bank_machine.dm index 41867a8520..2b683f16a3 100644 --- a/code/game/machinery/bank_machine.dm +++ b/code/game/machinery/bank_machine.dm @@ -8,6 +8,7 @@ var/obj/item/radio/radio var/radio_channel = RADIO_CHANNEL_COMMON var/minimum_time_between_warnings = 400 + var/syphoning_credits = 0 /obj/machinery/computer/bank_machine/Initialize() . = ..() @@ -25,9 +26,14 @@ if(istype(I, /obj/item/stack/spacecash)) var/obj/item/stack/spacecash/C = I value = C.value * C.amount + else if(istype(I, /obj/item/holochip)) + var/obj/item/holochip/H = I + value = H.credits if(value) - SSshuttle.points += value - to_chat(user, "You deposit [I]. The station now has [SSshuttle.points] credits.") + var/datum/bank_account/D = SSeconomy.get_dep_account(ACCOUNT_CAR) + if(D) + D.adjust_money(value) + to_chat(user, "You deposit [I]. The Cargo Budget is now [D.account_balance] cr.") qdel(I) return return ..() @@ -38,14 +44,16 @@ if(siphoning) if (stat & (BROKEN|NOPOWER)) say("Insufficient power. Halting siphon.") - siphoning = FALSE - if(SSshuttle.points < 200) - say("Station funds depleted. Halting siphon.") - siphoning = FALSE - else - new /obj/item/stack/spacecash/c200(drop_location()) // will autostack - playsound(src.loc, 'sound/items/poster_being_created.ogg', 100, 1) - SSshuttle.points -= 200 + end_syphon() + var/datum/bank_account/D = SSeconomy.get_dep_account(ACCOUNT_CAR) + if(!D.has_money(200)) + say("Cargo budget depleted. Halting siphon.") + end_syphon() + return + + playsound(src.loc, 'sound/items/poster_being_created.ogg', 100, 1) + syphoning_credits += 200 + D.adjust_money(-200) if(next_warning < world.time && prob(15)) var/area/A = get_area(loc) var/message = "Unauthorized credit withdrawal underway in [A.map_name]!!" @@ -61,7 +69,8 @@ /obj/machinery/computer/bank_machine/ui_data(mob/user) var/list/data = list() - data["current_balance"] = SSshuttle.points + var/datum/bank_account/D = SSeconomy.get_dep_account(ACCOUNT_CAR) + data["current_balance"] = D.account_balance data["siphoning"] = siphoning data["station_name"] = station_name() @@ -78,5 +87,10 @@ . = TRUE if("halt") say("Station credit withdrawal halted.") - siphoning = FALSE + end_syphon() . = TRUE + +/obj/machinery/computer/bank_machine/proc/end_syphon() + siphoning = FALSE + new /obj/item/holochip(drop_location(), syphoning_credits) //get the loot + syphoning_credits = 0 diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm index bc0fec68ba..ecea8c74c3 100644 --- a/code/game/machinery/cloning.dm +++ b/code/game/machinery/cloning.dm @@ -37,6 +37,9 @@ var/list/unattached_flesh var/flesh_number = 0 + var/datum/bank_account/current_insurance + fair_market_price = 5 // He nodded, because he knew I was right. Then he swiped his credit card to pay me for arresting him. + payment_department = ACCOUNT_MED /obj/machinery/clonepod/Initialize() . = ..() @@ -131,7 +134,7 @@ return examine(user) //Start growing a human clone in the pod! -/obj/machinery/clonepod/proc/growclone(ckey, clonename, ui, mutation_index, mindref, datum/species/mrace, list/features, factions, list/quirks) +/obj/machinery/clonepod/proc/growclone(ckey, clonename, ui, mutation_index, mindref, datum/species/mrace, list/features, factions, list/quirks, datum/bank_account/insurance) if(panel_open) return FALSE if(mess || attempting) @@ -161,7 +164,7 @@ mess = TRUE update_icon() return FALSE - + current_insurance = insurance attempting = TRUE //One at a time!! countdown.start() @@ -224,15 +227,29 @@ connected_message("Clone Ejected: Loss of power.") else if(mob_occupant && (mob_occupant.loc == src)) - if((mob_occupant.stat == DEAD) || (mob_occupant.suiciding) || mob_occupant.hellbound) //Autoeject corpses and suiciding dudes. - connected_message("Clone Rejected: Deceased.") + if(SSeconomy.full_ancap) + if(!current_insurance) + go_out() + connected_message("Clone Ejected: No bank account.") + if(internal_radio) + SPEAK("The cloning of [mob_occupant.real_name] has been terminated due to no bank account to draw payment from.") + else if(!current_insurance.adjust_money(-fair_market_price)) + go_out() + connected_message("Clone Ejected: Out of Money.") + if(internal_radio) + SPEAK("The cloning of [mob_occupant.real_name] has been ended prematurely due to being unable to pay.") + else + var/datum/bank_account/D = SSeconomy.get_dep_account(payment_department) + if(D) + D.adjust_money(fair_market_price) + if(mob_occupant && (mob_occupant.stat == DEAD) || (mob_occupant.suiciding) || mob_occupant.hellbound) //Autoeject corpses and suiciding dudes. connected_message("Clone Rejected: Deceased.") if(internal_radio) SPEAK("The cloning has been \ aborted due to unrecoverable tissue failure.") go_out() mob_occupant.copy_from_prefs_vr() - else if(mob_occupant.cloneloss > (100 - heal_level)) + else if(mob_occupant && mob_occupant.cloneloss > (100 - heal_level)) mob_occupant.Unconscious(80) var/dmg_mult = CONFIG_GET(number/damage_multiplier) //Slowly get that clone healed and finished. @@ -259,7 +276,7 @@ use_power(7500) //This might need tweaking. - else if((mob_occupant.cloneloss <= (100 - heal_level))) + else if((mob_occupant && mob_occupant.cloneloss <= (100 - heal_level))) connected_message("Cloning Process Complete.") if(internal_radio) SPEAK("The cloning cycle is complete.") @@ -368,7 +385,7 @@ if(!mob_occupant) return - + current_insurance = null REMOVE_TRAIT(mob_occupant, TRAIT_STABLEHEART, CLONING_POD_TRAIT) REMOVE_TRAIT(mob_occupant, TRAIT_MUTATION_STASIS, CLONING_POD_TRAIT) REMOVE_TRAIT(mob_occupant, TRAIT_STABLELIVER, CLONING_POD_TRAIT) diff --git a/code/game/machinery/computer/card.dm b/code/game/machinery/computer/card.dm index b0e80b63d2..74cceacd12 100644 --- a/code/game/machinery/computer/card.dm +++ b/code/game/machinery/computer/card.dm @@ -467,7 +467,8 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0) to_chat(usr, "No log exists for this job.") updateUsrDialog() return - + if(inserted_modify_id.registered_account) + inserted_modify_id.registered_account.account_job = jobdatum // this is a terrible idea and people will grief but sure whatever inserted_modify_id.access = ( istype(src, /obj/machinery/computer/card/centcom) ? get_centcom_access(t1) : jobdatum.get_access() ) if (inserted_modify_id) inserted_modify_id.assignment = t1 diff --git a/code/game/machinery/computer/cloning.dm b/code/game/machinery/computer/cloning.dm index 07cc252b87..981a5643a8 100644 --- a/code/game/machinery/computer/cloning.dm +++ b/code/game/machinery/computer/cloning.dm @@ -73,7 +73,7 @@ if(pod.occupant) continue //how though? - if(pod.growclone(R.fields["ckey"], R.fields["name"], R.fields["UI"], R.fields["SE"], R.fields["mind"], R.fields["mrace"], R.fields["features"], R.fields["factions"], R.fields["quirks"])) + if(pod.growclone(R.fields["ckey"], R.fields["name"], R.fields["UI"], R.fields["SE"], R.fields["mind"], R.fields["mrace"], R.fields["features"], R.fields["factions"], R.fields["quirks"], R.fields["bank_account"])) temp = "[R.fields["name"]] => Cloning cycle in progress..." records -= R @@ -415,7 +415,7 @@ else if(pod.occupant) temp = "Cloning cycle already in progress." playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) - else if(pod.growclone(C.fields["ckey"], C.fields["name"], C.fields["UI"], C.fields["SE"], C.fields["mind"], C.fields["mrace"], C.fields["features"], C.fields["factions"], C.fields["quirks"])) + else if(pod.growclone(C.fields["ckey"], C.fields["name"], C.fields["UI"], C.fields["SE"], C.fields["mind"], C.fields["mrace"], C.fields["features"], C.fields["factions"], C.fields["quirks"], C.fields["bank_account"])) temp = "[C.fields["name"]] => Cloning cycle in progress..." playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) records.Remove(C) @@ -441,9 +441,13 @@ /obj/machinery/computer/cloning/proc/scan_occupant(occupant) var/mob/living/mob_occupant = get_mob_or_brainmob(occupant) var/datum/dna/dna + var/datum/bank_account/has_bank_account if(ishuman(mob_occupant)) var/mob/living/carbon/C = mob_occupant dna = C.has_dna() + var/obj/item/card/id/I = C.get_idcard() + if(I) + has_bank_account = I.registered_account if(isbrain(mob_occupant)) var/mob/living/brain/B = mob_occupant dna = B.stored_dna @@ -468,7 +472,10 @@ scantemp = "Subject already in database." playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) return - + if(SSeconomy.full_ancap && !has_bank_account) + scantemp = "Subject is either missing an ID card with a bank account on it, or does not have an account to begin with. Please ensure the ID card is on the body before attempting to scan." + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + return var/datum/data/record/R = new() if(dna.species) // We store the instance rather than the path, because some @@ -490,6 +497,7 @@ R.fields["features"] = dna.features R.fields["factions"] = mob_occupant.faction R.fields["quirks"] = list() + R.fields["bank_account"] = has_bank_account for(var/V in mob_occupant.roundstart_quirks) var/datum/quirk/T = V R.fields["quirks"][T.type] = T.clone_data() diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm index 4c3d85a162..4cef487baf 100755 --- a/code/game/machinery/computer/communications.dm +++ b/code/game/machinery/computer/communications.dm @@ -163,11 +163,15 @@ else if(!S.prerequisites_met()) to_chat(usr, "You have not met the requirements for purchasing this shuttle.") else - if(SSshuttle.points >= S.credit_cost) + var/points_to_check + var/datum/bank_account/D = SSeconomy.get_dep_account(ACCOUNT_CAR) + if(D) + points_to_check = D.account_balance + if(points_to_check >= S.credit_cost) var/obj/machinery/shuttle_manipulator/M = locate() in GLOB.machines if(M) SSshuttle.shuttle_purchased = TRUE - SSshuttle.points -= S.credit_cost + D.adjust_money(-S.credit_cost) minor_announce("[usr.real_name] has purchased [S.name] for [S.credit_cost] credits." , "Shuttle Purchase") message_admins("[ADMIN_LOOKUPFLW(usr)] purchased [S.name].") SSblackbox.record_feedback("text", "shuttle_purchase", 1, "[S.name]") @@ -576,7 +580,8 @@ dat += "
Lift access restrictions on maintenance and external airlocks?
\[ OK | Cancel \]" if(STATE_PURCHASE) - dat += "Budget: [SSshuttle.points] Credits.
" + var/datum/bank_account/D = SSeconomy.get_dep_account(ACCOUNT_CAR) + dat += "Budget: [D.account_balance] Credits.
" dat += "
" dat += "Caution: Purchasing dangerous shuttles may lead to mutiny and/or death.
" dat += "
" diff --git a/code/game/machinery/doors/airlock_electronics.dm b/code/game/machinery/doors/airlock_electronics.dm index 7b90715f2b..fed54f55f8 100644 --- a/code/game/machinery/doors/airlock_electronics.dm +++ b/code/game/machinery/doors/airlock_electronics.dm @@ -1,6 +1,7 @@ /obj/item/electronics/airlock name = "airlock electronics" req_access = list(ACCESS_MAINT_TUNNELS) + custom_price = 50 var/list/accesses = list() var/one_access = 0 diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm index 1b83bb4b96..4533d18ae4 100644 --- a/code/game/machinery/doors/firedoor.dm +++ b/code/game/machinery/doors/firedoor.dm @@ -260,6 +260,7 @@ /obj/item/electronics/firelock name = "firelock circuitry" + custom_price = 50 desc = "A circuit board used in construction of firelocks." icon_state = "mainboard" diff --git a/code/game/machinery/doppler_array.dm b/code/game/machinery/doppler_array.dm index db806ef3ac..a9c411c634 100644 --- a/code/game/machinery/doppler_array.dm +++ b/code/game/machinery/doppler_array.dm @@ -174,9 +174,11 @@ GLOBAL_LIST_EMPTY(doppler_arrays) else linked_techweb.largest_bomb_value = TECHWEB_BOMB_POINTCAP point_gain = 1000 - + var/datum/bank_account/D = SSeconomy.get_dep_account(ACCOUNT_SCI) + if(D) + D.adjust_money(point_gain) linked_techweb.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, point_gain) - say("Gained [point_gain] points from explosion dataset.") + say("Explosion details and mixture analyzed and sold to the highest bidder for [point_gain] cr, with a reward of [point_gain] points.") else //you've made smaller bombs say("Data already captured. Aborting.") diff --git a/code/game/machinery/firealarm.dm b/code/game/machinery/firealarm.dm index f4f308c490..16ad36d0e1 100644 --- a/code/game/machinery/firealarm.dm +++ b/code/game/machinery/firealarm.dm @@ -2,6 +2,7 @@ /obj/item/electronics/firealarm name = "fire alarm electronics" + custom_price = 50 desc = "A fire alarm circuit. Can handle heat levels up to 40 degrees celsius." /obj/item/wallframe/firealarm diff --git a/code/game/objects/items/RCD.dm b/code/game/objects/items/RCD.dm index d248556a9c..565030b13a 100644 --- a/code/game/objects/items/RCD.dm +++ b/code/game/objects/items/RCD.dm @@ -154,6 +154,7 @@ RLD icon_state = "rcd" lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' + custom_price = 1700 max_matter = 160 item_flags = NO_MAT_REDEMPTION | NOBLUDGEON has_ammobar = TRUE diff --git a/code/game/objects/items/RSF.dm b/code/game/objects/items/RSF.dm index ba0766de00..35843c1030 100644 --- a/code/game/objects/items/RSF.dm +++ b/code/game/objects/items/RSF.dm @@ -41,24 +41,21 @@ RSF /obj/item/rsf/attack_self(mob/user) playsound(src.loc, 'sound/effects/pop.ogg', 50, 0) switch(mode) + if(5) + mode = 1 + to_chat(user, "Changed dispensing mode to 'Drinking Glass'") if(1) mode = 2 - to_chat(user, "Changed dispensing mode to 'Drinking Glass'") + to_chat(user, "Changed dispensing mode to 'Paper'") if(2) mode = 3 - to_chat(user, "Changed dispensing mode to 'Paper'") + to_chat(user, "Changed dispensing mode to 'Pen'") if(3) mode = 4 - to_chat(user, "Changed dispensing mode to 'Pen'") + to_chat(user, "Changed dispensing mode to 'Dice Pack'") if(4) mode = 5 - to_chat(user, "Changed dispensing mode to 'Dice Pack'") - if(5) - mode = 6 to_chat(user, "Changed dispensing mode to 'Cigarette'") - if(6) - mode = 1 - to_chat(user, "Changed dispensing mode to 'Dosh'") // Change mode /obj/item/rsf/afterattack(atom/A, mob/user, proximity) @@ -81,26 +78,22 @@ RSF playsound(src.loc, 'sound/machines/click.ogg', 10, 1) switch(mode) if(1) - to_chat(user, "Dispensing Dosh...") - new /obj/item/stack/spacecash/c10(T) - use_matter(200, user) - if(2) to_chat(user, "Dispensing Drinking Glass...") new /obj/item/reagent_containers/food/drinks/drinkingglass(T) use_matter(20, user) - if(3) + if(2) to_chat(user, "Dispensing Paper Sheet...") new /obj/item/paper(T) use_matter(10, user) - if(4) + if(3) to_chat(user, "Dispensing Pen...") new /obj/item/pen(T) use_matter(50, user) - if(5) + if(4) to_chat(user, "Dispensing Dice Pack...") new /obj/item/storage/pill_bottle/dice(T) use_matter(200, user) - if(6) + if(5) to_chat(user, "Dispensing Cigarette...") new /obj/item/clothing/mask/cigarette(T) use_matter(10, user) diff --git a/code/game/objects/items/cards_ids.dm b/code/game/objects/items/cards_ids.dm index 20e0b09d26..bcc4697d0b 100644 --- a/code/game/objects/items/cards_ids.dm +++ b/code/game/objects/items/cards_ids.dm @@ -6,8 +6,6 @@ * FINGERPRINT CARD */ - - /* * DATA CARDS - Used for the IC data card reader */ @@ -173,13 +171,19 @@ var/registered_name = null // The name registered_name on the card var/assignment = null var/access_txt // mapping aid - - + var/bank_support = ID_FREE_BANK_ACCOUNT + var/datum/bank_account/registered_account + var/obj/machinery/paystand/my_store /obj/item/card/id/Initialize(mapload) . = ..() if(mapload && access_txt) access = text2access(access_txt) + var/turf/T = get_turf(src) + if(bank_support == ID_FREE_BANK_ACCOUNT && is_vr_level(T.z)) //economy is quite exploitable on VR in so many ways. + bank_support = ID_NO_BANK_ACCOUNT + else if(bank_support == ID_LOCKED_BANK_ACCOUNT) + registered_account = new /datum/bank_account/remote/non_transferable(pick(GLOB.redacted_strings)) /obj/item/card/id/vv_edit_var(var_name, var_value) . = ..() @@ -193,12 +197,150 @@ user.visible_message("[user] shows you: [icon2html(src, viewers(user))] [src.name].", \ "You show \the [src.name].") add_fingerprint(user) + +/obj/item/card/id/attackby(obj/item/W, mob/user, params) + if(!bank_support) + return ..() + if(istype(W, /obj/item/holochip)) + insert_money(W, user) + else if(istype(W, /obj/item/stack/spacecash) || istype(W, /obj/item/coin)) + insert_money(W, user, TRUE) + else if(istype(W, /obj/item/storage/bag/money)) + var/obj/item/storage/bag/money/money_bag = W + var/list/money_contained = money_bag.contents + var/money_added = mass_insert_money(money_contained, user) + if (money_added) + to_chat(user, "You stuff the contents into the card! They disappear in a puff of bluespace smoke, adding [money_added] worth of credits to the linked account.") + else + return ..() + +/obj/item/card/id/proc/insert_money(obj/item/I, mob/user, physical_currency) + var/cash_money = I.get_item_credit_value() + if(!cash_money) + to_chat(user, "[I] doesn't seem to be worth anything!") return + if(!registered_account) + to_chat(user, "[src] doesn't have a linked account to deposit [I] into!") + return + + registered_account.adjust_money(cash_money) + if(physical_currency) + to_chat(user, "You stuff [I] into [src]. It disappears in a small puff of bluespace smoke, adding [cash_money] credits to the linked account.") + else + to_chat(user, "You insert [I] into [src], adding [cash_money] credits to the linked account.") + + to_chat(user, "The linked account now reports a balance of [registered_account.account_balance] cr.") + qdel(I) + +/obj/item/card/id/proc/mass_insert_money(list/money, mob/user) + if (!money || !money.len) + return FALSE + + var/total = 0 + + for (var/obj/item/physical_money in money) + var/cash_money = physical_money.get_item_credit_value() + + total += cash_money + + registered_account.adjust_money(cash_money) + + QDEL_LIST(money) + + return total + +/obj/item/card/id/proc/alt_click_can_use_id(mob/living/user) + if(!isliving(user)) + return + if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) + return + + return TRUE + +// Returns true if new account was set. +/obj/item/card/id/proc/set_new_account(mob/living/user) + if(bank_support != ID_FREE_BANK_ACCOUNT) + to_chat(user, "This ID has no modular banking support whatsover, must be an older model...") + return + . = FALSE + var/datum/bank_account/old_account = registered_account + + var/new_bank_id = input(user, "Enter your account ID number.", "Account Reclamation", 111111) as num | null + + if (isnull(new_bank_id)) + return + + if(!alt_click_can_use_id(user)) + return + if(!new_bank_id || new_bank_id < 111111 || new_bank_id > 999999) + to_chat(user, "The account ID number needs to be between 111111 and 999999.") + return + if (registered_account && registered_account.account_id == new_bank_id) + to_chat(user, "The account ID was already assigned to this card.") + return + + for(var/A in SSeconomy.bank_accounts) + var/datum/bank_account/B = A + if(B.account_id == new_bank_id) + if (old_account) + old_account.bank_cards -= src + + B.bank_cards += src + registered_account = B + to_chat(user, "The provided account has been linked to this ID card.") + + return TRUE + + to_chat(user, "The account ID number provided is invalid.") + return + +/obj/item/card/id/AltClick(mob/living/user) + . = ..() + if(!bank_support || !alt_click_can_use_id(user)) + return + + if(!registered_account) + set_new_account(user) + return + + if (world.time < registered_account.withdrawDelay) + registered_account.bank_card_talk("ERROR: UNABLE TO LOGIN DUE TO SCHEDULED MAINTENANCE. MAINTENANCE IS SCHEDULED TO COMPLETE IN [(registered_account.withdrawDelay - world.time)/10] SECONDS.", TRUE) + return + + var/amount_to_remove = FLOOR(input(user, "How much do you want to withdraw? Current Balance: [registered_account.account_balance]", "Withdraw Funds", 5) as num|null, 1) + + if(!amount_to_remove || amount_to_remove < 0) + return + if(!alt_click_can_use_id(user)) + return + if(registered_account.adjust_money(-amount_to_remove)) + var/obj/item/holochip/holochip = new (user.drop_location(), amount_to_remove) + user.put_in_hands(holochip) + to_chat(user, "You withdraw [amount_to_remove] credits into a holochip.") + return + else + var/difference = amount_to_remove - registered_account.account_balance + registered_account.bank_card_talk("ERROR: The linked account requires [difference] more credit\s to perform that withdrawal.", TRUE) + /obj/item/card/id/examine(mob/user) . = ..() if(mining_points) . += "There's [mining_points] mining equipment redemption point\s loaded onto this card." + if(!bank_support || (bank_support == ID_LOCKED_BANK_ACCOUNT && !registered_account)) + . += "This ID has no banking support whatsover, must be an older model..." + else if(registered_account) + . += "The account linked to the ID belongs to '[registered_account.account_holder]' and reports a balance of [registered_account.account_balance] cr." + 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] cr." + . += "Alt-Click the ID to pull money from the linked account in the form of holochips." + . += "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) + . += "If you lose this ID card, you can reclaim your account by Alt-Clicking a blank ID card while holding it and entering your account ID number." + else + . += "There is no registered account linked to this card. Alt-Click to add one." /obj/item/card/id/GetAccess() return access @@ -278,7 +420,11 @@ update_label("John Doe", "Clowny") else return ..() - var/popup_input = alert(user, "Choose Action", "Agent ID", "Show", "Forge/Reset") + var/popup_input + if(bank_support == ID_FREE_BANK_ACCOUNT) + popup_input = alert(user, "Choose Action", "Agent ID", "Show", "Forge/Reset", "Change Account ID") + else + popup_input = alert(user, "Choose Action", "Agent ID", "Show", "Forge/Reset") if(user.incapacitated()) return if(popup_input == "Forge/Reset" && !forged) @@ -302,6 +448,18 @@ update_label("John Doe", "Clowny") forged = TRUE to_chat(user, "You successfully forge the ID card.") log_game("[key_name(user)] has forged \the [initial(name)] with name \"[registered_name]\" and occupation \"[assignment]\".") + + // First time use automatically sets the account id to the user. + if (first_use && !registered_account) + if(ishuman(user)) + var/mob/living/carbon/human/accountowner = user + + for(var/bank_account in SSeconomy.bank_accounts) + var/datum/bank_account/account = bank_account + if(account.account_id == accountowner.account_id) + account.bank_cards += src + registered_account = account + to_chat(user, "Your account number has been automatically assigned.") return else if (popup_input == "Forge/Reset" && forged) registered_name = initial(registered_name) @@ -311,6 +469,9 @@ update_label("John Doe", "Clowny") forged = FALSE to_chat(user, "You successfully reset the ID card.") return + else if (popup_input == "Change Account ID") + set_new_account(user) + return return ..() /obj/item/card/id/syndicate/anyone @@ -327,6 +488,15 @@ update_label("John Doe", "Clowny") assignment = "Syndicate Overlord" access = list(ACCESS_SYNDICATE) +/obj/item/card/id/no_banking + bank_support = ID_NO_BANK_ACCOUNT + +/obj/item/card/id/locked_banking + bank_support = ID_LOCKED_BANK_ACCOUNT + +/obj/item/card/id/syndicate/locked_banking + bank_support = ID_LOCKED_BANK_ACCOUNT + /obj/item/card/id/captains_spare name = "captain's spare ID" desc = "The spare ID of the High Lord himself." @@ -396,6 +566,17 @@ update_label("John Doe", "Clowny") access = get_all_accesses()+get_ert_access("sec")-ACCESS_CHANGE_IDS . = ..() +/obj/item/card/id/debug + name = "\improper Debug ID" + desc = "A debug ID card. Has ALL the all access, you really shouldn't have this." + icon_state = "centcom" + assignment = "Jannie" + +/obj/item/card/id/debug/Initialize() + access = get_all_accesses()+get_all_centcom_access()+get_all_syndicate_access() + registered_account = SSeconomy.get_dep_account(ACCOUNT_CAR) + . = ..() + /obj/item/card/id/prisoner name = "prisoner ID card" desc = "You are a number, you are not a free man." @@ -514,6 +695,34 @@ update_label("John Doe", "Clowny") desc = "A special ID card that allows access to APC terminals." access = list(ACCESS_ENGINE_EQUIP) +/obj/item/card/id/departmental_budget + name = "departmental card (FUCK)" + desc = "Provides access to the departmental budget." + var/department_ID = ACCOUNT_CIV + var/department_name = ACCOUNT_CIV_NAME + +/obj/item/card/id/departmental_budget/Initialize() + . = ..() + var/datum/bank_account/B = SSeconomy.get_dep_account(department_ID) + if(B) + registered_account = B + if(!B.bank_cards.Find(src)) + B.bank_cards += src + name = "departmental card ([department_name])" + desc = "Provides access to the [department_name]." + SSeconomy.dep_cards += src + +/obj/item/card/id/departmental_budget/Destroy() + SSeconomy.dep_cards -= src + return ..() + +/obj/item/card/id/departmental_budget/update_label() + return + +/obj/item/card/id/departmental_budget/car + department_ID = ACCOUNT_CAR + department_name = ACCOUNT_CAR_NAME + //Polychromatic Knight Badge /obj/item/card/id/knight @@ -577,4 +786,3 @@ update_label("John Doe", "Clowny") /obj/item/card/id/debug/Initialize() access = get_all_accesses()+get_all_centcom_access()+get_all_syndicate_access() . = ..() - diff --git a/code/game/objects/items/cigs_lighters.dm b/code/game/objects/items/cigs_lighters.dm index 2303278f5c..6ebeffe90f 100644 --- a/code/game/objects/items/cigs_lighters.dm +++ b/code/game/objects/items/cigs_lighters.dm @@ -506,6 +506,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM resistance_flags = FIRE_PROOF light_color = LIGHT_COLOR_FIRE grind_results = list(/datum/reagent/iron = 1, /datum/reagent/fuel = 5, /datum/reagent/oil = 5) + custom_price = 55 /obj/item/lighter/Initialize() . = ..() @@ -710,7 +711,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM item_state = "black_vape" w_class = WEIGHT_CLASS_TINY var/chem_volume = 100 - var/vapetime = FALSE //this so it won't puff out clouds every tick + var/vapetime = FALSE //this so it won't puff out clouds every tick var/screw = FALSE // kinky var/super = FALSE //for the fattest vapes dude. diff --git a/code/game/objects/items/circuitboards/machine_circuitboards.dm b/code/game/objects/items/circuitboards/machine_circuitboards.dm index b13cfd9f64..890a17e52c 100644 --- a/code/game/objects/items/circuitboards/machine_circuitboards.dm +++ b/code/game/objects/items/circuitboards/machine_circuitboards.dm @@ -229,10 +229,11 @@ def_components = list(/obj/item/stack/ore/bluespace_crystal = /obj/item/stack/ore/bluespace_crystal/artificial) /obj/item/circuitboard/machine/vendor - name = "Booze-O-Mat Vendor (Machine Board)" + name = "Custom Vendor (Machine Board)" desc = "You can turn the \"brand selection\" dial using a screwdriver." - build_path = /obj/machinery/vending/boozeomat - req_components = list(/obj/item/vending_refill/boozeomat = 1) + custom_premium_price = 100 + build_path = /obj/machinery/vending/custom + req_components = list(/obj/item/vending_refill/custom = 1) var/static/list/vending_names_paths = list( /obj/machinery/vending/boozeomat = "Booze-O-Mat", @@ -269,7 +270,8 @@ /obj/machinery/vending/wardrobe/viro_wardrobe = "ViroDrobe", /obj/machinery/vending/clothing = "ClothesMate", /obj/machinery/vending/medical = "NanoMed Plus", - /obj/machinery/vending/wallmed = "NanoMed") + /obj/machinery/vending/wallmed = "NanoMed", + /obj/machinery/vending/custom = "Custom Vendor") /obj/item/circuitboard/machine/vendor/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/screwdriver)) @@ -1019,6 +1021,11 @@ build_path = /obj/machinery/ore_silo req_components = list() +/obj/item/circuitboard/machine/paystand + name = "Pay Stand (Machine Board)" + build_path = /obj/machinery/paystand + req_components = list() + /obj/item/circuitboard/machine/autobottler name = "Auto-Bottler (Machine Board)" build_path = /obj/machinery/rnd/production/protolathe/department/autobottler //Manips make you print things cheaper, even chems diff --git a/code/game/objects/items/crab17.dm b/code/game/objects/items/crab17.dm new file mode 100644 index 0000000000..8d55d3d5a2 --- /dev/null +++ b/code/game/objects/items/crab17.dm @@ -0,0 +1,229 @@ +/obj/item/suspiciousphone + name = "suspicious phone" + desc = "This device raises pink levels to unknown highs." + icon = 'icons/obj/items_and_weapons.dmi' + icon_state = "suspiciousphone" + w_class = WEIGHT_CLASS_SMALL + attack_verb = list("dumped") + var/dumped = FALSE + +/obj/item/suspiciousphone/attack_self(mob/user) + if(!ishuman(user)) + to_chat(user, "This device is too advanced for you!") + return + if(dumped) + to_chat(user, "You already activated Protocol CRAB-17.") + return FALSE + if(alert(user, "Are you sure you want to crash this market with no survivors?", "Protocol CRAB-17", "Yes", "No") == "Yes") + if(dumped || QDELETED(src)) //Prevents fuckers from cheesing alert + return FALSE + var/turf/targetturf = get_safe_random_station_turf() + if (!targetturf) + return FALSE + new /obj/effect/dumpeetTarget(targetturf, user) + dumped = TRUE + +/obj/structure/checkoutmachine + name = "\improper Nanotrasen Space-Coin Market" + desc = "This is good for spacecoin because" + icon = 'icons/obj/money_machine.dmi' + icon_state = "bogdanoff" + layer = LARGE_MOB_LAYER + armor = list("melee" = 80, "bullet" = 30, "laser" = 30, "energy" = 60, "bomb" = 90, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 80) + density = TRUE + pixel_z = -8 + max_integrity = 5000 + var/list/accounts_to_rob + var/mob/living/carbon/human/bogdanoff + var/canwalk = FALSE + +/obj/structure/checkoutmachine/examine(mob/living/user) + . = ..() + . += "It's integrated integrity meter reads: HEALTH: [obj_integrity]." + +/obj/structure/checkoutmachine/proc/check_if_finished() + for(var/i in accounts_to_rob) + var/datum/bank_account/B = i + if (B.being_dumped) + return FALSE + return TRUE + +/obj/structure/checkoutmachine/attackby(obj/item/W, mob/user, params) + if(check_if_finished()) + qdel(src) + return + if(istype(W, /obj/item/card/id)) + var/obj/item/card/id/card = W + if(!card.registered_account) + to_chat(user, "This card does not have a registered account!") + return + if(!card.registered_account.being_dumped) + to_chat(user, "It appears that your funds are safe from draining!") + return + if(do_after(user, 40, target = src)) + if(!card.registered_account.being_dumped) + return + to_chat(user, "You quickly cash out your funds to a more secure banking location. Funds are safu.") // This is a reference and not a typo + card.registered_account.being_dumped = FALSE + card.registered_account.withdrawDelay = 0 + if(check_if_finished()) + qdel(src) + return + else + return ..() + +/obj/structure/checkoutmachine/Initialize(mapload, mob/living/user) + . = ..() + bogdanoff = user + add_overlay("flaps") + add_overlay("hatch") + add_overlay("legs_retracted") + addtimer(CALLBACK(src, .proc/startUp), 50) + QDEL_IN(src, 8 MINUTES) //Self destruct after 8 min + + +/obj/structure/checkoutmachine/proc/startUp() //very VERY snowflake code that adds a neat animation when the pod lands. + start_dumping() //The machine doesnt move during this time, giving people close by a small window to grab their funds before it starts running around + sleep(10) + if(QDELETED(src)) + return + playsound(src, 'sound/machines/click.ogg', 15, TRUE, -3) + cut_overlay("flaps") + sleep(10) + if(QDELETED(src)) + return + playsound(src, 'sound/machines/click.ogg', 15, TRUE, -3) + cut_overlay("hatch") + sleep(30) + if(QDELETED(src)) + return + playsound(src,'sound/machines/twobeep.ogg',50,FALSE) + var/mutable_appearance/hologram = mutable_appearance(icon, "hologram") + hologram.pixel_y = 16 + add_overlay(hologram) + var/mutable_appearance/holosign = mutable_appearance(icon, "holosign") + holosign.pixel_y = 16 + add_overlay(holosign) + add_overlay("legs_extending") + cut_overlay("legs_retracted") + pixel_z += 4 + sleep(5) + if(QDELETED(src)) + return + add_overlay("legs_extended") + cut_overlay("legs_extending") + pixel_z += 4 + sleep(20) + if(QDELETED(src)) + return + add_overlay("screen_lines") + sleep(5) + if(QDELETED(src)) + return + cut_overlay("screen_lines") + sleep(5) + if(QDELETED(src)) + return + add_overlay("screen_lines") + add_overlay("screen") + sleep(5) + if(QDELETED(src)) + return + playsound(src,'sound/machines/triple_beep.ogg',50,FALSE) + add_overlay("text") + sleep(10) + if(QDELETED(src)) + return + add_overlay("legs") + cut_overlay("legs_extended") + cut_overlay("screen") + add_overlay("screen") + cut_overlay("screen_lines") + add_overlay("screen_lines") + cut_overlay("text") + add_overlay("text") + canwalk = TRUE + START_PROCESSING(SSfastprocess, src) + +/obj/structure/checkoutmachine/Destroy() + stop_dumping() + STOP_PROCESSING(SSfastprocess, src) + priority_announce("The credit deposit machine at [get_area(src)] has been destroyed. Station funds have stopped draining!", sender_override = "CRAB-17 Protocol") + explosion(src, 0,0,1, flame_range = 2) + return ..() + +/obj/structure/checkoutmachine/proc/start_dumping() + accounts_to_rob = SSeconomy.bank_accounts.Copy() + accounts_to_rob -= bogdanoff.get_bank_account() + for(var/i in accounts_to_rob) + var/datum/bank_account/B = i + B.dumpeet() + dump() + +/obj/structure/checkoutmachine/proc/dump() + var/percentage_lost = (rand(5, 15) / 100) + for(var/i in accounts_to_rob) + var/datum/bank_account/B = i + if(!B.being_dumped) + continue + var/amount = B.account_balance * percentage_lost + var/datum/bank_account/account = bogdanoff.get_bank_account() + if (account) // get_bank_account() may return FALSE + account.transfer_money(B, amount) + B.bank_card_talk("You have lost [percentage_lost * 100]% of your funds! A spacecoin credit deposit machine is located at: [get_area(src)].") + addtimer(CALLBACK(src, .proc/dump), 150) //Drain every 15 seconds + +/obj/structure/checkoutmachine/process() + var/anydir = pick(GLOB.cardinals) + if(Process_Spacemove(anydir)) + Move(get_step(src, anydir), anydir) + +/obj/structure/checkoutmachine/proc/stop_dumping() + for(var/i in accounts_to_rob) + var/datum/bank_account/B = i + B.being_dumped = FALSE + +/obj/effect/dumpeetFall //Falling pod + name = "" + icon = 'icons/obj/money_machine_64.dmi' + pixel_z = 300 + desc = "Get out of the way!" + layer = FLY_LAYER//that wasnt flying, that was falling with style! + icon_state = "missile_blur" + +/obj/effect/dumpeetTarget + name = "Landing Zone Indicator" + desc = "A holographic projection designating the landing zone of something. It's probably best to stand back." + icon = 'icons/mob/actions/actions_items.dmi' + icon_state = "sniper_zoom" + layer = PROJECTILE_HIT_THRESHHOLD_LAYER + light_range = 2 + var/obj/effect/dumpeetFall/DF + var/obj/structure/checkoutmachine/dump + var/mob/living/carbon/human/bogdanoff + +/obj/effect/ex_act() + return + +/obj/effect/dumpeetTarget/Initialize(mapload, user) + . = ..() + bogdanoff = user + addtimer(CALLBACK(src, .proc/startLaunch), 100) + sound_to_playing_players('sound/items/dump_it.ogg', 20) + deadchat_broadcast("Protocol CRAB-17 has been activated. A space-coin market has been launched at the station!", turf_target = get_turf(src)) + +/obj/effect/dumpeetTarget/proc/startLaunch() + DF = new /obj/effect/dumpeetFall(drop_location()) + dump = new /obj/structure/checkoutmachine(null, bogdanoff) + priority_announce("The spacecoin bubble has popped! Get to the credit deposit machine at [get_area(src)] and cash out before you lose all of your funds!", sender_override = "CRAB-17 Protocol") + animate(DF, pixel_z = -8, time = 5, , easing = LINEAR_EASING) + playsound(src, 'sound/weapons/mortar_whistle.ogg', 70, TRUE, 6) + addtimer(CALLBACK(src, .proc/endLaunch), 5, TIMER_CLIENT_TIME) //Go onto the last step after a very short falling animation + + + +/obj/effect/dumpeetTarget/proc/endLaunch() + QDEL_NULL(DF) //Delete the falling machine effect, because at this point its animation is over. We dont use temp_visual because we want to manually delete it as soon as the pod appears + playsound(src, "explosion", 80, TRUE) + dump.forceMove(get_turf(src)) + qdel(src) //The target's purpose is complete. It can rest easy now diff --git a/code/game/objects/items/credit_holochip.dm b/code/game/objects/items/credit_holochip.dm new file mode 100644 index 0000000000..0acb225772 --- /dev/null +++ b/code/game/objects/items/credit_holochip.dm @@ -0,0 +1,107 @@ +/obj/item/holochip + name = "credit holochip" + desc = "A hard-light chip encoded with an amount of credits. It is a modern replacement for physical money that can be directly converted to virtual currency and viceversa. Keep away from magnets." + icon = 'icons/obj/economy.dmi' + icon_state = "holochip" + throwforce = 0 + force = 0 + w_class = WEIGHT_CLASS_TINY + var/credits = 0 + +/obj/item/holochip/Initialize(mapload, amount) + . = ..() + credits = amount + update_icon() + +/obj/item/holochip/examine(mob/user) + . = ..() + . += "It's loaded with [credits] credit[( credits > 1 ) ? "s" : ""]\n"+\ + "Alt-Click to split." + +/obj/item/holochip/get_item_credit_value() + return credits + +/obj/item/holochip/update_icon() + name = "\improper [credits] credit holochip" + var/rounded_credits = credits + switch(credits) + if(1 to 999) + icon_state = "holochip" + if(1000 to 999999) + icon_state = "holochip_kilo" + rounded_credits = round(rounded_credits * 0.001) + if(1000000 to 999999999) + icon_state = "holochip_mega" + rounded_credits = round(rounded_credits * 0.000001) + if(1000000000 to INFINITY) + icon_state = "holochip_giga" + rounded_credits = round(rounded_credits * 0.000000001) + var/overlay_color = "#914792" + switch(rounded_credits) + if(0 to 4) + overlay_color = "#8E2E38" + if(5 to 9) + overlay_color = "#914792" + if(10 to 19) + overlay_color = "#BF5E0A" + if(20 to 49) + overlay_color = "#358F34" + if(50 to 99) + overlay_color = "#676767" + if(100 to 199) + overlay_color = "#009D9B" + if(200 to 499) + overlay_color = "#0153C1" + if(500 to INFINITY) + overlay_color = "#2C2C2C" + cut_overlays() + var/mutable_appearance/holochip_overlay = mutable_appearance('icons/obj/economy.dmi', "[icon_state]-color") + holochip_overlay.color = overlay_color + add_overlay(holochip_overlay) + +/obj/item/holochip/proc/spend(amount, pay_anyway = FALSE) + if(credits >= amount) + credits -= amount + if(credits == 0) + qdel(src) + update_icon() + return amount + else if(pay_anyway) + qdel(src) + return credits + else + return 0 + +/obj/item/holochip/attackby(obj/item/I, mob/user, params) + ..() + if(istype(I, /obj/item/holochip)) + var/obj/item/holochip/H = I + credits += H.credits + to_chat(user, "You insert the credits into [src].") + update_icon() + qdel(H) + +/obj/item/holochip/AltClick(mob/user) + if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user))) + return + var/split_amount = round(input(user,"How many credits do you want to extract from the holochip?") as null|num) + if(split_amount == null || split_amount <= 0 || !user.canUseTopic(src, BE_CLOSE, ismonkey(user))) + return + else + var/new_credits = spend(split_amount, TRUE) + var/obj/item/holochip/H = new(user ? user : drop_location(), new_credits) + if(user) + if(!user.put_in_hands(H)) + H.forceMove(user.drop_location()) + add_fingerprint(user) + H.add_fingerprint(user) + to_chat(user, "You extract [split_amount] credits into a new holochip.") + +/obj/item/holochip/emp_act(severity) + . = ..() + if(. & EMP_PROTECT_SELF) + return + var/wipe_chance = 60 / severity + if(prob(wipe_chance)) + visible_message("[src] fizzles and disappears!") + qdel(src) //rip cash diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm index 29a31122bf..1c50717bd5 100644 --- a/code/game/objects/items/devices/flashlight.dm +++ b/code/game/objects/items/devices/flashlight.dm @@ -1,6 +1,7 @@ /obj/item/flashlight name = "flashlight" desc = "A hand-held emergency light." + custom_price = 100 icon = 'icons/obj/lighting.dmi' icon_state = "flashlight" item_state = "flashlight" @@ -422,6 +423,7 @@ /obj/item/flashlight/glowstick name = "glowstick" desc = "A military-grade glowstick." + custom_price = 50 w_class = WEIGHT_CLASS_SMALL brightness_on = 4 color = LIGHT_COLOR_GREEN diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index b6cab8b438..1bc0f81695 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -11,6 +11,7 @@ SLIME SCANNER /obj/item/t_scanner name = "\improper T-ray scanner" desc = "A terahertz-ray emitter and scanner used to detect underfloor objects such as cables and pipes." + custom_price = 150 icon = 'icons/obj/device.dmi' icon_state = "t-ray0" var/on = FALSE @@ -79,6 +80,7 @@ SLIME SCANNER var/mode = 1 var/scanmode = 0 var/advanced = FALSE + custom_price = 300 /obj/item/healthanalyzer/suicide_act(mob/living/carbon/user) user.visible_message("[user] begins to analyze [user.p_them()]self with [src]! The display shows that [user.p_theyre()] dead!") diff --git a/code/game/objects/items/devices/sensor_device.dm b/code/game/objects/items/devices/sensor_device.dm index 79d26776a9..07b975f133 100644 --- a/code/game/objects/items/devices/sensor_device.dm +++ b/code/game/objects/items/devices/sensor_device.dm @@ -5,6 +5,7 @@ icon_state = "scanner" w_class = WEIGHT_CLASS_SMALL slot_flags = ITEM_SLOT_BELT + custom_price = 1750 /obj/item/sensor_device/attack_self(mob/user) GLOB.crewmonitor.show(user,src) //Proc already exists, just had to call it diff --git a/code/game/objects/items/kitchen.dm b/code/game/objects/items/kitchen.dm index 502930bf65..df5c840a1c 100644 --- a/code/game/objects/items/kitchen.dm +++ b/code/game/objects/items/kitchen.dm @@ -70,6 +70,7 @@ sharpness = IS_SHARP_ACCURATE armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) var/bayonet = FALSE //Can this be attached to a gun? + custom_price = 250 /obj/item/kitchen/knife/Initialize() . = ..() @@ -107,6 +108,7 @@ custom_materials = list(/datum/material/iron=18000) attack_verb = list("cleaved", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") w_class = WEIGHT_CLASS_NORMAL + custom_price = 600 /obj/item/kitchen/knife/combat name = "combat knife" @@ -174,6 +176,7 @@ throw_range = 7 w_class = WEIGHT_CLASS_NORMAL attack_verb = list("bashed", "battered", "bludgeoned", "thrashed", "whacked") + custom_price = 200 /obj/item/kitchen/rollingpin/suicide_act(mob/living/carbon/user) user.visible_message("[user] begins flattening [user.p_their()] head with \the [src]! It looks like [user.p_theyre()] trying to commit suicide!") diff --git a/code/game/objects/items/pinpointer.dm b/code/game/objects/items/pinpointer.dm index 090c2f6d57..5a47b2eecc 100644 --- a/code/game/objects/items/pinpointer.dm +++ b/code/game/objects/items/pinpointer.dm @@ -78,6 +78,7 @@ name = "crew pinpointer" desc = "A handheld tracking device that points to crew suit sensors." icon_state = "pinpointer_crew" + custom_price = 1000 var/has_owner = FALSE var/pinpointer_owner = null diff --git a/code/game/objects/items/stacks/cash.dm b/code/game/objects/items/stacks/cash.dm index 94f6fca28c..430018929d 100644 --- a/code/game/objects/items/stacks/cash.dm +++ b/code/game/objects/items/stacks/cash.dm @@ -3,7 +3,7 @@ singular_name = "bill" icon = 'icons/obj/economy.dmi' icon_state = "spacecash" - amount = 1 + amount = INFINITY max_amount = 20 throwforce = 0 throw_speed = 2 diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm index 50e9b94e97..588b231bda 100644 --- a/code/game/objects/items/stacks/medical.dm +++ b/code/game/objects/items/stacks/medical.dm @@ -93,6 +93,7 @@ var/stop_bleeding = 1800 var/heal_brute = 5 self_delay = 10 + custom_price = 100 /obj/item/stack/medical/gauze/heal(mob/living/M, mob/user) if(ishuman(M)) diff --git a/code/game/objects/items/storage/belt.dm b/code/game/objects/items/storage/belt.dm index dc6f5f701e..0cc108c1b9 100755 --- a/code/game/objects/items/storage/belt.dm +++ b/code/game/objects/items/storage/belt.dm @@ -43,6 +43,7 @@ icon_state = "utilitybelt" item_state = "utility" content_overlays = TRUE + custom_premium_price = 300 rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE //because this is easier than trying to have showers wash all contents. /obj/item/storage/belt/utility/ComponentInitialize() @@ -709,6 +710,7 @@ icon_state = "fannypack_leather" item_state = "fannypack_leather" dying_key = DYE_REGISTRY_FANNYPACK + custom_price = 100 /obj/item/storage/belt/fannypack/ComponentInitialize() . = ..() diff --git a/code/game/objects/items/storage/boxes.dm b/code/game/objects/items/storage/boxes.dm index 515c39ffcb..91206df4c2 100644 --- a/code/game/objects/items/storage/boxes.dm +++ b/code/game/objects/items/storage/boxes.dm @@ -622,6 +622,7 @@ item_state = "zippo" w_class = WEIGHT_CLASS_TINY slot_flags = ITEM_SLOT_BELT + custom_price = 20 /obj/item/storage/box/matches/ComponentInitialize() . = ..() diff --git a/code/game/objects/items/storage/fancy.dm b/code/game/objects/items/storage/fancy.dm index 3bc90d3615..18499d66be 100644 --- a/code/game/objects/items/storage/fancy.dm +++ b/code/game/objects/items/storage/fancy.dm @@ -136,6 +136,7 @@ slot_flags = ITEM_SLOT_BELT icon_type = "cigarette" spawn_type = /obj/item/clothing/mask/cigarette/space_cigarette + custom_price = 75 /obj/item/storage/fancy/cigarettes/ComponentInitialize() . = ..() @@ -276,6 +277,7 @@ icon_state = "cig_paper_pack" icon_type = "rolling paper" spawn_type = /obj/item/rollingpaper + custom_price = 25 /obj/item/storage/fancy/rollingpapers/ComponentInitialize() . = ..() diff --git a/code/game/objects/items/storage/wallets.dm b/code/game/objects/items/storage/wallets.dm index 27cd9c8908..0b4b6f54f3 100644 --- a/code/game/objects/items/storage/wallets.dm +++ b/code/game/objects/items/storage/wallets.dm @@ -16,6 +16,7 @@ STR.cant_hold = typecacheof(list(/obj/item/screwdriver/power)) STR.can_hold = typecacheof(list( /obj/item/stack/spacecash, + /obj/item/holochip, /obj/item/card, /obj/item/clothing/mask/cigarette, /obj/item/flashlight/pen, @@ -101,17 +102,5 @@ icon_state = "random_wallet" /obj/item/storage/wallet/random/PopulateContents() - var/item1_type = pick( /obj/item/stack/spacecash/c10, /obj/item/stack/spacecash/c100, /obj/item/stack/spacecash/c1000, /obj/item/stack/spacecash/c20, /obj/item/stack/spacecash/c200, /obj/item/stack/spacecash/c50, /obj/item/stack/spacecash/c500) - var/item2_type - if(prob(50)) - item2_type = pick( /obj/item/stack/spacecash/c10, /obj/item/stack/spacecash/c100, /obj/item/stack/spacecash/c1000, /obj/item/stack/spacecash/c20, /obj/item/stack/spacecash/c200, /obj/item/stack/spacecash/c50, /obj/item/stack/spacecash/c500) - var/item3_type = pick( /obj/item/coin/silver, /obj/item/coin/silver, /obj/item/coin/gold, /obj/item/coin/iron, /obj/item/coin/iron, /obj/item/coin/iron ) - - spawn(2) - if(item1_type) - new item1_type(src) - if(item2_type) - new item2_type(src) - if(item3_type) - new item3_type(src) - update_icon() + new /obj/item/holochip(src, rand(5,30)) + icon_state = "wallet" diff --git a/code/game/objects/items/tanks/watertank.dm b/code/game/objects/items/tanks/watertank.dm index 6ff5dfc8ad..67dbc19289 100644 --- a/code/game/objects/items/tanks/watertank.dm +++ b/code/game/objects/items/tanks/watertank.dm @@ -145,6 +145,7 @@ desc = "A janitorial watertank backpack with nozzle to clean dirt and graffiti." icon_state = "waterbackpackjani" item_state = "waterbackpackjani" + custom_price = 1200 /obj/item/watertank/janitor/Initialize() . = ..() diff --git a/code/game/objects/items/weaponry.dm b/code/game/objects/items/weaponry.dm index 8496a8a216..01131a3e85 100644 --- a/code/game/objects/items/weaponry.dm +++ b/code/game/objects/items/weaponry.dm @@ -525,6 +525,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 icon_state = "skateboard2" item_state = "skateboard2" board_item_type = /obj/vehicle/ridden/scooter/skateboard/pro + custom_premium_price = 500 /obj/item/melee/skateboard/hoverboard name = "hoverboard" @@ -532,6 +533,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 icon_state = "hoverboard_red" item_state = "hoverboard_red" board_item_type = /obj/vehicle/ridden/scooter/skateboard/hoverboard + custom_premium_price = 2015 /obj/item/melee/skateboard/hoverboard/admin name = "\improper Board Of Directors" diff --git a/code/game/objects/structures/crates_lockers/crates/secure.dm b/code/game/objects/structures/crates_lockers/crates/secure.dm index 4ac69253d3..2c923c1905 100644 --- a/code/game/objects/structures/crates_lockers/crates/secure.dm +++ b/code/game/objects/structures/crates_lockers/crates/secure.dm @@ -74,4 +74,43 @@ /obj/structure/closet/crate/secure/medical desc = "A secure medical crate." name = "medical crate" - icon_state = "medical_secure_crate" \ No newline at end of file + icon_state = "medical_secure_crate" + +/obj/structure/closet/crate/secure/owned + name = "private crate" + desc = "A crate cover designed to only open for who purchased its contents." + icon_state = "privatecrate" + var/datum/bank_account/buyer_account + var/privacy_lock = TRUE + +/obj/structure/closet/crate/secure/owned/examine(mob/user) + . = ..() + to_chat(user, "It's locked with a privacy lock, and can only be unlocked by the buyer's ID.") + +/obj/structure/closet/crate/secure/owned/Initialize(mapload, datum/bank_account/_buyer_account) + . = ..() + buyer_account = _buyer_account + +/obj/structure/closet/crate/secure/owned/togglelock(mob/living/user, silent) + if(privacy_lock) + if(!broken) + var/obj/item/card/id/id_card = user.get_idcard(TRUE) + if(id_card) + if(id_card.registered_account) + if(id_card.registered_account == buyer_account) + if(iscarbon(user)) + add_fingerprint(user) + locked = !locked + user.visible_message("[user] unlocks [src]'s privacy lock.", + "You unlock [src]'s privacy lock.") + privacy_lock = FALSE + update_icon() + else if(!silent) + to_chat(user, "Bank account does not match with buyer!") + else if(!silent) + to_chat(user, "No linked bank account detected!") + else if(!silent) + to_chat(user, "No ID detected!") + else if(!silent) + to_chat(user, "[src] is broken!") + else ..() diff --git a/code/game/objects/structures/ghost_role_spawners.dm b/code/game/objects/structures/ghost_role_spawners.dm index c918e7b867..d0be6c8469 100644 --- a/code/game/objects/structures/ghost_role_spawners.dm +++ b/code/game/objects/structures/ghost_role_spawners.dm @@ -689,7 +689,7 @@ name = "ID, jumpsuit and shoes" uniform = /obj/item/clothing/under/color/random shoes = /obj/item/clothing/shoes/sneakers/black - id = /obj/item/card/id + id = /obj/item/card/id/no_banking r_hand = /obj/item/storage/box/syndie_kit/chameleon/ghostcafe diff --git a/code/modules/admin/secrets.dm b/code/modules/admin/secrets.dm index c70db70ee8..a06b674e42 100644 --- a/code/modules/admin/secrets.dm +++ b/code/modules/admin/secrets.dm @@ -63,6 +63,7 @@ There can only be one! (40-second delay)
Make all players stupid
Egalitarian Station Mode
+ Anarcho-Capitalist Station Mode
Break all lights
Fix all lights
The floor is lava! (DANGEROUS: extremely lame)
@@ -478,6 +479,17 @@ usr.client.ak47s() sound_to_playing_players('sound/misc/ak47s.ogg') + if("ancap") + if(!check_rights(R_FUN)) + return + SSblackbox.record_feedback("nested tally", "admin_secrets_fun_used", 1, list("Anarcho-capitalist Station")) + SSeconomy.full_ancap = !SSeconomy.full_ancap + message_admins("[key_name_admin(usr)] toggled Anarcho-capitalist mode") + if(SSeconomy.full_ancap) + priority_announce("The NAP is now in full effect.", null, "commandreport") + else + priority_announce("The NAP has been revoked.", null, "commandreport") + if("guns") if(!check_rights(R_FUN)) return diff --git a/code/modules/antagonists/blob/blob/blob_report.dm b/code/modules/antagonists/blob/blob/blob_report.dm index 4385b732c3..d532121e12 100644 --- a/code/modules/antagonists/blob/blob/blob_report.dm +++ b/code/modules/antagonists/blob/blob/blob_report.dm @@ -8,6 +8,13 @@ var/mach = 0 /datum/station_state/proc/count() + floor = 0 + wall = 0 + r_wall = 0 + window = 0 + door = 0 + grille = 0 + mach = 0 for(var/Z in SSmapping.levels_by_trait(ZTRAIT_STATION)) for(var/turf/T in block(locate(1,1,Z), locate(world.maxx,world.maxy,Z))) // don't count shuttles since they may have just left @@ -48,6 +55,10 @@ else if(ismachinery(O)) mach += 1 + CHECK_TICK + CHECK_TICK + CHECK_TICK + /datum/station_state/proc/score(datum/station_state/result) if(!result) return 0 diff --git a/code/modules/antagonists/traitor/syndicate_contract.dm b/code/modules/antagonists/traitor/syndicate_contract.dm index daa9127591..70ff59eee0 100644 --- a/code/modules/antagonists/traitor/syndicate_contract.dm +++ b/code/modules/antagonists/traitor/syndicate_contract.dm @@ -78,14 +78,28 @@ var/mob/living/carbon/human/target = M // After we remove items, at least give them what they need to live. target.dna.species.give_important_for_life(target) handleVictimExperience(M) // After pod is sent we start the victim narrative/heal. - var/points_to_check = SSshuttle.points // This is slightly delayed because of the sleep calls above to handle the narrative. We don't want to tell the station instantly. - if(points_to_check >= ransom) - SSshuttle.points -= ransom - else - SSshuttle.points -= points_to_check + var/datum/bank_account/D = SSeconomy.get_dep_account(ACCOUNT_CAR) + var/points_to_check = min(D.account_balance, ransom) + D.adjust_money(min(points_to_check, ransom)) priority_announce("One of your crew was captured by a rival organisation - we've needed to pay their ransom to bring them back. \ As is policy we've taken a portion of the station's funds to offset the overall cost.", null, "attention", null, "Nanotrasen Asset Protection") + sleep(30) + + // Pay contractor their portion of ransom + if (status == CONTRACT_STATUS_COMPLETE) + var/mob/living/carbon/human/H + var/obj/item/card/id/C + if(ishuman(contract.owner.current)) + H = contract.owner.current + C = H.get_idcard(TRUE) + + if(C && C.registered_account) + C.registered_account.adjust_money(points_to_check * 0.35) + + C.registered_account.bank_card_talk("We've processed the ransom, agent. Here's your cut - your balance is now \ + [C.registered_account.account_balance] cr.", TRUE) + /datum/syndicate_contract/proc/handleVictimExperience(var/mob/living/M) // They're off to holding - handle the return timer and give some text about what's going on. addtimer(CALLBACK(src, .proc/returnVictim, M), 4 MINUTES) // Ship 'em back - dead or alive... 4 minutes wait. if(M.stat != DEAD) //Even if they weren't the target, we're still treating them the same. diff --git a/code/modules/atmospherics/machinery/airalarm.dm b/code/modules/atmospherics/machinery/airalarm.dm index a4617462fe..aa1e5c7401 100644 --- a/code/modules/atmospherics/machinery/airalarm.dm +++ b/code/modules/atmospherics/machinery/airalarm.dm @@ -36,6 +36,7 @@ /obj/item/electronics/airalarm name = "air alarm electronics" icon_state = "airalarm_electronics" + custom_price = 50 /obj/item/wallframe/airalarm name = "air alarm frame" diff --git a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm index e013a86fd2..b859c536cc 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm @@ -33,6 +33,9 @@ var/message_cooldown var/breakout_time = 300 + fair_market_price = 10 + payment_department = ACCOUNT_MED + /obj/machinery/atmospherics/components/unary/cryo_cell/Initialize() . = ..() initialize_directions = dir @@ -149,6 +152,9 @@ add_overlay("cover-on") addtimer(CALLBACK(src, .proc/run_anim, anim_up, occupant_overlay), 7, TIMER_UNIQUE) +/obj/machinery/atmospherics/components/unary/cryo_cell/nap_violation(mob/violator) + open_machine() + /obj/machinery/atmospherics/components/unary/cryo_cell/process() ..() @@ -162,7 +168,8 @@ return var/mob/living/mob_occupant = occupant - + if(!check_nap_violations()) + return if(mob_occupant.stat == DEAD) // We don't bother with dead people. return diff --git a/code/modules/awaymissions/zlevel.dm b/code/modules/awaymissions/zlevel.dm index d4c9fdbee7..00460e8a85 100644 --- a/code/modules/awaymissions/zlevel.dm +++ b/code/modules/awaymissions/zlevel.dm @@ -1,5 +1,7 @@ // How much "space" we give the edge of the map GLOBAL_LIST_INIT(potentialRandomZlevels, generateMapList(filename = "[global.config.directory]/awaymissionconfig.txt")) +// So far only adds an additional trait to vr levels. But I'll probably use make VR separate from away missions in a near future. +GLOBAL_LIST_INIT(potentialRandomVRlevels, generateMapList(filename = "[global.config.directory]/vr_config.txt")) /proc/createRandomZlevel() if(GLOB.awaydestinations.len) //crude, but it saves another var! @@ -8,7 +10,10 @@ GLOBAL_LIST_INIT(potentialRandomZlevels, generateMapList(filename = "[global.con if(GLOB.potentialRandomZlevels && GLOB.potentialRandomZlevels.len) to_chat(world, "Loading away mission...") var/map = pick(GLOB.potentialRandomZlevels) - load_new_z_level(map, "Away Mission") + var/list/traits = list(ZTRAIT_AWAY = TRUE) + if(map in GLOB.potentialRandomVRlevels) + traits[ZTRAIT_VIRTUAL_REALITY] = TRUE + load_new_z_level(map, "Away Mission", traits) to_chat(world, "Away mission loaded.") /proc/reset_gateway_spawns(reset = FALSE) diff --git a/code/modules/cargo/bounties/science.dm b/code/modules/cargo/bounties/science.dm index ad03b2f393..a4632f7ed0 100644 --- a/code/modules/cargo/bounties/science.dm +++ b/code/modules/cargo/bounties/science.dm @@ -55,7 +55,7 @@ /datum/bounty/item/science/advanced_mop name = "Advanced Mop" - description = "Excuse me. I'd like to request 17 credits for a push broom rebristling. Either that, or an advanced mop." + description = "Excuse me. I'd like to request 17 cr for a push broom rebristling. Either that, or an advanced mop." reward = 3000 wanted_types = list(/obj/item/mop/advanced) diff --git a/code/modules/cargo/bounty.dm b/code/modules/cargo/bounty.dm index bfd97e4d1f..b888dc1a28 100644 --- a/code/modules/cargo/bounty.dm +++ b/code/modules/cargo/bounty.dm @@ -21,7 +21,9 @@ GLOBAL_LIST_EMPTY(bounties_list) // Called when the claim button is clicked. Override to provide fancy rewards. /datum/bounty/proc/claim() if(can_claim()) - SSshuttle.points += reward + var/datum/bank_account/D = SSeconomy.get_dep_account(ACCOUNT_CAR) + if(D) + D.adjust_money(reward) claimed = TRUE // If an item sent in the cargo shuttle can satisfy the bounty. @@ -126,11 +128,11 @@ GLOBAL_LIST_EMPTY(bounties_list) /proc/setup_bounties() var/pick // instead of creating it a bunch let's go ahead and toss it here, we know we're going to use it for dynamics and subtypes! - + /********************************Subtype Gens********************************/ var/list/easy_add_list_subtypes = list(/datum/bounty/item/assistant = 2, - /datum/bounty/item/mech = 1, - /datum/bounty/item/chef = 2, + /datum/bounty/item/mech = 1, + /datum/bounty/item/chef = 2, /datum/bounty/item/security = 1, /datum/bounty/virus = 1, /datum/bounty/item/engineering = 1, @@ -139,30 +141,30 @@ GLOBAL_LIST_EMPTY(bounties_list) /datum/bounty/item/botany = 2, /datum/bounty/item/silly = 1, /datum/bounty/item/gardencook = 1) - + for(var/the_type in easy_add_list_subtypes) for(var/i in 1 to easy_add_list_subtypes[the_type]) pick = pick(subtypesof(the_type)) try_add_bounty(new pick) - + /********************************Strict Type Gens********************************/ var/list/easy_add_list_strict_types = list(/datum/bounty/reagent/simple_drink = 1, /datum/bounty/reagent/complex_drink = 1, /datum/bounty/reagent/chemical = 1) - + for(var/the_strict_type in easy_add_list_strict_types) for(var/i in 1 to easy_add_list_strict_types[the_strict_type]) try_add_bounty(new the_strict_type) - + /********************************Dynamic Gens********************************/ - + for(var/i in 0 to 1) if(prob(50)) pick = pick(subtypesof(/datum/bounty/item/slime)) else pick = pick(subtypesof(/datum/bounty/item/science)) try_add_bounty(new pick) - + /********************************Cutoff for Non-Low Priority Bounties********************************/ var/datum/bounty/B = pick(GLOB.bounties_list) B.mark_high_priority() @@ -172,7 +174,7 @@ GLOBAL_LIST_EMPTY(bounties_list) /datum/bounty/item/syndicate_documents, /datum/bounty/item/adamantine, /datum/bounty/more_bounties) - + for(var/low_priority_bounty in low_priority_strict_type_list) try_add_bounty(new low_priority_bounty) diff --git a/code/modules/cargo/bounty_console.dm b/code/modules/cargo/bounty_console.dm index 45260f4926..f499c38090 100644 --- a/code/modules/cargo/bounty_console.dm +++ b/code/modules/cargo/bounty_console.dm @@ -35,10 +35,10 @@ if(!GLOB.bounties_list.len) setup_bounties() - + var/datum/bank_account/D = SSeconomy.get_dep_account(ACCOUNT_CAR) var/list/dat = list({"Refresh Print Paper -

Credits: [SSshuttle.points]

+

Credits: [D.account_balance]

"}) for(var/datum/bounty/B in GLOB.bounties_list) diff --git a/code/modules/cargo/console.dm b/code/modules/cargo/console.dm index 64b208a90b..1883a5f615 100644 --- a/code/modules/cargo/console.dm +++ b/code/modules/cargo/console.dm @@ -74,9 +74,12 @@ /obj/machinery/computer/cargo/ui_data() var/list/data = list() data["location"] = SSshuttle.supply.getStatusText() + var/datum/bank_account/D = SSeconomy.get_dep_account(ACCOUNT_CAR) + if(D) + data["points"] = D.account_balance data["away"] = SSshuttle.supply.getDockedId() == "supply_away" + data["self_paid"] = self_paid data["docked"] = SSshuttle.supply.mode == SHUTTLE_IDLE - data["points"] = SSshuttle.points data["loan"] = !!SSshuttle.shuttle_loan data["loan_dispatched"] = SSshuttle.shuttle_loan && SSshuttle.shuttle_loan.dispatched var/message = "Remember to stamp and send back the supply manifests." @@ -92,6 +95,7 @@ "cost" = SO.pack.cost, "id" = SO.id, "orderer" = SO.orderer, + "paid" = !isnull(SO.paying_account) //paid by requester )) data["requests"] = list() @@ -165,6 +169,7 @@ . = TRUE if("add") var/id = text2path(params["id"]) + var/self_paid = text2num(params["self_paid"]) var/datum/supply_pack/pack = SSshuttle.supply_packs[id] if(!istype(pack)) return @@ -182,19 +187,33 @@ name = usr.real_name rank = "Silicon" + var/datum/bank_account/account + if(self_paid && ishuman(usr)) + var/mob/living/carbon/human/H = usr + var/obj/item/card/id/id_card = H.get_idcard(TRUE) + if(!istype(id_card)) + say("No ID card detected.") + return + account = id_card.registered_account + if(!istype(account)) + say("Invalid bank account.") + return + var/reason = "" - if(requestonly) + if(requestonly && !self_paid) reason = stripped_input("Reason:", name, "") if(isnull(reason) || ..()) return var/turf/T = get_turf(src) - var/datum/supply_order/SO = new(pack, name, rank, ckey, reason) + var/datum/supply_order/SO = new(pack, name, rank, ckey, reason, account) SO.generateRequisition(T) - if(requestonly) + if(requestonly && !self_paid) SSshuttle.requestlist += SO else SSshuttle.shoppinglist += SO + if(self_paid) + say("Order processed. The price will be charged to [account.account_holder]'s bank account on delivery.") . = TRUE if("remove") var/id = text2num(params["id"]) diff --git a/code/modules/cargo/exports.dm b/code/modules/cargo/exports.dm index bb90fa717a..0a1346ba01 100644 --- a/code/modules/cargo/exports.dm +++ b/code/modules/cargo/exports.dm @@ -26,6 +26,7 @@ Credit dupes that require a lot of manual work shouldn't be removed, unless they var/list/total_value = list() //export instance => total value of sold objects var/list/reagents_volume = list()//export reagents => into the total volume of the object sold var/list/reagents_value = list()//export reagents => into the reagent type total value. + var/list/exported_atoms_ref = list() //if they're not deleted they go in here for use. // external_report works as "transaction" object, pass same one in if you're doing more than one export in single go /proc/export_item_and_contents(atom/movable/AM, allowed_categories = EXPORT_CARGO, apply_elastic = TRUE, delete_unsold = TRUE, dry_run=FALSE, datum/export_report/external_report) diff --git a/code/modules/cargo/expressconsole.dm b/code/modules/cargo/expressconsole.dm index a65d8cad40..678f5c851f 100644 --- a/code/modules/cargo/expressconsole.dm +++ b/code/modules/cargo/expressconsole.dm @@ -96,17 +96,19 @@ /obj/machinery/computer/cargo/express/ui_data(mob/user) var/canBeacon = beacon && (isturf(beacon.loc) || ismob(beacon.loc))//is the beacon in a valid location? var/list/data = list() + var/datum/bank_account/D = SSeconomy.get_dep_account(ACCOUNT_CAR) + if(D) + data["points"] = D.account_balance data["locked"] = locked//swipe an ID to unlock data["siliconUser"] = hasSiliconAccessInArea(user) data["beaconzone"] = beacon ? get_area(beacon) : ""//where is the beacon located? outputs in the tgui data["usingBeacon"] = usingBeacon //is the mode set to deliver to the beacon or the cargobay? data["canBeacon"] = !usingBeacon || canBeacon //is the mode set to beacon delivery, and is the beacon in a valid location? - data["canBuyBeacon"] = cooldown <= 0 && SSshuttle.points >= BEACON_COST + data["canBuyBeacon"] = cooldown <= 0 && D.account_balance >= BEACON_COST data["beaconError"] = usingBeacon && !canBeacon ? "(BEACON ERROR)" : ""//changes button text to include an error alert if necessary data["hasBeacon"] = beacon != null//is there a linked beacon? data["beaconName"] = beacon ? beacon.name : "No Beacon Found" data["printMsg"] = cooldown > 0 ? "Print Beacon for [BEACON_COST] credits ([cooldown])" : "Print Beacon for [BEACON_COST] credits"//buttontext for printing beacons - data["points"] = SSshuttle.points data["supplies"] = list() message = "Sales are near-instantaneous - please choose carefully." if(SSshuttle.supplyBlocked) @@ -137,13 +139,14 @@ if (beacon) beacon.update_status(SP_READY) //turns on the beacon's ready light if("printBeacon") - if (SSshuttle.points >= BEACON_COST) - cooldown = 10//a ~ten second cooldown for printing beacons to prevent spam - var/obj/item/supplypod_beacon/C = new /obj/item/supplypod_beacon(drop_location()) - C.link_console(src, usr)//rather than in beacon's Initialize(), we can assign the computer to the beacon by reusing this proc) - printed_beacons++//printed_beacons starts at 0, so the first one out will be called beacon # 1 - beacon.name = "Supply Pod Beacon #[printed_beacons]" - SSshuttle.points -= BEACON_COST + var/datum/bank_account/D = SSeconomy.get_dep_account(ACCOUNT_CAR) + if(D) + if(D.adjust_money(-BEACON_COST)) + cooldown = 10//a ~ten second cooldown for printing beacons to prevent spam + var/obj/item/supplypod_beacon/C = new /obj/item/supplypod_beacon(drop_location()) + C.link_console(src, usr)//rather than in beacon's Initialize(), we can assign the computer to the beacon by reusing this proc) + printed_beacons++//printed_beacons starts at 0, so the first one out will be called beacon # 1 + beacon.name = "Supply Pod Beacon #[printed_beacons]" if("add")//Generate Supply Order first var/id = text2path(params["id"]) @@ -163,8 +166,12 @@ var/reason = "" var/list/empty_turfs var/datum/supply_order/SO = new(pack, name, rank, ckey, reason) + var/points_to_check + var/datum/bank_account/D = SSeconomy.get_dep_account(ACCOUNT_CAR) + if(D) + points_to_check = D.account_balance if(!(obj_flags & EMAGGED)) - if(SO.pack.cost <= SSshuttle.points) + if(SO.pack.cost <= points_to_check) var/LZ if (istype(beacon) && usingBeacon)//prioritize beacons over landing in cargobay LZ = get_turf(beacon) @@ -181,14 +188,14 @@ CHECK_TICK if(empty_turfs && empty_turfs.len) LZ = pick(empty_turfs) - if (SO.pack.cost <= SSshuttle.points && LZ)//we need to call the cost check again because of the CHECK_TICK call - SSshuttle.points -= SO.pack.cost + if (SO.pack.cost <= points_to_check && LZ)//we need to call the cost check again because of the CHECK_TICK call + D.adjust_money(-SO.pack.cost) SSblackbox.record_feedback("nested tally", "cargo_imports", 1, list("[SO.pack.cost]", "[SO.pack.name]")) new /obj/effect/abstract/DPtarget(LZ, podType, SO) . = TRUE update_icon() else - if(SO.pack.cost * (0.72*MAX_EMAG_ROCKETS) <= SSshuttle.points) // bulk discount :^) + if(SO.pack.cost * (0.72*MAX_EMAG_ROCKETS) <= points_to_check) // bulk discount :^) landingzone = GLOB.areas_by_type[pick(GLOB.the_station_areas)] //override default landing zone for(var/turf/open/floor/T in landingzone.contents) if(is_blocked_turf(T)) @@ -196,7 +203,7 @@ LAZYADD(empty_turfs, T) CHECK_TICK if(empty_turfs && empty_turfs.len) - SSshuttle.points -= SO.pack.cost * (0.72*MAX_EMAG_ROCKETS) + D.adjust_money(-(SO.pack.cost * (0.72*MAX_EMAG_ROCKETS))) SSblackbox.record_feedback("nested tally", "cargo_imports", MAX_EMAG_ROCKETS, list("[SO.pack.cost * 0.72]", "[SO.pack.name]")) SO.generateRequisition(get_turf(src)) for(var/i in 1 to MAX_EMAG_ROCKETS) diff --git a/code/modules/cargo/order.dm b/code/modules/cargo/order.dm index b78f218348..5e6f7c677d 100644 --- a/code/modules/cargo/order.dm +++ b/code/modules/cargo/order.dm @@ -28,14 +28,16 @@ var/orderer_ckey var/reason var/datum/supply_pack/pack + var/datum/bank_account/paying_account -/datum/supply_order/New(datum/supply_pack/pack, orderer, orderer_rank, orderer_ckey, reason) +/datum/supply_order/New(datum/supply_pack/pack, orderer, orderer_rank, orderer_ckey, reason, paying_account) id = SSshuttle.ordernum++ src.pack = pack src.orderer = orderer src.orderer_rank = orderer_rank src.orderer_ckey = orderer_ckey src.reason = reason + src.paying_account = paying_account /datum/supply_order/proc/generateRequisition(turf/T) var/obj/item/paper/P = new(T) @@ -47,6 +49,8 @@ P.info += "Item: [pack.name]
" P.info += "Access Restrictions: [get_access_desc(pack.access)]
" P.info += "Requested by: [orderer]
" + if(paying_account) + P.info += "Paid by: [paying_account.account_holder]
" P.info += "Rank: [orderer_rank]
" P.info += "Comment: [reason]
" @@ -61,6 +65,9 @@ P.name = "shipping manifest - #[id] ([pack.name])" P.info += "

[command_name()] Shipping Manifest

" P.info += "
" + if(paying_account) + P.info += "Direct purchase from [paying_account.account_holder]
" + P.name += " - Purchased by [paying_account.account_holder]" P.info += "Order #[id]
" P.info += "Destination: [station_name]
" P.info += "Item: [pack.name]
" @@ -84,7 +91,7 @@ return P /datum/supply_order/proc/generate(atom/A) - var/obj/structure/closet/crate/C = pack.generate(A) + var/obj/structure/closet/crate/C = pack.generate(A, paying_account) var/obj/item/paper/fluff/jobs/cargo/manifest/M = generateManifest(C) if(M.errors & MANIFEST_ERROR_ITEM) diff --git a/code/modules/cargo/packs.dm b/code/modules/cargo/packs.dm index 07a75bbfaf..96557d58ef 100644 --- a/code/modules/cargo/packs.dm +++ b/code/modules/cargo/packs.dm @@ -16,16 +16,20 @@ var/DropPodOnly = FALSE //only usable by the Bluespace Drop Pod via the express cargo console var/admin_spawned = FALSE //Can only an admin spawn this crate? -/datum/supply_pack/proc/generate(atom/A) - var/obj/structure/closet/crate/C = new crate_type(A) - C.name = crate_name +/datum/supply_pack/proc/generate(atom/A, datum/bank_account/paying_account) + var/obj/structure/closet/crate/C + if(paying_account) + C = new /obj/structure/closet/crate/secure/owned(A, paying_account) + C.name = "[crate_name] - Purchased by [paying_account.account_holder]" + else + C = new crate_type(A) + C.name = crate_name if(access) C.req_access = list(access) if(access_any) C.req_one_access = access_any fill(C) - return C /datum/supply_pack/proc/fill(obj/structure/closet/crate/C) diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index f7d251f32d..1fbf93a914 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -900,7 +900,12 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "Ghosts of Others:[button_name]
" dat += "
" + dat += "FPS:[clientfps]
" + + dat += "Income Updates:[(chat_toggles & CHAT_BANKCARD) ? "Allowed" : "Muted"]
" + dat += "
" + dat += "Parallax (Fancy Space):" switch (parallax) if (PARALLAX_LOW) diff --git a/code/modules/client/preferences_toggles.dm b/code/modules/client/preferences_toggles.dm index 8f7156863d..2670e1bcf4 100644 --- a/code/modules/client/preferences_toggles.dm +++ b/code/modules/client/preferences_toggles.dm @@ -250,6 +250,16 @@ TOGGLE_CHECKBOX(/datum/verbs/menu/Settings, listen_ooc)() /datum/verbs/menu/Settings/listen_ooc/Get_checked(client/C) return C.prefs.chat_toggles & CHAT_OOC +TOGGLE_CHECKBOX(/datum/verbs/menu/Settings, listen_bank_card)() + set name = "Show/Hide Income Updates" + set category = "Preferences" + set desc = "Show or hide updates to your income" + usr.client.prefs.chat_toggles ^= CHAT_BANKCARD + usr.client.prefs.save_preferences() + to_chat(usr, "You will [(usr.client.prefs.chat_toggles & CHAT_BANKCARD) ? "now" : "no longer"] be notified when you get paid.") + SSblackbox.record_feedback("nested tally", "preferences_verb", 1, list("Toggle Income Notifications", "[(usr.client.prefs.chat_toggles & CHAT_BANKCARD) ? "Enabled" : "Disabled"]")) +/datum/verbs/menu/Settings/listen_bank_card/Get_checked(client/C) + return C.prefs.chat_toggles & CHAT_BANKCARD GLOBAL_LIST_INIT(ghost_forms, list("ghost","ghostking","ghostian2","skeleghost","ghost_red","ghost_black", \ "ghost_blue","ghost_yellow","ghost_green","ghost_pink", \ diff --git a/code/modules/clothing/ears/_ears.dm b/code/modules/clothing/ears/_ears.dm index 1c31e19202..39d23c0107 100644 --- a/code/modules/clothing/ears/_ears.dm +++ b/code/modules/clothing/ears/_ears.dm @@ -6,6 +6,7 @@ throwforce = 0 slot_flags = ITEM_SLOT_EARS resistance_flags = NONE + custom_price = 250 /obj/item/clothing/ears/earmuffs name = "earmuffs" @@ -30,6 +31,7 @@ slot_flags = ITEM_SLOT_EARS | ITEM_SLOT_HEAD | ITEM_SLOT_NECK //Fluff item, put it whereever you want! actions_types = list(/datum/action/item_action/toggle_headphones) var/headphones_on = FALSE + custom_price = 125 /obj/item/clothing/ears/headphones/Initialize() . = ..() diff --git a/code/modules/clothing/gloves/color.dm b/code/modules/clothing/gloves/color.dm index 77f06a8a74..63521c9b75 100644 --- a/code/modules/clothing/gloves/color.dm +++ b/code/modules/clothing/gloves/color.dm @@ -10,6 +10,8 @@ permeability_coefficient = 0.05 resistance_flags = NONE var/can_be_cut = 1 + custom_price = 1200 + custom_premium_price = 1200 /obj/item/clothing/gloves/color/fyellow //Cheap Chinese Crap desc = "These gloves are cheap knockoffs of the coveted ones - no way this can end badly." diff --git a/code/modules/clothing/gloves/miscellaneous.dm b/code/modules/clothing/gloves/miscellaneous.dm index a37dc8b638..948f14a960 100644 --- a/code/modules/clothing/gloves/miscellaneous.dm +++ b/code/modules/clothing/gloves/miscellaneous.dm @@ -10,6 +10,7 @@ cold_protection = HANDS min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT strip_mod = 0.9 + custom_price = 75 /obj/item/clothing/gloves/fingerless/pugilist name = "armwraps" diff --git a/code/modules/clothing/head/beanie.dm b/code/modules/clothing/head/beanie.dm index 4117e88811..79f8931889 100644 --- a/code/modules/clothing/head/beanie.dm +++ b/code/modules/clothing/head/beanie.dm @@ -5,6 +5,7 @@ name = "white beanie" desc = "A stylish beanie. The perfect winter accessory for those with a keen fashion sense, and those who just can't handle a cold breeze on their heads." icon_state = "beanie" //Default white + custom_price = 60 /obj/item/clothing/head/beanie/black name = "black beanie" diff --git a/code/modules/clothing/head/helmet.dm b/code/modules/clothing/head/helmet.dm index 9ad05efb7a..987faf8fbb 100644 --- a/code/modules/clothing/head/helmet.dm +++ b/code/modules/clothing/head/helmet.dm @@ -58,6 +58,7 @@ desc = "A reliable, blue tinted helmet reminding you that you still owe that engineer a beer." icon_state = "blueshift" item_state = "blueshift" + custom_premium_price = 750 /obj/item/clothing/head/helmet/riot name = "riot helmet" diff --git a/code/modules/clothing/head/misc.dm b/code/modules/clothing/head/misc.dm index 2cb043ba88..8627887492 100644 --- a/code/modules/clothing/head/misc.dm +++ b/code/modules/clothing/head/misc.dm @@ -129,6 +129,7 @@ dog_fashion = /datum/dog_fashion/head/pirate /obj/item/clothing/head/pirate/captain + name = "pirate captain hat" icon_state = "hgpiratecap" item_state = "hgpiratecap" diff --git a/code/modules/clothing/neck/_neck.dm b/code/modules/clothing/neck/_neck.dm index 402ea37f21..3052d7af8e 100644 --- a/code/modules/clothing/neck/_neck.dm +++ b/code/modules/clothing/neck/_neck.dm @@ -22,6 +22,7 @@ icon_state = "bluetie" item_state = "" //no inhands w_class = WEIGHT_CLASS_SMALL + custom_price = 60 /obj/item/clothing/neck/tie/blue name = "blue tie" @@ -87,6 +88,7 @@ /obj/item/clothing/neck/scarf //Default white color, same functionality as beanies. name = "white scarf" icon_state = "scarf" + custom_price = 60 desc = "A stylish scarf. The perfect winter accessory for those with a keen fashion sense, and those who just can't handle a cold breeze on their necks." dog_fashion = /datum/dog_fashion/head @@ -251,6 +253,40 @@ icon = 'icons/obj/clothing/neck.dmi' icon_state = "bling" +/obj/item/clothing/neck/necklace/dope/merchant + desc = "Don't ask how it works, the proof is in the holochips!" + /// scales the amount received in case an admin wants to emulate taxes/fees. + var/profit_scaling = 1 + /// toggles between sell (TRUE) and get price post-fees (FALSE) + var/selling = FALSE + +/obj/item/clothing/neck/necklace/dope/merchant/attack_self(mob/user) + . = ..() + selling = !selling + to_chat(user, "[src] has been set to [selling ? "'Sell'" : "'Get Price'"] mode.") + +/obj/item/clothing/neck/necklace/dope/merchant/afterattack(obj/item/I, mob/user, proximity) + . = ..() + if(!proximity) + return + var/datum/export_report/ex = export_item_and_contents(I, allowed_categories = (ALL), dry_run=TRUE) + var/price = 0 + for(var/x in ex.total_amount) + price += ex.total_value[x] + + if(price) + var/true_price = round(price*profit_scaling) + to_chat(user, "[selling ? "Sold" : "Getting the price of"] [I], value: [true_price] credits[I.contents.len ? " (exportable contents included)" : ""].[profit_scaling < 1 && selling ? "[round(price-true_price)] credit\s taken as processing fee\s." : ""]") + if(selling) + new /obj/item/holochip(get_turf(user),true_price) + for(var/i in ex.exported_atoms_ref) + var/atom/movable/AM = i + if(QDELETED(AM)) + continue + qdel(AM) + else + to_chat(user, "There is no export value for [I] or any items within it.") + ////////////////////////////////// //VERY SUPER BADASS NECKERCHIEFS// ////////////////////////////////// diff --git a/code/modules/clothing/outfits/vr.dm b/code/modules/clothing/outfits/vr.dm index ee350e3891..669c03be2c 100644 --- a/code/modules/clothing/outfits/vr.dm +++ b/code/modules/clothing/outfits/vr.dm @@ -3,15 +3,21 @@ uniform = /obj/item/clothing/under/color/random shoes = /obj/item/clothing/shoes/sneakers/black ears = /obj/item/radio/headset - id = /obj/item/card/id + id = /obj/item/card/id/locked_banking + var/starting_funds = 350 /datum/outfit/vr/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE, client/preference_source) H.dna.species.before_equip_job(null, H) /datum/outfit/vr/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE, client/preference_source) var/obj/item/card/id/id = H.wear_id - if (istype(id)) - id.access |= get_all_accesses() + if(!istype(id)) + return + id.access |= get_all_accesses() + if(id.registered_account) + id.registered_account.account_holder = "[H.real_name] (VR)" + if(starting_funds && id.bank_support == ID_LOCKED_BANK_ACCOUNT) //No payroll or ability to virtually transfer funds to an external account. + id.registered_account.adjust_money(starting_funds) /datum/outfit/vr/syndicate name = "Syndicate VR Operative - Basic" @@ -19,11 +25,12 @@ shoes = /obj/item/clothing/shoes/combat gloves = /obj/item/clothing/gloves/combat back = /obj/item/storage/backpack - id = /obj/item/card/id/syndicate + id = /obj/item/card/id/syndicate/locked_banking belt = /obj/item/gun/ballistic/automatic/pistol l_pocket = /obj/item/paper/fluff/vr/fluke_ops backpack_contents = list(/obj/item/storage/box/syndie=1,\ /obj/item/kitchen/knife/combat/survival) + starting_funds = 0 //Should be operating, not shopping. /datum/outfit/vr/syndicate/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE, client/preference_source) . = ..() diff --git a/code/modules/clothing/shoes/colour.dm b/code/modules/clothing/shoes/colour.dm index df0f03f614..8cadb84cef 100644 --- a/code/modules/clothing/shoes/colour.dm +++ b/code/modules/clothing/shoes/colour.dm @@ -1,5 +1,6 @@ /obj/item/clothing/shoes/sneakers dying_key = DYE_REGISTRY_SNEAKERS + custom_price = 50 /obj/item/clothing/shoes/sneakers/black name = "black shoes" diff --git a/code/modules/clothing/shoes/miscellaneous.dm b/code/modules/clothing/shoes/miscellaneous.dm index 7a3ed902ea..d6d4b1af1e 100644 --- a/code/modules/clothing/shoes/miscellaneous.dm +++ b/code/modules/clothing/shoes/miscellaneous.dm @@ -71,6 +71,7 @@ equip_delay_other = 50 resistance_flags = NONE armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 40, "acid" = 75) + custom_price = 600 /obj/item/clothing/shoes/galoshes/dry name = "absorbent galoshes" @@ -371,6 +372,7 @@ /obj/item/clothing/shoes/cowboyboots name = "cowboy boots" desc = "A standard pair of brown cowboy boots." + custom_price = 60 //remember to replace these lame cosmetics with tg's YEEEEHAW counterparts. icon_state = "cowboyboots" /obj/item/clothing/shoes/cowboyboots/black diff --git a/code/modules/clothing/suits/armor.dm b/code/modules/clothing/suits/armor.dm index a19dfaa889..0df1b1e18c 100644 --- a/code/modules/clothing/suits/armor.dm +++ b/code/modules/clothing/suits/armor.dm @@ -47,6 +47,7 @@ desc = "A large, yet comfortable piece of armor, protecting you from some threats." icon_state = "blueshift" item_state = "blueshift" + custom_premium_price = 750 /obj/item/clothing/suit/armor/hos name = "armored greatcoat" diff --git a/code/modules/clothing/under/miscellaneous.dm b/code/modules/clothing/under/miscellaneous.dm index d475ca8100..4ff3a3f9de 100644 --- a/code/modules/clothing/under/miscellaneous.dm +++ b/code/modules/clothing/under/miscellaneous.dm @@ -86,6 +86,7 @@ icon_state = "overalls" item_state = "lb_suit" can_adjust = FALSE + custom_price = 60 /obj/item/clothing/under/misc/assistantformal name = "assistant's formal uniform" diff --git a/code/modules/clothing/under/pants.dm b/code/modules/clothing/under/pants.dm index d0048326ff..11543ac675 100644 --- a/code/modules/clothing/under/pants.dm +++ b/code/modules/clothing/under/pants.dm @@ -3,6 +3,7 @@ body_parts_covered = GROIN|LEGS fitted = NO_FEMALE_UNIFORM can_adjust = FALSE + custom_price = 60 /obj/item/clothing/under/pants/classicjeans name = "classic jeans" @@ -13,6 +14,7 @@ name = "Must Hang jeans" desc = "Made in the finest space jeans factory this side of Alpha Centauri." icon_state = "jeansmustang" + custom_price = 180 /obj/item/clothing/under/pants/blackjeans name = "black jeans" diff --git a/code/modules/clothing/under/skirt_dress.dm b/code/modules/clothing/under/skirt_dress.dm index fa2c9eed71..94483f5804 100644 --- a/code/modules/clothing/under/skirt_dress.dm +++ b/code/modules/clothing/under/skirt_dress.dm @@ -15,6 +15,7 @@ body_parts_covered = CHEST|GROIN|ARMS fitted = FEMALE_UNIFORM_TOP can_adjust = FALSE + custom_price = 60 /obj/item/clothing/under/dress/skirt/red name = "red skirt" @@ -24,6 +25,7 @@ body_parts_covered = CHEST|GROIN|ARMS fitted = FEMALE_UNIFORM_TOP can_adjust = FALSE + custom_price = 60 /obj/item/clothing/under/dress/skirt/purple name = "purple skirt" @@ -33,6 +35,7 @@ body_parts_covered = CHEST|GROIN|ARMS fitted = FEMALE_UNIFORM_TOP can_adjust = FALSE + custom_price = 60 /obj/item/clothing/under/dress/sundress name = "sundress" @@ -146,6 +149,7 @@ fitted = FEMALE_UNIFORM_TOP can_adjust = TRUE alt_covers_chest = TRUE + custom_price = 60 /obj/item/clothing/under/dress/skirt/plaid/blue name = "blue plaid skirt" diff --git a/code/modules/economy/_economy.dm b/code/modules/economy/_economy.dm new file mode 100644 index 0000000000..9bafb62eae --- /dev/null +++ b/code/modules/economy/_economy.dm @@ -0,0 +1,2 @@ +/obj/item/proc/get_item_credit_value() + return \ No newline at end of file diff --git a/code/modules/economy/account.dm b/code/modules/economy/account.dm new file mode 100644 index 0000000000..f9addc1f14 --- /dev/null +++ b/code/modules/economy/account.dm @@ -0,0 +1,118 @@ +#define DUMPTIME 3000 + +/datum/bank_account + var/account_holder = "Rusty Venture" + var/account_balance = 0 + var/datum/job/account_job + var/list/bank_cards = list() + var/add_to_accounts = TRUE + var/transferable = TRUE + var/account_id + var/being_dumped = FALSE //pink levels are rising + var/withdrawDelay = 0 + +/datum/bank_account/New(newname, job) + if(add_to_accounts) + SSeconomy.bank_accounts += src + account_holder = newname + account_job = job + account_id = rand(111111,999999) + +/datum/bank_account/Destroy() + if(add_to_accounts) + SSeconomy.bank_accounts -= src + return ..() + +/datum/bank_account/proc/dumpeet() + being_dumped = TRUE + withdrawDelay = world.time + DUMPTIME + +/datum/bank_account/proc/_adjust_money(amt) + account_balance += amt + if(account_balance < 0) + account_balance = 0 + +/datum/bank_account/proc/has_money(amt) + return account_balance >= amt + +/datum/bank_account/proc/adjust_money(amt) + if((amt < 0 && has_money(-amt)) || amt > 0) + _adjust_money(amt) + return TRUE + return FALSE + +/datum/bank_account/proc/transfer_money(datum/bank_account/from, amount) + if(!transferable || !from.has_money(amount)) + return FALSE + adjust_money(amount) + from.adjust_money(-amount) + return TRUE + +/datum/bank_account/proc/payday(amt_of_paychecks, free = FALSE) + var/money_to_transfer = account_job.paycheck * amt_of_paychecks + if(free) + adjust_money(money_to_transfer) + else + var/datum/bank_account/D = SSeconomy.get_dep_account(account_job.paycheck_department) + if(D) + if(!transfer_money(D, money_to_transfer)) + bank_card_talk("ERROR: Payday aborted, departmental funds insufficient.") + return FALSE + else + bank_card_talk("Payday processed, account now holds [account_balance] cr.") + return TRUE + bank_card_talk("ERROR: Payday aborted, unable to contact departmental account.") + return FALSE + +/datum/bank_account/proc/bank_card_talk(message, force) + if(!message || !bank_cards.len) + return + for(var/obj/A in bank_cards) + var/icon_source = A + /* + if(istype(A, /obj/item/card/id)) + var/obj/item/card/id/id_card = A + if(id_card.uses_overlays) + icon_source = id_card.get_cached_flat_icon() + */ + var/mob/card_holder = recursive_loc_check(A, /mob) + if(ismob(card_holder)) //If on a mob + if(card_holder.client && !(card_holder.client.prefs.chat_toggles & CHAT_BANKCARD) && !force) + return + + card_holder.playsound_local(get_turf(card_holder), 'sound/machines/twobeep.ogg', 50, TRUE) + if(card_holder.can_hear()) + to_chat(card_holder, "[icon2html(icon_source, card_holder)] [message]") + else if(isturf(A.loc)) //If on the ground + for(var/mob/M in hearers(1,get_turf(A))) + if(M.client && !(M.client.prefs.chat_toggles & CHAT_BANKCARD) && !force) + return + playsound(A, 'sound/machines/twobeep.ogg', 50, TRUE) + A.audible_message("[icon2html(icon_source, hearers(A))] [message]", null, 1) + break + else + for(var/mob/M in A.loc) //If inside a container with other mobs (e.g. locker) + if(M.client && !(M.client.prefs.chat_toggles & CHAT_BANKCARD) && !force) + return + M.playsound_local(get_turf(M), 'sound/machines/twobeep.ogg', 50, TRUE) + if(M.can_hear()) + to_chat(M, "[icon2html(icon_source, M)] [message]") + +/datum/bank_account/department + account_holder = "Guild Credit Agency" + var/department_id = "REPLACE_ME" + add_to_accounts = FALSE + +/datum/bank_account/department/New(dep_id, budget) + department_id = dep_id + account_balance = budget + account_holder = SSeconomy.department_accounts[dep_id] + SSeconomy.generated_accounts += src + +/datum/bank_account/remote // Bank account not belonging to the local station + add_to_accounts = FALSE + +/datum/bank_account/remote/non_transferable + transferable = FALSE + +#undef DUMPTIME diff --git a/code/modules/economy/paystand.dm b/code/modules/economy/paystand.dm new file mode 100644 index 0000000000..f674bc230d --- /dev/null +++ b/code/modules/economy/paystand.dm @@ -0,0 +1,138 @@ +/obj/machinery/paystand + name = "unregistered pay stand" + desc = "See title." + icon = 'icons/obj/economy.dmi' + icon_state = "card_scanner" + density = TRUE + anchored = TRUE + var/locked = FALSE + var/obj/item/card/id/my_card + var/obj/item/assembly/signaler/signaler //attached signaler, let people attach signalers that get activated if the user's transaction limit is achieved. + var/signaler_threshold = 0 //signaler threshold amount + var/amount_deposited = 0 //keep track of the amount deposited over time so you can pay multiple times to reach the signaler threshold + var/force_fee = 0 //replaces the "pay whatever" functionality with a set amount when non-zero. + +/obj/machinery/paystand/attackby(obj/item/W, mob/user, params) + if(istype(W, /obj/item/card/id)) + if(W == my_card) + if(user.a_intent == INTENT_DISARM) + var/rename_msg = stripped_input(user, "Rename the Paystand:", "Paystand Naming", name) + if(!rename_msg || !user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) + return + name = rename_msg + return + else if(user.a_intent == INTENT_GRAB) + var/force_fee_input = input(user,"Set the fee!","Set a fee!",0) as num|null + if(isnull(force_fee_input) || !user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) + return + force_fee = force_fee_input + return + locked = !locked + to_chat(user, "You [src.locked ? "lock" : "unlock"] the paystand, protecting the bolts from [anchored ? "loosening" : "tightening"].") + return + if(!my_card) + var/obj/item/card/id/assistant_mains_need_to_die = W + if(!assistant_mains_need_to_die.registered_account) + return + var/msg = stripped_input(user, "Name of pay stand:", "Paystand Naming", "[user]'s Awesome Paystand") + if(!msg) + return + name = msg + desc = "Owned by [assistant_mains_need_to_die.registered_account.account_holder], pays directly into [user.p_their()] account." + my_card = assistant_mains_need_to_die + to_chat(user, "You link the stand to your account.") + return + var/obj/item/card/id/vbucks = W + if(vbucks.registered_account) + var/momsdebitcard = 0 + if(!force_fee) + momsdebitcard = input(user, "How much would you like to deposit?", "Money Deposit") as null|num + else + momsdebitcard = force_fee + if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) + return + if(momsdebitcard < 1) + to_chat(user, "ERROR: Invalid amount designated.") + return + if(vbucks.registered_account.adjust_money(-momsdebitcard)) + purchase(vbucks.registered_account.account_holder, momsdebitcard) + to_chat(user, "Thanks for purchasing! The vendor has been informed.") + return + else + to_chat(user, "ERROR: Account has insufficient funds to make transaction.") + return + else + to_chat(user, "ERROR: No bank account assigned to identification card.") + return + if(istype(W, /obj/item/holochip)) + var/obj/item/holochip/H = W + var/cashmoney = input(user, "How much would you like to deposit?", "Money Deposit") as null|num + if(H.spend(cashmoney, FALSE)) + purchase(user, cashmoney) + to_chat(user, "Thanks for purchasing! The vendor has been informed.") + return + else + to_chat(user, "ERROR: Insufficient funds to make transaction.") + return + if(istype(W, /obj/item/stack/spacecash)) + to_chat(user, "What is this, the 2000s? We only take card here.") + return + if(istype(W, /obj/item/coin)) + to_chat(user, "What is this, the 1800s? We only take card here.") + return + if(istype(W, /obj/item/assembly/signaler)) + var/obj/item/assembly/signaler/S = W + if(S.secured) + to_chat(user, "The signaler needs to be in attachable mode to add it to the paystand!") + return + if(!my_card) + to_chat(user, "ERROR: No identification card has been assigned to this paystand yet!") + return + if(!signaler) + var/cash_limit = input(user, "Enter the minimum amount of cash needed to deposit before the signaler is activated.", "Signaler Activation Threshold") as null|num + if(cash_limit < 1) + to_chat(user, "ERROR: Invalid amount designated.") + return + if(cash_limit) + S.forceMove(src) + signaler = S + signaler_threshold = cash_limit + to_chat(user, "You attach the signaler to the paystand.") + desc += " A signaler appears to be attached to the scanner." + else + to_chat(user, "A signaler is already attached to this unit!") + + if(default_deconstruction_screwdriver(user, "card_scanner", "card_scanner", W)) + return + + else if(default_pry_open(W)) + return + + else if(default_unfasten_wrench(user, W)) + return + + else if(default_deconstruction_crowbar(W)) + return + else + return ..() + +/obj/machinery/paystand/proc/purchase(buyer, price) + my_card.registered_account.adjust_money(price) + my_card.registered_account.bank_card_talk("Purchase made at your vendor by [buyer] for [price] credits.") + amount_deposited = amount_deposited + price + if(signaler && amount_deposited >= signaler_threshold) + signaler.activate() + amount_deposited = 0 + +/obj/machinery/paystand/default_unfasten_wrench(mob/user, obj/item/I, time = 20) + if(locked) + to_chat(user, "The bolts on this paystand are currently covered!") + return FALSE + . = ..() + +/obj/machinery/paystand/examine(mob/user) + . = ..() + if(force_fee) + . += "This paystand forces a payment of [force_fee] credit\s per swipe instead of a variable amount." + if(user.get_active_held_item() == my_card) + . += "Paystands can be edited through swiping your card with different intents. Disarm allows editing the name while Grab changes payment functionality." diff --git a/code/modules/events/pirates.dm b/code/modules/events/pirates.dm index 86ff1ed0da..0198dd445e 100644 --- a/code/modules/events/pirates.dm +++ b/code/modules/events/pirates.dm @@ -29,7 +29,9 @@ if(fake) return threat_message = new - payoff = round(SSshuttle.points * 0.80) + var/datum/bank_account/D = SSeconomy.get_dep_account(ACCOUNT_CAR) + if(D) + payoff = round(D.account_balance * 0.80) threat_message.title = "Business proposition" threat_message.content = "This is [ship_name]. Pay up [payoff] credits or you'll walk the plank." threat_message.possible_answers = list("We'll pay.","No way.") @@ -38,13 +40,14 @@ /datum/round_event/pirates/proc/answered() if(threat_message && threat_message.answered == 1) - if(SSshuttle.points >= payoff) - SSshuttle.points -= payoff - priority_announce("Thanks for the credits, landlubbers.",sender_override = ship_name) - paid_off = TRUE - return - else - priority_announce("Trying to cheat us? You'll regret this!",sender_override = ship_name) + var/datum/bank_account/D = SSeconomy.get_dep_account(ACCOUNT_CAR) + if(D) + if(D.adjust_money(-payoff)) + priority_announce("Thanks for the credits, landlubbers.",sender_override = ship_name) + paid_off = TRUE + return + else + priority_announce("Trying to cheat us? You'll regret this!",sender_override = ship_name) if(!shuttle_spawned) spawn_shuttle() @@ -101,9 +104,10 @@ /obj/machinery/shuttle_scrambler/process() if(active) if(is_station_level(z)) - var/siphoned = min(SSshuttle.points,siphon_per_tick) - SSshuttle.points -= siphoned - credits_stored += siphoned + var/datum/bank_account/D = SSeconomy.get_dep_account(ACCOUNT_CAR) + if(D) + var/siphoned = min(D.account_balance,siphon_per_tick) + D.adjust_money(-siphoned) interrupt_research() else return @@ -139,12 +143,7 @@ new /obj/effect/temp_visual/emp(get_turf(S)) /obj/machinery/shuttle_scrambler/proc/dump_loot(mob/user) - if(credits_stored < 200) - to_chat(user,"Not enough credits to retrieve.") - return - while(credits_stored >= 200) - new /obj/item/stack/spacecash/c200(drop_location()) - credits_stored -= 200 + new /obj/item/holochip(drop_location(), credits_stored) to_chat(user,"You retrieve the siphoned credits!") credits_stored = 0 @@ -456,3 +455,12 @@ /datum/export/pirate/cash/get_amount(obj/O) var/obj/item/stack/spacecash/C = O return ..() * C.amount * C.value + +/datum/export/pirate/holochip + cost = 1 + unit_name = "holochip" + export_types = list(/obj/item/holochip) + +/datum/export/pirate/holochip/get_cost(atom/movable/AM) + var/obj/item/holochip/H = AM + return H.credits diff --git a/code/modules/events/shuttle_loan.dm b/code/modules/events/shuttle_loan.dm index c585961604..bf9f25cb04 100644 --- a/code/modules/events/shuttle_loan.dm +++ b/code/modules/events/shuttle_loan.dm @@ -69,7 +69,9 @@ priority_announce(thanks_msg, "Cargo shuttle commandeered by CentCom.") dispatched = 1 - SSshuttle.points += bonus_points + var/datum/bank_account/D = SSeconomy.get_dep_account(ACCOUNT_CAR) + if(D) + D.adjust_money(bonus_points) endWhen = activeFor + 1 SSshuttle.supply.mode = SHUTTLE_CALL diff --git a/code/modules/food_and_drinks/drinks/drinks.dm b/code/modules/food_and_drinks/drinks/drinks.dm index 1592efb032..46600e9fee 100644 --- a/code/modules/food_and_drinks/drinks/drinks.dm +++ b/code/modules/food_and_drinks/drinks/drinks.dm @@ -147,7 +147,7 @@ return if (!(locate(/obj/structure/table) in src_location) || !(locate(/obj/structure/table) in over_location)) return - + //Are we an expert slider? var/datum/action/innate/D = get_action_of_type(user, /datum/action/innate/drink_fling) if(!D?.active) @@ -268,6 +268,7 @@ /obj/item/reagent_containers/food/drinks/ice name = "ice cup" desc = "Careful, cold ice, do not chew." + custom_price = 15 icon_state = "coffee" list_reagents = list(/datum/reagent/consumable/ice = 30) spillable = TRUE @@ -281,7 +282,7 @@ spillable = TRUE /obj/item/reagent_containers/food/drinks/mug/on_reagent_change(changetype) - cut_overlays() + cut_overlays() if(reagents.total_volume) var/mutable_appearance/MA = mutable_appearance(icon,"mugoverlay") MA.color = mix_color_from_reagents(reagents.reagent_list) @@ -302,6 +303,7 @@ list_reagents = list(/datum/reagent/consumable/hot_coco = 30, /datum/reagent/consumable/sugar = 5) foodtype = SUGAR resistance_flags = FREEZE_PROOF + custom_price = 120 /obj/item/reagent_containers/food/drinks/dry_ramen name = "cup ramen" @@ -310,6 +312,7 @@ list_reagents = list(/datum/reagent/consumable/dry_ramen = 30) foodtype = GRAIN isGlass = FALSE + custom_price = 95 /obj/item/reagent_containers/food/drinks/beer name = "space beer" @@ -317,6 +320,7 @@ icon_state = "beer" list_reagents = list(/datum/reagent/consumable/ethanol/beer = 30) foodtype = GRAIN | ALCOHOL + custom_price = 60 /obj/item/reagent_containers/food/drinks/beer/light name = "Carp Lite" @@ -417,6 +421,7 @@ custom_materials = list(/datum/material/iron=250) volume = 60 isGlass = FALSE + custom_price = 200 /obj/item/reagent_containers/food/drinks/flask/gold name = "captain's flask" @@ -447,6 +452,7 @@ reagent_flags = NONE spillable = FALSE isGlass = FALSE + custom_price = 45 /obj/item/reagent_containers/food/drinks/soda_cans/suicide_act(mob/living/carbon/user) user.visible_message("[user] is trying to eat \the [src]! It looks like [user.p_theyre()] trying to commit suicide!") diff --git a/code/modules/food_and_drinks/drinks/drinks/bottle.dm b/code/modules/food_and_drinks/drinks/drinks/bottle.dm index 95b9f92873..21c3af442e 100644 --- a/code/modules/food_and_drinks/drinks/drinks/bottle.dm +++ b/code/modules/food_and_drinks/drinks/drinks/bottle.dm @@ -254,6 +254,7 @@ var/shortname = pickweight( list("T&T" = 1, "A&A" = 1, "Generic" = 1)) var/fullname + var/removals = GLOB.redacted_strings.Copy() switch(shortname) if("T&T") fullname = "Teal and Tealer" @@ -261,9 +262,6 @@ fullname = "Ash and Asher" if("Generic") fullname = "Nanotrasen Cheap Imitations" - var/removals = list("\[REDACTED\]", "\[EXPLETIVE DELETED\]", - "\[EXPUNGED\]", "\[INFORMATION ABOVE YOUR SECURITY CLEARANCE\]", - "\[MOVE ALONG CITIZEN\]", "\[NOTHING TO SEE HERE\]") var/chance = 50 if(prob(chance)) @@ -348,6 +346,7 @@ /obj/item/reagent_containers/food/drinks/bottle/applejack name = "Buckin' Bronco's Applejack" desc = "Kicks like a horse, tastes like an apple!" + custom_price = 100 icon_state = "applejack_bottle" list_reagents = list(/datum/reagent/consumable/ethanol/applejack = 100) foodtype = FRUIT @@ -358,6 +357,7 @@ /obj/item/reagent_containers/food/drinks/bottle/champagne name = "Eau d' Dandy Brut Champagne" desc = "Finely sourced from only the most pretentious French vineyards." + custom_premium_price = 250 icon_state = "champagne_bottle" list_reagents = list(/datum/reagent/consumable/ethanol/champagne = 100) @@ -376,6 +376,7 @@ /obj/item/reagent_containers/food/drinks/bottle/trappist name = "Mont de Requin Trappistes Bleu" desc = "Brewed in space-Belgium. Fancy!" + custom_premium_price = 170 icon_state = "trappistbottle" volume = 50 list_reagents = list(/datum/reagent/consumable/ethanol/trappist = 50) @@ -388,6 +389,7 @@ /obj/item/reagent_containers/food/drinks/bottle/orangejuice name = "orange juice" desc = "Full of vitamins and deliciousness!" + custom_price = 100 icon_state = "orangejuice" item_state = "carton" lefthand_file = 'icons/mob/inhands/equipment/kitchen_lefthand.dmi' @@ -399,6 +401,7 @@ /obj/item/reagent_containers/food/drinks/bottle/cream name = "milk cream" desc = "It's cream. Made from milk. What else did you think you'd find in there?" + custom_price = 100 icon_state = "cream" item_state = "carton" lefthand_file = 'icons/mob/inhands/equipment/kitchen_lefthand.dmi' @@ -410,6 +413,7 @@ /obj/item/reagent_containers/food/drinks/bottle/tomatojuice name = "tomato juice" desc = "Well, at least it LOOKS like tomato juice. You can't tell with all that redness." + custom_price = 100 icon_state = "tomatojuice" item_state = "carton" lefthand_file = 'icons/mob/inhands/equipment/kitchen_lefthand.dmi' @@ -421,6 +425,7 @@ /obj/item/reagent_containers/food/drinks/bottle/limejuice name = "lime juice" desc = "Sweet-sour goodness." + custom_price = 100 icon_state = "limejuice" item_state = "carton" lefthand_file = 'icons/mob/inhands/equipment/kitchen_lefthand.dmi' @@ -454,6 +459,7 @@ /obj/item/reagent_containers/food/drinks/bottle/menthol name = "menthol" desc = "Tastes naturally minty, and imparts a very mild numbing sensation." + custom_price = 100 icon_state = "mentholbox" item_state = "carton" lefthand_file = 'icons/mob/inhands/equipment/kitchen_lefthand.dmi' @@ -464,6 +470,7 @@ /obj/item/reagent_containers/food/drinks/bottle/grenadine name = "Jester Grenadine" desc = "Contains 0% real cherries!" + custom_price = 100 icon_state = "grenadine" isGlass = TRUE list_reagents = list(/datum/reagent/consumable/grenadine = 100) diff --git a/code/modules/food_and_drinks/drinks/drinks/drinkingglass.dm b/code/modules/food_and_drinks/drinks/drinks/drinkingglass.dm index defc44ed51..5ebcec91b9 100644 --- a/code/modules/food_and_drinks/drinks/drinks/drinkingglass.dm +++ b/code/modules/food_and_drinks/drinks/drinks/drinkingglass.dm @@ -11,6 +11,7 @@ spillable = TRUE resistance_flags = ACID_PROOF obj_flags = UNIQUE_RENAME + custom_price = 25 /obj/item/reagent_containers/food/drinks/drinkingglass/on_reagent_change(changetype) cut_overlays() @@ -46,6 +47,7 @@ possible_transfer_amounts = list() volume = 15 custom_materials = list(/datum/material/glass=100) + custom_price = 20 /obj/item/reagent_containers/food/drinks/drinkingglass/shotglass/on_reagent_change(changetype) cut_overlays() diff --git a/code/modules/food_and_drinks/food/snacks_vend.dm b/code/modules/food_and_drinks/food/snacks_vend.dm index 239dd433b0..a4d924bae4 100644 --- a/code/modules/food_and_drinks/food/snacks_vend.dm +++ b/code/modules/food_and_drinks/food/snacks_vend.dm @@ -41,6 +41,7 @@ filling_color = "#FFD700" tastes = list("salt" = 1, "crisps" = 1) foodtype = JUNKFOOD | FRIED + custom_price = 90 /obj/item/reagent_containers/food/snacks/no_raisin name = "4no raisins" @@ -68,6 +69,7 @@ junkiness = 25 filling_color = "#FFD700" foodtype = JUNKFOOD | GRAIN | SUGAR + custom_price = 30 /obj/item/reagent_containers/food/snacks/cheesiehonkers name = "cheesie honkers" @@ -79,6 +81,7 @@ filling_color = "#FFD700" tastes = list("cheese" = 5, "crisps" = 2) foodtype = JUNKFOOD | DAIRY | SUGAR + custom_price = 45 /obj/item/reagent_containers/food/snacks/syndicake name = "syndi-cakes" diff --git a/code/modules/jobs/job_types/_job.dm b/code/modules/jobs/job_types/_job.dm index ee441c21f7..88a953e310 100644 --- a/code/modules/jobs/job_types/_job.dm +++ b/code/modules/jobs/job_types/_job.dm @@ -56,6 +56,9 @@ //can be overridden by antag_rep.txt config var/antag_rep = 10 + var/paycheck = PAYCHECK_MINIMAL + var/paycheck_department = ACCOUNT_CIV + var/list/mind_traits // Traits added to the mind of the mob assigned this job var/list/blacklisted_quirks //list of quirk typepaths blacklisted. @@ -99,7 +102,13 @@ /datum/job/proc/equip(mob/living/carbon/human/H, visualsOnly = FALSE, announce = TRUE, latejoin = FALSE, datum/outfit/outfit_override = null, client/preference_source) if(!H) return FALSE - + if(!visualsOnly) + var/datum/bank_account/bank_account = new(H.real_name, src) + bank_account.account_holder = H.real_name + bank_account.account_job = src + bank_account.account_id = rand(111111,999999) + bank_account.payday(STARTING_PAYCHECKS, TRUE) + H.account_id = bank_account.account_id if(CONFIG_GET(flag/enforce_human_authority) && (title in GLOB.command_positions)) if(H.dna.species.id != "human") H.set_species(/datum/species/human) @@ -227,12 +236,18 @@ H.real_name = "[J.title] #[rand(10000, 99999)]" var/obj/item/card/id/C = H.wear_id - if(istype(C)) + if(istype(C) && C.bank_support) C.access = J.get_access() shuffle_inplace(C.access) // Shuffle access list to make NTNet passkeys less predictable C.registered_name = H.real_name C.assignment = J.title C.update_label() + for(var/A in SSeconomy.bank_accounts) + var/datum/bank_account/B = A + if(B.account_id == H.account_id) + C.registered_account = B + B.bank_cards += C + break H.sec_hud_set_ID() var/obj/item/pda/PDA = H.get_item_by_slot(pda_slot) diff --git a/code/modules/jobs/job_types/assistant.dm b/code/modules/jobs/job_types/assistant.dm index c4fa213b61..91b3a3f581 100644 --- a/code/modules/jobs/job_types/assistant.dm +++ b/code/modules/jobs/job_types/assistant.dm @@ -14,6 +14,8 @@ Assistant minimal_access = list() //See /datum/job/assistant/get_access() outfit = /datum/outfit/job/assistant antag_rep = 7 + paycheck = PAYCHECK_ASSISTANT // Get a job. Job reassignment changes your paycheck now. Get over it. + paycheck_department = ACCOUNT_CIV display_order = JOB_DISPLAY_ORDER_ASSISTANT dresscodecompliant = FALSE threat = 0.2 diff --git a/code/modules/jobs/job_types/atmospheric_technician.dm b/code/modules/jobs/job_types/atmospheric_technician.dm index 019e50799e..0934507721 100644 --- a/code/modules/jobs/job_types/atmospheric_technician.dm +++ b/code/modules/jobs/job_types/atmospheric_technician.dm @@ -17,6 +17,8 @@ ACCESS_EXTERNAL_AIRLOCKS, ACCESS_CONSTRUCTION, ACCESS_ATMOSPHERICS, ACCESS_MINERAL_STOREROOM) minimal_access = list(ACCESS_ATMOSPHERICS, ACCESS_MAINT_TUNNELS, ACCESS_EXTERNAL_AIRLOCKS, ACCESS_ENGINE, ACCESS_ENGINE_EQUIP, ACCESS_EMERGENCY_STORAGE, ACCESS_CONSTRUCTION, ACCESS_MINERAL_STOREROOM) + paycheck = PAYCHECK_MEDIUM + paycheck_department = ACCOUNT_ENG display_order = JOB_DISPLAY_ORDER_ATMOSPHERIC_TECHNICIAN threat = 0.5 diff --git a/code/modules/jobs/job_types/bartender.dm b/code/modules/jobs/job_types/bartender.dm index 709c53d51d..e5cd015460 100644 --- a/code/modules/jobs/job_types/bartender.dm +++ b/code/modules/jobs/job_types/bartender.dm @@ -14,6 +14,8 @@ access = list(ACCESS_HYDROPONICS, ACCESS_BAR, ACCESS_KITCHEN, ACCESS_MORGUE, ACCESS_WEAPONS, ACCESS_MINERAL_STOREROOM) minimal_access = list(ACCESS_BAR, ACCESS_MINERAL_STOREROOM) + paycheck = PAYCHECK_EASY + paycheck_department = ACCOUNT_SRV display_order = JOB_DISPLAY_ORDER_BARTENDER threat = 0.5 diff --git a/code/modules/jobs/job_types/botanist.dm b/code/modules/jobs/job_types/botanist.dm index 4cf106ea99..65f3e7ca48 100644 --- a/code/modules/jobs/job_types/botanist.dm +++ b/code/modules/jobs/job_types/botanist.dm @@ -13,6 +13,8 @@ access = list(ACCESS_HYDROPONICS, ACCESS_BAR, ACCESS_KITCHEN, ACCESS_MORGUE, ACCESS_MINERAL_STOREROOM) minimal_access = list(ACCESS_HYDROPONICS, ACCESS_MORGUE, ACCESS_MINERAL_STOREROOM) + paycheck = PAYCHECK_EASY + paycheck_department = ACCOUNT_SRV display_order = JOB_DISPLAY_ORDER_BOTANIST threat = 1.5 // lol powergame diff --git a/code/modules/jobs/job_types/captain.dm b/code/modules/jobs/job_types/captain.dm index d38a2a3ddf..3733658c33 100644 --- a/code/modules/jobs/job_types/captain.dm +++ b/code/modules/jobs/job_types/captain.dm @@ -15,11 +15,15 @@ exp_type = EXP_TYPE_COMMAND exp_type_department = EXP_TYPE_COMMAND + outfit = /datum/outfit/job/captain access = list() //See get_access() minimal_access = list() //See get_access() + paycheck = PAYCHECK_COMMAND + paycheck_department = ACCOUNT_SEC + mind_traits = list(TRAIT_CAPTAIN_METABOLISM, TRAIT_DISK_VERIFIER) display_order = JOB_DISPLAY_ORDER_CAPTAIN diff --git a/code/modules/jobs/job_types/cargo_technician.dm b/code/modules/jobs/job_types/cargo_technician.dm index d574482444..840af56a0e 100644 --- a/code/modules/jobs/job_types/cargo_technician.dm +++ b/code/modules/jobs/job_types/cargo_technician.dm @@ -14,6 +14,8 @@ access = list(ACCESS_MAINT_TUNNELS, ACCESS_MAILSORTING, ACCESS_CARGO, ACCESS_CARGO_BOT, ACCESS_MINING, ACCESS_MINING_STATION, ACCESS_MINERAL_STOREROOM) minimal_access = list(ACCESS_MAINT_TUNNELS, ACCESS_CARGO, ACCESS_MAILSORTING, ACCESS_MINERAL_STOREROOM) + paycheck = PAYCHECK_EASY + paycheck_department = ACCOUNT_CAR display_order = JOB_DISPLAY_ORDER_CARGO_TECHNICIAN threat = 0.2 diff --git a/code/modules/jobs/job_types/chaplain.dm b/code/modules/jobs/job_types/chaplain.dm index cf9c5a6a3c..5f66519365 100644 --- a/code/modules/jobs/job_types/chaplain.dm +++ b/code/modules/jobs/job_types/chaplain.dm @@ -13,6 +13,8 @@ access = list(ACCESS_MORGUE, ACCESS_CHAPEL_OFFICE, ACCESS_CREMATORIUM, ACCESS_THEATRE) minimal_access = list(ACCESS_MORGUE, ACCESS_CHAPEL_OFFICE, ACCESS_CREMATORIUM, ACCESS_THEATRE) + paycheck = PAYCHECK_EASY + paycheck_department = ACCOUNT_CIV display_order = JOB_DISPLAY_ORDER_CHAPLAIN threat = 0.5 diff --git a/code/modules/jobs/job_types/chemist.dm b/code/modules/jobs/job_types/chemist.dm index 44b0e90ec8..9ffabd6a06 100644 --- a/code/modules/jobs/job_types/chemist.dm +++ b/code/modules/jobs/job_types/chemist.dm @@ -15,6 +15,8 @@ access = list(ACCESS_MEDICAL, ACCESS_MORGUE, ACCESS_SURGERY, ACCESS_CHEMISTRY, ACCESS_VIROLOGY, ACCESS_GENETICS, ACCESS_CLONING, ACCESS_MINERAL_STOREROOM) minimal_access = list(ACCESS_MEDICAL, ACCESS_MORGUE, ACCESS_CHEMISTRY, ACCESS_MINERAL_STOREROOM) + paycheck = PAYCHECK_MEDIUM + paycheck_department = ACCOUNT_MED display_order = JOB_DISPLAY_ORDER_CHEMIST threat = 1.5 diff --git a/code/modules/jobs/job_types/chief_engineer.dm b/code/modules/jobs/job_types/chief_engineer.dm index 0d70e872ac..b16b6ffa44 100644 --- a/code/modules/jobs/job_types/chief_engineer.dm +++ b/code/modules/jobs/job_types/chief_engineer.dm @@ -26,6 +26,8 @@ ACCESS_EXTERNAL_AIRLOCKS, ACCESS_ATMOSPHERICS, ACCESS_EVA, ACCESS_HEADS, ACCESS_CONSTRUCTION, ACCESS_SEC_DOORS, ACCESS_MINISAT, ACCESS_CE, ACCESS_RC_ANNOUNCE, ACCESS_KEYCARD_AUTH, ACCESS_TCOMSAT, ACCESS_MINERAL_STOREROOM) + paycheck = PAYCHECK_COMMAND + paycheck_department = ACCOUNT_ENG display_order = JOB_DISPLAY_ORDER_CHIEF_ENGINEER blacklisted_quirks = list(/datum/quirk/mute, /datum/quirk/brainproblems, /datum/quirk/paraplegic, /datum/quirk/insanity) diff --git a/code/modules/jobs/job_types/chief_medical_officer.dm b/code/modules/jobs/job_types/chief_medical_officer.dm index 8dd7fafab3..ce072d4641 100644 --- a/code/modules/jobs/job_types/chief_medical_officer.dm +++ b/code/modules/jobs/job_types/chief_medical_officer.dm @@ -24,6 +24,8 @@ minimal_access = list(ACCESS_MEDICAL, ACCESS_MORGUE, ACCESS_GENETICS, ACCESS_CLONING, ACCESS_HEADS, ACCESS_MINERAL_STOREROOM, ACCESS_CHEMISTRY, ACCESS_VIROLOGY, ACCESS_CMO, ACCESS_SURGERY, ACCESS_RC_ANNOUNCE, ACCESS_KEYCARD_AUTH, ACCESS_SEC_DOORS, ACCESS_MAINT_TUNNELS) + paycheck = PAYCHECK_COMMAND + paycheck_department = ACCOUNT_MED display_order = JOB_DISPLAY_ORDER_CHIEF_MEDICAL_OFFICER blacklisted_quirks = list(/datum/quirk/mute, /datum/quirk/brainproblems, /datum/quirk/insanity) diff --git a/code/modules/jobs/job_types/clown.dm b/code/modules/jobs/job_types/clown.dm index c65c062bce..7ad7148614 100644 --- a/code/modules/jobs/job_types/clown.dm +++ b/code/modules/jobs/job_types/clown.dm @@ -13,6 +13,8 @@ access = list(ACCESS_THEATRE) minimal_access = list(ACCESS_THEATRE) + paycheck = PAYCHECK_MINIMAL + paycheck_department = ACCOUNT_SRV mind_traits = list(TRAIT_CLOWN_MENTALITY) diff --git a/code/modules/jobs/job_types/cook.dm b/code/modules/jobs/job_types/cook.dm index 20969bf1d9..5a5916cb7e 100644 --- a/code/modules/jobs/job_types/cook.dm +++ b/code/modules/jobs/job_types/cook.dm @@ -14,6 +14,8 @@ access = list(ACCESS_HYDROPONICS, ACCESS_BAR, ACCESS_KITCHEN, ACCESS_MORGUE, ACCESS_MINERAL_STOREROOM) minimal_access = list(ACCESS_KITCHEN, ACCESS_MORGUE, ACCESS_MINERAL_STOREROOM) + paycheck = PAYCHECK_EASY + paycheck_department = ACCOUNT_SRV display_order = JOB_DISPLAY_ORDER_COOK threat = 0.2 diff --git a/code/modules/jobs/job_types/curator.dm b/code/modules/jobs/job_types/curator.dm index d73d909f4f..4c588901c4 100644 --- a/code/modules/jobs/job_types/curator.dm +++ b/code/modules/jobs/job_types/curator.dm @@ -13,6 +13,8 @@ access = list(ACCESS_LIBRARY) minimal_access = list(ACCESS_LIBRARY, ACCESS_CONSTRUCTION, ACCESS_MINING_STATION) + paycheck = PAYCHECK_EASY + paycheck_department = ACCOUNT_CIV display_order = JOB_DISPLAY_ORDER_CURATOR threat = 0.3 diff --git a/code/modules/jobs/job_types/detective.dm b/code/modules/jobs/job_types/detective.dm index 55c13df7a2..e5afe7e1b3 100644 --- a/code/modules/jobs/job_types/detective.dm +++ b/code/modules/jobs/job_types/detective.dm @@ -17,6 +17,8 @@ access = list(ACCESS_SEC_DOORS, ACCESS_FORENSICS_LOCKERS, ACCESS_MORGUE, ACCESS_MAINT_TUNNELS, ACCESS_COURT, ACCESS_BRIG, ACCESS_WEAPONS, ACCESS_MINERAL_STOREROOM) minimal_access = list(ACCESS_SEC_DOORS, ACCESS_FORENSICS_LOCKERS, ACCESS_MORGUE, ACCESS_MAINT_TUNNELS, ACCESS_COURT, ACCESS_BRIG, ACCESS_WEAPONS, ACCESS_MINERAL_STOREROOM) + paycheck = PAYCHECK_MEDIUM + paycheck_department = ACCOUNT_SEC mind_traits = list(TRAIT_LAW_ENFORCEMENT_METABOLISM) diff --git a/code/modules/jobs/job_types/geneticist.dm b/code/modules/jobs/job_types/geneticist.dm index 2e8b18d772..6ab0f46c63 100644 --- a/code/modules/jobs/job_types/geneticist.dm +++ b/code/modules/jobs/job_types/geneticist.dm @@ -15,6 +15,8 @@ access = list(ACCESS_MEDICAL, ACCESS_MORGUE, ACCESS_CHEMISTRY, ACCESS_GENETICS, ACCESS_CLONING, ACCESS_RESEARCH, ACCESS_XENOBIOLOGY, ACCESS_ROBOTICS, ACCESS_MINERAL_STOREROOM, ACCESS_TECH_STORAGE) minimal_access = list(ACCESS_MEDICAL, ACCESS_MORGUE, ACCESS_GENETICS, ACCESS_CLONING, ACCESS_RESEARCH, ACCESS_MINERAL_STOREROOM) + paycheck = PAYCHECK_MEDIUM + paycheck_department = ACCOUNT_MED display_order = JOB_DISPLAY_ORDER_GENETICIST threat = 1.5 diff --git a/code/modules/jobs/job_types/head_of_personnel.dm b/code/modules/jobs/job_types/head_of_personnel.dm index b1fe3471f1..8015c19c36 100644 --- a/code/modules/jobs/job_types/head_of_personnel.dm +++ b/code/modules/jobs/job_types/head_of_personnel.dm @@ -30,6 +30,8 @@ ACCESS_CREMATORIUM, ACCESS_KITCHEN, ACCESS_HYDROPONICS, ACCESS_LAWYER, ACCESS_THEATRE, ACCESS_CHAPEL_OFFICE, ACCESS_LIBRARY, ACCESS_RESEARCH, ACCESS_MINING, ACCESS_VAULT, ACCESS_MINING_STATION, ACCESS_HOP, ACCESS_RC_ANNOUNCE, ACCESS_KEYCARD_AUTH, ACCESS_GATEWAY, ACCESS_MINERAL_STOREROOM) + paycheck = PAYCHECK_COMMAND + paycheck_department = ACCOUNT_SRV display_order = JOB_DISPLAY_ORDER_HEAD_OF_PERSONNEL diff --git a/code/modules/jobs/job_types/head_of_security.dm b/code/modules/jobs/job_types/head_of_security.dm index 3cf4fbb102..69ed63a514 100644 --- a/code/modules/jobs/job_types/head_of_security.dm +++ b/code/modules/jobs/job_types/head_of_security.dm @@ -27,6 +27,8 @@ ACCESS_FORENSICS_LOCKERS, ACCESS_MORGUE, ACCESS_MAINT_TUNNELS, ACCESS_ALL_PERSONAL_LOCKERS, ACCESS_RESEARCH, ACCESS_ENGINE, ACCESS_MINING, ACCESS_MEDICAL, ACCESS_CONSTRUCTION, ACCESS_MAILSORTING, ACCESS_HEADS, ACCESS_HOS, ACCESS_RC_ANNOUNCE, ACCESS_KEYCARD_AUTH, ACCESS_GATEWAY, ACCESS_MAINT_TUNNELS, ACCESS_MINERAL_STOREROOM) + paycheck = PAYCHECK_COMMAND + paycheck_department = ACCOUNT_SEC display_order = JOB_DISPLAY_ORDER_HEAD_OF_SECURITY blacklisted_quirks = list(/datum/quirk/mute, /datum/quirk/brainproblems, /datum/quirk/nonviolent, /datum/quirk/paraplegic, /datum/quirk/insanity) diff --git a/code/modules/jobs/job_types/janitor.dm b/code/modules/jobs/job_types/janitor.dm index 73028255be..2f6d6f0e32 100644 --- a/code/modules/jobs/job_types/janitor.dm +++ b/code/modules/jobs/job_types/janitor.dm @@ -13,6 +13,8 @@ access = list(ACCESS_JANITOR, ACCESS_MAINT_TUNNELS, ACCESS_MINERAL_STOREROOM) minimal_access = list(ACCESS_JANITOR, ACCESS_MAINT_TUNNELS, ACCESS_MINERAL_STOREROOM) + paycheck = PAYCHECK_EASY + paycheck_department = ACCOUNT_SRV display_order = JOB_DISPLAY_ORDER_JANITOR threat = 0.2 diff --git a/code/modules/jobs/job_types/lawyer.dm b/code/modules/jobs/job_types/lawyer.dm index 3f80e44492..1a7499800b 100644 --- a/code/modules/jobs/job_types/lawyer.dm +++ b/code/modules/jobs/job_types/lawyer.dm @@ -14,6 +14,8 @@ access = list(ACCESS_LAWYER, ACCESS_COURT, ACCESS_SEC_DOORS) minimal_access = list(ACCESS_LAWYER, ACCESS_COURT, ACCESS_SEC_DOORS) + paycheck = PAYCHECK_EASY + paycheck_department = ACCOUNT_CIV mind_traits = list(TRAIT_LAW_ENFORCEMENT_METABOLISM) diff --git a/code/modules/jobs/job_types/medical_doctor.dm b/code/modules/jobs/job_types/medical_doctor.dm index 3eaa2ae10a..89a766762c 100644 --- a/code/modules/jobs/job_types/medical_doctor.dm +++ b/code/modules/jobs/job_types/medical_doctor.dm @@ -13,6 +13,8 @@ access = list(ACCESS_MEDICAL, ACCESS_MORGUE, ACCESS_SURGERY, ACCESS_CHEMISTRY, ACCESS_GENETICS, ACCESS_CLONING, ACCESS_VIROLOGY, ACCESS_MINERAL_STOREROOM) minimal_access = list(ACCESS_MEDICAL, ACCESS_MORGUE, ACCESS_SURGERY, ACCESS_CLONING, ACCESS_MINERAL_STOREROOM) + paycheck = PAYCHECK_MEDIUM + paycheck_department = ACCOUNT_MED display_order = JOB_DISPLAY_ORDER_MEDICAL_DOCTOR threat = 0.5 diff --git a/code/modules/jobs/job_types/mime.dm b/code/modules/jobs/job_types/mime.dm index 72a6ac8e13..4ba2489ab2 100644 --- a/code/modules/jobs/job_types/mime.dm +++ b/code/modules/jobs/job_types/mime.dm @@ -13,6 +13,8 @@ access = list(ACCESS_THEATRE) minimal_access = list(ACCESS_THEATRE) + paycheck = PAYCHECK_MINIMAL + paycheck_department = ACCOUNT_SRV display_order = JOB_DISPLAY_ORDER_MIME diff --git a/code/modules/jobs/job_types/paramedic.dm b/code/modules/jobs/job_types/paramedic.dm index df6e1431ae..a9703e3f9e 100644 --- a/code/modules/jobs/job_types/paramedic.dm +++ b/code/modules/jobs/job_types/paramedic.dm @@ -14,6 +14,8 @@ access = list(ACCESS_MEDICAL, ACCESS_MORGUE, ACCESS_SURGERY, ACCESS_GENETICS, ACCESS_CLONING, ACCESS_MINERAL_STOREROOM, ACCESS_MAINT_TUNNELS) minimal_access = list(ACCESS_MEDICAL, ACCESS_MORGUE, ACCESS_CLONING, ACCESS_MINERAL_STOREROOM, ACCESS_MAINT_TUNNELS) + paycheck = PAYCHECK_MEDIUM + paycheck_department = ACCOUNT_MED display_order = JOB_DISPLAY_ORDER_PARAMEDIC diff --git a/code/modules/jobs/job_types/quartermaster.dm b/code/modules/jobs/job_types/quartermaster.dm index 897defb0ea..4c6b8e064f 100644 --- a/code/modules/jobs/job_types/quartermaster.dm +++ b/code/modules/jobs/job_types/quartermaster.dm @@ -24,6 +24,8 @@ minimal_access = list(ACCESS_MAINT_TUNNELS, ACCESS_MAILSORTING, ACCESS_CARGO, ACCESS_CARGO_BOT, ACCESS_QM, ACCESS_MINING, ACCESS_MINING_STATION, ACCESS_MINERAL_STOREROOM, ACCESS_KEYCARD_AUTH, ACCESS_RC_ANNOUNCE, ACCESS_SEC_DOORS, ACCESS_HEADS) + paycheck = PAYCHECK_HARD //They can already buy stuff using cargo budget, don't give em a command-level paycheck. + paycheck_department = ACCOUNT_CAR display_order = JOB_DISPLAY_ORDER_QUARTERMASTER blacklisted_quirks = list(/datum/quirk/mute, /datum/quirk/brainproblems, /datum/quirk/insanity) diff --git a/code/modules/jobs/job_types/research_director.dm b/code/modules/jobs/job_types/research_director.dm index 15e5c64654..7128fbe2c7 100644 --- a/code/modules/jobs/job_types/research_director.dm +++ b/code/modules/jobs/job_types/research_director.dm @@ -28,6 +28,8 @@ ACCESS_RESEARCH, ACCESS_ROBOTICS, ACCESS_XENOBIOLOGY, ACCESS_AI_UPLOAD, ACCESS_RC_ANNOUNCE, ACCESS_KEYCARD_AUTH, ACCESS_GATEWAY, ACCESS_MINERAL_STOREROOM, ACCESS_TECH_STORAGE, ACCESS_MINISAT, ACCESS_MAINT_TUNNELS, ACCESS_NETWORK) + paycheck = PAYCHECK_COMMAND + paycheck_department = ACCOUNT_SCI display_order = JOB_DISPLAY_ORDER_RESEARCH_DIRECTOR blacklisted_quirks = list(/datum/quirk/mute, /datum/quirk/brainproblems, /datum/quirk/insanity) diff --git a/code/modules/jobs/job_types/roboticist.dm b/code/modules/jobs/job_types/roboticist.dm index f9f1d20d3b..d77b2120a2 100644 --- a/code/modules/jobs/job_types/roboticist.dm +++ b/code/modules/jobs/job_types/roboticist.dm @@ -15,6 +15,8 @@ access = list(ACCESS_ROBOTICS, ACCESS_TOX, ACCESS_TOX_STORAGE, ACCESS_TECH_STORAGE, ACCESS_MORGUE, ACCESS_RESEARCH, ACCESS_MINERAL_STOREROOM, ACCESS_XENOBIOLOGY, ACCESS_GENETICS) minimal_access = list(ACCESS_ROBOTICS, ACCESS_TECH_STORAGE, ACCESS_MORGUE, ACCESS_RESEARCH, ACCESS_MINERAL_STOREROOM) + paycheck = PAYCHECK_MEDIUM + paycheck_department = ACCOUNT_SCI display_order = JOB_DISPLAY_ORDER_ROBOTICIST threat = 1 diff --git a/code/modules/jobs/job_types/scientist.dm b/code/modules/jobs/job_types/scientist.dm index 9809e7b4dc..476f740b9d 100644 --- a/code/modules/jobs/job_types/scientist.dm +++ b/code/modules/jobs/job_types/scientist.dm @@ -15,6 +15,8 @@ access = list(ACCESS_ROBOTICS, ACCESS_TOX, ACCESS_TOX_STORAGE, ACCESS_RESEARCH, ACCESS_XENOBIOLOGY, ACCESS_MINERAL_STOREROOM, ACCESS_TECH_STORAGE, ACCESS_GENETICS) minimal_access = list(ACCESS_TOX, ACCESS_TOX_STORAGE, ACCESS_RESEARCH, ACCESS_XENOBIOLOGY, ACCESS_MINERAL_STOREROOM) + paycheck = PAYCHECK_MEDIUM + paycheck_department = ACCOUNT_SCI display_order = JOB_DISPLAY_ORDER_SCIENTIST threat = 1.2 diff --git a/code/modules/jobs/job_types/security_officer.dm b/code/modules/jobs/job_types/security_officer.dm index decb334423..bc6f6a94c7 100644 --- a/code/modules/jobs/job_types/security_officer.dm +++ b/code/modules/jobs/job_types/security_officer.dm @@ -17,6 +17,8 @@ access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_BRIG, ACCESS_COURT, ACCESS_MAINT_TUNNELS, ACCESS_MORGUE, ACCESS_WEAPONS, ACCESS_ENTER_GENPOP, ACCESS_LEAVE_GENPOP, ACCESS_FORENSICS_LOCKERS, ACCESS_MINERAL_STOREROOM) minimal_access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_BRIG, ACCESS_COURT, ACCESS_WEAPONS, ACCESS_ENTER_GENPOP, ACCESS_LEAVE_GENPOP, ACCESS_MINERAL_STOREROOM) // See /datum/job/officer/get_access() + paycheck = PAYCHECK_HARD + paycheck_department = ACCOUNT_SEC mind_traits = list(TRAIT_LAW_ENFORCEMENT_METABOLISM) diff --git a/code/modules/jobs/job_types/shaft_miner.dm b/code/modules/jobs/job_types/shaft_miner.dm index 9eb268895e..a09c4376fb 100644 --- a/code/modules/jobs/job_types/shaft_miner.dm +++ b/code/modules/jobs/job_types/shaft_miner.dm @@ -16,6 +16,8 @@ access = list(ACCESS_MAINT_TUNNELS, ACCESS_MAILSORTING, ACCESS_CARGO, ACCESS_CARGO_BOT, ACCESS_MINING, ACCESS_MINING_STATION, ACCESS_MINERAL_STOREROOM) minimal_access = list(ACCESS_MINING, ACCESS_MINING_STATION, ACCESS_MAILSORTING, ACCESS_MINERAL_STOREROOM) + paycheck = PAYCHECK_HARD + paycheck_department = ACCOUNT_CAR display_order = JOB_DISPLAY_ORDER_SHAFT_MINER diff --git a/code/modules/jobs/job_types/station_engineer.dm b/code/modules/jobs/job_types/station_engineer.dm index 66ddc90e9b..83a175f240 100644 --- a/code/modules/jobs/job_types/station_engineer.dm +++ b/code/modules/jobs/job_types/station_engineer.dm @@ -17,6 +17,8 @@ ACCESS_EXTERNAL_AIRLOCKS, ACCESS_CONSTRUCTION, ACCESS_ATMOSPHERICS, ACCESS_TCOMSAT, ACCESS_MINERAL_STOREROOM) minimal_access = list(ACCESS_ENGINE, ACCESS_ENGINE_EQUIP, ACCESS_TECH_STORAGE, ACCESS_MAINT_TUNNELS, ACCESS_EXTERNAL_AIRLOCKS, ACCESS_CONSTRUCTION, ACCESS_TCOMSAT, ACCESS_MINERAL_STOREROOM) + paycheck = PAYCHECK_MEDIUM + paycheck_department = ACCOUNT_ENG display_order = JOB_DISPLAY_ORDER_STATION_ENGINEER diff --git a/code/modules/jobs/job_types/virologist.dm b/code/modules/jobs/job_types/virologist.dm index 4ba65dff59..c965341054 100644 --- a/code/modules/jobs/job_types/virologist.dm +++ b/code/modules/jobs/job_types/virologist.dm @@ -15,6 +15,8 @@ access = list(ACCESS_MEDICAL, ACCESS_MORGUE, ACCESS_SURGERY, ACCESS_CHEMISTRY, ACCESS_VIROLOGY, ACCESS_GENETICS, ACCESS_CLONING, ACCESS_MINERAL_STOREROOM) minimal_access = list(ACCESS_MEDICAL, ACCESS_VIROLOGY, ACCESS_MINERAL_STOREROOM) + paycheck = PAYCHECK_MEDIUM + paycheck_department = ACCOUNT_MED display_order = JOB_DISPLAY_ORDER_VIROLOGIST diff --git a/code/modules/jobs/job_types/warden.dm b/code/modules/jobs/job_types/warden.dm index 15d839ac48..5762731f62 100644 --- a/code/modules/jobs/job_types/warden.dm +++ b/code/modules/jobs/job_types/warden.dm @@ -18,6 +18,9 @@ access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_BRIG, ACCESS_ARMORY, ACCESS_COURT, ACCESS_MAINT_TUNNELS, ACCESS_MORGUE, ACCESS_WEAPONS, ACCESS_ENTER_GENPOP, ACCESS_LEAVE_GENPOP, ACCESS_FORENSICS_LOCKERS, ACCESS_MINERAL_STOREROOM) minimal_access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_BRIG, ACCESS_ARMORY, ACCESS_COURT, ACCESS_WEAPONS, ACCESS_ENTER_GENPOP, ACCESS_LEAVE_GENPOP, ACCESS_MINERAL_STOREROOM) // See /datum/job/warden/get_access() + paycheck = PAYCHECK_HARD + paycheck_department = ACCOUNT_SEC + mind_traits = list(TRAIT_LAW_ENFORCEMENT_METABOLISM) display_order = JOB_DISPLAY_ORDER_WARDEN diff --git a/code/modules/mapping/map_template.dm b/code/modules/mapping/map_template.dm index 3e361179de..30bb74a927 100644 --- a/code/modules/mapping/map_template.dm +++ b/code/modules/mapping/map_template.dm @@ -55,11 +55,11 @@ SSmachines.setup_template_powernets(cables) SSair.setup_template_machinery(atmos_machines) -/datum/map_template/proc/load_new_z() +/datum/map_template/proc/load_new_z(list/traits = list(ZTRAIT_AWAY = TRUE)) var/x = round((world.maxx - width)/2) var/y = round((world.maxy - height)/2) - var/datum/space_level/level = SSmapping.add_new_zlevel(name, list(ZTRAIT_AWAY = TRUE)) + var/datum/space_level/level = SSmapping.add_new_zlevel(name, traits) var/datum/parsed_map/parsed = load_map(file(mappath), x, y, level.z_value, no_changeturf=(SSatoms.initialized == INITIALIZATION_INSSATOMS), placeOnTop=TRUE) var/list/bounds = parsed.bounds if(!bounds) @@ -121,6 +121,6 @@ //for your ever biggening badminnery kevinz000 //❤ - Cyberboss -/proc/load_new_z_level(var/file, var/name) +/proc/load_new_z_level(file, name, list/traits = list(ZTRAIT_AWAY = TRUE)) var/datum/map_template/template = new(file, name) - template.load_new_z() + template.load_new_z(traits) diff --git a/code/modules/mining/money_bag.dm b/code/modules/mining/money_bag.dm index fd5997d3c4..66f99ec40c 100644 --- a/code/modules/mining/money_bag.dm +++ b/code/modules/mining/money_bag.dm @@ -15,7 +15,7 @@ STR.max_w_class = WEIGHT_CLASS_NORMAL STR.max_items = 40 STR.max_combined_w_class = 40 - STR.can_hold = typecacheof(list(/obj/item/coin, /obj/item/stack/spacecash)) + STR.can_hold = typecacheof(list(/obj/item/coin, /obj/item/stack/spacecash, /obj/item/holochip)) /obj/item/storage/bag/money/vault/PopulateContents() new /obj/item/coin/silver(src) diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index 68c312b19c..b9e787b7d5 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -11,7 +11,7 @@ status_flags = CANSTUN|CANKNOCKDOWN|CANUNCONSCIOUS|CANPUSH|CANSTAGGER blocks_emissive = EMISSIVE_BLOCK_UNIQUE - + //Hair colour and style var/hair_color = "000" var/hair_style = "Bald" @@ -72,4 +72,5 @@ var/creamed = FALSE //to use with creampie overlays var/static/list/can_ride_typecache = typecacheof(list(/mob/living/carbon/human, /mob/living/simple_animal/slime, /mob/living/simple_animal/parrot)) var/lastpuke = 0 + var/account_id var/last_fire_update diff --git a/code/modules/mob/living/carbon/human/human_helpers.dm b/code/modules/mob/living/carbon/human/human_helpers.dm index 7b3953e40e..7c256f5367 100644 --- a/code/modules/mob/living/carbon/human/human_helpers.dm +++ b/code/modules/mob/living/carbon/human/human_helpers.dm @@ -127,6 +127,17 @@ to_chat(src, "Your fingers don't fit in the trigger guard!") return FALSE +/mob/living/carbon/human/proc/get_bank_account() + RETURN_TYPE(/datum/bank_account) + var/datum/bank_account/account + var/obj/item/card/id/I = get_idcard() + + if(I && I.registered_account) + account = I.registered_account + return account + + return FALSE + /mob/living/carbon/human/can_see_reagents() . = ..() if(.) //No need to run through all of this if it's already true. diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm index d3e7d7c395..473a7d4c98 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules.dm @@ -698,9 +698,9 @@ /obj/item/toy/crayon/spraycan/borg, /obj/item/hand_labeler/borg, /obj/item/razor, + /obj/item/rsf, /obj/item/instrument/violin, /obj/item/instrument/guitar, - /obj/item/rsf/cyborg, /obj/item/reagent_containers/dropper, /obj/item/lighter, /obj/item/storage/bag/tray, diff --git a/code/modules/modular_computers/hardware/hard_drive.dm b/code/modules/modular_computers/hardware/hard_drive.dm index 285463bc0f..76463c6867 100644 --- a/code/modules/modular_computers/hardware/hard_drive.dm +++ b/code/modules/modular_computers/hardware/hard_drive.dm @@ -157,6 +157,7 @@ max_capacity = 64 icon_state = "ssd_mini" w_class = WEIGHT_CLASS_TINY + custom_price = 150 /obj/item/computer_hardware/hard_drive/small/syndicate // Syndicate variant - very slight better desc = "An efficient SSD for portable devices developed by a rival organisation." diff --git a/code/modules/modular_computers/laptop_vendor.dm b/code/modules/modular_computers/laptop_vendor.dm index 2bed456c41..9e0e1c8014 100644 --- a/code/modules/modular_computers/laptop_vendor.dm +++ b/code/modules/modular_computers/laptop_vendor.dm @@ -244,12 +244,12 @@ visible_message("[user] inserts [c.value] credits into [src].") qdel(c) return - /*else if(istype(I, /obj/item/holochip)) + else if(istype(I, /obj/item/holochip)) var/obj/item/holochip/HC = I credits += HC.credits - visible_message("[user] inserts a $[HC.credits] holocredit chip into [src].") + visible_message("[user] inserts a [HC.credits] cr holocredit chip into [src].") qdel(HC) - return + return else if(istype(I, /obj/item/card/id)) if(state != 2) return @@ -260,8 +260,8 @@ say("Insufficient money on card to purchase!") return credits += target_credits - say("$[target_credits] has been desposited from your account.") - return */ //Goonconomy when + say("[target_credits] cr has been desposited from your account.") + return return ..() // Simplified payment processing, returns 1 on success. diff --git a/code/modules/photography/camera/camera.dm b/code/modules/photography/camera/camera.dm index b7b7bc36b7..0090856d83 100644 --- a/code/modules/photography/camera/camera.dm +++ b/code/modules/photography/camera/camera.dm @@ -15,6 +15,7 @@ flags_1 = CONDUCT_1 slot_flags = ITEM_SLOT_NECK custom_materials = list(/datum/material/iron = 50, /datum/material/glass = 150) + custom_price = 120 var/flash_enabled = TRUE var/state_on = "camera" var/state_off = "camera_off" diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index 1b23b1bb5d..d29b0b62fd 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -1350,7 +1350,7 @@ lighting = autoset(lighting, 0) environ = autoset(environ, 0) area.poweralert(0, src) - + else if(cell_percent < 15 && longtermpower < 0) // <15%, turn off lighting & equipment equipment = autoset(equipment, 2) lighting = autoset(lighting, 2) @@ -1579,4 +1579,5 @@ /obj/item/electronics/apc name = "power control module" icon_state = "power_mod" + custom_price = 50 desc = "Heavy-duty switching circuits for power control." diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index 49848824e4..4eac585999 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -472,6 +472,7 @@ By design, d1 is the smallest direction and d2 is the highest /obj/item/stack/cable_coil name = "cable coil" + custom_price = 75 gender = NEUTER //That's a cable coil sounds better than that's some cable coils icon = 'icons/obj/power.dmi' icon_state = "coil" @@ -566,7 +567,7 @@ By design, d1 is the smallest direction and d2 is the highest return var/obj/item/restraints/handcuffs/cable/result = new(get_turf(user)) user.put_in_hands(result) - result.color = color + result.color = color to_chat(user, "You make some restraints out of cable") //add cables to the stack @@ -849,4 +850,4 @@ By design, d1 is the smallest direction and d2 is the highest . = ..() var/list/cable_colors = GLOB.cable_colors color = pick(cable_colors) - + diff --git a/code/modules/power/singularity/collector.dm b/code/modules/power/singularity/collector.dm index 2e6ec57f77..f5a841ab42 100644 --- a/code/modules/power/singularity/collector.dm +++ b/code/modules/power/singularity/collector.dm @@ -62,7 +62,11 @@ loaded_tank.air_contents.gases[/datum/gas/oxygen] -= gasdrained loaded_tank.air_contents.gases[/datum/gas/carbon_dioxide] += gasdrained*2 GAS_GARBAGE_COLLECT(loaded_tank.air_contents.gases) - SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, stored_power*RAD_COLLECTOR_MINING_CONVERSION_RATE) + var/bitcoins_mined = stored_power*RAD_COLLECTOR_MINING_CONVERSION_RATE + var/datum/bank_account/D = SSeconomy.get_dep_account(ACCOUNT_ENG) + if(D) + D.adjust_money(bitcoins_mined) + SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, bitcoins_mined) last_push = stored_power stored_power = 0 diff --git a/code/modules/power/tesla/coil.dm b/code/modules/power/tesla/coil.dm index e29ffa865e..64d317b385 100644 --- a/code/modules/power/tesla/coil.dm +++ b/code/modules/power/tesla/coil.dm @@ -83,6 +83,9 @@ flick("coilhit", src) playsound(src.loc, 'sound/magic/lightningshock.ogg', 100, 1, extrarange = 5) tesla_zap(src, 5, power_produced, tesla_flags, shocked_targets) + var/datum/bank_account/D = SSeconomy.get_dep_account(ACCOUNT_ENG) + if(D) + D.adjust_money(min(power_produced, 1)) if(istype(linked_techweb)) linked_techweb.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, min(power_produced, 1)) // x4 coils = ~240/m point bonus for R&D addtimer(CALLBACK(src, .proc/reset_shocked), 10) @@ -118,6 +121,9 @@ flick("rpcoilhit", src) playsound(src.loc, 'sound/magic/lightningshock.ogg', 100, 1, extrarange = 5) tesla_zap(src, 5, power_produced, tesla_flags, shocked_things) + var/datum/bank_account/D = SSeconomy.get_dep_account(ACCOUNT_ENG) + if(D) + D.adjust_money(min(power_produced, 3)) if(istype(linked_techweb)) linked_techweb.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, min(power_produced, 3)) // x4 coils with a pulse per second or so = ~720/m point bonus for R&D addtimer(CALLBACK(src, .proc/reset_shocked), 10) diff --git a/code/modules/reagents/reagent_containers/dropper.dm b/code/modules/reagents/reagent_containers/dropper.dm index 846637850b..b4c570dfc6 100644 --- a/code/modules/reagents/reagent_containers/dropper.dm +++ b/code/modules/reagents/reagent_containers/dropper.dm @@ -7,6 +7,7 @@ possible_transfer_amounts = list(1, 2, 3, 4, 5) volume = 5 reagent_flags = TRANSPARENT + custom_price = 75 /obj/item/reagent_containers/dropper/afterattack(obj/target, mob/user , proximity) . = ..() diff --git a/code/modules/reagents/reagent_containers/glass.dm b/code/modules/reagents/reagent_containers/glass.dm index 800d66969d..ab58510482 100644 --- a/code/modules/reagents/reagent_containers/glass.dm +++ b/code/modules/reagents/reagent_containers/glass.dm @@ -362,6 +362,7 @@ icon = 'icons/obj/drinks.dmi' icon_state = "smallbottle" item_state = "bottle" + custom_price = 30 list_reagents = list(/datum/reagent/water = 49.5, /datum/reagent/fluorine = 0.5)//see desc, don't think about it too hard custom_materials = list(/datum/material/glass=0) volume = 50 diff --git a/code/modules/reagents/reagent_containers/hypospray.dm b/code/modules/reagents/reagent_containers/hypospray.dm index 9555f5b64b..06db1d46ab 100644 --- a/code/modules/reagents/reagent_containers/hypospray.dm +++ b/code/modules/reagents/reagent_containers/hypospray.dm @@ -96,6 +96,8 @@ reagent_flags = DRAWABLE flags_1 = null list_reagents = list(/datum/reagent/medicine/epinephrine = 10, /datum/reagent/preservahyde = 3) + custom_price = 150 + custom_premium_price = 300 /obj/item/reagent_containers/hypospray/medipen/suicide_act(mob/living/carbon/user) user.visible_message("[user] begins to choke on \the [src]! It looks like [user.p_theyre()] trying to commit suicide!") diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm index b8957775b1..fc4a95e58d 100644 --- a/code/modules/reagents/reagent_containers/syringes.dm +++ b/code/modules/reagents/reagent_containers/syringes.dm @@ -15,6 +15,7 @@ var/show_filling = TRUE custom_materials = list(/datum/material/iron=10, /datum/material/glass=20) reagent_flags = TRANSPARENT + custom_price = 150 /obj/item/reagent_containers/syringe/Initialize() . = ..() diff --git a/code/modules/research/designs/autolathe_desings/autolathe_designs_tcomms_and_misc.dm b/code/modules/research/designs/autolathe_desings/autolathe_designs_tcomms_and_misc.dm index 30cd56c66a..eebeec2c78 100644 --- a/code/modules/research/designs/autolathe_desings/autolathe_designs_tcomms_and_misc.dm +++ b/code/modules/research/designs/autolathe_desings/autolathe_designs_tcomms_and_misc.dm @@ -256,3 +256,19 @@ materials = list(/datum/material/iron = 300, /datum/material/glass = 150) build_path = /obj/item/key/collar category = list("initial", "Misc") + +/datum/design/price_tagger + name = "Price Tagger" + id = "price_tagger" + build_type = AUTOLATHE + materials = list(/datum/material/iron = 1500, /datum/material/glass = 500) + build_path = /obj/item/price_tagger + category = list("initial", "Misc") + +/datum/design/custom_vendor_refill + name = "Custom Vendor Refill" + id = "custom_vendor_refill" + build_type = AUTOLATHE + materials = list(/datum/material/iron = 5000, /datum/material/glass = 2000) + build_path = /obj/item/vending_refill/custom + category = list("initial", "Misc") \ No newline at end of file diff --git a/code/modules/research/designs/machine_desings/machine_designs_all_misc.dm b/code/modules/research/designs/machine_desings/machine_designs_all_misc.dm index 6d63df7d4b..21c39ff0e0 100644 --- a/code/modules/research/designs/machine_desings/machine_designs_all_misc.dm +++ b/code/modules/research/designs/machine_desings/machine_designs_all_misc.dm @@ -107,6 +107,14 @@ departmental_flags = DEPARTMENTAL_FLAG_ALL category = list ("Medical Machinery") +/datum/design/board/paystand + name = "Machine Design (Pay Stand)" + desc = "The circuit board for a paystand." + id = "paystand" + build_path = /obj/item/circuitboard/machine/paystand + category = list ("Misc. Machinery") + departmental_flags = DEPARTMENTAL_FLAG_ALL + /datum/design/board/autoylathe name = "Machine Design (Autoylathe)" desc = "The circuit board for an autoylathe." diff --git a/code/modules/research/techweb/_techweb.dm b/code/modules/research/techweb/_techweb.dm index 388fa3785c..a505fefb91 100644 --- a/code/modules/research/techweb/_techweb.dm +++ b/code/modules/research/techweb/_techweb.dm @@ -199,6 +199,10 @@ researched_designs -= design.id return TRUE +/datum/techweb/proc/get_point_total(list/pointlist) + for(var/i in pointlist) + . += pointlist[i] + /datum/techweb/proc/can_afford(list/pointlist) for(var/i in pointlist) if(research_points[i] < pointlist[i]) @@ -227,6 +231,10 @@ for(var/id in node.design_ids) add_design_by_id(id) update_node_status(node) + if(!istype(src, /datum/techweb/admin)) + var/datum/bank_account/D = SSeconomy.get_dep_account(ACCOUNT_SCI) + if(D) + D.adjust_money(SSeconomy.techweb_bounty) return TRUE /datum/techweb/proc/unresearch_node_id(id) diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm index dafa119873..fd58dbd308 100644 --- a/code/modules/research/techweb/all_nodes.dm +++ b/code/modules/research/techweb/all_nodes.dm @@ -9,7 +9,7 @@ description = "NT default research technologies." // Default research tech, prevents bricking design_ids = list("basic_matter_bin", "basic_cell", "basic_scanning", "basic_capacitor", "basic_micro_laser", "micro_mani", "desttagger", "handlabel", "packagewrap", - "destructive_analyzer", "circuit_imprinter", "experimentor", "rdconsole", "design_disk", "tech_disk", "rdserver", "rdservercontrol", "mechfab", + "destructive_analyzer", "circuit_imprinter", "experimentor", "rdconsole", "design_disk", "tech_disk", "rdserver", "rdservercontrol", "mechfab", "paystand", "space_heater", "beaker", "large_beaker", "bucket", "xlarge_beaker", "sec_beanbag", "sec_rshot", "sec_bshot", "sec_slug", "sec_Islug", "sec_dart", "sec_38", "sec_38lethal", "rglass","plasteel","plastitanium","plasmaglass","plasmareinforcedglass","titaniumglass","plastitaniumglass") diff --git a/code/modules/ruins/spaceruin_code/listeningstation.dm b/code/modules/ruins/spaceruin_code/listeningstation.dm index 8efeaaabff..e48a1c45d5 100644 --- a/code/modules/ruins/spaceruin_code/listeningstation.dm +++ b/code/modules/ruins/spaceruin_code/listeningstation.dm @@ -32,7 +32,7 @@ /obj/item/paper/fluff/ruins/listeningstation/receipt name = "receipt" - info = "1 x Stechkin pistol - $600
1 x silencer - $200
shipping charge - $4360
total - $5160" + info = "1 x Stechkin pistol - 600 cr
1 x silencer - 200 cr
shipping charge - 4360 cr
total - 5160 cr" /obj/item/paper/fluff/ruins/listeningstation/odd_report name = "odd report" diff --git a/code/modules/shuttle/supply.dm b/code/modules/shuttle/supply.dm index bdf6e8cc87..a4ef2dfde9 100644 --- a/code/modules/shuttle/supply.dm +++ b/code/modules/shuttle/supply.dm @@ -109,30 +109,46 @@ GLOBAL_LIST_INIT(cargo_shuttle_leave_behind_typecache, typecacheof(list( continue empty_turfs += T + var/datum/bank_account/cargo_budget = SSeconomy.get_dep_account(ACCOUNT_CAR) var/value = 0 var/purchases = 0 for(var/datum/supply_order/SO in SSshuttle.shoppinglist) if(!empty_turfs.len) break - if(SO.pack.cost > SSshuttle.points) - continue - SSshuttle.points -= SO.pack.cost + var/price = SO.pack.cost + var/datum/bank_account/D + if(SO.paying_account) //Someone paid out of pocket + D = SO.paying_account + price *= 1.1 //TODO make this customizable by the quartermaster + else + D = cargo_budget + if(D) + if(!D.adjust_money(-SO.pack.cost)) + if(SO.paying_account) + D.bank_card_talk("Cargo order #[SO.id] rejected due to lack of funds. Credits required: [price]") + continue + + if(SO.paying_account) + D.bank_card_talk("Cargo order #[SO.id] has shipped. [price] credits have been charged to your bank account.") + var/datum/bank_account/department/cargo = SSeconomy.get_dep_account(ACCOUNT_CAR) + cargo.adjust_money(price - SO.pack.cost) //Cargo gets the handling fee value += SO.pack.cost SSshuttle.shoppinglist -= SO SSshuttle.orderhistory += SO SO.generate(pick_n_take(empty_turfs)) SSblackbox.record_feedback("nested tally", "cargo_imports", 1, list("[SO.pack.cost]", "[SO.pack.name]")) - investigate_log("Order #[SO.id] ([SO.pack.name], placed by [key_name(SO.orderer_ckey)]) has shipped.", INVESTIGATE_CARGO) + investigate_log("Order #[SO.id] ([SO.pack.name], placed by [key_name(SO.orderer_ckey)]), paid by [D.account_holder] has shipped.", INVESTIGATE_CARGO) if(SO.pack.dangerous) - message_admins("\A [SO.pack.name] ordered by [ADMIN_LOOKUPFLW(SO.orderer_ckey)] has shipped.") + message_admins("\A [SO.pack.name] ordered by [ADMIN_LOOKUPFLW(SO.orderer_ckey)], paid by [D.account_holder] has shipped.") purchases++ - investigate_log("[purchases] orders in this shipment, worth [value] credits. [SSshuttle.points] credits left.", INVESTIGATE_CARGO) + investigate_log("[purchases] orders in this shipment, worth [value] credits. [cargo_budget.account_balance] credits left.", INVESTIGATE_CARGO) /obj/docking_port/mobile/supply/proc/sell() - var/presale_points = SSshuttle.points + var/datum/bank_account/D = SSeconomy.get_dep_account(ACCOUNT_CAR) + var/gain = 0 if(!GLOB.exports_list.len) // No exports list? Generate it! setupExports() @@ -164,14 +180,15 @@ GLOBAL_LIST_INIT(cargo_shuttle_leave_behind_typecache, typecacheof(list( continue msg += export_text + "\n" - SSshuttle.points += ex.total_value[E] + gain += ex.total_value[E] for(var/chem in ex.reagents_value) var/value = ex.reagents_value[chem] msg += "[value > 0 ? "+" : ""][value] credits: received [ex.reagents_volume[chem]]u of [chem].\n" - SSshuttle.points += value + gain += value + D.adjust_money(gain) msg = copytext_char(msg, 1, MAX_MESSAGE_LEN) SSshuttle.centcom_message = msg - investigate_log("Shuttle contents sold for [SSshuttle.points - presale_points] credits. Contents: [ex.exported_atoms || "none."] Message: [SSshuttle.centcom_message || "none."]", INVESTIGATE_CARGO) + investigate_log("Shuttle contents sold for [gain] credits. Contents: [ex.exported_atoms || "none."] Message: [SSshuttle.centcom_message || "none."]", INVESTIGATE_CARGO) diff --git a/code/modules/spells/spell_types/devil_boons.dm b/code/modules/spells/spell_types/devil_boons.dm index ab3e3cc27e..8ba106d77b 100644 --- a/code/modules/spells/spell_types/devil_boons.dm +++ b/code/modules/spells/spell_types/devil_boons.dm @@ -16,14 +16,14 @@ for(var/mob/living/carbon/C in targets) if(user.dropItemToGround(user.get_active_held_item())) var/obj/item = pick( - new /obj/item/coin/gold(user.loc), - new /obj/item/coin/diamond(user.loc), - new /obj/item/coin/silver(user.loc), - new /obj/item/clothing/accessory/medal/gold(user.loc), - new /obj/item/stack/sheet/mineral/gold(user.loc), - new /obj/item/stack/sheet/mineral/silver(user.loc), - new /obj/item/stack/sheet/mineral/diamond(user.loc), - new /obj/item/stack/spacecash/c1000(user.loc)) + new /obj/item/coin/gold(user.drop_location()), + new /obj/item/coin/diamond(user.drop_location()), + new /obj/item/coin/silver(user.drop_location()), + new /obj/item/clothing/accessory/medal/gold(user.drop_location()), + new /obj/item/stack/sheet/mineral/gold(user.drop_location()), + new /obj/item/stack/sheet/mineral/silver(user.drop_location()), + new /obj/item/stack/sheet/mineral/diamond(user.drop_location()), + new /obj/item/holochip(user.drop_location(), 1000)) C.put_in_hands(item) /obj/effect/proc_holder/spell/targeted/view_range diff --git a/code/modules/uplink/uplink_items/uplink_badass.dm b/code/modules/uplink/uplink_items/uplink_badass.dm index 681efea5b3..0be2071ba5 100644 --- a/code/modules/uplink/uplink_items/uplink_badass.dm +++ b/code/modules/uplink/uplink_items/uplink_badass.dm @@ -58,6 +58,7 @@ manufactured to pack a little bit more of a punch if your client needs some convincing." item = /obj/item/storage/secure/briefcase/syndie cost = 1 + restricted = TRUE /datum/uplink_item/badass/syndiecards name = "Syndicate Playing Cards" diff --git a/code/modules/uplink/uplink_items/uplink_bundles.dm b/code/modules/uplink/uplink_items/uplink_bundles.dm index 7d0e52947a..1a9dcbd0a6 100644 --- a/code/modules/uplink/uplink_items/uplink_bundles.dm +++ b/code/modules/uplink/uplink_items/uplink_bundles.dm @@ -40,6 +40,7 @@ cost = 20 player_minimum = 30 exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + restricted = TRUE /datum/uplink_item/suits/infiltrator_bundle name = "Insidious Infiltration Gear Case" diff --git a/code/modules/uplink/uplink_items/uplink_devices.dm b/code/modules/uplink/uplink_items/uplink_devices.dm index 194281ded6..15437020a6 100644 --- a/code/modules/uplink/uplink_items/uplink_devices.dm +++ b/code/modules/uplink/uplink_items/uplink_devices.dm @@ -262,3 +262,13 @@ cost = 2 include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) restricted = TRUE + +/* for now +/datum/uplink_item/device_tools/suspiciousphone + name = "Protocol CRAB-17 Phone" + desc = "The Protocol CRAB-17 Phone, a phone borrowed from an unknown third party, it can be used to crash the space market, funneling the losses of the crew to your bank account.\ + The crew can move their funds to a new banking site though, unless they HODL, in which case they deserve it." + item = /obj/item/suspiciousphone + cost = 7 + restricted = TRUE +*/ diff --git a/code/modules/vending/_vending.dm b/code/modules/vending/_vending.dm index 4f7502bb02..abbfa94f11 100644 --- a/code/modules/vending/_vending.dm +++ b/code/modules/vending/_vending.dm @@ -30,6 +30,10 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C var/amount = 0 ///How many we can store at maximum var/max_amount = 0 + ///Does the item have a custom price override + var/custom_price + ///Does the item have a custom premium price override + var/custom_premium_price /** * # vending machines @@ -50,6 +54,7 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C integrity_failure = 0.33 armor = list("melee" = 20, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 70) circuit = /obj/item/circuitboard/machine/vendor + payment_department = ACCOUNT_SRV light_power = 0.5 light_range = MINIMUM_USEFUL_LIGHT_RANGE /// Is the machine active (No sales pitches if off)! @@ -120,7 +125,12 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C var/scan_id = TRUE ///Coins that we accept? var/obj/item/coin/coin + ///Bills we accept? + var/obj/item/stack/spacecash/bill ///Default price of items if not overridden + var/default_price = 25 + ///Default price of premium items if not overridden + var/extra_price = 50 /** * Is this item on station or not * @@ -142,7 +152,7 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C var/obj/item/vending_refill/refill_canister = null /// how many items have been inserted in a vendor - var/loaded_items + var/loaded_items = 0 ///Name of lighting mask for the vending machine var/light_mask @@ -178,6 +188,15 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C // so if slogantime is 10 minutes, it will say it at somewhere between 10 and 20 minutes after the machine is crated. last_slogan = world.time + rand(0, slogan_delay) power_change() + if(onstation_override) //overrides the checks if true. + onstation = TRUE + return + if(mapload && !is_station_level(z)) //check if it was initially created off station during mapload. + onstation = FALSE + if(circuit) + circuit.onstation = onstation //sync up the circuit so the pricing schema is carried over if it's reconstructed. + else if(circuit && (circuit.onstation != onstation)) //check if they're not the same to minimize the amount of edited values. + onstation = circuit.onstation //if it was constructed outside mapload, sync the vendor up with the circuit's var so you can't bypass price requirements by moving / reconstructing it off station. /obj/machinery/vending/Destroy() QDEL_NULL(wires) @@ -281,6 +300,7 @@ GLOBAL_LIST_EMPTY(vending_products) if(!start_empty) R.amount = amount R.max_amount = amount + R.custom_price = initial(temp.custom_price) recordlist += R /** * Refill a vending machine from a refill canister @@ -372,19 +392,7 @@ GLOBAL_LIST_EMPTY(vending_products) if(panel_open && is_wire_tool(I)) wires.interact(user) return - else if(istype(I, /obj/item/coin)) - if(coin) - to_chat(user, "[src] already has [coin] inserted") - return - if(!premium.len) - to_chat(user, "[src] doesn't have a coin slot.") - return - if(!user.transferItemToLoc(I, src)) - return - coin = I - to_chat(user, "You insert [I] into [src].") - return - else if(refill_canister && istype(I, refill_canister)) + if(refill_canister && istype(I, refill_canister)) if (!panel_open) to_chat(user, "You should probably unscrew the service panel first!") else if (stat & (BROKEN|NOPOWER)) @@ -439,7 +447,7 @@ GLOBAL_LIST_EMPTY(vending_products) vending_machine_input[format_text(I.name)] = 1 to_chat(user, "You insert [I] into [src]'s input compartment.") loaded_items++ - + /** * Is the passed in user allowed to load this vending machines compartments * @@ -520,11 +528,14 @@ GLOBAL_LIST_EMPTY(vending_products) /obj/machinery/vending/ui_static_data(mob/user) . = list() + .["onstation"] = onstation + .["department"] = payment_department .["product_records"] = list() for (var/datum/data/vending_product/R in product_records) var/list/data = list( path = replacetext(replacetext("[R.product_path]", "/obj/item/", ""), "/", "-"), name = R.name, + price = R.custom_price || default_price, max_amount = R.max_amount, ref = REF(R) ) @@ -534,6 +545,7 @@ GLOBAL_LIST_EMPTY(vending_products) var/list/data = list( path = replacetext(replacetext("[R.product_path]", "/obj/item/", ""), "/", "-"), name = R.name, + price = R.custom_premium_price || extra_price, max_amount = R.max_amount, ref = REF(R), premium = TRUE @@ -544,6 +556,7 @@ GLOBAL_LIST_EMPTY(vending_products) var/list/data = list( path = replacetext(replacetext("[R.product_path]", "/obj/item/", ""), "/", "-"), name = R.name, + price = R.custom_price || default_price, max_amount = R.max_amount, ref = REF(R), premium = TRUE @@ -552,11 +565,25 @@ GLOBAL_LIST_EMPTY(vending_products) /obj/machinery/vending/ui_data(mob/user) . = list() + var/mob/living/carbon/human/H + var/obj/item/card/id/C + if(ishuman(user)) + H = user + C = H.get_idcard(TRUE) + if(C?.registered_account) + .["user"] = list() + .["user"]["name"] = C.registered_account.account_holder + .["user"]["cash"] = C.registered_account.account_balance + if(C.registered_account.account_job) + .["user"]["job"] = C.registered_account.account_job.title + .["user"]["department"] = C.registered_account.account_job.paycheck_department + else + .["user"]["job"] = "No Job" + .["user"]["department"] = "No Department" .["stock"] = list() - for(var/datum/data/vending_product/R in product_records + coin_records + hidden_records) + for (var/datum/data/vending_product/R in product_records + coin_records + hidden_records) .["stock"][R.name] = R.amount .["extended_inventory"] = extended_inventory - .["coin"] = coin /obj/machinery/vending/ui_act(action, params) . = ..() @@ -570,74 +597,74 @@ GLOBAL_LIST_EMPTY(vending_products) if(panel_open) to_chat(usr, "The vending machine cannot dispense products while its service panel is open!") return - if((!allowed(usr)) && !(obj_flags & EMAGGED) && scan_id) //For SECURE VENDING MACHINES YEAH - to_chat(usr, "Access denied." ) - flick(icon_deny,src) - return vend_ready = FALSE //One thing at a time!! var/datum/data/vending_product/R = locate(params["ref"]) + var/list/record_to_check = product_records + coin_records + if(extended_inventory) + record_to_check = product_records + coin_records + hidden_records if(!R || !istype(R) || !R.product_path) vend_ready = TRUE return + var/price_to_use = default_price + if(R.custom_price) + price_to_use = R.custom_price if(R in hidden_records) if(!extended_inventory) vend_ready = TRUE return - else if(R in coin_records) - if(!(coin)) - to_chat(usr, "You need to a coin to get this item!") - vend_ready = TRUE - return - if(coin && coin.string_attached) - if(!prob(50)) - to_chat(usr, "You weren't able to pull [coin] out fast enough, the machine ate it, string and all!") - QDEL_NULL(coin) - return - if(!usr.CanReach(src)) - to_chat(usr, "You successfully pull [coin] out of [src] to the floor.") - coin = null - if(!usr.put_in_hands(coin)) - to_chat(usr, "You couldn't pull [coin] out because your hands are full!") - QDEL_NULL(coin) - to_chat(usr, "You successfully pull [coin] out before [src] could swallow it.") - coin = null - QDEL_NULL(coin) - else if(!(R in product_records)) + else if (!(R in record_to_check)) vend_ready = TRUE message_admins("Vending machine exploit attempted by [ADMIN_LOOKUPFLW(usr)]!") return - if(R.amount <= 0) - to_chat(usr, "Sold out.") + if (R.amount <= 0) + say("Sold out of [R.name].") + flick(icon_deny,src) vend_ready = TRUE return - else - R.amount-- - if(((last_reply + 200) <= world.time) && vend_reply) - speak(vend_reply) - last_reply = world.time + if(onstation && ishuman(usr)) + var/mob/living/carbon/human/H = usr + var/obj/item/card/id/C = H.get_idcard(TRUE) + + if(!C) + say("No card found.") + flick(icon_deny,src) + vend_ready = TRUE + return + else if (!C.registered_account) + say("No account found.") + flick(icon_deny,src) + vend_ready = TRUE + return + var/datum/bank_account/account = C.registered_account + if(account.account_job && account.account_job.paycheck_department == payment_department) + price_to_use = 0 + if(coin_records.Find(R) || hidden_records.Find(R)) + price_to_use = R.custom_premium_price ? R.custom_premium_price : extra_price + if(price_to_use && !account.adjust_money(-price_to_use)) + say("You do not possess the funds to purchase [R.name].") + flick(icon_deny,src) + vend_ready = TRUE + return + var/datum/bank_account/D = SSeconomy.get_dep_account(payment_department) + if(D) + D.adjust_money(price_to_use) + if(last_shopper != usr || purchase_message_cooldown < world.time) + say("Thank you for shopping with [src]!") + purchase_message_cooldown = world.time + 5 SECONDS + last_shopper = usr use_power(5) if(icon_vend) //Show the vending animation if needed flick(icon_vend,src) - var/vended = new R.product_path(get_turf(src)) + playsound(src, 'sound/machines/machine_vend.ogg', 50, TRUE, extrarange = -3) + var/obj/item/vended = new R.product_path(get_turf(src)) + R.amount-- if(usr.CanReach(src) && usr.put_in_hands(vended)) to_chat(usr, "You take [R.name] out of the slot.") else to_chat(usr, "[capitalize(R.name)] falls onto the floor!") - - SSblackbox.record_feedback("nested tally", "vending_machine_usage", 1, list("[type]", "[R.product_path]")) vend_ready = TRUE - return - if("takeoutcoin") - usr.put_in_hands(coin) - to_chat(usr, "You remove [coin] from [src].") - coin = null - return - - if("togglevoice") - if(panel_open) - shut_up = !shut_up - + /obj/machinery/vending/process() if(stat & (BROKEN|NOPOWER)) return PROCESS_KILL @@ -748,3 +775,196 @@ GLOBAL_LIST_EMPTY(vending_products) /obj/machinery/vending/onTransitZ() return + +/obj/machinery/vending/custom + name = "Custom Vendor" + icon_state = "robotics" + icon_deny = "robotics-deny" + max_integrity = 400 + payment_department = NO_FREEBIES + refill_canister = /obj/item/vending_refill/custom + /// where the money is sent + var/datum/bank_account/private_a + /// max number of items that the custom vendor can hold + var/max_loaded_items = 20 + /// Base64 cache of custom icons. + var/list/base64_cache = list() + +/obj/machinery/vending/custom/compartmentLoadAccessCheck(mob/user) + . = FALSE + var/mob/living/carbon/human/H + var/obj/item/card/id/C + if(ishuman(user)) + H = user + C = H.get_idcard(FALSE) + if(C?.registered_account && C.registered_account == private_a) + return TRUE + +/obj/machinery/vending/custom/canLoadItem(obj/item/I, mob/user) + . = FALSE + if(loaded_items >= max_loaded_items) + say("There are too many items in stock.") + return + if(istype(I, /obj/item/stack)) + say("Loose items may cause problems, try use it inside wrapping paper.") + return + if(I.custom_price) + return TRUE + +/obj/machinery/vending/custom/ui_data(mob/user) + . = ..() + .["access"] = compartmentLoadAccessCheck(user) + .["vending_machine_input"] = list() + for (var/O in vending_machine_input) + if(vending_machine_input[O] > 0) + var/base64 + var/price = 0 + for(var/obj/T in contents) + if(T.name == O) + price = T.custom_price + if(!base64) + if(base64_cache[T.type]) + base64 = base64_cache[T.type] + else + base64 = icon2base64(icon(T.icon, T.icon_state)) + base64_cache[T.type] = base64 + break + var/list/data = list( + name = O, + price = price, + img = base64 + ) + .["vending_machine_input"] += list(data) + +/obj/machinery/vending/custom/ui_act(action, params) + . = ..() + if(.) + return + switch(action) + if("dispense") + . = TRUE + if(!vend_ready) + return + var/N = params["item"] + var/obj/S + vend_ready = FALSE + if(ishuman(usr)) + var/mob/living/carbon/human/H = usr + var/obj/item/card/id/C = H.get_idcard(TRUE) + + if(!C) + say("No card found.") + flick(icon_deny,src) + vend_ready = TRUE + return + else if (!C.registered_account) + say("No account found.") + flick(icon_deny,src) + vend_ready = TRUE + return + var/datum/bank_account/account = C.registered_account + for(var/obj/O in contents) + if(O.name == N) + S = O + break + if(S) + if(compartmentLoadAccessCheck(usr)) + vending_machine_input[N] = max(vending_machine_input[N] - 1, 0) + S.forceMove(drop_location()) + loaded_items-- + use_power(5) + vend_ready = TRUE + updateUsrDialog() + return + if(account.has_money(S.custom_price)) + account.adjust_money(-S.custom_price) + var/datum/bank_account/owner = private_a + if(owner) + owner.adjust_money(S.custom_price) + vending_machine_input[N] = max(vending_machine_input[N] - 1, 0) + S.forceMove(drop_location()) + loaded_items-- + use_power(5) + if(last_shopper != usr || purchase_message_cooldown < world.time) + say("Thank you for buying local and purchasing [S]!") + purchase_message_cooldown = world.time + 5 SECONDS + last_shopper = usr + vend_ready = TRUE + updateUsrDialog() + return + else + say("You do not possess the funds to purchase this.") + vend_ready = TRUE + +/obj/machinery/vending/custom/attackby(obj/item/I, mob/user, params) + if(!private_a) + var/mob/living/carbon/human/H + var/obj/item/card/id/C + if(ishuman(user)) + H = user + C = H.get_idcard(TRUE) + if(C?.registered_account) + private_a = C.registered_account + say("\The [src] has been linked to [C].") + + if(compartmentLoadAccessCheck(user)) + if(istype(I, /obj/item/pen)) + name = stripped_input(user,"Set name","Name", name, 20) + desc = stripped_input(user,"Set description","Description", desc, 60) + slogan_list += stripped_input(user,"Set slogan","Slogan","Epic", 60) + last_slogan = world.time + rand(0, slogan_delay) + return + + if(canLoadItem(I)) + loadingAttempt(I,user) + updateUsrDialog() + return + + if(panel_open && is_wire_tool(I)) + wires.interact(user) + return + + return ..() + +/obj/machinery/vending/custom/crowbar_act(mob/living/user, obj/item/I) + return FALSE + +/obj/machinery/vending/custom/Destroy() + unbuckle_all_mobs(TRUE) + var/turf/T = get_turf(src) + if(T) + for(var/obj/item/I in contents) + I.forceMove(T) + explosion(T, -1, 0, 3) + return ..() + +/obj/machinery/vending/custom/unbreakable + name = "Indestructible Vendor" + resistance_flags = INDESTRUCTIBLE + +/obj/item/vending_refill/custom + machine_name = "Custom Vendor" + icon_state = "refill_custom" + custom_premium_price = 100 + +/obj/item/price_tagger + name = "price tagger" + desc = "This tool is used to set a price for items used in custom vendors." + icon = 'icons/obj/device.dmi' + icon_state = "pricetagger" + custom_premium_price = 25 + ///the price of the item + var/price = 1 + +/obj/item/price_tagger/attack_self(mob/user) + price = max(1, round(input(user,"set price","price") as num|null, 1)) + to_chat(user, " The [src] will now give things a [price] cr tag.") + +/obj/item/price_tagger/afterattack(atom/target, mob/user, proximity) + . = ..() + if(!proximity) + return + if(isitem(target)) + var/obj/item/I = target + I.custom_price = price + to_chat(user, "You set the price of [I] to [price] cr.") diff --git a/code/modules/vending/assist.dm b/code/modules/vending/assist.dm index 5dafd3935c..b1b8519803 100644 --- a/code/modules/vending/assist.dm +++ b/code/modules/vending/assist.dm @@ -19,6 +19,9 @@ armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50) refill_canister = /obj/item/vending_refill/assist resistance_flags = FIRE_PROOF + default_price = 125 + extra_price = 100 + payment_department = NO_FREEBIES /obj/item/vending_refill/assist icon_state = "refill_engi" \ No newline at end of file diff --git a/code/modules/vending/autodrobe.dm b/code/modules/vending/autodrobe.dm index 2eaf24c493..d791ceedf1 100644 --- a/code/modules/vending/autodrobe.dm +++ b/code/modules/vending/autodrobe.dm @@ -138,12 +138,19 @@ /obj/item/clothing/head/christmashat = 3, /obj/item/clothing/head/christmashatg = 3, /obj/item/clothing/under/costume/drfreeze = 1) //End of Cit Changes + refill_canister = /obj/item/vending_refill/autodrobe + default_price = 180 + extra_price = 360 + payment_department = ACCOUNT_SRV /obj/machinery/vending/autodrobe/all_access desc = "A vending machine for costumes. This model appears to have no access restrictions." req_access = null +/obj/machinery/vending/autodrobe/canLoadItem(obj/item/I,mob/user) + return (I.type in products) + /obj/item/vending_refill/autodrobe machine_name = "AutoDrobe" icon_state = "refill_costume" diff --git a/code/modules/vending/boozeomat.dm b/code/modules/vending/boozeomat.dm index 5a6380c322..4b73344c22 100644 --- a/code/modules/vending/boozeomat.dm +++ b/code/modules/vending/boozeomat.dm @@ -4,7 +4,7 @@ icon_state = "boozeomat" icon_deny = "boozeomat-deny" products = list(/obj/item/reagent_containers/food/drinks/drinkingglass = 30, - /obj/item/reagent_containers/food/drinks/drinkingglass/shotglass = 12, + /obj/item/reagent_containers/food/drinks/drinkingglass/shotglass = 12, /obj/item/reagent_containers/food/drinks/bottle/gin = 5, /obj/item/reagent_containers/food/drinks/bottle/whiskey = 5, /obj/item/reagent_containers/food/drinks/bottle/tequila = 5, @@ -41,6 +41,9 @@ product_ads = "Drink up!;Booze is good for you!;Alcohol is humanity's best friend.;Quite delighted to serve you!;Care for a nice, cold beer?;Nothing cures you like booze!;Have a sip!;Have a drink!;Have a beer!;Beer is good for you!;Only the finest alcohol!;Best quality booze since 2053!;Award-winning wine!;Maximum alcohol!;Man loves beer.;A toast for progress!" req_access = list(ACCESS_BAR) refill_canister = /obj/item/vending_refill/boozeomat + default_price = 120 + extra_price = 100 + payment_department = ACCOUNT_SRV /obj/machinery/vending/boozeomat/all_access desc = "A technological marvel, supposedly able to mix just the mixture you'd like to drink the moment you ask for one. This model appears to have no access restrictions." diff --git a/code/modules/vending/cartridge.dm b/code/modules/vending/cartridge.dm index 35b1a1da7a..93fb3a0af8 100644 --- a/code/modules/vending/cartridge.dm +++ b/code/modules/vending/cartridge.dm @@ -16,6 +16,9 @@ armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50) refill_canister = /obj/item/vending_refill/cart resistance_flags = FIRE_PROOF + default_price = 250 + extra_price = 500 + payment_department = ACCOUNT_SRV /obj/item/vending_refill/cart icon_state = "refill_pda" diff --git a/code/modules/vending/cigarette.dm b/code/modules/vending/cigarette.dm index f567c9765e..5895568158 100644 --- a/code/modules/vending/cigarette.dm +++ b/code/modules/vending/cigarette.dm @@ -20,6 +20,9 @@ /obj/item/storage/fancy/cigarettes/cigars/havana = 1, /obj/item/storage/fancy/cigarettes/cigars/cohiba = 1) refill_canister = /obj/item/vending_refill/cigarette + default_price = 75 + extra_price = 250 + payment_department = ACCOUNT_SRV /obj/machinery/vending/cigarette/syndicate products = list(/obj/item/storage/fancy/cigarettes/cigpack_syndicate = 7, diff --git a/code/modules/vending/clothesmate.dm b/code/modules/vending/clothesmate.dm index 521c1e0999..2155d0fe8b 100644 --- a/code/modules/vending/clothesmate.dm +++ b/code/modules/vending/clothesmate.dm @@ -173,6 +173,12 @@ /obj/item/clothing/suit/jacket/letterman_nanotrasen = 5, /obj/item/clothing/suit/hooded/wintercoat/polychromic = 5) refill_canister = /obj/item/vending_refill/clothing + default_price = 60 + extra_price = 120 + payment_department = NO_FREEBIES + +/obj/machinery/vending/clothing/canLoadItem(obj/item/I,mob/user) + return (I.type in products) /obj/item/vending_refill/clothing machine_name = "ClothesMate" diff --git a/code/modules/vending/coffee.dm b/code/modules/vending/coffee.dm index 355d037f99..f4a8b2503e 100644 --- a/code/modules/vending/coffee.dm +++ b/code/modules/vending/coffee.dm @@ -14,6 +14,9 @@ /obj/item/reagent_containers/food/condiment/sugar = 1) refill_canister = /obj/item/vending_refill/coffee + default_price = 45 + extra_price = 150 + payment_department = ACCOUNT_SRV /obj/item/vending_refill/coffee machine_name = "Solar's Best Hot Drinks" diff --git a/code/modules/vending/cola.dm b/code/modules/vending/cola.dm index 57cf315209..5bbd0c3d02 100644 --- a/code/modules/vending/cola.dm +++ b/code/modules/vending/cola.dm @@ -21,6 +21,9 @@ /obj/item/reagent_containers/food/drinks/soda_cans/grey_bull = 1, /obj/item/reagent_containers/food/drinks/soda_cans/monkey_energy = 1) refill_canister = /obj/item/vending_refill/cola + default_price = 45 + extra_price = 200 + payment_department = ACCOUNT_SRV /obj/item/vending_refill/cola machine_name = "Robust Softdrinks" diff --git a/code/modules/vending/drinnerware.dm b/code/modules/vending/drinnerware.dm index 8f257d07ec..2e574a50a1 100644 --- a/code/modules/vending/drinnerware.dm +++ b/code/modules/vending/drinnerware.dm @@ -29,6 +29,9 @@ armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50) refill_canister = /obj/item/vending_refill/dinnerware resistance_flags = FIRE_PROOF + default_price = 50 + extra_price = 250 + payment_department = ACCOUNT_SRV /obj/item/vending_refill/dinnerware icon_state = "refill_cook" \ No newline at end of file diff --git a/code/modules/vending/engineering.dm b/code/modules/vending/engineering.dm index e067c094f6..20ca364277 100644 --- a/code/modules/vending/engineering.dm +++ b/code/modules/vending/engineering.dm @@ -29,3 +29,6 @@ /obj/item/stock_parts/manipulator = 5) armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50) resistance_flags = FIRE_PROOF + default_price = 450 + extra_price = 500 + payment_department = ACCOUNT_ENG diff --git a/code/modules/vending/engivend.dm b/code/modules/vending/engivend.dm index 15da7cab15..e5571d1d6a 100644 --- a/code/modules/vending/engivend.dm +++ b/code/modules/vending/engivend.dm @@ -30,6 +30,9 @@ armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50) refill_canister = /obj/item/vending_refill/engivend resistance_flags = FIRE_PROOF + default_price = 450 + extra_price = 500 + payment_department = ACCOUNT_ENG /obj/item/vending_refill/engivend icon_state = "refill_engi" \ No newline at end of file diff --git a/code/modules/vending/games.dm b/code/modules/vending/games.dm index e663dca7ce..81c49eeb31 100644 --- a/code/modules/vending/games.dm +++ b/code/modules/vending/games.dm @@ -11,6 +11,9 @@ premium = list(/obj/item/melee/skateboard/pro = 3, /obj/item/melee/skateboard/hoverboard = 1) refill_canister = /obj/item/vending_refill/games + default_price = 50 + extra_price = 250 + payment_department = ACCOUNT_SRV /obj/item/vending_refill/games machine_name = "\improper Good Clean Fun" diff --git a/code/modules/vending/kinkmate.dm b/code/modules/vending/kinkmate.dm index acfeeddaa9..37f4e380ce 100644 --- a/code/modules/vending/kinkmate.dm +++ b/code/modules/vending/kinkmate.dm @@ -40,6 +40,9 @@ /obj/item/clothing/under/pants/chaps = 5 ) refill_canister = /obj/item/vending_refill/kink + default_price = 80 + extra_price = 250 + payment_department = NO_FREEBIES /obj/item/vending_refill/kink machine_name = "KinkMate" diff --git a/code/modules/vending/liberation.dm b/code/modules/vending/liberation.dm index affc1dfed7..c75d313c52 100644 --- a/code/modules/vending/liberation.dm +++ b/code/modules/vending/liberation.dm @@ -28,3 +28,6 @@ /obj/item/reagent_containers/food/snacks/burger/superbite = 3) //U S A armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50) resistance_flags = FIRE_PROOF + default_price = 150 + extra_price = 500 + payment_department = ACCOUNT_SEC diff --git a/code/modules/vending/liberation_toy.dm b/code/modules/vending/liberation_toy.dm index e2c97b32db..09cbd006d0 100644 --- a/code/modules/vending/liberation_toy.dm +++ b/code/modules/vending/liberation_toy.dm @@ -25,3 +25,6 @@ armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50) resistance_flags = FIRE_PROOF refill_canister = /obj/item/vending_refill/donksoft + default_price = 150 + extra_price = 300 + payment_department = ACCOUNT_SRV diff --git a/code/modules/vending/magivend.dm b/code/modules/vending/magivend.dm index ab7670c453..525b9f1af2 100644 --- a/code/modules/vending/magivend.dm +++ b/code/modules/vending/magivend.dm @@ -16,3 +16,6 @@ contraband = list(/obj/item/reagent_containers/glass/bottle/wizarditis = 1) //No one can get to the machine to hack it anyways; for the lulz - Microwave armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50, "magic" = 100) resistance_flags = FIRE_PROOF + default_price = 250 + extra_price = 500 + payment_department = ACCOUNT_SRV diff --git a/code/modules/vending/medical.dm b/code/modules/vending/medical.dm index d32af7de03..af8df11cc6 100644 --- a/code/modules/vending/medical.dm +++ b/code/modules/vending/medical.dm @@ -47,6 +47,9 @@ armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50) resistance_flags = FIRE_PROOF refill_canister = /obj/item/vending_refill/medical + default_price = 250 + extra_price = 500 + payment_department = ACCOUNT_MED /obj/item/vending_refill/medical machine_name = "NanoMed Plus" diff --git a/code/modules/vending/medical_wall.dm b/code/modules/vending/medical_wall.dm index a048d253c5..9d1885c769 100644 --- a/code/modules/vending/medical_wall.dm +++ b/code/modules/vending/medical_wall.dm @@ -18,6 +18,9 @@ armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50) resistance_flags = FIRE_PROOF refill_canister = /obj/item/vending_refill/wallmed + default_price = 250 + extra_price = 500 + payment_department = ACCOUNT_MED /obj/item/vending_refill/wallmed machine_name = "NanoMed" diff --git a/code/modules/vending/megaseed.dm b/code/modules/vending/megaseed.dm index 37ce00069c..4cc19d4df5 100644 --- a/code/modules/vending/megaseed.dm +++ b/code/modules/vending/megaseed.dm @@ -57,6 +57,9 @@ armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50) refill_canister = /obj/item/vending_refill/hydroseeds resistance_flags = FIRE_PROOF + default_price = 100 + extra_price = 350 + payment_department = ACCOUNT_SRV /obj/item/vending_refill/hydroseeds icon_state = "refill_hydro" diff --git a/code/modules/vending/nutrimax.dm b/code/modules/vending/nutrimax.dm index 42b7848ac1..b55a39ff1e 100644 --- a/code/modules/vending/nutrimax.dm +++ b/code/modules/vending/nutrimax.dm @@ -19,6 +19,9 @@ armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50) refill_canister = /obj/item/vending_refill/hydronutrients resistance_flags = FIRE_PROOF + default_price = 100 + extra_price = 250 + payment_department = ACCOUNT_SRV /obj/item/vending_refill/hydronutrients icon_state = "refill_hydro" diff --git a/code/modules/vending/plasmaresearch.dm b/code/modules/vending/plasmaresearch.dm index 40b709f5b5..412a9fb33c 100644 --- a/code/modules/vending/plasmaresearch.dm +++ b/code/modules/vending/plasmaresearch.dm @@ -11,3 +11,6 @@ /obj/item/assembly/prox_sensor = 6, /obj/item/assembly/igniter = 6) contraband = list(/obj/item/assembly/health = 3) + default_price = 400 + extra_price = 600 + payment_department = ACCOUNT_SCI diff --git a/code/modules/vending/robotics.dm b/code/modules/vending/robotics.dm index 852b7d65f0..ca07724460 100644 --- a/code/modules/vending/robotics.dm +++ b/code/modules/vending/robotics.dm @@ -21,3 +21,5 @@ /obj/item/crowbar = 5) armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50) resistance_flags = FIRE_PROOF + default_price = 600 + payment_department = ACCOUNT_SCI diff --git a/code/modules/vending/security.dm b/code/modules/vending/security.dm index 09681def64..2fc1afa375 100644 --- a/code/modules/vending/security.dm +++ b/code/modules/vending/security.dm @@ -25,6 +25,9 @@ armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50) resistance_flags = FIRE_PROOF refill_canister = /obj/item/vending_refill/security + default_price = 650 + extra_price = 700 + payment_department = ACCOUNT_SEC /obj/machinery/vending/security/pre_throw(obj/item/I) if(istype(I, /obj/item/grenade)) diff --git a/code/modules/vending/snack.dm b/code/modules/vending/snack.dm index 9dda649b24..aff02b019a 100644 --- a/code/modules/vending/snack.dm +++ b/code/modules/vending/snack.dm @@ -26,77 +26,15 @@ /obj/item/storage/box/donkpockets = 2) refill_canister = /obj/item/vending_refill/snack - var/chef_compartment_access = "28" //ACCESS_KITCHEN + canload_access_list = list(ACCESS_KITCHEN) + default_price = 60 + extra_price = 160 + payment_department = ACCOUNT_SRV + input_display_header = "Chef's Food Selection" /obj/item/vending_refill/snack machine_name = "Getmore Chocolate Corp" -/obj/machinery/vending/snack/attackby(obj/item/W, mob/user, params) - if(istype(W, /obj/item/reagent_containers/food/snacks)) - if(!compartment_access_check(user)) - return - var/obj/item/reagent_containers/food/snacks/S = W - if(!S.junkiness) - if(!iscompartmentfull(user)) - if(!user.transferItemToLoc(W, src)) - return - food_load(W) - to_chat(user, "You insert [W] into [src]'s chef compartment.") - else - to_chat(user, "[src]'s chef compartment does not accept junk food.") - - else if(istype(W, /obj/item/storage/bag/tray)) - if(!compartment_access_check(user)) - return - var/obj/item/storage/T = W - var/loaded = 0 - var/denied_items = 0 - for(var/obj/item/reagent_containers/food/snacks/S in T.contents) - if(iscompartmentfull(user)) - break - if(!S.junkiness) - SEND_SIGNAL(T, COMSIG_TRY_STORAGE_TAKE, S, src, TRUE) - food_load(S) - loaded++ - else - denied_items++ - if(denied_items) - to_chat(user, "[src] refuses some items.") - if(loaded) - to_chat(user, "You insert [loaded] dishes into [src]'s chef compartment.") - updateUsrDialog() - return - - else - return ..() - -/obj/machinery/vending/snack/Destroy() - for(var/obj/item/reagent_containers/food/snacks/S in contents) - S.forceMove(get_turf(src)) - return ..() - -/obj/machinery/vending/snack/proc/compartment_access_check(user) - req_access_txt = chef_compartment_access - if(!allowed(user) && !(obj_flags & EMAGGED) && scan_id) - to_chat(user, "[src]'s chef compartment blinks red: Access denied.") - req_access_txt = "0" - return 0 - req_access_txt = "0" - return 1 - -/obj/machinery/vending/snack/proc/iscompartmentfull(mob/user) - if(contents.len >= 30) // no more than 30 dishes can fit inside - to_chat(user, "[src]'s chef compartment is full.") - return 1 - return 0 - -/obj/machinery/vending/snack/proc/food_load(obj/item/reagent_containers/food/snacks/S) - if(dish_quants[S.name]) - dish_quants[S.name]++ - else - dish_quants[S.name] = 1 - sortList(dish_quants) - /obj/machinery/vending/snack/random name = "\improper Random Snackies" icon_state = "random_snack" diff --git a/code/modules/vending/sovietsoda.dm b/code/modules/vending/sovietsoda.dm index 39364d78da..d820794660 100644 --- a/code/modules/vending/sovietsoda.dm +++ b/code/modules/vending/sovietsoda.dm @@ -7,3 +7,6 @@ contraband = list(/obj/item/reagent_containers/food/drinks/drinkingglass/filled/cola = 20) armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50) resistance_flags = FIRE_PROOF + default_price = 1 + extra_price = 1 + payment_department = NO_FREEBIES diff --git a/code/modules/vending/sovietvend.dm b/code/modules/vending/sovietvend.dm index c555362fb6..daf64d5f3e 100644 --- a/code/modules/vending/sovietvend.dm +++ b/code/modules/vending/sovietvend.dm @@ -23,6 +23,9 @@ premium = list() refill_canister = /obj/item/vending_refill/soviet + default_price = 1 + extra_price = 1 + payment_department = NO_FREEBIES /obj/item/vending_refill/soviet machine_name = "sovietvend" diff --git a/code/modules/vending/sustenance.dm b/code/modules/vending/sustenance.dm index 9783607a21..55e6b02e8e 100644 --- a/code/modules/vending/sustenance.dm +++ b/code/modules/vending/sustenance.dm @@ -14,6 +14,9 @@ armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50) refill_canister = /obj/item/vending_refill/sustenance resistance_flags = FIRE_PROOF + default_price = 0 + extra_price = 0 + payment_department = NO_FREEBIES /obj/item/vending_refill/sustenance icon_state = "refill_cook" diff --git a/code/modules/vending/toys.dm b/code/modules/vending/toys.dm index 08bb4615bb..a00dd17a9c 100644 --- a/code/modules/vending/toys.dm +++ b/code/modules/vending/toys.dm @@ -25,6 +25,9 @@ armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50) resistance_flags = FIRE_PROOF refill_canister = /obj/item/vending_refill/donksoft + default_price = 150 + extra_price = 300 + payment_department = ACCOUNT_SRV /obj/item/vending_refill/donksoft machine_name = "Donksoft Toy Vendor" diff --git a/code/modules/vending/wardrobes.dm b/code/modules/vending/wardrobes.dm index acd58959f1..0da6a68583 100644 --- a/code/modules/vending/wardrobes.dm +++ b/code/modules/vending/wardrobes.dm @@ -1,6 +1,15 @@ /obj/item/vending_refill/wardrobe icon_state = "refill_clothes" +/obj/machinery/vending/wardrobe + default_price = 350 + extra_price = 400 + payment_department = NO_FREEBIES + input_display_header = "Returned Clothing" + +/obj/machinery/vending/wardrobe/canLoadItem(obj/item/I,mob/user) + return (I.type in products) + /obj/machinery/vending/wardrobe/sec_wardrobe name = "\improper SecDrobe" desc = "A vending machine for security and security-related clothing!" @@ -22,6 +31,7 @@ premium = list(/obj/item/clothing/under/rank/security/officer/formal = 5, /obj/item/clothing/head/beret/sec/navyofficer = 5) refill_canister = /obj/item/vending_refill/wardrobe/sec_wardrobe + payment_department = ACCOUNT_SEC /obj/item/vending_refill/wardrobe/sec_wardrobe machine_name = "SecDrobe" @@ -57,6 +67,7 @@ /obj/item/clothing/suit/apron/surgical = 5, /obj/item/clothing/mask/surgical = 5) refill_canister = /obj/item/vending_refill/wardrobe/medi_wardrobe + payment_department = ACCOUNT_MED /obj/item/vending_refill/wardrobe/medi_wardrobe machine_name = "MediDrobe" @@ -80,6 +91,7 @@ /obj/item/clothing/head/hardhat = 5, /obj/item/clothing/head/hardhat/weldhat = 3) refill_canister = /obj/item/vending_refill/wardrobe/engi_wardrobe + payment_department = ACCOUNT_ENG /obj/item/vending_refill/wardrobe/engi_wardrobe machine_name = "EngiDrobe" @@ -101,6 +113,7 @@ /obj/item/clothing/under/rank/engineering/atmospheric_technician/skirt = 5, /obj/item/clothing/shoes/sneakers/black = 5) refill_canister = /obj/item/vending_refill/wardrobe/atmos_wardrobe + payment_department = ACCOUNT_ENG /obj/item/vending_refill/wardrobe/atmos_wardrobe machine_name = "AtmosDrobe" @@ -119,6 +132,7 @@ /obj/item/clothing/head/soft = 5, /obj/item/radio/headset/headset_cargo = 3) refill_canister = /obj/item/vending_refill/wardrobe/cargo_wardrobe + payment_department = ACCOUNT_CAR /obj/item/vending_refill/wardrobe/cargo_wardrobe machine_name = "CargoDrobe" @@ -141,6 +155,7 @@ /obj/item/clothing/mask/bandana/skull = 2) contraband = list(/obj/item/clothing/suit/hooded/techpriest = 2) refill_canister = /obj/item/vending_refill/wardrobe/robo_wardrobe + payment_department = ACCOUNT_SCI /obj/item/vending_refill/wardrobe/robo_wardrobe machine_name = "RoboDrobe" @@ -163,6 +178,7 @@ /obj/item/radio/headset/headset_sci = 4, /obj/item/clothing/mask/gas = 5) refill_canister = /obj/item/vending_refill/wardrobe/science_wardrobe + payment_department = ACCOUNT_SCI /obj/item/vending_refill/wardrobe/science_wardrobe machine_name = "SciDrobe" @@ -182,6 +198,7 @@ /obj/item/clothing/under/rank/civilian/hydroponics/skirt = 5, /obj/item/clothing/mask/bandana = 4) refill_canister = /obj/item/vending_refill/wardrobe/hydro_wardrobe + payment_department = ACCOUNT_SRV /obj/item/vending_refill/wardrobe/hydro_wardrobe machine_name = "HyDrobe" @@ -206,6 +223,7 @@ /obj/item/clothing/glasses/regular/jamjar = 1, /obj/item/storage/bag/books = 1) refill_canister = /obj/item/vending_refill/wardrobe/curator_wardrobe + payment_department = ACCOUNT_CIV /obj/item/vending_refill/wardrobe/curator_wardrobe machine_name = "CuraDrobe" @@ -234,6 +252,7 @@ /obj/item/clothing/neck/petcollar = 3, /obj/item/storage/belt/bandolier = 1) refill_canister = /obj/item/vending_refill/wardrobe/bar_wardrobe + payment_department = ACCOUNT_SRV /obj/item/vending_refill/wardrobe/bar_wardrobe machine_name = "BarDrobe" @@ -259,6 +278,7 @@ /obj/item/book/granter/crafting_recipe/cooking_sweets_101 = 2, /obj/item/book/granter/crafting_recipe/coldcooking = 2) refill_canister = /obj/item/vending_refill/wardrobe/chef_wardrobe + payment_department = ACCOUNT_SRV /obj/item/vending_refill/wardrobe/chef_wardrobe machine_name = "ChefDrobe" @@ -290,6 +310,7 @@ /obj/item/screwdriver = 2, /obj/item/stack/cable_coil/random = 4) refill_canister = /obj/item/vending_refill/wardrobe/jani_wardrobe + payment_department = ACCOUNT_SRV /obj/item/vending_refill/wardrobe/jani_wardrobe machine_name = "JaniDrobe" @@ -321,6 +342,7 @@ /obj/item/clothing/shoes/laceup = 3, /obj/item/clothing/accessory/lawyers_badge = 3) refill_canister = /obj/item/vending_refill/wardrobe/law_wardrobe + payment_department = ACCOUNT_CIV /obj/item/vending_refill/wardrobe/law_wardrobe machine_name = "LawDrobe" @@ -368,6 +390,7 @@ /obj/item/storage/bag/chemistry = 3, /obj/item/fermichem/pHbooklet = 3)//pH indicator) refill_canister = /obj/item/vending_refill/wardrobe/chem_wardrobe + payment_department = ACCOUNT_MED /obj/item/vending_refill/wardrobe/chem_wardrobe machine_name = "ChemDrobe" @@ -386,6 +409,7 @@ /obj/item/storage/backpack/genetics = 3, /obj/item/storage/backpack/satchel/gen = 3) refill_canister = /obj/item/vending_refill/wardrobe/gene_wardrobe + payment_department = ACCOUNT_MED /obj/item/vending_refill/wardrobe/gene_wardrobe machine_name = "GeneDrobe" @@ -406,6 +430,7 @@ /obj/item/storage/backpack/virology = 3, /obj/item/storage/backpack/satchel/vir = 3) refill_canister = /obj/item/vending_refill/wardrobe/viro_wardrobe + payment_department = ACCOUNT_MED /obj/item/vending_refill/wardrobe/viro_wardrobe machine_name = "ViroDrobe" @@ -436,6 +461,7 @@ /obj/item/clothing/glasses/sunglasses/gar/supergar = 1, /obj/item/clothing/gloves/color/captain = 1) refill_canister = /obj/item/vending_refill/wardrobe/cap_wardrobe + payment_department = ACCOUNT_CIV /obj/item/vending_refill/wardrobe/cap_wardrobe machine_name = "Captain's Wardrobe" diff --git a/code/modules/vending/youtool.dm b/code/modules/vending/youtool.dm index c027cea6e5..009621b85a 100644 --- a/code/modules/vending/youtool.dm +++ b/code/modules/vending/youtool.dm @@ -21,6 +21,9 @@ armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 70) refill_canister = /obj/item/vending_refill/tool resistance_flags = FIRE_PROOF + default_price = 125 + extra_price = 350 + payment_department = ACCOUNT_ENG /obj/item/vending_refill/tool icon_state = "refill_engi" \ No newline at end of file diff --git a/config/game_options.txt b/config/game_options.txt index 8c48ac6ede..51e68ac273 100644 --- a/config/game_options.txt +++ b/config/game_options.txt @@ -583,6 +583,9 @@ NIGHTSHIFT_TOGGLE_PUBLIC_REQUIRES_AUTH ## A cap on how many monkeys may be created via monkey cubes MONKEYCAP 64 +## Enable the capitalist agenda on your server. +ECONOMY + ## Uncomment to use TG-style combat #DISABLE_STAMBUFFER diff --git a/config/vr_config.txt b/config/vr_config.txt new file mode 100644 index 0000000000..8ca2334d5f --- /dev/null +++ b/config/vr_config.txt @@ -0,0 +1,13 @@ +#List the potential virtual reality Z-levels here. awaymissionconfig copypasta follows. + +#Maps must be the full path to them +#Maps should be 255x255 or smaller and be bounded. Falling off the edge of the map will result in undefined behavior. +#SPECIFYING AN INVALID MAP WILL RESULT IN RUNTIMES ON GAME START + +#!!IMPORTANT NOTES FOR HOSTING VR MAPS!!: +#Do NOT tick the maps during compile -- the game uses this list to decide which map to load. Ticking the maps will result in them ALL being loaded at once. +#DO tick the associated code file for the virtual reality levels you are enabling. Otherwise, the map will be trying to reference objects which do not exist, which will cause runtime errors! + +#_maps/RandomZLevels/VR/murderdome.dmm +#_maps/RandomZLevels/VR/snowdin_VR.dm +#_maps/RandomZLevels/VR/syndicate_trainer.dm \ No newline at end of file diff --git a/icons/obj/crates.dmi b/icons/obj/crates.dmi index ecb66d0119..532324fcf4 100644 Binary files a/icons/obj/crates.dmi and b/icons/obj/crates.dmi differ diff --git a/icons/obj/device.dmi b/icons/obj/device.dmi index c58fb5d940..a60620bfef 100644 Binary files a/icons/obj/device.dmi and b/icons/obj/device.dmi differ diff --git a/icons/obj/economy.dmi b/icons/obj/economy.dmi index 9cc6498454..a73f50ef7f 100644 Binary files a/icons/obj/economy.dmi and b/icons/obj/economy.dmi differ diff --git a/icons/obj/items_and_weapons.dmi b/icons/obj/items_and_weapons.dmi index 6ee7873469..c8834057f9 100644 Binary files a/icons/obj/items_and_weapons.dmi and b/icons/obj/items_and_weapons.dmi differ diff --git a/icons/obj/money_machine.dmi b/icons/obj/money_machine.dmi new file mode 100644 index 0000000000..3e7fde761f Binary files /dev/null and b/icons/obj/money_machine.dmi differ diff --git a/icons/obj/money_machine_64.dmi b/icons/obj/money_machine_64.dmi new file mode 100644 index 0000000000..7bad748f2e Binary files /dev/null and b/icons/obj/money_machine_64.dmi differ diff --git a/icons/obj/vending_restock.dmi b/icons/obj/vending_restock.dmi index 035c01de6b..978a13803c 100644 Binary files a/icons/obj/vending_restock.dmi and b/icons/obj/vending_restock.dmi differ diff --git a/sound/items/dump_it.ogg b/sound/items/dump_it.ogg new file mode 100644 index 0000000000..33bdb49e69 Binary files /dev/null and b/sound/items/dump_it.ogg differ diff --git a/tgstation.dme b/tgstation.dme index 26bb4e2e5a..b769ec4a22 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -45,6 +45,7 @@ #include "code\__DEFINES\donator_groupings.dm" #include "code\__DEFINES\dye_keys.dm" #include "code\__DEFINES\dynamic.dm" +#include "code\__DEFINES\economy.dm" #include "code\__DEFINES\events.dm" #include "code\__DEFINES\exports.dm" #include "code\__DEFINES\fantasy_affixes.dm" @@ -260,6 +261,7 @@ #include "code\controllers\subsystem\dbcore.dm" #include "code\controllers\subsystem\dcs.dm" #include "code\controllers\subsystem\disease.dm" +#include "code\controllers\subsystem\economy.dm" #include "code\controllers\subsystem\events.dm" #include "code\controllers\subsystem\fail2topic.dm" #include "code\controllers\subsystem\fire_burning.dm" @@ -908,7 +910,9 @@ #include "code\game\objects\items\control_wand.dm" #include "code\game\objects\items\cosmetics.dm" #include "code\game\objects\items\courtroom.dm" +#include "code\game\objects\items\crab17.dm" #include "code\game\objects\items\crayons.dm" +#include "code\game\objects\items\credit_holochip.dm" #include "code\game\objects\items\debug_items.dm" #include "code\game\objects\items\defib.dm" #include "code\game\objects\items\dehy_carp.dm" @@ -1803,6 +1807,9 @@ #include "code\modules\detectivework\detective_work.dm" #include "code\modules\detectivework\evidence.dm" #include "code\modules\detectivework\scanner.dm" +#include "code\modules\economy\_economy.dm" +#include "code\modules\economy\account.dm" +#include "code\modules\economy\paystand.dm" #include "code\modules\emoji\emoji_parse.dm" #include "code\modules\error_handler\error_handler.dm" #include "code\modules\error_handler\error_viewer.dm" diff --git a/tgui-next/packages/tgui/interfaces/Cargo.js b/tgui-next/packages/tgui/interfaces/Cargo.js index 85ae19755e..b31a25c611 100644 --- a/tgui-next/packages/tgui/interfaces/Cargo.js +++ b/tgui-next/packages/tgui/interfaces/Cargo.js @@ -75,7 +75,17 @@ export const Cargo = props => { {() => (
+ buttons={( + + {cartButtons} +
)} @@ -137,11 +147,6 @@ const Catalog = props => {
-
NameDescriptionRewardCompletionStatus
{pack.name}: - {!!pack.small_item && ( - Small Item - )} - {!!pack.access && ( Restrictions Apply @@ -336,4 +341,4 @@ export const CargoExpress = props => { )} ); -}; +}; \ No newline at end of file diff --git a/tgui-next/packages/tgui/interfaces/Vending.js b/tgui-next/packages/tgui/interfaces/Vending.js index b6ffde015d..c96bae7c70 100644 --- a/tgui-next/packages/tgui/interfaces/Vending.js +++ b/tgui-next/packages/tgui/interfaces/Vending.js @@ -9,40 +9,54 @@ export const Vending = props => { const { ref } = config; let inventory; let custom = false; - const onstation = true; - if (data.extended_inventory && data.coin) { - inventory = [ - ...data.product_records, - ...data.hidden_records, - ...data.coin_records, - ]; + if (data.vending_machine_input) { + inventory = data.vending_machine_input; + custom = true; } else if (data.extended_inventory) { - inventory = [ - ...data.product_records, - ...data.hidden_records, - ]; - } else if (data.coin) { inventory = [ ...data.product_records, ...data.coin_records, + ...data.hidden_records, ]; } else { inventory = [ ...data.product_records, + ...data.coin_records, ]; } return ( - {data.coin && ( -
-