using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DominionBase.Currencies;
using DominionBase.Piles;
using DominionBase.Players;
namespace DominionBase.Cards.Prosperity
{
public static class TypeClass
{
public static Type Bank = typeof(Bank);
public static Type Bishop = typeof(Bishop);
public static Type City = typeof(City);
public static Type Colony = typeof(Colony);
public static Type Contraband = typeof(Contraband);
public static Type CountingHouse = typeof(CountingHouse);
public static Type Expand = typeof(Expand);
public static Type Forge = typeof(Forge);
public static Type Goons = typeof(Goons);
public static Type GrandMarket = typeof(GrandMarket);
public static Type Hoard = typeof(Hoard);
public static Type KingsCourt = typeof(KingsCourt);
public static Type Loan = typeof(Loan);
public static Type Mint = typeof(Mint);
public static Type Monument = typeof(Monument);
public static Type Mountebank = typeof(Mountebank);
public static Type Peddler = typeof(Peddler);
public static Type Platinum = typeof(Platinum);
public static Type Quarry = typeof(Quarry);
public static Type Rabble = typeof(Rabble);
public static Type RoyalSeal = typeof(RoyalSeal);
public static Type Talisman = typeof(Talisman);
public static Type TradeRoute = typeof(TradeRoute);
public static Type Vault = typeof(Vault);
public static Type Venture = typeof(Venture);
public static Type Watchtower = typeof(Watchtower);
public static Type WorkersVillage = typeof(WorkersVillage);
public static Type ContrabandToken = typeof(ContrabandToken);
public static Type TradeRouteToken = typeof(TradeRouteToken);
public static Type VictoryToken = typeof(VictoryToken);
}
public class Bank : Card
{
public Bank()
: base("Bank", Category.Treasure, Source.Prosperity, Location.Kingdom, Group.PlusCoin)
{
this.BaseCost = new Cost(7);
this.Text = "When you play this, it's worth 1 per Treasure card you have in play (counting this).";
this.Benefit.Currency.Coin.IsVariable = true;
}
public override void Play(Player player)
{
base.Play(player);
CardBenefit benefit = new CardBenefit();
benefit.Currency += new Coin(player.Tableau[Category.Treasure].Count);
player.ReceiveBenefit(this, benefit);
}
}
public class Bishop : Card
{
public Bishop()
: base("Bishop", Category.Action, Source.Prosperity, Location.Kingdom, Group.Component | Group.DeckReduction | Group.PlusCoin | Group.Trash | Group.RemoveCurses | Group.AffectOthers | Group.Terminal)
{
this.BaseCost = new Cost(4);
this.Benefit.Currency.Coin.Value = 1;
this.Benefit.VictoryPoints = 1;
this.Text = "Trash a card from your hand.+ equal to half its cost in coins, rounded down.Each other player may trash a card from his hand.";
}
internal override void ReceivedBy(Player player)
{
base.ReceivedBy(player);
if (!player.TokenPiles.ContainsKey(TypeClass.VictoryToken))
player.TokenPiles[TypeClass.VictoryToken] = new TokenCollection();
}
public override void Play(Player player)
{
base.Play(player);
Choice choice = new Choice("Trash a card. + equal to half its cost in coins, rounded down.", this, player.Hand, player);
ChoiceResult result = player.MakeChoice(choice);
if (result.Cards.Count > 0)
{
Card trash = player.RetrieveCardFrom(DeckLocation.Hand, result.Cards[0]);
Cost trashedCardCost = player._Game.Cost(trash);
player.Trash(trash);
player.ReceiveBenefit(this, new CardBenefit() { VictoryPoints = trashedCardCost.Coin.Value / 2 });
}
IEnumerator enumerator = player._Game.GetPlayersStartingWithEnumerator(player);
enumerator.MoveNext(); // skip active player
while (enumerator.MoveNext())
{
Player otherPlayer = enumerator.Current;
Choice choicePlayer = new Choice("Trash a card if you wish", this, otherPlayer.Hand, otherPlayer, false, 0, 1);
ChoiceResult resultPlayer = otherPlayer.MakeChoice(choicePlayer);
if (resultPlayer.Cards.Count > 0)
{
otherPlayer.Trash(otherPlayer.RetrieveCardFrom(DeckLocation.Hand, resultPlayer.Cards[0]));
}
}
}
}
public class City : Card
{
public City()
: base("City",
Category.Action,
Source.Prosperity,
Location.Kingdom,
Group.PlusCard | Group.PlusAction | Group.PlusMultipleActions | Group.PlusCoin | Group.PlusBuy)
{
this.BaseCost = new Cost(5);
this.Benefit.Actions = 2;
this.Benefit.Cards = 1;
this.Text = "If there are one or more empty Supply piles, +1Card. If there are two or more, +1 and +1Buy.";
}
public override void Play(Player player)
{
int emptyPiles = player._Game.Table.Supplies.Values.Count(s => s.Count == 0);
if (emptyPiles > 0)
{
this.Benefit.Cards = 2;
if (emptyPiles > 1)
{
this.Benefit.Currency.Coin.Value = 1;
this.Benefit.Buys = 1;
}
}
base.Play(player);
}
}
public class Colony : Card
{
public Colony()
: base("Colony", Category.Victory, Source.Prosperity, Location.General)
{
this.BaseCost = new Cost(11);
this.VictoryPoints = 10;
}
public override Boolean IsEndgameTriggered(Supply supply)
{
return (supply.Count == 0);
}
}
public class Contraband : Card
{
private Supply.BuyCheckEventHandler _BuyCheckEventHandler = null;
private Supply _Supply = null;
public Contraband()
: base("Contraband", Category.Treasure, Source.Prosperity, Location.Kingdom, Group.PlusBuy | Group.PlusCoin)
{
this.BaseCost = new Cost(5);
this.Benefit.Buys = 1;
this.Benefit.Currency.Coin.Value = 3;
this.Text = "When you play this, the player to your left names a card.You can't buy that card this turn.";
}
internal override void TearDown()
{
base.TearDown();
_Supply = null;
}
public override void Play(Player player)
{
base.Play(player);
// Get the player to my left
Player playerToLeft = player._Game.GetPlayerFromIndex(player, 1);
Choice choice = new Choice(String.Format("Name a card {0} can't buy", player), this, player._Game.Table.Supplies, player, false);
ChoiceResult result = playerToLeft.MakeChoice(choice);
player._Game.SendMessage(playerToLeft, this, result.Supply);
_BuyCheckEventHandler = new Supply.BuyCheckEventHandler(Supply_BuyCheck);
_Supply = result.Supply;
_Supply.AddToken(new ContrabandToken());
_Supply.BuyCheck += _BuyCheckEventHandler;
}
private void Supply_BuyCheck(object sender, BuyCheckEventArgs e)
{
// Already been cancelled -- don't need to process this one
if (e.Cancelled)
return;
e.Cancelled = true;
return;
}
public override void RemovedFrom(DeckLocation location, Player player)
{
base.RemovedFrom(location, player);
if (_BuyCheckEventHandler != null)
_Supply.BuyCheck -= _BuyCheckEventHandler;
_BuyCheckEventHandler = null;
_Supply = null;
}
}
public class ContrabandToken : Token
{
public ContrabandToken()
: base("X", "Unbuyable")
{
}
public override string Title { get { return "This card cannot be bought this turn"; } }
public override Boolean IsTemporary { get { return true; } }
}
public class CountingHouse : Card
{
public CountingHouse()
: base("Counting House", Category.Action, Source.Prosperity, Location.Kingdom, Group.PlusCard | Group.Terminal)
{
this.BaseCost = new Cost(5);
this.Text = "Look through your discard pile, reveal any number of Copper cards from it, and put them into your hand.";
}
public override void Play(Player player)
{
base.Play(player);
int copperCount = player.DiscardPile.LookThrough(c => c.CardType == Cards.Universal.TypeClass.Copper).Count;
List options = new List();
for (int i = 0; i <= copperCount; i++)
options.Add(i.ToString());
Choice choice = new Choice("How many Copper cards would you like to reveal and put into your hand?", this, new CardCollection() { this }, options, player);
ChoiceResult result = player.MakeChoice(choice);
int number = int.Parse(result.Options[0]);
player.AddCardsInto(DeckLocation.Revealed, player.RetrieveCardsFrom(DeckLocation.Discard, Cards.Universal.TypeClass.Copper, number));
player.AddCardsToHand(DeckLocation.Revealed);
}
}
public class Expand : Card
{
public Expand()
: base("Expand", Category.Action, Source.Prosperity, Location.Kingdom, Group.Gain | Group.Trash | Group.RemoveCurses | Group.Terminal)
{
this.BaseCost = new Cost(7);
this.Text = "Trash a card from your hand.Gain a card costing up to 3 more than the trashed card.";
}
public override void Play(Player player)
{
base.Play(player);
Choice choiceTrash = new Choice("Choose a card to trash", this, player.Hand, player);
ChoiceResult resultTrash = player.MakeChoice(choiceTrash);
player.Trash(player.RetrieveCardsFrom(DeckLocation.Hand, resultTrash.Cards));
if (resultTrash.Cards.Count > 0)
{
Cost trashedCardCost = player._Game.Cost(resultTrash.Cards[0]);
SupplyCollection gainableSupplies = player._Game.Table.Supplies.FindAll(supply => supply.CanGain() && supply.CurrentCost <= (trashedCardCost + new Coin(3)));
Choice choice = new Choice("Gain a card", this, gainableSupplies, player, false);
ChoiceResult result = player.MakeChoice(choice);
if (result.Supply != null)
player.Gain(result.Supply);
}
}
}
public class Forge : Card
{
public Forge()
: base("Forge", Category.Action, Source.Prosperity, Location.Kingdom, Group.DeckReduction | Group.Gain | Group.Trash | Group.RemoveCurses | Group.Terminal)
{
this.BaseCost = new Cost(7);
this.Text = "Trash any number of cards from your hand. Gain a card with cost exactly equal to the total cost in coins of the trashed cards.";
}
public override void Play(Player player)
{
base.Play(player);
Choice choiceTrash = new Choice("Choose any number of cards to trash", this, player.Hand, player, false, 0, player.Hand.Count);
ChoiceResult resultTrash = player.MakeChoice(choiceTrash);
player.Trash(player.RetrieveCardsFrom(DeckLocation.Hand, resultTrash.Cards));
Cost totalCost = new Cost();
foreach (Card card in resultTrash.Cards)
totalCost += player._Game.Cost(card);
SupplyCollection gainableSupplies = player._Game.Table.Supplies.FindAll(supply => supply.CanGain() && supply.CurrentCost == totalCost);
Choice choice = new Choice("Gain a card", this, gainableSupplies, player, false);
ChoiceResult result = player.MakeChoice(choice);
if (result.Supply != null)
player.Gain(result.Supply);
}
}
public class Goons : Card
{
private Player.CardBoughtEventHandler _CardBoughtHandler = null;
public Goons()
: base("Goons", Category.Action | Category.Attack, Source.Prosperity, Location.Kingdom, Group.Component | Group.PlusCoin | Group.PlusBuy | Group.Discard | Group.Terminal)
{
this.BaseCost = new Cost(6);
this.Benefit.Buys = 1;
this.Benefit.Currency.Coin.Value = 2;
this.Text = "Each other player discards down to 3 cards in his hand.
While this is in play, when you buy a card, +1.";
}
internal override void ReceivedBy(Player player)
{
base.ReceivedBy(player);
if (!player.TokenPiles.ContainsKey(TypeClass.VictoryToken))
player.TokenPiles[TypeClass.VictoryToken] = new TokenCollection();
}
public override void Play(Player player)
{
base.Play(player);
IEnumerator enumerator = player._Game.GetPlayersStartingWithEnumerator(player);
enumerator.MoveNext();
while (enumerator.MoveNext())
{
Player attackee = enumerator.Current;
// Skip if the attack is blocked (Moat, Lighthouse, etc.)
if (this.IsAttackBlocked[attackee])
continue;
Choice choice = new Choice("Choose cards to discard. You must discard down to 3 cards in hand", this, attackee.Hand, attackee, false, attackee.Hand.Count - 3, attackee.Hand.Count - 3);
ChoiceResult result = attackee.MakeChoice(choice);
attackee.Discard(DeckLocation.Hand, result.Cards);
}
}
public override void AddedTo(DeckLocation location, Player player)
{
base.AddedTo(location, player);
if (location == DeckLocation.Tableau)
{
_CardBoughtHandler = new Player.CardBoughtEventHandler(player_CardBought);
player.CardBought += _CardBoughtHandler;
}
}
void player_CardBought(object sender, CardBuyEventArgs e)
{
// Already been cancelled or processed -- don't need to process this one
if (e.Cancelled || e.HandledBy.Contains(this))
return;
e.HandledBy.Add(this);
(sender as Player).ReceiveBenefit(this, new CardBenefit() { VictoryPoints = 1 });
}
public override void RemovedFrom(DeckLocation location, Player player)
{
base.RemovedFrom(location, player);
if (_CardBoughtHandler != null)
player.CardBought -= _CardBoughtHandler;
_CardBoughtHandler = null;
}
}
public class GrandMarket : Card
{
public GrandMarket()
: base("Grand Market", Category.Action, Source.Prosperity, Location.Kingdom, Group.PlusCard | Group.PlusAction | Group.PlusCoin | Group.PlusBuy)
{
this.BaseCost = new Cost(6);
this.Benefit.Actions = 1;
this.Benefit.Cards = 1;
this.Benefit.Buys = 1;
this.Benefit.Currency.Coin.Value = 2;
this.Text = "
You can't buy this if you have any Copper in play.";
}
internal override bool CanBuy(Player player)
{
return (player.Tableau[Cards.Universal.TypeClass.Copper].Count == 0);
}
}
public class Hoard : Card
{
private Player.CardBoughtEventHandler _CardBoughtHandler = null;
public Hoard()
: base("Hoard", Category.Treasure, Source.Prosperity, Location.Kingdom, Group.Gain | Group.PlusCoin)
{
this.BaseCost = new Cost(6);
this.Benefit.Currency.Coin.Value = 2;
this.Text = "
While this is in play, when you buy a Victory card, gain a Gold.";
}
public override void Play(Player player)
{
base.Play(player);
}
public override void AddedTo(DeckLocation location, Player player)
{
base.AddedTo(location, player);
if (location == DeckLocation.Tableau)
{
_CardBoughtHandler = new Player.CardBoughtEventHandler(player_CardBought);
player.CardBought += _CardBoughtHandler;
}
}
void player_CardBought(object sender, CardBuyEventArgs e)
{
if (e.HandledBy.Contains(this) || e.Actions.ContainsKey(TypeClass.Hoard) ||
(e.Card.Category & Category.Victory) != Category.Victory || !e.Game.Table.Gold.CanGain())
return;
Player player = sender as Player;
e.Actions[TypeClass.Hoard] = new Players.CardBuyAction(this.Owner, this, "gain a Gold", player_BuyWithHoard, true);
}
internal void player_BuyWithHoard(Player player, ref Players.CardBuyEventArgs e)
{
player.Gain(e.Game.Table.Gold);
e.HandledBy.Add(this);
}
public override void RemovedFrom(DeckLocation location, Player player)
{
base.RemovedFrom(location, player);
if (_CardBoughtHandler != null)
player.CardBought -= _CardBoughtHandler;
_CardBoughtHandler = null;
}
}
public class KingsCourt : Card
{
public KingsCourt()
: base("King's Court", Category.Action, Source.Prosperity, Location.Kingdom)
{
this.BaseCost = new Cost(7);
this.Text = "You may choose an Action card in your hand. Play it three times.";
}
public override void Play(Player player)
{
base.Play(player);
Choice choice = new Choice(String.Format("You may choose an Action card to play three times", player), this, player.Hand[Cards.Category.Action], player, false, 0, 1);
ChoiceResult result = player.MakeChoice(choice);
if (result.Cards.Count > 0)
{
result.Cards[0].ModifiedBy = this;
player.Actions++;
player.PlayCardInternal(result.Cards[0]);
player.Actions++;
player.PlayCardInternal(result.Cards[0], " again");
player.Actions++;
player.PlayCardInternal(result.Cards[0], " again");
}
else
player.PlayNothing();
}
protected override void Modify(Player player, Card card)
{
base.Modify(player, card);
base.Modify(player, card);
base.Modify(player, card);
}
}
public class Loan : Card
{
public Loan()
: base("Loan", Category.Treasure, Source.Prosperity, Location.Kingdom, Group.DeckReduction | Group.Trash | Group.PlusCoin | Group.Discard)
{
this.BaseCost = new Cost(3);
this.Benefit.Currency.Coin.Value = 1;
this.Text = "When you play this, reveal cards from your deck until you reveal a Treasure.Discard it or trash it.Discard the other cards.";
}
public override void Play(Player player)
{
base.Play(player);
player.BeginDrawing();
while (player.Revealed[Category.Treasure].Count < 1 && player.CanDraw)
player.Draw(DeckLocation.Revealed);
player.EndDrawing();
CardCollection treasureCards = player.Revealed[c => (c.Category & Category.Treasure) == Category.Treasure];
if (treasureCards.Count > 0)
{
Card card = treasureCards[0];
Choice choice = new Choice(String.Format("You revealed a {0}.", card.Name), this, new CardCollection() { card }, new List() { "Discard it", "Trash it" }, player);
ChoiceResult result = player.MakeChoice(choice);
if (result.Options[0] == "Discard it")
{
player.Discard(DeckLocation.Revealed, card);
}
else if (result.Options[0] == "Trash it")
{
player.Trash(player.RetrieveCardFrom(DeckLocation.Revealed, card));
}
}
player.DiscardRevealed();
}
}
public class Mint : Card
{
private Dictionary _CardBoughtHandlers = new Dictionary();
public Mint()
: base("Mint", Category.Action, Source.Prosperity, Location.Kingdom, Group.DeckReduction | Group.Gain | Group.Trash | Group.Terminal)
{
this.BaseCost = new Cost(5);
this.Text = "You may reveal a Treasure card from your hand. Gain a copy of it.
When you buy this, trash all Treasures you have in play.";
}
internal override void TearDown()
{
base.TearDown();
foreach (Player playerLoop in _CardBoughtHandlers.Keys)
playerLoop.CardBought -= _CardBoughtHandlers[playerLoop];
_CardBoughtHandlers.Clear();
}
public override void Play(Player player)
{
base.Play(player);
if (player.Hand[Category.Treasure].Count > 0)
{
Choice choice = new Choice("You may reveal a Treasure card to gain a copy of it.", this, player.Hand[Category.Treasure], player, false, 0, 1);
ChoiceResult result = player.MakeChoice(choice);
if (result.Cards.Count > 0)
{
player.AddCardInto(DeckLocation.Revealed, player.RetrieveCardFrom(DeckLocation.Hand, result.Cards[0]));
player.AddCardInto(DeckLocation.Hand, player.RetrieveCardFrom(DeckLocation.Revealed, result.Cards[0]));
Supply supply = player._Game.Table.FindSupplyPileByCard(result.Cards[0], true);
if (supply != null)
player.Gain(supply);
}
}
}
public override void AddedToSupply(Game game, Supply supply)
{
base.AddedToSupply(game, supply);
ResetTriggers(game);
}
private void ResetTriggers(Game game)
{
IEnumerator enumPlayers = game.GetPlayersStartingWithActiveEnumerator();
while (enumPlayers.MoveNext())
{
_CardBoughtHandlers[enumPlayers.Current] = new Player.CardBoughtEventHandler(player_CardBought);
enumPlayers.Current.CardBought += _CardBoughtHandlers[enumPlayers.Current];
}
}
void player_CardBought(object sender, Players.CardBuyEventArgs e)
{
// This is not the card you are looking for
if (e.Card != this || e.Actions.ContainsKey(TypeClass.Mint))
return;
Player player = sender as Player;
e.Actions[TypeClass.Mint] = new Players.CardBuyAction(this.Owner, this, "trash all Treasures in play", player_BuyMint, true);
}
internal void player_BuyMint(Player player, ref Players.CardBuyEventArgs e)
{
player.Trash(player.RetrieveCardsFrom(DeckLocation.Tableau, Category.Treasure));
player.Trash(player.RetrieveCardsFrom(DeckLocation.PreviousTableau, Category.Treasure));
e.HandledBy.Add(TypeClass.Mint);
// Clear out the Event Triggers -- this only happens when its Gained, so we don't care any more
foreach (Player playerLoop in _CardBoughtHandlers.Keys)
playerLoop.CardBought -= _CardBoughtHandlers[playerLoop];
_CardBoughtHandlers.Clear();
}
}
public class Monument : Card
{
public Monument()
: base("Monument", Category.Action, Source.Prosperity, Location.Kingdom, Group.Component | Group.PlusCoin | Group.Terminal)
{
this.BaseCost = new Cost(4);
this.Benefit.Currency.Coin.Value = 2;
this.Benefit.VictoryPoints = 1;
}
internal override void ReceivedBy(Player player)
{
base.ReceivedBy(player);
if (!player.TokenPiles.ContainsKey(TypeClass.VictoryToken))
player.TokenPiles[TypeClass.VictoryToken] = new TokenCollection();
}
}
public class Mountebank : Card
{
public Mountebank()
: base("Mountebank", Category.Action | Category.Attack, Source.Prosperity, Location.Kingdom, Group.PlusCurses | Group.PlusCoin | Group.Discard | Group.Terminal)
{
this.BaseCost = new Cost(5);
this.Benefit.Currency.Coin.Value = 2;
this.Text = "Each other player may discard a Curse. If he doesn't, he gains a Curse and a Copper.";
}
public override void Play(Player player)
{
base.Play(player);
// Perform attack on every other player
IEnumerator enumerator = player._Game.GetPlayersStartingWithEnumerator(player);
enumerator.MoveNext();
while (enumerator.MoveNext())
{
Player attackee = enumerator.Current;
// Skip if the attack is blocked (Moat, Lighthouse, etc.)
if (this.IsAttackBlocked[attackee])
continue;
Boolean discardedCurse = false;
if (attackee.Hand[Category.Curse].Count > 0)
{
Choice choice = new Choice("Do you want to discard a Curse or gain a Curse and a Copper?", this, new CardCollection() { this }, new List() { "Discard Curse", "Gain Curse & Copper" }, attackee);
ChoiceResult result = attackee.MakeChoice(choice);
if (result.Options[0] == "Discard Curse")
{
discardedCurse = true;
attackee.Discard(DeckLocation.Hand, Cards.Universal.TypeClass.Curse, 1);
}
}
if (!discardedCurse)
{
attackee.Gain(player._Game.Table.Curse);
attackee.Gain(player._Game.Table.Copper);
}
}
}
}
public class Peddler : Card
{
private Dictionary _CardGainedHandlers = new Dictionary();
private Game.CostComputeEventHandler _CostComputeEventHandler = null;
public Peddler()
: base("Peddler", Category.Action, Source.Prosperity, Location.Kingdom, Group.PlusCard | Group.PlusAction | Group.PlusCoin | Group.ModifyCost)
{
this.BaseCost = new Cost(8, true);
this.Benefit.Cards = 1;
this.Benefit.Actions = 1;
this.Benefit.Currency.Coin.Value = 1;
this.Text = "
During your Buy phase, this costs 2 less per Action card you have in play, but not less than 0.";
}
internal override void TearDown()
{
base.TearDown();
foreach (Player playerLoop in _CardGainedHandlers.Keys)
playerLoop.CardGained -= _CardGainedHandlers[playerLoop];
_CardGainedHandlers.Clear();
}
public override void AddedToSupply(Game game, Supply supply)
{
base.AddedToSupply(game, supply);
ResetTriggers(game);
}
private void ResetTriggers(Game game)
{
IEnumerator enumPlayers = game.GetPlayersStartingWithActiveEnumerator();
while (enumPlayers.MoveNext())
{
_CardGainedHandlers[enumPlayers.Current] = new Player.CardGainedEventHandler(player_CardGained);
enumPlayers.Current.CardGained += _CardGainedHandlers[enumPlayers.Current];
}
if (_CostComputeEventHandler == null)
{
_CostComputeEventHandler = new Game.CostComputeEventHandler(peddler_CostCompute);
game.CostCompute += _CostComputeEventHandler;
}
}
void player_CardGained(object sender, Players.CardGainEventArgs e)
{
// This is not the card you are looking for
if (e.Card != this)
return;
// Clear out the Event Triggers -- the cost computation only matters when it's in the Supply
foreach (Player playerLoop in _CardGainedHandlers.Keys)
playerLoop.CardGained -= _CardGainedHandlers[playerLoop];
_CardGainedHandlers.Clear();
if (_CostComputeEventHandler != null)
_CostComputeEventHandler = null;
}
void peddler_CostCompute(object sender, CostComputeEventArgs e)
{
if (e.Card != this)
return;
Game game = sender as Game;
if (game.ActivePlayer != null &&
(game.ActivePlayer.Phase == PhaseEnum.Buy || game.ActivePlayer.Phase == PhaseEnum.Treasure))
{
int actionCardsInPlay = game.ActivePlayer.Tableau[Cards.Category.Action].Count + game.ActivePlayer.PreviousTableau[Cards.Category.Action].Count;
e.Cost.Coin -= 2 * actionCardsInPlay;
}
}
}
public class Platinum : Card
{
public Platinum()
: base("Platinum", Category.Treasure, Source.Prosperity, Location.General)
{
this.BaseCost = new Cost(9);
this.Benefit.Currency.Coin.Value = 5;
}
}
public class Quarry : Card
{
private Game.CostComputeEventHandler _CostComputeEventHandler = null;
public Quarry()
: base("Quarry", Category.Treasure, Source.Prosperity, Location.Kingdom, Group.ModifyCost | Group.PlusCoin)
{
this.BaseCost = new Cost(4);
this.Benefit.Currency.Coin.Value = 1;
this.Text = "
While this is in play, Action cards cost 2 less, but not less than 0";
}
public override void Play(Player player)
{
base.Play(player);
}
public override void AddedTo(DeckLocation location, Player player)
{
base.AddedTo(location, player);
if (location == DeckLocation.Tableau)
{
_CostComputeEventHandler = new Game.CostComputeEventHandler(player_QuarryInPlayArea);
player._Game.CostCompute += _CostComputeEventHandler;
}
}
void player_QuarryInPlayArea(object sender, CostComputeEventArgs e)
{
if ((e.Card.Category & Cards.Category.Action) == Cards.Category.Action)
e.Cost.Coin -= 2;
}
public override void RemovedFrom(DeckLocation location, Player player)
{
base.RemovedFrom(location, player);
if (_CostComputeEventHandler != null)
player._Game.CostCompute -= _CostComputeEventHandler;
_CostComputeEventHandler = null;
}
}
public class Rabble : Card
{
public Rabble()
: base("Rabble", Category.Action | Category.Attack, Source.Prosperity, Location.Kingdom, Group.CardOrdering | Group.PlusCard | Group.Discard | Group.Terminal)
{
this.BaseCost = new Cost(5);
this.Benefit.Cards = 3;
this.Text = "Each other player reveals the top 3 cards of his deck, discards the revealed Actions and Treasures, and puts the rest back on top in any order he chooses.";
}
public override void Play(Player player)
{
base.Play(player);
// Perform attack on every other player
IEnumerator enumerator = player._Game.GetPlayersStartingWithEnumerator(player);
enumerator.MoveNext();
while (enumerator.MoveNext())
{
Player attackee = enumerator.Current;
// Skip if the attack is blocked (Moat, Lighthouse, etc.)
if (this.IsAttackBlocked[attackee])
continue;
attackee.Draw(3, DeckLocation.Revealed);
Predicate actionsTreasures = (c =>
(c.Category & Category.Action) == Category.Action ||
(c.Category & Category.Treasure) == Category.Treasure);
attackee.Discard(DeckLocation.Revealed, actionsTreasures);
Choice replaceChoice = new Choice("Choose order of cards to put back on your deck", this, attackee.Revealed, player, true, attackee.Revealed.Count, attackee.Revealed.Count);
ChoiceResult replaceResult = attackee.MakeChoice(replaceChoice);
attackee.AddCardsToDeck(attackee.RetrieveCardsFrom(DeckLocation.Revealed, replaceResult.Cards), DeckPosition.Top);
}
}
}
public class RoyalSeal : Card
{
private Player.CardGainedEventHandler _CardGainedHandler = null;
public RoyalSeal()
: base("Royal Seal", Category.Treasure, Source.Prosperity, Location.Kingdom, Group.CardOrdering | Group.PlusCoin)
{
this.BaseCost = new Cost(5);
this.Benefit.Currency.Coin.Value = 2;
this.Text = "
While this is in play, when you gain a card, you may put that card on top of your deck.";
}
public override void AddedTo(DeckLocation location, Player player)
{
base.AddedTo(location, player);
if (location == DeckLocation.Tableau)
{
_CardGainedHandler = new Player.CardGainedEventHandler(player_CardGained);
player.CardGained += _CardGainedHandler;
}
}
void player_CardGained(object sender, Players.CardGainEventArgs e)
{
Player player = sender as Player;
// Already been cancelled -- don't need to process this one
if (e.Cancelled || e.Actions.ContainsKey(TypeClass.RoyalSeal))
return;
e.Actions[TypeClass.RoyalSeal] = new Players.CardGainAction(this.Owner, this, "Put it on top your deck", player_Action, false);
}
internal void player_Action(Player player, ref Players.CardGainEventArgs e)
{
e.Cancelled = true;
e.Location = DeckLocation.Deck;
e.Position = DeckPosition.Top;
e.HandledBy.Add(TypeClass.RoyalSeal);
}
public override void RemovedFrom(DeckLocation location, Player player)
{
base.RemovedFrom(location, player);
if (_CardGainedHandler != null)
player.CardGained -= _CardGainedHandler;
_CardGainedHandler = null;
}
}
public class Talisman : Card
{
private Player.CardBoughtEventHandler _CardBoughtHandler = null;
public Talisman()
: base("Talisman", Category.Treasure, Source.Prosperity, Location.Kingdom, Group.Gain | Group.PlusCoin)
{
this.BaseCost = new Cost(4);
this.Benefit.Currency.Coin.Value = 1;
this.Text = "
While this is in play, when you buy a card costing 4 or less that is not a Victory card, gain a copy of it.";
}
public override void AddedTo(DeckLocation location, Player player)
{
base.AddedTo(location, player);
if (location == DeckLocation.Tableau)
{
_CardBoughtHandler = new Player.CardBoughtEventHandler(player_CardBought);
player.CardBought += _CardBoughtHandler;
}
}
void player_CardBought(object sender, CardBuyEventArgs e)
{
// Already been cancelled -- don't need to process this one
if (e.Cancelled)
return;
if (e.HandledBy.Contains(this) || e.Actions.ContainsKey(TypeClass.Talisman))
return;
if ((e.Card.Category & Category.Victory) != Category.Victory && e.Game.Table[e.Card].CurrentCost <= new Coin(4))
{
Player player = sender as Player;
e.Actions[TypeClass.Talisman] = new Players.CardBuyAction(this.Owner, this, String.Format("Gain a copy of {0}", e.Card), player_GainFromTalisman, true);
}
}
internal void player_GainFromTalisman(Player player, ref Players.CardBuyEventArgs e)
{
Supply supply = e.Game.Table[e.Card];
if (supply != null && supply.CanGain() && supply.TopCard.Name == e.Card.Name)
player.Gain(e.Game.Table[e.Card]);
e.HandledBy.Add(this);
}
public override void RemovedFrom(DeckLocation location, Player player)
{
base.RemovedFrom(location, player);
if (_CardBoughtHandler != null)
player.CardBought -= _CardBoughtHandler;
_CardBoughtHandler = null;
}
}
public class TradeRoute : Card
{
public TradeRoute()
: base("Trade Route", Category.Action, Source.Prosperity, Location.Kingdom, Group.Component | Group.DeckReduction | Group.PlusCoin | Group.PlusBuy | Group.Trash | Group.RemoveCurses | Group.Terminal)
{
this.BaseCost = new Cost(3);
this.Benefit.Buys = 1;
this.Text = "+1 per token on the Trade Route mat.Trash a card from your hand.
Setup: Put a token on each Victory card Supply pile. When a card is gained from that pile, move the token to the Trade Route mat.";
}
public override void Setup(Game game, Supply supply)
{
base.Setup(game, supply);
foreach (Supply sVictory in game.Table.Supplies.Values)
{
if ((sVictory.Randomizer.Category & Category.Victory) == Category.Victory)
sVictory.AddToken(new TradeRouteToken());
}
game.Table.TokenPiles[TypeClass.TradeRouteToken] = new TokenCollection();
}
public override void Play(Player player)
{
base.Play(player);
Choice choice = new Choice("Trash a card.", this, player.Hand, player);
ChoiceResult result = player.MakeChoice(choice);
if (result.Cards.Count > 0)
player.Trash(player.RetrieveCardFrom(DeckLocation.Hand, result.Cards[0]));
CardBenefit benefit = new CardBenefit();
benefit.Currency += new Coin(player._Game.Table.TokenPiles[TypeClass.TradeRouteToken].Count);
player.ReceiveBenefit(this, benefit);
}
}
public class TradeRouteToken : Token
{
public Boolean Placed = true;
public Boolean Used = false;
public TradeRouteToken()
: base("T", "Trade Route token")
{
}
public override Boolean Gaining()
{
if (!Used)
{
Used = true;
return true;
}
return false;
}
public override string Title { get { return "Once a card is gained from this supply pile, this token will get added to the Trade Route Mat"; } }
}
public class Vault : Card
{
public Vault()
: base("Vault", Category.Action, Source.Prosperity, Location.Kingdom, Group.PlusCard | Group.PlusCoin | Group.Discard | Group.AffectOthers | Group.Terminal)
{
this.BaseCost = new Cost(5);
this.Benefit.Cards = 2;
this.Text = "Discard any number of cards. +1 per card discarded.Each other player may discard 2 cards. If he does, he draws a card.";
}
public override void Play(Player player)
{
base.Play(player);
Choice choice = new Choice("Discard any number of cards. +1 per card discarded.", this, player.Hand, player, false, 0, player.Hand.Count);
ChoiceResult result = player.MakeChoice(choice);
player.Discard(DeckLocation.Hand, result.Cards);
CardBenefit benefit = new CardBenefit();
benefit.Currency += new Coin(result.Cards.Count);
player.ReceiveBenefit(this, benefit);
IEnumerator enumerator = player._Game.GetPlayersStartingWithEnumerator(player);
enumerator.MoveNext(); // skip active player
while (enumerator.MoveNext())
{
Player otherPlayer = enumerator.Current;
if (otherPlayer.Hand.Count >= 2)
{
Choice choicePlayer = Choice.CreateYesNoChoice("Do you want to discard 2 cards to draw 1 card?", this, otherPlayer);
ChoiceResult resultPlayer = otherPlayer.MakeChoice(choicePlayer);
if (resultPlayer.Options[0] == "Yes")
{
Choice choiceDiscard = new Choice("Choose 2 cards to discard", this, otherPlayer.Hand, otherPlayer, false, 2, 2);
ChoiceResult discards = otherPlayer.MakeChoice(choiceDiscard);
otherPlayer.Discard(DeckLocation.Hand, discards.Cards);
otherPlayer.Draw(DeckLocation.Hand);
}
}
}
this.Benefit.Currency.Coin.Value = 0;
}
}
public class Venture : Card
{
public Venture()
: base("Venture", Category.Treasure, Source.Prosperity, Location.Kingdom, Group.PlusCard | Group.PlusCoin | Group.Discard)
{
this.BaseCost = new Cost(5);
this.Benefit.Currency.Coin.Value = 1;
this.Text = "When you play this, reveal cards from your deck until you reveal a Treasure. Discard the other cards.Play that Treasure.";
}
public override void Play(Player player)
{
base.Play(player);
player.BeginDrawing();
while (player.Revealed[Category.Treasure].Count < 1 && player.CanDraw)
player.Draw(DeckLocation.Revealed);
player.EndDrawing();
CardCollection cards = player.Revealed[Cards.Category.Treasure];
player.DiscardRevealed(c => !cards.Contains(c));
if (cards.Count > 0)
player.PlayCardInternal(cards[0]);
}
}
public class VictoryToken : Token
{
public VictoryToken()
: base("", "Victory Point chit")
{
}
public override string Title { get { return "Worth 1 at the end of the game"; } }
}
public class Watchtower : Card
{
private Player.CardGainedEventHandler _CardGainedHandler = null;
public Watchtower()
: base("Watchtower",
Category.Action | Category.Reaction,
Source.Prosperity,
Location.Kingdom,
Group.ReactToGain | Group.Defense | Group.CardOrdering | Group.PlusCard | Group.Trash | Group.Terminal)
{
this.BaseCost = new Cost(3);
this.Text = "Draw until you have 6 cards in hand.
When you gain a card, you may reveal this from your hand. If you do, either trash that card, or put it on top of your deck.";
}
public override void Play(Player player)
{
base.Play(player);
player.Draw(6 - player.Hand.Count, DeckLocation.Hand);
}
public override void AddedTo(DeckLocation location, Player player)
{
base.AddedTo(location, player);
if (location == DeckLocation.Hand)
{
_CardGainedHandler = new Player.CardGainedEventHandler(player_CardGained);
player.CardGained += _CardGainedHandler;
}
}
void player_CardGained(object sender, Players.CardGainEventArgs e)
{
Player player = sender as Player;
// Already been cancelled -- don't need to process this one
if (e.Cancelled || !player.Hand.Contains(this) || e.Actions.ContainsKey(TypeClass.Watchtower))
return;
e.Actions[TypeClass.Watchtower] = new Players.CardGainAction(this.Owner, this, String.Format("Reveal {0}", this), player_RevealWatchtower, false);
}
internal void player_RevealWatchtower(Player player, ref Players.CardGainEventArgs e)
{
player.AddCardInto(DeckLocation.Revealed, player.RetrieveCardFrom(DeckLocation.Hand, this));
player.AddCardInto(DeckLocation.Hand, player.RetrieveCardFrom(DeckLocation.Revealed, this));
Choice trashChoice = new Choice(String.Format("Trash {0} or put it on top of your deck?", e.Card), this, new CardCollection() { e.Card }, new List() { "Trash", "Put on Deck" }, player);
ChoiceResult trashResult = player.MakeChoice(trashChoice);
if (trashResult.Options[0] == "Trash")
{
e.Cancelled = true;
player.RetrieveCardFrom(e.Location, e.Card);
player.Trash(e.Card);
}
else
{
e.Cancelled = true;
player.RetrieveCardFrom(e.Location, e.Card);
e.Location = DeckLocation.Deck;
e.Position = DeckPosition.Top;
}
e.HandledBy.Add(TypeClass.Watchtower);
}
public override void RemovedFrom(DeckLocation location, Player player)
{
base.RemovedFrom(location, player);
if (_CardGainedHandler != null)
player.CardGained -= _CardGainedHandler;
_CardGainedHandler = null;
}
}
public class WorkersVillage : Card
{
public WorkersVillage()
: base("Worker's Village", Category.Action, Source.Prosperity, Location.Kingdom, Group.PlusCard | Group.PlusAction | Group.PlusMultipleActions | Group.PlusBuy)
{
this.BaseCost = new Cost(4);
this.Benefit.Actions = 2;
this.Benefit.Cards = 1;
this.Benefit.Buys = 1;
}
}
}