using DominionBase.Enums; using DominionBase.Piles; using DominionBase.Players; using DominionBase.Properties; using System.Diagnostics.Contracts; using System.Linq; namespace DominionBase.Cards.Nocturne { public class Changeling : Card { public Changeling() : base(Categories.Night, Source.Nocturne, Location.Kingdom, Traits.Gainer | Traits.ReactToGain | Traits.Trasher) { BaseCost = new Cost(3); } public override void SetupCard(IGame game) { Contract.Requires(game != null, "game cannot be null"); base.SetupCard(game); foreach (var player in game.Players) player.CardGained += Player_CardGained; } 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; } private void Player_CardGained(object sender, Players.CardGainEventArgs e) { var player = sender as IPlayer; var key = TypeClass.Changeling.ToString(); // This is not the card you are looking for using (var cost3 = new Currency(3)) { if (player.Phase == PhaseEnum.Setup || e.Cancelled || e.IsLostTrackOf || e.HandledBy.Contains(TypeClass.Changeling) || !(e.Game.ComputeCost(e.Card) >= cost3) || ((ISupply)e.Game.Table[TypeClass.Changeling]).TopCard != this || !((ISupply)e.Game.Table[TypeClass.Changeling]).CanGain()) return; } e.Resolvers[key] = new CardGainResolver(player, this, "ExchangeCard", Resource.ExchangeForChangeling, Player_GainOtherCard, false); } internal void Player_GainOtherCard(IPlayer player, ref Players.CardGainEventArgs e) { if (e.Card != null) { // Cancel the gain, add the card back to the Supply pile, and then Gain a Changeling instead. e.Cancelled = true; e.IsLostTrackOf = true; // Exchanging isn't a gain, so treat it specially var retrievedCard = player.RetrieveCardFrom(e.Location, e.Card); var exchangeFromSupply = player._Game.Table.FindSupplyPileByType(retrievedCard.BaseType, true); player.Lose(retrievedCard); exchangeFromSupply.AddTo(retrievedCard); var exchangeToCard = ((ISupply)player._Game.Table[TypeClass.Changeling]).Take(TypeClass.Changeling); player.AddCardInto(DeckLocation.Discard, exchangeToCard); exchangeToCard.ReceivedBy(player); player._Game.SendMessage(player, this, retrievedCard, exchangeToCard); } e.HandledBy.Add(TypeClass.Changeling); } public override void FollowInstructions(IPlayer player) { Contract.Requires(player != null, "player cannot be null"); base.FollowInstructions(player); if (player.InPlay.Contains(PhysicalCard)) { player.Trash(this, player.RetrieveCardFrom(DeckLocation.InPlay, PhysicalCard)); } var gainableSupplies = new SupplyCollection(player._Game.Table.TableEntities.FindAll(supply => supply.CanGain() && player.InPlayAndSetAside.Any(c => supply.TopCard.Name == c.Name))); var choice = new Choice(Resource.GainFromPlay, this, gainableSupplies, ChoiceOutcome.Gain, player, false); var result = player.MakeChoice(choice); if (result.Supply != null) player.Gain(result.Supply, this); } } }