Search in sources :

Example 1 with RouteScripted

use of games.strategy.engine.data.RouteScripted in project triplea by triplea-game.

the class BattleDelegate method setupUnitsInSameTerritoryBattles.

/**
 * Setup the battles where the battle occurs because units are in the
 * same territory. This happens when subs emerge (after being submerged), and
 * when naval units are placed in enemy occupied sea zones, and also
 * when political relationships change and potentially leave units in now-hostile territories.
 */
private static void setupUnitsInSameTerritoryBattles(final BattleTracker battleTracker, final IDelegateBridge bridge) {
    final PlayerID player = bridge.getPlayerId();
    final GameData data = bridge.getData();
    final boolean ignoreTransports = isIgnoreTransportInMovement(data);
    final boolean ignoreSubs = isIgnoreSubInMovement(data);
    final Predicate<Unit> seaTransports = Matches.unitIsTransportButNotCombatTransport().and(Matches.unitIsSea());
    final Predicate<Unit> seaTranportsOrSubs = seaTransports.or(Matches.unitIsSub());
    // we want to match all sea zones with our units and enemy units
    final Predicate<Territory> anyTerritoryWithOwnAndEnemy = Matches.territoryHasUnitsOwnedBy(player).and(Matches.territoryHasEnemyUnits(player, data));
    final Predicate<Territory> enemyTerritoryAndOwnUnits = Matches.isTerritoryEnemyAndNotUnownedWater(player, data).and(Matches.territoryHasUnitsOwnedBy(player));
    final Predicate<Territory> enemyUnitsOrEnemyTerritory = anyTerritoryWithOwnAndEnemy.or(enemyTerritoryAndOwnUnits);
    final List<Territory> battleTerritories = CollectionUtils.getMatches(data.getMap().getTerritories(), enemyUnitsOrEnemyTerritory);
    for (final Territory territory : battleTerritories) {
        final List<Unit> attackingUnits = territory.getUnits().getMatches(Matches.unitIsOwnedBy(player));
        // now make sure to add any units that must move with these attacking units, so that they get included as
        // dependencies
        final Map<Unit, Collection<Unit>> transportMap = TransportTracker.transporting(territory.getUnits());
        final HashSet<Unit> dependants = new HashSet<>();
        for (final Entry<Unit, Collection<Unit>> entry : transportMap.entrySet()) {
            // only consider those transports that we are attacking with. allied and enemy transports are not added.
            if (attackingUnits.contains(entry.getKey())) {
                dependants.addAll(entry.getValue());
            }
        }
        // no duplicates
        dependants.removeAll(attackingUnits);
        // add the dependants to the attacking list
        attackingUnits.addAll(dependants);
        final List<Unit> enemyUnits = territory.getUnits().getMatches(Matches.enemyUnit(player, data));
        final IBattle bombingBattle = battleTracker.getPendingBattle(territory, true, null);
        if (bombingBattle != null) {
            // we need to remove any units which are participating in bombing raids
            attackingUnits.removeAll(bombingBattle.getAttackingUnits());
        }
        if (attackingUnits.stream().allMatch(Matches.unitIsInfrastructure())) {
            continue;
        }
        IBattle battle = battleTracker.getPendingBattle(territory, false, BattleType.NORMAL);
        if (battle == null) {
            // fires)
            if (enemyUnits.stream().allMatch(Matches.unitIsInfrastructure())) {
                landParatroopers(player, territory, bridge);
            }
            bridge.getHistoryWriter().startEvent(player.getName() + " creates battle in territory " + territory.getName());
            battleTracker.addBattle(new RouteScripted(territory), attackingUnits, player, bridge, null, null);
            battle = battleTracker.getPendingBattle(territory, false, BattleType.NORMAL);
        }
        if (battle == null) {
            continue;
        }
        if (bombingBattle != null) {
            battleTracker.addDependency(battle, bombingBattle);
        }
        if (battle.isEmpty()) {
            battle.addAttackChange(new RouteScripted(territory), attackingUnits, null);
        }
        if (!battle.getAttackingUnits().containsAll(attackingUnits)) {
            List<Unit> attackingUnitsNeedToBeAdded = new ArrayList<>(attackingUnits);
            attackingUnitsNeedToBeAdded.removeAll(battle.getAttackingUnits());
            attackingUnitsNeedToBeAdded.removeAll(battle.getDependentUnits(battle.getAttackingUnits()));
            if (territory.isWater()) {
                attackingUnitsNeedToBeAdded = CollectionUtils.getMatches(attackingUnitsNeedToBeAdded, Matches.unitIsLand().negate());
            } else {
                attackingUnitsNeedToBeAdded = CollectionUtils.getMatches(attackingUnitsNeedToBeAdded, Matches.unitIsSea().negate());
            }
            if (!attackingUnitsNeedToBeAdded.isEmpty()) {
                battle.addAttackChange(new RouteScripted(territory), attackingUnitsNeedToBeAdded, null);
            }
        }
        // Reach stalemate if all attacking and defending units are transports
        if ((ignoreTransports && !attackingUnits.isEmpty() && attackingUnits.stream().allMatch(seaTransports) && !enemyUnits.isEmpty() && enemyUnits.stream().allMatch(seaTransports)) || (!attackingUnits.isEmpty() && attackingUnits.stream().allMatch(Matches.unitHasAttackValueOfAtLeast(1).negate()) && !enemyUnits.isEmpty() && enemyUnits.stream().allMatch(Matches.unitHasDefendValueOfAtLeast(1).negate()))) {
            final BattleResults results = new BattleResults(battle, WhoWon.DRAW, data);
            battleTracker.getBattleRecords().addResultToBattle(player, battle.getBattleId(), null, 0, 0, BattleRecord.BattleResultDescription.STALEMATE, results);
            battle.cancelBattle(bridge);
            battleTracker.removeBattle(battle);
            continue;
        }
        // possibility to ignore battle altogether
        if (!attackingUnits.isEmpty()) {
            final ITripleAPlayer remotePlayer = getRemotePlayer(bridge);
            if (territory.isWater() && Properties.getSeaBattlesMayBeIgnored(data)) {
                if (!remotePlayer.selectAttackUnits(territory)) {
                    final BattleResults results = new BattleResults(battle, WhoWon.NOTFINISHED, data);
                    battleTracker.getBattleRecords().addResultToBattle(player, battle.getBattleId(), null, 0, 0, BattleRecord.BattleResultDescription.NO_BATTLE, results);
                    battle.cancelBattle(bridge);
                    battleTracker.removeBattle(battle);
                }
                continue;
            }
            // Check for ignored units
            if (ignoreTransports || ignoreSubs) {
                // if only enemy transports... attack them?
                if (ignoreTransports && !enemyUnits.isEmpty() && enemyUnits.stream().allMatch(seaTransports)) {
                    if (!remotePlayer.selectAttackTransports(territory)) {
                        final BattleResults results = new BattleResults(battle, WhoWon.NOTFINISHED, data);
                        battleTracker.getBattleRecords().addResultToBattle(player, battle.getBattleId(), null, 0, 0, BattleRecord.BattleResultDescription.NO_BATTLE, results);
                        battle.cancelBattle(bridge);
                        battleTracker.removeBattle(battle);
                    }
                    continue;
                }
                // if only enemy subs... attack them?
                if (ignoreSubs && !enemyUnits.isEmpty() && enemyUnits.stream().allMatch(Matches.unitIsSub())) {
                    if (!remotePlayer.selectAttackSubs(territory)) {
                        final BattleResults results = new BattleResults(battle, WhoWon.NOTFINISHED, data);
                        battleTracker.getBattleRecords().addResultToBattle(player, battle.getBattleId(), null, 0, 0, BattleRecord.BattleResultDescription.NO_BATTLE, results);
                        battle.cancelBattle(bridge);
                        battleTracker.removeBattle(battle);
                    }
                    continue;
                }
                // if only enemy transports and subs... attack them?
                if (ignoreSubs && ignoreTransports && !enemyUnits.isEmpty() && enemyUnits.stream().allMatch(seaTranportsOrSubs)) {
                    if (!remotePlayer.selectAttackUnits(territory)) {
                        final BattleResults results = new BattleResults(battle, WhoWon.NOTFINISHED, data);
                        battleTracker.getBattleRecords().addResultToBattle(player, battle.getBattleId(), null, 0, 0, BattleRecord.BattleResultDescription.NO_BATTLE, results);
                        battle.cancelBattle(bridge);
                        battleTracker.removeBattle(battle);
                    }
                }
            }
        }
    }
}
Also used : PlayerID(games.strategy.engine.data.PlayerID) Territory(games.strategy.engine.data.Territory) GameData(games.strategy.engine.data.GameData) BattleResults(games.strategy.triplea.oddsCalculator.ta.BattleResults) ArrayList(java.util.ArrayList) RouteScripted(games.strategy.engine.data.RouteScripted) TripleAUnit(games.strategy.triplea.TripleAUnit) Unit(games.strategy.engine.data.Unit) ITripleAPlayer(games.strategy.triplea.player.ITripleAPlayer) Collection(java.util.Collection) ResourceCollection(games.strategy.engine.data.ResourceCollection) HashSet(java.util.HashSet)

