120 lines
3.8 KiB
JavaScript
120 lines
3.8 KiB
JavaScript
import React, { useState } from "react";
|
|
import "./Activities.css";
|
|
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 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 <></>;
|
|
}
|
|
|
|
const
|
|
game = table.game,
|
|
isTurn = (game.turn && game.turn.color === game.color) ? true : false,
|
|
normalPlay = (game.state === 'initial-placement' || game.state === 'normal'),
|
|
mustPlaceRobber = (game.turn && !game.turn.placedRobber && game.turn.robberInAction),
|
|
placement = (game.state === 'initial-placement' || game.turn.active === 'road-building'),
|
|
placeRoad = placement && game.turn && game.turn.actions && game.turn.actions.indexOf('place-road') !== -1,
|
|
mustStealResource = game.turn && game.turn.actions && game.turn.actions.indexOf('steal-resource') !== -1;
|
|
|
|
let discarders = [], mustDiscard = false;
|
|
for (let color in table.game.players) {
|
|
const player = table.game.players[color];
|
|
if (!player.mustDiscard) {
|
|
continue;
|
|
}
|
|
mustDiscard = true;
|
|
const name = (game.color === color) ? 'You' : getPlayerName(table.game.sessions, color);
|
|
discarders.push(<div key={name} className="Requirement">{name} must discard <b>{player.mustDiscard}</b> cards.</div>);
|
|
}
|
|
|
|
const list = game.activities
|
|
.filter(activity => game.timestamp - activity.date < 11000)
|
|
.map(activity => {
|
|
return <Activity key={activity.date} activity={activity}/>;
|
|
});
|
|
|
|
let who;
|
|
if (isTurn) {
|
|
who = 'You';
|
|
} else {
|
|
who = <><PlayerColor color={table.game.turn.color}/> {table.game.turn.name}</>
|
|
}
|
|
return (
|
|
<div className="Activities">
|
|
{ list }
|
|
{ normalPlay && mustDiscard === 0 && mustPlaceRobber &&
|
|
<div className="Requirement">{who} must move the Robber.</div>
|
|
}
|
|
|
|
{ placement &&
|
|
<div className="Requirement">{who} must place a {placeRoad ? 'road' : 'settlement'}.</div>
|
|
}
|
|
|
|
{ mustStealResource &&
|
|
<div className="Requirement">{who} must select a player to steal from.</div>
|
|
}
|
|
|
|
{ normalPlay && mustDiscard !== 0 && <> { discarders } </> }
|
|
|
|
{ !isTurn && normalPlay &&
|
|
<div>It is <PlayerColor color={table.game.turn.color}/> {table.game.turn.name}'s turn.</div>
|
|
}
|
|
|
|
{ isTurn && normalPlay &&
|
|
<div className="Go"><PlayerColor color={game.turn.color}/> It is your turn.</div>
|
|
}
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default Activities; |