diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/cmr/HellkiteCourserTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/cmr/HellkiteCourserTest.java new file mode 100644 index 00000000000..6467b82b1f7 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/cmr/HellkiteCourserTest.java @@ -0,0 +1,50 @@ +package org.mage.test.cards.single.cmr; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestCommanderDuelBase; + +/** + * @author JayDi85 + */ + +public class HellkiteCourserTest extends CardTestCommanderDuelBase { + + @Test + public void test_ETB() { + // https://github.com/magefree/mage/issues/7198 + + // When Hellkite Courser enters the battlefield, you may put a commander you own from the command + // zone onto the battlefield. It gains haste. Return it to the command zone at the + // beginning of the next end step. + addCard(Zone.HAND, playerA, "Hellkite Courser", 1); // {4}{R}{R} + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 6); + // + addCard(Zone.COMMAND, playerA, "Balduvian Bears", 1); // {1}{G} + + checkCommandCardCount("before", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Balduvian Bears", 1); + + // cast card and move commander to battle + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Hellkite Courser"); + setChoice(playerA, "Yes"); // put commander to battlefield + setChoice(playerA, "Balduvian Bears"); + waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN); + checkPermanentCount("after etb", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Balduvian Bears", 1); + + // try to attack (test haste) + attack(1, playerA, "Balduvian Bears", playerB); + + // keep until end + checkPermanentCount("keep after battle", 1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Balduvian Bears", 1); + + // return to command zone + checkPermanentCount("return on end", 2, PhaseStep.PRECOMBAT_MAIN, playerA, "Balduvian Bears", 0); + checkCommandCardCount("return on end", 2, PhaseStep.PRECOMBAT_MAIN, playerA, "Balduvian Bears", 1); + + setStrictChooseMode(true); + setStopAt(2, PhaseStep.END_TURN); + execute(); + assertAllCommandsUsed(); + } +} diff --git a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java index ffc0b2541b9..9f448363f68 100644 --- a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java +++ b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java @@ -2055,7 +2055,7 @@ public class TestPlayer implements Player { Set possibleCards = target.possibleTargets(sourceId, abilityControllerId, game); CheckTargetsList: for (UUID targetId : possibleCards) { - MageObject targetObject = game.getObject(targetId); + MageObject targetObject = game.getCard(targetId); if (hasObjectTargetNameOrAlias(targetObject, possibleChoice)) { if (target.canTarget(targetObject.getId(), game)) { // only unique targets diff --git a/Mage/src/main/java/mage/filter/FilterCard.java b/Mage/src/main/java/mage/filter/FilterCard.java index f5560b493fc..cd1a0bb2cfe 100644 --- a/Mage/src/main/java/mage/filter/FilterCard.java +++ b/Mage/src/main/java/mage/filter/FilterCard.java @@ -12,6 +12,8 @@ import java.util.UUID; import java.util.stream.Collectors; /** + * Works with cards only. For objects like commanders you must override your canTarget method. + * * @author BetaSteward_at_googlemail.com * @author North */ diff --git a/Mage/src/main/java/mage/target/TargetCard.java b/Mage/src/main/java/mage/target/TargetCard.java index 464b14ff221..8e52747a7e5 100644 --- a/Mage/src/main/java/mage/target/TargetCard.java +++ b/Mage/src/main/java/mage/target/TargetCard.java @@ -10,9 +10,7 @@ import mage.game.Game; import mage.game.events.GameEvent; import mage.players.Player; -import java.util.HashSet; -import java.util.Set; -import java.util.UUID; +import java.util.*; import java.util.stream.Collectors; /** @@ -158,7 +156,7 @@ public class TargetCard extends TargetObject { case LIBRARY: for (Card card : player.getLibrary().getUniqueCards(game)) { if (sourceId == null || isNotTarget() || !game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.TARGET, card.getId(), sourceId, sourceControllerId))) { - if (filter.match(card, game)) { + if (filter.match(card, sourceId, sourceControllerId, game)) { possibleTargets.add(card.getId()); } } @@ -167,12 +165,25 @@ public class TargetCard extends TargetObject { case EXILED: for (Card card : game.getExile().getPermanentExile().getCards(game)) { if (sourceId == null || isNotTarget() || !game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.TARGET, card.getId(), sourceId, sourceControllerId))) { - if (filter.match(card, player.getId(), game)) { + if (filter.match(card, sourceId, sourceControllerId, game)) { possibleTargets.add(card.getId()); } } } break; + case COMMAND: + List possibleCards = game.getCommandersIds(player).stream() + .map(game::getCard) + .filter(Objects::nonNull) + .filter(card -> game.getState().getZone(card.getId()).equals(Zone.COMMAND)) + .filter(card -> filter.match(card, sourceId, sourceControllerId, game)) + .collect(Collectors.toList()); + for (Card card : possibleCards) { + if (sourceId == null || isNotTarget() || !game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.TARGET, card.getId(), sourceId, sourceControllerId))) { + possibleTargets.add(card.getId()); + } + } + break; } } } @@ -192,7 +203,11 @@ public class TargetCard extends TargetObject { @Override public boolean canTarget(UUID id, Game game) { - return super.canTarget(id, game); + // copy-pasted from super but with card instead object + Card card = game.getCard(id); + return card != null + && zone != null && zone.match(game.getState().getZone(id)) + && getFilter() != null && getFilter().match(card, game); } @Override diff --git a/Mage/src/main/java/mage/target/TargetObject.java b/Mage/src/main/java/mage/target/TargetObject.java index e5efde8b8b9..c13790a0157 100644 --- a/Mage/src/main/java/mage/target/TargetObject.java +++ b/Mage/src/main/java/mage/target/TargetObject.java @@ -47,6 +47,14 @@ public abstract class TargetObject extends TargetImpl { return sb.toString().trim(); } + /** + * Warning, don't use with non card objects here like commanders/emblems/etc. If you want it then + * override canTarget in your own target. + * + * @param id + * @param game + * @return + */ @Override public boolean canTarget(UUID id, Game game) { MageObject object = game.getObject(id);