Lots of fixes. Road mapping, longest army, monopoly, year of plenty (sort of), road building (sort of), etc.
Signed-off-by: James Ketrenos <james_eikona@ketrenos.com>
This commit is contained in:
parent
433eff8473
commit
2152f6b93a
@ -2,9 +2,9 @@ import React from "react";
|
||||
import "./Resource.css";
|
||||
import { assetsPath } from './Common.js';
|
||||
|
||||
const Resource = ({ type, disabled, count }) => {
|
||||
const Resource = ({ type, select, disabled, count }) => {
|
||||
const array = new Array(Number(count ? count : 0));
|
||||
const select = (event) => {
|
||||
const click = select ? select : (event) => {
|
||||
if (!disabled) {
|
||||
event.target.classList.toggle('Selected');
|
||||
}
|
||||
@ -16,7 +16,7 @@ const Resource = ({ type, disabled, count }) => {
|
||||
{ React.Children.map(array, i => (
|
||||
<div className="Resource"
|
||||
data-type={type}
|
||||
onClick={select}
|
||||
onClick={click}
|
||||
style={{backgroundImage:`url(${assetsPath}/gfx/card-${type}.png)`}}>
|
||||
</div>
|
||||
)) }
|
||||
|
@ -16,6 +16,7 @@ import Dice from './Dice.js';
|
||||
import Resource from './Resource.js';
|
||||
import ViewCard from './ViewCard.js';
|
||||
import Winner from './Winner.js';
|
||||
import ChooseCard from './ChooseCard.js';
|
||||
|
||||
/* Start of withRouter polyfill */
|
||||
// https://reactrouter.com/docs/en/v6/faq#what-happened-to-withrouter-i-need-it
|
||||
@ -549,6 +550,7 @@ class Table extends React.Component {
|
||||
this.buildClicked = this.buildClicked.bind(this);
|
||||
this.closeCard = this.closeCard.bind(this);
|
||||
this.playCard = this.playCard.bind(this);
|
||||
this.selectResource = this.selectResource.bind(this);
|
||||
|
||||
this.mouse = { x: 0, y: 0 };
|
||||
this.radius = 0.317;
|
||||
@ -615,6 +617,10 @@ class Table extends React.Component {
|
||||
return this.sendAction('chat', undefined, {message: message});
|
||||
}
|
||||
|
||||
selectResource(card) {
|
||||
return this.sendAction('select-resource', card);
|
||||
}
|
||||
|
||||
playCard(card) {
|
||||
this.setState({ cardActive: undefined });
|
||||
return this.sendAction('play-card', undefined, card);
|
||||
@ -1005,7 +1011,9 @@ class Table extends React.Component {
|
||||
|
||||
render() {
|
||||
const game = this.state.game,
|
||||
player = game ? game.player : undefined
|
||||
player = game ? game.player : undefined,
|
||||
isTurn = (game && game.turn && game.turn.color === game.color) ? true : false;
|
||||
|
||||
let color;
|
||||
switch (game ? game.color : undefined) {
|
||||
case "O": color = "orange"; break;
|
||||
@ -1100,14 +1108,21 @@ class Table extends React.Component {
|
||||
<Trade table={this}/>
|
||||
}
|
||||
|
||||
{ game
|
||||
&& isTurn
|
||||
&& game.turn.actions
|
||||
&& game.turn.actions.indexOf('select-resource') !== -1 &&
|
||||
<ChooseCard table={this} type={game.turn.active}/>
|
||||
}
|
||||
|
||||
{ game && game.state === 'normal' &&
|
||||
game.turn &&
|
||||
game.turn.color === game.color &&
|
||||
isTurn &&
|
||||
game.turn.actions && game.turn.actions.indexOf('steal-resource') !== -1 &&
|
||||
<SelectPlayer table={this} players={game.turn.limits.players}/>
|
||||
}
|
||||
|
||||
{ game && game.turn && game.turn.color !== game.color &&
|
||||
{ game && game.turn && !isTurn &&
|
||||
(game.state === 'initial-placement' || game.state === 'normal') &&
|
||||
(!game.player || !game.player.mustDiscard) && <WaitingForPlayer table={this}/>
|
||||
}
|
||||
|
@ -34,8 +34,20 @@ const ViewCard = ({table, card}) => {
|
||||
knight or one progress card.</p></>,
|
||||
vp: <><b>1</b> victory point.
|
||||
<p>You only reveal your victory point cards when the game is over, either
|
||||
when you or an opponent reaches <b>10+</b> victory points on their turn and declares
|
||||
when you or an opponent
|
||||
reaches <b>10+</b> victory points on their turn and declares
|
||||
victory!</p></>,
|
||||
'progress-road-1': <>
|
||||
<p>Play <b>2</b> new roads as if you had just built them.</p>
|
||||
<p>This is still limited by the number of roads you have (a maximum of 15.)</p>
|
||||
<p><b>NOTE:</b> This card is not yet implemented. The server will give you <b>2</b> wood
|
||||
and <b>2</b> brick and we trust you will use them to build <b>2</b> roads.</p>
|
||||
<p>If
|
||||
you do not have enough roads remaining, you may end up with extra resources...
|
||||
but the game is in beta, so... be happy :)
|
||||
</p>
|
||||
<p>As an FYI, you currently have {15 - table.game.player.roads} roads remaining.</p>
|
||||
</>,
|
||||
'progress-road-2': <>
|
||||
<p>Play <b>2</b> new roads as if you had just built them.</p>
|
||||
<p>This is still limited by the number of roads you have (a maximum of 15.)</p>
|
||||
@ -46,7 +58,17 @@ const ViewCard = ({table, card}) => {
|
||||
but the game is in beta, so... be happy :)
|
||||
</p>
|
||||
<p>As an FYI, you currently have {15 - table.game.player.roads} roads remaining.</p>
|
||||
</>
|
||||
</>,
|
||||
'progress-monopoly': <>
|
||||
When you play this card, you will select <b>1</b> type of resource.
|
||||
All other players must give you all their resource cards of that type.
|
||||
</>,
|
||||
'progress-year-of-plenty': <>
|
||||
Take any <b>2</b> resources from the bank. Add them to your hand. They can be
|
||||
<b>2</b> of the same resource or <b>2</b> different resources.
|
||||
<p><b>Unfortunately</b> the current implementation only lets you pick a single
|
||||
resource and you will then get <b>2</b> of those.</p>
|
||||
</>
|
||||
};
|
||||
|
||||
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}<p>You have already played a development card this turn.</p></>;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (card.played) {
|
||||
description = <>{description}<p>You have already played this card.</p></>;
|
||||
canPlay = false;
|
||||
}
|
||||
|
||||
return (
|
||||
|
@ -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) {
|
||||
@ -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];
|
||||
|
Loading…
x
Reference in New Issue
Block a user