1
0

Volcano mode working; resource allocation not enabled yet

Signed-off-by: James Ketrenos <james_eikona@ketrenos.com>
This commit is contained in:
James Ketrenos 2022-05-29 15:34:12 -07:00
parent 3034520aae
commit af83538027
7 changed files with 135 additions and 18 deletions

View File

@ -160,14 +160,17 @@ const Actions = ({
isTurn = (turn && turn.color === color) ? true : false, isTurn = (turn && turn.color === color) ? true : false,
robberActions = (turn && turn.robberInAction), robberActions = (turn && turn.robberInAction),
haveResources = priv ? priv.resources !== 0 : false, haveResources = priv ? priv.resources !== 0 : false,
volcanoActive = state === 'volcano',
placement = (state === 'initial-placement' || (turn && turn.active === 'road-building')), placement = (state === 'initial-placement' || (turn && turn.active === 'road-building')),
placeRoad = placement && turn && turn.actions && placeRoad = placement && turn && turn.actions &&
(turn.actions.indexOf('place-road') !== -1 (turn.actions.indexOf('place-road') !== -1
|| turn.actions.indexOf('place-city') !== -1 || turn.actions.indexOf('place-city') !== -1
|| turn.actions.indexOf('place-settlement') !== -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); 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); setTradeActive(true);
} }
@ -189,14 +192,17 @@ const Actions = ({
robberActions || robberActions ||
(inGame && (!isTurn || hasRolled)) || (inGame && (!isTurn || hasRolled)) ||
(inGameOrder && hasGameOrderRolled) || (inGameOrder && hasGameOrderRolled) ||
(!inGame && !inGameOrder) (!inGame && !inGameOrder && (!isTurn || !volcanoActive))
} onClick={rollClick}>Roll Dice</Button> } 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> <Button disabled={volcanoActive || placeRoad || robberActions || !isTurn || !hasRolled || !haveResources} onClick={tradeClick}>Trade</Button>
<Button disabled={volcanoActive || placeRoad || robberActions || !isTurn || !hasRolled || !haveResources} onClick={buildClicked}>Build</Button>
<Button disabled={!(turn && turn.roll === 7 && priv && priv.mustDiscard > 0)}onClick={discardClick}>Discard</Button> <Button disabled={!(turn && turn.roll === 7 && priv && priv.mustDiscard > 0)}onClick={discardClick}>Discard</Button>
{name && color && <Button disabled={color ? false : true} {name && color && <Button disabled={color ? false : true}
onClick={houseRulesClick}>House Rules</Button>} onClick={houseRulesClick}>House Rules</Button>}
<Button disabled={placeRoad || robberActions || !isTurn || !hasRolled} onClick={passClick}>Done</Button> <Button disabled={volcanoActive || placeRoad || robberActions || !isTurn || !hasRolled} onClick={passClick}>Done</Button>
</> } </> }
{ /* inLobby && { /* inLobby &&
<Button onClick={quitClick}>Quit</Button> <Button onClick={quitClick}>Quit</Button>

View File

@ -135,11 +135,12 @@ const Activities = () => {
const const
isTurn = (turn && turn.color === color) ? true : false, 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), mustPlaceRobber = (turn && !turn.placedRobber && turn.robberInAction),
placement = (state === 'initial-placement' || (turn && turn.active === 'road-building')), placement = (state === 'initial-placement' || (turn && turn.active === 'road-building')),
placeRoad = placement && turn && turn.actions && turn.actions.indexOf('place-road') !== -1, placeRoad = placement && turn && turn.actions && turn.actions.indexOf('place-road') !== -1,
mustStealResource = turn && turn.actions && turn.actions.indexOf('steal-resource') !== -1, mustStealResource = turn && turn.actions && turn.actions.indexOf('steal-resource') !== -1,
rollForVolcano = (isTurn && state === 'volcano'),
rollForOrder = (state === 'game-order'); rollForOrder = (state === 'game-order');
console.log(`activities - `, state, turn, activities); console.log(`activities - `, state, turn, activities);
let discarders = [], mustDiscard = false; let discarders = [], mustDiscard = false;
@ -189,6 +190,10 @@ console.log(`activities - `, state, turn, activities);
<div className="Requirement">{who} must roll for game order.</div> <div className="Requirement">{who} must roll for game order.</div>
} }
{rollForVolcano &&
<div className="Requirement">{who} must roll for Volcano devastation!</div>
}
{ normalPlay && mustDiscard && <> { discarders } </> } { normalPlay && mustDiscard && <> { discarders } </> }
{ !isTurn && normalPlay && turn && { !isTurn && normalPlay && turn &&

View File

@ -192,3 +192,22 @@ body {
opacity: 0.5; opacity: 0.5;
border: 1px solid #ccc; /* why !important */ 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;
}

