1
0

Implemented place-robber, pass, and steal-resource. Added SelectPlayer.

Signed-off-by: James Ketrenos <james_eikona@ketrenos.com>
This commit is contained in:
James Ketrenos 2022-03-12 16:57:21 -08:00
parent 9633e48f21
commit d01ab17e13
7 changed files with 232 additions and 60 deletions

View File

@ -60,6 +60,7 @@ body {
}
.Table .Game {
position: relative;
display: flex;
flex-direction: column;
flex-grow: 1;

View File

@ -19,6 +19,7 @@ import { Actions } from "./Actions.js";
import { base, gamesPath } from './Common.js';
import { GameOrder } from "./GameOrder.js";
import { Activities } from "./Activities.js";
import { SelectPlayer } from "./SelectPlayer.js";
import history from "./history.js";
import "./App.css";
@ -291,10 +292,10 @@ const Table = () => {
</Paper>
</div> }
{ warning && <div className="WarningDialog"><Paper className="Warning">{ warning }</Paper></div> }
{ state === 'normal' && <SelectPlayer/> }
{ color && state === 'game-order' && <GameOrder/> }
<Board/>
{ color && state === 'game-order' &&
<GameOrder/>
}
{ /* state === 'winner' &&
<Winner color={winner}/>
@ -311,11 +312,6 @@ const Table = () => {
{ isTurn && turn && turn.actions && game.turn.actions.indexOf('select-resources') !== -1 &&
<ChooseCard type={turn.active}/>
}
{ game.state === 'normal' &&
turn && isTurn && turn.actions && turn.actions.indexOf('steal-resource') !== -1 &&
<SelectPlayer table={this} game={this.state} players={game.turn.limits.players}/>
*/ }
<div className="Hand">todo: player's hand</div>

View File

@ -2,13 +2,12 @@
display: flex;
position: absolute;
left: 0;
right: 30vw;
right: 0;
bottom: 0;
top: 0;
justify-content: center;
align-items: center;
z-index: 1000;
max-height: 100vh;
overflow: auto;
}

View File

@ -0,0 +1,53 @@
.SelectPlayer {
display: flex;
position: absolute;
left: 0;
right: 0;
bottom: 0;
top: 0;
justify-content: center;
align-items: center;
overflow: auto;
background-color: #40404020;
z-index: 10000;
}
.SelectPlayer .Title {
align-self: center;
padding: 2px;
font-weight: bold;
}
.SelectPlayer .SelectPlayerList {
display: flex;
flex-direction: column;
justify-content: flex-start;
padding: 0.5em;
background-color:rgba(224, 224, 224);
margin: 0.5em 0;
}
.SelectPlayer > * {
width: 20em;
display: inline-flex;
padding: 0.5em;
flex-direction: column;
}
.SelectPlayer .PlayerColor {
width: 1em;
height: 1em;
}
.SelectPlayer .SelectPlayerItem {
display: flex;
flex-direction: row;
width: 100%;
align-items: center;
padding: 2px 0;
cursor: pointer;
}
.SelectPlayer > * {
margin: 0 0.25em;
}

View File

