Toggle build works
Signed-off-by: James Ketrenos <james_eikona@ketrenos.com>
This commit is contained in:
parent
8fc3f1edcd
commit
a2e47fe083
@ -5,14 +5,19 @@
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
justify-content: space-evenly;
|
||||
background-color: rgba(16, 16, 16, 0.25);
|
||||
margin: 0.25rem 0.25rem 0.25rem 0;
|
||||
padding: 0.25em;
|
||||
}
|
||||
|
||||
.Actions > div {
|
||||
.Actions .Buttons {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.Actions .Buttons button:last-child {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.Actions .PlayerName {
|
||||
|
@ -7,14 +7,14 @@ import "./Actions.css";
|
||||
import { PlayerName } from './PlayerName.js';
|
||||
import { GlobalContext } from "./GlobalContext.js";
|
||||
|
||||
const Actions = () => {
|
||||
const Actions = ({buildActive, setBuildActive}) => {
|
||||
const { ws, gameId, name } = useContext(GlobalContext);
|
||||
const [state, setState] = useState('lobby');
|
||||
const [color, setColor] = useState(undefined);
|
||||
const [priv, setPriv] = useState(undefined);
|
||||
const [turn, setTurn] = useState({});
|
||||
const [active, setActive] = useState(0);
|
||||
const [edit, setEdit] = useState(name);
|
||||
const [active, setActive] = useState(0);
|
||||
|
||||
const fields = useMemo(() => [
|
||||
'state', 'turn', 'private', 'active', 'color'
|
||||
@ -24,6 +24,7 @@ const Actions = () => {
|
||||
const data = JSON.parse(event.data);
|
||||
switch (data.type) {
|
||||
case 'game-update':
|
||||
console.log(`actions - game update`, data.update);
|
||||
if ('private' in data.update && !equal(data.update.private, priv)) {
|
||||
setPriv(data.update.private);
|
||||
}
|
||||
@ -48,24 +49,17 @@ const Actions = () => {
|
||||
}
|
||||
};
|
||||
const refWsMessage = useRef(onWsMessage);
|
||||
|
||||
useEffect(() => { refWsMessage.current = onWsMessage; });
|
||||
|
||||
useEffect(() => {
|
||||
if (!ws) {
|
||||
return;
|
||||
}
|
||||
if (!ws) { return; }
|
||||
const cbMessage = e => refWsMessage.current(e);
|
||||
ws.addEventListener('message', cbMessage);
|
||||
return () => {
|
||||
ws.removeEventListener('message', cbMessage);
|
||||
}
|
||||
}, [ws, refWsMessage]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!ws) {
|
||||
return;
|
||||
}
|
||||
if (!ws) { return; }
|
||||
ws.send(JSON.stringify({
|
||||
type: 'get',
|
||||
fields
|
||||
@ -75,8 +69,9 @@ const Actions = () => {
|
||||
const sendMessage = (data) => {
|
||||
ws.send(JSON.stringify(data));
|
||||
}
|
||||
const buildClicked = (event) => {
|
||||
alert(`This is a no-op currently; you can click the Build cost card.`);
|
||||
|
||||
const buildClicked = () => {
|
||||
setBuildActive(!buildActive);
|
||||
};
|
||||
|
||||
const setName = (update) => {
|
||||
@ -86,39 +81,39 @@ const Actions = () => {
|
||||
setEdit(name);
|
||||
}
|
||||
|
||||
const changeNameClick = (event) => {
|
||||
const changeNameClick = () => {
|
||||
setEdit("");
|
||||
}
|
||||
|
||||
const discardClick = (event) => {
|
||||
const discardClick = () => {
|
||||
const nodes = document.querySelectorAll('.Hand .Resource.Selected'),
|
||||
discarding = { wheat: 0, brick: 0, sheep: 0, stone: 0, wood: 0 };
|
||||
discards = { wheat: 0, brick: 0, sheep: 0, stone: 0, wood: 0 };
|
||||
|
||||
for (let i = 0; i < nodes.length; i++) {
|
||||
discarding[nodes[i].getAttribute("data-type")]++;
|
||||
discards[nodes[i].getAttribute("data-type")]++;
|
||||
nodes[i].classList.remove('Selected');
|
||||
}
|
||||
|
||||
sendMessage({ type: 'discard', discarding });
|
||||
sendMessage({ type: 'discard', discards });
|
||||
}
|
||||
|
||||
const newTableClick = (event) => {
|
||||
const newTableClick = () => {
|
||||
sendMessage({ type: 'shuffle' });
|
||||
};
|
||||
|
||||
const tradeClick = (event) => {
|
||||
const tradeClick = () => {
|
||||
sendMessage({ type: 'trade' });
|
||||
}
|
||||
|
||||
const rollClick = (event) => {
|
||||
const rollClick = () => {
|
||||
sendMessage({ type: 'roll' });
|
||||
}
|
||||
|
||||
const passClick = (event) => {
|
||||
const passClick = () => {
|
||||
sendMessage({ type: 'pass' });
|
||||
}
|
||||
|
||||
const startClick = (event) => {
|
||||
const startClick = () => {
|
||||
sendMessage({
|
||||
type: 'set',
|
||||
field: 'state',
|
||||
@ -144,7 +139,7 @@ const Actions = () => {
|
||||
return (
|
||||
<Paper className="Actions">
|
||||
{ edit === "" && <PlayerName name={name} setName={setName}/> }
|
||||
<div>
|
||||
<div className="Buttons">
|
||||
{ name && inLobby && <>
|
||||
<Button disabled={(color && active >= 2) ? false : true } onClick={startClick}>Start game</Button>
|
||||
<Button disabled={color ? false : true} onClick={newTableClick}>New table</Button>
|
||||
@ -159,9 +154,7 @@ const Actions = () => {
|
||||
} onClick={rollClick}>Roll Dice</Button>
|
||||
<Button disabled={placeRoad || robberActions || !isTurn || !hasRolled || !haveResources} onClick={tradeClick}>Trade</Button>
|
||||
<Button disabled={placeRoad || robberActions || !isTurn || !hasRolled || !haveResources} onClick={buildClicked}>Build</Button>
|
||||
{ turn && turn.roll === 7 && priv && priv.mustDiscard > 0 &&
|
||||
<Button onClick={discardClick}>Discard</Button>
|
||||
}
|
||||
<Button disabled={!(turn && turn.roll === 7 && priv && priv.mustDiscard > 0)}onClick={discardClick}>Discard</Button>
|
||||
<Button disabled={placeRoad || robberActions || !isTurn || !hasRolled} onClick={passClick}>Done</Button>
|
||||
</> }
|
||||
{ /* inLobby &&
|
||||
|
@ -28,7 +28,7 @@ body {
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
background-color: #80000060;
|
||||
background-color: #40000060;
|
||||
}
|
||||
|
||||
.Table .ErrorDialog .Error {
|
||||
@ -52,6 +52,7 @@ body {
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
background-color: #00000060;
|
||||
}
|
||||
|
||||
.Table .WarningDialog .Warning {
|
||||
@ -75,6 +76,11 @@ body {
|
||||
display: flex;
|
||||
position: relative;
|
||||
flex-grow: 1;
|
||||
z-index: 500;
|
||||
}
|
||||
|
||||
.Table .PlayersStatus {
|
||||
z-index: 750;
|
||||
}
|
||||
|
||||
.Table .Hand {
|
||||
@ -94,12 +100,6 @@ body {
|
||||
z-index: 5000;
|
||||
}
|
||||
|
||||
.Table .Board {
|
||||
display: flex;
|
||||
flex-grow: 1;
|
||||
z-index: 500;
|
||||
}
|
||||
|
||||
.Table .Sidebar .Chat {
|
||||
display: flex;
|
||||
position: relative;
|
||||
|
@ -40,6 +40,7 @@ const Table = () => {
|
||||
const [color, setColor] = useState(undefined);
|
||||
const [players, setPlayers] = useState(undefined);
|
||||
const [player, setPlayer] = useState(undefined);
|
||||
const [buildActive, setBuildActive] = useState(false);
|
||||
const fields = [ 'id', 'state', 'color', 'name' ];
|
||||
|
||||
useEffect(() => {
|
||||
@ -79,12 +80,9 @@ const Table = () => {
|
||||
console.warn(`App - warning`, data.warning);
|
||||
setWarning(data.warning);
|
||||
setTimeout(() => {
|
||||
if (data.warning === warning) {
|
||||
console.log(`todo: stack warnings in a window and have them disappear one at a time.`);
|
||||
console.log(`app - clearing warning`);
|
||||
setWarning("");
|
||||
} else {
|
||||
console.log(`app - a different warning is being displayed`);
|
||||
}
|
||||
}, 3000);
|
||||
break;
|
||||
case 'game-update':
|
||||
@ -300,7 +298,7 @@ const Table = () => {
|
||||
<Board/>
|
||||
<PlayersStatus/>
|
||||
<PlayersStatus active={true}/>
|
||||
<Hand/>
|
||||
<Hand {...{buildActive, setBuildActive}}/>
|
||||
{ /* state === 'winner' &&
|
||||
<Winner color={winner}/>
|
||||
}
|
||||
@ -321,7 +319,7 @@ const Table = () => {
|
||||
<div className="Sidebar">
|
||||
{ name !== "" && <PlayerList/> }
|
||||
{ name !== "" && <Chat/> }
|
||||
{ loaded && <Actions/> }
|
||||
{ loaded && <Actions {...{buildActive, setBuildActive}}/> }
|
||||
</div>
|
||||
</div>
|
||||
</GlobalContext.Provider>;
|
||||
|
@ -5,40 +5,39 @@ import { GlobalContext } from "./GlobalContext.js";
|
||||
|
||||
import "./Placard.css";
|
||||
|
||||
const Placard = ({type, disabled, count}) => {
|
||||
const Placard = ({type, disabled, count, buildActive, setBuildActive}) => {
|
||||
const { ws } = useContext(GlobalContext);
|
||||
const [active, setActive] = useState(false);
|
||||
|
||||
const dismissClicked = () => {
|
||||
setActive(false);
|
||||
setBuildActive(false);
|
||||
}
|
||||
|
||||
const buildClicked = () => {
|
||||
if (!type.match(/^l.*/)) { /* longest / largest ... */
|
||||
if (!active) {
|
||||
setActive(true);
|
||||
if (!buildActive) {
|
||||
setBuildActive(true);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const roadClicked = () => {
|
||||
ws.send(JSON.stringify({ type: 'buy-road'}));
|
||||
setActive(false);
|
||||
setBuildActive(false);
|
||||
};
|
||||
|
||||
const settlementClicked = () => {
|
||||
ws.send(JSON.stringify({ type: 'buy-settlement'}));
|
||||
setActive(false);
|
||||
setBuildActive(false);
|
||||
};
|
||||
|
||||
const cityClicked = () => {
|
||||
ws.send(JSON.stringify({ type: 'buy-city'}));
|
||||
setActive(false);
|
||||
setBuildActive(false);
|
||||
};
|
||||
|
||||
const developmentClicked = () => {
|
||||
ws.send(JSON.stringify({ type: 'buy-development'}));
|
||||
setActive(false);
|
||||
setBuildActive(false);
|
||||
};
|
||||
|
||||
if (type === 'B') { type = 'blue'; }
|
||||
@ -47,7 +46,7 @@ const Placard = ({type, disabled, count}) => {
|
||||
else if (type === 'W') { type = 'white'; }
|
||||
|
||||
let buttons;
|
||||
if (!disabled && active) {
|
||||
if (!disabled && buildActive) {
|
||||
switch (type) {
|
||||
case 'orange':
|
||||
case 'red':
|
||||
@ -69,7 +68,7 @@ const Placard = ({type, disabled, count}) => {
|
||||
}
|
||||
|
||||
if (!disabled) {
|
||||
return <div className={`Placard${active ? ' Selected' : ''}`}
|
||||
return <div className={`Placard${buildActive ? ' Selected' : ''}`}
|
||||
onClick={buildClicked}
|
||||
disabled={disabled}
|
||||
data-type={type}
|
||||
@ -78,7 +77,7 @@ const Placard = ({type, disabled, count}) => {
|
||||
}}
|
||||
>{buttons}</div>
|
||||
} else {
|
||||
return <div className={`Placard${active ? ' Selected' : ''}`}
|
||||
return <div className={`Placard${buildActive ? ' Selected' : ''}`}
|
||||
disabled={disabled}
|
||||
data-type={type}
|
||||
style={{
|
||||
|
@ -2458,6 +2458,63 @@ const placeRoad = (game, session, index) => {
|
||||
});
|
||||
}
|
||||
|
||||
const discard = (game, session, discards) => {
|
||||
const player = session.player;
|
||||
|
||||
if (game.turn.roll !== 7) {
|
||||
return `You can only discard due to the Robber!`;
|
||||
}
|
||||
let sum = 0;
|
||||
for (let type in discards) {
|
||||
if (player[type] < parseInt(discards[type])) {
|
||||
return `You have requested to discard more ${type} than you have.`
|
||||
}
|
||||
sum += parseInt(discards[type]);
|
||||
}
|
||||
if (sum !== player.mustDiscard) {
|
||||
return `You need to discard ${player.mustDiscard} cards.`;
|
||||
}
|
||||
|
||||
for (let type in discards) {
|
||||
const count = parseInt(discards[type]);
|
||||
player[type] -= count;
|
||||
player.mustDiscard -= count;
|
||||
player.resources -= count;
|
||||
}
|
||||
addChatMessage(game, null, `${session.name} discarded ${sum} resource cards.`);
|
||||
if (player.mustDiscard) {
|
||||
addChatMessage(game, null, `${session.name} did not discard enough and must discard ${player.mustDiscard} more cards.`);
|
||||
}
|
||||
|
||||
let move = true;
|
||||
for (let color in game.players) {
|
||||
const discard = game.players[color].mustDiscard;
|
||||
if (discard) {
|
||||
move = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (move) {
|
||||
addChatMessage(game, null, `Drat! 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++) {
|
||||
if (i === game.robber) {
|
||||
continue;
|
||||
}
|
||||
game.turn.limits.pips.push(i);
|
||||
}
|
||||
}
|
||||
sendUpdateToPlayer(session, {
|
||||
private: player
|
||||
});
|
||||
sendUpdateToPlayers(game, {
|
||||
players: game.players,
|
||||
chat: game.chat,
|
||||
turn: game.turn
|
||||
});
|
||||
}
|
||||
|
||||
const asdf = () => {
|
||||
const game = 0, session = 0;
|
||||
switch (game) {
|
||||
@ -2732,55 +2789,6 @@ const asdf = () => {
|
||||
|
||||
break;
|
||||
|
||||
case 'discard':
|
||||
if (game.turn.roll !== 7) {
|
||||
error = `You can only discard due to the Robber!`;
|
||||
break;
|
||||
}
|
||||
const discards = req.body;
|
||||
let sum = 0;
|
||||
for (let type in discards) {
|
||||
if (player[type] < parseInt(discards[type])) {
|
||||
error = `You have requested to discard more ${type} than you have.`
|
||||
break;
|
||||
}
|
||||
sum += parseInt(discards[type]);
|
||||
}
|
||||
if (sum > player.mustDiscard) {
|
||||
error = `You have requested to discard more cards than you are allowed!`;
|
||||
break;
|
||||
}
|
||||
for (let type in discards) {
|
||||
const count = parseInt(discards[type]);
|
||||
player[type] -= count;
|
||||
player.mustDiscard -= count;
|
||||
player.resources -= count;
|
||||
}
|
||||
addChatMessage(game, null, `${session.name} discarded ${sum} resource cards.`);
|
||||
if (player.mustDiscard) {
|
||||
addChatMessage(game, null, `${session.name} did not discard enough and must discard ${player.mustDiscard} more cards.`);
|
||||
break;
|
||||
}
|
||||
|
||||
let move = true;
|
||||
for (let color in game.players) {
|
||||
const discard = game.players[color].mustDiscard;
|
||||
if (discard) {
|
||||
move = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (move) {
|
||||
addChatMessage(game, null, `Drat! 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++) {
|
||||
if (i === game.robber) {
|
||||
continue;
|
||||
}
|
||||
game.turn.limits.pips.push(i);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
};
|
||||
@ -3411,6 +3419,13 @@ const wsConnect = async (ws, req) => {
|
||||
sendWarning(session, warning);
|
||||
}
|
||||
break;
|
||||
case 'discard':
|
||||
console.log(`${short}: <- discard:${getName(session)}`);
|
||||
warning = discard(game, session, data.discards);
|
||||
if (warning) {
|
||||
sendWarning(session, warning);
|
||||
}
|
||||
break;
|
||||
case 'pass':
|
||||
console.log(`${short}: <- pass:${getName(session)}`);
|
||||
warning = pass(game, session);
|
||||
|
Loading…
x
Reference in New Issue
Block a user