51 #define ERR_NG LOG_STREAM(err, log_engine)
52 #define LOG_NG LOG_STREAM(info, log_engine)
55 #define ERR_WML LOG_STREAM(err, log_wml)
64 , previous_free_hex_()
69 , unselected_paths_(false)
70 , unselected_reach_(false)
74 , reachmap_invalid_(false)
75 , show_partial_move_(false)
76 , teleport_selected_(false)
77 , preventing_units_highlight_(false)
96 const unsigned threshold_1080p = 14;
98 const double scale_factor = threshold_1080p / std::hypot(1080,1920);
99 return static_cast<int>(screen_diagonal * scale_factor);
117 if(mini_loc.
valid()) {
136 const double drag_distance = std::pow(
static_cast<double>(
drag_from_x_- mx), 2)
146 bool selected_hex_has_my_unit = found_unit.valid() && found_unit.get_shared_ptr()->side() ==
side_num_;
196 selected_hex_has_my_unit = found_unit.valid();
250 if (attack_from.
valid()) {
253 else if (!mouseover_unit &&
266 && mouseover_unit->side() ==
side_num_ ) {
291 if (attack_from.
valid()) {
321 && mouseover_unit.
valid()
348 !
gui().fogged(un->get_location()))
354 if(!
gui().viewing_team().is_enemy(un->side()) && !
pc_.
get_teams()[un->side() - 1].is_ai()) {
373 std::unique_ptr<unit_movement_resetter> move_reset;
375 move_reset = std::make_unique<unit_movement_resetter>(*un);
414 lk->mouse_over_hex_callback(new_hex);
447 bool selected_hex_has_unit;
502 if(attack_from.
valid()) {
539 if(attack_from.
valid()) {
608 static const std::array<const std::string, 6> buttons = {
617 if (
gui().view_locked() || button < SDL_BUTTON_LEFT || button > buttons.size()) {
619 }
else if (event.state > SDL_PRESSED || !
gui().get_map().on_board(loc)) {
624 lk->mouse_button_callback(loc, buttons[button], (event.state == SDL_RELEASED ?
"up" :
"down"));
633 return lk->mouse_button_callback(loc, buttons[button],
"click");
667 return it.
valid() ? &*it :
nullptr;
673 return it.
valid() ? &*it :
nullptr;
703 bool source_eligible = source_unit.
valid();
704 if(!source_eligible) {
710 if(!source_eligible) {
719 if(!source_eligible) {
725 source_eligible &= source_unit->attacks_left() != 0;
726 if(!source_eligible) {
737 bool target_eligible = target_unit.
valid();
738 if(!target_eligible) {
743 target_eligible &= viewer.
is_enemy(target_unit->side());
744 if(!target_eligible) {
749 assert(source_unit->side() != target_unit->side());
751 target_eligible &= !target_unit->incapacitated();
752 if(!target_eligible) {
760 int best_rating = 100;
765 for(std::size_t
n = 0;
n < adj.size(); ++
n) {
777 unsigned int difference = std::abs(
static_cast<int>(preferred -
n));
778 if(difference > NDIRECTIONS / 2) {
779 difference = NDIRECTIONS - difference;
782 unsigned int second_difference = std::abs(
static_cast<int>(second_preferred -
n));
783 if(second_difference > NDIRECTIONS / 2) {
784 second_difference = NDIRECTIONS - second_difference;
787 const int rating = difference * 2 + (second_difference > difference);
788 if(rating < best_rating || res.
valid() ==
false) {
789 best_rating = rating;
810 un->
get_location(), go_to, 10000.0, calc, board.
map().
w(), board.
map().
h(), &allowed_teleports);
837 if(clicked_u && (!selected_u || selected_u->side() !=
side_num_ ||
838 (clicked_u->side() ==
side_num_ && clicked_u->id() != selected_u->id()))
883 if(clicked_u && (!selected_u || selected_u->side() !=
side_num_ ||
884 (clicked_u->side() ==
side_num_ && clicked_u->id() != selected_u->id()))
912 const unit* clicked_u =
nullptr;
1161 bool invisible = u->invisible(u->get_location());
1163 if(!
gui_->
fogged(u->get_location()) && !u->incapacitated() && !invisible) {
1167 if(
path.destinations.find(hex) !=
path.destinations.end()) {
1212 bool interrupted =
false;
1213 if(steps.size() > 1) {
1216 interrupted = interrupted || num_moves + 1 < steps.size();
1224 return !interrupted;
1248 interrupted =
false;
1260 if(u && u->can_recruit() && u->side() ==
gui().viewing_team().side()
1263 _(
"You cannot move your leader away from the keep with some planned recruits or recalls left."));
1268 LOG_NG <<
"move unit along route from " << steps.front() <<
" to " << steps.back();
1277 if(interrupted && moves + 1 < steps.size()) {
1279 select_hex(steps[moves],
false,
false,
false);
1313 pc_.
get_whiteboard()->save_temp_attack(attacker_loc, defender_loc, weapon_choice);
1320 for(
unsigned int i = 0;
i < attacker->attacks().
size();
i++) {
1322 if(attacker->attacks()[
i].attack_weight() > 0) {
1330 if(!bc_vector.empty() && bc.
better_attack(bc_vector[best], 0.5)) {
1332 best = bc_vector.size();
1335 bc_vector.emplace_back(std::move(bc));
1349 if(!attacker || !defender) {
1350 ERR_NG <<
"One fighter is missing, can't attack";
1354 std::vector<battle_context> bc_vector;
1357 if(bc_vector.empty()) {
1376 }
catch(
const std::bad_alloc&) {
1377 lg::log_to_chat() <<
"Memory exhausted a unit has either a lot hitpoints or a negative amount.\n";
1378 ERR_WML <<
"Memory exhausted a unit has either a lot hitpoints or a negative amount.";
1390 unit* attacker =
nullptr;
1391 const unit* defender =
nullptr;
1392 std::vector<battle_context> bc_vector;
1396 if(!attacker_it || attacker_it->side() !=
side_num_ || attacker_it->incapacitated()) {
1401 if(!defender_it ||
current_team().is_enemy(defender_it->side()) ==
false || defender_it->incapacitated()) {
1407 attacker = &*attacker_it;
1408 defender = &*defender_it;
1411 if(std::size_t(choice) >= bc_vector.size()) {
1455 std::set<map_location> res;
1479 if(u->attacks_left() == 0) {
1496 if(!
i || !
i->is_visible_to_team(cur_team,
false)) {
1500 const unit& target = *
i;
1521 if(
current_team().is_enemy(
gui().viewing_team().side()) && it->invisible(it->get_location())) {
1525 if(it->get_hidden()) {
1549 if(it == units.
begin()) {
1555 if(it == units.
end()) {
Various functions that implement attacks and attack calculations.
Various functions related to moving units.
Computes the statistics of a battle between an attacker and a defender unit.
const battle_context_unit_stats & get_attacker_stats() const
This method returns the statistics of the attacker.
bool better_attack(class battle_context &that, double harm_weight)
Given this harm_weight, is this attack better than that?
can_move_result unit_can_move(const unit &u) const
Work out what u can do - this does not check which player's turn is currently active,...
const team & viewing_team() const
const map_location hex_clicked_on(int x, int y) const
given x,y co-ordinates of an onscreen pixel, will return the location of the hex that this pixel corr...
bool scroll(int xmov, int ymov, bool force=false)
Scrolls the display by xmov,ymov pixels.
void invalidate_game_status()
Function to invalidate the game status displayed on the sidebar.
void scroll_to_tile(const map_location &loc, SCROLL_TYPE scroll_type=ONSCREEN, bool check_fogged=true, bool force=true)
Scroll such that location loc is on-screen.
bool fogged(const map_location &loc) const
Returns true if location (x,y) is covered in fog.
void invalidate_all()
Function to invalidate all tiles.
map_location minimap_location_on(int x, int y)
given x,y co-ordinates of the mouse, will return the location of the hex in the minimap that the mous...
rect map_area() const
Returns the area used for the map.
bool minimap_scrolling_
minimap scrolling (scroll-drag) state flag
map_location last_hex_
last highlighted hex
map_location drag_from_hex_
Drag start or mouse-down map location.
int drag_from_y_
Drag start position y.
bool simple_warp_
MMB click (on game map) state flag.
bool mouse_motion_default(int x, int y, bool update)
This handles minimap scrolling and click-drag.
bool dragging_started_
Actual drag flag.
bool dragging_touch_
Finger drag init flag.
int drag_from_x_
Drag start position x.
void disable_units_highlight()
Use this to disable hovering an unit from highlighting its movement range.
bool move_unit_along_current_route()
Moves a unit along the currently cached route.
bool mouse_button_event(const SDL_MouseButtonEvent &event, uint8_t button, map_location loc, bool click=false) override
int show_attack_dialog(const map_location &attacker_loc, const map_location &defender_loc)
map_location previous_hex_
void show_reach_for_unit(const unit_ptr &un)
Highlight the hexes that a unit can move to.
game_display & gui() override
Due to the way this class is constructed we can assume that the display* gui_ member actually points ...
void select_or_action(bool browse)
void attack_enemy_(const map_location &attacker_loc, const map_location &defender_loc, int choice)
void save_whiteboard_attack(const map_location &attacker_loc, const map_location &defender_loc, int weapon_choice)
void set_current_paths(const pathfind::paths &new_paths)
pathfind::marked_route get_route(const unit *un, map_location go_to, const team &team) const
unit_map::iterator selected_unit()
static mouse_handler * singleton_
int fill_weapon_choices(std::vector< battle_context > &bc_vector, unit_map::iterator attacker, unit_map::iterator defender)
void enable_units_highlight()
When unit highlighting is disabled, call this when the mouse no longer hovers any unit to enable high...
void touch_motion(int x, int y, const bool browse, bool update=false, map_location loc=map_location::null_location()) override
void attack_enemy(const map_location &attacker_loc, const map_location &defender_loc, int choice)
std::set< map_location > get_adj_enemies(const map_location &loc, int side) const
map_location previous_free_hex_
void select_hex(const map_location &hex, const bool browse, const bool highlight=true, const bool fire_event=true)
unit_map::const_iterator find_unit(const map_location &hex) const
map_location current_unit_attacks_from(const map_location &loc) const
mouse_handler(game_display *gui, play_controller &pc)
bool right_click_show_menu(int x, int y, const bool browse) override
Called in the default right_click when the context menu is about to be shown, can be used for preproc...
map_location selected_hex_
pathfind::marked_route current_route_
const map_location hovered_hex() const
Uses SDL and game_display::hex_clicked_on to fetch the hex the mouse is hovering, if applicable.
void touch_action(const map_location hex, bool browse) override
bool unit_in_cycle(unit_map::const_iterator it)
void set_side(int side_number)
void move_action(bool browse) override
Overridden in derived class.
pathfind::paths current_paths_
If non-empty, current_paths_.destinations contains a cache of highlighted hexes, likely the movement ...
bool hex_hosts_unit(const map_location &hex) const
Unit exists on the hex, no matter if friend or foe.
int drag_threshold() const override
Minimum dragging distance to fire the drag&drop.
unit * find_unit_nonowning(const map_location &hex)
bool preventing_units_highlight_
void cycle_units(const bool browse, const bool reverse=false)
std::size_t move_unit_along_route(const std::vector< map_location > &steps, bool &interrupted)
Moves a unit across the board for a player.
void show_attack_options(const unit_map::const_iterator &u)
Causes attackable hexes to be highlighted.
void mouse_motion(int x, int y, const bool browse, bool update=false, map_location loc=map_location::null_location()) override
Use update to force an update of the mouse state.
virtual const std::vector< team > & teams() const override
unit_map::iterator find_visible_unit(const map_location &loc, const team ¤t_team, bool see_all=false)
virtual const unit_map & units() const override
virtual const gamemap & map() const override
void display_unit_hex(map_location hex)
Change the unit to be displayed in the sidebar.
virtual void highlight_hex(map_location hex) override
Function to highlight a location.
void set_attack_indicator(const map_location &src, const map_location &dst)
Set the attack direction indicator.
void set_route(const pathfind::marked_route *route)
Sets the route along which footsteps are drawn to show movement of a unit.
virtual void select_hex(map_location hex) override
Function to display a location as selected.
void highlight_reach(const pathfind::paths &paths_list)
Sets the paths that are currently displayed as available for the unit to move along.
void clear_attack_indicator()
void highlight_another_reach(const pathfind::paths &paths_list, const map_location &goal=map_location::null_location())
Add more paths to highlight.
bool unhighlight_reach()
Reset highlighting of paths.
pump_result_t fire(const std::string &event, const entity_location &loc1=entity_location::null_entity, const entity_location &loc2=entity_location::null_entity, const config &data=config())
Function to fire an event.
std::unique_ptr< game_lua_kernel > lua_kernel_
int w() const
Effective map width.
int h() const
Effective map height.
bool on_board(const map_location &loc) const
Tell if a location is on the map.
bool is_keep(const map_location &loc) const
bool show(const unsigned auto_close_time=0)
Shows the window.
int get_selected_weapon() const
std::vector< team > & get_teams()
actions::undo_list & get_undo_stack()
const unit_map & get_units() const
const tod_manager & get_tod_manager() const
int current_side() const
Returns the number of the side whose turn it is.
std::shared_ptr< wb::manager > get_whiteboard() const
const gamemap & get_map() const
game_events::wml_event_pump & pump()
static config get_attack(const map_location &a, const map_location &b, int att_weapon, int def_weapon, const std::string &attacker_type_id, const std::string &defender_type_id, int attacker_lvl, int defender_lvl, const std::size_t turn, const time_of_day &t)
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)
This class stores all the data for a single 'side' (in game nomenclature).
void set_action_bonus_count(const int count)
bool is_enemy(int n) const
const time_of_day & get_time_of_day(int for_turn=0) const
Returns global time of day for the passed turn.
void set_selecting()
Sets the animation state to that when the unit is selected.
Container associating units to locations.
unit_iterator find(std::size_t id)
This class represents a single unit of a specific type.
Definitions for the interface to Wesnoth Markup Language (WML).
static std::string _(const char *str)
bool incapacitated() const
Check if the unit has been petrified.
const std::string & type_id() const
The id of this unit's type.
bool get_hidden() const
Gets whether this unit is currently hidden on the map.
int side() const
The side this unit belongs to.
unit_animation_component & anim_comp() const
const map_location & get_location() const
The current map location this unit is at.
void set_goto(const map_location &new_goto)
Sets this unit's long term destination.
void get_adjacent_tiles(const map_location &a, map_location *res)
Function which, given a location, will place all adjacent locations in res.
Standard logging facilities (interface).
static lg::log_domain log_engine("engine")
static lg::log_domain log_wml("wml")
std::size_t move_unit_and_record(const std::vector< map_location > &steps, undo_list *undo_stack, bool continued_move, bool show_move, bool *interrupted, move_unit_spectator *move_spectator)
Moves a unit across the board.
void teleport_unit_and_record(const map_location &teleport_from, const map_location &teleport_to, bool show_move, move_unit_spectator *move_spectator)
Teleports a unit across the board and enters the synced context.
void set(CURSOR_TYPE type)
Use the default parameter to reset cursors.
Handling of system events.
bool fire_event(const ui_event event, const std::vector< std::pair< widget *, ui_event >> &event_chain, widget *dispatcher, widget *w, F &&... params)
Helper function for fire_event.
unsigned screen_width
The screen resolution and pixel pitch should be available for all widgets since their drawing method ...
void show_transient_message(const std::string &title, const std::string &message, const std::string &image, const bool message_use_markup, const bool title_use_markup)
Shows a transient message to the user.
std::stringstream & log_to_chat()
Use this to show WML errors in the ingame chat.
plain_route a_star_search(const map_location &src, const map_location &dst, double stop_at, const cost_calculator &calc, const std::size_t width, const std::size_t height, const teleport_map *teleports, bool border)
marked_route mark_route(const plain_route &rt, bool update_move_cost)
Add marks on a route rt assuming that the unit located at the first hex of rt travels along it.
const teleport_map get_teleport_locations(const unit &u, const team &viewing_team, bool see_all, bool ignore_units, bool check_vision)
uint32_t get_mouse_state(int *x, int *y)
A wrapper for SDL_GetMouseState that gives coordinates in draw space.
void play_UI_sound(const std::string &files)
std::size_t size(const std::string &str)
Length in characters of a UTF-8 string.
bool contains(const Container &container, const Value &value)
Returns true iff value is found in container.
std::shared_ptr< bool > whiteboard_lock
std::shared_ptr< unit > unit_ptr
Define the game's event mechanism.
This file contains the settings handling of the widget library.
rect src
Non-transparent portion of the surface to compose.
Structure describing the statistics of a unit involved in the battle.
bool disable
Attack has disable special.
int attack_num
Index into unit->attacks() or -1 for none.
Encapsulates the map of the game.
DIRECTION
Valid directions which can be moved in our hexagonal world.
DIRECTION get_relative_dir(const map_location &loc, map_location::RELATIVE_DIR_MODE mode) const
static const map_location & null_location()
Structure which holds a single route and marks for special events.
std::vector< map_location > & steps
void insert(const map_location &)
bool contains(const map_location &) const
const_iterator find(const map_location &) const
Object which contains all the possible locations a unit can move to, with associated best routes to t...
Structure which holds a single route between one location and another.
bool contains(int x, int y) const
Whether the given point lies within the rectangle.
This object is used to temporary move a unit in the unit map, swapping out any unit that is already t...
pointer get_shared_ptr() const
This is exactly the same as operator-> but it's slightly more readable, and can replace &*iter syntax...
ONLY IF whiteboard is currently active, applies the planned unit map for the duration of the struct's...
Ensures that the real unit map is active for the duration of the struct's life.
static map_location::DIRECTION n
Contains typedefs for the whiteboard.