mirror of
https://github.com/correl/mage.git
synced 2025-04-01 19:07:57 -09:00
* Fixed a problem of triggered effects that detect if a creature was exiled but the creature ended in a another zone (e.g. commander) (fixes #5905),
This commit is contained in:
parent
12639bce26
commit
554c5baf25
3 changed files with 71 additions and 13 deletions
Mage.Sets/src/mage/cards/s
Mage.Tests/src/test/java/org/mage/test/commander/duel
Mage/src/main/java/mage/game/events
|
@ -49,7 +49,7 @@ public final class Soulherder extends CardImpl {
|
|||
Ability ability = new BeginningOfEndStepTriggeredAbility(
|
||||
new ExileTargetForSourceEffect(), TargetController.YOU, true
|
||||
);
|
||||
ability.addEffect(new ReturnToBattlefieldUnderOwnerControlTargetEffect().concatBy("then"));
|
||||
ability.addEffect(new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, true).concatBy("then"));
|
||||
ability.addTarget(new TargetControlledCreaturePermanent(filter));
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
@ -89,7 +89,8 @@ class SoulherderTriggeredAbility extends ZoneChangeTriggeredAbility {
|
|||
if (permanent != null && permanent.isCreature()) {
|
||||
// custom check cause ZoneChangeTriggeredAbility for source object only
|
||||
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
|
||||
return (fromZone == null || zEvent.getFromZone() == fromZone) && (toZone == null || zEvent.getToZone() == toZone);
|
||||
return (fromZone == null || zEvent.getFromZone() == fromZone)
|
||||
&& (zEvent.getToZone() == toZone || zEvent.getOriginalToZone() == toZone);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -82,6 +82,11 @@ public class CommanderReplaceEffectTest extends CardTestCommanderDuelBase {
|
|||
|
||||
}
|
||||
|
||||
// https://github.com/magefree/mage/issues/5905
|
||||
/* From the rulings of Soulherder:
|
||||
If a creature is exiled but ends up in another zone (most likely because
|
||||
it’s a player’s commander in the Commander variant), Soulherder’s first ability triggers.
|
||||
I exiled an opponents Commander, but Soulherder did not trigger.*/
|
||||
@Test
|
||||
public void soulherderAndExiledCommanders() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 3);
|
||||
|
@ -110,4 +115,50 @@ public class CommanderReplaceEffectTest extends CardTestCommanderDuelBase {
|
|||
assertPowerToughness(playerA, "Soulherder", 2, 2);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void soulherderAndDestroyedCommanders() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 3);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 3);
|
||||
|
||||
// Whenever a creature is exiled from the battlefield, put a +1/+1 counter on Soulherder.
|
||||
// At the beginning of your end step, you may exile another target creature you control,
|
||||
// then return that card to the battlefield under its owner's control.
|
||||
addCard(Zone.HAND, playerA, "Soulherder", 1); // Creature {1}{W}{U}
|
||||
|
||||
// Farm {2}{W} - Instant
|
||||
// Destroy target attacking or blocking creature.
|
||||
// Market {2}{U} - Sorcery
|
||||
// Aftermath (Cast this spell only from your graveyard. Then exile it.)
|
||||
// Draw two cards, then discard two cards.
|
||||
addCard(Zone.HAND, playerB, "Farm // Market", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Plains", 3);
|
||||
|
||||
// Daxos of Meletis can't be blocked by creatures with power 3 or greater.
|
||||
// Whenever Daxos of Meletis deals combat damage to a player, exile the top card of that player's library. You gain life equal to that card's converted mana cost. Until end of turn, you may cast that card and you may spend mana as though it were mana of any color to cast it.
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Daxos of Meletis");
|
||||
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Soulherder");
|
||||
|
||||
setChoice(playerA, "No"); // Use Soulherder's triggered ability
|
||||
|
||||
attack(3, playerA, "Daxos of Meletis");
|
||||
|
||||
castSpell(3, PhaseStep.DECLARE_BLOCKERS, playerB, "Farm", "Daxos of Meletis");
|
||||
|
||||
setChoice(playerA, "Yes"); // Move Daxos to command Zone
|
||||
|
||||
setStopAt(3, PhaseStep.POSTCOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertLife(playerB, 40);
|
||||
|
||||
assertPermanentCount(playerA, "Soulherder", 1);
|
||||
assertHandCount(playerB, "Farm // Market", 0);
|
||||
assertGraveyardCount(playerB, "Farm // Market", 1);
|
||||
assertPermanentCount(playerA, "Daxos of Meletis", 0);
|
||||
assertCommandZoneCount(playerA, "Daxos of Meletis", 1);
|
||||
|
||||
assertPowerToughness(playerA, "Soulherder", 1, 1);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,9 @@
|
|||
|
||||
|
||||
package mage.game.events;
|
||||
|
||||
import mage.constants.Zone;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import mage.constants.Zone;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -16,19 +13,20 @@ public class ZoneChangeEvent extends GameEvent {
|
|||
|
||||
private Zone fromZone;
|
||||
private Zone toZone;
|
||||
private Zone originalToZone;
|
||||
private Permanent target;
|
||||
|
||||
public ZoneChangeEvent(Permanent target, UUID sourceId, UUID playerId, Zone fromZone, Zone toZone) {
|
||||
super(EventType.ZONE_CHANGE, target.getId(), sourceId, playerId);
|
||||
this.fromZone = fromZone;
|
||||
this.toZone = toZone;
|
||||
this.setToZone(toZone);
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
public ZoneChangeEvent(Permanent target, UUID sourceId, UUID playerId, Zone fromZone, Zone toZone, List<UUID> appliedEffects) {
|
||||
super(EventType.ZONE_CHANGE, target.getId(), sourceId, playerId);
|
||||
this.fromZone = fromZone;
|
||||
this.toZone = toZone;
|
||||
this.setToZone(toZone);
|
||||
this.target = target;
|
||||
if (appliedEffects != null) {
|
||||
this.appliedEffects = appliedEffects;
|
||||
|
@ -38,13 +36,13 @@ public class ZoneChangeEvent extends GameEvent {
|
|||
public ZoneChangeEvent(UUID targetId, UUID sourceId, UUID playerId, Zone fromZone, Zone toZone) {
|
||||
super(EventType.ZONE_CHANGE, targetId, sourceId, playerId);
|
||||
this.fromZone = fromZone;
|
||||
this.toZone = toZone;
|
||||
this.setToZone(toZone);
|
||||
}
|
||||
|
||||
public ZoneChangeEvent(UUID targetId, UUID sourceId, UUID playerId, Zone fromZone, Zone toZone, List<UUID> appliedEffects) {
|
||||
super(EventType.ZONE_CHANGE, targetId, sourceId, playerId);
|
||||
this.fromZone = fromZone;
|
||||
this.toZone = toZone;
|
||||
this.setToZone(toZone);
|
||||
if (appliedEffects != null) {
|
||||
this.appliedEffects = appliedEffects;
|
||||
}
|
||||
|
@ -57,7 +55,7 @@ public class ZoneChangeEvent extends GameEvent {
|
|||
public ZoneChangeEvent(UUID targetId, UUID playerId, Zone fromZone, Zone toZone) {
|
||||
this(targetId, null, playerId, fromZone, toZone);
|
||||
}
|
||||
|
||||
|
||||
public Zone getFromZone() {
|
||||
return fromZone;
|
||||
}
|
||||
|
@ -68,6 +66,9 @@ public class ZoneChangeEvent extends GameEvent {
|
|||
|
||||
public void setToZone(Zone toZone) {
|
||||
this.toZone = toZone;
|
||||
if (originalToZone == null && toZone != null) {
|
||||
originalToZone = toZone;
|
||||
}
|
||||
}
|
||||
|
||||
public Permanent getTarget() {
|
||||
|
@ -79,6 +80,11 @@ public class ZoneChangeEvent extends GameEvent {
|
|||
}
|
||||
|
||||
public boolean isDiesEvent() {
|
||||
return (toZone == Zone.GRAVEYARD && fromZone == Zone.BATTLEFIELD);
|
||||
return (toZone == Zone.GRAVEYARD && fromZone == Zone.BATTLEFIELD);
|
||||
}
|
||||
|
||||
public Zone getOriginalToZone() {
|
||||
return originalToZone;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue