50 #define ERR_NG LOG_STREAM(err, log_engine)
51 #define LOG_NG LOG_STREAM(info, log_engine)
64 const std::string str = cfg[
"type"];
69 if ( str ==
"move" ) {
70 return std::make_unique<undo::move_action>(cfg, cfg.
child_or_empty(
"unit"),
71 cfg[
"starting_moves"].to_int(),
75 else if ( str ==
"recruit" ) {
82 ERR_NG <<
"Invalid recruit found in [undo] or [redo]; unit type '"
83 << child[
"type"] <<
"' was not found.\n";
89 else if ( str ==
"recall" )
92 else if ( str ==
"dismiss" )
93 return std::make_unique<undo::dismiss_action>(cfg, cfg.
mandatory_child(
"unit"));
95 else if ( str ==
"auto_shroud" )
96 return std::make_unique<undo::auto_shroud_action>(cfg[
"active"].to_bool());
98 else if ( str ==
"update_shroud" )
99 return std::make_unique<undo::update_shroud_action>();
100 else if ( str ==
"dummy" )
101 return std::make_unique<undo_dummy_action>(cfg);
105 ERR_NG <<
"Unrecognized undo action type: " << str <<
".";
116 undos_(), redos_(), side_(1), committed_actions_(false)
135 add(std::make_unique<undo::auto_shroud_action>(turned_on));
140 add(std::make_unique<undo_dummy_action>());
148 add(std::make_unique<undo::dismiss_action>(u));
155 const std::vector<map_location>::const_iterator & begin,
156 const std::vector<map_location>::const_iterator & end,
157 int start_moves,
int timebonus,
int village_owner,
160 add(std::make_unique<undo::move_action>(u, begin, end, start_moves, timebonus, village_owner, dir));
167 const map_location& from,
int orig_village_owner,
bool time_bonus)
169 add(std::make_unique<undo::recall_action>(u, loc, from, orig_village_owner, time_bonus));
176 const map_location& from,
int orig_village_owner,
bool time_bonus)
178 add(std::make_unique<undo::recruit_action>(u, loc, from, orig_village_owner, time_bonus));
188 add(std::make_unique<undo::update_shroud_action>());
226 if (cleared_something) {
233 return cleared_something;
245 ERR_NG <<
"Undo stack not empty in new_side_turn().";
250 else if ( !
redos_.empty() ) {
251 ERR_NG <<
"Redo stack not empty in new_side_turn().";
277 undos_.push_back(std::move(action));
280 ERR_NG <<
"Error when parsing undo list from config: bad lexical cast.";
281 ERR_NG <<
"config was: " << child.debug();
282 ERR_NG <<
"Skipping this undo action...";
284 ERR_NG <<
"Error when parsing undo list from config: " <<
e.what();
285 ERR_NG <<
"config was: " << child.debug();
286 ERR_NG <<
"Skipping this undo action...";
295 ERR_NG <<
"Error when parsing redo list from config: bad lexical cast.";
296 ERR_NG <<
"config was: " << child.debug();
297 ERR_NG <<
"Skipping this redo action...";
299 ERR_NG <<
"Error when parsing redo list from config: " <<
e.what();
300 ERR_NG <<
"config was: " << child.debug();
301 ERR_NG <<
"Skipping this redo action...";
318 for (
const auto& cfg_ptr :
redos_)
337 auto action = std::move(
undos_.back());
341 if ( !undoable_action->undo(
side_) ) {
344 if(last_unit_id - undoable_action->unit_id_diff < 0) {
345 ERR_NG <<
"Next unit id is below 0 after undoing";
357 gui.invalidate_unit();
358 gui.invalidate_game_status();
359 gui.redraw_minimap();
369 undos_.emplace_back(std::move(action));
371 if(std::all_of(
undos_.begin(),
undos_.end(), [](
const action_ptr_t& action){ return dynamic_cast<undo_action*>(action.get()) == nullptr; }))
389 auto action = std::move(
redos_.back());
392 auto [commandname,
data] = action->mandatory_child(
"command").all_children_view().front();
397 auto error_handler = [](
const std::string&
msg) {
398 ERR_NG <<
"Out of sync when redoing: " <<
msg;
400 _(
"The redo stack is out of sync. This is most commonly caused by a corrupt save file or by faulty WML code in the scenario or era. Details:") +
msg);
414 gui.invalidate_unit();
415 gui.invalidate_game_status();
416 gui.redraw_minimap();
437 bool cleared_shroud =
false;
438 const std::size_t list_size =
undos_.size();
442 for( std::size_t
i = 0;
i != list_size; ++
i ) {
444 LOG_NG <<
"Turning an undo...";
448 std::vector<map_location>::const_iterator step;
449 for (step = action->route.begin(); step != action->route.end(); ++step) {
452 if ( clearer.
clear_unit(*step, tm, action->view_info,
true) ) {
453 cleared_shroud =
true;
460 if (!cleared_shroud) {
Class to encapsulate fog/shroud clearing and the resultant sighted events.
void invalidate_after_clear()
The invalidations that should occur after invoking clear_unit().
game_events::pump_result_t fire_events()
Fires the sighted events that were earlier recorded by fog/shroud clearing.
bool clear_unit(const map_location &view_loc, team &view_team, std::size_t viewer_id, int sight_range, bool slowed, const movetype::terrain_costs &costs, const map_location &real_loc, const std::set< map_location > *known_units=nullptr, std::size_t *enemy_count=nullptr, std::size_t *friend_count=nullptr, move_unit_spectator *spectator=nullptr, bool instant=true)
Clears shroud (and fog) around the provided location for view_team based on sight_range,...
static std::unique_ptr< undo_action_base > create_action(const config &cfg)
Creates an undo_action based on a config.
void new_side_turn(int side)
Performs some initializations and error checks when starting a new side-turn.
void add_dismissal(const unit_const_ptr u)
Adds a dismissal to the undo stack.
void read(const config &cfg)
Read the undo_list from the provided config.
void add_recall(const unit_const_ptr u, const map_location &loc, const map_location &from, int orig_village_owner, bool time_bonus)
Adds a recall to the undo stack.
bool committed_actions_
Tracks if actions have been cleared from the stack since the turn began.
void write(config &cfg) const
Write the undo_list into the provided config.
void add(std::unique_ptr< undo_action_base > &&action)
Adds an action to the undo stack.
bool commit_vision()
Updates fog/shroud based on the undo stack, then updates stack as needed.
void redo()
Redoes the top action on the redo stack.
bool apply_shroud_changes() const
Applies the pending fog/shroud changes from the undo stack.
std::vector< std::unique_ptr< config > > redos_list
void clear()
Clears the stack of undoable (and redoable) actions.
void add_dummy()
Adds an auto-shroud toggle to the undo stack.
int side_
Tracks the current side.
void add_auto_shroud(bool turned_on)
Adds an auto-shroud toggle to the undo stack.
void add_move(const unit_const_ptr u, const std::vector< map_location >::const_iterator &begin, const std::vector< map_location >::const_iterator &end, int start_moves, int timebonus=0, int village_owner=-1, const map_location::direction dir=map_location::direction::indeterminate)
Adds a move to the undo stack.
void add_update_shroud()
Adds a shroud update to the undo stack.
std::unique_ptr< undo_action_base > action_ptr_t
void add_recruit(const unit_const_ptr u, const map_location &loc, const map_location &from, int orig_village_owner, bool time_bonus)
Adds a recruit to the undo stack.
void undo()
Undoes the top action on the undo stack.
A config object defines a single node in a WML file, with access to child nodes.
const config & child_or_empty(config_key_type key) const
Returns the first child with the given key, or an empty config if there is none.
config & mandatory_child(config_key_type key, int n=0)
Returns the nth child with the given key, or throws an error if there is none.
child_itors child_range(config_key_type key)
config & add_child(config_key_type key)
n_unit::id_manager & unit_id_manager()
void invalidate_unit()
Function to invalidate that unit status displayed on the sidebar.
static game_display * get_singleton()
std::size_t get_save_id() const
Used for saving id to savegame.
void set_save_id(std::size_t)
void undo_cut(config &dst)
void redo(const config &dst, bool set_to_end=false)
static bool run(const std::string &commandname, const config &data, bool use_undo=true, bool show=true, synced_command::error_handler_function error_handler=default_error_function)
Sets the context to 'synced', initialises random context, and calls the given function.
This class stores all the data for a single 'side' (in game nomenclature).
bool fog_or_shroud() const
bool auto_shroud_updates() const
const unit_type * find(const std::string &key, unit_type::BUILD_STATUS status=unit_type::FULL) const
Finds a unit_type by its id() and makes sure it is built to the specified level.
A single unit type that the player may recruit.
static std::string _(const char *str)
Standard logging facilities (interface).
bool clear_shroud(int side, bool reset_fog, bool fire_events)
Function that will clear shroud (and fog) based on current unit positions.
void show_transient_message(const std::string &title, const std::string &message, const std::string &image, const bool message_use_markup, const bool title_use_markup)
Shows a transient message to the user.
std::shared_ptr< wb::manager > whiteboard
std::shared_ptr< action > action_ptr
static void msg(const char *act, debug_info &i, const char *to="", const char *result="")
std::shared_ptr< const unit > unit_const_ptr
base class for classes that clear srhoud (move/recruit/recall)
actions that are undoable (this does not include update_shroud and auto_shroud)
Thrown when a lexical_cast fails.
Encapsulates the map of the game.
direction
Valid directions which can be moved in our hexagonal world.
static direction parse_direction(const std::string &str)
unit_type_data unit_types
static lg::log_domain log_engine("engine")
Various functions that implement the undoing (and redoing) of in-game commands.
Various functions implementing vision (through fog of war and shroud).