1
0
Fork 0
mirror of https://github.com/correl/mage.git synced 2025-04-09 17:00:09 -09:00

Improved cards with "may spend mana as though":

* Game: added combo support with adventure and split cards;
 * AI: computer can see and play it;
 * UI: users can see playable cards for as though mana cost.
This commit is contained in:
Oleg Agafonov 2019-12-14 18:59:18 +04:00
parent c9ea0f1877
commit ddedabad85
17 changed files with 109 additions and 182 deletions

View file

@ -156,11 +156,12 @@ class CovetousUrgeSpendAnyManaEffect extends AsThoughEffectImpl implements AsTho
@Override @Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
objectId = game.getCard(objectId).getMainCard().getId(); // for split cards
FixedTarget fixedTarget = ((FixedTarget) getTargetPointer()); FixedTarget fixedTarget = ((FixedTarget) getTargetPointer());
return source.isControlledBy(affectedControllerId) return source.isControlledBy(affectedControllerId)
&& Objects.equals(objectId, fixedTarget.getTarget()) && Objects.equals(objectId, fixedTarget.getTarget())
&& fixedTarget.getZoneChangeCounter() + 1 == game.getState().getZoneChangeCounter(objectId) && game.getState().getZoneChangeCounter(objectId) <= fixedTarget.getZoneChangeCounter() + 1
&& game.getState().getZone(objectId) == Zone.STACK; && (game.getState().getZone(objectId) == Zone.STACK || game.getState().getZone(objectId) == Zone.EXILED);
} }
@Override @Override

View file

