* Some rework of play card effects.

This commit is contained in:
LevelX2 2015-11-26 17:06:50 +01:00
parent 780702be1b
commit eb6a5e7dcb
14 changed files with 201 additions and 240 deletions

View file

@ -79,8 +79,6 @@ import mage.cards.decks.Deck;
import mage.cards.repository.CardCriteria; import mage.cards.repository.CardCriteria;
import mage.cards.repository.CardInfo; import mage.cards.repository.CardInfo;
import mage.cards.repository.CardRepository; import mage.cards.repository.CardRepository;
import mage.cards.repository.ExpansionInfo;
import mage.cards.repository.ExpansionRepository;
import mage.choices.Choice; import mage.choices.Choice;
import mage.choices.ChoiceColor; import mage.choices.ChoiceColor;
import mage.constants.AsThoughEffectType; import mage.constants.AsThoughEffectType;
@ -995,7 +993,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
} }
while (lands.size() > 0 && this.canPlayLand()) { while (lands.size() > 0 && this.canPlayLand()) {
if (lands.size() == 1) { if (lands.size() == 1) {
this.playLand(lands.iterator().next(), game); this.playLand(lands.iterator().next(), game, false);
} else { } else {
playALand(lands, game); playALand(lands, game);
} }
@ -1010,7 +1008,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
for (ManaAbility ability : card.getAbilities().getManaAbilities(Zone.BATTLEFIELD)) { for (ManaAbility ability : card.getAbilities().getManaAbilities(Zone.BATTLEFIELD)) {
for (Mana netMana : ability.getNetMana(game)) { for (Mana netMana : ability.getNetMana(game)) {
if (netMana.enough(mana)) { if (netMana.enough(mana)) {
this.playLand(card, game); this.playLand(card, game, false);
lands.remove(card); lands.remove(card);
return; return;
} }
@ -1024,7 +1022,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
for (ManaAbility ability : card.getAbilities().getManaAbilities(Zone.BATTLEFIELD)) { for (ManaAbility ability : card.getAbilities().getManaAbilities(Zone.BATTLEFIELD)) {
for (Mana netMana : ability.getNetMana(game)) { for (Mana netMana : ability.getNetMana(game)) {
if (mana.contains(netMana)) { if (mana.contains(netMana)) {
this.playLand(card, game); this.playLand(card, game, false);
lands.remove(card); lands.remove(card);
return; return;
} }
@ -1033,7 +1031,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
} }
} }
//play first available land //play first available land
this.playLand(lands.iterator().next(), game); this.playLand(lands.iterator().next(), game, false);
lands.remove(lands.iterator().next()); lands.remove(lands.iterator().next());
} }

View file

@ -113,7 +113,7 @@ class EmeriaShepherdReturnToHandTargetEffect extends OneShotEffect {
&& controller.chooseUse(Outcome.PutCardInPlay, "Put the card to battlefield instead?", source, game)) { && controller.chooseUse(Outcome.PutCardInPlay, "Put the card to battlefield instead?", source, game)) {
toZone = Zone.BATTLEFIELD; toZone = Zone.BATTLEFIELD;
} }
return controller.moveCards(new CardsImpl(targetPointer.getTargets(game, source)), null, toZone, source, game); return controller.moveCards(new CardsImpl(targetPointer.getTargets(game, source)), toZone, source, game);
} }
} }

View file

