Refactor team_data usage and fix issue with Game Stats's Scroll To functionality
This removes unnecessary struct members that can be accessed directly from the team class and fixes an issue where hidden teams could cause the Game Stats dialog to break when scrolling to leader (fixes #4029)
This commit is contained in:
parent
884439730c
commit
a0d82528e7
7 changed files with 41 additions and 55 deletions
|
@ -159,15 +159,11 @@ int display_context::side_upkeep(int side) const
|
|||
return res;
|
||||
}
|
||||
|
||||
team_data display_context::calculate_team_data(const team& tm) const
|
||||
team_data::team_data(const display_context& dc, const team& tm)
|
||||
: side(tm.side())
|
||||
, units(dc.side_units(side))
|
||||
, upkeep(dc.side_upkeep(side))
|
||||
, expenses(std::max<int>(0, upkeep - tm.support()))
|
||||
, net_income(tm.total_income() - expenses)
|
||||
{
|
||||
team_data res;
|
||||
res.units = side_units(tm.side());
|
||||
res.upkeep = side_upkeep(tm.side());
|
||||
res.villages = tm.villages().size();
|
||||
res.expenses = std::max<int>(0,res.upkeep - tm.support());
|
||||
res.net_income = tm.total_income() - res.expenses;
|
||||
res.gold = tm.gold();
|
||||
res.teamname = tm.user_team_name();
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -31,24 +31,8 @@ class unit_map;
|
|||
class unit;
|
||||
struct map_location;
|
||||
|
||||
struct team_data
|
||||
class display_context
|
||||
{
|
||||
team_data() :
|
||||
units(0),
|
||||
upkeep(0),
|
||||
villages(0),
|
||||
expenses(0),
|
||||
net_income(0),
|
||||
gold(0),
|
||||
teamname()
|
||||
{
|
||||
}
|
||||
|
||||
int units, upkeep, villages, expenses, net_income, gold;
|
||||
std::string teamname;
|
||||
};
|
||||
|
||||
class display_context {
|
||||
public:
|
||||
virtual const std::vector<team> & teams() const = 0;
|
||||
virtual const gamemap & map() const = 0;
|
||||
|
@ -99,8 +83,6 @@ public:
|
|||
|
||||
int side_upkeep(int side_num) const ;
|
||||
|
||||
team_data calculate_team_data(const class team& tm) const;
|
||||
|
||||
// Accessor from team.cpp
|
||||
|
||||
/// Check if we are an observer in this game
|
||||
|
@ -110,3 +92,10 @@ public:
|
|||
|
||||
virtual ~display_context() {}
|
||||
};
|
||||
|
||||
struct team_data
|
||||
{
|
||||
team_data(const display_context& dc, const team& tm);
|
||||
|
||||
int side = 0, units = 0, upkeep = 0, expenses = 0, net_income = 0;
|
||||
};
|
||||
|
|
|
@ -48,14 +48,11 @@ namespace dialogs
|
|||
|
||||
REGISTER_DIALOG(game_stats)
|
||||
|
||||
game_stats::game_stats(const display_context& board, const int viewing_team, int& selected_index)
|
||||
game_stats::game_stats(const display_context& board, const int viewing_team, int& selected_side_number)
|
||||
: board_(board)
|
||||
, viewing_team_(board_.teams()[viewing_team])
|
||||
, selected_index_(selected_index)
|
||||
, selected_side_number_(selected_side_number)
|
||||
{
|
||||
for(const auto& team : board_.teams()) {
|
||||
team_data_.push_back(board_.calculate_team_data(team));
|
||||
}
|
||||
}
|
||||
|
||||
unit_const_ptr game_stats::get_leader(const int side)
|
||||
|
@ -85,13 +82,15 @@ void game_stats::pre_show(window& window)
|
|||
continue;
|
||||
}
|
||||
|
||||
team_data_.emplace_back(board_, team);
|
||||
|
||||
std::map<std::string, string_map> row_data_stats;
|
||||
string_map column_stats;
|
||||
|
||||
const bool known = viewing_team_.knows_about_team(team.side() - 1);
|
||||
const bool enemy = viewing_team_.is_enemy(team.side());
|
||||
|
||||
const team_data& data = team_data_[team.side() - 1];
|
||||
const team_data& data = team_data_.back();
|
||||
|
||||
unit_const_ptr leader = get_leader(team.side());
|
||||
|
||||
|
@ -130,20 +129,20 @@ void game_stats::pre_show(window& window)
|
|||
column_stats["label"] = leader_name + "\n" + controller_name(team);
|
||||
row_data_stats.emplace("team_leader_name", column_stats);
|
||||
|
||||
column_stats["label"] = data.teamname.empty() ? team.team_name() : data.teamname;
|
||||
column_stats["label"] = team.user_team_name().empty() ? team.team_name() : team.user_team_name();
|
||||
row_data_stats.emplace("team_name", column_stats);
|
||||
|
||||
// Only fill in the rest of the info if the side is known...
|
||||
if(known || game_config::debug) {
|
||||
std::string gold_str;
|
||||
if(game_config::debug || !enemy || !viewing_team_.uses_fog()) {
|
||||
gold_str = utils::half_signed_value(data.gold);
|
||||
gold_str = utils::half_signed_value(team.gold());
|
||||
}
|
||||
|
||||
column_stats["label"] = data.gold < 0 ? "<span color='#ff0000'>" + gold_str + "</span>" : gold_str;
|
||||
column_stats["label"] = team.gold() < 0 ? "<span color='#ff0000'>" + gold_str + "</span>" : gold_str;
|
||||
row_data_stats.emplace("team_gold", column_stats);
|
||||
|
||||
std::string village_count = std::to_string(data.villages);
|
||||
std::string village_count = std::to_string(team.villages().size());
|
||||
if(!viewing_team_.uses_fog() && !viewing_team_.uses_shroud()) {
|
||||
village_count += "/" + std::to_string(board_.map().villages().size());
|
||||
}
|
||||
|
@ -205,7 +204,8 @@ void game_stats::pre_show(window& window)
|
|||
// Sorting options for the status list
|
||||
stats_list.register_translatable_sorting_option(0, [this](const int i) {
|
||||
unit_const_ptr leader = get_leader(i + 1);
|
||||
return leader ? leader->name().str() : ""; });
|
||||
return leader ? leader->name().str() : "";
|
||||
});
|
||||
|
||||
stats_list.register_translatable_sorting_option(1, [this](const int i) {
|
||||
return board_.teams()[i].user_team_name().str(); });
|
||||
|
@ -218,7 +218,8 @@ void game_stats::pre_show(window& window)
|
|||
// Sorting options for the settings list
|
||||
settings_list.register_translatable_sorting_option(0, [this](const int i) {
|
||||
unit_const_ptr leader = get_leader(i + 1);
|
||||
return leader ? leader->name().str() : ""; });
|
||||
return leader ? leader->name().str() : "";
|
||||
});
|
||||
|
||||
settings_list.register_sorting_option(1, [this](const int i) { return board_.teams()[i].side(); });
|
||||
settings_list.register_sorting_option(2, [this](const int i) { return board_.teams()[i].start_gold(); });
|
||||
|
@ -258,7 +259,7 @@ void game_stats::post_show(window& window)
|
|||
const int selected_tab = find_widget<listbox>(&window, "tab_bar", false).get_selected_row();
|
||||
|
||||
const std::string list_id = selected_tab == 0 ? "game_stats_list" : "scenario_settings_list";
|
||||
selected_index_ = find_widget<listbox>(&window, list_id, false).get_selected_row();
|
||||
selected_side_number_ = team_data_[find_widget<listbox>(&window, list_id, false).get_selected_row()].side;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -35,16 +35,16 @@ namespace dialogs
|
|||
class game_stats : public modal_dialog
|
||||
{
|
||||
public:
|
||||
game_stats(const display_context& board, const int viewing_team, int& selected_index);
|
||||
game_stats(const display_context& board, const int viewing_team, int& selected_side_number);
|
||||
|
||||
static bool execute(game_board& board, const int viewing_team, int& selected_index)
|
||||
static bool execute(game_board& board, const int viewing_team, int& selected_side_number)
|
||||
{
|
||||
if(std::all_of(board.teams().begin(), board.teams().end(), [](team& team) { return team.hidden(); })) {
|
||||
show_transient_message("", _("No visible sides found."));
|
||||
return false;
|
||||
}
|
||||
|
||||
return game_stats(board, viewing_team, selected_index).show();
|
||||
return game_stats(board, viewing_team, selected_side_number).show();
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -55,7 +55,7 @@ private:
|
|||
|
||||
std::vector<team_data> team_data_;
|
||||
|
||||
int& selected_index_;
|
||||
int& selected_side_number_;
|
||||
|
||||
unit_const_ptr get_leader(const int side);
|
||||
|
||||
|
|
|
@ -159,10 +159,10 @@ void menu_handler::unit_list()
|
|||
|
||||
void menu_handler::status_table()
|
||||
{
|
||||
int selected_index;
|
||||
int selected_side;
|
||||
|
||||
if(gui2::dialogs::game_stats::execute(board(), gui_->viewing_team(), selected_index)) {
|
||||
gui_->scroll_to_leader(teams()[selected_index].side());
|
||||
if(gui2::dialogs::game_stats::execute(board(), gui_->viewing_team(), selected_side)) {
|
||||
gui_->scroll_to_leader(selected_side);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -666,7 +666,7 @@ static config unit_moves(reports::context & rc, const unit* u)
|
|||
|
||||
for (const terrain_movement& tm : terrain_moves) {
|
||||
tooltip << tm.name << ": ";
|
||||
|
||||
|
||||
std::string color;
|
||||
//movement - range: 1 .. 5, movetype::UNREACHABLE=impassable
|
||||
const bool cannot_move = tm.moves > u->total_movement();
|
||||
|
@ -1339,7 +1339,7 @@ REPORT_GENERATOR(upkeep, rc)
|
|||
std::ostringstream str;
|
||||
int viewing_side = rc.screen().viewing_side();
|
||||
const team &viewing_team = rc.dc().get_team(viewing_side);
|
||||
team_data td = rc.dc().calculate_team_data(viewing_team);
|
||||
team_data td(rc.dc(), viewing_team);
|
||||
str << td.expenses << " (" << td.upkeep << ")";
|
||||
return gray_inactive(rc,str.str(), _("Upkeep") + "\n\n" + _("The expenses incurred at the end of every turn to maintain your army. The first number is the amount of gold that will be deducted. The second is the total cost of upkeep, including that covered by villages — in other words, the amount of gold that would be deducted if you lost all villages."));
|
||||
}
|
||||
|
@ -1348,7 +1348,7 @@ REPORT_GENERATOR(expenses, rc)
|
|||
{
|
||||
int viewing_side = rc.screen().viewing_side();
|
||||
const team &viewing_team = rc.dc().get_team(viewing_side);
|
||||
team_data td = rc.dc().calculate_team_data(viewing_team);
|
||||
team_data td(rc.dc(), viewing_team);
|
||||
return gray_inactive(rc,std::to_string(td.expenses));
|
||||
}
|
||||
|
||||
|
@ -1357,7 +1357,7 @@ REPORT_GENERATOR(income, rc)
|
|||
std::ostringstream str;
|
||||
int viewing_side = rc.screen().viewing_side();
|
||||
const team &viewing_team = rc.dc().get_team(viewing_side);
|
||||
team_data td = rc.dc().calculate_team_data(viewing_team);
|
||||
team_data td(rc.dc(), viewing_team);
|
||||
char const *end = naps;
|
||||
if (viewing_side != rc.screen().playing_side()) {
|
||||
if (td.net_income < 0) {
|
||||
|
|
|
@ -58,6 +58,7 @@ static int impl_side_get(lua_State *L)
|
|||
return_tstring_attrib("objectives", t.objectives());
|
||||
return_int_attrib("village_gold", t.village_gold());
|
||||
return_int_attrib("village_support", t.village_support());
|
||||
return_int_attrib("num_villages", t.villages().size());
|
||||
return_int_attrib("recall_cost", t.recall_cost());
|
||||
return_int_attrib("base_income", t.base_income());
|
||||
return_int_attrib("total_income", t.total_income());
|
||||
|
@ -102,10 +103,9 @@ static int impl_side_get(lua_State *L)
|
|||
|
||||
// These are blocked together because they are all part of the team_data struct.
|
||||
// Some of these values involve iterating over the units map to calculate them.
|
||||
auto d = [&](){ return resources::gameboard->calculate_team_data(t); };
|
||||
auto d = [&](){ return team_data(*resources::gameboard, t); };
|
||||
return_int_attrib("num_units", d().units);
|
||||
return_int_attrib("total_upkeep", d().upkeep);
|
||||
return_int_attrib("num_villages", d().villages);
|
||||
return_int_attrib("expenses", d().expenses);
|
||||
return_int_attrib("net_income", d().net_income);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue