internal void GainCard(GameState gameState, Card card, DeckPlacement originalLocation, DeckPlacement defaultPlacement = DeckPlacement.Discard, GainReason gainReason = GainReason.Gain) { if (gainReason == GainReason.Buy) { this.gameLog.PlayerBoughtCard(this, card); this.turnCounters.cardsBoughtThisTurn.Add(card); gameState.cardContextStack.PushCardContext(this, card, CardContextReason.CardBeingBought); } else { this.gameLog.PlayerGainedCard(this, card); gameState.cardContextStack.PushCardContext(this, card, CardContextReason.CardBeingGained); } // should only include cards gained on the players turned, not cards gained as a side effect on some other players turn // important for smugglers ... if (this == gameState.players.CurrentPlayer) { this.turnCounters.cardsGainedThisTurn.Add(card); } this.gameLog.PushScope(); // technically, the hovel reaction can cause hand size to change. This is not a problem though // would only be a problem if cards were added that would subsequently needed to be enumerated. bool wasCardMoved = false; if (this.ownsCardWithSpecializedActionOnBuyWhileInHand || this.ownsCardWithSpecializedActionOnGainWhileInHand) { foreach (Card cardInHand in this.Hand) { gameState.cardContextStack.PushCardContext(this, cardInHand, CardContextReason.CardReacting); DeckPlacement preferredPlacement = (gainReason == GainReason.Buy) ? cardInHand.DoSpecializedActionOnBuyWhileInHand(this, gameState, card) : DeckPlacement.Default; if (!wasCardMoved && preferredPlacement == DeckPlacement.Default) { preferredPlacement = cardInHand.DoSpecializedActionOnGainWhileInHand(this, gameState, card); } if (!wasCardMoved && preferredPlacement != DeckPlacement.Default) { defaultPlacement = preferredPlacement; wasCardMoved = true; } gameState.cardContextStack.Pop(); } } if (this.ownsCardWithSpecializedActionOnGainWhileInPlay) { foreach (Card cardInPlay in this.CardsInPlay) { gameState.cardContextStack.PushCardContext(this, cardInPlay, CardContextReason.CardReacting); DeckPlacement preferredPlacement = cardInPlay.DoSpecializedActionOnGainWhileInPlay(this, gameState, card); if (!wasCardMoved && preferredPlacement != DeckPlacement.Default) { defaultPlacement = preferredPlacement; wasCardMoved = true; } gameState.cardContextStack.Pop(); } } // buys are also gains. { DeckPlacement preferredPlacement = card.DoSpecializedWhenGain(this, gameState); if (!wasCardMoved && preferredPlacement != DeckPlacement.Default) { defaultPlacement = preferredPlacement; wasCardMoved = true; } } if (gainReason == GainReason.Buy) { if (card.canOverpay) { gameState.CurrentContext.PushCardContext(this, card, CardContextReason.CardReacting); this.RequestPlayerOverpayForCard(card, gameState); gameState.CurrentContext.Pop(); } card.DoSpecializedWhenBuy(this, gameState); if (this.ownsCardWithSpecializedActionOnBuyWhileInPlay) { foreach (Card cardInPlay in this.CardsInPlay) { gameState.cardContextStack.PushCardContext(this, card, CardContextReason.CardReacting); gameLog.PushScope(); cardInPlay.DoSpecializedActionOnBuyWhileInPlay(this, gameState, card); gameLog.PopScope(); gameState.cardContextStack.Pop(); } } } this.PlaceCardFromPlacement(new CardPlacementPair(card, defaultPlacement), gameState, originalLocation); gameState.cardContextStack.Pop(); this.gameLog.PopScope(); gameState.hasCurrentPlayerGainedCard |= true; this.ownsCardThatMightProvideDiscountWhileInPlay |= card.MightProvideDiscountWhileInPlay; this.ownsCardThatHasSpecializedCleanupAtStartOfCleanup |= card.HasSpecializedCleanupAtStartOfCleanup; this.ownsCardWithSpecializedActionOnBuyWhileInPlay |= card.HasSpecializedActionOnBuyWhileInPlay; this.ownsCardWithSpecializedActionOnTrashWhileInHand |= card.HasSpecializedActionOnTrashWhileInHand; this.ownsCardWithSpecializedActionOnGainWhileInPlay |= card.HasSpecializedActionOnGainWhileInPlay; this.ownsCardWithSpecializedActionOnBuyWhileInHand |= card.HasSpecializedActionOnBuyWhileInHand; this.ownsCardWithSpecializedActionOnGainWhileInHand |= card.HasSpecializedActionOnGainWhileInHand; this.ownsCardWithSpecializedActionToCardWhileInPlay |= card.HasSpecializedActionToCardWhileInPlay; }
internal void GainCard(GameState gameState, Card card, DeckPlacement originalLocation, DeckPlacement defaultPlacement = DeckPlacement.Discard, GainReason gainReason = GainReason.Gain) { if (gainReason == GainReason.Buy) { this.gameLog.PlayerBoughtCard(this, card); } else { this.gameLog.PlayerGainedCard(this, card); } this.gameLog.PushScope(); // technically, the hovel reaction can cause hand size to change. This is not a problem though // would only be a problem if cards were added that would subsequently needed to be enumerated. bool wasCardMoved = false; if (this.ownsCardWithSpecializedActionOnBuyWhileInHand || this.ownsCardWithSpecializedActionOnGainWhileInHand) { foreach (Card cardInHand in this.Hand) { DeckPlacement preferredPlacement = (gainReason == GainReason.Buy) ? cardInHand.DoSpecializedActionOnBuyWhileInHand(this, gameState, card) : DeckPlacement.Default; if (!wasCardMoved && preferredPlacement == DeckPlacement.Default) { preferredPlacement = cardInHand.DoSpecializedActionOnGainWhileInHand(this, gameState, card); } if (!wasCardMoved && preferredPlacement != DeckPlacement.Default) { defaultPlacement = preferredPlacement; wasCardMoved = true; } } } if (this.ownsCardWithSpecializedActionOnGainWhileInPlay) { foreach (Card cardInPlay in this.CardsInPlay) { DeckPlacement preferredPlacement = cardInPlay.DoSpecializedActionOnGainWhileInPlay(this, gameState, card); if (!wasCardMoved && preferredPlacement != DeckPlacement.Default) { defaultPlacement = preferredPlacement; wasCardMoved = true; } } } // buys are also gains. { DeckPlacement preferredPlacement = card.DoSpecializedWhenGain(this, gameState); if (!wasCardMoved && preferredPlacement != DeckPlacement.Default) { defaultPlacement = preferredPlacement; wasCardMoved = true; } } if (gainReason == GainReason.Buy) { card.DoSpecializedWhenBuy(this, gameState); } this.PlaceCardFromPlacement(new CardPlacementPair(card, defaultPlacement), gameState, originalLocation); this.gameLog.PopScope(); gameState.hasCurrentPlayerGainedCard |= true; this.ownsCardThatMightProvideDiscountWhileInPlay |= card.MightProvideDiscountWhileInPlay; this.ownsCardThatHasSpecializedCleanupAtStartOfCleanup |= card.HasSpecializedCleanupAtStartOfCleanup; this.ownsCardWithSpecializedActionOnBuyWhileInPlay |= card.HasSpecializedActionOnBuyWhileInPlay; this.ownsCardWithSpecializedActionOnTrashWhileInHand |= card.HasSpecializedActionOnTrashWhileInHand; this.ownsCardWithSpecializedActionOnGainWhileInPlay |= card.HasSpecializedActionOnGainWhileInPlay; this.ownsCardWithSpecializedActionOnBuyWhileInHand |= card.HasSpecializedActionOnBuyWhileInHand; this.ownsCardWithSpecializedActionOnGainWhileInHand |= card.HasSpecializedActionOnGainWhileInHand; }