From 913a6ec65378bf5ae9b3c46893f45e9a9db814a8 Mon Sep 17 00:00:00 2001 From: Sol Date: Mon, 15 Jul 2013 02:56:54 +0000 Subject: [PATCH] - ChooseCard will now use the "order" dialog instead of multiple popups if you need to choose more than one Card - Convert Phyrexian Dreadnought and Sutured Ghoul to script --- res/cardsfolder/p/phyrexian_dreadnought.txt | 7 +- res/cardsfolder/s/sutured_ghoul.txt | 9 +- .../ability/effects/ChooseCardEffect.java | 29 ++-- .../cardfactory/CardFactoryCreatures.java | 154 ------------------ .../forge/game/player/PlayerController.java | 1 + .../forge/game/player/PlayerControllerAi.java | 15 ++ .../game/player/PlayerControllerHuman.java | 18 ++ 7 files changed, 61 insertions(+), 172 deletions(-) diff --git a/res/cardsfolder/p/phyrexian_dreadnought.txt b/res/cardsfolder/p/phyrexian_dreadnought.txt index 5e8efeb75fb..76de127e685 100644 --- a/res/cardsfolder/p/phyrexian_dreadnought.txt +++ b/res/cardsfolder/p/phyrexian_dreadnought.txt @@ -1,9 +1,14 @@ Name:Phyrexian Dreadnought ManaCost:1 Types:Artifact Creature Dreadnought -Text:When CARDNAME enters the battlefield, sacrifice it unless you sacrifice any number of creatures with total power 12 or greater. PT:12/12 K:Trample +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ ChooseCreatures | TriggerDescription$ When CARDNAME enters the battlefield, sacrifice it unless you sacrifice any number of creatures with total power 12 or greater. +SVar:ChooseCreatures:DB$ ChooseCard | Defined$ You | Amount$ X | Choices$ Creature.YouCtrl | ChoiceTitle$ Sacrifice any number of creatures with total power 12 or greater. | ChoiceZone$ Battlefield | RememberChosen$ True | SubAbility$ SacrificeSelf +SVar:SacrificeSelf:DB$ Sacrifice | Defined$ Self | ConditionCheckSVar$ TotalPower | ConditionSVarCompare$ LT12 | SubAbility$ SacrificeCreatures | References$ TotalPower +SVar:SacrificeCreatures:DB$ SacrificeAll | Defined$ Remembered | ConditionCheckSVar$ TotalPower | ConditionSVarCompare$ GE12 | SubAbility$ DBCleanup | References$ TotalPower +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +SVar:TotalPower:Remembered$CardPower SVar:RemRandomDeck:True SVar:Picture:http://www.wizards.com/global/images/magic/general/phyrexian_dreadnought.jpg Oracle:Trample\nWhen Phyrexian Dreadnought enters the battlefield, sacrifice it unless you sacrifice any number of creatures with total power 12 or greater. \ No newline at end of file diff --git a/res/cardsfolder/s/sutured_ghoul.txt b/res/cardsfolder/s/sutured_ghoul.txt index 839ed8017e9..868f62b3d6d 100644 --- a/res/cardsfolder/s/sutured_ghoul.txt +++ b/res/cardsfolder/s/sutured_ghoul.txt @@ -1,9 +1,16 @@ Name:Sutured Ghoul ManaCost:4 B B B Types:Creature Zombie -Text:As Sutured Ghoul enters the battlefield, exile any number of creature cards from your graveyard.\r\nSutured Ghoul's power is equal to the total power of the exiled cards and its toughness is equal to their total toughness. PT:*/* K:Trample +K:ETBReplacement:Copy:ChooseCreatures +SVar:ChooseCreatures:DB$ ChooseCard | Defined$ You | Amount$ X | Choices$ Creature.YouOwn | ChoiceTitle$ Exile any number of creature cards from your graveyard. | ChoiceZone$ Graveyard | RememberChosen$ True | SubAbility$ ExileCreatures | SpellDescription$ As CARDNAME enters the battlefield, exile any number of creature cards from your graveyard. CARDNAME's power is equal to the total power of the exiled cards and its toughness is equal to their total toughness. | References$ X +SVar:ExileCreatures:DB$ ChangeZoneAll | ChangeType$ Remembered | Origin$ Graveyard | Destination$ Exile | SubAbility$ AnimateSuture +SVar:AnimateSuture:DB$ Animate | Defined$ Self | Power$ TotalPower | Toughness$ TotalToughness | Permanent$ True | SubAbility$ DBCleanup | References$ TotalPower,TotalToughness +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +SVar:TotalPower:Remembered$CardPower +SVar:TotalToughness:Remembered$CardToughness +SVar:X:Count$TypeInYourYard.Creature SVar:RemRandomDeck:True SVar:Picture:http://www.wizards.com/global/images/magic/general/sutured_ghoul.jpg Oracle:Trample\nAs Sutured Ghoul enters the battlefield, exile any number of creature cards from your graveyard.\nSutured Ghoul's power is equal to the total power of the exiled cards and its toughness is equal to their total toughness. \ No newline at end of file diff --git a/src/main/java/forge/card/ability/effects/ChooseCardEffect.java b/src/main/java/forge/card/ability/effects/ChooseCardEffect.java index f308c7e90a9..ce485ccfdd3 100644 --- a/src/main/java/forge/card/ability/effects/ChooseCardEffect.java +++ b/src/main/java/forge/card/ability/effects/ChooseCardEffect.java @@ -35,7 +35,7 @@ public class ChooseCardEffect extends SpellAbilityEffect { public void resolve(SpellAbility sa) { final Card host = sa.getSourceCard(); final Game game = sa.getActivatingPlayer().getGame(); - final ArrayList chosen = new ArrayList(); + final List chosen = new ArrayList(); final TargetRestrictions tgt = sa.getTargetRestrictions(); final List tgtPlayers = getTargetPlayers(sa); @@ -77,21 +77,19 @@ public class ChooseCardEffect extends SpellAbilityEffect { } } } else if ((tgt == null) || p.canBeTargetedBy(sa)) { - for (int i = 0; i < validAmount; i++) { - - Card c; - if (sa.hasParam("AtRandom")) { - c = Aggregates.random(choices); - } else { - c = p.getController().chooseSingleCardForEffect(choices, sa, sa.hasParam("ChoiceTitle") ? sa.getParam("ChoiceTitle") : "Choose a card ", !sa.hasParam("Mandatory")); - } - - if (c != null) { - chosen.add(c); - choices.remove(c); - } else { - break; + if (sa.hasParam("AtRandom")) { + for (int i = 0; i < validAmount; i++) { + Card c = Aggregates.random(choices); + if (c != null) { + chosen.add(c); + choices.remove(c); + } else { + break; + } } + } else { + chosen.addAll(p.getController().chooseCardsForEffect(choices, sa, sa.hasParam("ChoiceTitle") ? + sa.getParam("ChoiceTitle") : "Choose a card ", validAmount, !sa.hasParam("Mandatory"))); } } } @@ -107,5 +105,4 @@ public class ChooseCardEffect extends SpellAbilityEffect { } } } - } diff --git a/src/main/java/forge/card/cardfactory/CardFactoryCreatures.java b/src/main/java/forge/card/cardfactory/CardFactoryCreatures.java index e09b381220c..0623a070fc1 100644 --- a/src/main/java/forge/card/cardfactory/CardFactoryCreatures.java +++ b/src/main/java/forge/card/cardfactory/CardFactoryCreatures.java @@ -20,31 +20,18 @@ package forge.card.cardfactory; import java.util.ArrayList; import java.util.List; -import com.google.common.base.Predicate; -import com.google.common.collect.Iterables; - import forge.Card; -import forge.CardLists; -import forge.Singletons; -import forge.CardPredicates.Presets; -import forge.Command; import forge.CounterType; import forge.card.cost.Cost; import forge.card.mana.ManaCost; -import forge.card.spellability.Ability; import forge.card.spellability.AbilityActivated; import forge.card.spellability.AbilityStatic; import forge.card.spellability.SpellAbility; -import forge.card.spellability.SpellPermanent; -import forge.card.trigger.Trigger; -import forge.card.trigger.TriggerHandler; -import forge.game.Game; import forge.game.phase.PhaseType; import forge.game.player.Player; import forge.game.zone.PlayerZone; import forge.game.zone.ZoneType; import forge.gui.GuiChoose; -import forge.gui.input.InputSelectCards; /** *

@@ -55,43 +42,6 @@ import forge.gui.input.InputSelectCards; * @version $Id$ */ public class CardFactoryCreatures { - /** - * TODO: Write javadoc for this type. - * - */ - public static final class InputSelectCardsForDreadnought extends InputSelectCards { - private static final long serialVersionUID = 2698036349873486664L; - protected final Player player; - - public InputSelectCardsForDreadnought(Player p, int min, int max) { - super(min, max); - player = p; - } - - @Override - protected String getMessage() { - return String.format(message, selected.size(), getTotalPower()); - } - - @Override - protected boolean isValidChoice(Card c) { - return c.isCreature() && player.getZone(ZoneType.Battlefield).contains(c); - } // selectCard() - - @Override - protected boolean hasEnoughTargets() { - return getTotalPower() >= 12; - } - - private int getTotalPower() { - int sum = 0; - for (final Card c : selected) { - sum += c.getNetAttack(); - } - return sum; - } - } - private static void getCard_SphinxJwar(final Card card) { final SpellAbility ability1 = new AbilityStatic(card, ManaCost.ZERO) { @@ -124,114 +74,10 @@ public class CardFactoryCreatures { card.addSpellAbility(ability1); } - private static void getCard_SurturedGhoul(final Card card) { - final Command intoPlay = new Command() { - private static final long serialVersionUID = -75234586897814L; - - @Override - public void run() { - final Game game = card.getGame(); - int intermSumPower = 0; - int intermSumToughness = 0; - // intermSumPower = intermSumToughness = 0; - List creats = CardLists.filter(card.getController().getCardsIn(ZoneType.Graveyard), new Predicate() { - @Override - public boolean apply(final Card c) { - return c.isCreature() && !c.equals(card); - } - }); - - if (card.getController().isHuman()) { - if (!creats.isEmpty()) { - final List selection = GuiChoose.noneOrMany("Select creatures to exile", creats); - - for (int m = 0; m < selection.size(); m++) { - intermSumPower += selection.get(m).getBaseAttack(); - intermSumToughness += selection.get(m).getBaseDefense(); - game.getAction().exile(selection.get(m)); - } - } - - } // human - else { - for (int i = 0; i < creats.size(); i++) { - final Card c = creats.get(i); - if ((c.getNetAttack() <= 2) && (c.getNetDefense() <= 3)) { - intermSumPower += c.getBaseAttack(); - intermSumToughness += c.getBaseDefense(); - game.getAction().exile(c); - } - } - } - card.setBaseAttack(intermSumPower); - card.setBaseDefense(intermSumToughness); - } - }; - // Do not remove SpellAbilities created by AbilityFactory or - // Keywords. - card.clearFirstSpell(); - card.addComesIntoPlayCommand(intoPlay); - card.addSpellAbility(new SpellPermanent(card) { - private static final long serialVersionUID = 304885517082977723L; - - @Override - public boolean canPlayAI() { - return Iterables.any(getActivatingPlayer().getCardsIn(ZoneType.Graveyard), Presets.CREATURES); - } - }); - } - - private static void getCard_PhyrexianDreadnought(final Card card, final String cardName) { - final Player player = card.getController(); - - final Ability sacOrSac = new Ability(card, ManaCost.NO_COST) { - @Override - public void resolve() { - final Game game = player.getGame(); - if (player.isHuman()) { - final InputSelectCards target = new InputSelectCardsForDreadnought(player, 0, Integer.MAX_VALUE); // Input - String toDisplay = cardName + " - Select any number of creatures to sacrifice.\n" + - "Currently, (%d) selected with a total power of: %d\n\n" + "Click OK when Done."; - target.setMessage(toDisplay); - target.setCancelAllowed(true); - Singletons.getControl().getInputQueue().setInputAndWait(target); - if(!target.hasCancelled()) { - for (final Card sac : target.getSelected()) { - game.getAction().sacrifice(sac, null); - } - } else { - game.getAction().sacrifice(card, null); - } - } - } // end resolve - }; // end sacOrSac - - final StringBuilder sbTrig = new StringBuilder(); - sbTrig.append("Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | "); - sbTrig.append("Execute$ TrigOverride | TriggerDescription$ "); - sbTrig.append("When CARDNAME enters the battlefield, sacrifice it unless "); - sbTrig.append("you sacrifice any number of creatures with total power 12 or greater."); - final Trigger myTrigger = TriggerHandler.parseTrigger(sbTrig.toString(), card, true); - myTrigger.setOverridingAbility(sacOrSac); - - card.addTrigger(myTrigger); - } - - - -// // This is a hardcoded card template -// -// private static void getCard_(final Card card, final String cardName) { -// } - public static void buildCard(final Card card, final String cardName) { if (cardName.equals("Sphinx of Jwar Isle")) { getCard_SphinxJwar(card); - } else if (cardName.equals("Sutured Ghoul")) { - getCard_SurturedGhoul(card); - } else if (cardName.equals("Phyrexian Dreadnought")) { - getCard_PhyrexianDreadnought(card, cardName); } // *************************************************** diff --git a/src/main/java/forge/game/player/PlayerController.java b/src/main/java/forge/game/player/PlayerController.java index 12c16f30557..5989c9c048f 100644 --- a/src/main/java/forge/game/player/PlayerController.java +++ b/src/main/java/forge/game/player/PlayerController.java @@ -112,6 +112,7 @@ public abstract class PlayerController { // Specify a target of a spell (Spellskite) public abstract Pair chooseTarget(SpellAbility sa, List> allTargets); + public abstract List chooseCardsForEffect(List sourceList, SpellAbility sa, String title, int amount, boolean isOptional); public Card chooseSingleCardForEffect(Collection sourceList, SpellAbility sa, String title) { return chooseSingleCardForEffect(sourceList, sa, title, false); } public abstract Card chooseSingleCardForEffect(Collection sourceList, SpellAbility sa, String title, boolean isOptional); public abstract Player chooseSinglePlayerForEffect(List options, SpellAbility sa, String title); diff --git a/src/main/java/forge/game/player/PlayerControllerAi.java b/src/main/java/forge/game/player/PlayerControllerAi.java index 27afc49ac26..73a5357feb8 100644 --- a/src/main/java/forge/game/player/PlayerControllerAi.java +++ b/src/main/java/forge/game/player/PlayerControllerAi.java @@ -124,6 +124,21 @@ public class PlayerControllerAi extends PlayerController { return ComputerUtil.choosePermanentsToSacrifice(player, validTargets, max, sa, true, min == 0); } + @Override + public List chooseCardsForEffect(List sourceList, SpellAbility sa, String title, int amount, + boolean isOptional) { + List chosen = new ArrayList(); + for (int i = 0; i < amount; i++) { + Card c = this.chooseSingleCardForEffect(sourceList, sa, title, isOptional); + if (c != null) { + chosen.add(c); + sourceList.remove(c); + } else { + break; + } + } + return chosen; + } @Override public Card chooseSingleCardForEffect(Collection options, SpellAbility sa, String title, boolean isOptional) { diff --git a/src/main/java/forge/game/player/PlayerControllerHuman.java b/src/main/java/forge/game/player/PlayerControllerHuman.java index b11e18c3aaf..3e2b38130df 100644 --- a/src/main/java/forge/game/player/PlayerControllerHuman.java +++ b/src/main/java/forge/game/player/PlayerControllerHuman.java @@ -272,6 +272,24 @@ public class PlayerControllerHuman extends PlayerController { return inp.hasCancelled() ? Lists.newArrayList() : inp.getSelected(); } + + /* (non-Javadoc) + * @see forge.game.player.PlayerController#chooseCardsForEffect(java.util.Collection, forge.card.spellability.SpellAbility, java.lang.String, int, boolean) + */ + @Override + public List chooseCardsForEffect(List sourceList, SpellAbility sa, String title, int amount, + boolean isOptional) { + // If only one card to choose, use a dialog box. + // Otherwise, use the order dialog to be able to grab multiple cards in one shot + if (amount == 1) { + return Lists.newArrayList(chooseSingleCardForEffect(sourceList, sa, title, isOptional)); + } + + GuiUtils.setPanelSelection(sa.getSourceCard()); + int remaining = isOptional ? -1 : Math.max(sourceList.size() - amount, 0); + return GuiChoose.order(title, "Chosen Cards", remaining, sourceList, null, sa.getSourceCard()); + } + @Override public Card chooseSingleCardForEffect(Collection options, SpellAbility sa, String title, boolean isOptional) { // Human is supposed to read the message and understand from it what to choose