Added Activity feed
Fixed some more WebSocket timeouts Changed Resource to support a label=true mode which puts a bubble lable instead of creating a stack Signed-off-by: James Ketrenos <james_eikona@ketrenos.com>
This commit is contained in:
parent
2fa436081b
commit
4ff9ad015e
@ -18,12 +18,36 @@
|
||||
|
||||
.Activities .PlayerColor {
|
||||
display: inline-flex;
|
||||
width: 0.8em;
|
||||
height: 0.8em;
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
margin: 0 0.2rem;
|
||||
}
|
||||
|
||||
.Activities > div {
|
||||
padding: 0.5em;
|
||||
padding: 0.25rem 0.5rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.Activity b,
|
||||
.Activity .Dice {
|
||||
margin-left: 0.25em;
|
||||
}
|
||||
|
||||
.Activities > div:last-child {
|
||||
border-top: 1px solid black;
|
||||
}
|
||||
|
||||
.Activity.open{
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.Activity.close{
|
||||
animation: bounce-out 1s ease-in;
|
||||
}
|
||||
|
||||
@keyframes bounce-out{
|
||||
0% {opacity: 1; }
|
||||
100% {opacity: 0; };
|
||||
}
|
@ -1,12 +1,60 @@
|
||||
import React from "react";
|
||||
import React, { useState, useCallback, useEffect } from "react";
|
||||
import "./Activities.css";
|
||||
import Paper from '@material-ui/core/Paper';
|
||||
import Resource from './Resource.js';
|
||||
import { getPlayerName } from './Common.js';
|
||||
import PlayerColor from './PlayerColor.js';
|
||||
import Dice from './Dice.js';
|
||||
|
||||
const Activity = ({ activity }) => {
|
||||
const [animation, setAnimation] = useState('open');
|
||||
const [display, setDisplay] = useState(true)
|
||||
|
||||
const Activities = ({table }) => {
|
||||
const hide = async (ms) => {
|
||||
await new Promise(r => setTimeout(r, ms));
|
||||
setAnimation('close')
|
||||
await new Promise(r => setTimeout(r, 1000));
|
||||
setDisplay(false)
|
||||
};
|
||||
|
||||
if (display) {
|
||||
setTimeout(() => hide(10000), 0);
|
||||
}
|
||||
|
||||
let message;
|
||||
/* If the date is in the future, set it to now */
|
||||
const dice = activity.message.match(/^(.*rolled )([1-6])(, ([1-6]))?(.*)$/);
|
||||
if (dice) {
|
||||
if (dice[4]) {
|
||||
const sum = parseInt(dice[2]) + parseInt(dice[4]);
|
||||
message = <>{dice[1]}<b>{sum}</b>: <Dice pips={dice[2]}/>, <Dice pips={dice[4]}/>{dice[5]}</>;
|
||||
} else {
|
||||
message = <>{dice[1]}<Dice pips={dice[2]}/>{dice[5]}</>;
|
||||
}
|
||||
} else {
|
||||
message = activity.message; /*
|
||||
let start = activity.message;
|
||||
while (start) {
|
||||
const resource = start.match(/^(.*)(([0-9]+) (wood|sheep|wheat|stone|brick),?)(.*)$/);
|
||||
if (resource) {
|
||||
const count = resource[3] ? parseInt(resource[3]) : 1;
|
||||
message = <><Resource count={count} type={resource[4]}/>{resource[5]}{message}</>;
|
||||
start = resource[1];
|
||||
} else {
|
||||
message = <>{start}{message}</>;
|
||||
start = '';
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
return <>{ display &&
|
||||
<div className={`Activity ${animation}`}>
|
||||
<PlayerColor color={activity.color}/>{message}
|
||||
</div>
|
||||
}</>;
|
||||
}
|
||||
|
||||
const Activities = ({ table }) => {
|
||||
if (!table.game) {
|
||||
return <></>;
|
||||
}
|
||||
@ -14,20 +62,31 @@ const Activities = ({table }) => {
|
||||
const
|
||||
game = table.game,
|
||||
isTurn = (game.turn && game.turn.color === game.color) ? true : false,
|
||||
normalPlay = (game.state === 'initial-placement' || game.state === 'normal');
|
||||
|
||||
normalPlay = (game.state === 'initial-placement' || game.state === 'normal'),
|
||||
mustDiscard = game.player ? (parseInt(game.player.mustDiscard ? game.player.mustDiscard : 0) !== 0) : false;
|
||||
|
||||
const list = game.activities
|
||||
.filter(activity => game.timestamp - activity.date < 11000)
|
||||
.map(activity => {
|
||||
return <Activity key={activity.date} activity={activity}/>;
|
||||
});
|
||||
|
||||
return (
|
||||
<Paper className="Activities">
|
||||
{ !isTurn && normalPlay && (!game.player || !game.player.mustDiscard) &&
|
||||
<div>Waiting for {table.game.turn.name} to complete their turn.</div>
|
||||
<div className="Activities">
|
||||
{ list }
|
||||
|
||||
{ !isTurn && normalPlay && !mustDiscard &&
|
||||
<div>Waiting for <PlayerColor color={table.game.turn.color}/> {table.game.turn.name} to complete their turn.</div>
|
||||
}
|
||||
{ isTurn && normalPlay && game.player && game.player.mustDiscard &&
|
||||
|
||||
{ isTurn && normalPlay && game.player && mustDiscard &&
|
||||
<div>You must discard.</div>
|
||||
}
|
||||
{ isTurn && normalPlay && (!game.player || !game.player.mustDiscard) &&
|
||||
<div>It is your turn.</div>
|
||||
|
||||
{ isTurn && normalPlay &&
|
||||
<div><PlayerColor color={game.turn.color}/> It is your turn.</div>
|
||||
}
|
||||
</Paper>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -35,6 +35,7 @@
|
||||
.ChatList .MuiTypography-body1 {
|
||||
font-size: 0.8rem;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.ChatList .System .MuiTypography-body1 {
|
||||
@ -61,19 +62,32 @@
|
||||
|
||||
.ChatList .Resource {
|
||||
display: inline-flex;
|
||||
width: 3em;
|
||||
height: 4.3em;
|
||||
align-items: center;
|
||||
justify-content: space-around;
|
||||
height: 1.5rem;
|
||||
width: 1.5rem;
|
||||
min-width: 1.5rem;
|
||||
min-height: 1.5rem;
|
||||
pointer-events: none;
|
||||
margin: 0 0.125rem;
|
||||
background-size: 130%;
|
||||
border: 2px solid #444;
|
||||
border-radius: 2px;
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
.ChatList .Stack {
|
||||
margin-left: 0;
|
||||
transition: none;
|
||||
}
|
||||
|
||||
.ChatList .Stack > *:not(:first-child) {
|
||||
margin-left: 0;
|
||||
transition: none;
|
||||
.ChatList .Resource > div {
|
||||
position: absolute;
|
||||
top: -0.625rem;
|
||||
right: -0.625rem;
|
||||
border-radius: 50%;
|
||||
border: 1px solid white;
|
||||
background-color: rgb(36, 148, 46);
|
||||
font-size: 0.75rem;
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
text-align: center;
|
||||
line-height: 1rem;
|
||||
}
|
||||
|
||||
.ChatList .Dice {
|
||||
|
@ -96,7 +96,7 @@ const Chat = ({ table }) => {
|
||||
const resource = start.match(/^(.*)(([0-9]+) (wood|sheep|wheat|stone|brick),?)(.*)$/);
|
||||
if (resource) {
|
||||
const count = resource[3] ? parseInt(resource[3]) : 1;
|
||||
message = <><Resource count={count} type={resource[4]}/>{resource[5]}{message}</>;
|
||||
message = <><Resource label={true} count={count} type={resource[4]}/>{resource[5]}{message}</>;
|
||||
start = resource[1];
|
||||
} else {
|
||||
message = <>{start}{message}</>;
|
||||
|
@ -8,6 +8,11 @@
|
||||
background-size: cover;
|
||||
margin: 0.25em;
|
||||
cursor: pointer;
|
||||
display: inline-flex;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.Resource:hover {
|
||||
|
@ -2,13 +2,23 @@ import React from "react";
|
||||
import "./Resource.css";
|
||||
import { assetsPath } from './Common.js';
|
||||
|
||||
const Resource = ({ type, select, disabled, count }) => {
|
||||
const Resource = ({ type, select, disabled, count, label }) => {
|
||||
const array = new Array(Number(count ? count : 0));
|
||||
const click = select ? select : (event) => {
|
||||
if (!disabled) {
|
||||
event.target.classList.toggle('Selected');
|
||||
}
|
||||
};
|
||||
|
||||
if (label) {
|
||||
return <div className="Resource"
|
||||
data-type={type}
|
||||
onClick={click}
|
||||
style={{backgroundImage:`url(${assetsPath}/gfx/card-${type}.png)`}}>
|
||||
<div>{count}</div>
|
||||
</div>;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{ array.length > 0 &&
|
||||
|
@ -266,6 +266,7 @@ const Action = ({ table }) => {
|
||||
|
||||
const game = table.game,
|
||||
inLobby = game.state === 'lobby',
|
||||
inGame = game.state === 'normal',
|
||||
player = game ? game.player : undefined,
|
||||
hasRolled = (game && game.turn && game.turn.roll) ? true : false,
|
||||
isTurn = (game && game.turn && game.turn.color === game.color) ? true : false,
|
||||
@ -279,7 +280,7 @@ const Action = ({ table }) => {
|
||||
<Button disabled={game.color ? false : true} onClick={newTableClick}>New table</Button>
|
||||
<Button disabled={game.color ? true : false} onClick={() => {table.setState({ pickName: true})}}>Change name</Button> </> }
|
||||
{ !inLobby && <>
|
||||
<Button disabled={robberActions || !isTurn || hasRolled} onClick={rollClick}>Roll Dice</Button>
|
||||
<Button disabled={robberActions || !isTurn || hasRolled || !inGame} onClick={rollClick}>Roll Dice</Button>
|
||||
<Button disabled={robberActions || !isTurn || !hasRolled || !haveResources} onClick={tradeClick}>Trade</Button>
|
||||
<Button disabled={robberActions || !isTurn || !hasRolled || !haveResources} onClick={buildClicked}>Build</Button>
|
||||
{ game.turn.roll === 7 && player && player.mustDiscard > 0 &&
|
||||
@ -734,30 +735,33 @@ class Table extends React.Component {
|
||||
}
|
||||
|
||||
resetKeepAlive(isDead) {
|
||||
if (isDead) {
|
||||
console.log(`Short circuiting keep-alive`);
|
||||
} else {
|
||||
console.log(`Resetting keep-alive`);
|
||||
}
|
||||
|
||||
if (this.keepAlive) {
|
||||
clearTimeout(this.keepAlive);
|
||||
this.keepAlive = 0;
|
||||
} else {
|
||||
console.log(`No keep-alive active`);
|
||||
}
|
||||
|
||||
this.keepAlive = setTimeout(() => {
|
||||
console.error(`No server ping after 10 seconds (or connection closed by server)!`);
|
||||
this.setState({ noNetwork: true });
|
||||
if (this.ws) {
|
||||
this.ws.close();
|
||||
}
|
||||
this.connectWebSocket();
|
||||
}, isDead ? 3000 : 10000);
|
||||
|
||||
if (this.state.noNetwork !== false && !isDead) {
|
||||
this.setState({ noNetwork: false });
|
||||
} else if (this.state.noNetwork !== true && isDead) {
|
||||
this.setState({ noNetwork: true });
|
||||
}
|
||||
|
||||
this.keepAlive = setTimeout(() => {
|
||||
console.error(`No server ping!`);
|
||||
this.setState({ noNetwork: true });
|
||||
if (this.ws) {
|
||||
this.ws.close();
|
||||
}
|
||||
if (!this.websocketReconnect) {
|
||||
this.websocketReconnect = setTimeout(() => {
|
||||
delete this.websocketReconnect;
|
||||
this.connectWebSocket();
|
||||
}, 1000);
|
||||
}
|
||||
}, isDead ? 1000 : 5000);
|
||||
}
|
||||
|
||||
connectWebSocket() {
|
||||
@ -907,10 +911,6 @@ class Table extends React.Component {
|
||||
clearTimeout(this.keepAlive);
|
||||
this.keepAlive = 0;
|
||||
}
|
||||
if (this.websocketReconnect) {
|
||||
clearTimeout(this.websocketReconnect);
|
||||
this.websocketReconnect = 0;
|
||||
}
|
||||
if (this.updateSizeTimer) {
|
||||
clearTimeout(this.updateSizeTimer);
|
||||
this.updateSizeTimer = 0;
|
||||
|
@ -365,7 +365,7 @@ const processRoll = (game, dice) => {
|
||||
return;
|
||||
}
|
||||
game.dice = dice;
|
||||
addChatMessage(game, session, `${session.name} rolled ${game.dice[0]}, ${game.dice[1]}.`);
|
||||
addActivity(game, session, `${session.name} rolled ${game.dice[0]}, ${game.dice[1]}.`);
|
||||
game.turn.roll = game.dice[0] + game.dice[1];
|
||||
if (game.turn.roll === 7) {
|
||||
game.turn.robberInAction = true;
|
||||
@ -388,7 +388,7 @@ const processRoll = (game, dice) => {
|
||||
|
||||
if (mustDiscard.length === 0) {
|
||||
addChatMessage(game, null, `ROBBER! ${game.robberName} Robber Roberson has fled, and no one had to discard!`);
|
||||
addChatMessage(game, null, `But drat! A new robber has arrived and must be placed by ${game.turn.name}.`);
|
||||
addChatMessage(game, null, `A new robber has arrived and must be placed by ${game.turn.name}.`);
|
||||
game.turn.actions = [ 'place-robber' ];
|
||||
game.turn.limits = { pips: [] };
|
||||
for (let i = 0; i < 19; i++) {
|
||||
@ -677,7 +677,7 @@ const adminActions = (game, action, value) => {
|
||||
case 'game-order':
|
||||
game.dice = dice;
|
||||
message = `${game.turn.name} rolled ${game.dice[0]}.`;
|
||||
addChatMessage(game, session, message);
|
||||
addActivity(game, session, message);
|
||||
message = undefined;
|
||||
processGameOrder(game, session.player, game.dice[0]);
|
||||
break;
|
||||
@ -717,7 +717,7 @@ const adminActions = (game, action, value) => {
|
||||
continue;
|
||||
}
|
||||
console.log(`Kicking ${value} from ${game.id}.`);
|
||||
const preamble = session.name ? `${session.name}, playing as ${color},` : color;
|
||||
const preamble = session.name ? `${session.name}, playing as ${colorToWord(color)},` : colorToWord(color);
|
||||
addChatMessage(game, null, `${preamble} was kicked from game by the Admin.`);
|
||||
if (player) {
|
||||
session.player = undefined;
|
||||
@ -726,7 +726,7 @@ const adminActions = (game, action, value) => {
|
||||
session.color = undefined;
|
||||
return;
|
||||
}
|
||||
return `Unable to find active session for ${color} (${value})`;
|
||||
return `Unable to find active session for ${colorToWord(color)} (${value})`;
|
||||
|
||||
default:
|
||||
return `Invalid admin action ${action}.`;
|
||||
@ -774,6 +774,17 @@ const setPlayerName = (game, session, name) => {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const colorToWord = (color) => {
|
||||
switch (color) {
|
||||
case 'O': return 'orange';
|
||||
case 'W': return 'white';
|
||||
case 'B': return 'blue';
|
||||
case 'R': return 'red';
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
const setPlayerColor = (game, session, color) => {
|
||||
if (!game) {
|
||||
return `No game found`;
|
||||
@ -793,10 +804,10 @@ const setPlayerColor = (game, session, color) => {
|
||||
/* Deselect currently active player for this session */
|
||||
clearPlayer(player);
|
||||
if (game.state !== 'lobby') {
|
||||
message = `${name} has exited to the lobby and is no longer playing as ${session.color}.`
|
||||
message = `${name} has exited to the lobby and is no longer playing as ${colorToWord(session.color)}.`
|
||||
addChatMessage(game, null, message);
|
||||
} else {
|
||||
message = `${name} is no longer ${session.color}.`;
|
||||
message = `${name} is no longer ${colorToWord(session.color)}.`;
|
||||
}
|
||||
session.player = undefined;
|
||||
session.color = undefined;
|
||||
@ -824,7 +835,7 @@ const setPlayerColor = (game, session, color) => {
|
||||
for (let key in game.sessions) {
|
||||
const tmp = game.sessions[key].player;
|
||||
if (tmp && tmp.color === color) {
|
||||
return `${game.sessions[key].name} already has ${color}`;
|
||||
return `${game.sessions[key].name} already has ${colorToWord(color)}`;
|
||||
}
|
||||
}
|
||||
|
||||
@ -834,7 +845,7 @@ const setPlayerColor = (game, session, color) => {
|
||||
session.player.status = `Active`;
|
||||
session.player.lastActive = Date.now();
|
||||
session.color = color;
|
||||
addChatMessage(game, session, `${session.name} has chosen to play as ${color}.`);
|
||||
addChatMessage(game, session, `${session.name} has chosen to play as ${colorToWord(color)}.`);
|
||||
|
||||
const afterActive = getActiveCount(game);
|
||||
if (afterActive !== priorActive) {
|
||||
@ -845,6 +856,14 @@ const setPlayerColor = (game, session, color) => {
|
||||
}
|
||||
};
|
||||
|
||||
const addActivity = (game, session, message) => {
|
||||
let date = Date.now();
|
||||
if (game.activities.length && game.activities[game.activities.length - 1].date === date) {
|
||||
date++;
|
||||
}
|
||||
game.activities.push({ color: session.color, message, date });
|
||||
}
|
||||
|
||||
const addChatMessage = (game, session, message) => {
|
||||
game.chat.push({
|
||||
from: session ? session.name : undefined,
|
||||
@ -1521,7 +1540,7 @@ router.put("/:id/:action/:value?", async (req, res) => {
|
||||
game.players[key].gets = [];
|
||||
delete game.players[key].offerRejected;
|
||||
}
|
||||
addChatMessage(game, session, `${name} requested to begin trading negotiations.`);
|
||||
addActivity(game, session, `${name} requested to begin trading negotiations.`);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1534,7 +1553,7 @@ router.put("/:id/:action/:value?", async (req, res) => {
|
||||
}
|
||||
game.turn.actions = [];
|
||||
game.turn.limits = {};
|
||||
addChatMessage(game, session, `${name} has cancelled trading negotiations.`);
|
||||
addActivity(game, session, `${name} has cancelled trading negotiations.`);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1564,14 +1583,14 @@ router.put("/:id/:action/:value?", async (req, res) => {
|
||||
}
|
||||
game.turn.offer = offer;
|
||||
}
|
||||
addChatMessage(game, session, `${session.name} submitted an offer to give ${offerToString(offer)}.`);
|
||||
// addActivity(game, session, `${session.name} submitted an offer to give ${offerToString(offer)}.`);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Any player can reject an offer */
|
||||
if (value === 'reject') {
|
||||
session.player.offerRejected = true;
|
||||
addChatMessage(game, session, `${session.name} rejected ${game.turn.name}'s offer.`);
|
||||
addActivity(game, session, `${session.name} rejected ${game.turn.name}'s offer.`);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1699,7 +1718,7 @@ router.put("/:id/:action/:value?", async (req, res) => {
|
||||
color: getColorFromName(game, next)
|
||||
};
|
||||
game.turns++;
|
||||
addChatMessage(game, session, `${name} passed their turn.`);
|
||||
addActivity(game, session, `${name} passed their turn.`);
|
||||
addChatMessage(game, null, `It is ${next}'s turn.`);
|
||||
break;
|
||||
|
||||
@ -1774,7 +1793,7 @@ router.put("/:id/:action/:value?", async (req, res) => {
|
||||
debugChat(game, 'Before steal');
|
||||
|
||||
if (cards.length === 0) {
|
||||
addChatMessage(game, session, `${playerNameFromColor(game, value)} did not have any cards to steal.`);
|
||||
addActivity(game, session, `${playerNameFromColor(game, value)} did not have any cards to steal.`);
|
||||
game.turn.actions = [];
|
||||
game.turn.limits = {};
|
||||
} else {
|
||||
@ -1824,7 +1843,7 @@ router.put("/:id/:action/:value?", async (req, res) => {
|
||||
}
|
||||
|
||||
debugChat(game, 'Before development purchase');
|
||||
addChatMessage(game, session, `${session.name} purchased a development card.`);
|
||||
addActivity(game, session, `${session.name} purchased a development card.`);
|
||||
player.stone--;
|
||||
player.wheat--;
|
||||
player.sheep--;
|
||||
@ -1882,29 +1901,29 @@ router.put("/:id/:action/:value?", async (req, res) => {
|
||||
error = `You can not play victory point cards until you can reach 10!`;
|
||||
break;
|
||||
}
|
||||
addChatMessage(game, session, `${session.name} played a Victory Point card.`);
|
||||
addActivity(game, session, `${session.name} played a Victory Point card.`);
|
||||
}
|
||||
|
||||
if (card.type === 'progress') {
|
||||
switch (card.card) {
|
||||
case 'road-1':
|
||||
case 'road-2':
|
||||
addChatMessage(game, session, `${session.name} played a Road Building card. The server is giving them 2 brick and 2 wood to build those roads!`);
|
||||
addActivity(game, session, `${session.name} played a Road Building card. The server is giving them 2 brick and 2 wood to build those roads!`);
|
||||
player.brick += 2;
|
||||
player.wood += 2;
|
||||
break;
|
||||
case 'monopoly':
|
||||
game.turn.actions = [ 'select-resource' ];
|
||||
game.turn.active = 'monopoly';
|
||||
addChatMessage(game, session, `${session.name} played the Monopoly card, and is selecting their resource type to claim.`);
|
||||
addActivity(game, session, `${session.name} played the Monopoly card, and is selecting their resource type to claim.`);
|
||||
break;
|
||||
case 'year-of-plenty':
|
||||
game.turn.actions = [ 'select-resource' ];
|
||||
game.turn.active = 'year-of-plenty';
|
||||
addChatMessage(game, session, `${session.name} played the Year of Plenty card.`);
|
||||
addActivity(game, session, `${session.name} played the Year of Plenty card.`);
|
||||
break;
|
||||
default:
|
||||
addChatMessage(game, session, `Oh no! ${card.card} isn't impmented yet!`);
|
||||
addActivity(game, session, `Oh no! ${card.card} isn't impmented yet!`);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1913,7 +1932,7 @@ router.put("/:id/:action/:value?", async (req, res) => {
|
||||
|
||||
if (card.type === 'army') {
|
||||
player.army++;
|
||||
addChatMessage(game, session, `${session.name} played a Kaniget!`);
|
||||
addActivity(game, session, `${session.name} played a Kaniget!`);
|
||||
|
||||
if (player.army > 2 &&
|
||||
(!game.largestArmy || game.players[game.largestArmy].army < player.army)) {
|
||||
@ -1967,7 +1986,7 @@ router.put("/:id/:action/:value?", async (req, res) => {
|
||||
if (error) {
|
||||
break;
|
||||
}
|
||||
addChatMessage(game, session, `${session.name} has chosen ${type}!`);
|
||||
addActivity(game, session, `${session.name} has chosen ${type}!`);
|
||||
|
||||
switch (game.turn.active) {
|
||||
case 'monopoly':
|
||||
@ -1992,7 +2011,7 @@ router.put("/:id/:action/:value?", async (req, res) => {
|
||||
if (gave.length) {
|
||||
addChatMessage(game, session, `Players ${gave.join(', ')}. In total, ${session.name} received ${total} ${type}.`);
|
||||
} else {
|
||||
addChatMessage(game, session, 'No players had that resource. Wa-waaaa.');
|
||||
addActivity(game, session, 'No players had that resource. Wa-waaaa.');
|
||||
}
|
||||
break;
|
||||
|
||||
@ -2038,7 +2057,7 @@ router.put("/:id/:action/:value?", async (req, res) => {
|
||||
break;
|
||||
}
|
||||
placeSettlement(game, corners);
|
||||
addChatMessage(game, session, `${game.turn.name} is considering placing a settlement.`);
|
||||
addActivity(game, session, `${game.turn.name} is considering placing a settlement.`);
|
||||
break;
|
||||
|
||||
case 'place-settlement':
|
||||
@ -2118,10 +2137,10 @@ router.put("/:id/:action/:value?", async (req, res) => {
|
||||
game.turn.actions = [];
|
||||
game.turn.limits = {};
|
||||
if (bankType) {
|
||||
addChatMessage(game, session,
|
||||
addActivity(game, session,
|
||||
`${name} placed a settlement by a maritime bank that trades ${bankType}.`);
|
||||
} else {
|
||||
addChatMessage(game, session, `${name} placed a settlement.`);
|
||||
addActivity(game, session, `${name} placed a settlement.`);
|
||||
}
|
||||
calculateRoadLengths(game, session);
|
||||
} else if (game.state === 'initial-placement') {
|
||||
@ -2151,11 +2170,11 @@ router.put("/:id/:action/:value?", async (req, res) => {
|
||||
}
|
||||
player.settlements--;
|
||||
if (bankType) {
|
||||
addChatMessage(game, session,
|
||||
addActivity(game, session,
|
||||
`${name} placed a settlement by a maritime bank that trades ${bankType}. ` +
|
||||
`Next, they need to place a road.`);
|
||||
} else {
|
||||
addChatMessage(game, session, `${name} placed a settlement. ` +
|
||||
addActivity(game, session, `${name} placed a settlement. ` +
|
||||
`Next, they need to place a road.`);
|
||||
}
|
||||
placeRoad(game, layout.corners[index].roads);
|
||||
@ -2195,7 +2214,7 @@ router.put("/:id/:action/:value?", async (req, res) => {
|
||||
break;
|
||||
}
|
||||
placeCity(game, corners);
|
||||
addChatMessage(game, session, `${game.turn.name} is considering upgrading a settlement to a city.`);
|
||||
addActivity(game, session, `${game.turn.name} is considering upgrading a settlement to a city.`);
|
||||
break;
|
||||
|
||||
case 'place-city':
|
||||
@ -2252,7 +2271,7 @@ router.put("/:id/:action/:value?", async (req, res) => {
|
||||
debugChat(game, 'After city purchase');
|
||||
game.turn.actions = [];
|
||||
game.turn.limits = {};
|
||||
addChatMessage(game, session, `${name} upgraded a settlement to a city!`);
|
||||
addActivity(game, session, `${name} upgraded a settlement to a city!`);
|
||||
break;
|
||||
|
||||
case 'buy-road':
|
||||
@ -2288,7 +2307,7 @@ router.put("/:id/:action/:value?", async (req, res) => {
|
||||
break;
|
||||
}
|
||||
placeRoad(game, roads);
|
||||
addChatMessage(game, session, `${game.turn.name} is considering building a road.`);
|
||||
addActivity(game, session, `${game.turn.name} is considering building a road.`);
|
||||
break;
|
||||
|
||||
case 'place-road':
|
||||
@ -2340,12 +2359,12 @@ router.put("/:id/:action/:value?", async (req, res) => {
|
||||
road.color = session.color;
|
||||
game.turn.actions = [];
|
||||
game.turn.limits = {};
|
||||
addChatMessage(game, session, `${name} placed a road.`);
|
||||
addActivity(game, session, `${name} placed a road.`);
|
||||
calculateRoadLengths(game, session);
|
||||
|
||||
} else if (game.state === 'initial-placement') {
|
||||
road.color = session.color;
|
||||
addChatMessage(game, session, `${name} placed a road.`);
|
||||
addActivity(game, session, `${name} placed a road.`);
|
||||
calculateRoadLengths(game, session);
|
||||
|
||||
let next;
|
||||
@ -2402,7 +2421,7 @@ router.put("/:id/:action/:value?", async (req, res) => {
|
||||
player[type] += receives[type];
|
||||
message.push(`${receives[type]} ${type}`);
|
||||
}
|
||||
addChatMessage(game, session, `${session.name} receives ${message.join(', ')}.`);
|
||||
addActivity(game, session, `${session.name} receives ${message.join(', ')}.`);
|
||||
}
|
||||
}
|
||||
addChatMessage(game, null, `It is ${name}'s turn.`);
|
||||
@ -2491,6 +2510,7 @@ router.put("/:id/:action/:value?", async (req, res) => {
|
||||
|
||||
const ping = (session) => {
|
||||
session.ping = Date.now();
|
||||
console.log(`Sending ping to ${session.name}`);
|
||||
session.ws.send(JSON.stringify({ type: 'ping', ping: session.ping }));
|
||||
if (session.keepAlive) {
|
||||
clearTimeout(session.keepAlive);
|
||||
@ -2783,6 +2803,7 @@ const resetGame = (game) => {
|
||||
},
|
||||
developmentCards: [],
|
||||
chat: [],
|
||||
activities: [],
|
||||
pipOrder: game.pipOrder,
|
||||
borderOrder: game.borderOrder,
|
||||
tileOrder: game.tileOrder,
|
||||
|
Loading…
x
Reference in New Issue
Block a user