From 2152f6b93a444cf5130c37d6d28ef088e54c71b6 Mon Sep 17 00:00:00 2001
From: James Ketrenos
You only reveal your victory point cards when the game is over, either - when you or an opponent reaches 10+ victory points on their turn and declares + when you or an opponent + reaches 10+ victory points on their turn and declares victory!
>, + 'progress-road-1': <> +Play 2 new roads as if you had just built them.
+This is still limited by the number of roads you have (a maximum of 15.)
+NOTE: This card is not yet implemented. The server will give you 2 wood + and 2 brick and we trust you will use them to build 2 roads.
+If + you do not have enough roads remaining, you may end up with extra resources... + but the game is in beta, so... be happy :) +
+As an FYI, you currently have {15 - table.game.player.roads} roads remaining.
+ >, 'progress-road-2': <>Play 2 new roads as if you had just built them.
This is still limited by the number of roads you have (a maximum of 15.)
@@ -46,7 +58,17 @@ const ViewCard = ({table, card}) => { but the game is in beta, so... be happy :)As an FYI, you currently have {15 - table.game.player.roads} roads remaining.
- > + >, + 'progress-monopoly': <> + When you play this card, you will select 1 type of resource. + All other players must give you all their resource cards of that type. + >, + 'progress-year-of-plenty': <> + Take any 2 resources from the bank. Add them to your hand. They can be + 2 of the same resource or 2 different resources. +Unfortunately the current implementation only lets you pick a single + resource and you will then get 2 of those.
+ > }; let description; @@ -57,7 +79,7 @@ const ViewCard = ({table, card}) => { } if (description === undefined) { - console.log('No description for ', card); + console.log(`No description for ${card.type}-${card.card}`); } let canPlay = false; @@ -79,11 +101,15 @@ const ViewCard = ({table, card}) => { } if (canPlay) { canPlay = table.game.player.playedCard !== table.game.turns; + if (!canPlay) { + description = <>{description}You have already played a development card this turn.
>; + } } } if (card.played) { description = <>{description}You have already played this card.
>; + canPlay = false; } return ( diff --git a/server/routes/games.js b/server/routes/games.js index 4ebad75..3ab5df3 100755 --- a/server/routes/games.js +++ b/server/routes/games.js @@ -562,10 +562,12 @@ const adminActions = (game, action, value) => { break; case "give": - parts = value.match(/^([^-]+)-([0-9]+)$/); + parts = value.match(/^([^-]+)-(.*)$/); if (!parts) { return `Unable to parse give request.`; } + const type = parts[1], card = parts[2]; + for (let id in game.sessions) { if (game.sessions[id].name === game.turn.name) { session = game.sessions[id]; @@ -574,13 +576,31 @@ const adminActions = (game, action, value) => { if (!session) { return `Unable to determine current player turn to give resources.`; } - if (!(parts[1] in session.player)) { - return `Invalid resource request.`; + if (type in session.player) { + const count = parseInt(card); + session.player[card] += count; + addChatMessage(game, null, `Admin gave ${count} ${type} to ${game.turn.name}.`); + break; } - session.player[parts[1]] += parseInt(parts[2]); - addChatMessage(game, null, `Admin gave ${parseInt(parts[2])} ${parts[1]} to ${game.turn.name}.`); + + const index = game.developmentCards.findIndex(item => + item.card === 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); + addChatMessage(game, null, `Admin gave a ${card}-${type} to ${game.turn.name}.`); break; + case "cards": + let results = game.developmentCards.map(card => `${card.type}-${card.card}`) + .join(', '); + return results; + case "roll": parts = value.match(/^([1-6])(-([1-6]))?$/); if (!parts) { @@ -1036,7 +1056,7 @@ const calculateRoadLengths = (game, session) => { let checkForTies = false; console.log(currentLongest, currentLength); - + if (currentLongest && game.players[currentLongest].longestRoad < currentLength) { addChatMessage(game, session, `${playerNameFromColor(game, currentLongest)} had their longest road split!`); checkForTies = true; @@ -1187,7 +1207,15 @@ const isCompatibleOffer = (player, offer) => { return false; } - console.log(player.gets, player.gives, offer); + console.log({ + player: getPlayerName(player), + gets: player.gets, + gives: player.gives + }, { + name: offer.name, + gets: offer.gets, + gives: offer.gives + }); player.gets.forEach(get => { if (!valid) { @@ -1242,6 +1270,17 @@ const isSameOffer = (player, offer) => { const checkOffer = (player, offer) => { let error = undefined; + + console.log({ + player: getPlayerName(player), + gets: player.gets, + gives: player.gives + }, { + name: offer.name, + gets: offer.gets, + gives: offer.gives + }); + offer.gives.forEach(give => { if (!error) { return; @@ -1397,7 +1436,6 @@ router.put("/:id/:action/:value?", async (req, res) => { /* Any player can reject an offer */ if (value === 'reject') { - const offer = req.body; session.player.offerRejected = true; addChatMessage(game, session, `${session.name} rejected ${game.turn.name}'s offer.`); break; @@ -1469,7 +1507,7 @@ router.put("/:id/:action/:value?", async (req, res) => { }); addChatMessage(game, session, `${session.name} has accepted a trade ` + - `offer for ${offerToString(session.player)} ` + + `offer to give ${offerToString(session.player)} ` + `from ${(offer.name === 'The bank') ? 'the bank' : offer.name}.`); delete game.turn.offer; @@ -1709,17 +1747,35 @@ router.put("/:id/:action/:value?", async (req, res) => { } } - if (card.type === 'progress' && card.card === 'road-2') { - addChatMessage(game, session, `${session.name} played a Road Building card. The server is giving them 2 brick and 2 wood to build those roads!`); - player.brick += 2; - player.wood += 2; + if (card.type === 'progress') { + switch (card.card) { + case 'road-1': + case 'road-2': + addChatMessage(game, session, `${session.name} played a Road Building card. The server is giving them 2 brick and 2 wood to build those roads!`); + player.brick += 2; + player.wood += 2; + break; + case 'monopoly': + game.turn.actions = [ 'select-resource' ]; + game.turn.active = 'monopoly'; + addChatMessage(game, session, `${session.name} played the Monopoly card.`); + break; + case 'year-of-plenty': + game.turn.actions = [ 'select-resource' ]; + game.turn.active = 'year-of-plenty'; + addChatMessage(game, session, `${session.name} played the Year of Plenty card.`); + break; + default: + addChatMessage(game, session, `Oh no! ${card.card} isn't impmented yet!`); + break; + } } card.played = true; player.playedCard = game.turns; - addChatMessage(game, session, `${session.name} played a ${card.type}-${card.card} development card.`); if (card.type === 'army') { player.army++; + addChatMessage(game, session, `${session.name} played a Kaniget!`); if (player.army > 2 && (!game.largestArmy || game.players[game.largestArmy].army < player.army)) { @@ -1736,6 +1792,72 @@ router.put("/:id/:action/:value?", async (req, res) => { break; + case 'select-resource': + if (!game || !game.turn || !game.turn.actions || + game.turn.actions.indexOf('select-resource') === -1) { + error = `Please, let's not cheat. Ok?`; + console.log(game); + break; + } + + if (session.color !== game.turn.color) { + error = `It is not your turn! It is ${game.turn.name}'s turn.`; + break; + } + + const type = value.trim(); + switch (type) { + case 'wheat': + case 'brick': + case 'sheep': + case 'stone': + case 'wood': + break; + default: + error = `That is not a valid resource type!`; + break; + }; + if (error) { + break; + } + addChatMessage(game, session, `${session.name} has chosen ${type}!`); + + switch (game.turn.active) { + case 'monopoly': + const gave = []; + let total = 0; + for (let color in game.players) { + const player = game.players[color]; + if (player.status === 'Not active') { + continue + } + if (color === session.color) { + continue; + } + if (player[type]) { + gave.push(`${playerNameFromColor(game, color)} gave ${player[type]} ${type}`); + session.player[type] += player[type]; + total += player[type]; + player[type] = 0; + } + } + + if (gave.length) { + addChatMessage(game, session, `Players ${gave.join(', ')}. In total, ${session.name} received ${total} ${type}.`); + } else { + addChatMessage(game, session, 'No players had that resource. Wa-waaaa.'); + } + break; + + case 'year-of-plenty': + session.player[type] += 2; + addChatMessage(game, session, `${session.name} received 2 ${type} from the bank.`); + break; + } + delete game.turn.active; + game.turn.actions = []; + break; + case 'buy-settlement': if (game.state !== 'normal') { error = `You cannot purchase a settlement unless the game is active.`; @@ -2197,10 +2319,8 @@ const debugChat = (game, preamble) => { } playerInventory += ` ${playerNameFromColor(game, key)} has `; const has = [ 'wheat', 'brick', 'sheep', 'stone', 'wood' ].map(resource => { - if (game.players[key][resource] > 0) { - return `${game.players[key][resource]} ${resource}`; - } - return ''; + const count = game.players[key][resource] ? game.players[key][resource] : 0; + return `${count} ${resource}`; }).filter(item => item !== '').join(', '); if (has) { playerInventory += `${has}, `; @@ -2276,7 +2396,6 @@ const sendGame = async (req, res, game, error) => { lastTime = message.date; }); - /* Calculate points and determine if there is a winner */ for (let key in game.players) { const player = game.players[key];