Fixed some bugs where return to battlefield effects on end of turn could bring back cards, that should return first on next turn (e.g. Flickerwisp targets Flickerwisp).

This commit is contained in:
LevelX2 2016-10-12 17:44:58 +02:00
parent 583f696320
commit baeaaa3eb7
15 changed files with 151 additions and 78 deletions

View file

@ -35,8 +35,9 @@ import mage.abilities.common.ActivateIfConditionActivatedAbility;
import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility;
import mage.abilities.condition.common.MetalcraftCondition;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ReturnFromExileEffect;
import mage.abilities.effects.common.ReturnToBattlefieldUnderYourControlTargetEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
@ -46,6 +47,7 @@ import mage.constants.Outcome;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.targetpointer.FixedTarget;
/**
*
@ -54,7 +56,7 @@ import mage.game.permanent.Permanent;
public class ArgentSphinx extends CardImpl {
public ArgentSphinx(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{U}{U}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}{U}");
this.subtype.add("Sphinx");
this.power = new MageInt(4);
@ -100,10 +102,10 @@ class ArgentSphinxEffect extends OneShotEffect {
if (permanent != null && sourceObject != null) {
if (permanent.moveToExile(source.getSourceId(), sourceObject.getIdName(), source.getSourceId(), game)) {
//create delayed triggered ability
AtTheBeginOfNextEndStepDelayedTriggeredAbility delayedAbility
= new AtTheBeginOfNextEndStepDelayedTriggeredAbility(
new ReturnFromExileEffect(source.getSourceId(), Zone.BATTLEFIELD));
game.addDelayedTriggeredAbility(delayedAbility, source);
Effect effect = new ReturnToBattlefieldUnderYourControlTargetEffect();
effect.setText("Return it to the battlefield under your control at the beginning of the next end step");
effect.setTargetPointer(new FixedTarget(source.getSourceId(), game));
game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect), source);
return true;
}
}

View file

@ -32,17 +32,18 @@ import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.CycleAllTriggeredAbility;
import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ReturnFromExileEffect;
import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetCreaturePermanent;
import mage.target.targetpointer.FixedTarget;
/**
*
@ -51,7 +52,7 @@ import mage.target.common.TargetCreaturePermanent;
public class AstralSlide extends CardImpl {
public AstralSlide(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{W}");
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}");
// Whenever a player cycles a card, you may exile target creature. If you do, return that card to the battlefield under its owner's control at the beginning of the next end step.
Ability ability = new CycleAllTriggeredAbility(new AstralSlideEffect(), true);
@ -90,8 +91,10 @@ class AstralSlideEffect extends OneShotEffect {
UUID exileId = UUID.randomUUID();
if (controller.moveCardsToExile(permanent, source, game, true, exileId, sourceObject.getIdName())) {
//create delayed triggered ability
AtTheBeginOfNextEndStepDelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(new ReturnFromExileEffect(exileId, Zone.BATTLEFIELD, false));
game.addDelayedTriggeredAbility(delayedAbility, source);
Effect effect = new ReturnToBattlefieldUnderOwnerControlTargetEffect();
effect.setText("Return that card to the battlefield under its owner's control at the beginning of the next end step");
effect.setTargetPointer(new FixedTarget(permanent.getId(), game));
game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect), source);
}
}
return true;

View file

@ -31,16 +31,17 @@ import java.util.UUID;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ReturnFromExileEffect;
import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.common.TargetControlledCreaturePermanent;
import mage.target.targetpointer.FixedTarget;
/**
*
@ -49,7 +50,7 @@ import mage.target.common.TargetControlledCreaturePermanent;
public class EscapePod extends CardImpl {
public EscapePod(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{W}");
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{W}");
// Exile target creature you control. Return that card to the battlefield under its owner's control at the beginning of the next end step.
this.getSpellAbility().addEffect(new EscapePodEffect());
@ -84,8 +85,10 @@ class EscapePodEffect extends OneShotEffect {
MageObject sourceObject = game.getObject(source.getSourceId());
if (permanent != null && sourceObject != null) {
if (permanent.moveToExile(source.getSourceId(), sourceObject.getIdName(), source.getSourceId(), game)) {
AtTheBeginOfNextEndStepDelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(new ReturnFromExileEffect(source.getSourceId(), Zone.BATTLEFIELD, false));
game.addDelayedTriggeredAbility(delayedAbility, source);
Effect effect = new ReturnToBattlefieldUnderOwnerControlTargetEffect();
effect.setText("Return that card to the battlefield under its owner's control at the beginning of the next end step");
effect.setTargetPointer(new FixedTarget(source.getFirstTarget(), game));
game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect), source);
return true;
}
}

View file

@ -32,8 +32,9 @@ import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ReturnFromExileEffect;
import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
@ -46,6 +47,7 @@ import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetPermanent;
import mage.target.targetpointer.FixedTarget;
/**
*
@ -60,7 +62,7 @@ public class Flickerwisp extends CardImpl {
}
public Flickerwisp(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{W}{W}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}{W}");
this.subtype.add("Elemental");
this.power = new MageInt(3);
@ -104,8 +106,10 @@ class FlickerwispEffect extends OneShotEffect {
if (controller != null && permanent != null && sourcePermanent != null) {
if (controller.moveCardToExileWithInfo(permanent, source.getSourceId(), sourcePermanent.getIdName(), source.getSourceId(), game, Zone.BATTLEFIELD, true)) {
//create delayed triggered ability
game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(
new ReturnFromExileEffect(source.getSourceId(), Zone.BATTLEFIELD, false)), source);
Effect effect = new ReturnToBattlefieldUnderOwnerControlTargetEffect();
effect.setText("Return that card to the battlefield under its owner's control at the beginning of the next end step");
effect.setTargetPointer(new FixedTarget(source.getFirstTarget(), game));
game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect), source);
return true;
}
}

View file

@ -32,9 +32,10 @@ import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.CopyEffect;
import mage.abilities.effects.common.ReturnFromExileEffect;
import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
@ -50,6 +51,7 @@ import mage.game.events.GameEvent.EventType;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetCreaturePermanent;
import mage.target.targetpointer.FixedTarget;
/**
*
@ -64,7 +66,7 @@ public class IdentityThief extends CardImpl {
}
public IdentityThief(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{U}{U}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}{U}");
this.subtype.add("Shapeshifter");
this.power = new MageInt(0);
this.toughness = new MageInt(3);
@ -146,8 +148,10 @@ class IdentityThiefEffect extends OneShotEffect {
// Copy exiled permanent
game.addEffect(copyEffect, source);
// Create delayed triggered ability
game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(
new ReturnFromExileEffect(source.getSourceId(), Zone.BATTLEFIELD, false)), source);
Effect effect = new ReturnToBattlefieldUnderOwnerControlTargetEffect();
effect.setText("Return the exiled card to the battlefield under its owner's control at the beginning of the next end step");
effect.setTargetPointer(new FixedTarget(source.getFirstTarget(), game));
game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect), source);
return true;
}
}

View file

@ -31,16 +31,17 @@ import java.util.UUID;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ReturnFromExileEffect;
import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.common.TargetControlledCreaturePermanent;
import mage.target.targetpointer.FixedTarget;
/**
*
@ -50,7 +51,7 @@ import mage.target.common.TargetControlledCreaturePermanent;
public class Liberate extends CardImpl {
public Liberate(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{W}");
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{W}");
// Exile target creature you control. Return that card to the battlefield under its owner's control at the beginning of the next end step.
this.getSpellAbility().addEffect(new LiberateEffect());
@ -84,8 +85,10 @@ class LiberateEffect extends OneShotEffect {
MageObject sourceObject = game.getObject(source.getSourceId());
if (permanent != null && sourceObject != null) {
if (permanent.moveToExile(source.getSourceId(), sourceObject.getIdName(), source.getSourceId(), game)) {
AtTheBeginOfNextEndStepDelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(new ReturnFromExileEffect(source.getSourceId(), Zone.BATTLEFIELD, false));
game.addDelayedTriggeredAbility(delayedAbility, source);
Effect effect = new ReturnToBattlefieldUnderOwnerControlTargetEffect();
effect.setText("Return that card to the battlefield under its owner's control at the beginning of the next end step");
effect.setTargetPointer(new FixedTarget(source.getFirstTarget(), game));
game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect), source);
return true;
}
}

View file

@ -28,13 +28,15 @@
package mage.cards.m;
import java.util.UUID;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ReturnFromExileEffect;
import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect;
import mage.abilities.mana.ColorlessManaAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
@ -47,6 +49,7 @@ import mage.filter.predicate.permanent.ControllerPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.common.TargetCreaturePermanent;
import mage.target.targetpointer.FixedTarget;
/**
*
@ -61,8 +64,12 @@ public class MystifyingMaze extends CardImpl {
}
public MystifyingMaze(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.LAND},null);
super(ownerId, setInfo, new CardType[]{CardType.LAND}, null);
// {T}: Add Colorless to your mana pool.
this.addAbility(new ColorlessManaAbility());
// {4}, {T}: Exile target attacking creature an opponent controls. At the beginning of the next end step, return it to the battlefield tapped under its owner's control.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new MystifyingMazeEffect(), new ManaCostsImpl("{4}"));
ability.addCost(new TapSourceCost());
ability.addTarget(new TargetCreaturePermanent(filter));
@ -93,11 +100,14 @@ class MystifyingMazeEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(source.getFirstTarget());
if (permanent != null) {
if (permanent.moveToExile(source.getSourceId(), "Mystifying Maze Exile", source.getSourceId(), game)) {
MageObject sourceObject = source.getSourceObject(game);
if (permanent != null && sourceObject != null) {
if (permanent.moveToExile(source.getSourceId(), sourceObject.getIdName(), source.getSourceId(), game)) {
//create delayed triggered ability
game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(
new ReturnFromExileEffect(source.getSourceId(), Zone.BATTLEFIELD, true)), source);
Effect effect = new ReturnToBattlefieldUnderOwnerControlTargetEffect();
effect.setText("At the beginning of the next end step, return it to the battlefield tapped under its owner's control");
effect.setTargetPointer(new FixedTarget(source.getFirstTarget(), game));
game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect), source);
return true;
}
}

View file

@ -31,19 +31,20 @@ import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.abilityword.ConstellationAbility;
import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ReturnFromExileEffect;
import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.filter.FilterPermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.TargetPermanent;
import mage.target.targetpointer.FixedTarget;
/**
*
@ -58,7 +59,7 @@ public class Skybind extends CardImpl {
}
public Skybind(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{3}{W}{W}");
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{W}{W}");
// Constellation When Skybind or another enchantment enters the battlefield under your control, exile target nonenchantment permanent. Return that card to the battlefield under its owner's control at the beginning of the next end step.
Ability ability = new ConstellationAbility(new SkybindEffect(), false);
@ -94,8 +95,10 @@ class SkybindEffect extends OneShotEffect {
if (permanent != null && sourcePermanent != null) {
if (permanent.moveToExile(source.getSourceId(), sourcePermanent.getName(), source.getSourceId(), game)) {
//create delayed triggered ability
AtTheBeginOfNextEndStepDelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(new ReturnFromExileEffect(source.getSourceId(), Zone.BATTLEFIELD));
game.addDelayedTriggeredAbility(delayedAbility, source);
Effect effect = new ReturnToBattlefieldUnderOwnerControlTargetEffect();
effect.setText("Return that card to the battlefield under its owner's control at the beginning of the next end step");
effect.setTargetPointer(new FixedTarget(getTargetPointer().getFirst(game, source), game));
game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect), source);
return true;
}
}

View file

@ -27,23 +27,27 @@
*/
package mage.cards.s;
import java.util.List;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ReturnFromExileEffect;
import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.cards.Cards;
import mage.cards.CardsImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.filter.common.FilterNonlandPermanent;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetPlayer;
import mage.target.targetpointer.FixedTargets;
/**
*
@ -52,7 +56,7 @@ import mage.target.TargetPlayer;
public class SuddenDisappearance extends CardImpl {
public SuddenDisappearance(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{5}{W}");
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{5}{W}");
// Exile all nonland permanents target player controls. Return the exiled cards to the battlefield under their owner's control at the beginning of the next end step.
this.getSpellAbility().addEffect(new SuddenDisappearanceEffect());
@ -88,14 +92,17 @@ class SuddenDisappearanceEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId());
MageObject sourceObject = source.getSourceObject(game);
if (controller != null && sourceObject != null) {
List<Permanent> perms = game.getBattlefield().getAllActivePermanents(filter, source.getFirstTarget(), game);
if (perms.size() > 0) {
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, source.getFirstTarget(), game)) {
controller.moveCardToExileWithInfo(permanent, source.getSourceId(), sourceObject.getIdName(), source.getSourceId(), game, Zone.BATTLEFIELD, true);
Set<Card> permsSet = new HashSet<>(game.getBattlefield().getAllActivePermanents(filter, source.getFirstTarget(), game));
if (permsSet.size() > 0) {
controller.moveCardsToExile(permsSet, source, game, true, source.getSourceId(), sourceObject.getIdName());
Cards targets = new CardsImpl();
for (Card card : permsSet) {
targets.add(card.getId());
}
AtTheBeginOfNextEndStepDelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(new ReturnFromExileEffect(source.getSourceId(), Zone.BATTLEFIELD));
game.addDelayedTriggeredAbility(delayedAbility, source);
Effect effect = new ReturnToBattlefieldUnderOwnerControlTargetEffect();
effect.setText("Return the exiled cards to the battlefield under their owner's control at the beginning of the next end step");
effect.setTargetPointer(new FixedTargets(targets, game));
game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect), source);
}
return true;
}

View file

@ -38,7 +38,7 @@ import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ExileTargetEffect;
import mage.abilities.effects.common.GetEmblemEffect;
import mage.abilities.effects.common.ReturnFromExileEffect;
import mage.abilities.effects.common.ReturnToBattlefieldUnderYourControlTargetEffect;
import mage.abilities.effects.common.combat.CantBeBlockedAllEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
@ -74,7 +74,7 @@ public class VenserTheSojourner extends CardImpl {
}
public VenserTheSojourner(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.PLANESWALKER},"{3}{W}{U}");
super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{3}{W}{U}");
this.subtype.add("Venser");
this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(3));
@ -127,8 +127,10 @@ class VenserTheSojournerEffect extends OneShotEffect {
if (permanent != null) {
if (controller.moveCardToExileWithInfo(permanent, source.getSourceId(), sourceObject.getIdName(), source.getSourceId(), game, Zone.BATTLEFIELD, true)) {
//create delayed triggered ability
game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(
new ReturnFromExileEffect(source.getSourceId(), Zone.BATTLEFIELD)), source);
Effect effect = new ReturnToBattlefieldUnderYourControlTargetEffect();
effect.setText("Return it to the battlefield under your control at the beginning of the next end step");
effect.setTargetPointer(new FixedTarget(permanent.getId(), game));
game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect), source);
return true;
}
}

View file

@ -33,8 +33,9 @@ import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility;
import mage.abilities.costs.common.SacrificeSourceCost;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ReturnFromExileEffect;
import mage.abilities.effects.common.ReturnToBattlefieldUnderYourControlTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
@ -44,6 +45,7 @@ import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetCreaturePermanent;
import mage.target.targetpointer.FixedTarget;
/**
*
@ -52,7 +54,7 @@ import mage.target.common.TargetCreaturePermanent;
public class VoyagerStaff extends CardImpl {
public VoyagerStaff(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{1}");
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}");
// {2}, Sacrifice Voyager Staff: Exile target creature. Return the exiled card to the battlefield under its owner's control at the beginning of the next end step.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new VoyagerStaffEffect(), new GenericManaCost(2));
@ -90,8 +92,10 @@ class VoyagerStaffEffect extends OneShotEffect {
if (controller != null && creature != null && sourcePermanent != null) {
if (controller.moveCardToExileWithInfo(creature, source.getSourceId(), sourcePermanent.getIdName(), source.getSourceId(), game, Zone.BATTLEFIELD, true)) {
//create delayed triggered ability
game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(
new ReturnFromExileEffect(source.getSourceId(), Zone.BATTLEFIELD, false)), source);
Effect effect = new ReturnToBattlefieldUnderYourControlTargetEffect();
effect.setText("Return the exiled card to the battlefield under its owner's control at the beginning of the next end step");
effect.setTargetPointer(new FixedTarget(creature.getId(), game));
game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect), source);
return true;
}
}

View file

@ -38,7 +38,7 @@ import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.GetEmblemEffect;
import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
import mage.abilities.effects.common.ReturnFromExileEffect;
import mage.abilities.effects.common.ReturnToBattlefieldUnderYourControlTargetEffect;
import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
import mage.abilities.effects.common.continuous.GainAbilityControllerEffect;
import mage.abilities.keyword.HexproofAbility;
@ -58,6 +58,7 @@ import mage.game.Game;
import mage.game.command.Emblem;
import mage.game.permanent.Permanent;
import mage.target.TargetPermanent;
import mage.target.targetpointer.FixedTarget;
/**
*
@ -73,7 +74,7 @@ public class YodaJediMaster extends CardImpl {
}
public YodaJediMaster(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.PLANESWALKER},"{1}{G}{U}");
super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{1}{G}{U}");
this.subtype.add("Yoda");
this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(3));
@ -108,7 +109,7 @@ class YodaJediMasterEffect extends OneShotEffect {
public YodaJediMasterEffect() {
super(Outcome.Detriment);
staticText = "Exile another target permanent you own. Return that card to the battlefield under your control at the beggining of your next end step";
staticText = "Exile another target permanent you own. Return that card to the battlefield under your control at the beginning of your next end step";
}
public YodaJediMasterEffect(final YodaJediMasterEffect effect) {
@ -122,8 +123,10 @@ class YodaJediMasterEffect extends OneShotEffect {
if (permanent != null && sourcePermanent != null) {
if (permanent.moveToExile(source.getSourceId(), sourcePermanent.getName(), source.getSourceId(), game)) {
//create delayed triggered ability
AtTheBeginOfNextEndStepDelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(new ReturnFromExileEffect(source.getSourceId(), Zone.BATTLEFIELD));
game.addDelayedTriggeredAbility(delayedAbility, source);
Effect effect = new ReturnToBattlefieldUnderYourControlTargetEffect();
effect.setText("Return that card to the battlefield under your control at the beginning of your next end step");
effect.setTargetPointer(new FixedTarget(permanent.getId(), game));
game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect), source);
return true;
}
}

View file

@ -1,16 +1,16 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
@ -20,12 +20,11 @@
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.abilities;
import mage.abilities.effects.Effect;
@ -49,6 +48,7 @@ public abstract class DelayedTriggeredAbility extends TriggeredAbilityImpl {
public DelayedTriggeredAbility(Effect effect, Duration duration) {
this(effect, duration, true);
}
public DelayedTriggeredAbility(Effect effect, Duration duration, Boolean triggerOnlyOnce) {
this(effect, duration, triggerOnlyOnce, false);
}
@ -75,13 +75,25 @@ public abstract class DelayedTriggeredAbility extends TriggeredAbilityImpl {
public Boolean getTriggerOnlyOnce() {
return triggerOnlyOnce;
}
/**
* This method is called as the ability is added to the game (not as the
* ability triggers later)
*
* @param game
*/
public void initOnAdding(Game game) {
}
public void init(Game game) {
for (Effect effect: this.getEffects()) {
for (Effect effect : this.getEffects()) {
effect.getTargetPointer().init(game, this);
}
};
}
;
public boolean isInactive(Game game) {
return false;
}

