diff --git a/_maps/RandomRuins/SpaceRuinsStation/roid7.dmm b/_maps/RandomRuins/SpaceRuinsStation/roid7.dmm index d694fc7c9f..9cc192efc7 100644 --- a/_maps/RandomRuins/SpaceRuinsStation/roid7.dmm +++ b/_maps/RandomRuins/SpaceRuinsStation/roid7.dmm @@ -168,7 +168,7 @@ /turf/template_noop, /area/template_noop) "H" = ( -/obj/machinery/vending/boozeomat/all_access, +/obj/machinery/vending/boozeomat, /turf/open/floor/plasteel/airless/cafeteria, /area/ruin/space) "I" = ( diff --git a/_maps/RandomZLevels/away_mission/TheBeach.dmm b/_maps/RandomZLevels/away_mission/TheBeach.dmm index cc9f50d029..5430d8dd92 100644 --- a/_maps/RandomZLevels/away_mission/TheBeach.dmm +++ b/_maps/RandomZLevels/away_mission/TheBeach.dmm @@ -799,7 +799,7 @@ /turf/open/floor/wood, /area/awaymission/beach) "cn" = ( -/obj/machinery/vending/boozeomat/all_access{ +/obj/machinery/vending/boozeomat{ desc = "A technological marvel, supposedly able to mix just the mixture you'd like to drink the moment you ask for one. May not work for bartenders that don't have Nanotrasen bank accounts." }, /turf/open/floor/wood, diff --git a/_maps/map_files/BoxStation/BoxStation.dmm b/_maps/map_files/BoxStation/BoxStation.dmm index 75efefd8e1..3d95ed9dbd 100644 --- a/_maps/map_files/BoxStation/BoxStation.dmm +++ b/_maps/map_files/BoxStation/BoxStation.dmm @@ -18338,7 +18338,7 @@ /turf/open/floor/plasteel, /area/crew_quarters/locker) "aQV" = ( -/obj/machinery/vending/autodrobe/all_access, +/obj/machinery/vending/autodrobe, /obj/structure/disposalpipe/segment{ dir = 4 }, @@ -41478,13 +41478,6 @@ }, /turf/open/floor/plasteel, /area/engine/atmos) -"bUO" = ( -/obj/machinery/portable_atmospherics/canister, -/obj/machinery/atmospherics/components/unary/portables_connector/visible{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/engine/atmos) "bUR" = ( /obj/machinery/atmospherics/pipe/simple/green/visible, /turf/open/floor/plasteel, @@ -55361,14 +55354,6 @@ /obj/effect/turf_decal/tile/green, /turf/open/floor/plasteel, /area/hallway/primary/starboard) -"ivJ" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/visible, -/obj/effect/spawner/structure/window/reinforced, -/obj/machinery/atmospherics/pipe/layer_manifold{ - dir = 4 - }, -/turf/open/floor/plating, -/area/engine/atmos) "iwB" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 @@ -56424,7 +56409,7 @@ }, /area/maintenance/bar) "lsk" = ( -/obj/machinery/vending/autodrobe/all_access, +/obj/machinery/vending/autodrobe, /turf/open/floor/plasteel, /area/crew_quarters/fitness) "ltK" = ( @@ -58873,7 +58858,7 @@ /turf/open/floor/plating, /area/maintenance/fore/secondary) "sXA" = ( -/obj/machinery/vending/boozeomat/all_access, +/obj/machinery/vending/boozeomat, /turf/closed/wall, /area/maintenance/bar) "sXV" = ( @@ -93957,7 +93942,7 @@ bMQ bRC rdl daq -bUO +bUN bOd bOd bOd @@ -94214,7 +94199,7 @@ cBF bRD rdl daq -bUO +bUN bOd bOd bOd @@ -94471,7 +94456,7 @@ bQs cez ceA daq -bUO +bUN bOd bOd bOd @@ -96008,19 +95993,19 @@ bKH bLK bLK bOf -ivJ +bPh bQy bRI bSP -ivJ +bPh jzM bRI cCF -ivJ +bPh bQy bRI bQy -ivJ +bPh bQy bRI bSP diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm index 02e44d0a5a..104cee0b9d 100644 --- a/_maps/map_files/Deltastation/DeltaStation2.dmm +++ b/_maps/map_files/Deltastation/DeltaStation2.dmm @@ -11361,7 +11361,7 @@ "ayW" = ( /obj/machinery/light/small, /obj/effect/decal/cleanable/dirt, -/obj/machinery/vending/autodrobe/all_access, +/obj/machinery/vending/autodrobe, /obj/effect/turf_decal/tile/red{ dir = 1 }, @@ -81511,7 +81511,7 @@ /turf/open/floor/plasteel/dark, /area/crew_quarters/locker) "cGO" = ( -/obj/machinery/vending/autodrobe/all_access, +/obj/machinery/vending/autodrobe, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -108635,7 +108635,7 @@ /obj/structure/sign/poster/contraband/random{ pixel_y = -32 }, -/obj/machinery/vending/boozeomat/all_access, +/obj/machinery/vending/boozeomat, /turf/open/floor/plating, /area/crew_quarters/abandoned_gambling_den) "dBS" = ( diff --git a/_maps/map_files/IceBoxStation/IceBoxStation.dmm b/_maps/map_files/IceBoxStation/IceBoxStation.dmm index a18d3ab68e..e9aa4819e9 100644 --- a/_maps/map_files/IceBoxStation/IceBoxStation.dmm +++ b/_maps/map_files/IceBoxStation/IceBoxStation.dmm @@ -18490,7 +18490,7 @@ /turf/open/floor/plasteel, /area/crew_quarters/locker) "aQV" = ( -/obj/machinery/vending/autodrobe/all_access, +/obj/machinery/vending/autodrobe, /obj/structure/disposalpipe/segment{ dir = 4 }, @@ -56834,7 +56834,7 @@ /turf/open/floor/engine, /area/engine/engineering) "lsk" = ( -/obj/machinery/vending/autodrobe/all_access, +/obj/machinery/vending/autodrobe, /turf/open/floor/plasteel, /area/crew_quarters/fitness) "ltK" = ( @@ -59723,7 +59723,7 @@ /turf/open/floor/plating, /area/maintenance/fore/secondary) "sXA" = ( -/obj/machinery/vending/boozeomat/all_access, +/obj/machinery/vending/boozeomat, /turf/closed/wall, /area/maintenance/bar) "sXV" = ( diff --git a/_maps/map_files/KiloStation/KiloStation.dmm b/_maps/map_files/KiloStation/KiloStation.dmm index a87ea077b3..e3f4b18103 100644 --- a/_maps/map_files/KiloStation/KiloStation.dmm +++ b/_maps/map_files/KiloStation/KiloStation.dmm @@ -54029,7 +54029,7 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, -/obj/machinery/vending/autodrobe/all_access, +/obj/machinery/vending/autodrobe, /obj/effect/turf_decal/delivery, /turf/open/floor/plasteel/dark, /area/crew_quarters/locker) @@ -78316,7 +78316,7 @@ /obj/effect/turf_decal/tile/neutral{ dir = 4 }, -/obj/machinery/vending/autodrobe/all_access, +/obj/machinery/vending/autodrobe, /obj/structure/noticeboard{ dir = 4; pixel_x = -27 @@ -84861,7 +84861,7 @@ /turf/open/floor/engine, /area/engine/engineering) "iLn" = ( -/obj/machinery/vending/boozeomat/all_access, +/obj/machinery/vending/boozeomat, /turf/open/floor/wood, /area/maintenance/port/fore) "iMb" = ( diff --git a/_maps/map_files/LambdaStation/lambda.dmm b/_maps/map_files/LambdaStation/lambda.dmm index 5d9018f4cc..6bb3807ea4 100644 --- a/_maps/map_files/LambdaStation/lambda.dmm +++ b/_maps/map_files/LambdaStation/lambda.dmm @@ -45021,7 +45021,7 @@ /turf/open/floor/wood, /area/maintenance/bar) "bGM" = ( -/obj/machinery/vending/boozeomat/all_access, +/obj/machinery/vending/boozeomat, /turf/open/floor/wood, /area/maintenance/bar) "bGN" = ( @@ -47241,7 +47241,6 @@ /area/hydroponics/garden/abandoned) "bKT" = ( /obj/item/poster/random_contraband, -/turf/open/floor/plating, /turf/open/floor/plating{ icon_state = "platingdmg2" }, @@ -58598,7 +58597,7 @@ /turf/open/space, /area/space/nearstation) "cgJ" = ( -/obj/machinery/vending/autodrobe/all_access, +/obj/machinery/vending/autodrobe, /turf/open/floor/plating, /area/maintenance/aft) "cgK" = ( @@ -62158,7 +62157,6 @@ /obj/structure/cable{ icon_state = "0-4" }, -/turf/open/floor/plating, /turf/open/floor/plating{ icon_state = "platingdmg2" }, @@ -63619,7 +63617,6 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, -/turf/open/floor/plating, /turf/open/floor/plating{ icon_state = "platingdmg2" }, @@ -72658,7 +72655,7 @@ /turf/open/floor/plasteel/grimy, /area/bridge) "cIV" = ( -/obj/machinery/vending/boozeomat/all_access, +/obj/machinery/vending/boozeomat, /obj/machinery/status_display/evac{ pixel_y = 32 }, @@ -75970,7 +75967,6 @@ }, /area/maintenance/department/medical) "cPo" = ( -/turf/open/floor/plating, /turf/open/floor/plating{ icon_state = "platingdmg2" }, @@ -76073,7 +76069,6 @@ }, /area/maintenance/fore/secondary) "cPB" = ( -/turf/open/floor/plating, /turf/open/floor/plating{ icon_state = "platingdmg2" }, @@ -76098,17 +76093,10 @@ }, /area/maintenance/department/crew_quarters/dorms) "cPE" = ( -/turf/open/floor/plating, /turf/open/floor/plating{ icon_state = "platingdmg2" }, /area/maintenance/department/crew_quarters/dorms) -"cPF" = ( -/turf/open/floor/plating, -/turf/open/floor/plating{ - icon_state = "platingdmg2" - }, -/area/maintenance/aft) "cPG" = ( /obj/structure/cable{ icon_state = "4-8" @@ -115439,7 +115427,7 @@ cgm thv uRw boU -cPF +cfm chI cqg cWW @@ -118541,7 +118529,7 @@ aaA ceG cqt bYa -cPF +cfm ceG aaA aaA @@ -119299,7 +119287,7 @@ cQK bYa bYa cRQ -cPF +cfm chI cRv bYa diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm index 9d36d26f6f..40a9cd9842 100644 --- a/_maps/map_files/MetaStation/MetaStation.dmm +++ b/_maps/map_files/MetaStation/MetaStation.dmm @@ -45054,7 +45054,7 @@ /turf/open/floor/plating, /area/maintenance/port) "bLe" = ( -/obj/machinery/vending/autodrobe/all_access, +/obj/machinery/vending/autodrobe, /turf/open/floor/plating, /area/maintenance/port) "bLf" = ( @@ -57077,7 +57077,7 @@ /turf/open/floor/plating/airless, /area/engine/atmos) "cjp" = ( -/obj/machinery/vending/boozeomat/all_access, +/obj/machinery/vending/boozeomat, /turf/open/floor/wood, /area/maintenance/port/aft) "cjq" = ( diff --git a/_maps/map_files/debug/runtimestation.dmm b/_maps/map_files/debug/runtimestation.dmm index feb8fc8cc0..40d02bcd0c 100644 --- a/_maps/map_files/debug/runtimestation.dmm +++ b/_maps/map_files/debug/runtimestation.dmm @@ -2526,7 +2526,6 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 1 }, -/turf/open/space/basic, /turf/open/floor/carpet/blackred, /area/crew_quarters/bar) "gR" = ( @@ -2806,7 +2805,6 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/turf/open/space/basic, /turf/open/floor/carpet/blackred, /area/crew_quarters/bar) "vP" = ( @@ -2832,7 +2830,6 @@ /turf/open/floor/plasteel, /area/hallway/primary/central) "wf" = ( -/turf/open/space/basic, /turf/open/floor/carpet/blackred, /area/crew_quarters/bar) "wS" = ( @@ -2854,7 +2851,6 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/turf/open/space/basic, /turf/open/floor/carpet/blackred, /area/crew_quarters/bar) "xh" = ( @@ -2869,7 +2865,6 @@ /obj/structure/cable{ icon_state = "4-8" }, -/turf/open/space/basic, /turf/open/floor/carpet/blackred, /area/crew_quarters/bar) "yt" = ( @@ -3002,7 +2997,7 @@ /turf/open/floor/grass, /area/hydroponics) "Ga" = ( -/obj/machinery/vending/boozeomat/all_access, +/obj/machinery/vending/boozeomat, /obj/machinery/airalarm{ dir = 8; pixel_x = 24 @@ -3041,7 +3036,6 @@ /area/bridge) "IB" = ( /obj/structure/chair/stool/bar, -/turf/open/space/basic, /turf/open/floor/carpet/blackred, /area/crew_quarters/bar) "JF" = ( @@ -3086,7 +3080,6 @@ /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 8 }, -/turf/open/space/basic, /turf/open/floor/carpet/blackred, /area/crew_quarters/bar) "Ly" = ( @@ -3115,7 +3108,6 @@ icon_state = "1-4" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/space/basic, /turf/open/floor/carpet/blackred, /area/crew_quarters/bar) "MS" = ( @@ -3334,7 +3326,6 @@ /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 4 }, -/turf/open/space/basic, /turf/open/floor/carpet/blackred, /area/crew_quarters/bar) diff --git a/_maps/map_files/generic/CentCom.dmm b/_maps/map_files/generic/CentCom.dmm index d015547ac4..633a998fdb 100644 --- a/_maps/map_files/generic/CentCom.dmm +++ b/_maps/map_files/generic/CentCom.dmm @@ -13278,7 +13278,7 @@ /turf/open/floor/engine/cult, /area/wizard_station) "ED" = ( -/obj/machinery/vending/boozeomat/all_access, +/obj/machinery/vending/boozeomat, /turf/closed/indestructible{ icon = 'icons/turf/walls/wood_wall.dmi'; icon_state = "wood"; @@ -17650,7 +17650,7 @@ /turf/open/floor/wood, /area/syndicate_mothership) "Sj" = ( -/obj/machinery/vending/autodrobe/all_access{ +/obj/machinery/vending/autodrobe{ extended_inventory = 1 }, /obj/machinery/light, diff --git a/_maps/shuttles/emergency_luxury.dmm b/_maps/shuttles/emergency_luxury.dmm index 2834f0c93f..a7faface75 100644 --- a/_maps/shuttles/emergency_luxury.dmm +++ b/_maps/shuttles/emergency_luxury.dmm @@ -422,7 +422,7 @@ /turf/open/floor/carpet/red, /area/shuttle/escape/luxury) "bD" = ( -/obj/machinery/vending/boozeomat/all_access, +/obj/machinery/vending/boozeomat, /turf/open/floor/carpet/red, /area/shuttle/escape/luxury) "bE" = ( diff --git a/_maps/shuttles/pirate_default.dmm b/_maps/shuttles/pirate_default.dmm index 9bd9d335c9..f664ea2c56 100644 --- a/_maps/shuttles/pirate_default.dmm +++ b/_maps/shuttles/pirate_default.dmm @@ -733,7 +733,7 @@ /turf/open/floor/plasteel, /area/shuttle/pirate) "bH" = ( -/obj/machinery/vending/boozeomat/all_access, +/obj/machinery/vending/boozeomat, /obj/effect/turf_decal/tile/bar, /obj/effect/turf_decal/tile/bar{ dir = 1 diff --git a/_maps/shuttles/whiteship_delta.dmm b/_maps/shuttles/whiteship_delta.dmm index 817f337503..84d2282c37 100644 --- a/_maps/shuttles/whiteship_delta.dmm +++ b/_maps/shuttles/whiteship_delta.dmm @@ -145,7 +145,7 @@ /turf/open/floor/plating, /area/shuttle/abandoned/crew) "ap" = ( -/obj/machinery/vending/boozeomat/all_access, +/obj/machinery/vending/boozeomat, /obj/effect/decal/cleanable/dirt{ desc = "A thin layer of dust coating the floor."; name = "dust" 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 47546cac30..c5c2dd58c2 100644 --- a/code/__DEFINES/maps.dm +++ b/code/__DEFINES/maps.dm @@ -41,6 +41,7 @@ require only minor tweaks. #define ZTRAIT_ICE_RUINS "Ice Ruins" #define ZTRAIT_ICE_RUINS_UNDERGROUND "Ice Ruins Underground" #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" //boolean - weather types that occur on the level #define ZTRAIT_SNOWSTORM "Weather_Snowstorm" @@ -80,6 +81,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 3abef3a61c..6eb38fce81 100644 --- a/code/__DEFINES/subsystems.dm +++ b/code/__DEFINES/subsystems.dm @@ -64,7 +64,8 @@ #define INIT_ORDER_TICKER 55 #define INIT_ORDER_INSTRUMENTS 53 #define INIT_ORDER_MAPPING 50 -#define INIT_ORDER_NETWORKS 45 +#define INIT_ORDER_ECONOMY 45 +#define INIT_ORDER_NETWORKS 40 #define INIT_ORDER_HOLODECK 35 #define INIT_ORDER_ATOMS 30 #define INIT_ORDER_LANGUAGE 25 diff --git a/code/__HELPERS/_cit_helpers.dm b/code/__HELPERS/_cit_helpers.dm index 5f78aeb740..86e8d1bc2b 100644 --- a/code/__HELPERS/_cit_helpers.dm +++ b/code/__HELPERS/_cit_helpers.dm @@ -105,16 +105,6 @@ GLOBAL_VAR_INIT(miscreants_allowed, FALSE) if(!src.holder) return message_admins("[key_name_admin(usr)] manually reloaded mentors") -//LOOC toggles -/client/verb/listen_looc() - set name = "Show/Hide LOOC" - set category = "Preferences" - set desc = "Toggles seeing LocalOutOfCharacter chat" - prefs.chat_toggles ^= CHAT_LOOC - prefs.save_preferences() - to_chat(src, "You will [(prefs.chat_toggles & CHAT_LOOC) ? "now" : "no longer"] see messages on the LOOC channel.") - SSblackbox.record_feedback("tally", "admin_verb", 1, "TLOOC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - /mob/living/carbon/proc/has_penis() var/obj/item/organ/genital/G = getorganslot(ORGAN_SLOT_PENIS) if(G && istype(G, /obj/item/organ/genital/penis)) diff --git a/code/__HELPERS/_lists.dm b/code/__HELPERS/_lists.dm index ad977ec493..c913a8ea5c 100644 --- a/code/__HELPERS/_lists.dm +++ b/code/__HELPERS/_lists.dm @@ -629,6 +629,8 @@ L["[key]"] = "[value]" return list2params(L) +#define NUMLIST2TEXTLIST(list) splittext(list2params(list), "&") + //Picks from the list, with some safeties, and returns the "default" arg if it fails #define DEFAULTPICK(L, default) ((islist(L) && length(L)) ? pick(L) : default) 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/unsorted.dm b/code/__HELPERS/unsorted.dm index 13ac820778..a22f430140 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -1048,6 +1048,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 diff --git a/code/_globalvars/lists/flavor_misc.dm b/code/_globalvars/lists/flavor_misc.dm index aacb1737a2..df83f1b4e3 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 2eefb82f97..b35f4fe0e7 100644 --- a/code/controllers/configuration/entries/game_options.dm +++ b/code/controllers/configuration/entries/game_options.dm @@ -81,6 +81,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 7c48adef24..4b2cf24f1e 100644 --- a/code/controllers/subsystem/job.dm +++ b/code/controllers/subsystem/job.dm @@ -479,6 +479,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/shuttle.dm b/code/controllers/subsystem/shuttle.dm index a3e804d541..532eb19bc9 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 dbb6864028..98027acc61 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 33560dbb8b..3b32213509 100644 --- a/code/game/machinery/autolathe.dm +++ b/code/game/machinery/autolathe.dm @@ -30,6 +30,8 @@ var/list/datum/design/matching_designs var/selected_category var/screen = 1 + var/base_price = 25 + var/hacked_price = 50 var/datum/techweb/specialized/autounlocking/stored_research = /datum/techweb/specialized/autounlocking/autolathe var/list/categories = list( 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 3f4b389b77..cfe9d14663 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 6eb06e3be4..22bea14381 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 28b9796bb6..915fad6418 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 4a0042e1da..6501a5b45e 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..7f6e561f55 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 = 900 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 c23bc2bd5b..8a5723e894 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,22 @@ 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) + switch(bank_support) + if(ID_FREE_BANK_ACCOUNT) + var/turf/T = get_turf(src) + if(T && is_vr_level(T.z)) //economy is exploitable on VR in so many ways. + bank_support = ID_NO_BANK_ACCOUNT + if(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 +200,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 && bank_support == ID_FREE_BANK_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 @@ -280,8 +425,12 @@ update_label("John Doe", "Clowny") else return ..() - var/popup_input = alert(user, "Choose Action", "Agent ID", "Show", "Forge/Reset") - if(user.incapacitated()) + 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.canUseTopic(src, BE_CLOSE, FALSE)) return if(popup_input == "Forge/Reset" && !forged) var/input_name = stripped_input(user, "What name would you like to put on this card? Leave blank to randomise.", "Agent card name", registered_name ? registered_name : (ishuman(user) ? user.real_name : user.name), MAX_NAME_LEN) @@ -304,6 +453,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) @@ -313,6 +474,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 @@ -329,6 +493,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." @@ -516,6 +689,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 @@ -578,5 +779,5 @@ update_label("John Doe", "Clowny") /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) . = ..() - 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 b788c3fcba..0e3744cd84 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)) @@ -1040,6 +1042,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 7329db0679..aa8c61ae0c 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" @@ -428,6 +429,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..a7b22a4c30 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 diff --git a/code/game/objects/items/devices/sensor_device.dm b/code/game/objects/items/devices/sensor_device.dm index 79d26776a9..a92d9221c2 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 = 900 /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 f6e52181ef..168bca0b9a 100644 --- a/code/game/objects/items/kitchen.dm +++ b/code/game/objects/items/kitchen.dm @@ -71,6 +71,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() . = ..() @@ -130,6 +131,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" @@ -197,6 +199,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..a1652fd211 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 = 600 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..a06b96ad9c 100644 --- a/code/game/objects/items/stacks/cash.dm +++ b/code/game/objects/items/stacks/cash.dm @@ -4,7 +4,7 @@ icon = 'icons/obj/economy.dmi' icon_state = "spacecash" amount = 1 - max_amount = 20 + max_amount = INFINITY throwforce = 0 throw_speed = 2 throw_range = 2 @@ -18,9 +18,11 @@ update_desc() /obj/item/stack/spacecash/proc/update_desc() - var/total_worth = amount*value + var/total_worth = get_item_credit_value() desc = "It's worth [total_worth] credit[( total_worth > 1 ) ? "s" : ""]" +/obj/item/stack/spacecash/get_item_credit_value() + return (amount*value) /obj/item/stack/spacecash/merge(obj/item/stack/S) . = ..() diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm index 19c15b309b..59a993ad96 100644 --- a/code/game/objects/items/stacks/medical.dm +++ b/code/game/objects/items/stacks/medical.dm @@ -96,6 +96,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 97b7ee8a38..82ae274012 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() @@ -712,6 +713,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 9dbbb35862..c5b48164a0 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 f32532537b..685a3b59f6 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() . = ..() @@ -277,6 +278,7 @@ ///The value in here has NOTHING to do with icons. It needs to be this for the proper examine. 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/firstaid.dm b/code/game/objects/items/storage/firstaid.dm index 01193d0e21..454807a8b8 100644 --- a/code/game/objects/items/storage/firstaid.dm +++ b/code/game/objects/items/storage/firstaid.dm @@ -422,6 +422,8 @@ throw_range = 7 var/empty = FALSE item_state = "firstaid" + custom_price = 300 + custom_premium_price = 500 /obj/item/storage/hypospraykit/ComponentInitialize() . = ..() diff --git a/code/game/objects/items/storage/wallets.dm b/code/game/objects/items/storage/wallets.dm index 3aa9911d97..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 = /obj/effect/spawner/lootdrop/space_cash/no_turf - var/item2_type - if(prob(50)) - item2_type = /obj/effect/spawner/lootdrop/space_cash/no_turf - var/item3_type = /obj/effect/spawner/lootdrop/coin/no_turf - - 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..57e9ea9aaa 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 = 1000 /obj/item/watertank/janitor/Initialize() . = ..() diff --git a/code/game/objects/items/weaponry.dm b/code/game/objects/items/weaponry.dm index 2d132e4eef..d34daf5c75 100644 --- a/code/game/objects/items/weaponry.dm +++ b/code/game/objects/items/weaponry.dm @@ -524,6 +524,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" @@ -531,6 +532,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 082c4bd723..86aff44e02 100644 --- a/code/game/objects/structures/ghost_role_spawners.dm +++ b/code/game/objects/structures/ghost_role_spawners.dm @@ -686,7 +686,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 0838c7b091..21eed2caf4 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 38042fe64d..9b7183092d 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/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..d1d895ca69 100644 --- a/code/modules/cargo/console.dm +++ b/code/modules/cargo/console.dm @@ -3,6 +3,7 @@ desc = "Used to order supplies, approve requests, and control the shuttle." icon_screen = "supply" circuit = /obj/item/circuitboard/computer/cargo + req_access = list(ACCESS_CARGO) ui_x = 780 ui_y = 750 @@ -25,6 +26,7 @@ desc = "Used to request supplies from cargo." icon_screen = "request" circuit = /obj/item/circuitboard/computer/cargo/request + req_access = list() requestonly = TRUE /obj/machinery/computer/cargo/Initialize() @@ -49,6 +51,7 @@ . |= EXPORT_EMAG /obj/machinery/computer/cargo/emag_act(mob/user) + . = ..() if(obj_flags & EMAGGED) return if(user) @@ -62,7 +65,9 @@ var/obj/item/circuitboard/computer/cargo/board = circuit board.contraband = TRUE board.obj_flags |= EMAGGED + req_access = list() update_static_data(user) + return ..() /obj/machinery/computer/cargo/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) @@ -74,9 +79,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 +100,7 @@ "cost" = SO.pack.cost, "id" = SO.id, "orderer" = SO.orderer, + "paid" = !isnull(SO.paying_account) //paid by requester )) data["requests"] = list() @@ -131,6 +140,9 @@ /obj/machinery/computer/cargo/ui_act(action, params, datum/tgui/ui) if(..()) return + if(!allowed(usr)) + to_chat(usr, "Access denied.") + return switch(action) if("send") if(!SSshuttle.supply.canMove()) @@ -182,19 +194,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"]) @@ -224,6 +250,9 @@ if("denyall") SSshuttle.requestlist.Cut() . = TRUE + if("toggleprivate") + self_paid = !self_paid + . = TRUE if(.) post_signal("supply") 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..9fe427c45a 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) @@ -127,6 +129,9 @@ return data /obj/machinery/computer/cargo/express/ui_act(action, params, datum/tgui/ui) + if(!allowed(usr)) + to_chat(usr, "Access denied.") + return switch(action) if("LZCargo") usingBeacon = FALSE @@ -137,13 +142,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 +169,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 +191,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 +206,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 13e223bca3..3d1caf6ba6 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]
" @@ -81,7 +88,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 7e9cc7d3eb..bb105f2652 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -918,7 +918,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) @@ -2319,6 +2324,9 @@ GLOBAL_LIST_EMPTY(preferences_datums) if("ghost_pda") chat_toggles ^= CHAT_GHOSTPDA + if("income_pings") + chat_toggles ^= CHAT_BANKCARD + if("pull_requests") chat_toggles ^= CHAT_PULLR diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm index 3fa36cc254..ca8599c4d5 100644 --- a/code/modules/client/preferences_savefile.dm +++ b/code/modules/client/preferences_savefile.dm @@ -290,7 +290,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car buttons_locked = sanitize_integer(buttons_locked, 0, 1, initial(buttons_locked)) windowflashing = sanitize_integer(windowflashing, 0, 1, initial(windowflashing)) default_slot = sanitize_integer(default_slot, 1, max_save_slots, initial(default_slot)) - toggles = sanitize_integer(toggles, 0, 65535, initial(toggles)) + toggles = sanitize_integer(toggles, 0, 16777215, initial(toggles)) clientfps = sanitize_integer(clientfps, 0, 1000, 0) parallax = sanitize_integer(parallax, PARALLAX_INSANE, PARALLAX_DISABLE, null) ambientocclusion = sanitize_integer(ambientocclusion, 0, 1, initial(ambientocclusion)) @@ -312,7 +312,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car damagescreenshake = sanitize_integer(damagescreenshake, 0, 2, initial(damagescreenshake)) widescreenpref = sanitize_integer(widescreenpref, 0, 1, initial(widescreenpref)) autostand = sanitize_integer(autostand, 0, 1, initial(autostand)) - cit_toggles = sanitize_integer(cit_toggles, 0, 65535, initial(cit_toggles)) + cit_toggles = sanitize_integer(cit_toggles, 0, 16777215, initial(cit_toggles)) auto_ooc = sanitize_integer(auto_ooc, 0, 1, initial(auto_ooc)) no_tetris_storage = sanitize_integer(no_tetris_storage, 0, 1, initial(no_tetris_storage)) diff --git a/code/modules/client/preferences_toggles.dm b/code/modules/client/preferences_toggles.dm index 8f7156863d..951e36f9a6 100644 --- a/code/modules/client/preferences_toggles.dm +++ b/code/modules/client/preferences_toggles.dm @@ -250,6 +250,27 @@ 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_looc)() + set name = "Show/Hide LOOC" + set category = "Preferences" + set desc = "Toggles seeing LocalOutOfCharacter chat" + usr.client.prefs.chat_toggles ^= CHAT_LOOC + usr.client.prefs.save_preferences() + to_chat(usr, "You will [(usr.client.prefs.chat_toggles & CHAT_LOOC) ? "now" : "no longer"] see messages on the LOOC channel.") + SSblackbox.record_feedback("nested tally", "preferences_verb", 1, list("Toggle Seeing LOOC", "[usr.client.prefs.chat_toggles & CHAT_LOOC ? "Enabled" : "Disabled"]")) +/datum/verbs/menu/Settings/listen_ooc/Get_checked(client/C) + return C.prefs.chat_toggles & CHAT_LOOC + +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 d537e2fb60..b1c6746351 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 25ef367b48..ae851ec4f1 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 7a057eda41..ff4ef28649 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/tackler/combat/insulated 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 46477097d0..9c6c81372a 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" @@ -382,6 +383,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 bbfab5fda7..21dcd37bc2 100644 --- a/code/modules/clothing/suits/armor.dm +++ b/code/modules/clothing/suits/armor.dm @@ -49,6 +49,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 997f10a379..cd58571251 100644 --- a/code/modules/clothing/under/miscellaneous.dm +++ b/code/modules/clothing/under/miscellaneous.dm @@ -87,6 +87,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 8aa1ee429c..46fc13d06e 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 mutantrace_variation = STYLE_DIGITIGRADE //how do they show up on taurs otherwise? /obj/item/clothing/under/pants/classicjeans @@ -14,6 +15,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 e1212cf337..0d04193e1f 100644 --- a/code/modules/clothing/under/skirt_dress.dm +++ b/code/modules/clothing/under/skirt_dress.dm @@ -17,6 +17,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" @@ -26,6 +27,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" @@ -35,6 +37,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" @@ -148,6 +151,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..e8b6498c36 --- /dev/null +++ b/code/modules/economy/account.dm @@ -0,0 +1,120 @@ +#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) + if(!SSeconomy) + log_world("Wack") + 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(!from.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 70b8e4873c..8a693b77d2 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() @@ -104,9 +107,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 @@ -142,12 +146,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 @@ -459,3 +458,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 ccce186304..9faf0918ab 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' @@ -409,6 +411,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' @@ -420,6 +423,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' @@ -431,6 +435,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' @@ -464,6 +469,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' @@ -474,6 +480,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 e10f009cec..8539ed071d 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. @@ -104,7 +107,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) @@ -242,12 +251,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 42c6afaed8..768aff0927 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 starting_skills = list(/datum/skill/level/job/wiring = GET_STANDARD_LVL(JOB_SKILL_BASIC)) skill_affinities = list(/datum/skill/level/job/wiring = STARTING_SKILL_AFFINITY_WIRING_ENGI_ROBO) 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 571785526b..a477ff3da3 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 bd4732f3c3..eee0c3437f 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 starting_skills = list(/datum/skill/level/job/wiring = GET_STANDARD_LVL(JOB_SKILL_TRAINED)) skill_affinities = list(/datum/skill/level/job/wiring = STARTING_SKILL_AFFINITY_WIRING_ENGI_ROBO) diff --git a/code/modules/jobs/job_types/chief_medical_officer.dm b/code/modules/jobs/job_types/chief_medical_officer.dm index 478c33551d..89bb4ed96b 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 440675c73c..47bfd4914a 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 4fb989f6e8..21ba9f0f9b 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 0e8b2e645b..bff83df973 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 e8098daddc..c253574268 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 d9e891f057..b4801ce6df 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 starting_skills = list(/datum/skill/level/job/wiring = GET_STANDARD_LVL(JOB_SKILL_TRAINED)) skill_affinities = list(/datum/skill/level/job/wiring = STARTING_SKILL_AFFINITY_WIRING_ENGI_ROBO) 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 c5280d72db..f5b8c7cd4e 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 starting_skills = list(/datum/skill/level/job/wiring = GET_STANDARD_LVL(JOB_SKILL_TRAINED)) skill_affinities = list(/datum/skill/level/job/wiring = STARTING_SKILL_AFFINITY_WIRING_ENGI_ROBO) diff --git a/code/modules/jobs/job_types/virologist.dm b/code/modules/jobs/job_types/virologist.dm index 78f0ba4272..37a21dd3ac 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/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/mining/ores_coins.dm b/code/modules/mining/ores_coins.dm index e85d4a2e75..b54b990c77 100644 --- a/code/modules/mining/ores_coins.dm +++ b/code/modules/mining/ores_coins.dm @@ -340,6 +340,9 @@ GLOBAL_LIST_INIT(sand_recipes, list(\ var/datum/material/M = i value += M.value_per_unit * custom_materials[M] +/obj/item/coin/get_item_credit_value() + return value + /obj/item/coin/suicide_act(mob/living/user) user.visible_message("[user] contemplates suicide with \the [src]!") if (!attack_self(user)) diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index 59766b03a4..e0eec0e599 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -68,4 +68,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 539c11de4b..bf693d70b6 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules.dm @@ -769,9 +769,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 f039dc32b2..705888a427 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 93fa7149bd..fd04ef0a1f 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -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 3d8e35935f..c8563c653f 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -487,6 +487,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" diff --git a/code/modules/power/singularity/collector.dm b/code/modules/power/singularity/collector.dm index 68a6b34216..651892e5b1 100644 --- a/code/modules/power/singularity/collector.dm +++ b/code/modules/power/singularity/collector.dm @@ -72,7 +72,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 368f476183..b4e954f147 100644 --- a/code/modules/reagents/reagent_containers/glass.dm +++ b/code/modules/reagents/reagent_containers/glass.dm @@ -361,6 +361,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 b24e6ab733..99a93e58dc 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 1a2742d2a6..4782a80c62 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 = 100 /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 06cdef5ecc..95e5a66099 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 ddf6edc9f9..ccfcecf66c 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/_techweb_node.dm b/code/modules/research/techweb/_techweb_node.dm index 33147aa717..6750fa5475 100644 --- a/code/modules/research/techweb/_techweb_node.dm +++ b/code/modules/research/techweb/_techweb_node.dm @@ -102,6 +102,6 @@ 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_shellclip", "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 840f100611..43e5523bad 100644 --- a/code/modules/uplink/uplink_items/uplink_badass.dm +++ b/code/modules/uplink/uplink_items/uplink_badass.dm @@ -51,6 +51,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 478be5960e..321b9121bc 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/bundles_TC/northstar_bundle name = "Northstar Bundle" diff --git a/code/modules/uplink/uplink_items/uplink_devices.dm b/code/modules/uplink/uplink_items/uplink_devices.dm index c5d95fdc4f..d4fa226a90 100644 --- a/code/modules/uplink/uplink_items/uplink_devices.dm +++ b/code/modules/uplink/uplink_items/uplink_devices.dm @@ -271,3 +271,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 5a96a92f07..06a3f6ae1d 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)! @@ -118,11 +123,13 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C var/extended_inventory ///Are we checking the users ID var/scan_id = TRUE - ///Coins that we accept? var/obj/item/coin/coin - ///Bills that 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 + ///cost multiplier per department or access + var/list/cost_multiplier_per_dept = list() /** * Is this item on station or not * @@ -144,7 +151,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 @@ -180,11 +187,18 @@ 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) - QDEL_NULL(coin) - QDEL_NULL(bill) return ..() /obj/machinery/vending/can_speak() @@ -284,6 +298,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 @@ -375,39 +390,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(bill) - to_chat(user, "[src] already has [bill] 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(istype(I, /obj/item/stack/spacecash)) - if(coin) - to_chat(user, "[src] already has [coin] inserted") - return - if(bill) - to_chat(user, "[src] already has [bill] inserted") - return - if(!premium.len) - to_chat(user, "[src] doesn't have a bill slot.") - return - if(!user.transferItemToLoc(I, src)) - return - var/obj/item/stack/S = I - S.use(1) - bill = new S.type(src, 1) - 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)) @@ -543,11 +526,13 @@ GLOBAL_LIST_EMPTY(vending_products) /obj/machinery/vending/ui_static_data(mob/user) . = list() + .["onstation"] = onstation .["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) ) @@ -557,6 +542,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 @@ -567,6 +553,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 @@ -575,12 +562,28 @@ GLOBAL_LIST_EMPTY(vending_products) /obj/machinery/vending/ui_data(mob/user) . = list() + var/obj/item/card/id/C = user.get_idcard(TRUE) + .["cost_mult"] = 1 + .["cost_text"] = "" + if(C && 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 + else + .["user"]["job"] = "No Job" + var/cost_mult = get_best_discount(C) + if(cost_mult != 1) + .["cost_mult"] = cost_mult + if(cost_mult < 1) + .["cost_text"] = " [(1 - cost_mult) * 100]% OFF" + else + .["cost_text"] = " [(cost_mult - 1) * 100]% EXTRA" .["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 - .["bill"] = bill /obj/machinery/vending/ui_act(action, params) . = ..() @@ -594,75 +597,71 @@ 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 - if(R.amount <= 0) - to_chat(usr, "Sold out.") - 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 || bill)) - to_chat(usr, "You need to insert a coin to get this item!") - vend_ready = TRUE - return - if(coin && coin.string_attached) - if(prob(50)) - if(usr.put_in_hands(coin)) - to_chat(usr, "You successfully pull [coin] out before [src] could swallow it.") - coin = null - else - to_chat(usr, "You couldn't pull [coin] out because your hands are full!") - QDEL_NULL(coin) - else - to_chat(usr, "You weren't able to pull [coin] out fast enough, the machine ate it, string and all!") - QDEL_NULL(coin) - else - QDEL_NULL(coin) - QDEL_NULL(bill) - 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(((last_reply + 200) <= world.time) && vend_reply) - speak(vend_reply) - last_reply = world.time + if (R.amount <= 0) + say("Sold out of [R.name].") + flick(icon_deny,src) + vend_ready = TRUE + return + if(onstation && price_to_use >= 0) + var/obj/item/card/id/C = usr.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(coin_records.Find(R) || hidden_records.Find(R)) + price_to_use = R.custom_premium_price ? R.custom_premium_price : extra_price + else + price_to_use = round(price_to_use * get_best_discount(C)) + 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!") - R.amount-- 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("takeoutbill") - usr.put_in_hands(bill) - to_chat(usr, "You remove [bill] from [src].") - bill = null - return - - if("togglevoice") - if(panel_open) - shut_up = !shut_up /obj/machinery/vending/process() if(stat & (BROKEN|NOPOWER)) @@ -697,6 +696,25 @@ GLOBAL_LIST_EMPTY(vending_products) say(message) +/** + * Gets the best discount from a given ID card, comparing its access and paycheck depart with cost_multiplier_per_dept. + * It only applies to the regular selection, not premium or contraband. And a bank account is still required. + * But it can also be used to charge more to certain departments or accesses. :) + * + * Arguments: + * * list/dept_access_list - the list to compare + */ +/obj/machinery/vending/proc/get_best_discount(obj/item/card/id/C) + var/list/discounts = NUMLIST2TEXTLIST(C.GetAccess()) + if(C.registered_account?.account_job) + discounts += C.registered_account.account_job.paycheck_department + discounts &= cost_multiplier_per_dept + if(!length(discounts)) + return 1 + . = INFINITY + for(var/k in discounts) + . = min(cost_multiplier_per_dept[k], .) + /obj/machinery/vending/power_change() . = ..() if(powered()) @@ -774,3 +792,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..25dbee66bc 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 = 50 + 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..216b95145d 100644 --- a/code/modules/vending/autodrobe.dm +++ b/code/modules/vending/autodrobe.dm @@ -3,7 +3,6 @@ desc = "A vending machine for costumes." icon_state = "theater" icon_deny = "theater-deny" - req_access = list(ACCESS_THEATRE) product_slogans = "Dress for success!;Suited and booted!;It's show time!;Why leave style up to fate? Use AutoDrobe!" vend_reply = "Thank you for using AutoDrobe!" products = list(/obj/item/clothing/suit/chickensuit = 1, @@ -124,7 +123,7 @@ /obj/item/clothing/shoes/roman = 1, /obj/item/shield/riot/roman/fake = 1, /obj/item/skub = 1, - /obj/item/clothing/under/costume/lobster = 1, // CIT CHANGES + /obj/item/clothing/under/costume/lobster = 1, /obj/item/clothing/head/lobsterhat = 1, /obj/item/clothing/head/drfreezehat = 1, /obj/item/clothing/suit/dracula = 1, @@ -137,12 +136,19 @@ /obj/item/clothing/under/costume/christmas/croptop/green = 3, /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 + /obj/item/clothing/under/costume/drfreeze = 1) -/obj/machinery/vending/autodrobe/all_access - desc = "A vending machine for costumes. This model appears to have no access restrictions." - req_access = null + refill_canister = /obj/item/vending_refill/autodrobe + default_price = 180 + extra_price = 360 + payment_department = ACCOUNT_SRV + +/obj/machinery/vending/autodrobe/Initialize() + . = ..() + cost_multiplier_per_dept = list("[ACCESS_THEATRE]" = 0) + +/obj/machinery/vending/autodrobe/canLoadItem(obj/item/I,mob/user) + return (I.type in products) /obj/item/vending_refill/autodrobe machine_name = "AutoDrobe" diff --git a/code/modules/vending/boozeomat.dm b/code/modules/vending/boozeomat.dm index 5a6380c322..e24813c2e9 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, @@ -39,12 +39,11 @@ /obj/item/reagent_containers/food/drinks/bottle/trappist = 5) product_slogans = "I hope nobody asks me for a bloody cup o' tea...;Alcohol is humanity's friend. Would you abandon a friend?;Quite delighted to serve you!;Is nobody thirsty on this station?" 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 - -/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." - req_access = null + default_price = 120 + extra_price = 100 + payment_department = ACCOUNT_SRV + cost_multiplier_per_dept = list(ACCOUNT_SRV = 0) /obj/machinery/vending/boozeomat/pubby_maint //abandoned bar on Pubbystation products = list(/obj/item/reagent_containers/food/drinks/bottle/whiskey = 1, @@ -56,7 +55,6 @@ /obj/item/reagent_containers/food/drinks/ice = 3, /obj/item/reagent_containers/food/drinks/drinkingglass/shotglass = 6, /obj/item/reagent_containers/food/drinks/flask = 1) - req_access = null /obj/machinery/vending/boozeomat/pubby_captain //Captain's quarters on Pubbystation products = list(/obj/item/reagent_containers/food/drinks/bottle/rum = 1, @@ -65,10 +63,17 @@ /obj/item/reagent_containers/food/drinks/drinkingglass = 6, /obj/item/reagent_containers/food/drinks/ice = 1, /obj/item/reagent_containers/food/drinks/drinkingglass/shotglass = 4); - req_access = list(ACCESS_CAPTAIN) + +/obj/machinery/vending/boozeomat/pubby_captain/Initialize() + . = ..() + cost_multiplier_per_dept = list("[ACCESS_CAPTAIN]" = 0) /obj/machinery/vending/boozeomat/syndicate_access - req_access = list(ACCESS_SYNDICATE) + payment_department = NO_FREEBIES + +/obj/machinery/vending/boozeomat/syndicate_access/Initialize() + . = ..() + cost_multiplier_per_dept = list("[ACCESS_SYNDICATE]" = 0) /obj/item/vending_refill/boozeomat machine_name = "Booze-O-Mat" diff --git a/code/modules/vending/cartridge.dm b/code/modules/vending/cartridge.dm index 35b1a1da7a..79380ca1f3 100644 --- a/code/modules/vending/cartridge.dm +++ b/code/modules/vending/cartridge.dm @@ -16,6 +16,10 @@ 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 + cost_multiplier_per_dept = list(ACCOUNT_SRV = 0) /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..6f535b2c6d 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, @@ -30,6 +33,11 @@ /obj/item/storage/box/matches = 10, /obj/item/lighter/greyscale = 4, /obj/item/storage/fancy/rollingpapers = 5) + payment_department = NO_FREEBIES + +/obj/machinery/vending/cigarette/syndicate/Initialize() + . = ..() + cost_multiplier_per_dept = list("[ACCESS_SYNDICATE]" = 0) /obj/machinery/vending/cigarette/beach //Used in the lavaland_biodome_beach.dmm ruin name = "\improper ShadyCigs Ultra" 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/dinnerware.dm b/code/modules/vending/dinnerware.dm index da8baa7e1c..e780104b1e 100644 --- a/code/modules/vending/dinnerware.dm +++ b/code/modules/vending/dinnerware.dm @@ -29,6 +29,10 @@ 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 + cost_multiplier_per_dept = list(ACCOUNT_SRV = 0) /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..36bacd4259 100644 --- a/code/modules/vending/engineering.dm +++ b/code/modules/vending/engineering.dm @@ -4,7 +4,6 @@ desc = "Everything you need for do-it-yourself station repair." icon_state = "engi" icon_deny = "engi-deny" - req_access = list(ACCESS_ENGINE_EQUIP) products = list(/obj/item/clothing/under/rank/engineering/chief_engineer = 4, /obj/item/clothing/under/rank/engineering/engineer = 4, /obj/item/clothing/shoes/sneakers/orange = 4, @@ -29,3 +28,7 @@ /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 + cost_multiplier_per_dept = list(ACCOUNT_ENG = 0) diff --git a/code/modules/vending/engivend.dm b/code/modules/vending/engivend.dm index 15da7cab15..ca45483ff5 100644 --- a/code/modules/vending/engivend.dm +++ b/code/modules/vending/engivend.dm @@ -3,7 +3,6 @@ desc = "Spare tool vending. What? Did you expect some witty description?" icon_state = "engivend" icon_deny = "engivend-deny" - req_access = list(ACCESS_ENGINE_EQUIP) products = list(/obj/item/clothing/glasses/meson/engine = 5, /obj/item/clothing/glasses/welding = 5, /obj/item/multitool = 5, @@ -30,6 +29,10 @@ 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 + cost_multiplier_per_dept = list(ACCOUNT_ENG = 0) /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..efd9aad673 100644 --- a/code/modules/vending/games.dm +++ b/code/modules/vending/games.dm @@ -11,6 +11,10 @@ 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 + cost_multiplier_per_dept = list(ACCOUNT_SRV = 0) /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..8ed4cd85ae 100644 --- a/code/modules/vending/liberation_toy.dm +++ b/code/modules/vending/liberation_toy.dm @@ -25,3 +25,10 @@ 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 = NO_FREEBIES + +/obj/machinery/vending/toyliberationstation/Initialize() + . = ..() + cost_multiplier_per_dept = list("[ACCESS_SYNDICATE]" = 0) 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..797fdabce7 100644 --- a/code/modules/vending/medical.dm +++ b/code/modules/vending/medical.dm @@ -4,7 +4,6 @@ icon_state = "med" icon_deny = "med-deny" product_ads = "Go save some lives!;The best stuff for your medbay.;Only the finest tools.;Natural chemicals!;This stuff saves lives.;Don't you want some?;Ping!" - req_access = list(ACCESS_MEDICAL) products = list(/obj/item/reagent_containers/syringe = 12, /obj/item/reagent_containers/dropper = 3, /obj/item/healthanalyzer = 4, @@ -47,6 +46,10 @@ 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 = 200 + extra_price = 250 + payment_department = ACCOUNT_MED + cost_multiplier_per_dept = list(ACCOUNT_MED = 0) /obj/item/vending_refill/medical machine_name = "NanoMed Plus" @@ -54,4 +57,8 @@ /obj/machinery/vending/medical/syndicate_access name = "\improper SyndiMed Plus" - req_access = list(ACCESS_SYNDICATE) + payment_department = NO_FREEBIES + +/obj/machinery/vending/medical/syndicate_access/Initialize() + . = ..() + cost_multiplier_per_dept = list("[ACCESS_SYNDICATE]" = 0) diff --git a/code/modules/vending/medical_wall.dm b/code/modules/vending/medical_wall.dm index a048d253c5..b51705c7e1 100644 --- a/code/modules/vending/medical_wall.dm +++ b/code/modules/vending/medical_wall.dm @@ -18,6 +18,10 @@ 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 = 0 + extra_price = 100 + payment_department = ACCOUNT_MED + cost_multiplier_per_dept = list(ACCOUNT_MED = 0) /obj/item/vending_refill/wallmed machine_name = "NanoMed" diff --git a/code/modules/vending/megaseed.dm b/code/modules/vending/megaseed.dm index 37ce00069c..f8759bd8f4 100644 --- a/code/modules/vending/megaseed.dm +++ b/code/modules/vending/megaseed.dm @@ -57,6 +57,10 @@ 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 + cost_multiplier_per_dept = list(ACCOUNT_SRV = 0) /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..95ba4e23e8 100644 --- a/code/modules/vending/nutrimax.dm +++ b/code/modules/vending/nutrimax.dm @@ -19,6 +19,10 @@ 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 + cost_multiplier_per_dept = list(ACCOUNT_SRV = 0) /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..410154fa20 100644 --- a/code/modules/vending/plasmaresearch.dm +++ b/code/modules/vending/plasmaresearch.dm @@ -11,3 +11,7 @@ /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 + cost_multiplier_per_dept = list(ACCOUNT_SCI = 0) diff --git a/code/modules/vending/robotics.dm b/code/modules/vending/robotics.dm index 852b7d65f0..3ad7134498 100644 --- a/code/modules/vending/robotics.dm +++ b/code/modules/vending/robotics.dm @@ -4,7 +4,6 @@ desc = "All the tools you need to create your own robot army." icon_state = "robotics" icon_deny = "robotics-deny" - req_access = list(ACCESS_ROBOTICS) products = list(/obj/item/clothing/suit/toggle/labcoat = 4, /obj/item/clothing/under/rank/rnd/roboticist = 4, /obj/item/stack/cable_coil = 4, @@ -21,3 +20,6 @@ /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 + cost_multiplier_per_dept = list(ACCOUNT_SCI = 0) diff --git a/code/modules/vending/security.dm b/code/modules/vending/security.dm index b1a6297981..284e957864 100644 --- a/code/modules/vending/security.dm +++ b/code/modules/vending/security.dm @@ -4,7 +4,6 @@ product_ads = "Crack capitalist skulls!;Beat some heads in!;Don't forget - harm is good!;Your weapons are right here.;Handcuffs!;Freeze, scumbag!;Don't tase me bro!;Tase them, bro.;Why not have a donut?" icon_state = "sec" icon_deny = "sec-deny" - req_access = list(ACCESS_SECURITY) products = list(/obj/item/restraints/handcuffs = 8, /obj/item/restraints/handcuffs/cable/zipties = 10, /obj/item/grenade/flashbang = 4, @@ -26,6 +25,10 @@ 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 + cost_multiplier_per_dept = list(ACCOUNT_SEC = 0) /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..e051d6135b 100644 --- a/code/modules/vending/snack.dm +++ b/code/modules/vending/snack.dm @@ -26,77 +26,16 @@ /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 + cost_multiplier_per_dept = list(ACCOUNT_SRV = 0) + 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..b2a8b59403 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,8 @@ 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 + cost_multiplier_per_dept = list(ACCOUNT_SEC = 0) /obj/item/vending_refill/wardrobe/sec_wardrobe machine_name = "SecDrobe" @@ -57,6 +68,8 @@ /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 + cost_multiplier_per_dept = list(ACCOUNT_MED = 0) /obj/item/vending_refill/wardrobe/medi_wardrobe machine_name = "MediDrobe" @@ -80,6 +93,8 @@ /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 + cost_multiplier_per_dept = list(ACCOUNT_ENG = 0) /obj/item/vending_refill/wardrobe/engi_wardrobe machine_name = "EngiDrobe" @@ -101,6 +116,8 @@ /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 + cost_multiplier_per_dept = list(ACCOUNT_ENG = 0) /obj/item/vending_refill/wardrobe/atmos_wardrobe machine_name = "AtmosDrobe" @@ -119,6 +136,8 @@ /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 + cost_multiplier_per_dept = list(ACCOUNT_CAR = 0) /obj/item/vending_refill/wardrobe/cargo_wardrobe machine_name = "CargoDrobe" @@ -141,6 +160,8 @@ /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 + cost_multiplier_per_dept = list(ACCOUNT_SCI = 0) /obj/item/vending_refill/wardrobe/robo_wardrobe machine_name = "RoboDrobe" @@ -163,6 +184,8 @@ /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 + cost_multiplier_per_dept = list(ACCOUNT_SCI = 0) /obj/item/vending_refill/wardrobe/science_wardrobe machine_name = "SciDrobe" @@ -182,6 +205,8 @@ /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 + cost_multiplier_per_dept = list(ACCOUNT_SRV = 0) /obj/item/vending_refill/wardrobe/hydro_wardrobe machine_name = "HyDrobe" @@ -206,6 +231,8 @@ /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 + cost_multiplier_per_dept = list(ACCOUNT_CIV = 0) /obj/item/vending_refill/wardrobe/curator_wardrobe machine_name = "CuraDrobe" @@ -234,6 +261,8 @@ /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 + cost_multiplier_per_dept = list(ACCOUNT_SRV = 0) /obj/item/vending_refill/wardrobe/bar_wardrobe machine_name = "BarDrobe" @@ -259,6 +288,8 @@ /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 + cost_multiplier_per_dept = list(ACCOUNT_SRV = 0) /obj/item/vending_refill/wardrobe/chef_wardrobe machine_name = "ChefDrobe" @@ -290,6 +321,8 @@ /obj/item/screwdriver = 2, /obj/item/stack/cable_coil/random = 4) refill_canister = /obj/item/vending_refill/wardrobe/jani_wardrobe + payment_department = ACCOUNT_SRV + cost_multiplier_per_dept = list(ACCOUNT_SRV = 0) /obj/item/vending_refill/wardrobe/jani_wardrobe machine_name = "JaniDrobe" @@ -321,6 +354,8 @@ /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 + cost_multiplier_per_dept = list(ACCOUNT_CIV = 0) /obj/item/vending_refill/wardrobe/law_wardrobe machine_name = "LawDrobe" @@ -347,6 +382,8 @@ premium = list(/obj/item/toy/plush/plushvar = 1, /obj/item/toy/plush/narplush = 1) refill_canister = /obj/item/vending_refill/wardrobe/chap_wardrobe + payment_department = ACCOUNT_CIV + cost_multiplier_per_dept = list(ACCOUNT_CIV = 0) /obj/item/vending_refill/wardrobe/chap_wardrobe machine_name = "ChapDrobe" @@ -368,6 +405,8 @@ /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 + cost_multiplier_per_dept = list(ACCOUNT_MED = 0) /obj/item/vending_refill/wardrobe/chem_wardrobe machine_name = "ChemDrobe" @@ -386,6 +425,8 @@ /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 + cost_multiplier_per_dept = list(ACCOUNT_MED = 0) /obj/item/vending_refill/wardrobe/gene_wardrobe machine_name = "GeneDrobe" @@ -406,6 +447,8 @@ /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 + cost_multiplier_per_dept = list(ACCOUNT_MED = 0) /obj/item/vending_refill/wardrobe/viro_wardrobe machine_name = "ViroDrobe" @@ -416,7 +459,6 @@ icon_state = "capsdrobe" icon_deny = "capsdrobe-deny" product_ads = "Only the greatest for a commander such as ours." - req_access = list(ACCESS_CAPTAIN) vend_reply = "A wonderful day to you, great leader." products = list(/obj/item/clothing/suit/hooded/wintercoat/captain = 1, /obj/item/storage/backpack/captain = 1, @@ -436,6 +478,11 @@ /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/machinery/vending/wardrobe/cap_wardrobe/Initialize() + . = ..() + cost_multiplier_per_dept = list("[ACCESS_CAPTAIN]" = 0) /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..6b38ec0b9d 100644 --- a/code/modules/vending/youtool.dm +++ b/code/modules/vending/youtool.dm @@ -15,12 +15,17 @@ /obj/item/flashlight/glowstick/red = 6, /obj/item/flashlight = 7) contraband = list(/obj/item/weldingtool/largetank = 4, - /obj/item/clothing/gloves/color/fyellow = 4) + /obj/item/clothing/gloves/color/fyellow = 4, + /obj/item/multitool = 2) premium = list(/obj/item/clothing/gloves/color/yellow = 2, /obj/item/weldingtool/hugetank = 2) 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 = 50 + extra_price = 300 + payment_department = ACCOUNT_ENG + cost_multiplier_per_dept = list(ACCOUNT_ENG = 0) /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 d81653b840..2d326493bb 100644 --- a/config/game_options.txt +++ b/config/game_options.txt @@ -603,6 +603,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/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 58c1cd921c..2cc3b784f4 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 c843afca5f..58083f5f6d 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 cd0a44eba6..9f567a50c5 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -44,6 +44,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" @@ -269,6 +270,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" @@ -929,7 +931,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" @@ -1838,6 +1842,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 85f6796230..5e84f26a75 100644 --- a/tgui-next/packages/tgui/interfaces/Vending.js +++ b/tgui-next/packages/tgui/interfaces/Vending.js @@ -9,47 +9,45 @@ export const Vending = props => { const { ref } = config; let inventory; let custom = false; - const onstation = true; - if (data.extended_inventory && (data.coin || data.bill)) { - 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 || data.bill) { inventory = [ ...data.product_records, ...data.coin_records, + ...data.hidden_records, ]; } else { inventory = [ ...data.product_records, + ...data.coin_records, ]; } return ( - {data.coin && ( -
-
- )} - {data.bill && ( -
-