Search in sources :

Example 1 with IDelegateBridge

use of games.strategy.engine.delegate.IDelegateBridge in project triplea by triplea-game.

the class MovePerformer method populateStack.

/**
 * We assume that the move is valid.
 */
private void populateStack(final Collection<Unit> units, final Route route, final PlayerID id, final Collection<Unit> transportsToLoad) {
    final IExecutable preAaFire = new IExecutable() {

        private static final long serialVersionUID = -7945930782650355037L;

        @Override
        public void execute(final ExecutionStack stack, final IDelegateBridge bridge) {
            // this can happen for air units moving out of a battle zone
            for (final IBattle battle : getBattleTracker().getPendingBattles(route.getStart(), null)) {
                for (final Unit unit : units) {
                    final Route routeUnitUsedToMove = moveDelegate.getRouteUsedToMoveInto(unit, route.getStart());
                    if (battle != null) {
                        battle.removeAttack(routeUnitUsedToMove, Collections.singleton(unit));
                    }
                }
            }
        }
    };
    // hack to allow the executables to share state
    final IExecutable fireAa = new IExecutable() {

        private static final long serialVersionUID = -3780228078499895244L;

        @Override
        public void execute(final ExecutionStack stack, final IDelegateBridge bridge) {
            final Collection<Unit> aaCasualties = fireAa(route, units);
            final Set<Unit> aaCasualtiesWithDependents = new HashSet<>();
            // need to remove any dependents here
            if (aaCasualties != null) {
                aaCasualtiesWithDependents.addAll(aaCasualties);
                final Map<Unit, Collection<Unit>> dependencies = TransportTracker.transporting(units, units);
                for (final Unit u : aaCasualties) {
                    final Collection<Unit> dependents = dependencies.get(u);
                    if (dependents != null) {
                        aaCasualtiesWithDependents.addAll(dependents);
                    }
                    // we might have new dependents too (ie: paratroopers)
                    final Collection<Unit> newDependents = m_newDependents.get(u);
                    if (newDependents != null) {
                        aaCasualtiesWithDependents.addAll(newDependents);
                    }
                }
            }
            arrivingUnits = CollectionUtils.difference(units, aaCasualtiesWithDependents);
        }
    };
    final IExecutable postAaFire = new IExecutable() {

        private static final long serialVersionUID = 670783657414493643L;

        @Override
        public void execute(final ExecutionStack stack, final IDelegateBridge bridge) {
            // if any non enemy territories on route
            // or if any enemy units on route the
            // battles on (note water could have enemy but its
            // not owned)
            final GameData data = bridge.getData();
            final Predicate<Territory> mustFightThrough = getMustFightThroughMatch(id, data);
            final Collection<Unit> arrived = Collections.unmodifiableList(CollectionUtils.intersection(units, arrivingUnits));
            // Reset Optional
            arrivingUnits = new ArrayList<>();
            final Collection<Unit> arrivedCopyForBattles = new ArrayList<>(arrived);
            final Map<Unit, Unit> transporting = TransportUtils.mapTransports(route, arrived, transportsToLoad);
            // If we have paratrooper land units being carried by air units, they should be dropped off in the last
            // territory. This means they
            // are still dependent during the middle steps of the route.
            final Collection<Unit> dependentOnSomethingTilTheEndOfRoute = new ArrayList<>();
            final Collection<Unit> airTransports = CollectionUtils.getMatches(arrived, Matches.unitIsAirTransport());
            final Collection<Unit> paratroops = CollectionUtils.getMatches(arrived, Matches.unitIsAirTransportable());
            if (!airTransports.isEmpty() && !paratroops.isEmpty()) {
                final Map<Unit, Unit> transportingAir = TransportUtils.mapTransportsToLoad(paratroops, airTransports);
                dependentOnSomethingTilTheEndOfRoute.addAll(transportingAir.keySet());
            }
            final Collection<Unit> presentFromStartTilEnd = new ArrayList<>(arrived);
            presentFromStartTilEnd.removeAll(dependentOnSomethingTilTheEndOfRoute);
            final CompositeChange change = new CompositeChange();
            // markFuelCostResourceChange must be done before we load/unload units
            change.add(Route.getFuelChanges(units, route, id, data));
            markTransportsMovement(arrived, transporting, route);
            if (route.anyMatch(mustFightThrough) && arrived.size() != 0) {
                boolean bombing = false;
                boolean ignoreBattle = false;
                // could it be a bombing raid
                final Collection<Unit> enemyUnits = route.getEnd().getUnits().getMatches(Matches.enemyUnit(id, data));
                final Collection<Unit> enemyTargetsTotal = CollectionUtils.getMatches(enemyUnits, Matches.unitCanBeDamaged().and(Matches.unitIsBeingTransported().negate()));
                final boolean canCreateAirBattle = !enemyTargetsTotal.isEmpty() && Properties.getRaidsMayBePreceededByAirBattles(data) && AirBattle.territoryCouldPossiblyHaveAirBattleDefenders(route.getEnd(), id, data, true);
                final Predicate<Unit> allBombingRaid = PredicateBuilder.of(Matches.unitIsStrategicBomber()).orIf(canCreateAirBattle, Matches.unitCanEscort()).build();
                final boolean allCanBomb = !arrived.isEmpty() && arrived.stream().allMatch(allBombingRaid);
                final Collection<Unit> enemyTargets = CollectionUtils.getMatches(enemyTargetsTotal, Matches.unitIsOfTypes(UnitAttachment.getAllowedBombingTargetsIntersection(CollectionUtils.getMatches(arrived, Matches.unitIsStrategicBomber()), data)));
                final boolean targetsOrEscort = !enemyTargets.isEmpty() || (!enemyTargetsTotal.isEmpty() && canCreateAirBattle && !arrived.isEmpty() && arrived.stream().allMatch(Matches.unitCanEscort()));
                boolean targetedAttack = false;
                // if it's all bombers and there's something to bomb
                if (allCanBomb && targetsOrEscort && GameStepPropertiesHelper.isCombatMove(data)) {
                    bombing = getRemotePlayer().shouldBomberBomb(route.getEnd());
                    // if bombing and there's something to target- ask what to bomb
                    if (bombing) {
                        // CompositeMatchOr<Unit> unitsToBeBombed = new CompositeMatchOr<Unit>(Matches.UnitIsFactory,
                        // Matches.UnitCanBeDamagedButIsNotFactory);
                        // determine which unit to bomb
                        final Unit target;
                        if (enemyTargets.size() > 1 && Properties.getDamageFromBombingDoneToUnitsInsteadOfTerritories(data) && !canCreateAirBattle) {
                            target = getRemotePlayer().whatShouldBomberBomb(route.getEnd(), enemyTargets, arrived);
                        } else if (!enemyTargets.isEmpty()) {
                            target = enemyTargets.iterator().next();
                        } else {
                            // in case we are escorts only
                            target = enemyTargetsTotal.iterator().next();
                        }
                        if (target == null) {
                            bombing = false;
                            targetedAttack = false;
                        } else {
                            targetedAttack = true;
                            final HashMap<Unit, HashSet<Unit>> targets = new HashMap<>();
                            targets.put(target, new HashSet<>(arrived));
                            // createdBattle = true;
                            getBattleTracker().addBattle(route, arrivedCopyForBattles, bombing, id, MovePerformer.this.bridge, m_currentMove, dependentOnSomethingTilTheEndOfRoute, targets, false);
                        }
                    }
                }
                // Ignore Trn on Trn forces.
                if (isIgnoreTransportInMovement(bridge.getData())) {
                    final boolean allOwnedTransports = !arrived.isEmpty() && arrived.stream().allMatch(Matches.unitIsTransportButNotCombatTransport());
                    final boolean allEnemyTransports = !enemyUnits.isEmpty() && enemyUnits.stream().allMatch(Matches.unitIsTransportButNotCombatTransport());
                    // If everybody is a transport, don't create a battle
                    if (allOwnedTransports && allEnemyTransports) {
                        ignoreBattle = true;
                    }
                }
                if (!ignoreBattle && GameStepPropertiesHelper.isCombatMove(data) && !targetedAttack) {
                    // createdBattle = true;
                    if (bombing) {
                        getBattleTracker().addBombingBattle(route, arrivedCopyForBattles, id, MovePerformer.this.bridge, m_currentMove, dependentOnSomethingTilTheEndOfRoute);
                    } else {
                        getBattleTracker().addBattle(route, arrivedCopyForBattles, id, MovePerformer.this.bridge, m_currentMove, dependentOnSomethingTilTheEndOfRoute);
                    }
                }
                if (!ignoreBattle && GameStepPropertiesHelper.isNonCombatMove(data, false) && !targetedAttack) {
                    // difficult if we want these recorded in battle records).
                    for (final Territory t : route.getMatches(Matches.territoryIsOwnedByPlayerWhosRelationshipTypeCanTakeOverOwnedTerritoryAndPassableAndNotWater(id).and(Matches.territoryIsBlitzable(id, data)))) {
                        if (Matches.isTerritoryEnemy(id, data).test(t) || Matches.territoryHasEnemyUnits(id, data).test(t)) {
                            continue;
                        }
                        if ((t.equals(route.getEnd()) && !arrivedCopyForBattles.isEmpty() && arrivedCopyForBattles.stream().allMatch(Matches.unitIsAir())) || (!t.equals(route.getEnd()) && !presentFromStartTilEnd.isEmpty() && presentFromStartTilEnd.stream().allMatch(Matches.unitIsAir()))) {
                            continue;
                        }
                        // createdBattle = true;
                        getBattleTracker().takeOver(t, id, bridge, m_currentMove, arrivedCopyForBattles);
                    }
                }
            }
            // mark movement
            final Change moveChange = markMovementChange(arrived, route, id);
            change.add(moveChange);
            // actually move the units
            if (route.getStart() != null && route.getEnd() != null) {
                // ChangeFactory.addUnits(route.getEnd(), arrived);
                final Change remove = ChangeFactory.removeUnits(route.getStart(), units);
                final Change add = ChangeFactory.addUnits(route.getEnd(), arrived);
                change.add(add, remove);
            }
            MovePerformer.this.bridge.addChange(change);
            m_currentMove.addChange(change);
            m_currentMove.setDescription(MyFormatter.unitsToTextNoOwner(arrived) + " moved from " + route.getStart().getName() + " to " + route.getEnd().getName());
            moveDelegate.updateUndoableMoves(m_currentMove);
        }
    };
    m_executionStack.push(postAaFire);
    m_executionStack.push(fireAa);
    m_executionStack.push(preAaFire);
    m_executionStack.execute(bridge);
}
Also used : Territory(games.strategy.engine.data.Territory) GameData(games.strategy.engine.data.GameData) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) CompositeChange(games.strategy.engine.data.CompositeChange) Change(games.strategy.engine.data.Change) TripleAUnit(games.strategy.triplea.TripleAUnit) Unit(games.strategy.engine.data.Unit) Collection(java.util.Collection) CompositeChange(games.strategy.engine.data.CompositeChange) Route(games.strategy.engine.data.Route) IDelegateBridge(games.strategy.engine.delegate.IDelegateBridge) HashSet(java.util.HashSet)

