diff --git a/game-app/game-core/src/main/java/games/strategy/triplea/delegate/Matches.java b/game-app/game-core/src/main/java/games/strategy/triplea/delegate/Matches.java index ae3ef06de86..7ad0fdd0e5d 100644 --- a/game-app/game-core/src/main/java/games/strategy/triplea/delegate/Matches.java +++ b/game-app/game-core/src/main/java/games/strategy/triplea/delegate/Matches.java @@ -611,14 +611,6 @@ static Predicate unitIsRocket() { return obj -> unitTypeIsRocket().test(obj.getType()); } - public static Predicate unitHasMovementLimit() { - return u -> u.getUnitAttachment().getMovementLimit() != null; - } - - public static Predicate unitHasAttackingLimit() { - return u -> u.getUnitAttachment().getAttackingLimit() != null; - } - public static Predicate unitTypeCanNotMoveDuringCombatMove() { return u -> u.getUnitAttachment().getCanNotMoveDuringCombatMove(); } diff --git a/game-app/game-core/src/main/java/games/strategy/triplea/delegate/move/validation/MoveValidator.java b/game-app/game-core/src/main/java/games/strategy/triplea/delegate/move/validation/MoveValidator.java index 564029eeceb..5929c1a784f 100644 --- a/game-app/game-core/src/main/java/games/strategy/triplea/delegate/move/validation/MoveValidator.java +++ b/game-app/game-core/src/main/java/games/strategy/triplea/delegate/move/validation/MoveValidator.java @@ -17,6 +17,7 @@ import games.strategy.triplea.Constants; import games.strategy.triplea.Properties; import games.strategy.triplea.attachments.CanalAttachment; +import games.strategy.triplea.attachments.PlayerAttachment; import games.strategy.triplea.attachments.RulesAttachment; import games.strategy.triplea.attachments.TechAbilityAttachment; import games.strategy.triplea.attachments.UnitAttachment; @@ -53,6 +54,7 @@ import org.triplea.java.PredicateBuilder; import org.triplea.java.collections.CollectionUtils; import org.triplea.java.collections.IntegerMap; +import org.triplea.util.Triple; /** Responsible for validating unit movement. */ @AllArgsConstructor @@ -803,9 +805,31 @@ private MoveValidationResult validateBasic( } } // test for stack limits per unit + final PlayerAttachment pa = PlayerAttachment.get(player); + final Set>> playerMovementLimit = + (pa != null ? pa.getMovementLimit() : Set.of()); + final Set>> playerAttackingLimit = + (pa != null ? pa.getAttackingLimit() : Set.of()); + final Predicate hasMovementOrAttackingLimit = + unit -> { + final var ua = unit.getUnitAttachment(); + if (ua.getMovementLimit() != null || ua.getAttackingLimit() != null) { + return true; + } + for (final var limit : playerMovementLimit) { + if (limit.getThird().contains(unit.getType())) { + return true; + } + } + for (final var limit : playerAttackingLimit) { + if (limit.getThird().contains(unit.getType())) { + return true; + } + } + return false; + }; final Collection unitsWithStackingLimits = - CollectionUtils.getMatches( - units, Matches.unitHasMovementLimit().or(Matches.unitHasAttackingLimit())); + CollectionUtils.getMatches(units, hasMovementOrAttackingLimit); for (final Territory t : route.getSteps()) { final String limitType; if (Matches.isTerritoryEnemyAndNotUnownedWater(player).test(t)