Skip to content

Commit cc6fb36

Browse files
committed
Fix: Unable to use Air Balloon to copy Messenger in opponent's city #81
1 parent 7d85a05 commit cc6fb36

File tree

2 files changed

+76
-54
lines changed

2 files changed

+76
-54
lines changed

src/model/card.test.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7382,6 +7382,35 @@ describe("Card", () => {
73827382
);
73837383
expect(player.numCardsInHand).to.be(3);
73847384
});
7385+
it("should allow you to copy MESSENGER in another player's city", () => {
7386+
let player2 = gameState.players[1];
7387+
player2.addToCity(gameState, CardName.FARM);
7388+
player2.addToCity(gameState, CardName.MESSENGER);
7389+
player2.updatePlayedCard(
7390+
gameState,
7391+
player2.getFirstPlayedCard(CardName.FARM),
7392+
{ shareSpaceWith: CardName.MESSENGER }
7393+
);
7394+
player2.updatePlayedCard(
7395+
gameState,
7396+
player2.getFirstPlayedCard(CardName.MESSENGER),
7397+
{ shareSpaceWith: CardName.FARM }
7398+
);
7399+
7400+
// player plays AIR_BALLOON card
7401+
const card = Card.fromName(CardName.AIR_BALLOON);
7402+
player.addCardToHand(gameState, card.name);
7403+
player.gainResources(gameState, card.baseCost);
7404+
expect(player.numCardsInHand).to.be(1);
7405+
7406+
[player, gameState] = multiStepGameInputTest(
7407+
gameState,
7408+
[playCardInput(CardName.AIR_BALLOON)],
7409+
{ autoAdvance: true }
7410+
);
7411+
expect(player.numCardsInHand).to.be(1);
7412+
expect(player.getNumResourcesByType(ResourceType.VP)).to.be(1);
7413+
});
73857414
});
73867415

73877416
describe(CardName.BAKER, () => {

src/model/card.ts

Lines changed: 47 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -4014,65 +4014,58 @@ const CARD_REGISTRY: Record<CardName, Card> = {
40144014
playInner: (gameState: GameState, gameInput: GameInput) => {
40154015
const player = gameState.getActivePlayer();
40164016
if (gameInput.inputType === GameInputType.PLAY_CARD) {
4017-
const seenCards: Set<CardName> = new Set();
4018-
const cardOptions: Set<CardName> = new Set();
4019-
gameState.players.forEach((p) => {
4020-
if (p.playerId === player.playerId) {
4021-
return;
4022-
}
4023-
p.getAllPlayedCardsByType(CardType.TRAVELER).forEach(
4024-
({ cardName }) => {
4025-
if (seenCards.has(cardName)) {
4026-
return;
4027-
}
4028-
seenCards.add(cardName);
4029-
if (
4030-
cardName === CardName.FOOL ||
4031-
cardName === CardName.MAIN_ROAD ||
4032-
cardName === CardName.RUINS
4033-
) {
4034-
return;
4035-
}
4036-
const card = Card.fromName(cardName);
4037-
if (card.canReactivateCard(gameState)) {
4038-
cardOptions.add(cardName);
4039-
}
4040-
}
4041-
);
4042-
});
4043-
if (cardOptions.size === 0) {
4044-
return;
4017+
// Get all opponent TRAVELER cards that can be copied
4018+
const cardOptions = gameState.players
4019+
.filter((p) => p.playerId !== player.playerId)
4020+
.flatMap((p) => {
4021+
return p
4022+
.getAllPlayedCardsByType(CardType.TRAVELER)
4023+
.filter((playedCard) => {
4024+
// Filter out cards that can't be copied
4025+
const cardName = playedCard.cardName;
4026+
return ![
4027+
CardName.FOOL,
4028+
CardName.MAIN_ROAD,
4029+
CardName.RUINS,
4030+
].includes(cardName);
4031+
});
4032+
});
4033+
4034+
if (cardOptions.length !== 0) {
4035+
gameState.pendingGameInputs.push({
4036+
inputType: GameInputType.SELECT_PLAYED_CARDS,
4037+
prevInputType: gameInput.inputType,
4038+
cardContext: CardName.AIR_BALLOON,
4039+
playedCardContext: gameInput.playedCardContext, // Pass this through
4040+
cardOptions,
4041+
maxToSelect: 1,
4042+
minToSelect: 1,
4043+
clientOptions: {
4044+
selectedCards: [],
4045+
},
4046+
});
40454047
}
4046-
// Ask player to select 1
4047-
gameState.pendingGameInputs.push({
4048-
inputType: GameInputType.SELECT_CARDS,
4049-
prevInputType: gameInput.inputType,
4050-
label: "Select 1 TRAVELER to copy",
4051-
cardOptions: Array.from(cardOptions),
4052-
maxToSelect: 1,
4053-
minToSelect: 1,
4054-
cardContext: CardName.AIR_BALLOON,
4055-
clientOptions: {
4056-
selectedCards: [],
4057-
},
4058-
});
4059-
} else if (gameInput.inputType === GameInputType.SELECT_CARDS) {
4048+
} else if (
4049+
gameInput.inputType === GameInputType.SELECT_PLAYED_CARDS &&
4050+
gameInput.cardContext === CardName.AIR_BALLOON
4051+
) {
40604052
const selectedCards = gameInput.clientOptions.selectedCards;
4061-
if (selectedCards.length !== 1) {
4062-
throw new Error(`Please select 1 card to copy`);
4053+
if (!selectedCards || selectedCards.length !== 1) {
4054+
throw new Error("Must select one card to copy");
40634055
}
40644056
const selectedCard = selectedCards[0];
4065-
gameState.addGameLogFromCard(CardName.AIR_BALLOON, [
4057+
const card = Card.fromName(selectedCard.cardName);
4058+
4059+
// When copying the card, make sure to pass the playedCardContext
4060+
card.reactivateCard(
4061+
gameState,
4062+
{
4063+
...gameInput,
4064+
playedCardContext: selectedCard, // Important: Pass the selected card as context
4065+
},
40664066
player,
4067-
" reactivated ",
4068-
{ type: "entity", entityType: "card", card: selectedCard },
4069-
".",
4070-
]);
4071-
const targetCard = Card.fromName(selectedCard);
4072-
targetCard.reactivateCard(gameState, gameInput, player, {
4073-
cardOwnerId: "",
4074-
cardName: selectedCard,
4075-
});
4067+
selectedCard
4068+
);
40764069
}
40774070
},
40784071
}),

0 commit comments

Comments
 (0)