Jofthomas commited on
Commit
8b11ff4
·
1 Parent(s): 126d4dd
Files changed (1) hide show
  1. src/components/Game.tsx +33 -31
src/components/Game.tsx CHANGED
@@ -1,7 +1,4 @@
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,21 +17,24 @@ import { createPortal } from 'react-dom';
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, setHumans] = useState(0);
28
 
29
  useEffect(() => {
30
  const updateHumanPlayers = () => {
31
- const humanCount = [...game.world.playersInit.values()].filter(player => player.human).length;
32
  setHumans(humanCount);
33
  };
34
 
35
  // Update the count of human players when the component mounts and when game.world.players changes
36
  updateHumanPlayers();
37
- }, [game.world.playersInit]);
 
 
38
 
39
  switch (game.world.gameCycle.cycleState) {
40
  case 'Day':
@@ -45,7 +45,7 @@ export function GameStateLabel(game: GameObj, me: PlayerDescription | undefined)
45
  case 'WerewolfVoting':
46
  return {
47
  label: 'Werewolf Vote',
48
- desc: 'Select a player who is a warewolf',
49
  };
50
  case 'PlayerKillVoting':
51
  return {
@@ -55,31 +55,32 @@ export function GameStateLabel(game: GameObj, me: PlayerDescription | undefined)
55
  case 'LobbyState':
56
  return {
57
  label: 'Lobby (waiting for start)',
58
- desc: `Waiting the game to start. ${ humans } out of the ${ LOBBY_SIZE } requiered `,
59
  };
60
  case 'Night':
61
  return {
62
  label: 'Night',
63
- desc: me?.type === 'werewolf' ? 'Discuss who to kill with other warewolves' : 'Hide in your home!!',
64
  };
65
  case 'EndGame':
66
  return {
67
  label: 'The End',
68
- desc: `Winners are ${ game.world.winner }!`,
69
  };
 
 
70
  }
71
  }
72
 
73
- export function canVote(game: ServerGame, me: PlayerDescription | undefined) {
74
  return me && (game.world.gameCycle.cycleState === "WerewolfVoting" || (game.world.gameCycle.cycleState === "PlayerKillVoting" && me.type === "werewolf"));
75
  }
76
 
77
- export function isEndGame(game: ServerGame) {
78
  return game.world.gameCycle.cycleState === "EndGame";
79
  }
80
 
81
- function showMap(gameCycle: GameCycle, me: PlayerDescription | undefined) {
82
- // Here also check for player description
83
  return (gameCycle.cycleState === "Day" || gameCycle.cycleState === "WerewolfVoting") || me?.type === "werewolf";
84
  }
85
 
