-
Notifications
You must be signed in to change notification settings - Fork 41
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This patch makes the user interface look more consistent by sorting units in two contexts: * In the city dialog * In the unit picker The sorting logic is an improved version of code formerly used to sort units in the city dialog (but that had been lost for some reasion). It tries to produce a sort order that looks natural and is stable in time. To do so: * Loaded units are always sorted right after their transport, so one can tell in which transport they are loaded; * The best defensive units go to the beginning of the list. These tend to stay in cities and not move around too much; * Tie breaker by unit type and nationality ensure similar units are grouped together; * Finally, the unit id is used as a last resort. I tested this logic in a few contexts and it seems to achieve its goal. With respect to the previous sorting function, I removed an order based on unit activities (fortified, fortifying, sentried) because it felt wrong to have a unit move in the list just because I changed its activity. Closes #1836. See #1838.
- Loading branch information
Showing
8 changed files
with
128 additions
and
94 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
// SPDX-FileCopyrightText: Louis Moureaux <[email protected]> | ||
// SPDX-License-Identifier: GPLv3-or-later | ||
|
||
#include "unit_utils.h" | ||
|
||
#include "player.h" | ||
#include "unit.h" | ||
#include "unitlist.h" | ||
|
||
#include <algorithm> | ||
|
||
namespace /* anonymous */ { | ||
/** | ||
* Finds how deeply the unit is nested in transports. | ||
*/ | ||
int transport_depth(const unit *unit) | ||
{ | ||
int depth = 0; | ||
for (auto parent = unit->transporter; parent != nullptr; | ||
parent = parent->transporter) { | ||
depth++; | ||
} | ||
return depth; | ||
} | ||
|
||
/** | ||
* Comparison function to sort units. Used in the city dialog and the unit | ||
* selector. | ||
*/ | ||
bool units_sort(const unit *lhs, const unit *rhs) | ||
{ | ||
if (lhs == rhs) { | ||
return 0; | ||
} | ||
|
||
// Transports are shown before the units they transport. | ||
if (lhs == rhs->transporter) { | ||
return true; | ||
} else if (lhs->transporter == rhs) { | ||
return false; | ||
} | ||
|
||
// When one unit is deeper or the two transporters are different, compare | ||
// the parents instead. | ||
int lhs_depth = transport_depth(lhs); | ||
int rhs_depth = transport_depth(rhs); | ||
if (lhs_depth > rhs_depth) { | ||
return units_sort(lhs->transporter, rhs); | ||
} else if (lhs_depth < rhs_depth) { | ||
return units_sort(lhs, rhs->transporter); | ||
} else if (lhs->transporter != rhs->transporter) { | ||
return units_sort(lhs->transporter, rhs->transporter); | ||
} | ||
|
||
// Put defensive units on the left - these are least likely to move, having | ||
// them first makes the list more stable | ||
const auto lhs_def = lhs->utype->defense_strength * lhs->utype->hp; | ||
const auto rhs_def = rhs->utype->defense_strength * rhs->utype->hp; | ||
if (lhs_def != rhs_def) { | ||
return lhs_def > rhs_def; | ||
} | ||
|
||
// More veteran units further left | ||
if (lhs->veteran != rhs->veteran) { | ||
return lhs->veteran > rhs->veteran; | ||
} | ||
|
||
// Reverse order by unit type - in most ruleset this means old units last | ||
if (lhs->utype != rhs->utype) { | ||
return lhs->utype->item_number > rhs->utype->item_number; | ||
} | ||
|
||
// By nationality so units from the same player are grouped together | ||
if (player_index(lhs->nationality) != player_index(rhs->nationality)) { | ||
return player_index(lhs->nationality) < player_index(rhs->nationality); | ||
} | ||
|
||
// Then unit id | ||
return lhs->id < rhs->id; | ||
} | ||
} // anonymous namespace | ||
|
||
/** | ||
* Returns a version of \c units sorted in the way the user would like to see | ||
* them. | ||
*/ | ||
std::vector<unit *> sorted(const unit_list *units) | ||
{ | ||
std::vector<unit *> vec; | ||
unit_list_iterate(units, unit) { vec.push_back(unit); } | ||
unit_list_iterate_end; | ||
|
||
std::sort(vec.begin(), vec.end(), units_sort); | ||
|
||
return vec; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
// SPDX-FileCopyrightText: Louis Moureaux <[email protected]> | ||
// SPDX-License-Identifier: GPLv3-or-later | ||
|
||
#pragma once | ||
|
||
#include <vector> | ||
|
||
struct unit; | ||
struct unit_list; | ||
|
||
std::vector<unit *> sorted(const unit_list *units); |