Address bug #12714:

[end_turn] now works properly in "turn events" and in multiplayer.
Known issues remaining:

-[end_turn] currently breaks replays

-If an attack is prevented by [end_turn] in a moveto [event], the
attack cursor remains and prevents further control of
units. Workaround: reloading from autosave.
This commit is contained in:
Alexander van Gessel 2008-12-23 06:11:04 +01:00
parent 8fed71047b
commit 4745240da5
6 changed files with 70 additions and 17 deletions

View file

@ -50,7 +50,7 @@ Xu , Xu , Qxu , Qxu , Ql , Ql
canrecruit=yes
controller=human
max_hitpoints=90
recruit="Ghost,Troll Whelp,Assassin,Elvish Hero,Elvish Fighter,Elvish Archer,Horseman,Mage,Elvish Shaman,Red Mage,Spearman,Swordsman,Duelist,Fencer,Elvish Captain,Elvish Ranger,Elvish Shyde,Thief,Rogue,White Mage,Mage of Light,Elvish Sharpshooter,Silver Mage,Vampire Bat,Blood Bat,Soulless,Walking Corpse"
recruit="Ghost,Troll Whelp,Assassin,Elvish Hero,Elvish Fighter,Elvish Archer,Horseman,Mage,Elvish Shaman,Red Mage,Spearman,Swordsman,Duelist,Fencer,Elvish Captain,Elvish Ranger,Elvish Shyde,Thief,Rogue,White Mage,Mage of Light,Elvish Sharpshooter,Silver Mage,Vampire Bat,Blood Bat,Dread Bat,Soulless,Walking Corpse"
gold=2000
enemy=2
shroud=yes
@ -1112,6 +1112,29 @@ Result:
[/message]
[/event]
[label]
x,y=32,3
text="forfeit"
[/label]
[event]
name=moveto
[filter]
x,y=32,3
[/filter]
[event]
name=new turn
first_time_only=no
[end_turn]
[/end_turn]
[/event]
[message]
side=2
message="No more turns for you!"
[/message]
[end_turn]
[/end_turn]
[/event]
# Capture connected villages near 13,2 for team 2
[event]
name=prestart

View file

@ -389,6 +389,13 @@ void play_controller::init_gui(){
}
}
void play_controller::init_turn(){
std::stringstream turn_stream;
turn_stream << status_.turn();
game_events::fire("turn " + turn_stream.str());
game_events::fire("new turn");
}
void play_controller::init_side(const unsigned int team_index, bool /*is_replay*/){
log_scope("player turn");
team& current_team = teams_[team_index];
@ -417,10 +424,10 @@ void play_controller::init_side(const unsigned int team_index, bool /*is_replay*
*/
bool real_side_change = true;
if(first_turn_) {
first_turn_ = false;
game_events::fire("turn " + str_cast<size_t>(start_turn_));
game_events::fire("new turn");
game_events::fire("side turn");
first_turn_ = false;
} else if (team_index != (first_player_ - 1) || status_.turn() > start_turn_) {
// Fire side turn event only if real side change occurs,
// not counting changes from void to a side
@ -502,8 +509,6 @@ void play_controller::finish_turn(){
update_locker lock_display(gui_->video(),recorder.is_skipping());
const std::string turn_num = event_stream.str();
gamestate_.set_variable("turn_number",turn_num);
game_events::fire("turn " + turn_num);
game_events::fire("new turn");
}
}

View file

@ -104,6 +104,7 @@ protected:
void fire_prestart(bool execute);
void fire_start(bool execute);
virtual void init_gui();
void init_turn();
virtual void init_side(const unsigned int team_index, bool is_replay = false);
void place_sides_in_preferred_locations(gamemap& map, const config::child_list& sides);
virtual void finish_side_turn();

View file

@ -110,6 +110,8 @@ void playmp_controller::play_side(const unsigned int team_index, bool save){
gui_->invalidate_all();
gui_->draw(true,true);
}
} else {
after_human_turn();
}
}
LOG_NG << "human finished turn...\n";

View file

@ -516,10 +516,23 @@ void playsingle_controller::play_turn(bool save)
for(player_number_ = first_player_; player_number_ <= teams_.size(); player_number_++) {
// If a side is empty skip over it.
if (current_team().is_empty()) continue;
try {
if (player_number_ == first_player_) {
init_turn();
}
// If a side is empty skip over it.
if (current_team().is_empty()) continue;
init_side(player_number_ - 1);
init_side(player_number_ - 1);
} catch (end_turn_exception) {
if (current_team().is_network() == false) {
turn_info turn_data(gamestate_, status_, *gui_, map_,
teams_, player_number_, units_, replay_sender_, undo_stack_);
recorder.end_turn();
turn_data.sync_network();
}
continue;
}
if (replaying_) {
LOG_NG << "doing replay " << player_number_ << "\n";
@ -800,7 +813,10 @@ void playsingle_controller::play_ai_turn(){
ai_obj->unit_recruited().attach_handler(this);
ai_obj->unit_moved().attach_handler(this);
ai_obj->enemy_attacked().attach_handler(this);
ai_obj->play_turn();
try {
ai_obj->play_turn();
} catch (end_turn_exception) {
}
recorder.end_turn();
turn_data.sync_network();

View file

@ -324,16 +324,22 @@ void replay_controller::play_side(const unsigned int /*team_index*/, bool){
statistics::reset_turn_stats(current_team().save_id());
try{
play_controller::init_side(player_number_ - 1, true);
DBG_REPLAY << "doing replay " << player_number_ << "\n";
try {
::do_replay(*gui_, map_, units_, teams_,
player_number_, status_, gamestate_);
} catch(replay::error&) {
if(!continue_replay()) {
throw;
try{
if (player_number_ == 1) {
play_controller::init_turn();
}
play_controller::init_side(player_number_ - 1, true);
DBG_REPLAY << "doing replay " << player_number_ << "\n";
try {
::do_replay(*gui_, map_, units_, teams_,
player_number_, status_, gamestate_);
} catch(replay::error&) {
if(!continue_replay()) {
throw;
}
}
} catch(end_turn_exception) {
}
finish_side_turn();