52 #include <boost/lexical_cast.hpp>
61 inverted_behavior_(false),
62 self_activate_once_(true),
64 print_help_once_(true),
66 wait_for_side_init_(true),
67 planned_unit_map_active_(false),
68 executing_actions_(false),
69 executing_all_actions_(false),
70 preparing_to_end_turn_(false),
71 gamestate_mutated_(false),
72 activation_state_lock_(new bool),
73 unit_map_lock_(new bool),
79 temp_move_unit_underlying_id_(0),
80 key_poller_(new
CKey),
86 LOG_WB <<
"Manager initialized.\n";
91 LOG_WB <<
"Manager destroyed.\n";
106 if (!print_help_once_)
109 print_help_once_ =
false;
111 print_to_chat(
"whiteboard",
std::string(
"Type :wb to activate/deactivate planning mode.")
112 +
" Hold TAB to temporarily deactivate/activate it.");
113 std::stringstream hotkeys;
115 if(!hk_execute.null()) {
117 hotkeys <<
"Execute: " << hk_execute.get_name() <<
", ";
120 if(!hk_execute_all.null()) {
122 hotkeys <<
"Execute all: " << hk_execute_all.get_name() <<
", ";
125 if(!hk_delete.null()) {
127 hotkeys <<
"Delete: " << hk_delete.get_name() <<
", ";
130 if(!hk_bump_up.null()) {
132 hotkeys <<
"Move earlier: " << hk_bump_up.get_name() <<
", ";
135 if(!hk_bump_down.null()) {
137 hotkeys <<
"Move later: " << hk_bump_down.get_name() <<
", ";
139 print_to_chat(
"HOTKEYS:", hotkeys.str() +
"\n");
173 LOG_WB <<
"Whiteboard can't be activated now.\n";
188 LOG_WB <<
"Whiteboard deactivated!\n";
199 bool block_whiteboard_activation =
false;
202 block_whiteboard_activation =
true;
211 DBG_WB <<
"Whiteboard deactivated temporarily.\n";
215 else if (!block_whiteboard_activation)
217 DBG_WB <<
"Whiteboard activated temporarily.\n";
229 DBG_WB <<
"Whiteboard set back to deactivated status.\n";
233 else if (!block_whiteboard_activation)
235 DBG_WB <<
"Whiteboard set back to activated status.\n";
267 WRN_WB <<
"Unable to build future map to determine whether leader's allowed to move." << std::endl;
282 if(recruit || recall)
284 map_location const target_hex = recruit?recruit->get_recruit_hex():recall->get_recall_hex();
299 LOG_WB <<
"on_init_side()\n";
317 LOG_WB <<
"on_finish_side_turn()\n";
332 unit_ptr actor = action->get_unit();
335 if(action_it != side_actions->end()) {
336 move_ptr move = boost::dynamic_pointer_cast<
class move>(*action_it);
337 if(move && move->get_fake_unit()) {
338 move->get_fake_unit()->anim_comp().set_standing(
true);
347 t.get_side_actions()->hide();
362 if(!
t.is_network_human())
366 t.get_side_actions()->hide();
368 t.get_side_actions()->show();
402 for(
size_t i=0;
i<num_teams; ++
i)
418 return range.first != range.second;
423 LOG_WB <<
"'gamestate_mutated_' flag dirty, validating actions.\n";
436 std::vector<size_t>& team_numbers = numbers.
team_numbers;
440 const double x_offset_base = 0.0;
441 const double y_offset_base = 0.2;
444 const double x_origin = 0.8 - numbers_to_draw.size() * x_offset_base;
446 const double y_origin = 0.5 - numbers_to_draw.size() * (y_offset_base / 2);
447 double x_offset = 0, y_offset = 0;
449 size_t size = numbers_to_draw.size();
452 int number = numbers_to_draw[
i];
456 if (
int(
i) == main_number) font_size = 19;
457 else if (secondary_numbers.find(
i)!=secondary_numbers.end()) font_size = 17;
461 const double x_in_hex = x_origin + x_offset;
462 const double y_in_hex = y_origin + y_offset;
464 number_text, font_size, color, x_in_hex, y_in_hex);
465 x_offset += x_offset_base;
466 y_offset += y_offset_base;
476 struct move_owners_finder:
public visitor
480 move_owners_finder(): move_owners_() { }
482 void operator()(action* action) {
483 action->accept(*
this);
486 std::set<size_t>
const& get_units_owning_moves() {
491 if(
size_t id = move->get_unit_id()) {
492 move_owners_.insert(
id);
498 if(attack->get_route().steps.size() >= 2) {
499 if(
size_t id = attack->get_unit_id()) {
500 move_owners_.insert(
id);
509 std::set<size_t> move_owners_;
516 move_owners_finder move_finder;
522 assert(unit_iter.
valid());
533 if (unit_iter.
valid()) {
537 units_owning_moves_.clear();
574 if (!((selected_hex.
valid() && hex_has_unit)
588 DBG_WB <<
"Manager received gamestate change notification.\n";
601 for(
size_t team_index=0; team_index<
size; ++team_index)
610 wb_cfg[
"side"] =
static_cast<int>(team_index+1);
618 LOG_WB <<
"Side " << (team_index+1) <<
" sent wb data (" << count <<
" cmds).\n";
626 size_t count = wb_cfg.child_count(
"net_cmd");
627 LOG_WB <<
"Received wb data (" << count <<
").\n";
656 if (route.
steps.empty() || route.
steps.size() < 2)
return;
658 unit* temp_moved_unit =
660 if (!temp_moved_unit) temp_moved_unit =
662 if (!temp_moved_unit)
return;
682 for(; curr_itor!=end_itor; ++curr_itor)
687 pathfind::marked_route::mark_map::const_iterator
w =
688 route.
marks.find(hex);
689 if(w != route.
marks.end() && w->second.turns > 0)
691 turn = w->second.turns-1;
704 move_arrow.reset(
new arrow());
711 move_arrow->set_path(path);
717 if(!fake_unit || fake_unit.
get_unit_ptr()->id() != temp_moved_unit->
id())
721 fake_unit->anim_comp().set_ghosted(
true);
726 fake_unit->set_location(*curr_itor);
727 fake_unit->anim_comp().set_ghosted(
true);
732 prev_itor = curr_itor;
775 size_t turn = first_turn +
i;
781 route.
steps = move_arrow->get_path();
784 sa.
queue_move(turn,*u,route,move_arrow,fake_unit);
802 assert(weapon_choice >= 0);
816 assert(
route_->steps.back() == attacker_loc);
817 source_hex =
route_->steps.front();
819 fake_unit->anim_comp().set_disabled_ghosted(
true);
824 move_arrow.reset(
new arrow);
825 source_hex = attacker_loc;
828 route_->steps.push_back(attacker_loc);
832 assert(attacking_unit);
850 bool created_planned_recruit =
false;
855 LOG_WB <<
"manager::save_recruit called for a different side than viewing side.\n";
856 created_planned_recruit =
false;
868 created_planned_recruit =
true;
873 return created_planned_recruit;
878 bool created_planned_recall =
false;
884 LOG_WB <<
"manager::save_recall called for a different side than viewing side.\n";
885 created_planned_recall =
false;
894 created_planned_recall =
true;
899 return created_planned_recall;
981 ERR_WB <<
"Modifying action queue while temp modifiers are applied!!!" << std::endl;
986 while (sa->turn_begin(0) != sa->turn_end(0))
988 bool action_successful = sa->execute(sa->begin());
991 if (!action_successful)
1058 assert(unit !=
nullptr);
1068 return resources::teams->at(side - 1).get_side_actions()->get_gold_spent();
1077 std::vector<team*> allies;
1078 std::vector<std::string>
options;
1081 options.push_back(
_(
"SHOW ALL allies’ plans"));
1082 options.push_back(
_(
"HIDE ALL allies’ plans"));
1088 if(
t.is_enemy(v_side) || !
t.is_network())
1091 allies.push_back(&
t);
1093 t_vars[
"player"] =
t.current_player();
1094 size_t t_index =
t.side()-1;
1096 options.push_back(
vgettext(
"Show plans for $player", t_vars));
1098 options.push_back(
vgettext(
"Hide plans for $player", t_vars));
1111 for(
team*
t : allies) {
1116 for(
team*
t : allies) {
1123 size_t t_index = allies[selection-2]->side()-1;
1136 LOG_WB <<
"Not building planned unit map: cannot modify game state now.\n";
1141 LOG_WB <<
"Not building planned unit map: unit map locked.\n";
1145 WRN_WB <<
"Not building planned unit map: already set." << std::endl;
1149 log_scope2(
"whiteboard",
"Building planned unit map");
1164 log_scope2(
"whiteboard",
"Restoring regular unit map.");
1171 LOG_WB <<
"Not disabling planned unit map: already disabled.\n";
1191 DBG_WB <<
"Scoped future unit map failed to apply.\n";
1217 DBG_WB <<
"Scoped future unit map failed to apply.\n";
void clear()
Clears the stack of undoable (and redoable) actions.
container::iterator iterator
bool initial_planned_unit_map_
play_controller * controller
child_itors child_range(const std::string &key)
void reset()
Reset the internal unit pointer, and deregister from the manager. This fake_unit_ptr is now dissassoc...
events::mouse_handler & get_mouse_handler_base()
Get a reference to a mouse handler member a derived class uses.
const std::string & id() const
virtual void send_to_wesnothd(const config &, const std::string &="unknown") const
boost::shared_ptr< wb::side_actions > get_side_actions() const
get the whiteboard planned actions for this team
Arrows destined to be drawn on the map.
bool can_activate() const
Determine whether the whiteboard can be activated safely.
void update_plan_hiding()
bool invalidate(const map_location &loc)
Function to invalidate a specific tile for redrawing.
bool can_enable_modifier_hotkeys() const
Used to ask the whiteboard if hotkeys affecting the action queue should be available to the user...
size_t underlying_id() const
The unique internal ID of the unit.
boost::shared_ptr< attack > attack_ptr
void on_viewer_change(size_t team_index)
void process_network_data(config const &)
Called by turn_info::process_network_data() when network data needs to be processed.
bool can_enable_reorder_hotkeys() const
Used to ask the whiteboard if its action reordering hotkeys should be available to the user...
bool initial_planned_unit_map_
internal_ptr get_unit_ptr()
Get a copy of the internal unit pointer.
bool show(CVideo &video, const unsigned auto_close_time=0)
Shows the window.
void clear_exclusive_draws()
Cancels all the exclusive draw requests.
std::vector< int > numbers_to_draw
std::vector< arrow_ptr > move_arrows_
void set_invert_behavior(bool invert)
Called by the key that temporarily toggles the activated state when held.
void contextual_delete()
Deletes last action in the queue for current side.
whiteboard_lock activation_state_lock_
Reference counted "lock" to allow preventing whiteboard activation state changes. ...
bool is_enemy(int n) const
unit * find_recruiter(size_t team_index, map_location const &hex)
void validate_actions_if_needed()
bool has_actions()
Return whether the whiteboard has actions.
const pathfind::marked_route & get_current_route() const
void post_delete_action(action_ptr action)
Handles various cleanup right after removing an action from the queue.
boost::scoped_ptr< mapbuilder > mapbuilder_
void save_suppose_dead(unit &curr_unit, map_location const &loc)
Creates a suppose-dead action for the current side.
int path_cost(std::vector< map_location > const &path, unit const &u)
Computes the MP cost for u to travel path.
boost::shared_ptr< highlighter > highlighter_
void draw_text_in_hex(const map_location &loc, const tdrawing_layer layer, const std::string &text, size_t font_size, SDL_Color color, double x_in_hex=0.5, double y_in_hex=0.5)
Draw text on a hex.
size_t temp_move_unit_underlying_id_
const std::string number
template to number regex
bool executing_all_actions_
Track whether we're in the process of executing all actions.
void pre_draw()
Called from the display before drawing.
iterator queue_suppose_dead(size_t turn_num, unit &curr_unit, map_location const &loc)
Queues a suppose_dead to be executed last.
void contextual_bump_down_action()
Moves the action determined by the UI toward the beginning of the queue.
map_location get_selected_hex() const
std::vector< map_location > arrow_path_t
std::set< size_t > secondary_numbers
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< fake_unit_ptr > fake_units_
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)
boost::shared_ptr< suppose_dead > suppose_dead_ptr
bool can_enable_execution_hotkeys() const
Used to ask the whiteboard if its action execution hotkeys should be available to the user...
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_
iterator queue_recruit(size_t turn_num, const std::string &unit_name, const map_location &recruit_hex)
Queues a recruit to be executed last.
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...
static std::vector< team > *& teams
This class stores all the data for a single 'side' (in game nomenclature).
static std::string at(const std::string &file, int line)
static UNUSEDNOWARN std::string _(const char *str)
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::vector< size_t > team_numbers
boost::scoped_ptr< pathfind::marked_route > route_
GLsizei const char ** path
whiteboard_lock unit_map_lock_
Reference counted "lock" to prevent the building of the unit map at certain times.
iterator queue_move(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.
std::map< std::string, t_string > string_map
void queue_net_cmd(size_t team_index, side_actions::net_cmd const &)
Adds a side_actions::net_cmd to net_buffer_[team_index], whereupon it will (later) be sent to all all...
size_t num_turns() const
Returns the number of turns that have plans.
void set_real_unit_map()
Restore the regular unit map.
int current_side() const
Returns the number of the side whose turn it is.
std::vector< team > * teams
bool has_actions() const
Checks whether the whiteboard has any planned action on any team.
void options_dlg()
Displays the whiteboard options dialog.
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...
unit_map::iterator get_temp_move_unit() const
Applies the planned unit map for the duration of the struct's life.
filter_context * filter_con
GLubyte GLubyte GLubyte GLubyte w
void contextual_execute()
Executes first action in the queue for current side.
static bool valid_path(arrow_path_t const &path)
Checks that the path is not of length 0 or 1.
iterator queue_recall(size_t turn_num, const unit &unit, const map_location &recall_hex)
Queues a recall to be executed last.
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_
static std::string const STYLE_HIGHLIGHTED
Class that handles highlighting planned actions as you hover over them and determine the right target...
int selected_index() const
Returns the selected item index after displaying.
config & add_child(const std::string &key)
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.
std::set< size_t > units_owning_moves_
used to keep track of units owning planned moves for visual ghosting/unghosting
bool is_local_human() const
Modify, read and display user preferences.
#define log_scope2(domain, description)
iterator queue_attack(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.
void ghost_owner_unit(unit *unit)
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)
GLuint GLuint GLsizei count
void on_finish_side_turn(int side)
size_t get_turn_num_of(unit const &) const
Determines the appropriate turn number for the next action planned for this unit. ...
std::vector< bool > team_plans_hidden_
team_plans_hidden_[i] = whether or not to hide actions from teams[i].
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.
Various functions related to the creation of units (recruits, recalls, and placed units)...
size_t team_index()
Returns the team index this action queue belongs to.
Move numbering for the whiteboard.
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.
bool can_modify_game_state() const
Determine whether the game is initialized and the current side has control of the game i...
std::vector< config > net_buffer_
net_buffer_[i] = whiteboard network data to be sent "from" teams[i].
std::pair< iterator, iterator > range_t
static SDL_Color get_side_color(int side)
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.
bool allow_leader_to_move(unit const &leader) const
Used to ask permission to the wb to move a leader, to avoid invalidating planned recruits.
side_actions_ptr viewer_actions()
unsigned child_count(const std::string &key) const
void contextual_bump_up_action()
Moves the action determined by the UI toward the beginning of the queue.
net_cmd make_net_cmd_clear() const
GLuint const GLchar * name
void on_init_side()
The on_* methods below inform the whiteboard of specific events.
bool save_recall(const unit &unit, int side_num, const map_location &recall_hex)
Creates a recall action for the current side.
void send_network_data()
Called by replay_network_sender to add whiteboard data to the outgoing network packets.
boost::shared_ptr< move > move_ptr
static void draw_numbers(map_location const &hex, side_actions::numbers_t numbers)
config & child(const std::string &key, int n=0)
Returns the nth child with the given key, or a reference to an invalid config if there is none...
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.
bool is_network_ai() const
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.
GLsizei GLenum GLuint GLuint GLsizei char * message
static std::string get_side_color_index(int side)
unit * future_visible_unit(map_location hex, int viewer_side)
Applies the future unit map and.
bool should_clear_undo() const
Determines whether or not the undo_stack should be cleared.
boost::shared_ptr< wb::manager > whiteboard
actions::undo_list * undo_stack
bool has_temp_move() const
Informs whether an arrow is being displayed for move creation purposes.
unit_iterator find(size_t id)
boost::shared_ptr< recall > recall_ptr
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.
bool execute_all_actions()
Executes all actions for the current turn in sequence.
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.
GLsizei const GLcharARB ** string
This internal whiteboard class holds the planned action queues for a team, and offers many utility me...
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...
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.
boost::shared_ptr< recruit > recruit_ptr
std::vector< map_location > & steps
bool unit_has_actions(unit const *unit) const
Checks whether the specified unit has at least one planned action.
bool has_planned_unit_map() const
Whether the planned unit map is currently applied.
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.
side_actions_ptr current_side_actions()