Fixed a problem with casting split cards from non hand zone. Added some generic cast from non hand zone effects and started replacing card specific effects by the generic ones (fixes #5356 and fixes #4493).

This commit is contained in:
LevelX2 2018-10-03 13:44:01 +02:00
parent c097ec053f
commit c41c6e1fe9
25 changed files with 304 additions and 476 deletions

View file

@ -1,4 +1,3 @@
package mage.cards.a; package mage.cards.a;
import java.util.HashMap; import java.util.HashMap;
@ -7,18 +6,18 @@ import java.util.Map.Entry;
import java.util.UUID; import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.AsThoughEffectImpl;
import mage.abilities.effects.ReplacementEffectImpl; import mage.abilities.effects.ReplacementEffectImpl;
import mage.abilities.effects.common.asthought.PlayFromNotOwnHandZoneAllEffect;
import mage.abilities.keyword.CyclingAbility; import mage.abilities.keyword.CyclingAbility;
import mage.cards.Card; import mage.cards.Card;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.cards.Cards; import mage.cards.Cards;
import mage.cards.CardsImpl; import mage.cards.CardsImpl;
import mage.constants.AsThoughEffectType;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Duration; import mage.constants.Duration;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.constants.TargetController;
import mage.constants.WatcherScope; import mage.constants.WatcherScope;
import mage.constants.Zone; import mage.constants.Zone;
import mage.filter.FilterCard; import mage.filter.FilterCard;
@ -42,7 +41,14 @@ public final class AbandonedSarcophagus extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}"); super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}");
// You may cast nonland cards with cycling from your graveyard. // You may cast nonland cards with cycling from your graveyard.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new AbandonedSarcophagusCastFromGraveyardEffect())); FilterCard filter = new FilterCard("nonland cards with cycling");
filter.add(Predicates.not(new CardTypePredicate(CardType.LAND)));
filter.add(new AbilityPredicate(CyclingAbility.class));
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD,
new PlayFromNotOwnHandZoneAllEffect(filter,
Zone.GRAVEYARD, true, TargetController.YOU, Duration.WhileOnBattlefield)
.setText("You may cast nonland cards with cycling from your graveyard"))
);
// If a card with cycling would be put into your graveyard from anywhere and it wasn't cycled, exile it instead. // If a card with cycling would be put into your graveyard from anywhere and it wasn't cycled, exile it instead.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new AbandonedSarcophagusReplacementEffect()), new AbandonedSarcophagusWatcher()); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new AbandonedSarcophagusReplacementEffect()), new AbandonedSarcophagusWatcher());
@ -59,46 +65,6 @@ public final class AbandonedSarcophagus extends CardImpl {
} }
} }
class AbandonedSarcophagusCastFromGraveyardEffect extends AsThoughEffectImpl {
private static final FilterCard filter = new FilterCard("nonland cards with cycling");
static {
filter.add(Predicates.not(new CardTypePredicate(CardType.LAND)));
filter.add(new AbilityPredicate(CyclingAbility.class));
}
AbandonedSarcophagusCastFromGraveyardEffect() {
super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.WhileOnBattlefield, Outcome.Benefit);
staticText = "You may cast nonland cards with cycling from your graveyard";
}
AbandonedSarcophagusCastFromGraveyardEffect(final AbandonedSarcophagusCastFromGraveyardEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
return true;
}
@Override
public AbandonedSarcophagusCastFromGraveyardEffect copy() {
return new AbandonedSarcophagusCastFromGraveyardEffect(this);
}
@Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
Card card = game.getCard(objectId);
if (card != null) {
return (affectedControllerId.equals(source.getControllerId())
&& filter.match(card, game)
&& game.getState().getZone(card.getId()) == Zone.GRAVEYARD);
}
return false;
}
}
class AbandonedSarcophagusReplacementEffect extends ReplacementEffectImpl { class AbandonedSarcophagusReplacementEffect extends ReplacementEffectImpl {
boolean cardHasCycling; boolean cardHasCycling;

View file

@ -1,4 +1,3 @@
package mage.cards.a; package mage.cards.a;
import java.util.UUID; import java.util.UUID;
@ -8,6 +7,7 @@ import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.AsThoughEffectImpl; import mage.abilities.effects.AsThoughEffectImpl;
import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.asthought.PlayFromNotOwnHandZoneTargetEffect;
import mage.abilities.keyword.ProwessAbility; import mage.abilities.keyword.ProwessAbility;
import mage.cards.Card; import mage.cards.Card;
import mage.cards.CardImpl; import mage.cards.CardImpl;
@ -75,7 +75,7 @@ class AbbotOfKeralKeepExileEffect extends OneShotEffect {
if (card != null) { if (card != null) {
String exileName = sourcePermanent.getIdName() + " <this card may be played the turn it was exiled>"; String exileName = sourcePermanent.getIdName() + " <this card may be played the turn it was exiled>";
controller.moveCardsToExile(card, source, game, true, source.getSourceId(), exileName); controller.moveCardsToExile(card, source, game, true, source.getSourceId(), exileName);
ContinuousEffect effect = new AbbotOfKeralKeepCastFromExileEffect(); ContinuousEffect effect = new PlayFromNotOwnHandZoneTargetEffect(Duration.EndOfTurn);
effect.setTargetPointer(new FixedTarget(card.getId(), card.getZoneChangeCounter(game))); effect.setTargetPointer(new FixedTarget(card.getId(), card.getZoneChangeCounter(game)));
game.addEffect(effect, source); game.addEffect(effect, source);
} }

View file

@ -1,4 +1,3 @@
package mage.cards.a; package mage.cards.a;
import java.util.HashSet; import java.util.HashSet;
@ -6,9 +5,9 @@ import java.util.Set;
import java.util.UUID; import java.util.UUID;
import mage.MageObject; import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.effects.AsThoughEffectImpl;
import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.asthought.PlayFromNotOwnHandZoneTargetEffect;
import mage.cards.Card; import mage.cards.Card;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
@ -44,7 +43,7 @@ class ActOnImpulseExileEffect extends OneShotEffect {
public ActOnImpulseExileEffect() { public ActOnImpulseExileEffect() {
super(Outcome.Benefit); super(Outcome.Benefit);
this.staticText = "Exile the top three cards of your library. Until end of turn, you may play cards exiled this way."; this.staticText = "Exile the top three cards of your library. Until end of turn, you may play cards exiled this way";
} }
public ActOnImpulseExileEffect(final ActOnImpulseExileEffect effect) { public ActOnImpulseExileEffect(final ActOnImpulseExileEffect effect) {
@ -71,7 +70,7 @@ class ActOnImpulseExileEffect extends OneShotEffect {
} }
} }
if (!cards.isEmpty()) { if (!cards.isEmpty()) {
ContinuousEffect effect = new ActOnImpulseMayPlayExiledEffect(); ContinuousEffect effect = new PlayFromNotOwnHandZoneTargetEffect(Zone.EXILED, Duration.EndOfTurn);
effect.setTargetPointer(new FixedTargets(cards, game)); effect.setTargetPointer(new FixedTargets(cards, game));
game.addEffect(effect, source); game.addEffect(effect, source);
} }
@ -82,31 +81,3 @@ class ActOnImpulseExileEffect extends OneShotEffect {
} }
} }
class ActOnImpulseMayPlayExiledEffect extends AsThoughEffectImpl {
public ActOnImpulseMayPlayExiledEffect() {
super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.EndOfTurn, Outcome.Benefit);
}
public ActOnImpulseMayPlayExiledEffect(final ActOnImpulseMayPlayExiledEffect effect) {
super(effect);
}
@Override
public ActOnImpulseMayPlayExiledEffect copy() {
return new ActOnImpulseMayPlayExiledEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
return true;
}
@Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
return affectedControllerId.equals(source.getControllerId())
&& getTargetPointer().getTargets(game, source).contains(objectId);
}
}

View file

