diff --git a/Mage.Sets/src/mage/cards/r/Radiate.java b/Mage.Sets/src/mage/cards/r/Radiate.java index 3898c50a951..5e14d66fcd7 100644 --- a/Mage.Sets/src/mage/cards/r/Radiate.java +++ b/Mage.Sets/src/mage/cards/r/Radiate.java @@ -122,7 +122,9 @@ class RadiateEffect extends CopySpellForEachItCouldTargetEffect { @Override protected List prepareCopiesWithTargets(StackObject stackObject, Player player, Ability source, Game game) { List predicates = new ArrayList<>(); - UUID targeted = ((Spell) stackObject) + + // spell must be with single target already (see filter for choose) + UUID ignoreTargeted = ((Spell) stackObject) .getSpellAbilities() .stream() .map(AbilityImpl::getTargets) @@ -132,24 +134,29 @@ class RadiateEffect extends CopySpellForEachItCouldTargetEffect { .filter(Objects::nonNull) .findAny() .orElse(null); + + // possible permanents game.getBattlefield() .getActivePermanents( StaticFilters.FILTER_PERMANENT, player.getId(), source, game ).stream() .filter(Objects::nonNull) - .filter(p -> !p.equals(game.getPermanent(targeted))) + .filter(p -> !p.equals(game.getPermanent(ignoreTargeted))) .filter(p -> stackObject.canTarget(game, p.getId())) .map(p -> new MageObjectReference(p, game)) .map(MageObjectReferencePredicate::new) .forEach(predicates::add); + + // possible players game.getState() .getPlayersInRange(source.getControllerId(), game) .stream() - .filter(uuid -> !uuid.equals(targeted)) + .filter(uuid -> !uuid.equals(ignoreTargeted)) .filter(uuid -> stackObject.canTarget(game, uuid)) .map(MageObjectReference::new) .map(MageObjectReferencePredicate::new) .forEach(predicates::add); + return predicates; } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/tor/RadiateTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/tor/RadiateTest.java index e991f410b42..6eb3688ab08 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/single/tor/RadiateTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/tor/RadiateTest.java @@ -26,10 +26,10 @@ public class RadiateTest extends CardTestPlayerBaseWithAIHelps { addCard(Zone.BATTLEFIELD, playerB, "Kitesail Corsair", 2); // cast bolt and copy spell for each another target - setChoice(playerA, TestPlayer.CHOICE_SKIP); // skip stack order castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", playerB); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Radiate", "Lightning Bolt", "Lightning Bolt"); checkStackSize("before radiate", 1, PhaseStep.PRECOMBAT_MAIN, playerA, 2); + setChoice(playerA, TestPlayer.CHOICE_SKIP); // skip stack order for copies waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, true); // must have: 2x for corsairs, 2x for bears, 1x for A checkStackSize("after radiate", 1, PhaseStep.PRECOMBAT_MAIN, playerA, 1 + 5); @@ -46,8 +46,6 @@ public class RadiateTest extends CardTestPlayerBaseWithAIHelps { @Test public void test_Play_AI() { - // This test has trouble now but the manual version works - // Choose target instant or sorcery spell that targets only a single permanent or player. Copy that spell // for each other permanent or player the spell could target. Each copy targets a different one of those // permanents and players. diff --git a/Mage/src/main/java/mage/MageObject.java b/Mage/src/main/java/mage/MageObject.java index 6d1c3d7e4b3..dd079105ee7 100644 --- a/Mage/src/main/java/mage/MageObject.java +++ b/Mage/src/main/java/mage/MageObject.java @@ -36,6 +36,11 @@ public interface MageObject extends MageItem, Serializable, Copyable String getName(); + /** + * Warning, don't use it as a key - multiple objects can have same parts of the id in rare use cases + * + * @return + */ String getIdName(); String getLogName(); diff --git a/Mage/src/main/java/mage/MageObjectReference.java b/Mage/src/main/java/mage/MageObjectReference.java index c12604c2bde..b0cdc055a78 100644 --- a/Mage/src/main/java/mage/MageObjectReference.java +++ b/Mage/src/main/java/mage/MageObjectReference.java @@ -111,7 +111,7 @@ public class MageObjectReference implements Comparable, Ser @Override public int compareTo(MageObjectReference o) { if (o.getSourceId() == null || this.sourceId == null || Objects.equals(o.getSourceId(), this.sourceId)) { - return o.getZoneChangeCounter() - this.zoneChangeCounter; + return Integer.compare(o.getZoneChangeCounter(), this.zoneChangeCounter); } return o.getSourceId().compareTo(sourceId); } diff --git a/Mage/src/main/java/mage/filter/predicate/mageobject/MageObjectReferencePredicate.java b/Mage/src/main/java/mage/filter/predicate/mageobject/MageObjectReferencePredicate.java index 411360b5f6b..21e1b58acfc 100644 --- a/Mage/src/main/java/mage/filter/predicate/mageobject/MageObjectReferencePredicate.java +++ b/Mage/src/main/java/mage/filter/predicate/mageobject/MageObjectReferencePredicate.java @@ -38,15 +38,27 @@ public class MageObjectReferencePredicate implements Predicate { } public String getName(Game game) { + UUID id = null; + String name = null; + Permanent permanent = mor.getPermanent(game); if (permanent != null) { - return permanent.getIdName(); + id = permanent.getId(); + name = permanent.getName(); } + Player player = game.getPlayer(mor.getSourceId()); if (player != null) { - return player.getName(); + id = player.getId(); + name = player.getName(); + } + + // workaround to use unique keys for choose dialog (getIdName can't be used here) + if (id != null) { + return String.format("%s [%s]", name, id); + } else { + return null; } - return null; } @Override