mirror of
https://github.com/correl/mage.git
synced 2024-11-21 19:18:40 +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;
|
||||
|
||||
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());
|
||||
|
||||
// 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 @@ 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, ");
|
||||
return this.targetPointer.getTargets(game, source).contains(permanent.getId());
|
||||
}
|
||||
|
||||
private TadeasJuniperAscendantTriggeredAbility(final TadeasJuniperAscendantTriggeredAbility ability) {
|
||||
super(ability);
|
||||
public boolean canBeBlocked(Permanent attacker, Permanent blocker, Ability source, Game game, boolean canUseChooseDialogs) {
|
||||
return blocker.getPower().getValue() <= attacker.getPower().getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TadeasJuniperAscendantTriggeredAbility copy() {
|
||||
return new TadeasJuniperAscendantTriggeredAbility(this);
|
||||
public TadeasJuniperAscendantEvasionEffect copy() {
|
||||
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