View file

@ -159,7 +159,6 @@ public abstract class GameImpl implements Game, Serializable {
FILTER_LEGENDARY.add(new SupertypePredicate("Legendary"));
}
private transient Object customData;
protected boolean simulation = false;
@ -1520,10 +1519,11 @@ public abstract class GameImpl implements Game, Serializable {
// return addDelayedTriggeredAbility(delayedAbility);
DelayedTriggeredAbility newAbility = delayedAbility.copy();
newAbility.newId();
newAbility.initOnAdding(this);
// ability.init is called as the ability triggeres not now.
// If a FixedTarget pointer is already set from the effect setting up this delayed ability
// it has to be already initialized so it won't be overwitten as the ability triggers
state.addDelayedTriggeredAbility(newAbility);
getState().addDelayedTriggeredAbility(newAbility);
return newAbility.getId();
}
@ -1532,10 +1532,11 @@ public abstract class GameImpl implements Game, Serializable {
public UUID addDelayedTriggeredAbility(DelayedTriggeredAbility delayedAbility) {
DelayedTriggeredAbility newAbility = delayedAbility.copy();
newAbility.newId();
newAbility.initOnAdding(this);
// ability.init is called as the ability triggeres not now.
// If a FixedTarget pointer is already set from the effect setting up this delayed ability
// it has to be already initialized so it won't be overwitten as the ability triggers
state.addDelayedTriggeredAbility(newAbility);
getState().addDelayedTriggeredAbility(newAbility);
return newAbility.getId();
}

View file

@ -41,6 +41,18 @@ public class FixedTarget implements TargetPointer {
this.zoneChangeCounter = zoneChangeCounter;
}
/**
* Use this to set the target to exactly the zone the target is currently in
*
* @param targetId
* @param game
*/
public FixedTarget(UUID targetId, Game game) {
this.targetId = targetId;
this.initialized = true;
this.zoneChangeCounter = game.getState().getZoneChangeCounter(targetId);
}
public FixedTarget(final FixedTarget fixedTarget) {
this.targetId = fixedTarget.targetId;
this.zoneChangeCounter = fixedTarget.zoneChangeCounter;