@@ -95,8 +96,7 @@ export default function Game() {
95
  const engineId = worldStatus?.engineId;
96
  const oauth = JSON.parse(localStorage.getItem('oauth'));
97
  const oauthToken = oauth ? oauth.userInfo.fullname : undefined;
98
- const humanTokenIdentifier = useQuery(api.world.userStatus, { worldId, oauthToken });
99
-
100
 
101
  const game = useServerGame(worldId);
102
 
@@ -108,24 +108,26 @@ export default function Game() {
108
 
109
  const scrollViewRef = useRef<HTMLDivElement>(null);
110
 
111
- if (!worldId || !engineId || !game ) {
112
  return null;
113
  }
114
- //console.log(humanTokenIdentifier)
115
- //console.log("game.world.players.values() :",game.world.players.values())
116
  const playerId = [...game.world.players.values()].find(
117
  (p) => !!p && p.human === humanTokenIdentifier,
118
  )?.id;
119
- console.log("playerId",playerId)
120
 
121
  const meDescription = playerId ? game?.playerDescriptions.get(playerId) : undefined;
 
 
 
122
  return (
123
  <>
124
  {SHOW_DEBUG_UI && <DebugTimeManager timeManager={timeManager} width={200} height={100} />}
125
  <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">
126
  {/* Game area */}
127
  <div className="relative overflow-hidden bg-brown-900" ref={gameWrapperRef}>
128
- <div className={`absolute inset-0 ${showMap(game.world.gameCycle, meDescription) ? '' : 'invisible' }`}>
129
  <div className="container">
130
  <Stage width={width} height={height} options={{ backgroundColor: 0x7ab5ff }}>
131
  {/* Re-propagate context because contexts are not shared between renderers.
@@ -144,21 +146,21 @@ https://github.com/michalochman/react-pixi-fiber/issues/145#issuecomment-5315492
144
  </Stage>
145
  </div>
146
  </div>
147
- <div className={`absolute inset-0 ${!showMap(game.world.gameCycle, meDescription) ? '' : 'invisible' }`}>
148
  <Cloud worldId={worldId} />
149
  </div>
150
  </div>
151
  {/* Right column area */}
152
  <div
153
- 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"
154
  ref={scrollViewRef}
155
  >
156
  <div className="flex flex-col items-center mb-4 gap-4">
157
- <h2 className="text-2xl font-bold">{GameStateLabel(game as GameObj, meDescription).label}</h2>
158
- <p className="text-lg text-center">{GameStateLabel(game as GameObj, meDescription).desc}</p>
159
  </div>
160
  {playerId && !isEndGame(game) && canVote(game, meDescription) && <GameVote engineId={engineId} game={game} playerId={playerId} />}
161
- {!isEndGame(game) && !canVote(game, meDescription) && playerId &&<PlayerDetails
162
  worldId={worldId}
163
  engineId={engineId}
164
  game={game}
@@ -171,10 +173,10 @@ https://github.com/michalochman/react-pixi-fiber/issues/145#issuecomment-5315492
171
  </div>
172
  </div>
173
  {createPortal(
174
- <div className="max-w-[1400px] mx-auto">
175
- {playerId && <VotingPopover engineId={engineId} game={game} playerId={playerId} />}
176
- </div>,
177
- document.getElementById('footer-buttons')
178
  )}
179
  </>
180
  );
 
1
+ import React, { useRef, useState, useEffect } from 'react';
 
 
 
2
  import { Stage } from '@pixi/react';
3
  import { ConvexProvider, useConvex, useQuery } from 'convex/react';
4
  import PlayerDetails from './PlayerDetails.tsx';
 
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({ game, me }) {
25
  const [humans, setHumans] = useState(0);
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':
 
45
  case 'WerewolfVoting':
46
  return {
47
  label: 'Werewolf Vote',
48
+ desc: 'Select a player who is a werewolf',
49
  };
50
  case 'PlayerKillVoting':
51
  return {
 
55
  case 'LobbyState':
56
  return {
57
  label: 'Lobby (waiting for start)',
58
+ desc: `Waiting for the game to start. ${humans} out of the ${LOBBY_SIZE} required`,
59
  };
60
  case 'Night':
61
  return {
62
  label: 'Night',
63
+ desc: me?.type === 'werewolf' ? 'Discuss who to kill with other werewolves' : 'Hide in your home!!',
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
  const engineId = worldStatus?.engineId;
97
  const oauth = JSON.parse(localStorage.getItem('oauth'));
98
  const oauthToken = oauth ? oauth.userInfo.fullname : undefined;
99
+ const humanTokenIdentifier = useQuery(api.world.userStatus, { worldId, oauthToken });
 
100
 
101
  const game = useServerGame(worldId);
102
 
 
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", 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
  </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 bg-brown-800 text-brown-100"
156
  ref={scrollViewRef}
157
  >
158
  <div className="flex flex-col items-center mb-4 gap-4">
159
+ <h2 className="text-2xl font-bold">{gameStateLabel.label}</h2>
160
+ <p className="text-lg text-center">{gameStateLabel.desc}</p>
161
  </div>
162
  {playerId && !isEndGame(game) && canVote(game, meDescription) && <GameVote engineId={engineId} game={game} playerId={playerId} />}
163
+ {!isEndGame(game) && !canVote(game, meDescription) && playerId && <PlayerDetails
164
  worldId={worldId}
165
  engineId={engineId}
166
  game={game}
 
173
  </div>
174
  </div>
175
  {createPortal(
176
+ <div className="max-w-[1400px] mx-auto">
177
+ {playerId && <VotingPopover engineId={engineId} game={game} playerId={playerId} />}
178
+ </div>,
179
+ document.getElementById('footer-buttons')
180
  )}
181
  </>
182
  );