use of games.strategy.engine.data.UnitType in project triplea by triplea-game.
the class SpecialMoveDelegate method allowAirborne.
private static boolean allowAirborne(final PlayerID player, final GameData data) {
if (!TechAbilityAttachment.getAllowAirborneForces(player, data)) {
return false;
}
final int airborneDistance = TechAbilityAttachment.getAirborneDistance(player, data);
final Set<UnitType> airborneBases = TechAbilityAttachment.getAirborneBases(player, data);
final Set<UnitType> airborneTypes = TechAbilityAttachment.getAirborneTypes(player, data);
if (airborneDistance <= 0 || airborneBases.isEmpty() || airborneTypes.isEmpty()) {
return false;
}
final GameMap map = data.getMap();
final Collection<PlayerID> alliesForBases = data.getRelationshipTracker().getAllies(player, true);
final Collection<Territory> territoriesWeCanLaunchFrom = CollectionUtils.getMatches(map.getTerritories(), Matches.territoryHasUnitsThatMatch(getAirborneMatch(airborneBases, alliesForBases)));
return !territoriesWeCanLaunchFrom.isEmpty();
}
use of games.strategy.engine.data.UnitType in project triplea by triplea-game.
the class SpecialMoveDelegate method validateAirborneMovements.
private static MoveValidationResult validateAirborneMovements(final GameData data, final Collection<Unit> units, final Route route, final PlayerID player, final MoveValidationResult result) {
if (!TechAbilityAttachment.getAllowAirborneForces(player, data)) {
return result.setErrorReturnResult("Do Not Have Airborne Tech");
}
final int airborneDistance = TechAbilityAttachment.getAirborneDistance(player, data);
final Set<UnitType> airborneBases = TechAbilityAttachment.getAirborneBases(player, data);
final Set<UnitType> airborneTypes = TechAbilityAttachment.getAirborneTypes(player, data);
if (airborneDistance <= 0 || airborneBases.isEmpty() || airborneTypes.isEmpty()) {
return result.setErrorReturnResult("Require Airborne Forces And Launch Capacity Tech");
}
if (route.numberOfSteps() > airborneDistance) {
return result.setErrorReturnResult("Destination Is Out Of Range");
}
final Collection<PlayerID> alliesForBases = data.getRelationshipTracker().getAllies(player, true);
final Predicate<Unit> airborneBaseMatch = getAirborneMatch(airborneBases, alliesForBases);
final Territory start = route.getStart();
final Territory end = route.getEnd();
final Collection<Unit> basesAtStart = start.getUnits().getMatches(airborneBaseMatch);
if (basesAtStart.isEmpty()) {
return result.setErrorReturnResult("Require Airborne Base At Originating Territory");
}
final int airborneCapacity = TechAbilityAttachment.getAirborneCapacity(basesAtStart, player, data);
if (airborneCapacity <= 0) {
return result.setErrorReturnResult("Airborne Bases Must Have Launch Capacity");
} else if (airborneCapacity < units.size()) {
final Collection<Unit> overMax = new ArrayList<>(units);
overMax.removeAll(CollectionUtils.getNMatches(units, airborneCapacity, Matches.always()));
for (final Unit u : overMax) {
result.addDisallowedUnit("Airborne Base Capacity Has Been Reached", u);
}
}
final Collection<Unit> airborne = new ArrayList<>();
for (final Unit u : units) {
if (!Matches.unitIsOwnedBy(player).test(u)) {
result.addDisallowedUnit("Must Own All Airborne Forces", u);
} else if (!Matches.unitIsOfTypes(airborneTypes).test(u)) {
result.addDisallowedUnit("Can Only Launch Airborne Forces", u);
} else if (Matches.unitIsDisabled().test(u)) {
result.addDisallowedUnit("Must Not Be Disabled", u);
} else if (!Matches.unitHasNotMoved().test(u)) {
result.addDisallowedUnit("Must Not Have Previously Moved Airborne Forces", u);
} else if (Matches.unitIsAirborne().test(u)) {
result.addDisallowedUnit("Cannot Move Units Already Airborne", u);
} else {
airborne.add(u);
}
}
if (airborne.isEmpty()) {
return result;
}
final BattleTracker battleTracker = AbstractMoveDelegate.getBattleTracker(data);
final boolean onlyWhereUnderAttackAlready = Properties.getAirborneAttacksOnlyInExistingBattles(data);
final boolean onlyEnemyTerritories = Properties.getAirborneAttacksOnlyInEnemyTerritories(data);
final List<Territory> steps = route.getSteps();
if (steps.isEmpty() || !steps.stream().allMatch(Matches.territoryIsPassableAndNotRestricted(player, data))) {
return result.setErrorReturnResult("May Not Fly Over Impassable or Restricted Territories");
}
if (steps.isEmpty() || !steps.stream().allMatch(Matches.territoryAllowsCanMoveAirUnitsOverOwnedLand(player, data))) {
return result.setErrorReturnResult("May Only Fly Over Territories Where Air May Move");
}
final boolean someLand = airborne.stream().anyMatch(Matches.unitIsLand());
final boolean someSea = airborne.stream().anyMatch(Matches.unitIsSea());
final boolean land = Matches.territoryIsLand().test(end);
final boolean sea = Matches.territoryIsWater().test(end);
if (someLand && someSea) {
return result.setErrorReturnResult("Cannot Mix Land and Sea Units");
} else if (someLand) {
if (!land) {
return result.setErrorReturnResult("Cannot Move Land Units To Sea");
}
} else if (someSea) {
if (!sea) {
return result.setErrorReturnResult("Cannot Move Sea Units To Land");
}
}
if (onlyWhereUnderAttackAlready) {
if (!battleTracker.getConquered().contains(end)) {
final IBattle battle = battleTracker.getPendingBattle(end, false, BattleType.NORMAL);
if (battle == null) {
return result.setErrorReturnResult("Airborne May Only Attack Territories Already Under Assault");
} else if (land && someLand && battle.getAttackingUnits().stream().noneMatch(Matches.unitIsLand())) {
return result.setErrorReturnResult("Battle Must Have Some Land Units Participating Already");
} else if (sea && someSea && battle.getAttackingUnits().stream().noneMatch(Matches.unitIsSea())) {
return result.setErrorReturnResult("Battle Must Have Some Sea Units Participating Already");
}
}
} else if (onlyEnemyTerritories) {
if (!(Matches.isTerritoryEnemyAndNotUnownedWater(player, data).test(end) || Matches.territoryHasEnemyUnits(player, data).test(end))) {
return result.setErrorReturnResult("Destination Must Be Enemy Or Contain Enemy Units");
}
}
return result;
}
use of games.strategy.engine.data.UnitType in project triplea by triplea-game.
the class StrategicBombingRaidBattle method removeAaHits.
private void removeAaHits(final IDelegateBridge bridge, final CasualtyDetails casualties, final String currentTypeAa) {
final List<Unit> killed = casualties.getKilled();
if (!killed.isEmpty()) {
bridge.getHistoryWriter().addChildToEvent(MyFormatter.unitsToTextNoOwner(killed) + " killed by " + currentTypeAa, new ArrayList<>(killed));
final IntegerMap<UnitType> costs = TuvUtils.getCostsForTuv(m_attacker, m_data);
final int tuvLostAttacker = TuvUtils.getTuv(killed, m_attacker, costs, m_data);
m_attackerLostTUV += tuvLostAttacker;
// m_attackingUnits.removeAll(casualties);
removeAttackers(killed, false);
final Change remove = ChangeFactory.removeUnits(m_battleSite, killed);
bridge.addChange(remove);
}
}
use of games.strategy.engine.data.UnitType in project triplea by triplea-game.
the class PlayerUnitsPanel method init.
/**
* Sets up components to an initial state.
*/
public void init(final PlayerID id, final List<Unit> units, final boolean land) {
isLand = land;
categories = new ArrayList<>(categorize(id, units));
categories.sort(Comparator.comparing(UnitCategory::getType, (ut1, ut2) -> {
final UnitAttachment u1 = UnitAttachment.get(ut1);
final UnitAttachment u2 = UnitAttachment.get(ut2);
// For land battles, sort by land, air, can't combat move (AA), bombarding
if (land) {
if (u1.getIsSea() != u2.getIsSea()) {
return u1.getIsSea() ? 1 : -1;
}
final boolean u1CanNotCombatMove = Matches.unitTypeCanNotMoveDuringCombatMove().test(ut1) || !Matches.unitTypeCanMove(id).test(ut1);
final boolean u2CanNotCombatMove = Matches.unitTypeCanNotMoveDuringCombatMove().test(ut2) || !Matches.unitTypeCanMove(id).test(ut2);
if (u1CanNotCombatMove != u2CanNotCombatMove) {
return u1CanNotCombatMove ? 1 : -1;
}
if (u1.getIsAir() != u2.getIsAir()) {
return u1.getIsAir() ? 1 : -1;
}
} else {
if (u1.getIsSea() != u2.getIsSea()) {
return u1.getIsSea() ? -1 : 1;
}
}
return u1.getName().compareTo(u2.getName());
}));
removeAll();
final Predicate<UnitType> predicate;
if (land) {
if (defender) {
predicate = Matches.unitTypeIsNotSea();
} else {
predicate = Matches.unitTypeIsNotSea().or(Matches.unitTypeCanBombard(id));
}
} else {
predicate = Matches.unitTypeIsSeaOrAir();
}
final IntegerMap<UnitType> costs;
try {
data.acquireReadLock();
costs = TuvUtils.getCostsForTuv(id, data);
} finally {
data.releaseReadLock();
}
for (final UnitCategory category : categories) {
if (predicate.test(category.getType())) {
final UnitPanel upanel = new UnitPanel(uiContext, category, costs);
upanel.addChangeListener(this::notifyListeners);
add(upanel);
}
}
// TODO: probably do not need to do this much revalidation.
invalidate();
validate();
revalidate();
getParent().invalidate();
}
use of games.strategy.engine.data.UnitType in project triplea by triplea-game.
the class OddsCalculatorPanel method setWidgetActivation.
private void setWidgetActivation() {
keepOneAttackingLandUnitCheckBox.setEnabled(landBattleCheckBox.isSelected());
amphibiousCheckBox.setEnabled(landBattleCheckBox.isSelected());
final boolean isLand = isLand();
try {
data.acquireReadLock();
// do not include bombardment and aa guns in our "total" labels
final List<Unit> attackers = CollectionUtils.getMatches(attackingUnitsPanel.getUnits(), Matches.unitCanBeInBattle(true, isLand, 1, false, true, true));
final List<Unit> defenders = CollectionUtils.getMatches(defendingUnitsPanel.getUnits(), Matches.unitCanBeInBattle(false, isLand, 1, false, true, true));
attackerUnitsTotalNumber.setText("Units: " + attackers.size());
defenderUnitsTotalNumber.setText("Units: " + defenders.size());
attackerUnitsTotalTuv.setText("TUV: " + TuvUtils.getTuv(attackers, getAttacker(), TuvUtils.getCostsForTuv(getAttacker(), data), data));
defenderUnitsTotalTuv.setText("TUV: " + TuvUtils.getTuv(defenders, getDefender(), TuvUtils.getCostsForTuv(getDefender(), data), data));
final int attackHitPoints = BattleCalculator.getTotalHitpointsLeft(attackers);
final int defenseHitPoints = BattleCalculator.getTotalHitpointsLeft(defenders);
attackerUnitsTotalHitpoints.setText("HP: " + attackHitPoints);
defenderUnitsTotalHitpoints.setText("HP: " + defenseHitPoints);
final boolean isAmphibiousBattle = isAmphibiousBattle();
final Collection<TerritoryEffect> territoryEffects = getTerritoryEffects();
final IntegerMap<UnitType> costs = TuvUtils.getCostsForTuv(getAttacker(), data);
attackers.sort(new UnitBattleComparator(false, costs, territoryEffects, data, false, false));
Collections.reverse(attackers);
final int attackPower = DiceRoll.getTotalPower(DiceRoll.getUnitPowerAndRollsForNormalBattles(attackers, defenders, false, false, data, location, territoryEffects, isAmphibiousBattle, (isAmphibiousBattle ? attackers : new ArrayList<>())), data);
// defender is never amphibious
final int defensePower = DiceRoll.getTotalPower(DiceRoll.getUnitPowerAndRollsForNormalBattles(defenders, attackers, true, false, data, location, territoryEffects, isAmphibiousBattle, new ArrayList<>()), data);
attackerUnitsTotalPower.setText("Power: " + attackPower);
defenderUnitsTotalPower.setText("Power: " + defensePower);
} finally {
data.releaseReadLock();
}
}
Aggregations