Skip to content

Commit

Permalink
Battle Calculator: Allow fighting any player (#9532)
Browse files Browse the repository at this point in the history
* Battle Calculator: Allow fighting any player

When changing a player, do not set the other player automatically to an
enemy.  This allows fights between any two players.  Moreover, it does
not erase the battle configuration in case of a misclick.

* Battle Calculator: Mimic legacy behaviour for intial setup

Mimic the legacy behaviour and force the two parties in the initial
setup to be non-allied.  This legacy behaviour was requested in #9532.
  • Loading branch information
emmanuel-perlow authored Sep 11, 2021
1 parent b95d166 commit 59e2681
Showing 1 changed file with 24 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -954,14 +954,6 @@ class BattleCalculatorPanel extends JPanel {

defenderCombo.addActionListener(
e -> {
data.acquireReadLock();
try {
if (data.getRelationshipTracker().isAllied(getDefender(), getAttacker())) {
attackerCombo.setSelectedItem(getEnemy(getDefender()));
}
} finally {
data.releaseReadLock();
}
setDefendingUnits(
defendingUnitsPanel.getUnits().stream().anyMatch(Matches.unitIsOwnedBy(getDefender()))
? defendingUnitsPanel.getUnits()
Expand All @@ -970,14 +962,6 @@ class BattleCalculatorPanel extends JPanel {
});
attackerCombo.addActionListener(
e -> {
data.acquireReadLock();
try {
if (data.getRelationshipTracker().isAllied(getDefender(), getAttacker())) {
defenderCombo.setSelectedItem(getEnemy(getAttacker()));
}
} finally {
data.releaseReadLock();
}
setAttackingUnits(null);
setWidgetActivation();
});
Expand Down Expand Up @@ -1109,6 +1093,19 @@ class BattleCalculatorPanel extends JPanel {
}
}

// In the above code, if the territory owner and the current player are the same, then
// attacker and defender are. Since we cannot infer whether the user wants to defend the
// territory or attack with the units in that territory, we cannot refine this setup
// further. To not break the user's habits, we solve this by falling back to the legacy
// behaviour and force the attacker and defender to be on non-allied teams.
if (data.getRelationshipTracker().isAllied(getDefender(), getAttacker())) {
if (location.isWater() && players.isEmpty()) {
getEnemy(getAttacker()).ifPresent(this::setDefender);
} else {
getEnemy(getDefender()).ifPresent(this::setAttacker);
}
}

setAttackingUnits(
location.getUnitCollection().getMatches(Matches.unitIsOwnedBy(getAttacker())));
setDefendingUnits(
Expand Down Expand Up @@ -1377,19 +1374,25 @@ private boolean isLand() {
return landBattleCheckBox.isSelected();
}

private GamePlayer getEnemy(final GamePlayer player) {
/**
* Get a suitable enemy for {@code player}. First checks for players at war, if none found, checks
* for non-allied players, if still no foe was found, returns an empty Optional.
*
* @param player the player to find a foe for
* @return Optional with not an ally or an empty Optional
*/
private Optional<GamePlayer> getEnemy(final GamePlayer player) {
for (final GamePlayer gamePlayer : data.getPlayerList()) {
if (data.getRelationshipTracker().isAtWar(player, gamePlayer)) {
return gamePlayer;
return Optional.of(gamePlayer);
}
}
for (final GamePlayer gamePlayer : data.getPlayerList()) {
if (!data.getRelationshipTracker().isAllied(player, gamePlayer)) {
return gamePlayer;
return Optional.of(gamePlayer);
}
}
// TODO: do we allow fighting allies in the battle calc?
throw new IllegalStateException("No enemies or non-allies for :" + player);
return Optional.empty();
}

private void setResultsToBlank() {
Expand Down

0 comments on commit 59e2681

Please sign in to comment.