Set player to disconnected on disconnect, some minor refactoring, comments

This commit is contained in:
Martin Berg Alstad 2023-07-16 14:15:59 +02:00
parent 11ef229664
commit e6d8648eff
6 changed files with 39 additions and 11 deletions

View File

@ -57,10 +57,18 @@ const Board: Component<BoardProps> = (
const takenChar = characters.find(c => c.isPacMan() && c.isAt(destination.End)); const takenChar = characters.find(c => c.isPacMan() && c.isAt(destination.End));
if (takenChar) { if (takenChar) {
takenChar.moveToSpawn(); takenChar.moveToSpawn();
// TODO steal from other player stealFromPlayer();
} }
} }
// TODO steal from other player
function stealFromPlayer(): void {
// TODO select player to steal from
// TODO modal to select player
// const victim
// currentPlayer?.stealFrom(victim)
}
function pickUpPellets(destination: Path): Position[] { function pickUpPellets(destination: Path): Position[] {
const positions: Position[] = []; const positions: Position[] = [];
if (selectedCharacter?.isPacMan()) { if (selectedCharacter?.isPacMan()) {

View File

@ -3,28 +3,33 @@ import {AllDice} from "./dice";
import {doAction, GameAction} from "../utils/actions"; import {doAction, GameAction} from "../utils/actions";
import GameBoard from "./gameBoard"; import GameBoard from "./gameBoard";
import WebSocketService from "../websockets/WebSocketService"; import WebSocketService from "../websockets/WebSocketService";
import {getCharacterSpawns, testMap} from "../game/map"; import {getCharacterSpawns} from "../game/map";
import Player from "../game/player"; import Player from "../game/player";
import PlayerStats from "../components/playerStats"; import PlayerStats from "../components/playerStats";
import {getDefaultStore, useAtom, useAtomValue, useSetAtom} from "jotai"; import {useAtom, useAtomValue, useSetAtom} from "jotai";
import {diceAtom, ghostsAtom, playersAtom, rollDiceButtonAtom, selectedDiceAtom} from "../utils/state"; import {diceAtom, ghostsAtom, playersAtom, rollDiceButtonAtom, selectedDiceAtom} from "../utils/state";
import {CharacterType} from "../game/character"; import {CharacterType} from "../game/character";
import GameButton from "./gameButton"; import GameButton from "./gameButton";
const wsService = new WebSocketService(import.meta.env.VITE_API); const wsService = new WebSocketService(import.meta.env.VITE_API);
// TODO ghost should be able to take pacmen
// TODO don't start game until at least 2 players have joined // TODO don't start game until at least 2 players have joined
// TODO join game lobby // TODO join game lobby
// TODO sign up player page
// TODO sign in page
// TODO steal from other players // TODO steal from other players
// TODO show box with collected pellets // TODO show box with collected pellets
// TODO layout // TODO layout
export const GameComponent: Component<{ player: Player }> = ({player}) => { export const GameComponent: Component<{ player: Player, map: GameMap }> = ({player, map}) => {
const players = useAtomValue(playersAtom);
const players = useAtomValue(playersAtom);
const dice = useAtomValue(diceAtom); const dice = useAtomValue(diceAtom);
const [selectedDice, setSelectedDice] = useAtom(selectedDiceAtom); const [selectedDice, setSelectedDice] = useAtom(selectedDiceAtom);
const setActiveRollDiceButton = useSetAtom(rollDiceButtonAtom); const setActiveRollDiceButton = useSetAtom(rollDiceButtonAtom);
const ghosts = useAtomValue(ghostsAtom);
function rollDice(): void { function rollDice(): void {
if (!player.isTurn()) return; if (!player.isTurn()) return;
@ -44,7 +49,7 @@ export const GameComponent: Component<{ player: Player }> = ({player}) => {
Data: { Data: {
Dice: dice?.length ?? 0 > 0 ? dice : null, Dice: dice?.length ?? 0 > 0 ? dice : null,
Players: players, Players: players,
Ghosts: getDefaultStore().get(ghostsAtom), Ghosts: ghosts,
EatenPellets: eatenPellets EatenPellets: eatenPellets
} }
}; };
@ -59,7 +64,7 @@ export const GameComponent: Component<{ player: Player }> = ({player}) => {
wsService.send({ wsService.send({
Action: GameAction.playerInfo, Action: GameAction.playerInfo,
Data: { Data: {
Player: player, Spawns: getCharacterSpawns(testMap) Player: player, Spawns: getCharacterSpawns(map)
.filter(s => s.type === CharacterType.pacMan) .filter(s => s.type === CharacterType.pacMan)
.map(s => s.position) .map(s => s.position)
} }
@ -70,7 +75,7 @@ export const GameComponent: Component<{ player: Player }> = ({player}) => {
wsService.send({Action: GameAction.ready}); wsService.send({Action: GameAction.ready});
} }
function endTurn() { function endTurn(): void {
wsService.send({Action: GameAction.nextPlayer}); wsService.send({Action: GameAction.nextPlayer});
} }
@ -92,7 +97,7 @@ export const GameComponent: Component<{ player: Player }> = ({player}) => {
<div className={"flex justify-center"}> <div className={"flex justify-center"}>
{players?.map(p => <PlayerStats key={p.Name} player={p}/>)} {players?.map(p => <PlayerStats key={p.Name} player={p}/>)}
</div> </div>
<GameBoard className={"mx-auto my-2"} onMove={onCharacterMove} map={testMap}/> <GameBoard className={"mx-auto my-2"} onMove={onCharacterMove} map={map}/>
</> </>
); );
}; };

View File

@ -2,6 +2,7 @@ import React, {useEffect} from "react";
import {GameComponent} from "../components/gameComponent"; import {GameComponent} from "../components/gameComponent";
import {useAtomValue} from "jotai"; import {useAtomValue} from "jotai";
import {thisPlayerAtom} from "../utils/state"; import {thisPlayerAtom} from "../utils/state";
import {testMap} from "../game/map";
const Game: Component = () => { const Game: Component = () => {
const player = useAtomValue(thisPlayerAtom); const player = useAtomValue(thisPlayerAtom);
@ -15,7 +16,7 @@ const Game: Component = () => {
}, [player]); }, [player]);
if (player) { if (player) {
return <GameComponent player={player}/>; return <GameComponent player={player} map={testMap}/>;
} else { } else {
return null; return null;
} }

View File

@ -30,4 +30,10 @@ public class GameController : GenericController // TODO reconnect using player i
_actionService.DoAction(action); _actionService.DoAction(action);
return action.ToArraySegment(); return action.ToArraySegment();
} }
protected override void Disconnect()
{
base.Disconnect();
_actionService.Disconnect();
}
} }

View File

@ -66,8 +66,10 @@ public abstract class GenericController : ControllerBase
Logger.Log(LogLevel.Error, "{}", e.Message); Logger.Log(LogLevel.Error, "{}", e.Message);
} }
WsService.Connections -= WsServiceOnFire; Disconnect();
} }
protected abstract ArraySegment<byte> Run(WebSocketReceiveResult result, byte[] data); protected abstract ArraySegment<byte> Run(WebSocketReceiveResult result, byte[] data);
protected virtual void Disconnect() => WsService.Connections -= WsServiceOnFire;
} }

View File

@ -15,6 +15,7 @@ public interface IActionService
List<IPlayer> SetPlayerInfo(ActionMessage message); List<IPlayer> SetPlayerInfo(ActionMessage message);
object Ready(); object Ready();
string FindNextPlayer(); string FindNextPlayer();
void Disconnect();
} }
public class ActionService : IActionService public class ActionService : IActionService
@ -96,6 +97,11 @@ public class ActionService : IActionService
} }
public string FindNextPlayer() => Group?.NextPlayer().Name ?? "Error: No group found"; public string FindNextPlayer() => Group?.NextPlayer().Name ?? "Error: No group found";
public void Disconnect()
{
if (Player != null) Player.State = State.Disconnected;
}
} }
public struct PlayerInfoData public struct PlayerInfoData