using DominionBase.Enums; using DominionBase.Players; using DominionBase.Properties; using System.Collections.Generic; using System.Diagnostics.Contracts; using System.Linq; namespace DominionBase.Cards.Renaissance { public class Citadel : Project { private Dictionary _firstActionPlayed = new Dictionary(); public Citadel() : base(Source.Renaissance, 8, Traits.Multiplier) { } public override void TearDown(IGame game) { foreach (var cpp in PurchasedPlayers) { cpp.TurnStarted -= Player_TurnStarted; cpp.TurnEnded -= Player_TurnEnded; cpp.CardPlaying -= Player_CardPlaying; cpp.CardPlayed -= Player_CardPlayed; } _firstActionPlayed.Clear(); base.TearDown(game); } public override void Bought(IPlayer player) { Contract.Requires(player != null, "player cannot be null"); base.Bought(player); var cpp = PurchasedPlayers.Find(p => p == player); if (cpp != null) { cpp.TurnStarted -= Player_TurnStarted; cpp.TurnEnded -= Player_TurnEnded; cpp.CardPlaying -= Player_CardPlaying; cpp.CardPlayed -= Player_CardPlayed; } else PurchasedPlayers.Add(player); player.TurnStarted += Player_TurnStarted; // Only set up the CardPlaying trigger for this turn if the player hasn't played any Action cards yet // This is a rare edgecase, but that doesn't mean it can't/won't happen _firstActionPlayed[player] = player.CurrentTurn.CardsPlayed.FirstOrDefault(c => c.Category.HasFlag(Categories.Action)); if (_firstActionPlayed[player] == null) player.CardPlaying += Player_CardPlaying; player.TurnEnded += Player_TurnEnded; } private void Player_TurnStarted(object sender, TurnStartedEventArgs e) { _firstActionPlayed[e.Player] = null; e.Player.CardPlaying += Player_CardPlaying; } private void Player_TurnEnded(object sender, TurnEndedEventArgs e) { var player = sender as IPlayer; player.CardPlaying -= Player_CardPlaying; player.CardPlayed -= Player_CardPlayed; } private void Player_CardPlaying(object sender, CardPlayingEventArgs e) { var player = sender as IPlayer; if (_firstActionPlayed[player] == null) { var firstAction = e.Cards.FirstOrDefault(c => c.Category.HasFlag(Categories.Action)); if (firstAction != null) { _firstActionPlayed[player] = firstAction; e.Player.CardPlayed += Player_CardPlayed; } } } private void Player_CardPlayed(object sender, CardPlayedEventArgs e) { var player = sender as IPlayer; var key = TypeClass.Citadel; if (e.HandledBy.Contains(TypeClass.Citadel) || !e.Cards[0].Category.HasFlag(Categories.Action) || e.Player._Game.ActivePlayer != player || _firstActionPlayed[player] == null || _firstActionPlayed[player] != e.Cards[0] ) return; if (!e.Resolvers.ContainsKey(key)) e.Resolvers[key] = new CardPlayedResolver(player, this, Resource.ResolveCard.Replace("{card}", Name), Player_Action, true); } internal void Player_Action(IPlayer player, ref CardPlayedEventArgs e) { // No more this turn player.CardPlaying -= Player_CardPlaying; player.CardPlayed -= Player_CardPlayed; var cardToReplay = e.Cards[0]; cardToReplay.ChainedInto.Add(this); player.Actions++; var previousPlayerMode = player.PutCardIntoPlay(cardToReplay, Resource.AgainFromCard.Replace("{card}", this.ToString())); player.PlayCard(cardToReplay.LogicalCard, previousPlayerMode); e.HandledBy.Add(TypeClass.Citadel); } } }