@ -1,4 +1,3 @@
package mage.cards.a; package mage.cards.a;
import java.util.UUID; import java.util.UUID;
@ -6,18 +5,18 @@ import mage.MageInt;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.AsThoughEffectImpl;
import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.asthought.PlayFromNotOwnHandZoneTargetEffect;
import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.FlyingAbility;
import mage.cards.Card; import mage.cards.Card;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.AsThoughEffectType;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Duration; import mage.constants.Duration;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.constants.SubType; import mage.constants.SubType;
import mage.constants.Zone;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.players.Library; import mage.players.Library;
@ -81,7 +80,7 @@ class AerialCaravanExileEffect extends OneShotEffect {
if (card != null) { if (card != null) {
String exileName = sourcePermanent.getIdName() + " <this card may be played the turn it was exiled>"; String exileName = sourcePermanent.getIdName() + " <this card may be played the turn it was exiled>";
controller.moveCardsToExile(card, source, game, true, source.getSourceId(), exileName); controller.moveCardsToExile(card, source, game, true, source.getSourceId(), exileName);
ContinuousEffect effect = new AerialCaravanCastFromExileEffect(); ContinuousEffect effect = new PlayFromNotOwnHandZoneTargetEffect(Zone.EXILED, Duration.EndOfTurn);
effect.setTargetPointer(new FixedTarget(card.getId(), card.getZoneChangeCounter(game))); effect.setTargetPointer(new FixedTarget(card.getId(), card.getZoneChangeCounter(game)));
game.addEffect(effect, source); game.addEffect(effect, source);
} }
@ -90,31 +89,3 @@ class AerialCaravanExileEffect extends OneShotEffect {
return false; return false;
} }
} }
class AerialCaravanCastFromExileEffect extends AsThoughEffectImpl {
public AerialCaravanCastFromExileEffect() {
super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.EndOfTurn, Outcome.Benefit);
staticText = "You may play the card from exile";
}
public AerialCaravanCastFromExileEffect(final AerialCaravanCastFromExileEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
return true;
}
@Override
public AerialCaravanCastFromExileEffect copy() {
return new AerialCaravanCastFromExileEffect(this);
}
@Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
return source.isControlledBy(affectedControllerId)
&& objectId.equals(getTargetPointer().getFirst(game, source));
}
}

View file

