[MIRROR] Mafia can be played on your PDA [MDB IGNORE] (#24485)
* Mafia can be played on your PDA (#78576) ## About The Pull Request Mafia is now friggin playable from the PDA, I also changed other stuff too - You can't use abilities on dead people if you're not supposed to (cant kill the same person over and over) - Changelings cant kill other Changelings - Changelings can now only talk to eachother at night, rather than using :j - Everyone starts spawned in the center of the map, since people playing on PDA can't move their characters. This is so everyone can hear PDA users in person, as I don't want the chat log to be mandatory. To do this, all messages you are meant to be able to see, is now logged for you to see in your Mafia panel. This essentially means that people playing through the PDA get a downgraded version of it, but I don't know how much larger I want this UI to be. Playing Mafia through the PDA will not tell you of other players ahead of time when signing up (as it shows ckeys + pdas), but they can see the names in-game. Unfortunately this means we'll have to remove your customization coming with you, to prevent using it to tell who is dead in round. Things I am missing - Program overlays on PDA/Laptop/Computer - Icon for the app's header while a game is active I'm not a spriter and can't make either of these This is the new UI  I also fixed alert calls for PDAs and stuff  and removed the X at the top on computers since they had no battery  Looks a little better now hopefully 👍 ## Why It's Good For The Game - The current Arcade app sucks, and is a solo game. This is much more entertaining and you can talk to others in it, which is swag as fuck. - There's a larger potential playerbase for the Minigame making it more likely to be played. - Sets groundwork for a better version of https://github.com/tgstation/tgstation/pull/75879 - Adds more suspense and teamwork in the minigame. ## Changelog 🆑 JohnFulpWillard, sprites by CoiledLamb add: You can now play Mafia on your PDA. balance: Mafia changelings can now only talk to eachother during the night. fix: Mafia abilities can't be repeatedly used on people. /🆑 * Mafia can be played on your PDA --------- Co-authored-by: John Willard <53777086+JohnFulpWillard@users.noreply.github.com>
@@ -5,6 +5,10 @@
|
||||
"b" = (
|
||||
/turf/closed/indestructible/alien,
|
||||
/area/centcom/mafia)
|
||||
"d" = (
|
||||
/obj/effect/landmark/mafia,
|
||||
/turf/open/floor/plating/abductor,
|
||||
/area/centcom/mafia)
|
||||
"g" = (
|
||||
/obj/mafia_game_board,
|
||||
/obj/effect/mapping_helpers/broken_floor,
|
||||
@@ -32,12 +36,10 @@
|
||||
/turf/open/floor/plating/abductor,
|
||||
/area/centcom/mafia)
|
||||
"m" = (
|
||||
/obj/effect/landmark/mafia,
|
||||
/obj/structure/bed/abductor,
|
||||
/turf/open/floor/plating/abductor,
|
||||
/area/centcom/mafia)
|
||||
"n" = (
|
||||
/obj/effect/landmark/mafia,
|
||||
/obj/structure/bed/abductor,
|
||||
/turf/open/floor/plating/abductor2,
|
||||
/area/centcom/mafia)
|
||||
@@ -146,6 +148,10 @@
|
||||
icon_state = "alien21"
|
||||
},
|
||||
/area/centcom/mafia)
|
||||
"O" = (
|
||||
/obj/effect/landmark/mafia,
|
||||
/turf/open/floor/plating/abductor2,
|
||||
/area/centcom/mafia)
|
||||
"P" = (
|
||||
/turf/closed/indestructible/abductor,
|
||||
/area/centcom/mafia)
|
||||
@@ -394,13 +400,13 @@ W
|
||||
G
|
||||
x
|
||||
r
|
||||
r
|
||||
O
|
||||
x
|
||||
q
|
||||
d
|
||||
x
|
||||
r
|
||||
O
|
||||
x
|
||||
q
|
||||
d
|
||||
q
|
||||
x
|
||||
E
|
||||
@@ -444,13 +450,13 @@ j
|
||||
m
|
||||
q
|
||||
q
|
||||
q
|
||||
d
|
||||
x
|
||||
t
|
||||
t
|
||||
t
|
||||
x
|
||||
r
|
||||
O
|
||||
r
|
||||
r
|
||||
n
|
||||
@@ -494,13 +500,13 @@ j
|
||||
n
|
||||
r
|
||||
r
|
||||
r
|
||||
O
|
||||
x
|
||||
t
|
||||
t
|
||||
t
|
||||
x
|
||||
q
|
||||
d
|
||||
q
|
||||
q
|
||||
m
|
||||
@@ -544,13 +550,13 @@ I
|
||||
J
|
||||
x
|
||||
q
|
||||
q
|
||||
d
|
||||
x
|
||||
r
|
||||
O
|
||||
x
|
||||
q
|
||||
d
|
||||
x
|
||||
r
|
||||
O
|
||||
r
|
||||
x
|
||||
Y
|
||||
|
||||
@@ -252,11 +252,11 @@ b
|
||||
o
|
||||
r
|
||||
p
|
||||
m
|
||||
q
|
||||
q
|
||||
p
|
||||
r
|
||||
n
|
||||
r
|
||||
p
|
||||
q
|
||||
l
|
||||
@@ -274,7 +274,7 @@ c
|
||||
d
|
||||
d
|
||||
b
|
||||
n
|
||||
r
|
||||
r
|
||||
b
|
||||
b
|
||||
@@ -284,7 +284,7 @@ r
|
||||
b
|
||||
b
|
||||
q
|
||||
m
|
||||
q
|
||||
b
|
||||
d
|
||||
d
|
||||
@@ -301,13 +301,13 @@ b
|
||||
b
|
||||
p
|
||||
r
|
||||
r
|
||||
n
|
||||
p
|
||||
q
|
||||
m
|
||||
p
|
||||
r
|
||||
n
|
||||
p
|
||||
q
|
||||
m
|
||||
q
|
||||
p
|
||||
b
|
||||
@@ -348,19 +348,19 @@ b
|
||||
c
|
||||
d
|
||||
j
|
||||
q
|
||||
q
|
||||
q
|
||||
m
|
||||
q
|
||||
q
|
||||
q
|
||||
p
|
||||
s
|
||||
t
|
||||
s
|
||||
p
|
||||
r
|
||||
r
|
||||
r
|
||||
n
|
||||
r
|
||||
r
|
||||
r
|
||||
j
|
||||
i
|
||||
c
|
||||
@@ -398,19 +398,19 @@ b
|
||||
c
|
||||
d
|
||||
j
|
||||
r
|
||||
r
|
||||
r
|
||||
n
|
||||
r
|
||||
r
|
||||
r
|
||||
p
|
||||
s
|
||||
t
|
||||
s
|
||||
p
|
||||
q
|
||||
q
|
||||
q
|
||||
m
|
||||
q
|
||||
q
|
||||
q
|
||||
j
|
||||
d
|
||||
c
|
||||
@@ -451,13 +451,13 @@ b
|
||||
b
|
||||
p
|
||||
q
|
||||
q
|
||||
m
|
||||
p
|
||||
r
|
||||
n
|
||||
p
|
||||
q
|
||||
m
|
||||
p
|
||||
r
|
||||
n
|
||||
r
|
||||
p
|
||||
b
|
||||
@@ -474,7 +474,7 @@ c
|
||||
f
|
||||
d
|
||||
b
|
||||
m
|
||||
q
|
||||
q
|
||||
b
|
||||
b
|
||||
@@ -484,7 +484,7 @@ q
|
||||
b
|
||||
b
|
||||
r
|
||||
n
|
||||
r
|
||||
b
|
||||
d
|
||||
d
|
||||
@@ -502,11 +502,11 @@ b
|
||||
l
|
||||
q
|
||||
p
|
||||
n
|
||||
r
|
||||
r
|
||||
p
|
||||
q
|
||||
m
|
||||
q
|
||||
p
|
||||
r
|
||||
o
|
||||
|
||||
@@ -297,11 +297,11 @@ b
|
||||
J
|
||||
r
|
||||
p
|
||||
m
|
||||
q
|
||||
q
|
||||
p
|
||||
E
|
||||
N
|
||||
O
|
||||
p
|
||||
q
|
||||
l
|
||||
@@ -319,7 +319,7 @@ c
|
||||
d
|
||||
d
|
||||
b
|
||||
D
|
||||
E
|
||||
O
|
||||
b
|
||||
b
|
||||
@@ -329,7 +329,7 @@ r
|
||||
b
|
||||
b
|
||||
q
|
||||
m
|
||||
q
|
||||
b
|
||||
d
|
||||
d
|
||||
@@ -346,13 +346,13 @@ b
|
||||
b
|
||||
p
|
||||
X
|
||||
r
|
||||
M
|
||||
p
|
||||
q
|
||||
m
|
||||
p
|
||||
O
|
||||
N
|
||||
p
|
||||
q
|
||||
m
|
||||
q
|
||||
p
|
||||
b
|
||||
@@ -393,19 +393,19 @@ b
|
||||
c
|
||||
d
|
||||
j
|
||||
q
|
||||
q
|
||||
q
|
||||
m
|
||||
q
|
||||
q
|
||||
q
|
||||
p
|
||||
t
|
||||
t
|
||||
t
|
||||
p
|
||||
X
|
||||
n
|
||||
r
|
||||
E
|
||||
N
|
||||
O
|
||||
j
|
||||
i
|
||||
c
|
||||
@@ -443,19 +443,19 @@ b
|
||||
c
|
||||
d
|
||||
j
|
||||
n
|
||||
X
|
||||
r
|
||||
E
|
||||
O
|
||||
N
|
||||
p
|
||||
t
|
||||
t
|
||||
t
|
||||
p
|
||||
q
|
||||
q
|
||||
q
|
||||
m
|
||||
q
|
||||
q
|
||||
q
|
||||
j
|
||||
d
|
||||
c
|
||||
@@ -496,13 +496,13 @@ b
|
||||
b
|
||||
p
|
||||
q
|
||||
q
|
||||
m
|
||||
p
|
||||
X
|
||||
n
|
||||
p
|
||||
q
|
||||
m
|
||||
p
|
||||
E
|
||||
D
|
||||
O
|
||||
p
|
||||
b
|
||||
@@ -519,7 +519,7 @@ c
|
||||
f
|
||||
d
|
||||
b
|
||||
m
|
||||
q
|
||||
q
|
||||
b
|
||||
b
|
||||
@@ -529,7 +529,7 @@ q
|
||||
b
|
||||
b
|
||||
X
|
||||
M
|
||||
r
|
||||
b
|
||||
d
|
||||
d
|
||||
@@ -547,11 +547,11 @@ b
|
||||
l
|
||||
q
|
||||
p
|
||||
n
|
||||
X
|
||||
r
|
||||
p
|
||||
q
|
||||
m
|
||||
q
|
||||
p
|
||||
E
|
||||
P
|
||||
|
||||
@@ -60,7 +60,6 @@
|
||||
/turf/open/floor/fakebasalt,
|
||||
/area/centcom/mafia)
|
||||
"an" = (
|
||||
/obj/effect/landmark/mafia,
|
||||
/obj/effect/turf_decal/trimline/brown/filled/line{
|
||||
dir = 9
|
||||
},
|
||||
@@ -126,6 +125,7 @@
|
||||
/obj/effect/turf_decal/trimline/brown/filled/end{
|
||||
dir = 4
|
||||
},
|
||||
/obj/effect/landmark/mafia,
|
||||
/turf/open/floor/iron,
|
||||
/area/centcom/mafia)
|
||||
"az" = (
|
||||
@@ -137,17 +137,11 @@
|
||||
/obj/structure/closet/secure_closet/miner/unlocked,
|
||||
/turf/open/floor/iron,
|
||||
/area/centcom/mafia)
|
||||
"aA" = (
|
||||
/obj/effect/landmark/mafia,
|
||||
/obj/effect/turf_decal/trimline/brown/filled/line{
|
||||
dir = 6
|
||||
},
|
||||
/turf/open/floor/iron,
|
||||
/area/centcom/mafia)
|
||||
"aB" = (
|
||||
/obj/effect/turf_decal/trimline/brown/filled/end{
|
||||
dir = 1
|
||||
},
|
||||
/obj/effect/landmark/mafia,
|
||||
/turf/open/floor/iron,
|
||||
/area/centcom/mafia)
|
||||
"aC" = (
|
||||
@@ -183,13 +177,6 @@
|
||||
},
|
||||
/turf/open/floor/iron,
|
||||
/area/centcom/mafia)
|
||||
"aG" = (
|
||||
/obj/effect/landmark/mafia,
|
||||
/obj/effect/turf_decal/trimline/brown/filled/line{
|
||||
dir = 10
|
||||
},
|
||||
/turf/open/floor/iron,
|
||||
/area/centcom/mafia)
|
||||
"aH" = (
|
||||
/obj/effect/turf_decal/trimline/brown/filled/line{
|
||||
dir = 10
|
||||
@@ -209,7 +196,6 @@
|
||||
/turf/open/floor/iron,
|
||||
/area/centcom/mafia)
|
||||
"aJ" = (
|
||||
/obj/effect/landmark/mafia,
|
||||
/obj/effect/turf_decal/trimline/brown/filled/line{
|
||||
dir = 6
|
||||
},
|
||||
@@ -227,13 +213,6 @@
|
||||
/obj/structure/closet/secure_closet/miner/unlocked,
|
||||
/turf/open/floor/iron,
|
||||
/area/centcom/mafia)
|
||||
"aL" = (
|
||||
/obj/effect/landmark/mafia,
|
||||
/obj/effect/turf_decal/trimline/brown/filled/line{
|
||||
dir = 5
|
||||
},
|
||||
/turf/open/floor/iron,
|
||||
/area/centcom/mafia)
|
||||
"aM" = (
|
||||
/obj/effect/turf_decal/trimline/brown/filled/line{
|
||||
dir = 10
|
||||
@@ -258,13 +237,7 @@
|
||||
/area/centcom/mafia)
|
||||
"aP" = (
|
||||
/obj/effect/turf_decal/trimline/brown/filled/end,
|
||||
/turf/open/floor/iron,
|
||||
/area/centcom/mafia)
|
||||
"aQ" = (
|
||||
/obj/effect/landmark/mafia,
|
||||
/obj/effect/turf_decal/trimline/brown/filled/line{
|
||||
dir = 9
|
||||
},
|
||||
/turf/open/floor/iron,
|
||||
/area/centcom/mafia)
|
||||
"aR" = (
|
||||
@@ -277,6 +250,7 @@
|
||||
/obj/effect/turf_decal/trimline/brown/filled/end{
|
||||
dir = 8
|
||||
},
|
||||
/obj/effect/landmark/mafia,
|
||||
/turf/open/floor/iron,
|
||||
/area/centcom/mafia)
|
||||
"aT" = (
|
||||
@@ -473,11 +447,11 @@ aY
|
||||
ar
|
||||
aM
|
||||
ap
|
||||
am
|
||||
aq
|
||||
aq
|
||||
ap
|
||||
aw
|
||||
aA
|
||||
aV
|
||||
ap
|
||||
aq
|
||||
al
|
||||
@@ -495,7 +469,7 @@ ac
|
||||
ad
|
||||
ad
|
||||
aY
|
||||
aL
|
||||
aF
|
||||
aN
|
||||
aY
|
||||
aY
|
||||
@@ -505,7 +479,7 @@ ax
|
||||
aY
|
||||
aY
|
||||
aq
|
||||
am
|
||||
aq
|
||||
aY
|
||||
ad
|
||||
ad
|
||||
@@ -524,11 +498,11 @@ ap
|
||||
aO
|
||||
aP
|
||||
ap
|
||||
aq
|
||||
am
|
||||
ap
|
||||
ay
|
||||
ap
|
||||
aq
|
||||
am
|
||||
aq
|
||||
ap
|
||||
aY
|
||||
@@ -569,10 +543,10 @@ aY
|
||||
ac
|
||||
ad
|
||||
aj
|
||||
aq
|
||||
aq
|
||||
aq
|
||||
am
|
||||
aq
|
||||
aq
|
||||
aq
|
||||
ap
|
||||
aq
|
||||
aZ
|
||||
@@ -628,10 +602,10 @@ aq
|
||||
ab
|
||||
aq
|
||||
ap
|
||||
aq
|
||||
aq
|
||||
aq
|
||||
am
|
||||
aq
|
||||
aq
|
||||
aq
|
||||
aj
|
||||
ad
|
||||
ac
|
||||
@@ -672,11 +646,11 @@ aY
|
||||
aY
|
||||
ap
|
||||
aq
|
||||
aq
|
||||
am
|
||||
ap
|
||||
aS
|
||||
ap
|
||||
aq
|
||||
am
|
||||
ap
|
||||
aB
|
||||
aD
|
||||
@@ -695,7 +669,7 @@ ac
|
||||
af
|
||||
ad
|
||||
aY
|
||||
am
|
||||
aq
|
||||
aq
|
||||
aY
|
||||
aY
|
||||
@@ -705,7 +679,7 @@ aq
|
||||
aY
|
||||
aY
|
||||
aE
|
||||
aG
|
||||
aM
|
||||
aY
|
||||
ad
|
||||
ad
|
||||
@@ -723,11 +697,11 @@ aY
|
||||
al
|
||||
aq
|
||||
ap
|
||||
aQ
|
||||
as
|
||||
aU
|
||||
ap
|
||||
aq
|
||||
am
|
||||
aq
|
||||
ap
|
||||
aF
|
||||
aI
|
||||
|
||||
@@ -8,6 +8,10 @@
|
||||
"d" = (
|
||||
/turf/open/floor/plating,
|
||||
/area/centcom/mafia)
|
||||
"e" = (
|
||||
/obj/effect/landmark/mafia,
|
||||
/turf/open/floor/iron/dark,
|
||||
/area/centcom/mafia)
|
||||
"f" = (
|
||||
/obj/effect/mapping_helpers/burnt_floor,
|
||||
/turf/open/floor/plating,
|
||||
@@ -46,10 +50,6 @@
|
||||
},
|
||||
/turf/open/floor/holofloor/wood,
|
||||
/area/centcom/mafia)
|
||||
"m" = (
|
||||
/obj/effect/landmark/mafia,
|
||||
/turf/open/floor/holofloor/wood,
|
||||
/area/centcom/mafia)
|
||||
"n" = (
|
||||
/obj/item/bedsheet/green,
|
||||
/obj/structure/bed,
|
||||
@@ -133,11 +133,6 @@
|
||||
},
|
||||
/turf/open/floor/iron,
|
||||
/area/centcom/mafia)
|
||||
"B" = (
|
||||
/obj/effect/landmark/mafia,
|
||||
/obj/structure/lattice/catwalk,
|
||||
/turf/open/lava/plasma/mafia,
|
||||
/area/centcom/mafia)
|
||||
"C" = (
|
||||
/obj/mafia_game_board,
|
||||
/turf/open/floor/holofloor/snow,
|
||||
@@ -181,6 +176,15 @@
|
||||
"K" = (
|
||||
/turf/closed/indestructible/rock/snow,
|
||||
/area/centcom/mafia)
|
||||
"R" = (
|
||||
/obj/effect/landmark/mafia,
|
||||
/turf/open/floor/iron,
|
||||
/area/centcom/mafia)
|
||||
"W" = (
|
||||
/obj/structure/lattice/catwalk,
|
||||
/obj/effect/landmark/mafia,
|
||||
/turf/open/lava/plasma/mafia,
|
||||
/area/centcom/mafia)
|
||||
|
||||
(1,1,1) = {"
|
||||
a
|
||||
@@ -342,11 +346,11 @@ s
|
||||
o
|
||||
F
|
||||
p
|
||||
m
|
||||
F
|
||||
q
|
||||
p
|
||||
t
|
||||
y
|
||||
t
|
||||
p
|
||||
z
|
||||
E
|
||||
@@ -364,7 +368,7 @@ s
|
||||
d
|
||||
d
|
||||
s
|
||||
m
|
||||
F
|
||||
r
|
||||
s
|
||||
s
|
||||
@@ -374,7 +378,7 @@ t
|
||||
p
|
||||
p
|
||||
z
|
||||
B
|
||||
z
|
||||
p
|
||||
w
|
||||
w
|
||||
@@ -391,13 +395,13 @@ s
|
||||
s
|
||||
p
|
||||
r
|
||||
r
|
||||
R
|
||||
p
|
||||
q
|
||||
e
|
||||
p
|
||||
t
|
||||
y
|
||||
p
|
||||
z
|
||||
W
|
||||
z
|
||||
p
|
||||
p
|
||||
@@ -438,19 +442,19 @@ b
|
||||
s
|
||||
d
|
||||
j
|
||||
m
|
||||
F
|
||||
F
|
||||
q
|
||||
q
|
||||
e
|
||||
x
|
||||
J
|
||||
t
|
||||
t
|
||||
p
|
||||
t
|
||||
t
|
||||
t
|
||||
y
|
||||
t
|
||||
t
|
||||
t
|
||||
p
|
||||
w
|
||||
t
|
||||
@@ -488,19 +492,19 @@ b
|
||||
s
|
||||
d
|
||||
j
|
||||
m
|
||||
F
|
||||
F
|
||||
r
|
||||
r
|
||||
R
|
||||
A
|
||||
J
|
||||
t
|
||||
t
|
||||
p
|
||||
t
|
||||
t
|
||||
t
|
||||
y
|
||||
t
|
||||
t
|
||||
t
|
||||
p
|
||||
w
|
||||
w
|
||||
@@ -541,13 +545,13 @@ s
|
||||
s
|
||||
p
|
||||
q
|
||||
q
|
||||
e
|
||||
p
|
||||
r
|
||||
R
|
||||
p
|
||||
t
|
||||
y
|
||||
p
|
||||
z
|
||||
W
|
||||
z
|
||||
p
|
||||
p
|
||||
@@ -564,7 +568,7 @@ s
|
||||
f
|
||||
d
|
||||
s
|
||||
m
|
||||
F
|
||||
q
|
||||
s
|
||||
s
|
||||
@@ -574,7 +578,7 @@ t
|
||||
p
|
||||
p
|
||||
z
|
||||
B
|
||||
z
|
||||
p
|
||||
w
|
||||
w
|
||||
@@ -592,11 +596,11 @@ s
|
||||
G
|
||||
F
|
||||
p
|
||||
m
|
||||
F
|
||||
r
|
||||
p
|
||||
t
|
||||
y
|
||||
t
|
||||
p
|
||||
z
|
||||
E
|
||||
|
||||
@@ -258,11 +258,11 @@ S
|
||||
b
|
||||
r
|
||||
p
|
||||
m
|
||||
q
|
||||
q
|
||||
p
|
||||
r
|
||||
n
|
||||
r
|
||||
p
|
||||
q
|
||||
o
|
||||
@@ -280,7 +280,7 @@ c
|
||||
d
|
||||
d
|
||||
S
|
||||
n
|
||||
r
|
||||
r
|
||||
S
|
||||
S
|
||||
@@ -290,7 +290,7 @@ r
|
||||
S
|
||||
S
|
||||
q
|
||||
m
|
||||
q
|
||||
S
|
||||
d
|
||||
d
|
||||
@@ -307,13 +307,13 @@ S
|
||||
S
|
||||
p
|
||||
r
|
||||
r
|
||||
n
|
||||
p
|
||||
q
|
||||
m
|
||||
p
|
||||
r
|
||||
n
|
||||
p
|
||||
q
|
||||
m
|
||||
q
|
||||
p
|
||||
S
|
||||
@@ -354,19 +354,19 @@ S
|
||||
c
|
||||
d
|
||||
j
|
||||
q
|
||||
q
|
||||
q
|
||||
m
|
||||
q
|
||||
q
|
||||
q
|
||||
p
|
||||
t
|
||||
t
|
||||
t
|
||||
p
|
||||
r
|
||||
r
|
||||
r
|
||||
n
|
||||
r
|
||||
r
|
||||
r
|
||||
j
|
||||
i
|
||||
c
|
||||
@@ -404,19 +404,19 @@ S
|
||||
c
|
||||
d
|
||||
j
|
||||
r
|
||||
r
|
||||
r
|
||||
n
|
||||
r
|
||||
r
|
||||
r
|
||||
p
|
||||
t
|
||||
t
|
||||
t
|
||||
p
|
||||
q
|
||||
q
|
||||
q
|
||||
m
|
||||
q
|
||||
q
|
||||
q
|
||||
j
|
||||
d
|
||||
c
|
||||
@@ -457,13 +457,13 @@ S
|
||||
S
|
||||
p
|
||||
q
|
||||
q
|
||||
m
|
||||
p
|
||||
r
|
||||
n
|
||||
p
|
||||
q
|
||||
m
|
||||
p
|
||||
r
|
||||
n
|
||||
r
|
||||
p
|
||||
S
|
||||
@@ -480,7 +480,7 @@ c
|
||||
f
|
||||
d
|
||||
S
|
||||
m
|
||||
q
|
||||
q
|
||||
S
|
||||
S
|
||||
@@ -490,7 +490,7 @@ q
|
||||
S
|
||||
S
|
||||
r
|
||||
n
|
||||
r
|
||||
S
|
||||
d
|
||||
d
|
||||
@@ -508,11 +508,11 @@ S
|
||||
o
|
||||
q
|
||||
p
|
||||
n
|
||||
r
|
||||
r
|
||||
p
|
||||
q
|
||||
m
|
||||
q
|
||||
p
|
||||
r
|
||||
b
|
||||
|
||||
@@ -45,10 +45,6 @@
|
||||
/obj/mafia_game_board,
|
||||
/turf/open/floor/plating,
|
||||
/area/centcom/mafia)
|
||||
"n" = (
|
||||
/obj/effect/landmark/mafia,
|
||||
/turf/open/floor/mineral/plastitanium,
|
||||
/area/centcom/mafia)
|
||||
"o" = (
|
||||
/obj/effect/turf_decal/tile/red/fourcorners,
|
||||
/turf/open/floor/iron/dark,
|
||||
@@ -68,6 +64,7 @@
|
||||
name = "tactical swivel chair"
|
||||
},
|
||||
/obj/effect/turf_decal/tile/red/fourcorners,
|
||||
/obj/effect/landmark/mafia,
|
||||
/turf/open/floor/iron/dark,
|
||||
/area/centcom/mafia)
|
||||
"r" = (
|
||||
@@ -93,12 +90,14 @@
|
||||
name = "tactical swivel chair"
|
||||
},
|
||||
/obj/effect/turf_decal/tile/red/fourcorners,
|
||||
/obj/effect/landmark/mafia,
|
||||
/turf/open/floor/iron/dark,
|
||||
/area/centcom/mafia)
|
||||
"y" = (
|
||||
/obj/structure/chair/office{
|
||||
name = "tactical swivel chair"
|
||||
},
|
||||
/obj/effect/landmark/mafia,
|
||||
/turf/open/floor/mineral/plastitanium,
|
||||
/area/centcom/mafia)
|
||||
"z" = (
|
||||
@@ -106,6 +105,7 @@
|
||||
name = "tactical swivel chair"
|
||||
},
|
||||
/obj/effect/turf_decal/tile/red/fourcorners,
|
||||
/obj/effect/landmark/mafia,
|
||||
/turf/open/floor/iron/dark,
|
||||
/area/centcom/mafia)
|
||||
"A" = (
|
||||
@@ -113,6 +113,7 @@
|
||||
dir = 8;
|
||||
name = "tactical swivel chair"
|
||||
},
|
||||
/obj/effect/landmark/mafia,
|
||||
/turf/open/floor/mineral/plastitanium,
|
||||
/area/centcom/mafia)
|
||||
"B" = (
|
||||
@@ -120,6 +121,7 @@
|
||||
dir = 4;
|
||||
name = "tactical swivel chair"
|
||||
},
|
||||
/obj/effect/landmark/mafia,
|
||||
/turf/open/floor/mineral/plastitanium,
|
||||
/area/centcom/mafia)
|
||||
"C" = (
|
||||
@@ -128,6 +130,7 @@
|
||||
name = "tactical swivel chair"
|
||||
},
|
||||
/obj/effect/turf_decal/tile/red/fourcorners,
|
||||
/obj/effect/landmark/mafia,
|
||||
/turf/open/floor/iron/dark,
|
||||
/area/centcom/mafia)
|
||||
"E" = (
|
||||
@@ -135,6 +138,7 @@
|
||||
dir = 1;
|
||||
name = "tactical swivel chair"
|
||||
},
|
||||
/obj/effect/landmark/mafia,
|
||||
/turf/open/floor/mineral/plastitanium,
|
||||
/area/centcom/mafia)
|
||||
"G" = (
|
||||
@@ -146,11 +150,6 @@
|
||||
/obj/effect/spawner/random/clothing/syndie,
|
||||
/turf/open/floor/iron/dark,
|
||||
/area/centcom/mafia)
|
||||
"H" = (
|
||||
/obj/effect/landmark/mafia,
|
||||
/obj/effect/turf_decal/tile/red/fourcorners,
|
||||
/turf/open/floor/iron/dark,
|
||||
/area/centcom/mafia)
|
||||
"Q" = (
|
||||
/turf/open/floor/circuit/red,
|
||||
/area/centcom/mafia)
|
||||
@@ -318,11 +317,11 @@ w
|
||||
G
|
||||
o
|
||||
p
|
||||
n
|
||||
r
|
||||
r
|
||||
p
|
||||
o
|
||||
H
|
||||
o
|
||||
p
|
||||
r
|
||||
b
|
||||
@@ -340,7 +339,7 @@ c
|
||||
d
|
||||
d
|
||||
w
|
||||
H
|
||||
o
|
||||
o
|
||||
w
|
||||
w
|
||||
@@ -350,7 +349,7 @@ o
|
||||
w
|
||||
w
|
||||
r
|
||||
n
|
||||
r
|
||||
w
|
||||
d
|
||||
d
|
||||
@@ -414,7 +413,7 @@ w
|
||||
c
|
||||
d
|
||||
j
|
||||
n
|
||||
r
|
||||
r
|
||||
r
|
||||
y
|
||||
@@ -426,7 +425,7 @@ p
|
||||
q
|
||||
o
|
||||
o
|
||||
H
|
||||
o
|
||||
j
|
||||
i
|
||||
c
|
||||
@@ -464,7 +463,7 @@ w
|
||||
c
|
||||
d
|
||||
j
|
||||
H
|
||||
o
|
||||
o
|
||||
o
|
||||
z
|
||||
@@ -476,7 +475,7 @@ p
|
||||
E
|
||||
r
|
||||
r
|
||||
n
|
||||
r
|
||||
j
|
||||
d
|
||||
c
|
||||
@@ -540,7 +539,7 @@ c
|
||||
f
|
||||
d
|
||||
w
|
||||
n
|
||||
r
|
||||
r
|
||||
w
|
||||
w
|
||||
@@ -550,7 +549,7 @@ r
|
||||
w
|
||||
w
|
||||
o
|
||||
H
|
||||
o
|
||||
w
|
||||
d
|
||||
d
|
||||
@@ -568,11 +567,11 @@ w
|
||||
b
|
||||
r
|
||||
p
|
||||
H
|
||||
o
|
||||
o
|
||||
p
|
||||
r
|
||||
n
|
||||
r
|
||||
p
|
||||
o
|
||||
G
|
||||
|
||||
@@ -96,17 +96,3 @@
|
||||
AI.holopad_talk(message, language)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/saymode/mafia
|
||||
key = "j"
|
||||
mode = MODE_MAFIA
|
||||
|
||||
/datum/saymode/mafia/handle_message(mob/living/user, message, datum/language/language)
|
||||
var/datum/mafia_controller/MF = GLOB.mafia_game
|
||||
if (!MF)
|
||||
return TRUE
|
||||
var/datum/mafia_role/R = MF.player_role_lookup[user]
|
||||
if(!R || R.team != "mafia")
|
||||
return TRUE
|
||||
MF.send_message(span_changeling("<b>[R.body.real_name]:</b> [message]"), "mafia")
|
||||
return FALSE
|
||||
|
||||
@@ -213,6 +213,18 @@
|
||||
name = "Syndicate Elite Squad"
|
||||
icon_state = "syndie-elite"
|
||||
|
||||
//MAFIA
|
||||
/area/centcom/mafia
|
||||
name = "Mafia Minigame"
|
||||
icon_state = "mafia"
|
||||
static_lighting = FALSE
|
||||
|
||||
base_lighting_alpha = 255
|
||||
requires_power = FALSE
|
||||
has_gravity = STANDARD_GRAVITY
|
||||
flags_1 = NONE
|
||||
area_flags = BLOCK_SUICIDE | UNIQUE_AREA
|
||||
|
||||
//CAPTURE THE FLAG
|
||||
/area/centcom/ctf
|
||||
name = "Capture the Flag"
|
||||
|
||||
@@ -62,6 +62,7 @@
|
||||
mask = /obj/item/clothing/mask/surgical
|
||||
neck = /obj/item/camera
|
||||
suit = /obj/item/clothing/suit/apron
|
||||
shoes = /obj/item/clothing/shoes/sneakers/black
|
||||
|
||||
/datum/outfit/obsessed/post_equip(mob/living/carbon/human/H)
|
||||
for(var/obj/item/carried_item in H.get_equipped_items(include_pockets = TRUE, include_accessories = TRUE))
|
||||
|
||||
@@ -382,6 +382,7 @@
|
||||
mask = /obj/item/clothing/mask/gas
|
||||
l_hand = /obj/item/melee/energy/sword
|
||||
r_hand = /obj/item/gun/energy/recharge/ebow
|
||||
shoes = /obj/item/clothing/shoes/magboots/advance
|
||||
|
||||
/datum/outfit/traitor/post_equip(mob/living/carbon/human/H, visualsOnly)
|
||||
var/obj/item/melee/energy/sword/sword = locate() in H.held_items
|
||||
|
||||
@@ -27,4 +27,5 @@
|
||||
"smmon_6.gif" = 'icons/program_icons/smmon_6.gif',
|
||||
"borg_mon.gif" = 'icons/program_icons/borg_mon.gif',
|
||||
"robotact.gif" = 'icons/program_icons/robotact.gif',
|
||||
"mafia.gif" = 'icons/program_icons/mafia.gif',
|
||||
)
|
||||
|
||||
@@ -100,6 +100,8 @@
|
||||
/// now clearing refs to prepare for the next day. Do not do any actions here, it's just for ref clearing.
|
||||
#define COMSIG_MAFIA_NIGHT_END "night_end"
|
||||
|
||||
/// signal sent to roles when the game is confirmed starting
|
||||
#define COMSIG_MAFIA_GAME_START "game_start"
|
||||
/// signal sent to roles when the game is confirmed ending
|
||||
#define COMSIG_MAFIA_GAME_END "game_end"
|
||||
|
||||
@@ -107,6 +109,8 @@
|
||||
GLOBAL_LIST_EMPTY(mafia_signup)
|
||||
/// list of ghosts who want to play mafia that have since disconnected. They are kept in the lobby, but not counted for starting a game.
|
||||
GLOBAL_LIST_EMPTY(mafia_bad_signup)
|
||||
/// list of PDAs who want to play mafia, every time someone enters the list it checks to see if enough are in
|
||||
GLOBAL_LIST_EMPTY(pda_mafia_signup)
|
||||
/// the current global mafia game running.
|
||||
GLOBAL_VAR(mafia_game)
|
||||
/// list of ghosts in mafia_signup who have voted to start early
|
||||
|
||||
@@ -29,6 +29,11 @@
|
||||
target_role = null
|
||||
return ..()
|
||||
|
||||
///Handles special messagese sent by ability-specific stuff (such as changeling chat).
|
||||
/datum/mafia_ability/proc/handle_speech(datum/source, list/speech_args)
|
||||
SIGNAL_HANDLER
|
||||
return FALSE
|
||||
|
||||
/**
|
||||
* Called when refs need to be cleared, when the target is no longer set.
|
||||
*/
|
||||
@@ -52,21 +57,28 @@
|
||||
if(game.phase != valid_use_period)
|
||||
return FALSE
|
||||
if(host_role.role_flags & ROLE_ROLEBLOCKED)
|
||||
to_chat(host_role.body, span_warning("You were roleblocked!"))
|
||||
host_role.send_message_to_player(span_warning("You were roleblocked!"))
|
||||
return FALSE
|
||||
if(host_role.game_status == MAFIA_DEAD)
|
||||
return FALSE
|
||||
|
||||
if(potential_target)
|
||||
if((use_flags & CAN_USE_ON_DEAD) && (potential_target.game_status != MAFIA_DEAD))
|
||||
if(use_flags & CAN_USE_ON_DEAD)
|
||||
if(potential_target.game_status != MAFIA_DEAD)
|
||||
if(!silent)
|
||||
host_role.send_message_to_player(span_notice("This can only be used on dead players."))
|
||||
return FALSE
|
||||
else if(potential_target.game_status == MAFIA_DEAD)
|
||||
if(!silent)
|
||||
to_chat(host_role.body, span_notice("This can only be used on dead players."))
|
||||
host_role.send_message_to_player(span_notice("This can only be used on living players."))
|
||||
return FALSE
|
||||
if(!(use_flags & CAN_USE_ON_SELF) && (potential_target == host_role))
|
||||
if(!silent)
|
||||
to_chat(host_role.body, span_notice("This can only be used on others."))
|
||||
host_role.send_message_to_player(span_notice("This can only be used on others."))
|
||||
return FALSE
|
||||
if(!(use_flags & CAN_USE_ON_OTHERS) && (potential_target != host_role))
|
||||
if(!silent)
|
||||
to_chat(host_role.body, span_notice("This can only be used on yourself."))
|
||||
host_role.send_message_to_player(span_notice("This can only be used on yourself."))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
@@ -90,7 +102,7 @@
|
||||
|
||||
if(target_role)
|
||||
if(SEND_SIGNAL(target_role, COMSIG_MAFIA_ON_VISIT, game, host_role) & MAFIA_VISIT_INTERRUPTED) //visited a warden. something that prevents you by visiting that person
|
||||
to_chat(host_role.body, span_danger("Your [name] was interrupted!"))
|
||||
host_role.send_message_to_player(span_danger("Your [name] was interrupted!"))
|
||||
return FALSE
|
||||
|
||||
return TRUE
|
||||
@@ -121,5 +133,5 @@
|
||||
target_role = new_target
|
||||
feedback_text = replacetext(feedback_text, "%WILL_PERFORM%", "now")
|
||||
|
||||
to_chat(host_role.body, span_notice(feedback_text))
|
||||
host_role.send_message_to_player(span_notice(feedback_text))
|
||||
return TRUE
|
||||
|
||||
@@ -20,5 +20,5 @@
|
||||
if(MAFIA_TEAM_SOLO)
|
||||
fluff = "rogue, with their own objectives..."
|
||||
|
||||
to_chat(host_role.body, span_warning("Your investigations reveal that [target_role.body.real_name] is [fluff]"))
|
||||
host_role.send_message_to_player(span_warning("Your investigations reveal that [target_role.body.real_name] is [fluff]"))
|
||||
return TRUE
|
||||
|
||||
@@ -14,5 +14,5 @@
|
||||
if(!.)
|
||||
return FALSE
|
||||
|
||||
to_chat(host_role.body, span_warning("You invoke spirit of [target_role.body.real_name] and learn their role was <b>[target_role.name]<b>."))
|
||||
host_role.send_message_to_player(span_warning("You invoke spirit of [target_role.body.real_name] and learn their role was <b>[target_role.name]<b>."))
|
||||
return TRUE
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
if(!.)
|
||||
return FALSE
|
||||
|
||||
to_chat(host_role.body, span_warning("You have revealed the true nature of the [target_role]!"))
|
||||
host_role.send_message_to_player(span_warning("You have revealed the true nature of the [target_role]!"))
|
||||
target_role.reveal_role(game, verbose = TRUE)
|
||||
return TRUE
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
return FALSE
|
||||
|
||||
if((target_role.role_flags & ROLE_UNDETECTABLE))
|
||||
to_chat(host_role.body,span_warning("[target_role.body.real_name]'s memories reveal that they are the [pick(game.all_roles - target_role)]."))
|
||||
host_role.send_message_to_player(span_warning("[target_role.body.real_name]'s memories reveal that they are the [pick(game.all_roles - target_role)]."))
|
||||
else
|
||||
to_chat(host_role.body,span_warning("[target_role.body.real_name]'s memories reveal that they are the [target_role.name]."))
|
||||
host_role.send_message_to_player(span_warning("[target_role.body.real_name]'s memories reveal that they are the [target_role.name]."))
|
||||
return TRUE
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
SIGNAL_HANDLER
|
||||
if(attacker == host_role)
|
||||
return
|
||||
to_chat(host_role.body, span_userdanger("You have shot a visitor!"))
|
||||
to_chat(attacker.body, span_userdanger("You have visited the warden!"))
|
||||
host_role.send_message_to_player(span_userdanger("You have shot a visitor!"))
|
||||
attacker.send_message_to_player(span_userdanger("You have visited the warden!"))
|
||||
attacker.kill(game, host_role, lynch = FALSE)
|
||||
return MAFIA_VISIT_INTERRUPTED
|
||||
|
||||
|
||||
@@ -22,11 +22,11 @@
|
||||
return FALSE
|
||||
|
||||
if(!(target_role in darkened_players))
|
||||
to_chat(target_role.body, span_userdanger("The lights begin to flicker and dim. You're in danger."))
|
||||
target_role.send_message_to_player(span_userdanger("The lights begin to flicker and dim. You're in danger."))
|
||||
darkened_players += target_role
|
||||
else
|
||||
for(var/datum/mafia_role/dead_players as anything in darkened_players)
|
||||
to_chat(dead_players.body, span_userdanger("A shadowy figure appears out of the darkness!"))
|
||||
dead_players.send_message_to_player(span_userdanger("A shadowy figure appears out of the darkness!"))
|
||||
dead_players.kill(game, host_role, FALSE)
|
||||
darkened_players -= dead_players
|
||||
return TRUE
|
||||
@@ -37,6 +37,6 @@
|
||||
return //no chance man, that's a town lynch
|
||||
|
||||
if(attacker in darkened_players)
|
||||
to_chat(host_role.body, span_userdanger("You were attacked by someone in a flickering room. You have danced in the shadows, evading them."))
|
||||
host_role.send_message_to_player(span_userdanger("You were attacked by someone in a flickering room. You have danced in the shadows, evading them."))
|
||||
return MAFIA_PREVENT_KILL
|
||||
|
||||
|
||||
@@ -18,17 +18,17 @@
|
||||
return FALSE
|
||||
|
||||
if(!target_role.kill(game, host_role, FALSE))
|
||||
to_chat(host_role.body, span_danger("Your attempt at killing [target_role.body.real_name] was prevented!"))
|
||||
host_role.send_message_to_player(span_danger("Your attempt at killing [target_role.body.real_name] was prevented!"))
|
||||
else
|
||||
to_chat(target_role.body, span_userdanger("You have been [attack_action] \a [host_role.name]!"))
|
||||
target_role.send_message_to_player(span_userdanger("You have been [attack_action] \a [host_role.name]!"))
|
||||
if(honorable && (target_role.team != MAFIA_TEAM_TOWN))
|
||||
to_chat(host_role.body, span_userdanger("You have killed an innocent crewmember. You will die tomorrow night."))
|
||||
host_role.send_message_to_player(span_userdanger("You have killed an innocent crewmember. You will die tomorrow night."))
|
||||
RegisterSignal(game, COMSIG_MAFIA_SUNDOWN, PROC_REF(internal_affairs))
|
||||
return TRUE
|
||||
|
||||
/datum/mafia_ability/attack_player/proc/internal_affairs(datum/mafia_controller/game)
|
||||
SIGNAL_HANDLER
|
||||
to_chat(host_role.body, span_userdanger("You have been killed by Nanotrasen Internal Affairs!"))
|
||||
host_role.send_message_to_player(span_userdanger("You have been killed by Nanotrasen Internal Affairs!"))
|
||||
host_role.reveal_role(game, verbose = TRUE)
|
||||
host_role.kill(game, host_role, FALSE) //you technically kill yourself but that shouldn't matter
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
if(!.)
|
||||
return FALSE
|
||||
if(new_target.role_flags & ROLE_VULNERABLE)
|
||||
to_chat(host_role.body, span_notice("[new_target] can't be protected."))
|
||||
host_role.send_message_to_player(span_notice("[new_target] can't be protected."))
|
||||
return FALSE
|
||||
|
||||
/datum/mafia_ability/heal/perform_action_target(datum/mafia_controller/game, datum/mafia_role/day_target)
|
||||
@@ -39,10 +39,10 @@
|
||||
/datum/mafia_ability/heal/proc/prevent_kill(datum/source, datum/mafia_controller/game, datum/mafia_role/attacker, lynch)
|
||||
SIGNAL_HANDLER
|
||||
if(host_role == target_role)
|
||||
to_chat(host_role.body, span_warning("You were attacked last night!"))
|
||||
host_role.send_message_to_player(span_warning("You were attacked last night!"))
|
||||
return MAFIA_PREVENT_KILL
|
||||
to_chat(host_role.body, span_warning("The person you protected tonight was attacked!"))
|
||||
to_chat(target_role.body, span_greentext("You were attacked last night, but [saving_message]!"))
|
||||
host_role.send_message_to_player(span_warning("The person you protected tonight was attacked!"))
|
||||
target_role.send_message_to_player(span_greentext("You were attacked last night, but [saving_message]!"))
|
||||
return MAFIA_PREVENT_KILL
|
||||
|
||||
/**
|
||||
@@ -60,6 +60,6 @@
|
||||
return FALSE
|
||||
|
||||
if(attacker.kill(game, host_role, FALSE)) //you attack the attacker
|
||||
to_chat(attacker.body, span_userdanger("You have been ambushed by Security!"))
|
||||
attacker.send_message_to_player(span_userdanger("You have been ambushed by Security!"))
|
||||
host_role.kill(game, attacker, FALSE) //the attacker attacks you, they were able to attack the target so they can attack you.
|
||||
return FALSE
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
|
||||
/datum/mafia_ability/vest/proc/self_defense(datum/source, datum/mafia_controller/game, datum/mafia_role/attacker, lynch)
|
||||
SIGNAL_HANDLER
|
||||
to_chat(host_role.body, span_greentext("Your vest saved you!"))
|
||||
host_role.send_message_to_player(span_greentext("Your vest saved you!"))
|
||||
return MAFIA_PREVENT_KILL
|
||||
|
||||
/datum/mafia_ability/vest/proc/end_protection(datum/mafia_controller/game)
|
||||
|
||||
@@ -30,12 +30,32 @@
|
||||
|
||||
ling_sent = TRUE
|
||||
if(target_role.kill(game, host_role, FALSE))
|
||||
to_chat(target_role.body, span_userdanger("You have been killed by a Changeling!"))
|
||||
target_role.send_message_to_player(span_userdanger("You have been killed by a Changeling!"))
|
||||
game.send_message(span_danger("[host_role.body.real_name] was selected to attack [target_role.body.real_name] tonight!"), MAFIA_TEAM_MAFIA)
|
||||
return TRUE
|
||||
|
||||
/datum/mafia_ability/changeling_kill/set_target(datum/mafia_controller/game, datum/mafia_role/new_target)
|
||||
if(new_target.team == MAFIA_TEAM_MAFIA)
|
||||
return FALSE
|
||||
if(!validate_action_target(game, new_target))
|
||||
return FALSE
|
||||
using_ability = TRUE
|
||||
game.vote_for(host_role, new_target, "Mafia", MAFIA_TEAM_MAFIA)
|
||||
|
||||
/**
|
||||
* handle_message
|
||||
*
|
||||
* During the night, Changelings talking will instead redirect it to Changeling chat.
|
||||
*/
|
||||
/datum/mafia_ability/changeling_kill/handle_speech(datum/source, list/speech_args)
|
||||
. = ..()
|
||||
var/datum/mafia_controller/mafia_game = GLOB.mafia_game
|
||||
if(!mafia_game)
|
||||
return FALSE
|
||||
if (mafia_game.phase != MAFIA_PHASE_NIGHT)
|
||||
return FALSE
|
||||
|
||||
var/phrase = html_decode(speech_args[SPEECH_MESSAGE])
|
||||
mafia_game.send_message(span_changeling("<b>[host_role.body.real_name]:</b> [phrase]"), MAFIA_TEAM_MAFIA)
|
||||
speech_args[SPEECH_MESSAGE] = ""
|
||||
return TRUE
|
||||
|
||||
@@ -2,6 +2,9 @@ GLOBAL_LIST_INIT(mafia_roles_by_name, setup_mafia_roles_by_name())
|
||||
|
||||
GLOBAL_LIST_INIT(mafia_role_by_alignment, setup_mafia_role_by_alignment())
|
||||
|
||||
///How many votes are needed to unlock the 'Universally Hated' achievement.
|
||||
#define UNIVERSALLY_HATED_REQUIREMENT 12
|
||||
|
||||
/**
|
||||
* The mafia controller handles the mafia minigame in progress.
|
||||
* It is first created when the first ghost signs up to play.
|
||||
@@ -11,7 +14,8 @@ GLOBAL_LIST_INIT(mafia_role_by_alignment, setup_mafia_role_by_alignment())
|
||||
var/list/datum/mafia_role/all_roles = list()
|
||||
///all living roles in the game, removed on death.
|
||||
var/list/datum/mafia_role/living_roles = list()
|
||||
///exists to speed up role retrieval, it's a dict. `player_role_lookup[player ckey]` will give you the role they play
|
||||
///exists to speed up role retrieval, it's a dict.
|
||||
/// `player_role_lookup[player ckey/PDA]` will give you the role they play
|
||||
var/list/player_role_lookup = list()
|
||||
///what part of the game you're playing in. day phases, night phases, judgement phases, etc.
|
||||
var/phase = MAFIA_PHASE_SETUP
|
||||
@@ -105,10 +109,10 @@ GLOBAL_LIST_INIT(mafia_role_by_alignment, setup_mafia_role_by_alignment())
|
||||
|
||||
/datum/mafia_controller/Destroy(force, ...)
|
||||
. = ..()
|
||||
if(GLOB.mafia_game == src)
|
||||
GLOB.mafia_game = null
|
||||
end_game()
|
||||
QDEL_NULL(map_deleter)
|
||||
if(GLOB.mafia_game == src)
|
||||
GLOB.mafia_game = null
|
||||
|
||||
/**
|
||||
* Triggers at beginning of the game when there is a confirmed list of valid, ready players.
|
||||
@@ -122,9 +126,10 @@ GLOBAL_LIST_INIT(mafia_role_by_alignment, setup_mafia_role_by_alignment())
|
||||
* * Puts players in each role randomly
|
||||
* Arguments:
|
||||
* * setup_list: list of all the datum setups (fancy list of roles) that would work for the game
|
||||
* * ready_players: list of filtered, sane players (so not playing or disconnected) for the game to put into roles
|
||||
* * ready_ghosts: list of filtered, sane players (so not playing or disconnected) for the game to put into roles
|
||||
* * ready_pdas: list of PDAs wanting to play the Mafia game.
|
||||
*/
|
||||
/datum/mafia_controller/proc/prepare_game(setup_list, ready_players)
|
||||
/datum/mafia_controller/proc/prepare_game(setup_list, ready_ghosts, ready_pdas)
|
||||
var/static/list/possible_maps = subtypesof(/datum/map_template/mafia)
|
||||
var/turf/spawn_area = get_turf(locate(/obj/effect/landmark/mafia_game_area) in GLOB.landmarks_list)
|
||||
|
||||
@@ -156,16 +161,32 @@ GLOBAL_LIST_INIT(mafia_role_by_alignment, setup_mafia_role_by_alignment())
|
||||
var/list/spawnpoints = landmarks.Copy()
|
||||
for(var/datum/mafia_role/role as anything in all_roles)
|
||||
role.assigned_landmark = pick_n_take(spawnpoints)
|
||||
var/selected_player
|
||||
if(!debug)
|
||||
role.player_key = pick_n_take(ready_players)
|
||||
if(length(ready_pdas))
|
||||
selected_player = pick(ready_pdas)
|
||||
else
|
||||
selected_player = pick(ready_ghosts)
|
||||
else
|
||||
role.player_key = pop(ready_players)
|
||||
if(length(ready_pdas))
|
||||
selected_player = peek(ready_pdas)
|
||||
else
|
||||
selected_player = peek(ready_ghosts)
|
||||
if(selected_player in ready_pdas)
|
||||
role.player_pda = selected_player
|
||||
ready_pdas -= selected_player
|
||||
else
|
||||
role.player_key = selected_player
|
||||
ready_ghosts -= selected_player
|
||||
|
||||
/datum/mafia_controller/proc/send_message(msg, team)
|
||||
///Sends a global message to all players, or just 'team' if set.
|
||||
/datum/mafia_controller/proc/send_message(msg, team, log_only = FALSE)
|
||||
for(var/datum/mafia_role/role as anything in all_roles)
|
||||
if(team && role.team != team)
|
||||
continue
|
||||
to_chat(role.body, msg)
|
||||
role.role_messages += msg
|
||||
if(!log_only)
|
||||
to_chat(role.body, msg)
|
||||
|
||||
/**
|
||||
* The game by this point is now all set up, and so we can put people in their bodies and start the first phase.
|
||||
@@ -176,10 +197,16 @@ GLOBAL_LIST_INIT(mafia_role_by_alignment, setup_mafia_role_by_alignment())
|
||||
*/
|
||||
/datum/mafia_controller/proc/start_game()
|
||||
create_bodies()
|
||||
SEND_GLOBAL_SIGNAL(COMSIG_MAFIA_GAME_START, src)
|
||||
start_day(can_vote = FALSE)
|
||||
send_message(span_notice("<b>The selected map is [current_map.name]!</b></br>[current_map.description]"))
|
||||
send_message(span_notice("<b>The selected map is [current_map.name]!</b></br> [current_map.description]"))
|
||||
send_message("<b>Day [turn] started! There is no voting on the first day. Say hello to everybody!</b>")
|
||||
next_phase_timer = addtimer(CALLBACK(src, PROC_REF(check_trial), FALSE), (FIRST_DAY_PERIOD_LENGTH / time_speedup), TIMER_STOPPABLE) //no voting period = no votes = instant night
|
||||
for(var/datum/mafia_role/roles as anything in all_roles)
|
||||
var/obj/item/modular_computer/modpc = roles.player_pda
|
||||
if(!modpc)
|
||||
continue
|
||||
modpc.update_static_data_for_all_viewers()
|
||||
|
||||
/**
|
||||
* How every day starts.
|
||||
@@ -229,7 +256,7 @@ GLOBAL_LIST_INIT(mafia_role_by_alignment, setup_mafia_role_by_alignment())
|
||||
var/datum/mafia_role/loser = get_vote_winner("Day")//, majority_of_town = TRUE)
|
||||
var/loser_votes = get_vote_count(loser, "Day")
|
||||
if(loser)
|
||||
if(loser_votes > 12)
|
||||
if(loser_votes > UNIVERSALLY_HATED_REQUIREMENT)
|
||||
award_role(/datum/award/achievement/mafia/universally_hated, loser)
|
||||
//refresh the lists
|
||||
judgement_abstain_votes = list()
|
||||
@@ -369,8 +396,11 @@ GLOBAL_LIST_INIT(mafia_role_by_alignment, setup_mafia_role_by_alignment())
|
||||
* * role: mafia_role datum to reward.
|
||||
*/
|
||||
/datum/mafia_controller/proc/award_role(award, datum/mafia_role/rewarded)
|
||||
var/client/role_client = rewarded.body.client
|
||||
role_client?.give_award(award, rewarded.body)
|
||||
rewarded.body?.client?.give_award(award, rewarded.body)
|
||||
if(!rewarded.player_pda)
|
||||
return
|
||||
for(var/datum/tgui/window as anything in rewarded.player_pda.open_uis)
|
||||
window.user?.client?.give_award(award, rewarded.body)
|
||||
|
||||
/**
|
||||
* The end of the game is in two procs, because we want a bit of time for players to see eachothers roles.
|
||||
@@ -584,21 +614,28 @@ GLOBAL_LIST_INIT(mafia_role_by_alignment, setup_mafia_role_by_alignment())
|
||||
RegisterSignal(H, COMSIG_ATOM_UPDATE_OVERLAYS, PROC_REF(display_votes))
|
||||
var/datum/action/innate/mafia_panel/mafia_panel = new(null,src)
|
||||
mafia_panel.Grant(H)
|
||||
var/obj/item/modular_computer/modpc = role.player_pda
|
||||
role.register_body(H)
|
||||
if(modpc)
|
||||
player_role_lookup[modpc] = role
|
||||
else
|
||||
player_role_lookup[H] = role
|
||||
var/client/player_client = GLOB.directory[role.player_key]
|
||||
if(player_client)
|
||||
player_client.prefs.safe_transfer_prefs_to(H, is_antag = TRUE)
|
||||
role.body = H
|
||||
player_role_lookup[H] = role
|
||||
role.put_player_in_body(player_client)
|
||||
role.put_player_in_body(player_client)
|
||||
role.greet()
|
||||
|
||||
/datum/mafia_controller/ui_static_data(mob/user)
|
||||
/datum/mafia_controller/ui_static_data(atom/user)
|
||||
var/list/data = list()
|
||||
|
||||
if(user.client?.holder)
|
||||
if(usr.client?.holder)
|
||||
data["admin_controls"] = TRUE //show admin buttons to start/setup/stop
|
||||
data["is_observer"] = isobserver(user)
|
||||
data["all_roles"] = current_setup_text
|
||||
|
||||
if(phase == MAFIA_PHASE_SETUP)
|
||||
return data
|
||||
|
||||
var/datum/mafia_role/user_role = player_role_lookup[user]
|
||||
if(user_role)
|
||||
data["roleinfo"] = list(
|
||||
@@ -610,7 +647,7 @@ GLOBAL_LIST_INIT(mafia_role_by_alignment, setup_mafia_role_by_alignment())
|
||||
|
||||
return data
|
||||
|
||||
/datum/mafia_controller/ui_data(mob/user)
|
||||
/datum/mafia_controller/ui_data(atom/user)
|
||||
var/list/data = list()
|
||||
|
||||
data["phase"] = phase
|
||||
@@ -619,18 +656,25 @@ GLOBAL_LIST_INIT(mafia_role_by_alignment, setup_mafia_role_by_alignment())
|
||||
|
||||
if(phase == MAFIA_PHASE_SETUP)
|
||||
data["lobbydata"] = list()
|
||||
for(var/key in GLOB.mafia_signup + GLOB.mafia_bad_signup)
|
||||
for(var/key in GLOB.mafia_signup + GLOB.mafia_bad_signup + GLOB.pda_mafia_signup)
|
||||
var/list/lobby_member = list()
|
||||
lobby_member["name"] = key
|
||||
lobby_member["status"] = (key in GLOB.mafia_bad_signup) ? "Disconnected" : "Ready"
|
||||
data["lobbydata"] += list(lobby_member)
|
||||
return data
|
||||
|
||||
data["timeleft"] = next_phase_timer ? timeleft(next_phase_timer) : 0 //the tgui menu counts this down.
|
||||
data["timeleft"] = next_phase_timer ? timeleft(next_phase_timer) : 0
|
||||
|
||||
var/datum/mafia_role/user_role = player_role_lookup[user]
|
||||
if(user_role)
|
||||
data["user_notes"] = user_role.written_notes
|
||||
data["messages"] = list()
|
||||
var/list/ui_messages = list()
|
||||
for(var/i = user_role.role_messages.len to 1 step -1)
|
||||
ui_messages.Add(list(list(
|
||||
"msg" = user_role.role_messages[i],
|
||||
)))
|
||||
data["messages"] = ui_messages
|
||||
|
||||
data["players"] = list()
|
||||
for(var/datum/mafia_role/role as anything in all_roles)
|
||||
@@ -659,8 +703,13 @@ GLOBAL_LIST_INIT(mafia_role_by_alignment, setup_mafia_role_by_alignment())
|
||||
if(.)
|
||||
return
|
||||
var/datum/mafia_role/user_role = player_role_lookup[usr]
|
||||
var/obj/item/modular_computer/modpc = ui.src_object
|
||||
if(istype(modpc))
|
||||
user_role = player_role_lookup[modpc]
|
||||
else
|
||||
modpc = null
|
||||
//Admin actions
|
||||
if(usr.client?.holder)
|
||||
if(ui.user.client.holder)
|
||||
switch(action)
|
||||
if("new_game")
|
||||
if(phase == MAFIA_PHASE_SETUP)
|
||||
@@ -686,9 +735,8 @@ GLOBAL_LIST_INIT(mafia_role_by_alignment, setup_mafia_role_by_alignment())
|
||||
player.body.forceMove(get_turf(player.assigned_landmark))
|
||||
if(failed.len)
|
||||
to_chat(usr, "List of players who no longer had a body (if you see this, the game is runtiming anyway so just hit \"New Game\" to end it)")
|
||||
for(var/i in failed)
|
||||
var/datum/mafia_role/fail = i
|
||||
to_chat(usr, fail.player_key)
|
||||
for(var/datum/mafia_role/fail as anything in failed)
|
||||
to_chat(usr, fail.player_key || fail.player_pda)
|
||||
if("debug_setup")
|
||||
var/list/debug_setup = list()
|
||||
var/list/rolelist_dict = list("CANCEL", "FINISH") + GLOB.mafia_roles_by_name
|
||||
@@ -732,38 +780,61 @@ GLOBAL_LIST_INIT(mafia_role_by_alignment, setup_mafia_role_by_alignment())
|
||||
if(!user_role)//just the dead
|
||||
switch(action)
|
||||
if("mf_signup")
|
||||
var/client/C = ui.user.client
|
||||
var/client/ghost_client = ui.user.client
|
||||
if(!SSticker.HasRoundStarted())
|
||||
to_chat(usr, span_warning("Wait for the round to start."))
|
||||
return
|
||||
if(GLOB.mafia_signup[C.ckey])
|
||||
GLOB.mafia_signup -= C.ckey
|
||||
GLOB.mafia_early_votes -= C.ckey //Remove their early start vote as well
|
||||
to_chat(usr, span_notice("You unregister from Mafia."))
|
||||
return TRUE
|
||||
if(isnull(modpc))
|
||||
if(GLOB.mafia_signup[ghost_client.ckey])
|
||||
GLOB.mafia_signup -= ghost_client.ckey
|
||||
GLOB.mafia_early_votes -= ghost_client.ckey //Remove their early start vote as well
|
||||
to_chat(usr, span_notice("You unregister from Mafia."))
|
||||
return TRUE
|
||||
else
|
||||
GLOB.mafia_signup[ghost_client.ckey] = TRUE
|
||||
to_chat(usr, span_notice("You sign up for Mafia."))
|
||||
else
|
||||
GLOB.mafia_signup[C.ckey] = TRUE
|
||||
to_chat(usr, span_notice("You sign up for Mafia."))
|
||||
if(GLOB.pda_mafia_signup[modpc])
|
||||
GLOB.pda_mafia_signup -= modpc
|
||||
GLOB.mafia_early_votes -= modpc //Remove their early start vote as well
|
||||
to_chat(usr, span_notice("You unregister from Mafia."))
|
||||
return TRUE
|
||||
else
|
||||
GLOB.pda_mafia_signup[modpc] = TRUE
|
||||
to_chat(usr, span_notice("You sign up for Mafia."))
|
||||
if(phase == MAFIA_PHASE_SETUP)
|
||||
check_signups()
|
||||
try_autostart()
|
||||
return TRUE
|
||||
if("vote_to_start")
|
||||
var/client/C = ui.user.client
|
||||
var/client/ghost_client = ui.user.client
|
||||
if(phase != MAFIA_PHASE_SETUP)
|
||||
to_chat(usr, span_notice("You cannot vote to start while a game is underway!"))
|
||||
return
|
||||
if(!GLOB.mafia_signup[C.ckey])
|
||||
to_chat(usr, span_notice("You must be signed up for this game to vote!"))
|
||||
return
|
||||
if(GLOB.mafia_early_votes[C.ckey])
|
||||
GLOB.mafia_early_votes -= C.ckey
|
||||
to_chat(usr, span_notice("You are no longer voting to start the game early."))
|
||||
if(isnull(modpc))
|
||||
if(!GLOB.mafia_signup[ghost_client.ckey])
|
||||
to_chat(usr, span_notice("You must be signed up for this game to vote!"))
|
||||
return
|
||||
if(GLOB.mafia_early_votes[ghost_client.ckey])
|
||||
GLOB.mafia_early_votes -= ghost_client.ckey
|
||||
to_chat(usr, span_notice("You are no longer voting to start the game early."))
|
||||
else
|
||||
GLOB.mafia_early_votes[ghost_client.ckey] = ghost_client
|
||||
to_chat(usr, span_notice("You vote to start the game early ([length(GLOB.mafia_early_votes)] out of [max(round(length(GLOB.mafia_signup) / 2), round(MAFIA_MIN_PLAYER_COUNT / 2))])."))
|
||||
if(check_start_votes()) //See if we have enough votes to start
|
||||
forced_setup()
|
||||
else
|
||||
GLOB.mafia_early_votes[C.ckey] = C
|
||||
to_chat(usr, span_notice("You vote to start the game early ([length(GLOB.mafia_early_votes)] out of [max(round(length(GLOB.mafia_signup) / 2), round(MAFIA_MIN_PLAYER_COUNT / 2))])."))
|
||||
if(check_start_votes()) //See if we have enough votes to start
|
||||
forced_setup()
|
||||
if(!GLOB.pda_mafia_signup[modpc])
|
||||
to_chat(usr, span_notice("You must be signed up for this game to vote!"))
|
||||
return
|
||||
if(GLOB.mafia_early_votes[modpc])
|
||||
GLOB.mafia_early_votes -= modpc
|
||||
to_chat(usr, span_notice("You are no longer voting to start the game early."))
|
||||
else
|
||||
GLOB.mafia_early_votes[modpc] = modpc
|
||||
to_chat(usr, span_notice("You vote to start the game early ([length(GLOB.mafia_early_votes)] out of [max(round(length(GLOB.mafia_signup) / 2), round(MAFIA_MIN_PLAYER_COUNT / 2))])."))
|
||||
if(check_start_votes()) //See if we have enough votes to start
|
||||
forced_setup()
|
||||
return TRUE
|
||||
|
||||
if(user_role && user_role.game_status == MAFIA_DEAD)
|
||||
@@ -774,8 +845,14 @@ GLOBAL_LIST_INIT(mafia_role_by_alignment, setup_mafia_role_by_alignment())
|
||||
if("change_notes")
|
||||
if(user_role.game_status == MAFIA_DEAD)
|
||||
return TRUE
|
||||
user_role.written_notes = params["new_notes"]
|
||||
user_role.body.balloon_alert(user_role.body, "notes saved")
|
||||
user_role.written_notes = sanitize_text(params["new_notes"])
|
||||
user_role.send_message_to_player("notes saved", balloon_alert = TRUE)
|
||||
return TRUE
|
||||
if("send_message_to_chat")
|
||||
if(user_role.game_status == MAFIA_DEAD)
|
||||
return TRUE
|
||||
var/message_said = sanitize_text(params["message"])
|
||||
user_role.body.say(message_said, forced = "mafia chat (sent by [ui.user.client])")
|
||||
return TRUE
|
||||
if("send_notes_to_chat")
|
||||
if(user_role.game_status == MAFIA_DEAD || !user_role.written_notes)
|
||||
@@ -807,21 +884,21 @@ GLOBAL_LIST_INIT(mafia_role_by_alignment, setup_mafia_role_by_alignment())
|
||||
if("vote_abstain")
|
||||
if(phase != MAFIA_PHASE_JUDGEMENT || (user_role in judgement_abstain_votes))
|
||||
return
|
||||
to_chat(user_role.body,"You have decided to abstain.")
|
||||
user_role.send_message_to_player("You have decided to abstain.")
|
||||
judgement_innocent_votes -= user_role
|
||||
judgement_guilty_votes -= user_role
|
||||
judgement_abstain_votes += user_role
|
||||
if("vote_innocent")
|
||||
if(phase != MAFIA_PHASE_JUDGEMENT || (user_role in judgement_innocent_votes))
|
||||
return
|
||||
to_chat(user_role.body,"Your vote on [on_trial.body.real_name] submitted as INNOCENT!")
|
||||
user_role.send_message_to_player("Your vote on [on_trial.body.real_name] submitted as INNOCENT!")
|
||||
judgement_abstain_votes -= user_role//no fakers, and...
|
||||
judgement_guilty_votes -= user_role//no radical centrism
|
||||
judgement_innocent_votes += user_role
|
||||
if("vote_guilty")
|
||||
if(phase != MAFIA_PHASE_JUDGEMENT || (user_role in judgement_guilty_votes))
|
||||
return
|
||||
to_chat(user_role.body,"Your vote on [on_trial.body.real_name] submitted as GUILTY!")
|
||||
user_role.send_message_to_player("Your vote on [on_trial.body.real_name] submitted as GUILTY!")
|
||||
judgement_abstain_votes -= user_role//no fakers, and...
|
||||
judgement_innocent_votes -= user_role//no radical centrism
|
||||
judgement_guilty_votes += user_role
|
||||
@@ -886,12 +963,15 @@ GLOBAL_LIST_INIT(mafia_role_by_alignment, setup_mafia_role_by_alignment())
|
||||
if(setup.len)
|
||||
req_players = assoc_value_sum(setup)
|
||||
|
||||
var/list/filtered_pdas = GLOB.pda_mafia_signup
|
||||
if(!isnull(filtered_pdas)) //pdas get priority
|
||||
req_players -= length(GLOB.pda_mafia_signup)
|
||||
var/list/filtered_keys = filter_players(req_players)
|
||||
var/needed_players = length(filtered_keys)
|
||||
var/needed_players = length(filtered_keys) + length(filtered_pdas)
|
||||
|
||||
if(!setup.len) //don't actually have one yet, so generate a max player random setup. it's good to do this here instead of above so it doesn't generate one every time a game could possibly start.
|
||||
setup = generate_standard_setup(needed_players)
|
||||
prepare_game(setup, filtered_keys)
|
||||
prepare_game(setup, filtered_keys, filtered_pdas)
|
||||
start_game()
|
||||
|
||||
/**
|
||||
@@ -902,8 +982,9 @@ GLOBAL_LIST_INIT(mafia_role_by_alignment, setup_mafia_role_by_alignment())
|
||||
|
||||
/datum/mafia_controller/proc/forced_setup()
|
||||
check_signups() //Refresh the signup list, so our numbers are accurate and we only take active players into consideration.
|
||||
var/list/filtered_pdas = GLOB.pda_mafia_signup
|
||||
var/list/filtered_keys = filter_players(length(GLOB.mafia_signup))
|
||||
var/req_players = length(filtered_keys)
|
||||
var/req_players = length(filtered_keys) + length(filtered_pdas)
|
||||
|
||||
if(!req_players) //If we have nobody signed up, we give up on starting
|
||||
log_admin("Attempted to force a mafia game to start with nobody signed up!")
|
||||
@@ -911,7 +992,7 @@ GLOBAL_LIST_INIT(mafia_role_by_alignment, setup_mafia_role_by_alignment())
|
||||
|
||||
var/list/setup = generate_standard_setup(req_players)
|
||||
|
||||
prepare_game(setup, filtered_keys)
|
||||
prepare_game(setup, filtered_keys, filtered_pdas)
|
||||
early_start = TRUE
|
||||
start_game()
|
||||
|
||||
@@ -983,7 +1064,7 @@ GLOBAL_LIST_INIT(mafia_role_by_alignment, setup_mafia_role_by_alignment())
|
||||
/datum/mafia_controller/proc/try_autostart()
|
||||
if(phase != MAFIA_PHASE_SETUP || !(GLOB.ghost_role_flags & GHOSTROLE_MINIGAME))
|
||||
return
|
||||
if(GLOB.mafia_signup.len >= MAFIA_MAX_PLAYER_COUNT || custom_setup)//enough people to try and make something (or debug mode)
|
||||
if((GLOB.mafia_signup.len + GLOB.pda_mafia_signup.len) >= MAFIA_MAX_PLAYER_COUNT || custom_setup)//enough people to try and make something (or debug mode)
|
||||
basic_setup()
|
||||
|
||||
/**
|
||||
@@ -1034,7 +1115,7 @@ GLOBAL_LIST_INIT(mafia_role_by_alignment, setup_mafia_role_by_alignment())
|
||||
maptext_height = 480
|
||||
maptext_width = 480
|
||||
///The client that owns the popup.
|
||||
var/datum/mafia_role/mafia/owner
|
||||
var/datum/mafia_role/owner
|
||||
|
||||
/atom/movable/screen/mafia_popup/Initialize(mapload, datum/mafia_role/mafia)
|
||||
. = ..()
|
||||
@@ -1045,6 +1126,9 @@ GLOBAL_LIST_INIT(mafia_role_by_alignment, setup_mafia_role_by_alignment())
|
||||
return ..()
|
||||
|
||||
/atom/movable/screen/mafia_popup/proc/update_text(text)
|
||||
owner.role_messages += text
|
||||
if(!owner.body.client)
|
||||
return
|
||||
maptext = MAPTEXT("<span style='color: [COLOR_RED]; text-align: center; font-size: 24pt'> [text]</span>")
|
||||
maptext_width = view_to_pixels(owner.body.client?.view_size.getView())[1]
|
||||
owner.body.client?.screen += src
|
||||
@@ -1063,3 +1147,5 @@ GLOBAL_LIST_INIT(mafia_role_by_alignment, setup_mafia_role_by_alignment())
|
||||
QDEL_NULL(GLOB.mafia_game)
|
||||
var/datum/mafia_controller/new_controller = new()
|
||||
return new_controller
|
||||
|
||||
#undef UNIVERSALLY_HATED_REQUIREMENT
|
||||
|
||||
@@ -26,17 +26,6 @@
|
||||
MF = create_mafia_game()
|
||||
MF.ui_interact(user)
|
||||
|
||||
/area/centcom/mafia
|
||||
name = "Mafia Minigame"
|
||||
icon_state = "mafia"
|
||||
static_lighting = FALSE
|
||||
|
||||
base_lighting_alpha = 255
|
||||
requires_power = FALSE
|
||||
has_gravity = STANDARD_GRAVITY
|
||||
flags_1 = NONE
|
||||
area_flags = BLOCK_SUICIDE | UNIQUE_AREA
|
||||
|
||||
/datum/map_template/mafia
|
||||
should_place_on_top = FALSE
|
||||
///A brief background tidbit
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/datum/mafia_role/mafia
|
||||
name = "Changeling"
|
||||
desc = "You're a member of the changeling hive. Use ':j' talk prefix to talk to your fellow lings."
|
||||
desc = "You're a member of the changeling hive. You may speak with your fellow Changelings at night."
|
||||
team = MAFIA_TEAM_MAFIA
|
||||
role_type = MAFIA_REGULAR
|
||||
role_flags = ROLE_CAN_KILL
|
||||
|
||||
@@ -15,7 +15,15 @@
|
||||
///The player's written notes, that they can send to chat at any time.
|
||||
var/written_notes
|
||||
|
||||
///The ckey of the person playing as this Mafia role, CAN BE NULL IN FAVOR OF player_pda.
|
||||
var/player_key
|
||||
///The PDA of the person playing as this Mafia role, CAN BE NULL IN FAVOR OF player_key.
|
||||
var/obj/item/modular_computer/player_pda
|
||||
|
||||
///List of all messages this role got throughout the game.
|
||||
var/list/role_messages = list()
|
||||
|
||||
|
||||
var/mob/living/carbon/human/body
|
||||
var/obj/effect/landmark/mafia/assigned_landmark
|
||||
|
||||
@@ -46,11 +54,52 @@
|
||||
role_unique_actions -= abilities
|
||||
|
||||
/datum/mafia_role/Destroy(force, ...)
|
||||
UnregisterSignal(body, COMSIG_MOB_SAY)
|
||||
QDEL_NULL(mafia_alert)
|
||||
QDEL_NULL(body)
|
||||
QDEL_LIST(role_unique_actions)
|
||||
role_messages = null
|
||||
return ..()
|
||||
|
||||
/datum/mafia_role/proc/register_body(mob/living/carbon/human/new_body)
|
||||
body = new_body
|
||||
RegisterSignal(new_body, COMSIG_MOB_SAY, PROC_REF(handle_speech))
|
||||
|
||||
/**
|
||||
* send_message_to_player
|
||||
*
|
||||
* Sends a message to a player, checking if they are playing through a PDA or not.
|
||||
* Args:
|
||||
* * message - The message to send to the person
|
||||
* * balloon_alert - Whether it should be as a balloon alert, only if it's to a non-PDA user.
|
||||
*/
|
||||
/datum/mafia_role/proc/send_message_to_player(message, balloon_alert = FALSE)
|
||||
if(player_pda)
|
||||
role_messages += message
|
||||
return
|
||||
if(balloon_alert)
|
||||
body.balloon_alert(body, message)
|
||||
return
|
||||
to_chat(body, message)
|
||||
|
||||
/**
|
||||
* handle_speech
|
||||
*
|
||||
* Handles Mafia roles talking in chat.
|
||||
* First it will go through their abilities for Ability-specific speech,
|
||||
* if none affects it, we will go to day chat.
|
||||
*/
|
||||
/datum/mafia_role/proc/handle_speech(datum/source, list/speech_args)
|
||||
SIGNAL_HANDLER
|
||||
for(var/datum/mafia_ability/abilities as anything in role_unique_actions)
|
||||
if(abilities.handle_speech(source, speech_args))
|
||||
return
|
||||
var/datum/mafia_controller/mafia_game = GLOB.mafia_game
|
||||
if(!mafia_game || mafia_game.phase == MAFIA_PHASE_NIGHT)
|
||||
return
|
||||
var/message = "[source]: [html_decode(speech_args[SPEECH_MESSAGE])]"
|
||||
mafia_game.send_message(message, log_only = TRUE)
|
||||
|
||||
/**
|
||||
* Puts the player in their body and keeps track of their previous one to put them back in later.
|
||||
* Adds the playing_mafia trait so people examining them will know why they're currently lacking a soul.
|
||||
|
||||
@@ -500,7 +500,7 @@
|
||||
if(!caller || !caller.alert_able || caller.alert_silenced || !alerttext) //Yeah, we're checking alert_able. No, you don't get to make alerts that the user can't silence.
|
||||
return FALSE
|
||||
playsound(src, sound, 50, TRUE)
|
||||
loc.visible_message(span_notice("[icon2html(src)] [span_notice("The [src] displays a [caller.filedesc] notification: [alerttext]")]"))
|
||||
physical.loc.visible_message(span_notice("[icon2html(physical, viewers(physical.loc))] \The [src] displays a [caller.filedesc] notification: [alerttext]"))
|
||||
|
||||
/obj/item/modular_computer/proc/ring(ringtone) // bring bring
|
||||
if(HAS_TRAIT(SSstation, STATION_TRAIT_PDA_GLITCHED))
|
||||
@@ -517,7 +517,6 @@
|
||||
var/list/data = list()
|
||||
|
||||
data["PC_device_theme"] = device_theme
|
||||
data["PC_showbatteryicon"] = !!internal_cell
|
||||
|
||||
if(internal_cell)
|
||||
switch(internal_cell.percent())
|
||||
@@ -535,8 +534,8 @@
|
||||
data["PC_batteryicon"] = "batt_5.gif"
|
||||
data["PC_batterypercent"] = "[round(internal_cell.percent())]%"
|
||||
else
|
||||
data["PC_batteryicon"] = "batt_5.gif"
|
||||
data["PC_batterypercent"] = "N/C"
|
||||
data["PC_batteryicon"] = null
|
||||
data["PC_batterypercent"] = null
|
||||
|
||||
switch(get_ntnet_status())
|
||||
if(NTNET_NO_SIGNAL)
|
||||
|
||||
@@ -132,7 +132,7 @@
|
||||
if(isAdminGhostAI(user))
|
||||
return TRUE
|
||||
|
||||
if(!transfer && computer && (computer.obj_flags & EMAGGED)) //emags can bypass the execution locks but not the download ones.
|
||||
if(computer && (computer.obj_flags & EMAGGED) && (available_on_syndinet || !transfer)) //emagged can run anything on syndinet, and can bypass execution locks, but not download.
|
||||
return TRUE
|
||||
|
||||
// Defaults to required_access
|
||||
|
||||
@@ -19,11 +19,11 @@
|
||||
/datum/computer_file/program/ntnet_dos/process_tick(seconds_per_tick)
|
||||
dos_speed = 0
|
||||
switch(ntnet_status)
|
||||
if(1)
|
||||
if(NTNET_LOW_SIGNAL)
|
||||
dos_speed = NTNETSPEED_LOWSIGNAL * 10
|
||||
if(2)
|
||||
if(NTNET_GOOD_SIGNAL)
|
||||
dos_speed = NTNETSPEED_HIGHSIGNAL * 10
|
||||
if(3)
|
||||
if(NTNET_ETHERNET_SIGNAL)
|
||||
dos_speed = NTNETSPEED_ETHERNET * 10
|
||||
if(target && executed)
|
||||
target.dos_overload += dos_speed
|
||||
|
||||
@@ -18,12 +18,9 @@
|
||||
/// The file under consideration.
|
||||
var/datum/computer_file/data/ordnance/selected_file
|
||||
|
||||
/datum/computer_file/program/scipaper_program/New()
|
||||
/datum/computer_file/program/scipaper_program/on_install(datum/computer_file/source, obj/item/modular_computer/computer_installing)
|
||||
. = ..()
|
||||
paper_to_be = new
|
||||
|
||||
/datum/computer_file/program/scipaper_program/on_start(mob/living/user)
|
||||
. = ..()
|
||||
if(!CONFIG_GET(flag/no_default_techweb_link) && !linked_techweb)
|
||||
CONNECT_TO_RND_SERVER_ROUNDSTART(linked_techweb, computer)
|
||||
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
/datum/computer_file/program/mafia
|
||||
filename = "mafia"
|
||||
filedesc = "Mafia"
|
||||
program_icon_state = "mafia"
|
||||
extended_desc = "A program that allows you to play the infamous Mafia game, straight from your Modular PC."
|
||||
requires_ntnet = FALSE
|
||||
size = 6
|
||||
tgui_id = "NtosMafiaPanel"
|
||||
program_icon = "user-secret"
|
||||
alert_able = TRUE
|
||||
|
||||
/datum/computer_file/program/mafia/on_install(datum/computer_file/source, obj/item/modular_computer/computer_installing)
|
||||
. = ..()
|
||||
RegisterSignal(SSdcs, COMSIG_MAFIA_GAME_START, PROC_REF(on_game_start))
|
||||
|
||||
/datum/computer_file/program/mafia/Destroy(force)
|
||||
var/datum/mafia_controller/game = GLOB.mafia_game
|
||||
if(!game)
|
||||
return
|
||||
UnregisterSignal(game, COMSIG_MAFIA_GAME_END)
|
||||
var/datum/mafia_role/pda_role = game.player_role_lookup[computer]
|
||||
if(!pda_role)
|
||||
return
|
||||
game.send_message(span_notice("[pda_role.body] has deleted the game from their PDA, and therefore has left the game."))
|
||||
pda_role.kill(game)
|
||||
return ..()
|
||||
|
||||
/datum/computer_file/program/mafia/ui_static_data(mob/user)
|
||||
var/list/data = list()
|
||||
var/datum/mafia_controller/game = GLOB.mafia_game
|
||||
if(!game)
|
||||
game = create_mafia_game()
|
||||
data += game.ui_static_data(computer)
|
||||
return data
|
||||
|
||||
/datum/computer_file/program/mafia/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
var/datum/mafia_controller/game = GLOB.mafia_game
|
||||
if(!game)
|
||||
game = create_mafia_game()
|
||||
data += game.ui_data(computer)
|
||||
return data
|
||||
|
||||
/datum/computer_file/program/mafia/ui_assets(mob/user)
|
||||
var/list/data = list()
|
||||
var/datum/mafia_controller/game = GLOB.mafia_game
|
||||
if(!game)
|
||||
game = create_mafia_game()
|
||||
data += game.ui_assets(user)
|
||||
return data
|
||||
|
||||
/datum/computer_file/program/mafia/ui_act(mob/user, params, datum/tgui/ui, datum/ui_state/state)
|
||||
var/datum/mafia_controller/game = GLOB.mafia_game
|
||||
if(!game)
|
||||
game = create_mafia_game()
|
||||
return game.ui_act(user, params, ui, state)
|
||||
|
||||
///Called when a game of Mafia starts, sets the ui header to the proper one.
|
||||
/datum/computer_file/program/mafia/proc/on_game_start(datum/controller/subsystem/processing/dcs/source, datum/mafia_controller/game)
|
||||
SIGNAL_HANDLER
|
||||
RegisterSignal(game, COMSIG_MAFIA_GAME_END, PROC_REF(on_game_end))
|
||||
ui_header = "mafia.gif"
|
||||
if(game.player_role_lookup[computer])
|
||||
alert_pending = TRUE
|
||||
computer.alert_call(src, "Mafia game started!")
|
||||
|
||||
///Called when a game of Mafia ends, deletes its ui header.
|
||||
/datum/computer_file/program/mafia/proc/on_game_end(datum/mafia_controller/game)
|
||||
SIGNAL_HANDLER
|
||||
UnregisterSignal(game, COMSIG_MAFIA_GAME_END)
|
||||
ui_header = null
|
||||
update_static_data_for_all_viewers()
|
||||
@@ -7,19 +7,16 @@
|
||||
size = 4
|
||||
requires_ntnet = TRUE
|
||||
available_on_ntnet = FALSE
|
||||
ui_header = "downloader_finished.gif"
|
||||
tgui_id = "NtosNetDownloader"
|
||||
program_icon = "download"
|
||||
|
||||
var/datum/computer_file/program/downloaded_file = null
|
||||
var/datum/computer_file/program/downloaded_file
|
||||
var/hacked_download = FALSE
|
||||
var/download_completion = FALSE //GQ of downloaded data.
|
||||
var/download_netspeed = 0
|
||||
var/downloaderror = ""
|
||||
var/list/main_repo
|
||||
var/list/antag_repo
|
||||
|
||||
var/list/show_categories = list(
|
||||
var/static/list/show_categories = list(
|
||||
PROGRAM_CATEGORY_CREW,
|
||||
PROGRAM_CATEGORY_ENGI,
|
||||
PROGRAM_CATEGORY_SCI,
|
||||
@@ -27,10 +24,9 @@
|
||||
PROGRAM_CATEGORY_MISC,
|
||||
)
|
||||
|
||||
/datum/computer_file/program/ntnetdownload/on_start()
|
||||
/datum/computer_file/program/ntnetdownload/kill_program(mob/user)
|
||||
. = ..()
|
||||
main_repo = SSmodular_computers.available_station_software
|
||||
antag_repo = SSmodular_computers.available_antag_software
|
||||
ui_header = null
|
||||
|
||||
/datum/computer_file/program/ntnetdownload/proc/begin_file_download(filename)
|
||||
if(downloaded_file)
|
||||
@@ -50,10 +46,10 @@
|
||||
|
||||
ui_header = "downloader_running.gif"
|
||||
|
||||
if(PRG in main_repo)
|
||||
if(PRG in SSmodular_computers.available_station_software)
|
||||
generate_network_log("Began downloading file [PRG.filename].[PRG.filetype] from NTNet Software Repository.")
|
||||
hacked_download = FALSE
|
||||
else if(PRG in antag_repo)
|
||||
else if(PRG in SSmodular_computers.available_antag_software)
|
||||
generate_network_log("Began downloading file **ENCRYPTED**.[PRG.filetype] from unspecified server.")
|
||||
hacked_download = TRUE
|
||||
else
|
||||
@@ -68,7 +64,7 @@
|
||||
generate_network_log("Aborted download of file [hacked_download ? "**ENCRYPTED**" : "[downloaded_file.filename].[downloaded_file.filetype]"].")
|
||||
downloaded_file = null
|
||||
download_completion = FALSE
|
||||
ui_header = "downloader_finished.gif"
|
||||
ui_header = null
|
||||
|
||||
/datum/computer_file/program/ntnetdownload/proc/complete_file_download()
|
||||
if(!downloaded_file)
|
||||
@@ -90,11 +86,11 @@
|
||||
download_netspeed = 0
|
||||
// Speed defines are found in misc.dm
|
||||
switch(ntnet_status)
|
||||
if(1)
|
||||
if(NTNET_LOW_SIGNAL)
|
||||
download_netspeed = NTNETSPEED_LOWSIGNAL
|
||||
if(2)
|
||||
if(NTNET_GOOD_SIGNAL)
|
||||
download_netspeed = NTNETSPEED_HIGHSIGNAL
|
||||
if(3)
|
||||
if(NTNET_ETHERNET_SIGNAL)
|
||||
download_netspeed = NTNETSPEED_ETHERNET
|
||||
download_completion += download_netspeed
|
||||
|
||||
@@ -132,7 +128,7 @@
|
||||
data["disk_used"] = computer.used_capacity
|
||||
data["emagged"] = (computer.obj_flags & EMAGGED)
|
||||
|
||||
var/list/repo = antag_repo | main_repo
|
||||
var/list/repo = SSmodular_computers.available_antag_software | SSmodular_computers.available_station_software
|
||||
var/list/program_categories = list()
|
||||
|
||||
for(var/datum/computer_file/program/programs as anything in repo)
|
||||
@@ -147,7 +143,7 @@
|
||||
"installed" = !!computer.find_file_by_name(programs.filename),
|
||||
"compatible" = check_compatibility(programs),
|
||||
"size" = programs.size,
|
||||
"access" = (computer.obj_flags & EMAGGED) && programs.available_on_syndinet ? TRUE : programs.can_run(user, transfer = TRUE, access = access),
|
||||
"access" = programs.can_run(user, transfer = TRUE, access = access),
|
||||
"verifiedsource" = programs.available_on_ntnet,
|
||||
))
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
/// Sequence var for the id cache
|
||||
var/id_cache_seq = 1
|
||||
|
||||
/datum/computer_file/program/science/on_start(mob/living/user)
|
||||
/datum/computer_file/program/science/on_install(datum/computer_file/source, obj/item/modular_computer/computer_installing)
|
||||
. = ..()
|
||||
if(!CONFIG_GET(flag/no_default_techweb_link) && !stored_research)
|
||||
CONNECT_TO_RND_SERVER_ROUNDSTART(stored_research, computer)
|
||||
|
||||
|
Before Width: | Height: | Size: 89 KiB After Width: | Height: | Size: 90 KiB |
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 193 B |
@@ -4963,6 +4963,7 @@
|
||||
#include "code\modules\modular_computers\file_system\programs\file_browser.dm"
|
||||
#include "code\modules\modular_computers\file_system\programs\frontier.dm"
|
||||
#include "code\modules\modular_computers\file_system\programs\jobmanagement.dm"
|
||||
#include "code\modules\modular_computers\file_system\programs\mafia_ntos.dm"
|
||||
#include "code\modules\modular_computers\file_system\programs\newscasterapp.dm"
|
||||
#include "code\modules\modular_computers\file_system\programs\notepad.dm"
|
||||
#include "code\modules\modular_computers\file_system\programs\nt_pay.dm"
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { classes } from 'common/react';
|
||||
import { decodeHtmlEntities } from 'common/string';
|
||||
import { multiline } from 'common/string';
|
||||
import { useBackend, useLocalState } from '../backend';
|
||||
import { Box, Button, Collapsible, Flex, NoticeBox, Section, Stack, Tabs, TextArea } from '../components';
|
||||
@@ -31,39 +32,58 @@ type LobbyData = {
|
||||
status: string;
|
||||
};
|
||||
|
||||
type MessageData = {
|
||||
msg: string;
|
||||
};
|
||||
|
||||
type MafiaData = {
|
||||
players: PlayerInfo[];
|
||||
lobbydata: LobbyData[];
|
||||
messages: MessageData[];
|
||||
user_notes: string;
|
||||
roleinfo: RoleInfo;
|
||||
phase: string;
|
||||
turn: number;
|
||||
timeleft: number;
|
||||
is_observer: boolean;
|
||||
all_roles: string[];
|
||||
admin_controls: boolean;
|
||||
};
|
||||
|
||||
export const MafiaPanel = (props, context) => {
|
||||
export const MafiaPanelData = (props, context) => {
|
||||
const { act, data } = useBackend<MafiaData>(context);
|
||||
const { phase, roleinfo, admin_controls } = data;
|
||||
const { phase, roleinfo, admin_controls, messages } = data;
|
||||
const [mafia_tab, setMafiaMode] = useLocalState(
|
||||
context,
|
||||
'mafia_tab',
|
||||
'Role list'
|
||||
);
|
||||
|
||||
if (phase === 'No Game') {
|
||||
return (
|
||||
<Stack fill>
|
||||
<Stack.Item grow={1}>
|
||||
<Stack fill vertical>
|
||||
<MafiaLobby />
|
||||
|
||||
<Stack grow>
|
||||
<Stack.Item>{!!admin_controls && <MafiaAdmin />}</Stack.Item>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Window
|
||||
title="Mafia"
|
||||
theme={roleinfo && roleinfo.role_theme}
|
||||
width={650}
|
||||
height={580}>
|
||||
<Window.Content>
|
||||
<Stack fill>
|
||||
{!!roleinfo && (
|
||||
<Stack.Item grow={1}>
|
||||
<MafiaChat />
|
||||
</Stack.Item>
|
||||
)}
|
||||
<Stack.Item grow={1}>
|
||||
<Stack fill vertical>
|
||||
{!roleinfo && (
|
||||
<Stack.Item grow>
|
||||
<MafiaLobby />
|
||||
</Stack.Item>
|
||||
)}
|
||||
{!!roleinfo && (
|
||||
<>
|
||||
<Stack.Item>
|
||||
@@ -76,65 +96,125 @@ export const MafiaPanel = (props, context) => {
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
{!!admin_controls && <MafiaAdmin />}
|
||||
<Stack grow>
|
||||
<Stack.Item>{!!admin_controls && <MafiaAdmin />}</Stack.Item>
|
||||
</Stack>
|
||||
{phase !== 'No Game' && (
|
||||
<Stack.Item grow>
|
||||
<Stack grow fill>
|
||||
<>
|
||||
<Stack.Item grow>
|
||||
<MafiaPlayers />
|
||||
</Stack.Item>
|
||||
<Stack.Item fluid grow>
|
||||
<Stack.Item>
|
||||
<Tabs fluid>
|
||||
<Tabs.Tab
|
||||
align="center"
|
||||
selected={mafia_tab === 'Role list'}
|
||||
onClick={() => setMafiaMode('Role list')}>
|
||||
Role list
|
||||
<Button
|
||||
color="transparent"
|
||||
icon="address-book"
|
||||
tooltipPosition="bottom-start"
|
||||
tooltip={multiline`
|
||||
<Stack grow fill>
|
||||
<>
|
||||
<Stack.Item grow>
|
||||
<MafiaPlayers />
|
||||
</Stack.Item>
|
||||
<Stack.Item fluid grow>
|
||||
<Stack.Item>
|
||||
<Tabs fluid>
|
||||
<Tabs.Tab
|
||||
align="center"
|
||||
selected={mafia_tab === 'Role list'}
|
||||
onClick={() => setMafiaMode('Role list')}>
|
||||
Role list
|
||||
<Button
|
||||
color="transparent"
|
||||
icon="address-book"
|
||||
tooltipPosition="bottom-start"
|
||||
tooltip={multiline`
|
||||
This is the list of roles in the game. You can
|
||||
press the question mark to get a quick blurb
|
||||
about the role itself.`}
|
||||
/>
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab
|
||||
align="center"
|
||||
selected={mafia_tab === 'Notes'}
|
||||
onClick={() => setMafiaMode('Notes')}>
|
||||
Notes
|
||||
<Button
|
||||
color="transparent"
|
||||
icon="pencil"
|
||||
tooltipPosition="bottom-start"
|
||||
tooltip={multiline`
|
||||
/>
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab
|
||||
align="center"
|
||||
selected={mafia_tab === 'Notes'}
|
||||
onClick={() => setMafiaMode('Notes')}>
|
||||
Notes
|
||||
<Button
|
||||
color="transparent"
|
||||
icon="pencil"
|
||||
tooltipPosition="bottom-start"
|
||||
tooltip={multiline`
|
||||
This is your notes, anything you want to write
|
||||
can be saved for future reference. You can
|
||||
also send it to chat with a button.`}
|
||||
/>
|
||||
</Tabs.Tab>
|
||||
</Tabs>
|
||||
</Stack.Item>
|
||||
{mafia_tab === 'Role list' && <MafiaListOfRoles />}
|
||||
{mafia_tab === 'Notes' && <MafiaNotesTab />}
|
||||
/>
|
||||
</Tabs.Tab>
|
||||
</Tabs>
|
||||
</Stack.Item>
|
||||
</>
|
||||
</Stack>
|
||||
</Stack.Item>
|
||||
{mafia_tab === 'Role list' && <MafiaListOfRoles />}
|
||||
{mafia_tab === 'Notes' && <MafiaNotesTab />}
|
||||
</Stack.Item>
|
||||
</>
|
||||
</Stack>
|
||||
)}
|
||||
</Stack>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
|
||||
export const MafiaPanel = (props, context) => {
|
||||
const { act, data } = useBackend<MafiaData>(context);
|
||||
const { roleinfo } = data;
|
||||
return (
|
||||
<Window
|
||||
title="Mafia"
|
||||
theme={roleinfo && roleinfo.role_theme}
|
||||
width={900}
|
||||
height={600}>
|
||||
<Window.Content>
|
||||
<MafiaPanelData />
|
||||
</Window.Content>
|
||||
</Window>
|
||||
);
|
||||
};
|
||||
|
||||
const MafiaChat = (props, context) => {
|
||||
const { act, data } = useBackend<MafiaData>(context);
|
||||
const { messages } = data;
|
||||
const [message_to_send, setMessagingBox] = useLocalState(context, 'Chat', '');
|
||||
return (
|
||||
<Stack vertical fill>
|
||||
{!!messages && (
|
||||
<>
|
||||
{' '}
|
||||
<Section fill scrollable title="Chat Logs">
|
||||
{messages.map((message) => (
|
||||
<Box key={message.msg}>{decodeHtmlEntities(message.msg)}</Box>
|
||||
))}
|
||||
</Section>
|
||||
<TextArea
|
||||
fluid
|
||||
height="10%"
|
||||
maxLength={300}
|
||||
className="Section__title candystripe"
|
||||
onChange={(e, value) => setMessagingBox(value)}
|
||||
placeholder={'Type to chat'}
|
||||
value={message_to_send}
|
||||
/>
|
||||
<Stack grow>
|
||||
<Stack.Item grow fill>
|
||||
<Button
|
||||
color="bad"
|
||||
fluid
|
||||
content="Send to Chat"
|
||||
textAlign="center"
|
||||
tooltip="Sends your message to chat."
|
||||
onClick={() => {
|
||||
setMessagingBox('');
|
||||
act('send_message_to_chat', { message: message_to_send });
|
||||
}}
|
||||
/>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
</>
|
||||
)}
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
|
||||
const MafiaLobby = (props, context) => {
|
||||
const { act, data } = useBackend<MafiaData>(context);
|
||||
const { lobbydata = [] } = data;
|
||||
const { lobbydata = [], is_observer } = data;
|
||||
const readyGhosts = lobbydata
|
||||
? lobbydata.filter((player) => player.status === 'Ready')
|
||||
: null;
|
||||
@@ -173,18 +253,22 @@ const MafiaLobby = (props, context) => {
|
||||
The lobby currently has {readyGhosts ? readyGhosts.length : '0'}/12
|
||||
valid players signed up.
|
||||
</NoticeBox>
|
||||
<NoticeBox color="green" textAlign="center">
|
||||
Players who sign up for Mafia while dead will be returned to their
|
||||
bodies after the game finishes, allowing you to temporarily exit to play
|
||||
a match.
|
||||
</NoticeBox>
|
||||
{!!is_observer && (
|
||||
<NoticeBox color="green" textAlign="center">
|
||||
Players who sign up for Mafia while dead will be returned to their
|
||||
bodies after the game finishes, allowing you to temporarily exit to
|
||||
play a match.
|
||||
</NoticeBox>
|
||||
)}
|
||||
{lobbydata.map((lobbyist) => (
|
||||
<Stack
|
||||
key={lobbyist.name}
|
||||
className="candystripe"
|
||||
p={1}
|
||||
align="baseline">
|
||||
<Stack.Item grow>{lobbyist.name}</Stack.Item>
|
||||
<Stack.Item grow>
|
||||
{!is_observer ? 'Unknown Player' : lobbyist.name}
|
||||
</Stack.Item>
|
||||
<Stack.Item>Status:</Stack.Item>
|
||||
<Stack.Item color={lobbyist.status === 'Ready' ? 'green' : 'red'}>
|
||||
{lobbyist.status}
|
||||
@@ -200,6 +284,7 @@ const MafiaRole = (props, context) => {
|
||||
const { phase, turn, roleinfo, timeleft } = data;
|
||||
return (
|
||||
<Section
|
||||
fill
|
||||
title={phase + turn}
|
||||
minHeight="100px"
|
||||
maxHeight="50px"
|
||||
@@ -341,22 +426,19 @@ const MafiaPlayers = (props, context) => {
|
||||
const { players } = data;
|
||||
return (
|
||||
<Section fill scrollable title="Players">
|
||||
<Flex direction="column">
|
||||
<Flex direction="column" fill justify="space-around">
|
||||
{players?.map((player) => (
|
||||
<Flex.Item
|
||||
height="30px"
|
||||
className="Section__title candystripe"
|
||||
key={player.ref}>
|
||||
<Stack height="18px" align="center">
|
||||
<Flex.Item className="Section__title candystripe" key={player.ref}>
|
||||
<Stack align="center">
|
||||
<Stack.Item grow color={!player.alive && 'red'}>
|
||||
{player.name} {!player.alive && '(DEAD)'}
|
||||
</Stack.Item>
|
||||
<Stack.Item shrink={0}>
|
||||
<Stack.Item>
|
||||
{player.votes !== undefined &&
|
||||
!!player.alive &&
|
||||
`Votes: ${player.votes}`}
|
||||
</Stack.Item>
|
||||
<Stack.Item shrink={0} minWidth="42px" textAlign="center">
|
||||
<Stack.Item minWidth="42px" textAlign="center">
|
||||
{player.possible_actions?.map((action) => (
|
||||
<Button
|
||||
key={action.name}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
import { MafiaPanelData } from './MafiaPanel';
|
||||
import { NtosWindow } from '../layouts';
|
||||
|
||||
export const NtosMafiaPanel = (props, context) => {
|
||||
return (
|
||||
<NtosWindow width={900} height={600}>
|
||||
<NtosWindow.Content>
|
||||
<MafiaPanelData />
|
||||
</NtosWindow.Content>
|
||||
</NtosWindow>
|
||||
);
|
||||
};
|
||||
@@ -15,7 +15,6 @@ export const NtosWindow = (props, context) => {
|
||||
const {
|
||||
PC_device_theme,
|
||||
PC_batteryicon,
|
||||
PC_showbatteryicon,
|
||||
PC_batterypercent,
|
||||
PC_ntneticon,
|
||||
PC_stationdate,
|
||||
@@ -61,7 +60,7 @@ export const NtosWindow = (props, context) => {
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
{!!(PC_showbatteryicon && PC_batteryicon) && (
|
||||
{!!PC_batteryicon && (
|
||||
<Box inline mr={1}>
|
||||
<img
|
||||
className="NtosHeader__icon"
|
||||
|
||||