diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1.dmm index b22c9787ba..dab9d0316b 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1.dmm @@ -61,8 +61,7 @@ }, /obj/structure/sign/barsign{ pixel_y = -32; - req_access = null; - req_access_txt = "0" + req_access = null }, /turf/open/floor/wood, /area/ruin/unpowered/syndicate_lava_base/bar) @@ -212,7 +211,6 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, /obj/machinery/computer/arcade/orion_trail{ - icon_state = "arcade"; dir = 1 }, /turf/open/floor/plasteel/dark, @@ -270,7 +268,6 @@ dir = 4 }, /obj/machinery/firealarm{ - dir = 2; pixel_y = 24 }, /obj/machinery/light/small{ @@ -1501,7 +1498,6 @@ /area/ruin/unpowered/syndicate_lava_base/virology) "fk" = ( /obj/machinery/power/apc/syndicate{ - dir = 2; name = "Experimentation Lab APC"; pixel_y = -24 }, @@ -1565,15 +1561,10 @@ /obj/machinery/door/firedoor, /obj/structure/table/reinforced, /obj/machinery/door/window/southleft{ - base_state = "left"; - dir = 2; - icon_state = "left"; name = "Chemistry" }, /obj/machinery/door/window/southleft{ - base_state = "left"; dir = 1; - icon_state = "left"; name = "Chemistry"; req_access_txt = "150" }, @@ -1968,9 +1959,7 @@ /area/ruin/unpowered/syndicate_lava_base/virology) "gs" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden/layer3{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden/layer3, /obj/machinery/light/small, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel/white, @@ -2153,9 +2142,7 @@ icon_state = "4-8" }, /obj/machinery/atmospherics/pipe/manifold/supply/hidden, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden/layer3{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden/layer3, /obj/structure/cable/yellow{ icon_state = "1-8" }, @@ -2864,7 +2851,6 @@ /area/ruin/unpowered/syndicate_lava_base/main) "ib" = ( /obj/effect/mob_spawn/human/lavaland_syndicate{ - icon_state = "sleeper_s"; dir = 4 }, /turf/open/floor/plasteel/grimy, @@ -2904,8 +2890,7 @@ /area/ruin/unpowered/syndicate_lava_base/dormitories) "ie" = ( /obj/effect/mob_spawn/human/lavaland_syndicate/comms{ - dir = 8; - icon_state = "sleeper_s" + dir = 8 }, /turf/open/floor/plasteel/grimy, /area/ruin/unpowered/syndicate_lava_base/dormitories) @@ -3029,10 +3014,10 @@ dir = 1 }, /obj/machinery/turretid{ + ailock = 1; control_area = "/area/ruin/unpowered/syndicate_lava_base/main"; dir = 1; icon_state = "control_kill"; - ailock = 1; lethal = 1; name = "Base turret controls"; pixel_y = 30; @@ -3149,7 +3134,6 @@ dir = 1 }, /obj/machinery/firealarm{ - dir = 2; pixel_y = 24 }, /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer3, @@ -3321,9 +3305,7 @@ "iT" = ( /obj/machinery/light/small, /obj/machinery/atmospherics/pipe/manifold/supply/hidden, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden/layer3{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden/layer3, /obj/structure/cable/yellow{ icon_state = "4-8" }, @@ -3356,7 +3338,6 @@ dir = 4 }, /obj/machinery/power/apc/syndicate{ - dir = 2; name = "Dormitories APC"; pixel_y = -24 }, @@ -3565,7 +3546,6 @@ /area/ruin/unpowered/syndicate_lava_base/main) "jn" = ( /obj/effect/mob_spawn/human/lavaland_syndicate{ - icon_state = "sleeper_s"; dir = 4 }, /obj/machinery/airalarm/syndicate{ @@ -3591,8 +3571,7 @@ /area/ruin/unpowered/syndicate_lava_base/main) "jq" = ( /obj/effect/mob_spawn/human/lavaland_syndicate{ - dir = 8; - icon_state = "sleeper_s" + dir = 8 }, /obj/machinery/airalarm/syndicate{ pixel_y = 24 @@ -3986,9 +3965,7 @@ /area/ruin/unpowered/syndicate_lava_base/main) "kd" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden/layer3{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden/layer3, /obj/structure/cable/yellow{ icon_state = "1-4" }, @@ -4059,9 +4036,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 9 }, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden/layer3{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden/layer3, /turf/open/floor/plasteel, /area/ruin/unpowered/syndicate_lava_base/main) "kj" = ( @@ -4247,8 +4222,10 @@ icon_state = "4-8" }, /obj/machinery/atmospherics/pipe/simple/supply/visible, -/obj/machinery/atmospherics/pipe/manifold4w/scrubbers/visible/layer3, /obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/visible/layer3{ + dir = 4 + }, /turf/open/floor/plasteel, /area/ruin/unpowered/syndicate_lava_base/engineering) "kA" = ( @@ -4266,11 +4243,9 @@ /obj/structure/cable/yellow{ icon_state = "0-8" }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible/layer3{ - dir = 9 - }, /obj/machinery/atmospherics/components/unary/vent_pump/on, /obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible/layer3, /turf/open/floor/plasteel, /area/ruin/unpowered/syndicate_lava_base/engineering) "kB" = ( @@ -4285,6 +4260,7 @@ /obj/machinery/computer/atmos_control/tank{ dir = 8; frequency = 1442; + input_tag = "syndie_lavaland_n2_in"; name = "Nitrogen Supply Control"; output_tag = "syndie_lavaland_n2_out"; sensors = list("syndie_lavaland_n2_sensor" = "Tank") @@ -4477,12 +4453,19 @@ /obj/machinery/atmospherics/pipe/simple/supply/visible{ dir = 5 }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible/layer3, /obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/components/trinary/filter/atmos/flipped/n2{ + dir = 1; + piping_layer = 3 + }, /turf/open/floor/plasteel, /area/ruin/unpowered/syndicate_lava_base/engineering) "kY" = ( /obj/machinery/atmospherics/pipe/manifold4w/supply/visible, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible/layer3, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible/layer3{ + dir = 8 + }, /turf/open/floor/plasteel, /area/ruin/unpowered/syndicate_lava_base/engineering) "kZ" = ( @@ -4490,6 +4473,9 @@ dir = 4 }, /obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible/layer3{ + dir = 8 + }, /turf/open/floor/plasteel, /area/ruin/unpowered/syndicate_lava_base/engineering) "la" = ( @@ -4503,6 +4489,9 @@ /obj/effect/turf_decal/tile/red{ dir = 4 }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible/layer3{ + dir = 4 + }, /turf/open/floor/plasteel, /area/ruin/unpowered/syndicate_lava_base/engineering) "lb" = ( @@ -4511,6 +4500,9 @@ /obj/machinery/atmospherics/pipe/simple/supplymain/visible{ dir = 4 }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ + dir = 10 + }, /turf/open/floor/plating, /area/ruin/unpowered/syndicate_lava_base/engineering) "lc" = ( @@ -4523,6 +4515,11 @@ /turf/open/floor/plating/airless, /area/ruin/unpowered/syndicate_lava_base/engineering) "ld" = ( +/obj/machinery/atmospherics/components/unary/outlet_injector/layer3{ + dir = 4; + id = "syndie_lavaland_n2_in"; + piping_layer = 3 + }, /turf/open/floor/plating/airless, /area/ruin/unpowered/syndicate_lava_base/engineering) "le" = ( @@ -4676,15 +4673,24 @@ /turf/open/floor/plating, /area/ruin/unpowered/syndicate_lava_base/engineering) "lr" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible/layer3, -/turf/open/floor/plasteel, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ + dir = 10 + }, +/turf/closed/wall/mineral/plastitanium/nodiagonal, /area/ruin/unpowered/syndicate_lava_base/engineering) "ls" = ( /obj/machinery/atmospherics/pipe/simple/supply/visible, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible/layer3, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible/layer3{ + dir = 8 + }, /turf/open/floor/plasteel, /area/ruin/unpowered/syndicate_lava_base/engineering) "lt" = ( /obj/machinery/atmospherics/pipe/simple/supplymain/visible, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible/layer3{ + dir = 4 + }, /turf/open/floor/plasteel, /area/ruin/unpowered/syndicate_lava_base/engineering) "lu" = ( @@ -4694,6 +4700,9 @@ /obj/machinery/portable_atmospherics/scrubber, /obj/effect/turf_decal/bot, /obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible/layer3{ + dir = 10 + }, /turf/open/floor/plasteel, /area/ruin/unpowered/syndicate_lava_base/engineering) "lv" = ( @@ -4848,29 +4857,33 @@ /turf/open/floor/plasteel, /area/ruin/unpowered/syndicate_lava_base/engineering) "lM" = ( -/obj/structure/cable{ - icon_state = "1-2" +/obj/machinery/atmospherics/components/unary/outlet_injector/layer3{ + id = "syndie_lavaland_tox_in"; + piping_layer = 3 }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer3{ - dir = 4 - }, -/turf/open/floor/plasteel, +/turf/open/floor/plating/airless, /area/ruin/unpowered/syndicate_lava_base/engineering) "lN" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible/layer3{ - dir = 9 +/obj/machinery/atmospherics/components/trinary/filter/atmos/flipped/o2{ + dir = 1; + piping_layer = 3 }, /turf/open/floor/plasteel, /area/ruin/unpowered/syndicate_lava_base/engineering) "lO" = ( /obj/machinery/atmospherics/pipe/simple/supply/visible, /obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible/layer3, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible/layer3{ + dir = 8 + }, /turf/open/floor/plasteel, /area/ruin/unpowered/syndicate_lava_base/engineering) "lP" = ( /obj/machinery/computer/atmos_control/tank{ dir = 8; frequency = 1442; + input_tag = "syndie_lavaland_o2_in"; name = "Oxygen Supply Control"; output_tag = "syndie_lavaland_o2_out"; sensors = list("syndie_lavaland_o2_sensor" = "Tank") @@ -4879,12 +4892,15 @@ /obj/effect/turf_decal/tile/blue{ dir = 4 }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible/layer3{ + dir = 5 + }, /turf/open/floor/plasteel, /area/ruin/unpowered/syndicate_lava_base/engineering) "lQ" = ( /obj/machinery/air_sensor{ frequency = 1442; - id_tag = "Syndicate_Construction_o2_sensor" + id_tag = "syndie_lavaland_o2_sensor" }, /turf/open/floor/plating/airless, /area/ruin/unpowered/syndicate_lava_base/engineering) @@ -5083,6 +5099,9 @@ dir = 6 }, /obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible/layer3{ + dir = 5 + }, /turf/open/floor/plasteel, /area/ruin/unpowered/syndicate_lava_base/engineering) "mj" = ( @@ -5093,11 +5112,15 @@ }, /obj/machinery/atmospherics/pipe/simple/supply/visible, /obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible/layer3{ + dir = 9 + }, /turf/open/floor/plasteel, /area/ruin/unpowered/syndicate_lava_base/engineering) "mk" = ( /obj/machinery/atmospherics/pipe/manifold/supplymain/visible, /obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible/layer3, /turf/open/floor/plasteel, /area/ruin/unpowered/syndicate_lava_base/engineering) "ml" = ( @@ -5170,7 +5193,6 @@ /obj/machinery/light/small, /obj/structure/cable/yellow, /obj/machinery/power/apc/syndicate{ - dir = 2; name = "Bar APC"; pixel_y = -24 }, @@ -5297,6 +5319,9 @@ /obj/structure/reagent_dispensers/watertank, /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible/layer3{ + dir = 5 + }, /turf/open/floor/plasteel, /area/ruin/unpowered/syndicate_lava_base/engineering) "mK" = ( @@ -5304,12 +5329,16 @@ /obj/machinery/computer/atmos_control/tank{ dir = 1; frequency = 1442; + input_tag = "syndie_lavaland_tox_in"; name = "Toxins Supply Control"; output_tag = "syndie_lavaland_tox_out"; sensors = list("syndie_lavaland_tox_sensor" = "Tank") }, /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible/layer3{ + dir = 4 + }, /turf/open/floor/plasteel, /area/ruin/unpowered/syndicate_lava_base/engineering) "mM" = ( @@ -5700,9 +5729,7 @@ /area/ruin/unpowered/syndicate_lava_base/arrivals) "nw" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden/layer3{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden/layer3, /obj/structure/cable/yellow{ icon_state = "1-4" }, @@ -5998,7 +6025,6 @@ dir = 4 }, /obj/machinery/firealarm{ - dir = 2; pixel_y = 24 }, /obj/structure/cable/yellow{ @@ -6212,7 +6238,6 @@ }, /obj/structure/cable/yellow, /obj/machinery/power/apc/syndicate{ - dir = 2; name = "Telecommunications APC"; pixel_y = -24 }, @@ -6391,7 +6416,6 @@ "oG" = ( /obj/structure/cable, /obj/machinery/power/turbine{ - dir = 2; luminosity = 2 }, /turf/open/floor/engine/vacuum, @@ -6413,6 +6437,21 @@ /obj/structure/sign/departments/chemistry, /turf/closed/wall/mineral/plastitanium/nodiagonal, /area/ruin/unpowered/syndicate_lava_base/testlab) +"pC" = ( +/obj/structure/grille, +/obj/structure/window/plastitanium, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ + dir = 10 + }, +/turf/open/floor/plating, +/area/ruin/unpowered/syndicate_lava_base/engineering) +"qc" = ( +/obj/machinery/atmospherics/pipe/simple/supplymain/visible, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible/layer3{ + dir = 10 + }, +/turf/open/floor/plasteel, +/area/ruin/unpowered/syndicate_lava_base/engineering) "tW" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/closed/wall/mineral/plastitanium/nodiagonal, @@ -6466,12 +6505,29 @@ /obj/effect/mapping_helpers/airlock/cyclelink_helper, /turf/open/floor/plating, /area/ruin/unpowered/syndicate_lava_base/arrivals) +"Gm" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, +/turf/closed/wall/mineral/plastitanium/nodiagonal, +/area/ruin/unpowered/syndicate_lava_base/engineering) +"Go" = ( +/obj/machinery/atmospherics/components/trinary/filter/atmos/flipped/plasma{ + dir = 1; + piping_layer = 3 + }, +/turf/open/floor/plasteel, +/area/ruin/unpowered/syndicate_lava_base/engineering) "IJ" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ dir = 1 }, /turf/closed/wall/mineral/plastitanium/nodiagonal, /area/ruin/unpowered/syndicate_lava_base/engineering) +"KA" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ + dir = 4 + }, +/turf/closed/wall/mineral/plastitanium/nodiagonal, +/area/ruin/unpowered/syndicate_lava_base/engineering) "Lg" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer3{ dir = 4 @@ -6487,6 +6543,12 @@ /obj/effect/decal/cleanable/dirt, /turf/closed/wall/mineral/plastitanium/nodiagonal, /area/ruin/unpowered/syndicate_lava_base/circuits) +"Ng" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ + dir = 9 + }, +/turf/closed/wall/mineral/plastitanium/nodiagonal, +/area/ruin/unpowered/syndicate_lava_base/engineering) "Pa" = ( /turf/closed/wall/mineral/plastitanium/nodiagonal, /area/ruin/unpowered/syndicate_lava_base/circuits) @@ -6520,6 +6582,14 @@ }, /turf/open/floor/engine, /area/ruin/unpowered/syndicate_lava_base/testlab) +"Tt" = ( +/obj/machinery/atmospherics/components/unary/outlet_injector/layer3{ + dir = 4; + id = "syndie_lavaland_o2_in"; + piping_layer = 3 + }, +/turf/open/floor/plating/airless, +/area/ruin/unpowered/syndicate_lava_base/engineering) "TC" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden/layer3{ dir = 4 @@ -6529,6 +6599,24 @@ }, /turf/open/floor/engine, /area/ruin/unpowered/syndicate_lava_base/testlab) +"Vw" = ( +/obj/structure/grille, +/obj/structure/window/plastitanium, +/obj/machinery/atmospherics/pipe/simple/supplymain/visible{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, +/turf/open/floor/plating, +/area/ruin/unpowered/syndicate_lava_base/engineering) +"Wq" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ + dir = 5 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ + dir = 10 + }, +/turf/closed/wall/mineral/plastitanium/nodiagonal, +/area/ruin/unpowered/syndicate_lava_base/engineering) (1,1,1) = {" aa @@ -8363,7 +8451,7 @@ ju ky kW lq -lM +mh mh mG nd @@ -8412,8 +8500,8 @@ jW kk kz kX -lr lN +Go mi mH ne @@ -8513,13 +8601,13 @@ km kB kZ lt -lt +qc mk mJ ng nF -ld -ju +lM +uB ab ab ab @@ -8569,7 +8657,7 @@ mK kD nG og -ju +KA ab ab ab @@ -8612,14 +8700,14 @@ ab ju kD lb -ju -kD -lb -ju -ju -ju -ju -ju +uB +pC +Vw +Wq +Gm +Gm +Gm +Ng ab ab ab @@ -8662,10 +8750,10 @@ ab ju kE lc -ju +KA lQ mm -ju +KA ab ab ab @@ -8712,10 +8800,10 @@ ab ju kF ld -ju +KA lR -ld -ju +Tt +KA ab ab ab @@ -8761,11 +8849,11 @@ ab ab ju ju +lr +Ng ju -ju -ju -ju -ju +lr +Ng ab ab ab 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 15d65029e0..7d6416d3bf 100644 --- a/_maps/RandomZLevels/away_mission/TheBeach.dmm +++ b/_maps/RandomZLevels/away_mission/TheBeach.dmm @@ -723,7 +723,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 4baab1e31a..f5af8b517b 100644 --- a/_maps/map_files/BoxStation/BoxStation.dmm +++ b/_maps/map_files/BoxStation/BoxStation.dmm @@ -18261,7 +18261,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 }, @@ -24659,9 +24659,6 @@ /obj/machinery/camera{ c_tag = "Chemistry" }, -/obj/machinery/firealarm{ - pixel_y = 24 - }, /obj/machinery/chem_heater, /turf/open/floor/plasteel/white, /area/medical/chemistry) @@ -27701,6 +27698,10 @@ /obj/machinery/light{ dir = 8 }, +/obj/machinery/firealarm{ + dir = 4; + pixel_x = -26 + }, /turf/open/floor/plasteel/white, /area/medical/chemistry) "boc" = ( @@ -41401,13 +41402,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, @@ -55284,14 +55278,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 @@ -56347,7 +56333,7 @@ }, /area/maintenance/bar) "lsk" = ( -/obj/machinery/vending/autodrobe/all_access, +/obj/machinery/vending/autodrobe, /turf/open/floor/plasteel, /area/crew_quarters/fitness) "ltK" = ( @@ -58796,7 +58782,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" = ( @@ -93880,7 +93866,7 @@ bMQ bRC rdl daq -bUO +bUN bOd bOd bOd @@ -94137,7 +94123,7 @@ cBF bRD rdl daq -bUO +bUN bOd bOd bOd @@ -94394,7 +94380,7 @@ bQs cez ceA daq -bUO +bUN bOd bOd bOd @@ -95931,19 +95917,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 868ded69ed..d1214fe0a0 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 }, @@ -81477,7 +81477,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 }, @@ -108601,7 +108601,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..5455070754 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 }, @@ -24888,9 +24888,6 @@ /obj/machinery/camera{ c_tag = "Chemistry" }, -/obj/machinery/firealarm{ - pixel_y = 24 - }, /obj/machinery/chem_heater, /turf/open/floor/plasteel/white, /area/medical/chemistry) @@ -27915,6 +27912,10 @@ /obj/machinery/light{ dir = 8 }, +/obj/machinery/firealarm{ + dir = 4; + pixel_x = -24 + }, /turf/open/floor/plasteel/white, /area/medical/chemistry) "boc" = ( @@ -56834,7 +56835,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 +59724,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 7706764fbd..636e0a18c4 100644 --- a/_maps/map_files/KiloStation/KiloStation.dmm +++ b/_maps/map_files/KiloStation/KiloStation.dmm @@ -54042,7 +54042,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) @@ -78313,7 +78313,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 @@ -84858,7 +84858,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 9fe0fd87ee..d4e3f285f1 100644 --- a/_maps/map_files/MetaStation/MetaStation.dmm +++ b/_maps/map_files/MetaStation/MetaStation.dmm @@ -45045,7 +45045,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" = ( @@ -57013,7 +57013,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 c6a303ab49..ac07b80900 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -527,6 +527,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 ac68692ebe..b2c6c94590 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 02a74bccc3..9bda1cd233 100644 --- a/code/controllers/subsystem/shuttle.dm +++ b/code/controllers/subsystem/shuttle.dm @@ -34,10 +34,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() @@ -118,9 +116,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()]" : ""]" @@ -573,7 +568,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/datums/action.dm b/code/datums/action.dm index 8862482dc2..00e7e0ad5d 100644 --- a/code/datums/action.dm +++ b/code/datums/action.dm @@ -186,6 +186,8 @@ /datum/action/item_action/New(Target) ..() + if(button_icon_state) + use_target_appearance = FALSE var/obj/item/I = target LAZYINITLIST(I.actions) I.actions += src @@ -345,6 +347,7 @@ /datum/action/item_action/clock/quickbind name = "Quickbind" desc = "If you're seeing this, file a bug report." + use_target_appearance = FALSE var/scripture_index = 0 //the index of the scripture we're associated with /datum/action/item_action/toggle_helmet_flashlight diff --git a/code/datums/components/crafting/craft.dm b/code/datums/components/crafting/craft.dm new file mode 100644 index 0000000000..3283c514b8 --- /dev/null +++ b/code/datums/components/crafting/craft.dm @@ -0,0 +1,491 @@ +/datum/component/personal_crafting/Initialize() + if(!ismob(parent)) + return COMPONENT_INCOMPATIBLE + RegisterSignal(parent, COMSIG_MOB_CLIENT_LOGIN, .proc/create_mob_button) + +/datum/component/personal_crafting/proc/create_mob_button(mob/user, client/CL) + var/datum/hud/H = user.hud_used + var/obj/screen/craft/C = new() + C.icon = H.ui_style + H.static_inventory += C + if(!CL.prefs.widescreenpref) + C.screen_loc = ui_boxcraft + CL.screen += C + RegisterSignal(C, COMSIG_CLICK, .proc/component_ui_interact) + +/datum/component/personal_crafting + var/busy + var/viewing_category = 1 + var/viewing_subcategory = 1 + var/list/categories = list( + CAT_WEAPONRY = list( + CAT_WEAPON, + CAT_AMMO, + ), + CAT_ROBOT = CAT_NONE, + CAT_MISC = list( + CAT_MISCELLANEOUS, + CAT_TOOL, + CAT_FURNITURE, + ), + CAT_PRIMAL = CAT_NONE, + CAT_FOOD = list( + CAT_BREAD, + CAT_BURGER, + CAT_CAKE, + CAT_DONUT, + CAT_EGG, + CAT_ICE, + CAT_MEAT, + CAT_MEXICAN, + CAT_MISCFOOD, + CAT_PASTRY, + CAT_PIE, + CAT_PIZZA, + CAT_SEAFOOD, + CAT_SALAD, + CAT_SANDWICH, + CAT_SOUP, + CAT_SPAGHETTI, + ), + CAT_DRINK = CAT_NONE, + CAT_CLOTHING = CAT_NONE, + ) + + var/cur_category = CAT_NONE + var/cur_subcategory = CAT_NONE + var/datum/action/innate/crafting/button + var/display_craftable_only = FALSE + var/display_compact = TRUE + + + + +/* This is what procs do: + get_environment - gets a list of things accessable for crafting by user + get_surroundings - takes a list of things and makes a list of key-types to values-amounts of said type in the list + check_contents - takes a recipe and a key-type list and checks if said recipe can be done with available stuff + check_tools - takes recipe, a key-type list, and a user and checks if there are enough tools to do the stuff, checks bugs one level deep + construct_item - takes a recipe and a user, call all the checking procs, calls do_after, checks all the things again, calls del_reqs, creates result, calls CheckParts of said result with argument being list returned by deel_reqs + del_reqs - takes recipe and a user, loops over the recipes reqs var and tries to find everything in the list make by get_environment and delete it/add to parts list, then returns the said list +*/ + + + +/** + * Check that the contents of the recipe meet the requirements. + * + * user: The /mob that initated the crafting. + * R: The /datum/crafting_recipe being attempted. + * contents: List of items to search for R's reqs. + */ +/datum/component/personal_crafting/proc/check_contents(mob/user, datum/crafting_recipe/R, list/contents) + var/list/item_instances = contents["instances"] + contents = contents["other"] + + var/list/requirements_list = list() + + // Process all requirements + for(var/requirement_path in R.reqs) + // Check we have the appropriate amount available in the contents list + var/needed_amount = R.reqs[requirement_path] + for(var/content_item_path in contents) + // Right path and not blacklisted + if(!ispath(content_item_path, requirement_path) || R.blacklist.Find(requirement_path)) + continue + + needed_amount -= contents[content_item_path] + if(needed_amount <= 0) + break + + if(needed_amount > 0) + return FALSE + + // Store the instances of what we will use for R.check_requirements() for requirement_path + var/list/instances_list = list() + for(var/instance_path in item_instances) + if(ispath(instance_path, requirement_path)) + instances_list += item_instances[instance_path] + + requirements_list[requirement_path] = instances_list + + for(var/requirement_path in R.chem_catalysts) + if(contents[requirement_path] < R.chem_catalysts[requirement_path]) + return FALSE + + return R.check_requirements(user, requirements_list) + +/datum/component/personal_crafting/proc/get_environment(mob/user) + . = list() + for(var/obj/item/I in user.held_items) + . += I + if(!isturf(user.loc)) + return + var/list/L = block(get_step(user, SOUTHWEST), get_step(user, NORTHEAST)) + for(var/A in L) + var/turf/T = A + if(T.Adjacent(user)) + for(var/B in T) + var/atom/movable/AM = B + if(AM.flags_1 & HOLOGRAM_1) + continue + . += AM + for(var/slot in list(SLOT_R_STORE, SLOT_L_STORE)) + . += user.get_item_by_slot(slot) + +/datum/component/personal_crafting/proc/get_surroundings(mob/user) + . = list() + .["tool_behaviour"] = list() + .["other"] = list() + .["instances"] = list() + for(var/obj/item/I in get_environment(user)) + if(I.flags_1 & HOLOGRAM_1) + continue + if(.["instances"][I.type]) + .["instances"][I.type] += I + else + .["instances"][I.type] = list(I) + if(istype(I, /obj/item/stack)) + var/obj/item/stack/S = I + .["other"][I.type] += S.amount + else if(I.tool_behaviour) + .["tool_behaviour"] += I.tool_behaviour + .["other"][I.type] += 1 + else + if(istype(I, /obj/item/reagent_containers)) + var/obj/item/reagent_containers/RC = I + if(RC.is_drainable()) + for(var/datum/reagent/A in RC.reagents.reagent_list) + .["other"][A.type] += A.volume + .["other"][I.type] += 1 + +/datum/component/personal_crafting/proc/check_tools(mob/user, datum/crafting_recipe/R, list/contents) + if(!R.tools.len) + return TRUE + var/list/possible_tools = list() + var/list/present_qualities = list() + present_qualities |= contents["tool_behaviour"] + for(var/obj/item/I in user.contents) + if(istype(I, /obj/item/storage)) + for(var/obj/item/SI in I.contents) + possible_tools += SI.type + if(SI.tool_behaviour) + present_qualities.Add(SI.tool_behaviour) + + possible_tools += I.type + + if(I.tool_behaviour) + present_qualities.Add(I.tool_behaviour) + + possible_tools |= contents["other"] + + main_loop: + for(var/A in R.tools) + if(A in present_qualities) + continue + else + for(var/I in possible_tools) + if(ispath(I, A)) + continue main_loop + return FALSE + return TRUE + +/datum/component/personal_crafting/proc/construct_item(mob/user, datum/crafting_recipe/R) + var/list/contents = get_surroundings(user) + var/send_feedback = TRUE + if(check_contents(user, R, contents)) + if(check_tools(user, R, contents)) + if(do_after(user, R.time, target = user)) + contents = get_surroundings(user) + if(!check_contents(user, R, contents)) + return ", missing component." + if(!check_tools(user, R, contents)) + return ", missing tool." + var/list/parts = del_reqs(R, user) + var/atom/movable/I = new R.result (get_turf(user.loc)) + I.CheckParts(parts, R) + if(isitem(I)) + if(isfood(I)) + var/obj/item/reagent_containers/food/food_result = I + var/total_quality = 0 + var/total_items = 0 + for(var/obj/item/reagent_containers/food/ingredient in parts) + total_items += 1 + total_quality += ingredient.food_quality + if(total_items == 0) + food_result.adjust_food_quality(50) + else + food_result.adjust_food_quality(total_quality / total_items) + user.put_in_hands(I) + if(send_feedback) + SSblackbox.record_feedback("tally", "object_crafted", 1, I.type) + log_craft("[I] crafted by [user] at [loc_name(I.loc)]") + return FALSE + return "." + return ", missing tool." + return ", missing component." + + +/*Del reqs works like this: + + Loop over reqs var of the recipe + Set var amt to the value current cycle req is pointing to, its amount of type we need to delete + Get var/surroundings list of things accessable to crafting by get_environment() + Check the type of the current cycle req + If its reagent then do a while loop, inside it try to locate() reagent containers, inside such containers try to locate needed reagent, if there isnt remove thing from surroundings + If there is enough reagent in the search result then delete the needed amount, create the same type of reagent with the same data var and put it into deletion list + If there isnt enough take all of that reagent from the container, put into deletion list, substract the amt var by the volume of reagent, remove the container from surroundings list and keep searching + While doing above stuff check deletion list if it already has such reagnet, if yes merge instead of adding second one + If its stack check if it has enough amount + If yes create new stack with the needed amount and put in into deletion list, substract taken amount from the stack + If no put all of the stack in the deletion list, substract its amount from amt and keep searching + While doing above stuff check deletion list if it already has such stack type, if yes try to merge them instead of adding new one + If its anything else just locate() in in the list in a while loop, each find --s the amt var and puts the found stuff in deletion loop + + Then do a loop over parts var of the recipe + Do similar stuff to what we have done above, but now in deletion list, until the parts conditions are satisfied keep taking from the deletion list and putting it into parts list for return + + After its done loop over deletion list and delete all the shit that wasnt taken by parts loop + + del_reqs return the list of parts resulting object will receive as argument of CheckParts proc, on the atom level it will add them all to the contents, on all other levels it calls ..() and does whatever is needed afterwards but from contents list already +*/ + +/datum/component/personal_crafting/proc/del_reqs(datum/crafting_recipe/R, mob/user) + var/list/surroundings + var/list/Deletion = list() + . = list() + var/data + var/amt + main_loop: + for(var/A in R.reqs) + amt = R.reqs[A] + surroundings = get_environment(user) + surroundings -= Deletion + if(ispath(A, /datum/reagent)) + var/datum/reagent/RG = new A + var/datum/reagent/RGNT + while(amt > 0) + var/obj/item/reagent_containers/RC = locate() in surroundings + RG = RC.reagents.get_reagent(A) + if(RG) + if(!locate(RG.type) in Deletion) + Deletion += new RG.type() + if(RG.volume > amt) + RG.volume -= amt + data = RG.data + RC.reagents.conditional_update(RC) + RG = locate(RG.type) in Deletion + RG.volume = amt + RG.data += data + continue main_loop + else + surroundings -= RC + amt -= RG.volume + RC.reagents.reagent_list -= RG + RC.reagents.conditional_update(RC) + RGNT = locate(RG.type) in Deletion + RGNT.volume += RG.volume + RGNT.data += RG.data + qdel(RG) + RC.on_reagent_change() + else + surroundings -= RC + else if(ispath(A, /obj/item/stack)) + var/obj/item/stack/S + var/obj/item/stack/SD + while(amt > 0) + S = locate(A) in surroundings + if(S.amount >= amt) + if(!locate(S.type) in Deletion) + SD = new S.type() + Deletion += SD + S.use(amt) + SD = locate(S.type) in Deletion + SD.amount += amt + continue main_loop + else + amt -= S.amount + if(!locate(S.type) in Deletion) + Deletion += S + else + data = S.amount + S = locate(S.type) in Deletion + S.add(data) + surroundings -= S + else + var/atom/movable/I + while(amt > 0) + I = locate(A) in surroundings + Deletion += I + surroundings -= I + amt-- + var/list/partlist = list(R.parts.len) + for(var/M in R.parts) + partlist[M] = R.parts[M] + for(var/A in R.parts) + if(istype(A, /datum/reagent)) + var/datum/reagent/RG = locate(A) in Deletion + if(RG.volume > partlist[A]) + RG.volume = partlist[A] + . += RG + Deletion -= RG + continue + else if(istype(A, /obj/item/stack)) + var/obj/item/stack/ST = locate(A) in Deletion + if(ST.amount > partlist[A]) + ST.amount = partlist[A] + . += ST + Deletion -= ST + continue + else + while(partlist[A] > 0) + var/atom/movable/AM = locate(A) in Deletion + . += AM + Deletion -= AM + partlist[A] -= 1 + while(Deletion.len) + var/DL = Deletion[Deletion.len] + Deletion.Cut(Deletion.len) + qdel(DL) + +/datum/component/personal_crafting/proc/component_ui_interact(obj/screen/craft/image, location, control, params, user) + if(user == parent) + ui_interact(user) + +/datum/component/personal_crafting/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.not_incapacitated_turf_state) + ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) + if(!ui) + cur_category = categories[1] + if(islist(categories[cur_category])) + var/list/subcats = categories[cur_category] + cur_subcategory = subcats[1] + else + cur_subcategory = CAT_NONE + ui = new(user, src, ui_key, "personal_crafting", "Crafting Menu", 700, 800, master_ui, state) + ui.open() + + +/datum/component/personal_crafting/ui_data(mob/user) + var/list/data = list() + data["busy"] = busy + data["category"] = cur_category + data["subcategory"] = cur_subcategory + data["display_craftable_only"] = display_craftable_only + data["display_compact"] = display_compact + + var/list/surroundings = get_surroundings(user) + var/list/craftability = list() + for(var/rec in GLOB.crafting_recipes) + var/datum/crafting_recipe/R = rec + + if(!R.always_availible && !(R.type in user?.mind?.learned_recipes)) //User doesn't actually know how to make this. + continue + + if((R.category != cur_category) || (R.subcategory != cur_subcategory)) + continue + + craftability["[REF(R)]"] = check_contents(user, R, surroundings) + + data["craftability"] = craftability + return data + +/datum/component/personal_crafting/ui_static_data(mob/user) + var/list/data = list() + + var/list/crafting_recipes = list() + for(var/rec in GLOB.crafting_recipes) + var/datum/crafting_recipe/R = rec + + if(R.name == "") //This is one of the invalid parents that sneaks in + continue + + if(!R.always_availible && !(R.type in user?.mind?.learned_recipes)) //User doesn't actually know how to make this. + continue + + if(isnull(crafting_recipes[R.category])) + crafting_recipes[R.category] = list() + + if(R.subcategory == CAT_NONE) + crafting_recipes[R.category] += list(build_recipe_data(R)) + else + if(isnull(crafting_recipes[R.category][R.subcategory])) + crafting_recipes[R.category][R.subcategory] = list() + crafting_recipes[R.category]["has_subcats"] = TRUE + crafting_recipes[R.category][R.subcategory] += list(build_recipe_data(R)) + + data["crafting_recipes"] = crafting_recipes + return data + + +/datum/component/personal_crafting/ui_act(action, params) + if(..()) + return + switch(action) + if("make") + var/datum/crafting_recipe/TR = locate(params["recipe"]) in GLOB.crafting_recipes + ui_interact(usr) + if(busy) + to_chat(usr, "You are already making something!") + return + busy = TRUE + var/fail_msg = construct_item(usr, TR) + if(!fail_msg) + to_chat(usr, "[TR.name] constructed.") + else + to_chat(usr, "Construction failed[fail_msg]") + busy = FALSE + if("toggle_recipes") + display_craftable_only = !display_craftable_only + . = TRUE + if("toggle_compact") + display_compact = !display_compact + . = TRUE + if("set_category") + if(!isnull(params["category"])) + cur_category = params["category"] + if(!isnull(params["subcategory"])) + if(params["subcategory"] == "0") + cur_subcategory = "" + else + cur_subcategory = params["subcategory"] + . = TRUE + +/datum/component/personal_crafting/proc/build_recipe_data(datum/crafting_recipe/R) + var/list/data = list() + data["name"] = R.name + data["ref"] = "[REF(R)]" + var/req_text = "" + var/tool_text = "" + var/catalyst_text = "" + + for(var/a in R.reqs) + //We just need the name, so cheat-typecast to /atom for speed (even tho Reagents are /datum they DO have a "name" var) + //Also these are typepaths so sadly we can't just do "[a]" + var/atom/A = a + req_text += " [R.reqs[A]] [initial(A.name)]," + req_text = replacetext(req_text,",","",-1) + data["req_text"] = req_text + + for(var/a in R.chem_catalysts) + var/atom/A = a //cheat-typecast + catalyst_text += " [R.chem_catalysts[A]] [initial(A.name)]," + catalyst_text = replacetext(catalyst_text,",","",-1) + data["catalyst_text"] = catalyst_text + + for(var/a in R.tools) + if(ispath(a, /obj/item)) + var/obj/item/b = a + tool_text += " [initial(b.name)]," + else + tool_text += " [a]," + tool_text = replacetext(tool_text,",","",-1) + data["tool_text"] = tool_text + + return data + +//Mind helpers + +/datum/mind/proc/teach_crafting_recipe(R) + if(!learned_recipes) + learned_recipes = list() + learned_recipes |= R diff --git a/code/datums/diseases/advance/symptoms/heal.dm b/code/datums/diseases/advance/symptoms/heal.dm index 59afe163b4..787704e848 100644 --- a/code/datums/diseases/advance/symptoms/heal.dm +++ b/code/datums/diseases/advance/symptoms/heal.dm @@ -126,7 +126,7 @@ var/datum/reagent/R = E M.reagents.remove_reagent(R.type, actual_power) if(food_conversion) - M.nutrition += 0.3 + M.adjust_nutrition(0.3) if(prob(2)) to_chat(M, "You feel a mild warmth as your blood purifies itself.") return 1 @@ -164,7 +164,7 @@ C.reagents.metabolize(C, can_overdose=TRUE) C.overeatduration = max(C.overeatduration - 2, 0) var/lost_nutrition = 9 - (reduced_hunger * 5) - C.nutrition = max(C.nutrition - (lost_nutrition * HUNGER_FACTOR), 0) //Hunger depletes at 10x the normal speed + C.adjust_nutrition(-lost_nutrition * HUNGER_FACTOR) //Hunger depletes at 10x the normal speed if(prob(2)) to_chat(C, "You feel an odd gurgle in your stomach, as if it was working much faster than normal.") return 1 @@ -454,7 +454,7 @@ "Transmission 6" = "Additionally heals cellular damage and toxin lovers.", "Resistance 7" = "Increases healing speed.", ) - + /datum/symptom/heal/radiation/Start(datum/disease/advance/A) if(!..()) return diff --git a/code/datums/diseases/advance/symptoms/weight.dm b/code/datums/diseases/advance/symptoms/weight.dm index 5eab698750..bb0d9bdcf9 100644 --- a/code/datums/diseases/advance/symptoms/weight.dm +++ b/code/datums/diseases/advance/symptoms/weight.dm @@ -50,4 +50,4 @@ Bonus else to_chat(M, "[pick("So hungry...", "You'd kill someone for a bite of food...", "Hunger cramps seize you...")]") M.overeatduration = max(M.overeatduration - 100, 0) - M.nutrition = max(M.nutrition - 100, 0) \ No newline at end of file + M.adjust_nutrition(-100) \ No newline at end of file diff --git a/code/datums/diseases/tuberculosis.dm b/code/datums/diseases/tuberculosis.dm index 23902603ce..f59a19c7a3 100644 --- a/code/datums/diseases/tuberculosis.dm +++ b/code/datums/diseases/tuberculosis.dm @@ -52,7 +52,7 @@ if(prob(3)) to_chat(affected_mob, "[pick("Your stomach silently rumbles...", "Your stomach seizes up and falls limp, muscles dead and lifeless.", "You could eat a crayon")]") affected_mob.overeatduration = max(affected_mob.overeatduration - 100, 0) - affected_mob.nutrition = max(affected_mob.nutrition - 100, 0) + affected_mob.adjust_nutrition(-100) if(prob(15)) to_chat(affected_mob, "[pick("You feel uncomfortably hot...", "You feel like unzipping your jumpsuit", "You feel like taking off some clothes...")]") affected_mob.adjust_bodytemperature(40) diff --git a/code/datums/dna.dm b/code/datums/dna.dm index 85880bd43d..68998ca1c6 100644 --- a/code/datums/dna.dm +++ b/code/datums/dna.dm @@ -155,10 +155,11 @@ return . /datum/dna/proc/generate_dna_blocks() - var/bonus + var/list/mutations_temp = GLOB.good_mutations + GLOB.bad_mutations + GLOB.not_good_mutations if(species && species.inert_mutation) - bonus = GET_INITIALIZED_MUTATION(species.inert_mutation) - var/list/mutations_temp = GLOB.good_mutations + GLOB.bad_mutations + GLOB.not_good_mutations + bonus + var/bonus = GET_INITIALIZED_MUTATION(species.inert_mutation) + if(bonus) + mutations_temp += bonus if(!LAZYLEN(mutations_temp)) return mutation_index.Cut() diff --git a/code/datums/wires/_wires.dm b/code/datums/wires/_wires.dm index a7da6d2c66..feb41cef0c 100644 --- a/code/datums/wires/_wires.dm +++ b/code/datums/wires/_wires.dm @@ -142,7 +142,7 @@ if(level_diff > 0) LAZYSET(current_users, user, TRUE) to_chat(user, "You begin cutting [holder]'s [color] wire...") - if(!do_after(user, 1.5 SECONDS * level_diff, target = holder) || !interactable(user)) + if(!do_after(user, 0.75 SECONDS * level_diff, target = holder) || !interactable(user)) LAZYREMOVE(current_users, user) return FALSE LAZYREMOVE(current_users, user) diff --git a/code/game/atoms.dm b/code/game/atoms.dm index ad71c3c2ac..484a0d8e0e 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 6c6b550cc5..fad27aaa25 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 fabf8e3343..8033f538ba 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 d2a3c08f94..6d5cce1f3c 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() . = ..() @@ -106,7 +109,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) @@ -136,7 +139,7 @@ mess = TRUE update_icon() return FALSE - + current_insurance = insurance attempting = TRUE //One at a time!! countdown.start() @@ -199,15 +202,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. @@ -234,7 +251,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.") @@ -343,7 +360,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/arcade/orion_trail.dm b/code/game/machinery/computer/arcade/orion_trail.dm index 2304312953..8b81c69ed2 100644 --- a/code/game/machinery/computer/arcade/orion_trail.dm +++ b/code/game/machinery/computer/arcade/orion_trail.dm @@ -117,7 +117,7 @@ if(food <= 0) dat += "
You ran out of food and starved." if(obj_flags & EMAGGED) - user.nutrition = 0 //yeah you pretty hongry + user.set_nutrition(0) //yeah you pretty hongry to_chat(user, "Your body instantly contracts to that of one who has not eaten in months. Agonizing cramps seize you as you fall to the floor.") if(fuel <= 0) dat += "
You ran out of fuel, and drift, slowly, into a star." 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 f71a3a8e39..60e8971937 100755 --- a/code/game/machinery/computer/communications.dm +++ b/code/game/machinery/computer/communications.dm @@ -61,7 +61,7 @@ // main interface if("main") state = STATE_DEFAULT - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, FALSE) if("login") var/mob/M = usr @@ -71,21 +71,21 @@ if(check_access(I)) authenticated = 1 auth_id = "[I.registered_name] ([I.assignment])" - if((ACCESS_CAPTAIN in I.access)) + if((20 in I.access)) authenticated = 2 - playsound(src, 'sound/machines/terminal_on.ogg', 50, 0) + playsound(src, 'sound/machines/terminal_on.ogg', 50, FALSE) if(obj_flags & EMAGGED) authenticated = 2 auth_id = "Unknown" to_chat(M, "[src] lets out a quiet alarm as its login is overridden.") - playsound(src, 'sound/machines/terminal_on.ogg', 50, 0) - playsound(src, 'sound/machines/terminal_alert.ogg', 25, 0) + playsound(src, 'sound/machines/terminal_on.ogg', 50, FALSE) + playsound(src, 'sound/machines/terminal_alert.ogg', 25, FALSE) if(prob(25)) for(var/mob/living/silicon/ai/AI in active_ais()) SEND_SOUND(AI, sound('sound/machines/terminal_alert.ogg', volume = 10)) //Very quiet for balance reasons if("logout") authenticated = 0 - playsound(src, 'sound/machines/terminal_off.ogg', 50, 0) + playsound(src, 'sound/machines/terminal_off.ogg', 50, FALSE) if("swipeidseclevel") var/mob/M = usr @@ -109,7 +109,7 @@ security_level_cd = world.time + 15 SECONDS if(GLOB.security_level != old_level) to_chat(usr, "Authorization confirmed. Modifying security level.") - playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) + playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE) //Only notify people if an actual change happened var/security_level = NUM2SECLEVEL(GLOB.security_level) log_game("[key_name(usr)] has changed the security level to [security_level] with [src] at [AREACOORD(usr)].") @@ -118,29 +118,34 @@ tmp_alertlevel = 0 else to_chat(usr, "You are not authorized to do this!") - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, FALSE) tmp_alertlevel = 0 state = STATE_DEFAULT else to_chat(usr, "You need to swipe your ID!") - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, FALSE) if("announce") if(authenticated==2) - playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0) + playsound(src, 'sound/machines/terminal_prompt.ogg', 50, FALSE) make_announcement(usr) if("crossserver") if(authenticated==2) + var/dest = href_list["cross_dest"] if(!checkCCcooldown()) - to_chat(usr, "Arrays recycling. Please stand by.") - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + to_chat(usr, "Arrays recycling. Please stand by.") + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, FALSE) return - var/input = stripped_multiline_input(usr, "Please choose a message to transmit to allied stations. Please be aware that this process is very expensive, and abuse will lead to... termination.", "Send a message to an allied station.", "") + var/warning = dest == "all" ? "Please choose a message to transmit to allied stations." : "Please choose a message to transmit to [dest] sector station." + var/input = stripped_multiline_input(usr, "[warning] Please be aware that this process is very expensive, and abuse will lead to... termination.", "Send a message to an allied station.", "") if(!input || !(usr in view(1,src)) || !checkCCcooldown()) return - playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) - send2otherserver("[station_name()]", input,"Comms_Console") + playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE) + if(dest == "all") + send2otherserver("[station_name()]", input,"Comms_Console") + else + send2otherserver("[station_name()]", input,"Comms_Console", list(dest)) minor_announce(input, title = "Outgoing message to allied station") usr.log_talk(input, LOG_SAY, tag="message to the other server") message_admins("[ADMIN_LOOKUPFLW(usr)] has sent a message to the other server.") @@ -156,30 +161,34 @@ var/datum/map_template/shuttle/S = locate(href_list["chosen_shuttle"]) in shuttles if(S && istype(S)) if(SSshuttle.emergency.mode != SHUTTLE_RECALL && SSshuttle.emergency.mode != SHUTTLE_IDLE) - to_chat(usr, "It's a bit late to buy a new shuttle, don't you think?") + to_chat(usr, "It's a bit late to buy a new shuttle, don't you think?") return if(SSshuttle.shuttle_purchased) - to_chat(usr, "A replacement shuttle has already been purchased.") + to_chat(usr, "A replacement shuttle has already been purchased.") else if(!S.prerequisites_met()) - to_chat(usr, "You have not met the requirements for purchasing this shuttle.") + 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) SSshuttle.shuttle_purchased = TRUE SSshuttle.unload_preview() SSshuttle.load_template(S) SSshuttle.existing_shuttle = SSshuttle.emergency SSshuttle.action_load(S) - SSshuttle.points -= S.credit_cost - minor_announce("[usr.real_name] has purchased [S.name] for [S.credit_cost] credits." , "Shuttle Purchase") + D.adjust_money(-S.credit_cost) + minor_announce("[usr.real_name] has purchased [S.name] for [S.credit_cost] credits.[S.extra_desc ? " [S.extra_desc]" : ""]" , "Shuttle Purchase") message_admins("[ADMIN_LOOKUPFLW(usr)] purchased [S.name].") log_shuttle("[key_name(usr)] has purchased [S.name].") SSblackbox.record_feedback("text", "shuttle_purchase", 1, "[S.name]") else - to_chat(usr, "Not enough credits.") + to_chat(usr, "Insufficient credits.") if("callshuttle") state = STATE_DEFAULT - if(authenticated) + if(authenticated && SSshuttle.canEvac(usr)) state = STATE_CALLSHUTTLE if("callshuttle2") if(authenticated) @@ -260,7 +269,7 @@ // Status display stuff if("setstat") - playsound(src, "terminal_type", 50, 0) + playsound(src, "terminal_type", 50, FALSE) switch(href_list["statdisp"]) if("message") post_status("message", stat_msg1, stat_msg2) @@ -280,12 +289,12 @@ if("MessageCentCom") if(authenticated) if(!checkCCcooldown()) - to_chat(usr, "Arrays recycling. Please stand by.") + to_chat(usr, "Arrays recycling. Please stand by.") return var/input = stripped_input(usr, "Please choose a message to transmit to CentCom via quantum entanglement. Please be aware that this process is very expensive, and abuse will lead to... termination. Transmission does not guarantee a response.", "Send a message to CentCom.", "") if(!input || !(usr in view(1,src)) || !checkCCcooldown()) return - playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) + playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE) CentCom_announce(input, usr) to_chat(usr, "Message transmitted to Central Command.") for(var/client/X in GLOB.admins) @@ -298,15 +307,15 @@ // OMG SYNDICATE ...LETTERHEAD if("MessageSyndicate") - if((authenticated==2) && (obj_flags & EMAGGED)) + if((authenticated) && (obj_flags & EMAGGED)) if(!checkCCcooldown()) - to_chat(usr, "Arrays recycling. Please stand by.") - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + to_chat(usr, "Arrays recycling. Please stand by.") + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, FALSE) return var/input = stripped_input(usr, "Please choose a message to transmit to \[ABNORMAL ROUTING COORDINATES\] via quantum entanglement. Please be aware that this process is very expensive, and abuse will lead to... termination. Transmission does not guarantee a response.", "Send a message to /??????/.", "") if(!input || !(usr in view(1,src)) || !checkCCcooldown()) return - playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) + playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE) Syndicate_announce(input, usr) to_chat(usr, "SYSERR @l(19833)of(transmit.dm): !@$ MESSAGE TRANSMITTED TO SYNDICATE COMMAND.") for(var/client/X in GLOB.admins) @@ -319,7 +328,7 @@ if("RestoreBackup") to_chat(usr, "Backup routing data restored!") - playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) + playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE) obj_flags &= ~EMAGGED updateDialog() @@ -333,8 +342,8 @@ return Nuke_request(input, usr) to_chat(usr, "Request sent.") - usr.log_message("has requested the nuclear codes from CentCom", LOG_SAY) - priority_announce("The codes for the on-station nuclear self-destruct have been requested by [usr]. Confirmation or denial of this request will be sent shortly.", "Nuclear Self Destruct Codes Requested","commandreport") + usr.log_message("has requested the nuclear codes from CentCom with reason \"[input]\"", LOG_SAY) + priority_announce("The codes for the on-station nuclear self-destruct have been requested by [usr]. Confirmation or denial of this request will be sent shortly.", "Nuclear Self Destruct Codes Requested",'sound/ai/commandreport.ogg') CM.lastTimeUsed = world.time @@ -440,8 +449,7 @@ if(authenticated == 1) authenticated = 2 to_chat(user, "You scramble the communication routing circuits!") - playsound(src, 'sound/machines/terminal_alert.ogg', 50, 0) - return TRUE + playsound(src, 'sound/machines/terminal_alert.ogg', 50, FALSE) /obj/machinery/computer/communications/ui_interact(mob/user) . = ..() @@ -506,16 +514,16 @@ dat += "
\[ Log In \]" if(STATE_CALLSHUTTLE) dat += get_call_shuttle_form() - playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0) + playsound(src, 'sound/machines/terminal_prompt.ogg', 50, FALSE) if(STATE_CANCELSHUTTLE) dat += get_cancel_shuttle_form() - playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0) + playsound(src, 'sound/machines/terminal_prompt.ogg', 50, FALSE) if(STATE_MESSAGELIST) dat += "Messages:" for(var/i in 1 to messages.len) var/datum/comm_message/M = messages[i] dat += "
[M.title]" - playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) + playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE) if(STATE_VIEWMESSAGE) if (currmsg) dat += "[currmsg.title]

