mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-16 10:48:00 +00:00
- 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:
@@ -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.
|
||||
@@ -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.
|
||||
@@ -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 {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
// ***************************************************
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user