- 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
This commit is contained in:
Sol
2013-07-15 02:56:54 +00:00
parent d2c2138be6
commit 913a6ec653
7 changed files with 61 additions and 172 deletions

View File

@@ -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.

View File

@@ -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.

View File

@@ -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<Card> chosen = new ArrayList<Card>();
final List<Card> chosen = new ArrayList<Card>();
final TargetRestrictions tgt = sa.getTargetRestrictions();
final List<Player> 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 {
}
}
}
}

View File

@@ -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;
/**
* <p>
@@ -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<Card> creats = CardLists.filter(card.getController().getCardsIn(ZoneType.Graveyard), new Predicate<Card>() {
@Override
public boolean apply(final Card c) {
return c.isCreature() && !c.equals(card);
}
});
if (card.getController().isHuman()) {
if (!creats.isEmpty()) {
final List<Card> 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);
}
// ***************************************************

View File

@@ -112,6 +112,7 @@ public abstract class PlayerController {
// Specify a target of a spell (Spellskite)
public abstract Pair<SpellAbilityStackInstance, ITargetable> chooseTarget(SpellAbility sa, List<Pair<SpellAbilityStackInstance, ITargetable>> allTargets);
public abstract List<Card> chooseCardsForEffect(List<Card> sourceList, SpellAbility sa, String title, int amount, boolean isOptional);
public Card chooseSingleCardForEffect(Collection<Card> sourceList, SpellAbility sa, String title) { return chooseSingleCardForEffect(sourceList, sa, title, false); }
public abstract Card chooseSingleCardForEffect(Collection<Card> sourceList, SpellAbility sa, String title, boolean isOptional);
public abstract Player chooseSinglePlayerForEffect(List<Player> options, SpellAbility sa, String title);

View File

@@ -124,6 +124,21 @@ public class PlayerControllerAi extends PlayerController {
return ComputerUtil.choosePermanentsToSacrifice(player, validTargets, max, sa, true, min == 0);
}
@Override
public List<Card> chooseCardsForEffect(List<Card> sourceList, SpellAbility sa, String title, int amount,
boolean isOptional) {
List<Card> chosen = new ArrayList<Card>();
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<Card> options, SpellAbility sa, String title, boolean isOptional) {

View File

@@ -272,6 +272,24 @@ public class PlayerControllerHuman extends PlayerController {
return inp.hasCancelled() ? Lists.<Card>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<Card> chooseCardsForEffect(List<Card> 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<Card> options, SpellAbility sa, String title, boolean isOptional) {
// Human is supposed to read the message and understand from it what to choose