From 8e1ef15b7027d8463ffbe20c28c8614912db040f Mon Sep 17 00:00:00 2001
From: Susucre <34709007+Susucre@users.noreply.github.com>
Date: Sun, 8 Oct 2023 23:52:36 +0200
Subject: [PATCH] [LCI] Implement Ojer Axonil, Deepest Might (#11195)
* [LCI] Implement Ojer Axonil, Deepest Might
* add tests
* Alter text generation on ActivateIfConditionActivatedAbility to handle "and as a sorcery"
---
.../src/mage/cards/h/HeronBlessedGeist.java | 2 +-
.../mage/cards/o/OjerAxonilDeepestMight.java | 149 ++++++++++++++
.../src/mage/cards/s/SpeakerOfTheHeavens.java | 17 +-
Mage.Sets/src/mage/cards/t/TempleOfPower.java | 157 ++++++++++++++
.../src/mage/sets/LostCavernsOfIxalan.java | 2 +
.../lci/OjerAxonilDeepestMightTest.java | 194 ++++++++++++++++++
.../ActivateIfConditionActivatedAbility.java | 13 +-
7 files changed, 521 insertions(+), 13 deletions(-)
create mode 100644 Mage.Sets/src/mage/cards/o/OjerAxonilDeepestMight.java
create mode 100644 Mage.Sets/src/mage/cards/t/TempleOfPower.java
create mode 100644 Mage.Tests/src/test/java/org/mage/test/cards/single/lci/OjerAxonilDeepestMightTest.java
diff --git a/Mage.Sets/src/mage/cards/h/HeronBlessedGeist.java b/Mage.Sets/src/mage/cards/h/HeronBlessedGeist.java
index d63452acafd..2578da43695 100644
--- a/Mage.Sets/src/mage/cards/h/HeronBlessedGeist.java
+++ b/Mage.Sets/src/mage/cards/h/HeronBlessedGeist.java
@@ -28,7 +28,7 @@ import java.util.UUID;
public final class HeronBlessedGeist extends CardImpl {
private static final Condition condition = new PermanentsOnTheBattlefieldCondition(
- new FilterEnchantmentPermanent("you control an enchantment and only as a sorcery")
+ new FilterEnchantmentPermanent("you control an enchantment")
);
private static final Hint hint = new ConditionHint(condition, "You control an enchantment");
diff --git a/Mage.Sets/src/mage/cards/o/OjerAxonilDeepestMight.java b/Mage.Sets/src/mage/cards/o/OjerAxonilDeepestMight.java
new file mode 100644
index 00000000000..d17fe96fa19
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/o/OjerAxonilDeepestMight.java
@@ -0,0 +1,149 @@
+package mage.cards.o;
+
+import mage.MageInt;
+import mage.MageObject;
+import mage.abilities.Ability;
+import mage.abilities.common.DiesSourceTriggeredAbility;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.ReplacementEffectImpl;
+import mage.abilities.keyword.TrampleAbility;
+import mage.abilities.keyword.TransformAbility;
+import mage.cards.Card;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.game.Game;
+import mage.game.events.DamageEvent;
+import mage.game.events.GameEvent;
+import mage.game.permanent.Permanent;
+import mage.players.Player;
+
+import java.util.UUID;
+
+/**
+ * @author Susucr
+ */
+public final class OjerAxonilDeepestMight extends CardImpl {
+
+ public OjerAxonilDeepestMight(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}{R}");
+ this.secondSideCardClazz = mage.cards.t.TempleOfPower.class;
+
+ this.supertype.add(SuperType.LEGENDARY);
+ this.subtype.add(SubType.GOD);
+ this.power = new MageInt(4);
+ this.toughness = new MageInt(4);
+
+ // Trample
+ this.addAbility(TrampleAbility.getInstance());
+
+ // If a red source you control would deal an amount of noncombat damage less than Ojer Axonil's power to an opponent, that source deals damage equal to Ojer Axonil's power instead.
+ this.addAbility(new SimpleStaticAbility(new OjerAxonilDeepestMightReplacementEffect()));
+
+ // When Ojer Axonil dies, return it to the battlefield tapped and transformed under its owner's control.
+ this.addAbility(new TransformAbility());
+ this.addAbility(new DiesSourceTriggeredAbility(new OjerAxonilDeepestMightTransformEffect()));
+ }
+
+ private OjerAxonilDeepestMight(final OjerAxonilDeepestMight card) {
+ super(card);
+ }
+
+ @Override
+ public OjerAxonilDeepestMight copy() {
+ return new OjerAxonilDeepestMight(this);
+ }
+}
+
+// Inspired by Edgar, Charmed Groom
+class OjerAxonilDeepestMightTransformEffect extends OneShotEffect {
+
+ OjerAxonilDeepestMightTransformEffect() {
+ super(Outcome.Benefit);
+ staticText = "return it to the battlefield tapped and transformed under its owner's control";
+ }
+
+ private OjerAxonilDeepestMightTransformEffect(final OjerAxonilDeepestMightTransformEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public OjerAxonilDeepestMightTransformEffect copy() {
+ return new OjerAxonilDeepestMightTransformEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player controller = game.getPlayer(source.getControllerId());
+ if (controller == null) {
+ return false;
+ }
+ MageObject sourceObject = source.getSourceObjectIfItStillExists(game);
+ if (!(sourceObject instanceof Card)) {
+ return false;
+ }
+ game.getState().setValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE);
+ controller.moveCards((Card) sourceObject, Zone.BATTLEFIELD, source, game, true, false, true, null);
+ return true;
+ }
+}
+
+// Inspired by Torbran, Thane of Red Fell
+class OjerAxonilDeepestMightReplacementEffect extends ReplacementEffectImpl {
+
+ OjerAxonilDeepestMightReplacementEffect() {
+ super(Duration.WhileOnBattlefield, Outcome.Damage);
+ this.staticText = "If a red source you control would deal an amount of noncombat damage less "
+ + "than {this}'s power to an opponent, that source deals damage equal to {this}'s power instead.";
+ }
+
+ private OjerAxonilDeepestMightReplacementEffect(final OjerAxonilDeepestMightReplacementEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public OjerAxonilDeepestMightReplacementEffect copy() {
+ return new OjerAxonilDeepestMightReplacementEffect(this);
+ }
+
+ @Override
+ public boolean replaceEvent(GameEvent event, Ability source, Game game) {
+ Permanent ojer = source.getSourcePermanentIfItStillExists(game);
+ if (ojer != null && ojer.getPower().getValue() > 0) {
+ event.setAmount(ojer.getPower().getValue());
+ }
+ return false;
+ }
+
+ @Override
+ public boolean checksEventType(GameEvent event, Game game) {
+ return event.getType() == GameEvent.EventType.DAMAGE_PLAYER;
+ }
+
+ @Override
+ public boolean applies(GameEvent event, Ability source, Game game) {
+ Player controller = game.getPlayer(source.getControllerId());
+ // Is damage to an opponent?
+ if (controller == null || !controller.hasOpponent(event.getTargetId(), game)) {
+ return false;
+ }
+ MageObject sourceObject;
+ Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(event.getSourceId());
+ if (sourcePermanent == null) {
+ sourceObject = game.getObject(event.getSourceId());
+ } else {
+ sourceObject = sourcePermanent;
+ }
+ Permanent ojer = source.getSourcePermanentIfItStillExists(game);
+ DamageEvent dmgEvent = (DamageEvent) event;
+
+ return sourceObject != null
+ && ojer != null
+ && dmgEvent != null
+ && sourceObject.getColor(game).isRed()
+ && !dmgEvent.isCombatDamage()
+ && event.getAmount() > 0
+ && event.getAmount() < ojer.getPower().getValue();
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/s/SpeakerOfTheHeavens.java b/Mage.Sets/src/mage/cards/s/SpeakerOfTheHeavens.java
index a2e8a69cf5c..7a44172c84e 100644
--- a/Mage.Sets/src/mage/cards/s/SpeakerOfTheHeavens.java
+++ b/Mage.Sets/src/mage/cards/s/SpeakerOfTheHeavens.java
@@ -2,10 +2,9 @@ package mage.cards.s;
import mage.MageInt;
import mage.abilities.Ability;
+import mage.abilities.common.ActivateIfConditionActivatedAbility;
import mage.abilities.condition.Condition;
-import mage.abilities.condition.common.MainPhaseStackEmptyCondition;
import mage.abilities.costs.common.TapSourceCost;
-import mage.abilities.decorator.ConditionalActivatedAbility;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.keyword.LifelinkAbility;
import mage.abilities.keyword.VigilanceAbility;
@@ -13,6 +12,7 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
+import mage.constants.TimingRule;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.permanent.token.AngelToken;
@@ -39,10 +39,11 @@ public final class SpeakerOfTheHeavens extends CardImpl {
// Lifelink
this.addAbility(LifelinkAbility.getInstance());
- // {T}: Create a 4/4 white Angel creature token with flying. Activate this ability only if you have at least 7 more life than your starting life total and only any time you could cast a sorcery.
- this.addAbility(new ConditionalActivatedAbility(
+ // {T}: Create a 4/4 white Angel creature token with flying. Activate only if you have at least 7 more life than your starting life total and only as a sorcery.
+ this.addAbility(new ActivateIfConditionActivatedAbility(
Zone.BATTLEFIELD, new CreateTokenEffect(new AngelToken()),
- new TapSourceCost(), SpeakerOfTheHeavensCondition.instance
+ new TapSourceCost(), SpeakerOfTheHeavensCondition.instance,
+ TimingRule.SORCERY
));
}
@@ -61,10 +62,6 @@ enum SpeakerOfTheHeavensCondition implements Condition {
@Override
public boolean apply(Game game, Ability source) {
- if (!MainPhaseStackEmptyCondition.instance.apply(game, source)
- || !game.isActivePlayer(source.getControllerId())) {
- return false;
- }
Player player = game.getPlayer(source.getControllerId());
if (player == null || player.getLife() < game.getStartingLife() + 7) {
return false;
@@ -74,6 +71,6 @@ enum SpeakerOfTheHeavensCondition implements Condition {
@Override
public String toString() {
- return "you have at least 7 life more than your starting life total and only as a sorcery";
+ return "you have at least 7 life more than your starting life total";
}
}
diff --git a/Mage.Sets/src/mage/cards/t/TempleOfPower.java b/Mage.Sets/src/mage/cards/t/TempleOfPower.java
new file mode 100644
index 00000000000..108d6ce97ee
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/t/TempleOfPower.java
@@ -0,0 +1,157 @@
+package mage.cards.t;
+
+import mage.MageObject;
+import mage.abilities.Ability;
+import mage.abilities.common.ActivateIfConditionActivatedAbility;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.condition.Condition;
+import mage.abilities.costs.common.TapSourceCost;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.effects.common.InfoEffect;
+import mage.abilities.effects.common.TransformSourceEffect;
+import mage.abilities.hint.Hint;
+import mage.abilities.mana.RedManaAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.TimingRule;
+import mage.constants.WatcherScope;
+import mage.constants.Zone;
+import mage.game.Game;
+import mage.game.events.DamagedEvent;
+import mage.game.events.GameEvent;
+import mage.game.permanent.Permanent;
+import mage.game.stack.StackObject;
+import mage.watchers.Watcher;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+/**
+ * @author Susucr
+ */
+public final class TempleOfPower extends CardImpl {
+
+ public TempleOfPower(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
+ this.nightCard = true;
+
+ // (Transforms from Ojer Axonil, Deepest Might.)
+ Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new InfoEffect("(Transforms from Ojer Axonil, Deepest Might.)"));
+ ability.setRuleAtTheTop(true);
+ this.addAbility(ability);
+
+ // {T}: Add {R}.
+ this.addAbility(new RedManaAbility());
+
+ // {2}{R}, {T}: Transform Temple of Power. Activate only if red sources you controlled dealt 4 or more noncombat damage this turn and only as a sorcery.
+ ability = new ActivateIfConditionActivatedAbility(
+ Zone.BATTLEFIELD,
+ new TransformSourceEffect(),
+ new ManaCostsImpl("{2}{R}"),
+ TempleOfPowerCondition.instance,
+ TimingRule.SORCERY
+ );
+ ability.addWatcher(new TempleOfPowerWatcher());
+ ability.addCost(new TapSourceCost());
+ ability.addHint(TempleOfPowerHint.instance);
+ this.addAbility(ability);
+ }
+
+ private TempleOfPower(final TempleOfPower card) {
+ super(card);
+ }
+
+ @Override
+ public TempleOfPower copy() {
+ return new TempleOfPower(this);
+ }
+}
+
+enum TempleOfPowerCondition implements Condition {
+ instance;
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ TempleOfPowerWatcher watcher = game.getState().getWatcher(TempleOfPowerWatcher.class);
+ return watcher != null
+ && 4 <= watcher.damageForPlayer(source.getControllerId());
+ }
+
+ @Override
+ public String toString() {
+ return "if red sources you controlled dealt 4 or more noncombat damage this turn";
+ }
+}
+
+enum TempleOfPowerHint implements Hint {
+ instance;
+
+ @Override
+ public String getText(Game game, Ability ability) {
+ TempleOfPowerWatcher watcher = game.getState().getWatcher(TempleOfPowerWatcher.class);
+ if (watcher == null) {
+ return "";
+ }
+
+ return "Non-combat damage from red source: "
+ + watcher.damageForPlayer(ability.getControllerId());
+ }
+
+ @Override
+ public TempleOfPowerHint copy() {
+ return instance;
+ }
+}
+
+class TempleOfPowerWatcher extends Watcher {
+
+ // player -> total non combat damage from red source controlled by that player dealt this turn.
+ private final Map damageMap = new HashMap<>();
+
+ public TempleOfPowerWatcher() {
+ super(WatcherScope.GAME);
+ }
+
+ @Override
+ public void watch(GameEvent event, Game game) {
+ if (event.getType() == GameEvent.EventType.DAMAGED_PLAYER
+ || event.getType() == GameEvent.EventType.DAMAGED_PERMANENT) {
+ DamagedEvent dmgEvent = (DamagedEvent) event;
+
+ // watch only non combat damage events.
+ if (dmgEvent == null || dmgEvent.isCombatDamage()) {
+ return;
+ }
+
+ MageObject sourceObject;
+ UUID sourceControllerId;
+ Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(event.getSourceId());
+ if (sourcePermanent == null) {
+ sourceObject = game.getSpellOrLKIStack(event.getSourceId());
+ sourceControllerId = ((StackObject) sourceObject).getControllerId();
+ } else {
+ sourceObject = sourcePermanent;
+ sourceControllerId = sourcePermanent.getControllerId();
+ }
+
+ // watch only red sources dealing damage
+ if (sourceObject == null || !sourceObject.getColor().isRed()) {
+ return;
+ }
+
+ damageMap.compute(sourceControllerId, (k, i) -> (i == null ? 0 : i) + event.getAmount());
+ }
+ }
+
+ @Override
+ public void reset() {
+ damageMap.clear();
+ super.reset();
+ }
+
+ int damageForPlayer(UUID playerId) {
+ return damageMap.getOrDefault(playerId, 0);
+ }
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/sets/LostCavernsOfIxalan.java b/Mage.Sets/src/mage/sets/LostCavernsOfIxalan.java
index e881808755f..e2d90bfa7a3 100644
--- a/Mage.Sets/src/mage/sets/LostCavernsOfIxalan.java
+++ b/Mage.Sets/src/mage/sets/LostCavernsOfIxalan.java
@@ -26,7 +26,9 @@ public final class LostCavernsOfIxalan extends ExpansionSet {
cards.add(new SetCardInfo("Ghalta, Stampede Tyrant", 185, Rarity.MYTHIC, mage.cards.g.GhaltaStampedeTyrant.class));
cards.add(new SetCardInfo("Island", 288, Rarity.LAND, mage.cards.basiclands.Island.class, FULL_ART_BFZ_VARIOUS));
cards.add(new SetCardInfo("Mountain", 290, Rarity.LAND, mage.cards.basiclands.Mountain.class, FULL_ART_BFZ_VARIOUS));
+ cards.add(new SetCardInfo("Ojer Axonil, Deepest Might", 317, Rarity.MYTHIC, mage.cards.o.OjerAxonilDeepestMight.class));
cards.add(new SetCardInfo("Plains", 287, Rarity.LAND, mage.cards.basiclands.Plains.class, FULL_ART_BFZ_VARIOUS));
cards.add(new SetCardInfo("Swamp", 289, Rarity.LAND, mage.cards.basiclands.Swamp.class, FULL_ART_BFZ_VARIOUS));
+ cards.add(new SetCardInfo("Temple of Power", 317, Rarity.MYTHIC, mage.cards.t.TempleOfPower.class));
}
}
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/lci/OjerAxonilDeepestMightTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/lci/OjerAxonilDeepestMightTest.java
new file mode 100644
index 00000000000..b3041b950a6
--- /dev/null
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/lci/OjerAxonilDeepestMightTest.java
@@ -0,0 +1,194 @@
+
+package org.mage.test.cards.single.lci;
+
+import mage.constants.PhaseStep;
+import mage.constants.Zone;
+import org.junit.Test;
+import org.mage.test.serverside.base.CardTestPlayerBase;
+
+/**
+ *
+ * @author Susucr
+ */
+public class OjerAxonilDeepestMightTest extends CardTestPlayerBase {
+
+ /**
+ * Ojer Axonil, Deepest Might
+ * {2}{R}{R}
+ * Legendary Creature — God
+ *
+ * Trample
+ * If a red source you control would deal an amount of noncombat damage less than Ojer Axonil’s power to an opponent, that source deals damage equal to Ojer Axonil’s power instead.
+ * When Ojer Axonil dies, return it to the battlefield tapped and transformed under its owner’s control.
+ * 4/4
+ *
+ * Temple of Power
+ * Land
+ *
+ * (Transforms from Ojer Axonil, Deepest Might.)
+ * {T}: Add {R}.
+ * {2}{R}, {T}: Transform Temple of Power. Activate only if red sources you controlled dealt 4 or more noncombat damage this turn and only as a sorcery.
+ */
+ private static final String ojer = "Ojer Axonil, Deepest Might";
+ private static final String temple = "Temple of Power";
+ private static final String templeTransformAbility = "{2}{R}, {T}: Transform {this}. Activate only if red sources you controlled dealt 4 or more noncombat damage this turn and only as a sorcery.";
+
+ /**
+ * Lightning Bolt
+ * {R}
+ * Instant
+ *
+ * Lightning Bolt deals 3 damage to any target.
+ */
+ private static final String bolt = "Lightning Bolt";
+ /**
+ * Lava Axe
+ * {4}{R}
+ * Sorcery
+ *
+ * Lava Axe deals 5 damage to target player or planeswalker.
+ */
+ private static final String axe = "Lava Axe";
+
+ @Test
+ public void testReplacement_BoltFace() {
+ setStrictChooseMode(true);
+
+ addCard(Zone.BATTLEFIELD, playerA, ojer, 1);
+ addCard(Zone.HAND, playerA, bolt, 1);
+ addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1);
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, bolt, playerB);
+
+ setStopAt(1, PhaseStep.BEGIN_COMBAT);
+ execute();
+
+ assertLife(playerB, 20 - 4);
+ }
+
+ @Test
+ public void testReplacement_BoltOwnFace() {
+ setStrictChooseMode(true);
+
+ addCard(Zone.BATTLEFIELD, playerA, ojer, 1);
+ addCard(Zone.HAND, playerA, bolt, 1);
+ addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1);
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, bolt, playerA);
+
+ setStopAt(1, PhaseStep.BEGIN_COMBAT);
+ execute();
+
+ assertLife(playerA, 20 - 3); // only work on opponnent
+ }
+
+ @Test
+ public void testReplacement_BoltOjer() {
+ setStrictChooseMode(true);
+
+ addCard(Zone.BATTLEFIELD, playerA, ojer, 1);
+ addCard(Zone.HAND, playerA, bolt, 1);
+ addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1);
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, bolt, ojer);
+
+ setStopAt(1, PhaseStep.BEGIN_COMBAT);
+ execute();
+
+ assertDamageReceived(playerA, ojer, 3); // does not work on creatures
+ }
+
+ @Test
+ public void testReplacement_CombatDamageNotReplaced() {
+ setStrictChooseMode(true);
+
+ addCard(Zone.BATTLEFIELD, playerA, ojer, 1);
+ addCard(Zone.BATTLEFIELD, playerA, "Raging Goblin", 1);
+
+ attack(1, playerA, "Raging Goblin", playerB);
+
+ setStopAt(1, PhaseStep.END_COMBAT);
+ execute();
+
+ assertLife(playerB, 20 - 1); // does not alter combat damage
+ }
+
+ @Test
+ public void testReplacement_Hellrider() {
+ setStrictChooseMode(true);
+
+ addCard(Zone.BATTLEFIELD, playerA, ojer, 1);
+ // Whenever a creature you control attacks, Hellrider deals 1 damage to the player or planeswalker it’s attacking.
+ addCard(Zone.BATTLEFIELD, playerA, "Hellrider", 1);
+ addCard(Zone.BATTLEFIELD, playerA, "Raging Goblin", 1);
+
+ attack(1, playerA, "Raging Goblin", playerB);
+
+ setStopAt(1, PhaseStep.END_COMBAT);
+ execute();
+
+ assertLife(playerB, 20 - 1 - 4); // Hellrider's trigger is altered.
+ }
+
+ @Test
+ public void testReplacement_LavaAxeFace() {
+ setStrictChooseMode(true);
+
+ addCard(Zone.BATTLEFIELD, playerA, ojer, 1);
+ addCard(Zone.HAND, playerA, axe, 1);
+ addCard(Zone.BATTLEFIELD, playerA, "Mountain", 5);
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, axe, playerB);
+
+ setStopAt(1, PhaseStep.BEGIN_COMBAT);
+ execute();
+
+ assertLife(playerB, 20 - 5); // no replacement
+ }
+
+ @Test
+ public void testReplacement_GiantGrowth_LavaAxeFace() {
+ setStrictChooseMode(true);
+
+ addCard(Zone.BATTLEFIELD, playerA, ojer, 1);
+ addCard(Zone.HAND, playerA, axe, 1);
+ addCard(Zone.HAND, playerA, "Giant Growth", 1); // +3/+3 until end of turn
+ addCard(Zone.BATTLEFIELD, playerA, "Taiga", 6);
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, axe, playerB);
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Giant Growth", ojer);
+
+ setStopAt(1, PhaseStep.BEGIN_COMBAT);
+ execute();
+
+ assertLife(playerB, 20 - (4 + 3));
+ }
+
+ @Test
+ public void testTransform() {
+ setStrictChooseMode(true);
+
+ addCard(Zone.BATTLEFIELD, playerA, ojer, 1);
+ addCard(Zone.HAND, playerA, axe, 1);
+ addCard(Zone.HAND, playerA, "Bathe in Dragonfire", 1); // 4 damage to target creature
+ addCard(Zone.BATTLEFIELD, playerA, "Battlefield Forge", 5 + 3); // Using Forge to distinguish the mana ability from the Temple one.
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Bathe in Dragonfire", ojer, true);
+ checkPermanentTapped("temple in play", 1, PhaseStep.PRECOMBAT_MAIN, playerA, temple, true, 1);
+
+ checkPlayableAbility("condition false", 3, PhaseStep.PRECOMBAT_MAIN, playerA, templeTransformAbility, false);
+ activateManaAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {R}. {this} deals 1 damage to you.", 5);
+ castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerA, axe, playerB);
+ waitStackResolved(3, PhaseStep.PRECOMBAT_MAIN);
+ activateManaAbility(3, PhaseStep.POSTCOMBAT_MAIN, playerA, "{T}: Add {R}. {this} deals 1 damage to you.", 3);
+ checkPlayableAbility("condition true", 3, PhaseStep.POSTCOMBAT_MAIN, playerA, templeTransformAbility, true);
+ activateAbility(3, PhaseStep.POSTCOMBAT_MAIN, playerA, templeTransformAbility);
+
+ setStopAt(3, PhaseStep.END_TURN);
+ execute();
+
+ assertLife(playerB, 20 - 5);
+ assertPermanentCount(playerA, ojer, 1);
+ assertTapped(ojer, true);
+ }
+}
diff --git a/Mage/src/main/java/mage/abilities/common/ActivateIfConditionActivatedAbility.java b/Mage/src/main/java/mage/abilities/common/ActivateIfConditionActivatedAbility.java
index 35243e7218f..31eae736390 100644
--- a/Mage/src/main/java/mage/abilities/common/ActivateIfConditionActivatedAbility.java
+++ b/Mage/src/main/java/mage/abilities/common/ActivateIfConditionActivatedAbility.java
@@ -6,6 +6,7 @@ import mage.abilities.condition.Condition;
import mage.abilities.condition.InvertCondition;
import mage.abilities.costs.Cost;
import mage.abilities.effects.Effect;
+import mage.constants.TimingRule;
import mage.constants.Zone;
import mage.game.Game;
@@ -13,10 +14,14 @@ import mage.game.Game;
* @author LevelX2
*/
public class ActivateIfConditionActivatedAbility extends ActivatedAbilityImpl {
-
public ActivateIfConditionActivatedAbility(Zone zone, Effect effect, Cost cost, Condition condition) {
+ this(zone, effect, cost, condition, TimingRule.INSTANT);
+ }
+
+ public ActivateIfConditionActivatedAbility(Zone zone, Effect effect, Cost cost, Condition condition, TimingRule timing) {
super(zone, effect, cost);
this.condition = condition;
+ this.timing = timing;
}
protected ActivateIfConditionActivatedAbility(final ActivateIfConditionActivatedAbility ability) {
@@ -41,7 +46,11 @@ public class ActivateIfConditionActivatedAbility extends ActivatedAbilityImpl {
&& !condition.toString().startsWith("if")) {
sb.append("if ");
}
- sb.append(condition.toString()).append('.');
+ sb.append(condition.toString());
+ if (timing == TimingRule.SORCERY) {
+ sb.append(" and only as a sorcery");
+ }
+ sb.append('.');
return sb.toString();
}