diff --git a/client/src/Actions.css b/client/src/Actions.css index b4014da..50928e9 100644 --- a/client/src/Actions.css +++ b/client/src/Actions.css @@ -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 { diff --git a/client/src/Actions.js b/client/src/Actions.js index df99fe8..8b3f4dc 100644 --- a/client/src/Actions.js +++ b/client/src/Actions.js @@ -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 ( { edit === "" && } -
+
{ name && inLobby && <> @@ -159,9 +154,7 @@ const Actions = () => { } onClick={rollClick}>Roll Dice - { turn && turn.roll === 7 && priv && priv.mustDiscard > 0 && - - } + } { /* inLobby && diff --git a/client/src/App.css b/client/src/App.css index a6cab83..b2f9649 100755 --- a/client/src/App.css +++ b/client/src/App.css @@ -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; diff --git a/client/src/App.js b/client/src/App.js index 3e83b31..b48cec6 100755 --- a/client/src/App.js +++ b/client/src/App.js @@ -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 = () => { - + { /* state === 'winner' && } @@ -321,7 +319,7 @@ const Table = () => {
{ name !== "" && } { name !== "" && } - { loaded && } + { loaded && }
; diff --git a/client/src/Placard.js b/client/src/Placard.js index e2e26bb..8b6c36e 100644 --- a/client/src/Placard.js +++ b/client/src/Placard.js @@ -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
{ }} >{buttons}
} else { - return
{ }); } +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);