mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-14 09:48:02 +00:00
Merge branch 'master' into AFC_Cards_20210717
This commit is contained in:
@@ -229,12 +229,12 @@ public class GameCopier {
|
|||||||
|
|
||||||
private static final boolean USE_FROM_PAPER_CARD = true;
|
private static final boolean USE_FROM_PAPER_CARD = true;
|
||||||
private Card createCardCopy(Game newGame, Player newOwner, Card c) {
|
private Card createCardCopy(Game newGame, Player newOwner, Card c) {
|
||||||
if (c.isToken() && !c.isEmblem()) {
|
if (c.isToken() && !c.isImmutable()) {
|
||||||
Card result = new TokenInfo(c).makeOneToken(newOwner);
|
Card result = new TokenInfo(c).makeOneToken(newOwner);
|
||||||
CardFactory.copyCopiableCharacteristics(c, result);
|
CardFactory.copyCopiableCharacteristics(c, result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
if (USE_FROM_PAPER_CARD && !c.isEmblem() && c.getPaperCard() != null) {
|
if (USE_FROM_PAPER_CARD && !c.isImmutable() && c.getPaperCard() != null) {
|
||||||
Card newCard = Card.fromPaperCard(c.getPaperCard(), newOwner);
|
Card newCard = Card.fromPaperCard(c.getPaperCard(), newOwner);
|
||||||
newCard.setCommander(c.isCommander());
|
newCard.setCommander(c.isCommander());
|
||||||
return newCard;
|
return newCard;
|
||||||
|
|||||||
@@ -58,7 +58,6 @@ public final class CardType implements Comparable<CardType>, CardTypeView {
|
|||||||
Conspiracy(false, "conspiracies"),
|
Conspiracy(false, "conspiracies"),
|
||||||
Creature(true, "creatures"),
|
Creature(true, "creatures"),
|
||||||
Dungeon(false, "dungeons"),
|
Dungeon(false, "dungeons"),
|
||||||
Emblem(false, "emblems"),
|
|
||||||
Enchantment(true, "enchantments"),
|
Enchantment(true, "enchantments"),
|
||||||
Instant(false, "instants"),
|
Instant(false, "instants"),
|
||||||
Land(true, "lands"),
|
Land(true, "lands"),
|
||||||
@@ -437,11 +436,6 @@ public final class CardType implements Comparable<CardType>, CardTypeView {
|
|||||||
return coreTypes.contains(CoreType.Phenomenon);
|
return coreTypes.contains(CoreType.Phenomenon);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isEmblem() {
|
|
||||||
return coreTypes.contains(CoreType.Emblem);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isTribal() {
|
public boolean isTribal() {
|
||||||
return coreTypes.contains(CoreType.Tribal);
|
return coreTypes.contains(CoreType.Tribal);
|
||||||
@@ -547,7 +541,7 @@ public final class CardType implements Comparable<CardType>, CardTypeView {
|
|||||||
if (!isInstant() && !isSorcery()) {
|
if (!isInstant() && !isSorcery()) {
|
||||||
Iterables.removeIf(subtypes, Predicates.IS_SPELL_TYPE);
|
Iterables.removeIf(subtypes, Predicates.IS_SPELL_TYPE);
|
||||||
}
|
}
|
||||||
if (!isPlaneswalker() && !isEmblem()) {
|
if (!isPlaneswalker()) {
|
||||||
Iterables.removeIf(subtypes, Predicates.IS_WALKER_TYPE);
|
Iterables.removeIf(subtypes, Predicates.IS_WALKER_TYPE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,6 @@ public interface CardTypeView extends Iterable<String>, Serializable {
|
|||||||
boolean isBasicLand();
|
boolean isBasicLand();
|
||||||
boolean isPlane();
|
boolean isPlane();
|
||||||
boolean isPhenomenon();
|
boolean isPhenomenon();
|
||||||
boolean isEmblem();
|
|
||||||
boolean isTribal();
|
boolean isTribal();
|
||||||
boolean isDungeon();
|
boolean isDungeon();
|
||||||
CardTypeView getTypeWithChanges(Iterable<CardChangedType> changedCardTypes);
|
CardTypeView getTypeWithChanges(Iterable<CardChangedType> changedCardTypes);
|
||||||
|
|||||||
@@ -153,8 +153,7 @@ public final class GameActionUtil {
|
|||||||
final StringBuilder sb = new StringBuilder(sa.getDescription());
|
final StringBuilder sb = new StringBuilder(sa.getDescription());
|
||||||
if (!source.equals(host)) {
|
if (!source.equals(host)) {
|
||||||
sb.append(" by ");
|
sb.append(" by ");
|
||||||
if ((host.isEmblem() || host.getType().hasSubtype("Effect"))
|
if ((host.isImmutable()) && host.getEffectSource() != null) {
|
||||||
&& host.getEffectSource() != null) {
|
|
||||||
sb.append(host.getEffectSource());
|
sb.append(host.getEffectSource());
|
||||||
} else {
|
} else {
|
||||||
sb.append(host);
|
sb.append(host);
|
||||||
@@ -542,7 +541,6 @@ public final class GameActionUtil {
|
|||||||
final Card eff = new Card(game.nextCardId(), game);
|
final Card eff = new Card(game.nextCardId(), game);
|
||||||
eff.setTimestamp(game.getNextTimestamp());
|
eff.setTimestamp(game.getNextTimestamp());
|
||||||
eff.setName(sourceCard.getName() + "'s Effect");
|
eff.setName(sourceCard.getName() + "'s Effect");
|
||||||
eff.addType("Effect");
|
|
||||||
eff.setOwner(controller);
|
eff.setOwner(controller);
|
||||||
|
|
||||||
eff.setImageKey(sourceCard.getImageKey());
|
eff.setImageKey(sourceCard.getImageKey());
|
||||||
|
|||||||
@@ -112,9 +112,9 @@ public class AbilityUtils {
|
|||||||
// Probably will move to One function solution sometime in the future
|
// Probably will move to One function solution sometime in the future
|
||||||
public static CardCollection getDefinedCards(final Card hostCard, final String def, final CardTraitBase sa) {
|
public static CardCollection getDefinedCards(final Card hostCard, final String def, final CardTraitBase sa) {
|
||||||
CardCollection cards = new CardCollection();
|
CardCollection cards = new CardCollection();
|
||||||
String defined = (def == null) ? "Self" : applyAbilityTextChangeEffects(def, sa); // default to Self
|
String changedDef = (def == null) ? "Self" : applyAbilityTextChangeEffects(def, sa); // default to Self
|
||||||
final String[] incR = defined.split("\\.", 2);
|
final String[] incR = changedDef.split("\\.", 2);
|
||||||
defined = incR[0];
|
String defined = incR[0];
|
||||||
final Game game = hostCard.getGame();
|
final Game game = hostCard.getGame();
|
||||||
|
|
||||||
Card c = null;
|
Card c = null;
|
||||||
@@ -132,7 +132,7 @@ public class AbilityUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (defined.equals("EffectSource")) {
|
else if (defined.equals("EffectSource")) {
|
||||||
if (hostCard.isEmblem() || hostCard.getType().hasSubtype("Effect")) {
|
if (hostCard.isImmutable()) {
|
||||||
c = findEffectRoot(hostCard);
|
c = findEffectRoot(hostCard);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -346,6 +346,23 @@ public class AbilityUtils {
|
|||||||
cards.add(game.getCardState(cardByID));
|
cards.add(game.getCardState(cardByID));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (defined.startsWith("Valid")) {
|
||||||
|
Iterable<Card> candidates;
|
||||||
|
String validDefined;
|
||||||
|
if (defined.startsWith("Valid ")) {
|
||||||
|
candidates = game.getCardsIn(ZoneType.Battlefield);
|
||||||
|
validDefined = changedDef.substring("Valid ".length());
|
||||||
|
} else if (defined.startsWith("ValidAll ")) {
|
||||||
|
candidates = game.getCardsInGame();
|
||||||
|
validDefined = changedDef.substring("ValidAll ".length());
|
||||||
|
} else {
|
||||||
|
String[] s = changedDef.split(" ", 2);
|
||||||
|
String zone = s[0].substring("Valid".length());
|
||||||
|
candidates = game.getCardsIn(ZoneType.smartValueOf(zone));
|
||||||
|
validDefined = s[1];
|
||||||
|
}
|
||||||
|
cards.addAll(CardLists.getValidCards(candidates, validDefined.split(","), hostCard.getController(), hostCard, sa));
|
||||||
|
return cards;
|
||||||
} else {
|
} else {
|
||||||
CardCollection list = null;
|
CardCollection list = null;
|
||||||
if (sa instanceof SpellAbility) {
|
if (sa instanceof SpellAbility) {
|
||||||
@@ -377,19 +394,6 @@ public class AbilityUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (defined.startsWith("Valid ")) {
|
|
||||||
String validDefined = defined.substring("Valid ".length());
|
|
||||||
list = CardLists.getValidCards(game.getCardsIn(ZoneType.Battlefield), validDefined.split(","), hostCard.getController(), hostCard, sa);
|
|
||||||
} else if (defined.startsWith("ValidAll ")) {
|
|
||||||
String validDefined = defined.substring("ValidAll ".length());
|
|
||||||
list = CardLists.getValidCards(game.getCardsInGame(), validDefined.split(","), hostCard.getController(), hostCard, sa);
|
|
||||||
} else if (defined.startsWith("Valid")) {
|
|
||||||
String[] s = defined.split(" ");
|
|
||||||
String zone = s[0].substring("Valid".length());
|
|
||||||
String validDefined = s[1];
|
|
||||||
list = CardLists.getValidCards(game.getCardsIn(ZoneType.smartValueOf(zone)), validDefined.split(","), hostCard.getController(), hostCard, sa);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (list != null) {
|
if (list != null) {
|
||||||
cards.addAll(list);
|
cards.addAll(list);
|
||||||
}
|
}
|
||||||
@@ -421,7 +425,7 @@ public class AbilityUtils {
|
|||||||
private static Card findEffectRoot(Card startCard) {
|
private static Card findEffectRoot(Card startCard) {
|
||||||
Card cc = startCard.getEffectSource();
|
Card cc = startCard.getEffectSource();
|
||||||
if (cc != null) {
|
if (cc != null) {
|
||||||
if (cc.isEmblem() || cc.getType().hasSubtype("Effect")) {
|
if (cc.isImmutable()) {
|
||||||
return findEffectRoot(cc);
|
return findEffectRoot(cc);
|
||||||
}
|
}
|
||||||
return cc;
|
return cc;
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import com.google.common.collect.Maps;
|
|||||||
import com.google.common.collect.Table;
|
import com.google.common.collect.Table;
|
||||||
|
|
||||||
import forge.GameCommand;
|
import forge.GameCommand;
|
||||||
import forge.card.CardType;
|
|
||||||
import forge.card.MagicColor;
|
import forge.card.MagicColor;
|
||||||
import forge.game.Game;
|
import forge.game.Game;
|
||||||
import forge.game.GameEntity;
|
import forge.game.GameEntity;
|
||||||
@@ -457,25 +456,19 @@ public abstract class SpellAbilityEffect {
|
|||||||
final Card eff = new Card(game.nextCardId(), game);
|
final Card eff = new Card(game.nextCardId(), game);
|
||||||
eff.setTimestamp(game.getNextTimestamp());
|
eff.setTimestamp(game.getNextTimestamp());
|
||||||
eff.setName(name);
|
eff.setName(name);
|
||||||
|
eff.setColor(hostCard.determineColor().getColor());
|
||||||
// if name includes emblem then it should be one
|
// if name includes emblem then it should be one
|
||||||
eff.addType(name.startsWith("Emblem") ? "Emblem" : "Effect");
|
if (name.startsWith("Emblem")) {
|
||||||
// add Planeswalker types into Emblem for fun
|
eff.setEmblem(true);
|
||||||
if (name.startsWith("Emblem") && hostCard.isPlaneswalker()) {
|
// Emblem needs to be colorless
|
||||||
for (final String type : hostCard.getType().getSubtypes()) {
|
eff.setColor(MagicColor.COLORLESS);
|
||||||
if (CardType.isAPlaneswalkerType(type)) {
|
|
||||||
eff.addType(type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
eff.setOwner(controller);
|
eff.setOwner(controller);
|
||||||
eff.setSVars(sa.getSVars());
|
eff.setSVars(sa.getSVars());
|
||||||
|
|
||||||
eff.setImageKey(image);
|
eff.setImageKey(image);
|
||||||
if (eff.getType().hasType(CardType.CoreType.Emblem)) {
|
|
||||||
eff.setColor(MagicColor.COLORLESS);
|
|
||||||
} else {
|
|
||||||
eff.setColor(hostCard.determineColor().getColor());
|
|
||||||
}
|
|
||||||
eff.setImmutable(true);
|
eff.setImmutable(true);
|
||||||
eff.setEffectSource(sa);
|
eff.setEffectSource(sa);
|
||||||
|
|
||||||
|
|||||||
@@ -190,11 +190,6 @@ public class AnimateEffect extends AnimateEffectBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Restore immutable to effect
|
|
||||||
if (sa.hasParam("Immutable")) {
|
|
||||||
c.setImmutable(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
game.fireEvent(new GameEventCardStatsChanged(c));
|
game.fireEvent(new GameEventCardStatsChanged(c));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -164,14 +164,6 @@ public abstract class AnimateEffectBase extends SpellAbilityEffect {
|
|||||||
final Trigger parsedTrigger = TriggerHandler.parseTrigger(AbilityUtils.getSVar(sa, s), c, false, sa);
|
final Trigger parsedTrigger = TriggerHandler.parseTrigger(AbilityUtils.getSVar(sa, s), c, false, sa);
|
||||||
addedTriggers.add(parsedTrigger);
|
addedTriggers.add(parsedTrigger);
|
||||||
}
|
}
|
||||||
if (sa.hasParam("GainsTriggeredAbilitiesOf")) {
|
|
||||||
final List<Card> cards = AbilityUtils.getDefinedCards(sa.getHostCard(), sa.getParam("GainsTriggeredAbilitiesOf"), sa);
|
|
||||||
for (final Card card : cards) {
|
|
||||||
for (Trigger t : card.getTriggers()) {
|
|
||||||
addedTriggers.add(t.copy(c, false));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// give replacement effects
|
// give replacement effects
|
||||||
final List<ReplacementEffect> addedReplacements = Lists.newArrayList();
|
final List<ReplacementEffect> addedReplacements = Lists.newArrayList();
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ public class DetachedCardEffect extends Card {
|
|||||||
card = card0;
|
card = card0;
|
||||||
|
|
||||||
setName(name0);
|
setName(name0);
|
||||||
addType("Effect");
|
|
||||||
setOwner(card0.getOwner());
|
setOwner(card0.getOwner());
|
||||||
setImmutable(true);
|
setImmutable(true);
|
||||||
|
|
||||||
|
|||||||
@@ -140,10 +140,6 @@ public class EffectEffect extends SpellAbilityEffect {
|
|||||||
final Card eff = createEffect(sa, controller, name, image);
|
final Card eff = createEffect(sa, controller, name, image);
|
||||||
eff.setSetCode(sa.getHostCard().getSetCode());
|
eff.setSetCode(sa.getHostCard().getSetCode());
|
||||||
eff.setRarity(sa.getHostCard().getRarity());
|
eff.setRarity(sa.getHostCard().getRarity());
|
||||||
// For Raging River effect to add attacker "left" or "right" pile later
|
|
||||||
if (sa.hasParam("Mutable")) {
|
|
||||||
eff.setImmutable(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Abilities and triggers work the same as they do for Token
|
// Abilities and triggers work the same as they do for Token
|
||||||
// Grant abilities
|
// Grant abilities
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ public class RegenerationEffect extends SpellAbilityEffect {
|
|||||||
// Play the Regen sound
|
// Play the Regen sound
|
||||||
game.fireEvent(new GameEventCardRegenerated());
|
game.fireEvent(new GameEventCardRegenerated());
|
||||||
|
|
||||||
if (host.getType().hasStringType("Effect")) {
|
if (host.isImmutable()) {
|
||||||
c.subtractShield(host);
|
c.subtractShield(host);
|
||||||
host.removeRemembered(c);
|
host.removeRemembered(c);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ public class ReplaceDamageEffect extends SpellAbilityEffect {
|
|||||||
prevent -= n;
|
prevent -= n;
|
||||||
|
|
||||||
if (!StringUtils.isNumeric(varValue) && card.getSVar(varValue).startsWith("Number$")) {
|
if (!StringUtils.isNumeric(varValue) && card.getSVar(varValue).startsWith("Number$")) {
|
||||||
if (card.getType().hasStringType("Effect") && prevent <= 0) {
|
if (card.isImmutable() && prevent <= 0) {
|
||||||
game.getAction().exile(card, null);
|
game.getAction().exile(card, null);
|
||||||
} else {
|
} else {
|
||||||
card.setSVar(varValue, "Number$" + prevent);
|
card.setSVar(varValue, "Number$" + prevent);
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ public class ReplaceSplitDamageEffect extends SpellAbilityEffect {
|
|||||||
dmg -= n;
|
dmg -= n;
|
||||||
prevent -= n;
|
prevent -= n;
|
||||||
|
|
||||||
if (card.getType().hasStringType("Effect") && prevent <= 0) {
|
if (card.isImmutable() && prevent <= 0) {
|
||||||
game.getAction().exile(card, null);
|
game.getAction().exile(card, null);
|
||||||
} else if (!StringUtils.isNumeric(varValue)) {
|
} else if (!StringUtils.isNumeric(varValue)) {
|
||||||
sa.setSVar(varValue, "Number$" + prevent);
|
sa.setSVar(varValue, "Number$" + prevent);
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import forge.game.event.GameEventCardStatsChanged;
|
|||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.replacement.ReplacementType;
|
import forge.game.replacement.ReplacementType;
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
|
import forge.game.trigger.Trigger;
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
|
|
||||||
public abstract class TokenEffectBase extends SpellAbilityEffect {
|
public abstract class TokenEffectBase extends SpellAbilityEffect {
|
||||||
@@ -118,7 +119,7 @@ public abstract class TokenEffectBase extends SpellAbilityEffect {
|
|||||||
}
|
}
|
||||||
tok.setTimestamp(timestamp);
|
tok.setTimestamp(timestamp);
|
||||||
tok.setToken(true);
|
tok.setToken(true);
|
||||||
|
|
||||||
// do effect stuff with the token
|
// do effect stuff with the token
|
||||||
if (sa.hasParam("TokenTapped")) {
|
if (sa.hasParam("TokenTapped")) {
|
||||||
tok.setTapped(true);
|
tok.setTapped(true);
|
||||||
@@ -138,6 +139,15 @@ public abstract class TokenEffectBase extends SpellAbilityEffect {
|
|||||||
tok.addEtbCounter(cType, cAmount, creator);
|
tok.addEtbCounter(cType, cAmount, creator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sa.hasParam("AddTriggersFrom")) {
|
||||||
|
final List<Card> cards = AbilityUtils.getDefinedCards(host, sa.getParam("AddTriggersFrom"), sa);
|
||||||
|
for (final Card card : cards) {
|
||||||
|
for (final Trigger trig : card.getTriggers()) {
|
||||||
|
tok.addTrigger(trig.copy(tok, false));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (clone) {
|
if (clone) {
|
||||||
tok.setCopiedPermanent(prototype);
|
tok.setCopiedPermanent(prototype);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -264,6 +264,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
|||||||
|
|
||||||
// for Vanguard / Manapool / Emblems etc.
|
// for Vanguard / Manapool / Emblems etc.
|
||||||
private boolean isImmutable = false;
|
private boolean isImmutable = false;
|
||||||
|
private boolean isEmblem = false;
|
||||||
|
|
||||||
private int exertThisTurn = 0;
|
private int exertThisTurn = 0;
|
||||||
private PlayerCollection exertedByPlayer = new PlayerCollection();
|
private PlayerCollection exertedByPlayer = new PlayerCollection();
|
||||||
@@ -4598,15 +4599,13 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final boolean isPermanent() {
|
public final boolean isPermanent() {
|
||||||
return !isImmutable && (isInZone(ZoneType.Battlefield) || getType().isPermanent());
|
return !isImmutable() && (isInZone(ZoneType.Battlefield) || getType().isPermanent());
|
||||||
}
|
}
|
||||||
|
|
||||||
public final boolean isSpell() {
|
public final boolean isSpell() {
|
||||||
return (isInstant() || isSorcery() || (isAura() && !isInZone((ZoneType.Battlefield))));
|
return (isInstant() || isSorcery() || (isAura() && !isInZone((ZoneType.Battlefield))));
|
||||||
}
|
}
|
||||||
|
|
||||||
public final boolean isEmblem() { return getType().isEmblem(); }
|
|
||||||
|
|
||||||
public final boolean isLand() { return getType().isLand(); }
|
public final boolean isLand() { return getType().isLand(); }
|
||||||
public final boolean isBasicLand() { return getType().isBasicLand(); }
|
public final boolean isBasicLand() { return getType().isBasicLand(); }
|
||||||
public final boolean isSnow() { return getType().isSnow(); }
|
public final boolean isSnow() { return getType().isSnow(); }
|
||||||
@@ -4865,11 +4864,6 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
|||||||
// Takes one argument like Permanent.Blue+withFlying
|
// Takes one argument like Permanent.Blue+withFlying
|
||||||
@Override
|
@Override
|
||||||
public final boolean isValid(final String restriction, final Player sourceController, final Card source, CardTraitBase spellAbility) {
|
public final boolean isValid(final String restriction, final Player sourceController, final Card source, CardTraitBase spellAbility) {
|
||||||
if (isImmutable() && source != null && !source.isRemembered(this) &&
|
|
||||||
!(restriction.startsWith("Emblem") || restriction.startsWith("Effect"))) { // special case exclusion
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Inclusive restrictions are Card types
|
// Inclusive restrictions are Card types
|
||||||
final String[] incR = restriction.split("\\.", 2);
|
final String[] incR = restriction.split("\\.", 2);
|
||||||
|
|
||||||
@@ -4879,14 +4873,27 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
|||||||
incR[0] = incR[0].substring(1); // consume negation sign
|
incR[0] = incR[0].substring(1); // consume negation sign
|
||||||
}
|
}
|
||||||
|
|
||||||
if (incR[0].equals("Spell") && !isSpell()) {
|
if (incR[0].equals("Spell")) {
|
||||||
return testFailed;
|
if (!isSpell()) {
|
||||||
}
|
return testFailed;
|
||||||
if (incR[0].equals("Permanent") && !isPermanent()) {
|
}
|
||||||
return testFailed;
|
} else if (incR[0].equals("Permanent")) {
|
||||||
}
|
if (!isPermanent()) {
|
||||||
if (!incR[0].equals("card") && !incR[0].equals("Card") && !incR[0].equals("Spell")
|
return testFailed;
|
||||||
&& !incR[0].equals("Permanent") && !getType().hasStringType(incR[0])) {
|
}
|
||||||
|
} else if (incR[0].equals("Effect")) {
|
||||||
|
if (!isImmutable()) {
|
||||||
|
return testFailed;
|
||||||
|
}
|
||||||
|
} else if (incR[0].equals("Emblem")) {
|
||||||
|
if (!isEmblem()) {
|
||||||
|
return testFailed;
|
||||||
|
}
|
||||||
|
} else if (incR[0].equals("card") || incR[0].equals("Card")) {
|
||||||
|
if (isImmutable()) {
|
||||||
|
return testFailed;
|
||||||
|
}
|
||||||
|
} else if (!getType().hasStringType(incR[0])) {
|
||||||
return testFailed; // Check for wrong type
|
return testFailed; // Check for wrong type
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4916,6 +4923,15 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
|||||||
}
|
}
|
||||||
public final void setImmutable(final boolean isImmutable0) {
|
public final void setImmutable(final boolean isImmutable0) {
|
||||||
isImmutable = isImmutable0;
|
isImmutable = isImmutable0;
|
||||||
|
view.updateImmutable(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public final boolean isEmblem() {
|
||||||
|
return isEmblem;
|
||||||
|
}
|
||||||
|
public final void setEmblem(final boolean isEmblem0) {
|
||||||
|
isEmblem = isEmblem0;
|
||||||
|
view.updateEmblem(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -357,7 +357,7 @@ public class CardProperty {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else if (property.equals("EffectSource")) {
|
} else if (property.equals("EffectSource")) {
|
||||||
if (!source.isEmblem() && !source.getType().hasSubtype("Effect")) {
|
if (!source.isImmutable()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -242,6 +242,7 @@ public final class CardUtil {
|
|||||||
newCopy.setToken(in.isToken());
|
newCopy.setToken(in.isToken());
|
||||||
newCopy.setCopiedSpell(in.isCopiedSpell());
|
newCopy.setCopiedSpell(in.isCopiedSpell());
|
||||||
newCopy.setImmutable(in.isImmutable());
|
newCopy.setImmutable(in.isImmutable());
|
||||||
|
newCopy.setEmblem(in.isEmblem());
|
||||||
|
|
||||||
// lock in the current P/T
|
// lock in the current P/T
|
||||||
newCopy.setBasePower(in.getCurrentPower());
|
newCopy.setBasePower(in.getCurrentPower());
|
||||||
|
|||||||
@@ -233,6 +233,20 @@ public class CardView extends GameEntityView {
|
|||||||
set(TrackableProperty.Token, c.isToken());
|
set(TrackableProperty.Token, c.isToken());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isImmutable() {
|
||||||
|
return get(TrackableProperty.IsImmutable);
|
||||||
|
}
|
||||||
|
public void updateImmutable(Card c) {
|
||||||
|
set(TrackableProperty.IsImmutable, c.isImmutable());
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEmblem() {
|
||||||
|
return get(TrackableProperty.IsEmblem);
|
||||||
|
}
|
||||||
|
public void updateEmblem(Card c) {
|
||||||
|
set(TrackableProperty.IsEmblem, c.isEmblem());
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isTokenCard() { return get(TrackableProperty.TokenCard); }
|
public boolean isTokenCard() { return get(TrackableProperty.TokenCard); }
|
||||||
void updateTokenCard(Card c) { set(TrackableProperty.TokenCard, c.isTokenCard()); }
|
void updateTokenCard(Card c) { set(TrackableProperty.TokenCard, c.isTokenCard()); }
|
||||||
|
|
||||||
|
|||||||
@@ -3176,6 +3176,7 @@ public class Player extends GameEntity implements Comparable<Player> {
|
|||||||
if (monarchEffect == null) {
|
if (monarchEffect == null) {
|
||||||
monarchEffect = new Card(game.nextCardId(), null, game);
|
monarchEffect = new Card(game.nextCardId(), null, game);
|
||||||
monarchEffect.setOwner(this);
|
monarchEffect.setOwner(this);
|
||||||
|
monarchEffect.setImmutable(true);
|
||||||
if (set != null) {
|
if (set != null) {
|
||||||
monarchEffect.setImageKey("t:monarch_" + set.toLowerCase());
|
monarchEffect.setImageKey("t:monarch_" + set.toLowerCase());
|
||||||
monarchEffect.setSetCode(set);
|
monarchEffect.setSetCode(set);
|
||||||
@@ -3183,7 +3184,6 @@ public class Player extends GameEntity implements Comparable<Player> {
|
|||||||
monarchEffect.setImageKey("t:monarch");
|
monarchEffect.setImageKey("t:monarch");
|
||||||
}
|
}
|
||||||
monarchEffect.setName("The Monarch");
|
monarchEffect.setName("The Monarch");
|
||||||
monarchEffect.addType("Effect");
|
|
||||||
|
|
||||||
{
|
{
|
||||||
final String drawTrig = "Mode$ Phase | Phase$ End of Turn | TriggerZones$ Command | " +
|
final String drawTrig = "Mode$ Phase | Phase$ End of Turn | TriggerZones$ Command | " +
|
||||||
@@ -3280,8 +3280,7 @@ public class Player extends GameEntity implements Comparable<Player> {
|
|||||||
blessingEffect.setOwner(this);
|
blessingEffect.setOwner(this);
|
||||||
blessingEffect.setImageKey("t:blessing");
|
blessingEffect.setImageKey("t:blessing");
|
||||||
blessingEffect.setName("City's Blessing");
|
blessingEffect.setName("City's Blessing");
|
||||||
blessingEffect.addType("Effect");
|
blessingEffect.setImmutable(true);
|
||||||
|
|
||||||
|
|
||||||
blessingEffect.updateStateForView();
|
blessingEffect.updateStateForView();
|
||||||
|
|
||||||
@@ -3353,7 +3352,6 @@ public class Player extends GameEntity implements Comparable<Player> {
|
|||||||
keywordEffect.setOwner(this);
|
keywordEffect.setOwner(this);
|
||||||
keywordEffect.setName("Keyword Effects");
|
keywordEffect.setName("Keyword Effects");
|
||||||
keywordEffect.setImageKey(ImageKeys.HIDDEN_CARD);
|
keywordEffect.setImageKey(ImageKeys.HIDDEN_CARD);
|
||||||
keywordEffect.addType("Effect");
|
|
||||||
|
|
||||||
keywordEffect.updateStateForView();
|
keywordEffect.updateStateForView();
|
||||||
|
|
||||||
|
|||||||
@@ -220,7 +220,7 @@ public abstract class ReplacementEffect extends TriggerReplacementBase {
|
|||||||
if (hasParam("Description") && !this.isSuppressed()) {
|
if (hasParam("Description") && !this.isSuppressed()) {
|
||||||
String desc = AbilityUtils.applyDescriptionTextChangeEffects(getParam("Description"), this);
|
String desc = AbilityUtils.applyDescriptionTextChangeEffects(getParam("Description"), this);
|
||||||
String currentName;
|
String currentName;
|
||||||
if (this.isIntrinsic() && !this.getHostCard().isMutated() && cardState != null) {
|
if (this.isIntrinsic() && cardState != null && cardState.getCard() == getHostCard()) {
|
||||||
currentName = cardState.getName();
|
currentName = cardState.getName();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
@@ -95,8 +95,7 @@ public class LandAbility extends Ability {
|
|||||||
Card source = sta.getHostCard();
|
Card source = sta.getHostCard();
|
||||||
if (!source.equals(getHostCard())) {
|
if (!source.equals(getHostCard())) {
|
||||||
sb.append(" by ");
|
sb.append(" by ");
|
||||||
if ((source.isEmblem() || source.getType().hasSubtype("Effect"))
|
if (source.isImmutable() && source.getEffectSource() != null) {
|
||||||
&& source.getEffectSource() != null) {
|
|
||||||
sb.append(source.getEffectSource());
|
sb.append(source.getEffectSource());
|
||||||
} else {
|
} else {
|
||||||
sb.append(source);
|
sb.append(source);
|
||||||
|
|||||||
@@ -854,7 +854,7 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit
|
|||||||
if (node.getHostCard() != null) {
|
if (node.getHostCard() != null) {
|
||||||
String currentName;
|
String currentName;
|
||||||
// if alternate state is viewed while card uses original
|
// if alternate state is viewed while card uses original
|
||||||
if (node.isIntrinsic() && !node.getHostCard().isMutated() && node.cardState != null) {
|
if (node.isIntrinsic() && node.cardState != null && node.cardState.getCard() == node.getHostCard()) {
|
||||||
currentName = node.cardState.getName();
|
currentName = node.cardState.getName();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
@@ -209,7 +209,7 @@ public class StaticAbility extends CardTraitBase implements IIdentifiable, Clone
|
|||||||
public final String toString() {
|
public final String toString() {
|
||||||
if (hasParam("Description") && !this.isSuppressed()) {
|
if (hasParam("Description") && !this.isSuppressed()) {
|
||||||
String currentName;
|
String currentName;
|
||||||
if (this.isIntrinsic() && !this.getHostCard().isMutated() && cardState != null) {
|
if (this.isIntrinsic() && cardState != null && cardState.getCard() == getHostCard()) {
|
||||||
currentName = cardState.getName();
|
currentName = cardState.getName();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
@@ -132,7 +132,7 @@ public abstract class Trigger extends TriggerReplacementBase {
|
|||||||
|
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
String currentName;
|
String currentName;
|
||||||
if (this.isIntrinsic() && !this.getHostCard().isMutated() && cardState != null) {
|
if (this.isIntrinsic() && cardState != null && cardState.getCard() == getHostCard()) {
|
||||||
currentName = cardState.getName();
|
currentName = cardState.getName();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
@@ -24,6 +24,9 @@ public enum TrackableProperty {
|
|||||||
Controller(TrackableTypes.PlayerViewType),
|
Controller(TrackableTypes.PlayerViewType),
|
||||||
Zone(TrackableTypes.EnumType(ZoneType.class)),
|
Zone(TrackableTypes.EnumType(ZoneType.class)),
|
||||||
|
|
||||||
|
IsImmutable(TrackableTypes.BooleanType),
|
||||||
|
IsEmblem(TrackableTypes.BooleanType),
|
||||||
|
|
||||||
Flipped(TrackableTypes.BooleanType),
|
Flipped(TrackableTypes.BooleanType),
|
||||||
Facedown(TrackableTypes.BooleanType),
|
Facedown(TrackableTypes.BooleanType),
|
||||||
Foretold(TrackableTypes.BooleanType),
|
Foretold(TrackableTypes.BooleanType),
|
||||||
|
|||||||
@@ -311,7 +311,7 @@ public class CardPanel extends SkinnedPanel implements CardContainer, IDisposabl
|
|||||||
final CardStateView state = getCard().getCurrentState();
|
final CardStateView state = getCard().getCurrentState();
|
||||||
final CardEdition ed = FModel.getMagicDb().getEditions().get(state.getSetCode());
|
final CardEdition ed = FModel.getMagicDb().getEditions().get(state.getSetCode());
|
||||||
boolean colorIsSet = false;
|
boolean colorIsSet = false;
|
||||||
if (state.getType().isEmblem() || state.getType().hasStringType("Effect")) {
|
if (getCard().isImmutable()) {
|
||||||
// Effects are drawn with orange border
|
// Effects are drawn with orange border
|
||||||
g2d.setColor(Color.ORANGE);
|
g2d.setColor(Color.ORANGE);
|
||||||
colorIsSet = true;
|
colorIsSet = true;
|
||||||
|
|||||||
@@ -362,8 +362,7 @@ public class CardImageRenderer {
|
|||||||
drawDetails(g, card, gameView, altState, x, y, w, h);
|
drawDetails(g, card, gameView, altState, x, y, w, h);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(card.isToken() && card.getCurrentState().getType().hasSubtype("Effect")
|
if(card.isImmutable() && FModel.getPreferences().getPrefBoolean(ForgePreferences.FPref.UI_DISABLE_IMAGES_EFFECT_CARDS)){
|
||||||
&& FModel.getPreferences().getPrefBoolean(ForgePreferences.FPref.UI_DISABLE_IMAGES_EFFECT_CARDS)){
|
|
||||||
drawDetails(g, card, gameView, altState, x, y, w, h);
|
drawDetails(g, card, gameView, altState, x, y, w, h);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
16
forge-gui/res/cardsfolder/c/catti_brie_of_mithral_hall.txt
Normal file
16
forge-gui/res/cardsfolder/c/catti_brie_of_mithral_hall.txt
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
Name:Catti-brie of Mithral Hall
|
||||||
|
ManaCost:G W
|
||||||
|
Types:Legendary Creature Human Archer
|
||||||
|
PT:2/2
|
||||||
|
K:First Strike
|
||||||
|
K:Reach
|
||||||
|
T:Mode$ Attacks | ValidCard$ Creature.Self | Execute$ TrigPutCounter | TriggerDescription$ Whenever CARDNAME attacks, put a +1/+1 counter on it for each Equipment attached to it.
|
||||||
|
SVar:TrigPutCounter:DB$ PutCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ Y
|
||||||
|
SVar:Y:Count$Valid Equipment.Attached
|
||||||
|
A:AB$ DealDamage | Cost$ 1 SubCounter<All/P1P1> | NumDmg$ X | ValidTgts$ Creature.attacking+OppCtrl,Creature.blocking+OppCtrl | TgtPrompt$ Select target attacking or blocking creature an opponent controls | SpellDescription$ It deals X damage to target attacking or blocking creature an opponent controls, where X is the number of counters removed this way.
|
||||||
|
SVar:X:SVar$CostCountersRemoved
|
||||||
|
SVar:HasAttackEffect:TRUE
|
||||||
|
SVar:EquipMe:Multiple
|
||||||
|
DeckNeeds:Type$Equipment
|
||||||
|
DeckHas:Ability$Counters
|
||||||
|
Oracle:First strike, reach\nWhenever Catti-brie of Mithral Hall attacks, put a +1/+1 counter on it for each Equipment attached to it.\n{1}, Remove all +1/+1 counters from Catti-brie: It deals X damage to target attacking or blocking creature an opponent controls, where X is the number of counters removed this way.
|
||||||
@@ -5,9 +5,11 @@ PT:3/2
|
|||||||
T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ DBLoop | TriggerDescription$ Whenever CARDNAME attacks, choose target creature you control, then ABILITY
|
T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ DBLoop | TriggerDescription$ Whenever CARDNAME attacks, choose target creature you control, then ABILITY
|
||||||
SVar:DBLoop:DB$ Repeat | ValidTgts$ Creature.YouCtrl | RepeatCheckSVar$ RepeatCheck | RepeatSVarCompare$ GT0 | RepeatSubAbility$ DBRollDice | RepeatOptional$ True
|
SVar:DBLoop:DB$ Repeat | ValidTgts$ Creature.YouCtrl | RepeatCheckSVar$ RepeatCheck | RepeatSVarCompare$ GT0 | RepeatSubAbility$ DBRollDice | RepeatOptional$ True
|
||||||
SVar:DBRollDice:DB$ RollDice | Sides$ 20 | ResultSubAbilities$ 1-14:DBCopy,15-20:DBCopyRepeat | SpellDescription$ roll a d20.
|
SVar:DBRollDice:DB$ RollDice | Sides$ 20 | ResultSubAbilities$ 1-14:DBCopy,15-20:DBCopyRepeat | SpellDescription$ roll a d20.
|
||||||
SVar:DBCopy:DB$ CopyPermanent | Defined$ Targeted | TokenTapped$ True | TokenAttacking$ True | NonLegendary$ True | AtEOT$ ExileCombat | SubAbility$ DBNotRepeat | SpellDescription$ 1-14 VERT Create a tapped and attacking token that's a copy of that creature, except it's not legendary and it has "Exile this creature at end of combat.
|
SVar:DBCopy:DB$ CopyPermanent | Defined$ Targeted | TokenTapped$ True | TokenAttacking$ True | NonLegendary$ True | AddSVars$ DelinaTrigExile | AddTriggers$ TrigPhase | SubAbility$ DBNotRepeat | SpellDescription$ 1-14 VERT Create a tapped and attacking token that's a copy of that creature, except it's not legendary and it has "Exile this creature at end of combat.
|
||||||
SVar:DBNotRepeat:DB$ StoreSVar | SVar$ RepeatCheck | Type$ Number | Expression$ 0
|
SVar:DBNotRepeat:DB$ StoreSVar | SVar$ RepeatCheck | Type$ Number | Expression$ 0
|
||||||
SVar:DBCopyRepeat:DB$ CopyPermanent | Defined$ Targeted | TokenTapped$ True | TokenAttacking$ True | NonLegendary$ True | AtEOT$ ExileCombat | SubAbility$ DBRepeat | SpellDescription$ 15-20 VERT Create one of those tokens. You may roll again.
|
SVar:DBCopyRepeat:DB$ CopyPermanent | Defined$ Targeted | TokenTapped$ True | TokenAttacking$ True | NonLegendary$ True | AddSVars$ DelinaTrigExile | AddTriggers$ TrigPhase | SubAbility$ DBRepeat | SpellDescription$ 15-20 VERT Create one of those tokens. You may roll again.
|
||||||
|
SVar:TrigPhase:Mode$ Phase | Phase$ EndCombat | TriggerZones$ Battlefield | Execute$ DelinaTrigExile | TriggerDescription$ Exile this creature at end of combat.
|
||||||
|
SVar:DelinaTrigExile:DB$ ChangeZone | Defined$ Self | Origin$ Battlefield | Destination$ Exile
|
||||||
SVar:DBRepeat:DB$ StoreSVar | SVar$ RepeatCheck | Type$ Number | Expression$ 1
|
SVar:DBRepeat:DB$ StoreSVar | SVar$ RepeatCheck | Type$ Number | Expression$ 1
|
||||||
SVar:RepeatCheck:Number$1
|
SVar:RepeatCheck:Number$1
|
||||||
SVar:HasAttackEffect:TRUE
|
SVar:HasAttackEffect:TRUE
|
||||||
@@ -5,7 +5,7 @@ PT:3/4
|
|||||||
T:Mode$ Phase | Phase$ EndCombat | Execute$ TrigCounter | TriggerZones$ Battlefield | TriggerDescription$ At end of combat, put a paralyzation counter on each creature blocking or blocked by CARDNAME and tap those creatures. Each of those creatures doesn't untap during its controller's untap step for as long as it has a paralyzation counter on it. Each of those creatures gains "{4}: Remove a paralyzation counter from this creature."
|
T:Mode$ Phase | Phase$ EndCombat | Execute$ TrigCounter | TriggerZones$ Battlefield | TriggerDescription$ At end of combat, put a paralyzation counter on each creature blocking or blocked by CARDNAME and tap those creatures. Each of those creatures doesn't untap during its controller's untap step for as long as it has a paralyzation counter on it. Each of those creatures gains "{4}: Remove a paralyzation counter from this creature."
|
||||||
SVar:TrigCounter:DB$ PutCounterAll | CounterType$ PARALYZATION | CounterNum$ 1 | ValidCards$ Creature.blockedBySource,Creature.blockingSource | SubAbility$ DBTap
|
SVar:TrigCounter:DB$ PutCounterAll | CounterType$ PARALYZATION | CounterNum$ 1 | ValidCards$ Creature.blockedBySource,Creature.blockingSource | SubAbility$ DBTap
|
||||||
SVar:DBTap:DB$ TapAll | ValidCards$ Creature.blockedBySource,Creature.blockingSource | SubAbility$ DBEffect
|
SVar:DBTap:DB$ TapAll | ValidCards$ Creature.blockedBySource,Creature.blockingSource | SubAbility$ DBEffect
|
||||||
SVar:DBEffect:DB$ Effect | RememberObjects$ Valid Creature.blockedBySource,Valid Creature.blockingSource | StaticAbilities$ DontUntap | Duration$ Permanent | ConditionPresent$ Creature.blockedBySource,Creature.blockingSource | SubAbility$ DBAnimate | ForgetOnMoved$ Battlefield | ForgetCounter$ PARALYZATION
|
SVar:DBEffect:DB$ Effect | RememberObjects$ Valid Creature.blockedBySource,Creature.blockingSource | StaticAbilities$ DontUntap | Duration$ Permanent | ConditionPresent$ Creature.blockedBySource,Creature.blockingSource | SubAbility$ DBAnimate | ForgetOnMoved$ Battlefield | ForgetCounter$ PARALYZATION
|
||||||
SVar:DBAnimate:DB$ AnimateAll | ValidCards$ Creature.blockedBySource,Creature.blockingSource | Abilities$ ABRemoveCounter | Duration$ Permanent
|
SVar:DBAnimate:DB$ AnimateAll | ValidCards$ Creature.blockedBySource,Creature.blockingSource | Abilities$ ABRemoveCounter | Duration$ Permanent
|
||||||
SVar:ABRemoveCounter:AB$ RemoveCounter | Defined$ Self | Cost$ 4 | CounterType$ PARALYZATION | CounterNum$ 1 | SpellDescription$ Remove a paralyzation counter from this creature.
|
SVar:ABRemoveCounter:AB$ RemoveCounter | Defined$ Self | Cost$ 4 | CounterType$ PARALYZATION | CounterNum$ 1 | SpellDescription$ Remove a paralyzation counter from this creature.
|
||||||
SVar:DontUntap:Mode$ Continuous | EffectZone$ Command | AffectedZone$ Battlefield | Affected$ Card.IsRemembered | AddHiddenKeyword$ CARDNAME doesn't untap during your untap step. | Description$ Each of those creatures doesn't untap during its controller's untap step for as long as it has a paralyzation counter on it.
|
SVar:DontUntap:Mode$ Continuous | EffectZone$ Command | AffectedZone$ Battlefield | Affected$ Card.IsRemembered | AddHiddenKeyword$ CARDNAME doesn't untap during your untap step. | Description$ Each of those creatures doesn't untap during its controller's untap step for as long as it has a paralyzation counter on it.
|
||||||
|
|||||||
11
forge-gui/res/cardsfolder/d/druid_of_purification.txt
Normal file
11
forge-gui/res/cardsfolder/d/druid_of_purification.txt
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
Name:Druid of Purification
|
||||||
|
ManaCost:3 G
|
||||||
|
Types:Creature Human Druid
|
||||||
|
PT:2/3
|
||||||
|
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigChoice | TriggerDescription$ When CARDNAME enters the battlefield, starting with you, each player may choose an artifact or enchantment you don’t control. Destroy each permanent chosen this way.
|
||||||
|
SVar:TrigChoice:DB$ RepeatEach | RepeatPlayers$ Player | StartingWithActivator$ True | RepeatSubAbility$ DBChoosePermanent | SubAbility$ DBDestroy
|
||||||
|
SVar:DBChoosePermanent:DB$ ChooseCard | Defined$ Remembered | Choices$ Artifact.YouDontCtrl,Enchantment.YouDontCtrl | Optional$ True | ChoiceTitle$ Choose an artifact or enchantment | RememberChosen$ True
|
||||||
|
SVar:DBDestroy:DB$ Destroy | Defined$ Remembered | SubAbility$ DBCleanup
|
||||||
|
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||||
|
AI:RemoveDeck:Random
|
||||||
|
Oracle:When Druid of Purification enters the battlefield, starting with you, each player may choose an artifact or enchantment you don't control. Destroy each permanent chosen this way.
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user