The problm was that the old code tried to use `undo_stack().can_undo()`
to check whether the current action can be undone. But
`undo_stack().can_undo()` uses the undo stack which is only updated at
the end of each action, so it cannot be used to check whether the action
that is currently executed can be undone.
This code removes some assertion that were wrong due to the
justmentioned.
This constitutes drop-in replacements for:
* boost::shared_ptr
* boost::scoped_ptr
* boost::weak_ptr
* boost::enable_shared_from_this
* boost::static_pointer_cast
* boost::dynamic_pointer_cast
This excludes boost::intrusive_ptr, except for stray includes. Refactoring that is more complicated.
This adds play_controller::is_networked_mp() and
play_controller::send_to_wesnothd() which are now used to comminucate
with wesnothd during a game instead of using network::send_data and
network::nconnections() directly.
The main intention is to make future changes to this code easier
specially:
1) to have more than one connection during a game, for example to check
for updates
2) to replace the clientsided network code with boost asio.
In order to do that i needed a little change to the chat_handler class
which is used both ingame and in the mp lobby. And to do that i
had to cleanup up the menu_events.cpp file and move huge helper
classes into their own files.
This means they can access auto-stored variables.
However, using [unstore_unit] for $unit or $second_unit is not recommended.
Also, $unit.x and $unit.y may not be the same as they were during the original event.
(The same with $second_unit)
This commit removes the utility srt_cast() function and replaces its calls,
along with calls to lexical_cast<std::string>() (and its boost variant),
with std::to_string().
In a few cases where the input type isn't compatible with to_string,
lexical_cast<std::string> is still used.
In other cases where lexical_cast was operating on MAKE_ENUM enums, the
call has been replaced with ENUM::enum_to_string, which is faster.
previously rng::next_random_impl() returned rand() which is in range
1-2^16. so random_new::generator->next_random() would return a number
1-2^16 in unsynced context and a number in 1-2^32 in synced contexts.
Now it always returns a number in 1-2^32.
renamed set_scontext_local_choice to leave_synced_context and
set_scontext_leave_for_draw to set_scontext_unsynced.
The old names do not fit anymore because set_scontext_leave_for_draw is
also used for wml menu items.
Also simplified the implementation of set_scontext_leave_for_draw.
Previously it could happen that a client would wait for a remote user
imput while still having a non-empty undo stack. Becasue of this the
client would not send the move that issued the user input (because the
client thinks it is undoable) to the other clients which then never gave
the user input.
This resulted in a situation where the game could not proceed and had to
be aborted.
Fixed it by calling resources::undo_stack->clear() as soon as we know
that a remote user input is needed
(synced_context::set_is_simultaneously()). Also added some assertions to
guard against this situation.
Previously it was dont this way because we also wanted a replay chack in
case of an end_level_exception which was thrown by check_victory. Since
check_victory doesnt throw anymore this is not needed anymore.
Previously recorder had config memaber and saved_game had a config
memeber.
And when saving a game the config was copied from recorder to saved_game
and the other way when loading a game.
Now the recorder object directly writes into the saved_game object. This
saves some copying when saving and loading data.
I also moved the pos_ variable from the recorder object to the
saved_game replay_recorder_base object, This fixes a bug where saving a
game during a replay also caused to not yet played turns to be written
into the savefile.
Instead of having different exceptions (ai_end_turn_exception,
end_level_exception and restart_turn_exception) we now have one exception
(return_to_play_side_exception) that is used to escape from play_ai_turn
or play_slice and is catched in the play_side related functions.
The information why we returned to play_side is already stored in the
playsingle_controller object. That is also why we do not need the
possible_end_play_signal return value anymore.
play_controller::check_victory does not throw exceptions anymore
Also do_replay and thus turn_info::process_network_data don't throw
exceptions anymore when the scenario is finished by victory or defeat.
Instead it returns REPLAY_FOUND_END_LEVEL, this means
return_to_play_side_exception is not thrown during replay at all.
this also fixed up a previous commit 'refactor play_side' where
accidently play_idle_loop was called instead of play_human_turn in
play_side.
end_turn_exception was split into 2 exceptions.
restart_turn_exception/struct which is used when a side got reassigned
this case covers most of end_turn_exceptions previous usecases.
and ai_end_turn_exception which is only used by the ai internally, we
also move the throwing of ai_end_turn_exception fom
playsingle/mp_controller::handle_generic_event to
ai::action_result::execute so that non ai code that might call
handle_generic_event doesn't have to think about ai_end_turn_exception.
This also partly fixes a bug where undroiding a side caused the sides turn to end.
The game sometimes does some checkup to test whether the calculated results in a replay match the ones calculated during the original game.
This data was stored in the replay inside the [command] for that action. The problem is that this doesn't work in networked mp because we often send the [command] before calculating the results.
I added an alternative mode that used get_user_choice to compare the results, this also works in networked mp but it causes a little more network traffic.
adds a new method is_replay() to check whether we are in a replay.
fixes http://gna.org/bugs/?21906
Also also we make [do_command]/run_in_synced_context_if_not_already more
robust by checking is_replay