63 inverted_behavior_(false),
64 self_activate_once_(true),
66 print_help_once_(true),
68 wait_for_side_init_(true),
69 planned_unit_map_active_(false),
70 executing_actions_(false),
71 executing_all_actions_(false),
72 preparing_to_end_turn_(false),
73 gamestate_mutated_(false),
74 activation_state_lock_(new bool),
75 unit_map_lock_(new bool),
81 temp_move_unit_underlying_id_(0),
82 key_poller_(new
CKey),
91 LOG_WB <<
"Manager initialized.";
96 LOG_WB <<
"Manager destroyed.";
101 static void print_to_chat(
const std::string& title,
const std::string& message)
111 if (!print_help_once_)
114 print_help_once_ =
false;
116 print_to_chat(
"whiteboard", std::string(
"Type :wb to activate/deactivate planning mode.")
117 +
" Hold TAB to temporarily deactivate/activate it.");
118 std::stringstream hotkeys;
120 if(!hk_execute.null()) {
122 hotkeys <<
"Execute: " << hk_execute.get_name() <<
", ";
125 if(!hk_execute_all.null()) {
127 hotkeys <<
"Execute all: " << hk_execute_all.get_name() <<
", ";
130 if(!hk_delete.null()) {
132 hotkeys <<
"Delete: " << hk_delete.get_name() <<
", ";
135 if(!hk_bump_up.null()) {
137 hotkeys <<
"Move earlier: " << hk_bump_up.get_name() <<
", ";
140 if(!hk_bump_down.null()) {
142 hotkeys <<
"Move later: " << hk_bump_down.get_name() <<
", ";
144 print_to_chat(
"HOTKEYS:", hotkeys.str() +
"\n");
179 LOG_WB <<
"Whiteboard can't be activated now.";
198 LOG_WB <<
"Whiteboard deactivated!";
209 bool block_whiteboard_activation =
false;
212 block_whiteboard_activation =
true;
221 DBG_WB <<
"Whiteboard deactivated temporarily.";
225 else if (!block_whiteboard_activation)
227 DBG_WB <<
"Whiteboard activated temporarily.";
239 DBG_WB <<
"Whiteboard set back to deactivated status.";
243 else if (!block_whiteboard_activation)
245 DBG_WB <<
"Whiteboard set back to activated status.";
287 WRN_WB <<
"Unable to build future map to determine whether leader's allowed to move.";
319 LOG_WB <<
"on_init_side()";
337 LOG_WB <<
"on_finish_side_turn()";
356 move_ptr move = std::dynamic_pointer_cast<class move>(*action_it);
367 t.get_side_actions()->hide();
382 if(!
t.is_network_human())
386 t.get_side_actions()->hide();
388 t.get_side_actions()->show();
405 if(
t.is_local_human())
413 else if(
t.is_local_ai() ||
t.is_network_ai())
415 else if(
t.is_network())
422 for(std::size_t
i=0;
i<num_teams; ++
i)
445 return range.first != range.second;
450 LOG_WB <<
"'gamestate_mutated_' flag dirty, validating actions.";
463 std::vector<std::size_t>& team_numbers = numbers.
team_numbers;
467 const double x_offset_base = 0.0;
468 const double y_offset_base = 0.2;
471 const double x_origin = 0.8 - numbers_to_draw.size() * x_offset_base;
473 const double y_origin = 0.5 - numbers_to_draw.size() * (y_offset_base / 2);
474 double x_offset = 0, y_offset = 0;
476 std::size_t
size = numbers_to_draw.size();
477 for(std::size_t
i=0;
i<
size; ++
i)
479 int number = numbers_to_draw[
i];
481 std::string number_text = std::to_string(number);
482 std::size_t font_size;
483 if (
static_cast<int>(
i) == main_number) font_size = 19;
484 else if (secondary_numbers.find(
i)!=secondary_numbers.end()) font_size = 17;
488 const double x_in_hex = x_origin + x_offset;
489 const double y_in_hex = y_origin + y_offset;
491 number_text, font_size, color, x_in_hex, y_in_hex);
492 x_offset += x_offset_base;
493 y_offset += y_offset_base;
503 struct move_owners_finder:
public visitor
507 move_owners_finder(): move_owners_() { }
509 void operator()(action* action) {
510 action->accept(*
this);
513 const std::set<std::size_t>& get_units_owning_moves() {
518 if(std::size_t
id = move->get_unit_id()) {
519 move_owners_.insert(
id);
525 if(attack->get_route().steps.size() >= 2) {
526 if(std::size_t
id = attack->get_unit_id()) {
527 move_owners_.insert(
id);
536 std::set<std::size_t> move_owners_;
543 move_owners_finder move_finder;
549 if(unit_iter.
valid()) {
561 if (unit_iter.
valid()) {
602 if (!((selected_hex.
valid() && hex_has_unit)
616 DBG_WB <<
"Manager received gamestate change notification.";
629 for(std::size_t team_index=0; team_index<
size; ++team_index)
638 wb_cfg[
"side"] =
static_cast<int>(team_index+1);
646 LOG_WB <<
"Side " << (team_index+1) <<
" sent wb data (" << count <<
" cmds).";
654 std::size_t count = wb_cfg->child_count(
"net_cmd");
655 LOG_WB <<
"Received wb data (" << count <<
").";
684 if (route.
steps.empty() || route.
steps.size() < 2)
return;
686 unit* temp_moved_unit =
688 if (!temp_moved_unit) temp_moved_unit =
690 if (!temp_moved_unit)
return;
706 std::size_t turn = 0;
710 for(; curr_itor!=end_itor; ++curr_itor)
715 pathfind::marked_route::mark_map::const_iterator
w =
716 route.
marks.find(hex);
717 if(
w != route.
marks.end() &&
w->second.turns > 0)
719 turn =
w->second.turns-1;
732 move_arrow.reset(
new arrow());
739 move_arrow->set_path(
path);
745 if(!fake_unit || fake_unit.
get_unit_ptr()->id() != temp_moved_unit->
id())
749 fake_unit->anim_comp().set_ghosted(
true);
754 fake_unit->set_location(*curr_itor);
755 fake_unit->anim_comp().set_ghosted(
true);
760 prev_itor = curr_itor;
797 for(std::size_t
i=0;
i<
size; ++
i)
803 std::size_t turn = first_turn +
i;
808 route.
steps = move_arrow->get_path();
831 assert(weapon_choice >= 0);
845 assert(
route_->steps.back() == attacker_loc);
846 source_hex =
route_->steps.front();
848 (**fake_unit).anim_comp().set_disabled_ghosted(
true);
853 move_arrow.reset(
new arrow);
854 source_hex = attacker_loc;
857 route_->steps.push_back(attacker_loc);
861 assert(attacking_unit);
879 bool created_planned_recruit =
false;
884 LOG_WB <<
"manager::save_recruit called for a different side than viewing side.";
885 created_planned_recruit =
false;
897 created_planned_recruit =
true;
902 return created_planned_recruit;
907 bool created_planned_recall =
false;
913 LOG_WB <<
"manager::save_recall called for a different side than viewing side.";
914 created_planned_recall =
false;
923 created_planned_recall =
true;
928 return created_planned_recall;
959 if (selected_unit && check_action(
viewer_actions()->find_first_action_of(*selected_unit)))
987 ERR_WB <<
"Modifying action queue while temp modifiers are applied1!!!";
1017 ERR_WB <<
"Modifying action queue while temp modifiers are applied!!!";
1022 while (sa->turn_begin(0) != sa->turn_end(0))
1024 bool action_successful = sa->execute(sa->begin());
1027 if (!action_successful)
1093 assert(
unit !=
nullptr);
1117 std::vector<team*> allies;
1118 std::vector<std::string>
options;
1121 options.emplace_back(
_(
"SHOW ALL allies’ plans"));
1122 options.emplace_back(
_(
"HIDE ALL allies’ plans"));
1128 if(
t.is_enemy(v_side) || !
t.is_network())
1131 allies.push_back(&
t);
1133 t_vars[
"player"] =
t.current_player();
1134 std::size_t t_index =
t.side()-1;
1151 for(
team*
t : allies) {
1156 for(
team*
t : allies) {
1163 std::size_t t_index = allies[selection-2]->side()-1;
1176 LOG_WB <<
"Not building planned unit map: cannot modify game state now.";
1181 LOG_WB <<
"Not building planned unit map: unit map locked.";
1185 WRN_WB <<
"Not building planned unit map: already set.";
1211 LOG_WB <<
"Not disabling planned unit map: already disabled.";
1231 DBG_WB <<
"Scoped future unit map failed to apply.";
1257 DBG_WB <<
"Scoped future unit map failed to apply.";
const std::vector< map_location > & route_
Arrows destined to be drawn on the map.
std::vector< map_location > arrow_path_t
Class that keeps track of all the keys on the keyboard.
void clear()
Clears the stack of undoable (and redoable) actions.
Arrows destined to be drawn on the map.
static const std::string STYLE_HIGHLIGHTED
static bool valid_path(const arrow_path_t &path)
Checks that the path is not of length 0 or 1.
A config object defines a single node in a WML file, with access to child nodes.
std::size_t child_count(config_key_type key) const
child_itors child_range(config_key_type key)
optional_config_impl< config > optional_child(config_key_type key, int n=0)
Euivalent to mandatory_child, but returns an empty optional if the nth child was not found.
config & add_child(config_key_type key)
void draw_text_in_hex(const map_location &loc, const drawing_layer layer, const std::string &text, std::size_t font_size, color_t color, double x_in_hex=0.5, double y_in_hex=0.5)
Draw text on a hex.
int viewing_side() const
The 1-based equivalent of the 0-based viewing_team() function.
bool invalidate(const map_location &loc)
Function to invalidate a specific tile for redrawing.
@ LAYER_ACTIONS_NUMBERING
Move numbering for the whiteboard.
void clear_exclusive_draws()
Cancels all the exclusive draw requests.
static display * get_singleton()
Returns the display object if a display object exists.
map_location get_selected_hex() const
const pathfind::marked_route & get_current_route() const
Holds a temporary unit that can be drawn on the map without being placed in the unit_map.
internal_ptr get_unit_ptr()
Get a copy of the internal unit pointer.
void reset()
Reset the internal unit pointer, and deregister from the manager.
virtual const std::vector< team > & teams() const override
virtual const unit_map & units() const override
static game_display * get_singleton()
bool show(const unsigned auto_close_time=0)
Shows the window.
A simple one-column listbox with OK and Cancel buttons.
int selected_index() const
Returns the selected item index after displaying.
events::mouse_handler & get_mouse_handler_base() override
Get a reference to a mouse handler member a derived class uses.
virtual void send_to_wesnothd(const config &, const std::string &="unknown") const
int current_side() const
Returns the number of the side whose turn it is.
virtual bool is_networked_mp() const
static config get_auto_shroud(bool turned_on)
Records that the player has toggled automatic shroud updates.
static bool run_and_throw(const std::string &commandname, const config &data, bool use_undo=true, bool show=true, synced_command::error_handler_function error_handler=default_error_function)
static bool is_unsynced()
This class stores all the data for a single 'side' (in game nomenclature).
bool is_local_human() const
bool is_enemy(int n) const
static std::string get_side_color_id(unsigned side)
std::shared_ptr< wb::side_actions > get_side_actions() const
get the whiteboard planned actions for this team
static color_t get_side_color(int side)
unit_iterator find(std::size_t id)
This class represents a single unit of a specific type.
Abstract base class for all the whiteboard planned actions.
virtual unit_ptr get_unit() const =0
Return the unit targeted by this action.
std::size_t team_index() const
Returns the index of the team that owns this action.
virtual void draw_hex(const map_location &hex)=0
Gets called by display when drawing a hex, to allow actions to draw to the screen.
Class that handles highlighting planned actions as you hover over them and determine the right target...
bool executing_all_actions_
Track whether we're in the process of executing all actions.
void on_finish_side_turn(int side)
void contextual_bump_down_action()
Moves the action determined by the UI toward the beginning of the queue
void on_viewer_change(std::size_t team_index)
bool can_activate() const
Determine whether the whiteboard can be activated safely.
bool active_
Tracks whether the whiteboard is active.
bool executing_actions_
Track whenever we're modifying actions, to avoid dual execution etc.
std::unique_ptr< mapbuilder > mapbuilder_
whiteboard_lock activation_state_lock_
Reference counted "lock" to allow preventing whiteboard activation state changes.
std::vector< fake_unit_ptr > fake_units_
bool has_temp_move() const
Informs whether an arrow is being displayed for move creation purposes.
bool allow_end_turn()
@ return true if the whiteboard is ready to end turn.
bool allow_leader_to_move(const unit &leader) const
Used to ask permission to the wb to move a leader, to avoid invalidating planned recruits.
std::set< std::size_t > units_owning_moves_
used to keep track of units owning planned moves for visual ghosting/unghosting
void post_delete_action(action_ptr action)
Handles various cleanup right after removing an action from the queue.
bool has_planned_unit_map() const
Whether the planned unit map is currently applied.
void queue_net_cmd(std::size_t team_index, const side_actions::net_cmd &)
Adds a side_actions::net_cmd to net_buffer_[team_index], whereupon it will (later) be sent to all all...
void contextual_bump_up_action()
Moves the action determined by the UI toward the beginning of the queue
void set_active(bool active)
Activates/Deactivates the whiteboard.
void set_planned_unit_map()
Transforms the unit map so that it now reflects the future state of things, i.e.
bool gamestate_mutated_
Track whether the gamestate changed and we need to validate actions.
void save_suppose_dead(unit &curr_unit, const map_location &loc)
Creates a suppose-dead action for the current side.
int get_spent_gold_for(int side)
Used to track gold spending per-side when building the planned unit map Is referenced by the top bar ...
whiteboard_lock unit_map_lock_
Reference counted "lock" to prevent the building of the unit map at certain times.
void set_real_unit_map()
Restore the regular unit map.
bool can_enable_execution_hotkeys() const
Used to ask the whiteboard if its action execution hotkeys should be available to the user.
static bool current_side_has_actions()
Whether the current side has actions in the first turn of its planned actions queue.
void draw_hex(const map_location &hex)
Called from the display when drawing hexes, to allow the whiteboard to add visual elements.
std::size_t temp_move_unit_underlying_id_
void save_temp_attack(const map_location &attacker_loc, const map_location &defender_loc, int weapon_choice)
Creates an attack or attack-move action for the current side.
std::shared_ptr< highlighter > highlighter_
void process_network_data(const config &)
Called by turn_info::process_network_data() when network data needs to be processed.
void validate_actions_if_needed()
void options_dlg()
Displays the whiteboard options dialog.
void set_invert_behavior(bool invert)
Called by the key that temporarily toggles the activated state when held.
void on_change_controller(int side, const team &t)
bool planned_unit_map_active_
bool preparing_to_end_turn_
true if we're in the process of executing all action and should end turn once finished.
void pre_delete_action(action_ptr action)
Handles various cleanup right before removing an action from the queue.
bool can_modify_game_state() const
Determine whether the game is initialized and the current side has control of the game i....
void post_draw()
Called from the display after drawing.
bool can_enable_reorder_hotkeys() const
Used to ask the whiteboard if its action reordering hotkeys should be available to the user.
bool save_recall(const unit &unit, int side_num, const map_location &recall_hex)
Creates a recall action for the current side.
void update_plan_hiding()
std::vector< config > net_buffer_
net_buffer_[i] = whiteboard network data to be sent "from" teams[i].
void contextual_delete()
Deletes last action in the queue for current side.
void create_temp_move()
Creates a temporary visual arrow, that follows the cursor, for move creation purposes.
bool can_enable_modifier_hotkeys() const
Used to ask the whiteboard if hotkeys affecting the action queue should be available to the user.
void send_network_data()
Called by replay_network_sender to add whiteboard data to the outgoing network packets.
void save_temp_move()
Creates a move action for the current side, and erases the temp move.
bool should_clear_undo() const
Determines whether or not the undo_stack should be cleared.
void validate_viewer_actions()
Validates all actions of the current viewing side.
bool unit_has_actions(unit const *unit) const
Checks whether the specified unit has at least one planned action.
void on_init_side()
The on_* methods below inform the whiteboard of specific events.
bool save_recruit(const std::string &name, int side_num, const map_location &recruit_hex)
Creates a recruit action for the current side.
void on_gamestate_change()
void on_mouseover_change(const map_location &hex)
void erase_temp_move()
Erase the temporary arrow.
boost::dynamic_bitset team_plans_hidden_
team_plans_hidden_[i] = whether or not to hide actions from teams[i].
bool execute_all_actions()
Executes all actions for the current turn in sequence.
void pre_draw()
Called from the display before drawing.
void contextual_execute()
Executes first action in the queue for current side.
unit_map::iterator get_temp_move_unit() const
std::unique_ptr< pathfind::marked_route > route_
bool has_actions() const
Checks whether the whiteboard has any planned action on any team.
std::vector< arrow_ptr > move_arrows_
Class that collects and applies unit_map modifications from the actions it visits and reverts all cha...
A planned move, represented on the map by an arrow and a ghosted unit in the destination hex.
virtual fake_unit_ptr get_fake_unit()
map_location const get_recall_hex() const
map_location const get_recruit_hex() const
This internal whiteboard class holds the planned action queues for a team, and offers many utility me...
std::size_t team_index()
Returns the team index this action queue belongs to.
iterator queue_move(std::size_t turn_num, unit &mover, const pathfind::marked_route &route, arrow_ptr arrow, fake_unit_ptr fake_unit)
Queues a move to be executed last.
iterator queue_recruit(std::size_t turn_num, const std::string &unit_name, const map_location &recruit_hex)
Queues a recruit to be executed last.
iterator queue_recall(std::size_t turn_num, const unit &unit, const map_location &recall_hex)
Queues a recall to be executed last.
std::size_t num_turns() const
Returns the number of turns that have plans.
iterator find_last_action_of(const unit &unit, iterator start_position)
Finds the last action that belongs to this unit, starting the search backwards from the specified pos...
iterator queue_suppose_dead(std::size_t turn_num, unit &curr_unit, const map_location &loc)
Queues a suppose_dead to be executed last.
std::size_t get_turn_num_of(const unit &) const
Determines the appropriate turn number for the next action planned for this unit.
void get_numbers(const map_location &hex, numbers_t &result)
Gets called when display is drawing a hex to determine which numbers to draw on it.
net_cmd make_net_cmd_clear() const
container::iterator iterator
void clear()
Empties the action queue.
iterator end()
Returns the iterator for the position after the last executed action within the actions queue.
iterator queue_attack(std::size_t turn_num, unit &mover, const map_location &target_hex, int weapon_choice, const pathfind::marked_route &route, arrow_ptr arrow, fake_unit_ptr fake_unit)
Queues an attack or attack-move to be executed last.
std::pair< iterator, iterator > range_t
Finalizer class to help with exception safety sets variable to value on destruction.
Various functions related to the creation of units (recruits, recalls, and placed units).
static std::string _(const char *str)
const std::string & id() const
Gets this unit's id.
int side() const
The side this unit belongs to.
std::size_t underlying_id() const
This unit's unique internal ID.
#define log_scope2(domain, description)
static bool is_active(const widget *wgt)
const hotkey_ptr get_hotkey(const SDL_Event &event)
Iterate through the list of hotkeys and return a hotkey that matches the SDL_Event and the current ke...
@ HOTKEY_WB_EXECUTE_ALL_ACTIONS
@ HOTKEY_WB_EXECUTE_ACTION
@ HOTKEY_WB_BUMP_UP_ACTION
@ HOTKEY_WB_BUMP_DOWN_ACTION
@ HOTKEY_WB_DELETE_ACTION
bool enable_whiteboard_mode_on_start()
fake_unit_manager * fake_units
actions::undo_list * undo_stack
play_controller * controller
filter_context * filter_con
std::shared_ptr< wb::manager > whiteboard
static std::string at(const std::string &file, int line)
void move_unit(const std::vector< map_location > &path, unit_ptr u, bool animate, map_location::DIRECTION dir, bool force_scroll)
Display a unit moving along a given path.
std::size_t size(const std::string &str)
Length in characters of a UTF-8 string.
std::map< std::string, t_string > string_map
side_actions_ptr current_side_actions()
static void hide_all_plans()
std::shared_ptr< recruit > recruit_ptr
void for_each_action(std::function< void(action *)> function, team_filter team_filter)
Apply a function to all the actions of the whiteboard.
void ghost_owner_unit(unit *unit)
std::shared_ptr< suppose_dead > suppose_dead_ptr
std::shared_ptr< recall const > recall_const_ptr
std::shared_ptr< move > move_ptr
unit * find_recruiter(std::size_t team_index, const map_location &hex)
std::size_t viewer_team()
std::shared_ptr< action > action_ptr
unit * future_visible_unit(map_location hex, int viewer_side)
Applies the future unit map and.
std::shared_ptr< side_actions > side_actions_ptr
std::shared_ptr< recruit const > recruit_const_ptr
std::shared_ptr< arrow > arrow_ptr
unit_const_ptr find_backup_leader(const unit &leader)
For a given leader on a keep, find another leader on another keep in the same castle.
side_actions_ptr viewer_actions()
bool has_actions()
Return whether the whiteboard has actions.
static void draw_numbers(const map_location &hex, side_actions::numbers_t numbers)
std::shared_ptr< action const > action_const_ptr
void unghost_owner_unit(unit *unit)
std::shared_ptr< recall > recall_ptr
std::string::const_iterator iterator
This module contains various pathfinding functions and utilities.
std::shared_ptr< attack_type > attack_ptr
std::shared_ptr< unit > unit_ptr
This file contains object "key", which is used to store information about keys while annotation parsi...
The basic class for representing 8-bit RGB or RGBA colour values.
Encapsulates the map of the game.
Structure which holds a single route and marks for special events.
std::vector< map_location > & steps
bool initial_planned_unit_map_
Applies the planned unit map for the duration of the struct's life.
bool initial_planned_unit_map_
bool initial_planned_unit_map_
std::set< std::size_t > secondary_numbers
std::vector< int > numbers_to_draw
std::vector< std::size_t > team_numbers
static lg::log_domain log_whiteboard("whiteboard")
Display units performing various actions: moving, attacking, and dying.
Various functions that implement the undoing (and redoing) of in-game commands.