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");
178 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.";
302 if(recruit || recall)
304 map_location const target_hex = recruit?recruit->get_recruit_hex():recall->get_recall_hex();
319 LOG_WB <<
"on_init_side()";
337 LOG_WB <<
"on_finish_side_turn()";
352 unit_ptr actor = action->get_unit();
355 if(action_it != side_actions->end()) {
356 move_ptr move = std::dynamic_pointer_cast<
class move>(*action_it);
357 if(move && move->get_fake_unit()) {
367 t.get_side_actions()->hide();
382 if(!
t.is_network_human())
386 t.get_side_actions()->hide();
388 t.get_side_actions()->show();
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_() { }
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()) {
565 units_owning_moves_.clear();
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;
984 ERR_WB <<
"Modifying action queue while temp modifiers are applied1!!!";
1014 ERR_WB <<
"Modifying action queue while temp modifiers are applied!!!";
1019 while (sa->turn_begin(0) != sa->turn_end(0))
1021 bool action_successful = sa->execute(sa->begin());
1024 if (!action_successful)
1090 assert(unit !=
nullptr);
1114 std::vector<team*> allies;
1115 std::vector<std::string>
options;
1118 options.emplace_back(
_(
"SHOW ALL allies’ plans"));
1119 options.emplace_back(
_(
"HIDE ALL allies’ plans"));
1125 if(
t.is_enemy(v_side) || !
t.is_network())
1128 allies.push_back(&
t);
1130 t_vars[
"player"] =
t.current_player();
1131 std::size_t t_index =
t.side()-1;
1133 options.emplace_back(
VGETTEXT(
"Show plans for $player", t_vars));
1135 options.emplace_back(
VGETTEXT(
"Hide plans for $player", t_vars));
1148 for(
team*
t : allies) {
1153 for(
team*
t : allies) {
1160 std::size_t t_index = allies[selection-2]->side()-1;
1173 LOG_WB <<
"Not building planned unit map: cannot modify game state now.";
1178 LOG_WB <<
"Not building planned unit map: unit map locked.";
1182 WRN_WB <<
"Not building planned unit map: already set.";
1208 LOG_WB <<
"Not disabling planned unit map: already disabled.";
1228 DBG_WB <<
"Scoped future unit map failed to apply.";
1254 DBG_WB <<
"Scoped future unit map failed to apply.";
void clear()
Clears the stack of undoable (and redoable) actions.
container::iterator iterator
bool initial_planned_unit_map_
play_controller * controller
void reset()
Reset the internal unit pointer, and deregister from the manager.
std::shared_ptr< wb::side_actions > get_side_actions() const
get the whiteboard planned actions for this team
Move numbering for the whiteboard.
config & child(config_key_type key, int n=0)
Returns the nth child with the given key, or a reference to an invalid config if there is none...
Arrows destined to be drawn on the map.
void update_plan_hiding()
static display * get_singleton()
Returns the display object if a display object exists.
virtual const std::vector< team > & teams() const override
std::map< std::string, t_string > string_map
virtual const unit_map & units() const override
std::shared_ptr< recruit const > recruit_const_ptr
bool invalidate(const map_location &loc)
Function to invalidate a specific tile for redrawing.
This class represents a single unit of a specific type.
void on_viewer_change(std::size_t team_index)
const pathfind::marked_route & get_current_route() const
bool initial_planned_unit_map_
std::set< std::size_t > units_owning_moves_
used to keep track of units owning planned moves for visual ghosting/unghosting
internal_ptr get_unit_ptr()
Get a copy of the internal unit pointer.
void clear_exclusive_draws()
Cancels all the exclusive draw requests.
std::vector< int > numbers_to_draw
std::shared_ptr< highlighter > highlighter_
std::vector< arrow_ptr > move_arrows_
std::shared_ptr< recall const > recall_const_ptr
void set_invert_behavior(bool invert)
Called by the key that temporarily toggles the activated state when held.
unsigned child_count(config_key_type key) const
void contextual_delete()
Deletes last action in the queue for current side.
std::shared_ptr< side_actions > side_actions_ptr
whiteboard_lock activation_state_lock_
Reference counted "lock" to allow preventing whiteboard activation state changes. ...
child_itors child_range(config_key_type key)
unit * find_recruiter(std::size_t team_index, const map_location &hex)
void validate_actions_if_needed()
std::shared_ptr< attack > attack_ptr
bool has_actions()
Return whether the whiteboard has actions.
void post_delete_action(action_ptr action)
Handles various cleanup right after removing an action from the queue.
static config get_auto_shroud(bool turned_on)
Records that the player has toggled automatic shroud updates.
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.
bool is_network_ai() const
bool can_activate() const
Determine whether the whiteboard can be activated safely.
bool executing_all_actions_
Track whether we're in the process of executing all actions.
static std::string _(const char *str)
void pre_draw()
Called from the display before drawing.
bool show(const unsigned auto_close_time=0)
Shows the window.
void contextual_bump_down_action()
Moves the action determined by the UI toward the beginning of the 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::shared_ptr< unit > unit_ptr
static config get_update_shroud()
Records that the player has manually updated fog/shroud.
std::vector< map_location > arrow_path_t
void save_temp_move()
Creates a move action for the current side, and erases the temp move.
void set_active(bool active)
Activates/Deactivates the whiteboard.
std::vector< std::size_t > team_numbers
std::vector< fake_unit_ptr > fake_units_
static const std::string STYLE_HIGHLIGHTED
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.
void unghost_owner_unit(unit *unit)
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.
bool planned_unit_map_active_
static bool is_active(const widget *wgt)
map_location get_selected_hex() const
void on_gamestate_change()
void draw_hex(const map_location &hex)
Called from the display when drawing hexes, to allow the whiteboard to add visual elements...
This class stores all the data for a single 'side' (in game nomenclature).
static std::string at(const std::string &file, int line)
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.
std::size_t size(const std::string &str)
Length in characters of a UTF-8 string.
A simple one-column listbox with OK and Cancel buttons.
whiteboard_lock unit_map_lock_
Reference counted "lock" to prevent the building of the unit map at certain times.
const std::string & id() const
Gets this unit's id.
void set_real_unit_map()
Restore the regular unit map.
std::shared_ptr< recruit > recruit_ptr
void options_dlg()
Displays the whiteboard options dialog.
void process_network_data(const config &)
Called by turn_info::process_network_data() when network data needs to be processed.
Arrows destined to be drawn on the map.
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...
Applies the planned unit map for the duration of the struct's life.
filter_context * filter_con
void contextual_execute()
Executes first action in the queue for current side.
bool gamestate_mutated_
Track whether the gamestate changed and we need to validate actions.
bool allow_end_turn()
@ return true if the whiteboard is ready to end turn.
bool initial_planned_unit_map_
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.
unit_map::iterator get_temp_move_unit() const
The basic class for representing 8-bit RGB or RGBA colour values.
Class that handles highlighting planned actions as you hover over them and determine the right target...
std::shared_ptr< action > action_ptr
fake_unit_manager * fake_units
static bool current_side_has_actions()
Whether the current side has actions in the first turn of its planned actions queue.
bool is_enemy(int n) const
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.
iterator queue_recall(std::size_t turn_num, const unit &unit, const map_location &recall_hex)
Queues a recall to be executed last.
#define log_scope2(domain, description)
std::unique_ptr< pathfind::marked_route > route_
virtual fake_unit_ptr get_fake_unit()
void ghost_owner_unit(unit *unit)
iterator queue_suppose_dead(std::size_t turn_num, unit &curr_unit, const map_location &loc)
Queues a suppose_dead to be executed last.
Structure which holds a single route and marks for special events.
bool preparing_to_end_turn_
true if we're in the process of executing all action and should end turn once finished.
bool active_
Tracks whether the whiteboard is active.
static void hide_all_plans()
void for_each_action(std::function< void(action *)> function, team_filter team_filter)
Apply a function to all the actions of the whiteboard.
void on_change_controller(int side, const team &t)
void on_finish_side_turn(int side)
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...
static std::string get_side_color_id(unsigned side)
Encapsulates the map of the game.
bool save_recruit(const std::string &name, int side_num, const map_location &recruit_hex)
Creates a recruit action for the current side.
void post_draw()
Called from the display after drawing.
unit_iterator find(std::size_t id)
std::shared_ptr< wb::manager > whiteboard
Various functions related to the creation of units (recruits, recalls, and placed units)...
std::size_t get_turn_num_of(const unit &) const
Determines the appropriate turn number for the next action planned for this unit. ...
virtual bool is_networked_mp() const
std::size_t team_index()
Returns the team index this action queue belongs to.
static lg::log_domain log_whiteboard("whiteboard")
int selected_index() const
Returns the selected item index after displaying.
net_cmd make_net_cmd_clear() const
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 ...
void erase_temp_move()
Erase the temporary arrow.
std::vector< config > net_buffer_
net_buffer_[i] = whiteboard network data to be sent "from" teams[i].
bool can_modify_game_state() const
Determine whether the game is initialized and the current side has control of the game i...
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.
std::shared_ptr< suppose_dead > suppose_dead_ptr
std::pair< iterator, iterator > range_t
Class that collects and applies unit_map modifications from the actions it visits and reverts all cha...
void create_temp_move()
Creates a temporary visual arrow, that follows the cursor, for move creation purposes.
std::shared_ptr< move > move_ptr
side_actions_ptr viewer_actions()
bool unit_has_actions(unit const *unit) const
Checks whether the specified unit has at least one planned action.
void contextual_bump_up_action()
Moves the action determined by the UI toward the beginning of the queue.
config & add_child(config_key_type key)
bool has_actions() const
Checks whether the whiteboard has any planned action on any team.
std::shared_ptr< arrow > arrow_ptr
void on_init_side()
The on_* methods below inform the whiteboard of specific events.
std::size_t temp_move_unit_underlying_id_
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)
std::set< std::size_t > secondary_numbers
bool save_recall(const unit &unit, int side_num, const map_location &recall_hex)
Creates a recall action for the current side.
bool is_local_human() const
events::mouse_handler & get_mouse_handler_base() override
Get a reference to a mouse handler member a derived class uses.
void send_network_data()
Called by replay_network_sender to add whiteboard data to the outgoing network packets.
static color_t get_side_color(int side)
boost::dynamic_bitset team_plans_hidden_
team_plans_hidden_[i] = whether or not to hide actions from teams[i].
bool enable_whiteboard_mode_on_start()
Various functions that implement the undoing (and redoing) of in-game commands.
Finalizer class to help with exception safety sets variable to value on destruction.
void save_suppose_dead(unit &curr_unit, const map_location &loc)
Creates a suppose-dead action for the current side.
int current_side() const
Returns the number of the side whose turn it is.
static void draw_numbers(const map_location &hex, side_actions::numbers_t numbers)
bool has_temp_move() const
Informs whether an arrow is being displayed for move creation purposes.
unit * future_visible_unit(map_location hex, int viewer_side)
Applies the future unit map and.
bool can_enable_reorder_hotkeys() const
Used to ask the whiteboard if its action reordering hotkeys should be available to the user...
std::shared_ptr< recall > recall_ptr
int side() const
The side this unit belongs to.
actions::undo_list * undo_stack
virtual void accept(visitor &v)=0
std::size_t num_turns() const
Returns the number of turns that have plans.
bool should_clear_undo() const
Determines whether or not the undo_stack should be cleared.
Abstract base class for all the whiteboard planned actions.
A config object defines a single node in a WML file, with access to child nodes.
bool executing_actions_
Track whenever we're modifying actions, to avoid dual execution etc.
Class that keeps track of all the keys on the keyboard.
std::unique_ptr< mapbuilder > mapbuilder_
bool execute_all_actions()
Executes all actions for the current turn in sequence.
static bool valid_path(const arrow_path_t &path)
Checks that the path is not of length 0 or 1.
void on_mouseover_change(const map_location &hex)
void validate_viewer_actions()
Validates all actions of the current viewing side.
This module contains various pathfinding functions and utilities.
bool can_enable_execution_hotkeys() const
Used to ask the whiteboard if its action execution hotkeys should be available to the user...
This internal whiteboard class holds the planned action queues for a team, and offers many utility me...
std::string::const_iterator iterator
Holds a temporary unit that can be drawn on the map without being placed in the unit_map.
A planned move, represented on the map by an arrow and a ghosted unit in the destination hex...
std::size_t underlying_id() const
This unit's unique internal ID.
virtual void send_to_wesnothd(const config &, const std::string &="unknown") const
Display units performing various actions: moving, attacking, and dying.
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::vector< map_location > & steps
std::size_t viewer_team()
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.
Abstract base class for all the visitors (cf GoF Visitor Design Pattern) the whiteboard uses...
static game_display * get_singleton()
void set_planned_unit_map()
Transforms the unit map so that it now reflects the future state of things, i.e.
const std::vector< map_location > & route_
void clear()
Empties the action queue.
void pre_delete_action(action_ptr action)
Handles various cleanup right before removing an action from the queue.
bool can_enable_modifier_hotkeys() const
Used to ask the whiteboard if hotkeys affecting the action queue should be available to the user...
side_actions_ptr current_side_actions()
std::shared_ptr< action const > action_const_ptr