use of games.strategy.engine.data.Unit in project triplea by triplea-game.
the class NonFightingBattle method removeAttack.
@Override
public void removeAttack(final Route route, final Collection<Unit> units) {
m_attackingUnits.removeAll(units);
// the route could be null, in the case of a unit in a territory where a sub is submerged.
if (route == null) {
return;
}
final Territory attackingFrom = route.getTerritoryBeforeEnd();
Collection<Unit> attackingFromMapUnits = m_attackingFromMap.get(attackingFrom);
// handle possible null pointer
if (attackingFromMapUnits == null) {
attackingFromMapUnits = new ArrayList<>();
}
attackingFromMapUnits.removeAll(units);
if (attackingFromMapUnits.isEmpty()) {
m_attackingFrom.remove(attackingFrom);
}
// deal with amphibious assaults
if (attackingFrom.isWater()) {
if (route.getEnd() != null && !route.getEnd().isWater() && units.stream().anyMatch(Matches.unitIsLand())) {
m_amphibiousLandAttackers.removeAll(CollectionUtils.getMatches(units, Matches.unitIsLand()));
}
// that territory is no longer an amphibious assault
if (attackingFromMapUnits.stream().noneMatch(Matches.unitIsLand())) {
getAmphibiousAttackTerritories().remove(attackingFrom);
// do we have any amphibious attacks left?
m_isAmphibious = !getAmphibiousAttackTerritories().isEmpty();
}
}
for (final Collection<Unit> dependent : m_dependentUnits.values()) {
dependent.removeAll(units);
}
}
use of games.strategy.engine.data.Unit in project triplea by triplea-game.
the class NonFightingBattle method unitsLostInPrecedingBattle.
@Override
public void unitsLostInPrecedingBattle(final IBattle battle, final Collection<Unit> units, final IDelegateBridge bridge, final boolean withdrawn) {
if (withdrawn) {
return;
}
Collection<Unit> lost = getDependentUnits(units);
lost.addAll(CollectionUtils.intersection(units, m_attackingUnits));
lost = CollectionUtils.getMatches(lost, Matches.unitIsInTerritory(m_battleSite));
if (lost.size() != 0) {
final String transcriptText = MyFormatter.unitsToText(lost) + " lost in " + m_battleSite.getName();
bridge.getHistoryWriter().addChildToEvent(transcriptText, lost);
final Change change = ChangeFactory.removeUnits(m_battleSite, lost);
bridge.addChange(change);
}
}
use of games.strategy.engine.data.Unit in project triplea by triplea-game.
the class AAInMoveUtil method getTerritoriesWhereAaWillFire.
Collection<Territory> getTerritoriesWhereAaWillFire(final Route route, final Collection<Unit> units) {
final boolean alwaysOnAa = isAlwaysOnAaEnabled();
// Just the attacked territory will have AA firing
if (!alwaysOnAa && isAaTerritoryRestricted()) {
return Collections.emptyList();
}
final GameData data = getData();
// No AA in nonCombat unless 'Always on AA'
if (GameStepPropertiesHelper.isNonCombatMove(data, false) && !alwaysOnAa) {
return Collections.emptyList();
}
// can't rely on m_player being the unit owner in Edit Mode
// look at the units being moved to determine allies and enemies
final PlayerID movingPlayer = movingPlayer(units);
final HashMap<String, HashSet<UnitType>> airborneTechTargetsAllowed = TechAbilityAttachment.getAirborneTargettedByAa(movingPlayer, data);
// don't iterate over the end
// that will be a battle
// and handled else where in this tangled mess
final Predicate<Unit> hasAa = Matches.unitIsAaThatCanFire(units, airborneTechTargetsAllowed, movingPlayer, Matches.unitIsAaForFlyOverOnly(), 1, true, data);
// AA guns in transports shouldn't be able to fire
final List<Territory> territoriesWhereAaWillFire = new ArrayList<>();
for (final Territory current : route.getMiddleSteps()) {
if (current.getUnits().anyMatch(hasAa)) {
territoriesWhereAaWillFire.add(current);
}
}
if (Properties.getForceAaAttacksForLastStepOfFlyOver(data)) {
if (route.getEnd().getUnits().anyMatch(hasAa)) {
territoriesWhereAaWillFire.add(route.getEnd());
}
} else {
// fire
if (route.getStart().getUnits().anyMatch(hasAa) && !getBattleTracker().wasBattleFought(route.getStart())) {
territoriesWhereAaWillFire.add(route.getStart());
}
}
return territoriesWhereAaWillFire;
}
use of games.strategy.engine.data.Unit 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);
}
use of games.strategy.engine.data.Unit 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);
}
}
Aggregations