[currmsg.content]" @@ -549,13 +557,12 @@ dat += " Red Alert |" dat += " Lockdown |" dat += " Biohazard \]

" - playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) + playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE) if(STATE_ALERT_LEVEL) dat += "Current alert level: [NUM2SECLEVEL(GLOB.security_level)]
" if(GLOB.security_level == SEC_LEVEL_DELTA) dat += "The self-destruct mechanism is active. Find a way to deactivate the mechanism to lower the alert level or evacuate." else - dat += "Amber
" dat += "Blue
" dat += "Green" if(STATE_CONFIRM_LEVEL) @@ -563,7 +570,7 @@ dat += "Confirm the change to: [NUM2SECLEVEL(tmp_alertlevel)]
" dat += "Swipe ID to confirm change.
" if(STATE_TOGGLE_EMERGENCY) - playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0) + playsound(src, 'sound/machines/terminal_prompt.ogg', 50, FALSE) if(GLOB.emergency_access == 1) dat += "Emergency Maintenance Access is currently ENABLED" dat += "
Restore maintenance access restrictions?
\[ OK | Cancel \]" @@ -572,7 +579,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 += "
" @@ -696,7 +704,6 @@ if(GLOB.security_level == SEC_LEVEL_DELTA) dat += "The self-destruct mechanism is active. Find a way to deactivate the mechanism to lower the alert level or evacuate." else - dat += "Amber
" dat += "Blue
" dat += "Green" @@ -713,7 +720,7 @@ /obj/machinery/computer/communications/proc/make_announcement(mob/living/user, is_silicon) if(!SScommunications.can_announce(user, is_silicon)) - to_chat(user, "Intercomms recharging. Please stand by.") + to_chat(user, "Intercomms recharging. Please stand by.") return var/input = stripped_input(user, "Please choose a message to announce to the station crew.", "What?") if(!input || !user.canUseTopic(src)) diff --git a/code/game/machinery/doors/airlock_electronics.dm b/code/game/machinery/doors/airlock_electronics.dm index 32ebdba7a7..7d73d1afa7 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/effects/decals/cleanable/misc.dm b/code/game/objects/effects/decals/cleanable/misc.dm index 910c4f4609..e06c172519 100644 --- a/code/game/objects/effects/decals/cleanable/misc.dm +++ b/code/game/objects/effects/decals/cleanable/misc.dm @@ -133,7 +133,7 @@ if(reagents) for(var/datum/reagent/consumable/R in reagents.reagent_list) if(R.nutriment_factor > 0) - H.nutrition += R.nutriment_factor * R.volume + H.adjust_nutrition(R.nutriment_factor * R.volume) reagents.del_reagent(R.type) reagents.trans_to(H, reagents.total_volume) qdel(src) 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/dogborg_sleeper.dm b/code/game/objects/items/devices/dogborg_sleeper.dm index 2614775906..41a12136ef 100644 --- a/code/game/objects/items/devices/dogborg_sleeper.dm +++ b/code/game/objects/items/devices/dogborg_sleeper.dm @@ -3,7 +3,7 @@ /obj/item/dogborg/sleeper name = "hound sleeper" desc = "nothing should see this." - icon = 'icons/mob/dogborg.dmi' + icon = 'icons/mob/robot_items.dmi' icon_state = "sleeper" w_class = WEIGHT_CLASS_TINY var/mob/living/carbon/patient @@ -418,29 +418,15 @@ var/units = round(patient.reagents.get_reagent_amount(chem)) to_chat(hound, "Injecting [units] unit\s of [chem] into occupant.") //If they were immersed, the reagents wouldn't leave with them. -/obj/item/dogborg/sleeper/medihound //Medihound sleeper - name = "Mobile Sleeper" - desc = "Equipment for medical hound. A mounted sleeper that stabilizes patients and can inject reagents in the borg's reserves." - icon = 'icons/mob/dogborg.dmi' - icon_state = "sleeper" - breakout_time = 30 //Medical sleepers should be designed to be as easy as possible to get out of. - /obj/item/dogborg/sleeper/K9 //The K9 portabrig name = "Mobile Brig" desc = "Equipment for a K9 unit. A mounted portable-brig that holds criminals." - icon = 'icons/mob/dogborg.dmi' icon_state = "sleeperb" inject_amount = 0 min_health = -100 injection_chems = null //So they don't have all the same chems as the medihound! breakout_time = 300 -/obj/item/storage/attackby(obj/item/dogborg/sleeper/K9, mob/user, proximity) - if(istype(K9)) - K9.afterattack(src, user ,1) - else - . = ..() - /obj/item/dogborg/sleeper/K9/afterattack(mob/living/carbon/target, mob/living/silicon/user, proximity) var/mob/living/silicon/robot/hound = get_host() if(!hound || !istype(target) || !proximity || target.anchored) @@ -462,70 +448,6 @@ user.visible_message("[hound.name]'s mobile brig clunks in series as [target] slips inside.", "Your mobile brig groans lightly as [target] slips inside.") playsound(hound, 'sound/effects/bin_close.ogg', 80, 1) // Really don't need ERP sound effects for robots - -/obj/item/dogborg/sleeper/compactor //Janihound gut. - name = "garbage processor" - desc = "A mounted garbage compactor unit with fuel processor." - icon = 'icons/mob/dogborg.dmi' - icon_state = "compactor" - inject_amount = 0 - min_health = -100 - injection_chems = null //So they don't have all the same chems as the medihound! - var/max_item_count = 30 - -/obj/item/storage/attackby(obj/item/dogborg/sleeper/compactor, mob/user, proximity) //GIT CIRCUMVENTED YO! - if(istype(compactor)) - compactor.afterattack(src, user ,1) - else - . = ..() - -/obj/item/dogborg/sleeper/compactor/afterattack(atom/movable/target, mob/living/silicon/user, proximity)//GARBO NOMS - var/mob/living/silicon/robot/hound = get_host() - if(!hound || !istype(target) || !proximity || target.anchored) - return - if(length(contents) > (max_item_count - 1)) - to_chat(user,"Your [src] is full. Eject or process contents to continue.") - return - if(isitem(target)) - var/obj/item/I = target - if(CheckAccepted(I)) - to_chat(user,"[I] registers an error code to your [src]") - return - if(I.w_class > WEIGHT_CLASS_NORMAL) - to_chat(user,"[I] is too large to fit into your [src]") - return - user.visible_message("[hound.name] is ingesting [I] into their [src.name].", "You start ingesting [target] into your [src.name]...") - if(do_after(user, 15, target = target) && length(contents) < max_item_count) - I.forceMove(src) - I.visible_message("[hound.name]'s garbage processor groans lightly as [I] slips inside.", "Your garbage compactor groans lightly as [I] slips inside.") - playsound(hound, 'sound/machines/disposalflush.ogg', 50, 1) - if(length(contents) > 11) //grow that tum after a certain junk amount - hound.sleeper_r = 1 - hound.update_icons() - else - hound.sleeper_r = 0 - hound.update_icons() - return - - if(iscarbon(target) || issilicon(target)) - var/mob/living/trashman = target - if(!CHECK_BITFIELD(trashman.vore_flags,DEVOURABLE)) - to_chat(user, "[target] registers an error code to your [src]") - return - if(patient) - to_chat(user,"Your [src] is already occupied.") - return - if(trashman.buckled) - to_chat(user,"[trashman] is buckled and can not be put into your [src].") - return - user.visible_message("[hound.name] is ingesting [trashman] into their [src].", "You start ingesting [trashman] into your [src.name]...") - if(do_after(user, 30, target = trashman) && !patient && !trashman.buckled && length(contents) < max_item_count) - trashman.forceMove(src) - trashman.reset_perspective(src) - update_gut() - user.visible_message("[hound.name]'s garbage processor groans lightly as [trashman] slips inside.", "Your garbage compactor groans lightly as [trashman] slips inside.") - playsound(hound, 'sound/effects/bin_close.ogg', 80, 1) - /obj/item/dogborg/sleeper/K9/flavour name = "Recreational Sleeper" desc = "A mounted, underslung sleeper, intended for holding willing occupants for leisurely purposes." 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/granters.dm b/code/game/objects/items/granters.dm index 0a705df91c..bafffa18e3 100644 --- a/code/game/objects/items/granters.dm +++ b/code/game/objects/items/granters.dm @@ -249,10 +249,8 @@ /obj/item/book/granter/spell/smoke/recoil(mob/user) ..() to_chat(user,"Your stomach rumbles...") - if(user.nutrition) - user.nutrition = 200 - if(user.nutrition <= 0) - user.nutrition = 0 + if(user.nutrition > NUTRITION_LEVEL_STARVING + 50) + user.set_nutrition(NUTRITION_LEVEL_STARVING + 50) /obj/item/book/granter/spell/blind spell = /obj/effect/proc_holder/spell/targeted/trigger/blind 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/robot/robot_items.dm b/code/game/objects/items/robot/robot_items.dm index a5ed113e4c..1ca314f749 100644 --- a/code/game/objects/items/robot/robot_items.dm +++ b/code/game/objects/items/robot/robot_items.dm @@ -902,4 +902,47 @@ name = "mining point card" desc = "A robotic ID strip used for claiming and transferring mining points. Must be held in an active slot to transfer points." access = list(ACCESS_MINING, ACCESS_MINING_STATION, ACCESS_MAILSORTING, ACCESS_MINERAL_STOREROOM) - icon_state = "data_1" \ No newline at end of file + icon_state = "data_1" + + +///Mere cosmetic dogborg items, remnants of what were once the most annoying cyborg modules. +/obj/item/dogborg_tongue + name = "synthetic tongue" + desc = "Useful for slurping mess off the floor before affectionally licking the crew members in the face." + icon = 'icons/mob/robot_items.dmi' + icon_state = "synthtongue" + hitsound = 'sound/effects/attackblob.ogg' + desc = "For giving affectionate kisses." + item_flags = NOBLUDGEON + +/obj/item/dogborg_tongue/afterattack(atom/target, mob/user, proximity) + . = ..() + if(!proximity || !isliving(target)) + return + var/mob/living/silicon/robot/R = user + var/mob/living/L = target + if(L.ckey && !(L.client?.prefs.vore_flags & LICKABLE)) + to_chat(R, "ERROR ERROR: Target not lickable. Aborting display-of-affection subroutine.") + return + + if(check_zone(R.zone_selected) == "head") + R.visible_message("\the [R] affectionally licks \the [L]'s face!", "You affectionally lick \the [L]'s face!") + playsound(R, 'sound/effects/attackblob.ogg', 50, 1) + else + R.visible_message("\the [R] affectionally licks \the [L]!", "You affectionally lick \the [L]!") + playsound(R, 'sound/effects/attackblob.ogg', 50, 1) + +/obj/item/dogborg_nose + name = "boop module" + desc = "The BOOP module" + icon = 'icons/mob/robot_items.dmi' + icon_state = "nose" + flags_1 = CONDUCT_1|NOBLUDGEON + force = 0 + +/obj/item/dogborg_nose/afterattack(atom/target, mob/user, proximity) + . = ..() + if(!proximity) + return + do_attack_animation(target, null, src) + user.visible_message("[user] [pick("nuzzles", "pushes", "boops")] \the [target.name] with their nose!") 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..de98963693 100644 --- a/code/game/objects/items/storage/firstaid.dm +++ b/code/game/objects/items/storage/firstaid.dm @@ -373,7 +373,7 @@ ///////////// /obj/item/storage/belt/organbox - name = "Organ Storge" + name = "Organ Storage" desc = "A compact box that helps hold massive amounts of implants, organs, and some tools. Has a belt clip for easy carrying" w_class = WEIGHT_CLASS_BULKY icon = 'icons/obj/mysterybox.dmi' @@ -392,6 +392,12 @@ STR.can_hold = typecacheof(list( /obj/item/storage/pill_bottle, /obj/item/reagent_containers/hypospray, + /obj/item/pinpointer/crew, + /obj/item/tele_iv, + /obj/item/sequence_scanner, + /obj/item/sensor_device, + /obj/item/bodybag, + /obj/item/surgicaldrill/advanced, /obj/item/healthanalyzer, /obj/item/reagent_containers/syringe, /obj/item/clothing/glasses/hud/health, @@ -407,6 +413,8 @@ /obj/item/implantcase, /obj/item/implanter, /obj/item/circuitboard/computer/operating, + /obj/item/circuitboard/computer/crew, + /obj/item/stack/sheet/glass, /obj/item/stack/sheet/mineral/silver, /obj/item/organ_storage )) @@ -422,6 +430,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/bloodsucker/bloodsucker_life.dm b/code/modules/antagonists/bloodsucker/bloodsucker_life.dm index 1867be1594..8425309b6c 100644 --- a/code/modules/antagonists/bloodsucker/bloodsucker_life.dm +++ b/code/modules/antagonists/bloodsucker/bloodsucker_life.dm @@ -177,7 +177,7 @@ if(owner.current.blood_volume < BLOOD_VOLUME_BAD / 2) owner.current.blur_eyes(8 - 8 * (owner.current.blood_volume / BLOOD_VOLUME_BAD)) // Nutrition - owner.current.nutrition = clamp(owner.current.blood_volume, 545, 0) //The amount of blood is how full we are. + owner.current.set_nutrition(min(owner.current.blood_volume, NUTRITION_LEVEL_FULL)) //The amount of blood is how full we are. //A bit higher regeneration based on blood volume if(owner.current.blood_volume < 700) additional_regen = 0.4 @@ -331,7 +331,7 @@ return var/mob/living/carbon/C = owner.current // Remove Nutrition, Give Bad Food - C.nutrition -= food_nutrition + C.adjust_nutrition(-food_nutrition) foodInGut += food_nutrition // Already ate some bad clams? Then we can back out, because we're already sick from it. if(foodInGut != food_nutrition) diff --git a/code/modules/antagonists/changeling/powers/absorb.dm b/code/modules/antagonists/changeling/powers/absorb.dm index 2d5b38a456..3e2ff6f3dd 100644 --- a/code/modules/antagonists/changeling/powers/absorb.dm +++ b/code/modules/antagonists/changeling/powers/absorb.dm @@ -59,7 +59,7 @@ changeling.trueabsorbs++ if(user.nutrition < NUTRITION_LEVEL_WELL_FED) - user.nutrition = min((user.nutrition + target.nutrition), NUTRITION_LEVEL_WELL_FED) + user.adjust_nutrition(target.nutrition, NUTRITION_LEVEL_WELL_FED) // Absorb a lizard, speak Draconic. user.copy_languages(target, LANGUAGE_ABSORB) diff --git a/code/modules/antagonists/devil/devil.dm b/code/modules/antagonists/devil/devil.dm index e20203d9e6..c12259778e 100644 --- a/code/modules/antagonists/devil/devil.dm +++ b/code/modules/antagonists/devil/devil.dm @@ -183,7 +183,7 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master", if(soulsOwned.Find(soul)) return soulsOwned += soul - owner.current.nutrition = NUTRITION_LEVEL_FULL + owner.current.set_nutrition(NUTRITION_LEVEL_FULL) to_chat(owner.current, "You feel satiated as you received a new soul.") update_hud() switch(SOULVALUE) diff --git a/code/modules/antagonists/traitor/syndicate_contract.dm b/code/modules/antagonists/traitor/syndicate_contract.dm index 9dc79ea29c..0f67616a32 100644 --- a/code/modules/antagonists/traitor/syndicate_contract.dm +++ b/code/modules/antagonists/traitor/syndicate_contract.dm @@ -118,30 +118,33 @@ // After we remove items, at least give them what they need to live. target.dna.species.give_important_for_life(target) - - // After pod is sent we start the victim narrative/heal. - handleVictimExperience(M) - - // This is slightly delayed because of the sleep calls above to handle the narrative. - // We don't want to tell the station instantly. - var/points_to_check - if(points_to_check >= ransom) - SSshuttle.points -= ransom - else - SSshuttle.points -= points_to_check - + handleVictimExperience(M) // After pod is sent we start the victim narrative/heal. + 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") -// They're off to holding - handle the return timer and give some text about what's going on. -/datum/syndicate_contract/proc/handleVictimExperience(var/mob/living/M) - // Ship 'em back - dead or alive, 4 minutes wait. - // Even if they weren't the target, we're still treating them the same. - addtimer(CALLBACK(src, .proc/returnVictim, M), (60 * 10) * 4) + sleep(30) - if (M.stat != DEAD) - M.reagents.add_reagent(/datum/reagent/medicine/regen_jelly, 20) + // 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. + M.reagents.add_reagent(/datum/reagent/medicine/regen_jelly, 20) // Heal them up - gets them out of crit/soft crit. -- now 100% toxinlover friendly!! M.flash_act() M.confused += 10 M.blur_eyes(5) diff --git a/code/modules/atmospherics/machinery/airalarm.dm b/code/modules/atmospherics/machinery/airalarm.dm index fd0700115b..337486c78a 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 0670890c39..54f14b48a6 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 64c063f1af..d33d06feca 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 6a33074bf8..dc7e4b5a06 100644 --- a/code/modules/cargo/expressconsole.dm +++ b/code/modules/cargo/expressconsole.dm @@ -98,17 +98,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) @@ -129,6 +131,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 @@ -139,13 +144,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"]) @@ -165,8 +171,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) @@ -183,14 +193,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)) @@ -198,7 +208,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/cargo/packs/armory.dm b/code/modules/cargo/packs/armory.dm index 501b1426ae..87dfe243b3 100644 --- a/code/modules/cargo/packs/armory.dm +++ b/code/modules/cargo/packs/armory.dm @@ -170,8 +170,7 @@ cost = 7500 contraband = TRUE contains = list(/obj/item/reagent_containers/food/snacks/rationpack, - /obj/item/ammo_box/a762, - /obj/item/storage/toolbox/ammo, + /obj/item/ammo_box/magazine/m10mm/rifle, /obj/item/clothing/suit/armor/vest/russian, /obj/item/clothing/head/helmet/rus_helmet, /obj/item/clothing/shoes/russian, @@ -181,7 +180,7 @@ /obj/item/clothing/mask/russian_balaclava, /obj/item/clothing/head/helmet/rus_ushanka, /obj/item/clothing/suit/armor/vest/russian_coat, - /obj/item/gun/ballistic/shotgun/boltaction) + /obj/item/gun/ballistic/automatic/surplus) crate_name = "surplus military crate" /datum/supply_pack/security/armory/russian/fill(obj/structure/closet/crate/C) diff --git a/code/modules/cargo/packs/security.dm b/code/modules/cargo/packs/security.dm index ee750b8df7..d134d7bab8 100644 --- a/code/modules/cargo/packs/security.dm +++ b/code/modules/cargo/packs/security.dm @@ -99,11 +99,11 @@ crate_type = /obj/structure/closet/crate/internals /datum/supply_pack/security/russianmosin - name = "Russian Minutemen Gear" - desc = "An old russian Minutemen crate, comes with a full russian outfit, a mosin and a stripper clip." + name = "Russian Partisan Gear" + desc = "An old russian partisan equipment crate, comes with a full russian outfit, a loaded surplus rifle and a second magazine." contraband = TRUE access = FALSE - cost = 6500 // + cost = 6500 contains = list(/obj/item/clothing/suit/armor/navyblue/russian, /obj/item/clothing/shoes/combat, /obj/item/clothing/head/ushanka, @@ -111,8 +111,8 @@ /obj/item/clothing/head/helmet/alt, /obj/item/clothing/gloves/tackler/combat/insulated, /obj/item/clothing/mask/gas, - /obj/item/gun/ballistic/shotgun/boltaction, - /obj/item/ammo_box/a762) + /obj/item/ammo_box/magazine/m10mm/rifle, + /obj/item/gun/ballistic/automatic/surplus) crate_name = "surplus russian gear" crate_type = /obj/structure/closet/crate/internals diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index a0c0832c2e..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) @@ -1522,7 +1527,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) features["flavor_text"] = html_decode(msg) if("ooc_notes") - var/msg = stripped_multiline_input(usr, "Set always-visible OOC notes related to content preferences. THIS IS NOT FOR CHARACTE DESCRIPTIONS!!", "OOC notes", features["ooc_notes"], MAX_FLAVOR_LEN, TRUE) + var/msg = stripped_multiline_input(usr, "Set always-visible OOC notes related to content preferences. THIS IS NOT FOR CHARACTER DESCRIPTIONS!", "OOC notes", features["ooc_notes"], MAX_FLAVOR_LEN, TRUE) if(!isnull(msg)) features["ooc_notes"] = html_decode(msg) @@ -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 d5ab5c6f9c..f3126a362d 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,14 +146,9 @@ 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 - to_chat(user,"You retrieve the siphoned credits!") - credits_stored = 0 + new /obj/item/holochip(drop_location(), credits_stored) + to_chat(user,"You retrieve the siphoned credits!") + credits_stored = 0 /obj/machinery/shuttle_scrambler/proc/send_notification() priority_announce("Data theft signal detected, source registered on local gps units.") @@ -470,3 +469,11 @@ 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/language/sylvan.dm b/code/modules/language/sylvan.dm index 1eb696259e..3bbf5f6afd 100644 --- a/code/modules/language/sylvan.dm +++ b/code/modules/language/sylvan.dm @@ -14,6 +14,5 @@ "incas", "int", "elc", "ent", "aws", "qip", "nas", "vil", "jens", "dila", "fa", "la", "re", "do", "ji", "ae", "so", "qe", "ce", "na", "mo", "ha", "yu" ) - icon = 'icons/obj/hydroponics/harvest.dmi' - icon_state = "lily" + icon_state = "plant" default_priority = 90 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/blood.dm b/code/modules/mob/living/blood.dm index 41f2c7142f..a5275f677d 100644 --- a/code/modules/mob/living/blood.dm +++ b/code/modules/mob/living/blood.dm @@ -59,7 +59,7 @@ nutrition_ratio *= 1.2 if(satiety > 80) nutrition_ratio *= 1.25 - nutrition = max(0, nutrition - nutrition_ratio * HUNGER_FACTOR) + adjust_nutrition(-nutrition_ratio * HUNGER_FACTOR) blood_volume = min((BLOOD_VOLUME_NORMAL * blood_ratio), blood_volume + 0.5 * nutrition_ratio) //Effects of bloodloss diff --git a/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm b/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm index 42b2c4433b..be81e850b7 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm @@ -21,10 +21,10 @@ Doesn't work on other aliens/AI.*/ . = ..() action = new(src) -/obj/effect/proc_holder/alien/Trigger(mob/living/carbon/user, skip_cost_check) - if(!istype(user)) +/obj/effect/proc_holder/alien/Trigger(mob/living/carbon/user, skip_cost_check = FALSE) + if(!skip_cost_check || !istype(user)) return TRUE - if(!skip_cost_check || cost_check(check_turf,user)) + if(cost_check(check_turf,user)) if(fire(user) && user) // Second check to prevent runtimes when evolving user.adjustPlasma(-plasma_cost) return TRUE diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 821b432ea5..f694890b95 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -520,7 +520,7 @@ playsound(get_turf(src), 'sound/effects/splat.ogg', 50, 1) var/turf/T = get_turf(src) if(!blood) - nutrition -= lost_nutrition + adjust_nutrition(-lost_nutrition) adjustToxLoss(-3) for(var/i=0 to distance) if(blood) diff --git a/code/modules/mob/living/carbon/carbon_movement.dm b/code/modules/mob/living/carbon/carbon_movement.dm index fa060d8b34..cc390b9329 100644 --- a/code/modules/mob/living/carbon/carbon_movement.dm +++ b/code/modules/mob/living/carbon/carbon_movement.dm @@ -24,11 +24,12 @@ . = ..() if(. && (movement_type & FLOATING)) //floating is easy if(HAS_TRAIT(src, TRAIT_NOHUNGER)) - nutrition = NUTRITION_LEVEL_FED - 1 //just less than feeling vigorous + set_nutrition(NUTRITION_LEVEL_FED - 1) //just less than feeling vigorous else if(nutrition && stat != DEAD) - nutrition -= HUNGER_FACTOR/10 + var/loss = HUNGER_FACTOR/10 if(m_intent == MOVE_INTENT_RUN) - nutrition -= HUNGER_FACTOR/10 + loss *= 2 + adjust_nutrition(loss) /mob/living/carbon/can_move_under_living(mob/living/other) . = ..() 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/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index 962d3a649d..51837498c8 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -1290,7 +1290,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) H.Jitter(5) hunger_rate = 3 * HUNGER_FACTOR hunger_rate *= H.physiology.hunger_mod - H.nutrition = max(0, H.nutrition - hunger_rate) + H.adjust_nutrition(-hunger_rate) if (H.nutrition > NUTRITION_LEVEL_FULL) diff --git a/code/modules/mob/living/carbon/human/species_types/golems.dm b/code/modules/mob/living/carbon/human/species_types/golems.dm index 7a5e347060..81132080ab 100644 --- a/code/modules/mob/living/carbon/human/species_types/golems.dm +++ b/code/modules/mob/living/carbon/human/species_types/golems.dm @@ -293,9 +293,7 @@ if(isturf(H.loc)) //else, there's considered to be no light var/turf/T = H.loc light_amount = min(1,T.get_lumcount()) - 0.5 - H.nutrition += light_amount * 10 - if(H.nutrition > NUTRITION_LEVEL_FULL) - H.nutrition = NUTRITION_LEVEL_FULL + H.adjust_nutrition(light_amount * 10, NUTRITION_LEVEL_FULL) if(light_amount > 0.2) //if there's enough light, heal H.heal_overall_damage(1,1) H.adjustToxLoss(-1) diff --git a/code/modules/mob/living/carbon/human/species_types/podpeople.dm b/code/modules/mob/living/carbon/human/species_types/podpeople.dm index a8b9bbfc8f..fd958ccc13 100644 --- a/code/modules/mob/living/carbon/human/species_types/podpeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/podpeople.dm @@ -36,9 +36,7 @@ if(isturf(H.loc)) //else, there's considered to be no light var/turf/T = H.loc light_amount = min(1,T.get_lumcount()) - 0.5 - H.nutrition += light_amount * light_nutrition_gain_factor - if(H.nutrition >= NUTRITION_LEVEL_FULL) - H.nutrition = NUTRITION_LEVEL_FULL - 1 + H.adjust_nutrition(light_amount * light_nutrition_gain_factor, NUTRITION_LEVEL_FULL) if(light_amount > 0.2) //if there's enough light, heal H.heal_overall_damage(light_bruteheal, light_burnheal) H.adjustToxLoss(-light_toxheal) @@ -70,8 +68,7 @@ H.adjustFireLoss(rand(5,15)) H.show_message("The radiation beam singes you!") if(/obj/item/projectile/energy/florayield) - H.nutrition = min(H.nutrition+30, NUTRITION_LEVEL_FULL) - + H.adjust_nutrition(30, NUTRITION_LEVEL_FULL) /datum/species/pod/pseudo_weak name = "Anthromorphic Plant" diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index 00a0991e19..e85769ca12 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -476,7 +476,7 @@ if(SSmobs.times_fired%3==1) if(!(M.status_flags & GODMODE)) M.adjustBruteLoss(5) - nutrition += 10 + adjust_nutrition(10) /* @@ -502,11 +502,23 @@ GLOBAL_LIST_INIT(ballmer_good_msg, list("Hey guys, what if we rolled out a blues "Hear me out here. What if, and this is just a theory, we made R&D controllable from our PDAs?", "I'm thinking we should roll out a git repository for our research under the AGPLv3 license so that we can share it among the other stations freely.", "I dunno about you guys, but IDs and PDAs being separate is clunky as fuck. Maybe we should merge them into a chip in our arms? That way they can't be stolen easily.", - "Why the fuck aren't we just making every pair of shoes into galoshes? We have the technology.")) + "Why the fuck aren't we just making every pair of shoes into galoshes? We have the technology.", + "We can link the Ore Silo to our protolathes, so why don't we also link it to autolathes?", + "If we can make better bombs with heated plasma, oxygen, and tritium, then why do station nukes still use plutonium?", + "We should port all our NT programs to modular consoles and do away with computers. They're way more customizable, support cross-platform usage, and would allow crazy amounts of multitasking.", + "Wait, if we use more manipulators in something, then it prints for cheaper, right? So what if we just made a new type of printer that has like 12 manipulators inside of it to print stuff for really cheap?" + )) GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put a webserver that's automatically turned on with default admin passwords into every PDA?", - "So like, you know how we separate our codebase from the master copy that runs on our consumer boxes? What if we merged the two and undid the separation between codebase and server?", - "Dude, radical idea: H.O.N.K mechs but with no bananium required.", - "Best idea ever: Disposal pipes instead of hallways.")) + "So like, you know how we separate our codebase from the master copy that runs on our consumer boxes? What if we merged the two and undid the separation between codebase and server?", + "Dude, radical idea: H.O.N.K mechs but with no bananium required.", + "Best idea ever: Disposal pipes instead of hallways.", + "What if we use a language that was written on a napkin and created over 1 weekend for all of our servers?", + "What if we took a locker, some random trash, and made an exosuit out of it? Wouldn't that be like, super cool and stuff?", + "Okay, hear me out, what if we make illegal things not illegal, so that sec stops arresting us for having it?", + "I have a crazy idea, guys. Rather than having monkeys to test on, what if we only used apes?", + "Woh man ok, what if we took slime cores and smashed them into other slimes, be kinda cool to see what happens.", + "We're NANOtrasen but we need to unlock nano parts, what's the deal with that?" + )) //this updates all special effects: stun, sleeping, knockdown, druggy, stuttering, etc.. /mob/living/carbon/handle_status_effects() diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index db5771f75e..ced9fa3200 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -563,7 +563,7 @@ SetAllImmobility(0, FALSE) SetSleeping(0, FALSE) radiation = 0 - nutrition = NUTRITION_LEVEL_FED + 50 + set_nutrition(NUTRITION_LEVEL_FED + 50) bodytemperature = BODYTEMP_NORMAL set_blindness(0) set_blurriness(0) diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 508dc67dd7..98a5f0f234 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -3,122 +3,7 @@ real_name = "Cyborg" icon = 'icons/mob/robots.dmi' icon_state = "robot" - maxHealth = 100 - health = 100 bubble_icon = "robot" - designation = "Default" //used for displaying the prefix & getting the current module of cyborg - has_limbs = 1 - hud_type = /datum/hud/robot - - blocks_emissive = EMISSIVE_BLOCK_UNIQUE - - var/custom_name = "" - var/braintype = "Cyborg" - var/obj/item/robot_suit/robot_suit = null //Used for deconstruction to remember what the borg was constructed out of.. - var/obj/item/mmi/mmi = null - - var/shell = FALSE - var/deployed = FALSE - var/mob/living/silicon/ai/mainframe = null - var/datum/action/innate/undeployment/undeployment_action = new - -//Hud stuff - - var/obj/screen/inv1 = null - var/obj/screen/inv2 = null - var/obj/screen/inv3 = null - var/obj/screen/lamp_button = null - var/obj/screen/thruster_button = null - var/obj/screen/hands = null - - var/shown_robot_modules = 0 //Used to determine whether they have the module menu shown or not - var/obj/screen/robot_modules_background - -//3 Modules can be activated at any one time. - var/obj/item/robot_module/module = null - var/obj/item/module_active = null - held_items = list(null, null, null) //we use held_items for the module holding, because that makes sense to do! - - var/mutable_appearance/eye_lights - - var/mob/living/silicon/ai/connected_ai = null - var/obj/item/stock_parts/cell/cell = null - - var/opened = 0 - var/emagged = FALSE - var/emag_cooldown = 0 - var/wiresexposed = 0 - - var/ident = 0 - var/locked = TRUE - var/list/req_access = list(ACCESS_ROBOTICS) - - var/alarms = list("Motion"=list(), "Fire"=list(), "Atmosphere"=list(), "Power"=list(), "Camera"=list(), "Burglar"=list()) - - var/speed = 0 // VTEC speed boost. - var/magpulse = FALSE // Magboot-like effect. - var/ionpulse = FALSE // Jetpack-like effect. - var/ionpulse_on = FALSE // Jetpack-like effect. - var/datum/effect_system/trail_follow/ion/ion_trail // Ionpulse effect. - - var/low_power_mode = 0 //whether the robot has no charge left. - var/datum/effect_system/spark_spread/spark_system // So they can initialize sparks whenever/N - - var/lawupdate = 1 //Cyborgs will sync their laws with their AI by default - var/scrambledcodes = 0 // Used to determine if a borg shows up on the robotics console. Setting to one hides them. - var/locked_down //Boolean of whether the borg is locked down or not - - var/toner = 0 - var/tonermax = 40 - - var/lamp_max = 10 //Maximum brightness of a borg lamp. Set as a var for easy adjusting. - var/lamp_intensity = 0 //Luminosity of the headlamp. 0 is off. Higher settings than the minimum require power. - light_color = "#FFCC66" - light_power = 0.8 - var/lamp_cooldown = 0 //Flag for if the lamp is on cooldown after being forcibly disabled. - - var/sight_mode = 0 - hud_possible = list(ANTAG_HUD, DIAG_STAT_HUD, DIAG_HUD, DIAG_BATT_HUD, DIAG_TRACK_HUD) - - var/list/upgrades = list() - - var/hasExpanded = FALSE - var/obj/item/hat - var/hat_offset = -3 - var/list/equippable_hats = list(/obj/item/clothing/head/caphat, - /obj/item/clothing/head/hardhat, - /obj/item/clothing/head/centhat, - /obj/item/clothing/head/HoS, - /obj/item/clothing/head/beret, - /obj/item/clothing/head/kitty, - /obj/item/clothing/head/hopcap, - /obj/item/clothing/head/wizard, - /obj/item/clothing/head/nursehat, - /obj/item/clothing/head/sombrero, - /obj/item/clothing/head/helmet/chaplain/witchunter_hat, - /obj/item/clothing/head/soft/, //All baseball caps - /obj/item/clothing/head/that, //top hat - /obj/item/clothing/head/collectable/tophat, //Not sure where this one is found, but it looks the same so might as well include - /obj/item/clothing/mask/bandana/, //All bandanas (which only work in hat mode) - /obj/item/clothing/head/fedora, - /obj/item/clothing/head/beanie/, //All beanies - /obj/item/clothing/ears/headphones, - /obj/item/clothing/head/helmet/skull, - /obj/item/clothing/head/crown/fancy) - - can_buckle = TRUE - buckle_lying = FALSE - var/static/list/can_ride_typecache = typecacheof(/mob/living/carbon/human) - - var/sitting = 0 - var/bellyup = 0 - var/dogborg = FALSE - - var/cansprint = 1 - - var/orebox = null - -/mob/living/silicon/robot /mob/living/silicon/robot/get_cell() return cell diff --git a/code/modules/mob/living/silicon/robot/robot_defines.dm b/code/modules/mob/living/silicon/robot/robot_defines.dm new file mode 100644 index 0000000000..860d531608 --- /dev/null +++ b/code/modules/mob/living/silicon/robot/robot_defines.dm @@ -0,0 +1,123 @@ + +/mob/living/silicon/robot + designation = "Default" //used for displaying the prefix & getting the current module of cyborg + has_limbs = TRUE + hud_type = /datum/hud/robot + + blocks_emissive = EMISSIVE_BLOCK_UNIQUE + + maxHealth = 100 + health = 100 + + var/custom_name = "" + var/braintype = "Cyborg" + var/obj/item/robot_suit/robot_suit = null //Used for deconstruction to remember what the borg was constructed out of.. + var/obj/item/mmi/mmi = null + + var/shell = FALSE + var/deployed = FALSE + var/mob/living/silicon/ai/mainframe = null + var/datum/action/innate/undeployment/undeployment_action = new + +//Hud stuff + + var/obj/screen/inv1 = null + var/obj/screen/inv2 = null + var/obj/screen/inv3 = null + var/obj/screen/lamp_button = null + var/obj/screen/thruster_button = null + var/obj/screen/hands = null + + var/shown_robot_modules = 0 //Used to determine whether they have the module menu shown or not + var/obj/screen/robot_modules_background + +//3 Modules can be activated at any one time. + var/obj/item/robot_module/module = null + var/obj/item/module_active = null + held_items = list(null, null, null) //we use held_items for the module holding, because that makes sense to do! + + var/mutable_appearance/eye_lights + + var/mob/living/silicon/ai/connected_ai = null + var/obj/item/stock_parts/cell/cell = null + + var/opened = 0 + var/emagged = FALSE + var/emag_cooldown = 0 + var/wiresexposed = 0 + + var/ident = 0 + var/locked = TRUE + var/list/req_access = list(ACCESS_ROBOTICS) + + var/alarms = list("Motion"=list(), "Fire"=list(), "Atmosphere"=list(), "Power"=list(), "Camera"=list(), "Burglar"=list()) + + var/speed = 0 // VTEC speed boost. + var/magpulse = FALSE // Magboot-like effect. + var/ionpulse = FALSE // Jetpack-like effect. + var/ionpulse_on = FALSE // Jetpack-like effect. + var/datum/effect_system/trail_follow/ion/ion_trail // Ionpulse effect. + + var/low_power_mode = 0 //whether the robot has no charge left. + var/datum/effect_system/spark_spread/spark_system // So they can initialize sparks whenever/N + + var/lawupdate = 1 //Cyborgs will sync their laws with their AI by default + var/scrambledcodes = 0 // Used to determine if a borg shows up on the robotics console. Setting to one hides them. + var/locked_down //Boolean of whether the borg is locked down or not + + var/toner = 0 + var/tonermax = 40 + + var/lamp_max = 10 //Maximum brightness of a borg lamp. Set as a var for easy adjusting. + var/lamp_intensity = 0 //Luminosity of the headlamp. 0 is off. Higher settings than the minimum require power. + light_color = "#FFCC66" + light_power = 0.8 + var/lamp_cooldown = 0 //Flag for if the lamp is on cooldown after being forcibly disabled. + + var/sight_mode = 0 + hud_possible = list(ANTAG_HUD, DIAG_STAT_HUD, DIAG_HUD, DIAG_BATT_HUD, DIAG_TRACK_HUD) + + var/list/upgrades = list() + + var/hasExpanded = FALSE + var/obj/item/hat + var/hat_offset = -3 + var/list/equippable_hats = list(/obj/item/clothing/head/caphat, + /obj/item/clothing/head/hardhat, + /obj/item/clothing/head/centhat, + /obj/item/clothing/head/HoS, + /obj/item/clothing/head/beret, + /obj/item/clothing/head/kitty, + /obj/item/clothing/head/hopcap, + /obj/item/clothing/head/wizard, + /obj/item/clothing/head/nursehat, + /obj/item/clothing/head/sombrero, + /obj/item/clothing/head/helmet/chaplain/witchunter_hat, + /obj/item/clothing/head/soft/, //All baseball caps + /obj/item/clothing/head/that, //top hat + /obj/item/clothing/head/collectable/tophat, //Not sure where this one is found, but it looks the same so might as well include + /obj/item/clothing/mask/bandana/, //All bandanas (which only work in hat mode) + /obj/item/clothing/head/fedora, + /obj/item/clothing/head/beanie/, //All beanies + /obj/item/clothing/ears/headphones, + /obj/item/clothing/head/helmet/skull, + /obj/item/clothing/head/crown/fancy) + + can_buckle = TRUE + buckle_lying = FALSE + var/static/list/can_ride_typecache = typecacheof(/mob/living/carbon/human) + + var/sitting = 0 + var/bellyup = 0 + var/dogborg = FALSE + + var/cansprint = 1 + + var/orebox = null + + //doggie borg stuff. + var/disabler + var/laser + var/sleeper_g + var/sleeper_r + var/sleeper_nv \ No newline at end of file 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/mob/living/simple_animal/hostile/mining_mobs/ice_demon.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/ice_demon.dm index 7b9abd2b13..88ee27fcc9 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/ice_demon.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/ice_demon.dm @@ -55,8 +55,9 @@ if(isclosedturf(T)) continue possible_ends |= T - var/turf/end = pick(possible_ends) - do_teleport(src, end, 0, channel=TELEPORT_CHANNEL_BLUESPACE, forced = TRUE) + if(length(possible_ends)) + var/turf/end = pick(possible_ends) + do_teleport(src, end, 0, channel=TELEPORT_CHANNEL_BLUESPACE, forced = TRUE) SLEEP_CHECK_DEATH(8) return ..() diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/mining_mobs.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/mining_mobs.dm index 71c6d61d5d..6ad869afe6 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/mining_mobs.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/mining_mobs.dm @@ -63,7 +63,7 @@ ..(gibbed) /mob/living/simple_animal/hostile/asteroid/proc/spawn_crusher_loot() - butcher_results[crusher_loot] = 1 + LAZYSET(butcher_results, crusher_loot, 1) /mob/living/simple_animal/hostile/asteroid/handle_temperature_damage() if(bodytemperature < minbodytemp) diff --git a/code/modules/mob/living/simple_animal/slime/life.dm b/code/modules/mob/living/simple_animal/slime/life.dm index 4b89d96e64..08a5f0a2c9 100644 --- a/code/modules/mob/living/simple_animal/slime/life.dm +++ b/code/modules/mob/living/simple_animal/slime/life.dm @@ -232,7 +232,7 @@ Feedstop(0, 0) return - add_nutrition((rand(7, 15) * CONFIG_GET(number/damage_multiplier))) + adjust_nutrition((rand(7, 15) * CONFIG_GET(number/damage_multiplier)), get_max_nutrition(), TRUE) //Heal yourself. adjustBruteLoss(-3) @@ -244,15 +244,13 @@ return if(prob(15)) - nutrition -= 1 + is_adult + adjust_nutrition(-1 - is_adult) - if(nutrition <= 0) - nutrition = 0 - if(prob(75)) - adjustBruteLoss(rand(0,5)) + if(nutrition <= 0 && prob(75)) + adjustBruteLoss(rand(0,5)) else if (nutrition >= get_grow_nutrition() && amount_grown < SLIME_EVOLUTION_THRESHOLD) - nutrition -= 20 + adjust_nutrition(-20) amount_grown++ update_action_buttons_icon() @@ -262,9 +260,11 @@ else Evolve() -/mob/living/simple_animal/slime/proc/add_nutrition(nutrition_to_add = 0) - nutrition = min((nutrition + nutrition_to_add), get_max_nutrition()) - if(nutrition >= get_grow_nutrition()) +/mob/living/simple_animal/slime/adjust_nutrition(change, max = INFINITY, slime_check = FALSE) + . = ..() + if(!slime_check) + return + if(nutrition == max) if(powerlevel<10) if(prob(30-powerlevel*2)) powerlevel++ diff --git a/code/modules/mob/living/simple_animal/slime/powers.dm b/code/modules/mob/living/simple_animal/slime/powers.dm index d5da6d76fc..0c7f126ad5 100644 --- a/code/modules/mob/living/simple_animal/slime/powers.dm +++ b/code/modules/mob/living/simple_animal/slime/powers.dm @@ -184,7 +184,7 @@ var/mob/living/simple_animal/slime/M M = new(loc, child_colour) if(ckey) - M.nutrition = new_nutrition //Player slimes are more robust at spliting. Once an oversight of poor copypasta, now a feature! + M.set_nutrition(new_nutrition) //Player slimes are more robust at spliting. Once an oversight of poor copypasta, now a feature! M.powerlevel = new_powerlevel if(i != 1) step_away(M,src) diff --git a/code/modules/mob/living/simple_animal/slime/slime.dm b/code/modules/mob/living/simple_animal/slime/slime.dm index 78f7b17616..1c5916a249 100644 --- a/code/modules/mob/living/simple_animal/slime/slime.dm +++ b/code/modules/mob/living/simple_animal/slime/slime.dm @@ -27,6 +27,7 @@ healable = 0 gender = NEUTER blood_volume = 0 //Until someome reworks for them to have slime jelly + nutrition = 700 see_in_dark = 8 @@ -102,7 +103,6 @@ create_reagents(100, NONE, NO_REAGENTS_VALUE) set_colour(new_colour) . = ..() - nutrition = 700 /mob/living/simple_animal/slime/Destroy() for (var/A in actions) @@ -267,8 +267,8 @@ return attacked += 5 if(nutrition >= 100) //steal some nutrition. negval handled in life() - nutrition -= (50 + (40 * M.is_adult)) - M.add_nutrition(50 + (40 * M.is_adult)) + adjust_nutrition(-50 - (40 * M.is_adult)) + M.adjust_nutrition(50 + (40 * M.is_adult), get_max_nutrition(), TRUE) if(health > 0) M.adjustBruteLoss(-10 + (-10 * M.is_adult)) M.updatehealth() diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index ce3b8bf3d2..6e4bd534af 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -35,7 +35,7 @@ continue var/datum/atom_hud/alternate_appearance/AA = v AA.onNewMob(src) - nutrition = rand(NUTRITION_LEVEL_START_MIN, NUTRITION_LEVEL_START_MAX) + set_nutrition(rand(NUTRITION_LEVEL_START_MIN, NUTRITION_LEVEL_START_MAX)) . = ..() update_config_movespeed() update_movespeed(TRUE) @@ -1023,6 +1023,14 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0) var/datum/language_holder/H = get_language_holder() H.open_language_menu(usr) +///Adjust the nutrition of a mob +/mob/proc/adjust_nutrition(change, max = INFINITY) //Honestly FUCK the oldcoders for putting nutrition on /mob someone else can move it up because holy hell I'd have to fix SO many typechecks + nutrition = clamp(0, nutrition + change, max) + +///Force set the mob nutrition +/mob/proc/set_nutrition(var/change) //Seriously fuck you oldcoders. + nutrition = max(0, change) + /mob/setMovetype(newval) . = ..() update_movespeed(FALSE) diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index ce017ea0cc..d9a6adbb3f 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -459,7 +459,7 @@ var/list/babies = list() for(var/i=1,i<=number,i++) var/mob/living/simple_animal/slime/M = new/mob/living/simple_animal/slime(loc) - M.nutrition = round(nutrition/number) + M.set_nutrition(round(nutrition/number)) step_away(M,src) babies += M new_slime = pick(babies) 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 ffda79dabc..ee9def4191 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 7d314a3726..c2be8ec8a4 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/chemistry/reagents/alcohol_reagents.dm b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm index 464557f617..b22f34091f 100644 --- a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm @@ -1834,7 +1834,7 @@ All effects don't start immediately, but rather get worse over time; the rate is /datum/reagent/consumable/ethanol/fernet/on_mob_life(mob/living/carbon/M) if(M.nutrition <= NUTRITION_LEVEL_STARVING) M.adjustToxLoss(1*REM, 0) - M.nutrition = max(M.nutrition - 5, 0) + M.adjust_nutrition(-5) M.overeatduration = 0 return ..() @@ -1852,7 +1852,7 @@ All effects don't start immediately, but rather get worse over time; the rate is /datum/reagent/consumable/ethanol/fernet_cola/on_mob_life(mob/living/carbon/M) if(M.nutrition <= NUTRITION_LEVEL_STARVING) M.adjustToxLoss(0.5*REM, 0) - M.nutrition = max(M.nutrition - 3, 0) + M.adjust_nutrition(-3) M.overeatduration = 0 return ..() @@ -1868,7 +1868,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_desc = "A glass of Fanciulli. It's just Manhattan with Fernet." /datum/reagent/consumable/ethanol/fanciulli/on_mob_life(mob/living/carbon/M) - M.nutrition = max(M.nutrition - 5, 0) + M.adjust_nutrition(-5) M.overeatduration = 0 return ..() diff --git a/code/modules/reagents/chemistry/reagents/drink_reagents.dm b/code/modules/reagents/chemistry/reagents/drink_reagents.dm index 62aea28009..b157f328c5 100644 --- a/code/modules/reagents/chemistry/reagents/drink_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/drink_reagents.dm @@ -692,9 +692,8 @@ M.adjustFireLoss(-0.5, 0) M.adjustToxLoss(-0.5, 0) M.adjustOxyLoss(-0.5, 0) - if(M.nutrition && (M.nutrition - 2 > 0)) - if(!(M.mind && M.mind.assigned_role == "Medical Doctor")) //Drains the nutrition of the holder. Not medical doctors though, since it's the Doctor's Delight! - M.nutrition -= 2 + if(!(M.mind && M.mind.assigned_role == "Medical Doctor")) //Drains the nutrition of the holder. Not medical doctors though, since it's the Doctor's Delight! + M.adjust_nutrition(-2) ..() . = 1 diff --git a/code/modules/reagents/chemistry/reagents/food_reagents.dm b/code/modules/reagents/chemistry/reagents/food_reagents.dm index c7ff3f01c9..0e0056f958 100644 --- a/code/modules/reagents/chemistry/reagents/food_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/food_reagents.dm @@ -13,11 +13,12 @@ taste_mult = 4 value = REAGENT_VALUE_VERY_COMMON var/nutriment_factor = 1 * REAGENTS_METABOLISM + var/max_nutrition = INFINITY var/quality = 0 //affects mood, typically higher for mixed drinks with more complex recipes /datum/reagent/consumable/on_mob_life(mob/living/carbon/M) current_cycle++ - M.nutrition += nutriment_factor + M.adjust_nutrition(nutriment_factor, max_nutrition) M.CheckBloodsuckerEatFood(nutriment_factor) holder.remove_reagent(type, metabolization_rate) @@ -694,13 +695,10 @@ description = "A bioengineered protien-nutrient structure designed to decompose in high saturation. In layman's terms, it won't get you fat." reagent_state = SOLID nutriment_factor = 12 * REAGENTS_METABOLISM + max_nutrition = NUTRITION_LEVEL_FULL - 25 color = "#664330" // rgb: 102, 67, 48 value = REAGENT_VALUE_RARE -/datum/reagent/consumable/nutriment/stabilized/on_mob_life(mob/living/carbon/M) - if(M.nutrition > NUTRITION_LEVEL_FULL - 25) - M.nutrition -= 3*nutriment_factor - ..() ////Lavaland Flora Reagents//// diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm index e4973dd2d5..7913b24218 100644 --- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm @@ -413,7 +413,7 @@ datum/reagent/medicine/styptic_powder/overdose_start(mob/living/M) /datum/reagent/medicine/mine_salve/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message = 1) if(iscarbon(M) && M.stat != DEAD) if(method in list(INGEST, VAPOR, INJECT)) - M.nutrition -= 5 + M.adjust_nutrition(-5) if(show_message) to_chat(M, "Your stomach feels empty and cramps!") else @@ -1218,15 +1218,15 @@ datum/reagent/medicine/styptic_powder/overdose_start(mob/living/M) value = REAGENT_VALUE_VERY_RARE /datum/reagent/medicine/lesser_syndicate_nanites/on_mob_life(mob/living/carbon/M) - M.adjustBruteLoss(-3*REM, FALSE) // hidden gold shh - M.adjustFireLoss(-3*REM, FALSE) - M.adjustOxyLoss(-15, FALSE) - M.adjustToxLoss(-3*REM, FALSE) - M.adjustOrganLoss(ORGAN_SLOT_BRAIN, -15*REM) - M.adjustCloneLoss(-3*REM, FALSE) - M.adjustStaminaLoss(-20*REM,FALSE) + M.adjustBruteLoss(-2*REM, FALSE) + M.adjustFireLoss(-2*REM, FALSE) + M.adjustOxyLoss(-5*REM, FALSE) + M.adjustToxLoss(-2*REM, FALSE) + M.adjustOrganLoss(ORGAN_SLOT_BRAIN, -5*REM) + M.adjustCloneLoss(-1.25*REM, FALSE) + M.adjustStaminaLoss(-4*REM,FALSE) if(M.blood_volume < (BLOOD_VOLUME_NORMAL*M.blood_ratio)) - M.blood_volume += 20 // blood fall out man bad + M.blood_volume += 3 ..() . = 1 diff --git a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm index 3169d2d3aa..141367c9d9 100644 --- a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm @@ -675,7 +675,7 @@ /datum/reagent/toxin/lipolicide/on_mob_life(mob/living/carbon/M) if(M.nutrition <= NUTRITION_LEVEL_STARVING) M.adjustToxLoss(1*REM, 0) - M.nutrition = max(M.nutrition - 3, 0) // making the chef more valuable, one meme trap at a time + M.adjust_nutrition(-3) // making the chef more valuable, one meme trap at a time M.overeatduration = 0 return ..() 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/nanites/nanite_programs/utility.dm b/code/modules/research/nanites/nanite_programs/utility.dm index 71aa5bf09a..ebe623d73d 100644 --- a/code/modules/research/nanites/nanite_programs/utility.dm +++ b/code/modules/research/nanites/nanite_programs/utility.dm @@ -144,7 +144,7 @@ return ..() /datum/nanite_program/metabolic_synthesis/active_effect() - host_mob.nutrition -= 0.5 + host_mob.adjust_nutrition(-0.5) nanites.adjust_nanites(src, 0.5) /datum/nanite_program/research 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/research/xenobiology/crossbreeding/_status_effects.dm b/code/modules/research/xenobiology/crossbreeding/_status_effects.dm index 16263928c4..ed43576a61 100644 --- a/code/modules/research/xenobiology/crossbreeding/_status_effects.dm +++ b/code/modules/research/xenobiology/crossbreeding/_status_effects.dm @@ -917,7 +917,7 @@ datum/status_effect/stabilized/blue/on_remove() healing_types += CLONE if(length(healing_types)) owner.apply_damage_type(-heal_amount, damagetype=pick(healing_types)) - owner.nutrition += 3 + owner.adjust_nutrition(3) M.adjustCloneLoss(heal_amount * 1.2) //This way, two people can't just convert each other's damage away. else messagedelivered = FALSE diff --git a/code/modules/research/xenobiology/crossbreeding/burning.dm b/code/modules/research/xenobiology/crossbreeding/burning.dm index 48e6f720b0..7b5004e722 100644 --- a/code/modules/research/xenobiology/crossbreeding/burning.dm +++ b/code/modules/research/xenobiology/crossbreeding/burning.dm @@ -35,7 +35,7 @@ Burning extracts: S.visible_message("A baby slime emerges from [src], and it nuzzles [user] before burbling hungrily!") S.Friends[user] = 20 //Gas, gas, gas S.bodytemperature = T0C + 400 //We gonna step on the gas. - S.nutrition = S.get_hunger_nutrition() //Tonight, we fight! + S.set_nutrition(S.get_hunger_nutrition()) //Tonight, we fight! ..() /obj/item/slimecross/burning/orange diff --git a/code/modules/research/xenobiology/crossbreeding/regenerative.dm b/code/modules/research/xenobiology/crossbreeding/regenerative.dm index b33cee3a64..6b2b0b458c 100644 --- a/code/modules/research/xenobiology/crossbreeding/regenerative.dm +++ b/code/modules/research/xenobiology/crossbreeding/regenerative.dm @@ -128,7 +128,7 @@ Regenerative extracts: colour = "silver" /obj/item/slimecross/regenerative/silver/core_effect(mob/living/target, mob/user) - target.nutrition = NUTRITION_LEVEL_FULL - 1 + target.set_nutrition(NUTRITION_LEVEL_FULL - 1) to_chat(target, "You feel satiated.") /obj/item/slimecross/regenerative/bluespace diff --git a/code/modules/research/xenobiology/xenobiology.dm b/code/modules/research/xenobiology/xenobiology.dm index 65e1f80ed0..bc78e3ab1a 100644 --- a/code/modules/research/xenobiology/xenobiology.dm +++ b/code/modules/research/xenobiology/xenobiology.dm @@ -186,7 +186,7 @@ /obj/item/slime_extract/purple/activate(mob/living/carbon/human/user, datum/species/jelly/luminescent/species, activation_type) switch(activation_type) if(SLIME_ACTIVATE_MINOR) - user.nutrition += 50 + user.adjust_nutrition(50) user.blood_volume += 50 to_chat(user, "You activate [src], and your body is refilled with fresh slime jelly!") return 150 @@ -636,7 +636,7 @@ qdel(src) return M.docile = 1 - M.nutrition = 700 + M.set_nutrition(700) to_chat(M, "You absorb the potion and feel your intense desire to feed melt away.") to_chat(user, "You feed the slime the potion, removing its hunger and calming it.") var/newname = reject_bad_name(stripped_input(user, "Would you like to give the slime a name?", "Name your new pet", "pet slime", MAX_NAME_LEN), TRUE) 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/surgery/lipoplasty.dm b/code/modules/surgery/lipoplasty.dm index 63e828d3c9..5a0fd819f1 100644 --- a/code/modules/surgery/lipoplasty.dm +++ b/code/modules/surgery/lipoplasty.dm @@ -40,7 +40,7 @@ "[user] extracts [target]'s fat!") target.overeatduration = 0 //patient is unfatted var/removednutriment = target.nutrition - target.nutrition = NUTRITION_LEVEL_WELL_FED + target.set_nutrition(NUTRITION_LEVEL_WELL_FED) removednutriment -= 450 //whatever was removed goes into the meat var/mob/living/carbon/human/H = target var/typeofmeat = /obj/item/reagent_containers/food/snacks/meat/slab/human diff --git a/code/modules/surgery/organs/augments_chest.dm b/code/modules/surgery/organs/augments_chest.dm index 46092ff0c2..fcc3f71b8b 100644 --- a/code/modules/surgery/organs/augments_chest.dm +++ b/code/modules/surgery/organs/augments_chest.dm @@ -23,7 +23,7 @@ if(owner.nutrition <= hunger_threshold) synthesizing = TRUE to_chat(owner, "You feel less hungry...") - owner.nutrition += 50 + owner.adjust_nutrition(50) addtimer(CALLBACK(src, .proc/synth_cool), 50) /obj/item/organ/cyberimp/chest/nutriment/proc/synth_cool() diff --git a/code/modules/surgery/organs/heart.dm b/code/modules/surgery/organs/heart.dm index 1fee605b12..465c10c4cd 100644 --- a/code/modules/surgery/organs/heart.dm +++ b/code/modules/surgery/organs/heart.dm @@ -221,7 +221,7 @@ obj/item/organ/heart/cybernetic/upgraded/on_life() used_dose() if(ramount < 10) //eats your nutrition to regen epinephrine var/regen_amount = owner.nutrition/2000 - owner.nutrition -= regen_amount + owner.adjust_nutrition(-regen_amount) ramount += regen_amount /obj/item/organ/heart/cybernetic/upgraded/proc/used_dose() 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 13a2f2e9a0..34c9666d85 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/code/modules/vore/eating/belly_obj.dm b/code/modules/vore/eating/belly_obj.dm index b188cc0a99..685f8d76bb 100644 --- a/code/modules/vore/eating/belly_obj.dm +++ b/code/modules/vore/eating/belly_obj.dm @@ -512,7 +512,7 @@ if(!digested) items_preserved |= item else -// owner.nutrition += (5 * digested) // haha no. +// owner.adjust_nutrition(5 * digested) // haha no. if(iscyborg(owner)) var/mob/living/silicon/robot/R = owner R.cell.charge += (50 * digested) diff --git a/code/modules/vore/eating/bellymodes.dm b/code/modules/vore/eating/bellymodes.dm index 2caaae401e..77864021b4 100644 --- a/code/modules/vore/eating/bellymodes.dm +++ b/code/modules/vore/eating/bellymodes.dm @@ -98,7 +98,7 @@ to_chat(M, "[digest_alert_prey]") M.visible_message("You watch as [owner]'s form loses its additions.") - owner.nutrition += 400 // so eating dead mobs gives you *something*. + owner.adjust_nutrition(400) // so eating dead mobs gives you *something*. play_sound = pick(pred_death) if(M && M.client && M.client.prefs.cit_toggles & DIGESTION_NOISES) SEND_SOUND(M,prey_death) @@ -112,7 +112,7 @@ // Deal digestion damage (and feed the pred) if(!(M.status_flags & GODMODE)) M.adjustFireLoss(digest_burn) - owner.nutrition += 1 + owner.adjust_nutrition(1) //Contaminate or gurgle items var/obj/item/T = pick(touchable_items) @@ -130,7 +130,7 @@ if(owner.nutrition >= NUTRITION_LEVEL_STARVING && (M.health < M.maxHealth)) M.adjustBruteLoss(-3) M.adjustFireLoss(-3) - owner.nutrition -= 5 + owner.adjust_nutrition(-5) //for when you just want people to squelch around if(DM_NOISY) @@ -155,8 +155,8 @@ if(M.nutrition >= 100) //Drain them until there's no nutrients left. Slowly "absorb" them. var/oldnutrition = (M.nutrition * 0.05) - M.nutrition = (M.nutrition * 0.95) - owner.nutrition += oldnutrition + M.set_nutrition(M.nutrition * 0.95) + owner.adjust_nutrition(oldnutrition) else if(M.nutrition < 100) //When they're finally drained. absorb_living(M) to_update = TRUE @@ -168,7 +168,7 @@ DISABLE_BITFIELD(M.vore_flags, ABSORBED) to_chat(M,"You suddenly feel solid again ") to_chat(owner,"You feel like a part of you is missing.") - owner.nutrition -= 100 + owner.adjust_nutrition(-100) to_update = TRUE //because dragons need snowflake guts diff --git a/code/modules/zombie/items.dm b/code/modules/zombie/items.dm index 0f6ef14cd1..d4d92f54c4 100644 --- a/code/modules/zombie/items.dm +++ b/code/modules/zombie/items.dm @@ -74,4 +74,4 @@ user.adjustCloneLoss(-hp_gained, 0) user.updatehealth() user.adjustOrganLoss(ORGAN_SLOT_BRAIN, -hp_gained) // Zom Bee gibbers "BRAAAAISNSs!1!" - user.nutrition = min(user.nutrition + hp_gained, NUTRITION_LEVEL_FULL) + user.adjust_nutrition(hp_gained, NUTRITION_LEVEL_FULL) 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/misc/language.dmi b/icons/misc/language.dmi index 3b4ac1a16a..155dbab98d 100644 Binary files a/icons/misc/language.dmi and b/icons/misc/language.dmi differ diff --git a/icons/mob/dogborg.dmi b/icons/mob/dogborg.dmi deleted file mode 100644 index 856724be1f..0000000000 Binary files a/icons/mob/dogborg.dmi and /dev/null differ diff --git a/icons/mob/robot_items.dmi b/icons/mob/robot_items.dmi index 862e1be384..06521f1a84 100644 Binary files a/icons/mob/robot_items.dmi and b/icons/mob/robot_items.dmi differ 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/modular_citadel/code/modules/language/sylvan.dm b/modular_citadel/code/modules/language/sylvan.dm deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/modular_citadel/code/modules/mob/living/silicon/robot/dogborg_equipment.dm b/modular_citadel/code/modules/mob/living/silicon/robot/dogborg_equipment.dm deleted file mode 100644 index d5d1e56485..0000000000 --- a/modular_citadel/code/modules/mob/living/silicon/robot/dogborg_equipment.dm +++ /dev/null @@ -1,459 +0,0 @@ -/* -DOG BORG EQUIPMENT HERE -SLEEPER CODE IS IN game/objects/items/devices/dogborg_sleeper.dm ! -*/ - -/obj/item/dogborg/jaws - name = "Dogborg jaws" - desc = "The jaws of the debug errors oh god." - icon = 'icons/mob/dogborg.dmi' - flags_1 = CONDUCT_1 - force = 1 - throwforce = 0 - w_class = 3 - hitsound = 'sound/weapons/bite.ogg' - sharpness = IS_SHARP - var/stamtostunconversion = 0.1 //Total stamloss gets multiplied by this value for the help intent hard stun. Resting adds an additional 2x multiplier on top. Keep this low or so help me god. - var/stuncooldown = 4 SECONDS //How long it takes before you're able to attempt to stun a target again - var/nextstuntime - -/obj/item/dogborg/jaws/examine(mob/user) - . = ..() - if(!CONFIG_GET(flag/weaken_secborg)) - . += "Use help intent to attempt to non-lethally incapacitate the target by latching on with your maw. This is more effective against exhausted and resting targets." - -/obj/item/dogborg/jaws/big - name = "combat jaws" - desc = "The jaws of the law. Very sharp." - icon_state = "jaws" - force = 15 //Chomp chomp. Crew harm. - attack_verb = list("chomped", "bit", "ripped", "mauled", "enforced") - stamtostunconversion = 0.2 // 100*0.2*2=40. Stun's just long enough to slap on cuffs with click delay if the target is near hard stamcrit. - stuncooldown = 6 SECONDS - - -/obj/item/dogborg/jaws/small - name = "puppy jaws" - desc = "Rubberized teeth designed to protect accidental harm. Sharp enough for specialized tasks however." - icon_state = "smalljaws" - force = 6 - attack_verb = list("nibbled", "bit", "gnawed", "chomped", "nommed") - var/status = 0 - -/obj/item/dogborg/jaws/attack(atom/A, mob/living/silicon/robot/user) - if(!istype(user)) - return - if(!CONFIG_GET(flag/weaken_secborg) && user.a_intent != INTENT_HARM && istype(A, /mob/living)) - if(A == user.pulling) - to_chat(user, "You already have [A] in your jaws.") - return - if(nextstuntime >= world.time) - to_chat(user, "Your jaw servos are still recharging.") - return - nextstuntime = world.time + stuncooldown - var/mob/living/M = A - var/cachedstam = M.getStaminaLoss() - var/totalstuntime = cachedstam * stamtostunconversion * (M.lying ? 2 : 1) - if(CHECK_MOBILITY(M, MOBILITY_STAND)) - M.DefaultCombatKnockdown(cachedstam*2) //BORK BORK. GET DOWN. - M.Stun(totalstuntime) - user.do_attack_animation(A, ATTACK_EFFECT_BITE) - user.start_pulling(M, TRUE) //Yip yip. Come with. - user.changeNext_move(CLICK_CD_MELEE) - M.visible_message("[user] clamps [user.p_their()] [src] onto [M] and latches on!", "[user] clamps [user.p_their()] [src] onto you and latches on!") - if(totalstuntime >= 4 SECONDS) - playsound(usr, 'sound/effects/k9_jaw_strong.ogg', 75, FALSE, 2) //Wuff wuff. Big stun. - else - playsound(usr, 'sound/effects/k9_jaw_weak.ogg', 50, TRUE, -1) //Arf arf. Pls buff. - else - . = ..() - user.do_attack_animation(A, ATTACK_EFFECT_BITE) - -/obj/item/dogborg/jaws/small/attack_self(mob/user) - var/mob/living/silicon/robot/R = user - if(R.cell && R.cell.charge > 100) - if(R.emagged && status == 0) - name = "combat jaws" - icon_state = "jaws" - desc = "The jaws of the law." - force = 12 - attack_verb = list("chomped", "bit", "ripped", "mauled", "enforced") - stamtostunconversion = 0.15 - stuncooldown = 5 SECONDS - status = 1 - to_chat(user, "Your jaws are now [status ? "Combat" : "Pup'd"].") - else - name = "puppy jaws" - icon_state = "smalljaws" - desc = "The jaws of a small dog." - force = initial(force) - attack_verb = list("nibbled", "bit", "gnawed", "chomped", "nommed") - stamtostunconversion = initial(stamtostunconversion) - stuncooldown = initial(stuncooldown) - status = 0 - if(R.emagged) - to_chat(user, "Your jaws are now [status ? "Combat" : "Pup'd"].") - update_icon() - -//Boop - -/obj/item/analyzer/nose - name = "boop module" - icon = 'icons/mob/dogborg.dmi' - icon_state = "nose" - desc = "The BOOP module" - flags_1 = CONDUCT_1 - force = 0 - throwforce = 0 - attack_verb = list("nuzzles", "pushes", "boops") - w_class = 1 - -/obj/item/analyzer/nose/attack_self(mob/user) - user.visible_message("[user] sniffs around the air.", "You sniff the air for gas traces.") - - var/turf/location = user.loc - if(!istype(location)) - return - - var/datum/gas_mixture/environment = location.return_air() - - var/pressure = environment.return_pressure() - var/total_moles = environment.total_moles() - - to_chat(user, "Results:") - if(abs(pressure - ONE_ATMOSPHERE) < 10) - to_chat(user, "Pressure: [round(pressure,0.1)] kPa") - else - to_chat(user, "Pressure: [round(pressure,0.1)] kPa") - if(total_moles) - var/list/env_gases = environment.gases - - var/o2_concentration = env_gases[/datum/gas/oxygen]/total_moles - var/n2_concentration = env_gases[/datum/gas/nitrogen]/total_moles - var/co2_concentration = env_gases[/datum/gas/carbon_dioxide]/total_moles - var/plasma_concentration = env_gases[/datum/gas/plasma]/total_moles - GAS_GARBAGE_COLLECT(environment.gases) - - if(abs(n2_concentration - N2STANDARD) < 20) - to_chat(user, "Nitrogen: [round(n2_concentration*100, 0.01)] %") - else - to_chat(user, "Nitrogen: [round(n2_concentration*100, 0.01)] %") - - if(abs(o2_concentration - O2STANDARD) < 2) - to_chat(user, "Oxygen: [round(o2_concentration*100, 0.01)] %") - else - to_chat(user, "Oxygen: [round(o2_concentration*100, 0.01)] %") - - if(co2_concentration > 0.01) - to_chat(user, "CO2: [round(co2_concentration*100, 0.01)] %") - else - to_chat(user, "CO2: [round(co2_concentration*100, 0.01)] %") - - if(plasma_concentration > 0.005) - to_chat(user, "Plasma: [round(plasma_concentration*100, 0.01)] %") - else - to_chat(user, "Plasma: [round(plasma_concentration*100, 0.01)] %") - - - for(var/id in env_gases) - if(id in GLOB.hardcoded_gases) - continue - var/gas_concentration = env_gases[id]/total_moles - to_chat(user, "[GLOB.meta_gas_names[id]]: [round(gas_concentration*100, 0.01)] %") - to_chat(user, "Temperature: [round(environment.temperature-T0C)] °C") - -/obj/item/analyzer/nose/afterattack(atom/target, mob/user, proximity) - . = ..() - if(!proximity) - return - do_attack_animation(target, null, src) - user.visible_message("[user] [pick(attack_verb)] \the [target.name] with their nose!") - -//Delivery -/obj/item/storage/bag/borgdelivery - name = "fetching storage" - desc = "Fetch the thing!" - icon = 'icons/mob/dogborg.dmi' - icon_state = "dbag" - w_class = WEIGHT_CLASS_BULKY - -/obj/item/storage/bag/borgdelivery/ComponentInitialize() - . = ..() - var/datum/component/storage/STR = GetComponent(/datum/component/storage) - STR.max_w_class = WEIGHT_CLASS_BULKY - STR.max_combined_w_class = 5 - STR.max_items = 1 - STR.cant_hold = typecacheof(list(/obj/item/disk/nuclear, /obj/item/radio/intercom)) - -//Tongue stuff -/obj/item/soap/tongue - name = "synthetic tongue" - desc = "Useful for slurping mess off the floor before affectionally licking the crew members in the face." - icon = 'icons/mob/dogborg.dmi' - icon_state = "synthtongue" - hitsound = 'sound/effects/attackblob.ogg' - cleanspeed = 80 - var/status = 0 - -/obj/item/soap/tongue/scrubpup - cleanspeed = 25 //slightly faster than a mop. - -/obj/item/soap/tongue/New() - ..() - item_flags |= NOBLUDGEON //No more attack messages - -/obj/item/soap/tongue/attack_self(mob/user) - var/mob/living/silicon/robot/R = user - if(R.cell && R.cell.charge > 100) - if(R.emagged && status == 0) - status = !status - name = "energized tongue" - desc = "Your tongue is energized for dangerously maximum efficency." - icon_state = "syndietongue" - to_chat(user, "Your tongue is now [status ? "Energized" : "Normal"].") - cleanspeed = 10 //(nerf'd)tator soap stat - else - status = 0 - name = "synthetic tongue" - desc = "Useful for slurping mess off the floor before affectionally licking the crew members in the face." - icon_state = "synthtongue" - cleanspeed = initial(cleanspeed) - if(R.emagged) - to_chat(user, "Your tongue is now [status ? "Energized" : "Normal"].") - update_icon() - -/obj/item/soap/tongue/afterattack(atom/target, mob/user, proximity) - var/mob/living/silicon/robot/R = user - if(!proximity || !check_allowed_items(target)) - return - if(R.client && (target in R.client.screen)) - to_chat(R, "You need to take that [target.name] off before cleaning it!") - else if(is_cleanable(target)) - R.visible_message("[R] begins to lick off \the [target.name].", "You begin to lick off \the [target.name]...") - if(do_after(R, src.cleanspeed, target = target)) - if(!in_range(src, target)) //Proximity is probably old news by now, do a new check. - return //If they moved away, you can't eat them. - to_chat(R, "You finish licking off \the [target.name].") - qdel(target) - R.cell.give(50) - else if(isobj(target)) //hoo boy. danger zone man - if(istype(target,/obj/item/trash)) - R.visible_message("[R] nibbles away at \the [target.name].", "You begin to nibble away at \the [target.name]...") - if(!do_after(R, src.cleanspeed, target = target)) - return //If they moved away, you can't eat them. - to_chat(R, "You finish off \the [target.name].") - qdel(target) - R.cell.give(250) - return - if(istype(target,/obj/item/stock_parts/cell)) - R.visible_message("[R] begins cramming \the [target.name] down its throat.", "You begin cramming \the [target.name] down your throat...") - if(!do_after(R, 50, target = target)) - return //If they moved away, you can't eat them. - to_chat(R, "You finish off \the [target.name].") - var/obj/item/stock_parts/cell/C = target - R.cell.charge = R.cell.charge + (C.charge / 3) //Instant full cell upgrades op idgaf - qdel(target) - return - var/obj/item/I = target //HAHA FUCK IT, NOT LIKE WE ALREADY HAVE A SHITTON OF WAYS TO REMOVE SHIT - if(!I.anchored && R.emagged) - R.visible_message("[R] begins chewing up \the [target.name]. Looks like it's trying to loophole around its diet restriction!", "You begin chewing up \the [target.name]...") - if(!do_after(R, 100, target = I)) //Nerf dat time yo - return //If they moved away, you can't eat them. - visible_message("[R] chews up \the [target.name] and cleans off the debris!") - to_chat(R, "You finish off \the [target.name].") - qdel(I) - R.cell.give(500) - return - R.visible_message("[R] begins to lick \the [target.name] clean...", "You begin to lick \the [target.name] clean...") - else if(isliving(target)) - var/mob/living/L = target - if(!status) - if(L.ckey && !(L.client?.prefs.vore_flags & LICKABLE)) - to_chat(R, "ERROR ERROR: Target not lickable. Aborting display-of-affection subroutine.") - return - if(check_zone(R.zone_selected) == "head") - R.visible_message("\the [R] affectionally licks \the [L]'s face!", "You affectionally lick \the [L]'s face!") - playsound(src.loc, 'sound/effects/attackblob.ogg', 50, 1) - if(istype(L) && L.fire_stacks > 0) - L.adjust_fire_stacks(-10) - else - R.visible_message("\the [R] affectionally licks \the [L]!", "You affectionally lick \the [L]!") - playsound(src.loc, 'sound/effects/attackblob.ogg', 50, 1) - if(istype(L) && L.fire_stacks > 0) - L.adjust_fire_stacks(-10) - else - if(R.cell.charge <= 800) - to_chat(R, "Insufficent Power!") - return - L.Stun(4) // normal stunbaton is force 7 gimme a break good sir! - L.DefaultCombatKnockdown(80) - L.apply_effect(EFFECT_STUTTER, 4) - L.visible_message("[R] has shocked [L] with its tongue!", \ - "[R] has shocked you with its tongue!") - playsound(loc, 'sound/weapons/Egloves.ogg', 50, 1, -1) - R.cell.use(666) - log_combat(R, L, "tongue stunned") - - else if(istype(target, /obj/structure/window)) - R.visible_message("[R] begins to lick \the [target.name] clean...", "You begin to lick \the [target.name] clean...") - if(do_after(user, src.cleanspeed, target = target)) - to_chat(user, "You clean \the [target.name].") - target.remove_atom_colour(WASHABLE_COLOUR_PRIORITY) - target.set_opacity(initial(target.opacity)) - else - R.visible_message("[R] begins to lick \the [target.name] clean...", "You begin to lick \the [target.name] clean...") - if(do_after(user, src.cleanspeed, target = target)) - to_chat(user, "You clean \the [target.name].") - var/obj/effect/decal/cleanable/C = locate() in target - qdel(C) - target.remove_atom_colour(WASHABLE_COLOUR_PRIORITY) - SEND_SIGNAL(target, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_MEDIUM) - target.wash_cream() - return - -//Nerfed tongue for flavour reasons (haha geddit?). Used for aux skins for regular borgs -/obj/item/dogborg_tongue - name = "synthetic tongue" - desc = "Useful for slurping mess off the floor before affectionally licking the crew members in the face." - icon = 'icons/mob/dogborg.dmi' - icon_state = "synthtongue" - hitsound = 'sound/effects/attackblob.ogg' - desc = "For giving affectionate kisses." - item_flags = NOBLUDGEON - -/obj/item/dogborg_tongue/afterattack(atom/target, mob/user, proximity) - . = ..() - if(!proximity || !isliving(target)) - return - var/mob/living/silicon/robot/R = user - var/mob/living/L = target - if(L.ckey && !(L.client?.prefs.vore_flags & LICKABLE)) - to_chat(R, "ERROR ERROR: Target not lickable. Aborting display-of-affection subroutine.") - return - - if(check_zone(R.zone_selected) == "head") - R.visible_message("\the [R] affectionally licks \the [L]'s face!", "You affectionally lick \the [L]'s face!") - playsound(R, 'sound/effects/attackblob.ogg', 50, 1) - else - R.visible_message("\the [R] affectionally licks \the [L]!", "You affectionally lick \the [L]!") - playsound(R, 'sound/effects/attackblob.ogg', 50, 1) - - -/obj/item/dogborg_nose - name = "boop module" - icon = 'icons/mob/dogborg.dmi' - icon_state = "nose" - desc = "The BOOP module" - flags_1 = CONDUCT_1|NOBLUDGEON - force = 0 - -/obj/item/dogborg_nose/afterattack(atom/target, mob/user, proximity) - . = ..() - if(!proximity) - return - do_attack_animation(target, null, src) - user.visible_message("[user] [pick(attack_verb)] \the [target.name] with their nose!") - - -//Dogfood - -/obj/item/trash/rkibble - name = "robo kibble" - desc = "A novelty bowl of assorted mech fabricator byproducts. Mockingly feed this to the sec-dog to help it recharge." - icon = 'icons/mob/dogborg.dmi' - icon_state= "kibble" - -// Pounce stuff for K-9 - -/obj/item/dogborg/pounce - name = "pounce" - icon = 'icons/mob/dogborg.dmi' - icon_state = "pounce" - desc = "Leap at your target to momentarily stun them." - force = 0 - throwforce = 0 - -/obj/item/dogborg/pounce/New() - ..() - item_flags |= NOBLUDGEON - -/mob/living/silicon/robot - var/leaping = 0 - var/pounce_cooldown = 0 - var/pounce_cooldown_time = 30 //Time in deciseconds between pounces - var/pounce_spoolup = 5 //Time in deciseconds for the pounce to happen after clicking - var/pounce_stamloss_cap = 120 //How much staminaloss pounces alone are capable of bringing a spaceman to - var/pounce_stamloss = 80 //Base staminaloss value of the pounce - var/leap_at - var/disabler - var/laser - var/sleeper_g - var/sleeper_r - var/sleeper_nv - -#define MAX_K9_LEAP_DIST 4 //because something's definitely borked the pounce functioning from a distance. - -/obj/item/dogborg/pounce/afterattack(atom/A, mob/user) - var/mob/living/silicon/robot/R = user - if(R && (world.time >= R.pounce_cooldown)) - R.pounce_cooldown = world.time + R.pounce_cooldown_time - to_chat(R, "Your targeting systems lock on to [A]...") - playsound(R, 'sound/effects/servostep.ogg', 100, TRUE) - addtimer(CALLBACK(R, /mob/living/silicon/robot.proc/leap_at, A), R.pounce_spoolup) - else if(R && (world.time < R.pounce_cooldown)) - to_chat(R, "Your leg actuators are still recharging!") - -/mob/living/silicon/robot/proc/leap_at(atom/A) - if(leaping || stat || buckled || lying) - return - - if(!has_gravity(src) || !has_gravity(A)) - to_chat(src,"It is unsafe to leap without gravity!") - //It's also extremely buggy visually, so it's balance+bugfix - return - - if(cell.charge <= 750) - to_chat(src,"Insufficent reserves for jump actuators!") - return - - else - leaping = 1 - weather_immunities += "lava" - pixel_y = 10 - update_icons() - throw_at(A, MAX_K9_LEAP_DIST, 1, spin=0, diagonals_first = 1) - cell.use(750) //Less than a stunbaton since stunbatons hit everytime. - playsound(src, 'sound/effects/stealthoff.ogg', 25, TRUE, -1) - weather_immunities -= "lava" - -/mob/living/silicon/robot/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) - - if(!leaping) - return ..() - - if(hit_atom) - if(isliving(hit_atom)) - var/mob/living/L = hit_atom - if(L.mob_run_block(0, "the [name]", src, ATTACK_TYPE_TACKLE, 0, src, null, null) & BLOCK_SUCCESS) - DefaultCombatKnockdown(15, 1, 1) - else - L.visible_message("[src] pounces on [L]!", "[src] pounces on you!") - L.DefaultCombatKnockdown(iscarbon(L) ? 60 : 45, override_stamdmg = clamp(pounce_stamloss, 0, pounce_stamloss_cap-L.getStaminaLoss())) // Temporary. If someone could rework how dogborg pounces work to accomodate for combat changes, that'd be nice. - playsound(src, 'sound/weapons/Egloves.ogg', 50, 1) - sleep(2)//Runtime prevention (infinite bump() calls on hulks) - step_towards(src,L) - log_combat(src, L, "borg pounced") - - pounce_cooldown = !pounce_cooldown - spawn(pounce_cooldown_time) //3s by default - pounce_cooldown = !pounce_cooldown - else if(hit_atom.density && !hit_atom.CanPass(src)) - visible_message("[src] smashes into [hit_atom]!", "You smash into [hit_atom]!") - playsound(src, 'sound/items/trayhit1.ogg', 50, 1) - DefaultCombatKnockdown(15, 1, 1) - - if(leaping) - leaping = 0 - pixel_y = initial(pixel_y) - update_icons() - update_mobility() diff --git a/modular_citadel/code/modules/reagents/chemistry/reagents/SDGF.dm b/modular_citadel/code/modules/reagents/chemistry/reagents/SDGF.dm index 277a2e0a79..51b13f8c55 100644 --- a/modular_citadel/code/modules/reagents/chemistry/reagents/SDGF.dm +++ b/modular_citadel/code/modules/reagents/chemistry/reagents/SDGF.dm @@ -113,13 +113,13 @@ IMPORTANT FACTORS TO CONSIDER WHILE BALANCING SM.copy_languages(M, LANGUAGE_MIND) playerClone = TRUE M.next_move_modifier = 1 - M.nutrition -= 500 + M.adjust_nutrition(-500) //Damage the clone SM.blood_volume = (BLOOD_VOLUME_NORMAL*SM.blood_ratio)/2 SM.adjustCloneLoss(60, 0) SM.setOrganLoss(ORGAN_SLOT_BRAIN, 40) - SM.nutrition = startHunger/2 + SM.set_nutrition(startHunger/2) //Transfer remaining reagent to clone. I think around 30u will make a healthy clone, otherwise they'll have clone damage, blood loss, brain damage and hunger. SM.reagents.add_reagent(/datum/reagent/fermi/SDGFheal, volume) @@ -147,23 +147,23 @@ IMPORTANT FACTORS TO CONSIDER WHILE BALANCING if(21) to_chat(M, "You feel the synethic cells rest uncomfortably within your body as they start to pulse and grow rapidly.") if(22 to 29) - M.nutrition = M.nutrition + (M.nutrition/10) + M.adjust_nutrition(M.nutrition/10) if(30) to_chat(M, "You feel the synethic cells grow and expand within yourself, bloating your body outwards.") if(31 to 49) - M.nutrition = M.nutrition + (M.nutrition/5) + M.adjust_nutrition(M.nutrition/5) if(50) to_chat(M, "The synthetic cells begin to merge with your body, it feels like your body is made of a viscous water, making your movements difficult.") M.next_move_modifier += 4//If this makes you fast then please fix it, it should make you slow!! //candidates = pollGhostCandidates("Do you want to play as a clone of [M.name] and do you agree to respect their character and act in a similar manner to them? I swear to god if you diddle them I will be very disapointed in you. ", "FermiClone", null, ROLE_SENTIENCE, 300) // see poll_ignore.dm, should allow admins to ban greifers or bullies if(51 to 79) - M.nutrition = M.nutrition + (M.nutrition/2) + M.adjust_nutrition(M.nutrition/2) if(80) to_chat(M, "The cells begin to precipitate outwards of your body, you feel like you'll split soon...") if (M.nutrition < 20000) - M.nutrition = 20000 //https://www.youtube.com/watch?v=Bj_YLenOlZI + M.set_nutrition(20000) //https://www.youtube.com/watch?v=Bj_YLenOlZI if(86)//Upon splitting, you get really hungry and are capable again. Deletes the chem after you're done. - M.nutrition = 15//YOU BEST BE EATTING AFTER THIS YOU CUTIE + M.set_nutrition(15)//YOU BEST BE EATTING AFTER THIS YOU CUTIE M.next_move_modifier -= 4 to_chat(M, "Your body splits away from the cell clone of yourself, leaving you with a drained and hollow feeling inside.") @@ -204,7 +204,7 @@ IMPORTANT FACTORS TO CONSIDER WHILE BALANCING M.heal_bodypart_damage(1,1) M.next_move_modifier = 1 if (M.nutrition < 1500) - M.nutrition += 250 + M.adjust_nutrition(250) else if (unitCheck == TRUE && !M.has_status_effect(/datum/status_effect/chem/SGDF))// If they're ingested a little bit (10u minimum), then give them a little healing. unitCheck = FALSE to_chat(M, "the cells fail to hold enough mass to generate a clone, instead diffusing into your system.") @@ -213,7 +213,7 @@ IMPORTANT FACTORS TO CONSIDER WHILE BALANCING M.blood_volume += 100 M.next_move_modifier = 1 if (M.nutrition < 1500) - M.nutrition += 500 + M.adjust_nutrition(500) /datum/reagent/fermi/SDGF/reaction_mob(mob/living/carbon/human/M, method=TOUCH, reac_volume) if(volume<5) @@ -245,7 +245,7 @@ IMPORTANT FACTORS TO CONSIDER WHILE BALANCING SM.blood_volume = (BLOOD_VOLUME_NORMAL*SM.blood_ratio)/1.5 SM.adjustCloneLoss((bodydamage/10), 0) SM.setOrganLoss(ORGAN_SLOT_BRAIN, (bodydamage/10)) - SM.nutrition = 400 + SM.adjust_nutrition(400) if(bodydamage>200) SM.gain_trauma_type(BRAIN_TRAUMA_MILD) if(bodydamage>300) @@ -285,7 +285,7 @@ IMPORTANT FACTORS TO CONSIDER WHILE BALANCING M.blood_volume += 10 M.adjustCloneLoss(-2, 0) M.setOrganLoss(ORGAN_SLOT_BRAIN, -1) - M.nutrition += 10 + M.adjust_nutrition(10) ..() //Unobtainable, used if SDGF is impure but not too impure @@ -318,27 +318,27 @@ IMPORTANT FACTORS TO CONSIDER WHILE BALANCING to_chat(M, "You feel the synethic cells rest uncomfortably within your body as they start to pulse and grow rapidly.") startHunger = M.nutrition if(21 to 29) - M.nutrition = M.nutrition + (M.nutrition/10) + M.adjust_nutrition(M.nutrition/10) if(30) to_chat(M, "You feel the synethic cells grow and expand within yourself, bloating your body outwards.") if(31 to 49) - M.nutrition = M.nutrition + (M.nutrition/5) + M.adjust_nutrition(M.nutrition/5) if(50) to_chat(M, "The synethic cells begin to merge with your body, it feels like your body is made of a viscous water, making your movements difficult.") M.next_move_modifier = 4//If this makes you fast then please fix it, it should make you slow!! if(51 to 73) - M.nutrition = M.nutrition + (M.nutrition/2) + M.adjust_nutrition(M.nutrition/2) if(74) to_chat(M, "The cells begin to precipitate outwards of your body, but... something is wrong, the sythetic cells are beginnning to rot...") if (M.nutrition < 20000) //whoever knows the maxcap, please let me know, this seems a bit low. - M.nutrition = 20000 //https://www.youtube.com/watch?v=Bj_YLenOlZI + M.set_nutrition(20000) //https://www.youtube.com/watch?v=Bj_YLenOlZI if(75 to 85) M.adjustToxLoss(1, 0)// the warning! if(86)//mean clone time! if (!M.reagents.has_reagent(/datum/reagent/medicine/pen_acid))//Counterplay is pent.) message_admins("(non-infectious) SDZF: Zombie spawned at [M] [COORD(M)]!") - M.nutrition = startHunger - 500//YOU BEST BE RUNNING AWAY AFTER THIS YOU BADDIE + M.set_nutrition(startHunger - 500) //YOU BEST BE RUNNING AWAY AFTER THIS YOU BADDIE M.next_move_modifier = 1 to_chat(M, "Your body splits away from the cell clone of yourself, your attempted clone birthing itself violently from you as it begins to shamble around, a terrifying abomination of science.") M.visible_message("[M] suddenly shudders, and splits into a funky smelling copy of themselves!") @@ -354,7 +354,7 @@ IMPORTANT FACTORS TO CONSIDER WHILE BALANCING else//easier to deal with to_chat(M, "The pentetic acid seems to have stopped the decay for now, clumping up the cells into a horrifying tumour!") - M.nutrition = startHunger - 500 + M.set_nutrition(startHunger - 500) var/mob/living/simple_animal/slime/S = new(get_turf(M.loc),"grey") //TODO: replace slime as own simplemob/add tumour slime cores for science/chemistry interplay S.damage_coeff = list(BRUTE = ((1 / volume)**0.1) , BURN = 2, TOX = 1, CLONE = 1, STAMINA = 0, OXY = 1) S.name = "Living teratoma" diff --git a/modular_citadel/code/modules/reagents/chemistry/reagents/eigentstasium.dm b/modular_citadel/code/modules/reagents/chemistry/reagents/eigentstasium.dm index 28645cdc7b..1500d52b25 100644 --- a/modular_citadel/code/modules/reagents/chemistry/reagents/eigentstasium.dm +++ b/modular_citadel/code/modules/reagents/chemistry/reagents/eigentstasium.dm @@ -94,7 +94,7 @@ to_chat(M, "Your wavefunction feels like it's been ripped in half. You feel empty inside.") log_game("FERMICHEM: [M] ckey: [M.key] has become addicted to eigenstasium") M.Jitter(10) - M.nutrition = M.nutrition - (M.nutrition/15) + M.adjust_nutrition(-M.nutrition/15) ..() /datum/reagent/fermi/eigenstate/addiction_act_stage2(mob/living/M) 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 c1631c9ee8..96f0c9bcb0 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" @@ -270,6 +271,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" @@ -930,7 +932,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" @@ -1845,6 +1849,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" @@ -2449,6 +2456,7 @@ #include "code\modules\mob\living\silicon\robot\login.dm" #include "code\modules\mob\living\silicon\robot\robot.dm" #include "code\modules\mob\living\silicon\robot\robot_defense.dm" +#include "code\modules\mob\living\silicon\robot\robot_defines.dm" #include "code\modules\mob\living\silicon\robot\robot_mobility.dm" #include "code\modules\mob\living\silicon\robot\robot_modules.dm" #include "code\modules\mob\living\silicon\robot\robot_movement.dm" @@ -3381,7 +3389,6 @@ #include "modular_citadel\code\modules\mob\living\carbon\reindex_screams.dm" #include "modular_citadel\code\modules\mob\living\carbon\human\human.dm" #include "modular_citadel\code\modules\mob\living\carbon\human\human_defense.dm" -#include "modular_citadel\code\modules\mob\living\silicon\robot\dogborg_equipment.dm" #include "modular_citadel\code\modules\projectiles\gun.dm" #include "modular_citadel\code\modules\projectiles\ammunition\caseless.dm" #include "modular_citadel\code\modules\projectiles\ammunition\ballistic\smg\smg.dm" diff --git a/tgui-next/packages/tgui/interfaces/Vending.js b/tgui-next/packages/tgui/interfaces/Vending.js deleted file mode 100644 index 85f6796230..0000000000 --- a/tgui-next/packages/tgui/interfaces/Vending.js +++ /dev/null @@ -1,106 +0,0 @@ -import { Fragment } from 'inferno'; -import { act } from '../byond'; -import { Section, Box, Button, Table } from '../components'; -import { classes } from 'common/react'; - -export const Vending = props => { - const { state } = props; - const { config, data } = state; - 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, - ]; - } 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, - ]; - } else { - inventory = [ - ...data.product_records, - ]; - } - return ( - - {data.coin && ( -
-
- )} - {data.bill && ( -
-
- )} -
-
NameDescriptionRewardCompletionStatus
- {inventory.map((product => { - return ( - - - {product.base64 ? ( - - ) : ( - - )} - {product.name} - - - - {data.stock[product.name]} in stock - - - - {custom && ( -
- - - ); -};