using DominionBase.Enums; using DominionBase.Interfaces; using DominionBase.Piles; using DominionBase.Players; using System; using System.Collections.Generic; using System.Diagnostics.Contracts; using System.Linq; using System.Xml; namespace DominionBase.Cards.Empires2019Errata { public static class TypeClass { //public static readonly Type Overlord = typeof(Overlord); } public class Overlord : Card { public Card ClonedCard { get; private set; } private DeckLocation? _currentLocation; public Overlord() : this(Edition.Errata2019) { } public Overlord(Edition edition) : base(Categories.Action | Categories.Command, Source.Empires, Location.Kingdom, Traits.ConditionalBenefit | Traits.Component | Traits.Debts, edition: edition) { BaseCost = new Cost(debtCost: 8); } public override bool Finalize(IGame game, ISupply supply) { Contract.Requires(game != null, "game cannot be null"); if (base.Finalize(game, supply)) return true; foreach (var player in game.Players) if (!player.TokenPiles.ContainsKey(Empires.TypeClass.DebtToken)) player.TokenPiles[Empires.TypeClass.DebtToken] = new TokenCollection(); return false; } public override void AddedTo(DeckLocation location, IPlayer player) { base.AddedTo(location, player); _currentLocation = location; if (ClonedCard == null) return; switch (location) { case DeckLocation.InPlay: case DeckLocation.SetAside: ClonedCard.AddedTo(location, player); break; } } public override void RemovedFrom(DeckLocation location, IPlayer player) { Contract.Requires(player != null, "player cannot be null"); base.RemovedFrom(location, player); _currentLocation = null; if (ClonedCard == null) return; switch (location) { case DeckLocation.InPlay: case DeckLocation.SetAside: case DeckLocation.InPlayAndSetAside: ClonedCard.PhysicalCard = null; ClonedCard.RemovedFrom(location, player); ClonedCard.TearDown(player._Game); ClonedCard = null; break; } } public override Card LogicalCard => ClonedCard != null ? ClonedCard.LogicalCard : base.LogicalCard; public override Categories Category => ClonedCard?.Category ?? base.Category; public override Source Source => ClonedCard?.Source ?? base.Source; public override Location Location => ClonedCard?.Location ?? base.Location; public override Traits Traits => ClonedCard?.Traits ?? base.Traits; public override Cost BaseCost => ClonedCard != null ? ClonedCard.BaseCost : base.BaseCost; public override CardBenefit Benefit => ClonedCard != null ? ClonedCard.Benefit : base.Benefit; public override bool SuppressBenefit => ClonedCard != null ? ClonedCard.SuppressBenefit : base.SuppressBenefit; public override CardBenefit DurationBenefit => ClonedCard != null ? ClonedCard.DurationBenefit : base.DurationBenefit; public override int VictoryPoints => ClonedCard?.VictoryPoints ?? base.VictoryPoints; public override Card ModifiedBy => ClonedCard != null ? ClonedCard.ModifiedBy : base.ModifiedBy; public override ItemCollection ChainedInto => ClonedCard != null ? ClonedCard.ChainedInto : base.ChainedInto; public override bool CanCleanUp => ClonedCard?.CanCleanUp ?? base.CanCleanUp; public override int ComputeVictoryPoints(IPlayer player, IEnumerable collection) { if (ClonedCard != null) return ClonedCard.ComputeVictoryPoints(player, collection); return base.ComputeVictoryPoints(player, collection); } public override IEnumerable LookThrough(Predicate predicate) { if (ClonedCard != null) return ClonedCard.LookThrough(predicate); return base.LookThrough(predicate); } public override bool IsStackable => ClonedCard == null; public override DisplayableCollection Stack() { var cc = new DisplayableCollection { this }; if (ClonedCard != null) cc.AddRange(ClonedCard.Stack()); return cc; } public override void FollowInstructions(IPlayer player) { Contract.Requires(player != null, "player cannot be null"); if (ClonedCard == null) { base.FollowInstructions(player); var choice = new Choice("Choose a card to clone this card as", this, new SupplyCollection(player._Game.Table.TableEntities.FindAll( supply => supply.Any() && supply.TopCard.Category.HasFlag(Categories.Action) && supply.CurrentCost <= new Cost(5))), ChoiceOutcome.Select, player, false); var result = player.MakeChoice(choice); if (result.Supply != null) { player._Game.SendMessage(player, this, (Card)result.Supply.TopCard); ClonedCard = CreateInstance(result.Supply.TopCard.Type); ClonedCard.PhysicalCard = this; // This is needed in order to set up player mats & any other acutrements ClonedCard.ReceivedBy(player); // Add the card to this card's area ClonedCard.AddedTo(_currentLocation.GetValueOrDefault(DeckLocation.InPlay), player); } else player._Game.SendMessage(player, this); } if (ClonedCard != null) { player.Actions++; var previousPlayerMode = player.PutCardIntoPlay(ClonedCard); player.PlayCard(ClonedCard, previousPlayerMode); } } public override void ResolveDuration(IPlayer player) { ClonedCard?.ResolveDuration(player); } internal override XmlNode GenerateXml(XmlDocument doc, string nodeName) { var xn = base.GenerateXml(doc, nodeName); if (ClonedCard != null) xn.AppendChild(ClonedCard.GenerateXml(doc, "cloned_card")); return xn; } internal override void LoadInstance(XmlNode xnCard) { base.LoadInstance(xnCard); ClonedCard = (Card)Load(xnCard.SelectSingleNode("cloned_card")); } } }