using DominionBase.Enums; using DominionBase.Players; using DominionBase.Properties; using System.Collections.Generic; using System.Diagnostics.Contracts; using System.Linq; namespace DominionBase.Cards.Menagerie { public class AnimalFair : Card { public AnimalFair() : base(Categories.Action, Source.Menagerie, Location.Kingdom, Traits.ConditionalBenefit | Traits.PlusBuy | Traits.PlusCoin | Traits.Terminal) { BaseCost = new Cost(7, special: true); Benefit.Currency.Coin.Value = 4; } public override void SetupCard(IGame game) { Contract.Requires(game != null, "game cannot be null"); base.SetupCard(game); foreach (var player in game.Players) player.CardPaying += Player_CardPaying; } public override void TearDown(IGame game) { Contract.Requires(game != null, "game cannot be null"); base.TearDown(game); foreach (var player in game.Players) player.CardPaying -= Player_CardPaying; } public override bool CanBuy(IPlayer player, Currency currency) { Contract.Requires(player != default(IPlayer), "player cannot be null"); // If the player has an Action card in hand, they can "Buy" Animal Fair if (player.Hand[Categories.Action].Any()) return true; return base.CanBuy(player, currency); } private void Player_CardPaying(object sender, CardPayEventArgs e) { var player = sender as IPlayer; var key = TypeClass.AnimalFair; // This is not the card you are looking for if (e.Card != this || e.Resolvers.ContainsKey(key) || e.HandledBy.Contains(this)) return; e.Resolvers[key] = new CardPayResolver(player, this, Resource.ResolveCard.Replace("{card}", PhysicalCard.ToString()), (IPlayer playerAction, ref CardPayEventArgs eAction) => { var options = new List(); var payCost = Resource.PayCost.Replace("{cost}", e.Cost.ToStringInline()); if (base.CanBuy(playerAction, e.AvailableCurrency)) options.Add(payCost); if (playerAction.Hand[Categories.Action].Any()) options.Add(Resource.TrashActionFromHand); var choiceTurn = new Choice(Resource.ChooseOne, this, this, options, player); var resultTurn = player.MakeChoice(choiceTurn); if (resultTurn.Options.Any()) { if (resultTurn.Options[0] == payCost) { // Nothing special here; just return } else if (resultTurn.Options[0] == Resource.TrashActionFromHand) { // We'll pay for this another way e.Cost = new Currency(); var choiceTrash = new Choice(Resource.TrashActionFromHand, this, player.Hand[Categories.Action], ChoiceOutcome.Trash, player); var resultTrash = player.MakeChoice(choiceTrash); if (resultTrash.Cards.Any()) { player.Trash(this, player.RetrieveCardsFrom(DeckLocation.Hand, resultTrash.Cards)); } } e.HandledBy.Add(this); } }, true); } public override void FollowInstructions(IPlayer player) { Contract.Requires(player != null, "player cannot be null"); base.FollowInstructions(player); var emptyPiles = player._Game.Table.EmptySupplyPiles; if (emptyPiles > 0) player.ReceiveBenefit(this, new CardBenefit { Buys = emptyPiles }); } } }