Example 2 with IDelegateBridge

use of games.strategy.engine.delegate.IDelegateBridge in project triplea by triplea-game.

the class AAInMoveUtil method populateExecutionStack.

private void populateExecutionStack(final Route route, final Collection<Unit> units, final Comparator<Unit> decreasingMovement, final UndoableMove currentMove) {
    final List<Unit> targets = new ArrayList<>(units);
    // select units with lowest movement first
    targets.sort(decreasingMovement);
    final List<IExecutable> executables = new ArrayList<>();
    for (final Territory location : getTerritoriesWhereAaWillFire(route, units)) {
        executables.add(new IExecutable() {

            private static final long serialVersionUID = -1545771595683434276L;

            @Override
            public void execute(final ExecutionStack stack, final IDelegateBridge bridge) {
                fireAa(location, targets, currentMove);
            }
        });
    }
    Collections.reverse(executables);
    m_executionStack.push(executables);
}
Also used : Territory(games.strategy.engine.data.Territory) ArrayList(java.util.ArrayList) Unit(games.strategy.engine.data.Unit) IDelegateBridge(games.strategy.engine.delegate.IDelegateBridge)

Example 3 with IDelegateBridge

use of games.strategy.engine.delegate.IDelegateBridge in project triplea by triplea-game.

the class AAInMoveUtil method fireAa.

