Spaces:
Sleeping
Sleeping
revert
Browse files- src/components/Game.tsx +31 -43
src/components/Game.tsx
CHANGED
@@ -1,4 +1,7 @@
|
|
1 |
-
import
|
|
|
|
|
|
|
2 |
import { Stage } from '@pixi/react';
|
3 |
import { ConvexProvider, useConvex, useQuery } from 'convex/react';
|
4 |
import PlayerDetails from './PlayerDetails.tsx';
|
@@ -17,25 +20,12 @@ import { createPortal } from 'react-dom';
|
|
17 |
import GameVote from './GameVote.tsx';
|
18 |
import { EndGame } from './EndGame.tsx';
|
19 |
import { LOBBY_SIZE } from '../../convex/constants';
|
20 |
-
import { useElementSize } from 'usehooks-ts';
|
21 |
|
22 |
export const SHOW_DEBUG_UI = !!import.meta.env.VITE_SHOW_DEBUG_UI;
|
23 |
|
24 |
-
function GameStateLabel(
|
25 |
-
const
|
26 |
-
|
27 |
-
useEffect(() => {
|
28 |
-
const updateHumanPlayers = () => {
|
29 |
-
const humanCount = [...game.world.players.values()].filter(player => player.human).length;
|
30 |
-
setHumans(humanCount);
|
31 |
-
};
|
32 |
-
|
33 |
-
// Update the count of human players when the component mounts and when game.world.players changes
|
34 |
-
updateHumanPlayers();
|
35 |
-
}, [game.world.players]);
|
36 |
-
|
37 |
-
console.log('Human player seen by lobby', game.world.players.values());
|
38 |
-
|
39 |
switch (game.world.gameCycle.cycleState) {
|
40 |
case 'Day':
|
41 |
return {
|
@@ -45,7 +35,7 @@ function GameStateLabel({ game, me }) {
|
|
45 |
case 'WerewolfVoting':
|
46 |
return {
|
47 |
label: 'Werewolf Vote',
|
48 |
-
desc: 'Select a player who is a
|
49 |
};
|
50 |
case 'PlayerKillVoting':
|
51 |
return {
|
@@ -55,32 +45,31 @@ function GameStateLabel({ game, me }) {
|
|
55 |
case 'LobbyState':
|
56 |
return {
|
57 |
label: 'Lobby (waiting for start)',
|
58 |
-
desc: `Waiting
|
59 |
};
|
60 |
case 'Night':
|
61 |
return {
|
62 |
label: 'Night',
|
63 |
-
desc: me?.type === 'werewolf' ? 'Discuss who to kill with other
|
64 |
};
|
65 |
case 'EndGame':
|
66 |
return {
|
67 |
label: 'The End',
|
68 |
-
desc: `Winners are ${game.world.winner}!`,
|
69 |
};
|
70 |
-
default:
|
71 |
-
return null;
|
72 |
}
|
73 |
}
|
74 |
|
75 |
-
export function canVote(game, me) {
|
76 |
return me && (game.world.gameCycle.cycleState === "WerewolfVoting" || (game.world.gameCycle.cycleState === "PlayerKillVoting" && me.type === "werewolf"));
|
77 |
}
|
78 |
|
79 |
-
export function isEndGame(game) {
|
80 |
return game.world.gameCycle.cycleState === "EndGame";
|
81 |
}
|
82 |
|
83 |
-
function showMap(gameCycle, me) {
|
|
|
84 |
return (gameCycle.cycleState === "Day" || gameCycle.cycleState === "WerewolfVoting") || me?.type === "werewolf";
|
85 |
}
|
86 |
|
@@ -96,7 +85,8 @@ export default function Game() {
|
|
96 |
const engineId = worldStatus?.engineId;
|
97 |
const oauth = JSON.parse(localStorage.getItem('oauth'));
|
98 |
const oauthToken = oauth ? oauth.userInfo.fullname : undefined;
|
99 |
-
const humanTokenIdentifier =
|
|
|
100 |
|
101 |
const game = useServerGame(worldId);
|
102 |
|
@@ -108,26 +98,24 @@ export default function Game() {
|
|
108 |
|
109 |
const scrollViewRef = useRef<HTMLDivElement>(null);
|
110 |
|
111 |
-
if (!worldId || !engineId || !game) {
|
112 |
return null;
|
113 |
}
|
114 |
-
|
|
|
115 |
const playerId = [...game.world.players.values()].find(
|
116 |
(p) => !!p && p.human === humanTokenIdentifier,
|
117 |
)?.id;
|
118 |
-
console.log("playerId",
|
119 |
|
120 |
const meDescription = playerId ? game?.playerDescriptions.get(playerId) : undefined;
|
121 |
-
|
122 |
-
const gameStateLabel = GameStateLabel({ game: game as GameObj, me: meDescription });
|
123 |
-
|
124 |
return (
|
125 |
<>
|
126 |
{SHOW_DEBUG_UI && <DebugTimeManager timeManager={timeManager} width={200} height={100} />}
|
127 |
<div className="mx-auto w-full max-w grid grid-rows-[240px_1fr] lg:grid-rows-[1fr] lg:grid-cols-[1fr_auto] lg:grow max-w-[1400px] min-h-[480px] game-frame">
|
128 |
{/* Game area */}
|
129 |
<div className="relative overflow-hidden bg-brown-900" ref={gameWrapperRef}>
|
130 |
-
<div className={`absolute inset-0 ${showMap(game.world.gameCycle, meDescription) ? '' : 'invisible'}`}>
|
131 |
<div className="container">
|
132 |
<Stage width={width} height={height} options={{ backgroundColor: 0x7ab5ff }}>
|
133 |
{/* Re-propagate context because contexts are not shared between renderers.
|
@@ -146,21 +134,21 @@ https://github.com/michalochman/react-pixi-fiber/issues/145#issuecomment-5315492
|
|
146 |
</Stage>
|
147 |
</div>
|
148 |
</div>
|
149 |
-
<div className={`absolute inset-0 ${!showMap(game.world.gameCycle, meDescription) ? '' : 'invisible'}`}>
|
150 |
<Cloud worldId={worldId} />
|
151 |
</div>
|
152 |
</div>
|
153 |
{/* Right column area */}
|
154 |
<div
|
155 |
-
className="flex flex-col overflow-y-auto shrink-0 px-4 py-6 sm:px-6 lg:w-96 xl:pr-6 border-t-8 sm:border-t-0 sm:border-l-8 border-brown-900
|
156 |
ref={scrollViewRef}
|
157 |
>
|
158 |
<div className="flex flex-col items-center mb-4 gap-4">
|
159 |
-
<h2 className="text-2xl font-bold">{
|
160 |
-
<p className="text-lg text-center">{
|
161 |
</div>
|
162 |
{playerId && !isEndGame(game) && canVote(game, meDescription) && <GameVote engineId={engineId} game={game} playerId={playerId} />}
|
163 |
-
{!isEndGame(game) && !canVote(game, meDescription) && playerId
|
164 |
worldId={worldId}
|
165 |
engineId={engineId}
|
166 |
game={game}
|
@@ -173,10 +161,10 @@ https://github.com/michalochman/react-pixi-fiber/issues/145#issuecomment-5315492
|
|
173 |
</div>
|
174 |
</div>
|
175 |
{createPortal(
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
)}
|
181 |
</>
|
182 |
);
|
|
|
1 |
+
import { useRef, useState } from 'react';
|
2 |
+
import PixiGame from './PixiGame.tsx';
|
3 |
+
|
4 |
+
import { useElementSize } from 'usehooks-ts';
|
5 |
import { Stage } from '@pixi/react';
|
6 |
import { ConvexProvider, useConvex, useQuery } from 'convex/react';
|
7 |
import PlayerDetails from './PlayerDetails.tsx';
|
|
|
20 |
import GameVote from './GameVote.tsx';
|
21 |
import { EndGame } from './EndGame.tsx';
|
22 |
import { LOBBY_SIZE } from '../../convex/constants';
|
|
|
23 |
|
24 |
export const SHOW_DEBUG_UI = !!import.meta.env.VITE_SHOW_DEBUG_UI;
|
25 |
|
26 |
+
export function GameStateLabel(game: GameObj, me: PlayerDescription | undefined) {
|
27 |
+
const humans = [...game.world.playersInit.values()].filter(player => player.human).length
|
28 |
+
console.log(humans)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
switch (game.world.gameCycle.cycleState) {
|
30 |
case 'Day':
|
31 |
return {
|
|
|
35 |
case 'WerewolfVoting':
|
36 |
return {
|
37 |
label: 'Werewolf Vote',
|
38 |
+
desc: 'Select a player who is a warewolf',
|
39 |
};
|
40 |
case 'PlayerKillVoting':
|
41 |
return {
|
|
|
45 |
case 'LobbyState':
|
46 |
return {
|
47 |
label: 'Lobby (waiting for start)',
|
48 |
+
desc: `Waiting the game to start. ${ humans } out of the ${ LOBBY_SIZE } requiered `,
|
49 |
};
|
50 |
case 'Night':
|
51 |
return {
|
52 |
label: 'Night',
|
53 |
+
desc: me?.type === 'werewolf' ? 'Discuss who to kill with other warewolves' : 'Hide in your home!!',
|
54 |
};
|
55 |
case 'EndGame':
|
56 |
return {
|
57 |
label: 'The End',
|
58 |
+
desc: `Winners are ${ game.world.winner }!`,
|
59 |
};
|
|
|
|
|
60 |
}
|
61 |
}
|
62 |
|
63 |
+
export function canVote(game: ServerGame, me: PlayerDescription | undefined) {
|
64 |
return me && (game.world.gameCycle.cycleState === "WerewolfVoting" || (game.world.gameCycle.cycleState === "PlayerKillVoting" && me.type === "werewolf"));
|
65 |
}
|
66 |
|
67 |
+
export function isEndGame(game: ServerGame) {
|
68 |
return game.world.gameCycle.cycleState === "EndGame";
|
69 |
}
|
70 |
|
71 |
+
function showMap(gameCycle: GameCycle, me: PlayerDescription | undefined) {
|
72 |
+
// Here also check for player description
|
73 |
return (gameCycle.cycleState === "Day" || gameCycle.cycleState === "WerewolfVoting") || me?.type === "werewolf";
|
74 |
}
|
75 |
|
|
|
85 |
const engineId = worldStatus?.engineId;
|
86 |
const oauth = JSON.parse(localStorage.getItem('oauth'));
|
87 |
const oauthToken = oauth ? oauth.userInfo.fullname : undefined;
|
88 |
+
const humanTokenIdentifier = useQuery(api.world.userStatus, { worldId, oauthToken });
|
89 |
+
|
90 |
|
91 |
const game = useServerGame(worldId);
|
92 |
|
|
|
98 |
|
99 |
const scrollViewRef = useRef<HTMLDivElement>(null);
|
100 |
|
101 |
+
if (!worldId || !engineId || !game ) {
|
102 |
return null;
|
103 |
}
|
104 |
+
//console.log(humanTokenIdentifier)
|
105 |
+
//console.log("game.world.players.values() :",game.world.players.values())
|
106 |
const playerId = [...game.world.players.values()].find(
|
107 |
(p) => !!p && p.human === humanTokenIdentifier,
|
108 |
)?.id;
|
109 |
+
console.log("playerId",playerId)
|
110 |
|
111 |
const meDescription = playerId ? game?.playerDescriptions.get(playerId) : undefined;
|
|
|
|
|
|
|
112 |
return (
|
113 |
<>
|
114 |
{SHOW_DEBUG_UI && <DebugTimeManager timeManager={timeManager} width={200} height={100} />}
|
115 |
<div className="mx-auto w-full max-w grid grid-rows-[240px_1fr] lg:grid-rows-[1fr] lg:grid-cols-[1fr_auto] lg:grow max-w-[1400px] min-h-[480px] game-frame">
|
116 |
{/* Game area */}
|
117 |
<div className="relative overflow-hidden bg-brown-900" ref={gameWrapperRef}>
|
118 |
+
<div className={`absolute inset-0 ${showMap(game.world.gameCycle, meDescription) ? '' : 'invisible' }`}>
|
119 |
<div className="container">
|
120 |
<Stage width={width} height={height} options={{ backgroundColor: 0x7ab5ff }}>
|
121 |
{/* Re-propagate context because contexts are not shared between renderers.
|
|
|
134 |
</Stage>
|
135 |
</div>
|
136 |
</div>
|
137 |
+
<div className={`absolute inset-0 ${!showMap(game.world.gameCycle, meDescription) ? '' : 'invisible' }`}>
|
138 |
<Cloud worldId={worldId} />
|
139 |
</div>
|
140 |
</div>
|
141 |
{/* Right column area */}
|
142 |
<div
|
143 |
+
className="flex flex-col overflow-y-auto shrink-0 px-4 py-6 sm:px-6 lg:w-96 xl:pr-6 border-t-8 sm:border-t-0 sm:border-l-8 border-brown-900 bg-brown-800 text-brown-100"
|
144 |
ref={scrollViewRef}
|
145 |
>
|
146 |
<div className="flex flex-col items-center mb-4 gap-4">
|
147 |
+
<h2 className="text-2xl font-bold">{GameStateLabel(game as GameObj, meDescription).label}</h2>
|
148 |
+
<p className="text-lg text-center">{GameStateLabel(game as GameObj, meDescription).desc}</p>
|
149 |
</div>
|
150 |
{playerId && !isEndGame(game) && canVote(game, meDescription) && <GameVote engineId={engineId} game={game} playerId={playerId} />}
|
151 |
+
{!isEndGame(game) && !canVote(game, meDescription) && playerId &&<PlayerDetails
|
152 |
worldId={worldId}
|
153 |
engineId={engineId}
|
154 |
game={game}
|
|
|
161 |
</div>
|
162 |
</div>
|
163 |
{createPortal(
|
164 |
+
<div className="max-w-[1400px] mx-auto">
|
165 |
+
{playerId && <VotingPopover engineId={engineId} game={game} playerId={playerId} />}
|
166 |
+
</div>,
|
167 |
+
document.getElementById('footer-buttons')
|
168 |
)}
|
169 |
</>
|
170 |
);
|