@ -0,0 +1,84 @@
import React, { useState, useEffect, useContext, useRef, useMemo } from "react";
import Paper from '@material-ui/core/Paper';
import equal from "fast-deep-equal";
import { PlayerColor } from "./PlayerColor.js";
import "./SelectPlayer.css";
import { GlobalContext } from "./GlobalContext.js";
const SelectPlayer = () => {
const { ws } = useContext(GlobalContext);
const [turn, setTurn] = useState(undefined);
const [color, setColor] = useState(undefined);
const fields = useMemo(() => [
'turn', 'color'
], []);
const onWsMessage = (event) => {
const data = JSON.parse(event.data);
switch (data.type) {
case 'game-update':
console.log(`select-players - game-update: `, data.update);
if ('turn' in data.update && !equal(turn, data.update.turn)) {
setTurn(data.update.turn);
}
if ('color' in data.update && data.update.color !== color) {
setColor(data.update.color);
}
break;
default:
break;
}
};
const refWsMessage = useRef(onWsMessage);
useEffect(() => { refWsMessage.current = onWsMessage; });
useEffect(() => {
if (!ws) { return; }
const cbMessage = e => refWsMessage.current(e);
ws.addEventListener('message', cbMessage);
return () => { ws.removeEventListener('message', cbMessage); }
}, [ws, refWsMessage]);
useEffect(() => {
if (!ws) { return; }
ws.send(JSON.stringify({
type: 'get',
fields
}));
}, [ws, fields]);
const playerClick = (event) => {
ws.send(JSON.stringify({
type: 'steal-resource',
color: event.currentTarget.getAttribute('data-color')
}));
}
if (!color || !turn || turn.color !== color || !turn.limits || !turn.limits.players) {
return (<></>);
}
const list = turn.limits.players.map(item =>
<div className="SelectPlayerItem"
onClick={playerClick}
data-color={item.color}
key={`player-${item.color}`}>
<PlayerColor color={item.color}/>
<div>{item.name}</div>
</div>
);
return (
<div className="SelectPlayer">
<Paper>
<div className="Title">Select Player to Steal From</div>
<div className="SelectPlayerList">
{ list }
</div>
</Paper>
</div>
);
};
export { SelectPlayer };

View File

