diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSupportCards.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSupportCards.java index 31e5cd0eb2c..f74362798e5 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSupportCards.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSupportCards.java @@ -243,6 +243,7 @@ public class ScryfallImageSupportCards { add("C19"); add("ELD"); add("CELD"); + add("THB"); // add("EURO"); add("GPX"); 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 e3254b3a02f..75be926ecb7 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 32da651d46c..5741a658b0e 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/CommandingPresence.java b/Mage.Sets/src/mage/cards/c/CommandingPresence.java new file mode 100644 index 00000000000..c6443d3529e --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/CommandingPresence.java @@ -0,0 +1,62 @@ +package mage.cards.c; + +import mage.abilities.Ability; +import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.continuous.BoostEnchantedEffect; +import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.abilities.keyword.FirstStrikeAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.game.permanent.token.HumanSoldierToken; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class CommandingPresence extends CardImpl { + + public CommandingPresence(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{W}"); + + this.subtype.add(SubType.AURA); + + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + + // Enchanted creature gets +2/+2 and has first strike and "Whenever this creature deals combat damage to a player, create a 1/1 white Human Soldier creature token." + ability = new SimpleStaticAbility(new BoostEnchantedEffect(2, 2)); + ability.addEffect(new GainAbilityAttachedEffect( + FirstStrikeAbility.getInstance(), AttachmentType.AURA, + Duration.WhileOnBattlefield, "and has first strike" + )); + ability.addEffect(new GainAbilityAttachedEffect( + new DealsCombatDamageToAPlayerTriggeredAbility( + new CreateTokenEffect(new HumanSoldierToken()), false + ), AttachmentType.AURA, Duration.WhileOnBattlefield, + "and \"Whenever this creature deals combat damage to a player, " + + "create a 1/1 white Human Soldier creature token.\"" + )); + this.addAbility(ability); + } + + private CommandingPresence(final CommandingPresence card) { + super(card); + } + + @Override + public CommandingPresence copy() { + return new CommandingPresence(this); + } +} diff --git a/Mage.Sets/src/mage/cards/c/CovetousUrge.java b/Mage.Sets/src/mage/cards/c/CovetousUrge.java index 45b570c2613..b3cf2030bf8 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 48553cd2ea5..d0d5bd1cc47 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/DaxosBlessedByTheSun.java b/Mage.Sets/src/mage/cards/d/DaxosBlessedByTheSun.java new file mode 100644 index 00000000000..9335f9e349e --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DaxosBlessedByTheSun.java @@ -0,0 +1,89 @@ +package mage.cards.d; + +import mage.MageInt; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.common.DevotionCount; +import mage.abilities.effects.common.GainLifeEffect; +import mage.abilities.effects.common.continuous.SetToughnessSourceEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.ZoneChangeEvent; +import mage.game.permanent.Permanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class DaxosBlessedByTheSun extends CardImpl { + + private static final DynamicValue xValue = new DevotionCount(ColoredManaSymbol.W); + + public DaxosBlessedByTheSun(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "{W}{W}"); + + this.addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.DEMIGOD); + this.power = new MageInt(2); + this.toughness = new MageInt(0); + + // Daxos's toughness is equal to your devotion to white. + this.addAbility(new SimpleStaticAbility( + Zone.ALL, new SetToughnessSourceEffect(xValue, Duration.EndOfGame + ).setText("{this}'s toughness is equal to your devotion to white"))); + + // Whenever another creature you control enters the battlefield or dies, you gain 1 life. + this.addAbility(new DaxosBlessedByTheSunAbility()); + } + + private DaxosBlessedByTheSun(final DaxosBlessedByTheSun card) { + super(card); + } + + @Override + public DaxosBlessedByTheSun copy() { + return new DaxosBlessedByTheSun(this); + } +} + +class DaxosBlessedByTheSunAbility extends TriggeredAbilityImpl { + + DaxosBlessedByTheSunAbility() { + super(Zone.BATTLEFIELD, new GainLifeEffect(1)); + } + + private DaxosBlessedByTheSunAbility(DaxosBlessedByTheSunAbility ability) { + super(ability); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return (event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD) + || (event.getType() == GameEvent.EventType.ZONE_CHANGE + && ((ZoneChangeEvent) event).isDiesEvent()); + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (event.getTargetId().equals(this.getSourceId())) { + return false; + } + Permanent creature = game.getPermanentOrLKIBattlefield(event.getTargetId()); + return creature != null && creature.isControlledBy(this.getControllerId()); + } + + @Override + public String getRule() { + return "Whenever another creature you control enters the battlefield or dies, you gain 1 life."; + } + + @Override + public DaxosBlessedByTheSunAbility copy() { + return new DaxosBlessedByTheSunAbility(this); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/d/DaxosOfMeletis.java b/Mage.Sets/src/mage/cards/d/DaxosOfMeletis.java index e9cc5916243..da160f068f2 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 284ec871fbb..c88eabc0f7e 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 c39708c8936..bf72d244474 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 0755e3a2824..b4b5adf337b 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 478e2432a81..6553e92444b 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/HeroOfTheWinds.java b/Mage.Sets/src/mage/cards/h/HeroOfTheWinds.java new file mode 100644 index 00000000000..24a396a8bb3 --- /dev/null +++ b/Mage.Sets/src/mage/cards/h/HeroOfTheWinds.java @@ -0,0 +1,45 @@ +package mage.cards.h; + +import mage.MageInt; +import mage.abilities.effects.common.continuous.BoostControlledEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.HeroicAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class HeroOfTheWinds extends CardImpl { + + public HeroOfTheWinds(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.SOLDIER); + this.power = new MageInt(1); + this.toughness = new MageInt(4); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // Whenever you cast a spell that targets Hero of the Winds, creatures you control get +1/+0 until end of turn. + this.addAbility(new HeroicAbility(new BoostControlledEffect( + 1, 0, Duration.EndOfTurn + ), false, false)); + } + + private HeroOfTheWinds(final HeroOfTheWinds card) { + super(card); + } + + @Override + public HeroOfTheWinds copy() { + return new HeroOfTheWinds(this); + } +} diff --git a/Mage.Sets/src/mage/cards/h/HostageTaker.java b/Mage.Sets/src/mage/cards/h/HostageTaker.java index 816ff40e096..64ff610c52d 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/i/InevitableEnd.java b/Mage.Sets/src/mage/cards/i/InevitableEnd.java new file mode 100644 index 00000000000..f05ef549b7d --- /dev/null +++ b/Mage.Sets/src/mage/cards/i/InevitableEnd.java @@ -0,0 +1,52 @@ +package mage.cards.i; + +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.SacrificeControllerEffect; +import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.filter.StaticFilters; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class InevitableEnd extends CardImpl { + + public InevitableEnd(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{B}"); + + this.subtype.add(SubType.AURA); + + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + + // Enchanted creature has "At the beginning of your upkeep, sacrifice a creature." + this.addAbility(new SimpleStaticAbility(new GainAbilityAttachedEffect( + new BeginningOfUpkeepTriggeredAbility(new SacrificeControllerEffect( + StaticFilters.FILTER_PERMANENT_CREATURE, 1, null + ), TargetController.YOU, false), AttachmentType.AURA + ))); + } + + private InevitableEnd(final InevitableEnd card) { + super(card); + } + + @Override + public InevitableEnd copy() { + return new InevitableEnd(this); + } +} diff --git a/Mage.Sets/src/mage/cards/o/OathOfNissa.java b/Mage.Sets/src/mage/cards/o/OathOfNissa.java index 6f3fd0a6970..04821b21b90 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 9cc6cc4f33f..9383eae170f 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 994db84272e..24734a42a80 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 923b51ecb16..68c79579ec0 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/StaggeringInsight.java b/Mage.Sets/src/mage/cards/s/StaggeringInsight.java new file mode 100644 index 00000000000..b27cd459685 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/StaggeringInsight.java @@ -0,0 +1,60 @@ +package mage.cards.s; + +import mage.abilities.Ability; +import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.continuous.BoostEnchantedEffect; +import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.abilities.keyword.LifelinkAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class StaggeringInsight extends CardImpl { + + public StaggeringInsight(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{W}{U}"); + + this.subtype.add(SubType.AURA); + + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + + // Enchanted creature gets +1/+1 and has lifelink and "Whenever this creature deals combat damage to a player, draw a card." + ability = new SimpleStaticAbility(new BoostEnchantedEffect(1, 1)); + ability.addEffect(new GainAbilityAttachedEffect( + LifelinkAbility.getInstance(), AttachmentType.AURA, + Duration.WhileOnBattlefield, "and has lifelink" + )); + ability.addEffect(new GainAbilityAttachedEffect( + new DealsCombatDamageToAPlayerTriggeredAbility( + new DrawCardSourceControllerEffect(1), false + ), AttachmentType.AURA, Duration.WhileOnBattlefield, + "and \"Whenever this creature deals combat damage to a player, draw a card.\"" + )); + this.addAbility(ability); + } + + private StaggeringInsight(final StaggeringInsight card) { + super(card); + } + + @Override + public StaggeringInsight copy() { + return new StaggeringInsight(this); + } +} diff --git a/Mage.Sets/src/mage/cards/s/StolenStrategy.java b/Mage.Sets/src/mage/cards/s/StolenStrategy.java index e20f44395ec..9a89e8c370e 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 818970680f6..2a44855fa25 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 e258e5078d0..0ad1a9c4aee 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 7eacc7e747e..23d46f0a18d 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 a51a1e68b5b..6e424515cfc 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.Sets/src/mage/sets/TherosBeyondDeath.java b/Mage.Sets/src/mage/sets/TherosBeyondDeath.java index 2f822b54ed5..77dd6ef54b5 100644 --- a/Mage.Sets/src/mage/sets/TherosBeyondDeath.java +++ b/Mage.Sets/src/mage/sets/TherosBeyondDeath.java @@ -26,10 +26,14 @@ public final class TherosBeyondDeath extends ExpansionSet { this.ratioBoosterMythic = 8; this.maxCardNumberInBooster = 254; + cards.add(new SetCardInfo("Commanding Presence", 7, Rarity.UNCOMMON, mage.cards.c.CommandingPresence.class)); + cards.add(new SetCardInfo("Daxos, Blessed by the Sun", 9, Rarity.UNCOMMON, mage.cards.d.DaxosBlessedByTheSun.class)); cards.add(new SetCardInfo("Eidolon of Philosophy", 48, Rarity.COMMON, mage.cards.e.EidolonOfPhilosophy.class)); cards.add(new SetCardInfo("Elspeth, Sun's Nemesis", 14, Rarity.MYTHIC, mage.cards.e.ElspethSunsNemesis.class)); cards.add(new SetCardInfo("Forest", 254, Rarity.LAND, mage.cards.basiclands.Forest.class, FULL_ART_BFZ_VARIOUS)); + cards.add(new SetCardInfo("Hero of the Winds", 23, Rarity.UNCOMMON, mage.cards.h.HeroOfTheWinds.class)); cards.add(new SetCardInfo("Indomitable Will", 25, Rarity.COMMON, mage.cards.i.IndomitableWill.class)); + cards.add(new SetCardInfo("Inevitable End", 102, Rarity.UNCOMMON, mage.cards.i.InevitableEnd.class)); cards.add(new SetCardInfo("Island", 251, Rarity.LAND, mage.cards.basiclands.Island.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Klothys's Design", 176, Rarity.UNCOMMON, mage.cards.k.KlothyssDesign.class)); cards.add(new SetCardInfo("Leonin of the Lost Pride", 28, Rarity.COMMON, mage.cards.l.LeoninOfTheLostPride.class)); @@ -41,6 +45,7 @@ public final class TherosBeyondDeath extends ExpansionSet { cards.add(new SetCardInfo("Plains", 250, Rarity.LAND, mage.cards.basiclands.Plains.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Revoke Existence", 34, Rarity.COMMON, mage.cards.r.RevokeExistence.class)); cards.add(new SetCardInfo("Setessan Champion", 198, Rarity.RARE, mage.cards.s.SetessanChampion.class)); + cards.add(new SetCardInfo("Staggering Insight", 228, Rarity.UNCOMMON, mage.cards.s.StaggeringInsight.class)); cards.add(new SetCardInfo("Swamp", 252, Rarity.LAND, mage.cards.basiclands.Swamp.class, FULL_ART_BFZ_VARIOUS)); } } 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 268b58f7ef2..db8796ba96f 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 e1ddf99d6d1..8c900e619c0 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 00000000000..b4013c696b1 --- /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 1d117fc88be..3176f1d128c 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 681b4981bf3..3afca6ea16b 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 470ea3b23de..ac2e2d6fe62 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 f5932c74015..ee0d7c27d68 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/enchantments/StarfieldOfNyxTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/enchantments/StarfieldOfNyxTest.java
index 882c8e1efb8..5bc8cac2f13 100644
--- a/Mage.Tests/src/test/java/org/mage/test/cards/enchantments/StarfieldOfNyxTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/enchantments/StarfieldOfNyxTest.java
@@ -7,6 +7,7 @@ import mage.constants.Zone;
import mage.filter.Filter;
import mage.game.permanent.Permanent;
import org.junit.Assert;
+import org.junit.Ignore;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
@@ -117,4 +118,48 @@ public class StarfieldOfNyxTest extends CardTestPlayerBase {
Assert.assertFalse(emrakul.getAbilities().contains(FlyingAbility.getInstance())); // loses flying though
}
+
+ /**
+ * So Starfield of Nyx in play. Detention Sphere with a Song of the Dryads
+ * under it. Wrath of god on the stack. In response I Parallax Wave Honden
+ * of life's Web, Mirrari's Wake, Sphere of Safety, Aura Shards, and
+ * Enchantress's Presence to save them. Wrath resolves and Song of the
+ * Dryads come back along with the 5 named enchantments. Opp targets
+ * Starfield of Nyx with Song of the Dryads. When song of the dryads
+ * attaches all my enchantments stay creatures but as 1/1's instead of cmc.
+ * I untap draw and cast Humility. All my 1/1 enchantments die while opp's
+ * bruna, light of alabaster keeps her abilities. After mirrari's wake dies
+ * due to this I still have double mana. So yea, something broke big time
+ * there.
+ */
+ @Test
+ @Ignore
+ public void testStarfieldOfNyxAndSongOfTheDryads() {
+ // Nontoken creatures you control get +1/+1 and have vigilance.
+ addCard(Zone.BATTLEFIELD, playerA, "Always Watching", 5);
+ addCard(Zone.BATTLEFIELD, playerA, "Plains", 5);
+ // At the beginning of your upkeep, you may return target enchantment card from your graveyard to the battlefield.
+ // As long as you control five or more enchantments, each other non-Aura enchantment you control is a creature in
+ // addition to its other types and has base power and base toughness each equal to its converted mana cost.
+ addCard(Zone.HAND, playerA, "Starfield of Nyx"); // "{4}{W}"
+
+ addCard(Zone.BATTLEFIELD, playerB, "Forest", 3);
+ // Enchanted permanent is a colorless Forest land.
+ addCard(Zone.HAND, playerB, "Song of the Dryads"); // Enchant Permanent {2}{G}
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Starfield of Nyx");
+ castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Song of the Dryads", "Starfield of Nyx");
+
+ setStopAt(2, PhaseStep.BEGIN_COMBAT);
+ execute();
+
+ assertPermanentCount(playerA, "Always Watching", 5);
+ assertPermanentCount(playerB, "Song of the Dryads", 1);
+
+ assertPowerToughness(playerA, "Always Watching", 0, 0, Filter.ComparisonScope.All);
+
+ assertPermanentCount(playerA, "Forest", 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 bdde801cd48..4b9330199d9 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 0c1a2bfd5a2..14834dc934a 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