View File

@ -26,6 +26,7 @@ import { Hand } from "./Hand.js";
import { Trade } from "./Trade.js"; import { Trade } from "./Trade.js";
import { Winner } from "./Winner.js"; import { Winner } from "./Winner.js";
import { HouseRules } from "./HouseRules.js"; import { HouseRules } from "./HouseRules.js";
import { Dice } from "./Dice.js";
import history from "./history.js"; import history from "./history.js";
import "./App.css"; import "./App.css";
@ -42,6 +43,7 @@ const Table = () => {
const [ warning, setWarning ] = useState(undefined); const [ warning, setWarning ] = useState(undefined);
const [loaded, setLoaded] = useState(false); const [loaded, setLoaded] = useState(false);
const [dice, setDice] = useState(undefined);
const [state, setState] = useState(undefined); const [state, setState] = useState(undefined);
const [color, setColor] = useState(undefined); const [color, setColor] = useState(undefined);
const [priv, setPriv] = useState(undefined); const [priv, setPriv] = useState(undefined);
@ -52,7 +54,7 @@ const Table = () => {
const [winnerDismissed, setWinnerDismissed] = useState(undefined); const [winnerDismissed, setWinnerDismissed] = useState(undefined);
const [global, setGlobal] = useState({}); const [global, setGlobal] = useState({});
const [count, setCount] = useState(0); const [count, setCount] = useState(0);
const fields = [ 'id', 'state', 'color', 'name', 'private' ]; const fields = [ 'id', 'state', 'color', 'name', 'private', 'dice' ];
const onWsOpen = (event) => { const onWsOpen = (event) => {
console.log(`ws: open`); console.log(`ws: open`);
@ -132,6 +134,9 @@ const Table = () => {
} }
setState(data.update.state); 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) { if ('color' in data.update && data.update.color !== color) {
console.log(`App - setting color: ${color}`); console.log(`App - setting color: ${color}`);
setColor(data.update.color); setColor(data.update.color);
@ -318,7 +323,9 @@ const Table = () => {
{ /* <PingPong/> */ } { /* <PingPong/> */ }
<div className="Table"> <div className="Table">
<Activities/> <Activities/>
{ dice && dice.length && <div className="DiceRoll">
<Dice pips={dice[0]} /> <Dice pips={dice[1]} />
</div> }
<div className="Game"> <div className="Game">
<div className="Dialogs"> <div className="Dialogs">
{ error && <div className="Dialog ErrorDialog"> { error && <div className="Dialog ErrorDialog">
@ -327,6 +334,7 @@ const Table = () => {
<Button onClick={() => { setError("")}}>dismiss</Button> <Button onClick={() => { setError("")}}>dismiss</Button>
</Paper> </Paper>
</div> } </div> }
{ priv && priv.turnNotice && <div className="Dialog TurnNoticeDialog"> { priv && priv.turnNotice && <div className="Dialog TurnNoticeDialog">
<Paper className="TurnNotice"> <Paper className="TurnNotice">
<div>{ priv.turnNotice }</div> <div>{ priv.turnNotice }</div>
@ -341,6 +349,7 @@ const Table = () => {
</div> } </div> }
{ state === 'normal' && <SelectPlayer/> } { state === 'normal' && <SelectPlayer/> }
{ color && state === 'game-order' && <GameOrder/> } { color && state === 'game-order' && <GameOrder/> }
{ !winnerDismissed && <Winner {...{winnerDismissed, setWinnerDismissed}}/> } { !winnerDismissed && <Winner {...{winnerDismissed, setWinnerDismissed}}/> }
{ houseRulesActive && <HouseRules {...{houseRulesActive, setHouseRulesActive}}/> } { houseRulesActive && <HouseRules {...{houseRulesActive, setHouseRulesActive}}/> }
<ViewCard {...{cardActive, setCardActive }}/> <ViewCard {...{cardActive, setCardActive }}/>

View File

@ -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%); 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 { .Board .Road {
position: absolute; position: absolute;
display: flex; display: flex;

View File

@ -618,6 +618,11 @@ const Board = () => {
placements.corners.forEach((corner, index) => { placements.corners.forEach((corner, index) => {
const el = document.querySelector(`.Corner[data-index="${index}"]`); const el = document.querySelector(`.Corner[data-index="${index}"]`);
if (!el) { return; } if (!el) { return; }
if (turn.volcano === index) {
el.classList.add('Lava');
} else {
el.classList.remove('Lava');
}
if (!corner.color) { if (!corner.color) {
el.removeAttribute('data-color'); el.removeAttribute('data-color');
el.removeAttribute('data-type'); el.removeAttribute('data-type');

View File

@ -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 roll = (game, session, dice) => {
const player = session.player, const player = session.player,
name = session.name ? session.name : "Unnamed"; name = session.name ? session.name : "Unnamed";
@ -248,15 +292,11 @@ const roll = (game, session, dice) => {
sendUpdateToPlayers(game, { chat: game.chat }); sendUpdateToPlayers(game, { chat: game.chat });
return; return;
case 'volcano-resource': case 'volcano':
if (game.turn.color !== session.color) { if (game.turn.color !== session.color) {
return `It is not your turn.`; return `It is not your turn.`;
} }
if (game.turn.volcano) {
return `You already rolled for the Volcano!`;
}
processVolcano(game, session, dice); processVolcano(game, session, dice);
sendUpdateToPlayers(game, { chat: game.chat });
return; return;
default: default:
@ -376,9 +416,18 @@ const isRuleEnabled = (game, rule) => {
}; };
const processRoll = (game, session, dice) => { const processRoll = (game, session, dice) => {
addChatMessage(game, session, `${session.name} rolled ${dice[0]}, ${dice[1]}.`); addChatMessage(game, session, `${session.name} rolled ` +
game.turn.roll = dice[0] + dice[1]; `${dice[0]}, ${dice[1]}.`);
const sum = dice[0] + dice[1];
game.turn.roll = sum;
game.dice = dice;
if (game.turn.roll !== 7) { if (game.turn.roll !== 7) {
let synonym = isRuleEnabled(game, 'twelve-and-two-are-synonyms')
&& (sum === 2 || sum === 12);
distributeResources(game, game.turn.roll); distributeResources(game, game.turn.roll);
if (isRuleEnabled(game, 'twelve-and-two-are-synonyms')) { 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 (isRuleEnabled(game, 'roll-double-roll-again')) {
if (dice[0] === dice[1]) { if (dice[0] === dice[1]) {
addChatMessage(game, session, `House rule 'Roll Double, Roll addChatMessage(game, session, `House rule 'Roll Double, Roll
@ -413,7 +474,8 @@ const processRoll = (game, session, dice) => {
sendUpdateToPlayers(game, { sendUpdateToPlayers(game, {
turn: game.turn, turn: game.turn,
players: getFilteredPlayers(game), players: getFilteredPlayers(game),
chat: game.chat chat: game.chat,
dice: game.dice
}); });
return; return;
} }
@ -466,7 +528,8 @@ const processRoll = (game, session, dice) => {
sendUpdateToPlayers(game, { sendUpdateToPlayers(game, {
turn: game.turn, turn: game.turn,
players: getFilteredPlayers(game), 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.`; 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); const next = getNextPlayerSession(game, session.name);
session.player.totalTime += Date.now() - session.player.turnStart; session.player.totalTime += Date.now() - session.player.turnStart;
session.player.turnNotice = ""; session.player.turnNotice = "";