Skip to content

Commit

Permalink
PlacePanel: Limit max based on unit requirements.
Browse files Browse the repository at this point in the history
This change caps the max for each unit type in the place panel to the max that can be placed for that type when considering "units which require units" logic (i.e. factory types).

This partially prevents the error "Cannot place more units which require units, than production capacity of territories with the required units" after making the selection in the place panel.

Note: That error can still happen when selecting multiple units of different types that surpass the max.
  • Loading branch information
asvitkine committed Aug 18, 2023
1 parent 1f09efc commit a2afde1
Showing 1 changed file with 15 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import java.util.Map.Entry;
import java.util.Objects;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import org.triplea.java.collections.CollectionUtils;
import org.triplea.java.collections.IntegerMap;
Expand Down Expand Up @@ -980,6 +981,11 @@ protected Collection<Unit> getUnitsToBePlaced(
} else {
placeableUnits2 = placeableUnits;
}
// Limit count of each unit type to the max that can be placed based on unit requirements.
for (UnitType ut : placeableUnits2.stream().map(Unit::getType).collect(Collectors.toSet())) {
var unitsOfType = CollectionUtils.getMatches(placeableUnits2, Matches.unitIsOfType(ut));
placeableUnits2.removeAll(getUnitsThatCantBePlacedThatRequireUnits(unitsOfType, to));
}
// now check stacking limits
return UnitStackingLimitFilter.filterUnits(
placeableUnits2, PLACEMENT_LIMIT, player, to, produced.getOrDefault(to, List.of()));
Expand Down Expand Up @@ -1477,20 +1483,25 @@ private Predicate<Unit> unitWhichRequiresUnitsHasRequiredUnits(

private boolean getCanAllUnitsWithRequiresUnitsBePlacedCorrectly(
final Collection<Unit> units, final Territory to) {
return getUnitsThatCantBePlacedThatRequireUnits(units, to).isEmpty();
}

private Collection<Unit> getUnitsThatCantBePlacedThatRequireUnits(
final Collection<Unit> units, final Territory to) {
if (!Properties.getUnitPlacementRestrictions(getData().getProperties())
|| units.stream().noneMatch(Matches.unitRequiresUnitsOnCreation())) {
return true;
return List.of();
}
final IntegerMap<Territory> producersMap = getMaxUnitsToBePlacedMap(units, to, player);
final List<Territory> producers = getAllProducers(to, player, units);
if (producers.isEmpty()) {
return false;
return units;
}
producers.sort(getBestProducerComparator(to, units, player));
final Collection<Unit> unitsLeftToPlace = new ArrayList<>(units);
for (final Territory t : producers) {
if (unitsLeftToPlace.isEmpty()) {
return true;
return List.of();
}
final int productionHere = producersMap.getInt(t);
final List<Unit> canBePlacedHere =
Expand All @@ -1505,7 +1516,7 @@ private boolean getCanAllUnitsWithRequiresUnitsBePlacedCorrectly(
CollectionUtils.getNMatches(canBePlacedHere, productionHere, it -> true);
unitsLeftToPlace.removeAll(placedHere);
}
return unitsLeftToPlace.isEmpty();
return unitsLeftToPlace;
}

private Comparator<Territory> getBestProducerComparator(
Expand Down

0 comments on commit a2afde1

Please sign in to comment.