use of games.strategy.triplea.TripleAUnit in project triplea by triplea-game.
the class UnitType method create.
private Unit create(final PlayerID owner, final boolean isTemp, final int hitsTaken, final int bombingUnitDamage) {
final Unit u = getData().getGameLoader().getUnitFactory().createUnit(this, owner, getData());
u.setHits(hitsTaken);
if (u instanceof TripleAUnit) {
((TripleAUnit) u).setUnitDamage(bombingUnitDamage);
}
if (!isTemp) {
getData().getUnits().put(u);
}
return u;
}
use of games.strategy.triplea.TripleAUnit in project triplea by triplea-game.
the class BattleDelegate method resetMaxScrambleCount.
private static void resetMaxScrambleCount(final IDelegateBridge bridge) {
// reset the tripleaUnit property for all airbases that were used
final GameData data = bridge.getData();
if (!Properties.getScrambleRulesInEffect(data)) {
return;
}
final CompositeChange change = new CompositeChange();
for (final Territory t : data.getMap().getTerritories()) {
final Collection<Unit> airbases = t.getUnits().getMatches(Matches.unitIsAirBase());
for (final Unit u : airbases) {
final UnitAttachment ua = UnitAttachment.get(u.getType());
final int currentMax = ((TripleAUnit) u).getMaxScrambleCount();
final int allowedMax = ua.getMaxScrambleCount();
if (currentMax != allowedMax) {
change.add(ChangeFactory.unitPropertyChange(u, allowedMax, TripleAUnit.MAX_SCRAMBLE_COUNT));
}
}
}
if (!change.isEmpty()) {
bridge.getHistoryWriter().startEvent("Preparing Airbases for Possible Scrambling");
bridge.addChange(change);
}
}
use of games.strategy.triplea.TripleAUnit in project triplea by triplea-game.
the class BattleDelegate method getMaxScrambleCount.
public static int getMaxScrambleCount(final Collection<Unit> airbases) {
if (airbases.isEmpty() || !airbases.stream().allMatch(Matches.unitIsAirBase().and(Matches.unitIsNotDisabled()))) {
throw new IllegalStateException("All units must be viable airbases");
}
// find how many is the max this territory can scramble
int maxScrambled = 0;
for (final Unit base : airbases) {
final int baseMax = ((TripleAUnit) base).getMaxScrambleCount();
if (baseMax == -1) {
return Integer.MAX_VALUE;
}
maxScrambled += baseMax;
}
return maxScrambled;
}
use of games.strategy.triplea.TripleAUnit in project triplea by triplea-game.
the class BattleDelegate method landParatroopers.
private static void landParatroopers(final PlayerID player, final Territory battleSite, final IDelegateBridge bridge) {
if (TechTracker.hasParatroopers(player)) {
final Collection<Unit> airTransports = CollectionUtils.getMatches(battleSite.getUnits(), Matches.unitIsAirTransport());
final Collection<Unit> paratroops = CollectionUtils.getMatches(battleSite.getUnits(), Matches.unitIsAirTransportable());
if (!airTransports.isEmpty() && !paratroops.isEmpty()) {
final CompositeChange change = new CompositeChange();
for (final Unit u : paratroops) {
final TripleAUnit taUnit = (TripleAUnit) u;
final Unit transport = taUnit.getTransportedBy();
if (transport == null || !airTransports.contains(transport)) {
continue;
}
change.add(TransportTracker.unloadAirTransportChange(taUnit, battleSite, false));
}
if (!change.isEmpty()) {
bridge.getHistoryWriter().startEvent(player.getName() + " lands units in " + battleSite.getName());
bridge.addChange(change);
}
}
}
}
use of games.strategy.triplea.TripleAUnit in project triplea by triplea-game.
the class BattleTracker method captureOrDestroyUnits.
/**
* Called when a territory is conquered to determine if remaining enemy units should be
* captured, destroyed, or take damage.
*/
public static void captureOrDestroyUnits(final Territory territory, final PlayerID id, final PlayerID newOwner, final IDelegateBridge bridge, final UndoableMove changeTracker) {
final GameData data = bridge.getData();
// destroy any units that should be destroyed on capture
if (Properties.getUnitsCanBeDestroyedInsteadOfCaptured(data)) {
final Predicate<Unit> enemyToBeDestroyed = Matches.enemyUnit(id, data).and(Matches.unitDestroyedWhenCapturedByOrFrom(id));
final Collection<Unit> destroyed = territory.getUnits().getMatches(enemyToBeDestroyed);
if (!destroyed.isEmpty()) {
final Change destroyUnits = ChangeFactory.removeUnits(territory, destroyed);
bridge.getHistoryWriter().addChildToEvent("Some non-combat units are destroyed: ", destroyed);
bridge.addChange(destroyUnits);
if (changeTracker != null) {
changeTracker.addChange(destroyUnits);
}
}
}
// destroy any capture on entering units, IF the property to destroy them instead of capture is turned on
if (Properties.getOnEnteringUnitsDestroyedInsteadOfCaptured(data)) {
final Collection<Unit> destroyed = territory.getUnits().getMatches(Matches.unitCanBeCapturedOnEnteringToInThisTerritory(id, territory, data));
if (!destroyed.isEmpty()) {
final Change destroyUnits = ChangeFactory.removeUnits(territory, destroyed);
bridge.getHistoryWriter().addChildToEvent(id.getName() + " destroys some units instead of capturing them", destroyed);
bridge.addChange(destroyUnits);
if (changeTracker != null) {
changeTracker.addChange(destroyUnits);
}
}
}
// destroy any disabled units owned by the enemy that are NOT infrastructure or factories
final Predicate<Unit> enemyToBeDestroyed = Matches.enemyUnit(id, data).and(Matches.unitIsDisabled()).and(Matches.unitIsInfrastructure().negate());
final Collection<Unit> destroyed = territory.getUnits().getMatches(enemyToBeDestroyed);
if (!destroyed.isEmpty()) {
final Change destroyUnits = ChangeFactory.removeUnits(territory, destroyed);
bridge.getHistoryWriter().addChildToEvent(id.getName() + " destroys some disabled combat units", destroyed);
bridge.addChange(destroyUnits);
if (changeTracker != null) {
changeTracker.addChange(destroyUnits);
}
}
// take over non combatants
final Predicate<Unit> enemyNonCom = Matches.enemyUnit(id, data).and(Matches.unitIsInfrastructure());
final Predicate<Unit> willBeCaptured = enemyNonCom.or(Matches.unitCanBeCapturedOnEnteringToInThisTerritory(id, territory, data));
final Collection<Unit> nonCom = territory.getUnits().getMatches(willBeCaptured);
// change any units that change unit types on capture
if (Properties.getUnitsCanBeChangedOnCapture(data)) {
final Collection<Unit> toReplace = CollectionUtils.getMatches(nonCom, Matches.unitWhenCapturedChangesIntoDifferentUnitType());
for (final Unit u : toReplace) {
final Map<String, Tuple<String, IntegerMap<UnitType>>> map = UnitAttachment.get(u.getType()).getWhenCapturedChangesInto();
final PlayerID currentOwner = u.getOwner();
for (final String value : map.keySet()) {
final String[] s = value.split(":");
if (!(s[0].equals("any") || data.getPlayerList().getPlayerId(s[0]).equals(currentOwner))) {
continue;
}
// we could use "id" or "newOwner" here... not sure which to use
if (!(s[1].equals("any") || data.getPlayerList().getPlayerId(s[1]).equals(id))) {
continue;
}
final CompositeChange changes = new CompositeChange();
final Collection<Unit> toAdd = new ArrayList<>();
final Tuple<String, IntegerMap<UnitType>> toCreate = map.get(value);
final boolean translateAttributes = toCreate.getFirst().equalsIgnoreCase("true");
for (final UnitType ut : toCreate.getSecond().keySet()) {
toAdd.addAll(ut.create(toCreate.getSecond().getInt(ut), newOwner));
}
if (!toAdd.isEmpty()) {
if (translateAttributes) {
final Change translate = TripleAUnit.translateAttributesToOtherUnits(u, toAdd, territory);
if (!translate.isEmpty()) {
changes.add(translate);
}
}
changes.add(ChangeFactory.removeUnits(territory, Collections.singleton(u)));
changes.add(ChangeFactory.addUnits(territory, toAdd));
changes.add(ChangeFactory.markNoMovementChange(toAdd));
bridge.getHistoryWriter().addChildToEvent(id.getName() + " converts " + u.toStringNoOwner() + " into different units", toAdd);
bridge.addChange(changes);
if (changeTracker != null) {
changeTracker.addChange(changes);
}
// don't forget to remove this unit from the list
nonCom.remove(u);
break;
}
}
}
}
if (!nonCom.isEmpty()) {
// FYI: a dummy delegate will not do anything with this change,
// meaning that the battle calculator will think this unit lived,
// even though it died or was captured, etc!
final Change capture = ChangeFactory.changeOwner(nonCom, newOwner, territory);
bridge.addChange(capture);
if (changeTracker != null) {
changeTracker.addChange(capture);
}
final Change noMovementChange = ChangeFactory.markNoMovementChange(nonCom);
bridge.addChange(noMovementChange);
if (changeTracker != null) {
changeTracker.addChange(noMovementChange);
}
final IntegerMap<Unit> damageMap = new IntegerMap<>();
for (final Unit unit : CollectionUtils.getMatches(nonCom, Matches.unitWhenCapturedSustainsDamage())) {
final TripleAUnit taUnit = (TripleAUnit) unit;
final int damageLimit = taUnit.getHowMuchMoreDamageCanThisUnitTake(unit, territory);
final int sustainedDamage = UnitAttachment.get(unit.getType()).getWhenCapturedSustainsDamage();
final int actualDamage = Math.max(0, Math.min(sustainedDamage, damageLimit));
final int totalDamage = taUnit.getUnitDamage() + actualDamage;
damageMap.put(unit, totalDamage);
}
if (!damageMap.isEmpty()) {
final Change damageChange = ChangeFactory.bombingUnitDamage(damageMap);
bridge.addChange(damageChange);
if (changeTracker != null) {
changeTracker.addChange(damageChange);
}
// Kill any units that can die if they have reached max damage
if (damageMap.keySet().stream().anyMatch(Matches.unitCanDieFromReachingMaxDamage())) {
final List<Unit> unitsCanDie = CollectionUtils.getMatches(damageMap.keySet(), Matches.unitCanDieFromReachingMaxDamage());
unitsCanDie.retainAll(CollectionUtils.getMatches(unitsCanDie, Matches.unitIsAtMaxDamageOrNotCanBeDamaged(territory)));
if (!unitsCanDie.isEmpty()) {
final Change removeDead = ChangeFactory.removeUnits(territory, unitsCanDie);
bridge.addChange(removeDead);
if (changeTracker != null) {
changeTracker.addChange(removeDead);
}
}
}
}
}
}
Aggregations