@ -4,14 +4,13 @@ import java.util.Set;
import java.util.UUID; import java.util.UUID;
import mage.MageObject; import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.effects.AsThoughEffectImpl;
import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.asthought.PlayFromNotOwnHandZoneTargetEffect;
import mage.abilities.effects.mana.AddManaOfAnyColorEffect; import mage.abilities.effects.mana.AddManaOfAnyColorEffect;
import mage.cards.Card; import mage.cards.Card;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.AsThoughEffectType;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Duration; import mage.constants.Duration;
import mage.constants.Outcome; import mage.constants.Outcome;
@ -79,7 +78,7 @@ class ApexOfPowerSpellEffect extends OneShotEffect {
if (card.isLand()) { if (card.isLand()) {
continue; continue;
} }
ContinuousEffect effect = new ApexOfPowerCastFromExileEffect(); ContinuousEffect effect = new PlayFromNotOwnHandZoneTargetEffect(Zone.EXILED, Duration.EndOfTurn);
effect.setTargetPointer(new FixedTarget(card.getId(), card.getZoneChangeCounter(game))); effect.setTargetPointer(new FixedTarget(card.getId(), card.getZoneChangeCounter(game)));
game.addEffect(effect, source); game.addEffect(effect, source);
} }
@ -87,34 +86,6 @@ class ApexOfPowerSpellEffect extends OneShotEffect {
} }
} }
class ApexOfPowerCastFromExileEffect extends AsThoughEffectImpl {
public ApexOfPowerCastFromExileEffect() {
super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.EndOfTurn, Outcome.Benefit);
staticText = "You may play the card from exile";
}
public ApexOfPowerCastFromExileEffect(final ApexOfPowerCastFromExileEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
return true;
}
@Override
public ApexOfPowerCastFromExileEffect copy() {
return new ApexOfPowerCastFromExileEffect(this);
}
@Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
return source.isControlledBy(affectedControllerId)
&& objectId.equals(getTargetPointer().getFirst(game, source));
}
}
class ApexOfPowerManaEffect extends OneShotEffect { class ApexOfPowerManaEffect extends OneShotEffect {
public ApexOfPowerManaEffect() { public ApexOfPowerManaEffect() {

View file

@ -1,4 +1,3 @@
package mage.cards.c; package mage.cards.c;
import java.util.HashSet; import java.util.HashSet;
@ -9,9 +8,9 @@ import mage.MageObjectReference;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility; import mage.abilities.LoyaltyAbility;
import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility; import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.effects.AsThoughEffectImpl;
import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.asthought.PlayFromNotOwnHandZoneTargetEffect;
import mage.abilities.effects.common.combat.CantBlockTargetEffect; import mage.abilities.effects.common.combat.CantBlockTargetEffect;
import mage.cards.*; import mage.cards.*;
import mage.constants.*; import mage.constants.*;
@ -20,7 +19,6 @@ import mage.filter.common.FilterInstantOrSorceryCard;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.game.stack.StackObject; import mage.game.stack.StackObject;
import mage.players.Library;
import mage.players.Player; import mage.players.Player;
import mage.target.Target; import mage.target.Target;
import mage.target.TargetCard; import mage.target.TargetCard;
@ -177,12 +175,13 @@ class ChandraPyromasterEffect2 extends OneShotEffect {
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
MageObject sourceObject = source.getSourceObject(game); MageObject sourceObject = source.getSourceObject(game);
if (controller != null && sourceObject != null && controller.getLibrary().hasCards()) { if (controller != null && sourceObject != null) {
Library library = controller.getLibrary(); Card card = controller.getLibrary().getFromTop(game);
Card card = library.getFromTop(game);
if (card != null) { if (card != null) {
controller.moveCardToExileWithInfo(card, source.getSourceId(), sourceObject.getIdName() + " <this card may be played the turn it was exiled>", source.getSourceId(), game, Zone.LIBRARY, true); controller.moveCards(card, Zone.EXILED, source, game);
game.addEffect(new ChandraPyromasterPlayEffect(new MageObjectReference(card, game)), source); ContinuousEffect effect = new PlayFromNotOwnHandZoneTargetEffect(Zone.EXILED, Duration.EndOfTurn);
effect.setTargetPointer(new FixedTarget(card, game));
game.addEffect(effect, source);
} }
return true; return true;
} }
@ -190,45 +189,6 @@ class ChandraPyromasterEffect2 extends OneShotEffect {
} }
} }
class ChandraPyromasterPlayEffect extends AsThoughEffectImpl {
private final MageObjectReference objectReference;
public ChandraPyromasterPlayEffect(MageObjectReference objectReference) {
super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.EndOfTurn, Outcome.Benefit);
this.objectReference = objectReference;
staticText = "you may play that card until end of turn";
}
public ChandraPyromasterPlayEffect(final ChandraPyromasterPlayEffect effect) {
super(effect);
this.objectReference = effect.objectReference;
}
@Override
public boolean apply(Game game, Ability source) {
return true;
}
@Override
public ChandraPyromasterPlayEffect copy() {
return new ChandraPyromasterPlayEffect(this);
}
@Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
if (objectReference.refersTo(objectId, game) && affectedControllerId.equals(source.getControllerId())) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
return true;
} else {
discard();
}
}
return false;
}
}
class ChandraPyromasterEffect3 extends OneShotEffect { class ChandraPyromasterEffect3 extends OneShotEffect {
public ChandraPyromasterEffect3() { public ChandraPyromasterEffect3() {

View file

@ -1,4 +1,3 @@
package mage.cards.c; package mage.cards.c;
import java.util.Set; import java.util.Set;
@ -23,7 +22,7 @@ import mage.util.CardUtil;
public final class CommuneWithLava extends CardImpl { public final class CommuneWithLava extends CardImpl {
public CommuneWithLava(UUID ownerId, CardSetInfo setInfo) { public CommuneWithLava(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{X}{R}{R}"); super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{X}{R}{R}");
// Exile the top X cards of your library. Until the end of your next turn, you may play those cards. // Exile the top X cards of your library. Until the end of your next turn, you may play those cards.
this.getSpellAbility().addEffect(new CommuneWithLavaEffect()); this.getSpellAbility().addEffect(new CommuneWithLavaEffect());

View file

@ -1,4 +1,3 @@
package mage.cards.c; package mage.cards.c;
import java.util.UUID; import java.util.UUID;
@ -8,6 +7,7 @@ import mage.abilities.effects.AsThoughEffectImpl;
import mage.abilities.effects.AsThoughManaEffect; import mage.abilities.effects.AsThoughManaEffect;
import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.asthought.PlayFromNotOwnHandZoneTargetEffect;
import mage.cards.Card; import mage.cards.Card;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
@ -28,7 +28,7 @@ import mage.util.CardUtil;
public final class CunningAbduction extends CardImpl { public final class CunningAbduction extends CardImpl {
public CunningAbduction(UUID ownerId, CardSetInfo setInfo) { public CunningAbduction(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{1}{U}{B}"); super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{U}{B}");
// Target opponent reveals their hand. You choose a nonland card from that player's hand and exile it. You may cast that card for as long as it remains exiled, and you may spend mana as though it were mana of any color to cast that spell. // Target opponent reveals their hand. You choose a nonland card from that player's hand and exile it. You may cast that card for as long as it remains exiled, and you may spend mana as though it were mana of any color to cast that spell.
this.getSpellAbility().addTarget(new TargetOpponent()); this.getSpellAbility().addTarget(new TargetOpponent());
@ -82,10 +82,10 @@ class CunningAbductionExileEffect extends OneShotEffect {
if (card != null) { if (card != null) {
// move card to exile // move card to exile
UUID exileId = CardUtil.getCardExileZoneId(game, source); UUID exileId = CardUtil.getCardExileZoneId(game, source);
controller.moveCardToExileWithInfo(card, exileId, sourceObject.getIdName(), source.getSourceId(), game, Zone.HAND, true); controller.moveCardsToExile(card, source, game, true, exileId, sourceObject.getIdName());
// allow to cast the card // allow to cast the card
ContinuousEffect effect = new CunningAbductionCastFromExileEffect(); ContinuousEffect effect = new PlayFromNotOwnHandZoneTargetEffect(Zone.EXILED, Duration.Custom);
effect.setTargetPointer(new FixedTarget(card.getId())); effect.setTargetPointer(new FixedTarget(card, game));
game.addEffect(effect, source); game.addEffect(effect, source);
// and you may spend mana as though it were mana of any color to cast it // and you may spend mana as though it were mana of any color to cast it
effect = new CunningAbductionSpendAnyManaEffect(); effect = new CunningAbductionSpendAnyManaEffect();
@ -99,41 +99,6 @@ class CunningAbductionExileEffect extends OneShotEffect {
} }
} }
class CunningAbductionCastFromExileEffect extends AsThoughEffectImpl {
public CunningAbductionCastFromExileEffect() {
super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.Custom, Outcome.Benefit);
staticText = "You may cast that card for as long as it remains exiled, and you may spend mana as though it were mana of any color to cast that spell";
}
public CunningAbductionCastFromExileEffect(final CunningAbductionCastFromExileEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
return true;
}
@Override
public CunningAbductionCastFromExileEffect copy() {
return new CunningAbductionCastFromExileEffect(this);
}
@Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
if (objectId.equals(getTargetPointer().getFirst(game, source))) {
if (affectedControllerId.equals(source.getControllerId())) {
return true;
}
} else if (((FixedTarget) getTargetPointer()).getTarget().equals(objectId)) {
// object has moved zone so effect can be discarted
this.discard();
}
return false;
}
}
class CunningAbductionSpendAnyManaEffect extends AsThoughEffectImpl implements AsThoughManaEffect { class CunningAbductionSpendAnyManaEffect extends AsThoughEffectImpl implements AsThoughManaEffect {
public CunningAbductionSpendAnyManaEffect() { public CunningAbductionSpendAnyManaEffect() {

View file

@ -1,22 +1,20 @@
package mage.cards.d; package mage.cards.d;
import java.util.UUID; import java.util.UUID;
import mage.MageObject; import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.costs.common.PayLifeCost; import mage.abilities.costs.common.PayLifeCost;
import mage.abilities.effects.AsThoughEffectImpl;
import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.asthought.PlayFromNotOwnHandZoneTargetEffect;
import mage.cards.Card; import mage.cards.Card;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.AsThoughEffectType;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Duration; import mage.constants.Duration;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.constants.Zone;
import mage.filter.common.FilterNonlandCard; import mage.filter.common.FilterNonlandCard;
import mage.game.ExileZone;
import mage.game.Game; import mage.game.Game;
import mage.players.Player; import mage.players.Player;
import mage.target.common.TargetCardInLibrary; import mage.target.common.TargetCardInLibrary;
@ -76,7 +74,7 @@ class DarkDecisionEffect extends OneShotEffect {
Card card = game.getCard(targetId); Card card = game.getCard(targetId);
if (card != null) { if (card != null) {
controller.moveCardsToExile(card, source, game, true, source.getSourceId(), sourceObject.getIdName()); controller.moveCardsToExile(card, source, game, true, source.getSourceId(), sourceObject.getIdName());
ContinuousEffect effect = new DarkDecisionMayPlayExiledEffect(); ContinuousEffect effect = new PlayFromNotOwnHandZoneTargetEffect(Zone.EXILED, Duration.EndOfTurn);
effect.setTargetPointer(new FixedTarget(card.getId(), game)); effect.setTargetPointer(new FixedTarget(card.getId(), game));
game.addEffect(effect, source); game.addEffect(effect, source);
} }
@ -88,34 +86,3 @@ class DarkDecisionEffect extends OneShotEffect {
} }
} }
class DarkDecisionMayPlayExiledEffect extends AsThoughEffectImpl {
public DarkDecisionMayPlayExiledEffect() {
super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.EndOfTurn, Outcome.Benefit);
}
public DarkDecisionMayPlayExiledEffect(final DarkDecisionMayPlayExiledEffect effect) {
super(effect);
}
@Override
public DarkDecisionMayPlayExiledEffect copy() {
return new DarkDecisionMayPlayExiledEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
return true;
}
@Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
if (objectId.equals(getTargetPointer().getFirst(game, source)) && affectedControllerId.equals(source.getControllerId())) {
ExileZone exileZone = game.getExile().getExileZone(source.getSourceId());
return exileZone != null && exileZone.contains(getTargetPointer().getFirst(game, source));
}
return false;
}
}

View file

@ -6,17 +6,17 @@ import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.SacrificeTargetCost; import mage.abilities.costs.common.SacrificeTargetCost;
import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.AsThoughEffectImpl;
import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.asthought.PlayFromNotOwnHandZoneTargetEffect;
import mage.cards.Card; import mage.cards.Card;
import mage.constants.SubType;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.AsThoughEffectType;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Duration; import mage.constants.Duration;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
import static mage.filter.StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT; import static mage.filter.StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
@ -88,8 +88,8 @@ class DarkDwellerOracleExileEffect extends OneShotEffect {
if (card != null) { if (card != null) {
String exileName = sourcePermanent.getIdName() + " <this card may be played the turn it was exiled>"; String exileName = sourcePermanent.getIdName() + " <this card may be played the turn it was exiled>";
controller.moveCardsToExile(card, source, game, true, source.getSourceId(), exileName); controller.moveCardsToExile(card, source, game, true, source.getSourceId(), exileName);
ContinuousEffect effect = new DarkDwellerOracleCastFromExileEffect(); ContinuousEffect effect = new PlayFromNotOwnHandZoneTargetEffect(Zone.EXILED, Duration.EndOfTurn);
effect.setTargetPointer(new FixedTarget(card.getId(), card.getZoneChangeCounter(game))); effect.setTargetPointer(new FixedTarget(card, game));
game.addEffect(effect, source); game.addEffect(effect, source);
} }
return true; return true;
@ -97,31 +97,3 @@ class DarkDwellerOracleExileEffect extends OneShotEffect {
return false; return false;
} }
} }
class DarkDwellerOracleCastFromExileEffect extends AsThoughEffectImpl {
public DarkDwellerOracleCastFromExileEffect() {
super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.EndOfTurn, Outcome.Benefit);
staticText = "You may play the card from exile";
}
public DarkDwellerOracleCastFromExileEffect(final DarkDwellerOracleCastFromExileEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
return true;
}
@Override
public DarkDwellerOracleCastFromExileEffect copy() {
return new DarkDwellerOracleCastFromExileEffect(this);
}
@Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
return source.isControlledBy(affectedControllerId)
&& objectId.equals(getTargetPointer().getFirst(game, source));
}
}

View file

@ -1,4 +1,3 @@
package mage.cards.d; package mage.cards.d;
import java.util.Objects; import java.util.Objects;
@ -12,6 +11,7 @@ import mage.abilities.effects.AsThoughEffectImpl;
import mage.abilities.effects.AsThoughManaEffect; import mage.abilities.effects.AsThoughManaEffect;
import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.asthought.PlayFromNotOwnHandZoneTargetEffect;
import mage.abilities.effects.common.combat.CantBeBlockedByCreaturesSourceEffect; import mage.abilities.effects.common.combat.CantBeBlockedByCreaturesSourceEffect;
import mage.cards.Card; import mage.cards.Card;
import mage.cards.CardImpl; import mage.cards.CardImpl;
@ -39,7 +39,7 @@ public final class DaxosOfMeletis extends CardImpl {
} }
public DaxosOfMeletis(UUID ownerId, CardSetInfo setInfo) { public DaxosOfMeletis(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{W}{U}"); super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}{U}");
this.addSuperType(SuperType.LEGENDARY); this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.SOLDIER); this.subtype.add(SubType.SOLDIER);
@ -91,7 +91,7 @@ class DaxosOfMeletisEffect extends OneShotEffect {
Card card = damagedPlayer.getLibrary().getFromTop(game); Card card = damagedPlayer.getLibrary().getFromTop(game);
if (card != null) { if (card != null) {
// move card to exile // move card to exile
controller.moveCardToExileWithInfo(card, exileId, sourceObject.getIdName(), source.getSourceId(), game, Zone.LIBRARY, true); controller.moveCardsToExile(card, source, game, true, exileId, sourceObject.getIdName());
// player gains life // player gains life
int cmc = card.getConvertedManaCost(); int cmc = card.getConvertedManaCost();
if (cmc > 0) { if (cmc > 0) {
@ -100,10 +100,12 @@ class DaxosOfMeletisEffect extends OneShotEffect {
// Add effects only if the card has a spellAbility (e.g. not for lands). // Add effects only if the card has a spellAbility (e.g. not for lands).
if (card.getSpellAbility() != null) { if (card.getSpellAbility() != null) {
// allow to cast the card // allow to cast the card
game.addEffect(new DaxosOfMeletisCastFromExileEffect(card.getId(), exileId), source); ContinuousEffect effect = new PlayFromNotOwnHandZoneTargetEffect(Zone.EXILED, Duration.EndOfTurn);
effect.setTargetPointer(new FixedTarget(card, game));
game.addEffect(effect, source);
// and you may spend mana as though it were mana of any color to cast it // and you may spend mana as though it were mana of any color to cast it
ContinuousEffect effect = new DaxosOfMeletisSpendAnyManaEffect(); effect = new DaxosOfMeletisSpendAnyManaEffect();
effect.setTargetPointer(new FixedTarget(card.getId())); effect.setTargetPointer(new FixedTarget(card, game));
game.addEffect(effect, source); game.addEffect(effect, source);
} }
} }

View file

@ -1,4 +1,3 @@
package mage.cards.d; package mage.cards.d;
import java.util.Set; import java.util.Set;
@ -11,6 +10,7 @@ import mage.abilities.effects.AsThoughManaEffect;
import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.AttachEffect; import mage.abilities.effects.common.AttachEffect;
import mage.abilities.effects.common.asthought.PlayFromNotOwnHandZoneTargetEffect;
import mage.abilities.keyword.EnchantAbility; import mage.abilities.keyword.EnchantAbility;
import mage.cards.Card; import mage.cards.Card;
import mage.cards.CardImpl; import mage.cards.CardImpl;
@ -22,6 +22,7 @@ import mage.constants.ManaType;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.constants.SubType; import mage.constants.SubType;
import mage.constants.TargetController; import mage.constants.TargetController;
import mage.constants.Zone;
import mage.filter.common.FilterCreaturePermanent; import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.permanent.ControllerPredicate; import mage.filter.predicate.permanent.ControllerPredicate;
import mage.game.Game; import mage.game.Game;
@ -101,11 +102,11 @@ class DeadMansChestEffect extends OneShotEffect {
controller.moveCardsToExile(cards, source, game, true, source.getSourceId(), sourceObject.getLogName()); controller.moveCardsToExile(cards, source, game, true, source.getSourceId(), sourceObject.getLogName());
for (Card card : cards) { for (Card card : cards) {
if (!card.isLand()) { if (!card.isLand()) {
ContinuousEffect effect = new DeadMansChestCastFromExileEffect(); ContinuousEffect effect = new PlayFromNotOwnHandZoneTargetEffect(Zone.EXILED, Duration.Custom);
effect.setTargetPointer(new FixedTarget(card.getId(), card.getZoneChangeCounter(game))); effect.setTargetPointer(new FixedTarget(card, game));
game.addEffect(effect, source); game.addEffect(effect, source);
effect = new DeadMansChestSpendManaEffect(); effect = new DeadMansChestSpendManaEffect();
effect.setTargetPointer(new FixedTarget(card.getId(), card.getZoneChangeCounter(game))); effect.setTargetPointer(new FixedTarget(card, game));
game.addEffect(effect, source); game.addEffect(effect, source);
} }
} }

View file

@ -1,4 +1,3 @@
package mage.cards.d; package mage.cards.d;
import java.util.Objects; import java.util.Objects;
@ -11,6 +10,7 @@ import mage.abilities.effects.AsThoughManaEffect;
import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.ReplacementEffectImpl; import mage.abilities.effects.ReplacementEffectImpl;
import mage.abilities.effects.common.asthought.PlayFromNotOwnHandZoneTargetEffect;
import mage.abilities.keyword.FirstStrikeAbility; import mage.abilities.keyword.FirstStrikeAbility;
import mage.cards.Card; import mage.cards.Card;
import mage.cards.CardImpl; import mage.cards.CardImpl;
@ -102,14 +102,14 @@ class DireFleetDaredevilEffect extends OneShotEffect {
if (controller.moveCards(targetCard, Zone.EXILED, source, game)) { if (controller.moveCards(targetCard, Zone.EXILED, source, game)) {
targetCard = game.getCard(targetCard.getId()); targetCard = game.getCard(targetCard.getId());
if (targetCard != null) { if (targetCard != null) {
ContinuousEffect effect = new DireFleetDaredevilPlayEffect(); ContinuousEffect effect = new PlayFromNotOwnHandZoneTargetEffect(Zone.EXILED, Duration.EndOfTurn);
effect.setTargetPointer(new FixedTarget(targetCard.getId(), targetCard.getZoneChangeCounter(game))); effect.setTargetPointer(new FixedTarget(targetCard, game));
game.addEffect(effect, source); game.addEffect(effect, source);
effect = new DireFleetDaredevilSpendAnyManaEffect(); effect = new DireFleetDaredevilSpendAnyManaEffect();
effect.setTargetPointer(new FixedTarget(targetCard.getId(), targetCard.getZoneChangeCounter(game))); effect.setTargetPointer(new FixedTarget(targetCard, game));
game.addEffect(effect, source); game.addEffect(effect, source);
effect = new DireFleetDaredevilReplacementEffect(); effect = new DireFleetDaredevilReplacementEffect();
effect.setTargetPointer(new FixedTarget(targetCard.getId(), targetCard.getZoneChangeCounter(game))); effect.setTargetPointer(new FixedTarget(targetCard, game));
game.addEffect(effect, source); game.addEffect(effect, source);
} }
@ -121,41 +121,6 @@ class DireFleetDaredevilEffect extends OneShotEffect {
} }
} }
class DireFleetDaredevilPlayEffect extends AsThoughEffectImpl {
public DireFleetDaredevilPlayEffect() {
super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.EndOfTurn, Outcome.Benefit);
staticText = "You may cast that card this turn";
}
public DireFleetDaredevilPlayEffect(final DireFleetDaredevilPlayEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
return true;
}
@Override
public DireFleetDaredevilPlayEffect copy() {
return new DireFleetDaredevilPlayEffect(this);
}
@Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
UUID targetId = getTargetPointer().getFirst(game, source);
if (targetId != null) {
return targetId.equals(objectId)
&& source.isControlledBy(affectedControllerId);
} else {
// the target card has changed zone meanwhile, so the effect is no longer needed
discard();
return false;
}
}
}
class DireFleetDaredevilSpendAnyManaEffect extends AsThoughEffectImpl implements AsThoughManaEffect { class DireFleetDaredevilSpendAnyManaEffect extends AsThoughEffectImpl implements AsThoughManaEffect {
public DireFleetDaredevilSpendAnyManaEffect() { public DireFleetDaredevilSpendAnyManaEffect() {

View file

@ -1,4 +1,3 @@
package mage.cards.d; package mage.cards.d;
import java.util.Set; import java.util.Set;
@ -7,21 +6,23 @@ import mage.MageInt;
import mage.MageObject; import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl; import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.AsThoughEffectImpl;
import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.Effect; import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.asthought.PlayFromNotOwnHandZoneTargetEffect;
import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.FlyingAbility;
import mage.cards.Card; import mage.cards.Card;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.cards.Cards;
import mage.cards.CardsImpl;
import mage.constants.*; import mage.constants.*;
import mage.game.Game; import mage.game.Game;
import mage.game.events.DamagedPlayerEvent; import mage.game.events.DamagedPlayerEvent;
import mage.game.events.GameEvent; import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType; import mage.game.events.GameEvent.EventType;
import mage.players.Player; import mage.players.Player;
import mage.target.targetpointer.FixedTarget; import mage.target.targetpointer.FixedTargets;
/** /**
* *
@ -30,7 +31,7 @@ import mage.target.targetpointer.FixedTarget;
public final class DreamPillager extends CardImpl { public final class DreamPillager extends CardImpl {
public DreamPillager(UUID ownerId, CardSetInfo setInfo) { public DreamPillager(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{5}{R}{R}"); super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{R}{R}");
this.subtype.add(SubType.DRAGON); this.subtype.add(SubType.DRAGON);
this.power = new MageInt(4); this.power = new MageInt(4);
this.toughness = new MageInt(4); this.toughness = new MageInt(4);
@ -114,13 +115,15 @@ class DreamPillagerEffect extends OneShotEffect {
Set<Card> cards = controller.getLibrary().getTopCards(game, amount); Set<Card> cards = controller.getLibrary().getTopCards(game, amount);
if (!cards.isEmpty()) { if (!cards.isEmpty()) {
controller.moveCards(cards, Zone.EXILED, source, game); controller.moveCards(cards, Zone.EXILED, source, game);
Cards canBeCast = new CardsImpl();
for (Card card : cards) { for (Card card : cards) {
if (!card.isLand()) { if (!card.isLand()) {
ContinuousEffect effect = new DreamPillagerCastFromExileEffect(); canBeCast.add(card);
effect.setTargetPointer(new FixedTarget(card.getId(), card.getZoneChangeCounter(game)));
game.addEffect(effect, source);
} }
} }
ContinuousEffect effect = new PlayFromNotOwnHandZoneTargetEffect(Zone.EXILED, Duration.EndOfTurn);
effect.setTargetPointer(new FixedTargets(canBeCast, game));
game.addEffect(effect, source);
} }
return true; return true;
} }
@ -129,31 +132,3 @@ class DreamPillagerEffect extends OneShotEffect {
return false; return false;
} }
} }
class DreamPillagerCastFromExileEffect extends AsThoughEffectImpl {
public DreamPillagerCastFromExileEffect() {
super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.EndOfTurn, Outcome.Benefit);
staticText = "You may play the card from exile";
}
public DreamPillagerCastFromExileEffect(final DreamPillagerCastFromExileEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
return true;
}
@Override
public DreamPillagerCastFromExileEffect copy() {
return new DreamPillagerCastFromExileEffect(this);
}
@Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
return source.isControlledBy(affectedControllerId)
&& objectId.equals(getTargetPointer().getFirst(game, source));
}
}

View file

@ -1,4 +1,3 @@
package mage.cards.e; package mage.cards.e;
import java.util.Set; import java.util.Set;
@ -10,6 +9,7 @@ import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbil
import mage.abilities.effects.AsThoughEffectImpl; import mage.abilities.effects.AsThoughEffectImpl;
import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.asthought.PlayFromNotOwnHandZoneTargetEffect;
import mage.cards.Card; import mage.cards.Card;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
@ -20,9 +20,9 @@ import mage.constants.Outcome;
import mage.constants.SuperType; import mage.constants.SuperType;
import mage.constants.TargetController; import mage.constants.TargetController;
import mage.constants.Zone; import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.filter.FilterCard;
import mage.players.Player; import mage.players.Player;
import mage.target.targetpointer.FixedTarget; import mage.target.targetpointer.FixedTarget;
import mage.util.RandomUtil; import mage.util.RandomUtil;
@ -81,8 +81,8 @@ class ElkinLairUpkeepEffect extends OneShotEffect {
String exileName = sourcePermanent.getIdName() + " <this card may be played the turn it was exiled"; String exileName = sourcePermanent.getIdName() + " <this card may be played the turn it was exiled";
player.moveCardsToExile(card, source, game, true, source.getSourceId(), exileName); player.moveCardsToExile(card, source, game, true, source.getSourceId(), exileName);
if (game.getState().getZone(card.getId()) == Zone.EXILED) { if (game.getState().getZone(card.getId()) == Zone.EXILED) {
ContinuousEffect effect = new ElkinLairPlayExiledEffect(Duration.EndOfTurn); ContinuousEffect effect = new PlayFromNotOwnHandZoneTargetEffect(Zone.EXILED, Duration.EndOfTurn);
effect.setTargetPointer(new FixedTarget(card.getId(), card.getZoneChangeCounter(game))); effect.setTargetPointer(new FixedTarget(card, game));
game.addEffect(effect, source); game.addEffect(effect, source);
DelayedTriggeredAbility delayed = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(new ElkinLairPutIntoGraveyardEffect()); DelayedTriggeredAbility delayed = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(new ElkinLairPutIntoGraveyardEffect());

View file

@ -2,14 +2,13 @@ package mage.cards.m;
import java.util.UUID; import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.effects.AsThoughEffectImpl;
import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.ReplacementEffectImpl; import mage.abilities.effects.ReplacementEffectImpl;
import mage.abilities.effects.common.asthought.PlayFromNotOwnHandZoneTargetEffect;
import mage.cards.Card; import mage.cards.Card;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.AsThoughEffectType;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Duration; import mage.constants.Duration;
import mage.constants.Outcome; import mage.constants.Outcome;
@ -81,8 +80,8 @@ class MissionBriefingEffect extends OneShotEffect {
} }
Card card = game.getCard(target.getFirstTarget()); Card card = game.getCard(target.getFirstTarget());
if (card != null) { if (card != null) {
ContinuousEffect effect = new MissionBriefingCastFromGraveyardEffect(); ContinuousEffect effect = new PlayFromNotOwnHandZoneTargetEffect();
effect.setTargetPointer(new FixedTarget(card.getId(), card.getZoneChangeCounter(game))); effect.setTargetPointer(new FixedTarget(card, game));
game.addEffect(effect, source); game.addEffect(effect, source);
effect = new MissionBriefingReplacementEffect(card.getId()); effect = new MissionBriefingReplacementEffect(card.getId());
game.addEffect(effect, source); game.addEffect(effect, source);
@ -92,33 +91,6 @@ class MissionBriefingEffect extends OneShotEffect {
} }
} }
class MissionBriefingCastFromGraveyardEffect extends AsThoughEffectImpl {
public MissionBriefingCastFromGraveyardEffect() {
super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.EndOfTurn, Outcome.Benefit);
}
public MissionBriefingCastFromGraveyardEffect(final MissionBriefingCastFromGraveyardEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
return true;
}
@Override
public MissionBriefingCastFromGraveyardEffect copy() {
return new MissionBriefingCastFromGraveyardEffect(this);
}
@Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
return objectId.equals(this.getTargetPointer().getFirst(game, source))
&& affectedControllerId.equals(source.getControllerId());
}
}
class MissionBriefingReplacementEffect extends ReplacementEffectImpl { class MissionBriefingReplacementEffect extends ReplacementEffectImpl {
private final UUID cardId; private final UUID cardId;

View file

@ -1,4 +1,3 @@
package mage.cards.n; package mage.cards.n;
import java.util.Set; import java.util.Set;
@ -77,7 +76,7 @@ class NarsetEnlightenedMasterExileEffect extends OneShotEffect {
&& !card.isCreature() && !card.isCreature()
&& !card.isLand()) { && !card.isLand()) {
ContinuousEffect effect = new NarsetEnlightenedMasterCastFromExileEffect(); ContinuousEffect effect = new NarsetEnlightenedMasterCastFromExileEffect();
effect.setTargetPointer(new FixedTarget(card.getId())); effect.setTargetPointer(new FixedTarget(card, game));
game.addEffect(effect, source); game.addEffect(effect, source);
} }
} }
@ -115,7 +114,8 @@ class NarsetEnlightenedMasterCastFromExileEffect extends AsThoughEffectImpl {
@Override @Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
if (objectId.equals(getTargetPointer().getFirst(game, source)) && affectedControllerId.equals(source.getControllerId())) { if (objectId.equals(getTargetPointer().getFirst(game, source))
&& affectedControllerId.equals(source.getControllerId())) {
Card card = game.getCard(objectId); Card card = game.getCard(objectId);
if (card != null) { if (card != null) {
Player player = game.getPlayer(affectedControllerId); Player player = game.getPlayer(affectedControllerId);

View file

@ -1,4 +1,3 @@
package org.mage.test.cards.asthough; package org.mage.test.cards.asthough;
import mage.constants.PhaseStep; import mage.constants.PhaseStep;
@ -99,8 +98,9 @@ public class PlayFromNonHandZoneTest extends CardTestPlayerBase {
assertExileCount("Silvercoat Lion", 1); assertExileCount("Silvercoat Lion", 1);
assertPermanentCount(playerB, "Abzan Banner", 1); assertPermanentCount(playerB, "Abzan Banner", 1);
assertPermanentCount(playerB, "Dragon Grip", 1);
assertGraveyardCount(playerB, "Peach Garden Oath", 1); assertGraveyardCount(playerB, "Peach Garden Oath", 1);
assertExileCount(playerB, "Dragon Grip", 0);
assertGraveyardCount(playerB, "Dragon Grip", 0);
assertPowerToughness(playerB, "Narset, Enlightened Master", 5, 2); assertPowerToughness(playerB, "Narset, Enlightened Master", 5, 2);
@ -108,6 +108,8 @@ public class PlayFromNonHandZoneTest extends CardTestPlayerBase {
assertLife(playerA, 17); assertLife(playerA, 17);
assertLife(playerB, 22); assertLife(playerB, 22);
assertPermanentCount(playerB, "Dragon Grip", 1);
} }
@Test @Test
@ -140,7 +142,6 @@ public class PlayFromNonHandZoneTest extends CardTestPlayerBase {
assertExileCount(playerB, "Plains", 3); assertExileCount(playerB, "Plains", 3);
assertExileCount(playerB, 3); assertExileCount(playerB, 3);
} }
} }

View file

@ -13,6 +13,7 @@ import mage.abilities.keyword.SpliceOntoArcaneAbility;
import mage.cards.Card; import mage.cards.Card;
import mage.cards.Cards; import mage.cards.Cards;
import mage.cards.CardsImpl; import mage.cards.CardsImpl;
import mage.cards.SplitCardHalf;
import mage.constants.*; import mage.constants.*;
import mage.filter.FilterCard; import mage.filter.FilterCard;
import mage.filter.predicate.Predicate; import mage.filter.predicate.Predicate;
@ -488,15 +489,23 @@ public class ContinuousEffects implements Serializable {
*/ */
public MageObjectReference asThough(UUID objectId, AsThoughEffectType type, Ability affectedAbility, UUID controllerId, Game game) { public MageObjectReference asThough(UUID objectId, AsThoughEffectType type, Ability affectedAbility, UUID controllerId, Game game) {
List<AsThoughEffect> asThoughEffectsList = getApplicableAsThoughEffects(type, game); List<AsThoughEffect> asThoughEffectsList = getApplicableAsThoughEffects(type, game);
for (AsThoughEffect effect : asThoughEffectsList) { if (!asThoughEffectsList.isEmpty()) {
Set<Ability> abilities = asThoughEffectsMap.get(type).getAbility(effect.getId()); UUID idToCheck;
for (Ability ability : abilities) { if (affectedAbility != null && affectedAbility.getSourceObject(game) instanceof SplitCardHalf) {
if (affectedAbility == null) { idToCheck = ((SplitCardHalf) affectedAbility.getSourceObject(game)).getParentCard().getId();
if (effect.applies(objectId, ability, controllerId, game)) { } else {
idToCheck = objectId;
}
for (AsThoughEffect effect : asThoughEffectsList) {
Set<Ability> abilities = asThoughEffectsMap.get(type).getAbility(effect.getId());
for (Ability ability : abilities) {
if (affectedAbility == null) {
if (effect.applies(idToCheck, ability, controllerId, game)) {
return new MageObjectReference(ability.getSourceObject(game), game);
}
} else if (effect.applies(idToCheck, affectedAbility, ability, game, controllerId)) {
return new MageObjectReference(ability.getSourceObject(game), game); return new MageObjectReference(ability.getSourceObject(game), game);
} }
} else if (effect.applies(objectId, affectedAbility, ability, game, controllerId)) {
return new MageObjectReference(ability.getSourceObject(game), game);
} }
} }
} }

View file

@ -1,4 +1,3 @@
package mage.abilities.effects.common; package mage.abilities.effects.common;
import mage.abilities.Ability; import mage.abilities.Ability;
@ -39,7 +38,9 @@ public class AttachEffect extends OneShotEffect {
Permanent sourcePermanent = game.getPermanent(source.getSourceId()); Permanent sourcePermanent = game.getPermanent(source.getSourceId());
if (sourcePermanent != null) { if (sourcePermanent != null) {
int zcc = game.getState().getZoneChangeCounter(sourcePermanent.getId()); int zcc = game.getState().getZoneChangeCounter(sourcePermanent.getId());
if (zcc == source.getSourceObjectZoneChangeCounter() || zcc == source.getSourceObjectZoneChangeCounter() + 1) { if (zcc == source.getSourceObjectZoneChangeCounter()
|| zcc == source.getSourceObjectZoneChangeCounter() + 1
|| zcc == source.getSourceObjectZoneChangeCounter() + 2) {
Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
if (permanent != null) { if (permanent != null) {
return permanent.addAttachment(source.getSourceId(), game); return permanent.addAttachment(source.getSourceId(), game);

View file

@ -0,0 +1,74 @@
package mage.abilities.effects.common.asthought;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.effects.AsThoughEffectImpl;
import mage.cards.Card;
import mage.constants.AsThoughEffectType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.game.Game;
/**
*
* @author LevelX2
*/
public class PlayFromNotOwnHandZoneAllEffect extends AsThoughEffectImpl {
private final FilterCard filter;
private final Zone fromZone;
private final boolean onlyOwnedCards;
private final TargetController allowedCaster;
public PlayFromNotOwnHandZoneAllEffect(FilterCard filter, Zone fromZone, boolean onlyOwnedCards, TargetController allowedCaster, Duration duration) {
super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, duration, Outcome.Benefit);
this.filter = filter;
this.fromZone = fromZone;
this.onlyOwnedCards = onlyOwnedCards;
this.allowedCaster = allowedCaster;
}
public PlayFromNotOwnHandZoneAllEffect(final PlayFromNotOwnHandZoneAllEffect effect) {
super(effect);
this.filter = effect.filter;
this.fromZone = effect.fromZone;
this.onlyOwnedCards = effect.onlyOwnedCards;
this.allowedCaster = effect.allowedCaster;
}
@Override
public boolean apply(Game game, Ability source) {
return true;
}
@Override
public PlayFromNotOwnHandZoneAllEffect copy() {
return new PlayFromNotOwnHandZoneAllEffect(this);
}
@Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
Card card = game.getCard(objectId);
if (card != null) {
switch (allowedCaster) {
case YOU:
if (affectedControllerId != source.getControllerId()) {
return false;
}
break;
case OPPONENT:
if (!game.getOpponents(source.getControllerId()).contains(affectedControllerId)) {
return false;
}
break;
}
return !onlyOwnedCards || card.getOwnerId().equals(source.getControllerId())
&& filter.match(card, game)
&& game.getState().getZone(card.getId()).match(fromZone);
}
return false;
}
}

View file

@ -0,0 +1,82 @@
package mage.abilities.effects.common.asthought;
import java.util.List;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.effects.AsThoughEffectImpl;
import mage.constants.AsThoughEffectType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.game.Game;
/**
*
* @author LevelX2
*/
public class PlayFromNotOwnHandZoneTargetEffect extends AsThoughEffectImpl {
private final Zone fromZone;
private final TargetController allowedCaster;
public PlayFromNotOwnHandZoneTargetEffect() {
this(Duration.EndOfTurn);
}
public PlayFromNotOwnHandZoneTargetEffect(Duration duration) {
this(Zone.ALL, TargetController.YOU, duration);
}
public PlayFromNotOwnHandZoneTargetEffect(Zone fromZone, Duration duration) {
this(fromZone, TargetController.YOU, duration);
}
public PlayFromNotOwnHandZoneTargetEffect(Zone fromZone, TargetController allowedCaster, Duration duration) {
super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, duration, Outcome.Benefit);
this.fromZone = fromZone;
this.allowedCaster = allowedCaster;
}
public PlayFromNotOwnHandZoneTargetEffect(final PlayFromNotOwnHandZoneTargetEffect effect) {
super(effect);
this.fromZone = effect.fromZone;
this.allowedCaster = effect.allowedCaster;
}
@Override
public boolean apply(Game game, Ability source) {
return true;
}
@Override
public PlayFromNotOwnHandZoneTargetEffect copy() {
return new PlayFromNotOwnHandZoneTargetEffect(this);
}
@Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
switch (allowedCaster) {
case YOU:
if (affectedControllerId != source.getControllerId()) {
return false;
}
break;
case OPPONENT:
if (!game.getOpponents(source.getControllerId()).contains(affectedControllerId)) {
return false;
}
break;
case ANY:
break;
}
List<UUID> targets = getTargetPointer().getTargets(game, source);
if (targets.isEmpty()) {
this.discard();
return false;
}
return targets.contains(objectId)
&& affectedControllerId.equals(source.getControllerId())
&& game.getState().getZone(objectId).match(fromZone);
}
}

View file

@ -1,4 +1,3 @@
package mage.abilities.keyword; package mage.abilities.keyword;
import java.util.UUID; import java.util.UUID;
@ -68,16 +67,19 @@ class AftermathCastFromGraveyard extends AsThoughEffectImpl {
} }
@Override @Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { public boolean applies(UUID objectId, Ability affectedAbility, Ability source, Game game, UUID affectedControllerId) {
if (objectId.equals(source.getSourceId()) if (affectedAbility != null && affectedAbility.getSourceId().equals(source.getSourceId())
&& affectedControllerId.equals(source.getControllerId())) { && affectedControllerId.equals(source.getControllerId())) {
Card card = game.getCard(source.getSourceId()); return game.getState().getZone(objectId).equals(Zone.GRAVEYARD);
if (card != null && game.getState().getZone(source.getSourceId()) == Zone.GRAVEYARD) {
return true;
}
} }
return false; return false;
} }
@Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
return false;
}
} }
class AftermathCantCastFromHand extends ContinuousRuleModifyingEffectImpl { class AftermathCantCastFromHand extends ContinuousRuleModifyingEffectImpl {
@ -168,17 +170,14 @@ class AftermathExileAsResolvesFromGraveyard extends ReplacementEffectImpl {
@Override @Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) { public boolean replaceEvent(GameEvent event, Ability source, Game game) {
UUID sourceId = source.getSourceId();
Card sourceCard = game.getCard(source.getSourceId()); Card sourceCard = game.getCard(source.getSourceId());
if (sourceCard instanceof SplitCardHalf) { if (sourceCard instanceof SplitCardHalf) {
sourceCard = ((SplitCardHalf) sourceCard).getParentCard(); sourceCard = ((SplitCardHalf) sourceCard).getParentCard();
sourceId = sourceCard.getId();
} }
if (sourceCard != null) { if (sourceCard != null) {
Player player = game.getPlayer(sourceCard.getOwnerId()); Player player = game.getPlayer(sourceCard.getOwnerId());
if (player != null) { if (player != null) {
return player.moveCardToExileWithInfo(sourceCard, null, "", sourceId, game, ((ZoneChangeEvent) event).getFromZone(), true); return player.moveCards(sourceCard, Zone.EXILED, source, game);
} }
} }
return false; return false;

View file

@ -1,5 +1,9 @@
package mage.players; package mage.players;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.Map.Entry;
import mage.ConditionalMana; import mage.ConditionalMana;
import mage.MageObject; import mage.MageObject;
import mage.MageObjectReference; import mage.MageObjectReference;
@ -68,11 +72,6 @@ import mage.util.GameLog;
import mage.util.RandomUtil; import mage.util.RandomUtil;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.Map.Entry;
public abstract class PlayerImpl implements Player, Serializable { public abstract class PlayerImpl implements Player, Serializable {
private static final Logger logger = Logger.getLogger(PlayerImpl.class); private static final Logger logger = Logger.getLogger(PlayerImpl.class);
@ -2563,7 +2562,7 @@ public abstract class PlayerImpl implements Player, Serializable {
/** /**
* @param game * @param game
* @param appliedEffects * @param appliedEffects
* @param numSides Number of sides the dice has * @param numSides Number of sides the dice has
* @return the number that the player rolled * @return the number that the player rolled
*/ */
@Override @Override
@ -2597,10 +2596,10 @@ public abstract class PlayerImpl implements Player, Serializable {
/** /**
* @param game * @param game
* @param appliedEffects * @param appliedEffects
* @param numberChaosSides The number of chaos sides the planar die * @param numberChaosSides The number of chaos sides the planar die
* currently has (normally 1 but can be 5) * currently has (normally 1 but can be 5)
* @param numberPlanarSides The number of chaos sides the planar die * @param numberPlanarSides The number of chaos sides the planar die
* currently has (normally 1) * currently has (normally 1)
* @return the outcome that the player rolled. Either ChaosRoll, PlanarRoll * @return the outcome that the player rolled. Either ChaosRoll, PlanarRoll
* or NilRoll * or NilRoll
*/ */
@ -2757,7 +2756,7 @@ public abstract class PlayerImpl implements Player, Serializable {
/** /**
* @param ability * @param ability
* @param available if null, it won't be checked if enough mana is available * @param available if null, it won't be checked if enough mana is available
* @param sourceObject * @param sourceObject
* @param game * @param game
* @return * @return
@ -2927,7 +2926,7 @@ public abstract class PlayerImpl implements Player, Serializable {
} }
private void getPlayableFromGraveyardCard(Game game, Card card, Abilities<Ability> candidateAbilities, ManaOptions availableMana, List<Ability> output) { private void getPlayableFromGraveyardCard(Game game, Card card, Abilities<Ability> candidateAbilities, ManaOptions availableMana, List<Ability> output) {
MageObjectReference permittingObject = game.getContinuousEffects().asThough(card.getId(), AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, null, this.getId(), game); MageObjectReference permittingObject = game.getContinuousEffects().asThough(card.getId(), AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, card.getSpellAbility(), this.getId(), game);
for (ActivatedAbility ability : candidateAbilities.getActivatedAbilities(Zone.ALL)) { for (ActivatedAbility ability : candidateAbilities.getActivatedAbilities(Zone.ALL)) {
boolean possible = false; boolean possible = false;
if (ability.getZone().match(Zone.GRAVEYARD)) { if (ability.getZone().match(Zone.GRAVEYARD)) {
@ -3033,7 +3032,7 @@ public abstract class PlayerImpl implements Player, Serializable {
if (player != null) { if (player != null) {
if (/*player.isTopCardRevealed() &&*/player.getLibrary().hasCards()) { if (/*player.isTopCardRevealed() &&*/player.getLibrary().hasCards()) {
Card card = player.getLibrary().getFromTop(game); Card card = player.getLibrary().getFromTop(game);
if (null != game.getContinuousEffects().asThough(card.getId(), AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, null, getId(), game)) { if (null != game.getContinuousEffects().asThough(card.getId(), AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, card.getSpellAbility(), getId(), game)) {
for (ActivatedAbility ability : card.getAbilities().getActivatedAbilities(Zone.HAND)) { for (ActivatedAbility ability : card.getAbilities().getActivatedAbilities(Zone.HAND)) {
if (ability instanceof SpellAbility || ability instanceof PlayLandAbility) { if (ability instanceof SpellAbility || ability instanceof PlayLandAbility) {
playable.add(ability); playable.add(ability);
@ -3309,7 +3308,7 @@ public abstract class PlayerImpl implements Player, Serializable {
@Override @Override
public boolean canPaySacrificeCost(Permanent permanent, UUID sourceId, public boolean canPaySacrificeCost(Permanent permanent, UUID sourceId,
UUID controllerId, Game game UUID controllerId, Game game
) { ) {
return sacrificeCostFilter == null || !sacrificeCostFilter.match(permanent, sourceId, controllerId, game); return sacrificeCostFilter == null || !sacrificeCostFilter.match(permanent, sourceId, controllerId, game);
} }
@ -3457,8 +3456,8 @@ public abstract class PlayerImpl implements Player, Serializable {
@Override @Override
public boolean moveCards(Card card, Zone toZone, public boolean moveCards(Card card, Zone toZone,
Ability source, Game game, Ability source, Game game,
boolean tapped, boolean faceDown, boolean byOwner, List<UUID> appliedEffects boolean tapped, boolean faceDown, boolean byOwner, List<UUID> appliedEffects
) { ) {
Set<Card> cardList = new HashSet<>(); Set<Card> cardList = new HashSet<>();
if (card != null) { if (card != null) {
@ -3469,22 +3468,22 @@ public abstract class PlayerImpl implements Player, Serializable {
@Override @Override
public boolean moveCards(Cards cards, Zone toZone, public boolean moveCards(Cards cards, Zone toZone,
Ability source, Game game Ability source, Game game
) { ) {
return moveCards(cards.getCards(game), toZone, source, game); return moveCards(cards.getCards(game), toZone, source, game);
} }
@Override @Override
public boolean moveCards(Set<Card> cards, Zone toZone, public boolean moveCards(Set<Card> cards, Zone toZone,
Ability source, Game game Ability source, Game game
) { ) {
return moveCards(cards, toZone, source, game, false, false, false, null); return moveCards(cards, toZone, source, game, false, false, false, null);
} }
@Override @Override
public boolean moveCards(Set<Card> cards, Zone toZone, public boolean moveCards(Set<Card> cards, Zone toZone,
Ability source, Game game, Ability source, Game game,
boolean tapped, boolean faceDown, boolean byOwner, List<UUID> appliedEffects boolean tapped, boolean faceDown, boolean byOwner, List<UUID> appliedEffects
) { ) {
if (cards.isEmpty()) { if (cards.isEmpty()) {
return true; return true;
@ -3570,8 +3569,8 @@ public abstract class PlayerImpl implements Player, Serializable {
@Override @Override
public boolean moveCardsToExile(Card card, Ability source, public boolean moveCardsToExile(Card card, Ability source,
Game game, boolean withName, UUID exileId, Game game, boolean withName, UUID exileId,
String exileZoneName String exileZoneName
) { ) {
Set<Card> cards = new HashSet<>(); Set<Card> cards = new HashSet<>();
cards.add(card); cards.add(card);
@ -3580,8 +3579,8 @@ public abstract class PlayerImpl implements Player, Serializable {
@Override @Override
public boolean moveCardsToExile(Set<Card> cards, Ability source, public boolean moveCardsToExile(Set<Card> cards, Ability source,
Game game, boolean withName, UUID exileId, Game game, boolean withName, UUID exileId,
String exileZoneName String exileZoneName
) { ) {
if (cards.isEmpty()) { if (cards.isEmpty()) {
return true; return true;
@ -3596,14 +3595,14 @@ public abstract class PlayerImpl implements Player, Serializable {
@Override @Override
public boolean moveCardToHandWithInfo(Card card, UUID sourceId, public boolean moveCardToHandWithInfo(Card card, UUID sourceId,
Game game Game game
) { ) {
return this.moveCardToHandWithInfo(card, sourceId, game, true); return this.moveCardToHandWithInfo(card, sourceId, game, true);
} }
@Override @Override
public boolean moveCardToHandWithInfo(Card card, UUID sourceId, public boolean moveCardToHandWithInfo(Card card, UUID sourceId,
Game game, boolean withName Game game, boolean withName
) { ) {
boolean result = false; boolean result = false;
Zone fromZone = game.getState().getZone(card.getId()); Zone fromZone = game.getState().getZone(card.getId());
@ -3628,7 +3627,7 @@ public abstract class PlayerImpl implements Player, Serializable {
@Override @Override
public Set<Card> moveCardsToGraveyardWithInfo(Set<Card> allCards, Ability source, public Set<Card> moveCardsToGraveyardWithInfo(Set<Card> allCards, Ability source,
Game game, Zone fromZone Game game, Zone fromZone
) { ) {
UUID sourceId = source == null ? null : source.getSourceId(); UUID sourceId = source == null ? null : source.getSourceId();
Set<Card> movedCards = new LinkedHashSet<>(); Set<Card> movedCards = new LinkedHashSet<>();
@ -3636,7 +3635,7 @@ public abstract class PlayerImpl implements Player, Serializable {
// identify cards from one owner // identify cards from one owner
Cards cards = new CardsImpl(); Cards cards = new CardsImpl();
UUID ownerId = null; UUID ownerId = null;
for (Iterator<Card> it = allCards.iterator(); it.hasNext(); ) { for (Iterator<Card> it = allCards.iterator(); it.hasNext();) {
Card card = it.next(); Card card = it.next();
if (cards.isEmpty()) { if (cards.isEmpty()) {
ownerId = card.getOwnerId(); ownerId = card.getOwnerId();
@ -3697,7 +3696,7 @@ public abstract class PlayerImpl implements Player, Serializable {
@Override @Override
public boolean moveCardToGraveyardWithInfo(Card card, UUID sourceId, public boolean moveCardToGraveyardWithInfo(Card card, UUID sourceId,
Game game, Zone fromZone Game game, Zone fromZone
) { ) {
if (card == null) { if (card == null) {
return false; return false;
@ -3726,8 +3725,8 @@ public abstract class PlayerImpl implements Player, Serializable {
@Override @Override
public boolean moveCardToLibraryWithInfo(Card card, UUID sourceId, public boolean moveCardToLibraryWithInfo(Card card, UUID sourceId,
Game game, Zone fromZone, Game game, Zone fromZone,
boolean toTop, boolean withName boolean toTop, boolean withName
) { ) {
if (card == null) { if (card == null) {
return false; return false;
@ -3761,7 +3760,7 @@ public abstract class PlayerImpl implements Player, Serializable {
@Override @Override
public boolean moveCardToExileWithInfo(Card card, UUID exileId, String exileName, UUID sourceId, public boolean moveCardToExileWithInfo(Card card, UUID exileId, String exileName, UUID sourceId,
Game game, Zone fromZone, boolean withName) { Game game, Zone fromZone, boolean withName) {
if (card == null) { if (card == null) {
return false; return false;
} }

View file

@ -21,6 +21,12 @@ public class FixedTarget implements TargetPointer {
this.initialized = false; this.initialized = false;
} }
public FixedTarget(Card card, Game game) {
this.targetId = card.getId();
this.zoneChangeCounter = card.getZoneChangeCounter(game);
this.initialized = true;
}
public FixedTarget(Permanent permanent, Game game) { public FixedTarget(Permanent permanent, Game game) {
this.targetId = permanent.getId(); this.targetId = permanent.getId();
this.zoneChangeCounter = permanent.getZoneChangeCounter(game); this.zoneChangeCounter = permanent.getZoneChangeCounter(game);