attempt to fix crashes when units with invalid sides appear,
by rejecting such invalide sides in the unit's constructor
This commit is contained in:
parent
8512b2a8de
commit
011244a19e
6 changed files with 44 additions and 6 deletions
|
@ -635,6 +635,11 @@ int play_game(int argc, char** argv)
|
|||
gui::show_dialog(disp,NULL,"",
|
||||
string_table["bad_save_message"],gui::OK_ONLY);
|
||||
continue;
|
||||
} catch(gamestatus::game_error& e) {
|
||||
std::cerr << "caught game_error\n";
|
||||
gui::show_dialog(disp,NULL,"",
|
||||
string_table["bad_save_message"],gui::OK_ONLY);
|
||||
continue;
|
||||
} catch(config::error& e) {
|
||||
std::cerr << "caught config::error\n";
|
||||
gui::show_dialog(disp,NULL,"",
|
||||
|
@ -690,10 +695,12 @@ int play_game(int argc, char** argv)
|
|||
play_level(units_data,game_config,&starting_pos,video,state,story);
|
||||
recorder.clear();
|
||||
} catch(gamestatus::load_game_failed& e) {
|
||||
gui::show_dialog(disp,NULL,"","error loading the game: " + e.message,gui::OK_ONLY);
|
||||
std::cerr << "error loading the game: " << e.message
|
||||
<< "\n";
|
||||
return 0;
|
||||
} catch(gamestatus::game_error& e) {
|
||||
gui::show_dialog(disp,NULL,"","error while playing the game: " + e.message,gui::OK_ONLY);
|
||||
std::cerr << "error while playing the game: "
|
||||
<< e.message << "\n";
|
||||
return 0;
|
||||
|
|
|
@ -177,6 +177,10 @@ void find_routes(const gamemap& map, const gamestatus& status,
|
|||
std::vector<team>& teams,
|
||||
bool ignore_zocs, bool allow_teleport, int turns_left, bool starting_pos)
|
||||
{
|
||||
if(size_t(u.side()-1) >= teams.size()) {
|
||||
return;
|
||||
}
|
||||
|
||||
team& current_team = teams[u.side()-1];
|
||||
|
||||
//find adjacent tiles
|
||||
|
|
|
@ -162,6 +162,8 @@ LEVEL_RESULT play_level(game_data& gameinfo, const config& game_config,
|
|||
|
||||
std::vector<team> teams;
|
||||
|
||||
const teams_manager team_manager(teams);
|
||||
|
||||
int first_human_team = -1;
|
||||
|
||||
const config::child_list& unit_cfg = level->get_children("side");
|
||||
|
@ -193,6 +195,8 @@ LEVEL_RESULT play_level(game_data& gameinfo, const config& game_config,
|
|||
|
||||
std::cerr << "set gold to '" << ngold << "'\n";
|
||||
|
||||
teams.push_back(team(**ui,ngold));
|
||||
|
||||
//if this side tag describes the leader of the side
|
||||
if((**ui)["no_leader"] != "yes") {
|
||||
unit new_unit(gameinfo, **ui);
|
||||
|
@ -234,8 +238,6 @@ LEVEL_RESULT play_level(game_data& gameinfo, const config& game_config,
|
|||
}
|
||||
}
|
||||
|
||||
teams.push_back(team(**ui,ngold));
|
||||
|
||||
//if the game state specifies units that can be recruited for the player
|
||||
//then add them
|
||||
if(teams.size() == 1 && state_of_game.can_recruit.empty() == false) {
|
||||
|
@ -265,8 +267,6 @@ LEVEL_RESULT play_level(game_data& gameinfo, const config& game_config,
|
|||
}
|
||||
}
|
||||
|
||||
const teams_manager team_manager(teams);
|
||||
|
||||
const config* theme_cfg = NULL;
|
||||
if((*level)["theme"] != "") {
|
||||
theme_cfg = game_config.find_child("theme","name",(*level)["theme"]);
|
||||
|
|
20
src/team.cpp
20
src/team.cpp
|
@ -368,10 +368,14 @@ const std::string& team::name() const
|
|||
|
||||
bool team::is_enemy(int n) const
|
||||
{
|
||||
const size_t index = size_t(n-1);
|
||||
if(teams == NULL || index >= teams->size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//if we have a team name, we are friends with anyone who has the same team name
|
||||
if(info_.team_name.empty() == false) {
|
||||
return teams != NULL && size_t(n-1) < teams->size() &&
|
||||
(*teams)[n-1].info_.team_name != info_.team_name;
|
||||
return (*teams)[index].info_.team_name != info_.team_name;
|
||||
}
|
||||
|
||||
//if enemies aren't listed, then everyone is an enemy
|
||||
|
@ -589,3 +593,15 @@ bool is_observer()
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
void validate_side(int side)
|
||||
{
|
||||
if(teams == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(side < 1 || side > int(teams->size())) {
|
||||
std::cerr << "invalid side " << side << " throwing game_error\n";
|
||||
throw gamestatus::game_error("invalid side found in unit definition");
|
||||
}
|
||||
}
|
|
@ -146,4 +146,8 @@ struct teams_manager {
|
|||
|
||||
bool is_observer();
|
||||
|
||||
//function which will validate a side. Throws gamestatus::game_error
|
||||
//if the side is invalid
|
||||
void validate_side(int side); //throw gamestatus::game_error
|
||||
|
||||
#endif
|
||||
|
|
|
@ -71,6 +71,9 @@ unit::unit(const unit_type* t, int side, bool use_traits) :
|
|||
backupAttacks_(t->attacks()),
|
||||
guardian_(false), upkeep_(UPKEEP_FULL_PRICE)
|
||||
{
|
||||
|
||||
validate_side(side_);
|
||||
|
||||
if(use_traits) {
|
||||
//units that don't have traits generated are just generic
|
||||
//units, so they shouldn't get a description either.
|
||||
|
@ -100,6 +103,8 @@ unit::unit(const unit_type* t, const unit& u) :
|
|||
traitsDescription_(u.traitsDescription_),
|
||||
guardian_(false), upkeep_(u.upkeep_)
|
||||
{
|
||||
validate_side(side_);
|
||||
|
||||
//apply modifications etc, refresh the unit
|
||||
apply_modifications();
|
||||
heal_all();
|
||||
|
@ -541,6 +546,8 @@ void unit::read(game_data& data, const config& cfg)
|
|||
if(side_ <= 0)
|
||||
side_ = 1;
|
||||
|
||||
validate_side(side_);
|
||||
|
||||
description_ = cfg["user_description"];
|
||||
underlying_description_ = cfg["description"];
|
||||
if(description_ == "") {
|
||||
|
|
Loading…
Add table
Reference in a new issue