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;
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.constants.*;
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 final class TadeasJuniperAscendant extends CardImpl {
// Reach
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(
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 PunchWhenever 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 @@ class TadeasJuniperAscendantEffect extends OneShotEffect {
return false;
}
permanent.untap(game);
game.addEffect(new TadeasJuniperAscendantBlockEffect(permanent, game), source);
game.addEffect(new TadeasJuniperAscendantEvasionEffect(getTargetPointer()), source);
return true;
}
}
class TadeasJuniperAscendantBlockEffect extends RestrictionEffect {
class TadeasJuniperAscendantEvasionEffect extends RestrictionEffect {
private final MageObjectReference mor;
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<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) {
super(ability);
}
@Override
public TadeasJuniperAscendantTriggeredAbility copy() {
return new TadeasJuniperAscendantTriggeredAbility(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;
return this.targetPointer.getTargets(game, source).contains(permanent.getId());
}
public boolean canBeBlocked(Permanent attacker, Permanent blocker, Ability source, Game game, boolean canUseChooseDialogs) {
return blocker.getPower().getValue() <= attacker.getPower().getValue();
}
@Override
public TadeasJuniperAscendantEvasionEffect copy() {
return new TadeasJuniperAscendantEvasionEffect(this);
}
}

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