- Starting the process of migrating cards that use the player.cast() method to access the full abilities of a card not cast from the hand zone.

This commit is contained in:
jeffwadsworth 2019-12-26 15:54:22 -06:00
parent 05362dd55a
commit b9bee56c89
7 changed files with 60 additions and 38 deletions

View file

@ -118,9 +118,7 @@ class AshiokNightmareMuseCastEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
MageObject sourceObject = game.getObject(source.getSourceId()); if (controller == null) {
if (controller == null
|| sourceObject == null) {
return false; return false;
} }
TargetCardInExile target = new TargetCardInExile(0, 3, filter, null); TargetCardInExile target = new TargetCardInExile(0, 3, filter, null);
@ -135,10 +133,10 @@ class AshiokNightmareMuseCastEffect extends OneShotEffect {
&& game.getState().getZone(chosenCard.getId()) == Zone.EXILED // must be exiled && game.getState().getZone(chosenCard.getId()) == Zone.EXILED // must be exiled
&& game.getOpponents(controller.getId()).contains(chosenCard.getOwnerId()) // must be owned by an opponent && game.getOpponents(controller.getId()).contains(chosenCard.getOwnerId()) // must be owned by an opponent
&& controller.chooseUse(outcome, "Cast " + chosenCard.getName() + " without paying its mana cost?", source, game)) { && controller.chooseUse(outcome, "Cast " + chosenCard.getName() + " without paying its mana cost?", source, game)) {
game.getState().setValue("CastFromExileEnabled" + chosenCard.getId(), Boolean.TRUE); // enable the card to be cast from the exile zone game.getState().setValue("PlayFromNotOwnHandZone" + chosenCard.getId(), Boolean.TRUE);
controller.cast(controller.chooseAbilityForCast(chosenCard, game, true), controller.cast(controller.chooseAbilityForCast(chosenCard, game, true),
game, true, new MageObjectReference(sourceObject, game)); game, true, new MageObjectReference(source.getSourceObject(game), game));
game.getState().setValue("CastFromExileEnabled" + chosenCard.getId(), null); // reset to null game.getState().setValue("PlayFromNotOwnHandZone" + chosenCard.getId(), null);
} }
} }
} }

View file

@ -90,19 +90,19 @@ class ChandraTorchOfDefianceEffect extends OneShotEffect {
Library library = controller.getLibrary(); Library library = controller.getLibrary();
Card card = library.getFromTop(game); Card card = library.getFromTop(game);
if (card != null) { if (card != null) {
boolean exiledCardWasCast = false; boolean cardWasCast = false;
controller.moveCardsToExile(card, source, game, true, source.getSourceId(), sourceObject.getIdName()); controller.moveCardsToExile(card, source, game, true, source.getSourceId(), sourceObject.getIdName());
if (!card.getManaCost().isEmpty() if (!card.getManaCost().isEmpty()
|| !card.isLand()) { || !card.isLand()) {
if (controller.chooseUse(Outcome.Benefit, "Cast " + card.getName() + "? (You still pay the costs)", source, game) if (controller.chooseUse(Outcome.Benefit, "Cast " + card.getName() + "? (You still pay the costs)", source, game)
&& (game.getState().getZone(card.getId()) == Zone.EXILED)) { // card must be in the exile zone && (game.getState().getZone(card.getId()) == Zone.EXILED)) { // card must be in the exile zone
game.getState().setValue("CastFromExileEnabled" + card.getId(), Boolean.TRUE); // enable the card to be cast from the exile zone game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE); // enable the card to be cast from the exile zone
exiledCardWasCast = controller.cast(controller.chooseAbilityForCast(card, game, false), cardWasCast = controller.cast(controller.chooseAbilityForCast(card, game, false),
game, false, new MageObjectReference(sourceObject, game)); game, false, new MageObjectReference(sourceObject, game));
game.getState().setValue("CastFromExileEnabled" + card.getId(), null); // reset to null game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null); // reset to null
} }
} }
if (!exiledCardWasCast) { if (!cardWasCast) {
new DamagePlayersEffect(Outcome.Damage, new StaticValue(2), TargetController.OPPONENT).apply(game, source); new DamagePlayersEffect(Outcome.Damage, new StaticValue(2), TargetController.OPPONENT).apply(game, source);
} }
} }

View file

@ -1,4 +1,3 @@
package mage.cards.i; package mage.cards.i;
import java.util.UUID; import java.util.UUID;
@ -83,7 +82,7 @@ public final class IzzetChemister extends CardImpl {
class IzzetChemisterCastFromExileEffect extends OneShotEffect { class IzzetChemisterCastFromExileEffect extends OneShotEffect {
private UUID exileId; private final UUID exileId;
public IzzetChemisterCastFromExileEffect(UUID exileId, String description) { public IzzetChemisterCastFromExileEffect(UUID exileId, String description) {
super(Outcome.PlayForFree); super(Outcome.PlayForFree);
@ -106,7 +105,8 @@ class IzzetChemisterCastFromExileEffect extends OneShotEffect {
ExileZone exile = game.getExile().getExileZone(exileId); ExileZone exile = game.getExile().getExileZone(exileId);
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
FilterCard filter = new FilterCard(); FilterCard filter = new FilterCard();
if (controller != null && exile != null) { if (controller != null
&& exile != null) {
Cards cardsToExile = new CardsImpl(); Cards cardsToExile = new CardsImpl();
cardsToExile.addAll(exile.getCards(game)); cardsToExile.addAll(exile.getCards(game));
OuterLoop: OuterLoop:
@ -116,11 +116,17 @@ class IzzetChemisterCastFromExileEffect extends OneShotEffect {
} }
TargetCardInExile target = new TargetCardInExile(0, 1, filter, exileId, false); TargetCardInExile target = new TargetCardInExile(0, 1, filter, exileId, false);
target.setNotTarget(true); target.setNotTarget(true);
while (cardsToExile.count(filter, game) > 0 && controller.choose(Outcome.PlayForFree, cardsToExile, target, game)) { while (cardsToExile.count(filter, game) > 0
&& controller.choose(Outcome.PlayForFree, cardsToExile, target, game)) {
Card card = game.getCard(target.getFirstTarget()); Card card = game.getCard(target.getFirstTarget());
if (card != null) { if (card != null) {
controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game)); game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
cardsToExile.remove(card); Boolean cardWasCast = controller.cast(controller.chooseAbilityForCast(card, game, true), game, true,
new MageObjectReference(source.getSourceObject(game), game));
game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
if (cardWasCast) {
cardsToExile.remove(card);
}
} else { } else {
break OuterLoop; break OuterLoop;
} }

View file

@ -18,6 +18,7 @@ import mage.players.Player;
import mage.target.TargetCard; import mage.target.TargetCard;
import java.util.UUID; import java.util.UUID;
import mage.MageObject;
/** /**
* @author LevelX2 * @author LevelX2
@ -35,7 +36,8 @@ public final class SilentBladeOni extends CardImpl {
// Ninjutsu {4}{U}{B} // Ninjutsu {4}{U}{B}
this.addAbility(new NinjutsuAbility(new ManaCostsImpl("{4}{U}{B}"))); this.addAbility(new NinjutsuAbility(new ManaCostsImpl("{4}{U}{B}")));
// Whenever Silent-Blade Oni deals combat damage to a player, look at that player's hand. You may cast a nonland card in it without paying that card's mana cost. // Whenever Silent-Blade Oni deals combat damage to a player, look at that player's hand.
// You may cast a nonland card in it without paying that card's mana cost.
this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility( this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(
new SilentBladeOniEffect(), false, true new SilentBladeOniEffect(), false, true
)); ));
@ -55,8 +57,8 @@ class SilentBladeOniEffect extends OneShotEffect {
SilentBladeOniEffect() { SilentBladeOniEffect() {
super(Outcome.PlayForFree); super(Outcome.PlayForFree);
this.staticText = "look at that player's hand. " + this.staticText = "look at that player's hand. "
"You may cast a nonland card in it without paying that card's mana cost"; + "You may cast a nonland card in it without paying that card's mana cost";
} }
private SilentBladeOniEffect(final SilentBladeOniEffect effect) { private SilentBladeOniEffect(final SilentBladeOniEffect effect) {
@ -72,7 +74,8 @@ class SilentBladeOniEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player opponent = game.getPlayer(getTargetPointer().getFirst(game, source)); Player opponent = game.getPlayer(getTargetPointer().getFirst(game, source));
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
if (opponent == null || controller == null) { if (opponent == null
|| controller == null) {
return false; return false;
} }
Cards cardsInHand = new CardsImpl(); Cards cardsInHand = new CardsImpl();
@ -88,8 +91,13 @@ class SilentBladeOniEffect extends OneShotEffect {
return true; return true;
} }
Card card = game.getCard(target.getFirstTarget()); Card card = game.getCard(target.getFirstTarget());
return card != null && controller.cast( if (card == null) {
card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game) return false;
); }
game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
Boolean cardWasCast = controller.cast(controller.chooseAbilityForCast(card, game, true),
game, true, new MageObjectReference(source.getSourceObject(game), game));
game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
return cardWasCast;
} }
} }

View file

@ -16,6 +16,7 @@ import mage.game.Game;
import mage.players.Player; import mage.players.Player;
import java.util.UUID; import java.util.UUID;
import mage.MageObject;
/** /**
* @author fireshoes * @author fireshoes
@ -48,8 +49,10 @@ class TreasureKeeperEffect extends OneShotEffect {
public TreasureKeeperEffect() { public TreasureKeeperEffect() {
super(Outcome.PlayForFree); super(Outcome.PlayForFree);
this.staticText = "reveal cards from the top of your library until you reveal a nonland card with converted mana cost 3 or less. " this.staticText = "reveal cards from the top of your library until you reveal a "
+ "You may cast that card without paying its mana cost. Put all revealed cards not cast this way on the bottom of your library in a random order"; + "nonland card with converted mana cost 3 or less. "
+ "You may cast that card without paying its mana cost. Put all revealed "
+ "cards not cast this way on the bottom of your library in a random order";
} }
public TreasureKeeperEffect(TreasureKeeperEffect effect) { public TreasureKeeperEffect(TreasureKeeperEffect effect) {
@ -58,8 +61,10 @@ class TreasureKeeperEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Boolean cardWasCast = false;
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
if (controller != null) { if (controller != null
&& !controller.getLibrary().isEmptyDraw()) {
CardsImpl toReveal = new CardsImpl(); CardsImpl toReveal = new CardsImpl();
Card nonLandCard = null; Card nonLandCard = null;
for (Card card : controller.getLibrary().getCards(game)) { for (Card card : controller.getLibrary().getCards(game)) {
@ -70,14 +75,19 @@ class TreasureKeeperEffect extends OneShotEffect {
} }
} }
controller.revealCards(source, toReveal, game); controller.revealCards(source, toReveal, game);
if (nonLandCard != null && controller.chooseUse(outcome, "Cast " + nonLandCard.getLogName() + " without paying its mana cost?", source, game)) { if (nonLandCard != null
controller.cast(nonLandCard.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game)); && controller.chooseUse(Outcome.PlayForFree, "Cast " + nonLandCard.getLogName() + " without paying its mana cost?", source, game)) {
toReveal.remove(nonLandCard); game.getState().setValue("PlayFromNotOwnHandZone" + nonLandCard.getId(), Boolean.TRUE);
cardWasCast = controller.cast(controller.chooseAbilityForCast(nonLandCard, game, true),
game, true, new MageObjectReference(source.getSourceObject(game), game));
game.getState().setValue("PlayFromNotOwnHandZone" + nonLandCard.getId(), null);
if (cardWasCast) {
toReveal.remove(nonLandCard);
}
} }
controller.putCardsOnBottomOfLibrary(toReveal, game, source, false); controller.putCardsOnBottomOfLibrary(toReveal, game, source, false);
return true;
} }
return false; return cardWasCast;
} }
@Override @Override

View file

@ -106,10 +106,10 @@ class WildfireDevilsEffect extends OneShotEffect {
if (!controller.chooseUse(outcome, "Cast the copy of the exiled card?", source, game)) { if (!controller.chooseUse(outcome, "Cast the copy of the exiled card?", source, game)) {
return false; return false;
} }
game.getState().setValue("CastFromExileEnabled" + copiedCard.getId(), Boolean.TRUE); // enable the card to be cast from the exile zone game.getState().setValue("PlayFromNotOwnHandZone" + copiedCard.getId(), Boolean.TRUE);
Boolean exiledCardWasCast = controller.cast(controller.chooseAbilityForCast(copiedCard, game, true), game, true, Boolean cardWasCast = controller.cast(controller.chooseAbilityForCast(copiedCard, game, true), game, true,
new MageObjectReference(source.getSourceObject(game), game)); new MageObjectReference(source.getSourceObject(game), game));
game.getState().setValue("CastFromExileEnabled" + copiedCard.getId(), null); // reset to null game.getState().setValue("PlayFromNotOwnHandZone" + copiedCard.getId(), null);
return exiledCardWasCast; return cardWasCast;
} }
} }

View file

@ -65,8 +65,8 @@ public class SpellAbility extends ActivatedAbilityImpl {
if (object == null) { if (object == null) {
return false; return false;
} }
if (game.getState().getValue("CastFromExileEnabled" + object.getId()) != null) { if (game.getState().getValue("PlayFromNotOwnHandZone" + object.getId()) != null) {
return (Boolean) game.getState().getValue("CastFromExileEnabled" + object.getId()); // card like Chandra, Torch of Defiance +1 loyal ability) return (Boolean) game.getState().getValue("PlayFromNotOwnHandZone" + object.getId()); // card like Chandra, Torch of Defiance +1 loyal ability)
} }
return null != game.getContinuousEffects().asThough(sourceId, AsThoughEffectType.CAST_AS_INSTANT, this, playerId, game) // check this first to allow Offering in main phase return null != game.getContinuousEffects().asThough(sourceId, AsThoughEffectType.CAST_AS_INSTANT, this, playerId, game) // check this first to allow Offering in main phase
|| timing == TimingRule.INSTANT || timing == TimingRule.INSTANT