diff --git a/Mage.Sets/src/mage/cards/k/KarnLiberated.java b/Mage.Sets/src/mage/cards/k/KarnLiberated.java index 007c859d0a0..38a03f45ba1 100644 --- a/Mage.Sets/src/mage/cards/k/KarnLiberated.java +++ b/Mage.Sets/src/mage/cards/k/KarnLiberated.java @@ -11,7 +11,6 @@ import mage.constants.*; import mage.game.ExileZone; import mage.game.Game; import mage.game.GameImpl; -import mage.game.command.Commander; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.game.permanent.PermanentImpl; @@ -79,14 +78,14 @@ class KarnLiberatedEffect extends OneShotEffect { if (sourceObject == null) { return false; } - List exiledCards = new ArrayList<>(); + List keepExiled = new ArrayList<>(); for (ExileZone zone : game.getExile().getExileZones()) { exileId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter()); if (zone.getId().equals(exileId)) { for (Card card : zone.getCards(game)) { if (!card.hasSubtype(SubType.AURA, game) && card.isPermanent(game)) { - exiledCards.add(card); + keepExiled.add(card); } } } @@ -106,32 +105,30 @@ class KarnLiberatedEffect extends OneShotEffect { // TODO: miss copied cards? for (Player player : game.getPlayers().values()) { + // TODO: why it keep old players with old data (need reset and lose call for it???) if (player.canRespond()) { // only players alive are in the restarted game - player.getGraveyard().clear(); - player.getHand().clear(); - player.getLibrary().clear(); - for (Card card : game.getCards()) { - if (card.isOwnedBy(player.getId()) && !card.isCopy() // no copies - && !player.getSideboard().contains(card.getId()) - && !exiledCards.contains(card)) { - if (game.getCommandersIds(player, CommanderCardType.ANY, false).contains(card.getId())) { - game.addCommander(new Commander(card)); // TODO: check restart and init - // no needs in initCommander call -- it's used on game startup (init) - game.setZone(card.getId(), Zone.COMMAND); - } else { - player.getLibrary().putOnTop(card, game); - } - } - } - ((GameImpl) game).initPlayerDefaultWatchers(player.getId()); + // reset all player cards + // P.S. Time limits store in match player, so it will be kept for restarted game player.init(game); + + // simulate GameState::addPlayer + player.useDeck(player.getMatchPlayer().getDeck(), game); + ((GameImpl) game).initPlayerDefaultWatchers(player.getId()); + + // warning, xmage uses a deck's sideboard for commander init + // if you add commander in cheat/test mode then it will be a normal card after restart (it's not a bug) + // must use real commander decks for testing } } - for (Card card : exiledCards) { + + // prepare exiled cards for moving to battlefield on new game + for (Card card : keepExiled) { game.getState().setZone(card.getId(), Zone.EXILED); game.getExile().add(exileId, sourceObject.getIdName(), card); } game.addDelayedTriggeredAbility(new KarnLiberatedDelayedTriggeredAbility(exileId), source); + + // start new game game.setStartingPlayerId(source.getControllerId()); game.start(null); return true; diff --git a/Mage.Tests/src/test/java/org/mage/test/commander/duel/CastBRGCommanderTest.java b/Mage.Tests/src/test/java/org/mage/test/commander/duel/CastBRGCommanderTest.java index 24d653bc899..444a04840b1 100644 --- a/Mage.Tests/src/test/java/org/mage/test/commander/duel/CastBRGCommanderTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/commander/duel/CastBRGCommanderTest.java @@ -1,5 +1,6 @@ package org.mage.test.commander.duel; +import mage.constants.CommanderCardType; import mage.constants.PhaseStep; import mage.constants.Zone; import mage.game.Game; @@ -137,6 +138,9 @@ public class CastBRGCommanderTest extends CardTestCommanderDuelBase { assertCommandZoneCount(playerB, "Daxos of Meletis", 0); assertPermanentCount(playerA, "Daxos of Meletis", 1); // Karn brings back the cards under the control of Karn's controller + Assert.assertEquals("B commander must be on battlefield", 0, currentGame.getCommanderCardsFromCommandZone(playerB, CommanderCardType.COMMANDER_OR_OATHBREAKER).size()); + Assert.assertEquals("B commander must be on battlefield", 1, currentGame.getCommanderCardsFromAnyZones(playerB, CommanderCardType.COMMANDER_OR_OATHBREAKER, Zone.BATTLEFIELD).size()); + CommanderInfoWatcher watcher = currentGame.getState().getWatcher(CommanderInfoWatcher.class, playerB.getCommandersIds().iterator().next()); Assert.assertEquals("Watcher is reset to 0 commander damage", 0, watcher.getDamageToPlayer().size()); }