diff --git a/client/src/Board.css b/client/src/Board.css index f8b5ebe..7b0f36c 100644 --- a/client/src/Board.css +++ b/client/src/Board.css @@ -33,8 +33,11 @@ background-size: 600% auto; /* pip-numbers is a 6x6 grid of pip images */ width: 2em; height: 2em; - transform: translate(-50%, -50%); - clip-path: circle(48%); + transform: translate(-50%, -50%); +} + +.Pip.Active { + filter: drop-shadow(2.5px 2.5px 1.5px rgba(0, 0, 0, 0.75)); } .Roads[disabled], @@ -97,6 +100,16 @@ clip-path: polygon(0% 20%,0% 80%,100% 80%,100% 20%); } +.Pip-Shape { + display: flex; + position: absolute; + left: 0px; + right: 0px; + top: 0px; + bottom: 0px; + clip-path: circle(50%); +} + .Option { pointer-events: all; diff --git a/client/src/Board.js b/client/src/Board.js index 4c72143..1b261cc 100644 --- a/client/src/Board.js +++ b/client/src/Board.js @@ -48,7 +48,7 @@ const Board = ({ table, game }) => { backgroundImage: `url(${assetsPath}/gfx/tiles-${tile.type}.png)`, backgroundPositionY: `-${tile.card*tileHeight}px` }} - >; + />; }; const Road = ({road}) => { @@ -232,7 +232,7 @@ const Board = ({ table, game }) => { return game.pipOrder.map(order => { const pip = game.pips[order]; const div =
{ backgroundPositionX: `${ 100. * (order % 6) / 5.}%`, backgroundPositionY: `${ 100 * Math.floor(order / 6) / 5. }%` }} - />; + >
; if (++rowCount === rows[row]) { row++; @@ -351,6 +351,17 @@ const Board = ({ table, game }) => { } } + if (game && game.turn.roll) { + let nodes = document.querySelectorAll('.Pip.Active'); + for (let i = 0; i < nodes.length; i++) { + nodes[i].classList.remove('Active'); + } + nodes = document.querySelectorAll(`.Pip[data-roll="${game.turn.roll}"]`); + for (let i = 0; i < nodes.length; i++) { + nodes[i].classList.add('Active'); + } + } + if (game && game.placements) { /* Set color and type based on placement data from the server */ game.placements.corners.forEach((corner, index) => { diff --git a/client/src/Table.js b/client/src/Table.js index aad8aab..2d70f38 100755 --- a/client/src/Table.js +++ b/client/src/Table.js @@ -362,9 +362,11 @@ const Action = ({ table }) => { } - { table.game.state === 'active' && <> - - + { table.game.state === 'normal' && <> + + + + } { !inLobby && diff --git a/server/routes/games.js b/server/routes/games.js index 5a81488..5b682a7 100755 --- a/server/routes/games.js +++ b/server/routes/games.js @@ -59,7 +59,6 @@ const assetData = { { type: "brick", card: 2 } ], pips: [ - { roll: 7, pips: 0 }, { roll: 5, pips: 4 }, { roll: 2, pips: 1 }, { roll: 6, pips: 5 }, @@ -77,7 +76,8 @@ const assetData = { { roll: 5, pips: 4 }, { roll: 6, pips: 6 }, { roll: 3, pips: 2 }, - { roll: 11, pips: 2 } + { roll: 11, pips: 2 }, + { roll: 7, pips: 0 }, /* Robber is at the end or indexing gets off */ ], borders: [ { left: "sheep", right: "bank" }, @@ -253,8 +253,22 @@ const roll = (game, session) => { break; case "normal": + if (game.turn.color !== session.color) { + error = `It is not your turn.`; + break; + } + if (game.turn.roll) { + error = `You already rolled this turn.`; + break; + } game.dice = [ Math.ceil(Math.random() * 6), Math.ceil(Math.random() * 6) ]; - message = `${name} rolled ${game.dice[0]}, ${game.dice[1]}.`; + addChatMessage(game, session, `${name} rolled ${game.dice[0]}, ${game.dice[1]}.`); + game.turn.roll = game.dice[0] + game.dice[1]; + if (game.turn.roll === 7) { + addChatMessage(game, null, `ROBBER! ROBBER! ROBBER!`); + } else { + distributeResources(game, game.turn.roll); + } break; default: @@ -268,6 +282,54 @@ const roll = (game, session) => { return error; }; +const distributeResources = (game, roll) => { + console.log(`Roll: ${roll}`); + /* Find which tiles have this roll */ + let tiles = []; + for (let i = 0; i < game.pipOrder.length; i++) { + let index = game.pipOrder[i]; + if (assetData.pips[index].roll === roll) { + tiles.push(i); + } + } + + console.log(`Matched tiles: ${tiles.join(',')}.`); + + const receives = { + "O": { wood: 0, brick: 0, sheep: 0, wheat: 0 }, + "R": { wood: 0, brick: 0, sheep: 0, wheat: 0 }, + "W": { wood: 0, brick: 0, sheep: 0, wheat: 0 }, + "B": { wood: 0, brick: 0, sheep: 0, wheat: 0 }, + }; + + /* Find which corners are on each tile */ + tiles.forEach(index => { + let shuffle = game.tileOrder[index]; + console.log(index, game.tiles[shuffle]); + const resource = game.tiles[shuffle]; + layout.tiles[index].corners.forEach(cornerIndex => { + const active = game.placements.corners[cornerIndex]; + if (active && active.color) { + receives[active.color][resource.type] += active.type === 'settlement' ? 1 : 2; + } + }) + }); + + for (let color in receives) { + const entry = receives[color]; + if (!entry.wood && !entry.brick && !entry.sheep && !entry.wheat) { + continue; + } + let message = []; + for (let type in receives[color]) { + if (receives[color][type]) { + message.push(`${receives[color][type]} ${type}`); + } + } + addChatMessage(game, null, `${playerNameFromColor(game, color)} receives ${message.join(', ')}.`); + } +} + const getPlayer = (game, color) => { if (!game) { return { @@ -725,19 +787,19 @@ router.put("/:id/:action/:value?", async (req, res) => { } break; case 'pass': - if (game.turn !== name) { + if (game.turn.name !== name) { error = `You cannot pass when it isn't your turn.` } if (!error) { const next = getNextPlayer(game, name); game.turn = { - actions: game.turn.actions, name: next, color: getColorFromName(game, next) }; addChatMessage(game, session, `${name} passed their turn.`); addChatMessage(game, null, `It is ${next}'s turn.`); } + break; case 'place-settlement': if (game.state !== 'initial-placement' && game.state !== 'normal') { error = `You cannot place an item unless the game is active.`;