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.`;