mirror of
https://github.com/magefree/mage.git
synced 2026-01-25 12:49:39 -08:00
* Some fixes to the exile effects with duration. Fixed that exiled cards/permanets did not come back if causing card was put into play and exiled by Whip of Erebos.
This commit is contained in:
parent
9ba6f74bf6
commit
7b738474a9
15 changed files with 187 additions and 542 deletions
|
|
@ -27,29 +27,24 @@
|
|||
*/
|
||||
package mage.sets.journeyintonyx;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.TriggeredAbilityImpl;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
|
||||
import mage.abilities.effects.common.ExileTargetEffect;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Rarity;
|
||||
import mage.constants.TargetController;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.common.FilterNonlandPermanent;
|
||||
import mage.filter.predicate.permanent.ControllerPredicate;
|
||||
import mage.game.ExileZone;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.events.ZoneChangeEvent;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.target.TargetPermanent;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
@ -72,10 +67,8 @@ public class BanishingLight extends CardImpl {
|
|||
// When Banishing Light enters the battlefield, exile target nonland permanent an opponent controls until Banishing Light leaves the battlefield.
|
||||
Ability ability = new EntersBattlefieldTriggeredAbility(new BanishingLightExileEffect());
|
||||
ability.addTarget(new TargetPermanent(filter));
|
||||
ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility()));
|
||||
this.addAbility(ability);
|
||||
// Implemented as triggered effect that doesn't uses the stack (implementation with watcher does not work correctly because if the returned creature
|
||||
// has a DiesTriggeredAll ability it triggers for the dying / battlefield leaving source object, what shouldn't happen)
|
||||
this.addAbility(new BanishingLightReturnExiledAbility());
|
||||
}
|
||||
|
||||
public BanishingLight(final BanishingLight card) {
|
||||
|
|
@ -110,79 +103,7 @@ class BanishingLightExileEffect extends OneShotEffect {
|
|||
// If Banishing Light leaves the battlefield before its triggered ability resolves,
|
||||
// the target won't be exiled.
|
||||
if (permanent != null) {
|
||||
return new ExileTargetEffect(source.getSourceId(), permanent.getName()).apply(game, source);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the exiled card as source permanent leaves battlefield
|
||||
* Uses no stack
|
||||
* @author LevelX2
|
||||
*/
|
||||
|
||||
class BanishingLightReturnExiledAbility extends TriggeredAbilityImpl {
|
||||
|
||||
public BanishingLightReturnExiledAbility() {
|
||||
super(Zone.BATTLEFIELD, new ReturnExiledCreatureEffect());
|
||||
this.usesStack = false;
|
||||
this.setRuleVisible(false);
|
||||
}
|
||||
|
||||
public BanishingLightReturnExiledAbility(final BanishingLightReturnExiledAbility ability) {
|
||||
super(ability);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BanishingLightReturnExiledAbility copy() {
|
||||
return new BanishingLightReturnExiledAbility(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
if (event.getType() == GameEvent.EventType.ZONE_CHANGE && event.getTargetId().equals(this.getSourceId())) {
|
||||
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
|
||||
if (zEvent.getFromZone() == Zone.BATTLEFIELD) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
class ReturnExiledCreatureEffect extends OneShotEffect {
|
||||
|
||||
public ReturnExiledCreatureEffect() {
|
||||
super(Outcome.Benefit);
|
||||
this.staticText = "Return exiled permanent";
|
||||
}
|
||||
|
||||
public ReturnExiledCreatureEffect(final ReturnExiledCreatureEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReturnExiledCreatureEffect copy() {
|
||||
return new ReturnExiledCreatureEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller != null) {
|
||||
ExileZone exile = game.getExile().getExileZone(source.getSourceId());
|
||||
Card sourceCard = game.getCard(source.getSourceId());
|
||||
if (exile != null && sourceCard != null) {
|
||||
LinkedList<UUID> cards = new LinkedList<>(exile);
|
||||
for (UUID cardId : cards) {
|
||||
Card card = game.getCard(cardId);
|
||||
card.moveToZone(Zone.BATTLEFIELD, source.getSourceId(), game, false);
|
||||
game.informPlayers(new StringBuilder(sourceCard.getName()).append(": ").append(card.getName()).append(" returns to battlefield from exile").toString());
|
||||
}
|
||||
exile.clear();
|
||||
return true;
|
||||
}
|
||||
return new ExileTargetEffect(CardUtil.getCardExileZoneId(game, source), permanent.getName()).apply(game, source);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,12 +31,14 @@ import java.util.LinkedList;
|
|||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.TriggeredAbilityImpl;
|
||||
import mage.abilities.DelayedTriggeredAbility;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Rarity;
|
||||
import mage.constants.Zone;
|
||||
|
|
@ -70,10 +72,8 @@ public class BrainMaggot extends CardImpl {
|
|||
// When Brain Maggot enters the battlefield, target opponent reveals his or her hand and you choose a nonland card from it. Exile that card until Brain Maggot leaves the battlefield.
|
||||
Ability ability = new EntersBattlefieldTriggeredAbility(new BrainMaggotExileEffect());
|
||||
ability.addTarget(new TargetOpponent());
|
||||
ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new BrainMaggotReturnExiledCreatureAbility()));
|
||||
this.addAbility(ability);
|
||||
// Implemented as triggered effect that doesn't uses the stack (implementation with watcher does not work correctly because if the returned creature
|
||||
// has a DiesTriggeredAll ability it triggers for the dying / battlefield leaving source object, what shouldn't happen)
|
||||
this.addAbility(new BrainMaggotReturnExiledAbility());
|
||||
}
|
||||
|
||||
public BrainMaggot(final BrainMaggot card) {
|
||||
|
|
@ -108,15 +108,17 @@ class BrainMaggotExileEffect extends OneShotEffect {
|
|||
Player opponent = game.getPlayer(this.getTargetPointer().getFirst(game, source));
|
||||
Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId());
|
||||
if (controller != null && opponent != null && sourcePermanent != null) {
|
||||
opponent.revealCards(sourcePermanent.getLogName(), opponent.getHand(), game);
|
||||
if (!opponent.getHand().isEmpty()) {
|
||||
opponent.revealCards(sourcePermanent.getLogName(), opponent.getHand(), game);
|
||||
|
||||
FilterCard filter = new FilterNonlandCard("nonland card to exile");
|
||||
TargetCard target = new TargetCard(Zone.HAND, filter);
|
||||
if (opponent.getHand().count(filter, game) > 0 && controller.choose(Outcome.Exile, opponent.getHand(), target, game)) {
|
||||
Card card = opponent.getHand().get(target.getFirstTarget(), game);
|
||||
// If source permanent leaves the battlefield before its triggered ability resolves, the target card won't be exiled.
|
||||
if (card != null && game.getState().getZone(source.getSourceId()) == Zone.BATTLEFIELD) {
|
||||
controller.moveCardToExileWithInfo(card, CardUtil.getCardExileZoneId(game, source), sourcePermanent.getName(), source.getSourceId(), game, Zone.HAND);
|
||||
FilterCard filter = new FilterNonlandCard("nonland card to exile");
|
||||
TargetCard target = new TargetCard(Zone.HAND, filter);
|
||||
if (opponent.getHand().count(filter, game) > 0 && controller.choose(Outcome.Exile, opponent.getHand(), target, game)) {
|
||||
Card card = opponent.getHand().get(target.getFirstTarget(), game);
|
||||
// If source permanent leaves the battlefield before its triggered ability resolves, the target card won't be exiled.
|
||||
if (card != null && game.getState().getZone(source.getSourceId()) == Zone.BATTLEFIELD) {
|
||||
controller.moveCardToExileWithInfo(card, CardUtil.getCardExileZoneId(game, source), sourcePermanent.getName(), source.getSourceId(), game, Zone.HAND);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
|
@ -132,21 +134,21 @@ class BrainMaggotExileEffect extends OneShotEffect {
|
|||
* @author LevelX2
|
||||
*/
|
||||
|
||||
class BrainMaggotReturnExiledAbility extends TriggeredAbilityImpl {
|
||||
class BrainMaggotReturnExiledCreatureAbility extends DelayedTriggeredAbility {
|
||||
|
||||
public BrainMaggotReturnExiledAbility() {
|
||||
super(Zone.BATTLEFIELD, new BrainMaggotReturnExiledCreatureEffect());
|
||||
public BrainMaggotReturnExiledCreatureAbility() {
|
||||
super(new BrainMaggotReturnExiledCreatureEffect(), Duration.OneUse);
|
||||
this.usesStack = false;
|
||||
this.setRuleVisible(false);
|
||||
}
|
||||
|
||||
public BrainMaggotReturnExiledAbility(final BrainMaggotReturnExiledAbility ability) {
|
||||
public BrainMaggotReturnExiledCreatureAbility(final BrainMaggotReturnExiledCreatureAbility ability) {
|
||||
super(ability);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BrainMaggotReturnExiledAbility copy() {
|
||||
return new BrainMaggotReturnExiledAbility(this);
|
||||
public BrainMaggotReturnExiledCreatureAbility copy() {
|
||||
return new BrainMaggotReturnExiledCreatureAbility(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -179,7 +179,7 @@ class KheruLichLordReplacementEffect extends ReplacementEffectImpl {
|
|||
if (controller != null) {
|
||||
Card card = game.getCard(getTargetPointer().getFirst(game, source));
|
||||
if (card != null) {
|
||||
controller.moveCardToExileWithInfo(card, null, "", source.getSourceId(), game, null);
|
||||
controller.moveCardToExileWithInfo(card, null, "", source.getSourceId(), game, game.getState().getZone(card.getId()));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -27,29 +27,24 @@
|
|||
*/
|
||||
package mage.sets.khansoftarkir;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.TriggeredAbilityImpl;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
|
||||
import mage.abilities.effects.common.ExileTargetEffect;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Rarity;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.Filter.ComparisonType;
|
||||
import mage.filter.common.FilterCreaturePermanent;
|
||||
import mage.filter.predicate.mageobject.ToughnessPredicate;
|
||||
import mage.game.ExileZone;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.events.ZoneChangeEvent;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.target.common.TargetCreaturePermanent;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
@ -71,10 +66,9 @@ public class SuspensionField extends CardImpl {
|
|||
// When Suspension Field enters the battlefield, you may exile target creature with toughness 3 or greater until Suspension Field leaves the battlefield.
|
||||
Ability ability = new EntersBattlefieldTriggeredAbility(new SuspensionFieldExileEffect(), true);
|
||||
ability.addTarget(new TargetCreaturePermanent(filter));
|
||||
ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility()));
|
||||
this.addAbility(ability);
|
||||
// Implemented as triggered effect that doesn't uses the stack (implementation with watcher does not work correctly because if the returned creature
|
||||
// has a DiesTriggeredAll ability it triggers for the dying / battlefield leaving source object, what shouldn't happen)
|
||||
this.addAbility(new SuspensionFieldReturnExiledAbility());
|
||||
|
||||
}
|
||||
|
||||
public SuspensionField(final SuspensionField card) {
|
||||
|
|
@ -108,73 +102,7 @@ class SuspensionFieldExileEffect extends OneShotEffect {
|
|||
Permanent sourcePermanent = game.getPermanent(source.getSourceId());
|
||||
// If Suspension Field leaves the battlefield before its triggered ability resolves, the target won't be exiled.
|
||||
if (sourcePermanent != null) {
|
||||
return new ExileTargetEffect(source.getSourceId(), sourcePermanent.getName()).apply(game, source);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
class SuspensionFieldReturnExiledAbility extends TriggeredAbilityImpl {
|
||||
|
||||
SuspensionFieldReturnExiledAbility() {
|
||||
super(Zone.BATTLEFIELD, new SuspensionFieldReturnExiledCreatureEffect());
|
||||
this.usesStack = false;
|
||||
this.setRuleVisible(false);
|
||||
}
|
||||
|
||||
SuspensionFieldReturnExiledAbility(final SuspensionFieldReturnExiledAbility ability) {
|
||||
super(ability);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SuspensionFieldReturnExiledAbility copy() {
|
||||
return new SuspensionFieldReturnExiledAbility(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
if (event.getType() == GameEvent.EventType.ZONE_CHANGE && event.getTargetId().equals(this.getSourceId())) {
|
||||
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
|
||||
if (zEvent.getFromZone() == Zone.BATTLEFIELD) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
class SuspensionFieldReturnExiledCreatureEffect extends OneShotEffect {
|
||||
|
||||
SuspensionFieldReturnExiledCreatureEffect() {
|
||||
super(Outcome.Benefit);
|
||||
this.staticText = "Return exiled permanent";
|
||||
}
|
||||
|
||||
SuspensionFieldReturnExiledCreatureEffect(final SuspensionFieldReturnExiledCreatureEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SuspensionFieldReturnExiledCreatureEffect copy() {
|
||||
return new SuspensionFieldReturnExiledCreatureEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller != null) {
|
||||
ExileZone exile = game.getExile().getExileZone(source.getSourceId());
|
||||
Card sourceCard = game.getCard(source.getSourceId());
|
||||
if (exile != null && sourceCard != null) {
|
||||
LinkedList<UUID> cards = new LinkedList<>(exile);
|
||||
for (UUID cardId : cards) {
|
||||
Card card = game.getCard(cardId);
|
||||
card.moveToZone(Zone.BATTLEFIELD, source.getSourceId(), game, false);
|
||||
game.informPlayers(new StringBuilder(sourceCard.getName()).append(": ").append(card.getName()).append(" returns to battlefield from exile").toString());
|
||||
}
|
||||
exile.clear();
|
||||
return true;
|
||||
}
|
||||
return new ExileTargetEffect(CardUtil.getCardExileZoneId(game, source), sourcePermanent.getName()).apply(game, source);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,30 +27,25 @@
|
|||
*/
|
||||
package mage.sets.magic2014;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.TriggeredAbilityImpl;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
|
||||
import mage.abilities.effects.common.ExileTargetEffect;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Rarity;
|
||||
import mage.constants.TargetController;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.common.FilterCreaturePermanent;
|
||||
import mage.filter.predicate.permanent.ControllerPredicate;
|
||||
import mage.game.ExileZone;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.events.ZoneChangeEvent;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.target.common.TargetCreaturePermanent;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
@ -76,13 +71,8 @@ public class BanisherPriest extends CardImpl {
|
|||
// When Banisher Priest enters the battlefield, exile target creature an opponent controls until Banisher Priest leaves the battlefield.
|
||||
Ability ability = new EntersBattlefieldTriggeredAbility(new BanisherPriestExileEffect());
|
||||
ability.addTarget(new TargetCreaturePermanent(filter));
|
||||
ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility()));
|
||||
this.addAbility(ability);
|
||||
// Implemented as triggered effect that doesn't uses the stack (implementation with watcher does not work correctly because if the returned creature
|
||||
// has a DiesTriggeredAll ability it triggers for the dying Banish Priest, what shouldn't happen)
|
||||
this.addAbility(new BanisherPriestReturnExiledAbility());
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public BanisherPriest(final BanisherPriest card) {
|
||||
|
|
@ -117,76 +107,7 @@ class BanisherPriestExileEffect extends OneShotEffect {
|
|||
// If Banisher Priest leaves the battlefield before its triggered ability resolves,
|
||||
// the target creature won't be exiled.
|
||||
if (permanent != null) {
|
||||
return new ExileTargetEffect(source.getSourceId(), permanent.getName()).apply(game, source);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the exiled card as Banisher Priest leaves battlefield
|
||||
* Uses no stack
|
||||
* @author LevelX2
|
||||
*/
|
||||
|
||||
class BanisherPriestReturnExiledAbility extends TriggeredAbilityImpl {
|
||||
|
||||
public BanisherPriestReturnExiledAbility() {
|
||||
super(Zone.BATTLEFIELD, new ReturnExiledCreatureEffect());
|
||||
this.usesStack = false;
|
||||
this.setRuleVisible(false);
|
||||
}
|
||||
|
||||
public BanisherPriestReturnExiledAbility(final BanisherPriestReturnExiledAbility ability) {
|
||||
super(ability);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BanisherPriestReturnExiledAbility copy() {
|
||||
return new BanisherPriestReturnExiledAbility(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
if (event.getType() == GameEvent.EventType.ZONE_CHANGE && event.getTargetId().equals(this.getSourceId())) {
|
||||
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
|
||||
if (zEvent.getFromZone() == Zone.BATTLEFIELD) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
class ReturnExiledCreatureEffect extends OneShotEffect {
|
||||
|
||||
public ReturnExiledCreatureEffect() {
|
||||
super(Outcome.Benefit);
|
||||
this.staticText = "Return exiled creature";
|
||||
}
|
||||
|
||||
public ReturnExiledCreatureEffect(final ReturnExiledCreatureEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReturnExiledCreatureEffect copy() {
|
||||
return new ReturnExiledCreatureEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
ExileZone exile = game.getExile().getExileZone(source.getSourceId());
|
||||
MageObject sourceObject = game.getObject(source.getSourceId());
|
||||
if (exile != null && sourceObject != null) {
|
||||
LinkedList<UUID> cards = new LinkedList<>(exile);
|
||||
for (UUID cardId : cards) {
|
||||
Card card = game.getCard(cardId);
|
||||
card.moveToZone(Zone.BATTLEFIELD, source.getSourceId(), game, false);
|
||||
game.informPlayers(new StringBuilder(sourceObject.getLogName()).append(": ").append(card.getName()).append(" returns to battlefield from exile").toString());
|
||||
}
|
||||
exile.clear();
|
||||
return true;
|
||||
return new ExileTargetEffect(CardUtil.getCardExileZoneId(game, source), permanent.getName()).apply(game, source);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,15 +27,15 @@
|
|||
*/
|
||||
package mage.sets.magic2014;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.TriggeredAbilityImpl;
|
||||
import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
|
||||
import mage.abilities.effects.common.ExileTargetEffect;
|
||||
import mage.abilities.keyword.IslandwalkAbility;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
|
|
@ -43,12 +43,11 @@ import mage.constants.Rarity;
|
|||
import mage.constants.Zone;
|
||||
import mage.filter.common.FilterCreaturePermanent;
|
||||
import mage.filter.predicate.permanent.ControllerIdPredicate;
|
||||
import mage.game.ExileZone;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.events.ZoneChangeEvent;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.target.common.TargetCreaturePermanent;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
@ -69,9 +68,6 @@ public class ColossalWhale extends CardImpl {
|
|||
this.addAbility(new IslandwalkAbility());
|
||||
// Whenever Colossal Whale attacks, you may exile target creature defending player controls until Colossal Whale leaves the battlefield.
|
||||
this.addAbility(new ColossalWhaleAbility());
|
||||
// Implemented as triggered effect that doesn't uses the stack (implementation with watcher does not work correctly because if the returned creature
|
||||
// has a DiesTriggeredAll ability it triggers for the dying Banish Priest, what shouldn't happen)
|
||||
this.addAbility(new ColossalWhaleReturnExiledAbility());
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -90,6 +86,7 @@ class ColossalWhaleAbility extends TriggeredAbilityImpl {
|
|||
public ColossalWhaleAbility() {
|
||||
super(Zone.BATTLEFIELD, null);
|
||||
this.addEffect(new ColossalWhaleExileEffect());
|
||||
this.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility()));
|
||||
}
|
||||
|
||||
public ColossalWhaleAbility(final ColossalWhaleAbility ability) {
|
||||
|
|
@ -144,76 +141,7 @@ class ColossalWhaleExileEffect extends OneShotEffect {
|
|||
// If Whale leaves the battlefield before its triggered ability resolves,
|
||||
// the target creature won't be exiled.
|
||||
if (permanent != null) {
|
||||
return new ExileTargetEffect(source.getSourceId(), permanent.getName()).apply(game, source);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the exiled card as Banisher Priest leaves battlefield
|
||||
* Uses no stack
|
||||
* @author LevelX2
|
||||
*/
|
||||
|
||||
class ColossalWhaleReturnExiledAbility extends TriggeredAbilityImpl {
|
||||
|
||||
public ColossalWhaleReturnExiledAbility() {
|
||||
super(Zone.BATTLEFIELD, new ReturnExiledCreatureColossalWhaleEffect());
|
||||
this.usesStack = false;
|
||||
this.setRuleVisible(false);
|
||||
}
|
||||
|
||||
public ColossalWhaleReturnExiledAbility(final ColossalWhaleReturnExiledAbility ability) {
|
||||
super(ability);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ColossalWhaleReturnExiledAbility copy() {
|
||||
return new ColossalWhaleReturnExiledAbility(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
if (event.getType() == GameEvent.EventType.ZONE_CHANGE && event.getTargetId().equals(this.getSourceId())) {
|
||||
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
|
||||
if (zEvent.getFromZone() == Zone.BATTLEFIELD) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
class ReturnExiledCreatureColossalWhaleEffect extends OneShotEffect {
|
||||
|
||||
public ReturnExiledCreatureColossalWhaleEffect() {
|
||||
super(Outcome.Benefit);
|
||||
this.staticText = "Return exiled creatures";
|
||||
}
|
||||
|
||||
public ReturnExiledCreatureColossalWhaleEffect(final ReturnExiledCreatureColossalWhaleEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReturnExiledCreatureColossalWhaleEffect copy() {
|
||||
return new ReturnExiledCreatureColossalWhaleEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
ExileZone exile = game.getExile().getExileZone(source.getSourceId());
|
||||
Card sourceCard = game.getCard(source.getSourceId());
|
||||
if (exile != null && sourceCard != null) {
|
||||
LinkedList<UUID> cards = new LinkedList<>(exile);
|
||||
for (UUID cardId : cards) {
|
||||
Card card = game.getCard(cardId);
|
||||
card.moveToZone(Zone.BATTLEFIELD, source.getSourceId(), game, false);
|
||||
game.informPlayers(new StringBuilder(sourceCard.getName()).append(": ").append(card.getName()).append(" returns to battlefield from exile").toString());
|
||||
}
|
||||
exile.clear();
|
||||
return true;
|
||||
return new ExileTargetEffect(CardUtil.getCardExileZoneId(game, source), permanent.getName()).apply(game, source);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,18 +27,16 @@
|
|||
*/
|
||||
package mage.sets.magic2015;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.DelayedTriggeredAbility;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
|
||||
import mage.abilities.effects.common.ExileTargetEffect;
|
||||
import mage.abilities.effects.common.continious.GainAbilityAllEffect;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
|
|
@ -49,13 +47,10 @@ import mage.constants.Zone;
|
|||
import mage.filter.common.FilterControlledCreaturePermanent;
|
||||
import mage.filter.common.FilterCreaturePermanent;
|
||||
import mage.filter.predicate.permanent.ControllerPredicate;
|
||||
import mage.game.ExileZone;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.events.ZoneChangeEvent;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.target.common.TargetCreaturePermanent;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
@ -83,7 +78,7 @@ public class ConstrictingSliver extends CardImpl {
|
|||
// until this creature leaves the battlefield."
|
||||
Ability ability = new EntersBattlefieldTriggeredAbility(new ConstrictingSliverExileEffect(), true);
|
||||
ability.addTarget(new TargetCreaturePermanent(filterTarget));
|
||||
ability.addEffect(new ConstrictingSliverAddDelayedReturnEffect());
|
||||
ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility()));
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD,
|
||||
new GainAbilityAllEffect(ability,
|
||||
Duration.WhileOnBattlefield, new FilterControlledCreaturePermanent("Sliver","Sliver creatures"),
|
||||
|
|
@ -123,107 +118,7 @@ class ConstrictingSliverExileEffect extends OneShotEffect {
|
|||
// If the creature leaves the battlefield before its triggered ability resolves,
|
||||
// the target creature won't be exiled.
|
||||
if (permanent != null) {
|
||||
return new ExileTargetEffect(source.getSourceId(), permanent.getLogName()).apply(game, source);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
class ConstrictingSliverAddDelayedReturnEffect extends OneShotEffect {
|
||||
|
||||
public ConstrictingSliverAddDelayedReturnEffect() {
|
||||
super(Outcome.Benefit);
|
||||
this.staticText = "";
|
||||
}
|
||||
|
||||
public ConstrictingSliverAddDelayedReturnEffect(final ConstrictingSliverAddDelayedReturnEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConstrictingSliverAddDelayedReturnEffect copy() {
|
||||
return new ConstrictingSliverAddDelayedReturnEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
DelayedTriggeredAbility delayedAbility = new ConstrictingSliverReturnExiledCreatureAbility();
|
||||
delayedAbility.setSourceId(source.getSourceId());
|
||||
delayedAbility.setControllerId(source.getControllerId());
|
||||
game.addDelayedTriggeredAbility(delayedAbility);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the exiled card as creature leaves battlefield
|
||||
* Uses no stack
|
||||
* @author LevelX2
|
||||
*/
|
||||
|
||||
class ConstrictingSliverReturnExiledCreatureAbility extends DelayedTriggeredAbility {
|
||||
|
||||
public ConstrictingSliverReturnExiledCreatureAbility() {
|
||||
super(new ConstrictingSliverReturnExiledCreatureEffect(), Duration.OneUse);
|
||||
this.usesStack = false;
|
||||
this.setRuleVisible(false);
|
||||
}
|
||||
|
||||
public ConstrictingSliverReturnExiledCreatureAbility(final ConstrictingSliverReturnExiledCreatureAbility ability) {
|
||||
super(ability);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConstrictingSliverReturnExiledCreatureAbility copy() {
|
||||
return new ConstrictingSliverReturnExiledCreatureAbility(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
if (event.getType() == GameEvent.EventType.ZONE_CHANGE && event.getTargetId().equals(this.getSourceId())) {
|
||||
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
|
||||
if (zEvent.getFromZone() == Zone.BATTLEFIELD) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
class ConstrictingSliverReturnExiledCreatureEffect extends OneShotEffect {
|
||||
|
||||
public ConstrictingSliverReturnExiledCreatureEffect() {
|
||||
super(Outcome.Benefit);
|
||||
this.staticText = "Return exiled creatures";
|
||||
}
|
||||
|
||||
public ConstrictingSliverReturnExiledCreatureEffect(final ConstrictingSliverReturnExiledCreatureEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConstrictingSliverReturnExiledCreatureEffect copy() {
|
||||
return new ConstrictingSliverReturnExiledCreatureEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller != null) {
|
||||
ExileZone exile = game.getExile().getExileZone(source.getSourceId());
|
||||
MageObject sourceObject = game.getObject(source.getSourceId());
|
||||
if (exile != null && sourceObject != null) {
|
||||
LinkedList<UUID> cards = new LinkedList<>(exile);
|
||||
for (UUID cardId : cards) {
|
||||
Card card = game.getCard(cardId);
|
||||
card.moveToZone(Zone.BATTLEFIELD, source.getSourceId(), game, false);
|
||||
game.informPlayers(new StringBuilder(sourceObject.getName()).append(": ").append(card.getName()).append(" returns to battlefield from exile").toString());
|
||||
}
|
||||
exile.clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
return new ExileTargetEffect(CardUtil.getCardExileZoneId(game, source), permanent.getLogName()).apply(game, source);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ class DryadMilitantReplacementEffect extends ReplacementEffectImpl {
|
|||
if (controller != null) {
|
||||
Card card = game.getCard(event.getTargetId());
|
||||
if (card != null) {
|
||||
return controller.moveCardToExileWithInfo(card, null, "", source.getSourceId(), game, null);
|
||||
return controller.moveCardToExileWithInfo(card, null, "", source.getSourceId(), game, game.getState().getZone(card.getId()));
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -27,33 +27,29 @@
|
|||
*/
|
||||
package mage.sets.theros;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.TriggeredAbilityImpl;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.AttachEffect;
|
||||
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
|
||||
import mage.abilities.effects.common.ExileTargetEffect;
|
||||
import mage.abilities.keyword.EnchantAbility;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Rarity;
|
||||
import mage.constants.TargetController;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.common.FilterControlledLandPermanent;
|
||||
import mage.filter.common.FilterCreaturePermanent;
|
||||
import mage.filter.predicate.mageobject.SubtypePredicate;
|
||||
import mage.filter.predicate.permanent.ControllerPredicate;
|
||||
import mage.game.ExileZone;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.events.ZoneChangeEvent;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.target.TargetPermanent;
|
||||
import mage.target.common.TargetCreaturePermanent;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
/**
|
||||
* If the land Chained to the Rocks is enchanting stops being a Mountain or another player
|
||||
|
|
@ -112,10 +108,8 @@ public class ChainedToTheRocks extends CardImpl {
|
|||
// When Chained to the Rocks enters the battlefield, exile target creature an opponent controls until Chained to the Rocks leaves the battlefield. (That creature returns under its owner's control.)
|
||||
ability = new EntersBattlefieldTriggeredAbility(new ChainedToTheRocksEffect());
|
||||
ability.addTarget(new TargetCreaturePermanent(filterTarget));
|
||||
ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility()));
|
||||
this.addAbility(ability);
|
||||
// Implemented as triggered effect that doesn't uses the stack (implementation with watcher does not work correctly because if the returned creature
|
||||
// has a DiesTriggeredAll ability it triggers for the battlefield leaving Chained to the Rocks, what shouldn't happen)
|
||||
this.addAbility(new ChainedToTheRocksReturnExiledAbility());
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -151,77 +145,7 @@ class ChainedToTheRocksEffect extends OneShotEffect {
|
|||
// If Chained to the Rocks leaves the battlefield before its triggered ability resolves,
|
||||
// the target creature won't be exiled.
|
||||
if (permanent != null) {
|
||||
return new ExileTargetEffect(source.getSourceId(), permanent.getLogName()).apply(game, source);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the exiled card as Chained to the Rocks leaves battlefield
|
||||
* Uses no stack
|
||||
* @author LevelX2
|
||||
*/
|
||||
|
||||
class ChainedToTheRocksReturnExiledAbility extends TriggeredAbilityImpl {
|
||||
|
||||
public ChainedToTheRocksReturnExiledAbility() {
|
||||
super(Zone.BATTLEFIELD, new ReturnExiledCreatureChainedToTheRocksEffect());
|
||||
this.usesStack = false;
|
||||
this.setRuleVisible(false);
|
||||
}
|
||||
|
||||
public ChainedToTheRocksReturnExiledAbility(final ChainedToTheRocksReturnExiledAbility ability) {
|
||||
super(ability);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChainedToTheRocksReturnExiledAbility copy() {
|
||||
return new ChainedToTheRocksReturnExiledAbility(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
if (event.getType() == GameEvent.EventType.ZONE_CHANGE && event.getTargetId().equals(this.getSourceId())) {
|
||||
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
|
||||
if (zEvent.getFromZone() == Zone.BATTLEFIELD) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
class ReturnExiledCreatureChainedToTheRocksEffect extends OneShotEffect {
|
||||
|
||||
public ReturnExiledCreatureChainedToTheRocksEffect() {
|
||||
super(Outcome.Benefit);
|
||||
this.staticText = "Return exiled creatures";
|
||||
}
|
||||
|
||||
public ReturnExiledCreatureChainedToTheRocksEffect(final ReturnExiledCreatureChainedToTheRocksEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReturnExiledCreatureChainedToTheRocksEffect copy() {
|
||||
return new ReturnExiledCreatureChainedToTheRocksEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
ExileZone exile = game.getExile().getExileZone(source.getSourceId());
|
||||
Card sourceCard = game.getCard(source.getSourceId());
|
||||
if (exile != null && sourceCard != null) {
|
||||
LinkedList<UUID> cards = new LinkedList<>(exile);
|
||||
for (UUID cardId : cards) {
|
||||
Card card = game.getCard(cardId);
|
||||
card.moveToZone(Zone.BATTLEFIELD, source.getSourceId(), game, false);
|
||||
game.informPlayers(new StringBuilder(sourceCard.getName()).append(": ").append(card.getName()).append(" returns to battlefield from exile").toString());
|
||||
}
|
||||
exile.clear();
|
||||
return true;
|
||||
return new ExileTargetEffect(CardUtil.getCardExileZoneId(game, source), permanent.getLogName()).apply(game, source);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -156,8 +156,8 @@ class WhipOfErebosReplacementEffect extends ReplacementEffectImpl {
|
|||
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
|
||||
Card card = game.getCard(source.getFirstTarget());
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (card != null && controller != null) {
|
||||
controller.moveCardToExileWithInfo(card, null, null, source.getSourceId(), game, null);
|
||||
if (card != null && controller != null) {
|
||||
controller.moveCardToExileWithInfo(card, null, null, source.getSourceId(), game, Zone.BATTLEFIELD);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue