use of games.strategy.engine.data.Territory 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;
}
use of games.strategy.engine.data.Territory 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.Territory 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.Territory 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.Territory in project triplea by triplea-game.
the class AbstractEndTurnDelegate method start.
@Override
public void start() {
// figure out our current PUs before we do anything else, including super methods
final GameData data = bridge.getData();
final Resource pus = data.getResourceList().getResource(Constants.PUS);
final int leftOverPUs = bridge.getPlayerId().getResources().getQuantity(pus);
final IntegerMap<Resource> leftOverResources = bridge.getPlayerId().getResources().getResourcesCopy();
super.start();
if (!needToInitialize) {
return;
}
final StringBuilder endTurnReport = new StringBuilder();
hasPostedTurnSummary = false;
final PlayerAttachment pa = PlayerAttachment.get(player);
// can't collect unless you own your own capital
if (!canPlayerCollectIncome(player, data)) {
endTurnReport.append(rollWarBondsForFriends(bridge, player, data));
// we do not collect any income this turn
} else {
// just collect resources
final Collection<Territory> territories = data.getMap().getTerritoriesOwnedBy(player);
int toAdd = getProduction(territories);
final int blockadeLoss = getBlockadeProductionLoss(player, data, bridge, endTurnReport);
toAdd -= blockadeLoss;
toAdd *= Properties.getPuMultiplier(data);
int total = player.getResources().getQuantity(pus) + toAdd;
final String transcriptText;
if (blockadeLoss == 0) {
transcriptText = player.getName() + " collect " + toAdd + MyFormatter.pluralize(" PU", toAdd) + "; end with " + total + MyFormatter.pluralize(" PU", total);
} else {
transcriptText = player.getName() + " collect " + toAdd + MyFormatter.pluralize(" PU", toAdd) + " (" + blockadeLoss + " lost to blockades)" + "; end with " + total + MyFormatter.pluralize(" PU", total);
}
bridge.getHistoryWriter().startEvent(transcriptText);
endTurnReport.append(transcriptText).append("<br />");
// do war bonds
final int bonds = rollWarBonds(bridge, player, data);
if (bonds > 0) {
total += bonds;
toAdd += bonds;
final String bondText = player.getName() + " collect " + bonds + MyFormatter.pluralize(" PU", bonds) + " from War Bonds; end with " + total + MyFormatter.pluralize(" PU", total);
bridge.getHistoryWriter().startEvent(bondText);
endTurnReport.append("<br />").append(bondText).append("<br />");
}
if (total < 0) {
toAdd -= total;
}
final Change change = ChangeFactory.changeResourcesChange(player, pus, toAdd);
bridge.addChange(change);
if (data.getProperties().get(Constants.PACIFIC_THEATER, false) && pa != null) {
final Change changeVp = (ChangeFactory.attachmentPropertyChange(pa, (pa.getVps() + (toAdd / 10) + (pa.getCaptureVps() / 10)), "vps"));
final Change changeCaptureVp = ChangeFactory.attachmentPropertyChange(pa, "0", "captureVps");
final CompositeChange ccVp = new CompositeChange(changeVp, changeCaptureVp);
bridge.addChange(ccVp);
}
endTurnReport.append("<br />").append(addOtherResources(bridge));
endTurnReport.append("<br />").append(doNationalObjectivesAndOtherEndTurnEffects(bridge));
final IntegerMap<Resource> income = player.getResources().getResourcesCopy();
income.subtract(leftOverResources);
endTurnReport.append("<br />").append(BonusIncomeUtils.addBonusIncome(income, bridge, player));
// now we do upkeep costs, including upkeep cost as a percentage of our entire income for this turn (including
// NOs)
final int currentPUs = player.getResources().getQuantity(pus);
int relationshipUpkeepCostFlat = 0;
int relationshipUpkeepCostPercentage = 0;
for (final Relationship r : data.getRelationshipTracker().getRelationships(player)) {
final String[] upkeep = r.getRelationshipType().getRelationshipTypeAttachment().getUpkeepCost().split(":");
if (upkeep.length == 1 || upkeep[1].equals(RelationshipTypeAttachment.UPKEEP_FLAT)) {
relationshipUpkeepCostFlat += Integer.parseInt(upkeep[0]);
} else if (upkeep[1].equals(RelationshipTypeAttachment.UPKEEP_PERCENTAGE)) {
relationshipUpkeepCostPercentage += Integer.parseInt(upkeep[0]);
}
}
relationshipUpkeepCostPercentage = Math.min(100, relationshipUpkeepCostPercentage);
int relationshipUpkeepTotalCost = 0;
if (relationshipUpkeepCostPercentage != 0) {
final float gainedPus = Math.max(0, currentPUs - leftOverPUs);
relationshipUpkeepTotalCost += Math.round(gainedPus * (relationshipUpkeepCostPercentage) / 100f);
}
if (relationshipUpkeepCostFlat != 0) {
relationshipUpkeepTotalCost += relationshipUpkeepCostFlat;
}
// we can't remove more than we have, and we also must flip the sign
relationshipUpkeepTotalCost = Math.min(currentPUs, relationshipUpkeepTotalCost);
relationshipUpkeepTotalCost = -1 * relationshipUpkeepTotalCost;
if (relationshipUpkeepTotalCost != 0) {
final int newTotal = currentPUs + relationshipUpkeepTotalCost;
final String transcriptText2 = player.getName() + (relationshipUpkeepTotalCost < 0 ? " pays " : " taxes ") + (-1 * relationshipUpkeepTotalCost) + MyFormatter.pluralize(" PU", relationshipUpkeepTotalCost) + " in order to maintain current relationships with other players, and ends the turn with " + newTotal + MyFormatter.pluralize(" PU", newTotal);
bridge.getHistoryWriter().startEvent(transcriptText2);
endTurnReport.append("<br />").append(transcriptText2).append("<br />");
final Change upkeep = ChangeFactory.changeResourcesChange(player, pus, relationshipUpkeepTotalCost);
bridge.addChange(upkeep);
}
}
if (GameStepPropertiesHelper.isRepairUnits(data)) {
MoveDelegate.repairMultipleHitPointUnits(bridge, bridge.getPlayerId());
}
if (isGiveUnitsByTerritory() && pa != null && pa.getGiveUnitControl() != null && !pa.getGiveUnitControl().isEmpty()) {
changeUnitOwnership(bridge);
}
needToInitialize = false;
showEndTurnReport(endTurnReport.toString());
}
Aggregations