* Some more changes for rework of ENTERS_THE_BATTLEFIELD event and card movement.

This commit is contained in:
LevelX2 2015-10-18 23:33:23 +02:00
parent 4216fbab8c
commit 415700ccb2
129 changed files with 1029 additions and 1265 deletions

View file

@ -952,16 +952,15 @@ public abstract class AbilityImpl implements Ability {
// for singleton abilities like Flying we can't rely on abilities' source because it's only once in continuous effects
// so will use the sourceId of the object itself that came as a parameter if it is not null
if (object == null) {
object = game.getObject(getSourceId());
object = game.getPermanentEntering(getSourceId());
if (object == null) {
object = game.getObject(getSourceId());
}
}
if (object != null && !object.getAbilities().contains(this)) {
if (object instanceof Permanent) {
return false;
} else {
Permanent permanent = game.getPermanentEntering(getSourceId());
if (permanent != null && permanent.getAbilities().contains(this)) {
return true;
}
// check if it's an ability that is temporary gained to a card
Abilities<Ability> otherAbilities = game.getState().getAllOtherAbilities(this.getSourceId());
if (otherAbilities == null || !otherAbilities.contains(this)) {

View file

@ -98,7 +98,7 @@ public class CopyPermanentEffect extends OneShotEffect {
} else {
Target target = new TargetPermanent(filter);
target.setNotTarget(true);
if (target.canChoose(source.getControllerId(), game)) {
if (target.canChoose(source.getSourceId(), player.getId(), game)) {
player.choose(Outcome.Copy, target, source.getSourceId(), game);
copyFromPermanent = game.getPermanent(target.getFirstTarget());
}

View file

@ -25,7 +25,6 @@
* 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 mage.abilities.Ability;
@ -50,10 +49,11 @@ public class PutLandFromHandOntoBattlefieldEffect extends OneShotEffect {
public PutLandFromHandOntoBattlefieldEffect() {
this(false);
}
public PutLandFromHandOntoBattlefieldEffect(boolean tapped) {
super(Outcome.PutLandInPlay);
this.tapped = tapped;
staticText = "you may put a land card from your hand onto the battlefield" + (tapped ? " tapped":"");
staticText = "you may put a land card from your hand onto the battlefield" + (tapped ? " tapped" : "");
}
public PutLandFromHandOntoBattlefieldEffect(final PutLandFromHandOntoBattlefieldEffect effect) {
@ -66,12 +66,12 @@ public class PutLandFromHandOntoBattlefieldEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
Target target = new TargetCardInHand(new FilterLandCard("land card"));
if (target.canChoose(source.getSourceId(), source.getControllerId(), game) &&
controller.chooseUse(outcome, "Put land onto battlefield?", source, game) &&
controller.choose(outcome, target, source.getSourceId(), game)) {
if (target.canChoose(source.getSourceId(), source.getControllerId(), game)
&& controller.chooseUse(outcome, "Put land onto battlefield?", source, game)
&& controller.choose(outcome, target, source.getSourceId(), game)) {
Card card = game.getCard(target.getFirstTarget());
if (card != null) {
controller.putOntoBattlefieldWithInfo(card, game, Zone.HAND, source.getSourceId(), tapped);
controller.moveCards(card, Zone.BATTLEFIELD, source, game, tapped, false, false, null);
}
}
return true;
@ -85,4 +85,4 @@ public class PutLandFromHandOntoBattlefieldEffect extends OneShotEffect {
return new PutLandFromHandOntoBattlefieldEffect(this);
}
}
}

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,19 +20,18 @@
* 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 mage.constants.Outcome;
import mage.constants.Zone;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.game.Game;
import mage.players.Player;
@ -54,6 +53,7 @@ public class ReturnSourceFromGraveyardToBattlefieldEffect extends OneShotEffect
this.tapped = tapped;
setText();
}
public ReturnSourceFromGraveyardToBattlefieldEffect(boolean tapped, boolean ownerControl) {
super(Outcome.PutCreatureInPlay);
this.tapped = tapped;
@ -76,32 +76,31 @@ public class ReturnSourceFromGraveyardToBattlefieldEffect extends OneShotEffect
public boolean apply(Game game, Ability source) {
if (!game.getState().getZone(source.getSourceId()).equals(Zone.GRAVEYARD)) {
return false;
}
}
Card card = game.getCard(source.getSourceId());
if (card == null) {
return false;
}
Player player;
Player player;
if (ownerControl) {
player = game.getPlayer(card.getOwnerId());
} else {
player = game.getPlayer(source.getControllerId());
}
if (player == null) {
}
if (player == null) {
return false;
}
return player.putOntoBattlefieldWithInfo(card, game, Zone.GRAVEYARD, source.getSourceId(), tapped);
}
return player.moveCards(card, Zone.BATTLEFIELD, source, game, tapped, false, true, null);
}
private void setText() {
StringBuilder sb = new StringBuilder("return {this} from your graveyard to the battlefield");
if (tapped) {
sb.append(" tapped");
}
}
if (ownerControl) {
sb.append(" under its owner's control");
sb.append(" under its owner's control");
}
staticText = sb.toString();
}

View file

@ -1,38 +1,37 @@
/*
* 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.effects.common.search;
import java.util.List;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.effects.SearchEffect;
import mage.cards.Card;
import mage.cards.CardsImpl;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.game.Game;
@ -90,12 +89,8 @@ public class SearchLibraryPutInPlayEffect extends SearchEffect {
}
if (player.searchLibrary(target, game)) {
if (target.getTargets().size() > 0) {
for (UUID cardId: target.getTargets()) {
Card card = player.getLibrary().getCard(cardId, game);
if (card != null) {
player.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId(), tapped);
}
}
player.moveCards(new CardsImpl(target.getTargets()).getCards(game),
Zone.BATTLEFIELD, source, game, true, false, false, null);
}
player.shuffleLibrary(game);
return true;
@ -110,15 +105,13 @@ public class SearchLibraryPutInPlayEffect extends SearchEffect {
StringBuilder sb = new StringBuilder();
sb.append("search your library for ");
if (target.getNumberOfTargets() == 0 && target.getMaxNumberOfTargets() > 0) {
if ( target.getMaxNumberOfTargets() == Integer.MAX_VALUE ) {
if (target.getMaxNumberOfTargets() == Integer.MAX_VALUE) {
sb.append("any number of ").append(" ");
}
else {
} else {
sb.append("up to ").append(target.getMaxNumberOfTargets()).append(" ");
}
sb.append(target.getTargetName()).append(" and put them onto the battlefield");
}
else {
} else {
sb.append("a ").append(target.getTargetName()).append(" and put it onto the battlefield");
}
if (tapped) {
@ -126,8 +119,7 @@ public class SearchLibraryPutInPlayEffect extends SearchEffect {
}
if (forceShuffle) {
sb.append(". Then shuffle your library");
}
else {
} else {
sb.append(". If you do, shuffle your library");
}
staticText = sb.toString();

View file

@ -9,7 +9,7 @@ import java.util.List;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.effects.SearchEffect;
import mage.cards.Card;
import mage.cards.CardsImpl;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.game.Game;
@ -20,11 +20,11 @@ import mage.target.common.TargetCardInLibrary;
*
* @author LevelX2
*/
public class SearchLibraryPutInPlayTargetPlayerEffect extends SearchEffect {
protected boolean tapped;
protected boolean forceShuffle;
protected boolean ownerIsController;
public SearchLibraryPutInPlayTargetPlayerEffect(TargetCardInLibrary target) {
this(target, false, true, Outcome.PutCardInPlay);
@ -43,9 +43,14 @@ public class SearchLibraryPutInPlayTargetPlayerEffect extends SearchEffect {
}
public SearchLibraryPutInPlayTargetPlayerEffect(TargetCardInLibrary target, boolean tapped, boolean forceShuffle, Outcome outcome) {
this(target, tapped, forceShuffle, outcome, false);
}
public SearchLibraryPutInPlayTargetPlayerEffect(TargetCardInLibrary target, boolean tapped, boolean forceShuffle, Outcome outcome, boolean ownerIsController) {
super(target, outcome);
this.tapped = tapped;
this.forceShuffle = forceShuffle;
this.ownerIsController = ownerIsController;
setText();
}
@ -53,6 +58,7 @@ public class SearchLibraryPutInPlayTargetPlayerEffect extends SearchEffect {
super(effect);
this.tapped = effect.tapped;
this.forceShuffle = effect.forceShuffle;
this.ownerIsController = effect.ownerIsController;
}
@Override
@ -62,26 +68,22 @@ public class SearchLibraryPutInPlayTargetPlayerEffect extends SearchEffect {
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(getTargetPointer().getFirst(game, source));
Player player = game.getPlayer(getTargetPointer().getFirst(game, source));
if (player != null) {
if (player.searchLibrary(target, game)) {
if (target.getTargets().size() > 0) {
for (UUID cardId: target.getTargets()) {
Card card = player.getLibrary().getCard(cardId, game);
if (card != null) {
player.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId(), tapped);
}
}
player.moveCards(new CardsImpl(target.getTargets()).getCards(game),
Zone.BATTLEFIELD, source, game, tapped, false, ownerIsController, null);
}
player.shuffleLibrary(game);
return true;
}
if (forceShuffle) {
player.shuffleLibrary(game);
}
}
return false;
}
@ -89,15 +91,13 @@ public class SearchLibraryPutInPlayTargetPlayerEffect extends SearchEffect {
StringBuilder sb = new StringBuilder();
sb.append("target player searches his or her library for ");
if (target.getNumberOfTargets() == 0 && target.getMaxNumberOfTargets() > 0) {
if ( target.getMaxNumberOfTargets() == Integer.MAX_VALUE ) {
if (target.getMaxNumberOfTargets() == Integer.MAX_VALUE) {
sb.append("any number of ").append(" ");
}
else {
} else {
sb.append("up to ").append(target.getMaxNumberOfTargets()).append(" ");
}
sb.append(target.getTargetName()).append(" and put them onto the battlefield");
}
else {
} else {
sb.append("a ").append(target.getTargetName()).append(" and put it onto the battlefield");
}
if (tapped) {
@ -105,8 +105,7 @@ public class SearchLibraryPutInPlayTargetPlayerEffect extends SearchEffect {
}
if (forceShuffle) {
sb.append(". Then that player shuffles his or her library");
}
else {
} else {
sb.append(". If that player does, he or she shuffles his or her library");
}
staticText = sb.toString();

View file

@ -86,13 +86,15 @@ public class ManifestEffect extends OneShotEffect {
}
MageObjectReference objectReference = new MageObjectReference(card.getId(), card.getZoneChangeCounter(game) + 1, game);
game.addEffect(new BecomesFaceDownCreatureEffect(manaCosts, objectReference, Duration.Custom, FaceDownType.MANIFESTED), newSource);
controller.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, newSource.getSourceId(), false, true);
}
controller.moveCards(cards, Zone.BATTLEFIELD, source, game, false, true, false, null);
for (Card card : cards) {
Permanent permanent = game.getPermanent(card.getId());
if (permanent != null) {
permanent.setManifested(true);
}
}
game.applyEffects(); // to apply before ETB triggered or replace Effects are executed
return true;
}
return false;

View file

@ -89,7 +89,9 @@ public class ManifestTargetPlayerEffect extends OneShotEffect {
}
MageObjectReference objectReference = new MageObjectReference(card.getId(), card.getZoneChangeCounter(game) + 1, game);
game.addEffect(new BecomesFaceDownCreatureEffect(manaCosts, objectReference, Duration.Custom, FaceDownType.MANIFESTED), newSource);
targetPlayer.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, newSource.getSourceId(), false, true);
}
targetPlayer.moveCards(cards, Zone.BATTLEFIELD, source, game, false, true, false, null);
for (Card card : cards) {
Permanent permanent = game.getPermanent(card.getId());
if (permanent != null) {
permanent.setManifested(true);

View file

@ -61,7 +61,7 @@ public enum CardRepository {
private static final String JDBC_URL = "jdbc:h2:file:./db/cards.h2;AUTO_SERVER=TRUE";
private static final String VERSION_ENTITY_NAME = "card";
// raise this if db structure was changed
private static final long CARD_DB_VERSION = 41;
private static final long CARD_DB_VERSION = 42;
// raise this if new cards were added to the server
private static final long CARD_CONTENT_VERSION = 40;

View file

@ -741,46 +741,6 @@ public interface Player extends MageItem, Copyable<Player> {
*/
boolean moveCardToLibraryWithInfo(Card card, UUID sourceId, Game game, Zone fromZone, boolean toTop, boolean withName);
/**
* Uses putOntoBattlefield and posts also a info message about in the game
* log
*
* @param card
* @param game
* @param fromZone
* @param sourceId
* @return
*/
@Deprecated
boolean putOntoBattlefieldWithInfo(Card card, Game game, Zone fromZone, UUID sourceId);
/**
* Uses putOntoBattlefield and posts also a info message about in the game
* log
*
* @param card
* @param game
* @param fromZone
* @param sourceId
* @param tapped the card enters the battlefield tapped
* @return
*/
boolean putOntoBattlefieldWithInfo(Card card, Game game, Zone fromZone, UUID sourceId, boolean tapped);
/**
* Uses putOntoBattlefield and posts also a info message about in the game
* log
*
* @param card
* @param game
* @param fromZone
* @param sourceId
* @param tapped the card enters the battlefield tapped
* @param facedown the card enters the battlefield facedown
* @return
*/
boolean putOntoBattlefieldWithInfo(Card card, Game game, Zone fromZone, UUID sourceId, boolean tapped, boolean facedown);
/**
* Checks if the playerToCheckId is from an opponent in range
*

View file

@ -3025,7 +3025,7 @@ public abstract class PlayerImpl implements Player, Serializable {
List<Permanent> permanents = new ArrayList<>();
List<Permanent> permanentsEntered = new ArrayList<>();
for (Card card : cards) {
UUID controllingPlayerId = byOwner ? card.getOwnerId() : source.getControllerId();
UUID controllingPlayerId = byOwner ? card.getOwnerId() : getId();
fromZone = game.getState().getZone(card.getId());
if (faceDown) {
card.setFaceDown(true, game);
@ -3307,34 +3307,6 @@ public abstract class PlayerImpl implements Player, Serializable {
return result;
}
@Deprecated
@Override
public boolean putOntoBattlefieldWithInfo(Card card, Game game, Zone fromZone, UUID sourceId) {
return this.putOntoBattlefieldWithInfo(card, game, fromZone, sourceId, false, false);
}
@Deprecated
@Override
public boolean putOntoBattlefieldWithInfo(Card card, Game game, Zone fromZone, UUID sourceId, boolean tapped) {
return this.putOntoBattlefieldWithInfo(card, game, fromZone, sourceId, tapped, false);
}
@Deprecated
@Override
public boolean putOntoBattlefieldWithInfo(Card card, Game game, Zone fromZone, UUID sourceId, boolean tapped, boolean facedown) {
boolean result = false;
if (card.putOntoBattlefield(game, fromZone, sourceId, this.getId(), tapped, facedown)) {
if (!game.isSimulation()) {
game.informPlayers(new StringBuilder(this.getLogName())
.append(" puts ").append(facedown ? "a card face down " : card.getLogName())
.append(" from ").append(fromZone.toString().toLowerCase(Locale.ENGLISH)).append(" ")
.append("onto the Battlefield").toString());
}
result = true;
}
return result;
}
@Override
public boolean hasOpponent(UUID playerToCheckId, Game game) {
return !this.getId().equals(playerToCheckId) && game.isOpponent(this, playerToCheckId);