/**
 * Fire the aa units in the given territory, hits are removed from units.
 */
private void fireAa(final Territory territory, final Collection<Unit> units, final UndoableMove currentMove) {
    if (units.isEmpty()) {
        return;
    }
    final PlayerID movingPlayer = movingPlayer(units);
    final HashMap<String, HashSet<UnitType>> airborneTechTargetsAllowed = TechAbilityAttachment.getAirborneTargettedByAa(movingPlayer, getData());
    final List<Unit> defendingAa = territory.getUnits().getMatches(Matches.unitIsAaThatCanFire(units, airborneTechTargetsAllowed, movingPlayer, Matches.unitIsAaForFlyOverOnly(), 1, true, getData()));
    // comes ordered alphabetically already
    final List<String> aaTypes = UnitAttachment.getAllOfTypeAas(defendingAa);
    // stacks are backwards
    Collections.reverse(aaTypes);
    for (final String currentTypeAa : aaTypes) {
        final Collection<Unit> currentPossibleAa = CollectionUtils.getMatches(defendingAa, Matches.unitIsAaOfTypeAa(currentTypeAa));
        final Set<UnitType> targetUnitTypesForThisTypeAa = UnitAttachment.get(currentPossibleAa.iterator().next().getType()).getTargetsAa(getData());
        final Set<UnitType> airborneTypesTargettedToo = airborneTechTargetsAllowed.get(currentTypeAa);
        final Collection<Unit> validTargetedUnitsForThisRoll = CollectionUtils.getMatches(units, Matches.unitIsOfTypes(targetUnitTypesForThisTypeAa).or(Matches.unitIsAirborne().and(Matches.unitIsOfTypes(airborneTypesTargettedToo))));
        // once we fire the AA guns, we can't undo
        // otherwise you could keep undoing and redoing
        // until you got the roll you wanted
        currentMove.setCantUndo("Move cannot be undone after " + currentTypeAa + " has fired.");
        final DiceRoll[] dice = new DiceRoll[1];
        final IExecutable rollDice = new IExecutable() {

            private static final long serialVersionUID = 4714364489659654758L;

            @Override
            public void execute(final ExecutionStack stack, final IDelegateBridge bridge) {
                // get rid of units already killed, so we don't target them twice
                validTargetedUnitsForThisRoll.removeAll(m_casualties);
                if (!validTargetedUnitsForThisRoll.isEmpty()) {
                    dice[0] = DiceRoll.rollAa(validTargetedUnitsForThisRoll, currentPossibleAa, AAInMoveUtil.this.bridge, territory, true);
                }
            }
        };
        final IExecutable selectCasualties = new IExecutable() {

            private static final long serialVersionUID = -8633263235214834617L;

            @Override
            public void execute(final ExecutionStack stack, final IDelegateBridge bridge) {
                if (!validTargetedUnitsForThisRoll.isEmpty()) {
                    final int hitCount = dice[0].getHits();
                    if (hitCount == 0) {
                        if (currentTypeAa.equals("AA")) {
                            AAInMoveUtil.this.bridge.getSoundChannelBroadcaster().playSoundForAll(SoundPath.CLIP_BATTLE_AA_MISS, findDefender(currentPossibleAa, territory));
                        } else {
                            AAInMoveUtil.this.bridge.getSoundChannelBroadcaster().playSoundForAll(SoundPath.CLIP_BATTLE_X_PREFIX + currentTypeAa.toLowerCase() + SoundPath.CLIP_BATTLE_X_MISS, findDefender(currentPossibleAa, territory));
                        }
                        getRemotePlayer().reportMessage("No " + currentTypeAa + " hits in " + territory.getName(), "No " + currentTypeAa + " hits in " + territory.getName());
                    } else {
                        if (currentTypeAa.equals("AA")) {
                            AAInMoveUtil.this.bridge.getSoundChannelBroadcaster().playSoundForAll(SoundPath.CLIP_BATTLE_AA_HIT, findDefender(currentPossibleAa, territory));
                        } else {
                            AAInMoveUtil.this.bridge.getSoundChannelBroadcaster().playSoundForAll(SoundPath.CLIP_BATTLE_X_PREFIX + currentTypeAa.toLowerCase() + SoundPath.CLIP_BATTLE_X_HIT, findDefender(currentPossibleAa, territory));
                        }
                        selectCasualties(dice[0], units, validTargetedUnitsForThisRoll, currentPossibleAa, defendingAa, territory, currentTypeAa);
                    }
                }
            }
        };
        // push in reverse order of execution
        m_executionStack.push(selectCasualties);
        m_executionStack.push(rollDice);
    }
}
Also used : PlayerID(games.strategy.engine.data.PlayerID) Unit(games.strategy.engine.data.Unit) UnitType(games.strategy.engine.data.UnitType) HashSet(java.util.HashSet) IDelegateBridge(games.strategy.engine.delegate.IDelegateBridge)