@ -1,6 +1,5 @@
package mage.cards.c; package mage.cards.c;
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.AsThoughEffectImpl;
@ -21,8 +20,9 @@ import mage.target.common.TargetOpponent;
import mage.target.targetpointer.FixedTarget; import mage.target.targetpointer.FixedTarget;
import mage.util.CardUtil; import mage.util.CardUtil;
import java.util.UUID;
/** /**
*
* @author Styxo * @author Styxo
*/ */
public final class CunningAbduction extends CardImpl { public final class CunningAbduction extends CardImpl {
@ -125,12 +125,8 @@ class CunningAbductionSpendAnyManaEffect extends AsThoughEffectImpl implements A
objectId = game.getCard(objectId).getMainCard().getId(); // for split cards objectId = game.getCard(objectId).getMainCard().getId(); // for split cards
if (objectId.equals(((FixedTarget) getTargetPointer()).getTarget()) if (objectId.equals(((FixedTarget) getTargetPointer()).getTarget())
&& game.getState().getZoneChangeCounter(objectId) <= ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1) { && game.getState().getZoneChangeCounter(objectId) <= ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1) {
if (affectedControllerId.equals(source.getControllerId())) { // if the card moved from exile to spell the zone change counter is increased by 1 (effect must applies before and on stack, use isCheckPlayableMode?)
// if the card moved from exile to spell the zone change counter is increased by 1 return affectedControllerId.equals(source.getControllerId());
if (game.getState().getZoneChangeCounter(objectId) == ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1) {
return true;
}
}
} else if (((FixedTarget) getTargetPointer()).getTarget().equals(objectId)) { } else if (((FixedTarget) getTargetPointer()).getTarget().equals(objectId)) {
// object has moved zone so effect can be discarted // object has moved zone so effect can be discarted
this.discard(); this.discard();

View file

@ -1,7 +1,5 @@
package mage.cards.d; package mage.cards.d;
import java.util.Objects;
import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.MageObject; import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
@ -26,8 +24,10 @@ import mage.players.Player;
import mage.target.targetpointer.FixedTarget; import mage.target.targetpointer.FixedTarget;
import mage.util.CardUtil; import mage.util.CardUtil;
import java.util.Objects;
import java.util.UUID;
/** /**
*
* @author LevelX2 * @author LevelX2
*/ */
public final class DaxosOfMeletis extends CardImpl { public final class DaxosOfMeletis extends CardImpl {
@ -178,11 +178,11 @@ class DaxosOfMeletisSpendAnyManaEffect extends AsThoughEffectImpl implements AsT
@Override @Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
objectId = game.getCard(objectId).getMainCard().getId(); // for split cards objectId = game.getCard(objectId).getMainCard().getId(); // for split cards
FixedTarget fixedTarget = ((FixedTarget) getTargetPointer());
return source.isControlledBy(affectedControllerId) return source.isControlledBy(affectedControllerId)
&& Objects.equals(objectId, ((FixedTarget) getTargetPointer()).getTarget()) && Objects.equals(objectId, fixedTarget.getTarget())
&& ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1 == game.getState().getZoneChangeCounter(objectId) && game.getState().getZoneChangeCounter(objectId) <= fixedTarget.getZoneChangeCounter() + 1
&& (((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1 == game.getState().getZoneChangeCounter(objectId)) && (game.getState().getZone(objectId) == Zone.STACK || game.getState().getZone(objectId) == Zone.EXILED);
&& game.getState().getZone(objectId) == Zone.STACK;
} }
@Override @Override

View file

@ -1,7 +1,5 @@
package mage.cards.d; package mage.cards.d;
import java.util.Set;
import java.util.UUID;
import mage.MageObject; import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.DiesAttachedTriggeredAbility; import mage.abilities.common.DiesAttachedTriggeredAbility;
@ -15,14 +13,7 @@ import mage.abilities.keyword.EnchantAbility;
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.*;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.ManaType;
import mage.constants.Outcome;
import mage.constants.SubType;
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;
@ -32,8 +23,10 @@ import mage.players.Player;
import mage.target.TargetPermanent; import mage.target.TargetPermanent;
import mage.target.targetpointer.FixedTarget; import mage.target.targetpointer.FixedTarget;
import java.util.Set;
import java.util.UUID;
/** /**
*
* @author LevelX2 * @author LevelX2
*/ */
public final class DeadMansChest extends CardImpl { public final class DeadMansChest extends CardImpl {
@ -142,9 +135,7 @@ class DeadMansChestCastFromExileEffect 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))) { if (objectId.equals(getTargetPointer().getFirst(game, source))) {
if (affectedControllerId.equals(source.getControllerId())) { return affectedControllerId.equals(source.getControllerId());
return true;
}
} else { } else {
if (((FixedTarget) getTargetPointer()).getTarget().equals(objectId)) { if (((FixedTarget) getTargetPointer()).getTarget().equals(objectId)) {
// object has moved zone so effect can be discarted // object has moved zone so effect can be discarted
@ -181,12 +172,8 @@ class DeadMansChestSpendManaEffect extends AsThoughEffectImpl implements AsThoug
objectId = game.getCard(objectId).getMainCard().getId(); // for split cards objectId = game.getCard(objectId).getMainCard().getId(); // for split cards
if (objectId.equals(((FixedTarget) getTargetPointer()).getTarget()) if (objectId.equals(((FixedTarget) getTargetPointer()).getTarget())
&& game.getState().getZoneChangeCounter(objectId) <= ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1) { && game.getState().getZoneChangeCounter(objectId) <= ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1) {
if (affectedControllerId.equals(source.getControllerId())) { // if the card moved from exile to spell the zone change counter is increased by 1 (effect must applies before and on stack, use isCheckPlayableMode?)
// if the card moved from exile to spell the zone change counter is increased by 1 return affectedControllerId.equals(source.getControllerId());
if (game.getState().getZoneChangeCounter(objectId) == ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1) {
return true;
}
}
} else { } else {
if (((FixedTarget) getTargetPointer()).getTarget().equals(objectId)) { if (((FixedTarget) getTargetPointer()).getTarget().equals(objectId)) {
// object has moved zone so effect can be discarted // object has moved zone so effect can be discarted

View file

@ -1,27 +1,15 @@
package mage.cards.d; package mage.cards.d;
import java.util.Objects;
import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.AsThoughEffectImpl; import mage.abilities.effects.*;
import mage.abilities.effects.AsThoughManaEffect;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.ReplacementEffectImpl;
import mage.abilities.effects.common.asthought.PlayFromNotOwnHandZoneTargetEffect; 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;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.AsThoughEffectType; import mage.constants.*;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.ManaType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.FilterCard; import mage.filter.FilterCard;
import mage.filter.predicate.Predicates; import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.CardTypePredicate; import mage.filter.predicate.mageobject.CardTypePredicate;
@ -34,8 +22,10 @@ import mage.players.Player;
import mage.target.common.TargetCardInOpponentsGraveyard; import mage.target.common.TargetCardInOpponentsGraveyard;
import mage.target.targetpointer.FixedTarget; import mage.target.targetpointer.FixedTarget;
import java.util.Objects;
import java.util.UUID;
/** /**
*
* @author LevelX2 * @author LevelX2
*/ */
public final class DireFleetDaredevil extends CardImpl { public final class DireFleetDaredevil extends CardImpl {
@ -144,10 +134,11 @@ class DireFleetDaredevilSpendAnyManaEffect extends AsThoughEffectImpl implements
@Override @Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
objectId = game.getCard(objectId).getMainCard().getId(); // for split cards objectId = game.getCard(objectId).getMainCard().getId(); // for split cards
FixedTarget fixedTarget = ((FixedTarget) getTargetPointer());
return source.isControlledBy(affectedControllerId) return source.isControlledBy(affectedControllerId)
&& Objects.equals(objectId, ((FixedTarget) getTargetPointer()).getTarget()) && Objects.equals(objectId, ((FixedTarget) getTargetPointer()).getTarget())
&& ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1 == game.getState().getZoneChangeCounter(objectId) && game.getState().getZoneChangeCounter(objectId) <= fixedTarget.getZoneChangeCounter() + 1
&& game.getState().getZone(objectId) == Zone.STACK; && (game.getState().getZone(objectId) == Zone.STACK || game.getState().getZone(objectId) == Zone.EXILED);
} }
@Override @Override
@ -192,7 +183,7 @@ class DireFleetDaredevilReplacementEffect extends ReplacementEffectImpl {
ZoneChangeEvent zEvent = (ZoneChangeEvent) event; ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
return zEvent.getToZone() == Zone.GRAVEYARD return zEvent.getToZone() == Zone.GRAVEYARD
&& event.getTargetId().equals(((FixedTarget) getTargetPointer()).getTarget()) && event.getTargetId().equals(((FixedTarget) getTargetPointer()).getTarget())
&& ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1 && ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1
== game.getState().getZoneChangeCounter(event.getTargetId()); == game.getState().getZoneChangeCounter(event.getTargetId());
} }
} }

View file

@ -1,8 +1,5 @@
package mage.cards.g; package mage.cards.g;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.MageObject; import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
@ -25,8 +22,11 @@ import mage.target.common.TargetOpponent;
import mage.target.targetpointer.FixedTarget; import mage.target.targetpointer.FixedTarget;
import mage.util.CardUtil; import mage.util.CardUtil;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
/** /**
*
* @author LevelX2 * @author LevelX2
*/ */
public final class GontiLordOfLuxury extends CardImpl { public final class GontiLordOfLuxury extends CardImpl {
@ -185,22 +185,18 @@ class GontiLordOfLuxurySpendAnyManaEffect extends AsThoughEffectImpl implements
@Override @Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
Card theCard = game.getCard(objectId); Card theCard = game.getCard(objectId);
if(theCard == null){ if (theCard == null) {
return false; return false;
} }
Card mainCard = theCard.getMainCard(); Card mainCard = theCard.getMainCard();
if(mainCard == null){ if (mainCard == null) {
return false; return false;
} }
objectId = mainCard.getId(); // for split cards objectId = mainCard.getId(); // for split cards
if (objectId.equals(((FixedTarget) getTargetPointer()).getTarget()) if (objectId.equals(((FixedTarget) getTargetPointer()).getTarget())
&& game.getState().getZoneChangeCounter(objectId) <= ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1) { && game.getState().getZoneChangeCounter(objectId) <= ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1) {
if (affectedControllerId.equals(source.getControllerId())) { // if the card moved from exile to spell the zone change counter is increased by 1 (effect must applies before and on stack, use isCheckPlayableMode?)
// if the card moved from exile to spell the zone change counter is increased by 1 return affectedControllerId.equals(source.getControllerId());
if (game.getState().getZoneChangeCounter(objectId) == ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1) {
return true;
}
}
} else if (((FixedTarget) getTargetPointer()).getTarget().equals(objectId)) { } else if (((FixedTarget) getTargetPointer()).getTarget().equals(objectId)) {
// object has moved zone so effect can be discarted // object has moved zone so effect can be discarted
this.discard(); this.discard();
@ -238,11 +234,11 @@ class GontiLordOfLuxuryLookEffect 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) {
Card theCard = game.getCard(objectId); Card theCard = game.getCard(objectId);
if(theCard == null){ if (theCard == null) {
return false; return false;
} }
Card mainCard = theCard.getMainCard(); Card mainCard = theCard.getMainCard();
if(mainCard == null){ if (mainCard == null) {
return false; return false;
} }
objectId = mainCard.getId(); // for split cards objectId = mainCard.getId(); // for split cards

View file

@ -233,11 +233,12 @@ class GrenzoHavocRaiserSpendAnyManaEffect extends AsThoughEffectImpl implements
@Override @Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
objectId = game.getCard(objectId).getMainCard().getId(); // for split cards
FixedTarget fixedTarget = ((FixedTarget) getTargetPointer());
return source.isControlledBy(affectedControllerId) return source.isControlledBy(affectedControllerId)
&& Objects.equals(objectId, ((FixedTarget) getTargetPointer()).getTarget()) && Objects.equals(objectId, ((FixedTarget) getTargetPointer()).getTarget())
&& ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1 == game.getState().getZoneChangeCounter(objectId) && game.getState().getZoneChangeCounter(objectId) <= fixedTarget.getZoneChangeCounter() + 1
&& (((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1 == game.getState().getZoneChangeCounter(objectId)) && (game.getState().getZone(objectId) == Zone.STACK || game.getState().getZone(objectId) == Zone.EXILED);
&& game.getState().getZone(objectId) == Zone.STACK;
} }
@Override @Override

View file

@ -106,7 +106,7 @@ class HostageTakerExileEffect extends OneShotEffect {
ContinuousEffect effect = new HostageTakerSpendAnyManaEffect(); ContinuousEffect effect = new HostageTakerSpendAnyManaEffect();
effect.setTargetPointer(new FixedTarget(card.getId(), game)); effect.setTargetPointer(new FixedTarget(card.getId(), game));
game.addEffect(effect, source); game.addEffect(effect, source);
return false; return true;
} }
} }
@ -173,11 +173,12 @@ class HostageTakerSpendAnyManaEffect extends AsThoughEffectImpl implements AsTho
@Override @Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
objectId = game.getCard(objectId).getMainCard().getId(); // for split cards
FixedTarget fixedTarget = ((FixedTarget) getTargetPointer()); FixedTarget fixedTarget = ((FixedTarget) getTargetPointer());
return source.isControlledBy(affectedControllerId) return source.isControlledBy(affectedControllerId)
&& Objects.equals(objectId, fixedTarget.getTarget()) && Objects.equals(objectId, fixedTarget.getTarget())
&& fixedTarget.getZoneChangeCounter() + 1 == game.getState().getZoneChangeCounter(objectId) && game.getState().getZoneChangeCounter(objectId) <= fixedTarget.getZoneChangeCounter() + 1
&& game.getState().getZone(objectId) == Zone.STACK; && (game.getState().getZone(objectId) == Zone.STACK || game.getState().getZone(objectId) == Zone.EXILED);
} }
@Override @Override

View file

@ -1,7 +1,5 @@
package mage.cards.o; package mage.cards.o;
import java.util.UUID;
import mage.MageObject; import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility;
@ -19,8 +17,9 @@ import mage.players.ManaPoolItem;
import mage.players.Player; import mage.players.Player;
import mage.target.TargetCard; import mage.target.TargetCard;
import java.util.UUID;
/** /**
*
* @author LevelX2 * @author LevelX2
*/ */
public final class OathOfNissa extends CardImpl { public final class OathOfNissa extends CardImpl {
@ -128,13 +127,10 @@ class OathOfNissaSpendAnyManaEffect extends AsThoughEffectImpl implements AsThou
@Override @Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
objectId = game.getCard(objectId).getMainCard().getId(); // for split cards
if (source.isControlledBy(affectedControllerId)) { if (source.isControlledBy(affectedControllerId)) {
MageObject mageObject = game.getObject(objectId); MageObject mageObject = game.getObject(objectId);
if (mageObject != null) { return mageObject != null && mageObject.isPlaneswalker();
if (mageObject.isPlaneswalker()) {
return true;
}
}
} }
return false; return false;
} }

View file

@ -1,6 +1,5 @@
package mage.cards.p; package mage.cards.p;
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.AsThoughEffectImpl;
@ -10,12 +9,7 @@ import mage.abilities.effects.OneShotEffect;
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.*;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.ManaType;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.filter.common.FilterNonlandCard; import mage.filter.common.FilterNonlandCard;
import mage.game.Game; import mage.game.Game;
import mage.players.ManaPoolItem; import mage.players.ManaPoolItem;
@ -25,8 +19,9 @@ import mage.target.common.TargetOpponent;
import mage.target.targetpointer.FixedTarget; import mage.target.targetpointer.FixedTarget;
import mage.util.CardUtil; import mage.util.CardUtil;
import java.util.UUID;
/** /**
*
* @author LevelX2 * @author LevelX2
*/ */
public final class PsychicIntrusion extends CardImpl { public final class PsychicIntrusion extends CardImpl {
@ -149,10 +144,9 @@ class PsychicIntrusionCastFromExileEffect 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) {
objectId = game.getCard(objectId).getMainCard().getId(); // for split cards
if (objectId.equals(getTargetPointer().getFirst(game, source))) { if (objectId.equals(getTargetPointer().getFirst(game, source))) {
if (affectedControllerId.equals(source.getControllerId())) { return affectedControllerId.equals(source.getControllerId());
return true;
}
} else { } else {
if (((FixedTarget) getTargetPointer()).getTarget().equals(objectId)) { if (((FixedTarget) getTargetPointer()).getTarget().equals(objectId)) {
// object has moved zone so effect can be discarted // object has moved zone so effect can be discarted
@ -189,12 +183,8 @@ class PsychicIntrusionSpendAnyManaEffect extends AsThoughEffectImpl implements A
objectId = game.getCard(objectId).getMainCard().getId(); // for split cards objectId = game.getCard(objectId).getMainCard().getId(); // for split cards
if (objectId.equals(((FixedTarget) getTargetPointer()).getTarget()) if (objectId.equals(((FixedTarget) getTargetPointer()).getTarget())
&& game.getState().getZoneChangeCounter(objectId) <= ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1) { && game.getState().getZoneChangeCounter(objectId) <= ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1) {
if (affectedControllerId.equals(source.getControllerId())) { // if the card moved from exile to spell the zone change counter is increased by 1 (effect must applies before and on stack, use isCheckPlayableMode?)
// if the card moved from exile to spell the zone change counter is increased by 1 return affectedControllerId.equals(source.getControllerId());
if (game.getState().getZoneChangeCounter(objectId) == ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1) {
return true;
}
}
} else { } else {
if (((FixedTarget) getTargetPointer()).getTarget().equals(objectId)) { if (((FixedTarget) getTargetPointer()).getTarget().equals(objectId)) {
// object has moved zone so effect can be discarted // object has moved zone so effect can be discarted

View file

@ -1,7 +1,5 @@
package mage.cards.q; package mage.cards.q;
import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.ActivatedAbility; import mage.abilities.ActivatedAbility;
@ -10,28 +8,20 @@ import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.AsThoughEffectImpl; import mage.abilities.effects.AsThoughEffectImpl;
import mage.abilities.effects.AsThoughManaEffect; import mage.abilities.effects.AsThoughManaEffect;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.AsThoughEffectType; import mage.constants.*;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Duration;
import mage.constants.Layer;
import mage.constants.ManaType;
import mage.constants.Outcome;
import mage.constants.SubLayer;
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.ManaPoolItem; import mage.players.ManaPoolItem;
import mage.target.common.TargetCreaturePermanent; import mage.target.common.TargetCreaturePermanent;
import mage.target.targetpointer.FixedTarget; import mage.target.targetpointer.FixedTarget;
import java.util.UUID;
/** /**
*
* @author spjspj * @author spjspj
*/ */
public final class QuicksilverElemental extends CardImpl { public final class QuicksilverElemental extends CardImpl {
@ -151,10 +141,9 @@ class QuickSilverElementalBlueManaEffect extends AsThoughEffectImpl implements A
@Override @Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
objectId = game.getCard(objectId).getMainCard().getId(); // for split cards
if (objectId.equals(getTargetPointer().getFirst(game, source))) { if (objectId.equals(getTargetPointer().getFirst(game, source))) {
if (affectedControllerId.equals(source.getControllerId())) { return affectedControllerId.equals(source.getControllerId());
return true;
}
} }
return false; return false;

View file

@ -194,11 +194,12 @@ class RobberOfTheRichSpendAnyManaEffect extends AsThoughEffectImpl implements As
@Override @Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
objectId = game.getCard(objectId).getMainCard().getId(); // for split cards
FixedTarget fixedTarget = ((FixedTarget) getTargetPointer()); FixedTarget fixedTarget = ((FixedTarget) getTargetPointer());
return source.isControlledBy(affectedControllerId) return source.isControlledBy(affectedControllerId)
&& Objects.equals(objectId, fixedTarget.getTarget()) && Objects.equals(objectId, fixedTarget.getTarget())
&& fixedTarget.getZoneChangeCounter() + 1 == game.getState().getZoneChangeCounter(objectId) && game.getState().getZoneChangeCounter(objectId) <= fixedTarget.getZoneChangeCounter() + 1
&& game.getState().getZone(objectId) == Zone.STACK; && (game.getState().getZone(objectId) == Zone.STACK || game.getState().getZone(objectId) == Zone.EXILED);
} }
@Override @Override

View file

@ -1,8 +1,5 @@
package mage.cards.s; package mage.cards.s;
import java.util.Objects;
import java.util.UUID;
import mage.MageObject; import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
@ -13,13 +10,7 @@ import mage.abilities.effects.OneShotEffect;
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.*;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.ManaType;
import mage.constants.Outcome;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.game.ExileZone; import mage.game.ExileZone;
import mage.game.Game; import mage.game.Game;
import mage.players.ManaPoolItem; import mage.players.ManaPoolItem;
@ -27,8 +18,10 @@ import mage.players.Player;
import mage.target.targetpointer.FixedTarget; import mage.target.targetpointer.FixedTarget;
import mage.util.CardUtil; import mage.util.CardUtil;
import java.util.Objects;
import java.util.UUID;
/** /**
*
* @author TheElk801 * @author TheElk801
*/ */
public final class StolenStrategy extends CardImpl { public final class StolenStrategy extends CardImpl {
@ -165,11 +158,11 @@ class StolenStrategySpendAnyManaEffect extends AsThoughEffectImpl implements AsT
@Override @Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
objectId = game.getCard(objectId).getMainCard().getId(); // for split cards objectId = game.getCard(objectId).getMainCard().getId(); // for split cards
FixedTarget fixedTarget = ((FixedTarget) getTargetPointer());
return source.isControlledBy(affectedControllerId) return source.isControlledBy(affectedControllerId)
&& Objects.equals(objectId, ((FixedTarget) getTargetPointer()).getTarget()) && Objects.equals(objectId, fixedTarget.getTarget())
&& ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1 == game.getState().getZoneChangeCounter(objectId) && game.getState().getZoneChangeCounter(objectId) <= fixedTarget.getZoneChangeCounter() + 1
&& (((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1 == game.getState().getZoneChangeCounter(objectId)) && (game.getState().getZone(objectId) == Zone.STACK || game.getState().getZone(objectId) == Zone.EXILED);
&& game.getState().getZone(objectId) == Zone.STACK;
} }
@Override @Override

View file

@ -1,8 +1,5 @@
package mage.cards.t; package mage.cards.t;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.MageObject; import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
@ -12,18 +9,8 @@ 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.keyword.FlyingAbility; import mage.abilities.keyword.FlyingAbility;
import mage.cards.Card; import mage.cards.*;
import mage.cards.CardImpl; import mage.constants.*;
import mage.cards.CardSetInfo;
import mage.cards.Cards;
import mage.cards.CardsImpl;
import mage.constants.AsThoughEffectType;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.ManaType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.FilterCard; import mage.filter.FilterCard;
import mage.game.Game; import mage.game.Game;
import mage.players.ManaPoolItem; import mage.players.ManaPoolItem;
@ -32,8 +19,11 @@ import mage.target.TargetCard;
import mage.target.targetpointer.FixedTarget; import mage.target.targetpointer.FixedTarget;
import mage.util.CardUtil; import mage.util.CardUtil;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
/** /**
*
* @author LevelX2 * @author LevelX2
*/ */
public final class ThiefOfSanity extends CardImpl { public final class ThiefOfSanity extends CardImpl {
@ -200,12 +190,8 @@ class ThiefOfSanitySpendAnyManaEffect extends AsThoughEffectImpl implements AsTh
objectId = game.getCard(objectId).getMainCard().getId(); // for split cards objectId = game.getCard(objectId).getMainCard().getId(); // for split cards
if (objectId.equals(((FixedTarget) getTargetPointer()).getTarget()) if (objectId.equals(((FixedTarget) getTargetPointer()).getTarget())
&& game.getState().getZoneChangeCounter(objectId) <= ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1) { && game.getState().getZoneChangeCounter(objectId) <= ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1) {
if (affectedControllerId.equals(authorizedPlayerId)) { // if the card moved from exile to spell the zone change counter is increased by 1 (effect must applies before and on stack, use isCheckPlayableMode?)
// if the card moved from exile to stack the zone change counter is increased by 1 return affectedControllerId.equals(authorizedPlayerId);
if (game.getState().getZoneChangeCounter(objectId) == ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1) {
return true;
}
}
} else if (((FixedTarget) getTargetPointer()).getTarget().equals(objectId)) { } else if (((FixedTarget) getTargetPointer()).getTarget().equals(objectId)) {
// object has moved zone so effect can be discarted // object has moved zone so effect can be discarted
this.discard(); this.discard();

View file

@ -1,19 +1,19 @@
package mage.cards.t; package mage.cards.t;
import java.util.Objects;
import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.MageObject; import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.*; import mage.abilities.effects.AsThoughEffectImpl;
import mage.abilities.effects.common.ExileCardsFromTopOfLibraryTargetEffect; import mage.abilities.effects.AsThoughManaEffect;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.counter.AddCountersTargetEffect; import mage.abilities.effects.common.counter.AddCountersTargetEffect;
import mage.abilities.keyword.BountyAbility; import mage.abilities.keyword.BountyAbility;
import mage.cards.Card; import mage.cards.Card;
import mage.constants.*;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.counters.CounterType; import mage.counters.CounterType;
import mage.game.ExileZone; import mage.game.ExileZone;
import mage.game.Game; import mage.game.Game;
@ -24,15 +24,17 @@ import mage.target.common.TargetOpponentsCreaturePermanent;
import mage.target.targetpointer.FixedTarget; import mage.target.targetpointer.FixedTarget;
import mage.util.CardUtil; import mage.util.CardUtil;
import java.util.Objects;
import java.util.UUID;
/** /**
*
* @author NinthWorld * @author NinthWorld
*/ */
public final class TobiasBeckett extends CardImpl { public final class TobiasBeckett extends CardImpl {
public TobiasBeckett(UUID ownerId, CardSetInfo setInfo) { public TobiasBeckett(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}"); super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}");
this.addSuperType(SuperType.LEGENDARY); this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.HUNTER); this.subtype.add(SubType.HUNTER);
@ -75,7 +77,7 @@ class TobiasBeckettEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
if (controller != null) { if (controller != null) {
Permanent bountyTriggered = game.getPermanent(this.getTargetPointer().getFirst(game, source)); Permanent bountyTriggered = game.getPermanent(this.getTargetPointer().getFirst(game, source));
if(bountyTriggered != null) { if (bountyTriggered != null) {
Player opponent = game.getPlayer(bountyTriggered.getControllerId()); Player opponent = game.getPlayer(bountyTriggered.getControllerId());
if (opponent != null) { if (opponent != null) {
MageObject sourceObject = game.getObject(source.getSourceId()); MageObject sourceObject = game.getObject(source.getSourceId());
@ -171,11 +173,11 @@ class TobiasBeckettSpendAnyManaEffect extends AsThoughEffectImpl implements AsTh
@Override @Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
objectId = game.getCard(objectId).getMainCard().getId(); // for split cards objectId = game.getCard(objectId).getMainCard().getId(); // for split cards
FixedTarget fixedTarget = ((FixedTarget) getTargetPointer());
return source.isControlledBy(affectedControllerId) return source.isControlledBy(affectedControllerId)
&& Objects.equals(objectId, ((FixedTarget) getTargetPointer()).getTarget()) && Objects.equals(objectId, fixedTarget.getTarget())
&& ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1 == game.getState().getZoneChangeCounter(objectId) && game.getState().getZoneChangeCounter(objectId) <= fixedTarget.getZoneChangeCounter() + 1
&& (((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1 == game.getState().getZoneChangeCounter(objectId)) && (game.getState().getZone(objectId) == Zone.STACK || game.getState().getZone(objectId) == Zone.EXILED);
&& game.getState().getZone(objectId) == Zone.STACK;
} }
@Override @Override

View file

@ -1,4 +1,3 @@
package mage.cards.v; package mage.cards.v;
import mage.MageInt; import mage.MageInt;
@ -83,12 +82,10 @@ class VizierOfTheMenagerieTopCardCastEffect extends AsThoughEffectImpl {
MageObject vizierOfTheMenagerie = game.getObject(source.getSourceId()); MageObject vizierOfTheMenagerie = game.getObject(source.getSourceId());
if (vizierOfTheMenagerie != null if (vizierOfTheMenagerie != null
&& topCard != null) { && topCard != null) {
if (topCard == card return topCard == card
&& topCard.isCreature() && topCard.isCreature()
&& topCard.getSpellAbility() != null && topCard.getSpellAbility() != null
&& topCard.getSpellAbility().spellCanBeActivatedRegularlyNow(controller.getId(), game)) { && topCard.getSpellAbility().spellCanBeActivatedRegularlyNow(controller.getId(), game);
return true;
}
} }
} }
} }
@ -120,10 +117,10 @@ class VizierOfTheMenagerieManaEffect extends AsThoughEffectImpl implements AsTho
@Override @Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
objectId = game.getCard(objectId).getMainCard().getId(); // for split cards
if (source.isControlledBy(affectedControllerId)) { if (source.isControlledBy(affectedControllerId)) {
MageObject mageObject = game.getObject(objectId); MageObject mageObject = game.getObject(objectId);
return mageObject != null return mageObject != null && mageObject.isCreature();
&& mageObject.isCreature();
} }
return false; return false;
} }

View file

@ -1,4 +1,3 @@
package org.mage.test.cards.continuous; package org.mage.test.cards.continuous;
import mage.constants.PhaseStep; import mage.constants.PhaseStep;
@ -7,7 +6,6 @@ import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase; import org.mage.test.serverside.base.CardTestPlayerBase;
/** /**
*
* @author LevelX2 * @author LevelX2
*/ */
@ -23,20 +21,22 @@ public class PsychicIntrusionTest extends CardTestPlayerBase {
// Target opponent reveals their hand. You choose a nonland card from that player's // Target opponent reveals their hand. You choose a nonland card from that player's
// graveyard or hand and exile it. You may cast that card for as long as it remains exiled, // graveyard or 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. // and you may spend mana as though it were mana of any color to cast that spell.
addCard(Zone.HAND, playerA, "Psychic Intrusion", 1); addCard(Zone.HAND, playerA, "Psychic Intrusion", 1);
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 3); addCard(Zone.BATTLEFIELD, playerA, "Swamp", 3);
addCard(Zone.BATTLEFIELD, playerA, "Island", 3); addCard(Zone.BATTLEFIELD, playerA, "Island", 3);
addCard(Zone.HAND, playerB, "Elspeth, Sun's Champion", 1); addCard(Zone.HAND, playerB, "Elspeth, Sun's Champion", 1); // {4}{W}{W}
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Psychic Intrusion", playerB); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Psychic Intrusion", playerB);
addTarget(playerA, "Elspeth, Sun's Champion"); setChoice(playerA, "Elspeth, Sun's Champion");
// cast from exile with any mana // cast from exile with any mana
castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerA, "Elspeth, Sun's Champion"); castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerA, "Elspeth, Sun's Champion");
setStrictChooseMode(true);
setStopAt(3, PhaseStep.BEGIN_COMBAT); setStopAt(3, PhaseStep.BEGIN_COMBAT);
execute(); execute();
assertAllCommandsUsed();
assertGraveyardCount(playerA, "Psychic Intrusion", 1); assertGraveyardCount(playerA, "Psychic Intrusion", 1);
assertHandCount(playerB, "Elspeth, Sun's Champion", 0); assertHandCount(playerB, "Elspeth, Sun's Champion", 0);