@ -67,41 +67,6 @@ const StartButton = ({ table, game }) => {
);
};
const SelectPlayer = ({table, game, players}) => {
const playerClick = (event) => {
table.stealResource(event.currentTarget.getAttribute('data-color'));
}
if (!game.id) {
return (<></>);
}
let list = players.map(color => {
let item = {
color: color,
name: getPlayerName(game.sessions, color)
};
return <div className="SelectPlayerItem"
onClick={playerClick}
data-color={color}
key={`player-${item.color}`}>
<PlayerColor color={item.color}/>
<div>{item.name}</div>
</div>;
});
return (
<div className="SelectPlayer">
{ game && <Paper>
<div className="Title">Select Player to Steal From</div>
<div className="SelectPlayerList">
{ list }
</div>
</Paper> }
</div>
);
};
const PlayerName = ({table, game}) => {
const [name, setName] = useState(game.name ? game.name : "");

View File

@ -246,6 +246,7 @@ const roll = (game, session) => {
return `You already rolled this turn.`;
}
processRoll(game, session, [ Math.ceil(Math.random() * 6), Math.ceil(Math.random() * 6) ]);
sendUpdateToPlayers(game, { chat: game.chat });
return;
default:
@ -361,6 +362,7 @@ const processRoll = (game, session, dice) => {
players: game.players,
chat: game.chat
});
return;
}
/* ROBBER Robber Robinson! */
@ -1020,8 +1022,8 @@ const addChatMessage = (game, session, message) => {
if (game.chat.length) {
lastTime = game.chat[game.chat.length - 1].date;
}
if (now === lastTime) {
now++;
if (now <= lastTime) {
now = lastTime + 1;
}
const entry = {
@ -1870,10 +1872,17 @@ const pass = (game, session) => {
game.turns++;
addActivity(game, session, `${name} passed their turn.`);
addChatMessage(game, null, `It is ${next}'s turn.`);
sendUpdateToPlayers(game, {
turn: game.turn,
chat: game.chat,
activites: game.activities
});
}
const placeRobber = (game, session, value) => {
const placeRobber = (game, session, robber) => {
const name = session.name;
robber = parseInt(robber);
if (game.state !== 'normal' && game.turn.roll !== 7) {
return `You cannot place robber unless 7 was rolled!`;
@ -1890,7 +1899,7 @@ const placeRobber = (game, session, value) => {
return `You cannot place the robber until everyone has discarded!`;
}
}
const robber = parseInt(value ? value : 0);
if (game.robber === robber) {
return `You must move the robber to a new location!`;
}
@ -1900,17 +1909,22 @@ const placeRobber = (game, session, value) => {
pickRobber(game);
addActivity(game, null, `${game.robberName} Robber Robinson entered the scene as the nefarious robber!`);
let colors = [];
let targets = [];
layout.tiles[robber].corners.forEach(cornerIndex => {
const active = game.placements.corners[cornerIndex];
if (active && active.color && active.color !== game.turn.color && colors.indexOf(active.color) == -1) {
colors.push(active.color);
if (active && active.color
&& active.color !== game.turn.color
&& targets.findIndex(item => item.color === active.color) === -1) {
targets.push({
color: active.color,
name: game.players[active.color].name
});
}
});
if (colors.length) {
if (targets.length) {
game.turn.actions = [ 'steal-resource' ],
game.turn.limits = { players: colors };
game.turn.limits = { players: targets };
} else {
game.turn.actions = [];
game.turn.robberInAction = false;
@ -1920,18 +1934,29 @@ const placeRobber = (game, session, value) => {
`with no other players, ` +
`so ${game.turn.name} does not steal resources from anyone.`);
}
sendUpdateToPlayers(game, {
placements: game.placements,
turn: game.turn,
chat: game.chat,
robber: game.robber,
robberName: game.robberName,
activities: game.activities
});
sendUpdateToPlayer(session, {
private: game.player
});
}
const stealResource = (game, session, value) => {
const name = session.name;
const stealResource = (game, session, color) => {
if (game.turn.actions.indexOf('steal-resource') === -1) {
return `You can only steal a resource when it is valid to do so!`;
}
if (game.turn.limits.players.indexOf(value) === -1) {
if (game.turn.limits.players.findIndex(item => item.color === color) === -1) {
return `You can only steal a resource from a player on this terrain!`;
}
let victim = game.players[value];
cards = [];
const victim = game.players[color];
const cards = [];
[ 'wheat', 'brick', 'sheep', 'stone', 'wood' ].forEach(field => {
for (let i = 0; i < victim[field]; i++) {
cards.push(field);
@ -1962,6 +1987,14 @@ const stealResource = (game, session, value) => {
debugChat(game, 'After steal');
game.turn.robberInAction = false;
sendUpdateToPlayers(game, {
turn: game.turn,
chat: game.chat,
activities: game.activities
});
sendUpdateToPlayer(session, {
private: game.player
});
}
const buyDevelopment = (game, session, value) => {
@ -2005,6 +2038,15 @@ const buyDevelopment = (game, session, value) => {
card = game.developmentCards.pop();
card.turn = game.turns;
player.development.push(card);
sendUpdateToPlayers(game, {
chat: game.chat,
activities: game.activities,
players: getFilteredPlayers(game)
});
sendUpdateToPlayer(session, {
private: game.player
});
}
const playCard = (game, session, { card }) => {
@ -2115,6 +2157,17 @@ const playCard = (game, session, { card }) => {
game.turn.limits.pips.push(i);
}
}
sendUpdateToPlayers(game, {
chat: game.chat,
activities: game.activities,
largestArmy: game.largestArmy,
largestArmySize: game.largestArmySize,
turn: game.turn
});
sendUpdateToPlayer(session, {
private: game.player
});
}
const placeSettlement = (game, session, index) => {
@ -3344,6 +3397,27 @@ const wsConnect = async (ws, req) => {
sendWarning(session, warning);
}
break;
case 'place-robber':
console.log(`${short}: <- place-robber:${getName(session)} ${data.index}`);
warning = placeRobber(game, session, data.index);
if (warning) {
sendWarning(session, warning);
}
break;
case 'steal-resource':
console.log(`${short}: <- steal-resource:${getName(session)} ${data.color}`);
warning = stealResource(game, session, data.color);
if (warning) {
sendWarning(session, warning);
}
break;
case 'pass':
console.log(`${short}: <- pass:${getName(session)}`);
warning = pass(game, session);
if (warning) {
sendWarning(session, warning);
}
break;
default:
console.warn(`Unsupported request: ${data.type}`);
break;