Example 4 with IDelegateBridge

use of games.strategy.engine.delegate.IDelegateBridge in project triplea by triplea-game.

the class EndTurnDelegate method findNationalObjectiveAndTriggerResources.

/**
 * Find the resources generated by national objectives and triggers that are currently met.
 */
public static IntegerMap<Resource> findNationalObjectiveAndTriggerResources(final PlayerID player, final GameData data) {
    final IDelegateBridge bridge = new ObjectiveDummyDelegateBridge(data);
    // Find and test all the conditions for triggers and national objectives
    final Set<TriggerAttachment> triggers = new HashSet<>();
    final List<RulesAttachment> objectives = new ArrayList<>();
    final HashMap<ICondition, Boolean> testedConditions = testNationalObjectivesAndTriggers(player, data, bridge, triggers, objectives);
    // Find triggers value
    final IntegerMap<Resource> resources;
    final boolean useTriggers = Properties.getTriggers(data);
    if (useTriggers && !triggers.isEmpty()) {
        final Set<TriggerAttachment> toFireTestedAndSatisfied = new HashSet<>(CollectionUtils.getMatches(triggers, AbstractTriggerAttachment.isSatisfiedMatch(testedConditions)));
        resources = TriggerAttachment.findResourceIncome(toFireTestedAndSatisfied, bridge);
    } else {
        resources = new IntegerMap<>();
    }
    // Find national objectives value
    int pus = 0;
    for (final RulesAttachment rule : objectives) {
        final int uses = rule.getUses();
        if (uses == 0 || !rule.isSatisfied(testedConditions)) {
            continue;
        }
        pus += (rule.getObjectiveValue() * rule.getEachMultiple() * Properties.getPuMultiplier(data));
    }
    resources.add(data.getResourceList().getResource(Constants.PUS), pus);
    return resources;
}
Also used : TriggerAttachment(games.strategy.triplea.attachments.TriggerAttachment) AbstractTriggerAttachment(games.strategy.triplea.attachments.AbstractTriggerAttachment) ArrayList(java.util.ArrayList) Resource(games.strategy.engine.data.Resource) ObjectiveDummyDelegateBridge(games.strategy.triplea.ui.ObjectiveDummyDelegateBridge) RulesAttachment(games.strategy.triplea.attachments.RulesAttachment) ICondition(games.strategy.triplea.attachments.ICondition) IDelegateBridge(games.strategy.engine.delegate.IDelegateBridge) HashSet(java.util.HashSet)

