* 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

@ -1,31 +1,30 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.abilities;
import java.util.UUID;
@ -52,24 +51,24 @@ public class PlayLandAbility extends ActivatedAbilityImpl {
@Override
public boolean canActivate(UUID playerId, Game game) {
if (!controlsAbility(playerId, game) &&
!game.getContinuousEffects().asThough(getSourceId(), AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, playerId, game)) {
if (!controlsAbility(playerId, game)
&& !game.getContinuousEffects().asThough(getSourceId(), AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, playerId, game)) {
return false;
}
//20091005 - 114.2a
return game.canPlaySorcery(playerId) && game.getPlayer(playerId).canPlayLand();
//20091005 - 114.2a
return game.getPlayer(playerId).canPlayLand();
}
@Override
public String getGameLogMessage(Game game) {
return new StringBuilder(" plays ").append(getMessageText(game)).toString();
return " plays " + getMessageText(game);
}
@Override
public String toString() {
return this.name;
}
@Override
public String getRule() {
return this.name;

View file

@ -1,16 +1,16 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
@ -20,31 +20,26 @@
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.abilities.effects.common;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.SpellAbility;
import mage.abilities.effects.common.search.SearchTargetGraveyardHandLibraryForCardNameAndExileEffect;
import mage.cards.Card;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.Target;
import mage.target.TargetPermanent;
import mage.target.TargetPlayer;
/**
*
* @author LevelX2
*/
public class ExileTargetAndSearchGraveyardHandLibraryEffect extends SearchTargetGraveyardHandLibraryForCardNameAndExileEffect {
public ExileTargetAndSearchGraveyardHandLibraryEffect(Boolean graveyardExileOptional, String searchWhatText, String searchForText) {
@ -66,17 +61,16 @@ public class ExileTargetAndSearchGraveyardHandLibraryEffect extends SearchTarget
exileTarget = target;
break;
}
}
}
if (exileTarget != null) {
Permanent permanentToExile = game.getPermanent(exileTarget.getFirstTarget());
if (permanentToExile != null) {
targetPlayerId = permanentToExile.getControllerId();
result = permanentToExile.moveToExile(null, "", source.getSourceId(), game);
this.applySearchAndExile(game, source, permanentToExile.getName(), targetPlayerId);
this.applySearchAndExile(game, source, permanentToExile.getName(), targetPlayerId);
}
}
return result;
}
@ -92,4 +86,4 @@ public class ExileTargetAndSearchGraveyardHandLibraryEffect extends SearchTarget
sb.append(super.getText(mode));
return sb.toString();
}
}
}

View file

@ -28,17 +28,13 @@
package mage.abilities.effects.common;
import mage.abilities.Ability;
import mage.abilities.condition.common.MyMainPhaseCondition;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.game.ExileZone;
import mage.game.Game;
import mage.players.Player;
import mage.util.CardUtil;
import org.apache.log4j.Logger;
/**
* @author LevelX2
@ -64,35 +60,13 @@ public class HideawayPlayEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
ExileZone zone = game.getExile().getExileZone(CardUtil.getCardExileZoneId(game, source));
if (zone == null || zone.isEmpty()) {
return false;
return true;
}
Card card = zone.getCards(game).iterator().next();
Player controller = game.getPlayer(source.getControllerId());
if (card != null && controller != null) {
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(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;
}
if (controller.chooseUse(Outcome.PlayForFree, "Do you want to play " + card.getIdName() + " for free now?", source, game)) {
controller.playCard(card, game, true, false);
}
return true;
}

View file

@ -368,7 +368,29 @@ public interface Player extends MageItem, Copyable<Player> {
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);

View file

@ -955,6 +955,23 @@ public abstract class PlayerImpl implements Player, Serializable {
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
public boolean cast(SpellAbility ability, Game game, boolean noMana) {
if (!ability.getSpellAbilityType().equals(SpellAbilityType.BASE)) {
@ -1007,14 +1024,12 @@ public abstract class PlayerImpl implements Player, Serializable {
}
@Override
public SpellAbility chooseSpellAbilityForCast(SpellAbility ability, Game game, boolean noMana
) {
public SpellAbility chooseSpellAbilityForCast(SpellAbility ability, Game game, boolean noMana) {
return ability;
}
@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
ActivatedAbility playLandAbility = null;
boolean found = false;
@ -1038,9 +1053,18 @@ public abstract class PlayerImpl implements Player, Serializable {
if (playLandAbility == null) {
return false;
}
//20091005 - 114.2a
if (!playLandAbility.canActivate(this.playerId, game)) {
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
if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.PLAY_LAND, card.getId(), card.getId(), playerId))) {
// int bookmark = game.bookmarkState();
@ -1147,9 +1171,8 @@ public abstract class PlayerImpl implements Player, Serializable {
return true;
}
if (ability instanceof PlayLandAbility) {
Card card = game.getCard(ability.getSourceId());
result = playLand(card, game);
result = playLand(card, game, false);
} else {
if (!ability.canActivate(this.playerId, game)) {
return false;