use of games.strategy.engine.data.Territory in project triplea by triplea-game.
the class MustFightBattle 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> dependents : m_dependentUnits.values()) {
dependents.removeAll(units);
}
}
use of games.strategy.engine.data.Territory in project triplea by triplea-game.
the class MustFightBattle method retreatFromNonCombat.
/**
* Retreat landed units from allied territory when their transport retreats.
*/
private Change retreatFromNonCombat(Collection<Unit> units, final Territory retreatTo) {
final CompositeChange change = new CompositeChange();
units = CollectionUtils.getMatches(units, Matches.unitIsTransport());
final Collection<Unit> retreated = getTransportDependents(units);
if (!retreated.isEmpty()) {
for (final Unit unit : units) {
final Territory retreatedFrom = TransportTracker.getTerritoryTransportHasUnloadedTo(unit);
if (retreatedFrom != null) {
reLoadTransports(units, change);
change.add(ChangeFactory.moveUnits(retreatedFrom, retreatTo, retreated));
}
}
}
return change;
}
use of games.strategy.engine.data.Territory in project triplea by triplea-game.
the class MustFightBattle method getEmptyOrFriendlySeaNeighbors.
private Collection<Territory> getEmptyOrFriendlySeaNeighbors(final PlayerID player, final Collection<Unit> unitsToRetreat) {
Collection<Territory> possible = m_data.getMap().getNeighbors(m_battleSite);
if (m_headless) {
return possible;
}
// make sure we can move through the any canals
final Predicate<Territory> canalMatch = t -> {
final Route r = new Route();
r.setStart(m_battleSite);
r.add(t);
return MoveValidator.validateCanal(r, unitsToRetreat, m_defender, m_data) == null;
};
final Predicate<Territory> match = Matches.territoryIsWater().and(Matches.territoryHasNoEnemyUnits(player, m_data)).and(canalMatch);
possible = CollectionUtils.getMatches(possible, match);
return possible;
}
use of games.strategy.engine.data.Territory in project triplea by triplea-game.
the class MustFightBattle method queryRetreat.
private void queryRetreat(final boolean defender, final RetreatType retreatType, final IDelegateBridge bridge, Collection<Territory> availableTerritories) {
final boolean planes = retreatType == RetreatType.PLANES;
final boolean subs = retreatType == RetreatType.SUBS;
final boolean canSubsSubmerge = canSubsSubmerge();
final boolean canDefendingSubsSubmergeOrRetreat = subs && defender && Properties.getSubmarinesDefendingMaySubmergeOrRetreat(m_data);
final boolean partialAmphib = retreatType == RetreatType.PARTIAL_AMPHIB;
final boolean submerge = subs && canSubsSubmerge;
if (availableTerritories.isEmpty() && !(submerge || canDefendingSubsSubmergeOrRetreat)) {
return;
}
// If attacker then add all owned units at battle site as some might have been removed from battle (infra)
Collection<Unit> units = defender ? m_defendingUnits : m_attackingUnits;
if (!defender) {
units = new HashSet<>(units);
units.addAll(m_battleSite.getUnits().getMatches(Matches.unitIsOwnedBy(m_attacker)));
units.removeAll(m_killed);
}
if (subs) {
units = CollectionUtils.getMatches(units, Matches.unitIsSub());
} else if (planes) {
units = CollectionUtils.getMatches(units, Matches.unitIsAir());
} else if (partialAmphib) {
units = CollectionUtils.getMatches(units, Matches.unitWasNotAmphibious());
}
if (units.stream().anyMatch(Matches.unitIsSea())) {
availableTerritories = CollectionUtils.getMatches(availableTerritories, Matches.territoryIsWater());
}
if (canDefendingSubsSubmergeOrRetreat) {
availableTerritories.add(m_battleSite);
} else if (submerge) {
availableTerritories.clear();
availableTerritories.add(m_battleSite);
}
if (planes) {
availableTerritories.clear();
availableTerritories.add(m_battleSite);
}
if (units.size() == 0) {
return;
}
final PlayerID retreatingPlayer = defender ? m_defender : m_attacker;
final String text;
if (subs) {
text = retreatingPlayer.getName() + " retreat subs?";
} else if (planes) {
text = retreatingPlayer.getName() + " retreat planes?";
} else if (partialAmphib) {
text = retreatingPlayer.getName() + " retreat non-amphibious units?";
} else {
text = retreatingPlayer.getName() + " retreat?";
}
final String step;
if (defender) {
step = m_defender.getName() + (canSubsSubmerge ? SUBS_SUBMERGE : SUBS_WITHDRAW);
} else {
if (subs) {
step = m_attacker.getName() + (canSubsSubmerge ? SUBS_SUBMERGE : SUBS_WITHDRAW);
} else {
step = m_attacker.getName() + ATTACKER_WITHDRAW;
}
}
getDisplay(bridge).gotoBattleStep(m_battleID, step);
final Territory retreatTo = getRemote(retreatingPlayer, bridge).retreatQuery(m_battleID, (submerge || canDefendingSubsSubmergeOrRetreat), m_battleSite, availableTerritories, text);
if (retreatTo != null && !availableTerritories.contains(retreatTo) && !subs) {
System.err.println("Invalid retreat selection :" + retreatTo + " not in " + MyFormatter.defaultNamedToTextList(availableTerritories));
Thread.dumpStack();
return;
}
if (retreatTo != null) {
// if attacker retreating non subs then its all over
if (!defender && !subs && !planes && !partialAmphib) {
// this is illegal in ww2v2 revised and beyond (the fighters should die). still checking if illegal in classic.
m_isOver = true;
}
if (subs && m_battleSite.equals(retreatTo) && (submerge || canDefendingSubsSubmergeOrRetreat)) {
if (!m_headless) {
bridge.getSoundChannelBroadcaster().playSoundForAll(SoundPath.CLIP_BATTLE_RETREAT_SUBMERGE, m_attacker);
}
submergeUnits(units, defender, bridge);
final String messageShort = retreatingPlayer.getName() + " submerges subs";
getDisplay(bridge).notifyRetreat(messageShort, messageShort, step, retreatingPlayer);
} else if (planes) {
if (!m_headless) {
bridge.getSoundChannelBroadcaster().playSoundForAll(SoundPath.CLIP_BATTLE_RETREAT_AIR, m_attacker);
}
retreatPlanes(units, defender, bridge);
final String messageShort = retreatingPlayer.getName() + " retreats planes";
getDisplay(bridge).notifyRetreat(messageShort, messageShort, step, retreatingPlayer);
} else if (partialAmphib) {
if (!m_headless) {
if (units.stream().anyMatch(Matches.unitIsSea())) {
bridge.getSoundChannelBroadcaster().playSoundForAll(SoundPath.CLIP_BATTLE_RETREAT_SEA, m_attacker);
} else if (units.stream().anyMatch(Matches.unitIsLand())) {
bridge.getSoundChannelBroadcaster().playSoundForAll(SoundPath.CLIP_BATTLE_RETREAT_LAND, m_attacker);
} else {
bridge.getSoundChannelBroadcaster().playSoundForAll(SoundPath.CLIP_BATTLE_RETREAT_AIR, m_attacker);
}
}
// remove amphib units from those retreating
units = CollectionUtils.getMatches(units, Matches.unitWasNotAmphibious());
retreatUnitsAndPlanes(units, retreatTo, defender, bridge);
final String messageShort = retreatingPlayer.getName() + " retreats non-amphibious units";
getDisplay(bridge).notifyRetreat(messageShort, messageShort, step, retreatingPlayer);
} else {
if (!m_headless) {
if (units.stream().anyMatch(Matches.unitIsSea())) {
bridge.getSoundChannelBroadcaster().playSoundForAll(SoundPath.CLIP_BATTLE_RETREAT_SEA, m_attacker);
} else if (units.stream().anyMatch(Matches.unitIsLand())) {
bridge.getSoundChannelBroadcaster().playSoundForAll(SoundPath.CLIP_BATTLE_RETREAT_LAND, m_attacker);
} else {
bridge.getSoundChannelBroadcaster().playSoundForAll(SoundPath.CLIP_BATTLE_RETREAT_AIR, m_attacker);
}
}
retreatUnits(units, retreatTo, defender, bridge);
final String messageShort = retreatingPlayer.getName() + " retreats";
final String messageLong;
if (subs) {
messageLong = retreatingPlayer.getName() + " retreats subs to " + retreatTo.getName();
} else if (planes) {
messageLong = retreatingPlayer.getName() + " retreats planes to " + retreatTo.getName();
} else if (partialAmphib) {
messageLong = retreatingPlayer.getName() + " retreats non-amphibious units to " + retreatTo.getName();
} else {
messageLong = retreatingPlayer.getName() + " retreats all units to " + retreatTo.getName();
}
getDisplay(bridge).notifyRetreat(messageShort, messageLong, step, retreatingPlayer);
}
}
}
use of games.strategy.engine.data.Territory in project triplea by triplea-game.
the class MustFightBattle method removeFromNonCombatLandings.
// Remove landed units from allied territory when their transport sinks
private void removeFromNonCombatLandings(final Collection<Unit> units, final IDelegateBridge bridge) {
for (final Unit transport : CollectionUtils.getMatches(units, Matches.unitIsTransport())) {
final Collection<Unit> lost = getTransportDependents(Collections.singleton(transport));
if (lost.isEmpty()) {
continue;
}
final Territory landedTerritory = TransportTracker.getTerritoryTransportHasUnloadedTo(transport);
if (landedTerritory == null) {
throw new IllegalStateException("not unloaded?:" + units);
}
remove(lost, bridge, landedTerritory, false);
}
}
Aggregations