Example 5 with IDelegateBridge

use of games.strategy.engine.delegate.IDelegateBridge in project triplea by triplea-game.

the class DoesNothingAi method endTurn.

@Override
protected void endTurn(final IAbstractForumPosterDelegate endTurnForumPosterDelegate, final GameData data, final PlayerID player) {
    // destroy whatever we have
    final ResourceCollection resourceCollection = player.getResources();
    final Change removeChange = ChangeFactory.removeResourceCollection(player, resourceCollection);
    // shameless cheating... (do NOT do this, normally you are never supposed to access the IDelegateBridge from outside
    // of a delegate)
    final IDelegateBridge bridge = endTurnForumPosterDelegate.getBridge();
    // resourceCollection is not yet a valid renderingObject
    bridge.getHistoryWriter().startEvent(player.getName() + " removes resources: " + resourceCollection, null);
    bridge.addChange(removeChange);
}
Also used : Change(games.strategy.engine.data.Change) ResourceCollection(games.strategy.engine.data.ResourceCollection) IDelegateBridge(games.strategy.engine.delegate.IDelegateBridge)

Aggregations

IDelegateBridge (games.strategy.engine.delegate.IDelegateBridge)10 ArrayList (java.util.ArrayList)7 GameData (games.strategy.engine.data.GameData)6 Territory (games.strategy.engine.data.Territory)6 Unit (games.strategy.engine.data.Unit)6 HashSet (java.util.HashSet)6 Change (games.strategy.engine.data.Change)5 PlayerID (games.strategy.engine.data.PlayerID)5 HashMap (java.util.HashMap)5 CompositeChange (games.strategy.engine.data.CompositeChange)4 Resource (games.strategy.engine.data.Resource)4 UnitType (games.strategy.engine.data.UnitType)4 Collection (java.util.Collection)4 Map (java.util.Map)4 Route (games.strategy.engine.data.Route)3 ChangeFactory (games.strategy.engine.data.changefactory.ChangeFactory)3 Properties (games.strategy.triplea.Properties)3 TripleAUnit (games.strategy.triplea.TripleAUnit)3 MyFormatter (games.strategy.triplea.formatter.MyFormatter)3 CollectionUtils (games.strategy.util.CollectionUtils)3