diff --git a/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java b/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java index e3254b3a02..75be926ecb 100644 --- a/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java +++ b/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java @@ -1742,7 +1742,7 @@ public class HumanPlayer extends PlayerImpl { if (ability instanceof PlayLandAbility) { return true; } - if (!ability.getSourceId().equals(getCastSourceIdWithAlternateMana()) + if (!getCastSourceIdWithAlternateMana().contains(ability.getSourceId()) && ability.getManaCostsToPay().convertedManaCost() > 0) { return true; } diff --git a/Mage.Sets/src/mage/cards/b/BolassCitadel.java b/Mage.Sets/src/mage/cards/b/BolassCitadel.java index 32da651d46..5741a658b0 100644 --- a/Mage.Sets/src/mage/cards/b/BolassCitadel.java +++ b/Mage.Sets/src/mage/cards/b/BolassCitadel.java @@ -96,15 +96,14 @@ class BolassCitadelPlayTheTopCardEffect extends AsThoughEffectImpl { @Override public boolean applies(UUID objectId, Ability affectedAbility, Ability source, Game game, UUID playerId) { - Card cardOnTop = game.getCard(objectId); - if (cardOnTop == null) { - return false; - } - if (playerId.equals(source.getControllerId()) - && cardOnTop.isOwnedBy(source.getControllerId())) { - Player controller = game.getPlayer(cardOnTop.getOwnerId()); + Card cardToCheck = game.getCard(objectId); + objectId = game.getCard(objectId).getMainCard().getId(); // for split cards + + if (playerId.equals(source.getControllerId()) && cardToCheck.isOwnedBy(source.getControllerId())) { + Player controller = game.getPlayer(cardToCheck.getOwnerId()); if (controller != null - && cardOnTop.equals(controller.getLibrary().getFromTop(game))) { + && controller.getLibrary().getFromTop(game) != null + && objectId.equals(controller.getLibrary().getFromTop(game).getId())) { if (affectedAbility instanceof ActivatedAbility) { ActivatedAbility activatedAbility = (ActivatedAbility) affectedAbility; // add the life cost first diff --git a/Mage.Sets/src/mage/cards/c/CovetousUrge.java b/Mage.Sets/src/mage/cards/c/CovetousUrge.java index 45b570c261..b3cf2030bf 100644 --- a/Mage.Sets/src/mage/cards/c/CovetousUrge.java +++ b/Mage.Sets/src/mage/cards/c/CovetousUrge.java @@ -156,11 +156,12 @@ class CovetousUrgeSpendAnyManaEffect extends AsThoughEffectImpl implements AsTho @Override 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) && Objects.equals(objectId, fixedTarget.getTarget()) - && fixedTarget.getZoneChangeCounter() + 1 == game.getState().getZoneChangeCounter(objectId) - && game.getState().getZone(objectId) == Zone.STACK; + && game.getState().getZoneChangeCounter(objectId) <= fixedTarget.getZoneChangeCounter() + 1 + && (game.getState().getZone(objectId) == Zone.STACK || game.getState().getZone(objectId) == Zone.EXILED); } @Override diff --git a/Mage.Sets/src/mage/cards/c/CunningAbduction.java b/Mage.Sets/src/mage/cards/c/CunningAbduction.java index 48553cd2ea..d0d5bd1cc4 100644 --- a/Mage.Sets/src/mage/cards/c/CunningAbduction.java +++ b/Mage.Sets/src/mage/cards/c/CunningAbduction.java @@ -1,6 +1,5 @@ package mage.cards.c; -import java.util.UUID; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.effects.AsThoughEffectImpl; @@ -21,8 +20,9 @@ import mage.target.common.TargetOpponent; import mage.target.targetpointer.FixedTarget; import mage.util.CardUtil; +import java.util.UUID; + /** - * * @author Styxo */ 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 if (objectId.equals(((FixedTarget) getTargetPointer()).getTarget()) && 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 - if (game.getState().getZoneChangeCounter(objectId) == ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1) { - return true; - } - } + // 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?) + return affectedControllerId.equals(source.getControllerId()); } else if (((FixedTarget) getTargetPointer()).getTarget().equals(objectId)) { // object has moved zone so effect can be discarted this.discard(); diff --git a/Mage.Sets/src/mage/cards/d/DaxosOfMeletis.java b/Mage.Sets/src/mage/cards/d/DaxosOfMeletis.java index e9cc591624..da160f068f 100644 --- a/Mage.Sets/src/mage/cards/d/DaxosOfMeletis.java +++ b/Mage.Sets/src/mage/cards/d/DaxosOfMeletis.java @@ -1,7 +1,5 @@ package mage.cards.d; -import java.util.Objects; -import java.util.UUID; import mage.MageInt; import mage.MageObject; import mage.abilities.Ability; @@ -26,8 +24,10 @@ import mage.players.Player; import mage.target.targetpointer.FixedTarget; import mage.util.CardUtil; +import java.util.Objects; +import java.util.UUID; + /** - * * @author LevelX2 */ public final class DaxosOfMeletis extends CardImpl { @@ -178,11 +178,11 @@ class DaxosOfMeletisSpendAnyManaEffect extends AsThoughEffectImpl implements AsT @Override 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) - && Objects.equals(objectId, ((FixedTarget) getTargetPointer()).getTarget()) - && ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1 == game.getState().getZoneChangeCounter(objectId) - && (((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1 == game.getState().getZoneChangeCounter(objectId)) - && game.getState().getZone(objectId) == Zone.STACK; + && Objects.equals(objectId, fixedTarget.getTarget()) + && game.getState().getZoneChangeCounter(objectId) <= fixedTarget.getZoneChangeCounter() + 1 + && (game.getState().getZone(objectId) == Zone.STACK || game.getState().getZone(objectId) == Zone.EXILED); } @Override diff --git a/Mage.Sets/src/mage/cards/d/DeadMansChest.java b/Mage.Sets/src/mage/cards/d/DeadMansChest.java index 284ec871fb..c88eabc0f7 100644 --- a/Mage.Sets/src/mage/cards/d/DeadMansChest.java +++ b/Mage.Sets/src/mage/cards/d/DeadMansChest.java @@ -1,7 +1,5 @@ package mage.cards.d; -import java.util.Set; -import java.util.UUID; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.DiesAttachedTriggeredAbility; @@ -15,14 +13,7 @@ import mage.abilities.keyword.EnchantAbility; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -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.TargetController; -import mage.constants.Zone; +import mage.constants.*; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.permanent.ControllerPredicate; import mage.game.Game; @@ -32,8 +23,10 @@ import mage.players.Player; import mage.target.TargetPermanent; import mage.target.targetpointer.FixedTarget; +import java.util.Set; +import java.util.UUID; + /** - * * @author LevelX2 */ public final class DeadMansChest extends CardImpl { @@ -142,9 +135,7 @@ class DeadMansChestCastFromExileEffect extends AsThoughEffectImpl { @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; - } + return affectedControllerId.equals(source.getControllerId()); } else { if (((FixedTarget) getTargetPointer()).getTarget().equals(objectId)) { // 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 if (objectId.equals(((FixedTarget) getTargetPointer()).getTarget()) && 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 - if (game.getState().getZoneChangeCounter(objectId) == ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1) { - return true; - } - } + // 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?) + return affectedControllerId.equals(source.getControllerId()); } else { if (((FixedTarget) getTargetPointer()).getTarget().equals(objectId)) { // object has moved zone so effect can be discarted diff --git a/Mage.Sets/src/mage/cards/d/DireFleetDaredevil.java b/Mage.Sets/src/mage/cards/d/DireFleetDaredevil.java index c39708c893..bf72d24447 100644 --- a/Mage.Sets/src/mage/cards/d/DireFleetDaredevil.java +++ b/Mage.Sets/src/mage/cards/d/DireFleetDaredevil.java @@ -1,27 +1,15 @@ package mage.cards.d; -import java.util.Objects; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.effects.AsThoughEffectImpl; -import mage.abilities.effects.AsThoughManaEffect; -import mage.abilities.effects.ContinuousEffect; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.effects.*; import mage.abilities.effects.common.asthought.PlayFromNotOwnHandZoneTargetEffect; import mage.abilities.keyword.FirstStrikeAbility; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -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.constants.*; import mage.filter.FilterCard; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.CardTypePredicate; @@ -34,8 +22,10 @@ import mage.players.Player; import mage.target.common.TargetCardInOpponentsGraveyard; import mage.target.targetpointer.FixedTarget; +import java.util.Objects; +import java.util.UUID; + /** - * * @author LevelX2 */ public final class DireFleetDaredevil extends CardImpl { @@ -144,10 +134,11 @@ class DireFleetDaredevilSpendAnyManaEffect extends AsThoughEffectImpl implements @Override 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) && Objects.equals(objectId, ((FixedTarget) getTargetPointer()).getTarget()) - && ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1 == game.getState().getZoneChangeCounter(objectId) - && game.getState().getZone(objectId) == Zone.STACK; + && game.getState().getZoneChangeCounter(objectId) <= fixedTarget.getZoneChangeCounter() + 1 + && (game.getState().getZone(objectId) == Zone.STACK || game.getState().getZone(objectId) == Zone.EXILED); } @Override @@ -192,7 +183,7 @@ class DireFleetDaredevilReplacementEffect extends ReplacementEffectImpl { ZoneChangeEvent zEvent = (ZoneChangeEvent) event; return zEvent.getToZone() == Zone.GRAVEYARD && event.getTargetId().equals(((FixedTarget) getTargetPointer()).getTarget()) - && ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1 + && ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1 == game.getState().getZoneChangeCounter(event.getTargetId()); } } diff --git a/Mage.Sets/src/mage/cards/g/GontiLordOfLuxury.java b/Mage.Sets/src/mage/cards/g/GontiLordOfLuxury.java index 0755e3a282..b4b5adf337 100644 --- a/Mage.Sets/src/mage/cards/g/GontiLordOfLuxury.java +++ b/Mage.Sets/src/mage/cards/g/GontiLordOfLuxury.java @@ -1,8 +1,5 @@ package mage.cards.g; -import java.util.HashSet; -import java.util.Set; -import java.util.UUID; import mage.MageInt; import mage.MageObject; import mage.abilities.Ability; @@ -25,8 +22,11 @@ import mage.target.common.TargetOpponent; import mage.target.targetpointer.FixedTarget; import mage.util.CardUtil; +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; + /** - * * @author LevelX2 */ public final class GontiLordOfLuxury extends CardImpl { @@ -185,22 +185,18 @@ class GontiLordOfLuxurySpendAnyManaEffect extends AsThoughEffectImpl implements @Override public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { Card theCard = game.getCard(objectId); - if(theCard == null){ + if (theCard == null) { return false; } Card mainCard = theCard.getMainCard(); - if(mainCard == null){ + if (mainCard == null) { return false; } objectId = mainCard.getId(); // for split cards if (objectId.equals(((FixedTarget) getTargetPointer()).getTarget()) && 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 - if (game.getState().getZoneChangeCounter(objectId) == ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1) { - return true; - } - } + // 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?) + return affectedControllerId.equals(source.getControllerId()); } else if (((FixedTarget) getTargetPointer()).getTarget().equals(objectId)) { // object has moved zone so effect can be discarted this.discard(); @@ -238,11 +234,11 @@ class GontiLordOfLuxuryLookEffect extends AsThoughEffectImpl { @Override public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { Card theCard = game.getCard(objectId); - if(theCard == null){ + if (theCard == null) { return false; } Card mainCard = theCard.getMainCard(); - if(mainCard == null){ + if (mainCard == null) { return false; } objectId = mainCard.getId(); // for split cards diff --git a/Mage.Sets/src/mage/cards/g/GrenzoHavocRaiser.java b/Mage.Sets/src/mage/cards/g/GrenzoHavocRaiser.java index 478e2432a8..6553e92444 100644 --- a/Mage.Sets/src/mage/cards/g/GrenzoHavocRaiser.java +++ b/Mage.Sets/src/mage/cards/g/GrenzoHavocRaiser.java @@ -233,11 +233,12 @@ class GrenzoHavocRaiserSpendAnyManaEffect extends AsThoughEffectImpl implements @Override 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) && Objects.equals(objectId, ((FixedTarget) getTargetPointer()).getTarget()) - && ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1 == game.getState().getZoneChangeCounter(objectId) - && (((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1 == game.getState().getZoneChangeCounter(objectId)) - && game.getState().getZone(objectId) == Zone.STACK; + && game.getState().getZoneChangeCounter(objectId) <= fixedTarget.getZoneChangeCounter() + 1 + && (game.getState().getZone(objectId) == Zone.STACK || game.getState().getZone(objectId) == Zone.EXILED); } @Override diff --git a/Mage.Sets/src/mage/cards/h/HostageTaker.java b/Mage.Sets/src/mage/cards/h/HostageTaker.java index 816ff40e09..64ff610c52 100644 --- a/Mage.Sets/src/mage/cards/h/HostageTaker.java +++ b/Mage.Sets/src/mage/cards/h/HostageTaker.java @@ -106,7 +106,7 @@ class HostageTakerExileEffect extends OneShotEffect { ContinuousEffect effect = new HostageTakerSpendAnyManaEffect(); effect.setTargetPointer(new FixedTarget(card.getId(), game)); game.addEffect(effect, source); - return false; + return true; } } @@ -173,11 +173,12 @@ class HostageTakerSpendAnyManaEffect extends AsThoughEffectImpl implements AsTho @Override 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) && Objects.equals(objectId, fixedTarget.getTarget()) - && fixedTarget.getZoneChangeCounter() + 1 == game.getState().getZoneChangeCounter(objectId) - && game.getState().getZone(objectId) == Zone.STACK; + && game.getState().getZoneChangeCounter(objectId) <= fixedTarget.getZoneChangeCounter() + 1 + && (game.getState().getZone(objectId) == Zone.STACK || game.getState().getZone(objectId) == Zone.EXILED); } @Override diff --git a/Mage.Sets/src/mage/cards/o/OathOfNissa.java b/Mage.Sets/src/mage/cards/o/OathOfNissa.java index 6f3fd0a697..04821b21b9 100644 --- a/Mage.Sets/src/mage/cards/o/OathOfNissa.java +++ b/Mage.Sets/src/mage/cards/o/OathOfNissa.java @@ -1,7 +1,5 @@ - package mage.cards.o; -import java.util.UUID; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; @@ -19,8 +17,9 @@ import mage.players.ManaPoolItem; import mage.players.Player; import mage.target.TargetCard; +import java.util.UUID; + /** - * * @author LevelX2 */ public final class OathOfNissa extends CardImpl { @@ -128,13 +127,10 @@ class OathOfNissaSpendAnyManaEffect extends AsThoughEffectImpl implements AsThou @Override public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { + objectId = game.getCard(objectId).getMainCard().getId(); // for split cards if (source.isControlledBy(affectedControllerId)) { MageObject mageObject = game.getObject(objectId); - if (mageObject != null) { - if (mageObject.isPlaneswalker()) { - return true; - } - } + return mageObject != null && mageObject.isPlaneswalker(); } return false; } diff --git a/Mage.Sets/src/mage/cards/p/PsychicIntrusion.java b/Mage.Sets/src/mage/cards/p/PsychicIntrusion.java index 9cc6cc4f33..9383eae170 100644 --- a/Mage.Sets/src/mage/cards/p/PsychicIntrusion.java +++ b/Mage.Sets/src/mage/cards/p/PsychicIntrusion.java @@ -1,6 +1,5 @@ package mage.cards.p; -import java.util.UUID; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.effects.AsThoughEffectImpl; @@ -10,12 +9,7 @@ import mage.abilities.effects.OneShotEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.AsThoughEffectType; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.ManaType; -import mage.constants.Outcome; -import mage.constants.Zone; +import mage.constants.*; import mage.filter.common.FilterNonlandCard; import mage.game.Game; import mage.players.ManaPoolItem; @@ -25,8 +19,9 @@ import mage.target.common.TargetOpponent; import mage.target.targetpointer.FixedTarget; import mage.util.CardUtil; +import java.util.UUID; + /** - * * @author LevelX2 */ public final class PsychicIntrusion extends CardImpl { @@ -149,10 +144,9 @@ class PsychicIntrusionCastFromExileEffect extends AsThoughEffectImpl { @Override 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 (affectedControllerId.equals(source.getControllerId())) { - return true; - } + return affectedControllerId.equals(source.getControllerId()); } else { if (((FixedTarget) getTargetPointer()).getTarget().equals(objectId)) { // 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 if (objectId.equals(((FixedTarget) getTargetPointer()).getTarget()) && 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 - if (game.getState().getZoneChangeCounter(objectId) == ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1) { - return true; - } - } + // 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?) + return affectedControllerId.equals(source.getControllerId()); } else { if (((FixedTarget) getTargetPointer()).getTarget().equals(objectId)) { // object has moved zone so effect can be discarted diff --git a/Mage.Sets/src/mage/cards/q/QuicksilverElemental.java b/Mage.Sets/src/mage/cards/q/QuicksilverElemental.java index 994db84272..24734a42a8 100644 --- a/Mage.Sets/src/mage/cards/q/QuicksilverElemental.java +++ b/Mage.Sets/src/mage/cards/q/QuicksilverElemental.java @@ -1,7 +1,5 @@ - package mage.cards.q; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.ActivatedAbility; @@ -10,28 +8,20 @@ import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.AsThoughEffectImpl; import mage.abilities.effects.AsThoughManaEffect; -import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.AsThoughEffectType; -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.constants.*; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.ManaPoolItem; import mage.target.common.TargetCreaturePermanent; import mage.target.targetpointer.FixedTarget; +import java.util.UUID; + /** - * * @author spjspj */ public final class QuicksilverElemental extends CardImpl { @@ -151,10 +141,9 @@ class QuickSilverElementalBlueManaEffect extends AsThoughEffectImpl implements A @Override 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 (affectedControllerId.equals(source.getControllerId())) { - return true; - } + return affectedControllerId.equals(source.getControllerId()); } return false; diff --git a/Mage.Sets/src/mage/cards/r/RobberOfTheRich.java b/Mage.Sets/src/mage/cards/r/RobberOfTheRich.java index 923b51ecb1..68c79579ec 100644 --- a/Mage.Sets/src/mage/cards/r/RobberOfTheRich.java +++ b/Mage.Sets/src/mage/cards/r/RobberOfTheRich.java @@ -194,11 +194,12 @@ class RobberOfTheRichSpendAnyManaEffect extends AsThoughEffectImpl implements As @Override 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) && Objects.equals(objectId, fixedTarget.getTarget()) - && fixedTarget.getZoneChangeCounter() + 1 == game.getState().getZoneChangeCounter(objectId) - && game.getState().getZone(objectId) == Zone.STACK; + && game.getState().getZoneChangeCounter(objectId) <= fixedTarget.getZoneChangeCounter() + 1 + && (game.getState().getZone(objectId) == Zone.STACK || game.getState().getZone(objectId) == Zone.EXILED); } @Override diff --git a/Mage.Sets/src/mage/cards/s/StolenStrategy.java b/Mage.Sets/src/mage/cards/s/StolenStrategy.java index e20f44395e..9a89e8c370 100644 --- a/Mage.Sets/src/mage/cards/s/StolenStrategy.java +++ b/Mage.Sets/src/mage/cards/s/StolenStrategy.java @@ -1,8 +1,5 @@ - package mage.cards.s; -import java.util.Objects; -import java.util.UUID; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; @@ -13,13 +10,7 @@ import mage.abilities.effects.OneShotEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.AsThoughEffectType; -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.constants.*; import mage.game.ExileZone; import mage.game.Game; import mage.players.ManaPoolItem; @@ -27,8 +18,10 @@ import mage.players.Player; import mage.target.targetpointer.FixedTarget; import mage.util.CardUtil; +import java.util.Objects; +import java.util.UUID; + /** - * * @author TheElk801 */ public final class StolenStrategy extends CardImpl { @@ -165,11 +158,11 @@ class StolenStrategySpendAnyManaEffect extends AsThoughEffectImpl implements AsT @Override 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) - && Objects.equals(objectId, ((FixedTarget) getTargetPointer()).getTarget()) - && ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1 == game.getState().getZoneChangeCounter(objectId) - && (((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1 == game.getState().getZoneChangeCounter(objectId)) - && game.getState().getZone(objectId) == Zone.STACK; + && Objects.equals(objectId, fixedTarget.getTarget()) + && game.getState().getZoneChangeCounter(objectId) <= fixedTarget.getZoneChangeCounter() + 1 + && (game.getState().getZone(objectId) == Zone.STACK || game.getState().getZone(objectId) == Zone.EXILED); } @Override diff --git a/Mage.Sets/src/mage/cards/t/ThiefOfSanity.java b/Mage.Sets/src/mage/cards/t/ThiefOfSanity.java index 818970680f..2a44855fa2 100644 --- a/Mage.Sets/src/mage/cards/t/ThiefOfSanity.java +++ b/Mage.Sets/src/mage/cards/t/ThiefOfSanity.java @@ -1,8 +1,5 @@ package mage.cards.t; -import java.util.HashSet; -import java.util.Set; -import java.util.UUID; import mage.MageInt; import mage.MageObject; import mage.abilities.Ability; @@ -12,18 +9,8 @@ import mage.abilities.effects.AsThoughManaEffect; import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.OneShotEffect; import mage.abilities.keyword.FlyingAbility; -import mage.cards.Card; -import mage.cards.CardImpl; -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.cards.*; +import mage.constants.*; import mage.filter.FilterCard; import mage.game.Game; import mage.players.ManaPoolItem; @@ -32,8 +19,11 @@ import mage.target.TargetCard; import mage.target.targetpointer.FixedTarget; import mage.util.CardUtil; +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; + /** - * * @author LevelX2 */ 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 if (objectId.equals(((FixedTarget) getTargetPointer()).getTarget()) && game.getState().getZoneChangeCounter(objectId) <= ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1) { - if (affectedControllerId.equals(authorizedPlayerId)) { - // if the card moved from exile to stack the zone change counter is increased by 1 - if (game.getState().getZoneChangeCounter(objectId) == ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1) { - return true; - } - } + // 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?) + return affectedControllerId.equals(authorizedPlayerId); } else if (((FixedTarget) getTargetPointer()).getTarget().equals(objectId)) { // object has moved zone so effect can be discarted this.discard(); diff --git a/Mage.Sets/src/mage/cards/t/TobiasBeckett.java b/Mage.Sets/src/mage/cards/t/TobiasBeckett.java index e258e5078d..0ad1a9c4ae 100644 --- a/Mage.Sets/src/mage/cards/t/TobiasBeckett.java +++ b/Mage.Sets/src/mage/cards/t/TobiasBeckett.java @@ -1,19 +1,19 @@ package mage.cards.t; -import java.util.Objects; -import java.util.UUID; import mage.MageInt; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.effects.*; -import mage.abilities.effects.common.ExileCardsFromTopOfLibraryTargetEffect; +import mage.abilities.effects.AsThoughEffectImpl; +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.keyword.BountyAbility; import mage.cards.Card; -import mage.constants.*; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.*; import mage.counters.CounterType; import mage.game.ExileZone; import mage.game.Game; @@ -24,15 +24,17 @@ import mage.target.common.TargetOpponentsCreaturePermanent; import mage.target.targetpointer.FixedTarget; import mage.util.CardUtil; +import java.util.Objects; +import java.util.UUID; + /** - * * @author NinthWorld */ public final class TobiasBeckett extends CardImpl { public TobiasBeckett(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}"); - + this.addSuperType(SuperType.LEGENDARY); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.HUNTER); @@ -75,7 +77,7 @@ class TobiasBeckettEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { Permanent bountyTriggered = game.getPermanent(this.getTargetPointer().getFirst(game, source)); - if(bountyTriggered != null) { + if (bountyTriggered != null) { Player opponent = game.getPlayer(bountyTriggered.getControllerId()); if (opponent != null) { MageObject sourceObject = game.getObject(source.getSourceId()); @@ -171,11 +173,11 @@ class TobiasBeckettSpendAnyManaEffect extends AsThoughEffectImpl implements AsTh @Override 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) - && Objects.equals(objectId, ((FixedTarget) getTargetPointer()).getTarget()) - && ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1 == game.getState().getZoneChangeCounter(objectId) - && (((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1 == game.getState().getZoneChangeCounter(objectId)) - && game.getState().getZone(objectId) == Zone.STACK; + && Objects.equals(objectId, fixedTarget.getTarget()) + && game.getState().getZoneChangeCounter(objectId) <= fixedTarget.getZoneChangeCounter() + 1 + && (game.getState().getZone(objectId) == Zone.STACK || game.getState().getZone(objectId) == Zone.EXILED); } @Override diff --git a/Mage.Sets/src/mage/cards/v/ViviensInvocation.java b/Mage.Sets/src/mage/cards/v/ViviensInvocation.java index 7eacc7e747..23d46f0a18 100644 --- a/Mage.Sets/src/mage/cards/v/ViviensInvocation.java +++ b/Mage.Sets/src/mage/cards/v/ViviensInvocation.java @@ -73,6 +73,7 @@ class ViviensInvocationEffect extends OneShotEffect { Zone.LIBRARY, new FilterCreatureCard("creature card to put on the battlefield") ); + target.setNotTarget(true); if (controller.choose(Outcome.PutCreatureInPlay, cards, target, game)) { Card card = cards.get(target.getFirstTarget(), game); if (card != null) { diff --git a/Mage.Sets/src/mage/cards/v/VizierOfTheMenagerie.java b/Mage.Sets/src/mage/cards/v/VizierOfTheMenagerie.java index a51a1e68b5..6e424515cf 100644 --- a/Mage.Sets/src/mage/cards/v/VizierOfTheMenagerie.java +++ b/Mage.Sets/src/mage/cards/v/VizierOfTheMenagerie.java @@ -1,4 +1,3 @@ - package mage.cards.v; import mage.MageInt; @@ -83,12 +82,10 @@ class VizierOfTheMenagerieTopCardCastEffect extends AsThoughEffectImpl { MageObject vizierOfTheMenagerie = game.getObject(source.getSourceId()); if (vizierOfTheMenagerie != null && topCard != null) { - if (topCard == card + return topCard == card && topCard.isCreature() && topCard.getSpellAbility() != null - && topCard.getSpellAbility().spellCanBeActivatedRegularlyNow(controller.getId(), game)) { - return true; - } + && topCard.getSpellAbility().spellCanBeActivatedRegularlyNow(controller.getId(), game); } } } @@ -120,10 +117,10 @@ class VizierOfTheMenagerieManaEffect extends AsThoughEffectImpl implements AsTho @Override public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { + objectId = game.getCard(objectId).getMainCard().getId(); // for split cards if (source.isControlledBy(affectedControllerId)) { MageObject mageObject = game.getObject(objectId); - return mageObject != null - && mageObject.isCreature(); + return mageObject != null && mageObject.isCreature(); } return false; } diff --git a/Mage.Tests/src/test/java/org/mage/test/AI/basic/CastCreaturesTest.java b/Mage.Tests/src/test/java/org/mage/test/AI/basic/CastCreaturesTest.java index 268b58f7ef..db8796ba96 100644 --- a/Mage.Tests/src/test/java/org/mage/test/AI/basic/CastCreaturesTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/AI/basic/CastCreaturesTest.java @@ -1,4 +1,3 @@ - package org.mage.test.AI.basic; import mage.constants.PhaseStep; @@ -8,7 +7,6 @@ import org.junit.Test; import org.mage.test.serverside.base.CardTestPlayerBaseAI; /** - * * @author LevelX2 */ public class CastCreaturesTest extends CardTestPlayerBaseAI { @@ -173,7 +171,7 @@ public class CastCreaturesTest extends CardTestPlayerBaseAI { /** * Tests that the creature is cast if enough mana is available. - * + *
* Once Ammit Eternal is cast against a computer AI opponent, the AI just * decides to sit there and only play basic lands. I've sat there and decked * it because it just plays lands. It's like it views giving the Ammit @@ -194,8 +192,11 @@ public class CastCreaturesTest extends CardTestPlayerBaseAI { addCard(Zone.BATTLEFIELD, playerB, "Swamp", 3); castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Ammit Eternal"); + + setStrictChooseMode(true); setStopAt(3, PhaseStep.END_TURN); execute(); + assertAllCommandsUsed(); assertPermanentCount(playerB, "Ammit Eternal", 1); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/activated/LightningStormTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/activated/LightningStormTest.java index e1ddf99d6d..8c900e619c 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/activated/LightningStormTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/activated/LightningStormTest.java @@ -1,4 +1,3 @@ - package org.mage.test.cards.abilities.activated; import mage.constants.PhaseStep; @@ -7,7 +6,6 @@ import org.junit.Test; import org.mage.test.serverside.base.CardTestPlayerBase; /** - * * @author LevelX2 */ public class LightningStormTest extends CardTestPlayerBase { @@ -16,10 +14,9 @@ public class LightningStormTest extends CardTestPlayerBase { * So, this just happened to me. My opponent cast Lightning Storm and while * it was on the stack I couldn't use the ability despite having land in * hand which isn't something I've had an issue with before. - * + *
* My opponent had a Leyline of Sanctity in play, so perhaps that was * causing the issue somehow? Does anyone want to try and replicate it? - * */ @Test public void ActivateByBothPlayersTest() { @@ -31,22 +28,32 @@ public class LightningStormTest extends CardTestPlayerBase { addCard(Zone.HAND, playerA, "Mountain"); addCard(Zone.HAND, playerB, "Mountain"); + // A activate castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Storm", playerB); + + // B discard and re-target activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Discard"); - setChoice(playerB, "playerA"); + setChoice(playerB, "Mountain"); + setChoice(playerB, "Yes"); + addTarget(playerB, playerA); + + // A discard and re-target activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Discard"); - setChoice(playerA, "playerB"); + setChoice(playerA, "Mountain"); + setChoice(playerA, "Yes"); + addTarget(playerA, playerB); + setStrictChooseMode(true); setStopAt(1, PhaseStep.PRECOMBAT_MAIN); - execute(); + assertAllCommandsUsed(); assertGraveyardCount(playerA, "Lightning Storm", 1); assertGraveyardCount(playerB, "Mountain", 1); assertGraveyardCount(playerA, "Mountain", 1); assertLife(playerA, 20); - assertLife(playerB, 13); + assertLife(playerB, 20 - 3 - 2 - 2); } } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/asthough/PlayTopCardFromLibraryTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/asthough/PlayTopCardFromLibraryTest.java new file mode 100644 index 0000000000..b4013c696b --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/asthough/PlayTopCardFromLibraryTest.java @@ -0,0 +1,128 @@ +package org.mage.test.cards.asthough; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * @author JayDi85 + */ +public class PlayTopCardFromLibraryTest extends CardTestPlayerBase { + + /* + Bolas's Citadel + {3}{B}{B}{B} + You may look at the top card of your library any time. + You may play the top card of your library. If you cast a spell this way, pay life equal to its converted mana cost rather than pay its mana cost. + {T}, Sacrifice ten nonland permanents: Each opponent loses 10 life. + */ + + @Test + public void test_CreaturePlay() { + removeAllCardsFromLibrary(playerA); + addCard(Zone.LIBRARY, playerA, "Balduvian Bears", 1); + addCard(Zone.BATTLEFIELD, playerA, "Bolas's Citadel", 1); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Balduvian Bears"); // 2 CMC + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.END_TURN); + execute(); + assertAllCommandsUsed(); + + assertPermanentCount(playerA, "Balduvian Bears", 1); + assertLife(playerA, 20 - 2); + } + + @Test + public void test_CreaturePlay2() { + removeAllCardsFromLibrary(playerA); + addCard(Zone.LIBRARY, playerA, "Balduvian Bears", 1); + addCard(Zone.BATTLEFIELD, playerA, "Forest", 2); + addCard(Zone.BATTLEFIELD, playerA, "Vizier of the Menagerie", 1); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Balduvian Bears"); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.END_TURN); + execute(); + assertAllCommandsUsed(); + + assertPermanentCount(playerA, "Balduvian Bears", 1); + } + + @Test + public void test_ManaCostmodifications() { + // + // {5}{B}{B} + // You may cast Scourge of Nel Toth from your graveyard by paying {B}{B} and sacrificing two creatures rather than paying its mana cost. + addCard(Zone.GRAVEYARD, playerA, "Scourge of Nel Toth", 1); + addCard(Zone.BATTLEFIELD, playerA, "Kitesail Corsair", 2); + addCard(Zone.BATTLEFIELD, playerA, "Swamp", 2); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Scourge of Nel Toth"); + setChoice(playerA, "Kitesail Corsair"); + setChoice(playerA, "Kitesail Corsair"); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.END_TURN); + execute(); + assertAllCommandsUsed(); + + assertPermanentCount(playerA, "Scourge of Nel Toth", 1); + assertLife(playerA, 20); + } + + @Test + public void test_SplitRightPlay() { + // https://github.com/magefree/mage/issues/5912 + // Bolas's citadel requires you to pay mana instead of life for a split card on top of library. + // + // Steps to reproduce: + // + // Bolas's Citadel in play, Revival//Revenge on top of library. + // Cast Revenge, choose target + // receive prompt to pay 4WB. + // + // Expected outcome + // + // No prompt for mana payment, payment of six life instead. + + removeAllCardsFromLibrary(playerA); + addCard(Zone.LIBRARY, playerA, "Revival // Revenge", 1); + addCard(Zone.BATTLEFIELD, playerA, "Bolas's Citadel", 1); + + // Double your life total. Target opponent loses half their life, rounded up. + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Revenge", playerB); // {4}{W}{B} = 6 life + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.END_TURN); + execute(); + assertAllCommandsUsed(); + + assertLife(playerA, (20 - 6) * 2); + assertLife(playerB, 20 / 2); + } + + @Test + public void test_SplitLeftPlay() { + removeAllCardsFromLibrary(playerA); + addCard(Zone.LIBRARY, playerA, "Revival // Revenge", 1); + addCard(Zone.BATTLEFIELD, playerA, "Bolas's Citadel", 1); + addCard(Zone.GRAVEYARD, playerA, "Balduvian Bears", 1); + + // Return target creature card with converted mana cost 3 or less from your graveyard to the battlefield. + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Revival", "Balduvian Bears"); // {W/B}{W/B} = 2 life + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.END_TURN); + execute(); + assertAllCommandsUsed(); + + assertLife(playerA, 20 - 2); + assertLife(playerB, 20); + assertGraveyardCount(playerA, "Balduvian Bears", 0); + assertPermanentCount(playerA, "Balduvian Bears", 1); + } +} diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/asthough/SpendOtherManaTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/asthough/SpendOtherManaTest.java index 1d117fc88b..3176f1d128 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/asthough/SpendOtherManaTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/asthough/SpendOtherManaTest.java @@ -1,4 +1,3 @@ - package org.mage.test.cards.asthough; import mage.constants.PhaseStep; @@ -7,7 +6,6 @@ import org.junit.Test; import org.mage.test.serverside.base.CardTestPlayerBase; /** - * * @author LevelX2 */ public class SpendOtherManaTest extends CardTestPlayerBase { @@ -47,7 +45,7 @@ public class SpendOtherManaTest extends CardTestPlayerBase { /** * Tron mana doesn't work with Oath of Nissa. (e.g. can't cast Chandra, * Flamecaller with Urza's Tower, Power Plant, and Mine.) - * + *
* AI don't get the Planeswalker as playable card (probably because of the * as thought effect) */ @@ -76,7 +74,7 @@ public class SpendOtherManaTest extends CardTestPlayerBase { * I was unable to cast Nissa, Voice of Zendikar using black mana with Oath * of Nissa in play. Pretty sure Oath is working usually, so here were the * conditions in my game: - * + *
* -Cast Dark Petition with spell mastery -Attempt to cast Nissa, Voice of
* Zendikar using the triple black mana from Dark Petition
*/
@@ -122,20 +120,84 @@ public class SpendOtherManaTest extends CardTestPlayerBase {
addCard(Zone.HAND, playerA, "Hostage Taker"); // {2}{U}{B}
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Hostage Taker");
- setChoice(playerA, "Silvercoat Lion");
+ addTarget(playerA, "Silvercoat Lion");
+ // red mana must be used as any mana
activateManaAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{T}: Add {R}."); // red mana to pool
activateManaAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{T}: Add {R}."); // red mana to pool
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Silvercoat Lion"); // cast it from exile with red mana from pool
+ setStrictChooseMode(true);
setStopAt(1, PhaseStep.END_TURN);
execute();
+ assertAllCommandsUsed();
assertPermanentCount(playerA, "Hostage Taker", 1);
assertTappedCount("Mountain", true, 4);
assertPermanentCount(playerA, "Silvercoat Lion", 1);
-
}
+ @Test
+ public void test_QuicksilverElemental_Normal() {
+ addCard(Zone.BATTLEFIELD, playerA, "Island", 2);
+
+ // {U}: Quicksilver Elemental gains all activated abilities of target creature until end of turn.
+ // You may spend blue mana as though it were mana of any color to pay the activation costs of Quicksilver Elemental’s abilities.
+ addCard(Zone.BATTLEFIELD, playerA, "Quicksilver Elemental"); // Creature {1}{W}
+ // {R}, {T}: Anaba Shaman deals 1 damage to any target.
+ addCard(Zone.BATTLEFIELD, playerB, "Anaba Shaman");
+
+ // gain abilities
+ checkPlayableAbility("must not have", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "{R}, {T}:", false);
+ activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{U}:", "Anaba Shaman");
+
+ // use ability
+ checkPlayableAbility("must have new ability", 1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{R}, {T}:", true);
+ activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{R}, {T}:", playerB);
+
+ setStrictChooseMode(true);
+ setStopAt(1, PhaseStep.END_TURN);
+ execute();
+ assertAllCommandsUsed();
+
+ assertLife(playerA, 20);
+ assertLife(playerB, 20 - 1);
+ }
+
+ @Test
+ public void test_QuicksilverElemental_Flicker() {
+ addCard(Zone.BATTLEFIELD, playerA, "Island", 2);
+
+ // {U}: Quicksilver Elemental gains all activated abilities of target creature until end of turn.
+ // You may spend blue mana as though it were mana of any color to pay the activation costs of Quicksilver Elemental’s abilities.
+ addCard(Zone.BATTLEFIELD, playerA, "Quicksilver Elemental"); // Creature {1}{W}
+ // {R}, {T}: Anaba Shaman deals 1 damage to any target.
+ addCard(Zone.BATTLEFIELD, playerB, "Anaba Shaman");
+ // Exile target nontoken permanent, then return it to the battlefield under its owner’s control.
+ addCard(Zone.HAND, playerA, "Flicker"); // {1}{W}
+ addCard(Zone.BATTLEFIELD, playerA, "Plains", 2);
+
+ // gain abilities
+ checkPlayableAbility("must not have", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "{R}, {T}:", false);
+ activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{U}:", "Anaba Shaman");
+ waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, playerA);
+ checkPlayableAbility("must have new ability", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "{R}, {T}:", true);
+
+ // renew target
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Flicker", "Anaba Shaman");
+
+ // use ability
+ checkPlayableAbility("must save ability", 1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{R}, {T}:", true);
+ activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{R}, {T}:", playerB);
+
+ setStrictChooseMode(true);
+ setStopAt(1, PhaseStep.END_TURN);
+ execute();
+ assertAllCommandsUsed();
+
+ assertGraveyardCount(playerA, "Flicker", 1);
+ assertLife(playerA, 20);
+ assertLife(playerB, 20 - 1);
+ }
}
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/continuous/PsychicIntrusionTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/continuous/PsychicIntrusionTest.java
index 681b4981bf..3afca6ea16 100644
--- a/Mage.Tests/src/test/java/org/mage/test/cards/continuous/PsychicIntrusionTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/continuous/PsychicIntrusionTest.java
@@ -1,4 +1,3 @@
-
package org.mage.test.cards.continuous;
import mage.constants.PhaseStep;
@@ -7,7 +6,6 @@ import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
- *
* @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
// 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.
- addCard(Zone.HAND, playerA, "Psychic Intrusion", 1);
+ addCard(Zone.HAND, playerA, "Psychic Intrusion", 1);
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 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);
- addTarget(playerA, "Elspeth, Sun's Champion");
-
+ setChoice(playerA, "Elspeth, Sun's Champion");
+
// cast from exile with any mana
castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerA, "Elspeth, Sun's Champion");
-
+
+ setStrictChooseMode(true);
setStopAt(3, PhaseStep.BEGIN_COMBAT);
execute();
+ assertAllCommandsUsed();
assertGraveyardCount(playerA, "Psychic Intrusion", 1);
assertHandCount(playerB, "Elspeth, Sun's Champion", 0);
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/cost/adventure/AdventureCardsTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/cost/adventure/AdventureCardsTest.java
index 470ea3b23d..ac2e2d6fe6 100644
--- a/Mage.Tests/src/test/java/org/mage/test/cards/cost/adventure/AdventureCardsTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/cost/adventure/AdventureCardsTest.java
@@ -5,7 +5,6 @@ import mage.constants.Zone;
import mage.counters.CounterType;
import mage.game.permanent.Permanent;
import org.junit.Assert;
-import org.junit.Ignore;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
@@ -282,7 +281,8 @@ public class AdventureCardsTest extends CardTestPlayerBase {
addCard(Zone.HAND, playerB, "Curious Pair");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Psychic Intrusion", playerB);
- playerA.addChoice("Curious Pair");
+ setChoice(playerA, "Curious Pair");
+
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Treats to Share");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Curious Pair");
@@ -462,6 +462,7 @@ public class AdventureCardsTest extends CardTestPlayerBase {
removeAllCardsFromLibrary(playerA);
addCard(Zone.LIBRARY, playerA, "Curious Pair");
+ showAvaileableAbilities("abils", 1, PhaseStep.PRECOMBAT_MAIN, playerA);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Treats to Share");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
@@ -473,7 +474,7 @@ public class AdventureCardsTest extends CardTestPlayerBase {
}
@Test
- @Ignore("Not yet working correctly.")
+ //@Ignore("Not yet working correctly.")
public void testCastTreatsToShareWithWrennAndSixEmblem() {
/*
* Wrenn and Six {R}{G}
@@ -487,11 +488,16 @@ public class AdventureCardsTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerA, "Forest");
addCard(Zone.BATTLEFIELD, playerA, "Wrenn and Six");
addCard(Zone.GRAVEYARD, playerA, "Curious Pair");
- addCard(Zone.HAND, playerA, "Forest");
+ addCard(Zone.HAND, playerA, "Forest"); // pay for retrace
addCounters(1, PhaseStep.UPKEEP, playerA, "Wrenn and Six", CounterType.LOYALTY, 5);
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "-7: You get an emblem");
+ waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, playerA);
+ showAvaileableAbilities("abils", 1, PhaseStep.PRECOMBAT_MAIN, playerA);
+
+ // retrace - You may cast this card from your graveyard by discarding a land card as an additional cost to cast it
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Treats to Share");
+ setChoice(playerA, "Forest");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
@@ -523,6 +529,8 @@ public class AdventureCardsTest extends CardTestPlayerBase {
addCard(Zone.HAND, playerA, "Curious Pair");
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "+1: Until your next");
+ waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, playerA);
+ showAvaileableAbilities("abils", 1, PhaseStep.BEGIN_COMBAT, playerA);
castSpell(1, PhaseStep.BEGIN_COMBAT, playerA, "Treats to Share");
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/cost/alternate/BolassCitadelTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/cost/alternate/BolassCitadelTest.java
index f5932c7401..ee0d7c27d6 100644
--- a/Mage.Tests/src/test/java/org/mage/test/cards/cost/alternate/BolassCitadelTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/cost/alternate/BolassCitadelTest.java
@@ -32,7 +32,6 @@ public class BolassCitadelTest extends CardTestPlayerBase {
}
@Test
- @Ignore("This is broken for now.")
public void testCastAdventure() {
/*
* Curious Pair {1}{G}
@@ -44,7 +43,6 @@ public class BolassCitadelTest extends CardTestPlayerBase {
* Create a Food token.
*/
setStrictChooseMode(true);
- addCard(Zone.BATTLEFIELD, playerA, "Forest");
addCard(Zone.BATTLEFIELD, playerA, "Bolas's Citadel");
removeAllCardsFromLibrary(playerA);
addCard(Zone.LIBRARY, playerA, "Curious Pair");
@@ -54,7 +52,6 @@ public class BolassCitadelTest extends CardTestPlayerBase {
execute();
assertAllCommandsUsed();
- assertTapped("Forest", false);
assertHandCount(playerA, 0);
assertPermanentCount(playerA, "Food", 1);
assertExileCount(playerA, "Curious Pair", 1);
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/FiendOfTheShadowsTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/FiendOfTheShadowsTest.java
index bdde801cd4..4b9330199d 100644
--- a/Mage.Tests/src/test/java/org/mage/test/cards/single/FiendOfTheShadowsTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/FiendOfTheShadowsTest.java
@@ -6,7 +6,6 @@ import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
- *
* also tests regenerate and tests that permanents with protection can be
* sacrificed
*
@@ -46,10 +45,13 @@ public class FiendOfTheShadowsTest extends CardTestPlayerBase {
addCard(Zone.HAND, playerB, "Swamp");
attack(1, playerA, "Fiend of the Shadows");
+ addTarget(playerB, "Swamp");
playLand(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Swamp");
+ setStrictChooseMode(true);
setStopAt(1, PhaseStep.END_TURN);
execute();
+ assertAllCommandsUsed();
assertLife(playerA, 20);
assertLife(playerB, 17);
diff --git a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java
index 0c1a2bfd5a..14834dc934 100644
--- a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java
+++ b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java
@@ -2374,20 +2374,25 @@ public class TestPlayer implements Player {
}
@Override
- public UUID getCastSourceIdWithAlternateMana() {
+ public Set