diff --git a/forge-ai/src/main/java/forge/ai/ability/CopyPermanentAi.java b/forge-ai/src/main/java/forge/ai/ability/CopyPermanentAi.java index c43ec7c9001..a630836d38e 100644 --- a/forge-ai/src/main/java/forge/ai/ability/CopyPermanentAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/CopyPermanentAi.java @@ -4,6 +4,7 @@ import com.google.common.base.Predicate; import com.google.common.base.Predicates; import com.google.common.collect.Iterables; import forge.ai.*; +import forge.game.Game; import forge.game.ability.AbilityUtils; import forge.game.card.*; import forge.game.card.CardPredicates.Presets; @@ -13,7 +14,9 @@ import forge.game.player.Player; import forge.game.player.PlayerActionConfirmMode; import forge.game.player.PlayerCollection; import forge.game.spellability.SpellAbility; +import forge.game.zone.ZoneType; +import java.util.Collection; import java.util.List; public class CopyPermanentAi extends SpellAbilityAi { @@ -67,6 +70,12 @@ public class CopyPermanentAi extends SpellAbilityAi { @Override protected boolean doTriggerAINoCost(final Player aiPlayer, SpellAbility sa, boolean mandatory) { + final Card host = sa.getHostCard(); + final Player activator = sa.getActivatingPlayer(); + final Game game = host.getGame(); + final String sourceName = ComputerUtilAbility.getAbilitySourceName(sa); + + // //// // Targeting if (sa.usesTargeting()) { @@ -81,7 +90,7 @@ public class CopyPermanentAi extends SpellAbilityAi { } // Saheeli Rai + Felidar Guardian combo support - if (sa.getHostCard().getName().equals("Saheeli Rai")) { + if ("Saheeli Rai".equals(sourceName)) { CardCollection felidarGuardian = CardLists.filter(list, CardPredicates.nameEquals("Felidar Guardian")); if (felidarGuardian.size() > 0) { // can copy a Felidar Guardian and combo off, so let's do it @@ -131,6 +140,14 @@ public class CopyPermanentAi extends SpellAbilityAi { list.remove(choice); sa.getTargets().add(choice); } + } else if (sa.hasParam("Choices")) { + // only check for options, does not select there + CardCollectionView choices = game.getCardsIn(ZoneType.Battlefield); + choices = CardLists.getValidCards(choices, sa.getParam("Choices"), activator, host); + Collection betterChoices = getBetterOptions(aiPlayer, sa, choices, !mandatory); + if (betterChoices.isEmpty()) { + return mandatory; + } } else { // if no targeting, it should always be ok } @@ -153,8 +170,20 @@ public class CopyPermanentAi extends SpellAbilityAi { @Override public Card chooseSingleCard(Player ai, SpellAbility sa, Iterable options, boolean isOptional, Player targetedPlayer) { // Select a card to attach to + CardCollection betterOptions = getBetterOptions(ai, sa, options, isOptional); + if (!betterOptions.isEmpty()) { + options = betterOptions; + } return ComputerUtilCard.getBestAI(options); } + + private CardCollection getBetterOptions(Player ai, SpellAbility sa, Iterable options, boolean isOptional) { + final Card host = sa.getHostCard(); + final Player ctrl = host.getController(); + final String filter = "Permanent.YouDontCtrl,Permanent.nonLegendary"; + // TODO add filter to not select Legendary from Other Player when ai already have a Legendary with that name + return CardLists.getValidCards(options, filter.split(","), ctrl, host, sa); + } @Override protected Player chooseSinglePlayer(Player ai, SpellAbility sa, Iterable options) { diff --git a/forge-core/src/main/java/forge/card/CardType.java b/forge-core/src/main/java/forge/card/CardType.java index 925008561d1..afb476e54d8 100644 --- a/forge-core/src/main/java/forge/card/CardType.java +++ b/forge-core/src/main/java/forge/card/CardType.java @@ -17,6 +17,7 @@ */ package forge.card; +import java.util.Collection; import java.util.Collections; import java.util.EnumSet; import java.util.Iterator; @@ -24,10 +25,11 @@ import java.util.List; import java.util.Map; import java.util.Set; -import forge.util.TextUtil; import org.apache.commons.lang3.NotImplementedException; import org.apache.commons.lang3.StringUtils; +import com.google.common.base.Predicate; + import com.google.common.collect.BiMap; import com.google.common.collect.HashBiMap; import com.google.common.collect.ImmutableList; @@ -181,6 +183,20 @@ public final class CardType implements Comparable, CardTypeView { subtypes.clear(); calculatedType = null; } + + public boolean remove(final Supertype st) { + return supertypes.remove(st); + } + + public boolean setCreatureTypes(Collection ctypes) { + // if it isn't a creature then this has no effect + if (coreTypes.contains(CoreType.Creature)) { + return false; + } + boolean changed = Iterables.removeIf(subtypes, Predicates.IS_CREATURE_TYPE); + subtypes.addAll(ctypes); + return changed; + } @Override public boolean isEmpty() { @@ -552,6 +568,15 @@ public final class CardType implements Comparable, CardTypeView { // plural -> singular public static final BiMap singularTypes = pluralTypes.inverse(); } + public static class Predicates { + public static Predicate IS_CREATURE_TYPE = new Predicate() { + @Override + public boolean apply(String input) { + return CardType.isACreatureType(input); + } + }; + } + ///////// Utility methods public static boolean isACardType(final String cardType) { diff --git a/forge-game/src/main/java/forge/game/ability/effects/CopyPermanentEffect.java b/forge-game/src/main/java/forge/game/ability/effects/CopyPermanentEffect.java index 7de496a168a..3f25d8547f9 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/CopyPermanentEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/CopyPermanentEffect.java @@ -2,6 +2,7 @@ package forge.game.ability.effects; import com.google.common.base.Predicate; import com.google.common.base.Predicates; +import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.common.collect.Maps; @@ -45,6 +46,9 @@ public class CopyPermanentEffect extends SpellAbilityEffect { @Override protected String getStackDescription(SpellAbility sa) { + if (sa.hasParam("Populate")) { + return "Populate. (Create a token that's a copy of a creature token you control.)"; + } final StringBuilder sb = new StringBuilder(); @@ -61,8 +65,9 @@ public class CopyPermanentEffect extends SpellAbilityEffect { */ @Override public void resolve(final SpellAbility sa) { - final Card hostCard = sa.getHostCard(); - final Game game = hostCard.getGame(); + final Card host = sa.getHostCard(); + final Player activator = sa.getActivatingPlayer(); + final Game game = host.getGame(); final List keywords = Lists.newArrayList(); final List types = Lists.newArrayList(); final List svars = Lists.newArrayList(); @@ -74,7 +79,7 @@ public class CopyPermanentEffect extends SpellAbilityEffect { final long timestamp = game.getNextTimestamp(); if (sa.hasParam("Optional")) { - if (!sa.getActivatingPlayer().getController().confirmAction(sa, null, "Copy this permanent?")) { + if (!activator.getController().confirmAction(sa, null, "Copy this permanent?")) { return; } } @@ -99,28 +104,28 @@ public class CopyPermanentEffect extends SpellAbilityEffect { if (sa.hasParam("Triggers")) { triggers.addAll(Arrays.asList(sa.getParam("Triggers").split(" & "))); } - final int numCopies = sa.hasParam("NumCopies") ? AbilityUtils.calculateAmount(hostCard, + final int numCopies = sa.hasParam("NumCopies") ? AbilityUtils.calculateAmount(host, sa.getParam("NumCopies"), sa) : 1; Player controller = null; if (sa.hasParam("Controller")) { - final FCollectionView defined = AbilityUtils.getDefinedPlayers(hostCard, sa.getParam("Controller"), sa); + final FCollectionView defined = AbilityUtils.getDefinedPlayers(host, sa.getParam("Controller"), sa); if (!defined.isEmpty()) { controller = defined.getFirst(); } } if (controller == null) { - controller = sa.getActivatingPlayer(); + controller = activator; } - List tgtCards = getTargetCards(sa); + List tgtCards = Lists.newArrayList(); if (sa.hasParam("ValidSupportedCopy")) { List cards = Lists.newArrayList(StaticData.instance().getCommonCards().getUniqueCards()); String valid = sa.getParam("ValidSupportedCopy"); if (valid.contains("X")) { valid = TextUtil.fastReplace(valid, - "X", Integer.toString(AbilityUtils.calculateAmount(hostCard, "X", sa))); + "X", Integer.toString(AbilityUtils.calculateAmount(host, "X", sa))); } if (StringUtils.containsIgnoreCase(valid, "creature")) { Predicate cpp = Predicates.compose(CardRulesPredicates.Presets.IS_CREATURE, PaperCard.FN_GET_RULES); @@ -134,12 +139,12 @@ public class CopyPermanentEffect extends SpellAbilityEffect { List copysource = Lists.newArrayList(cards); List choice = Lists.newArrayList(); final String num = sa.hasParam("RandomNum") ? sa.getParam("RandomNum") : "1"; - int ncopied = AbilityUtils.calculateAmount(hostCard, num, sa); + int ncopied = AbilityUtils.calculateAmount(host, num, sa); while(ncopied > 0) { final PaperCard cp = Aggregates.random(copysource); - Card possibleCard = Card.fromPaperCard(cp, sa.getActivatingPlayer()); // Need to temporarily set the Owner so the Game is set + Card possibleCard = Card.fromPaperCard(cp, activator); // Need to temporarily set the Owner so the Game is set - if (possibleCard.isValid(valid, hostCard.getController(), hostCard, sa)) { + if (possibleCard.isValid(valid, host.getController(), host, sa)) { choice.add(possibleCard); copysource.remove(cp); ncopied -= 1; @@ -149,21 +154,34 @@ public class CopyPermanentEffect extends SpellAbilityEffect { } else if (sa.hasParam("DefinedName")) { String name = sa.getParam("DefinedName"); if (name.equals("NamedCard")) { - if (!hostCard.getNamedCard().isEmpty()) { - name = hostCard.getNamedCard(); + if (!host.getNamedCard().isEmpty()) { + name = host.getNamedCard(); } } Predicate cpp = Predicates.compose(CardRulesPredicates.name(StringOp.EQUALS, name), PaperCard.FN_GET_RULES); cards = Lists.newArrayList(Iterables.filter(cards, cpp)); - tgtCards.clear(); if (!cards.isEmpty()) { tgtCards.add(Card.fromPaperCard(cards.get(0), controller)); } } + } if (sa.hasParam("Choices")) { + CardCollectionView choices = game.getCardsIn(ZoneType.Battlefield); + choices = CardLists.getValidCards(choices, sa.getParam("Choices"), activator, host); + if (!choices.isEmpty()) { + String title = sa.hasParam("ChoiceTitle") ? sa.getParam("ChoiceTitle") : "Choose a card "; + + Card choosen = activator.getController().chooseSingleEntityForEffect(choices, sa, title, false); + + if (choosen != null) { + tgtCards.add(choosen); + } + } + } else { + tgtCards = getTargetCards(sa); } - hostCard.clearClones(); + host.clearClones(); for (final Card c : tgtCards) { if (!sa.usesTargeting() || c.canBeTargetedBy(sa)) { @@ -190,7 +208,7 @@ public class CopyPermanentEffect extends SpellAbilityEffect { final List crds = Lists.newArrayListWithCapacity(multiplier); for (int i = 0; i < multiplier; i++) { - final Card copy = CardFactory.copyCopiableCharacteristics(c, sa.getActivatingPlayer()); + final Card copy = CardFactory.copyCopiableCharacteristics(c, activator); copy.setToken(true); copy.setCopiedPermanent(c); // add keywords from sa @@ -198,35 +216,10 @@ public class CopyPermanentEffect extends SpellAbilityEffect { copy.addIntrinsicKeyword(kw); } if (asNonLegendary) { - String typeLine = ""; - for (CardType.Supertype st : copy.getType().getSupertypes()) { - if (!st.equals(CardType.Supertype.Legendary)) { - typeLine += st.name() + " "; - } - } - for (CardType.CoreType ct : copy.getType().getCoreTypes()) { - typeLine += ct.name() + " "; - } - for (String subt: copy.getType().getSubtypes()) { - typeLine += subt + " "; - } - - StringBuilder newType = new StringBuilder(typeLine); - copy.setType(CardType.parse(newType.toString())); + copy.removeType(CardType.Supertype.Legendary); } if (sa.hasParam("SetCreatureTypes")) { - String typeLine = ""; - for (CardType.Supertype st : copy.getType().getSupertypes()) { - typeLine += st.name() + " "; - } - for (CardType.CoreType ct : copy.getType().getCoreTypes()) { - typeLine += ct.name() + " "; - } - - StringBuilder newType = new StringBuilder(typeLine); - newType.append(sa.getParam("SetCreatureTypes")); - - copy.setType(CardType.parse(newType.toString())); + copy.setCreatureTypes(ImmutableList.copyOf(sa.getParam("SetCreatureTypes").split(" "))); } if (sa.hasParam("SetColor")) { @@ -237,7 +230,7 @@ public class CopyPermanentEffect extends SpellAbilityEffect { copy.addType(type); } for (final String svar : svars) { - String actualsVar = hostCard.getSVar(svar); + String actualsVar = host.getSVar(svar); String name = svar; if (actualsVar.startsWith("SVar:")) { actualsVar = actualsVar.split("SVar:")[1]; @@ -247,7 +240,7 @@ public class CopyPermanentEffect extends SpellAbilityEffect { copy.setSVar(name, actualsVar); } for (final String s : triggers) { - final String actualTrigger = hostCard.getSVar(s); + final String actualTrigger = host.getSVar(s); final Trigger parsedTrigger = TriggerHandler.parseTrigger(actualTrigger, copy, true); copy.addTrigger(parsedTrigger); } @@ -354,14 +347,14 @@ public class CopyPermanentEffect extends SpellAbilityEffect { // when copying something stolen: copyInPlay.setSetCode(c.getSetCode()); - copyInPlay.setCloneOrigin(hostCard); + copyInPlay.setCloneOrigin(host); sa.getHostCard().addClone(copyInPlay); if (!pumpKeywords.isEmpty()) { copyInPlay.addChangedCardKeywords(pumpKeywords, Lists.newArrayList(), false, timestamp); } crds.add(copyInPlay); if (sa.hasParam("RememberCopied")) { - hostCard.addRemembered(copyInPlay); + host.addRemembered(copyInPlay); } if (sa.hasParam("Tapped")) { copyInPlay.setTapped(true); @@ -373,7 +366,7 @@ public class CopyPermanentEffect extends SpellAbilityEffect { FCollectionView defs = game.getCombat().getDefenders(); defender = c.getController().getController().chooseSingleEntityForEffect(defs, sa, "Choose which defender to attack with " + c, false); } else { - defender = AbilityUtils.getDefinedPlayers(hostCard, sa.getParam("CopyAttacking"), sa).get(0); + defender = AbilityUtils.getDefinedPlayers(host, sa.getParam("CopyAttacking"), sa).get(0); if (sa.hasParam("ChoosePlayerOrPlaneswalker") && defender != null) { FCollectionView defs = game.getCombat().getDefendersControlledBy((Player) defender); defender = c.getController().getController().chooseSingleEntityForEffect(defs, sa, "Choose which defender to attack with " + c + " {defender: "+ defender + "}", false); @@ -385,7 +378,7 @@ public class CopyPermanentEffect extends SpellAbilityEffect { if (sa.hasParam("CopyBlocking") && game.getPhaseHandler().inCombat() && copyInPlay.isCreature()) { final Combat combat = game.getPhaseHandler().getCombat(); - final Card attacker = Iterables.getFirst(AbilityUtils.getDefinedCards(hostCard, sa.getParam("CopyBlocking"), sa), null); + final Card attacker = Iterables.getFirst(AbilityUtils.getDefinedCards(host, sa.getParam("CopyBlocking"), sa), null); if (attacker != null) { final boolean wasBlocked = combat.isBlocked(attacker); combat.addBlocker(attacker, copyInPlay); @@ -402,13 +395,13 @@ public class CopyPermanentEffect extends SpellAbilityEffect { } if (sa.hasParam("AttachedTo")) { - CardCollectionView list = AbilityUtils.getDefinedCards(hostCard, sa.getParam("AttachedTo"), sa); + CardCollectionView list = AbilityUtils.getDefinedCards(host, sa.getParam("AttachedTo"), sa); if (list.isEmpty()) { list = copyInPlay.getController().getGame().getCardsIn(ZoneType.Battlefield); list = CardLists.getValidCards(list, sa.getParam("AttachedTo"), copyInPlay.getController(), copyInPlay); } if (!list.isEmpty()) { - Card attachedTo = sa.getActivatingPlayer().getController().chooseSingleEntityForEffect(list, sa, copyInPlay + " - Select a card to attach to."); + Card attachedTo = activator.getController().chooseSingleEntityForEffect(list, sa, copyInPlay + " - Select a card to attach to."); if (copyInPlay.isAura()) { if (attachedTo.canBeEnchantedBy(copyInPlay)) { copyInPlay.enchantEntity(attachedTo); @@ -435,7 +428,7 @@ public class CopyPermanentEffect extends SpellAbilityEffect { registerDelayedTrigger(sa, sa.getParam("AtEOT"), crds); } if (sa.hasParam("ImprintCopied")) { - hostCard.addImprintedCards(crds); + host.addImprintedCards(crds); } } // end canBeTargetedBy } // end foreach Card diff --git a/forge-game/src/main/java/forge/game/card/Card.java b/forge-game/src/main/java/forge/game/card/Card.java index e2f00d65697..33223b2a606 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -2703,6 +2703,14 @@ public class Card extends GameEntity implements Comparable { public final void addType(final String type0) { currentState.addType(type0); } + + public final void removeType(final CardType.Supertype st) { + currentState.removeType(st); + } + + public final void setCreatureTypes(Collection ctypes) { + currentState.setCreatureTypes(ctypes); + } public final CardTypeView getType() { return getType(currentState); diff --git a/forge-game/src/main/java/forge/game/card/CardState.java b/forge-game/src/main/java/forge/game/card/CardState.java index 63d93fdb905..fb781195398 100644 --- a/forge-game/src/main/java/forge/game/card/CardState.java +++ b/forge-game/src/main/java/forge/game/card/CardState.java @@ -115,6 +115,18 @@ public class CardState extends GameObject { view.updateType(this); } + public final void removeType(final CardType.Supertype st) { + if (type.remove(st)) { + view.updateType(this); + } + } + + public final void setCreatureTypes(Collection ctypes) { + if (type.setCreatureTypes(ctypes)) { + view.updateType(this); + } + } + public final ManaCost getManaCost() { return manaCost; } diff --git a/forge-gui/res/cardsfolder/c/coursers_accord.txt b/forge-gui/res/cardsfolder/c/coursers_accord.txt index c89bbad2c1b..96d5cf501f9 100644 --- a/forge-gui/res/cardsfolder/c/coursers_accord.txt +++ b/forge-gui/res/cardsfolder/c/coursers_accord.txt @@ -1,10 +1,8 @@ Name:Coursers' Accord ManaCost:4 G W Types:Sorcery -A:SP$ Token | Cost$ 4 G W | TokenAmount$ 1 | TokenName$ Centaur | TokenTypes$ Creature,Centaur | TokenOwner$ You | TokenColors$ Green | TokenPower$ 3 | TokenToughness$ 3 | TokenImage$ g 3 3 centaur rtr | SubAbility$ DBChoose | SpellDescription$ Create a 3/3 green Centaur creature token, then populate. (Create a token that's a copy of a creature token you control.) -SVar:DBChoose:DB$ ChooseCard | Defined$ You | Amount$ 1 | Choices$ Creature.token+YouCtrl | SubAbility$ DBCopy | Mandatory$ True | AILogic$ Clone -SVar:DBCopy:DB$ CopyPermanent | Defined$ ChosenCard | NumCopies$ 1 | SubAbility$ DBCleanup -SVar:DBCleanup:DB$ Cleanup | ClearChosenCard$ True +A:SP$ Token | Cost$ 4 G W | TokenAmount$ 1 | TokenName$ Centaur | TokenTypes$ Creature,Centaur | TokenOwner$ You | TokenColors$ Green | TokenPower$ 3 | TokenToughness$ 3 | TokenImage$ g 3 3 centaur rtr | SubAbility$ DBCopy | SpellDescription$ Create a 3/3 green Centaur creature token, then populate. (Create a token that's a copy of a creature token you control.) +SVar:DBCopy:DB$ CopyPermanent | Choices$ Creature.token+YouCtrl | NumCopies$ 1 | Populate$ True DeckHas:Ability$Token DeckHints:Ability$Token SVar:Picture:http://www.wizards.com/global/images/magic/general/coursers_accord.jpg diff --git a/forge-gui/res/cardsfolder/d/druids_deliverance.txt b/forge-gui/res/cardsfolder/d/druids_deliverance.txt index 27d40d295af..0d9aefa4563 100644 --- a/forge-gui/res/cardsfolder/d/druids_deliverance.txt +++ b/forge-gui/res/cardsfolder/d/druids_deliverance.txt @@ -1,11 +1,9 @@ Name:Druid's Deliverance ManaCost:1 G Types:Instant -A:SP$ Effect | Cost$ 1 G | Name$ Druid's Deliverance Effect | StaticAbilities$ STPrevent | AILogic$ Fog | SubAbility$ DBChoose | SpellDescription$ Prevent all combat damage that would be dealt to you this turn. Populate. (Create a token that's a copy of a creature token you control.) +A:SP$ Effect | Cost$ 1 G | Name$ Druid's Deliverance Effect | StaticAbilities$ STPrevent | AILogic$ Fog | SubAbility$ DBCopy | SpellDescription$ Prevent all combat damage that would be dealt to you this turn. Populate. (Create a token that's a copy of a creature token you control.) SVar:STPrevent:Mode$ PreventDamage | EffectZone$ Command | CombatDamage$ True | Target$ You | Description$ Prevent all combat damage that would be dealt to you this turn. -SVar:DBChoose:DB$ ChooseCard | Defined$ You | Amount$ 1 | Choices$ Creature.token+YouCtrl | SubAbility$ DBCopy | Mandatory$ True | AILogic$ Clone -SVar:DBCopy:DB$ CopyPermanent | Defined$ ChosenCard | NumCopies$ 1 | SubAbility$ DBCleanup -SVar:DBCleanup:DB$ Cleanup | ClearChosenCard$ True +SVar:DBCopy:DB$ CopyPermanent | Choices$ Creature.token+YouCtrl | NumCopies$ 1 | Populate$ True DeckHints:Ability$Token SVar:Picture:http://www.wizards.com/global/images/magic/general/druids_deliverance.jpg Oracle:Prevent all combat damage that would be dealt to you this turn. Populate. (Create a token that's a copy of a creature token you control.) diff --git a/forge-gui/res/cardsfolder/e/eyes_in_the_skies.txt b/forge-gui/res/cardsfolder/e/eyes_in_the_skies.txt index d02dbb3a643..010c8b00d5e 100644 --- a/forge-gui/res/cardsfolder/e/eyes_in_the_skies.txt +++ b/forge-gui/res/cardsfolder/e/eyes_in_the_skies.txt @@ -1,10 +1,8 @@ Name:Eyes in the Skies ManaCost:3 W Types:Instant -A:SP$ Token | Cost$ 3 W | TokenOwner$ You | TokenAmount$ 1 | TokenName$ Bird | TokenTypes$ Creature,Bird | TokenColors$ White | TokenPower$ 1 | TokenToughness$ 1 | TokenKeywords$ Flying | TokenImage$ w 1 1 bird rtr | SubAbility$ DBChoose | SpellDescription$ Create a 1/1 white Bird creature token with flying, then populate. (Create a token that's a copy of a creature token you control.) -SVar:DBChoose:DB$ ChooseCard | Defined$ You | Amount$ 1 | Choices$ Creature.token+YouCtrl | Mandatory$ True | SubAbility$ DBCopy | AILogic$ Clone -SVar:DBCopy:DB$ CopyPermanent | Defined$ ChosenCard | NumCopies$ 1 | SubAbility$ DBCleanup -SVar:DBCleanup:DB$ Cleanup | ClearChosenCard$ True +A:SP$ Token | Cost$ 3 W | TokenOwner$ You | TokenAmount$ 1 | TokenName$ Bird | TokenTypes$ Creature,Bird | TokenColors$ White | TokenPower$ 1 | TokenToughness$ 1 | TokenKeywords$ Flying | TokenImage$ w 1 1 bird rtr | SubAbility$ DBCopy | SpellDescription$ Create a 1/1 white Bird creature token with flying, then populate. (Create a token that's a copy of a creature token you control.) +SVar:DBCopy:DB$ CopyPermanent | Choices$ Creature.token+YouCtrl | NumCopies$ 1 | Populate$ True DeckHas:Ability$Token DeckHints:Ability$Token SVar:Picture:http://www.wizards.com/global/images/magic/general/eyes_in_the_skies.jpg diff --git a/forge-gui/res/cardsfolder/g/growing_ranks.txt b/forge-gui/res/cardsfolder/g/growing_ranks.txt index 1c40181296d..a8781acf266 100644 --- a/forge-gui/res/cardsfolder/g/growing_ranks.txt +++ b/forge-gui/res/cardsfolder/g/growing_ranks.txt @@ -1,10 +1,8 @@ Name:Growing Ranks ManaCost:2 GW GW Types:Enchantment -T:Mode$ Phase | Phase$ Upkeep | TriggerZones$ Battlefield | ValidPlayer$ You | Execute$ TrigChoose | TriggerDescription$ At the beginning of your upkeep, populate. (Create a token that's a copy of a creature token you control.) -SVar:TrigChoose:DB$ ChooseCard | Defined$ You | Amount$ 1 | Choices$ Creature.token+YouCtrl | SubAbility$ DBCopy | Mandatory$ True | AILogic$ Clone -SVar:DBCopy:DB$ CopyPermanent | Defined$ ChosenCard | NumCopies$ 1 | SubAbility$ DBCleanup -SVar:DBCleanup:DB$ Cleanup | ClearChosenCard$ True +T:Mode$ Phase | Phase$ Upkeep | TriggerZones$ Battlefield | ValidPlayer$ You | Execute$ DBCopy | TriggerDescription$ At the beginning of your upkeep, populate. (Create a token that's a copy of a creature token you control.) +SVar:DBCopy:DB$ CopyPermanent | Choices$ Creature.token+YouCtrl | NumCopies$ 1 | Populate$ True DeckNeeds:Ability$Token SVar:Picture:http://www.wizards.com/global/images/magic/general/growing_ranks.jpg Oracle:At the beginning of your upkeep, populate. (Create a token that's a copy of a creature token you control.) diff --git a/forge-gui/res/cardsfolder/h/horncallers_chant.txt b/forge-gui/res/cardsfolder/h/horncallers_chant.txt index 3e1db02bee7..79bc430613c 100644 --- a/forge-gui/res/cardsfolder/h/horncallers_chant.txt +++ b/forge-gui/res/cardsfolder/h/horncallers_chant.txt @@ -1,10 +1,8 @@ Name:Horncaller's Chant ManaCost:7 G Types:Sorcery -A:SP$ Token | Cost$ 7 G | TokenAmount$ 1 | TokenName$ Rhino | TokenTypes$ Creature,Rhino | TokenColors$ Green | TokenOwner$ You | TokenPower$ 4 | TokenToughness$ 4 | TokenKeywords$ Trample | TokenImage$ g 4 4 rhino rtr | SubAbility$ DBChoose | SpellDescription$ Create a 4/4 green Rhino creature token with trample, then populate. (Create a token that's a copy of a creature token you control.) -SVar:DBChoose:DB$ ChooseCard | Defined$ You | Amount$ 1 | Choices$ Creature.token+YouCtrl | SubAbility$ DBCopy | Mandatory$ True | AILogic$ Clone -SVar:DBCopy:DB$ CopyPermanent | Defined$ ChosenCard | NumCopies$ 1 | SubAbility$ DBCleanup -SVar:DBCleanup:DB$ Cleanup | ClearChosenCard$ True +A:SP$ Token | Cost$ 7 G | TokenAmount$ 1 | TokenName$ Rhino | TokenTypes$ Creature,Rhino | TokenColors$ Green | TokenOwner$ You | TokenPower$ 4 | TokenToughness$ 4 | TokenKeywords$ Trample | TokenImage$ g 4 4 rhino rtr | SubAbility$ DBCopy | SpellDescription$ Create a 4/4 green Rhino creature token with trample, then populate. (Create a token that's a copy of a creature token you control.) +SVar:DBCopy:DB$ CopyPermanent | Choices$ Creature.token+YouCtrl | NumCopies$ 1 | Populate$ True DeckHas:Ability$Token DeckHints:Ability$Token SVar:Picture:http://www.wizards.com/global/images/magic/general/horncallers_chant.jpg diff --git a/forge-gui/res/cardsfolder/r/rootborn_defenses.txt b/forge-gui/res/cardsfolder/r/rootborn_defenses.txt index 3229dae8a9a..61be188bd09 100644 --- a/forge-gui/res/cardsfolder/r/rootborn_defenses.txt +++ b/forge-gui/res/cardsfolder/r/rootborn_defenses.txt @@ -1,10 +1,8 @@ Name:Rootborn Defenses ManaCost:2 W Types:Instant -A:SP$ ChooseCard | Cost$ 2 W | Defined$ You | Amount$ 1 | Choices$ Creature.token+YouCtrl | SubAbility$ DBCopy | AILogic$ Clone | Mandatory$ True | SpellDescription$ Populate. Creatures you control gain indestructible until end of turn. (To populate, create a token that's a copy of a creature token you control.) -SVar:DBCopy:DB$ CopyPermanent | Defined$ ChosenCard | NumCopies$ 1 | SubAbility$ DBPumpAll -SVar:DBPumpAll:DB$ PumpAll | ValidCards$ Creature.YouCtrl | KW$ Indestructible | SubAbility$ DBCleanup -SVar:DBCleanup:DB$ Cleanup | ClearChosenCard$ True +A:SP$ CopyPermanent | Cost$ 2 W | Choices$ Creature.token+YouCtrl | NumCopies$ 1 | Populate$ True | SubAbility$ DBPumpAll | StackDescription$ SpellDescription | SpellDescription$ Populate. Creatures you control gain indestructible until end of turn. (To populate, create a token that's a copy of a creature token you control.) +SVar:DBPumpAll:DB$ PumpAll | ValidCards$ Creature.YouCtrl | KW$ Indestructible DeckHints:Ability$Token SVar:Picture:http://www.wizards.com/global/images/magic/general/rootborn_defenses.jpg Oracle:Populate. Creatures you control gain indestructible until end of turn. (To populate, create a token that's a copy of a creature token you control.) diff --git a/forge-gui/res/cardsfolder/s/scion_of_vitu_ghazi.txt b/forge-gui/res/cardsfolder/s/scion_of_vitu_ghazi.txt index 9af83da1c02..85498d901bc 100644 --- a/forge-gui/res/cardsfolder/s/scion_of_vitu_ghazi.txt +++ b/forge-gui/res/cardsfolder/s/scion_of_vitu_ghazi.txt @@ -3,10 +3,8 @@ ManaCost:3 W W Types:Creature Elemental PT:4/4 T:Mode$ ChangesZone | ValidCard$ Card.wasCastFromHand+Self | Destination$ Battlefield | Execute$ TrigToken | TriggerDescription$ When CARDNAME enters the battlefield, if you cast it from your hand, create a 1/1 white Bird creature token with flying, then populate. (Create a token that's a copy of a creature token you control.) -SVar:TrigToken:DB$ Token | TokenOwner$ You | TokenAmount$ 1 | TokenName$ Bird | TokenTypes$ Creature,Bird | TokenColors$ White | TokenPower$ 1 | TokenToughness$ 1 | TokenKeywords$ Flying | TokenImage$ w 1 1 bird rtr | SubAbility$ DBChoose -SVar:DBChoose:DB$ ChooseCard | Defined$ You | Amount$ 1 | Choices$ Creature.token+YouCtrl | Mandatory$ True | AILogic$ Clone | SubAbility$ DBCopy -SVar:DBCopy:DB$ CopyPermanent | Defined$ ChosenCard | NumCopies$ 1 | SubAbility$ DBCleanup -SVar:DBCleanup:DB$ Cleanup | ClearChosenCard$ True +SVar:TrigToken:DB$ Token | TokenOwner$ You | TokenAmount$ 1 | TokenName$ Bird | TokenTypes$ Creature,Bird | TokenColors$ White | TokenPower$ 1 | TokenToughness$ 1 | TokenKeywords$ Flying | TokenImage$ w 1 1 bird rtr | SubAbility$ DBCopy +SVar:DBCopy:DB$ CopyPermanent | Choices$ Creature.token+YouCtrl | NumCopies$ 1 | Populate$ True DeckHas:Ability$Token SVar:Picture:http://www.wizards.com/global/images/magic/general/scion_of_vitu_ghazi.jpg Oracle:When Scion of Vitu-Ghazi enters the battlefield, if you cast it from your hand, create a 1/1 white Bird creature token with flying, then populate. (Create a token that's a copy of a creature token you control.) diff --git a/forge-gui/res/cardsfolder/s/sundering_growth.txt b/forge-gui/res/cardsfolder/s/sundering_growth.txt index 4236b4af62a..660b6c0d96a 100644 --- a/forge-gui/res/cardsfolder/s/sundering_growth.txt +++ b/forge-gui/res/cardsfolder/s/sundering_growth.txt @@ -1,10 +1,8 @@ Name:Sundering Growth ManaCost:GW GW Types:Instant -A:SP$ Destroy | Cost$ GW GW | ValidTgts$ Artifact,Enchantment | TgtPrompt$ Select target artifact or enchantment | SubAbility$ DBChoose | SpellDescription$ Destroy target artifact or enchantment, then populate. (Create a token that's a copy of a creature token you control.) -SVar:DBChoose:DB$ ChooseCard | Defined$ You | Amount$ 1 | Choices$ Creature.token+YouCtrl | SubAbility$ DBCopy | Mandatory$ True | AILogic$ Clone -SVar:DBCopy:DB$ CopyPermanent | Defined$ ChosenCard | NumCopies$ 1 | SubAbility$ DBCleanup -SVar:DBCleanup:DB$ Cleanup | ClearChosenCard$ True +A:SP$ Destroy | Cost$ GW GW | ValidTgts$ Artifact,Enchantment | TgtPrompt$ Select target artifact or enchantment | SubAbility$ DBCopy | SpellDescription$ Destroy target artifact or enchantment, then populate. (Create a token that's a copy of a creature token you control.) +SVar:DBCopy:DB$ CopyPermanent | Choices$ Creature.token+YouCtrl | NumCopies$ 1 | Populate$ True DeckHints:Ability$Token SVar:Picture:http://www.wizards.com/global/images/magic/general/sundering_growth.jpg Oracle:Destroy target artifact or enchantment, then populate. (Create a token that's a copy of a creature token you control.) diff --git a/forge-gui/res/cardsfolder/t/trostani_selesnyas_voice.txt b/forge-gui/res/cardsfolder/t/trostani_selesnyas_voice.txt index 15d67311650..41da7ed2d4d 100644 --- a/forge-gui/res/cardsfolder/t/trostani_selesnyas_voice.txt +++ b/forge-gui/res/cardsfolder/t/trostani_selesnyas_voice.txt @@ -5,9 +5,7 @@ PT:2/5 T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Creature.YouCtrl+Other | TriggerZones$ Battlefield | Execute$ TrigGainLife | TriggerDescription$ Whenever another creature enters the battlefield under your control, you gain life equal to that creature's toughness. SVar:TrigGainLife:DB$GainLife | Defined$ You | LifeAmount$ Life | References$ Life SVar:Life:TriggeredCard$CardToughness -A:AB$ ChooseCard | Cost$ 1 G W T | Defined$ You | Amount$ 1 | Choices$ Creature.token+YouCtrl | SubAbility$ DBCopy | Mandatory$ True | AILogic$ Clone | SpellDescription$ Populate. (Create a token that's a copy of a creature token you control.) -SVar:DBCopy:DB$ CopyPermanent | Defined$ ChosenCard | NumCopies$ 1 | SubAbility$ DBCleanup -SVar:DBCleanup:DB$ Cleanup | ClearChosenCard$ True +A:AB$ CopyPermanent | Cost$ 1 G W T | Choices$ Creature.token+YouCtrl | NumCopies$ 1 | Populate$ True | StackDescription$ SpellDescription | SpellDescription$ Populate. (Create a token that's a copy of a creature token you control.) DeckHints:Ability$Token SVar:Picture:http://www.wizards.com/global/images/magic/general/trostani_selesnyas_voice.jpg Oracle:Whenever another creature enters the battlefield under your control, you gain life equal to that creature's toughness.\n{1}{G}{W}, {T}: Populate. (Create a token that's a copy of a creature token you control.) diff --git a/forge-gui/res/cardsfolder/t/trostanis_judgment.txt b/forge-gui/res/cardsfolder/t/trostanis_judgment.txt index e9ec8f8ca3c..c62c72841cc 100644 --- a/forge-gui/res/cardsfolder/t/trostanis_judgment.txt +++ b/forge-gui/res/cardsfolder/t/trostanis_judgment.txt @@ -1,10 +1,8 @@ Name:Trostani's Judgment ManaCost:5 W Types:Instant -A:SP$ ChangeZone | Cost$ 5 W | ValidTgts$ Creature | TgtPrompt$ Select target creature | Origin$ Battlefield | Destination$ Exile | SubAbility$ DBChoose | SpellDescription$ Exile target creature, then populate. (Create a token that's a copy of a creature token you control.) -SVar:DBChoose:DB$ ChooseCard | Defined$ You | Amount$ 1 | Choices$ Creature.token+YouCtrl | SubAbility$ DBCopy | Mandatory$ True | AILogic$ Clone -SVar:DBCopy:DB$ CopyPermanent | Defined$ ChosenCard | NumCopies$ 1 | SubAbility$ DBCleanup -SVar:DBCleanup:DB$ Cleanup | ClearChosenCard$ True +A:SP$ ChangeZone | Cost$ 5 W | ValidTgts$ Creature | TgtPrompt$ Select target creature | Origin$ Battlefield | Destination$ Exile | SubAbility$ DBCopy | SpellDescription$ Exile target creature, then populate. (Create a token that's a copy of a creature token you control.) +SVar:DBCopy:DB$ CopyPermanent | Choices$ Creature.token+YouCtrl | NumCopies$ 1 | Populate$ True DeckHints:Ability$Token SVar:Picture:http://www.wizards.com/global/images/magic/general/trostanis_judgment.jpg Oracle:Exile target creature, then populate. (Create a token that's a copy of a creature token you control.) diff --git a/forge-gui/res/cardsfolder/v/vitu_ghazi_guildmage.txt b/forge-gui/res/cardsfolder/v/vitu_ghazi_guildmage.txt index b3d33af26ea..1555658b8b1 100644 --- a/forge-gui/res/cardsfolder/v/vitu_ghazi_guildmage.txt +++ b/forge-gui/res/cardsfolder/v/vitu_ghazi_guildmage.txt @@ -3,9 +3,7 @@ ManaCost:G W Types:Creature Dryad Shaman PT:2/2 A:AB$ Token | Cost$ 4 G W | TokenAmount$ 1 | TokenName$ Centaur | TokenTypes$ Creature,Centaur | TokenOwner$ You | TokenColors$ Green | TokenPower$ 3 | TokenToughness$ 3 | TokenImage$ g 3 3 centaur rtr | SpellDescription$ Create a 3/3 green Centaur creature token. -A:AB$ ChooseCard | Cost$ 2 G W | Defined$ You | Amount$ 1 | Choices$ Creature.token+YouCtrl | SubAbility$ DBCopy | Mandatory$ True | AILogic$ Clone | SpellDescription$ Populate. (Create a token that's a copy of a creature token you control.) -SVar:DBCopy:DB$ CopyPermanent | Defined$ ChosenCard | NumCopies$ 1 | SubAbility$ DBCleanup -SVar:DBCleanup:DB$ Cleanup | ClearChosenCard$ True +A:AB$ CopyPermanent | Cost$ 2 G W | Choices$ Creature.token+YouCtrl | NumCopies$ 1 | Populate$ True | StackDescription$ SpellDescription | SpellDescription$ Populate. (Create a token that's a copy of a creature token you control.) DeckHas:Ability$Token DeckHints:Ability$Token SVar:Picture:http://www.wizards.com/global/images/magic/general/vitu_ghazi_guildmage.jpg diff --git a/forge-gui/res/cardsfolder/w/wake_the_reflections.txt b/forge-gui/res/cardsfolder/w/wake_the_reflections.txt index eb28e7b92d7..ffffe78117d 100644 --- a/forge-gui/res/cardsfolder/w/wake_the_reflections.txt +++ b/forge-gui/res/cardsfolder/w/wake_the_reflections.txt @@ -1,9 +1,7 @@ Name:Wake the Reflections ManaCost:W Types:Sorcery -A:SP$ ChooseCard | Cost$ W | Defined$ You | Amount$ 1 | Choices$ Creature.token+YouCtrl | AILogic$ Clone | SubAbility$ DBCopy | Mandatory$ True | SpellDescription$ Populate. (Create a token that's a copy of a creature token you control.) -SVar:DBCopy:DB$ CopyPermanent | Defined$ ChosenCard | NumCopies$ 1 | SubAbility$ DBCleanup -SVar:DBCleanup:DB$ Cleanup | ClearChosenCard$ True +A:SP$ CopyPermanent | Cost$ W | Choices$ Creature.token+YouCtrl | NumCopies$ 1 | Populate$ True | SpellDescription$ Populate. (Create a token that's a copy of a creature token you control.) DeckNeeds:Ability$Token SVar:Picture:http://www.wizards.com/global/images/magic/general/wake_the_reflections.jpg Oracle:Populate. (Create a token that's a copy of a creature token you control.) diff --git a/forge-gui/res/cardsfolder/w/wayfaring_temple.txt b/forge-gui/res/cardsfolder/w/wayfaring_temple.txt index f3e0e9d021c..c2eb2e2530d 100644 --- a/forge-gui/res/cardsfolder/w/wayfaring_temple.txt +++ b/forge-gui/res/cardsfolder/w/wayfaring_temple.txt @@ -4,10 +4,8 @@ Types:Creature Elemental PT:*/* S:Mode$ Continuous | EffectZone$ All | CharacteristicDefining$ True | SetPower$ X | SetToughness$ X | Description$ CARDNAME's power and toughness are each equal to the number of creatures you control. SVar:X:Count$Valid Creature.YouCtrl -T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | CombatDamage$ True | Execute$ TrigPopulate | TriggerDescription$ Whenever CARDNAME deals combat damage to a player, populate. (Create a token that's a copy of a creature token you control.) -SVar:TrigPopulate:DB$ ChooseCard | Defined$ You | Amount$ 1 | Choices$ Creature.token+YouCtrl | SubAbility$ DBCopy | Mandatory$ True | AILogic$ Clone -SVar:DBCopy:DB$ CopyPermanent | Defined$ ChosenCard | NumCopies$ 1 | SubAbility$ DBCleanup -SVar:DBCleanup:DB$ Cleanup | ClearChosenCard$ True +T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | CombatDamage$ True | Execute$ DBCopy | TriggerDescription$ Whenever CARDNAME deals combat damage to a player, populate. (Create a token that's a copy of a creature token you control.) +SVar:DBCopy:DB$ CopyPermanent | Choices$ Creature.token+YouCtrl | NumCopies$ 1 | Populate$ True SVar:BuffedBy:Creature SVar:NoZeroToughnessAI:True DeckHints:Ability$Token