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();
404 if(
t.is_local_human())
412 else if(
t.is_local_ai() ||
t.is_network_ai())
414 else if(
t.is_network())
421 for(std::size_t
i=0;
i<num_teams; ++
i)
444 return range.first != range.second;
449 LOG_WB <<
"'gamestate_mutated_' flag dirty, validating actions.";
462 std::vector<std::size_t>& team_numbers = numbers.
team_numbers;
466 const double x_offset_base = 0.0;
467 const double y_offset_base = 0.2;
470 const double x_origin = 0.8 - numbers_to_draw.size() * x_offset_base;
472 const double y_origin = 0.5 - numbers_to_draw.size() * (y_offset_base / 2);
473 double x_offset = 0, y_offset = 0;
475 std::size_t
size = numbers_to_draw.size();
476 for(std::size_t
i=0;
i<
size; ++
i)
478 int number = numbers_to_draw[
i];
480 std::string number_text = std::to_string(number);
481 std::size_t font_size;
482 if (
static_cast<int>(
i) == main_number) font_size = 19;
483 else if (secondary_numbers.find(
i)!=secondary_numbers.end()) font_size = 17;
487 const double x_in_hex = x_origin + x_offset;
488 const double y_in_hex = y_origin + y_offset;
490 number_text, font_size, color, x_in_hex, y_in_hex);
491 x_offset += x_offset_base;
492 y_offset += y_offset_base;
502 struct move_owners_finder:
public visitor
506 move_owners_finder(): move_owners_() { }
508 void operator()(action* action) {
509 action->accept(*
this);
512 const std::set<std::size_t>& get_units_owning_moves() {
517 if(std::size_t
id = move->get_unit_id()) {
518 move_owners_.insert(
id);
524 if(attack->get_route().steps.size() >= 2) {
525 if(std::size_t
id = attack->get_unit_id()) {
526 move_owners_.insert(
id);
535 std::set<std::size_t> move_owners_;
542 move_owners_finder move_finder;
548 if(unit_iter.
valid()) {
560 if (unit_iter.
valid()) {
615 DBG_WB <<
"Manager received gamestate change notification.";
628 for(std::size_t team_index=0; team_index<
size; ++team_index)
637 wb_cfg[
"side"] =
static_cast<int>(team_index+1);
645 LOG_WB <<
"Side " << (team_index+1) <<
" sent wb data (" << count <<
" cmds).";
653 std::size_t count = wb_cfg->child_count(
"net_cmd");
654 LOG_WB <<
"Received wb data (" << count <<
").";
683 if (route.
steps.empty() || route.
steps.size() < 2)
return;
685 unit* temp_moved_unit =
687 if (!temp_moved_unit) temp_moved_unit =
689 if (!temp_moved_unit)
return;
705 std::size_t turn = 0;
709 for(; curr_itor!=end_itor; ++curr_itor)
714 pathfind::marked_route::mark_map::const_iterator
w =
715 route.
marks.find(hex);
716 if(
w != route.
marks.end() &&
w->second.turns > 0)
718 turn =
w->second.turns-1;
731 move_arrow.reset(
new arrow());
738 move_arrow->set_path(
path);
744 if(!fake_unit || fake_unit.
get_unit_ptr()->id() != temp_moved_unit->
id())
748 fake_unit->anim_comp().set_ghosted(
true);
753 fake_unit->set_location(*curr_itor);
754 fake_unit->anim_comp().set_ghosted(
true);
759 prev_itor = curr_itor;
796 for(std::size_t
i=0;
i<
size; ++
i)
802 std::size_t turn = first_turn +
i;
807 route.
steps = move_arrow->get_path();
830 assert(weapon_choice >= 0);
844 assert(
route_->steps.back() == attacker_loc);
845 source_hex =
route_->steps.front();
847 (**fake_unit).anim_comp().set_disabled_ghosted(
true);
852 move_arrow.reset(
new arrow);
853 source_hex = attacker_loc;
856 route_->steps.push_back(attacker_loc);
860 assert(attacking_unit);
878 bool created_planned_recruit =
false;
883 LOG_WB <<
"manager::save_recruit called for a different side than viewing side.";
884 created_planned_recruit =
false;
896 created_planned_recruit =
true;
901 return created_planned_recruit;
906 bool created_planned_recall =
false;
912 LOG_WB <<
"manager::save_recall called for a different side than viewing side.";
913 created_planned_recall =
false;
922 created_planned_recall =
true;
927 return created_planned_recall;
958 if (selected_unit && check_action(
viewer_actions()->find_first_action_of(*selected_unit)))
986 ERR_WB <<
"Modifying action queue while temp modifiers are applied1!!!";
1016 ERR_WB <<
"Modifying action queue while temp modifiers are applied!!!";
1021 while (sa->turn_begin(0) != sa->turn_end(0))
1023 bool action_successful = sa->execute(sa->begin());
1026 if (!action_successful)
1092 assert(
unit !=
nullptr);
1116 std::vector<team*> allies;
1117 std::vector<std::string> options;
1120 options.emplace_back(
_(
"SHOW ALL allies’ plans"));
1121 options.emplace_back(
_(
"HIDE ALL allies’ plans"));
1127 if(
t.is_enemy(v_side) || !
t.is_network())
1130 allies.push_back(&
t);
1132 t_vars[
"player"] =
t.current_player();
1133 std::size_t t_index =
t.side()-1;
1135 options.emplace_back(
VGETTEXT(
"Show plans for $player", t_vars));
1137 options.emplace_back(
VGETTEXT(
"Hide plans for $player", t_vars));
1150 for(
team*
t : allies) {
1155 for(
team*
t : allies) {
1162 std::size_t t_index = allies[selection-2]->side()-1;
1175 LOG_WB <<
"Not building planned unit map: cannot modify game state now.";
1180 LOG_WB <<
"Not building planned unit map: unit map locked.";
1184 WRN_WB <<
"Not building planned unit map: already set.";
1210 LOG_WB <<
"Not disabling planned unit map: already disabled.";
1230 DBG_WB <<
"Scoped future unit map failed to apply.";
1256 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)
Equivalent to mandatory_child, but returns an empty optional if the nth child was not found.
config & add_child(config_key_type key)
const team & viewing_team() 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.
bool invalidate(const map_location &loc)
Function to invalidate a specific tile for redrawing.
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.
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 is_unsynced()
static bool run_and_throw(const std::string &commandname, const config &data, action_spectator &spectator=get_default_spectator())
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.
@ actions_numbering
Move numbering for the whiteboard.
@ selected_hex
Image on the selected unit.
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
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::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.