using DominionBase.Enums; using DominionBase.Piles; using DominionBase.Players; using DominionBase.Properties; using System.Diagnostics.Contracts; namespace DominionBase.Cards.Menagerie { public class Falconer : Card { public Falconer() : base(Categories.Action | Categories.Reaction, Source.Menagerie, Location.Kingdom, Traits.AffectOthers | Traits.Gainer) { BaseCost = new Cost(5); } public override void TearDown(IGame game) { Contract.Requires(game != null, "game cannot be null"); base.TearDown(game); foreach (var player in game.Players) player.CardGained -= Player_CardGained; } public override void AddedTo(DeckLocation location, IPlayer player) { Contract.Requires(player != null, "player cannot be null"); base.AddedTo(location, player); if (location == DeckLocation.Hand) { var enumerator = player._Game.GetPlayersStartingWithEnumerator(player); while (enumerator.MoveNext()) { enumerator.Current.CardGained -= Player_CardGained; enumerator.Current.CardGained += Player_CardGained; } } } private void Player_CardGained(object sender, Players.CardGainEventArgs e) { var player = sender as IPlayer; var key = Type.ToString(); var uniqueTypes = (e.Card.Category & ~Categories.Card).Count(); // Already been cancelled -- don't need to process this one if (e.Cancelled || e.Resolvers.ContainsKey(key) || uniqueTypes <= 1 || e.HandledBy.Contains(this)) return; // This needs to be "Owner" & not "sender"/"player" because it's in reaction to // someone else gaining the Victory card e.Resolvers[key] = new CardGainResolver(Owner, this, "PlayCard", Resource.PlayCard.Replace("{card}", PhysicalCard.ToString()), Player_Action, false); } public override void FollowInstructions(IPlayer player) { Contract.Requires(player != null, "player cannot be null"); base.FollowInstructions(player); var thisCost = player._Game.ComputeCost(this); var supplies = new SupplyCollection(player._Game.Table.TableEntities.FindAll( s => s.CanGain() && s.CurrentCost < thisCost )); var choiceGain = new Choice(Resource.GainUpTo4ToDeck, this, supplies, ChoiceOutcome.Gain, player, false); var resultGain = player.MakeChoice(choiceGain); if (resultGain.Supply != null) player.Gain(resultGain.Supply, this, DeckLocation.Hand); } internal void Player_Action(IPlayer player, ref Players.CardGainEventArgs e) { if (player.Hand.Contains(PhysicalCard)) { player.Actions++; player.PlayCard(PhysicalCard, DeckLocation.InPlay); e.HandledBy.Add(this); } } public override void RemovedFrom(DeckLocation location, IPlayer player) { Contract.Requires(player != null, "player cannot be null"); base.RemovedFrom(location, player); foreach (var otherPlayer in player._Game.Players) otherPlayer.CardGained -= Player_CardGained; } } }