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 Mastermind : Card { private readonly List CardsPlayed = new List(); private IPlayer _turnStartedPlayer; public Mastermind() : base(Categories.Action | Categories.Duration, Source.Menagerie, Location.Kingdom, Traits.Multiplier | Traits.Terminal) { BaseCost = new Cost(5); } public override bool CanCleanUp { // If Mastermind played a Duration card but the Duration card only did something once (e.g. Tactician), then Mastermind can be cleaned up get => CardsPlayed.All(cp => cp.CanCleanUpPlayed.Count(cup => !cup) < 2) && base.CanCleanUp; } public override void TearDown(IGame game) { base.TearDown(game); if (_turnStartedPlayer != null) { _turnStartedPlayer.TurnEnded -= Player_TurnEnded; _turnStartedPlayer.TurnStarted -= Player_TurnStarted; } _turnStartedPlayer = null; } public override void FollowInstructions(IPlayer player) { Contract.Requires(player != null, "player cannot be null"); base.FollowInstructions(player); CanCleanUpPlayed.Add(false); _turnStartedPlayer = player; _turnStartedPlayer.TurnEnded += Player_TurnEnded; } private void Player_TurnEnded(object sender, TurnEndedEventArgs e) { _turnStartedPlayer.TurnEnded -= Player_TurnEnded; _turnStartedPlayer.TurnStarted += Player_TurnStarted; } protected override void ModifyDuration(IPlayer player, Card card) { base.ModifyDuration(player, card); base.ModifyDuration(player, card); base.ModifyDuration(player, card); } private void Player_TurnStarted(object sender, TurnStartedEventArgs e) { var key = ToString(); if (!e.Resolvers.ContainsKey(key)) e.Resolvers[key] = new TurnStartedResolver(e.Player, this, Resource.ResolveCard.Replace("{card}", PhysicalCard.ToString()), Player_Action, true); } internal void Player_Action(IPlayer player, ref TurnStartedEventArgs e) { CardsPlayed.Clear(); ResolveDuration(e.Player); CanCleanUpPlayed.Remove(false); e.Player.TurnStarted -= Player_TurnStarted; _turnStartedPlayer = null; } public override void ResolveDuration(IPlayer player) { Contract.Requires(player != null, "player cannot be null"); base.ResolveDuration(player); var choice = new Choice(Resource.ChooseActionPlay3x, this, player.Hand[Categories.Action], ChoiceOutcome.Select, player, minimum: 0); var result = player.MakeChoice(choice); if (result.Cards.Any()) { var cardToPlayThrice = result.Cards[0]; CardsPlayed.Add(cardToPlayThrice); cardToPlayThrice.ModifiedBy = this; player.Actions++; var previousPlayerMode = player.PutCardIntoPlay(cardToPlayThrice); var logicalCard = cardToPlayThrice.LogicalCard; player.PlayCard(cardToPlayThrice.LogicalCard, previousPlayerMode); player.Actions++; previousPlayerMode = player.PutCardIntoPlay(cardToPlayThrice, Resource.AgainFromCard.Replace("{card}", this.ToString())); player.PlayCard(logicalCard, previousPlayerMode); player.Actions++; previousPlayerMode = player.PutCardIntoPlay(cardToPlayThrice, Resource.AgainFromCard.Replace("{card}", this.ToString())); player.PlayCard(logicalCard, previousPlayerMode); } else player.PlayNothing(); } } }