diff --git a/_maps/RandomRuins/LavaRuins/lavaland_biodome_beach.dmm b/_maps/RandomRuins/LavaRuins/lavaland_biodome_beach.dmm
index 2e6a25bdab3..caf994011d8 100644
--- a/_maps/RandomRuins/LavaRuins/lavaland_biodome_beach.dmm
+++ b/_maps/RandomRuins/LavaRuins/lavaland_biodome_beach.dmm
@@ -1075,7 +1075,7 @@
/turf/closed/wall/mineral/sandstone,
/area/ruin/powered/beach)
"NJ" = (
-/obj/machinery/computer/slot_machine,
+/obj/effect/spawner/random/entertainment/slot_machine,
/turf/open/floor/wood,
/area/ruin/powered/beach)
"NK" = (
diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1.dmm
index b79b3650238..4a71ef27f78 100644
--- a/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1.dmm
+++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1.dmm
@@ -4099,6 +4099,7 @@
"Ue" = (
/obj/effect/decal/cleanable/dirt,
/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/machinery/computer/slot_machine/syndicate,
/turf/open/floor/iron/dark,
/area/ruin/syndicate_lava_base/bar)
"Um" = (
diff --git a/_maps/RandomRuins/SpaceRuins/listeningstation.dmm b/_maps/RandomRuins/SpaceRuins/listeningstation.dmm
index cb069a04b11..0ce9d1fb7c4 100644
--- a/_maps/RandomRuins/SpaceRuins/listeningstation.dmm
+++ b/_maps/RandomRuins/SpaceRuins/listeningstation.dmm
@@ -186,6 +186,10 @@
/obj/machinery/hydroponics/soil,
/turf/open/floor/iron,
/area/ruin/space/has_grav/listeningstation)
+"iN" = (
+/obj/machinery/computer/slot_machine/syndicate,
+/turf/open/floor/plating,
+/area/ruin/space/has_grav/listeningstation)
"jr" = (
/obj/machinery/power/port_gen/pacman{
anchored = 1
@@ -1346,7 +1350,7 @@ FV
ca
BX
dW
-We
+iN
JB
vI
vI
diff --git a/_maps/RandomZLevels/SnowCabin.dmm b/_maps/RandomZLevels/SnowCabin.dmm
index 52579ccdacc..d164796beab 100644
--- a/_maps/RandomZLevels/SnowCabin.dmm
+++ b/_maps/RandomZLevels/SnowCabin.dmm
@@ -639,7 +639,7 @@
/turf/open/floor/wood,
/area/awaymission/cabin)
"cN" = (
-/obj/machinery/computer/slot_machine,
+/obj/effect/spawner/random/entertainment/slot_machine,
/turf/open/floor/carpet,
/area/awaymission/cabin)
"cO" = (
diff --git a/_maps/RandomZLevels/TheBeach.dmm b/_maps/RandomZLevels/TheBeach.dmm
index 1cecb4bebfe..3eb04da8ee6 100644
--- a/_maps/RandomZLevels/TheBeach.dmm
+++ b/_maps/RandomZLevels/TheBeach.dmm
@@ -4026,7 +4026,7 @@
/obj/structure/sign/directions/medical/directional/north{
pixel_y = 29
},
-/obj/machinery/computer/slot_machine,
+/obj/effect/spawner/random/entertainment/slot_machine,
/turf/open/floor/wood/large,
/area/awaymission/beach)
"Zt" = (
diff --git a/_maps/map_files/CatwalkStation/CatwalkStation_2023.dmm b/_maps/map_files/CatwalkStation/CatwalkStation_2023.dmm
index fe79d7aa3aa..3ad6324e364 100644
--- a/_maps/map_files/CatwalkStation/CatwalkStation_2023.dmm
+++ b/_maps/map_files/CatwalkStation/CatwalkStation_2023.dmm
@@ -10861,7 +10861,7 @@
/turf/open/floor/iron,
/area/station/hallway/secondary/construction)
"cOJ" = (
-/obj/machinery/computer/slot_machine{
+/obj/effect/spawner/random/entertainment/slot_machine{
pixel_y = 2
},
/obj/effect/decal/cleanable/glitter,
@@ -24017,7 +24017,7 @@
"goW" = (
/obj/effect/decal/cleanable/cobweb/cobweb2,
/obj/effect/decal/cleanable/dirt,
-/obj/machinery/computer/slot_machine{
+/obj/effect/spawner/random/entertainment/slot_machine{
pixel_y = 2
},
/turf/open/floor/wood,
@@ -31604,7 +31604,7 @@
"itr" = (
/obj/effect/turf_decal/siding/thinplating_new/dark,
/obj/structure/extinguisher_cabinet/directional/south,
-/obj/machinery/computer/slot_machine{
+/obj/effect/spawner/random/entertainment/slot_machine{
pixel_y = 2
},
/turf/open/floor/iron/dark/smooth_large,
@@ -33224,7 +33224,7 @@
/turf/open/floor/iron/white,
/area/station/hallway/secondary/entry)
"iPv" = (
-/obj/machinery/computer/slot_machine{
+/obj/effect/spawner/random/entertainment/slot_machine{
pixel_y = 2
},
/obj/effect/decal/cleanable/dirt,
@@ -60940,7 +60940,7 @@
/turf/open/floor/iron,
/area/station/maintenance/starboard/aft)
"qjy" = (
-/obj/machinery/computer/slot_machine{
+/obj/effect/spawner/random/entertainment/slot_machine{
pixel_y = 2
},
/turf/open/floor/iron,
@@ -63099,7 +63099,7 @@
/turf/open/floor/iron/dark/textured,
/area/station/cargo/sorting)
"qNo" = (
-/obj/machinery/computer/slot_machine{
+/obj/effect/spawner/random/entertainment/slot_machine{
pixel_y = 2
},
/obj/effect/decal/cleanable/blood/oil,
@@ -65052,7 +65052,7 @@
/turf/open/floor/iron,
/area/station/science/research)
"rpq" = (
-/obj/machinery/computer/slot_machine{
+/obj/effect/spawner/random/entertainment/slot_machine{
pixel_y = 2
},
/turf/open/floor/plating,
@@ -79748,7 +79748,7 @@
/turf/open/floor/iron/dark,
/area/station/service/chapel)
"vgV" = (
-/obj/machinery/computer/slot_machine{
+/obj/effect/spawner/random/entertainment/slot_machine{
pixel_y = 2
},
/obj/effect/decal/cleanable/dirt,
@@ -84488,7 +84488,7 @@
/turf/open/floor/iron,
/area/station/cargo/storage)
"wtN" = (
-/obj/machinery/computer/slot_machine{
+/obj/effect/spawner/random/entertainment/slot_machine{
pixel_y = 2
},
/obj/effect/decal/cleanable/vomit/old,
diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm
index ab953026673..c9d741ff81e 100644
--- a/_maps/map_files/Deltastation/DeltaStation2.dmm
+++ b/_maps/map_files/Deltastation/DeltaStation2.dmm
@@ -3868,7 +3868,7 @@
/obj/structure/disposalpipe/segment{
dir = 4
},
-/obj/machinery/computer/slot_machine,
+/obj/effect/spawner/random/entertainment/slot_machine,
/obj/effect/decal/cleanable/dirt,
/obj/effect/turf_decal/tile/neutral/half/contrasted{
dir = 1
@@ -56213,7 +56213,7 @@
/obj/structure/disposalpipe/segment{
dir = 10
},
-/obj/machinery/computer/slot_machine,
+/obj/effect/spawner/random/entertainment/slot_machine,
/obj/effect/turf_decal/tile/neutral{
dir = 1
},
diff --git a/_maps/map_files/IceBoxStation/IceBoxStation.dmm b/_maps/map_files/IceBoxStation/IceBoxStation.dmm
index 1dc2cef08cc..ddd0b28d8f1 100644
--- a/_maps/map_files/IceBoxStation/IceBoxStation.dmm
+++ b/_maps/map_files/IceBoxStation/IceBoxStation.dmm
@@ -17243,7 +17243,7 @@
/obj/machinery/camera/directional/east{
c_tag = "Service - Gambling Lounge"
},
-/obj/machinery/computer/slot_machine{
+/obj/effect/spawner/random/entertainment/slot_machine{
name = "two-armed bandit"
},
/turf/open/floor/wood/large,
@@ -28771,7 +28771,7 @@
/area/station/security/prison/rec)
"ibJ" = (
/obj/item/radio/intercom/directional/east,
-/obj/machinery/computer/slot_machine{
+/obj/effect/spawner/random/entertainment/slot_machine{
name = "two-armed bandit"
},
/turf/open/floor/wood/large,
@@ -52934,7 +52934,7 @@
/turf/open/floor/iron/grimy,
/area/station/maintenance/aft/greater)
"oMP" = (
-/obj/machinery/computer/slot_machine,
+/obj/effect/spawner/random/entertainment/slot_machine,
/turf/open/floor/wood,
/area/station/command/meeting_room)
"oMR" = (
diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm
index fcfef778c10..0b681656f74 100644
--- a/_maps/map_files/MetaStation/MetaStation.dmm
+++ b/_maps/map_files/MetaStation/MetaStation.dmm
@@ -11658,7 +11658,7 @@
/turf/open/floor/iron,
/area/station/service/hydroponics)
"ebG" = (
-/obj/machinery/computer/slot_machine{
+/obj/effect/spawner/random/entertainment/slot_machine{
pixel_y = 2
},
/obj/effect/mapping_helpers/broken_floor,
@@ -12536,7 +12536,7 @@
/turf/open/floor/wood,
/area/station/commons/lounge)
"eov" = (
-/obj/machinery/computer/slot_machine{
+/obj/effect/spawner/random/entertainment/slot_machine{
pixel_y = 2
},
/obj/effect/mapping_helpers/broken_floor,
@@ -22916,7 +22916,7 @@
/turf/open/floor/engine,
/area/station/science/xenobiology)
"hWj" = (
-/obj/machinery/computer/slot_machine{
+/obj/effect/spawner/random/entertainment/slot_machine{
pixel_y = 2
},
/turf/open/floor/wood,
@@ -40886,7 +40886,7 @@
/area/station/command/bridge)
"nXG" = (
/obj/machinery/newscaster/directional/north,
-/obj/machinery/computer/slot_machine{
+/obj/effect/spawner/random/entertainment/slot_machine{
pixel_y = 2
},
/obj/effect/turf_decal/tile/bar/opposingcorners,
@@ -51307,7 +51307,7 @@
/area/station/security/interrogation)
"rzi" = (
/obj/machinery/airalarm/directional/north,
-/obj/machinery/computer/slot_machine{
+/obj/effect/spawner/random/entertainment/slot_machine{
pixel_y = 2
},
/obj/effect/turf_decal/tile/bar/opposingcorners,
diff --git a/_maps/map_files/NebulaStation/NebulaStation.dmm b/_maps/map_files/NebulaStation/NebulaStation.dmm
index 39dc26cc6e4..0060c13dc5a 100644
--- a/_maps/map_files/NebulaStation/NebulaStation.dmm
+++ b/_maps/map_files/NebulaStation/NebulaStation.dmm
@@ -90828,7 +90828,7 @@
/obj/effect/turf_decal/siding/wood{
dir = 6
},
-/obj/machinery/computer/slot_machine,
+/obj/effect/spawner/random/entertainment/slot_machine,
/obj/effect/turf_decal/siding/wood/corner{
dir = 1
},
@@ -137223,7 +137223,7 @@
/obj/effect/turf_decal/siding/wood{
dir = 5
},
-/obj/machinery/computer/slot_machine,
+/obj/effect/spawner/random/entertainment/slot_machine,
/obj/effect/turf_decal/siding/wood/corner{
dir = 8
},
@@ -139659,7 +139659,7 @@
/turf/open/floor/wood,
/area/station/security/courtroom)
"uFM" = (
-/obj/machinery/computer/slot_machine,
+/obj/effect/spawner/random/entertainment/slot_machine,
/obj/effect/turf_decal/siding/wood{
dir = 6
},
@@ -150211,7 +150211,7 @@
/turf/open/floor/wood/large,
/area/station/service/library/upper)
"wiG" = (
-/obj/machinery/computer/slot_machine,
+/obj/effect/spawner/random/entertainment/slot_machine,
/obj/effect/turf_decal/siding/wood{
dir = 10
},
diff --git a/_maps/map_files/tramstation/tramstation.dmm b/_maps/map_files/tramstation/tramstation.dmm
index 6edd7fc9d11..bc99abb402b 100644
--- a/_maps/map_files/tramstation/tramstation.dmm
+++ b/_maps/map_files/tramstation/tramstation.dmm
@@ -12214,7 +12214,7 @@
/turf/open/floor/iron/dark,
/area/station/medical/morgue)
"dds" = (
-/obj/machinery/computer/slot_machine{
+/obj/effect/spawner/random/entertainment/slot_machine{
pixel_y = 2
},
/obj/machinery/light/cold/directional/north,
@@ -12503,7 +12503,7 @@
/turf/open/floor/iron/dark,
/area/station/ai/satellite/foyer)
"diN" = (
-/obj/machinery/computer/slot_machine{
+/obj/effect/spawner/random/entertainment/slot_machine{
pixel_y = 2
},
/turf/open/floor/iron/dark,
@@ -67354,7 +67354,7 @@
/turf/open/floor/wood,
/area/station/service/bar/backroom)
"wwj" = (
-/obj/machinery/computer/slot_machine{
+/obj/effect/spawner/random/entertainment/slot_machine{
pixel_y = 2
},
/obj/machinery/light/cold/directional/south,
diff --git a/_maps/map_files/wawastation/wawastation.dmm b/_maps/map_files/wawastation/wawastation.dmm
index 2a439748deb..5ce45523ec0 100644
--- a/_maps/map_files/wawastation/wawastation.dmm
+++ b/_maps/map_files/wawastation/wawastation.dmm
@@ -5627,7 +5627,7 @@
"bXx" = (
/obj/machinery/camera/autoname/directional/south,
/obj/machinery/airalarm/directional/south,
-/obj/machinery/computer/slot_machine{
+/obj/effect/spawner/random/entertainment/slot_machine{
pixel_y = 2
},
/turf/open/floor/wood,
@@ -6753,7 +6753,7 @@
/turf/open/floor/glass/reinforced,
/area/station/security/prison)
"ctP" = (
-/obj/machinery/computer/slot_machine,
+/obj/effect/spawner/random/entertainment/slot_machine,
/obj/effect/decal/cleanable/dirt/dust,
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron/grimy,
@@ -39342,7 +39342,7 @@
/turf/closed/wall/r_wall,
/area/station/maintenance/central/greater)
"nzw" = (
-/obj/machinery/computer/slot_machine,
+/obj/effect/spawner/random/entertainment/slot_machine,
/obj/effect/turf_decal/sand/plating,
/turf/open/floor/plating,
/area/station/maintenance/central/greater)
@@ -41216,7 +41216,7 @@
/turf/open/floor/iron,
/area/station/hallway/primary/central)
"olC" = (
-/obj/machinery/computer/slot_machine,
+/obj/effect/spawner/random/entertainment/slot_machine,
/obj/effect/decal/cleanable/dirt/dust,
/obj/effect/decal/cleanable/dirt,
/obj/machinery/light/small/directional/west,
@@ -62694,7 +62694,7 @@
"vxl" = (
/obj/machinery/power/apc/auto_name/directional/south,
/obj/structure/cable,
-/obj/machinery/computer/slot_machine{
+/obj/effect/spawner/random/entertainment/slot_machine{
pixel_y = 2
},
/turf/open/floor/wood,
@@ -63653,7 +63653,7 @@
/turf/open/floor/iron/white/smooth_large,
/area/station/science/research)
"vNT" = (
-/obj/machinery/computer/slot_machine,
+/obj/effect/spawner/random/entertainment/slot_machine,
/obj/effect/decal/cleanable/dirt/dust,
/turf/open/floor/iron/grimy,
/area/station/maintenance/central/lesser)
diff --git a/_maps/shuttles/emergency_casino.dmm b/_maps/shuttles/emergency_casino.dmm
index 1bfe4744198..e4521dc80b6 100644
--- a/_maps/shuttles/emergency_casino.dmm
+++ b/_maps/shuttles/emergency_casino.dmm
@@ -33,7 +33,7 @@
/turf/open/floor/wood,
/area/shuttle/escape)
"bT" = (
-/obj/machinery/computer/slot_machine,
+/obj/effect/spawner/random/entertainment/slot_machine,
/obj/structure/window/reinforced/spawner/directional/west,
/obj/structure/window/reinforced/spawner/directional/north,
/turf/open/floor/carpet/green,
@@ -431,7 +431,7 @@
/turf/open/floor/carpet/royalblue,
/area/shuttle/escape)
"mx" = (
-/obj/machinery/computer/slot_machine,
+/obj/effect/spawner/random/entertainment/slot_machine,
/obj/structure/window/reinforced/spawner/directional/east,
/obj/structure/window/reinforced/spawner/directional/north,
/turf/open/floor/carpet/green,
@@ -509,7 +509,7 @@
/turf/open/floor/mineral/plastitanium/red,
/area/shuttle/escape/brig)
"oB" = (
-/obj/machinery/computer/slot_machine,
+/obj/effect/spawner/random/entertainment/slot_machine,
/obj/structure/window/reinforced/spawner/directional/north,
/turf/open/floor/carpet/green,
/area/shuttle/escape)
@@ -739,7 +739,7 @@
/turf/open/floor/sepia,
/area/shuttle/escape)
"we" = (
-/obj/machinery/computer/slot_machine,
+/obj/effect/spawner/random/entertainment/slot_machine,
/obj/effect/turf_decal/siding/thinplating{
dir = 8
},
@@ -911,7 +911,7 @@
/turf/open/floor/mineral/plastitanium/red,
/area/shuttle/escape/brig)
"Bf" = (
-/obj/machinery/computer/slot_machine,
+/obj/effect/spawner/random/entertainment/slot_machine,
/turf/open/floor/carpet/green,
/area/shuttle/escape)
"Bj" = (
diff --git a/_maps/shuttles/emergency_discoinferno.dmm b/_maps/shuttles/emergency_discoinferno.dmm
index d6dedd686af..73a76ec0556 100644
--- a/_maps/shuttles/emergency_discoinferno.dmm
+++ b/_maps/shuttles/emergency_discoinferno.dmm
@@ -122,7 +122,7 @@
/turf/open/floor/wood,
/area/shuttle/escape)
"C" = (
-/obj/machinery/computer/slot_machine,
+/obj/effect/spawner/random/entertainment/slot_machine,
/obj/machinery/light/directional/west,
/turf/open/floor/wood,
/area/shuttle/escape)
@@ -160,7 +160,7 @@
/turf/open/floor/wood,
/area/shuttle/escape)
"I" = (
-/obj/machinery/computer/slot_machine,
+/obj/effect/spawner/random/entertainment/slot_machine,
/turf/open/floor/wood,
/area/shuttle/escape)
"J" = (
diff --git a/_maps/shuttles/hunter_psyker.dmm b/_maps/shuttles/hunter_psyker.dmm
index b16650013c9..3aff0d2eed0 100644
--- a/_maps/shuttles/hunter_psyker.dmm
+++ b/_maps/shuttles/hunter_psyker.dmm
@@ -273,7 +273,7 @@
/area/shuttle/hunter)
"lD" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden,
-/obj/machinery/computer/slot_machine,
+/obj/effect/spawner/random/entertainment/slot_machine,
/obj/effect/decal/cleanable/wrapping,
/turf/open/floor/iron/grimy,
/area/shuttle/hunter)
diff --git a/_maps/templates/lazy_templates/nukie_base.dmm b/_maps/templates/lazy_templates/nukie_base.dmm
index 7d87dc7d4e6..537fe8fda84 100644
--- a/_maps/templates/lazy_templates/nukie_base.dmm
+++ b/_maps/templates/lazy_templates/nukie_base.dmm
@@ -3633,6 +3633,7 @@
/area/centcom/syndicate_mothership/control)
"Ni" = (
/obj/machinery/light/small/directional/north,
+/obj/machinery/computer/slot_machine/syndicate,
/turf/open/floor/wood/tile,
/area/centcom/syndicate_mothership/control)
"No" = (
diff --git a/_maps/virtual_domains/beach_bar.dmm b/_maps/virtual_domains/beach_bar.dmm
index e3e4a09e96b..a41b0c87d93 100644
--- a/_maps/virtual_domains/beach_bar.dmm
+++ b/_maps/virtual_domains/beach_bar.dmm
@@ -1006,7 +1006,7 @@
/turf/open/floor/wood,
/area/virtual_domain/fullbright)
"VA" = (
-/obj/machinery/computer/slot_machine,
+/obj/effect/spawner/random/entertainment/slot_machine,
/turf/open/floor/wood,
/area/virtual_domain/fullbright)
"VE" = (
diff --git a/_maps/virtual_domains/fredingtonfastingbear.dmm b/_maps/virtual_domains/fredingtonfastingbear.dmm
index e28813d8c94..24174de946b 100644
--- a/_maps/virtual_domains/fredingtonfastingbear.dmm
+++ b/_maps/virtual_domains/fredingtonfastingbear.dmm
@@ -362,7 +362,7 @@
/turf/open/floor/iron/kitchen,
/area/virtual_domain)
"sk" = (
-/obj/machinery/computer/slot_machine,
+/obj/effect/spawner/random/entertainment/slot_machine,
/turf/open/floor/iron/kitchen,
/area/virtual_domain)
"sl" = (
diff --git a/_maps/virtual_domains/island_brawl.dmm b/_maps/virtual_domains/island_brawl.dmm
index 31a65f790ab..4688e496bbf 100644
--- a/_maps/virtual_domains/island_brawl.dmm
+++ b/_maps/virtual_domains/island_brawl.dmm
@@ -2228,7 +2228,7 @@
/obj/structure/sign/directions/medical/directional/north{
pixel_y = 29
},
-/obj/machinery/computer/slot_machine,
+/obj/effect/spawner/random/entertainment/slot_machine,
/turf/open/floor/wood/large,
/area/virtual_domain)
"BW" = (
diff --git a/code/game/machinery/slotmachine.dm b/code/game/machinery/slotmachine.dm
index cd61dcebac0..4ff3d99a004 100644
--- a/code/game/machinery/slotmachine.dm
+++ b/code/game/machinery/slotmachine.dm
@@ -16,7 +16,6 @@
#define PRIZE_JACKPOT 10000
#define SPIN_TIME 4 SECONDS
#define REEL_DEACTIVATE_DELAY 0.4 SECONDS
-#define JACKPOT_SEVENS FA_ICON_7
#define HOLOCHIP 1
#define COIN 2
@@ -29,8 +28,8 @@
icon_screen = "slots_screen"
density = TRUE
circuit = /obj/item/circuitboard/computer/slot_machine
- light_color = LIGHT_COLOR_BROWN
interaction_flags_machine = INTERACT_MACHINE_ALLOW_SILICON // don't need to be literate to play slots
+ light_color = LIGHT_COLOR_BROWN
var/money = 3000 // How much money it has CONSUMED
var/plays = 0
var/working = FALSE
@@ -39,17 +38,35 @@
var/jackpots = 0
var/paymode = HOLOCHIP // toggles between HOLOCHIP/COIN, defined above
var/cointype = /obj/item/coin/iron //default cointype
- /// Icons that can be displayed by the slot machine.
- var/static/list/icons = list(
- FA_ICON_LEMON,
- FA_ICON_STAR,
- FA_ICON_BOMB,
- FA_ICON_BIOHAZARD,
- FA_ICON_APPLE_WHOLE,
- FA_ICON_7,
- FA_ICON_DOLLAR_SIGN,
+
+ /// The optional bank account used as the machine's bank. Player losses are deposited here, while payouts and jackpots are deducted from its balance
+ var/datum/bank_account/house_bank_account
+
+ /// Typepaths representing the symbols shown on this machine's reels
+ var/list/symbol_paths = list(
+ /obj/item/storage/bag/money,
+ /obj/item/food/grown/cherry_bomb,
+ /obj/item/grenade/flashbang,
+ /obj/item/poker_chip,
+ /obj/item/food/grown/chili,
+ /obj/item/clothing/neck/necklace/dope,
+ /obj/item/stack/spacecash/c20,
)
+ /// Used to determine the 1st name of the slot machine. Name = "[adjective] [noun]"
+ var/list/slot_adjectives = list("Blazing", "Bonus", "Grand", "Greedy", "Jumbo", "Platinum", "Lucky", "Mega", "Robust", "Super", "Turbo", "Wild")
+ /// Used to determine the 2nd name of the slot machine. Name = "[adjective] [noun]"
+ var/list/slot_nouns = list("Bankroll", "Cashout", "Fortune", "Jackpot", "Luck", "Money", "Payday", "Reels", "Riches", "Spinner", "Spins", "Strike", "Treasure", "Spess")
+
+ /// The symbol typepath that pays out the jackpot when it lines up five wide
+ var/jackpot_path = /obj/item/food/grown/cherry_bomb
+
+ /// The symbol typepath that activates a trap when it lines up five wide (set to null to disable)
+ var/trap_path = /obj/item/grenade/flashbang
+
+ /// Cached list of symbol data (id/name/icon/icon_state) sent to ui_static_data
+ var/list/symbol_data
+
var/static/list/coinvalues
var/list/reels = list(
list("", "", ""),
@@ -58,13 +75,21 @@
list("", "", ""),
list("", "", ""),
)
- var/static/list/ray_filter = list(type = "rays", y = 16, size = 40, density = 4, color = COLOR_RED_LIGHT, factor = 15, flags = FILTER_OVERLAY)
+ var/static/list/ray_filter = list(type = "rays", y = 14, size = 40, density = 4, color = COLOR_RED_LIGHT, factor = 15, flags = FILTER_OVERLAY)
/obj/machinery/computer/slot_machine/Initialize(mapload)
. = ..()
jackpots = rand(1, 4) //false hope
plays = rand(75, 200)
+ name = make_machine_name()
+
+ if(jackpot_path && !(jackpot_path in symbol_paths))
+ stack_trace("[type] has jackpot_path [jackpot_path] not present in symbol_paths!")
+ if(trap_path && !(trap_path in symbol_paths))
+ stack_trace("[type] has trap_path [trap_path] not present in symbol_paths!")
+
+ build_symbol_data()
// Populate the reels
randomize_reels()
@@ -76,6 +101,26 @@
coinvalues["[cointype]"] = C.get_item_credit_value()
qdel(C) //Sigh
+/obj/machinery/computer/slot_machine/Destroy()
+ house_bank_account = null
+ . = ..()
+
+/// Generates a randomised slot name by pulling an adjective and a noun
+/// Produces things like "Lucky Sevens", "Robust Payday", "Honking Bonanza", etc.
+/obj/machinery/computer/slot_machine/proc/make_machine_name()
+ var/adjective = pick(slot_adjectives)
+ var/noun = pick(slot_nouns)
+ return "[adjective] [noun]"
+
+/// Builds symbol_data from symbol_paths to be used for DmIcon in TGUI
+/obj/machinery/computer/slot_machine/proc/build_symbol_data()
+ symbol_data = list()
+ for(var/obj/symbol as anything in symbol_paths)
+ symbol_data += list(list(
+ "id" = "[symbol]",
+ "icon_id" = sanitize_css_class_name("[symbol::icon][symbol::icon_state]")
+ ))
+
/obj/machinery/computer/slot_machine/on_deconstruction(disassembled)
if(balance)
give_payout(balance)
@@ -138,6 +183,35 @@
balloon_alert(user, "coins only!")
return ITEM_INTERACT_BLOCKING
+ var/obj/item/card/id/id_card = inserted.GetID()
+ if(isidcard(id_card))
+ if(house_bank_account)
+ say("Already linked to [house_bank_account.account_holder]!")
+ playsound(src, 'sound/machines/buzz/buzz-two.ogg', 30, TRUE)
+ return ITEM_INTERACT_BLOCKING
+
+ var/datum/bank_account/id_bank_account = id_card.registered_account
+
+ if(!id_bank_account)
+ say("No bank account detected on id card!")
+ playsound(src, 'sound/machines/buzz/buzz-two.ogg', 30, TRUE)
+ return ITEM_INTERACT_BLOCKING
+
+ if(!id_bank_account.has_money(PRIZE_SMALL))
+ say("Insufficent funds for potential payout. Minimum of [PRIZE_SMALL] credits needed!")
+ playsound(src, 'sound/machines/buzz/buzz-two.ogg', 30, TRUE)
+ return ITEM_INTERACT_BLOCKING
+
+ var/msg = tgui_input_text(user, "Name of your slot machine (optional)", "Slot Customization", "Slot Machine", max_length = MAX_NAME_LEN)
+ if(msg)
+ name = msg
+
+ playsound(src, 'sound/machines/terminal/terminal_success.ogg', 50, TRUE)
+ desc = "Owned by [id_bank_account.account_holder], draws directly from [user.p_their()] account."
+ house_bank_account = id_bank_account
+ to_chat(user, span_notice("You link the slot machine to [id_bank_account.account_holder]'s account."))
+ return ITEM_INTERACT_SUCCESS
+
return NONE
/obj/machinery/computer/slot_machine/multitool_act(mob/living/user, obj/item/tool)
@@ -163,6 +237,11 @@
balloon_alert(user, "machine rigged")
return TRUE
+/obj/machinery/computer/slot_machine/ui_assets(mob/user)
+ return list(
+ get_asset_datum(/datum/asset/spritesheet_batched/slot_machines),
+ )
+
/obj/machinery/computer/slot_machine/ui_interact(mob/living/user, datum/tgui/ui)
. = ..()
ui = SStgui.try_update_ui(user, src, ui)
@@ -172,9 +251,12 @@
/obj/machinery/computer/slot_machine/ui_static_data(mob/user)
var/list/data = list()
- data["icons"] = icons
+ data["symbols"] = symbol_data
data["cost"] = SPIN_PRICE
data["jackpot"] = PRIZE_JACKPOT
+ data["jackpot_id"] = "[jackpot_path]"
+ if(trap_path)
+ data["trap_id"] = "[trap_path]"
return data
/obj/machinery/computer/slot_machine/ui_data(mob/user)
@@ -182,7 +264,7 @@
var/list/_reels = list()
for(var/reel in reels)
_reels += list(list(
- "icons" = reel,
+ "symbols" = reel,
))
data["reels"] = _reels
data["balance"] = balance
@@ -224,10 +306,25 @@
money -= max(0, give_payout(min(rand(-50, 100 * severity_ascending)), money)) //This starts at -50 because it shouldn't always dispense coins yo
spin()
+/// Returns TRUE if the owner has enough funds to payout
+/obj/machinery/computer/slot_machine/proc/has_funds_to_pay(payout)
+ if(!house_bank_account) // no owner so NT is paying
+ return TRUE
+
+ if(house_bank_account.has_money(payout))
+ return TRUE
+
+ say("The bank account of [house_bank_account.account_holder] does not have enough funds to pay out the potential prize, contact them to fill up their account or lower your bet!")
+ playsound(src, 'sound/machines/buzz/buzz-two.ogg', 30, TRUE)
+ return FALSE
+
/obj/machinery/computer/slot_machine/proc/spin(mob/user)
if(!can_spin(user))
return
+ if(!has_funds_to_pay(PRIZE_SMALL))
+ return
+
if(!use_energy(active_power_usage, force = FALSE))
say("Not enough energy!")
return
@@ -244,6 +341,12 @@
balance -= SPIN_PRICE
money += SPIN_PRICE
+
+ if(house_bank_account)
+ // Since big jackpots & free games aren't deducted directly from the account holder NT takes a 40% cut of profit
+ // Also discourages infinite money exploits since people playing slot machines they own will cause them to slowly lose money
+ house_bank_account.adjust_money(SPIN_PRICE * 0.60, "Slot Machine: Spin")
+
plays += 1
working = TRUE
@@ -284,28 +387,44 @@
/// Randomize the states of all reels
/obj/machinery/computer/slot_machine/proc/randomize_reels()
- for(var/reel in reels)
- reel[1] = pick(icons)
- reel[2] = pick(icons)
- reel[3] = pick(icons)
+ for(var/list/reel in reels)
+ reel[1] = "[pick(symbol_paths)]"
+ reel[2] = "[pick(symbol_paths)]"
+ reel[3] = "[pick(symbol_paths)]"
+
+/// Triggers a negative effect for a slot machine if all trap icons are lined up in the middle
+/obj/machinery/computer/slot_machine/proc/activate_trap(mob/living/user)
+ visible_message("[src] says, 'Big Loser! Prepare for your special prize!'")
+
+ switch(trap_path)
+ if(/obj/item/restraints/handcuffs)
+ if(iscarbon(user))
+ var/mob/living/carbon/carbon_user = user
+ playsound(loc, 'sound/items/weapons/handcuffs.ogg', 30, TRUE, -2)
+ carbon_user.set_handcuffed(new /obj/item/restraints/handcuffs(user))
+ if(/obj/item/suspiciousphone)
+ playsound(loc, 'sound/items/dump_it.ogg', 30, TRUE, -2)
+ balance = 0
+ if(/obj/singularity)
+ user.electrocute_act(80, src, flags = SHOCK_ILLUSION | SHOCK_NOGLOVES)
+ else // gibonite, syndicate bombs, flashbangs, etc.
+ var/obj/item/grenade/flashbang/bang = new(get_turf(src))
+ bang.arm_grenade(null, 1 SECONDS)
/// Checks if any prizes have been won, and pays them out
-/obj/machinery/computer/slot_machine/proc/give_prizes(usrname, mob/user)
+/obj/machinery/computer/slot_machine/proc/give_prizes(usrname, mob/living/user)
var/linelength = get_lines()
var/did_player_win = TRUE
- if(check_jackpot(FA_ICON_BOMB))
- var/obj/item/grenade/flashbang/bang = new(get_turf(src))
- bang.arm_grenade(null, 1 SECONDS)
+ if(trap_path && check_middle_row_all(trap_path))
+ activate_trap(user)
- else if(check_jackpot(JACKPOT_SEVENS))
+ else if(check_middle_row_all(jackpot_path))
winning = WINNING_JACKPOT
var/prize = money + PRIZE_JACKPOT
visible_message("[src] says, 'JACKPOT! You win [prize] [MONEY_NAME]!'")
priority_announce("Congratulations to [user ? user.real_name : usrname] for winning the jackpot at the slot machine in [get_area(src)]!")
- if(isliving(user) && (user in viewers(src)))
- var/mob/living/living_user = user
- living_user.add_mood_event("slots", /datum/mood_event/slots/win/jackpot)
+ user.add_mood_event("slots", /datum/mood_event/slots/win/jackpot)
jackpots += 1
money = 0
if(paymode == HOLOCHIP)
@@ -322,17 +441,13 @@
winning = WINNING_BIG
visible_message("[src] says, 'Big Winner! You win a thousand [MONEY_NAME]!'")
give_money(PRIZE_BIG)
- if(isliving(user) && (user in viewers(src)))
- var/mob/living/living_user = user
- living_user.add_mood_event("slots", /datum/mood_event/slots/win/big)
+ user.add_mood_event("slots", /datum/mood_event/slots/win/big)
else if(linelength == 4)
winning = WINNING_SMALL
visible_message("[src] says, 'Winner! You win four hundred [MONEY_NAME]!'")
give_money(PRIZE_SMALL)
- if(isliving(user) && (user in viewers(src)))
- var/mob/living/living_user = user
- living_user.add_mood_event("slots", /datum/mood_event/slots/win)
+ user.add_mood_event("slots", /datum/mood_event/slots/win)
else if(linelength == 3)
winning = WINNING_FREESPIN
@@ -344,9 +459,7 @@
winning = WINNING_NOTHING
balloon_alert(user, "no luck!")
did_player_win = FALSE
- if(isliving(user) && (user in viewers(src)))
- var/mob/living/living_user = user
- living_user.add_mood_event("slots", /datum/mood_event/slots/loss)
+ user.add_mood_event("slots", /datum/mood_event/slots/loss)
playsound(src, 'sound/machines/lever/lever_stop.ogg', 50)
@@ -362,30 +475,31 @@
/obj/machinery/computer/slot_machine/proc/clear_winning()
winning = WINNING_NOTHING
-/// Checks for a jackpot (5 matching icons in the middle row) with the given icon name
-/obj/machinery/computer/slot_machine/proc/check_jackpot(name)
- for(var/reel in reels)
- if(reel[2] != name)
+/// Checks for a jackpot (5 matching symbols in the middle row) for the given symbol typepath
+/obj/machinery/computer/slot_machine/proc/check_middle_row_all(symbol_path)
+ var/symbol_id = "[symbol_path]"
+ for(var/list/reel in reels)
+ if(reel[2] != symbol_id)
return FALSE
return TRUE
/// Finds the largest number of consecutive matching icons in a row
/obj/machinery/computer/slot_machine/proc/get_lines()
- var/amountthesame
+ var/amountthesame = 0
- for(var/i in 1 to 3)
- var/inputtext = reels[1][i] + reels[2][i] + reels[3][i] + reels[4][i] + reels[5][i]
- for(var/icon in icons)
- var/j = 3 //The lowest value we have to check for.
- var/symboltext = icon + icon + icon
- while(j <= 5)
- if(findtext(inputtext, symboltext))
- amountthesame = max(j, amountthesame)
- j++
- symboltext += icon
+ for(var/row in 1 to 3)
+ var/current_symbol = null
+ var/current_run = 0
- if(amountthesame)
- break
+ for(var/list/reel in reels)
+ var/symbol = reel[row]
+ if(symbol == current_symbol)
+ current_run++
+ else
+ current_symbol = symbol
+ current_run = 1
+ if(current_run >= 3)
+ amountthesame = max(amountthesame, current_run)
return amountthesame
@@ -396,6 +510,9 @@
money -= amount_to_give
balance += surplus
+ if(house_bank_account)
+ house_bank_account.adjust_money(-amount_to_give, "Slot Machine: Payout")
+
/// Pay out the specified amount in either coins or holochips
/obj/machinery/computer/slot_machine/proc/give_payout(amount)
if(paymode == HOLOCHIP)
@@ -436,6 +553,204 @@
playsound(src, pick(list('sound/machines/coindrop.ogg', 'sound/machines/coindrop2.ogg')), 50, TRUE)
return amount
+/obj/machinery/computer/slot_machine/command
+ name = "command slot machine"
+ desc = "The handle is made of solid gold, and the screen is polished with the tears of overworked assistants."
+ symbol_paths = list(
+ /obj/item/disk/nuclear,
+ /obj/item/clothing/accessory/medal/gold,
+ /obj/item/hand_tele,
+ /mob/living/basic/pet/dog/corgi,
+ /obj/item/card/id/advanced/gold,
+ /obj/item/melee/sabre,
+ /obj/item/grenade/syndieminibomb
+ )
+ jackpot_path = /obj/item/clothing/accessory/medal/gold
+ trap_path = /obj/item/grenade/syndieminibomb
+
+/obj/machinery/computer/slot_machine/command/Initialize(mapload)
+ slot_adjectives += list("Royal", "Regal", "Golden", "Captain's", "Glorious")
+ slot_nouns += list("Medal", "Ransom", "Authority", "Command")
+ . = ..()
+
+/obj/machinery/computer/slot_machine/security
+ name = "security slot machine"
+ desc = "Repurposed from a confiscated syndicate gambling ring. Losing is a crime. Winning is also a crime."
+ symbol_paths = list(
+ /obj/item/food/donut/berry,
+ /mob/living/simple_animal/bot/secbot/beepsky,
+ /obj/item/melee/baton/security/loaded,
+ /obj/item/gun/energy/disabler,
+ /obj/vehicle/sealed/mecha/ripley/paddy,
+ /obj/item/book/manual/wiki/security_space_law,
+ /obj/item/grown/bananapeel
+ )
+ jackpot_path = /obj/item/food/donut/berry
+ trap_path = /obj/item/grown/bananapeel
+
+/obj/machinery/computer/slot_machine/security/Initialize(mapload)
+ slot_adjectives += list("Stunned", "Flashed", "Confiscated", "Loyal", "Arrested")
+ slot_nouns += list("Baton", "Donut", "Contraband", "Brig", "Security")
+ . = ..()
+
+/obj/machinery/computer/slot_machine/medical
+ name = "medical slot machine"
+ desc = "A miracle of modern medicine! It cures boredom, but causes acute financial necrosis."
+ symbol_paths = list(
+ /obj/item/storage/medkit/brute,
+ /obj/vehicle/sealed/mecha/odysseus,
+ /obj/item/clothing/glasses/hud/health,
+ /mob/living/basic/pet/cat/runtime,
+ /obj/item/plunger,
+ /obj/item/clothing/neck/stethoscope,
+ /obj/machinery/syndicatebomb,
+ )
+ jackpot_path = /obj/item/clothing/neck/stethoscope
+ trap_path = /obj/machinery/syndicatebomb
+
+/obj/machinery/computer/slot_machine/medical/Initialize(mapload)
+ slot_adjectives += list("Mutated", "Overdosed", "Infectious", "Healing", "Husked")
+ slot_nouns += list("Medkit", "Defib", "Patient", "Doctor", "Cure")
+ . = ..()
+
+/obj/machinery/computer/slot_machine/engineering
+ name = "engineering slot machine"
+ desc = "Gambling for those who think wearing insulated gloves makes them invincible. Ground yourself before playing."
+ symbol_paths = list(
+ /obj/item/storage/toolbox/mechanical,
+ /obj/item/blueprints,
+ /obj/item/clothing/gloves/color/yellow,
+ /obj/item/clothing/head/utility/welding,
+ /obj/item/clothing/glasses/meson,
+ /mob/living/basic/parrot/poly,
+ /obj/singularity,
+ )
+ jackpot_path = /obj/item/blueprints
+ trap_path = /obj/singularity
+
+/obj/machinery/computer/slot_machine/engineering/Initialize(mapload)
+ slot_adjectives += list("Supercharged", "Pressurized", "Radioactive", "Overloaded", "Delaminating", "Insulated")
+ slot_nouns += list("Toolbox", "Emitter", "Supermatter")
+ . = ..()
+
+/obj/machinery/computer/slot_machine/cargo
+ name = "cargo slot machine"
+ desc = "Every credit spent here is a credit that won't be spent on 'useless' things, like food or medicine."
+ symbol_paths = list(
+ /obj/item/bounty_cube,
+ /obj/item/clipboard,
+ /obj/item/universal_scanner,
+ /mob/living/basic/sloth,
+ /obj/item/multitool,
+ /obj/vehicle/sealed/mecha/ripley,
+ /obj/item/suspiciousphone,
+ )
+ jackpot_path = /obj/item/bounty_cube
+ trap_path = /obj/item/suspiciousphone
+
+/obj/machinery/computer/slot_machine/cargo/Initialize(mapload)
+ slot_adjectives += list("Express", "Smuggled", "Stolen", "Overdue", "Subsidized", "Manifested")
+ slot_nouns += list("Bounty", "Crate", "Manifest", "MULE", "Profit")
+ . = ..()
+
+/obj/machinery/computer/slot_machine/service
+ name = "service slot machine"
+ desc = "The handle is a repurposed rolling pin. Every loss is just another ingredient for the daily special."
+ symbol_paths = list(
+ /obj/item/clothing/head/hats/tophat,
+ /obj/item/reagent_containers/cup/watering_can,
+ /obj/item/clothing/shoes/galoshes,
+ /mob/living/basic/goat/pete,
+ /obj/item/book/bible,
+ /obj/item/kitchen/rollingpin,
+ /obj/item/seeds/random,
+ )
+ jackpot_path = /obj/item/seeds/random
+ trap_path = /mob/living/basic/goat/pete
+
+/obj/machinery/computer/slot_machine/service/Initialize(mapload)
+ slot_adjectives += list("Fermented", "Seasoned", "Tipsy", "Cleaned", "Organic", "Culinary", "Refreshing", "Divine", "Holy")
+ slot_nouns += list("Recipe", "Cocktail", "Harvest", "Scrubber")
+ . = ..()
+
+/obj/machinery/computer/slot_machine/science
+ name = "research slot machine"
+ desc = "The reels seem to exist in multiple dimensions at once. It still takes your money in all of them."
+ symbol_paths = list(
+ /obj/item/stack/sheet/mineral/gold,
+ /obj/item/stack/sheet/mineral/silver,
+ /obj/item/stack/sheet/mineral/uranium,
+ /obj/item/stack/sheet/mineral/plasma,
+ /obj/item/stack/sheet/mineral/runite,
+ /obj/item/clothing/mask/facehugger/lamarr,
+ /obj/item/gibtonite,
+ )
+ jackpot_path = /obj/item/stack/sheet/mineral/runite
+ trap_path = /obj/item/gibtonite
+
+/obj/machinery/computer/slot_machine/science/Initialize(mapload)
+ slot_adjectives += list("Atomic", "Bluespace", "Cosmic", "Golden", "Diamond", "Silver", "Uranium", "Quantum", "Anomalous", "Plasma", "Experimental", "Robotic")
+ slot_nouns += list("Anomaly", "Artifact", "Slime", "Extract", "Circuit", "Discovery", "Explosion")
+ . = ..()
+
+/obj/machinery/computer/slot_machine/clown
+ desc = "Gambling is fun! Smells like bananas, wet shoes, and regret. HONK!"
+ symbol_paths = list(
+ /obj/item/food/grown/banana,
+ /obj/item/toy/crayon/spraycan/lubecan,
+ /obj/item/card/id/advanced/rainbow,
+ /obj/vehicle/sealed/mecha/honker,
+ /obj/item/clothing/mask/gas/clown_hat,
+ /obj/item/storage/backpack/clown,
+ /obj/item/restraints/handcuffs,
+ )
+ jackpot_path = /obj/vehicle/sealed/mecha/honker
+ trap_path = /obj/item/restraints/handcuffs
+
+/obj/machinery/computer/slot_machine/clown/Initialize(mapload)
+ slot_adjectives += list("Honking", "Slippery", "Pranked", "Squeaky", "Hilarious", "Giggling")
+ slot_nouns += list("Banana", "Peel", "Prank", "Joke", "Punchline", "Candy", "Honk")
+ . = ..()
+
+/obj/machinery/computer/slot_machine/mime
+ desc = "Gambling is a silent tragedy. The machine stares back at you with a cold indifference."
+ symbol_paths = list(
+ /obj/item/book/granter/action/spell/mime/mimery,
+ /obj/item/clothing/mask/gas/mime,
+ /obj/item/toy/crayon/spraycan/mimecan,
+ /obj/item/reagent_containers/cup/glass/bottle/bottleofnothing,
+ /obj/item/clothing/gloves/color/white,
+ /obj/item/storage/backpack/mime,
+ /obj/item/restraints/handcuffs,
+ )
+ jackpot_path = /obj/item/book/granter/action/spell/mime/mimery
+ trap_path = /obj/item/restraints/handcuffs
+
+/obj/machinery/computer/slot_machine/mime/Initialize(mapload)
+ slot_adjectives += list("Silent", "Transparent", "Unspeakable", "Voiceless", "Quiet", "Hushed", "Invisible", "Imaginary", "Empty")
+ slot_nouns += list("Silence", "Mute", "Introvert", "Nothing", "Baguette")
+ . = ..()
+
+/obj/machinery/computer/slot_machine/syndicate
+ name = "syndicate slot machine"
+ desc = "Gambling for the operative who's already lost everything. Death to Nanotrasen, and death to your wallet."
+ symbol_paths = list(
+ /obj/machinery/nuclearbomb,
+ /obj/item/card/emag,
+ /obj/item/storage/toolbox/syndicate,
+ /obj/vehicle/sealed/mecha/gygax/dark,
+ /obj/item/soap/syndie,
+ /obj/item/gun/energy/recharge/ebow,
+ /obj/item/restraints/handcuffs,
+ )
+ jackpot_path = /obj/machinery/nuclearbomb
+ trap_path = /obj/item/restraints/handcuffs
+
+/obj/machinery/computer/slot_machine/syndicate/Initialize(mapload)
+ slot_adjectives += list("Covert", "Nuclear", "Suspicious", "Bloody", "Syndie", "Sabotaged", "Clandestine", "Illicit", "Traitorous")
+ slot_nouns += list("Telecrystal", "Uplink", "Bomb", "Operative", "Disk", "Nuke", "Syndicate", "Traitor")
+ . = ..()
+
#undef SPIN_PRICE
#undef WINNING_NOTHING
#undef WINNING_FREESPIN
@@ -447,6 +762,5 @@
#undef PRIZE_JACKPOT
#undef SPIN_TIME
#undef REEL_DEACTIVATE_DELAY
-#undef JACKPOT_SEVENS
#undef HOLOCHIP
#undef COIN
diff --git a/code/game/objects/effects/spawners/random/entertainment.dm b/code/game/objects/effects/spawners/random/entertainment.dm
index ddc3dd790dc..fc766d6bd36 100644
--- a/code/game/objects/effects/spawners/random/entertainment.dm
+++ b/code/game/objects/effects/spawners/random/entertainment.dm
@@ -12,6 +12,23 @@
/obj/machinery/computer/arcade/amputation = 2,
)
+/obj/effect/spawner/random/entertainment/slot_machine
+ name = "spawn random slot machine"
+ desc = "Automagically transforms into a random slot machine. If you see this while in a shift, please create a bug report."
+ icon_state = "arcade"
+ loot = list( // syndie slots omitted
+ /obj/machinery/computer/slot_machine = 20,
+ /obj/machinery/computer/slot_machine/security = 10,
+ /obj/machinery/computer/slot_machine/medical = 10,
+ /obj/machinery/computer/slot_machine/engineering = 10,
+ /obj/machinery/computer/slot_machine/cargo = 10,
+ /obj/machinery/computer/slot_machine/service = 10,
+ /obj/machinery/computer/slot_machine/science = 10,
+ /obj/machinery/computer/slot_machine/command = 10,
+ /obj/machinery/computer/slot_machine/clown = 5,
+ /obj/machinery/computer/slot_machine/mime = 5,
+ )
+
/obj/effect/spawner/random/entertainment/musical_instrument
name = "musical instrument spawner"
icon_state = "eguitar"
diff --git a/code/game/objects/items/circuitboards/computer_circuitboards.dm b/code/game/objects/items/circuitboards/computer_circuitboards.dm
index b1a7e0bb445..8dd950e3a6c 100644
--- a/code/game/objects/items/circuitboards/computer_circuitboards.dm
+++ b/code/game/objects/items/circuitboards/computer_circuitboards.dm
@@ -313,6 +313,50 @@
name = "Slot Machine"
greyscale_colors = CIRCUIT_COLOR_GENERIC
build_path = /obj/machinery/computer/slot_machine
+ desc = "You can change the theme using a screwdriver."
+ /// List of pickable slot machines
+ var/static/list/slot_themes = list(
+ "Default" = /obj/machinery/computer/slot_machine,
+ "Command" = /obj/machinery/computer/slot_machine/command,
+ "Security" = /obj/machinery/computer/slot_machine/security,
+ "Medical" = /obj/machinery/computer/slot_machine/medical,
+ "Engineering" = /obj/machinery/computer/slot_machine/engineering,
+ "Cargo" = /obj/machinery/computer/slot_machine/cargo,
+ "Service" = /obj/machinery/computer/slot_machine/service,
+ "Science" = /obj/machinery/computer/slot_machine/science,
+ "Clown" = /obj/machinery/computer/slot_machine/clown,
+ "Mime" = /obj/machinery/computer/slot_machine/mime,
+ )
+
+/obj/item/circuitboard/computer/slot_machine/examine(mob/user)
+ . = ..()
+ var/current_theme = "Unknown"
+ for(var/theme_name in slot_themes)
+ if(slot_themes[theme_name] == build_path)
+ current_theme = theme_name
+ break
+ . += span_info("[src] is set to the [current_theme] theme. You can use a screwdriver to reconfigure it.")
+
+/obj/item/circuitboard/computer/slot_machine/screwdriver_act(mob/living/user, obj/item/tool)
+ if(obj_flags & EMAGGED)
+ balloon_alert(user, "board mode is broken!")
+ return FALSE
+
+ var/choice = tgui_input_list(user, "Choose a slot machine theme", "Theme Selection", slot_themes)
+ if(isnull(choice))
+ return ITEM_INTERACT_BLOCKING
+ build_path = slot_themes[choice]
+ to_chat(user, span_notice("You set the board to the [choice] theme."))
+ return ITEM_INTERACT_SUCCESS
+
+/obj/item/circuitboard/computer/slot_machine/emag_act(mob/user, obj/item/card/emag/emag_card)
+ if(obj_flags & EMAGGED)
+ return FALSE
+
+ obj_flags |= EMAGGED
+ build_path = /obj/machinery/computer/slot_machine/syndicate
+ balloon_alert(user, "illegal slot machine loaded")
+ return TRUE
/obj/item/circuitboard/computer/swfdoor
name = "Magix"
diff --git a/code/modules/asset_cache/assets/slot_machines.dm b/code/modules/asset_cache/assets/slot_machines.dm
new file mode 100644
index 00000000000..c3210bb3672
--- /dev/null
+++ b/code/modules/asset_cache/assets/slot_machines.dm
@@ -0,0 +1,24 @@
+/datum/asset/spritesheet_batched/slot_machines
+ name = "slotmachines"
+
+/datum/asset/spritesheet_batched/slot_machines/create_spritesheets()
+ // initialising the list of items we need
+ var/list/target_items = list()
+ for(var/obj/machinery/computer/slot_machine/slot_machine as anything in typesof(/obj/machinery/computer/slot_machine))
+ slot_machine = new slot_machine()
+ target_items |= slot_machine.symbol_paths // no dupes
+ qdel(slot_machine)
+
+ for(var/atom/atom as anything in target_items)
+ var/icon = initial(atom.icon)
+ var/icon_state = initial(atom.icon_state)
+ var/id = sanitize_css_class_name("[icon][icon_state]")
+
+ var/has_gags = atom::greyscale_config && atom::greyscale_colors
+ var/has_color = atom::color && icon_state
+ // GAGS and colored icons must be pregenerated so blacklist them for now
+ if(has_gags || has_color)
+ stack_trace("[atom] is either using GAGS or colored icons which is not supported for slot machine reels")
+ continue
+
+ insert_icon(id, uni_icon(icon, icon_state))
diff --git a/icons/effects/random_spawners.dmi b/icons/effects/random_spawners.dmi
index 3450f6754c2..4d816c6df80 100644
Binary files a/icons/effects/random_spawners.dmi and b/icons/effects/random_spawners.dmi differ
diff --git a/tgstation.dme b/tgstation.dme
index ca737cae21b..247820c849f 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -3716,6 +3716,7 @@
#include "code\modules\asset_cache\assets\safe.dm"
#include "code\modules\asset_cache\assets\seeds.dm"
#include "code\modules\asset_cache\assets\sheetmaterials.dm"
+#include "code\modules\asset_cache\assets\slot_machines.dm"
#include "code\modules\asset_cache\assets\supplypods.dm"
#include "code\modules\asset_cache\assets\tcomms.dm"
#include "code\modules\asset_cache\assets\tgfont.dm"
diff --git a/tgui/packages/tgui/interfaces/SlotMachine.tsx b/tgui/packages/tgui/interfaces/SlotMachine.tsx
index 54045ecfac1..784e6b98d57 100644
--- a/tgui/packages/tgui/interfaces/SlotMachine.tsx
+++ b/tgui/packages/tgui/interfaces/SlotMachine.tsx
@@ -1,12 +1,12 @@
-import { useEffect, useRef, useState } from 'react';
-import { Blink, Box, Button, Icon, Section, Stack } from 'tgui-core/components';
+import { useEffect, useMemo, useRef, useState } from 'react';
+import { Blink, Box, Button, Section, Stack } from 'tgui-core/components';
import { formatMoney } from 'tgui-core/format';
import { classes } from 'tgui-core/react';
import { useBackend } from '../backend';
import { Window } from '../layouts';
type Data = {
- icons: string[];
+ symbols: SlotSymbol[];
reels: Reel[];
balance: number;
working: number;
@@ -17,36 +17,24 @@ type Data = {
jackpots: number;
jackpot: number;
paymode: number;
+ jackpot_id: string;
+ trap_id: string;
+};
+
+type SlotSymbol = {
+ id: string;
+ icon_id: string;
};
type Reel = {
- icons: string[];
- spinning: number;
-};
-
-type IconMeta = {
- color: string;
-};
-
-const iconMetaByName: Record = {
- 'fa-7': { color: '#b22' },
- 'fa-star': { color: '#fd6' },
- 'fa-lemon': { color: '#ce0' },
- 'fa-apple-whole': { color: '#d64' },
- 'fa-biohazard': { color: '#2c0' },
- 'fa-dollar-sign': { color: '#08b' },
- 'fa-bomb': { color: '#876' },
+ symbols: string[];
};
const pluralS = (amount: number) => {
return amount === 1 ? '' : 's';
};
-const slotIconToColor = (iconName: string): string => {
- return iconMetaByName[iconName]?.color || '#f0f';
-};
-
-const pickRandomMany = (items: T[], n: number) => {
+const pickRandomMany = (items: T[], n: number) => {
const result: T[] = [];
for (let i = 0; i < n; i += 1) {
result.push(pickRandom(items));
@@ -54,17 +42,28 @@ const pickRandomMany = (items: T[], n: number) => {
return result;
};
-const pickRandom = (items: T[]) => {
+const pickRandom = (items: T[]) => {
return items[Math.floor(Math.random() * items.length)];
};
export const SlotMachine = () => {
const { act, data } = useBackend();
- const { icons, cost, reels, balance } = data;
+ const { symbols, cost, reels, balance } = data;
const spinning = data.working === 1;
+ const symbolsById = useMemo(() => {
+ const map: Record = {};
+ for (const symbol of symbols) {
+ map[symbol.id] = symbol;
+ }
+ return map;
+ }, [symbols]);
+
+ const jackpotSymbol = symbolsById[data.jackpot_id];
+ const trapSymbol = data.trap_id ? symbolsById[data.trap_id] : null;
+
return (
-
+
@@ -72,43 +71,82 @@ export const SlotMachine = () => {
{reels.map((reel, i) => (
))}
-
-
- act('payout')} disabled={balance <= 0}>
- Refund
-
- }
- >
-
- {formatMoney(balance)} cr
+
+
+
+
+ Jackpot:
+ {jackpotSymbol && (
+
+ )}
+
+ {trapSymbol && (
+ <>
+
+ Trap:
+
+
+ >
+ )}
-
-
-
+
+
+ act('payout')}
+ disabled={balance <= 0}
+ >
+ Refund
+
+ }
+ >
+
+ {formatMoney(balance)} cr
+
+
+
+
+
+
+
+
+
@@ -301,30 +339,32 @@ const BannerStats = () => {
const ICON_STRIP_LENGTH = 30;
type IconStripProps = {
- icons: string[];
- iconsNeeded: string[];
+ symbols: SlotSymbol[];
+ symbolsById: Record;
+ symbolsNeeded: string[];
spinning?: boolean;
};
const IconStrip = (props: IconStripProps) => {
- const { icons, iconsNeeded, spinning } = props;
+ const { symbols, symbolsById, symbolsNeeded, spinning } = props;
+ const symbolIds = useMemo(() => symbols.map((s) => s.id), [symbols]);
- const [drawnIcons, setDrawnIcons] = useState([
- ...pickRandomMany(icons, ICON_STRIP_LENGTH - 3),
- ...iconsNeeded,
+ const [drawnSymbols, setDrawnSymbols] = useState([
+ ...pickRandomMany(symbolIds, ICON_STRIP_LENGTH - 3),
+ ...symbolsNeeded,
]);
useEffect(() => {
if (spinning) {
- setDrawnIcons((drawnIcons) => [
- ...drawnIcons.slice(-3),
- ...pickRandomMany(icons, ICON_STRIP_LENGTH - 6),
- ...iconsNeeded,
+ setDrawnSymbols((drawn) => [
+ ...drawn.slice(-3),
+ ...pickRandomMany(symbolIds, ICON_STRIP_LENGTH - 6),
+ ...symbolsNeeded,
]);
} else {
- setDrawnIcons([
- ...pickRandomMany(icons, ICON_STRIP_LENGTH - 3),
- ...iconsNeeded,
+ setDrawnSymbols([
+ ...pickRandomMany(symbolIds, ICON_STRIP_LENGTH - 3),
+ ...symbolsNeeded,
]);
}
}, [spinning]);
@@ -336,18 +376,16 @@ const IconStrip = (props: IconStripProps) => {
spinning && 'SlotMachine__IconStrip--spinning',
])}
>
- {drawnIcons.map((icon, i) => (
-
- ))}
+ {drawnSymbols.map((symbolId, i) => {
+ const symbol = symbolsById[symbolId];
+ return (
+
+ {symbol && (
+
+ )}
+
+ );
+ })}
);
};
diff --git a/tgui/packages/tgui/styles/interfaces/SlotMachine.scss b/tgui/packages/tgui/styles/interfaces/SlotMachine.scss
index 82599f53d22..48583d4d982 100644
--- a/tgui/packages/tgui/styles/interfaces/SlotMachine.scss
+++ b/tgui/packages/tgui/styles/interfaces/SlotMachine.scss
@@ -152,15 +152,6 @@
transform: translateY(calc(-60px * 27));
// animation-duration: 3.5s;
text-align: center;
- // animation: scroll-up 2s linear infinite;
- // animation-play-state: paused;
- // transform: translateY(0px);
- text-shadow:
- 2px 2px 6px #000,
- 0 2px #000,
- 0 -2px #000,
- 2px 0 #000,
- -2px 0 #000;
}
.SlotMachine__IconStrip--spinning {
@@ -171,6 +162,20 @@
animation-timing-function: cubic-bezier(1, 1.26, 0.88, 0.96);
}
+.SlotMachine__Symbol {
+ height: 60px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+
+ .slotmachines32x32 {
+ width: 32px;
+ height: 32px;
+ image-rendering: pixelated;
+ filter: drop-shadow(1px 1px 1px black);
+ }
+}
+
@keyframes SlotMachine__Spin {
0% {
transform: translateY(0);