use of games.strategy.engine.data.Unit in project triplea by triplea-game.
the class MustFightBattle method fireNavalBombardment.
private void fireNavalBombardment(final IDelegateBridge bridge) {
// TODO - check within the method for the bombarding limitations
final Collection<Unit> bombard = getBombardingUnits();
final Collection<Unit> attacked = CollectionUtils.getMatches(m_defendingUnits, Matches.unitIsNotInfrastructureAndNotCapturedOnEntering(m_attacker, m_battleSite, m_data));
// bombarding units can't move after bombarding
if (!m_headless) {
final Change change = ChangeFactory.markNoMovementChange(bombard);
bridge.addChange(change);
}
/*
* TODO This code is actually a bug- the property is intended to tell if the return fire is
* RESTRICTED- but it's used as if it's ALLOWED. The reason is the default values on the
* property definition. However, fixing this will entail a fix to the XML to reverse
* all values. We'll leave it as is for now and try to figure out a patch strategy later.
*/
final boolean canReturnFire = isNavalBombardCasualtiesReturnFire();
if (bombard.size() > 0 && attacked.size() > 0) {
if (!m_headless) {
bridge.getSoundChannelBroadcaster().playSoundForAll(SoundPath.CLIP_BATTLE_BOMBARD, m_attacker);
}
final List<Unit> allEnemyUnitsAliveOrWaitingToDie = new ArrayList<>();
allEnemyUnitsAliveOrWaitingToDie.addAll(m_defendingUnits);
allEnemyUnitsAliveOrWaitingToDie.addAll(m_defendingWaitingToDie);
fire(SELECT_NAVAL_BOMBARDMENT_CASUALTIES, bombard, attacked, allEnemyUnitsAliveOrWaitingToDie, false, canReturnFire ? ReturnFire.ALL : ReturnFire.NONE, "Bombard");
}
}
use of games.strategy.engine.data.Unit in project triplea by triplea-game.
the class MustFightBattle method clearTransportedByForAlliedAirOnCarrier.
static CompositeChange clearTransportedByForAlliedAirOnCarrier(final Collection<Unit> attackingUnits, final Territory battleSite, final PlayerID attacker, final GameData data) {
final CompositeChange change = new CompositeChange();
// Clear the transported_by for successfully won battles where there was an allied air unit held as cargo by an
// carrier unit
final Collection<Unit> carriers = CollectionUtils.getMatches(attackingUnits, Matches.unitIsCarrier());
if (!carriers.isEmpty() && !Properties.getAlliedAirIndependent(data)) {
final Predicate<Unit> alliedFighters = Matches.isUnitAllied(attacker, data).and(Matches.unitIsOwnedBy(attacker).negate()).and(Matches.unitIsAir()).and(Matches.unitCanLandOnCarrier());
final Collection<Unit> alliedAirInTerr = CollectionUtils.getMatches(Sets.union(Sets.newHashSet(attackingUnits), Sets.newHashSet(battleSite.getUnits())), alliedFighters);
for (final Unit fighter : alliedAirInTerr) {
final TripleAUnit taUnit = (TripleAUnit) fighter;
if (taUnit.getTransportedBy() != null) {
final Unit carrierTransportingThisUnit = taUnit.getTransportedBy();
if (!Matches.unitHasWhenCombatDamagedEffect(UnitAttachment.UNITSMAYNOTLEAVEALLIEDCARRIER).test(carrierTransportingThisUnit)) {
change.add(ChangeFactory.unitPropertyChange(fighter, null, TripleAUnit.TRANSPORTED_BY));
}
}
}
}
return change;
}
use of games.strategy.engine.data.Unit 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.Unit 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);
}
}
use of games.strategy.engine.data.Unit in project triplea by triplea-game.
the class NoPUPurchaseDelegate method getProductionUnits.
private Collection<Unit> getProductionUnits(final Collection<Territory> territories, final PlayerID player) {
final Collection<Unit> productionUnits = new ArrayList<>();
if (!(isProductionPerXTerritoriesRestricted() || isProductionPerValuedTerritoryRestricted())) {
return productionUnits;
}
IntegerMap<UnitType> productionPerXTerritories = new IntegerMap<>();
final RulesAttachment ra = (RulesAttachment) player.getAttachment(Constants.RULES_ATTACHMENT_NAME);
// isProductionPerValuedTerritoryRestricted, then they want 1 infantry for each territory with PU value > 0
if (isProductionPerValuedTerritoryRestricted() && (ra == null || ra.getProductionPerXTerritories() == null || ra.getProductionPerXTerritories().size() == 0)) {
productionPerXTerritories.put(getData().getUnitTypeList().getUnitType(Constants.UNIT_TYPE_INFANTRY), 1);
} else if (isProductionPerXTerritoriesRestricted()) {
productionPerXTerritories = ra.getProductionPerXTerritories();
} else {
return productionUnits;
}
final Collection<UnitType> unitTypes = new ArrayList<>(productionPerXTerritories.keySet());
for (final UnitType ut : unitTypes) {
int unitCount = 0;
final int prodPerXTerrs = productionPerXTerritories.getInt(ut);
if (isPacific) {
unitCount += getBurmaRoad(player);
}
int terrCount = 0;
for (final Territory current : territories) {
if (!isProductionPerValuedTerritoryRestricted()) {
terrCount++;
} else {
if (TerritoryAttachment.getProduction(current) > 0) {
terrCount++;
}
}
}
unitCount += terrCount / prodPerXTerrs;
productionUnits.addAll(getData().getUnitTypeList().getUnitType(ut.getName()).create(unitCount, player));
}
return productionUnits;
}
Aggregations