Example 2 with RouteScripted

use of games.strategy.engine.data.RouteScripted in project triplea by triplea-game.

the class BattleDelegate method doScrambling.

private void doScrambling() {
    // first, figure out all the territories where scrambling units could scramble to
    // then ask the defending player if they wish to scramble units there, and actually move the units there
    final GameData data = getData();
    if (!Properties.getScrambleRulesInEffect(data)) {
        return;
    }
    final boolean fromIslandOnly = Properties.getScrambleFromIslandOnly(data);
    final boolean toSeaOnly = Properties.getScrambleToSeaOnly(data);
    final boolean toAnyAmphibious = Properties.getScrambleToAnyAmphibiousAssault(data);
    final boolean toSbr = Properties.getCanScrambleIntoAirBattles(data);
    int maxScrambleDistance = 0;
    for (final UnitType unitType : data.getUnitTypeList()) {
        final UnitAttachment ua = UnitAttachment.get(unitType);
        if (ua.getCanScramble() && maxScrambleDistance < ua.getMaxScrambleDistance()) {
            maxScrambleDistance = ua.getMaxScrambleDistance();
        }
    }
    final Predicate<Unit> airbasesCanScramble = Matches.unitIsEnemyOf(data, player).and(Matches.unitIsAirBase()).and(Matches.unitIsNotDisabled()).and(Matches.unitIsBeingTransported().negate());
    final Predicate<Territory> canScramble = PredicateBuilder.of(Matches.territoryIsWater().or(Matches.isTerritoryEnemy(player, data))).and(Matches.territoryHasUnitsThatMatch(Matches.unitCanScramble().and(Matches.unitIsEnemyOf(data, player)).and(Matches.unitIsNotDisabled()))).and(Matches.territoryHasUnitsThatMatch(airbasesCanScramble)).andIf(fromIslandOnly, Matches.territoryIsIsland()).build();
    final Set<Territory> territoriesWithBattles = battleTracker.getPendingBattleSites().getNormalBattlesIncludingAirBattles();
    if (toSbr) {
        territoriesWithBattles.addAll(battleTracker.getPendingBattleSites().getStrategicBombingRaidsIncludingAirBattles());
    }
    final Set<Territory> territoriesWithBattlesWater = new HashSet<>(CollectionUtils.getMatches(territoriesWithBattles, Matches.territoryIsWater()));
    final Set<Territory> territoriesWithBattlesLand = new HashSet<>(CollectionUtils.getMatches(territoriesWithBattles, Matches.territoryIsLand()));
    final Map<Territory, Set<Territory>> scrambleTerrs = new HashMap<>();
    for (final Territory battleTerr : territoriesWithBattlesWater) {
        final Set<Territory> canScrambleFrom = new HashSet<>(CollectionUtils.getMatches(data.getMap().getNeighbors(battleTerr, maxScrambleDistance), canScramble));
        if (!canScrambleFrom.isEmpty()) {
            scrambleTerrs.put(battleTerr, canScrambleFrom);
        }
    }
    for (final Territory battleTerr : territoriesWithBattlesLand) {
        if (!toSeaOnly) {
            final Set<Territory> canScrambleFrom = new HashSet<>(CollectionUtils.getMatches(data.getMap().getNeighbors(battleTerr, maxScrambleDistance), canScramble));
            if (!canScrambleFrom.isEmpty()) {
                scrambleTerrs.put(battleTerr, canScrambleFrom);
            }
        }
        final IBattle battle = battleTracker.getPendingBattle(battleTerr, false, BattleType.NORMAL);
        // it.
        if (battle != null && battle.isAmphibious() && battle instanceof DependentBattle) {
            final Collection<Territory> amphibFromTerrs = ((DependentBattle) battle).getAmphibiousAttackTerritories();
            amphibFromTerrs.removeAll(territoriesWithBattlesWater);
            for (final Territory amphibFrom : amphibFromTerrs) {
                final Set<Territory> canScrambleFrom = scrambleTerrs.getOrDefault(amphibFrom, new HashSet<>());
                if (toAnyAmphibious) {
                    canScrambleFrom.addAll(CollectionUtils.getMatches(data.getMap().getNeighbors(amphibFrom, maxScrambleDistance), canScramble));
                } else if (canScramble.test(battleTerr)) {
                    canScrambleFrom.add(battleTerr);
                }
                if (!canScrambleFrom.isEmpty()) {
                    scrambleTerrs.put(amphibFrom, canScrambleFrom);
                }
            }
        }
    }
    // now scrambleTerrs is a list of places we can scramble from
    if (scrambleTerrs.isEmpty()) {
        return;
    }
    final Map<Tuple<Territory, PlayerID>, Collection<Map<Territory, Tuple<Collection<Unit>, Collection<Unit>>>>> scramblersByTerritoryPlayer = new HashMap<>();
    for (final Territory to : scrambleTerrs.keySet()) {
        // find who we should ask
        PlayerID defender = null;
        if (battleTracker.hasPendingBattle(to, false)) {
            defender = AbstractBattle.findDefender(to, player, data);
        }
        final Map<Territory, Tuple<Collection<Unit>, Collection<Unit>>> scramblers = new HashMap<>();
        for (final Territory from : scrambleTerrs.get(to)) {
            if (defender == null) {
                defender = AbstractBattle.findDefender(from, player, data);
            }
            // find how many is the max this territory can scramble
            final Collection<Unit> airbases = from.getUnits().getMatches(airbasesCanScramble);
            final int maxCanScramble = getMaxScrambleCount(airbases);
            final Route toBattleRoute = data.getMap().getRoute_IgnoreEnd(from, to, Matches.territoryIsNotImpassable());
            final Collection<Unit> canScrambleAir = from.getUnits().getMatches(Matches.unitIsEnemyOf(data, player).and(Matches.unitCanScramble()).and(Matches.unitIsNotDisabled()).and(Matches.unitWasScrambled().negate()).and(Matches.unitCanScrambleOnRouteDistance(toBattleRoute)));
            if (maxCanScramble > 0 && !canScrambleAir.isEmpty()) {
                scramblers.put(from, Tuple.of(airbases, canScrambleAir));
            }
        }
        if (defender == null || scramblers.isEmpty()) {
            continue;
        }
        final Tuple<Territory, PlayerID> terrPlayer = Tuple.of(to, defender);
        final Collection<Map<Territory, Tuple<Collection<Unit>, Collection<Unit>>>> tempScrambleList = scramblersByTerritoryPlayer.getOrDefault(terrPlayer, new ArrayList<>());
        tempScrambleList.add(scramblers);
        scramblersByTerritoryPlayer.put(terrPlayer, tempScrambleList);
    }
    // now scramble them
    for (final Tuple<Territory, PlayerID> terrPlayer : scramblersByTerritoryPlayer.keySet()) {
        final Territory to = terrPlayer.getFirst();
        final PlayerID defender = terrPlayer.getSecond();
        if (defender == null || defender.isNull()) {
            continue;
        }
        boolean scrambledHere = false;
        for (final Map<Territory, Tuple<Collection<Unit>, Collection<Unit>>> scramblers : scramblersByTerritoryPlayer.get(terrPlayer)) {
            // verify that we didn't already scramble any of these units
            final Iterator<Territory> territoryIter = scramblers.keySet().iterator();
            while (territoryIter.hasNext()) {
                final Territory t = territoryIter.next();
                scramblers.get(t).getSecond().retainAll(t.getUnits());
                if (scramblers.get(t).getSecond().isEmpty()) {
                    territoryIter.remove();
                }
            }
            if (scramblers.isEmpty()) {
                continue;
            }
            final Map<Territory, Collection<Unit>> toScramble = getRemotePlayer(defender).scrambleUnitsQuery(to, scramblers);
            if (toScramble == null) {
                continue;
            }
            // verify max allowed
            if (!scramblers.keySet().containsAll(toScramble.keySet())) {
                throw new IllegalStateException("Trying to scramble from illegal territory");
            }
            for (final Territory t : scramblers.keySet()) {
                if (toScramble.get(t) == null) {
                    continue;
                }
                if (toScramble.get(t).size() > getMaxScrambleCount(scramblers.get(t).getFirst())) {
                    throw new IllegalStateException("Trying to scramble " + toScramble.get(t).size() + " out of " + t.getName() + ", but max allowed is " + scramblers.get(t).getFirst());
                }
            }
            // Validate players have enough fuel to move there and back
            final Map<PlayerID, ResourceCollection> playerFuelCost = new HashMap<>();
            for (final Entry<Territory, Collection<Unit>> entry : toScramble.entrySet()) {
                final Map<PlayerID, ResourceCollection> map = Route.getScrambleFuelCostCharge(entry.getValue(), entry.getKey(), to, data);
                for (final Entry<PlayerID, ResourceCollection> playerAndCost : map.entrySet()) {
                    if (playerFuelCost.containsKey(playerAndCost.getKey())) {
                        playerFuelCost.get(playerAndCost.getKey()).add(playerAndCost.getValue());
                    } else {
                        playerFuelCost.put(playerAndCost.getKey(), playerAndCost.getValue());
                    }
                }
            }
            for (final Entry<PlayerID, ResourceCollection> playerAndCost : playerFuelCost.entrySet()) {
                if (!playerAndCost.getKey().getResources().has(playerAndCost.getValue().getResourcesCopy())) {
                    throw new IllegalStateException("Not enough fuel to scramble, player: " + playerAndCost.getKey() + ", needs: " + playerAndCost.getValue());
                }
            }
            final CompositeChange change = new CompositeChange();
            for (final Territory t : toScramble.keySet()) {
                final Collection<Unit> scrambling = toScramble.get(t);
                if (scrambling == null || scrambling.isEmpty()) {
                    continue;
                }
                int numberScrambled = scrambling.size();
                final Collection<Unit> airbases = t.getUnits().getMatches(airbasesCanScramble);
                final int maxCanScramble = getMaxScrambleCount(airbases);
                if (maxCanScramble != Integer.MAX_VALUE) {
                    // TODO: maybe sort from biggest to smallest first?
                    for (final Unit airbase : airbases) {
                        final int allowedScramble = ((TripleAUnit) airbase).getMaxScrambleCount();
                        if (allowedScramble > 0) {
                            final int newAllowed;
                            if (allowedScramble >= numberScrambled) {
                                newAllowed = allowedScramble - numberScrambled;
                                numberScrambled = 0;
                            } else {
                                newAllowed = 0;
                                numberScrambled -= allowedScramble;
                            }
                            change.add(ChangeFactory.unitPropertyChange(airbase, newAllowed, TripleAUnit.MAX_SCRAMBLE_COUNT));
                        }
                        if (numberScrambled <= 0) {
                            break;
                        }
                    }
                }
                for (final Unit u : scrambling) {
                    change.add(ChangeFactory.unitPropertyChange(u, t, TripleAUnit.ORIGINATED_FROM));
                    change.add(ChangeFactory.unitPropertyChange(u, true, TripleAUnit.WAS_SCRAMBLED));
                    change.add(Route.getFuelChanges(Collections.singleton(u), new Route(t, to), u.getOwner(), data));
                }
                // should we mark combat, or call setupUnitsInSameTerritoryBattles again?
                change.add(ChangeFactory.moveUnits(t, to, scrambling));
                bridge.getHistoryWriter().startEvent(defender.getName() + " scrambles " + scrambling.size() + " units out of " + t.getName() + " to defend against the attack in " + to.getName(), scrambling);
                scrambledHere = true;
            }
            if (!change.isEmpty()) {
                bridge.addChange(change);
            }
        }
        if (!scrambledHere) {
            continue;
        }
        // make sure the units join the battle, or create a new battle.
        final IBattle bombing = battleTracker.getPendingBattle(to, true, null);
        IBattle battle = battleTracker.getPendingBattle(to, false, BattleType.NORMAL);
        if (battle == null) {
            final List<Unit> attackingUnits = to.getUnits().getMatches(Matches.unitIsOwnedBy(player));
            if (bombing != null) {
                attackingUnits.removeAll(bombing.getAttackingUnits());
            }
            // into an air battle / air raid
            if (attackingUnits.isEmpty()) {
                continue;
            }
            bridge.getHistoryWriter().startEvent(defender.getName() + " scrambles to create a battle in territory " + to.getName());
            // TODO: the attacking sea units do not remember where they came from, so they cannot retreat anywhere. Need to
            // fix.
            battleTracker.addBattle(new RouteScripted(to), attackingUnits, player, bridge, null, null);
            battle = battleTracker.getPendingBattle(to, false, BattleType.NORMAL);
            if (battle instanceof MustFightBattle) {
                // this is an ugly mess of hacks, but will have to stay here till all transport related code is gutted and
                // refactored.
                final MustFightBattle mfb = (MustFightBattle) battle;
                final Collection<Territory> neighborsLand = data.getMap().getNeighbors(to, Matches.territoryIsLand());
                if (attackingUnits.stream().anyMatch(Matches.unitIsTransport())) {
                    // first, we have to reset the "transportedBy" setting for all the land units that were offloaded
                    final CompositeChange change1 = new CompositeChange();
                    mfb.reLoadTransports(attackingUnits, change1);
                    if (!change1.isEmpty()) {
                        bridge.addChange(change1);
                    }
                    // after that is applied, we have to make a map of all dependencies
                    final Map<Unit, Collection<Unit>> dependenciesForMfb = TransportTracker.transporting(attackingUnits, attackingUnits);
                    for (final Unit transport : CollectionUtils.getMatches(attackingUnits, Matches.unitIsTransport())) {
                        // BUT it must still hold all transports
                        if (!dependenciesForMfb.containsKey(transport)) {
                            dependenciesForMfb.put(transport, new ArrayList<>());
                        }
                    }
                    final Map<Territory, Map<Unit, Collection<Unit>>> dependencies = new HashMap<>();
                    dependencies.put(to, dependenciesForMfb);
                    for (final Territory t : neighborsLand) {
                        // All other maps, must hold only the transported units that in their territory
                        final Collection<Unit> allNeighborUnits = new ArrayList<>(CollectionUtils.getMatches(attackingUnits, Matches.unitIsTransport()));
                        allNeighborUnits.addAll(t.getUnits().getMatches(Matches.unitIsLandAndOwnedBy(player)));
                        final Map<Unit, Collection<Unit>> dependenciesForNeighbors = TransportTracker.transporting(CollectionUtils.getMatches(allNeighborUnits, Matches.unitIsTransport()), CollectionUtils.getMatches(allNeighborUnits, Matches.unitIsTransport().negate()));
                        dependencies.put(t, dependenciesForNeighbors);
                    }
                    mfb.addDependentUnits(dependencies.get(to));
                    for (final Territory territoryNeighborToNewBattle : neighborsLand) {
                        final IBattle battleInTerritoryNeighborToNewBattle = battleTracker.getPendingBattle(territoryNeighborToNewBattle, false, BattleType.NORMAL);
                        if (battleInTerritoryNeighborToNewBattle instanceof MustFightBattle) {
                            final MustFightBattle mfbattleInTerritoryNeighborToNewBattle = (MustFightBattle) battleInTerritoryNeighborToNewBattle;
                            mfbattleInTerritoryNeighborToNewBattle.addDependentUnits(dependencies.get(territoryNeighborToNewBattle));
                        } else if (battleInTerritoryNeighborToNewBattle instanceof NonFightingBattle) {
                            final NonFightingBattle nfbattleInTerritoryNeighborToNewBattle = (NonFightingBattle) battleInTerritoryNeighborToNewBattle;
                            nfbattleInTerritoryNeighborToNewBattle.addDependentUnits(dependencies.get(territoryNeighborToNewBattle));
                        }
                    }
                }
                if (attackingUnits.stream().anyMatch(Matches.unitIsAir().negate())) {
                    // TODO: for now, we will hack and say that the attackers came from Everywhere, and hope the user will
                    // choose the correct place
                    // to retreat to! (TODO: Fix this)
                    final Map<Territory, Collection<Unit>> attackingFromMap = new HashMap<>();
                    final Collection<Territory> neighbors = data.getMap().getNeighbors(to, (Matches.territoryIsLand().test(to) ? Matches.territoryIsLand() : Matches.territoryIsWater()));
                    // neighbors.removeAll(Matches.getMatches(neighbors, Matches.territoryHasEnemyUnits(player, data)));
                    for (final Territory t : neighbors) {
                        attackingFromMap.put(t, attackingUnits);
                    }
                    mfb.setAttackingFromAndMap(attackingFromMap);
                }
            }
        } else if (battle instanceof MustFightBattle) {
            ((MustFightBattle) battle).resetDefendingUnits(player, data);
        }
        // now make sure any amphibious battles that are dependent on this 'new' sea battle have their dependencies set.
        if (to.isWater()) {
            for (final Territory t : data.getMap().getNeighbors(to, Matches.territoryIsLand())) {
                final IBattle battleAmphib = battleTracker.getPendingBattle(t, false, BattleType.NORMAL);
                if (battleAmphib != null) {
                    if (!battleTracker.getDependentOn(battle).contains(battleAmphib)) {
                        battleTracker.addDependency(battleAmphib, battle);
                    }
                    if (battleAmphib instanceof MustFightBattle) {
                        // and we want to reset the defenders if the scrambling air has left that battle
                        ((MustFightBattle) battleAmphib).resetDefendingUnits(player, data);
                    }
                }
            }
        }
    }
}
Also used : PlayerID(games.strategy.engine.data.PlayerID) GameData(games.strategy.engine.data.GameData) HashSet(java.util.HashSet) Set(java.util.Set) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) TripleAUnit(games.strategy.triplea.TripleAUnit) Unit(games.strategy.engine.data.Unit) UnitAttachment(games.strategy.triplea.attachments.UnitAttachment) UnitType(games.strategy.engine.data.UnitType) CompositeChange(games.strategy.engine.data.CompositeChange) Route(games.strategy.engine.data.Route) HashSet(java.util.HashSet) Territory(games.strategy.engine.data.Territory) RouteScripted(games.strategy.engine.data.RouteScripted) TripleAUnit(games.strategy.triplea.TripleAUnit) Collection(java.util.Collection) ResourceCollection(games.strategy.engine.data.ResourceCollection) HashMap(java.util.HashMap) Map(java.util.Map) IntegerMap(games.strategy.util.IntegerMap) Tuple(games.strategy.util.Tuple) ResourceCollection(games.strategy.engine.data.ResourceCollection)

