diff --git a/Mage.Sets/src/mage/cards/g/GenesisUltimatum.java b/Mage.Sets/src/mage/cards/g/GenesisUltimatum.java index 96ca603c23..129c44bf2a 100644 --- a/Mage.Sets/src/mage/cards/g/GenesisUltimatum.java +++ b/Mage.Sets/src/mage/cards/g/GenesisUltimatum.java @@ -1,6 +1,5 @@ package mage.cards.g; -import mage.MageItem; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.ExileSpellEffect; @@ -18,7 +17,6 @@ import mage.players.Player; import mage.target.TargetCard; import mage.target.common.TargetCardInLibrary; -import java.util.Objects; import java.util.UUID; /** @@ -49,7 +47,7 @@ class GenesisUltimatumEffect extends OneShotEffect { private static final FilterCard filter = new FilterPermanentCard("any number of permanent cards"); GenesisUltimatumEffect() { - super(Outcome.Benefit); + super(Outcome.PutCardInPlay); staticText = "Look at the top five cards of your library. Put any number of permanent cards " + "from among them onto the battlefield and the rest into your hand"; } @@ -72,14 +70,13 @@ class GenesisUltimatumEffect extends OneShotEffect { Cards toHand = new CardsImpl(player.getLibrary().getTopCards(game, 5)); player.lookAtCards(source, null, toHand, game); TargetCard targetCard = new TargetCardInLibrary(0, 5, filter); + targetCard.withChooseHint("put to battlefield"); player.choose(outcome, toHand, targetCard, game); Cards toBattlefield = new CardsImpl(targetCard.getTargets()); if (player.moveCards(toBattlefield, Zone.BATTLEFIELD, source, game)) { toBattlefield .stream() - .map(game::getPermanent) - .filter(Objects::nonNull) // to prevent exception https://github.com/magefree/mage/issues/7220 - .map(MageItem::getId) + .filter(id -> Zone.BATTLEFIELD.equals(game.getState().getZone(id))) .forEach(toHand::remove); } player.moveCards(toHand, Zone.HAND, source, game); diff --git a/Mage.Sets/src/mage/cards/s/SelectiveAdaptation.java b/Mage.Sets/src/mage/cards/s/SelectiveAdaptation.java index 1ccd946e15..9a3a3aedb2 100644 --- a/Mage.Sets/src/mage/cards/s/SelectiveAdaptation.java +++ b/Mage.Sets/src/mage/cards/s/SelectiveAdaptation.java @@ -61,7 +61,7 @@ class SelectiveAdaptationEffect extends OneShotEffect { private final String abilityName; private final FilterCard filter; - private AbilitySelector(Class abilityClass, String abilityName) { + AbilitySelector(Class abilityClass, String abilityName) { this.abilityClass = abilityClass; this.abilityName = abilityName; this.filter = new FilterCard("card with " + abilityName); @@ -121,7 +121,7 @@ class SelectiveAdaptationEffect extends OneShotEffect { Card toBattlefield = game.getCard(target.getFirstTarget()); if (toBattlefield != null && player.moveCards(toBattlefield, Zone.BATTLEFIELD, source, game) - && game.getPermanent(toBattlefield.getId()) != null) { + && Zone.BATTLEFIELD.equals(game.getState().getZone(toBattlefield.getId()))) { toHand.remove(toBattlefield); } } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/iko/BlitzLeechTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/iko/BlitzLeechTest.java deleted file mode 100644 index de2719da98..0000000000 --- a/Mage.Tests/src/test/java/org/mage/test/cards/single/iko/BlitzLeechTest.java +++ /dev/null @@ -1,4 +0,0 @@ -package org.mage.test.cards.single.iko; - -public class BlitzLeechTest { -} diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/iko/GenesisUltimatumTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/iko/GenesisUltimatumTest.java new file mode 100644 index 0000000000..c780e34c0b --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/iko/GenesisUltimatumTest.java @@ -0,0 +1,47 @@ +package org.mage.test.cards.single.iko; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * @author JayDi85 + */ + +public class GenesisUltimatumTest extends CardTestPlayerBase { + + @Test + public void test_Playable() { + removeAllCardsFromLibrary(playerA); + removeAllCardsFromHand(playerA); + + // Look at the top five cards of your library. Put any number of permanent cards from among them onto + // the battlefield and the rest into your hand. Exile Genesis Ultimatum. + addCard(Zone.HAND, playerA, "Genesis Ultimatum"); // {G}{G}{U}{U}{U}{R}{R} + addCard(Zone.BATTLEFIELD, playerA, "Forest", 2); + addCard(Zone.BATTLEFIELD, playerA, "Island", 3); + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2); + // + addCard(Zone.LIBRARY, playerA, "Grizzly Bears", 1); + addCard(Zone.LIBRARY, playerA, "Alpha Tyrranax", 1); + addCard(Zone.LIBRARY, playerA, "Kitesail Corsair", 1); + addCard(Zone.LIBRARY, playerA, "Riverglide Pathway", 1); // mdf card + + // cast spell and put 3 cards to battle + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Genesis Ultimatum"); + setChoice(playerA, "Grizzly Bears^Kitesail Corsair^Riverglide Pathway"); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.END_TURN); + execute(); + assertAllCommandsUsed(); + + assertExileCount(playerA, "Genesis Ultimatum", 1); + assertPermanentCount(playerA, "Grizzly Bears", 1); + assertPermanentCount(playerA, "Kitesail Corsair", 1); + assertPermanentCount(playerA, "Riverglide Pathway", 1); + assertHandCount(playerA, "Alpha Tyrranax", 1); + assertLibraryCount(playerA, 0); + } +} \ No newline at end of file diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/iko/OboshThePreypiercerTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/iko/OboshThePreypiercerTest.java index 38f45e2258..c80bb289e7 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/single/iko/OboshThePreypiercerTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/iko/OboshThePreypiercerTest.java @@ -1,8 +1,3 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ package org.mage.test.cards.single.iko; diff --git a/Mage/src/main/java/mage/game/Game.java b/Mage/src/main/java/mage/game/Game.java index 3a2adffe81..f7dd4aa8eb 100644 --- a/Mage/src/main/java/mage/game/Game.java +++ b/Mage/src/main/java/mage/game/Game.java @@ -90,6 +90,14 @@ public interface Game extends MageItem, Serializable { Spell getSpellOrLKIStack(UUID spellId); + /** + * Find permanent on the battlefield by id. If you works with cards and want to check it on battlefield then + * use game.getState().getZone() instead. Card's id and permanent's id can be different (example: mdf card + * puts half card to battlefield, not the main card). + * + * @param permanentId + * @return + */ Permanent getPermanent(UUID permanentId); Permanent getPermanentOrLKIBattlefield(UUID permanentId); diff --git a/Mage/src/main/java/mage/game/GameImpl.java b/Mage/src/main/java/mage/game/GameImpl.java index d48593c2e6..122b55f330 100644 --- a/Mage/src/main/java/mage/game/GameImpl.java +++ b/Mage/src/main/java/mage/game/GameImpl.java @@ -342,7 +342,6 @@ public abstract class GameImpl implements Game, Serializable { MageObject object; if (state.getBattlefield().containsPermanent(objectId)) { object = state.getBattlefield().getPermanent(objectId); - // state.setZone(objectId, Zone.BATTLEFIELD); // why is this neccessary? return object; } if (getPermanentsEntering().containsKey(objectId)) { @@ -350,7 +349,6 @@ public abstract class GameImpl implements Game, Serializable { } for (StackObject item : state.getStack()) { if (item.getId().equals(objectId)) { - // state.setZone(objectId, Zone.STACK); // why is this neccessary? return item; } if (item.getSourceId().equals(objectId) && item instanceof Spell) { diff --git a/Mage/src/main/java/mage/game/GameState.java b/Mage/src/main/java/mage/game/GameState.java index 606d4d2165..8a858e6045 100644 --- a/Mage/src/main/java/mage/game/GameState.java +++ b/Mage/src/main/java/mage/game/GameState.java @@ -167,8 +167,8 @@ public class GameState implements Serializable, Copyable { this.values.put(entry.getKey(), ((HashSet) entry.getValue()).clone()); } else if (entry.getValue() instanceof EnumSet) { this.values.put(entry.getKey(), ((EnumSet) entry.getValue()).clone()); - } else if (entry.getValue() instanceof HashMap){ - this.values.put(entry.getKey(), ((HashMap) entry.getValue()).clone()); + } else if (entry.getValue() instanceof HashMap) { + this.values.put(entry.getKey(), ((HashMap) entry.getValue()).clone()); } else { this.values.put(entry.getKey(), entry.getValue()); } @@ -696,9 +696,7 @@ public class GameState implements Serializable, Copyable { public Permanent getPermanent(UUID permanentId) { if (permanentId != null && battlefield.containsPermanent(permanentId)) { - Permanent permanent = battlefield.getPermanent(permanentId); - // setZone(permanent.getId(), Zone.BATTLEFIELD); // shouldn't this be set anyway? (LevelX2) - return permanent; + return battlefield.getPermanent(permanentId); } return null; } diff --git a/Mage/src/main/java/mage/game/permanent/Battlefield.java b/Mage/src/main/java/mage/game/permanent/Battlefield.java index d2e11c2c48..054dfcbd4f 100644 --- a/Mage/src/main/java/mage/game/permanent/Battlefield.java +++ b/Mage/src/main/java/mage/game/permanent/Battlefield.java @@ -1,15 +1,16 @@ package mage.game.permanent; -import java.io.Serializable; -import java.util.*; -import java.util.Map.Entry; -import java.util.stream.Collectors; import mage.abilities.keyword.PhasingAbility; import mage.constants.CardType; import mage.constants.RangeOfInfluence; import mage.filter.FilterPermanent; import mage.game.Game; +import java.io.Serializable; +import java.util.*; +import java.util.Map.Entry; +import java.util.stream.Collectors; + /** * @author BetaSteward_at_googlemail.com */ @@ -57,8 +58,8 @@ public class Battlefield implements Serializable { return (int) field.values() .stream() .filter(permanent -> permanent.isControlledBy(controllerId) - && filter.match(permanent, game) - && permanent.isPhasedIn()) + && filter.match(permanent, game) + && permanent.isPhasedIn()) .count(); } @@ -68,8 +69,8 @@ public class Battlefield implements Serializable { * influence of the specified player id and that match the supplied filter. * * @param filter - * @param sourceId - sourceId of the MageObject the calling effect/ability - * belongs to + * @param sourceId - sourceId of the MageObject the calling effect/ability + * belongs to * @param sourcePlayerId * @param game * @return count @@ -79,15 +80,15 @@ public class Battlefield implements Serializable { return (int) field.values() .stream() .filter(permanent -> filter.match(permanent, sourceId, sourcePlayerId, game) - && permanent.isPhasedIn()) + && permanent.isPhasedIn()) .count(); } else { List range = game.getState().getPlayersInRange(sourcePlayerId, game); return (int) field.values() .stream() .filter(permanent -> range.contains(permanent.getControllerId()) - && filter.match(permanent, sourceId, sourcePlayerId, game) - && permanent.isPhasedIn()).count(); + && filter.match(permanent, sourceId, sourcePlayerId, game) + && permanent.isPhasedIn()).count(); } } @@ -104,7 +105,7 @@ public class Battlefield implements Serializable { return field.values() .stream() .filter(permanent -> filter.match(permanent, game) - && permanent.isPhasedIn()).count() >= num; + && permanent.isPhasedIn()).count() >= num; } @@ -123,8 +124,8 @@ public class Battlefield implements Serializable { return field.values() .stream() .filter(permanent -> permanent.isControlledBy(controllerId) - && filter.match(permanent, game) - && permanent.isPhasedIn()) + && filter.match(permanent, game) + && permanent.isPhasedIn()) .count() >= num; } @@ -144,14 +145,14 @@ public class Battlefield implements Serializable { if (game.getRangeOfInfluence() == RangeOfInfluence.ALL) { return field.values().stream() .filter(permanent -> filter.match(permanent, null, sourcePlayerId, game) - && permanent.isPhasedIn()).count() >= num; + && permanent.isPhasedIn()).count() >= num; } else { List range = game.getState().getPlayersInRange(sourcePlayerId, game); return field.values().stream() .filter(permanent -> range.contains(permanent.getControllerId()) - && filter.match(permanent, null, sourcePlayerId, game) - && permanent.isPhasedIn()) + && filter.match(permanent, null, sourcePlayerId, game) + && permanent.isPhasedIn()) .count() >= num; } } @@ -168,6 +169,14 @@ public class Battlefield implements Serializable { field.remove(key); } + /** + * Find permanent on the battlefield by id. If you works with cards and want to check it on battlefield then + * use game.getState().getZone() instead. Card's id and permanent's id can be different (example: mdf card + * puts half card to battlefield, not the main card). + * + * @param key + * @return + */ public boolean containsPermanent(UUID key) { return field.containsKey(key); } @@ -211,7 +220,7 @@ public class Battlefield implements Serializable { return field.values() .stream() .filter(perm -> perm.isPhasedIn() - && perm.isControlledBy(controllerId)) + && perm.isControlledBy(controllerId)) .collect(Collectors.toList()); } @@ -300,7 +309,7 @@ public class Battlefield implements Serializable { return field.values() .stream() .filter(perm -> perm.isPhasedIn() && range.contains(perm.getControllerId()) - && filter.match(perm, sourceId, sourcePlayerId, game)).collect(Collectors.toList()); + && filter.match(perm, sourceId, sourcePlayerId, game)).collect(Collectors.toList()); } } @@ -321,7 +330,7 @@ public class Battlefield implements Serializable { return field.values() .stream() .filter(perm -> perm.isPhasedIn() - && range.contains(perm.getControllerId())) + && range.contains(perm.getControllerId())) .collect(Collectors.toList()); } @@ -331,8 +340,8 @@ public class Battlefield implements Serializable { return field.values() .stream() .filter(perm -> perm.hasAbility(PhasingAbility.getInstance(), game) - && perm.isPhasedIn() - && perm.isControlledBy(controllerId)) + && perm.isPhasedIn() + && perm.isControlledBy(controllerId)) .collect(Collectors.toList()); }