use of games.strategy.engine.data.Unit in project triplea by triplea-game.
the class BattleDelegate method getMaxScrambleCount.
public static int getMaxScrambleCount(final Collection<Unit> airbases) {
if (airbases.isEmpty() || !airbases.stream().allMatch(Matches.unitIsAirBase().and(Matches.unitIsNotDisabled()))) {
throw new IllegalStateException("All units must be viable airbases");
}
// find how many is the max this territory can scramble
int maxScrambled = 0;
for (final Unit base : airbases) {
final int baseMax = ((TripleAUnit) base).getMaxScrambleCount();
if (baseMax == -1) {
return Integer.MAX_VALUE;
}
maxScrambled += baseMax;
}
return maxScrambled;
}
use of games.strategy.engine.data.Unit in project triplea by triplea-game.
the class BattleDelegate method landParatroopers.
private static void landParatroopers(final PlayerID player, final Territory battleSite, final IDelegateBridge bridge) {
if (TechTracker.hasParatroopers(player)) {
final Collection<Unit> airTransports = CollectionUtils.getMatches(battleSite.getUnits(), Matches.unitIsAirTransport());
final Collection<Unit> paratroops = CollectionUtils.getMatches(battleSite.getUnits(), Matches.unitIsAirTransportable());
if (!airTransports.isEmpty() && !paratroops.isEmpty()) {
final CompositeChange change = new CompositeChange();
for (final Unit u : paratroops) {
final TripleAUnit taUnit = (TripleAUnit) u;
final Unit transport = taUnit.getTransportedBy();
if (transport == null || !airTransports.contains(transport)) {
continue;
}
change.add(TransportTracker.unloadAirTransportChange(taUnit, battleSite, false));
}
if (!change.isEmpty()) {
bridge.getHistoryWriter().startEvent(player.getName() + " lands units in " + battleSite.getName());
bridge.addChange(change);
}
}
}
}
use of games.strategy.engine.data.Unit in project triplea by triplea-game.
the class BattleDelegate method createDamageChange.
private static Change createDamageChange(final IntegerMap<Unit> damagedMap, final IDelegateBridge bridge) {
final Set<Unit> units = new HashSet<>(damagedMap.keySet());
for (final Unit u : units) {
damagedMap.add(u, u.getHits());
}
final Change damagedChange = ChangeFactory.unitsHit(damagedMap);
bridge.getHistoryWriter().addChildToEvent("Units damaged: " + MyFormatter.unitsToText(units), units);
return damagedChange;
}
use of games.strategy.engine.data.Unit in project triplea by triplea-game.
the class BattleDelegate method whereCanAirLand.
private static Collection<Territory> whereCanAirLand(final Collection<Unit> strandedAir, final Territory currentTerr, final PlayerID alliedPlayer, final GameData data, final BattleTracker battleTracker, final int carrierCostForCurrentTerr, final int allowedMovement, final boolean useMaxScrambleDistance) {
int maxDistance = allowedMovement;
if ((maxDistance > 1) || useMaxScrambleDistance) {
UnitType ut = null;
for (final Unit u : strandedAir) {
if (ut == null) {
ut = u.getType();
} else if (!ut.equals(u.getType())) {
throw new IllegalStateException("whereCanAirLand can only accept 1 UnitType if byMovementCost or scrambled is true");
}
}
if (useMaxScrambleDistance) {
maxDistance = UnitAttachment.get(ut).getMaxScrambleDistance();
}
}
if (maxDistance < 1 || strandedAir == null || strandedAir.isEmpty()) {
return Collections.singletonList(currentTerr);
}
final boolean areNeutralsPassableByAir = (Properties.getNeutralFlyoverAllowed(data) && !Properties.getNeutralsImpassable(data));
final HashSet<Territory> canNotLand = new HashSet<>();
canNotLand.addAll(battleTracker.getPendingBattleSites(false));
canNotLand.addAll(CollectionUtils.getMatches(data.getMap().getTerritories(), Matches.territoryHasEnemyUnits(alliedPlayer, data)));
final Collection<Territory> possibleTerrs = new ArrayList<>(data.getMap().getNeighbors(currentTerr, maxDistance));
if (maxDistance > 1) {
final Iterator<Territory> possibleIter = possibleTerrs.iterator();
while (possibleIter.hasNext()) {
final Route route = data.getMap().getRoute(currentTerr, possibleIter.next(), Matches.airCanFlyOver(alliedPlayer, data, areNeutralsPassableByAir));
if (route == null || route.getMovementCost(strandedAir.iterator().next()) > maxDistance) {
possibleIter.remove();
}
}
}
possibleTerrs.add(currentTerr);
final HashSet<Territory> availableLand = new HashSet<>(CollectionUtils.getMatches(possibleTerrs, Matches.isTerritoryAllied(alliedPlayer, data).and(Matches.territoryIsLand())));
availableLand.removeAll(canNotLand);
final HashSet<Territory> whereCanLand = new HashSet<>(availableLand);
// now for carrier-air-landing validation
if (!strandedAir.isEmpty() && strandedAir.stream().allMatch(Matches.unitCanLandOnCarrier())) {
final HashSet<Territory> availableWater = new HashSet<>(CollectionUtils.getMatches(possibleTerrs, Matches.territoryHasUnitsThatMatch(Matches.unitIsAlliedCarrier(alliedPlayer, data)).and(Matches.territoryIsWater())));
availableWater.removeAll(battleTracker.getPendingBattleSites(false));
// a rather simple calculation, either we can take all the air, or we can't, nothing in the middle
final int carrierCost = AirMovementValidator.carrierCost(strandedAir);
final Iterator<Territory> waterIter = availableWater.iterator();
while (waterIter.hasNext()) {
final Territory t = waterIter.next();
int carrierCapacity = AirMovementValidator.carrierCapacity(t.getUnits().getMatches(Matches.unitIsAlliedCarrier(alliedPlayer, data)), t);
if (!t.equals(currentTerr)) {
carrierCapacity -= AirMovementValidator.carrierCost(t.getUnits().getMatches(Matches.unitCanLandOnCarrier().and(Matches.alliedUnit(alliedPlayer, data))));
} else {
carrierCapacity -= carrierCostForCurrentTerr;
}
if (carrierCapacity < carrierCost) {
waterIter.remove();
}
}
whereCanLand.addAll(availableWater);
}
return whereCanLand;
}
use of games.strategy.engine.data.Unit in project triplea by triplea-game.
the class BattleDelegate method checkDefendingPlanesCanLand.
private void checkDefendingPlanesCanLand() {
final GameData data = getData();
final Map<Territory, Collection<Unit>> defendingAirThatCanNotLand = battleTracker.getDefendingAirThatCanNotLand();
final boolean isWW2v2orIsSurvivingAirMoveToLand = Properties.getWW2V2(data) || Properties.getSurvivingAirMoveToLand(data);
final Predicate<Unit> alliedDefendingAir = Matches.unitIsAir().and(Matches.unitWasScrambled().negate());
for (final Entry<Territory, Collection<Unit>> entry : defendingAirThatCanNotLand.entrySet()) {
final Territory battleSite = entry.getKey();
final Collection<Unit> defendingAir = entry.getValue();
if (defendingAir == null || defendingAir.isEmpty()) {
continue;
}
defendingAir.retainAll(battleSite.getUnits());
if (defendingAir.isEmpty()) {
continue;
}
final PlayerID defender = AbstractBattle.findDefender(battleSite, player, data);
// Get all land territories where we can land
final Set<Territory> neighbors = data.getMap().getNeighbors(battleSite);
final Predicate<Territory> alliedLandTerritories = Matches.airCanLandOnThisAlliedNonConqueredLandTerritory(defender, data);
// Get those that are neighbors
final Collection<Territory> canLandHere = CollectionUtils.getMatches(neighbors, alliedLandTerritories);
// Get all sea territories where there are allies
final Predicate<Territory> neighboringSeaZonesWithAlliedUnits = Matches.territoryIsWater().and(Matches.territoryHasAlliedUnits(defender, data));
// Get those that are neighbors
final Collection<Territory> areSeaNeighbors = CollectionUtils.getMatches(neighbors, neighboringSeaZonesWithAlliedUnits);
// Set up match criteria for allied carriers
final Predicate<Unit> alliedCarrier = Matches.unitIsCarrier().and(Matches.alliedUnit(defender, data));
// Set up match criteria for allied planes
final Predicate<Unit> alliedPlane = Matches.unitIsAir().and(Matches.alliedUnit(defender, data));
// See if neighboring carriers have any capacity available
for (final Territory currentTerritory : areSeaNeighbors) {
// get the capacity of the carriers and cost of fighters
final Collection<Unit> alliedCarriers = currentTerritory.getUnits().getMatches(alliedCarrier);
final Collection<Unit> alliedPlanes = currentTerritory.getUnits().getMatches(alliedPlane);
final int alliedCarrierCapacity = AirMovementValidator.carrierCapacity(alliedCarriers, currentTerritory);
final int alliedPlaneCost = AirMovementValidator.carrierCost(alliedPlanes);
// if there is free capacity, add the territory to landing possibilities
if (alliedCarrierCapacity - alliedPlaneCost >= 1) {
canLandHere.add(currentTerritory);
}
}
if (isWW2v2orIsSurvivingAirMoveToLand) {
Territory territory;
while (canLandHere.size() > 1 && defendingAir.size() > 0) {
territory = getRemotePlayer(defender).selectTerritoryForAirToLand(canLandHere, battleSite, "Select territory for air units to land. (Current territory is " + battleSite.getName() + "): " + MyFormatter.unitsToText(defendingAir));
// added for test script
if (territory == null) {
territory = canLandHere.iterator().next();
}
if (territory.isWater()) {
landPlanesOnCarriers(bridge, alliedDefendingAir, defendingAir, alliedCarrier, alliedPlane, territory, battleSite);
} else {
moveAirAndLand(bridge, defendingAir, defendingAir, territory, battleSite);
continue;
}
// remove the territory from those available
canLandHere.remove(territory);
}
// Land in the last remaining territory
if (canLandHere.size() > 0 && defendingAir.size() > 0) {
territory = canLandHere.iterator().next();
if (territory.isWater()) {
landPlanesOnCarriers(bridge, alliedDefendingAir, defendingAir, alliedCarrier, alliedPlane, territory, battleSite);
} else {
moveAirAndLand(bridge, defendingAir, defendingAir, territory, battleSite);
continue;
}
}
} else if (canLandHere.size() > 0) {
// check for an island in this sea zone
for (final Territory currentTerritory : canLandHere) {
// only one neighbor, its an island.
if (data.getMap().getNeighbors(currentTerritory).size() == 1) {
moveAirAndLand(bridge, defendingAir, defendingAir, currentTerritory, battleSite);
}
}
}
if (defendingAir.size() > 0) {
// no where to go, they must die
bridge.getHistoryWriter().addChildToEvent(MyFormatter.unitsToText(defendingAir) + " could not land and were killed", new ArrayList<>(defendingAir));
final Change change = ChangeFactory.removeUnits(battleSite, defendingAir);
bridge.addChange(change);
}
}
}
Aggregations