diff --git a/forge-ai/src/main/java/forge/ai/ability/RearrangeTopOfLibraryAi.java b/forge-ai/src/main/java/forge/ai/ability/RearrangeTopOfLibraryAi.java index ba7e3614f22..408d912f76b 100644 --- a/forge-ai/src/main/java/forge/ai/ability/RearrangeTopOfLibraryAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/RearrangeTopOfLibraryAi.java @@ -16,6 +16,7 @@ import forge.game.phase.PhaseType; import forge.game.player.Player; import forge.game.player.PlayerActionConfirmMode; import forge.game.player.PlayerCollection; +import forge.game.player.PlayerPredicates; import forge.game.spellability.SpellAbility; import forge.game.zone.ZoneType; import forge.util.MyRandom; @@ -30,28 +31,30 @@ public class RearrangeTopOfLibraryAi extends SpellAbilityAi { final PhaseHandler ph = aiPlayer.getGame().getPhaseHandler(); final Card source = sa.getHostCard(); - if (source.isPermanent() && !sa.getRestrictions().isSorcerySpeed() - && (sa.getPayCosts().hasTapCost() || sa.getPayCosts().hasManaCost())) { - // If it has an associated cost, try to only do this before own turn - if (!(ph.is(PhaseType.END_OF_TURN) && ph.getNextTurn() == aiPlayer)) { + if (!sa.isTrigger()) { + if (source.isPermanent() && !sa.getRestrictions().isSorcerySpeed() + && (sa.getPayCosts().hasTapCost() || sa.getPayCosts().hasManaCost())) { + // If it has an associated cost, try to only do this before own turn + if (!(ph.is(PhaseType.END_OF_TURN) && ph.getNextTurn() == aiPlayer)) { + return false; + } + } + + // Do it once per turn, generally (may be improved later) + if (AiCardMemory.isRememberedCardByName(aiPlayer, source.getName(), AiCardMemory.MemorySet.ACTIVATED_THIS_TURN)) { return false; } } - // Do it once per turn, generally (may be improved later) - if (!sa.isTrigger() - && AiCardMemory.isRememberedCardByName(aiPlayer, source.getName(), AiCardMemory.MemorySet.ACTIVATED_THIS_TURN)) { - return false; - } - if (sa.usesTargeting()) { // ability is targeted sa.resetTargets(); - Player opp = aiPlayer.getWeakestOpponent(); + PlayerCollection targetableOpps = aiPlayer.getOpponents().filter(PlayerPredicates.isTargetableBy(sa)); + Player opp = targetableOpps.min(PlayerPredicates.compareByLife()); final boolean canTgtAI = sa.canTarget(aiPlayer); - final boolean canTgtHuman = sa.canTarget(opp); - + final boolean canTgtHuman = opp != null && sa.canTarget(opp); + if (canTgtHuman && canTgtAI) { // TODO: maybe some other consideration rather than random? Player preferredTarget = MyRandom.percentTrue(50) ? aiPlayer : opp; diff --git a/forge-core/src/main/java/forge/util/Aggregates.java b/forge-core/src/main/java/forge/util/Aggregates.java index 7187841a36b..1d98afb8c5f 100644 --- a/forge-core/src/main/java/forge/util/Aggregates.java +++ b/forge-core/src/main/java/forge/util/Aggregates.java @@ -41,7 +41,6 @@ public class Aggregates { return max; } - public static final T itemWithMax(final Iterable source, final Function valueAccessor) { if (source == null) { return null; } int max = Integer.MIN_VALUE; @@ -188,7 +187,6 @@ public class Aggregates { return result; } - public static TItem firstFieldEquals(List source, Function valueAccessor, TField valueEquals) { if (source == null) { return null; }