59 inverted_behavior_(false),
60 self_activate_once_(true),
62 print_help_once_(true),
64 wait_for_side_init_(true),
65 planned_unit_map_active_(false),
66 executing_actions_(false),
67 executing_all_actions_(false),
68 preparing_to_end_turn_(false),
69 gamestate_mutated_(false),
70 activation_state_lock_(new bool),
71 unit_map_lock_(new bool),
77 temp_move_unit_underlying_id_(0),
78 key_poller_(new
CKey),
87 LOG_WB <<
"Manager initialized.";
92 LOG_WB <<
"Manager destroyed.";
97 static void print_to_chat(
const std::string& title,
const std::string& message)
107 if (!print_help_once_)
110 print_help_once_ =
false;
112 print_to_chat(
"whiteboard", std::string(
"Type :wb to activate/deactivate planning mode.")
113 +
" Hold TAB to temporarily deactivate/activate it.");
114 std::stringstream hotkeys;
116 if(!hk_execute.null()) {
118 hotkeys <<
"Execute: " << hk_execute.get_name() <<
", ";
121 if(!hk_execute_all.null()) {
123 hotkeys <<
"Execute all: " << hk_execute_all.get_name() <<
", ";
126 if(!hk_delete.null()) {
128 hotkeys <<
"Delete: " << hk_delete.get_name() <<
", ";
131 if(!hk_bump_up.null()) {
133 hotkeys <<
"Move earlier: " << hk_bump_up.get_name() <<
", ";
136 if(!hk_bump_down.null()) {
138 hotkeys <<
"Move later: " << hk_bump_down.get_name() <<
", ";
140 print_to_chat(
"HOTKEYS:", hotkeys.str() +
"\n");
175 LOG_WB <<
"Whiteboard can't be activated now.";
194 LOG_WB <<
"Whiteboard deactivated!";
205 bool block_whiteboard_activation =
false;
208 block_whiteboard_activation =
true;
217 DBG_WB <<
"Whiteboard deactivated temporarily.";
221 else if (!block_whiteboard_activation)
223 DBG_WB <<
"Whiteboard activated temporarily.";
235 DBG_WB <<
"Whiteboard set back to deactivated status.";
239 else if (!block_whiteboard_activation)
241 DBG_WB <<
"Whiteboard set back to activated status.";
283 WRN_WB <<
"Unable to build future map to determine whether leader's allowed to move.";
315 LOG_WB <<
"on_init_side()";
333 LOG_WB <<
"on_finish_side_turn()";
352 move_ptr move = std::dynamic_pointer_cast<class move>(*action_it);
363 t.get_side_actions()->hide();
378 if(!
t.is_network_human())
382 t.get_side_actions()->hide();
384 t.get_side_actions()->show();
401 if(
t.is_local_human())
409 else if(
t.is_local_ai() ||
t.is_network_ai())
411 else if(
t.is_network())
418 for(std::size_t
i=0;
i<num_teams; ++
i)
441 return range.first != range.second;
446 LOG_WB <<
"'gamestate_mutated_' flag dirty, validating actions.";
459 std::vector<std::size_t>& team_numbers = numbers.
team_numbers;
463 const double x_offset_base = 0.0;
464 const double y_offset_base = 0.2;
467 const double x_origin = 0.8 - numbers_to_draw.size() * x_offset_base;
469 const double y_origin = 0.5 - numbers_to_draw.size() * (y_offset_base / 2);
470 double x_offset = 0, y_offset = 0;
472 std::size_t
size = numbers_to_draw.size();
473 for(std::size_t
i=0;
i<
size; ++
i)
475 int number = numbers_to_draw[
i];
477 std::string number_text = std::to_string(number);
478 std::size_t font_size;
479 if (
static_cast<int>(
i) == main_number) font_size = 19;
480 else if (secondary_numbers.find(
i)!=secondary_numbers.end()) font_size = 17;
484 const double x_in_hex = x_origin + x_offset;
485 const double y_in_hex = y_origin + y_offset;
487 number_text, font_size, color, x_in_hex, y_in_hex);
488 x_offset += x_offset_base;
489 y_offset += y_offset_base;
499 struct move_owners_finder:
public visitor
503 move_owners_finder(): move_owners_() { }
505 void operator()(action* action) {
506 action->accept(*
this);
509 const std::set<std::size_t>& get_units_owning_moves() {
514 if(std::size_t
id = move->get_unit_id()) {
515 move_owners_.insert(
id);
521 if(attack->get_route().steps.size() >= 2) {
522 if(std::size_t
id = attack->get_unit_id()) {
523 move_owners_.insert(
id);
532 std::set<std::size_t> move_owners_;
539 move_owners_finder move_finder;
545 if(unit_iter.
valid()) {
557 if (unit_iter.
valid()) {
598 if (!((selected_hex.
valid() && hex_has_unit)
612 DBG_WB <<
"Manager received gamestate change notification.";
625 for(std::size_t team_index=0; team_index<
size; ++team_index)
634 wb_cfg[
"side"] =
static_cast<int>(team_index+1);
642 LOG_WB <<
"Side " << (team_index+1) <<
" sent wb data (" << count <<
" cmds).";
650 std::size_t count = wb_cfg->child_count(
"net_cmd");
651 LOG_WB <<
"Received wb data (" << count <<
").";
680 if (route.
steps.empty() || route.
steps.size() < 2)
return;
682 unit* temp_moved_unit =
684 if (!temp_moved_unit) temp_moved_unit =
686 if (!temp_moved_unit)
return;
702 std::size_t turn = 0;
706 for(; curr_itor!=end_itor; ++curr_itor)
711 pathfind::marked_route::mark_map::const_iterator
w =
712 route.
marks.find(hex);
713 if(
w != route.
marks.end() &&
w->second.turns > 0)
715 turn =
w->second.turns-1;
728 move_arrow.reset(
new arrow());
735 move_arrow->set_path(
path);
741 if(!fake_unit || fake_unit.
get_unit_ptr()->id() != temp_moved_unit->
id())
745 fake_unit->anim_comp().set_ghosted(
true);
750 fake_unit->set_location(*curr_itor);
751 fake_unit->anim_comp().set_ghosted(
true);
756 prev_itor = curr_itor;
793 for(std::size_t
i=0;
i<
size; ++
i)
799 std::size_t turn = first_turn +
i;
804 route.
steps = move_arrow->get_path();
827 assert(weapon_choice >= 0);
841 assert(
route_->steps.back() == attacker_loc);
842 source_hex =
route_->steps.front();
844 (**fake_unit).anim_comp().set_disabled_ghosted(
true);
849 move_arrow.reset(
new arrow);
850 source_hex = attacker_loc;
853 route_->steps.push_back(attacker_loc);
857 assert(attacking_unit);
875 bool created_planned_recruit =
false;
880 LOG_WB <<
"manager::save_recruit called for a different side than viewing side.";
881 created_planned_recruit =
false;
893 created_planned_recruit =
true;
898 return created_planned_recruit;
903 bool created_planned_recall =
false;
909 LOG_WB <<
"manager::save_recall called for a different side than viewing side.";
910 created_planned_recall =
false;
919 created_planned_recall =
true;
924 return created_planned_recall;
955 if (selected_unit && check_action(
viewer_actions()->find_first_action_of(*selected_unit)))
983 ERR_WB <<
"Modifying action queue while temp modifiers are applied1!!!";
1013 ERR_WB <<
"Modifying action queue while temp modifiers are applied!!!";
1018 while (sa->turn_begin(0) != sa->turn_end(0))
1020 bool action_successful = sa->execute(sa->begin());
1023 if (!action_successful)
1089 assert(
unit !=
nullptr);
1113 std::vector<team*> allies;
1114 std::vector<std::string>
options;
1117 options.emplace_back(
_(
"SHOW ALL allies’ plans"));
1118 options.emplace_back(
_(
"HIDE ALL allies’ plans"));
1124 if(
t.is_enemy(v_side) || !
t.is_network())
1127 allies.push_back(&
t);
1129 t_vars[
"player"] =
t.current_player();
1130 std::size_t t_index =
t.side()-1;
1147 for(
team*
t : allies) {
1152 for(
team*
t : allies) {
1159 std::size_t t_index = allies[selection-2]->side()-1;
1172 LOG_WB <<
"Not building planned unit map: cannot modify game state now.";
1177 LOG_WB <<
"Not building planned unit map: unit map locked.";
1181 WRN_WB <<
"Not building planned unit map: already set.";
1207 LOG_WB <<
"Not disabling planned unit map: already disabled.";
1227 DBG_WB <<
"Scoped future unit map failed to apply.";
1253 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.
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.