mirror of
https://github.com/correl/mage.git
synced 2024-11-22 03:00:11 +00:00
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:
parent
eea44bb13e
commit
2db08c6b7d
2 changed files with 184 additions and 81 deletions
|
@ -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());
|
||||||
|
|
||||||
// Teleport—Dhalsim, 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 Punch—Whenever 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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue