Spaces:
Sleeping
Sleeping
File size: 4,626 Bytes
90cbf22 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
import { useRef, useState } from 'react';
import PixiGame from './PixiGame.tsx';
import { useElementSize } from 'usehooks-ts';
import { Stage } from '@pixi/react';
import { ConvexProvider, useConvex, useQuery } from 'convex/react';
import PlayerDetails from './PlayerDetails.tsx';
import { api } from '../../convex/_generated/api';
import { useWorldHeartbeat } from '../hooks/useWorldHeartbeat.ts';
import { useHistoricalTime } from '../hooks/useHistoricalTime.ts';
import { DebugTimeManager } from './DebugTimeManager.tsx';
import { GameId } from '../../convex/aiTown/ids.ts';
import { useServerGame } from '../hooks/serverGame.ts';
import { VoteModal } from './VoteModal.tsx';
import { GameCycle } from '../../convex/aiTown/gameCycle.ts';
import { PlayerDescription } from '../../convex/aiTown/playerDescription.ts';
export const SHOW_DEBUG_UI = !!import.meta.env.VITE_SHOW_DEBUG_UI;
export function VotingName(gameState: string) {
switch (gameState) {
case 'warewolf-vote':
return {
name: 'Warewolf Vote',
desc: 'Select a player who is warewolf',
type: 'warewolf-vote',
};
case 'player-kill':
return {
name: 'Player Kill',
desc: 'Select a player to kill',
type: 'player-kill',
};
default:
return {
name: 'Voting',
desc: 'Select a player to vote',
type: 'voting',
};
}
}
export function isVotingState(gameCycle: GameCycle) {
return gameCycle.cycleIndex === 0 || gameCycle.cycleIndex === 2;
}
function showMap(gameCycle: GameCycle, player: PlayerDescription) {
// Here also check for player description
return gameCycle.cycleIndex === 2 || gameCycle.cycleIndex == 1;
}
export default function Game() {
const convex = useConvex();
const [selectedElement, setSelectedElement] = useState<{
kind: 'player';
id: GameId<'players'>;
}>();
const [gameWrapperRef, { width, height }] = useElementSize();
const worldStatus = useQuery(api.world.defaultWorldStatus);
const worldId = worldStatus?.worldId;
const engineId = worldStatus?.engineId;
const game = useServerGame(worldId);
// Send a periodic heartbeat to our world to keep it alive.
useWorldHeartbeat();
const worldState = useQuery(api.world.worldState, worldId ? { worldId } : 'skip');
const { historicalTime, timeManager } = useHistoricalTime(worldState?.engine);
const scrollViewRef = useRef<HTMLDivElement>(null);
// TODO: base this on the game state
const [gameState, setGameState] = useState<'warewolf-vote' | 'player-kill' | 'none'>('none');
if (!worldId || !engineId || !game) {
return null;
}
return (
<>
{SHOW_DEBUG_UI && <DebugTimeManager timeManager={timeManager} width={200} height={100} />}
<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">
{/* Game area */}
<div className="relative overflow-hidden bg-brown-900" ref={gameWrapperRef}>
<div className={`absolute inset-0 ${!showMap ? 'invisible' : '' }`}>
<div className="container">
<Stage width={width} height={height} options={{ backgroundColor: 0x7ab5ff }}>
{/* Re-propagate context because contexts are not shared between renderers.
https://github.com/michalochman/react-pixi-fiber/issues/145#issuecomment-531549215 */}
<ConvexProvider client={convex}>
<PixiGame
game={game}
worldId={worldId}
engineId={engineId}
width={width}
height={height}
historicalTime={historicalTime}
setSelectedElement={setSelectedElement}
/>
</ConvexProvider>
</Stage>
</div>
</div>
<div></div>
</div>
{/* Right column area */}
<div
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"
ref={scrollViewRef}
>
{isVotingState(game.world.gameCycle) ? <VoteModal game={game} worldId={worldId} engineId={engineId} /> :
<PlayerDetails
worldId={worldId}
engineId={engineId}
game={game}
playerId={selectedElement?.id}
setSelectedElement={setSelectedElement}
scrollViewRef={scrollViewRef}
/>
}
</div>
</div>
</>
);
}
|