* Fixed some corner cases for Worl Enchantment State-Based actions (704.5k).

This commit is contained in:
LevelX2 2020-07-18 12:23:19 +02:00
parent fdae577cef
commit a2ae232b43
7 changed files with 161 additions and 54 deletions

View file

@ -1,4 +1,3 @@
package mage.cards.l; package mage.cards.l;
import java.util.UUID; import java.util.UUID;
@ -11,8 +10,8 @@ import mage.abilities.effects.common.CreateTokenEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.constants.SubType;
import mage.counters.CounterType; import mage.counters.CounterType;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
@ -33,7 +32,9 @@ public final class LieutenantsOfTheGuard extends CardImpl {
this.power = new MageInt(2); this.power = new MageInt(2);
this.toughness = new MageInt(2); this.toughness = new MageInt(2);
// <i>Council's dilemma</i> &mdash; When Lieutenants of the Guard enters the battlefield, starting with you, each player votes for strength or numbers. Put a +1/+1 counter on Lieutenants of the Guard for each strength vote and put a 1/1 white Soldier creature token onto the battlefield for each numbers vote. // <i>Council's dilemma</i> &mdash; When Lieutenants of the Guard enters the battlefield, starting with you,
// each player votes for strength or numbers. Put a +1/+1 counter on Lieutenants of the Guard for each
// strength vote and put a 1/1 white Soldier creature token onto the battlefield for each numbers vote.
this.addAbility(new EntersBattlefieldTriggeredAbility(new LieutenantsOfTheGuardDilemmaEffect(), false, "<i>Council's dilemma</i> — ")); this.addAbility(new EntersBattlefieldTriggeredAbility(new LieutenantsOfTheGuardDilemmaEffect(), false, "<i>Council's dilemma</i> — "));
} }
@ -48,6 +49,7 @@ public final class LieutenantsOfTheGuard extends CardImpl {
} }
class LieutenantsOfTheGuardDilemmaEffect extends CouncilsDilemmaVoteEffect { class LieutenantsOfTheGuardDilemmaEffect extends CouncilsDilemmaVoteEffect {
public LieutenantsOfTheGuardDilemmaEffect() { public LieutenantsOfTheGuardDilemmaEffect() {
super(Outcome.Benefit); super(Outcome.Benefit);
this.staticText = "starting with you, each player votes for strength or numbers. Put a +1/+1 counter on {this} for each strength vote and put a 1/1 white Soldier creature token onto the battlefield for each numbers vote."; this.staticText = "starting with you, each player votes for strength or numbers. Put a +1/+1 counter on {this} for each strength vote and put a 1/1 white Soldier creature token onto the battlefield for each numbers vote.";
@ -62,7 +64,9 @@ class LieutenantsOfTheGuardDilemmaEffect extends CouncilsDilemmaVoteEffect {
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
//If no controller, exit out here and do not vote. //If no controller, exit out here and do not vote.
if (controller == null) return false; if (controller == null) {
return false;
}
this.vote("strength", "numbers", controller, game, source); this.vote("strength", "numbers", controller, game, source);
@ -70,8 +74,9 @@ class LieutenantsOfTheGuardDilemmaEffect extends CouncilsDilemmaVoteEffect {
//Strength Votes //Strength Votes
//If strength received zero votes or the permanent is no longer on the battlefield, do not attempt to put P1P1 counters on it. //If strength received zero votes or the permanent is no longer on the battlefield, do not attempt to put P1P1 counters on it.
if (voteOneCount > 0 && permanent != null) if (voteOneCount > 0 && permanent != null) {
permanent.addCounters(CounterType.P1P1.createInstance(voteOneCount), source, game); permanent.addCounters(CounterType.P1P1.createInstance(voteOneCount), source, game);
}
//Numbers Votes //Numbers Votes
if (voteTwoCount > 0) { if (voteTwoCount > 0) {

View file

@ -1,4 +1,3 @@
package org.mage.test.cards.rules; package org.mage.test.cards.rules;
import mage.constants.PhaseStep; import mage.constants.PhaseStep;
@ -10,14 +9,14 @@ import org.mage.test.serverside.base.CardTestMultiPlayerBase;
* *
* @author LevelX2 * @author LevelX2
*/ */
public class WorldEnchantmentsRuleTest extends CardTestMultiPlayerBase { public class WorldEnchantmentsRuleTest extends CardTestMultiPlayerBase {
/** /**
* 704.5m If two or more permanents have the supertype world, all except the one that has had * 704.5m If two or more permanents have the supertype world, all except the
* the world supertype for the shortest amount of time are put into their owners' graveyards. * one that has had the world supertype for the shortest amount of time are
* In the event of a tie for the shortest amount of time, all are put into their owners' graveyards. * put into their owners' graveyards. In the event of a tie for the shortest
* This is called the world rule. * amount of time, all are put into their owners' graveyards. This is called
* the world rule.
* *
*/ */
@Test @Test
@ -64,4 +63,83 @@ public class WorldEnchantmentsRuleTest extends CardTestMultiPlayerBase {
assertPermanentCount(playerA, "Nether Void", 1); assertPermanentCount(playerA, "Nether Void", 1);
assertPermanentCount(playerC, "Nether Void", 1); assertPermanentCount(playerC, "Nether Void", 1);
} }
// 704.5 In the event of a tie for the shortest amount of time, all are put into their owners graveyards. This is called the world rule.
// In this example the execution order of the leaves the battlefield triggers of the two Oblivion Rings decide, which World Enchnatment may stay
// Player order: A -> D -> C -> B
@Test
public void TestTwoWorldEnchantmentsFromTriggers() {
setStrictChooseMode(true);
// When Oblivion Ring enters the battlefield, exile another target nonland permanent.
// When Oblivion Ring leaves the battlefield, return the exiled card to the battlefield under its owner's control.
addCard(Zone.HAND, playerA, "Oblivion Ring", 1);
// All creatures have haste.
addCard(Zone.HAND, playerA, "Concordant Crossroads", 1);
addCard(Zone.BATTLEFIELD, playerA, "Forest", 3);
addCard(Zone.BATTLEFIELD, playerA, "Plains", 1);
// When Oblivion Ring enters the battlefield, exile another target nonland permanent.
// When Oblivion Ring leaves the battlefield, return the exiled card to the battlefield under its owner's control.
addCard(Zone.HAND, playerD, "Oblivion Ring", 1); // Enchantment {2}{W}
// Destroy all white permanents.
addCard(Zone.HAND, playerD, "Anarchy", 1); // Sorcery {2}{R}{R}
// All creatures have haste.
addCard(Zone.BATTLEFIELD, playerD, "Concordant Crossroads", 1); // World Enchantment {G}
addCard(Zone.BATTLEFIELD, playerD, "Plains", 1);
addCard(Zone.BATTLEFIELD, playerD, "Mountain", 6);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Oblivion Ring");
addTarget(playerA, "Concordant Crossroads");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Concordant Crossroads");
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerD, "Oblivion Ring");
addTarget(playerD, "Concordant Crossroads");
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerD, "Anarchy"); // Both World Enchantments return at the same time and go to grave
setStopAt(2, PhaseStep.BEGIN_COMBAT);
execute();
assertAllCommandsUsed();
assertPermanentCount(playerD, "Concordant Crossroads", 0);
assertPermanentCount(playerA, "Concordant Crossroads", 1);
assertGraveyardCount(playerA, "Oblivion Ring", 1);
assertGraveyardCount(playerA, "Concordant Crossroads", 0);
assertGraveyardCount(playerD, "Oblivion Ring", 1);
assertGraveyardCount(playerD, "Concordant Crossroads", 1);
assertGraveyardCount(playerD, "Anarchy", 1);
}
@Test
public void TestTwoWorldEnchantmentsWithSameOrder() {
setStrictChooseMode(true);
// When Charmed Griffin enters the battlefield, each other player may put an artifact or enchantment card onto the battlefield from their hand.
addCard(Zone.HAND, playerA, "Charmed Griffin", 1);
addCard(Zone.BATTLEFIELD, playerA, "Plains", 4);
// All creatures have haste.
addCard(Zone.HAND, playerD, "Concordant Crossroads", 1);
addCard(Zone.HAND, playerB, "Concordant Crossroads", 1);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Charmed Griffin");
setChoice(playerD, "Yes"); // Put an artifact or enchantment card from your hand onto the battlefield?
setChoice(playerD, "Concordant Crossroads");
setChoice(playerB, "Yes"); // Put an artifact or enchantment card from your hand onto the battlefield?
setChoice(playerB, "Concordant Crossroads");
concede(1, PhaseStep.PRECOMBAT_MAIN, playerC); // World Enchantments come into range
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertAllCommandsUsed();
assertPermanentCount(playerA, "Charmed Griffin", 1);
assertPermanentCount(playerD, "Concordant Crossroads", 0);
assertPermanentCount(playerB, "Concordant Crossroads", 0);
assertGraveyardCount(playerB, "Concordant Crossroads", 1);
assertGraveyardCount(playerD, "Concordant Crossroads", 1);
}
} }

View file

@ -1,5 +1,6 @@
package mage.abilities.effects; package mage.abilities.effects;
import java.util.UUID;
import mage.MageObject; import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.SpellAbility; import mage.abilities.SpellAbility;
@ -17,8 +18,6 @@ import mage.players.Player;
import mage.target.Target; import mage.target.Target;
import mage.target.common.TargetCardInGraveyard; import mage.target.common.TargetCardInGraveyard;
import java.util.UUID;
/** /**
* Cards with the Aura subtype don't change the zone they are in, if there is no * Cards with the Aura subtype don't change the zone they are in, if there is no
* valid target on the battlefield. Also, when entering the battlefield and it * valid target on the battlefield. Also, when entering the battlefield and it
@ -163,7 +162,7 @@ public class AuraReplacementEffect extends ReplacementEffectImpl {
PermanentCard permanent = new PermanentCard(card, (controllingPlayer == null ? card.getOwnerId() : controllingPlayer.getId()), game); PermanentCard permanent = new PermanentCard(card, (controllingPlayer == null ? card.getOwnerId() : controllingPlayer.getId()), game);
ZoneChangeEvent zoneChangeEvent = new ZoneChangeEvent(permanent, controllerId, fromZone, Zone.BATTLEFIELD); ZoneChangeEvent zoneChangeEvent = new ZoneChangeEvent(permanent, controllerId, fromZone, Zone.BATTLEFIELD);
permanent.updateZoneChangeCounter(game, zoneChangeEvent); permanent.updateZoneChangeCounter(game, zoneChangeEvent);
game.getBattlefield().addPermanent(permanent); game.addPermanent(permanent, 0);
card.setZone(Zone.BATTLEFIELD, game); card.setZone(Zone.BATTLEFIELD, game);
if (permanent.entersBattlefield(event.getSourceId(), game, fromZone, true)) { if (permanent.entersBattlefield(event.getSourceId(), game, fromZone, true)) {
if (targetCard != null) { if (targetCard != null) {

View file

@ -373,7 +373,16 @@ public interface Game extends MageItem, Serializable {
void addCommander(Commander commander); void addCommander(Commander commander);
void addPermanent(Permanent permanent); /**
* Adds a permanent to the battlefield
*
* @param permanent
* @param createOrder upcounting number from state about the create order of
* all permanents. Can equal for multiple permanents, if
* they go to battlefield at the same time. If the value
* is set to 0, a next number will be set automatically.
*/
void addPermanent(Permanent permanent, int createOrder);
// priority method // priority method
void sendPlayerAction(PlayerAction playerAction, UUID playerId, Object data); void sendPlayerAction(PlayerAction playerAction, UUID playerId, Object data);

View file

@ -187,6 +187,7 @@ public abstract class GameImpl implements Game, Serializable {
this.startLife = game.startLife; this.startLife = game.startLife;
this.enterWithCounters.putAll(game.enterWithCounters); this.enterWithCounters.putAll(game.enterWithCounters);
this.startingSize = game.startingSize; this.startingSize = game.startingSize;
this.gameStopped = game.gameStopped;
} }
@Override @Override
@ -1419,7 +1420,7 @@ public abstract class GameImpl implements Game, Serializable {
if (spell != null) { if (spell != null) {
if (spell.getCommandedBy() != null) { if (spell.getCommandedBy() != null) {
UUID commandedBy = spell.getCommandedBy(); UUID commandedBy = spell.getCommandedBy();
UUID spellControllerId = null; UUID spellControllerId;
if (commandedBy.equals(spell.getControllerId())) { if (commandedBy.equals(spell.getControllerId())) {
spellControllerId = spell.getSpellAbility().getFirstTarget(); // i.e. resolved spell is Word of Command spellControllerId = spell.getSpellAbility().getFirstTarget(); // i.e. resolved spell is Word of Command
} else { } else {
@ -1605,9 +1606,12 @@ public abstract class GameImpl implements Game, Serializable {
} }
@Override @Override
public void addPermanent(Permanent permanent) { public void addPermanent(Permanent permanent, int createOrder) {
if (createOrder == 0) {
createOrder = getState().getNextPermanentOrderNumber();
}
permanent.setCreateOrder(createOrder);
getBattlefield().addPermanent(permanent); getBattlefield().addPermanent(permanent);
permanent.setCreateOrder(getState().getNextPermanentOrderNumber());
} }
@Override @Override
@ -2254,23 +2258,30 @@ public abstract class GameImpl implements Game, Serializable {
} }
} }
} }
//704.5m - World Enchantments //704.5k - World Enchantments
if (worldEnchantment.size() > 1) { if (worldEnchantment.size() > 1) {
int newestCard = -1; int newestCard = -1;
Set<UUID> controllerIdOfNewest = new HashSet<>();
Permanent newestPermanent = null; Permanent newestPermanent = null;
for (Permanent permanent : worldEnchantment) { for (Permanent permanent : worldEnchantment) {
if (newestCard == -1) { if (newestCard == -1) {
newestCard = permanent.getCreateOrder(); newestCard = permanent.getCreateOrder();
newestPermanent = permanent; newestPermanent = permanent;
controllerIdOfNewest.clear();
controllerIdOfNewest.add(permanent.getControllerId());
} else if (newestCard < permanent.getCreateOrder()) { } else if (newestCard < permanent.getCreateOrder()) {
newestCard = permanent.getCreateOrder(); newestCard = permanent.getCreateOrder();
newestPermanent = permanent; newestPermanent = permanent;
controllerIdOfNewest.clear();
controllerIdOfNewest.add(permanent.getControllerId());
} else if (newestCard == permanent.getCreateOrder()) { } else if (newestCard == permanent.getCreateOrder()) {
// In the event of a tie for the shortest amount of time, all are put into their owners graveyards. This is called the world rule.
newestPermanent = null; newestPermanent = null;
controllerIdOfNewest.add(permanent.getControllerId());
} }
} }
for (UUID controllerId : controllerIdOfNewest) {
PlayerList newestPermanentControllerRange = state.getPlayersInRange(newestPermanent.getControllerId(), this); PlayerList newestPermanentControllerRange = state.getPlayersInRange(controllerId, this);
// 801.12 The "world rule" applies to a permanent only if other world permanents are within its controller's range of influence. // 801.12 The "world rule" applies to a permanent only if other world permanents are within its controller's range of influence.
for (Permanent permanent : worldEnchantment) { for (Permanent permanent : worldEnchantment) {
@ -2281,6 +2292,7 @@ public abstract class GameImpl implements Game, Serializable {
} }
} }
} }
}
//TODO: implement the rest //TODO: implement the rest
return somethingHappened; return somethingHappened;
@ -2788,7 +2800,7 @@ public abstract class GameImpl implements Game, Serializable {
} }
if (amountToPrevent != Integer.MAX_VALUE) { if (amountToPrevent != Integer.MAX_VALUE) {
// set remaining amount // set remaining amount
result.setRemainingAmount(amountToPrevent -= result.getPreventedDamage()); result.setRemainingAmount(amountToPrevent - result.getPreventedDamage());
} }
MageObject damageSource = game.getObject(damageEvent.getSourceId()); MageObject damageSource = game.getObject(damageEvent.getSourceId());
MageObject preventionSource = game.getObject(source.getSourceId()); MageObject preventionSource = game.getObject(source.getSourceId());
@ -3058,7 +3070,7 @@ public abstract class GameImpl implements Game, Serializable {
PermanentCard newPermanent = new PermanentCard(permanentCard.getCard(), ownerId, this); PermanentCard newPermanent = new PermanentCard(permanentCard.getCard(), ownerId, this);
getPermanentsEntering().put(newPermanent.getId(), newPermanent); getPermanentsEntering().put(newPermanent.getId(), newPermanent);
newPermanent.entersBattlefield(newPermanent.getId(), this, Zone.OUTSIDE, false); newPermanent.entersBattlefield(newPermanent.getId(), this, Zone.OUTSIDE, false);
getBattlefield().addPermanent(newPermanent); addPermanent(newPermanent, getState().getNextPermanentOrderNumber());
getPermanentsEntering().remove(newPermanent.getId()); getPermanentsEntering().remove(newPermanent.getId());
newPermanent.removeSummoningSickness(); newPermanent.removeSummoningSickness();
if (permanentCard.isTapped()) { if (permanentCard.isTapped()) {

View file

@ -1,5 +1,6 @@
package mage.game; package mage.game;
import java.util.*;
import mage.cards.Card; import mage.cards.Card;
import mage.cards.Cards; import mage.cards.Cards;
import mage.cards.CardsImpl; import mage.cards.CardsImpl;
@ -18,8 +19,6 @@ import mage.game.stack.Spell;
import mage.players.Player; import mage.players.Player;
import mage.target.TargetCard; import mage.target.TargetCard;
import java.util.*;
/** /**
* Created by samuelsandeen on 9/6/16. * Created by samuelsandeen on 9/6/16.
*/ */
@ -27,7 +26,7 @@ public final class ZonesHandler {
public static boolean cast(ZoneChangeInfo info, Game game) { public static boolean cast(ZoneChangeInfo info, Game game) {
if (maybeRemoveFromSourceZone(info, game)) { if (maybeRemoveFromSourceZone(info, game)) {
placeInDestinationZone(info, game); placeInDestinationZone(info, game, 0);
// create a group zone change event if a card is moved to stack for casting (it's always only one card, but some effects check for group events (one or more xxx)) // create a group zone change event if a card is moved to stack for casting (it's always only one card, but some effects check for group events (one or more xxx))
Set<Card> cards = new HashSet<>(); Set<Card> cards = new HashSet<>();
Set<PermanentToken> tokens = new HashSet<>(); Set<PermanentToken> tokens = new HashSet<>();
@ -53,7 +52,7 @@ public final class ZonesHandler {
public static List<ZoneChangeInfo> moveCards(List<ZoneChangeInfo> zoneChangeInfos, Game game) { public static List<ZoneChangeInfo> moveCards(List<ZoneChangeInfo> zoneChangeInfos, Game game) {
// Handle Unmelded Meld Cards // Handle Unmelded Meld Cards
for (ListIterator<ZoneChangeInfo> itr = zoneChangeInfos.listIterator(); itr.hasNext(); ) { for (ListIterator<ZoneChangeInfo> itr = zoneChangeInfos.listIterator(); itr.hasNext();) {
ZoneChangeInfo info = itr.next(); ZoneChangeInfo info = itr.next();
MeldCard card = game.getMeldCard(info.event.getTargetId()); MeldCard card = game.getMeldCard(info.event.getTargetId());
// Copies should be handled as normal cards. // Copies should be handled as normal cards.
@ -67,8 +66,13 @@ public final class ZonesHandler {
} }
} }
zoneChangeInfos.removeIf(zoneChangeInfo -> !maybeRemoveFromSourceZone(zoneChangeInfo, game)); zoneChangeInfos.removeIf(zoneChangeInfo -> !maybeRemoveFromSourceZone(zoneChangeInfo, game));
int createOrder = 0;
for (ZoneChangeInfo zoneChangeInfo : zoneChangeInfos) { for (ZoneChangeInfo zoneChangeInfo : zoneChangeInfos) {
placeInDestinationZone(zoneChangeInfo, game); if (createOrder == 0 && Zone.BATTLEFIELD.equals(zoneChangeInfo.event.getToZone())) {
// All permanents go to battlefield at the same time (=create order)
createOrder = game.getState().getNextPermanentOrderNumber();
}
placeInDestinationZone(zoneChangeInfo, game, createOrder);
if (game.getPhase() != null) { // moving cards to zones before game started does not need events if (game.getPhase() != null) { // moving cards to zones before game started does not need events
game.addSimultaneousEvent(zoneChangeInfo.event); game.addSimultaneousEvent(zoneChangeInfo.event);
} }
@ -76,14 +80,14 @@ public final class ZonesHandler {
return zoneChangeInfos; return zoneChangeInfos;
} }
private static void placeInDestinationZone(ZoneChangeInfo info, Game game) { private static void placeInDestinationZone(ZoneChangeInfo info, Game game, int createOrder) {
// Handle unmelded cards // Handle unmelded cards
if (info instanceof ZoneChangeInfo.Unmelded) { if (info instanceof ZoneChangeInfo.Unmelded) {
ZoneChangeInfo.Unmelded unmelded = (ZoneChangeInfo.Unmelded) info; ZoneChangeInfo.Unmelded unmelded = (ZoneChangeInfo.Unmelded) info;
Zone toZone = null; Zone toZone = null;
for (ZoneChangeInfo subInfo : unmelded.subInfo) { for (ZoneChangeInfo subInfo : unmelded.subInfo) {
toZone = subInfo.event.getToZone(); toZone = subInfo.event.getToZone();
placeInDestinationZone(subInfo, game); placeInDestinationZone(subInfo, game, createOrder);
} }
// We arbitrarily prefer the bottom half card. This should never be relevant. // We arbitrarily prefer the bottom half card. This should never be relevant.
if (toZone != null) { if (toZone != null) {
@ -161,7 +165,7 @@ public final class ZonesHandler {
break; break;
case BATTLEFIELD: case BATTLEFIELD:
Permanent permanent = event.getTarget(); Permanent permanent = event.getTarget();
game.addPermanent(permanent); game.addPermanent(permanent, createOrder);
game.getPermanentsEntering().remove(permanent.getId()); game.getPermanentsEntering().remove(permanent.getId());
break; break;
default: default:
@ -197,7 +201,7 @@ public final class ZonesHandler {
if (info instanceof ZoneChangeInfo.Unmelded) { if (info instanceof ZoneChangeInfo.Unmelded) {
ZoneChangeInfo.Unmelded unmelded = (ZoneChangeInfo.Unmelded) info; ZoneChangeInfo.Unmelded unmelded = (ZoneChangeInfo.Unmelded) info;
MeldCard meld = game.getMeldCard(info.event.getTargetId()); MeldCard meld = game.getMeldCard(info.event.getTargetId());
for (Iterator<ZoneChangeInfo> itr = unmelded.subInfo.iterator(); itr.hasNext(); ) { for (Iterator<ZoneChangeInfo> itr = unmelded.subInfo.iterator(); itr.hasNext();) {
ZoneChangeInfo subInfo = itr.next(); ZoneChangeInfo subInfo = itr.next();
if (!maybeRemoveFromSourceZone(subInfo, game)) { if (!maybeRemoveFromSourceZone(subInfo, game)) {
itr.remove(); itr.remove();

View file

@ -1,5 +1,9 @@
package mage.game.permanent.token; package mage.game.permanent.token;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.UUID;
import mage.MageObject; import mage.MageObject;
import mage.MageObjectImpl; import mage.MageObjectImpl;
import mage.abilities.Ability; import mage.abilities.Ability;
@ -14,11 +18,6 @@ import mage.game.permanent.PermanentToken;
import mage.players.Player; import mage.players.Player;
import mage.util.RandomUtil; import mage.util.RandomUtil;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.UUID;
public abstract class TokenImpl extends MageObjectImpl implements Token { public abstract class TokenImpl extends MageObjectImpl implements Token {
protected String description; protected String description;
@ -202,8 +201,9 @@ public abstract class TokenImpl extends MageObjectImpl implements Token {
} }
} }
game.setScopeRelevant(false); game.setScopeRelevant(false);
int createOrder = game.getState().getNextPermanentOrderNumber();
for (Permanent permanent : permanentsEntered) { for (Permanent permanent : permanentsEntered) {
game.addPermanent(permanent); game.addPermanent(permanent, createOrder);
permanent.setZone(Zone.BATTLEFIELD, game); permanent.setZone(Zone.BATTLEFIELD, game);
game.getPermanentsEntering().remove(permanent.getId()); game.getPermanentsEntering().remove(permanent.getId());
@ -242,8 +242,8 @@ public abstract class TokenImpl extends MageObjectImpl implements Token {
} }
/** /**
* Set token index to search in card-pictures-tok.txt (if set have multiple tokens with same name) * Set token index to search in card-pictures-tok.txt (if set have multiple
* Default is 1 * tokens with same name) Default is 1
*/ */
@Override @Override
public void setTokenType(int tokenType) { public void setTokenType(int tokenType) {