Fix bug #13268 (save corruption through undo/redo of recalls):

...Part 2. Bug should be completely fixed now.
This commit is contained in:
Jörg Hinrichs 2009-09-04 07:01:25 +00:00
parent db3b6e2c17
commit d535845b5b
4 changed files with 21 additions and 13 deletions

View file

@ -7,6 +7,7 @@ Version 1.7.5 +SVN:
* New portrait for Merman Spearman
* Miscellaneous and bugfixes:
* Fix broken "Skip Ai moves" option.
* Fix bug #13268 (corrupted replays due to undo of recall/dismiss)
Version 1.7.5:
* Campaigns:

View file

@ -105,8 +105,13 @@ namespace events{
filter_.delete_item(menu_selection);
//add dismissal to the undo stack
undo_stack_.push_back(undo_action(u, map_location(), static_cast<int>(index), true));
units_.erase(units_.begin() + index);
recorder.add_disband(index);
//remove the unit from the recall list
std::vector<unit>::iterator dismissed_unit = std::find_if(units_.begin(), units_.end(), boost::bind(&unit::matches_id, _1, u.id()));
assert(dismissed_unit != units_.end());
recorder.add_disband(dismissed_unit->id());
units_.erase(dismissed_unit);
//clear the redo stack to avoid duplication of dismissals
redo_stack_.clear();
return gui::DELETE_ITEM;
@ -975,7 +980,7 @@ private:
ERR_NG << "trying to undo a dismissal for side " << side_num
<< ", which has no recall list!\n";
} else {
current_team.recall_list().insert(current_team.recall_list().begin()+action.recall_pos,action.affected_unit);
current_team.recall_list().push_back(action.affected_unit);
}
} else if(action.is_recall()) {
@ -1089,8 +1094,10 @@ private:
<< ", which has no recall list!\n";
} else {
//redo a dismissal
recorder.add_disband(action.recall_pos);
current_team.recall_list().erase(current_team.recall_list().begin()+action.recall_pos);
recorder.add_disband(action.affected_unit.id());
std::vector<unit>::iterator unit_it = std::find_if(current_team.recall_list().begin(),
current_team.recall_list().end(), boost::bind(&unit::matches_id, _1, action.affected_unit.id()));
current_team.recall_list().erase(unit_it);
}
} else if(action.is_recall()) {
if(!current_team.persistent()) {

View file

@ -208,13 +208,13 @@ void replay::add_recall(const std::string& unit_id, const map_location& loc)
cmd->add_child("recall",val);
}
void replay::add_disband(int value)
void replay::add_disband(const std::string unit_id)
{
config* const cmd = add_command();
config val;
val["value"] = str_cast(value);
val["value"] = unit_id;
cmd->add_child("disband",val);
}
@ -999,12 +999,12 @@ bool do_replay_handle(int side_num, const std::string &do_untill)
replay::throw_error("illegal disband\n");
}
sort_units(current_team.recall_list());
const std::string& unit_num = child["value"];
const int val = lexical_cast_default<int>(unit_num);
const std::string& unit_id = child["value"];
std::vector<unit>::iterator disband_unit = std::find_if(current_team.recall_list().begin(),
current_team.recall_list().end(), boost::bind(&unit::matches_id, _1, unit_id));
if(val >= 0 && val < int(current_team.recall_list().size())) {
current_team.recall_list().erase(current_team.recall_list().begin()+val);
if(disband_unit != current_team.recall_list().end()) {
current_team.recall_list().erase(disband_unit);
} else {
replay::throw_error("illegal disband\n");
}

View file

@ -45,7 +45,7 @@ public:
void add_start();
void add_recruit(int unit_index, const map_location& loc);
void add_recall(const std::string& unit_id, const map_location& loc);
void add_disband(int unit_index);
void add_disband(const std::string unit_id);
void add_countdown_update(int value,int team);
void add_movement(const std::vector<map_location>& steps);
void add_attack(const map_location& a, const map_location& b,