diff --git a/Mage.Sets/src/mage/cards/t/TadeasJuniperAscendant.java b/Mage.Sets/src/mage/cards/t/TadeasJuniperAscendant.java index e58f02651b2d..2bbb6568cdae 100644 --- a/Mage.Sets/src/mage/cards/t/TadeasJuniperAscendant.java +++ b/Mage.Sets/src/mage/cards/t/TadeasJuniperAscendant.java @@ -1,10 +1,9 @@ package mage.cards.t; import mage.MageInt; -import mage.MageObjectReference; import mage.abilities.Ability; -import mage.abilities.TriggeredAbilityImpl; import mage.abilities.common.AttacksCreatureYouControlTriggeredAbility; +import mage.abilities.common.DealCombatDamageControlledTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.condition.Condition; import mage.abilities.condition.InvertCondition; @@ -22,12 +21,9 @@ import mage.filter.common.FilterControlledCreaturePermanent; import mage.filter.predicate.mageobject.AbilityPredicate; import mage.game.Game; -import mage.game.events.DamagedPlayerEvent; -import mage.game.events.GameEvent; import mage.game.permanent.Permanent; +import mage.target.targetpointer.TargetPointer; -import java.util.HashSet; -import java.util.Set; import java.util.UUID; /** @@ -55,19 +51,21 @@ public TadeasJuniperAscendant(UUID ownerId, CardSetInfo setInfo) { // Reach this.addAbility(ReachAbility.getInstance()); - // Teleport—Dhalsim, Pliable Pacifist has hexproof unless he's attacking. + // Tadeas has hexproof unless it's attacking. this.addAbility(new SimpleStaticAbility(new ConditionalContinuousEffect( new GainAbilitySourceEffect(HexproofAbility.getInstance()), condition, "{this} has hexproof unless he's attacking" - )).withFlavorWord("Teleport")); + ))); // Whenever a creature you control with reach attacks, untap it and it can't be blocked by creatures with greater power this combat. this.addAbility(new AttacksCreatureYouControlTriggeredAbility( new TadeasJuniperAscendantEffect(), false, filter, true )); - // Fierce Punch—Whenever one or more creatures you control deal combat damage to a player, draw a card. - this.addAbility(new TadeasJuniperAscendantTriggeredAbility()); + // Whenever one or more creatures you control deal combat damage to a player, draw a card. + this.addAbility(new DealCombatDamageControlledTriggeredAbility( + new DrawCardSourceControllerEffect(1) + )); } private TadeasJuniperAscendant(final TadeasJuniperAscendant card) { @@ -103,92 +101,34 @@ public boolean apply(Game game, Ability source) { return false; } permanent.untap(game); - game.addEffect(new TadeasJuniperAscendantBlockEffect(permanent, game), source); + game.addEffect(new TadeasJuniperAscendantEvasionEffect(getTargetPointer()), source); return true; } } -class TadeasJuniperAscendantBlockEffect extends RestrictionEffect { - - private final MageObjectReference mor; +class TadeasJuniperAscendantEvasionEffect extends RestrictionEffect { - TadeasJuniperAscendantBlockEffect(Permanent permanent, Game game) { - super(Duration.EndOfTurn); - this.mor = new MageObjectReference(permanent, game); + TadeasJuniperAscendantEvasionEffect(TargetPointer targetPointer) { + super(Duration.EndOfCombat); + this.targetPointer = targetPointer; + staticText = "and can't be blocked by creatures with greater power"; } - private TadeasJuniperAscendantBlockEffect(final TadeasJuniperAscendantBlockEffect effect) { + private TadeasJuniperAscendantEvasionEffect(final TadeasJuniperAscendantEvasionEffect effect) { super(effect); - this.mor = effect.mor; - } - - @Override - public TadeasJuniperAscendantBlockEffect copy() { - return new TadeasJuniperAscendantBlockEffect(this); - } - - @Override - public boolean canBeBlocked(Permanent attacker, Permanent blocker, Ability source, Game game, boolean canUseChooseDialogs) { - return false; } @Override public boolean applies(Permanent permanent, Ability source, Game game) { - Permanent attacker = mor.getPermanent(game); - if (attacker == null) { - discard(); - return false; - } - return permanent.getPower().getValue() > attacker.getPower().getValue(); - } -} - -class TadeasJuniperAscendantTriggeredAbility extends TriggeredAbilityImpl { - - private final Set damagedPlayerIds = new HashSet<>(); - - TadeasJuniperAscendantTriggeredAbility() { - super(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1), false); - this.withFlavorWord("Fierce Punch"); - setTriggerPhrase("Whenever one or more creatures you control deal combat damage to a player, "); + return this.targetPointer.getTargets(game, source).contains(permanent.getId()); } - private TadeasJuniperAscendantTriggeredAbility(final TadeasJuniperAscendantTriggeredAbility ability) { - super(ability); - } - - @Override - public TadeasJuniperAscendantTriggeredAbility copy() { - return new TadeasJuniperAscendantTriggeredAbility(this); + public boolean canBeBlocked(Permanent attacker, Permanent blocker, Ability source, Game game, boolean canUseChooseDialogs) { + return blocker.getPower().getValue() <= attacker.getPower().getValue(); } @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.DAMAGED_PLAYER - || event.getType() == GameEvent.EventType.COMBAT_DAMAGE_STEP_PRIORITY - || event.getType() == GameEvent.EventType.ZONE_CHANGE; + public TadeasJuniperAscendantEvasionEffect copy() { + return new TadeasJuniperAscendantEvasionEffect(this); } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - if (event.getType() == GameEvent.EventType.COMBAT_DAMAGE_STEP_PRIORITY || - (event.getType() == GameEvent.EventType.ZONE_CHANGE && event.getTargetId().equals(getSourceId()))) { - damagedPlayerIds.clear(); - return false; - } - if (event.getType() != GameEvent.EventType.DAMAGED_PLAYER) { - return false; - } - DamagedPlayerEvent damageEvent = (DamagedPlayerEvent) event; - Permanent permanent = game.getPermanent(event.getSourceId()); - if (!damageEvent.isCombatDamage() - || permanent == null - || !permanent.isControlledBy(this.getControllerId()) - || !permanent.isCreature(game) || - damagedPlayerIds.contains(event.getPlayerId())) { - return false; - } - damagedPlayerIds.add(event.getPlayerId()); - return true; - } -} +} \ No newline at end of file diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/slx/TadeasJuniperAscendantTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/slx/TadeasJuniperAscendantTest.java new file mode 100644 index 000000000000..b381eb297bbe --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/slx/TadeasJuniperAscendantTest.java @@ -0,0 +1,163 @@ +package org.mage.test.cards.single.slx; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import mage.game.permanent.Permanent; +import org.junit.Before; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class TadeasJuniperAscendantTest extends CardTestPlayerBase { + + @Before + public void setUp() { + addCard(Zone.BATTLEFIELD, playerA, "Tadeas, Juniper Ascendant"); // 1/3 + addCard(Zone.BATTLEFIELD, playerA, "Sweet-Gum Recluse"); // 0/3 //Reach + addCard(Zone.BATTLEFIELD, playerA, "Canopy Spider"); // 1/3 //Reach + addCard(Zone.BATTLEFIELD, playerA, "Brood Weaver"); // 2/4 //Reach + addCard(Zone.BATTLEFIELD, playerA, "Acolyte of Xathrid"); // 0/5 + + addCard(Zone.BATTLEFIELD, playerB, "Phyrexian Walker"); // 0/3 + addCard(Zone.BATTLEFIELD, playerB, "Dryad Arbor"); // 1/1 + addCard(Zone.BATTLEFIELD, playerB, "Runeclaw Bear"); // 2/2 + addCard(Zone.BATTLEFIELD, playerB, "Southern Elephant"); // 3/4 + } + + private Permanent getBlocker(String blocker, mage.game.Game game) { + return game.getBattlefield().getAllActivePermanents() + .stream() + .filter(p -> p.getName().equals(blocker)) + .findFirst() + .get(); + } + + @Test + public void testAttackerLessThanTadeasAttackBlockerPowerEqualAttacker() { + attack(1, playerA, "Canopy Spider"); + runCode("check blocking", 1, PhaseStep.DECLARE_BLOCKERS, playerB, (info, player, game) -> { + Permanent equalPowerBlocker = getBlocker("Dryad Arbor", game); + assertTrue(game.getCombat().getGroups().get(0).canBlock(equalPowerBlocker, game), + "equalPowerBlocker should be able to block"); + }); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.END_TURN); + execute(); + } + + @Test + public void testAttackerLessThanTadeasAttackBlockerPowerMoreThanAttacker() { + attack(1, playerA, "Sweet-Gum Recluse"); + runCode("check blocking", 1, PhaseStep.DECLARE_BLOCKERS, playerB, (info, player, game) -> { + Permanent morePowerBlocker = getBlocker("Southern Elephant", game); + assertFalse(game.getCombat().getGroups().get(0).canBlock(morePowerBlocker, game), + "morePowerBlocker should not be able to block"); + }); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.END_TURN); + execute(); + } + + @Test + public void testAttackerLessThanTadeasAttackWithoutReachBlockerPowerMoreThanAttacker() { + attack(1, playerA, "Canopy Spider"); + attack(1, playerA, "Acolyte of Xathrid"); + runCode("check blocking", 1, PhaseStep.DECLARE_BLOCKERS, playerB, (info, player, game) -> { + Permanent morePowerBlocker = getBlocker("Runeclaw Bear", game); + assertTrue(game.getCombat().getGroups().get(1).canBlock(morePowerBlocker, game), + "morePowerBlocker should be able to block"); + }); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.END_TURN); + execute(); + } + + @Test + public void testAttackerEqualTadeasAttackBlockerPowerLessThanAttacker() { + attack(1, playerA, "Canopy Spider"); + runCode("check blocking", 1, PhaseStep.DECLARE_BLOCKERS, playerB, (info, player, game) -> { + Permanent lessPowerBlocker = getBlocker("Phyrexian Walker", game); + assertTrue(game.getCombat().getGroups().get(0).canBlock(lessPowerBlocker, game), + "lessPowerBlocker should be able to block"); + }); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.END_TURN); + execute(); + } + + @Test + public void testAttackerEqualTadeasAttackBlockerPowerEqualAttacker() { + attack(1, playerA, "Canopy Spider"); + runCode("check blocking", 1, PhaseStep.DECLARE_BLOCKERS, playerB, (info, player, game) -> { + Permanent equalPowerBlocker = getBlocker("Dryad Arbor", game); + assertTrue(game.getCombat().getGroups().get(0).canBlock(equalPowerBlocker, game), + "equalPowerBlocker should be able to block"); + }); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.END_TURN); + execute(); + } + + @Test + public void testAttackerEqualTadeasAttackBlockerPowerMoreThanAttacker() { + attack(1, playerA, "Canopy Spider"); + runCode("check blocking", 1, PhaseStep.DECLARE_BLOCKERS, playerB, (info, player, game) -> { + Permanent morePowerBlocker = getBlocker("Southern Elephant", game); + assertFalse(game.getCombat().getGroups().get(0).canBlock(morePowerBlocker, game), + "morePowerBlocker should not be able to block"); + }); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.END_TURN); + execute(); + } + + @Test + public void testAttackerMoreThanTadeasAttackBlockerPowerLessThanAttacker() { + attack(1, playerA, "Brood Weaver"); + runCode("check blocking", 1, PhaseStep.DECLARE_BLOCKERS, playerB, (info, player, game) -> { + Permanent lessPowerBlocker = getBlocker("Dryad Arbor", game); + assertTrue(game.getCombat().getGroups().get(0).canBlock(lessPowerBlocker, game), + "lessPowerBlocker should not be able to block"); + }); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.END_TURN); + execute(); + } + + @Test + public void testAttackerMoreThanTadeasAttackBlockerPowerEqualAttacker() { + attack(1, playerA, "Brood Weaver"); + runCode("check blocking", 1, PhaseStep.DECLARE_BLOCKERS, playerB, (info, player, game) -> { + Permanent equalPowerBlocker = getBlocker("Runeclaw Bear", game); + assertTrue(game.getCombat().getGroups().get(0).canBlock(equalPowerBlocker, game), + "equalPowerBlocker should be able to block"); + }); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.END_TURN); + execute(); + } + + @Test + public void testAttackerMoreThanTadeasAttackBlockerPowerMoreThanAttacker() { + attack(1, playerA, "Brood Weaver"); + runCode("check blocking", 1, PhaseStep.DECLARE_BLOCKERS, playerB, (info, player, game) -> { + Permanent morePowerBlocker = getBlocker("Southern Elephant", game); + assertFalse(game.getCombat().getGroups().get(0).canBlock(morePowerBlocker, game), + "morePowerBlocker should not be able to block"); + }); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.END_TURN); + execute(); + } +}