1
0

Added Velocirobber

Fixed several robber and admin related commands

Signed-off-by: James Ketrenos <james_eikona@ketrenos.com>
This commit is contained in:
James Ketrenos 2022-02-26 02:57:08 -08:00
parent 1e51512ee8
commit 54e1a51c04
4 changed files with 124 additions and 72 deletions

View File

@ -43,14 +43,30 @@
transform: translate(-50%, -50%); transform: translate(-50%, -50%);
} }
.Pip.Option {
filter: brightness(150%);
}
.Pip.Active { .Pip.Active {
filter: drop-shadow(0px 0px 10px rgba(255, 0, 255, 1)); filter: drop-shadow(0px 0px 10px rgba(255, 0, 255, 1));
} }
.Pip.Option:hover,
.Pip:hover {
filter: brightness(100%);
}
.Pip.Active:hover {
filter: drop-shadow(0px 0px 10px rgba(255, 0, 255, 1));
}
.Pip.Active.Option { .Pip.Active.Option {
filter: brightness(150%) drop-shadow(0px 0px 10px rgba(255, 0, 255, 1)); filter: brightness(150%) drop-shadow(0px 0px 10px rgba(255, 0, 255, 1));
} }
.Pips[disabled], .Pips[disabled],
.Tiles[disabled], .Tiles[disabled],
.Roads[disabled], .Roads[disabled],
@ -121,6 +137,7 @@
top: 0px; top: 0px;
bottom: 0px; bottom: 0px;
clip-path: circle(50%); clip-path: circle(50%);
pointer-events: none;
} }
.Tile-Shape { .Tile-Shape {
@ -139,37 +156,38 @@
filter: brightness(115%); filter: brightness(115%);
} }
.Option .Pip-Shape,
.Option .Tile-Shape, .Option .Tile-Shape,
.Option .Corner-Shape, .Option .Corner-Shape,
.Option .Road-Shape { .Option .Road-Shape {
background-color: rgba(255, 255, 255, 0.5); background-color: rgba(255, 255, 255, 0.5);
} }
.Robber .Pip-Shape, .Robber .Pip-Shape {
.Pip-Shape:hover { top: -2em;
clip-path: circle(45%); /* show through the border */ left: -2em;
clip-path: circle(50%);
transform: scale(0.45);
background-color:#e7c099; background-color:#e7c099;
background-size: contain; background-size: contain;
background-position: center; background-position: center;
border: 0.2em solid #8c471f;
border-radius: 50%;
} }
.Roberta .Pip-Shape:hover,
.Roberta .Pip-Shape { .Roberta .Pip-Shape {
top: -2em;
left: -2em;
clip-path: circle(50%);
transform: scale(0.45);
background-image:url("./assets/woman-robber.png"); background-image:url("./assets/woman-robber.png");
} }
.Robert .Pip-Shape:hover,
.Robert .Pip-Shape { .Robert .Pip-Shape {
top: -2em;
left: -2em;
clip-path: circle(50%);
transform: scale(0.45);
background-image:url("./assets/man-robber.png"); background-image:url("./assets/man-robber.png");
} }
.Velocirobber .Pip-Shape {
background-image:url("./assets/raptor-robber.png");
}
.Tile-Shape:hover, .Tile-Shape:hover,
.Corner-Shape:hover, .Corner-Shape:hover,
.Road-Shape:hover { .Road-Shape:hover {

View File

@ -481,18 +481,19 @@ const Board = ({ table, game }) => {
} }
if (game) { if (game) {
let robberClass = game.gender === 'female' ? 'Roberta' : 'Robert';
let nodes = document.querySelectorAll(`.Pip.Robber`); let nodes = document.querySelectorAll(`.Pip.Robber`);
for (let i = 0; i < nodes.length; i++) { for (let i = 0; i < nodes.length; i++) {
nodes[i].classList.remove('Robber'); nodes[i].classList.remove('Robber');
nodes[i].classList.remove(robberClass); [ 'Robert', 'Roberta', 'Velocirobber' ].forEach(robberName =>
nodes[i].classList.remove(robberName)
);
} }
if (game.robber) { if (game.robber !== undefined) {
const el = document.querySelector(`.Pip[data-index="${game.robber}"]`); const el = document.querySelector(`.Pip[data-index="${game.robber}"]`);
if (el) { if (el) {
el.classList.add('Robber'); el.classList.add('Robber');
el.classList.add(robberClass); el.classList.add(game.robberName);
} }
} }
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

View File

@ -304,7 +304,7 @@ const distributeResources = (game, roll) => {
let index = game.pipOrder[i]; let index = game.pipOrder[i];
if (assetData.pips[index].roll === roll) { if (assetData.pips[index].roll === roll) {
if (game.robber === i) { if (game.robber === i) {
addChatMessage(game, null, `That pesky Robber stole resources!`); addChatMessage(game, null, `That pesky ${game.robberName} Roberson stole resources!`);
} else { } else {
tiles.push(i); tiles.push(i);
} }
@ -350,6 +350,21 @@ const distributeResources = (game, roll) => {
} }
} }
const pickRobber = (game) => {
const selection = Math.floor(Math.random() * 3);
switch (selection) {
case 0:
game.robberName = 'Robert';
break;
case 1:
game.robberName = 'Roberta';
break;
case 2:
game.robberName = 'Velocirobber';
break;
}
}
const processRoll = (game, dice) => { const processRoll = (game, dice) => {
let session; let session;
for (let id in game.sessions) { for (let id in game.sessions) {
@ -365,38 +380,40 @@ const processRoll = (game, dice) => {
addChatMessage(game, session, `${session.name} rolled ${game.dice[0]}, ${game.dice[1]}.`); addChatMessage(game, session, `${session.name} rolled ${game.dice[0]}, ${game.dice[1]}.`);
game.turn.roll = game.dice[0] + game.dice[1]; game.turn.roll = game.dice[0] + game.dice[1];
if (game.turn.roll === 7) { if (game.turn.roll === 7) {
addChatMessage(game, null, `ROBBER! ${game.gender === 'female' ? 'Roberta' : 'Robert'} Robber Roberson!`);
game.turn.robberInAction = true; game.turn.robberInAction = true;
delete game.turn.placedRobber; delete game.turn.placedRobber;
const mustDiscard = [];
for (let id in game.sessions) { for (let id in game.sessions) {
const player = game.sessions[id].player; const player = game.sessions[id].player;
if (player) { if (player) {
let discard = player.stone + player.wheat + player.brick + player.wood + player.sheep; let discard = player.stone + player.wheat + player.brick + player.wood + player.sheep;
if (discard > 7) { if (discard > 7) {
discard = Math.floor(discard / 2); discard = Math.floor(discard / 2);
player.mustDiscard = discard; player.mustDiscard = discard;
addChatMessage(game, null, `${game.sessions[id].name} must discard ${discard} resource cards.`); mustDiscard.push(player);
} else { } else {
delete player.mustDiscard; delete player.mustDiscard;
} }
} }
} }
/*
if you roll a 7, no one receives any resource cards. if (mustDiscard.length === 0) {
instead, every player who has more than 7 resource cards must select addChatMessage(game, null, `ROBBER! ${game.robberName} Robber Roberson has fled, and no one had to discard!`);
half (rounded down) of their addChatMessage(game, null, `But drat! A new robber has arrived and must be placed by ${game.turn.name}.`);
resource cards and return them to the bank. game.turn.actions = [ 'place-robber' ];
then you muyst move the robber: game.turn.limits = { pips: [] };
1. you must move the robber immediately to the number token of any other for (let i = 0; i < 19; i++) {
terrain ohex or to the desert hex, if (i === game.robber) {
2. you then steal 1 (random) resourcde card from an opponent who has a settlement or city continue;
adjacent to the target terrain hex. the player who is robbed holds their resource cards }
face down. you then take 1 card at random. if the target hex is adjacent to 2 or game.turn.limits.pips.push(i);
more player's settlements or cities, you choose which one you want to steal from. }
If the production number for the hex containing the robber is rolled, the owners of } else {
adjacent settlements and citieis do not receive resourcres. The robber prevents it. mustDiscard.forEach(player =>
*/ addChatMessage(game, null, `${getPlayerName(game, player)} must discard ${player.mustDiscard} resource cards the robber steals while fleeing!`)
);
}
} else { } else {
distributeResources(game, game.turn.roll); distributeResources(game, game.turn.roll);
} }
@ -582,20 +599,22 @@ const adminActions = (game, action, value) => {
if (!session) { if (!session) {
return `Unable to determine current player turn to give resources.`; return `Unable to determine current player turn to give resources.`;
} }
if (type in session.player) {
if ([ 'wheat', 'sheep', 'wood', 'stone', 'brick' ].indexOf(type) !== -1) {
const count = parseInt(card); const count = parseInt(card);
session.player[card] += count; session.player[type] += count;
addChatMessage(game, null, `Admin gave ${count} ${type} to ${game.turn.name}.`); addChatMessage(game, null, `Admin gave ${count} ${type} to ${game.turn.name}.`);
break; break;
} }
const index = game.developmentCards.findIndex(item => const index = game.developmentCards.findIndex(item =>
item.card === card && item.type === type); item.card.toString() === card && item.type === type);
if (index === -1) { if (index === -1) {
console.log({ card, type}, game.developmentCards); console.log({ card, type}, game.developmentCards);
return `Unable to find ${type}-${card} in the current deck of development cards.`; return `Unable to find ${type}-${card} in the current deck of development cards.`;
} }
let tmp = game.developmentCards.splice(index, 1)[0]; let tmp = game.developmentCards.splice(index, 1)[0];
tmp.turn = game.turns ? game.turns - 1 : 0; tmp.turn = game.turns ? game.turns - 1 : 0;
session.player.development.push(tmp); session.player.development.push(tmp);
@ -1203,7 +1222,7 @@ const getValidRoads = (game, color) => {
return limits; return limits;
} }
const isCompatibleOffer = (player, offer) => { const isCompatibleOffer = (game, player, offer) => {
const isBank = offer.name === 'The bank'; const isBank = offer.name === 'The bank';
let valid = player.gets.length === offer.gives.length && let valid = player.gets.length === offer.gives.length &&
player.gives.length === offer.gets.length; player.gives.length === offer.gets.length;
@ -1214,7 +1233,7 @@ const isCompatibleOffer = (player, offer) => {
} }
console.log({ console.log({
player: getPlayerName(player), player: getPlayerName(game, player),
gets: player.gets, gets: player.gets,
gives: player.gives gives: player.gives
}, { }, {
@ -1274,11 +1293,11 @@ const isSameOffer = (player, offer) => {
return same; return same;
}; };
const checkOffer = (player, offer) => { const checkOffer = (game, player, offer) => {
let error = undefined; let error = undefined;
console.log({ console.log({
player: getPlayerName(player), player: getPlayerName(game, player),
gets: player.gets, gets: player.gets,
gives: player.gives gives: player.gives
}, { }, {
@ -1476,7 +1495,7 @@ router.put("/:id/:action/:value?", async (req, res) => {
if (value === 'offer') { if (value === 'offer') {
const offer = req.body; const offer = req.body;
error = checkOffer(session.player, offer); error = checkOffer(game, session.player, offer);
if (error) { if (error) {
break; break;
} }
@ -1519,7 +1538,7 @@ router.put("/:id/:action/:value?", async (req, res) => {
const offer = req.body; const offer = req.body;
let target; let target;
error = checkOffer(session.player, offer); error = checkOffer(game, session.player, offer);
if (error) { if (error) {
break; break;
} }
@ -1553,7 +1572,7 @@ router.put("/:id/:action/:value?", async (req, res) => {
/* Verify the requesting offer wasn't jacked --\ /* Verify the requesting offer wasn't jacked --\
* make sure the target.gives === player.gets and target.gives === player.gets */ * make sure the target.gives === player.gets and target.gives === player.gets */
if (!isCompatibleOffer(player, target)) { if (!isCompatibleOffer(game, player, target)) {
error = `The requested offer does not match the negotiated terms!`; error = `The requested offer does not match the negotiated terms!`;
break; break;
} }
@ -1662,7 +1681,9 @@ router.put("/:id/:action/:value?", async (req, res) => {
} }
game.robber = robber; game.robber = robber;
game.turn.placedRobber = true; game.turn.placedRobber = true;
addChatMessage(game, session, `Robber has been moved!`);
pickRobber(game);
addChatMessage(game, session, `${game.robberName} Robber Robinson entered the scene as the nefarious robber!`);
let colors = []; let colors = [];
layout.tiles[robber].corners.forEach(cornerIndex => { layout.tiles[robber].corners.forEach(cornerIndex => {
@ -1680,7 +1701,8 @@ router.put("/:id/:action/:value?", async (req, res) => {
game.turn.actions = []; game.turn.actions = [];
game.turn.robberInAction = false; game.turn.robberInAction = false;
delete game.turn.limits; delete game.turn.limits;
addChatMessage(game, session, `The Robber was moved to a terrain with no other players.`); addChatMessage(game, session, `The dread robber ${game.robberName} was placed on a terrain with no other players, ` +
`so ${game.turn.name} does not steal resources from anyone.`);
} }
break; break;
@ -1855,7 +1877,16 @@ router.put("/:id/:action/:value?", async (req, res) => {
game.turn.robberInAction = true; game.turn.robberInAction = true;
delete game.turn.placedRobber; delete game.turn.placedRobber;
addChatMessage(game, session, `${session.name} must now move the robber.`); addChatMessage(game, session, `The robber ${game.robberName} has fled before the power of the Knight, ` +
`but a new robber has returned and ${session.name} must now place them.`);
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; break;
@ -2323,7 +2354,29 @@ router.put("/:id/:action/:value?", async (req, res) => {
addChatMessage(game, null, `${session.name} discarded ${sum} resource cards.`); addChatMessage(game, null, `${session.name} discarded ${sum} resource cards.`);
if (player.mustDiscard) { if (player.mustDiscard) {
addChatMessage(game, null, `${session.name} must discard ${player.mustDiscard} more cards.`); addChatMessage(game, null, `${session.name} 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; break;
case "state": case "state":
@ -2423,28 +2476,6 @@ const sendGame = async (req, res, game, error) => {
} }
game.active = active; game.active = active;
/* If the current turn is a robber placement, and everyone has
* discarded, set the limits for where the robber can be placed */
if (game.turn && game.turn.robberInAction) {
let move = true;
for (let color in game.players) {
const discard = game.players[color].mustDiscard;
if (discard) {
move = false;
}
}
if (move && !game.turn.placedRobber) {
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);
}
}
}
/* Update the session lastActive clock */ /* Update the session lastActive clock */
let session; let session;
if (req.session) { if (req.session) {
@ -2708,7 +2739,7 @@ router.post("/:id?", (req, res/*, next*/) => {
}); });
const setBeginnerGame = (game) => { const setBeginnerGame = (game) => {
game.gender = Math.random() > 0.5 ? 'male' : 'female'; pickRobber(game);
shuffle(game.developmentCards); shuffle(game.developmentCards);
game.borderOrder = []; game.borderOrder = [];
for (let i = 0; i < 6; i++) { for (let i = 0; i < 6; i++) {
@ -2721,6 +2752,8 @@ const setBeginnerGame = (game) => {
4, 11, 7, 14, 4, 11, 7, 14,
18, 8, 15 18, 8, 15
]; ];
game.robber = 9;
game.pipOrder = [ game.pipOrder = [
5, 1, 6, 5, 1, 6,
7, 2, 9, 11, 7, 2, 9, 11,
@ -2732,7 +2765,7 @@ const setBeginnerGame = (game) => {
} }
const shuffleBoard = (game, beginnersGame) => { const shuffleBoard = (game, beginnersGame) => {
game.gender = Math.random() > 0.5 ? 'male' : 'female'; pickRobber(game);
const seq = []; const seq = [];
for (let i = 0; i < 6; i++) { for (let i = 0; i < 6; i++) {