Example 3 with RouteScripted

use of games.strategy.engine.data.RouteScripted in project triplea by triplea-game.

the class AirBattle method makeBattle.

private void makeBattle(final IDelegateBridge bridge) {
    // record who was in this battle first, so that they do not take part in any ground battles
    if (m_isBombingRun) {
        recordUnitsWereInAirBattle(m_attackingUnits, bridge);
        recordUnitsWereInAirBattle(m_defendingUnits, bridge);
    }
    // setup new battle here
    if (m_isBombingRun) {
        final Collection<Unit> bombers = CollectionUtils.getMatches(m_attackingUnits, Matches.unitIsStrategicBomber());
        if (!bombers.isEmpty()) {
            HashMap<Unit, HashSet<Unit>> targets = null;
            final Collection<Unit> enemyTargetsTotal = m_battleSite.getUnits().getMatches(Matches.enemyUnit(bridge.getPlayerId(), m_data).and(Matches.unitCanBeDamaged()).and(Matches.unitIsBeingTransported().negate()));
            for (final Unit unit : bombers) {
                final Collection<Unit> enemyTargets = CollectionUtils.getMatches(enemyTargetsTotal, Matches.unitIsLegalBombingTargetBy(unit));
                if (!enemyTargets.isEmpty()) {
                    Unit target = null;
                    if (enemyTargets.size() > 1 && Properties.getDamageFromBombingDoneToUnitsInsteadOfTerritories(m_data)) {
                        while (target == null) {
                            target = getRemote(bridge).whatShouldBomberBomb(m_battleSite, enemyTargets, Collections.singletonList(unit));
                        }
                    } else if (!enemyTargets.isEmpty()) {
                        target = enemyTargets.iterator().next();
                    }
                    if (target != null) {
                        targets = new HashMap<>();
                        targets.put(target, new HashSet<>(Collections.singleton(unit)));
                    }
                    m_battleTracker.addBattle(new RouteScripted(m_battleSite), Collections.singleton(unit), true, m_attacker, bridge, null, null, targets, true);
                }
            }
            final IBattle battle = m_battleTracker.getPendingBattle(m_battleSite, true, null);
            final IBattle dependent = m_battleTracker.getPendingBattle(m_battleSite, false, BattleType.NORMAL);
            if (dependent != null) {
                m_battleTracker.addDependency(dependent, battle);
            }
            final IBattle dependentAirBattle = m_battleTracker.getPendingBattle(m_battleSite, false, BattleType.AIR_BATTLE);
            if (dependentAirBattle != null) {
                m_battleTracker.addDependency(dependentAirBattle, battle);
            }
        }
    }
}
Also used : RouteScripted(games.strategy.engine.data.RouteScripted) TripleAUnit(games.strategy.triplea.TripleAUnit) Unit(games.strategy.engine.data.Unit) HashSet(java.util.HashSet)

Aggregations

RouteScripted (games.strategy.engine.data.RouteScripted)3 Unit (games.strategy.engine.data.Unit)3 TripleAUnit (games.strategy.triplea.TripleAUnit)3 HashSet (java.util.HashSet)3 GameData (games.strategy.engine.data.GameData)2 PlayerID (games.strategy.engine.data.PlayerID)2 ResourceCollection (games.strategy.engine.data.ResourceCollection)2 Territory (games.strategy.engine.data.Territory)2 ArrayList (java.util.ArrayList)2 Collection (java.util.Collection)2 CompositeChange (games.strategy.engine.data.CompositeChange)1 Route (games.strategy.engine.data.Route)1 UnitType (games.strategy.engine.data.UnitType)1 UnitAttachment (games.strategy.triplea.attachments.UnitAttachment)1 BattleResults (games.strategy.triplea.oddsCalculator.ta.BattleResults)1 ITripleAPlayer (games.strategy.triplea.player.ITripleAPlayer)1 IntegerMap (games.strategy.util.IntegerMap)1 Tuple (games.strategy.util.Tuple)1 HashMap (java.util.HashMap)1 Map (java.util.Map)1