fix Tadeas, Juniper Ascendant (#10490)

* added Tests for Tadeas
* Fix and cleanup Tadeas Juniper Ascendant
* Fix same power test to attack with creature with same power
* Test: added test for tadeas elusive not applying for creatures without reach
* Fix: creatures without reach can be blocked by higher power blockers
* Fix: use TargetPointer instead of MageObjectReference
---------
Co-authored-by: gravitybone <gravitybone@protonmail.com>
This commit is contained in:
Alexander 2023-06-24 04:47:55 +02:00 committed by GitHub
parent eea44bb13e
commit 2db08c6b7d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 184 additions and 81 deletions

View file

@ -1,10 +1,9 @@
package mage.cards.t; package mage.cards.t;
import mage.MageInt; import mage.MageInt;
import mage.MageObjectReference;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.AttacksCreatureYouControlTriggeredAbility; import mage.abilities.common.AttacksCreatureYouControlTriggeredAbility;
import mage.abilities.common.DealCombatDamageControlledTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.Condition; import mage.abilities.condition.Condition;
import mage.abilities.condition.InvertCondition; import mage.abilities.condition.InvertCondition;
@ -22,12 +21,9 @@ import mage.constants.*;
import mage.filter.common.FilterControlledCreaturePermanent; import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.predicate.mageobject.AbilityPredicate; import mage.filter.predicate.mageobject.AbilityPredicate;
import mage.game.Game; import mage.game.Game;
import mage.game.events.DamagedPlayerEvent;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.target.targetpointer.TargetPointer;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID; import java.util.UUID;
/** /**
@ -55,19 +51,21 @@ public final class TadeasJuniperAscendant extends CardImpl {
// Reach // Reach
this.addAbility(ReachAbility.getInstance()); this.addAbility(ReachAbility.getInstance());
// TeleportDhalsim, Pliable Pacifist has hexproof unless he's attacking. // Tadeas has hexproof unless it's attacking.
this.addAbility(new SimpleStaticAbility(new ConditionalContinuousEffect( this.addAbility(new SimpleStaticAbility(new ConditionalContinuousEffect(
new GainAbilitySourceEffect(HexproofAbility.getInstance()), new GainAbilitySourceEffect(HexproofAbility.getInstance()),
condition, "{this} has hexproof unless he's attacking" 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. // 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( this.addAbility(new AttacksCreatureYouControlTriggeredAbility(
new TadeasJuniperAscendantEffect(), false, filter, true new TadeasJuniperAscendantEffect(), false, filter, true
)); ));
// Fierce PunchWhenever one or more creatures you control deal combat damage to a player, draw a card. // Whenever one or more creatures you control deal combat damage to a player, draw a card.
this.addAbility(new TadeasJuniperAscendantTriggeredAbility()); this.addAbility(new DealCombatDamageControlledTriggeredAbility(
new DrawCardSourceControllerEffect(1)
));
} }
private TadeasJuniperAscendant(final TadeasJuniperAscendant card) { private TadeasJuniperAscendant(final TadeasJuniperAscendant card) {
@ -103,92 +101,34 @@ class TadeasJuniperAscendantEffect extends OneShotEffect {
return false; return false;
} }
permanent.untap(game); permanent.untap(game);
game.addEffect(new TadeasJuniperAscendantBlockEffect(permanent, game), source); game.addEffect(new TadeasJuniperAscendantEvasionEffect(getTargetPointer()), source);
return true; return true;
} }
} }
class TadeasJuniperAscendantBlockEffect extends RestrictionEffect { class TadeasJuniperAscendantEvasionEffect extends RestrictionEffect {
private final MageObjectReference mor; TadeasJuniperAscendantEvasionEffect(TargetPointer targetPointer) {
super(Duration.EndOfCombat);
TadeasJuniperAscendantBlockEffect(Permanent permanent, Game game) { this.targetPointer = targetPointer;
super(Duration.EndOfTurn); staticText = "and can't be blocked by creatures with greater power";
this.mor = new MageObjectReference(permanent, game);
} }
private TadeasJuniperAscendantBlockEffect(final TadeasJuniperAscendantBlockEffect effect) { private TadeasJuniperAscendantEvasionEffect(final TadeasJuniperAscendantEvasionEffect effect) {
super(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 @Override
public boolean applies(Permanent permanent, Ability source, Game game) { public boolean applies(Permanent permanent, Ability source, Game game) {
Permanent attacker = mor.getPermanent(game); return this.targetPointer.getTargets(game, source).contains(permanent.getId());
if (attacker == null) {
discard();
return false;
}
return permanent.getPower().getValue() > attacker.getPower().getValue();
}
}
class TadeasJuniperAscendantTriggeredAbility extends TriggeredAbilityImpl {
private final Set<UUID> 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, ");
} }
private TadeasJuniperAscendantTriggeredAbility(final TadeasJuniperAscendantTriggeredAbility ability) { public boolean canBeBlocked(Permanent attacker, Permanent blocker, Ability source, Game game, boolean canUseChooseDialogs) {
super(ability); return blocker.getPower().getValue() <= attacker.getPower().getValue();
} }
@Override @Override
public TadeasJuniperAscendantTriggeredAbility copy() { public TadeasJuniperAscendantEvasionEffect copy() {
return new TadeasJuniperAscendantTriggeredAbility(this); return new TadeasJuniperAscendantEvasionEffect(this);
} }
}
@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;
}
@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;
}
}

View file

@ -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();
}
}