From af835380275971eccc52702be111c420b65650ab Mon Sep 17 00:00:00 2001 From: James Ketrenos Date: Sun, 29 May 2022 15:34:12 -0700 Subject: [PATCH] Volcano mode working; resource allocation not enabled yet Signed-off-by: James Ketrenos --- client/src/Actions.js | 18 ++++++--- client/src/Activities.js | 7 +++- client/src/App.css | 19 +++++++++ client/src/App.js | 13 +++++- client/src/Board.css | 6 +++ client/src/Board.js | 5 +++ server/routes/games.js | 85 +++++++++++++++++++++++++++++++++++----- 7 files changed, 135 insertions(+), 18 deletions(-) diff --git a/client/src/Actions.js b/client/src/Actions.js index d86cad0..4ee430d 100644 --- a/client/src/Actions.js +++ b/client/src/Actions.js @@ -160,14 +160,17 @@ const Actions = ({ isTurn = (turn && turn.color === color) ? true : false, robberActions = (turn && turn.robberInAction), haveResources = priv ? priv.resources !== 0 : false, + volcanoActive = state === 'volcano', placement = (state === 'initial-placement' || (turn && turn.active === 'road-building')), placeRoad = placement && turn && turn.actions && (turn.actions.indexOf('place-road') !== -1 || turn.actions.indexOf('place-city') !== -1 || turn.actions.indexOf('place-settlement') !== -1); - if (tradeActive && (!turn || !turn.actions || turn.actions.indexOf('trade'))) { + if (tradeActive + && (!turn || !turn.actions || turn.actions.indexOf('trade'))) { setTradeActive(false); - } else if (!tradeActive && turn && turn.actions && turn.actions.indexOf('trade') !== -1) { + } else if (!tradeActive + && turn && turn.actions && turn.actions.indexOf('trade') !== -1) { setTradeActive(true); } @@ -189,14 +192,17 @@ const Actions = ({ robberActions || (inGame && (!isTurn || hasRolled)) || (inGameOrder && hasGameOrderRolled) || - (!inGame && !inGameOrder) + (!inGame && !inGameOrder && (!isTurn || !volcanoActive)) } onClick={rollClick}>Roll Dice - - + + + + + {name && color && } - + } { /* inLobby && diff --git a/client/src/Activities.js b/client/src/Activities.js index 42f4518..21cc54c 100644 --- a/client/src/Activities.js +++ b/client/src/Activities.js @@ -135,11 +135,12 @@ const Activities = () => { const isTurn = (turn && turn.color === color) ? true : false, - normalPlay = (state === 'initial-placement' || state === 'normal'), + normalPlay = ([ 'initial-placement', 'normal', 'volcano' ].indexOf(state) !== -1), mustPlaceRobber = (turn && !turn.placedRobber && turn.robberInAction), placement = (state === 'initial-placement' || (turn && turn.active === 'road-building')), placeRoad = placement && turn && turn.actions && turn.actions.indexOf('place-road') !== -1, mustStealResource = turn && turn.actions && turn.actions.indexOf('steal-resource') !== -1, + rollForVolcano = (isTurn && state === 'volcano'), rollForOrder = (state === 'game-order'); console.log(`activities - `, state, turn, activities); let discarders = [], mustDiscard = false; @@ -189,6 +190,10 @@ console.log(`activities - `, state, turn, activities);
{who} must roll for game order.
} + {rollForVolcano && +
{who} must roll for Volcano devastation!
+ } + { normalPlay && mustDiscard && <> { discarders } } { !isTurn && normalPlay && turn && diff --git a/client/src/App.css b/client/src/App.css index fe6b011..f3be2d4 100755 --- a/client/src/App.css +++ b/client/src/App.css @@ -191,4 +191,23 @@ body { .Table button:disabled { opacity: 0.5; border: 1px solid #ccc; /* why !important */ +} + +.Table .DiceRoll { + display: flex; + flex-direction: row; + position: absolute; + left: calc(35vw - 5rem); + top: 1em; + flex-wrap: wrap; + justify-content: left; + align-items: left; + z-index: 1000; +} + +.Table .DiceRoll .Dice { + margin: 0.25rem; + width: 1.75rem; + height: 1.75rem; + border-radius: 0.25rem; } \ No newline at end of file diff --git a/client/src/App.js b/client/src/App.js index 14f80a1..260d76c 100755 --- a/client/src/App.js +++ b/client/src/App.js @@ -26,6 +26,7 @@ import { Hand } from "./Hand.js"; import { Trade } from "./Trade.js"; import { Winner } from "./Winner.js"; import { HouseRules } from "./HouseRules.js"; +import { Dice } from "./Dice.js"; import history from "./history.js"; import "./App.css"; @@ -42,6 +43,7 @@ const Table = () => { const [ warning, setWarning ] = useState(undefined); const [loaded, setLoaded] = useState(false); + const [dice, setDice] = useState(undefined); const [state, setState] = useState(undefined); const [color, setColor] = useState(undefined); const [priv, setPriv] = useState(undefined); @@ -52,7 +54,7 @@ const Table = () => { const [winnerDismissed, setWinnerDismissed] = useState(undefined); const [global, setGlobal] = useState({}); const [count, setCount] = useState(0); - const fields = [ 'id', 'state', 'color', 'name', 'private' ]; + const fields = [ 'id', 'state', 'color', 'name', 'private', 'dice' ]; const onWsOpen = (event) => { console.log(`ws: open`); @@ -132,6 +134,9 @@ const Table = () => { } setState(data.update.state); } + if ('dice' in data.update && !equal(data.update.dice, dice)) { + setDice(data.update.dice); + } if ('color' in data.update && data.update.color !== color) { console.log(`App - setting color: ${color}`); setColor(data.update.color); @@ -318,7 +323,9 @@ const Table = () => { { /* */ }
- + { dice && dice.length &&
+ +
}
{ error &&
@@ -327,6 +334,7 @@ const Table = () => {
} + { priv && priv.turnNotice &&
{ priv.turnNotice }
@@ -341,6 +349,7 @@ const Table = () => {
} { state === 'normal' && } { color && state === 'game-order' && } + { !winnerDismissed && } { houseRulesActive && } diff --git a/client/src/Board.css b/client/src/Board.css index 5fc3a52..e54bf80 100644 --- a/client/src/Board.css +++ b/client/src/Board.css @@ -102,6 +102,12 @@ clip-path: polygon(15% 0%,39% 23%,39% 52%,100% 56%,100% 74%,100% 100%,80% 100%,63% 100%,62% 75%,46% 75%,47% 100%,0% 100%,0% 24%); } +.Corner.Lava { + border-radius: 50%; + transform: translate(-50%, -50%) scale(1.5); + background-color: rgba(255, 77, 30, 0.8); +} + .Board .Road { position: absolute; display: flex; diff --git a/client/src/Board.js b/client/src/Board.js index 613b5f9..0a01813 100644 --- a/client/src/Board.js +++ b/client/src/Board.js @@ -618,6 +618,11 @@ const Board = () => { placements.corners.forEach((corner, index) => { const el = document.querySelector(`.Corner[data-index="${index}"]`); if (!el) { return; } + if (turn.volcano === index) { + el.classList.add('Lava'); + } else { + el.classList.remove('Lava'); + } if (!corner.color) { el.removeAttribute('data-color'); el.removeAttribute('data-type'); diff --git a/server/routes/games.js b/server/routes/games.js index 5a2f12d..a5db6bb 100755 --- a/server/routes/games.js +++ b/server/routes/games.js @@ -218,6 +218,50 @@ const processGameOrder = (game, player, dice) => { }); } +const processVolcano = (game, session, dice) => { + const player = session.player, + name = session.name ? session.name : "Unnamed"; + + const volcano = layout.tiles.findIndex((tile, index) => + staticData.tiles[game.tileOrder[index]].type === 'desert'); + + /* Find the volcano tile */ + console.log(`${info}: Processing volcano roll!`); + addChatMessage(game, session, `${name} rolled ${dice[0]} for the Volcano!`); + + game.state = 'normal'; + game.turn.volcano = layout.tiles[volcano].corners[dice[0] % 6]; + const corner = game.placements.corners[game.turn.volcano]; + if (corner.color) { + const player = game.players[corner.color]; + if (corner.type === 'city') { + if (player.settlements) { + addChatMessage(game, null, `${player.name}'s city was wiped back to just a settlement!`); + player.cities++; + player.settlements--; + corner.type = 'settlement'; + } else { + addChatMessage(game, null, `${player.name}'s city was wiped out, and they have no settlements to replace it!`); + delete corner.type; + delete corner.color; + player.cities++; + } + } else { + addChatMessage(game, null, `${player.name}'s settlement was wiped out!`); + delete corner.type; + delete corner.color; + player.settlements++; + } + } + + sendUpdateToPlayers(game, { + turn: game.turn, + state: game.state, + chat: game.chat, + placements: game.placements + }); +} + const roll = (game, session, dice) => { const player = session.player, name = session.name ? session.name : "Unnamed"; @@ -248,15 +292,11 @@ const roll = (game, session, dice) => { sendUpdateToPlayers(game, { chat: game.chat }); return; - case 'volcano-resource': + case 'volcano': if (game.turn.color !== session.color) { return `It is not your turn.`; } - if (game.turn.volcano) { - return `You already rolled for the Volcano!`; - } processVolcano(game, session, dice); - sendUpdateToPlayers(game, { chat: game.chat }); return; default: @@ -376,9 +416,18 @@ const isRuleEnabled = (game, rule) => { }; const processRoll = (game, session, dice) => { - addChatMessage(game, session, `${session.name} rolled ${dice[0]}, ${dice[1]}.`); - game.turn.roll = dice[0] + dice[1]; + addChatMessage(game, session, `${session.name} rolled ` + + `${dice[0]}, ${dice[1]}.`); + + const sum = dice[0] + dice[1]; + + game.turn.roll = sum; + game.dice = dice; + if (game.turn.roll !== 7) { + let synonym = isRuleEnabled(game, 'twelve-and-two-are-synonyms') + && (sum === 2 || sum === 12); + distributeResources(game, game.turn.roll); if (isRuleEnabled(game, 'twelve-and-two-are-synonyms')) { @@ -394,6 +443,18 @@ const processRoll = (game, session, dice) => { } } + if (isRuleEnabled(game, 'volcano')) { + if (sum === game.rules['volcano'].number + || (synonym + && (game.rules['volcano'].number === 2 + || game.rules['volcano'].number === 12))) { + addChatMessage(game, session, `House rule 'Volcano' activated. The + Volcano is erupting! You must roll the die to determine which + direciton the lava will flow!`); + game.state = 'volcano'; + } + } + if (isRuleEnabled(game, 'roll-double-roll-again')) { if (dice[0] === dice[1]) { addChatMessage(game, session, `House rule 'Roll Double, Roll @@ -413,7 +474,8 @@ const processRoll = (game, session, dice) => { sendUpdateToPlayers(game, { turn: game.turn, players: getFilteredPlayers(game), - chat: game.chat + chat: game.chat, + dice: game.dice }); return; } @@ -466,7 +528,8 @@ const processRoll = (game, session, dice) => { sendUpdateToPlayers(game, { turn: game.turn, players: getFilteredPlayers(game), - chat: game.chat + chat: game.chat, + dice: game.dice }); } @@ -2004,6 +2067,10 @@ const pass = (game, session) => { return `Robber is in action. Turn can not stop until all Robber tasks are resolved.`; } + if (game.state === 'volcano') { + return `You cannot not stop turn until you have finished the Volcano tasks.`; + } + const next = getNextPlayerSession(game, session.name); session.player.totalTime += Date.now() - session.player.turnStart; session.player.turnNotice = "";