1
0

Toggle build works

Signed-off-by: James Ketrenos <james_eikona@ketrenos.com>
This commit is contained in:
James Ketrenos 2022-03-13 04:57:34 -07:00
parent 8fc3f1edcd
commit a2e47fe083
6 changed files with 115 additions and 105 deletions

View File

@ -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 {

View File

@ -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 &&

View File

@ -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;

View File

@ -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(`app - clearing warning`);
setWarning("");
} else {
console.log(`app - a different warning is being displayed`);
}
console.log(`todo: stack warnings in a window and have them disappear one at a time.`);
console.log(`app - clearing warning`);
setWarning("");
}, 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>;

View File

@ -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={{

View File

@ -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);