mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-18 19:58:00 +00:00
Merge branch 'master' of https://git.cardforge.org/core-developers/forge.git
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<artifactId>forge</artifactId>
|
||||
<groupId>forge</groupId>
|
||||
<version>1.6.27-SNAPSHOT</version>
|
||||
<version>1.6.28-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>forge-ai</artifactId>
|
||||
|
||||
@@ -99,6 +99,8 @@ public class ComputerUtil {
|
||||
sa.resetPaidHash();
|
||||
}
|
||||
|
||||
sa = GameActionUtil.addExtraKeywordCost(sa);
|
||||
|
||||
if (sa.getApi() == ApiType.Charm && !sa.isWrapper()) {
|
||||
CharmEffect.makeChoices(sa);
|
||||
}
|
||||
@@ -208,9 +210,9 @@ public class ComputerUtil {
|
||||
}
|
||||
|
||||
// this is used for AI's counterspells
|
||||
public static final boolean playStack(final SpellAbility sa, final Player ai, final Game game) {
|
||||
public static final boolean playStack(SpellAbility sa, final Player ai, final Game game) {
|
||||
sa.setActivatingPlayer(ai);
|
||||
if (!ComputerUtilCost.canPayCost(sa, ai))
|
||||
if (!ComputerUtilCost.canPayCost(sa, ai))
|
||||
return false;
|
||||
|
||||
final Card source = sa.getHostCard();
|
||||
@@ -220,6 +222,9 @@ public class ComputerUtil {
|
||||
sa.setLastStateGraveyard(game.getLastStateGraveyard());
|
||||
sa.setHostCard(game.getAction().moveToStack(source, sa));
|
||||
}
|
||||
|
||||
sa = GameActionUtil.addExtraKeywordCost(sa);
|
||||
|
||||
final Cost cost = sa.getPayCosts();
|
||||
if (cost == null) {
|
||||
ComputerUtilMana.payManaCost(ai, sa);
|
||||
@@ -249,13 +254,15 @@ public class ComputerUtil {
|
||||
}
|
||||
|
||||
public static final boolean playSpellAbilityWithoutPayingManaCost(final Player ai, final SpellAbility sa, final Game game) {
|
||||
final SpellAbility newSA = sa.copyWithNoManaCost();
|
||||
SpellAbility newSA = sa.copyWithNoManaCost();
|
||||
newSA.setActivatingPlayer(ai);
|
||||
|
||||
if (!CostPayment.canPayAdditionalCosts(newSA.getPayCosts(), newSA)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
newSA = GameActionUtil.addExtraKeywordCost(newSA);
|
||||
|
||||
final Card source = newSA.getHostCard();
|
||||
if (newSA.isSpell() && !source.isCopiedSpell()) {
|
||||
source.setCastSA(newSA);
|
||||
@@ -275,7 +282,7 @@ public class ComputerUtil {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static final void playNoStack(final Player ai, final SpellAbility sa, final Game game) {
|
||||
public static final void playNoStack(final Player ai, SpellAbility sa, final Game game) {
|
||||
sa.setActivatingPlayer(ai);
|
||||
// TODO: We should really restrict what doesn't use the Stack
|
||||
if (ComputerUtilCost.canPayCost(sa, ai)) {
|
||||
@@ -287,6 +294,8 @@ public class ComputerUtil {
|
||||
sa.setHostCard(game.getAction().moveToStack(source, sa));
|
||||
}
|
||||
|
||||
sa = GameActionUtil.addExtraKeywordCost(sa);
|
||||
|
||||
final Cost cost = sa.getPayCosts();
|
||||
if (cost == null) {
|
||||
ComputerUtilMana.payManaCost(ai, sa);
|
||||
|
||||
@@ -25,6 +25,7 @@ import forge.game.card.*;
|
||||
import forge.game.card.CardPredicates.Presets;
|
||||
import forge.game.combat.Combat;
|
||||
import forge.game.cost.*;
|
||||
import forge.game.keyword.KeywordInterface;
|
||||
import forge.game.mana.Mana;
|
||||
import forge.game.mana.ManaConversionMatrix;
|
||||
import forge.game.mana.ManaCostBeingPaid;
|
||||
@@ -1253,4 +1254,25 @@ public class PlayerControllerAi extends PlayerController {
|
||||
// Always true?
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int chooseNumberForKeywordCost(SpellAbility sa, Cost cost, KeywordInterface keyword, String prompt,
|
||||
int max) {
|
||||
// TODO: improve the logic depending on the keyword and the playability of the cost-modified SA (enough targets present etc.)
|
||||
int chosenAmount = 0;
|
||||
|
||||
Cost costSoFar = sa.getPayCosts() != null ? sa.getPayCosts().copy() : Cost.Zero;
|
||||
|
||||
for (int i = 0; i < max; i++) {
|
||||
costSoFar.add(cost);
|
||||
SpellAbility fullCostSa = sa.copyWithDefinedCost(costSoFar);
|
||||
if (ComputerUtilCost.canPayCost(fullCostSa, player)) {
|
||||
chosenAmount++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return chosenAmount;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<artifactId>forge</artifactId>
|
||||
<groupId>forge</groupId>
|
||||
<version>1.6.27-SNAPSHOT</version>
|
||||
<version>1.6.28-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>forge-core</artifactId>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<artifactId>forge</artifactId>
|
||||
<groupId>forge</groupId>
|
||||
<version>1.6.27-SNAPSHOT</version>
|
||||
<version>1.6.28-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>forge-game</artifactId>
|
||||
|
||||
@@ -29,7 +29,9 @@ import forge.game.card.CardPlayOption.PayManaCost;
|
||||
import forge.game.cost.Cost;
|
||||
import forge.game.keyword.KeywordInterface;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.player.PlayerController;
|
||||
import forge.game.spellability.*;
|
||||
import forge.game.trigger.Trigger;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.util.TextUtil;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
@@ -250,11 +252,6 @@ public final class GameActionUtil {
|
||||
if (keyword.startsWith("Buyback")) {
|
||||
final Cost cost = new Cost(keyword.substring(8), false);
|
||||
costs.add(new OptionalCostValue(OptionalCost.Buyback, cost));
|
||||
} else if (keyword.equals("Conspire")) {
|
||||
final String conspireCost = "tapXType<2/Creature.SharesColorWith/" +
|
||||
"untapped creature you control that shares a color with " + source.getName() + ">";
|
||||
final Cost cost = new Cost(conspireCost, false);
|
||||
costs.add(new OptionalCostValue(OptionalCost.Conspire, cost));
|
||||
} else if (keyword.startsWith("Entwine")) {
|
||||
String[] k = keyword.split(":");
|
||||
final Cost cost = new Cost(k[1], false);
|
||||
@@ -301,15 +298,11 @@ public final class GameActionUtil {
|
||||
}
|
||||
final SpellAbility result = sa.copy();
|
||||
for (OptionalCostValue v : list) {
|
||||
// need to copy cost, otherwise it does alter the original
|
||||
result.setPayCosts(result.getPayCosts().copy().add(v.getCost()));
|
||||
result.getPayCosts().add(v.getCost());
|
||||
result.addOptionalCost(v.getType());
|
||||
|
||||
// add some extra logic, try to move it to other parts
|
||||
switch (v.getType()) {
|
||||
case Conspire:
|
||||
result.addConspireInstance();
|
||||
break;
|
||||
case Retrace:
|
||||
case Jumpstart:
|
||||
result.getRestrictions().setZone(ZoneType.Graveyard);
|
||||
@@ -363,6 +356,71 @@ public final class GameActionUtil {
|
||||
return abilities;
|
||||
}
|
||||
|
||||
public static SpellAbility addExtraKeywordCost(final SpellAbility sa) {
|
||||
if (!sa.isSpell() || sa.isCopied()) {
|
||||
return sa;
|
||||
}
|
||||
SpellAbility result = null;
|
||||
final Card host = sa.getHostCard();
|
||||
final PlayerController pc = sa.getActivatingPlayer().getController();
|
||||
|
||||
host.getGame().getAction().checkStaticAbilities(false);
|
||||
|
||||
boolean reset = false;
|
||||
|
||||
for (KeywordInterface ki : host.getKeywords()) {
|
||||
final String o = ki.getOriginal();
|
||||
if (o.equals("Conspire")) {
|
||||
Trigger tr = Iterables.getFirst(ki.getTriggers(), null);
|
||||
if (tr != null) {
|
||||
final String conspireCost = "tapXType<2/Creature.SharesColorWith/" +
|
||||
"untapped creature you control that shares a color with " + host.getName() + ">";
|
||||
final Cost cost = new Cost(conspireCost, false);
|
||||
String str = "Pay for Conspire? " + cost.toSimpleString();
|
||||
|
||||
boolean v = pc.addKeywordCost(sa, cost, ki, str);
|
||||
tr.setSVar("Conspire", v ? "1" : "0");
|
||||
|
||||
if (v) {
|
||||
if (result == null) {
|
||||
result = sa.copy();
|
||||
}
|
||||
result.getPayCosts().add(cost);
|
||||
reset = true;
|
||||
}
|
||||
}
|
||||
} else if (o.startsWith("Replicate")) {
|
||||
Trigger tr = Iterables.getFirst(ki.getTriggers(), null);
|
||||
if (tr != null) {
|
||||
String costStr = o.split(":")[1];
|
||||
final Cost cost = new Cost(costStr, false);
|
||||
|
||||
String str = "Choose Amount for Replicate: " + cost.toSimpleString();
|
||||
|
||||
int v = pc.chooseNumberForKeywordCost(sa, cost, ki, str, Integer.MAX_VALUE);
|
||||
|
||||
tr.setSVar("ReplicateAmount", String.valueOf(v));
|
||||
tr.getOverridingAbility().setSVar("ReplicateAmount", String.valueOf(v));
|
||||
|
||||
for (int i = 0; i < v; i++) {
|
||||
if (result == null) {
|
||||
result = sa.copy();
|
||||
}
|
||||
result.getPayCosts().add(cost);
|
||||
reset = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// reset active Trigger
|
||||
if (reset) {
|
||||
host.getGame().getTriggerHandler().resetActiveTriggers(false);
|
||||
}
|
||||
|
||||
return result != null ? result : sa;
|
||||
}
|
||||
|
||||
private static boolean hasUrzaLands(final Player p) {
|
||||
final CardCollectionView landsControlled = p.getCardsIn(ZoneType.Battlefield);
|
||||
return Iterables.any(landsControlled, Predicates.and(CardPredicates.isType("Urza's"), CardPredicates.isType("Mine")))
|
||||
|
||||
@@ -1843,7 +1843,11 @@ public class AbilityUtils {
|
||||
public static SpellAbility addSpliceEffects(final SpellAbility sa) {
|
||||
final Card source = sa.getHostCard();
|
||||
final Player player = sa.getActivatingPlayer();
|
||||
|
||||
|
||||
if (!sa.isSpell() || source.isCopiedSpell()) {
|
||||
return sa;
|
||||
}
|
||||
|
||||
final CardCollectionView hand = player.getCardsIn(ZoneType.Hand);
|
||||
|
||||
if (hand.isEmpty()) {
|
||||
|
||||
@@ -1905,13 +1905,14 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
}
|
||||
sb.append(keywordsToText(getUnhiddenKeywords(state)));
|
||||
|
||||
// Process replacement effects first so that ETB tabbed can be printed
|
||||
// Process replacement effects first so that "enters the battlefield tapped"
|
||||
// and "as ~ enters the battlefield, choose...", etc can be printed
|
||||
// here. The rest will be printed later.
|
||||
StringBuilder replacementEffects = new StringBuilder();
|
||||
for (final ReplacementEffect replacementEffect : state.getReplacementEffects()) {
|
||||
if (!replacementEffect.isSecondary()) {
|
||||
String text = replacementEffect.toString();
|
||||
if (text.equals("CARDNAME enters the battlefield tapped.")) {
|
||||
if (text.contains("enters the battlefield")) {
|
||||
sb.append(text).append("\r\n");
|
||||
} else {
|
||||
replacementEffects.append(text).append("\r\n");
|
||||
|
||||
@@ -2361,11 +2361,12 @@ public class CardFactoryUtil {
|
||||
inst.addTrigger(parsedTrigger);
|
||||
inst.addTrigger(parsedTrigReturn);
|
||||
} else if (keyword.equals("Conspire")) {
|
||||
final String trigScript = "Mode$ SpellCast | ValidCard$ Card.Self | Conspire$ True | Secondary$ True | TriggerDescription$ Copy CARDNAME if its conspire cost was paid";
|
||||
final String trigScript = "Mode$ SpellCast | ValidCard$ Card.Self | CheckSVar$ Conspire | Secondary$ True | TriggerDescription$ Copy CARDNAME if its conspire cost was paid";
|
||||
final String abString = "DB$ CopySpellAbility | Defined$ TriggeredSpellAbility | Amount$ 1";
|
||||
|
||||
final Trigger conspireTrigger = TriggerHandler.parseTrigger(trigScript, card, intrinsic);
|
||||
conspireTrigger.setOverridingAbility(AbilityFactory.getAbility(abString, card));
|
||||
conspireTrigger.setSVar("Conspire", "0");
|
||||
inst.addTrigger(conspireTrigger);
|
||||
} else if (keyword.startsWith("Cumulative upkeep")) {
|
||||
final String[] k = keyword.split(":");
|
||||
@@ -2942,6 +2943,17 @@ public class CardFactoryUtil {
|
||||
+ " exile CARDNAME. | Secondary$ True";
|
||||
final Trigger myTrigger = TriggerHandler.parseTrigger(trigStr, card, intrinsic);
|
||||
inst.addTrigger(myTrigger);
|
||||
} else if (keyword.startsWith("Replicate")) {
|
||||
final String trigScript = "Mode$ SpellCast | ValidCard$ Card.Self | CheckSVar$ ReplicateAmount | Secondary$ True | TriggerDescription$ Copy CARDNAME for each time you paid its replicate cost";
|
||||
final String abString = "DB$ CopySpellAbility | Defined$ TriggeredSpellAbility | Amount$ ReplicateAmount";
|
||||
|
||||
final Trigger replicateTrigger = TriggerHandler.parseTrigger(trigScript, card, intrinsic);
|
||||
final SpellAbility replicateAbility = AbilityFactory.getAbility(abString, card);
|
||||
replicateAbility.setSVar("ReplicateAmount", "0");
|
||||
replicateTrigger.setOverridingAbility(replicateAbility);
|
||||
replicateTrigger.setSVar("ReplicateAmount", "0");
|
||||
inst.addTrigger(replicateTrigger);
|
||||
|
||||
} else if (keyword.startsWith("Ripple")) {
|
||||
final String[] k = keyword.split(":");
|
||||
final String num = k[1];
|
||||
@@ -4225,9 +4237,6 @@ public class CardFactoryUtil {
|
||||
|
||||
sa.setTemporary(!intrinsic);
|
||||
inst.addSpellAbility(sa);
|
||||
|
||||
} else if (keyword.startsWith("Replicate")) {
|
||||
card.getFirstSpellAbility().addAnnounceVar("Replicate");
|
||||
} else if (keyword.startsWith("Scavenge")) {
|
||||
final String[] k = keyword.split(":");
|
||||
final String manacost = k[1];
|
||||
|
||||
@@ -19,6 +19,7 @@ import forge.game.combat.Combat;
|
||||
import forge.game.cost.Cost;
|
||||
import forge.game.cost.CostPart;
|
||||
import forge.game.cost.CostPartMana;
|
||||
import forge.game.keyword.KeywordInterface;
|
||||
import forge.game.mana.Mana;
|
||||
import forge.game.mana.ManaConversionMatrix;
|
||||
import forge.game.replacement.ReplacementEffect;
|
||||
@@ -47,7 +48,6 @@ public abstract class PlayerController {
|
||||
DeclareBlocker,
|
||||
Echo,
|
||||
Multikicker,
|
||||
Replicate,
|
||||
CumulativeUpkeep,
|
||||
}
|
||||
|
||||
@@ -182,6 +182,11 @@ public abstract class PlayerController {
|
||||
public abstract CardCollection chooseCardsToDiscardToMaximumHandSize(int numDiscard);
|
||||
public abstract boolean payManaOptional(Card card, Cost cost, SpellAbility sa, String prompt, ManaPaymentPurpose purpose);
|
||||
|
||||
public abstract int chooseNumberForKeywordCost(SpellAbility sa, Cost cost, KeywordInterface keyword, String prompt, int max);
|
||||
public boolean addKeywordCost(SpellAbility sa, Cost cost, KeywordInterface keyword, String prompt) {
|
||||
return chooseNumberForKeywordCost(sa, cost, keyword, prompt, 1) == 1;
|
||||
}
|
||||
|
||||
public abstract int chooseNumber(SpellAbility sa, String title, int min, int max);
|
||||
public abstract int chooseNumber(SpellAbility sa, String title, List<Integer> values, Player relatedPlayer);
|
||||
public int chooseNumber(SpellAbility sa, String string, int min, int max, Map<String, Object> params) {
|
||||
|
||||
@@ -5,7 +5,6 @@ package forge.game.spellability;
|
||||
*
|
||||
*/
|
||||
public enum OptionalCost {
|
||||
Conspire("Conspire"),
|
||||
Buyback("Buyback"),
|
||||
Entwine("Entwine"),
|
||||
Kicker1("Kicker"),
|
||||
|
||||
@@ -144,7 +144,6 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit
|
||||
private CardCollection tappedForConvoke = new CardCollection();
|
||||
private Card sacrificedAsOffering = null;
|
||||
private Card sacrificedAsEmerge = null;
|
||||
private int conspireInstances = 0;
|
||||
|
||||
private AbilityManaPart manaPart = null;
|
||||
|
||||
@@ -301,9 +300,7 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit
|
||||
}
|
||||
|
||||
public boolean canPlayWithOptionalCost(OptionalCostValue opt) {
|
||||
SpellAbility saCopy = this.copy();
|
||||
saCopy = GameActionUtil.addOptionalCosts(saCopy, Lists.newArrayList(opt));
|
||||
return saCopy.canPlay();
|
||||
return GameActionUtil.addOptionalCosts(this, Lists.newArrayList(opt)).canPlay();
|
||||
}
|
||||
|
||||
public boolean isPossible() {
|
||||
@@ -1700,19 +1697,6 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit
|
||||
return ForgeScript.spellAbilityHasProperty(this, property, sourceController, source, spellAbility);
|
||||
}
|
||||
|
||||
// Methods enabling multiple instances of conspire
|
||||
public void addConspireInstance() {
|
||||
conspireInstances++;
|
||||
}
|
||||
|
||||
public void subtractConspireInstance() {
|
||||
conspireInstances--;
|
||||
}
|
||||
|
||||
public int getConspireInstances() {
|
||||
return conspireInstances;
|
||||
} // End of Conspire methods
|
||||
|
||||
public boolean isCumulativeupkeep() {
|
||||
return cumulativeupkeep;
|
||||
}
|
||||
|
||||
@@ -32,7 +32,6 @@ import forge.game.card.CardLists;
|
||||
import forge.game.card.CardUtil;
|
||||
import forge.game.cost.Cost;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.spellability.OptionalCost;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.game.spellability.SpellAbilityStackInstance;
|
||||
import forge.game.spellability.TargetChoices;
|
||||
@@ -216,18 +215,6 @@ public class TriggerSpellAbilityCast extends Trigger {
|
||||
}
|
||||
}
|
||||
|
||||
if (hasParam("Conspire")) {
|
||||
if (!spellAbility.isOptionalCostPaid(OptionalCost.Conspire)) {
|
||||
return false;
|
||||
}
|
||||
if (spellAbility.getConspireInstances() == 0) {
|
||||
return false;
|
||||
} else {
|
||||
spellAbility.subtractConspireInstance();
|
||||
//System.out.println("Conspire instances left = " + spellAbility.getConspireInstances());
|
||||
}
|
||||
}
|
||||
|
||||
if (hasParam("Outlast")) {
|
||||
if (!spellAbility.isOutlast()) {
|
||||
return false;
|
||||
|
||||
@@ -38,7 +38,6 @@ import forge.card.mana.ManaCost;
|
||||
import forge.game.Game;
|
||||
import forge.game.GameLogEntryType;
|
||||
import forge.game.GameObject;
|
||||
import forge.game.ability.AbilityFactory;
|
||||
import forge.game.ability.AbilityUtils;
|
||||
import forge.game.ability.ApiType;
|
||||
import forge.game.card.Card;
|
||||
@@ -58,7 +57,6 @@ import forge.game.player.PlayerController.ManaPaymentPurpose;
|
||||
import forge.game.replacement.ReplacementEffect;
|
||||
import forge.game.replacement.ReplacementHandler;
|
||||
import forge.game.replacement.ReplacementLayer;
|
||||
import forge.game.spellability.AbilitySub;
|
||||
import forge.game.spellability.AbilityStatic;
|
||||
import forge.game.spellability.OptionalCost;
|
||||
import forge.game.spellability.Spell;
|
||||
@@ -319,35 +317,6 @@ public class MagicStack /* extends MyObservable */ implements Iterable<SpellAbil
|
||||
|
||||
// The ability is added to stack HERE
|
||||
si = push(sp);
|
||||
|
||||
if (sp.isSpell() && (source.hasStartOfKeyword("Replicate")
|
||||
|| ((source.isInstant() || source.isSorcery()) && Iterables.any(activator.getCardsIn(ZoneType.Battlefield),
|
||||
CardPredicates.hasKeyword("Each instant and sorcery spell you cast has replicate. The replicate cost is equal to its mana cost."))))) {
|
||||
Integer magnitude = sp.getSVarInt("Replicate");
|
||||
if (magnitude == null) {
|
||||
magnitude = 0;
|
||||
final Cost costReplicate = new Cost(source.getManaCost(), false);
|
||||
boolean hasPaid = false;
|
||||
int replicateCMC = source.getManaCost().getCMC();
|
||||
do {
|
||||
String prompt = TextUtil.concatWithSpace("Replicate for", source.toString(),"\r\nTimes Replicated:", magnitude.toString(),"\r\n");
|
||||
hasPaid = activator.getController().payManaOptional(source, costReplicate, sp, prompt, ManaPaymentPurpose.Replicate);
|
||||
if (hasPaid) {
|
||||
magnitude++;
|
||||
totManaSpent += replicateCMC;
|
||||
}
|
||||
} while (hasPaid);
|
||||
}
|
||||
|
||||
// Replicate Trigger
|
||||
String effect = TextUtil.concatWithSpace("DB$ CopySpellAbility | Cost$ 0 | Defined$ Parent | Amount$", magnitude.toString());
|
||||
AbilitySub sa = (AbilitySub) AbilityFactory.getAbility(effect, source);
|
||||
sa.setParent(sp);
|
||||
sa.setDescription("Replicate - " + source);
|
||||
sa.setTrigger(true);
|
||||
sa.setCopied(true);
|
||||
addSimultaneousStackEntry(sa);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<packaging.type>jar</packaging.type>
|
||||
<build.min.memory>-Xms1024m</build.min.memory>
|
||||
<build.max.memory>-Xmx1536m</build.max.memory>
|
||||
<alpha-version>1.6.26.001</alpha-version>
|
||||
<alpha-version>1.6.27.001</alpha-version>
|
||||
<sign.keystore>keystore</sign.keystore>
|
||||
<sign.alias>alias</sign.alias>
|
||||
<sign.storepass>storepass</sign.storepass>
|
||||
@@ -19,7 +19,7 @@
|
||||
<parent>
|
||||
<artifactId>forge</artifactId>
|
||||
<groupId>forge</groupId>
|
||||
<version>1.6.27-SNAPSHOT</version>
|
||||
<version>1.6.28-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>forge-gui-android</artifactId>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>forge</artifactId>
|
||||
<groupId>forge</groupId>
|
||||
<version>1.6.27-SNAPSHOT</version>
|
||||
<version>1.6.28-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>forge-gui-desktop</artifactId>
|
||||
|
||||
@@ -29,6 +29,7 @@ import forge.game.combat.CombatUtil;
|
||||
import forge.game.cost.Cost;
|
||||
import forge.game.cost.CostPart;
|
||||
import forge.game.cost.CostPartMana;
|
||||
import forge.game.keyword.KeywordInterface;
|
||||
import forge.game.mana.Mana;
|
||||
import forge.game.mana.ManaConversionMatrix;
|
||||
import forge.game.mana.ManaCostBeingPaid;
|
||||
@@ -695,4 +696,11 @@ public class PlayerControllerForTests extends PlayerController {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int chooseNumberForKeywordCost(SpellAbility sa, Cost cost, KeywordInterface keyword, String prompt,
|
||||
int max) {
|
||||
// TODO Auto-generated method stub
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -6,13 +6,13 @@
|
||||
<packaging.type>jar</packaging.type>
|
||||
<build.min.memory>-Xms128m</build.min.memory>
|
||||
<build.max.memory>-Xmx2048m</build.max.memory>
|
||||
<alpha-version>1.6.26.001</alpha-version>
|
||||
<alpha-version>1.6.27.001</alpha-version>
|
||||
</properties>
|
||||
|
||||
<parent>
|
||||
<artifactId>forge</artifactId>
|
||||
<groupId>forge</groupId>
|
||||
<version>1.6.27-SNAPSHOT</version>
|
||||
<version>1.6.28-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>forge-gui-ios</artifactId>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>forge</artifactId>
|
||||
<groupId>forge</groupId>
|
||||
<version>1.6.27-SNAPSHOT</version>
|
||||
<version>1.6.28-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>forge-gui-mobile-dev</artifactId>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>forge</artifactId>
|
||||
<groupId>forge</groupId>
|
||||
<version>1.6.27-SNAPSHOT</version>
|
||||
<version>1.6.28-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>forge-gui-mobile</artifactId>
|
||||
|
||||
@@ -34,7 +34,7 @@ import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class Forge implements ApplicationListener {
|
||||
public static final String CURRENT_VERSION = "1.6.26.001";
|
||||
public static final String CURRENT_VERSION = "1.6.27.001";
|
||||
|
||||
private static final ApplicationListener app = new Forge();
|
||||
private static Clipboard clipboard;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>forge</artifactId>
|
||||
<groupId>forge</groupId>
|
||||
<version>1.6.27-SNAPSHOT</version>
|
||||
<version>1.6.28-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>forge-gui</artifactId>
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
#Add one announcement per line
|
||||
Modern Horizons is here!
|
||||
London Mulligans are here! (And on by default)
|
||||
You can sideboard for the AI now, just turn on the preference.
|
||||
New net deck categories are available via genetic algorithms and metagame top decks.
|
||||
M20 pre-release!
|
||||
[b]Forge now requires Java 8 (or newer). You will not be able to start the game if you are not yet running Java 8.[/b]
|
||||
We have a Discord server for hanging out with Forge devs and other Forge fans. Feel free to [url=https://discord.gg/3v9JCVr]jump on in and say hi[/url]!
|
||||
@@ -1,5 +1,2 @@
|
||||
- Bug fixes -
|
||||
As always, this release of Forge features an assortment of bug fixes and improvements based on user feedback during the previous release run.
|
||||
|
||||
- Random Modern World -
|
||||
Just like the random standard world, there is now also a random modern world for quest mode that includes randomly generated deck archetypes and is limited to the modern card pool
|
||||
|
||||
@@ -1524,3 +1524,33 @@ Oakenform
|
||||
Prized Unicorn
|
||||
Titanic Growth
|
||||
Woodland Mystic
|
||||
|
||||
Bloodfell Caves
|
||||
Blossoming Sands
|
||||
Dismal Backwater
|
||||
Jungle Hollow
|
||||
Rugged Highlands
|
||||
Scoured Barrens
|
||||
Swiftwater Cliffs
|
||||
Thornwood Falls
|
||||
Tranquil Cove
|
||||
Wind-Scarred Crag
|
||||
Evolving Wilds
|
||||
|
||||
[M20 Lands]
|
||||
5 Bloodfell Caves|M20
|
||||
5 Blossoming Sands|M20
|
||||
5 Dismal Backwater|M20
|
||||
5 Jungle Hollow|M20
|
||||
5 Rugged Highlands|M20
|
||||
5 Scoured Barrens|M20
|
||||
5 Swiftwater Cliffs|M20
|
||||
5 Thornwood Falls|M20
|
||||
5 Tranquil Cove|M20
|
||||
5 Wind-Scarred Crag|M20
|
||||
5 Evolving Wilds
|
||||
13 Forest|M20
|
||||
13 Island|M20
|
||||
13 Mountain|M20
|
||||
13 Plains|M20
|
||||
13 Swamp|M20
|
||||
@@ -3,5 +3,6 @@ ManaCost:3 G G G
|
||||
Types:Creature Elephant
|
||||
K:Trample
|
||||
S:Mode$ Continuous | Affected$ Creature.Other+YouCtrl | AddKeyword$ Trample | Description$ Other creatures you control have trample.
|
||||
SVar:PlayMain1:TRUE
|
||||
Oracle:Trample (This creature can deal excess combat damage to the player or planeswalker it's attacking.)\nOther creatures you control have trample.
|
||||
PT:8/8
|
||||
@@ -7,5 +7,5 @@ SVar:DBPutCounter:DB$ PutCounter | CounterType$ P1P1 | CounterNum$ 2 | TargetMin
|
||||
A:AB$ ChangeZone | Cost$ SubCounter<3/LOYALTY> | Planeswalker$ True | ValidTgts$ Creature | TgtPrompt$ Select target creature | Origin$ Battlefield | Destination$ Exile | SubAbility$ DBGainLife | SpellDescription$ Exile target creature. Its controller gains 2 life.
|
||||
SVar:DBGainLife:DB$ GainLife | Defined$ TargetedController | LifeAmount$ 2
|
||||
A:AB$ PumpAll | Cost$ SubCounter<10/LOYALTY> | Planeswalker$ True | ValidCards$ Creature.YouCtrl | KW$ Flying & Double Strike | SpellDescription$ Creatures you control gain flying and double strike until end of turn.
|
||||
DeckHas:Ability$Counters
|
||||
DeckHas:Ability$Counters & Ability$LifeGain
|
||||
Oracle:[+2]: You gain 2 life. Put two +1/+1 counters on up to one target creature.\n[−3]: Exile target creature. Its controller gains 2 life.\n[−10]: Creatures you control gain flying and double strike until end of turn.
|
||||
|
||||
@@ -6,7 +6,7 @@ A:AB$ GainLife | Cost$ AddCounter<1/LOYALTY> | Planeswalker$ True | LifeAmount$
|
||||
SVar:NumCreatures:Count$Valid Creature.YouCtrl/Plus.NumPlaneswalkers
|
||||
SVar:NumPlaneswalkers:Count$Valid Planeswalker.YouCtrl
|
||||
A:AB$ Token | Cost$ SubCounter<2/LOYALTY> | Planeswalker$ True | TokenScript$ ajanis_pridemate | LegacyImage$ ajanis pridemate m20 | SpellDescription$ Create a 2/2 white Cat Soldier creature token named Ajani's Pridemate with "Whenever you gain life, put a +1/+1 counter on Ajani's Pridemate."
|
||||
DeckHas:Ability$Token
|
||||
DeckHas:Ability$Token & Ability$Counters & Ability$LifeGain
|
||||
A:AB$ ChangeZoneAll | Cost$ SubCounter<0/LOYALTY> | ConditionCheckSVar$ CurLife | ConditionSVarCompare$ GEInitLife | References$ CurLife,InitLife | Planeswalker$ True | Ultimate$ True | ChangeType$ Card.Self,Creature.OppCtrl,Artifact.OppCtrl | Origin$ Battlefield | Destination$ Exile | SpellDescription$ If you have at least 15 life more than your starting life total, exile CARDNAME and each artifact and creature your opponents control.
|
||||
SVar:CurLife:Count$YourLifeTotal
|
||||
SVar:InitLife:Count$YourStartingLife/Plus.15
|
||||
|
||||
@@ -6,7 +6,6 @@ SVar:TrigToken:DB$ Token | TokenAmount$ 1 | TokenScript$ w_1_1_soldier | TokenOw
|
||||
SVar:DBAttach:DB$ Attach | Defined$ Remembered | SubAbility$ DBCleanup
|
||||
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||
DeckHas:Ability$Token
|
||||
DeckHints:Type$White | Soldier
|
||||
S:Mode$ Continuous | Affected$ Creature.EquippedBy | AddPower$ 1 | AddToughness$ 1 | Description$ Equipped creature gets +1/+1.
|
||||
K:Equip:1
|
||||
Oracle:When Ancestral Blade enters the battlefield, create a 1/1 white Soldier creature token, then attach Ancestral Blade to it.\nEquipped creature gets +1/+1.\nEquip {1} ({1}: Attach to target creature you control. Equip only as a sorcery.)
|
||||
|
||||
@@ -4,4 +4,5 @@ Types:Creature Troll
|
||||
PT:2/2
|
||||
K:etbCounter:P1P1:1
|
||||
A:AB$ Pump | Cost$ 1 SubCounter<1/P1P1> | KW$ Hexproof | Defined$ Self | SpellDescription$ CARDNAME gains hexproof until end of turn.
|
||||
DeckHas:Ability$Counters
|
||||
Oracle:Barkhide Troll enters the battlefield with a +1/+1 counter on it.\n{1}, Remove a +1/+1 counter from Barkhide Troll: Barkhide Troll gains hexproof until end of turn. (It can't be the target of spells or abilities your opponents control.)
|
||||
|
||||
@@ -4,8 +4,7 @@ Types:Creature Human Cleric
|
||||
PT:1/4
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Angel.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigGainLife | TriggerDescription$ Whenever an Angel enters the battlefield under your control, you gain 4 life.
|
||||
SVar:TrigGainLife:DB$GainLife | Defined$ You | LifeAmount$ 4
|
||||
DeckHas:Ability$LifeGain
|
||||
T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Angel.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigToken | TriggerDescription$ Whenever an Angel you control dies, create a 1/1 white Spirit creature token with flying.
|
||||
SVar:TrigToken:DB$ Token | TokenAmount$ 1 | TokenScript$ w_1_1_spirit_flying | TokenOwner$ You | LegacyImage$ w 1 1 spirit flying m20
|
||||
DeckHas:Ability$Token
|
||||
DeckHas:Ability$Token & Ability$LifeGain
|
||||
Oracle:Whenever an Angel enters the battlefield under your control, you gain 4 life.\nWhenever an Angel you control dies, create a 1/1 white Spirit creature token with flying.
|
||||
|
||||
@@ -3,4 +3,5 @@ ManaCost:1 B
|
||||
Types:Creature Vampire Rogue
|
||||
PT:2/2
|
||||
S:Mode$ Continuous | Affected$ Card.Self | AddKeyword$ Lifelink | Condition$ PlayerTurn | Description$ As long as it's your turn, CARDNAME has lifelink.
|
||||
DeckHas:Ability$LifeGain
|
||||
Oracle:As long as it's your turn, Blood Burglar has lifelink. (Damage dealt by this creature also causes you to gain that much life.)
|
||||
|
||||
@@ -3,5 +3,6 @@ ManaCost:4 B B
|
||||
Types:Artifact
|
||||
A:AB$ Token | Cost$ T PayLife<2> Discard<1/Card> Sac<1/Creature> | LegacyImage$ b 5 5 demon flying m20 | TokenAmount$ 1 | TokenScript$ b_5_5_demon_flying | TokenOwner$ You | SorcerySpeed$ True | SpellDescription$ Create a 5/5 black Demon creature token with flying. Activate this ability only any time you could play a sorcery.
|
||||
SVar:AIPreference:DiscardCost$Card
|
||||
DeckHas:Ability$Token
|
||||
AI:RemoveDeck:Random
|
||||
Oracle:{T}, Pay 2 life, Discard a card, Sacrifice a creature: Create a 5/5 black Demon creature token with flying. Activate this ability only any time you could play a sorcery.
|
||||
|
||||
@@ -6,4 +6,5 @@ K:Flying
|
||||
T:Mode$ LifeGained | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigPutCounter | TriggerDescription$ Whenever you gain life, put a +1/+1 counter on CARDNAME.
|
||||
SVar:TrigPutCounter:DB$PutCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ 1
|
||||
DeckHints:Ability$LifeGain
|
||||
DeckHas:Ability$Counters
|
||||
Oracle:Flying\nWhenever you gain life, put a +1/+1 counter on Bloodthirsty Aerialist.
|
||||
|
||||
@@ -2,6 +2,7 @@ Name:Bone Splinters
|
||||
ManaCost:B
|
||||
Types:Sorcery
|
||||
A:SP$ Destroy | Cost$ B Sac<1/Creature> | ValidTgts$ Creature | TgtPrompt$ Select target creature | SpellDescription$ Destroy target creature.
|
||||
SVar:AICostPreference:SacCost$Creature.Token,Creature.cmcLE2
|
||||
AI:RemoveDeck:All
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/bone_splinters.jpg
|
||||
Oracle:As an additional cost to cast this spell, sacrifice a creature.\nDestroy target creature.
|
||||
|
||||
@@ -6,4 +6,5 @@ T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Creatu
|
||||
SVar:TrigExile:DB$ ChangeZone | Origin$ Graveyard | Destination$ Exile | ValidTgts$ Creature | SubAbility$ DBToken | RememberChanged$ True
|
||||
SVar:DBToken:DB$ Token | TokenAmount$ 1 | TokenScript$ b_2_2_zombie | TokenOwner$ You | LegacyImage$ b 2 2 zombie m20 | ConditionDefined$ Remembered | ConditionPresent$ Card.Creature | ConditionCompare$ EQ1 | SubAbility$ DBCleanup
|
||||
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||
DeckHas:Ability$Token
|
||||
Oracle:When Boneclad Necromancer enters the battlefield, you may exile target creature card from a graveyard. If you do, create a 2/2 black Zombie creature token.
|
||||
|
||||
@@ -5,4 +5,5 @@ PT:2/1
|
||||
K:Flash
|
||||
T:Mode$ SpellCast | ValidCard$ Card | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | OpponentTurn$ True | Execute$ TrigPutCounter | TriggerDescription$ Whenever you cast a spell during an opponent's turn, put a +1/+1 counter on CARDNAME.
|
||||
SVar:TrigPutCounter:DB$ PutCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ 1
|
||||
DeckHas:Ability$Counters
|
||||
Oracle:Flash (You may cast this spell any time you could cast an instant.)\nWhenever you cast a spell during an opponent's turn, put a +1/+1 counter on Brineborn Cutthroat.
|
||||
|
||||
@@ -11,4 +11,5 @@ SVar:Play:Mode$ Continuous | MayPlay$ True | EffectZone$ Command | Affected$ Car
|
||||
SVar:DBEffect:DB$ Effect | RememberObjects$ Targeted | ExileOnMoved$ Stack | ReplacementEffects$ ReplaceGraveyard | SVars$ MoveExile
|
||||
SVar:ReplaceGraveyard:Event$ Moved | ValidCard$ Card.IsRemembered | Origin$ Stack | Destination$ Graveyard | ReplaceWith$ MoveExile | Description$ If that card would be put into your graveyard this turn, exile it instead.
|
||||
SVar:MoveExile:DB$ ChangeZone | Defined$ ReplacedCard | Origin$ Stack | Destination$ Exile
|
||||
DeckHas:Ability$Token
|
||||
Oracle:[0]: Put a loyalty counter on each red planeswalker you control.\n[0]: Create two 1/1 red Elemental creature tokens. They gain haste. Sacrifice them at the beginning of the next end step.\n:[-2]: You may cast target instant or sorcery with mana cost 3 or less card from your graveyard this turn. If that card would be put into your graveyard this turn, exile it instead.
|
||||
@@ -5,4 +5,5 @@ Loyalty:5
|
||||
A:AB$ PumpAll | Cost$ AddCounter<1/LOYALTY> | ValidCards$ Elemental.YouCtrl | NumAtt$ +2 | NumDef$ +0 | Planeswalker$ True | AILogic$ Always | SpellDescription$ Elementals you control get +2/+0 until end of turn.
|
||||
A:AB$ Mana | Cost$ SubCounter<1/LOYALTY> | Planeswalker$ True | Produced$ R | Amount$ 2 | SpellDescription$ Add {R}{R}.
|
||||
A:AB$ DealDamage | Cost$ SubCounter<2/LOYALTY> | Planeswalker$ True | ValidTgts$ Creature,Player,Planeswalker | TgtPrompt$ Select any target | NumDmg$ 2 | SpellDescription$ CARDNAME deals 2 damage to any target.
|
||||
DeckHints:Type$Elemental
|
||||
Oracle:[+1]: Elementals you control get +2/+0 until end of turn.\n[-1]: Add {R}{R}.\n[-2]: Chandra, Novice Pyromancer deals 2 damage to any target.
|
||||
@@ -3,7 +3,7 @@ ManaCost:2 R
|
||||
Types:Creature Elemental
|
||||
PT:1/3
|
||||
K:Flying
|
||||
T:Mode$ DamageDone | ValidSource$ Card | CombatDamage$ False | ValidTarget$ Opponent | TriggerZones$ Battlefield | Execute$ TrigPump | TriggerDescription$ Whenever an opponent is dealt noncombat damage, CARDNAME gets +3/+0 until end of turn.
|
||||
T:Mode$ DamageDone | ValidSource$ Card,Emblem | CombatDamage$ False | ValidTarget$ Opponent | TriggerZones$ Battlefield | Execute$ TrigPump | TriggerDescription$ Whenever an opponent is dealt noncombat damage, CARDNAME gets +3/+0 until end of turn.
|
||||
SVar:TrigPump:DB$Pump | NumAtt$ +3 | NumDef$ +0 | Defined$ Self
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/chandras_spitfire.jpg
|
||||
Oracle:Flying\nWhenever an opponent is dealt noncombat damage, Chandra's Spitfire gets +3/+0 until end of turn.
|
||||
|
||||
@@ -7,4 +7,5 @@ SVar:PlayMain1:TRUE
|
||||
A:AB$ Pump | Cost$ 2 R G | NumAtt$ +X | NumDef$ +X | References$ X | SpellDescription$ CARDNAME gets +1/+1 until end of turn for each Elemental you control.
|
||||
SVar:X:Count$Valid Elemental.YouCtrl
|
||||
SVar:BuffedBy:Card.Elemental
|
||||
DeckHints:Type$Elemental
|
||||
Oracle:Other Elementals you control get +1/+0.\n{2}{R}{G}: Creeping Trailblazer gets +1/+1 until end of turn for each Elemental you control.
|
||||
|
||||
@@ -5,4 +5,5 @@ PT:3/2
|
||||
K:Flying
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigGainLife | TriggerDescription$ When CARDNAME enters the battlefield, you gain 4 life.
|
||||
SVar:TrigGainLife:DB$GainLife | LifeAmount$ 4
|
||||
DeckHas:Ability$LifeGain
|
||||
Oracle:Flying\nWhen Dawning Angel enters the battlefield, you gain 4 life.
|
||||
|
||||
@@ -8,4 +8,5 @@ SVar:ChooseColor:DB$ ChooseColor | Defined$ You | SpellDescription$ As CARDNAME
|
||||
T:Mode$ SpellCast | ValidCard$ Card.ChosenColor | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigPutCounter | TriggerDescription$ Whenever you cast a spell of the chosen color, put a +1/+1 counter on CARDNAME.
|
||||
SVar:TrigPutCounter:DB$ PutCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ 1
|
||||
SVar:BuffedBy:Card.ChosenColor
|
||||
DeckHas:Ability$Counters
|
||||
Oracle:Vigilance (Attacking doesn't cause this creature to tap.)\nAs Diamond Knight enters the battlefield, choose a color.\nWhenever you cast a spell of the chosen color, put a +1/+1 counter on Diamond Knight.
|
||||
|
||||
@@ -3,7 +3,7 @@ ManaCost:5 UR UR
|
||||
Types:Creature Djinn
|
||||
PT:3/5
|
||||
K:Flying
|
||||
K:Each instant and sorcery spell you cast has replicate. The replicate cost is equal to its mana cost.
|
||||
S:Mode$ Continuous | AddKeyword$ Replicate:CardManaCost | Affected$ Instant.YouCtrl,Sorcery.YouCtrl | AffectedZone$ Stack | EffectZone$ Battlefield | Description$ Each instant and sorcery spell you cast has replicate. The replicate cost is equal to its mana cost. (When you cast it, copy it for each time you paid its replicate cost. You may choose new targets for the copies.)
|
||||
AI:RemoveDeck:All
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/djinn_illuminatus.jpg
|
||||
Oracle:Flying\nEach instant and sorcery spell you cast has replicate. The replicate cost is equal to its mana cost. (When you cast it, copy it for each time you paid its replicate cost. You may choose new targets for the copies.)
|
||||
|
||||
@@ -4,4 +4,5 @@ Types:Creature Wolf
|
||||
PT:0/1
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigToken | TriggerDescription$ When CARDNAME enters the battlefield, create a 2/2 green Wolf creature token.
|
||||
SVar:TrigToken:DB$ Token | LegacyImage$ g 2 2 wolf m20 | TokenAmount$ 1 | TokenScript$ g_2_2_wolf | TokenOwner$ You
|
||||
DeckHas:Ability$Token
|
||||
Oracle:When Ferocious Pup enters the battlefield, create a 2/2 green Wolf creature token.
|
||||
|
||||
@@ -7,4 +7,5 @@ T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.S
|
||||
T:Mode$ ChangesZone | TriggerZones$ Battlefield | CheckSVar$ X | SVarCompare$ GE7 | Origin$ Any | Destination$ Battlefield | ValidCard$ Land.YouCtrl | Execute$ TrigToken | Secondary$ True | TriggerDescription$ Whenever CARDNAME or another land enters the battlefield under your control, if you control seven or more lands with different names, create a 2/2 black Zombie creature token.
|
||||
SVar:TrigToken:DB$ Token | TokenScript$ b_2_2_zombie | TokenOwner$ You | TokenAmount$ 1 | LegacyImage$ b 2 2 zombie m20
|
||||
SVar:X:Count$DifferentCardNames_Land.YouCtrl+inZoneBattlefield
|
||||
DeckHas:Ability$Token
|
||||
Oracle:Field of the Dead enters the battlefield tapped.\n{T}: Add {C}.\nWhenever Field of the Dead or another land enters the battlefield under your control, if you control seven or more lands with different names, create a 2/2 black Zombie creature token.
|
||||
|
||||
@@ -7,5 +7,6 @@ T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.S
|
||||
SVar:DBGainLife:DB$ GainLife | Defined$ You | LifeAmount$ 3
|
||||
S:Mode$ Continuous | Affected$ Card.EnchantedBy | AddAbility$ AbundantGrowthTap | Description$ Enchanted land has "{T}: Add two mana of any one color."
|
||||
SVar:AbundantGrowthTap:AB$ Mana | Cost$ T | Produced$ Any | Amount$ 2 | SpellDescription$ Add two mana of any one color.
|
||||
DeckHas:Ability$LifeGain
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/gift_of_paradise.jpg
|
||||
Oracle:Enchant land\nWhen Gift of Paradise enters the battlefield, you gain 3 life.\nEnchanted land has "{T}: Add two mana of any one color."
|
||||
@@ -5,5 +5,6 @@ PT:2/2
|
||||
K:Haste
|
||||
T:Mode$ ChangesZone | ValidCard$ Card.Self | Origin$ Any | Destination$ Battlefield | Execute$ TrigDig | TriggerDescription$ When CARDNAME enters the battlefield, reveal the top four cards of your library. Put all Goblin cards revealed this way into your hand and the rest on the bottom of your library in any order.
|
||||
SVar:TrigDig:DB$Dig | DigNum$ 4 | Reveal$ True | ChangeNum$ All | ChangeValid$ Goblin
|
||||
DeckHints:Type$Goblin
|
||||
SVar:Picture:http://resources.wizards.com/magic/cards/ap/en-us/card27664.jpg
|
||||
Oracle:Haste\nWhen Goblin Ringleader enters the battlefield, reveal the top four cards of your library. Put all Goblin cards revealed this way into your hand and the rest on the bottom of your library in any order.
|
||||
|
||||
@@ -8,5 +8,5 @@ SVar:TrigMill:DB$ Mill | NumCards$ 4 | Defined$ You | RememberMilled$ True | Sub
|
||||
SVar:DBGainLife:DB$ GainLife | Defined$ You | LifeAmount$ X | References$ X | SubAbility$ DBCleanup
|
||||
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||
SVar:X:Remembered$Valid Card.Creature
|
||||
DeckHas:Ability$Graveyard
|
||||
DeckHas:Ability$Graveyard & Ability$LifeGain
|
||||
Oracle:Flying\nWhen Gorging Vulture enters the battlefield, put the top four cards of your library into your graveyard. You gain 1 life for each creature card put into your graveyard this way.
|
||||
|
||||
@@ -4,4 +4,5 @@ Types:Creature Elemental
|
||||
PT:1/2
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigGainLife | TriggerDescription$ When CARDNAME enters the battlefield, you gain 3 life.
|
||||
SVar:TrigGainLife:DB$GainLife | LifeAmount$ 3
|
||||
DeckHas:Ability$LifeGain
|
||||
Oracle:When Healer of the Glade enters the battlefield, you gain 3 life.
|
||||
|
||||
@@ -4,4 +4,5 @@ Types:Creature Angel
|
||||
PT:4/4
|
||||
K:Flying
|
||||
A:AB$ PutCounter | Cost$ 3 W | ValidTgts$ Creature.Other+withFlying | TgtPrompt$ Select another target creature with flying | CounterType$ P1P1 | CounterNum$ 1 | SpellDescription$ Put a +1/+1 counter on another target creature with flying.
|
||||
DeckHas:Ability$Counters
|
||||
Oracle:Flying\n{3}{W}: Put a +1/+1 counter on another target creature with flying.
|
||||
|
||||
@@ -5,4 +5,5 @@ PT:5/5
|
||||
K:Reach
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigToken | TriggerDescription$ When CARDNAME enters the battlefield, create two 2/2 green Wolf creature tokens.
|
||||
SVar:TrigToken:DB$ Token | LegacyImage$ g 2 2 wolf m20 | TokenAmount$ 2 | TokenScript$ g_2_2_wolf | TokenOwner$ You
|
||||
DeckHas:Ability$Token
|
||||
Oracle:Reach (This creature can block creatures with flying.)\nWhen Howling Giant enters the battlefield, create two 2/2 green Wolf creature tokens.
|
||||
|
||||
@@ -5,4 +5,5 @@ PT:*/5
|
||||
S:Mode$ Continuous | EffectZone$ All | CharacteristicDefining$ True | SetPower$ X | Description$ CARDNAME's power is equal to the number of creatures you control.
|
||||
SVar:X:Count$Valid Creature.YouCtrl
|
||||
A:AB$ Token | Cost$ 3 G W | TokenAmount$ 1 | TokenScript$ w_1_1_soldier | TokenOwner$ You | LegacyImage$ w 1 1 soldier m20 | SpellDescription$ Create a 1/1 white Soldier creature token.
|
||||
DeckHas:Ability$Token
|
||||
Oracle:Ironroot Warlord's power is equal to the number of creatures you control.\n{3}{G}{W}: Create a 1/1 white Soldier creature token.
|
||||
|
||||
@@ -5,4 +5,5 @@ PT:3/4
|
||||
S:Mode$ ReduceCost | ValidCard$ Legendary | Type$ Spell | Activator$ You | Amount$ 1 | Description$ Legendary spells you cast cost {1} less to cast.
|
||||
A:AB$ Animate | Cost$ ExileFromGrave<2/Card.Legendary/legendary card> | staticAbilities$ Play | Defined$ ValidGraveyard Card.Legendary+YouOwn | SpellDescription$ Until end of turn, each legendary card in your graveyard gains "You may pay this card from your graveyard."
|
||||
SVar:Play:Mode$ Continuous | Affected$ Card.Self | EffectZone$ Graveyard | MayPlay$ True | Description$ You may pay this card from your graveyard.
|
||||
DeckHints:Type$Legendary
|
||||
Oracle:Legendary spells you cast cost {1} less to cast.\nExile two legendary cards from your graveyard: Until end of turn, each legendary card in your graveyard gains "You may pay this card from your graveyard."
|
||||
|
||||
@@ -6,4 +6,5 @@ A:AB$ Pump | Cost$ 2 B | NumAtt$ +3 | NumDef$ +3 | Defined$ Self | KW$ Deathtouc
|
||||
T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | TriggerZones$ Battlefield | CheckSVar$ X | SVarCompare$ GE4 | Execute$ TrigPutCounter | TriggerDescription$ At the beginning of your end step, if a player lost 4 or more life this turn, put a +1/+1 counter on CARDNAME. (Damage causes loss of life.)
|
||||
SVar:TrigPutCounter:DB$ PutCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ 1
|
||||
SVar:X:PlayerCountOpponents$HighestLifeLostThisTurn
|
||||
DeckHas:Ability$Counters
|
||||
Oracle:{2}{B}: Knight of the Ebon Legion gets +3/+3 and gains deathtouch until end of turn.\nAt the beginning of your end step, if a player lost 4 or more life this turn, put a +1/+1 counter on Knight of the Ebon Legion. (Damage causes loss of life.)
|
||||
|
||||
@@ -6,5 +6,6 @@ K:Flying
|
||||
T:Mode$ SpellCast | ValidCard$ Card.nonCreature | ValidActivatingPlayer$ You | Execute$ TrigToken | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast a noncreature spell, create a 1/1 white Spirit creature token with flying.
|
||||
SVar:TrigToken:DB$ Token | LegacyImage$ w 1 1 spirit flying m20 | TokenAmount$ 1 | TokenScript$ w_1_1_spirit_flying | TokenOwner$ You
|
||||
SVar:BuffedBy:Card.nonCreature+nonLand
|
||||
DeckHas:Ability$Counters
|
||||
A:AB$ Mana | Cost$ Sac<1/Spirit> | Produced$ R | SpellDescription$ Add {R}.
|
||||
Oracle:Flying\nWhenever you cast a noncreature spell, create a 1/1 white Spirit creature token with flying.\nSacrifice a Spirit: Add {R}.
|
||||
|
||||
@@ -6,4 +6,5 @@ SVar:FromHand:DB$ ChangeZone | Defined$ Self | Origin$ Hand | Destination$ Battl
|
||||
T:Mode$ TapsForMana | ValidCard$ Creature | Execute$ TrigMana | TriggerZones$ Battlefield | Static$ True | TriggerDescription$ Whenever you tap a creature for mana, add an additional {G}.
|
||||
SVar:TrigMana:DB$ Mana | Produced$ G
|
||||
A:AB$ PutCounterAll | Cost$ 6 G G | ValidCards$ Creature.YouCtrl | CounterType$ P1P1 | CounterNum$ 1 | SpellDescription$ Put a +1/+1 counter on each creature you control.
|
||||
DeckHas:Ability$Counters
|
||||
Oracle:If Leyline of Abundance is in your opening hand, you may begin the game with it on the battlefield.\nWhenever you tap a creature for mana, add an additional {G}.\n{6}{G}{G}: Put a +1/+1 counter on each creature you control.
|
||||
|
||||
@@ -9,5 +9,6 @@ S:Mode$ Continuous | Affected$ Card.EquippedBy | AddAbility$ Damage | AddSVar$ T
|
||||
SVar:Damage:AB$DealDamage | Cost$ Sac<1/CARDNAME> | ValidTgts$ Creature,Player,Planeswalker | TgtPrompt$ Select any target | NumDmg$ 1 | SpellDescription$ CARDNAME deals 1 damage to any target.
|
||||
SVar:NonStackingAttachEffect:True
|
||||
AI:RemoveDeck:All
|
||||
DeckHas:Ability$Token
|
||||
K:Equip:2
|
||||
Oracle:When Mask of Immolation enters the battlefield, create a 1/1 red Elemental creature token, then attach Mask of Immolation to it.\nEquipped creature has "Sacrifice this creature: It deals 1 damage to any target."\nEquip {2} ({2}: Attach to target creature you control. Equip only as a sorcery.)
|
||||
|
||||
@@ -5,5 +5,6 @@ PT:1/1
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigToken | TriggerDescription$ When CARDNAME enters the battlefield, create a 3/3 colorless Golem artifact creature token.
|
||||
SVar:TrigToken:DB$ Token | TokenAmount$ 1 | TokenScript$ c_3_3_a_golem | TokenOwner$ You | LegacyImage$ c 3 3 a golem nph
|
||||
S:Mode$ Continuous | Affected$ Creature.Golem+YouCtrl | AddPower$ 1 | AddToughness$ 1 | Description$ Golem creatures you control get +1/+1.
|
||||
DeckHas:Ability$Token
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/master_splicer.jpg
|
||||
Oracle:When Master Splicer enters the battlefield, create a 3/3 colorless Golem artifact creature token.\nGolem creatures you control get +1/+1.
|
||||
|
||||
@@ -8,4 +8,5 @@ SVar:DBRepeat:DB$ RepeatEach | RepeatCards$ Artifact.YouCtrl+IsNotImprinted | Re
|
||||
SVar:DBClone:DB$ Clone | Defined$ Imprinted | CloneTarget$ Remembered | Duration$ UntilEndOfTurn
|
||||
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True | ClearImprinted$ True
|
||||
AI:RemoveDeck:All
|
||||
DeckHas:Ability$Token
|
||||
Oracle:Choose one —\n• Create two 3/3 colorless Golem artifact creature tokens.\n• Choose target artifact you control. Each other artifact you control becomes a copy of that artifact until end of turn.
|
||||
|
||||
@@ -4,4 +4,5 @@ Types:Enchantment
|
||||
T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Creature.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigGainLife | TriggerDescription$ Whenever a creature you control dies, you gain 1 life and draw a card.
|
||||
SVar:TrigGainLife:DB$ GainLife | Defined$ You | LifeAmount$ 1 | SubAbility$ DBDraw
|
||||
SVar:DBDraw:DB$ Draw | Defined$ You | NumCards$ 1
|
||||
DeckHas:Ability$LifeGain
|
||||
Oracle:Whenever a creature you control dies, you gain 1 life and draw a card.
|
||||
|
||||
@@ -2,5 +2,6 @@ Name:Moment of Heroism
|
||||
ManaCost:1 W
|
||||
Types:Instant
|
||||
A:SP$ Pump | Cost$ 1 W | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumAtt$ +2 | NumDef$ +2 | KW$ Lifelink | SpellDescription$ Target creature gets +2/+2 and gains lifelink until end of turn.
|
||||
DeckHas:Ability$LifeGain
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/moment_of_heroism.jpg
|
||||
Oracle:Target creature gets +2/+2 and gains lifelink until end of turn.
|
||||
@@ -9,4 +9,5 @@ A:AB$ Effect | Cost$ SubCounter<8/LOYALTY> | Planeswalker$ True | Ultimate$ True
|
||||
SVar:STDraw:Mode$ Continuous | EffectZone$ Command | Affected$ Island.YouCtrl | AddAbility$ AnimateIsland | Description$ Islands you control have "{T}: Draw a card".
|
||||
SVar:AnimateIsland:AB$ Draw | Cost$ T | NumCards$ 1 | SpellDescription$ Draw a card.
|
||||
SVar:PlayMain1:TRUE
|
||||
DeckHas:Ability$Token
|
||||
Oracle:[+2]: Until your next turn, up to one target creature gets -2/-0 and loses flying.\n[-3]: Create a 4/4 blue Elemental Bird creature token with flying.\n[-8]: You get an emblem with "Islands you control have '{T}: Draw a card'."
|
||||
|
||||
@@ -8,4 +8,6 @@ SVar:PlayMain1:TRUE
|
||||
T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | CheckSVar$ X | SVarCompare$ EQ0 | References$ X | TriggerZones$ Battlefield | Execute$ TrigToken | TriggerDescription$ At the beginning of your end step, if you didn't cast a spell this turn, create a 2/2 green Wolf creature token.
|
||||
SVar:TrigToken:DB$ Token | TokenOwner$ You | TokenScript$ g_2_2_wolf | LegacyImage$ g 2 2 wolf m20 | TokenAmount$ 1
|
||||
SVar:X:Count$ThisTurnCast_Card.YouCtrl
|
||||
DeckHints:Type$Wolf & Type$Werewolf
|
||||
DeckHas:Ability$Token
|
||||
Oracle:Flash\nOther Wolves and Werewolves you control get +1/+1.\nAt the beginning of your end step, if you didn't cast a spell this turn, create a 2/2 green Wolf creature token.
|
||||
|
||||
@@ -4,4 +4,5 @@ Types:Instant
|
||||
A:SP$ Destroy | Cost$ 1 B | ValidTgts$ Creature.White,Planeswalker.White,Creature.Green,Planeswalker.Green | TgtPrompt$ Select target creature or planeswalker that's green or white | SubAbility$ DBGainLife | SpellDescription$ Destroy target creature or planeswalker that's green or white. You gain 1 life.
|
||||
SVar:DBGainLife:DB$GainLife | Defined$ You | LifeAmount$ 1 | SpellDescription$ You gain 1 life.
|
||||
AI:RemoveDeck:Random
|
||||
DeckHas:Ability$LifeGain
|
||||
Oracle:Destroy target creature or planeswalker that's green or white. You gain 1 life.
|
||||
|
||||
@@ -8,4 +8,6 @@ SVar:X:Count$Valid Elemental.YouCtrl
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Land.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigPutCounter | TriggerDescription$ Whenever a land enters the battlefield under your control, put a +1/+1 counter on target Elemental you control. If you control eight or more lands, draw a card.
|
||||
SVar:TrigPutCounter:DB$ PutCounter | ValidTgts$ Elemental.YouCtrl | TgtPrompt$ Select target Elemental you control | CounterType$ P1P1 | CounterNum$ 1 | SubAbility$ DBDraw
|
||||
SVar:DBDraw:DB$ Draw | NumCards$ 1 | Defined$ You | ConditionPresent$ Land.YouCtrl | ConditionCompare$ GE8
|
||||
DeckHas:Ability$Counters
|
||||
DeckHints:Type$Elemental
|
||||
Oracle:When Omnath, Locus of the Roil enters the battlefield, it deals damage to any target equal to the number of Elementals you control.\nWhenever a land enters the battlefield under your control, put a +1/+1 counter on target Elemental you control. If you control eight or more lands, draw a card.
|
||||
|
||||
@@ -11,4 +11,5 @@ T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$
|
||||
SVar:TrigGainLife:DB$ GainLife | Defined$ You | LifeAmount$ 1 | SubAbility$ DBPutCounter
|
||||
SVar:DBPutCounter:DB$ PutCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ 1 | ConditionDefined$ TriggeredCardLKICopy | ConditionPresent$ Creature.Elemental
|
||||
DeckHas:Ability$Counters
|
||||
DeckHints:Type$Elemental
|
||||
Oracle:When Overgrowth Elemental enters the battlefield, put a +1/+1 counter on another target Elemental you control.\nWhenever another creature you control dies, you gain 1 life. If that creature was an Elemental, put a +1/+1 counter on Overgrowth Elemental.
|
||||
|
||||
@@ -2,5 +2,6 @@ Name:Raise the Alarm
|
||||
ManaCost:1 W
|
||||
Types:Instant
|
||||
A:SP$ Token | Cost$ 1 W | TokenAmount$ 2 | TokenScript$ w_1_1_soldier | TokenOwner$ You | LegacyImage$ w 1 1 soldier mrd | SpellDescription$ Create two 1/1 white Soldier creature tokens.
|
||||
DeckHas:Ability$Token
|
||||
SVar:Picture:http://resources.wizards.com/magic/cards/mrd/en-us/card48103.jpg
|
||||
Oracle:Create two 1/1 white Soldier creature tokens.
|
||||
@@ -5,4 +5,5 @@ PT:3/3
|
||||
K:Flying
|
||||
T:Mode$ ChangesZone | ValidCard$ Card.Self | Origin$ Any | Destination$ Battlefield | Execute$ DBTreasureTokens | TriggerDescription$ When CARDNAME enters the battlefield, create two Treasure tokens.
|
||||
SVar:DBTreasureTokens:DB$ Token | TokenAmount$ 2 | TokenScript$ c_a_treasure_sac | TokenOwner$ You | LegacyImage$ c a treasure sac m20
|
||||
DeckHas:Ability$Token
|
||||
Oracle:Flying\nWhen Rapacious Dragon enters the battlefield, create two Treasure tokens. (They're artifacts with "{T}, Sacrifice this artifact: Add one mana of any color.")
|
||||
|
||||
@@ -6,4 +6,5 @@ K:Flying
|
||||
T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | CheckSVar$ X | References$ X | Execute$ TrigPutCounter | TriggerZones$ Battlefield | TriggerDescription$ At the beginning of your upkeep, if an opponent lost life this turn, put a +1/+1 counter on CARDNAME. (Damage causes loss of life.)
|
||||
SVar:TrigPutCounter:DB$ PutCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ 1
|
||||
SVar:X:Count$LifeOppsLostThisTurn
|
||||
DeckHas:Ability$Counters
|
||||
Oracle:Flying\nAt the beginning of your upkeep, if an opponent lost life this turn, put a +1/+1 counter on Savage Gorger. (Damage causes loss of life.)
|
||||
|
||||
@@ -5,4 +5,5 @@ PT:1/1
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigToken | TriggerDescription$ When CARDNAME enters the battlefield, create two 1/1 red Elemental creature tokens. Elementals you control gain haste until end of turn.
|
||||
SVar:TrigToken:DB$ Token | TokenAmount$ 2 | TokenScript$ r_1_1_elemental | TokenOwner$ You | LegacyImage$ r 1 1 elemental m20 | SubAbility$ DBPump
|
||||
SVar:DBPump:DB$ PumpAll | ValidCards$ Elemental.YouCtrl | KW$ Haste
|
||||
DeckHas:Ability$Token
|
||||
Oracle:When Scampering Scorcher enters the battlefield, create two 1/1 red Elemental creature tokens. Elementals you control gain haste until end of turn. (They can attack and {T} this turn.)
|
||||
|
||||
@@ -4,4 +4,4 @@ Types:Creature Skeleton Archer
|
||||
PT:3/3
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigDealDamage | TriggerDescription$ When CARDNAME enters the battlefield, it deals 1 damage to any target.
|
||||
SVar:TrigDealDamage:DB$DealDamage | ValidTgts$ Creature,Player,Planeswalker | TgtPrompt$ Select any target | NumDmg$ 1
|
||||
Oracle:When CARDNAME enters the battlefield, it deals 1 damage to any target.
|
||||
Oracle:When Skeleton Archer enters the battlefield, it deals 1 damage to any target.
|
||||
@@ -6,4 +6,5 @@ K:Flying
|
||||
T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigToken | TriggerDescription$ Whenever CARDNAME attacks, create a 1/1 white Soldier creature token that's tapped and attacking.
|
||||
SVar:TrigToken:DB$ Token | TokenAmount$ 1 | TokenScript$ w_1_1_soldier | TokenOwner$ You | TokenTapped$ True | TokenAttacking$ True | LegacyImage$ w 1 1 soldier m20
|
||||
SVar:HasAttackEffect:TRUE
|
||||
DeckHas:Ability$Token
|
||||
Oracle:Flying\nWhenever Skyknight Vanguard attacks, create a 1/1 white Soldier creature token that's tapped and attacking.
|
||||
|
||||
@@ -11,5 +11,6 @@ SVar:DBGainLife:DB$ GainLife | LifeAmount$ 3
|
||||
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||
A:AB$ ChangeZone | Cost$ SubCounter<3/LOYALTY> | Planeswalker$ True | Origin$ Hand | Destination$ Battlefield | ChangeType$ Creature.Vampire | ChangeNum$ 1 | SpellDescription$ You may put a vampire creature card from your hand onto the battlefield.
|
||||
SVar:PlayMain1:TRUE
|
||||
DeckHas:Ability$Counters
|
||||
DeckHints:Type$Vampire
|
||||
Oracle:[+1]: Target creature you control gains deathtouch and lifelink until end of turn. If it's a Vampire, put a +1/+1 counter on it.\n[+1]: You may sacrifice a Vampire. When you do, Sorin, Imperious Bloodlord deals 3 damage to any target and you gain 3 life.\n[-3]: You may put a vampire creature card from your hand onto the battlefield.
|
||||
|
||||
@@ -3,5 +3,6 @@ ManaCost:W
|
||||
Types:Creature Human Cleric
|
||||
PT:1/1
|
||||
A:AB$ GainLife | Cost$ T | Defined$ You | LifeAmount$ 1 | SpellDescription$ You gain 1 life.
|
||||
DeckHas:Ability$LifeGain
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/soulmender.jpg
|
||||
Oracle:{T}: You gain 1 life.
|
||||
|
||||
@@ -5,4 +5,5 @@ PT:2/2
|
||||
K:Vigilance
|
||||
K:etbCounter:P1P1:X:no Condition:CARDNAME enters the battlefield with a +1/+1 counter on it for each other creature you control.
|
||||
SVar:X:Count$LastStateBattlefield Creature.Other+YouCtrl
|
||||
DeckHas:Ability$Counters
|
||||
Oracle:Vigilance (Attacking doesn't cause this creature to tap.)\nSquad Captain enters the battlefield with a +1/+1 counter on it for each other creature you control.
|
||||
|
||||
@@ -5,4 +5,6 @@ PT:2/2
|
||||
S:Mode$ ReduceCost | ValidCard$ Enchantment | Type$ Spell | Activator$ You | Amount$ 1 | Description$ Enchantment spells you cast cost {1} less to cast.
|
||||
T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Enchantment.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigPutCounter | TriggerDescription$ Whenever an enchantment you control is put into a graveyard from the battlefield, put a +1/+1 counter on CARDNAME.
|
||||
SVar:TrigPutCounter:DB$PutCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ 1
|
||||
DeckHas:Ability$Counters
|
||||
DeckNeeds:Type$Enchantment
|
||||
Oracle:Enchantment spells you cast cost {1} less to cast.\nWhenever an enchantment you control is put into a graveyard from the battlefield, put a +1/+1 counter on Starfield Mystic.
|
||||
|
||||
@@ -5,4 +5,5 @@ PT:3/2
|
||||
K:Vigilance
|
||||
T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self | Execute$ TrigPutCounter | TriggerController$ TriggeredCardController | TriggerDescription$ When CARDNAME dies, put a +1/+1 counter on target creature you control.
|
||||
SVar:TrigPutCounter:DB$PutCounter | ValidTgts$ Creature.YouCtrl | TgtPrompt$ Select target creature you control | CounterType$ P1P1 | CounterNum$ 1
|
||||
DeckHas:Ability$Counters
|
||||
Oracle:Vigilance (Attacking doesn't cause this creature to tap.)\nWhen Steadfast Sentry dies, put a +1/+1 counter on target creature you control.
|
||||
|
||||
@@ -3,5 +3,6 @@ ManaCost:2
|
||||
Types:Artifact Creature Construct
|
||||
PT:1/1
|
||||
A:AB$ PutCounterAll | Cost$ T | ValidCards$ Artifact.Creature+YouCtrl | CounterType$ P1P1 | CounterNum$ 1 | SpellDescription$ Put a +1/+1 counter on each artifact creature you control.
|
||||
DeckHas:Ability$Counters
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/steel_overseer.jpg
|
||||
Oracle:{T}: Put a +1/+1 counter on each artifact creature you control.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Name:Stream of Thought
|
||||
ManaCost:U
|
||||
Types:Sorcery
|
||||
A:SP$ Mill | Cost$ U | NumCards$ 4 | ValidTgts$ Player | TgtPrompt$ Choose a player | RememberMilled$ True | SubAbility$ DBChangeZone | SpellDescription$ Target player puts the top four cards of their library into their graveyard. You shuffle up to four cards from your graveyard into your library.
|
||||
SVar:DBChangeZone:DB$ ChangeZone | Origin$ Graveyard | Destination$ Library | DefinedPlayer$ You | Hidden$ True | ChangeNum$ 4 | ChangeType$ Card.YouOwn | Shuffle$ True
|
||||
K:Replicate:2 U U
|
||||
A:SP$ Mill | Cost$ U | NumCards$ 4 | ValidTgts$ Player | TgtPrompt$ Choose a player | SubAbility$ DBChangeZone | SpellDescription$ Target player puts the top four cards of their library into their graveyard. You shuffle up to four cards from your graveyard into your library.
|
||||
SVar:DBChangeZone:DB$ ChangeZone | Origin$ Graveyard | Destination$ Library | DefinedPlayer$ You | Hidden$ True | ChangeNum$ 4 | ChangeType$ Card.YouOwn | Shuffle$ True
|
||||
Oracle:Target player puts the top four cards of their library into their graveyard. You shuffle up to four cards from your graveyard into your library.\nReplicate {2}{U}{U} (When you cast this spell, copy it for each time you paid the replicate cost. You may choose new targets for the copies.)
|
||||
|
||||
@@ -3,7 +3,7 @@ ManaCost:3 G
|
||||
Types:Creature Elemental Rhino
|
||||
PT:4/3
|
||||
K:Trample
|
||||
DeckHints:Name$Nissa's Encouragement | Nissa, Genesis Mage | Forest
|
||||
S:Mode$ Continuous | Affected$ Elemental.Other+YouCtrl | AddKeyword$ Trample | Description$ Other Elementals you control have trample.
|
||||
SVar:PlayMain1:TRUE
|
||||
DeckHints:Type$Elemental
|
||||
Oracle:Trample (This creature can deal excess combat damage to the player or planeswalker it's attacking.)\nOther Elementals you control have trample.
|
||||
|
||||
@@ -5,6 +5,7 @@ PT:3/3
|
||||
T:Mode$ LifeGained | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigPutCounter | TriggerDescription$ Whenever you gain life, put a +1/+1 counter on CARDNAME.
|
||||
SVar:TrigPutCounter:DB$ PutCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ 1
|
||||
DeckHints:Ability$LifeGain
|
||||
DeckHas:Ability$Counters
|
||||
S:Mode$ Continuous | Affected$ Card.Self | AddKeyword$ Double Strike | CheckSVar$ X | SVarCompare$ GE25 | Description$ As long as you have 25 or more life, CARDNAME has double strike. (It deals both first-strike and regular combat damage.)
|
||||
SVar:X:Count$YourLifeTotal
|
||||
Oracle:Whenever you gain life, put a +1/+1 counter on Twinblade Paladin.\nAs long as you have 25 or more life, Twinblade Paladin has double strike. (It deals both first-strike and regular combat damage.)
|
||||
|
||||
@@ -5,4 +5,5 @@ K:Enchant creature
|
||||
A:SP$ Attach | Cost$ 2 B | ValidTgts$ Creature | AILogic$ Pump
|
||||
T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.AttachedBy | Execute$ TrigChange | TriggerDescription$ When enchanted creature dies, return that card to the battlefield under your control with a +1/+1 counter on it.
|
||||
SVar:TrigChange:DB$ChangeZone | Origin$ Graveyard | Destination$ Battlefield | WithCounters$ P1P1 | Defined$ TriggeredCard
|
||||
DeckHas:Ability$Counters
|
||||
Oracle:Enchant creature\nWhen enchanted creature dies, return that card to the battlefield under your control with a +1/+1 counter on it.
|
||||
|
||||
@@ -8,4 +8,5 @@ SVar:DBPump:DB$ Pump | Defined$ You | KW$ Hexproof:Card.Black:black & Hexproof:C
|
||||
SVar:DBPumpAll:DB$ PumpAll | ValidCards$ Permanent.YouCtrl | KW$ Hexproof:Card.Black:black & Hexproof:Card.Blue:blue
|
||||
SVar:X:Count$ThisTurnCast_Card.OppCtrl+Blue,Card.OppCtrl+Black
|
||||
AI:RemoveDeck:Random
|
||||
DeckHints:Color$Blue|Black
|
||||
Oracle:Draw a card if an opponent has cast a blue or black spell this turn. Spells you control can't be countered this turn. You and permanents you control gain hexproof from blue and from black until end of turn. (You and they can't be the targets of blue or black spells or abilities your opponents control.)
|
||||
|
||||
@@ -4,4 +4,5 @@ Types:Creature Orc Warrior
|
||||
PT:4/4
|
||||
T:Mode$ LifeLost | ValidPlayer$ You | TriggerZones$ Battlefield | FirstTime$ True | Execute$ TrigPutCounter | TriggerDescription$ Whenever you lose life for the first time each turn, put a +1/+1 counter on CARDNAME. (Damage causes loss of life.)
|
||||
SVar:TrigPutCounter:DB$ PutCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ 1
|
||||
DeckHas:Ability$Counters
|
||||
Oracle:Whenever you lose life for the first time each turn, put a +1/+1 counter on Vengeful Warchief. (Damage causes loss of life.)
|
||||
|
||||
@@ -8,5 +8,5 @@ A:AB$ Pump | Cost$ SubCounter<3/LOYALTY> | Planeswalker$ True | ValidTgts$ Creat
|
||||
SVar:SoulsDamage:DB$ DealDamage | ValidTgts$ Creature,Planeswalker | AILogic$ PowerDmg | TgtPrompt$ Select target creature or planeswalker | NumDmg$ X | References$ X | DamageSource$ ParentTarget
|
||||
SVar:X:ParentTargeted$CardPower
|
||||
A:AB$ ChangeZone | Cost$ SubCounter<5/LOYALTY> | Planeswalker$ True | Origin$ Sideboard | Destination$ Hand | ChangeType$ Creature.YouOwn | ChangeNum$ 1 | SpellDescription$ You may choose a creature card you own from outside the game, reveal it, and put it into your hand.
|
||||
AI:RemoveDeck:Random
|
||||
DeckHas:Ability$Counters
|
||||
Oracle:[+1]: Distribute two +1/+1 counters among up to two target creatures. They gain trample until end of turn.\n[−3]: Target creature you control deals damage equal to its power to target creature or planeswalker.\n[−5]: You may choose a creature card you own from outside the game, reveal it, and put it into your hand.
|
||||
|
||||
@@ -5,4 +5,5 @@ Loyalty:3
|
||||
A:AB$ PutCounter | Cost$ AddCounter<1/LOYALTY> | Planeswalker$ True | CounterNum$ 3 | CounterType$ P1P1 | TargetMin$ 0 | TargetMax$ 1 | ValidTgts$ Creature | TgtPrompt$ Select target creature | SpellDescription$ Put three +1/+1 counters on up to one target creature.
|
||||
A:AB$ DigUntil | Cost$ SubCounter<1/LOYALTY> | Planeswalker$ True | Valid$ Card.Creature | ValidDescription$ creature | FoundDestination$ Hand | RevealedDestination$ Library | RevealedLibraryPosition$ -1 | RevealRandomOrder$ True | FoundDestination$ Hand | SpellDescription$ Reveal cards from the top of your library until you reveal a creature card. Put that card into your hand and the rest on the bottom of your library in a random order.
|
||||
A:AB$ Pump | Cost$ SubCounter<6/LOYALTY> | Planeswalker$ True | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumAtt$ +10 | NumDef$ +10 | KW$ Trample | SpellDescription$ Target creature gets +10/+10 and gains trample until end of turn.
|
||||
DeckHas:Ability$Counters
|
||||
Oracle:[+1]: Put three +1/+1 counters on up to one target creature.\n[−1]: Reveal cards from the top of your library until you reveal a creature card. Put that card into your hand and the rest on the bottom of your library in a random order.\n[−6]: Target creature gets +10/+10 and gains trample until end of turn.
|
||||
|
||||
@@ -6,5 +6,6 @@ A:SP$ Attach | Cost$ 4 G | ValidTgts$ Creature | AILogic$ Pump
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigToken | TriggerDescription$ When CARDNAME enters the battlefield, create a 2/2 green Wolf creature token.
|
||||
SVar:TrigToken:DB$ Token | TokenScript$ g_2_2_wolf | LegacyImage$ g 2 2 wolf emn | TokenOwner$ You | TokenAmount$ 1
|
||||
S:Mode$ Continuous | Affected$ Creature.EnchantedBy | AddPower$ 2 | AddToughness$ 2 | Description$ Enchanted creature gets +2/+2.
|
||||
DeckHas:Ability$Token
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/wolfkin_bond.jpg
|
||||
Oracle:Enchant creature\nWhen Wolfkin Bond enters the battlefield, create a 2/2 green Wolf creature token.\nEnchanted creature gets +2/+2.
|
||||
|
||||
6
forge-gui/res/cardsfolder/w/woodland_mystic.txt
Normal file
6
forge-gui/res/cardsfolder/w/woodland_mystic.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
Name:Woodland Mystic
|
||||
ManaCost:1 G
|
||||
Types:Creature Elf Druid
|
||||
PT:1/1
|
||||
A:AB$ Mana | Cost$ T | Produced$ G | SpellDescription$ Add {G}.
|
||||
Oracle:{T}: Add {G}.
|
||||
@@ -4,6 +4,6 @@ Types:Legendary Creature Goblin Shaman
|
||||
PT:3/3
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ WortETB | TriggerDescription$ When CARDNAME enters the battlefield, create two 1/1 red and green Goblin Warrior creature tokens.
|
||||
SVar:WortETB:DB$ Token | TokenAmount$ 2 | TokenScript$ rg_1_1_goblin_warrior | TokenOwner$ You
|
||||
S:Mode$ Continuous | AddKeyword$ Conspire | Affected$ Instant.Green+YouCtrl,Instant.Red+YouCtrl,Sorcery.Red+YouCtrl,Sorcery.Green+YouCtrl | AffectedZone$ Stack,Graveyard,Hand,Library,Exile | EffectZone$ Battlefield | Description$ Each red or green instant or sorcery spell you cast has conspire. (As you cast the spell, you may tap two untapped creatures you control that share a color with it. When you do, copy it and you may choose new targets for the copy.)
|
||||
S:Mode$ Continuous | AddKeyword$ Conspire | Affected$ Instant.Green+YouCtrl,Instant.Red+YouCtrl,Sorcery.Red+YouCtrl,Sorcery.Green+YouCtrl | AffectedZone$ Stack | EffectZone$ Battlefield | Description$ Each red or green instant or sorcery spell you cast has conspire. (As you cast the spell, you may tap two untapped creatures you control that share a color with it. When you do, copy it and you may choose new targets for the copy.)
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/wort_the_raidmother.jpg
|
||||
Oracle:When Wort, the Raidmother enters the battlefield, create two 1/1 red and green Goblin Warrior creature tokens.\nEach red or green instant or sorcery spell you cast has conspire. (As you cast the spell, you may tap two untapped creatures you control that share a color with it. When you do, copy it and you may choose new targets for the copy.)
|
||||
|
||||
@@ -5,7 +5,7 @@ Name=Core Set 2020
|
||||
MciCode=m20
|
||||
Type=Core
|
||||
BoosterCovers=3
|
||||
Booster=10 Common:!fromSheet("M20 Secret Cards"), 3 Uncommon:!fromSheet("M20 Secret Cards"), 1 RareMythic:!fromSheet("M20 Secret Cards"), 1 BasicLand
|
||||
Booster=10 Common:!fromSheet("M20 Secret Cards"), 3 Uncommon:!fromSheet("M20 Secret Cards"), 1 RareMythic:!fromSheet("M20 Secret Cards"), 1 fromSheet("M20 Lands")
|
||||
|
||||
[cards]
|
||||
1 C Aerial Assault
|
||||
|
||||
@@ -103,10 +103,8 @@ public class HumanPlay {
|
||||
|
||||
// System.out.println("Playing:" + sa.getDescription() + " of " + sa.getHostCard() + " new = " + newAbility);
|
||||
if (newAbility) {
|
||||
Cost abCost = sa.getPayCosts() == null ? new Cost("0", sa.isAbility()) : sa.getPayCosts();
|
||||
CostPayment payment = new CostPayment(abCost, sa);
|
||||
|
||||
final HumanPlaySpellAbility req = new HumanPlaySpellAbility(controller, sa, payment);
|
||||
final HumanPlaySpellAbility req = new HumanPlaySpellAbility(controller, sa);
|
||||
if (!req.playAbility(true, false, false)) {
|
||||
if (flippedToCast && !castFaceDown) {
|
||||
source.turnFaceDown(true);
|
||||
@@ -199,9 +197,8 @@ public class HumanPlay {
|
||||
}
|
||||
sa = AbilityUtils.addSpliceEffects(sa);
|
||||
}
|
||||
final CostPayment payment = new CostPayment(sa.getPayCosts(), sa);
|
||||
|
||||
final HumanPlaySpellAbility req = new HumanPlaySpellAbility(controller, sa, payment);
|
||||
final HumanPlaySpellAbility req = new HumanPlaySpellAbility(controller, sa);
|
||||
req.playAbility(mayChooseNewTargets, true, false);
|
||||
}
|
||||
else {
|
||||
@@ -231,7 +228,7 @@ public class HumanPlay {
|
||||
sa.setActivatingPlayer(player);
|
||||
|
||||
if (sa.getPayCosts() != null) {
|
||||
final HumanPlaySpellAbility req = new HumanPlaySpellAbility(controller, sa, new CostPayment(sa.getPayCosts(), sa));
|
||||
final HumanPlaySpellAbility req = new HumanPlaySpellAbility(controller, sa);
|
||||
|
||||
req.playAbility(!useOldTargets, false, true);
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import forge.card.CardStateName;
|
||||
import forge.card.CardType;
|
||||
import forge.card.MagicColor;
|
||||
import forge.game.Game;
|
||||
import forge.game.GameActionUtil;
|
||||
import forge.game.GameObject;
|
||||
import forge.game.ability.AbilityUtils;
|
||||
import forge.game.card.Card;
|
||||
@@ -53,13 +54,11 @@ import java.util.Map;
|
||||
*/
|
||||
public class HumanPlaySpellAbility {
|
||||
private final PlayerControllerHuman controller;
|
||||
private final SpellAbility ability;
|
||||
private final CostPayment payment;
|
||||
private SpellAbility ability;
|
||||
|
||||
public HumanPlaySpellAbility(final PlayerControllerHuman controller0, final SpellAbility ability0, final CostPayment payment0) {
|
||||
public HumanPlaySpellAbility(final PlayerControllerHuman controller0, final SpellAbility ability0) {
|
||||
controller = controller0;
|
||||
ability = ability0;
|
||||
payment = payment0;
|
||||
}
|
||||
|
||||
public final boolean playAbility(final boolean mayChooseTargets, final boolean isFree, final boolean skipStack) {
|
||||
@@ -116,6 +115,11 @@ public class HumanPlaySpellAbility {
|
||||
ability.resetPaidHash();
|
||||
}
|
||||
|
||||
ability = GameActionUtil.addExtraKeywordCost(ability);
|
||||
|
||||
Cost abCost = ability.getPayCosts() == null ? new Cost("0", ability.isAbility()) : ability.getPayCosts();
|
||||
CostPayment payment = new CostPayment(abCost, ability);
|
||||
|
||||
// TODO Apply this to the SAStackInstance instead of the Player
|
||||
if (manaTypeConversion) {
|
||||
AbilityUtils.applyManaColorConversion(payment, MagicColor.Constant.ANY_TYPE_CONVERSION);
|
||||
@@ -155,7 +159,7 @@ public class HumanPlaySpellAbility {
|
||||
|
||||
if (!prerequisitesMet) {
|
||||
if (!ability.isTrigger()) {
|
||||
rollbackAbility(fromZone, fromState, zonePosition);
|
||||
rollbackAbility(fromZone, fromState, zonePosition, payment);
|
||||
if (ability.getHostCard().isMadness()) {
|
||||
// if a player failed to play madness cost, move the card to graveyard
|
||||
Card newCard = game.getAction().moveToGraveyard(c, null);
|
||||
@@ -240,7 +244,7 @@ public class HumanPlaySpellAbility {
|
||||
}
|
||||
}
|
||||
|
||||
private void rollbackAbility(final Zone fromZone, final CardStateName fromState, final int zonePosition) {
|
||||
private void rollbackAbility(final Zone fromZone, final CardStateName fromState, final int zonePosition, CostPayment payment) {
|
||||
// cancel ability during target choosing
|
||||
final Game game = ability.getActivatingPlayer().getGame();
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ import forge.game.cost.Cost;
|
||||
import forge.game.cost.CostPart;
|
||||
import forge.game.cost.CostPartMana;
|
||||
import forge.game.keyword.Keyword;
|
||||
import forge.game.keyword.KeywordInterface;
|
||||
import forge.game.mana.Mana;
|
||||
import forge.game.mana.ManaConversionMatrix;
|
||||
import forge.game.player.*;
|
||||
@@ -2930,5 +2931,19 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
return InputConfirm.confirm(this, (SpellAbility)null, "Do you want to scry?");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int chooseNumberForKeywordCost(SpellAbility sa, Cost cost, KeywordInterface keyword, String prompt,
|
||||
int max) {
|
||||
if (max <= 0) {
|
||||
return 0;
|
||||
}
|
||||
if (max == 1) {
|
||||
return InputConfirm.confirm(this, sa, prompt) ? 1 : 0;
|
||||
}
|
||||
|
||||
Integer v = getGui().getInteger(prompt, 0, max, 9);
|
||||
return v == null ? 0 : v.intValue();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
2
pom.xml
2
pom.xml
@@ -5,7 +5,7 @@
|
||||
<artifactId>forge</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<name>Forge Parent</name>
|
||||
<version>1.6.27-SNAPSHOT</version>
|
||||
<version>1.6.28-SNAPSHOT</version>
|
||||
|
||||
<description>
|
||||
Forge lets you play the card game Magic: The Gathering against a computer opponent using all of the rules.
|
||||
|
||||
Reference in New Issue
Block a user