use of games.strategy.engine.data.Unit in project triplea by triplea-game.
the class DiceRoll method rollAa.
static DiceRoll rollAa(final Collection<Unit> validAttackingUnitsForThisRoll, final Collection<Unit> defendingAaForThisRoll, final IDelegateBridge bridge, final Territory location, final boolean defending) {
{
final Set<Unit> duplicatesCheckSet1 = new HashSet<>(validAttackingUnitsForThisRoll);
if (validAttackingUnitsForThisRoll.size() != duplicatesCheckSet1.size()) {
throw new IllegalStateException("Duplicate Units Detected: Original List:" + validAttackingUnitsForThisRoll + " HashSet:" + duplicatesCheckSet1);
}
final Set<Unit> duplicatesCheckSet2 = new HashSet<>(defendingAaForThisRoll);
if (defendingAaForThisRoll.size() != duplicatesCheckSet2.size()) {
throw new IllegalStateException("Duplicate Units Detected: Original List:" + defendingAaForThisRoll + " HashSet:" + duplicatesCheckSet2);
}
}
final List<Unit> defendingAa = CollectionUtils.getMatches(defendingAaForThisRoll, (defending ? Matches.unitAttackAaIsGreaterThanZeroAndMaxAaAttacksIsNotZero() : Matches.unitOffensiveAttackAaIsGreaterThanZeroAndMaxAaAttacksIsNotZero()));
if (defendingAa.isEmpty()) {
return new DiceRoll(new ArrayList<>(0), 0, 0);
}
final GameData data = bridge.getData();
final int totalAAattacksTotal = getTotalAAattacks(defendingAa, validAttackingUnitsForThisRoll);
if (totalAAattacksTotal <= 0) {
return new DiceRoll(new ArrayList<>(0), 0, 0);
}
// determine dicesides for everyone (we are not going to consider the possibility of different dicesides within the
// same typeAA)
final Tuple<Integer, Integer> attackThenDiceSidesForAll = getAAattackAndMaxDiceSides(defendingAa, data, defending);
// final int highestAttackPower = attackThenDiceSidesForAll.getFirst();
final int chosenDiceSizeForAll = attackThenDiceSidesForAll.getSecond();
int hits = 0;
final List<Die> sortedDice = new ArrayList<>();
final String typeAa = UnitAttachment.get(defendingAa.get(0).getType()).getTypeAa();
// LOW LUCK
final Triple<Integer, Integer, Boolean> triple = getTotalAaPowerThenHitsAndFillSortedDiceThenIfAllUseSameAttack(null, null, defending, defendingAa, validAttackingUnitsForThisRoll, data, false);
final int totalPower = triple.getFirst();
if (Properties.getLowLuck(data) || Properties.getLowLuckAaOnly(data)) {
final String annotation = "Roll " + typeAa + " in " + location.getName();
hits += getLowLuckHits(bridge, sortedDice, totalPower, chosenDiceSizeForAll, defendingAa.get(0).getOwner(), annotation);
} else {
final String annotation = "Roll " + typeAa + " in " + location.getName();
final int[] dice = bridge.getRandom(chosenDiceSizeForAll, totalAAattacksTotal, defendingAa.get(0).getOwner(), DiceType.COMBAT, annotation);
hits += getTotalAaPowerThenHitsAndFillSortedDiceThenIfAllUseSameAttack(dice, sortedDice, defending, defendingAa, validAttackingUnitsForThisRoll, data, true).getSecond();
}
final double expectedHits = ((double) totalPower) / chosenDiceSizeForAll;
final DiceRoll roll = new DiceRoll(sortedDice, hits, expectedHits);
final String annotation = typeAa + " fire in " + location + " : " + MyFormatter.asDice(roll);
bridge.getHistoryWriter().addChildToEvent(annotation, roll);
return roll;
}
use of games.strategy.engine.data.Unit in project triplea by triplea-game.
the class DiceRoll method getTotalAAattacks.
static int getTotalAAattacks(final Collection<Unit> defendingEnemyAa, final Collection<Unit> validAttackingUnitsForThisRoll) {
if (defendingEnemyAa.isEmpty() || validAttackingUnitsForThisRoll.isEmpty()) {
return 0;
}
int totalAAattacksNormal = 0;
int totalAAattacksSurplus = 0;
for (final Unit aa : defendingEnemyAa) {
final UnitAttachment ua = UnitAttachment.get(aa.getType());
if (ua.getMaxAaAttacks() == -1) {
totalAAattacksNormal = validAttackingUnitsForThisRoll.size();
} else {
if (ua.getMayOverStackAa()) {
totalAAattacksSurplus += ua.getMaxAaAttacks();
} else {
totalAAattacksNormal += ua.getMaxAaAttacks();
}
}
}
totalAAattacksNormal = Math.min(totalAAattacksNormal, validAttackingUnitsForThisRoll.size());
return totalAAattacksNormal + totalAAattacksSurplus;
}
use of games.strategy.engine.data.Unit in project triplea by triplea-game.
the class DiceRoll method getSupport.
/**
* Fills a set and map with the support possibly given by these units.
*
* @param supportsAvailable
* an empty set that will be filled with all support rules grouped into lists of non-stacking rules
* @param supportLeft
* an empty map that will be filled with all the support that can be given in the form of counters
* @param supportUnitsLeft
* an empty map that will be filled with all the support that can be given in the form of counters
* @param defence
* are the receiving units defending?
* @param allies
* are the receiving units allied to the giving units?
*/
public static void getSupport(final List<Unit> unitsGivingTheSupport, final Set<List<UnitSupportAttachment>> supportsAvailable, final IntegerMap<UnitSupportAttachment> supportLeft, final Map<UnitSupportAttachment, LinkedIntegerMap<Unit>> supportUnitsLeft, final GameData data, final boolean defence, final boolean allies) {
if (unitsGivingTheSupport == null || unitsGivingTheSupport.isEmpty()) {
return;
}
for (final UnitSupportAttachment rule : UnitSupportAttachment.get(data)) {
if (rule.getPlayers().isEmpty()) {
continue;
}
if (!((defence && rule.getDefence()) || (!defence && rule.getOffence()))) {
continue;
}
if (!((allies && rule.getAllied()) || (!allies && rule.getEnemy()))) {
continue;
}
final Predicate<Unit> canSupport = Matches.unitIsOfType((UnitType) rule.getAttachedTo()).and(Matches.unitOwnedBy(rule.getPlayers()));
final List<Unit> supporters = CollectionUtils.getMatches(unitsGivingTheSupport, canSupport);
int numSupport = supporters.size();
if (numSupport <= 0) {
continue;
}
final List<Unit> impArtTechUnits = new ArrayList<>();
if (rule.getImpArtTech()) {
impArtTechUnits.addAll(CollectionUtils.getMatches(supporters, Matches.unitOwnerHasImprovedArtillerySupportTech()));
}
numSupport += impArtTechUnits.size();
supportLeft.put(rule, numSupport * rule.getNumber());
supportUnitsLeft.put(rule, new LinkedIntegerMap<>(supporters, rule.getNumber()));
supportUnitsLeft.get(rule).addAll(impArtTechUnits, rule.getNumber());
final Iterator<List<UnitSupportAttachment>> iter2 = supportsAvailable.iterator();
List<UnitSupportAttachment> ruleType = null;
boolean found = false;
final String bonusType = rule.getBonusType();
while (iter2.hasNext()) {
ruleType = iter2.next();
if (ruleType.get(0).getBonusType().equals(bonusType)) {
found = true;
break;
}
}
if (!found) {
ruleType = new ArrayList<>();
supportsAvailable.add(ruleType);
}
if (ruleType != null) {
ruleType.add(rule);
}
}
sortSupportRules(supportsAvailable, defence, allies);
}
use of games.strategy.engine.data.Unit in project triplea by triplea-game.
the class EditDelegate method changeUnitHitDamage.
@Override
public String changeUnitHitDamage(final IntegerMap<Unit> unitDamageMap, final Territory territory) {
String result = checkEditMode();
if (result != null) {
return result;
}
result = EditValidator.validateChangeHitDamage(getData(), unitDamageMap, territory);
if (result != null) {
return result;
}
// remove anyone who is the same
final Collection<Unit> units = new ArrayList<>(unitDamageMap.keySet());
for (final Unit u : units) {
final int dmg = unitDamageMap.getInt(u);
if (u.getHits() == dmg) {
unitDamageMap.removeKey(u);
}
}
if (unitDamageMap.isEmpty()) {
return null;
}
final Collection<Unit> unitsFinal = new ArrayList<>(unitDamageMap.keySet());
logEvent("Changing unit hit damage for these " + unitsFinal.iterator().next().getOwner().getName() + " owned units to: " + MyFormatter.integerUnitMapToString(unitDamageMap, ", ", " = ", false), unitsFinal);
bridge.addChange(ChangeFactory.unitsHit(unitDamageMap));
// territory.notifyChanged();
return null;
}
use of games.strategy.engine.data.Unit in project triplea by triplea-game.
the class EditDelegate method changeTerritoryOwner.
@Override
public String changeTerritoryOwner(final Territory territory, final PlayerID player) {
String result = checkEditMode();
if (result != null) {
return result;
}
final GameData data = getData();
// validate this edit
result = EditValidator.validateChangeTerritoryOwner(data, territory);
if (result != null) {
return result;
}
logEvent("Changing ownership of " + territory.getName() + " from " + territory.getOwner().getName() + " to " + player.getName(), territory);
if (!data.getRelationshipTracker().isAtWar(territory.getOwner(), player)) {
// change ownership of friendly factories
final Collection<Unit> units = territory.getUnits().getMatches(Matches.unitIsInfrastructure());
for (final Unit unit : units) {
bridge.addChange(ChangeFactory.changeOwner(unit, player, territory));
}
} else {
final Predicate<Unit> enemyNonCom = Matches.unitIsInfrastructure().and(Matches.enemyUnit(player, data));
final Collection<Unit> units = territory.getUnits().getMatches(enemyNonCom);
// mark no movement for enemy units
bridge.addChange(ChangeFactory.markNoMovementChange(units));
// change ownership of enemy AA and factories
for (final Unit unit : units) {
bridge.addChange(ChangeFactory.changeOwner(unit, player, territory));
}
}
// change ownership of territory
bridge.addChange(ChangeFactory.changeOwner(territory, player));
return null;
}
Aggregations