mirror of
https://github.com/magefree/mage.git
synced 2025-12-28 22:42:03 -08:00
* Some rework of play card effects.
This commit is contained in:
parent
780702be1b
commit
eb6a5e7dcb
14 changed files with 201 additions and 240 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue