mirror of
https://github.com/magefree/mage.git
synced 2026-01-09 20:32:06 -08:00
Some more rework of player.moveCard (mainly to graveyard).
This commit is contained in:
parent
039c4f22a6
commit
ce64a22c15
79 changed files with 490 additions and 653 deletions
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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()) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
64
Mage/src/mage/game/events/ZoneChangeGroupEvent.java
Normal file
64
Mage/src/mage/game/events/ZoneChangeGroupEvent.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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)) {
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ public class TargetPermanentOrPlayer extends TargetImpl {
|
|||
|
||||
@Override
|
||||
public Filter getFilter() {
|
||||
return this.filter;
|
||||
return filter;
|
||||
}
|
||||
|
||||
public void setFilter(FilterPermanentOrPlayer filter) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue