Added Velocirobber
Fixed several robber and admin related commands Signed-off-by: James Ketrenos <james_eikona@ketrenos.com>
This commit is contained in:
parent
1e51512ee8
commit
54e1a51c04
@ -43,14 +43,30 @@
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.Pip.Option {
|
||||
filter: brightness(150%);
|
||||
}
|
||||
|
||||
.Pip.Active {
|
||||
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 {
|
||||
filter: brightness(150%) drop-shadow(0px 0px 10px rgba(255, 0, 255, 1));
|
||||
}
|
||||
|
||||
|
||||
.Pips[disabled],
|
||||
.Tiles[disabled],
|
||||
.Roads[disabled],
|
||||
@ -121,6 +137,7 @@
|
||||
top: 0px;
|
||||
bottom: 0px;
|
||||
clip-path: circle(50%);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.Tile-Shape {
|
||||
@ -139,37 +156,38 @@
|
||||
filter: brightness(115%);
|
||||
}
|
||||
|
||||
.Option .Pip-Shape,
|
||||
.Option .Tile-Shape,
|
||||
.Option .Corner-Shape,
|
||||
.Option .Road-Shape {
|
||||
background-color: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
|
||||
.Robber .Pip-Shape,
|
||||
.Pip-Shape:hover {
|
||||
clip-path: circle(45%); /* show through the border */
|
||||
.Robber .Pip-Shape {
|
||||
top: -2em;
|
||||
left: -2em;
|
||||
clip-path: circle(50%);
|
||||
transform: scale(0.45);
|
||||
background-color:#e7c099;
|
||||
background-size: contain;
|
||||
background-position: center;
|
||||
border: 0.2em solid #8c471f;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.Roberta .Pip-Shape:hover,
|
||||
.Roberta .Pip-Shape {
|
||||
top: -2em;
|
||||
left: -2em;
|
||||
clip-path: circle(50%);
|
||||
transform: scale(0.45);
|
||||
background-image:url("./assets/woman-robber.png");
|
||||
}
|
||||
|
||||
.Robert .Pip-Shape:hover,
|
||||
.Robert .Pip-Shape {
|
||||
top: -2em;
|
||||
left: -2em;
|
||||
clip-path: circle(50%);
|
||||
transform: scale(0.45);
|
||||
background-image:url("./assets/man-robber.png");
|
||||
}
|
||||
|
||||
.Velocirobber .Pip-Shape {
|
||||
background-image:url("./assets/raptor-robber.png");
|
||||
}
|
||||
|
||||
.Tile-Shape:hover,
|
||||
.Corner-Shape:hover,
|
||||
.Road-Shape:hover {
|
||||
|
@ -481,18 +481,19 @@ const Board = ({ table, game }) => {
|
||||
}
|
||||
|
||||
if (game) {
|
||||
let robberClass = game.gender === 'female' ? 'Roberta' : 'Robert';
|
||||
let nodes = document.querySelectorAll(`.Pip.Robber`);
|
||||
for (let i = 0; i < nodes.length; i++) {
|
||||
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}"]`);
|
||||
if (el) {
|
||||
el.classList.add('Robber');
|
||||
el.classList.add(robberClass);
|
||||
el.classList.add(game.robberName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
BIN
client/src/assets/raptor-robber.png
Executable file
BIN
client/src/assets/raptor-robber.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 29 KiB |
@ -304,7 +304,7 @@ const distributeResources = (game, roll) => {
|
||||
let index = game.pipOrder[i];
|
||||
if (assetData.pips[index].roll === roll) {
|
||||
if (game.robber === i) {
|
||||
addChatMessage(game, null, `That pesky Robber stole resources!`);
|
||||
addChatMessage(game, null, `That pesky ${game.robberName} Roberson stole resources!`);
|
||||
} else {
|
||||
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) => {
|
||||
let session;
|
||||
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]}.`);
|
||||
game.turn.roll = game.dice[0] + game.dice[1];
|
||||
if (game.turn.roll === 7) {
|
||||
addChatMessage(game, null, `ROBBER! ${game.gender === 'female' ? 'Roberta' : 'Robert'} Robber Roberson!`);
|
||||
game.turn.robberInAction = true;
|
||||
delete game.turn.placedRobber;
|
||||
const mustDiscard = [];
|
||||
|
||||
for (let id in game.sessions) {
|
||||
const player = game.sessions[id].player;
|
||||
if (player) {
|
||||
let discard = player.stone + player.wheat + player.brick + player.wood + player.sheep;
|
||||
if (discard > 7) {
|
||||
discard = Math.floor(discard / 2);
|
||||
|
||||
player.mustDiscard = discard;
|
||||
addChatMessage(game, null, `${game.sessions[id].name} must discard ${discard} resource cards.`);
|
||||
mustDiscard.push(player);
|
||||
} else {
|
||||
delete player.mustDiscard;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
if you roll a 7, no one receives any resource cards.
|
||||
instead, every player who has more than 7 resource cards must select
|
||||
half (rounded down) of their
|
||||
resource cards and return them to the bank.
|
||||
then you muyst move the robber:
|
||||
1. you must move the robber immediately to the number token of any other
|
||||
terrain ohex or to the desert hex,
|
||||
2. you then steal 1 (random) resourcde card from an opponent who has a settlement or city
|
||||
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
|
||||
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
|
||||
adjacent settlements and citieis do not receive resourcres. The robber prevents it.
|
||||
*/
|
||||
|
||||
if (mustDiscard.length === 0) {
|
||||
addChatMessage(game, null, `ROBBER! ${game.robberName} Robber Roberson has fled, and no one had to discard!`);
|
||||
addChatMessage(game, null, `But 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);
|
||||
}
|
||||
} else {
|
||||
mustDiscard.forEach(player =>
|
||||
addChatMessage(game, null, `${getPlayerName(game, player)} must discard ${player.mustDiscard} resource cards the robber steals while fleeing!`)
|
||||
);
|
||||
}
|
||||
} else {
|
||||
distributeResources(game, game.turn.roll);
|
||||
}
|
||||
@ -582,20 +599,22 @@ const adminActions = (game, action, value) => {
|
||||
if (!session) {
|
||||
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);
|
||||
session.player[card] += count;
|
||||
session.player[type] += count;
|
||||
addChatMessage(game, null, `Admin gave ${count} ${type} to ${game.turn.name}.`);
|
||||
break;
|
||||
}
|
||||
|
||||
const index = game.developmentCards.findIndex(item =>
|
||||
item.card === card && item.type === type);
|
||||
item.card.toString() === card && item.type === type);
|
||||
|
||||
if (index === -1) {
|
||||
console.log({ card, type}, game.developmentCards);
|
||||
return `Unable to find ${type}-${card} in the current deck of development cards.`;
|
||||
}
|
||||
|
||||
let tmp = game.developmentCards.splice(index, 1)[0];
|
||||
tmp.turn = game.turns ? game.turns - 1 : 0;
|
||||
session.player.development.push(tmp);
|
||||
@ -1203,7 +1222,7 @@ const getValidRoads = (game, color) => {
|
||||
return limits;
|
||||
}
|
||||
|
||||
const isCompatibleOffer = (player, offer) => {
|
||||
const isCompatibleOffer = (game, player, offer) => {
|
||||
const isBank = offer.name === 'The bank';
|
||||
let valid = player.gets.length === offer.gives.length &&
|
||||
player.gives.length === offer.gets.length;
|
||||
@ -1214,7 +1233,7 @@ const isCompatibleOffer = (player, offer) => {
|
||||
}
|
||||
|
||||
console.log({
|
||||
player: getPlayerName(player),
|
||||
player: getPlayerName(game, player),
|
||||
gets: player.gets,
|
||||
gives: player.gives
|
||||
}, {
|
||||
@ -1274,11 +1293,11 @@ const isSameOffer = (player, offer) => {
|
||||
return same;
|
||||
};
|
||||
|
||||
const checkOffer = (player, offer) => {
|
||||
const checkOffer = (game, player, offer) => {
|
||||
let error = undefined;
|
||||
|
||||
console.log({
|
||||
player: getPlayerName(player),
|
||||
player: getPlayerName(game, player),
|
||||
gets: player.gets,
|
||||
gives: player.gives
|
||||
}, {
|
||||
@ -1476,7 +1495,7 @@ router.put("/:id/:action/:value?", async (req, res) => {
|
||||
if (value === 'offer') {
|
||||
const offer = req.body;
|
||||
|
||||
error = checkOffer(session.player, offer);
|
||||
error = checkOffer(game, session.player, offer);
|
||||
if (error) {
|
||||
break;
|
||||
}
|
||||
@ -1519,7 +1538,7 @@ router.put("/:id/:action/:value?", async (req, res) => {
|
||||
const offer = req.body;
|
||||
let target;
|
||||
|
||||
error = checkOffer(session.player, offer);
|
||||
error = checkOffer(game, session.player, offer);
|
||||
if (error) {
|
||||
break;
|
||||
}
|
||||
@ -1553,7 +1572,7 @@ router.put("/:id/:action/:value?", async (req, res) => {
|
||||
|
||||
/* Verify the requesting offer wasn't jacked --\
|
||||
* 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!`;
|
||||
break;
|
||||
}
|
||||
@ -1662,7 +1681,9 @@ router.put("/:id/:action/:value?", async (req, res) => {
|
||||
}
|
||||
game.robber = robber;
|
||||
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 = [];
|
||||
layout.tiles[robber].corners.forEach(cornerIndex => {
|
||||
@ -1680,7 +1701,8 @@ router.put("/:id/:action/:value?", async (req, res) => {
|
||||
game.turn.actions = [];
|
||||
game.turn.robberInAction = false;
|
||||
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;
|
||||
@ -1855,7 +1877,16 @@ router.put("/:id/:action/:value?", async (req, res) => {
|
||||
|
||||
game.turn.robberInAction = true;
|
||||
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;
|
||||
@ -2323,7 +2354,29 @@ router.put("/:id/:action/:value?", async (req, res) => {
|
||||
addChatMessage(game, null, `${session.name} discarded ${sum} resource cards.`);
|
||||
if (player.mustDiscard) {
|
||||
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;
|
||||
|
||||
case "state":
|
||||
@ -2423,28 +2476,6 @@ const sendGame = async (req, res, game, error) => {
|
||||
}
|
||||
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 */
|
||||
let session;
|
||||
if (req.session) {
|
||||
@ -2708,7 +2739,7 @@ router.post("/:id?", (req, res/*, next*/) => {
|
||||
});
|
||||
|
||||
const setBeginnerGame = (game) => {
|
||||
game.gender = Math.random() > 0.5 ? 'male' : 'female';
|
||||
pickRobber(game);
|
||||
shuffle(game.developmentCards);
|
||||
game.borderOrder = [];
|
||||
for (let i = 0; i < 6; i++) {
|
||||
@ -2721,6 +2752,8 @@ const setBeginnerGame = (game) => {
|
||||
4, 11, 7, 14,
|
||||
18, 8, 15
|
||||
];
|
||||
game.robber = 9;
|
||||
|
||||
game.pipOrder = [
|
||||
5, 1, 6,
|
||||
7, 2, 9, 11,
|
||||
@ -2732,7 +2765,7 @@ const setBeginnerGame = (game) => {
|
||||
}
|
||||
|
||||
const shuffleBoard = (game, beginnersGame) => {
|
||||
game.gender = Math.random() > 0.5 ? 'male' : 'female';
|
||||
pickRobber(game);
|
||||
|
||||
const seq = [];
|
||||
for (let i = 0; i < 6; i++) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user