From f55bf4691d1af32473f2026f2913bc1d568493b8 Mon Sep 17 00:00:00 2001 From: Hans Mackowiak Date: Fri, 15 Aug 2025 09:24:45 +0200 Subject: [PATCH] TLA: Earthbend (#8386) --- .../forge/game/ability/AbilityApiBased.java | 10 +-- .../forge/game/ability/AbilityFactory.java | 9 -- .../main/java/forge/game/ability/ApiType.java | 1 + .../game/ability/SpellAbilityEffect.java | 2 + .../forge/game/ability/SpellApiBased.java | 9 +- .../game/ability/StaticAbilityApiBased.java | 6 +- .../ability/effects/ChangeTargetsEffect.java | 8 ++ .../ability/effects/ChangeZoneAllEffect.java | 7 ++ .../ability/effects/ChangeZoneEffect.java | 6 ++ .../ability/effects/ControlSpellEffect.java | 9 ++ .../effects/CopySpellAbilityEffect.java | 6 ++ .../game/ability/effects/CounterEffect.java | 7 ++ .../game/ability/effects/EarthbendEffect.java | 88 +++++++++++++++++++ .../game/ability/effects/ManaEffect.java | 8 ++ .../ability/effects/ManaReflectedEffect.java | 8 ++ .../forge/game/spellability/AbilitySub.java | 9 +- .../forge/game/spellability/SpellAbility.java | 2 +- .../game/spellability/TargetRestrictions.java | 2 +- .../game/trigger/TriggerElementalbend.java | 36 ++++++++ .../java/forge/game/trigger/TriggerType.java | 1 + .../upcoming/earthbending_lesson.txt | 5 ++ 21 files changed, 198 insertions(+), 41 deletions(-) create mode 100644 forge-game/src/main/java/forge/game/ability/effects/EarthbendEffect.java create mode 100644 forge-game/src/main/java/forge/game/trigger/TriggerElementalbend.java create mode 100644 forge-gui/res/cardsfolder/upcoming/earthbending_lesson.txt diff --git a/forge-game/src/main/java/forge/game/ability/AbilityApiBased.java b/forge-game/src/main/java/forge/game/ability/AbilityApiBased.java index e65ef5006f2..3acc345fdad 100644 --- a/forge-game/src/main/java/forge/game/ability/AbilityApiBased.java +++ b/forge-game/src/main/java/forge/game/ability/AbilityApiBased.java @@ -3,7 +3,6 @@ package forge.game.ability; import forge.game.card.Card; import forge.game.cost.Cost; import forge.game.spellability.AbilityActivated; -import forge.game.spellability.AbilityManaPart; import forge.game.spellability.TargetRestrictions; import java.util.Map; @@ -18,14 +17,7 @@ public class AbilityApiBased extends AbilityActivated { api = api0; effect = api.getSpellEffect(); - if (api.equals(ApiType.Mana) || api.equals(ApiType.ManaReflected)) { - this.setManaPart(new AbilityManaPart(this, mapParams)); - this.setUndoable(true); // will try at least - } - - if (api.equals(ApiType.ChangeZone) || api.equals(ApiType.ChangeZoneAll)) { - AbilityFactory.adjustChangeZoneTarget(mapParams, this); - } + effect.buildSpellAbility(this); } @Override diff --git a/forge-game/src/main/java/forge/game/ability/AbilityFactory.java b/forge-game/src/main/java/forge/game/ability/AbilityFactory.java index f0bf5c2cc84..4b452a7620c 100644 --- a/forge-game/src/main/java/forge/game/ability/AbilityFactory.java +++ b/forge-game/src/main/java/forge/game/ability/AbilityFactory.java @@ -202,15 +202,6 @@ public final class AbilityFactory { final Card hostCard = state.getCard(); TargetRestrictions abTgt = mapParams.containsKey("ValidTgts") ? readTarget(mapParams) : null; - if (api == ApiType.CopySpellAbility || api == ApiType.Counter || api == ApiType.ChangeTargets || api == ApiType.ControlSpell) { - // Since all "CopySpell" ABs copy things on the Stack no need for it to be everywhere - // Since all "Counter" or "ChangeTargets" abilities only target the Stack Zone - // No need to have each of those scripts have that info - if (abTgt != null) { - abTgt.setZone(ZoneType.Stack); - } - } - if (abCost == null) { abCost = parseAbilityCost(state, mapParams, type); } diff --git a/forge-game/src/main/java/forge/game/ability/ApiType.java b/forge-game/src/main/java/forge/game/ability/ApiType.java index db71881a254..1093655d647 100644 --- a/forge-game/src/main/java/forge/game/ability/ApiType.java +++ b/forge-game/src/main/java/forge/game/ability/ApiType.java @@ -81,6 +81,7 @@ public enum ApiType { Draft (DraftEffect.class), Draw (DrawEffect.class), EachDamage (DamageEachEffect.class), + Earthbend (EarthbendEffect.class), Effect (EffectEffect.class), Encode (EncodeEffect.class), EndCombatPhase (EndCombatPhaseEffect.class), diff --git a/forge-game/src/main/java/forge/game/ability/SpellAbilityEffect.java b/forge-game/src/main/java/forge/game/ability/SpellAbilityEffect.java index 506a6983e4c..96bc1c9c6e1 100644 --- a/forge-game/src/main/java/forge/game/ability/SpellAbilityEffect.java +++ b/forge-game/src/main/java/forge/game/ability/SpellAbilityEffect.java @@ -49,6 +49,8 @@ public abstract class SpellAbilityEffect { return sa.getDescription(); } + public void buildSpellAbility(final SpellAbility sa) {} + /** * Returns this effect description with needed prelude and epilogue. * @param params diff --git a/forge-game/src/main/java/forge/game/ability/SpellApiBased.java b/forge-game/src/main/java/forge/game/ability/SpellApiBased.java index 0bba72f13c2..8fe9f3ec5fc 100644 --- a/forge-game/src/main/java/forge/game/ability/SpellApiBased.java +++ b/forge-game/src/main/java/forge/game/ability/SpellApiBased.java @@ -4,7 +4,6 @@ import java.util.Map; import forge.game.card.Card; import forge.game.cost.Cost; -import forge.game.spellability.AbilityManaPart; import forge.game.spellability.Spell; import forge.game.spellability.TargetRestrictions; @@ -24,13 +23,7 @@ public class SpellApiBased extends Spell { // A spell is always intrinsic this.setIntrinsic(true); - if (api.equals(ApiType.Mana) || api.equals(ApiType.ManaReflected)) { - this.setManaPart(new AbilityManaPart(this, mapParams)); - } - - if (api.equals(ApiType.ChangeZone) || api.equals(ApiType.ChangeZoneAll)) { - AbilityFactory.adjustChangeZoneTarget(mapParams, this); - } + effect.buildSpellAbility(this); } @Override diff --git a/forge-game/src/main/java/forge/game/ability/StaticAbilityApiBased.java b/forge-game/src/main/java/forge/game/ability/StaticAbilityApiBased.java index 33a3b2e7b91..09f2e10b84d 100644 --- a/forge-game/src/main/java/forge/game/ability/StaticAbilityApiBased.java +++ b/forge-game/src/main/java/forge/game/ability/StaticAbilityApiBased.java @@ -2,8 +2,6 @@ package forge.game.ability; import java.util.Map; -import forge.game.ability.effects.ChangeZoneAllEffect; -import forge.game.ability.effects.ChangeZoneEffect; import forge.game.card.Card; import forge.game.cost.Cost; import forge.game.spellability.AbilityStatic; @@ -20,9 +18,7 @@ public class StaticAbilityApiBased extends AbilityStatic { api = api0; effect = api.getSpellEffect(); - if (effect instanceof ChangeZoneEffect || effect instanceof ChangeZoneAllEffect) { - AbilityFactory.adjustChangeZoneTarget(mapParams, this); - } + effect.buildSpellAbility(this); } @Override diff --git a/forge-game/src/main/java/forge/game/ability/effects/ChangeTargetsEffect.java b/forge-game/src/main/java/forge/game/ability/effects/ChangeTargetsEffect.java index ef463bd6baa..66ef7c5e14d 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/ChangeTargetsEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/ChangeTargetsEffect.java @@ -18,6 +18,7 @@ import forge.game.spellability.SpellAbility; import forge.game.spellability.SpellAbilityStackInstance; import forge.game.spellability.TargetChoices; import forge.game.zone.MagicStack; +import forge.game.zone.ZoneType; import forge.util.Aggregates; import forge.util.Localizer; @@ -27,6 +28,13 @@ import forge.util.Localizer; */ public class ChangeTargetsEffect extends SpellAbilityEffect { + @Override + public void buildSpellAbility(SpellAbility sa) { + if (sa.usesTargeting()) { + sa.getTargetRestrictions().setZone(ZoneType.Stack); + } + } + /* (non-Javadoc) * @see forge.card.ability.SpellAbilityEffect#resolve(forge.card.spellability.SpellAbility) */ diff --git a/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneAllEffect.java b/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneAllEffect.java index c658d2cfd43..d1ef2dc8ec4 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneAllEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneAllEffect.java @@ -7,6 +7,7 @@ import com.google.common.collect.Iterables; import forge.game.Game; import forge.game.GameActionUtil; import forge.game.GameEntityCounterTable; +import forge.game.ability.AbilityFactory; import forge.game.ability.AbilityKey; import forge.game.ability.AbilityUtils; import forge.game.ability.SpellAbilityEffect; @@ -21,6 +22,12 @@ import forge.util.Localizer; import forge.util.TextUtil; public class ChangeZoneAllEffect extends SpellAbilityEffect { + + @Override + public void buildSpellAbility(SpellAbility sa) { + AbilityFactory.adjustChangeZoneTarget(sa.getMapParams(), sa); + } + @Override protected String getStackDescription(SpellAbility sa) { // TODO build Stack Description will need expansion as more cards are added diff --git a/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneEffect.java b/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneEffect.java index b7d8ac7b671..a62e31e631d 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneEffect.java @@ -6,6 +6,7 @@ import com.google.common.collect.Maps; import forge.card.CardStateName; import forge.card.CardType; import forge.game.*; +import forge.game.ability.AbilityFactory; import forge.game.ability.AbilityKey; import forge.game.ability.AbilityUtils; import forge.game.ability.SpellAbilityEffect; @@ -34,6 +35,11 @@ import java.util.Map; public class ChangeZoneEffect extends SpellAbilityEffect { + @Override + public void buildSpellAbility(SpellAbility sa) { + AbilityFactory.adjustChangeZoneTarget(sa.getMapParams(), sa); + } + @Override protected String getStackDescription(SpellAbility sa) { if (sa.isHidden()) { diff --git a/forge-game/src/main/java/forge/game/ability/effects/ControlSpellEffect.java b/forge-game/src/main/java/forge/game/ability/effects/ControlSpellEffect.java index bb0e866f08b..e7aa100d75c 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/ControlSpellEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/ControlSpellEffect.java @@ -10,8 +10,17 @@ import forge.game.card.Card; import forge.game.player.Player; import forge.game.spellability.SpellAbility; import forge.game.spellability.SpellAbilityStackInstance; +import forge.game.zone.ZoneType; public class ControlSpellEffect extends SpellAbilityEffect { + + @Override + public void buildSpellAbility(SpellAbility sa) { + if (sa.usesTargeting()) { + sa.getTargetRestrictions().setZone(ZoneType.Stack); + } + } + /* (non-Javadoc) * @see forge.card.abilityfactory.SpellEffect#getStackDescription(java.util.Map, forge.card.spellability.SpellAbility) */ diff --git a/forge-game/src/main/java/forge/game/ability/effects/CopySpellAbilityEffect.java b/forge-game/src/main/java/forge/game/ability/effects/CopySpellAbilityEffect.java index e0db5eb1045..5c675bd0a63 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/CopySpellAbilityEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/CopySpellAbilityEffect.java @@ -23,6 +23,12 @@ import java.util.Map; public class CopySpellAbilityEffect extends SpellAbilityEffect { + @Override + public void buildSpellAbility(SpellAbility sa) { + if (sa.usesTargeting()) { + sa.getTargetRestrictions().setZone(ZoneType.Stack); + } + } @Override protected String getStackDescription(SpellAbility sa) { diff --git a/forge-game/src/main/java/forge/game/ability/effects/CounterEffect.java b/forge-game/src/main/java/forge/game/ability/effects/CounterEffect.java index 5d9e9a54bc6..64a2f2bc5aa 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/CounterEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/CounterEffect.java @@ -21,6 +21,13 @@ import java.util.List; import java.util.Map; public class CounterEffect extends SpellAbilityEffect { + @Override + public void buildSpellAbility(SpellAbility sa) { + if (sa.usesTargeting()) { + sa.getTargetRestrictions().setZone(ZoneType.Stack); + } + } + @Override protected String getStackDescription(SpellAbility sa) { final StringBuilder sb = new StringBuilder(); diff --git a/forge-game/src/main/java/forge/game/ability/effects/EarthbendEffect.java b/forge-game/src/main/java/forge/game/ability/effects/EarthbendEffect.java new file mode 100644 index 00000000000..ca7ed1e54a0 --- /dev/null +++ b/forge-game/src/main/java/forge/game/ability/effects/EarthbendEffect.java @@ -0,0 +1,88 @@ +package forge.game.ability.effects; + +import java.util.Arrays; +import java.util.EnumSet; + +import forge.card.RemoveType; +import forge.game.Game; +import forge.game.GameEntityCounterTable; +import forge.game.ability.AbilityFactory; +import forge.game.ability.AbilityKey; +import forge.game.ability.AbilityUtils; +import forge.game.ability.SpellAbilityEffect; +import forge.game.card.Card; +import forge.game.card.CardCopyService; +import forge.game.card.CounterEnumType; +import forge.game.player.Player; +import forge.game.spellability.SpellAbility; +import forge.game.spellability.TargetRestrictions; +import forge.game.trigger.Trigger; +import forge.game.trigger.TriggerHandler; +import forge.game.trigger.TriggerType; +import forge.util.Lang; + +public class EarthbendEffect extends SpellAbilityEffect { + + @Override + protected String getStackDescription(SpellAbility sa) { + final StringBuilder sb = new StringBuilder("Earthbend "); + final Card card = sa.getHostCard(); + final int amount = AbilityUtils.calculateAmount(card, sa.getParamOrDefault("Num", "1"), sa); + + sb.append(amount).append(". (Target land you control becomes a 0/0 creature with haste that’s still a land. Put "); + sb.append(Lang.nounWithNumeral(amount, "+1/+1 counter")); + sb.append(" on it. When it dies or is exiled, return it to the battlefield tapped.)"); + + return sb.toString(); + } + + @Override + public void buildSpellAbility(final SpellAbility sa) { + TargetRestrictions abTgt = new TargetRestrictions("Select target land you control", "Land.YouCtrl".split(","), "1", "1"); + sa.setTargetRestrictions(abTgt); + } + @Override + public void resolve(SpellAbility sa) { + final Card source = sa.getHostCard(); + final Game game = source.getGame(); + final Player pl = sa.getActivatingPlayer(); + int num = AbilityUtils.calculateAmount(source, sa.getParamOrDefault("Num", "1"), sa); + + long ts = game.getNextTimestamp(); + + String desc = "When it dies or is exiled, return it to the battlefield tapped."; + String sbTrigA = "Mode$ ChangesZone | ValidCard$ Card.IsTriggerRemembered | Origin$ Battlefield | Destination$ Graveyard | TriggerDescription$ " + desc; + String sbTrigB = "Mode$ Exiled | Origin$ Battlefield | ValidCard$ Card.IsTriggerRemembered | TriggerZones$ Battlefield | TriggerDescription$ " + desc; + + // Earthbend should only target one land + for (Card c : getTargetCards(sa)) { + c.addNewPT(0, 0, ts, 0); + c.addChangedCardTypes(Arrays.asList("Creature"), null, false, EnumSet.noneOf(RemoveType.class), ts, 0, true, false); + c.addChangedCardKeywords(Arrays.asList("Haste"), null, false, ts, null); + + GameEntityCounterTable table = new GameEntityCounterTable(); + c.addCounter(CounterEnumType.P1P1, num, pl, table); + table.replaceCounterEffect(game, sa, true); + + buildTrigger(sa, c, sbTrigA, "Graveyard"); + buildTrigger(sa, c, sbTrigB, "Exile"); + } + game.getTriggerHandler().runTrigger(TriggerType.Earthbend, AbilityKey.mapFromPlayer(pl), false); + } + + protected void buildTrigger(SpellAbility sa, Card c, String sbTrig, String zone) { + final Card source = sa.getHostCard(); + final Game game = source.getGame(); + String trigSA = "DB$ ChangeZone | Defined$ DelayTriggerRemembered | Origin$ " + zone + " | Destination$ Battlefield | Tapped$ True"; + + final Trigger trig = TriggerHandler.parseTrigger(sbTrig, CardCopyService.getLKICopy(source), sa.isIntrinsic()); + final SpellAbility newSa = AbilityFactory.getAbility(trigSA, sa.getHostCard()); + newSa.setIntrinsic(sa.isIntrinsic()); + trig.addRemembered(c); + trig.setOverridingAbility(newSa); + trig.setSpawningAbility(sa.copy(sa.getHostCard(), true)); + trig.setKeyword(trig.getSpawningAbility().getKeyword()); + + game.getTriggerHandler().registerDelayedTrigger(trig); + } +} diff --git a/forge-game/src/main/java/forge/game/ability/effects/ManaEffect.java b/forge-game/src/main/java/forge/game/ability/effects/ManaEffect.java index b5b99aaa103..83a389666f1 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/ManaEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/ManaEffect.java @@ -29,6 +29,14 @@ import io.sentry.Sentry; public class ManaEffect extends SpellAbilityEffect { + @Override + public void buildSpellAbility(SpellAbility sa) { + sa.setManaPart(new AbilityManaPart(sa, sa.getMapParams())); + if (sa.getParent() == null) { + sa.setUndoable(true); // will try at least + } + } + @Override public void resolve(SpellAbility sa) { final Card card = sa.getHostCard(); diff --git a/forge-game/src/main/java/forge/game/ability/effects/ManaReflectedEffect.java b/forge-game/src/main/java/forge/game/ability/effects/ManaReflectedEffect.java index caf78c90520..fc8a0203f35 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/ManaReflectedEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/ManaReflectedEffect.java @@ -17,6 +17,14 @@ import forge.util.Localizer; public class ManaReflectedEffect extends SpellAbilityEffect { + @Override + public void buildSpellAbility(SpellAbility sa) { + sa.setManaPart(new AbilityManaPart(sa, sa.getMapParams())); + if (sa.getParent() == null) { + sa.setUndoable(true); // will try at least + } + } + /* (non-Javadoc) * @see forge.card.abilityfactory.SpellEffect#resolve(java.util.Map, forge.card.spellability.SpellAbility) */ diff --git a/forge-game/src/main/java/forge/game/spellability/AbilitySub.java b/forge-game/src/main/java/forge/game/spellability/AbilitySub.java index 01fcb68e35d..76d1b1184cc 100644 --- a/forge-game/src/main/java/forge/game/spellability/AbilitySub.java +++ b/forge-game/src/main/java/forge/game/spellability/AbilitySub.java @@ -22,7 +22,6 @@ import java.util.List; import com.google.common.collect.Lists; import forge.game.IHasSVars; -import forge.game.ability.AbilityFactory; import forge.game.ability.ApiType; import forge.game.ability.SpellAbilityEffect; import forge.game.card.Card; @@ -87,13 +86,7 @@ public final class AbilitySub extends SpellAbility implements java.io.Serializab effect = api.getSpellEffect(); - if (api.equals(ApiType.Mana) || api.equals(ApiType.ManaReflected)) { - this.setManaPart(new AbilityManaPart(this, mapParams)); - } - - if (api.equals(ApiType.ChangeZone) || api.equals(ApiType.ChangeZoneAll)) { - AbilityFactory.adjustChangeZoneTarget(mapParams, this); - } + effect.buildSpellAbility(this); } @Override diff --git a/forge-game/src/main/java/forge/game/spellability/SpellAbility.java b/forge-game/src/main/java/forge/game/spellability/SpellAbility.java index b40c225a71e..12cc7fb1b68 100644 --- a/forge-game/src/main/java/forge/game/spellability/SpellAbility.java +++ b/forge-game/src/main/java/forge/game/spellability/SpellAbility.java @@ -415,7 +415,7 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit return false; } - protected final void setManaPart(AbilityManaPart manaPart0) { + public final void setManaPart(AbilityManaPart manaPart0) { manaPart = manaPart0; } diff --git a/forge-game/src/main/java/forge/game/spellability/TargetRestrictions.java b/forge-game/src/main/java/forge/game/spellability/TargetRestrictions.java index 299a3837a5c..0c5f6209adc 100644 --- a/forge-game/src/main/java/forge/game/spellability/TargetRestrictions.java +++ b/forge-game/src/main/java/forge/game/spellability/TargetRestrictions.java @@ -289,7 +289,7 @@ public class TargetRestrictions { */ public final boolean isMinTargetsChosen(final Card c, final SpellAbility sa) { int min = getMinTargets(c, sa); - if (min == 0 || (sa.isDividedAsYouChoose() && ObjectUtils.defaultIfNull(sa.getDividedValue(), 0) == 0)) { + if (min == 0 || (sa.isDividedAsYouChoose() && ObjectUtils.getIfNull(sa.getDividedValue(), 0) == 0)) { return true; } return min <= sa.getTargets().size(); diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerElementalbend.java b/forge-game/src/main/java/forge/game/trigger/TriggerElementalbend.java new file mode 100644 index 00000000000..dc3acbb3362 --- /dev/null +++ b/forge-game/src/main/java/forge/game/trigger/TriggerElementalbend.java @@ -0,0 +1,36 @@ +package forge.game.trigger; + +import java.util.Map; + +import forge.game.ability.AbilityKey; +import forge.game.card.Card; +import forge.game.spellability.SpellAbility; +import forge.util.Localizer; + +public class TriggerElementalbend extends Trigger { + + public TriggerElementalbend(final Map params, final Card host, final boolean intrinsic) { + super(params, host, intrinsic); + } + + @Override + public boolean performTest(Map runParams) { + if (!matchesValidParam("ValidPlayer", runParams.get(AbilityKey.Player))) { + return false; + } + return true; + } + + @Override + public void setTriggeringObjects(SpellAbility sa, Map runParams) { + sa.setTriggeringObjectsFrom(runParams, AbilityKey.Player); + } + + @Override + public String getImportantStackObjects(SpellAbility sa) { + StringBuilder sb = new StringBuilder(); + sb.append(Localizer.getInstance().getMessage("lblPlayer")).append(": ").append(sa.getTriggeringObject(AbilityKey.Player)); + return sb.toString(); + } + +} diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerType.java b/forge-game/src/main/java/forge/game/trigger/TriggerType.java index 7e97480d4b1..b3a5804a545 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerType.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerType.java @@ -74,6 +74,7 @@ public enum TriggerType { Discover(TriggerDiscover.class), Drawn(TriggerDrawn.class), DungeonCompleted(TriggerCompletedDungeon.class), + Earthbend(TriggerElementalbend.class), Evolved(TriggerEvolved.class), ExcessDamage(TriggerExcessDamage.class), ExcessDamageAll(TriggerExcessDamageAll.class), diff --git a/forge-gui/res/cardsfolder/upcoming/earthbending_lesson.txt b/forge-gui/res/cardsfolder/upcoming/earthbending_lesson.txt new file mode 100644 index 00000000000..195d6aef594 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/earthbending_lesson.txt @@ -0,0 +1,5 @@ +Name:Earthbending Lesson +ManaCost:3 G +Types:Sorcery Lesson +A:SP$ Earthbend | Num$ 4 | SpellDescription$ Earthbend 4. (Target land you control becomes a 0/0 creature with haste that’s still a land. Put four +1/+1 counters on it. When it dies or is exiled, return it to the battlefield tapped.) +Oracle:Earthbend 4. (Target land you control becomes a 0/0 creature with haste that’s still a land. Put four +1/+1 counters on it. When it dies or is exiled, return it to the battlefield tapped.)