Some more rework of player.moveCard (mainly to graveyard).

This commit is contained in:
LevelX2 2015-05-23 15:35:40 +02:00
parent 039c4f22a6
commit ce64a22c15
79 changed files with 490 additions and 653 deletions

View file

@ -68,9 +68,7 @@ public class PutTopCardOfYourLibraryToGraveyardCost extends CostImpl {
Player player = game.getPlayer(controllerId);
if (player != null && player.getLibrary().size() >= numberOfCards) {
paid = true;
Cards cards = new CardsImpl();
cards.addAll(player.getLibrary().getTopCards(game, numberOfCards));
player.moveCardsToGraveyardWithInfo(cards, ability, game, Zone.LIBRARY);
player.moveCards(player.getLibrary().getTopCards(game, numberOfCards), Zone.LIBRARY, Zone.GRAVEYARD, ability, game);
}
return paid;
}

View file

@ -69,7 +69,7 @@ public class AddManaOfAnyColorEffect extends BasicManaEffect {
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
ChoiceColor choice = new ChoiceColor(false);
ChoiceColor choice = new ChoiceColor(true);
if (controller.choose(outcome, choice, game)) {
if (choice.getColor() == null) {

View file

@ -94,9 +94,6 @@ public class CounterTargetWithReplacementEffect extends OneShotEffect {
if (mageObject instanceof Card) {
Card card = (Card) mageObject;
switch (targetZone) {
case HAND:
controller.moveCardToHandWithInfo(card, sourceId, game, Zone.STACK);
break;
case LIBRARY:
controller.moveCardToLibraryWithInfo(card, sourceId, game, Zone.STACK, flag, true);
break;
@ -104,7 +101,7 @@ public class CounterTargetWithReplacementEffect extends OneShotEffect {
controller.moveCardToExileWithInfo(card, null, "", sourceId, game, Zone.STACK, true);
break;
default:
card.moveToZone(targetZone, sourceId, game, flag);
controller.moveCards(card, Zone.STACK, targetZone, source, game);
}
} else {
return false;

View file

@ -74,9 +74,7 @@ public class PutLibraryIntoGraveTargetEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(targetPointer.getFirst(game, source));
if (player != null) {
// putting cards to grave shouldn't end the game, so getting minimun available
int cardsCount = Math.min(amount.calculate(game, source, this), player.getLibrary().size());
player.moveCardsToGraveyardWithInfo(player.getLibrary().getTopCards(game, cardsCount), source, game, Zone.LIBRARY);
player.moveCards(player.getLibrary().getTopCards(game, amount.calculate(game, source, this)), Zone.LIBRARY, Zone.GRAVEYARD, source, game);
return true;
}
return false;

View file

@ -65,8 +65,7 @@ public class PutTopCardOfLibraryIntoGraveControllerEffect extends OneShotEffect
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
controller.moveCardsToGraveyardWithInfo(controller.getLibrary().getTopCards(game, numberCards), source, game, Zone.LIBRARY);
return true;
return controller.moveCards(controller.getLibrary().getTopCards(game, numberCards), Zone.LIBRARY, Zone.GRAVEYARD, source, game);
}
return false;
}

View file

@ -33,7 +33,6 @@ import mage.abilities.Ability;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
import mage.constants.Outcome;
import mage.constants.TargetController;
import mage.constants.Zone;
@ -106,13 +105,7 @@ public class PutTopCardOfLibraryIntoGraveEachPlayerEffect extends OneShotEffect
private void putCardsToGravecard(UUID playerId, Ability source, Game game) {
Player player = game.getPlayer(playerId);
if (player != null) {
int cardsCount = Math.min(numberCards.calculate(game, source, this), player.getLibrary().size());
for (int i = 0; i < cardsCount; i++) {
Card card = player.getLibrary().removeFromTop(game);
if (card != null) {
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, true);
}
}
player.moveCards(player.getLibrary().getTopCards(game, numberCards.calculate(game, source, this)), Zone.LIBRARY, Zone.GRAVEYARD, source, game);
}
}

View file

@ -100,11 +100,14 @@ public class ReturnFromExileEffect extends OneShotEffect {
}
break;
case HAND:
controller.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.EXILED);
controller.moveCards(card, Zone.EXILED, Zone.HAND, source, game);
break;
case LIBRARY:
controller.moveCardToLibraryWithInfo(card, source.getSourceId(), game, Zone.EXILED, true, true);
break;
case GRAVEYARD:
controller.moveCards(card, Zone.EXILED, Zone.GRAVEYARD, source, game);
break;
default:
card.moveToZone(zone, source.getSourceId(), game, tapped);
if (!game.isSimulation()) {

View file

@ -104,8 +104,8 @@ class DredgeEffect extends ReplacementEffectImpl {
}
Cards cardsToGrave = new CardsImpl();
cardsToGrave.addAll(player.getLibrary().getTopCards(game, amount));
player.moveCardsToGraveyardWithInfo(cardsToGrave, source, game, Zone.LIBRARY);
player.moveCardToHandWithInfo(sourceCard, source.getSourceId(), game, Zone.GRAVEYARD);
player.moveCards(cardsToGrave, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
player.moveCards(sourceCard, Zone.GRAVEYARD, Zone.HAND, source, game);
return true;
}
return false;

View file

@ -1204,7 +1204,7 @@ public abstract class GameImpl implements Game, Serializable {
top.resolve(this);
} finally {
if (top != null) {
state.getStack().remove(top);
state.getStack().remove(top); // seems partly redundant because move card from stack to grave is already done and the stack removed
rememberLKI(top.getSourceId(), Zone.STACK, top);
if (!getTurn().isEndTurnRequested()) {
while (state.hasSimultaneousEvents()) {
@ -1739,8 +1739,7 @@ public abstract class GameImpl implements Game, Serializable {
boolean result = false;
if (permanent.moveToZone(Zone.GRAVEYARD, null, this, false)) {
if (!this.isSimulation()) {
this.informPlayers(new StringBuilder(permanent.getLogName())
.append(" is put into graveyard from battlefield").toString());
this.informPlayers(permanent.getLogName() + " is put into graveyard from battlefield");
}
result = true;
}

View file

@ -81,13 +81,14 @@ public class GameEvent implements Serializable {
//player events
/* ZONE_CHANGE
targetId id of the zone chaning object
targetId id of the zone changing object
sourceId sourceId of the ability with the object moving effect
playerId controller of the moved object
amount not used for this event
flag not used for this event
*/
ZONE_CHANGE,
ZONE_CHANGE_GROUP,
EMPTY_DRAW,
DRAW_CARD, DREW_CARD,
MIRACLE_CARD_REVEALED,

View file

@ -87,7 +87,7 @@ public class ZoneChangeEvent extends GameEvent {
public ZoneChangeEvent(UUID targetId, UUID playerId, Zone fromZone, Zone toZone) {
this(targetId, null, playerId, fromZone, toZone);
}
public Zone getFromZone() {
return fromZone;
}

View file

@ -0,0 +1,64 @@
/*
* 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.game.events;
import java.util.List;
import java.util.UUID;
import mage.cards.Card;
import mage.constants.Zone;
/**
*
* @author LevelX2
*/
public class ZoneChangeGroupEvent extends GameEvent {
private final Zone fromZone;
private final Zone toZone;
private final List<Card> cards;
public ZoneChangeGroupEvent(List<Card> cards, UUID sourceId, UUID playerId, Zone fromZone, Zone toZone) {
super(EventType.ZONE_CHANGE_GROUP, null, sourceId, playerId);
this.fromZone = fromZone;
this.toZone = toZone;
this.cards = cards;
}
public Zone getFromZone() {
return fromZone;
}
public Zone getToZone() {
return toZone;
}
public List<Card> getCards() {
return cards;
}
}

View file

@ -201,13 +201,14 @@ public class Spell implements StackObject, Card {
result |= spellAbility.resolve(game);
}
}
// game.getState().handleSimultaneousEvent(game);
// game.resetShortLivingLKI();
index++;
}
}
if (game.getState().getZone(card.getMainCard().getId()) == Zone.STACK) {
card.moveToZone(Zone.GRAVEYARD, ability.getSourceId(), game, false);
Player player = game.getPlayer(getControllerId());
if (player != null) {
player.moveCards(card, Zone.STACK, Zone.GRAVEYARD, ability, game);
}
}
return result;
}
@ -524,7 +525,15 @@ public class Spell implements StackObject, Card {
public void counter(UUID sourceId, Game game) {
this.countered = true;
if (!isCopiedSpell()) {
card.moveToZone(Zone.GRAVEYARD, sourceId, game, false);
Player player = game.getPlayer(getControllerId());
if (player != null) {
Ability counteringAbility = null;
MageObject counteringObject = game.getObject(sourceId);
if (counteringObject instanceof StackObject) {
counteringAbility = ((StackObject)counteringObject).getStackAbility();
}
player.moveCards(card, Zone.STACK, Zone.GRAVEYARD, counteringAbility, game);
}
}
}

View file

@ -502,10 +502,8 @@ public interface Player extends MageItem, Copyable<Player> {
/**
* Moves 1 to n cards to the graveyard. The owner of the cards may determine the order,
* if more than one card is moved to graveyard.
* Uses card.moveToZone and posts a inform message about moving the card to graveyard
* into the game log
* Internal used to move cards
* Use commonly player.moveCards()
*
* @param cards
* @param source
@ -513,7 +511,6 @@ public interface Player extends MageItem, Copyable<Player> {
* @param fromZone if null, this info isn't postet
* @return
*/
boolean moveCardsToGraveyardWithInfo(Cards cards, Ability source, Game game, Zone fromZone);
boolean moveCardsToGraveyardWithInfo(List<Card> cards, Ability source, Game game, Zone fromZone);
/**

View file

@ -113,6 +113,7 @@ import mage.game.events.DamagePlayerEvent;
import mage.game.events.DamagedPlayerEvent;
import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
import mage.game.events.ZoneChangeGroupEvent;
import mage.game.match.MatchPlayer;
import mage.game.permanent.Permanent;
import mage.game.permanent.PermanentCard;
@ -2844,14 +2845,19 @@ public abstract class PlayerImpl implements Player, Serializable {
@Override
public boolean moveCards(List<Card> cards, Zone fromZone, Zone toZone, Ability source, Game game) {
if (cards.isEmpty()) {
return true;
}
game.fireEvent(new ZoneChangeGroupEvent(cards, source == null ? null : source.getSourceId(), this.getId(), fromZone, toZone));
switch(toZone) {
case GRAVEYARD:
return moveCardsToGraveyardWithInfo(cards, source, game, fromZone);
case HAND:
boolean result = false;
for(Card card: cards) {
moveCardToHandWithInfo(card, playerId, game, fromZone);
result |= moveCardToHandWithInfo(card, playerId, game, fromZone);
}
return true;
return result;
default:
throw new UnsupportedOperationException("to Zone not supported yet");
}
@ -2886,33 +2892,25 @@ public abstract class PlayerImpl implements Player, Serializable {
}
return result;
}
@Override
public boolean moveCardsToGraveyardWithInfo(Cards allCards, Ability source, Game game, Zone fromZone) {
ArrayList<Card> cards = new ArrayList<>();
cards.addAll(allCards.getCards(game));
return moveCardsToGraveyardWithInfo(cards, source, game, fromZone);
}
@Override
public boolean moveCardsToGraveyardWithInfo(List<Card> allCards, Ability source, Game game, Zone fromZone) {
while (!allCards.isEmpty()) {
// identify cards from one owner
Cards cards = new CardsImpl();
UUID ownerId = null;
for (Card card: allCards) {
for (Iterator<Card> it = allCards.iterator(); it.hasNext();) {
Card card = it.next();
if (cards.isEmpty()) {
ownerId = card.getOwnerId();
}
if (card.getOwnerId().equals(ownerId)) {
it.remove();
cards.add(card);
}
}
allCards.removeAll(cards.getCards(game));
// move cards ot graveyard in order the owner decides
if (cards.size() != 0) {
TargetCard target = new TargetCard(fromZone, new FilterCard("card to put on the top of your graveyard (last one chosen will be topmost)"));
target.setRequired(true);
if (!cards.isEmpty()) {
Player choosingPlayer = this;
if (ownerId != this.getId()) {
choosingPlayer = game.getPlayer(ownerId);
@ -2925,6 +2923,8 @@ public abstract class PlayerImpl implements Player, Serializable {
chooseOrder = choosingPlayer.chooseUse(Outcome.Neutral, "Would you like to choose the order the cards go to graveyard?", game);
}
if (chooseOrder) {
TargetCard target = new TargetCard(fromZone, new FilterCard("card to put on the top of your graveyard (last one chosen will be topmost)"));
target.setRequired(true);
while (choosingPlayer.isInGame() && cards.size() > 1) {
choosingPlayer.chooseTarget(Outcome.Neutral, cards, target, source, game);
UUID targetObjectId = target.getFirstTarget();
@ -2936,7 +2936,7 @@ public abstract class PlayerImpl implements Player, Serializable {
target.clearChosen();
}
if (cards.size() == 1) {
choosingPlayer.moveCardToGraveyardWithInfo(cards.getCards(game).iterator().next(), source.getSourceId(), game, fromZone);
choosingPlayer.moveCardToGraveyardWithInfo(cards.getCards(game).iterator().next(), source == null ? null : source.getSourceId(), game, fromZone);
}
} else {
for (Card card : cards.getCards(game)) {

View file

@ -83,7 +83,7 @@ public class TargetPermanentOrPlayer extends TargetImpl {
@Override
public Filter getFilter() {
return this.filter;
return filter;
}
public void setFilter(FilterPermanentOrPlayer filter) {

View file

@ -34,7 +34,6 @@ import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import java.util.UUID;
import mage.counters.CounterType;
import mage.filter.FilterPermanent;
import mage.filter.predicate.permanent.CounterPredicate;