@ -109,11 +109,11 @@ class GuileReplacementEffect extends ReplacementEffectImpl {
Spell spell = game.getStack().getSpell(event.getTargetId()); Spell spell = game.getStack().getSpell(event.getTargetId());
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
if (spell != null && controller != null) { if (spell != null && controller != null) {
controller.moveCards(spell, null, Zone.EXILED, source, game); controller.moveCards(spell, Zone.EXILED, source, game);
if (!spell.isCopy()) { if (!spell.isCopy()) {
Card spellCard = spell.getCard(); Card spellCard = spell.getCard();
if (spellCard != null && controller.chooseUse(Outcome.PlayForFree, "Cast " + spellCard.getIdName() + " for free?", source, game)) { if (spellCard != null && controller.chooseUse(Outcome.PlayForFree, "Cast " + spellCard.getIdName() + " for free?", source, game)) {
controller.cast(spellCard.getSpellAbility(), game, true); controller.playCard(spellCard, game, true, true);
} }
return true; return true;
} }

View file

@ -33,9 +33,9 @@ import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.keyword.VigilanceAbility;
import mage.abilities.keyword.TrampleAbility;
import mage.abilities.keyword.HasteAbility; import mage.abilities.keyword.HasteAbility;
import mage.abilities.keyword.TrampleAbility;
import mage.abilities.keyword.VigilanceAbility;
import mage.cards.Card; import mage.cards.Card;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.constants.CardType; import mage.constants.CardType;
@ -112,17 +112,8 @@ class HordeOfNotionsEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
if (controller != null) { if (controller != null) {
Card card = game.getCard(getTargetPointer().getFirst(game, source)); Card card = game.getCard(getTargetPointer().getFirst(game, source));
if (card != null ) { if (card != null && controller.chooseUse(outcome, "Play " + card.getName() + " from your graveyard for free?", source, game)) {
// Probably there is no Elemental land, but who knows controller.playCard(card, game, true, true);
if (card.getCardType().contains(CardType.LAND) && controller.canPlayLand() &&
controller.chooseUse(outcome, "Play " + card.getName() + " from your graveyard for free?", source, game)) {
controller.playLand(card, game);
} else {
if (card.getSpellAbility().canChooseTarget(game) &&
controller.chooseUse(outcome, "Play " + card.getName() + " from your graveyard for free?", source, game)) {
controller.cast(card.getSpellAbility(), game, true);
}
}
} }
return true; return true;
} }

View file

@ -28,12 +28,8 @@
package mage.sets.magic2010; package mage.sets.magic2010;
import java.util.UUID; import java.util.UUID;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.MageInt; import mage.MageInt;
import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.common.EntersBattlefieldAbility;
import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleActivatedAbility;
@ -46,6 +42,10 @@ import mage.cards.Card;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.Cards; import mage.cards.Cards;
import mage.cards.CardsImpl; import mage.cards.CardsImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.counters.CounterType; import mage.counters.CounterType;
import mage.game.Game; import mage.game.Game;
import mage.players.Player; import mage.players.Player;
@ -100,33 +100,16 @@ class DjinnOfWishesEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
if (player != null && player.getLibrary().size() > 0) { MageObject sourceObject = game.getObject(source.getSourceId());
Card card = player.getLibrary().getFromTop(game); if (controller != null && sourceObject != null && controller.getLibrary().size() > 0) {
Cards cards = new CardsImpl(); Card card = controller.getLibrary().getFromTop(game);
cards.add(card); Cards cards = new CardsImpl(card);
player.revealCards("Djinn of Wishes", cards, game); controller.revealCards(sourceObject.getIdName(), cards, game);
if (!controller.chooseUse(Outcome.PlayForFree, "Play " + card.getName() + " without paying its mana cost?", source, game)
player.getLibrary().removeFromTop(game); || !controller.playCard(card, game, true, true)) {
boolean used = false;
if (player.chooseUse(Outcome.PlayForFree, "Play " + card.getName() + " without paying its mana cost?", source, game)) {
if (card.getCardType().contains(CardType.LAND)) {
// If the revealed card is a land, you can play it only if it's your turn and you haven't yet played a land this turn.
if (game.getActivePlayerId().equals(player.getId()) && player.canPlayLand()) {
used = true;
player.playLand(card, game);
}
} else {
used = true;
player.cast(card.getSpellAbility(), game, true);
}
}
if (!used) {
card.moveToZone(Zone.EXILED, source.getSourceId(), game, false); card.moveToZone(Zone.EXILED, source.getSourceId(), game, false);
} }
return true; return true;
} }
return false; return false;

View file

@ -84,18 +84,11 @@ class LeafCrownedElderPlayEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
Card card = game.getCard(getTargetPointer().getFirst(game, source)); Card card = game.getCard(getTargetPointer().getFirst(game, source));
if (player != null && card != null) { if (controller != null && card != null) {
if (player.chooseUse(Outcome.PlayForFree, "Play " + card.getName() + " without paying its mana cost?", source, game)) { if (controller.chooseUse(Outcome.PlayForFree, "Play " + card.getIdName() + " without paying its mana cost?", source, game)) {
if (card.getCardType().contains(CardType.LAND)) { controller.playCard(card, game, true, true);
// If the revealed card is a land, you can play it only if it's your turn and you haven't yet played a land this turn.
if (game.getActivePlayerId().equals(player.getId()) && player.canPlayLand()) {
player.playLand(card, game);
}
} else {
player.cast(card.getSpellAbility(), game, true);
}
} }
return true; return true;
} }

View file

@ -30,6 +30,7 @@ package mage.sets.shardsofalara;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.cards.Card; import mage.cards.Card;
@ -56,11 +57,8 @@ public class BrilliantUltimatum extends CardImpl {
super(ownerId, 159, "Brilliant Ultimatum", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{W}{W}{U}{U}{U}{B}{B}"); super(ownerId, 159, "Brilliant Ultimatum", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{W}{W}{U}{U}{U}{B}{B}");
this.expansionSetCode = "ALA"; this.expansionSetCode = "ALA";
// Exile the top five cards of your library. An opponent separates those cards into two piles. You may play any number of cards from one of those piles without paying their mana costs. // Exile the top five cards of your library. An opponent separates those cards into two piles. You may play any number of cards from one of those piles without paying their mana costs.
this.getSpellAbility().addEffect(new BrilliantUltimatumEffect()); this.getSpellAbility().addEffect(new BrilliantUltimatumEffect());
this.getSpellAbility().addTarget(new TargetOpponent(true));
} }
public BrilliantUltimatum(final BrilliantUltimatum card) { public BrilliantUltimatum(final BrilliantUltimatum card) {
@ -91,22 +89,19 @@ class BrilliantUltimatumEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player you = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
if (you == null) { MageObject sourceObject = game.getObject(source.getSourceId());
if (controller == null || sourceObject == null) {
return false; return false;
} }
Cards pile2 = new CardsImpl(); Cards pile2 = new CardsImpl();
int max = Math.min(you.getLibrary().size(), 5); pile2.addAll(controller.getLibrary().getTopCards(game, 5));
for (int i = 0; i < max; i++) { controller.moveCardsToExile(pile2.getCards(game), source, game, true, source.getSourceId(), sourceObject.getIdName());
Card card = you.getLibrary().removeFromTop(game);
if (card != null) {
card.moveToExile(source.getSourceId(), "Brilliant Ultimatum", source.getSourceId(), game);
pile2.add(card);
}
}
Player opponent = game.getPlayer(source.getFirstTarget()); TargetOpponent targetOpponent = new TargetOpponent(true);
targetOpponent.choose(outcome, source.getControllerId(), source.getSourceId(), game);
Player opponent = game.getPlayer(targetOpponent.getFirstTarget());
if (opponent != null) { if (opponent != null) {
TargetCard target = new TargetCard(0, pile2.size(), Zone.EXILED, new FilterCard("cards to put in the first pile")); TargetCard target = new TargetCard(0, pile2.size(), Zone.EXILED, new FilterCard("cards to put in the first pile"));
target.setRequired(false); target.setRequired(false);
@ -123,55 +118,32 @@ class BrilliantUltimatumEffect extends OneShotEffect {
} }
} }
} }
for (UUID cardID : pile1) { pileOne.addAll(pile1.getCards(game));
Card card = pile1.get(cardID, game); pileTwo.addAll(pile2.getCards(game));
pileOne.add(card); controller.revealCards("Pile 1 - " + sourceObject.getIdName(), pile1, game);
} controller.revealCards("Pile 2 - " + sourceObject.getIdName(), pile2, game);
for (UUID cardId : pile2) {
Card card = pile2.get(cardId, game);
pileTwo.add(card);
}
you.revealCards("Pile 1 (Brilliant Ultimatum)", pile1, game); boolean choice = controller.choosePile(Outcome.PlayForFree, "Which pile (play for free)?", pileOne, pileTwo, game);
you.revealCards("Pile 2 (Brilliant Ultimatum)", pile2, game); String selectedPileName;
List<Card> selectedPileCards;
boolean choice = you.choosePile(Outcome.PlayForFree, "Which pile (play for free)?", pileOne, pileTwo, game); Cards selectedPile;
if (choice) { if (choice) {
game.informPlayer(you, you.getLogName() + " chose Pile 1."); selectedPileName = "pile 1";
while (!pileOne.isEmpty() && you.chooseUse(Outcome.PlayForFree, "Do you want to play a card from Pile 1?", source, game)) { selectedPileCards = pileOne;
selectedPile = pile1;
} else {
selectedPileName = "pile 2";
selectedPileCards = pileTwo;
selectedPile = pile2;
}
game.informPlayers(controller.getLogName() + " chose " + selectedPileName + ".");
while (!selectedPileCards.isEmpty() && controller.chooseUse(Outcome.PlayForFree, "Do you want to play a card for free from " + selectedPileName + "?", source, game)) {
TargetCard targetExiledCard = new TargetCard(Zone.EXILED, new FilterCard()); TargetCard targetExiledCard = new TargetCard(Zone.EXILED, new FilterCard());
if (you.chooseTarget(Outcome.PlayForFree, pile1, targetExiledCard, source, game)) { if (controller.chooseTarget(Outcome.PlayForFree, selectedPile, targetExiledCard, source, game)) {
Card card = pile1.get(targetExiledCard.getFirstTarget(), game); Card card = selectedPile.get(targetExiledCard.getFirstTarget(), game);
if (card != null) { if (controller.playCard(card, game, true, true)) {
if (card.getCardType().contains(CardType.LAND)) { selectedPileCards.remove(card);
you.playLand(card, game); selectedPile.remove(card);
pileOne.remove(card);
pile1.remove(card);
} else {
you.cast(card.getSpellAbility(), game, true);
pileOne.remove(card);
pile1.remove(card);
}
}
}
}
} else {
game.informPlayer(you, you.getLogName() + " chose Pile 2.");
while (!pileTwo.isEmpty() && you.chooseUse(Outcome.PlayForFree, "Do you want to play a card from Pile 2?", source, game)) {
TargetCard targetExiledCard = new TargetCard(Zone.EXILED, new FilterCard());
if (you.chooseTarget(Outcome.PlayForFree, pile2, targetExiledCard, source, game)) {
Card card = pile2.get(targetExiledCard.getFirstTarget(), game);
if (card != null) {
if (card.getCardType().contains(CardType.LAND)) {
you.playLand(card, game);
pileTwo.remove(card);
pile2.remove(card);
} else {
you.cast(card.getSpellAbility(), game, true);
pileTwo.remove(card);
pile2.remove(card);
}
}
} }
} }
} }

View file

@ -1207,8 +1207,13 @@ public class TestPlayer implements Player {
} }
@Override @Override
public boolean playLand(Card card, Game game) { public boolean playCard(Card card, Game game, boolean noMana, boolean ignoreTiming) {
return computerPlayer.playLand(card, game); return computerPlayer.playCard(card, game, noMana, ignoreTiming);
}
@Override
public boolean playLand(Card card, Game game, boolean ignoreTiming) {
return computerPlayer.playLand(card, game, ignoreTiming);
} }
@Override @Override
@ -1786,34 +1791,23 @@ public class TestPlayer implements Player {
} }
@Override @Override
@Deprecated
public boolean moveCards(Cards cards, Zone fromZone, Zone toZone, Ability source, Game game) { public boolean moveCards(Cards cards, Zone fromZone, Zone toZone, Ability source, Game game) {
return computerPlayer.moveCards(cards, fromZone, toZone, source, game); return computerPlayer.moveCards(cards, fromZone, toZone, source, game);
} }
@Override @Override
@Deprecated
public boolean moveCards(Card card, Zone fromZone, Zone toZone, Ability source, Game game) { public boolean moveCards(Card card, Zone fromZone, Zone toZone, Ability source, Game game) {
return computerPlayer.moveCards(card, fromZone, toZone, source, game); return computerPlayer.moveCards(card, fromZone, toZone, source, game);
} }
@Override @Override
@Deprecated
public boolean moveCards(Set<Card> cards, Zone fromZone, Zone toZone, Ability source, Game game) { public boolean moveCards(Set<Card> cards, Zone fromZone, Zone toZone, Ability source, Game game) {
return computerPlayer.moveCards(cards, fromZone, toZone, source, game); return computerPlayer.moveCards(cards, fromZone, toZone, source, game);
} }
// @Override
// public boolean moveCards(Cards cards, Zone fromZone, Zone toZone, Ability source, Game game, boolean withName) {
// return computerPlayer.moveCards(cards, fromZone, toZone, source, game);
// }
//
// @Override
// public boolean moveCards(Card card, Zone fromZone, Zone toZone, Ability source, Game game, boolean withName) {
// return computerPlayer.moveCards(card, fromZone, toZone, source, game);
// }
//
// @Override
// public boolean moveCards(Set<Card> cards, Zone fromZone, Zone toZone, Ability source, Game game, boolean withName) {
// return computerPlayer.moveCards(cards, fromZone, toZone, source, game);
// }
@Override @Override
public boolean moveCardToHandWithInfo(Card card, UUID sourceId, Game game) { public boolean moveCardToHandWithInfo(Card card, UUID sourceId, Game game) {
return computerPlayer.moveCardToHandWithInfo(card, sourceId, game); return computerPlayer.moveCardToHandWithInfo(card, sourceId, game);

View file

@ -25,11 +25,23 @@
* authors and should not be interpreted as representing official policies, either expressed * authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com. * or implied, of BetaSteward_at_googlemail.com.
*/ */
package org.mage.test.stub; package org.mage.test.stub;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import mage.MageObject; import mage.MageObject;
import mage.abilities.*; import mage.abilities.Abilities;
import mage.abilities.Ability;
import mage.abilities.ActivatedAbility;
import mage.abilities.Mode;
import mage.abilities.Modes;
import mage.abilities.SpellAbility;
import mage.abilities.TriggeredAbility;
import mage.abilities.costs.AlternativeSourceCosts; import mage.abilities.costs.AlternativeSourceCosts;
import mage.abilities.costs.Cost; import mage.abilities.costs.Cost;
import mage.abilities.costs.Costs; import mage.abilities.costs.Costs;
@ -41,8 +53,12 @@ import mage.cards.Card;
import mage.cards.Cards; import mage.cards.Cards;
import mage.cards.decks.Deck; import mage.cards.decks.Deck;
import mage.choices.Choice; import mage.choices.Choice;
import mage.constants.*; import mage.constants.AbilityType;
import mage.constants.ManaType;
import mage.constants.Outcome;
import mage.constants.PlayerAction; import mage.constants.PlayerAction;
import mage.constants.RangeOfInfluence;
import mage.constants.Zone;
import mage.counters.Counter; import mage.counters.Counter;
import mage.counters.Counters; import mage.counters.Counters;
import mage.game.Game; import mage.game.Game;
@ -64,9 +80,6 @@ import mage.target.TargetCard;
import mage.target.common.TargetCardInLibrary; import mage.target.common.TargetCardInLibrary;
import mage.util.MessageToClient; import mage.util.MessageToClient;
import java.io.Serializable;
import java.util.*;
/** /**
* *
* @author Quercitron * @author Quercitron
@ -601,7 +614,12 @@ public class PlayerStub implements Player {
} }
@Override @Override
public boolean playLand(Card card, Game game) { public boolean playCard(Card card, Game game, boolean noMana, boolean checkTiming) {
return false;
}
@Override
public boolean playLand(Card card, Game game, boolean ignoreTiming) {
return false; return false;
} }

View file

@ -25,7 +25,6 @@
* authors and should not be interpreted as representing official policies, either expressed * authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com. * or implied, of BetaSteward_at_googlemail.com.
*/ */
package mage.abilities; package mage.abilities;
import java.util.UUID; import java.util.UUID;
@ -52,17 +51,17 @@ public class PlayLandAbility extends ActivatedAbilityImpl {
@Override @Override
public boolean canActivate(UUID playerId, Game game) { public boolean canActivate(UUID playerId, Game game) {
if (!controlsAbility(playerId, game) && if (!controlsAbility(playerId, game)
!game.getContinuousEffects().asThough(getSourceId(), AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, playerId, game)) { && !game.getContinuousEffects().asThough(getSourceId(), AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, playerId, game)) {
return false; return false;
} }
//20091005 - 114.2a //20091005 - 114.2a
return game.canPlaySorcery(playerId) && game.getPlayer(playerId).canPlayLand(); return game.getPlayer(playerId).canPlayLand();
} }
@Override @Override
public String getGameLogMessage(Game game) { public String getGameLogMessage(Game game) {
return new StringBuilder(" plays ").append(getMessageText(game)).toString(); return " plays " + getMessageText(game);
} }
@Override @Override

View file

@ -25,26 +25,21 @@
* authors and should not be interpreted as representing official policies, either expressed * authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com. * or implied, of BetaSteward_at_googlemail.com.
*/ */
package mage.abilities.effects.common; package mage.abilities.effects.common;
import java.util.UUID; import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.Mode; import mage.abilities.Mode;
import mage.abilities.SpellAbility;
import mage.abilities.effects.common.search.SearchTargetGraveyardHandLibraryForCardNameAndExileEffect; import mage.abilities.effects.common.search.SearchTargetGraveyardHandLibraryForCardNameAndExileEffect;
import mage.cards.Card;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.target.Target; import mage.target.Target;
import mage.target.TargetPermanent; import mage.target.TargetPermanent;
import mage.target.TargetPlayer;
/** /**
* *
* @author LevelX2 * @author LevelX2
*/ */
public class ExileTargetAndSearchGraveyardHandLibraryEffect extends SearchTargetGraveyardHandLibraryForCardNameAndExileEffect { public class ExileTargetAndSearchGraveyardHandLibraryEffect extends SearchTargetGraveyardHandLibraryForCardNameAndExileEffect {
public ExileTargetAndSearchGraveyardHandLibraryEffect(Boolean graveyardExileOptional, String searchWhatText, String searchForText) { public ExileTargetAndSearchGraveyardHandLibraryEffect(Boolean graveyardExileOptional, String searchWhatText, String searchForText) {
@ -76,7 +71,6 @@ public class ExileTargetAndSearchGraveyardHandLibraryEffect extends SearchTarget
} }
} }
return result; return result;
} }

View file

@ -28,17 +28,13 @@
package mage.abilities.effects.common; package mage.abilities.effects.common;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.condition.common.MyMainPhaseCondition;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.cards.Card; import mage.cards.Card;
import mage.constants.CardType;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.constants.Zone;
import mage.game.ExileZone; import mage.game.ExileZone;
import mage.game.Game; import mage.game.Game;
import mage.players.Player; import mage.players.Player;
import mage.util.CardUtil; import mage.util.CardUtil;
import org.apache.log4j.Logger;
/** /**
* @author LevelX2 * @author LevelX2
@ -64,35 +60,13 @@ public class HideawayPlayEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
ExileZone zone = game.getExile().getExileZone(CardUtil.getCardExileZoneId(game, source)); ExileZone zone = game.getExile().getExileZone(CardUtil.getCardExileZoneId(game, source));
if (zone == null || zone.isEmpty()) { if (zone == null || zone.isEmpty()) {
return false; return true;
} }
Card card = zone.getCards(game).iterator().next(); Card card = zone.getCards(game).iterator().next();
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
if (card != null && controller != null) { if (card != null && controller != null) {
if (card.getCardType().contains(CardType.LAND)) { if (controller.chooseUse(Outcome.PlayForFree, "Do you want to play " + card.getIdName() + " for free now?", source, game)) {
// If the revealed card is a land, you can play it only if it's your turn and you haven't yet played a land this turn. controller.playCard(card, game, true, false);
if (game.getActivePlayerId().equals(source.getControllerId()) && controller.canPlayLand() && MyMainPhaseCondition.getInstance().apply(game, source)) {
if (controller.chooseUse(Outcome.Benefit, "Play " + card.getLogName() + " from Exile?", source, game)) {
// normal player.playLand(card, game) can't be used because this abilit is on the stack
card.setFaceDown(false, game);
return controller.moveCards(card, Zone.EXILED, Zone.BATTLEFIELD, source, game);
}
} else if (!game.isSimulation()) {
game.informPlayer(controller, "You're not able to play the land now due to regular restrictions.");
}
} else {
if (card.getSpellAbility() != null) {
// The land's last ability allows you to play the removed card as part of the resolution of that ability.
// Timing restrictions based on the card's type are ignored (for instance, if it's a creature or sorcery).
// Other play restrictions are not (such as "Play [this card] only during combat").
if (controller.chooseUse(Outcome.Benefit, "Cast " + card.getLogName() + " without paying its mana cost?", source, game)) {
card.setFaceDown(false, game);
return controller.cast(card.getSpellAbility(), game, true);
}
} else {
Logger.getLogger(HideawayPlayEffect.class).error("Non land card had no spell ability: " + card.getName());
return false;
}
} }
return true; return true;
} }

View file

@ -368,7 +368,29 @@ public interface Player extends MageItem, Copyable<Player> {
boolean canPlayLand(); boolean canPlayLand();
boolean playLand(Card card, Game game); /**
* Plays a card if possible
*
* @param card the card that can be cast
* @param game
* @param noMana if it's a spell i can be cast without paying mana
* @param ignoreTiming if it's cast during the resolution of another spell
* no sorcery or play land timing restriction are checked. For a land it has
* to be the turn of the player playing that card.
* @return
*/
boolean playCard(Card card, Game game, boolean noMana, boolean ignoreTiming);
/**
*
* @param card the land card to play
* @param game
* @param ignoreTiming false - it won't be checked if the stack is empty and
* you are able to play a Sorcery. It's still checked, if you are able to
* play a land concerning the numner of lands you already played.
* @return
*/
boolean playLand(Card card, Game game, boolean ignoreTiming);
boolean activateAbility(ActivatedAbility ability, Game game); boolean activateAbility(ActivatedAbility ability, Game game);

View file

@ -955,6 +955,23 @@ public abstract class PlayerImpl implements Player, Serializable {
return payManaMode; return payManaMode;
} }
@Override
public boolean playCard(Card card, Game game, boolean noMana, boolean ignoreTiming) {
if (card == null) {
return false;
}
boolean result;
if (card.getCardType().contains(CardType.LAND)) {
result = playLand(card, game, ignoreTiming);
} else {
result = cast(card.getSpellAbility(), game, noMana);
}
if (result == false) {
game.informPlayer(this, "You can't play " + card.getIdName() + ".");
}
return result;
}
@Override @Override
public boolean cast(SpellAbility ability, Game game, boolean noMana) { public boolean cast(SpellAbility ability, Game game, boolean noMana) {
if (!ability.getSpellAbilityType().equals(SpellAbilityType.BASE)) { if (!ability.getSpellAbilityType().equals(SpellAbilityType.BASE)) {
@ -1007,14 +1024,12 @@ public abstract class PlayerImpl implements Player, Serializable {
} }
@Override @Override
public SpellAbility chooseSpellAbilityForCast(SpellAbility ability, Game game, boolean noMana public SpellAbility chooseSpellAbilityForCast(SpellAbility ability, Game game, boolean noMana) {
) {
return ability; return ability;
} }
@Override @Override
public boolean playLand(Card card, Game game public boolean playLand(Card card, Game game, boolean ignoreTiming) {
) {
// Check for alternate casting possibilities: e.g. land with Morph // Check for alternate casting possibilities: e.g. land with Morph
ActivatedAbility playLandAbility = null; ActivatedAbility playLandAbility = null;
boolean found = false; boolean found = false;
@ -1038,9 +1053,18 @@ public abstract class PlayerImpl implements Player, Serializable {
if (playLandAbility == null) { if (playLandAbility == null) {
return false; return false;
} }
//20091005 - 114.2a
if (!playLandAbility.canActivate(this.playerId, game)) { if (!playLandAbility.canActivate(this.playerId, game)) {
return false; return false;
} }
if (ignoreTiming) {
if (!game.getActivePlayerId().equals(playerId)) {
// Also if a land can be played during the resolution of another spell, it has to be the turn of the player playing the land
return false;
}
} else if (!game.canPlaySorcery(playerId)) {
return false;
}
//20091005 - 305.1 //20091005 - 305.1
if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.PLAY_LAND, card.getId(), card.getId(), playerId))) { if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.PLAY_LAND, card.getId(), card.getId(), playerId))) {
// int bookmark = game.bookmarkState(); // int bookmark = game.bookmarkState();
@ -1147,9 +1171,8 @@ public abstract class PlayerImpl implements Player, Serializable {
return true; return true;
} }
if (ability instanceof PlayLandAbility) { if (ability instanceof PlayLandAbility) {
Card card = game.getCard(ability.getSourceId()); Card card = game.getCard(ability.getSourceId());
result = playLand(card, game); result = playLand(card, game, false);
} else { } else {
if (!ability.canActivate(this.playerId, game)) { if (!ability.canActivate(this.playerId, game)) {
return false; return false;