The Battle for Wesnoth  1.17.0-dev
mouse_action_unit.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2008 - 2021
3  by Fabian Mueller <fabianmueller5@gmx.de>
4  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY.
12 
13  See the COPYING file for more details.
14 */
15 
16 #define GETTEXT_DOMAIN "wesnoth-editor"
17 
20 
22 #include "formula/string_utils.hpp"
24 #include "tooltips.hpp"
25 #include "gettext.hpp"
26 
27 #include "map/location.hpp"
28 #include "sdl/rect.hpp"
29 #include "team.hpp"
30 #include "units/unit.hpp"
31 #include "units/map.hpp"
32 
33 namespace editor {
34 
35 
37 {
38  if (hex != previous_move_hex_) {
39 
40  update_brush_highlights(disp, hex);
41 
42  std::set<map_location> adjacent_set;
44  adjacent_set.insert(adj);
45  }
46 
47  disp.invalidate(adjacent_set);
48  previous_move_hex_ = hex;
49 
50  const unit_map& units = disp.get_units();
51  const unit_map::const_unit_iterator unit_it = units.find(hex);
52  if (unit_it != units.end()) {
53 
54  disp.set_mouseover_hex_overlay(nullptr);
55 
56  SDL_Rect rect;
57  rect.x = disp.get_location_x(hex);
58  rect.y = disp.get_location_y(hex);
59  rect.h = disp.hex_size();
60  rect.w = disp.hex_size();
61  std::stringstream str;
62  str << _("Identifier: ") << unit_it->id() << "\n";
63  if(unit_it->name() != "") {
64  str << _("Name: ") << unit_it->name() << "\n";
65  }
66  str << _("Type: ") << unit_it->type_name() << "\n"
67  << _("Level: ") << unit_it->level() << "\n"
68  << _("Cost: ") << unit_it->cost() << "\n";
70  tooltips::add_tooltip(rect, str.str());
71  }
72  else {
73  set_mouse_overlay(disp);
74  }
75  }
76 }
77 
78 std::unique_ptr<editor_action> mouse_action_unit::click_left(editor_display& disp, int x, int y)
79 {
80  start_hex_ = disp.hex_clicked_on(x, y);
81  if (!disp.get_map().on_board(start_hex_)) {
82  return nullptr;
83  }
84 
85  const unit_map& units = disp.get_units();
86  const unit_map::const_unit_iterator unit_it = units.find(start_hex_);
87  if (unit_it != units.end())
88  set_unit_mouse_overlay(disp, unit_it->type());
89 
90  click_ = true;
91  return nullptr;
92 }
93 
94 std::unique_ptr<editor_action> mouse_action_unit::drag_left(editor_display& disp, int x, int y, bool& /*partial*/, editor_action* /*last_undo*/)
95 {
96  map_location hex = disp.hex_clicked_on(x, y);
97  click_ = (hex == start_hex_);
98  return nullptr;
99 }
100 
101 std::unique_ptr<editor_action> mouse_action_unit::up_left(editor_display& disp, int x, int y)
102 {
103  if (!click_) return nullptr;
104  click_ = false;
105  map_location hex = disp.hex_clicked_on(x, y);
106  if (!disp.get_map().on_board(hex)) {
107  return nullptr;
108  }
109 
111 
112  // Does this serve a purpose other than making sure the type is built?
113  // (Calling unit_types.build_unit_type(type) would now accomplish that
114  // with less overhead.)
115  const std::string& type_id = type.id();
116  const unit_type *new_unit_type = unit_types.find(type_id);
117  if (!new_unit_type) {
118  //TODO rewrite the error message.
119  ERR_ED << "create unit dialog returned inexistent or unusable unit_type id '" << type_id << "'" << std::endl;
120  return nullptr;
121  }
122 
123  const unit_type &ut = *new_unit_type;
124  unit_race::GENDER gender = ut.genders().front();
125 
126  unit_ptr new_unit = unit::create(ut, disp.viewing_side(), true, gender);
127  auto action = std::make_unique<editor_action_unit>(hex, *new_unit);
128  return action;
129 }
130 
131 std::unique_ptr<editor_action> mouse_action_unit::drag_end_left(editor_display& disp, int x, int y)
132 {
133  if (click_) return nullptr;
134 
135  map_location hex = disp.hex_clicked_on(x, y);
136  if (!disp.get_map().on_board(hex))
137  return nullptr;
138 
139  const unit_map& units = disp.get_units();
140  const unit_map::const_unit_iterator unit_it = units.find(start_hex_);
141  if (unit_it == units.end())
142  return nullptr;
143 
144  return std::make_unique<editor_action_unit_replace>(start_hex_, hex);
145 }
146 
148 {
150  set_unit_mouse_overlay(disp, u);
151 }
152 
154 {
155 
156  std::stringstream filename;
157  filename << u.image() << "~RC(" << u.flag_rgb() << '>'
158  << team::get_side_color_id(disp.viewing_side()) << ')';
159 
160  surface image(image::get_image(filename.str()));
161  uint8_t alpha = 196;
162  //TODO don't hardcode
163  int size = 72;
164  //int size = image->w;
165  int zoom = static_cast<int>(size * disp.get_zoom_factor());
166 
167  // Add the alpha factor and scale the image
168  adjust_surface_alpha(image, alpha);
169  image = scale_surface(image, zoom, zoom);
170  disp.set_mouseover_hex_overlay(image);
171 }
172 
173 
174 } //end namespace editor
surface get_image(const image::locator &i_locator, TYPE type)
Caches and returns an image.
Definition: picture.cpp:816
std::unique_ptr< editor_action > drag_left(editor_display &disp, int x, int y, bool &partial, editor_action *last_undo) override
Drag operation.
unit_iterator end()
Definition: map.hpp:429
const unit_type * find(const std::string &key, unit_type::BUILD_STATUS status=unit_type::FULL) const
Finds a unit_type by its id() and makes sure it is built to the specified level.
Definition: types.cpp:1262
map_location previous_move_hex_
The hex previously used in move operations.
void get_adjacent_tiles(const map_location &a, map_location *res)
Function which, given a location, will place all adjacent locations in res.
Definition: location.cpp:475
bool invalidate(const map_location &loc)
Function to invalidate a specific tile for redrawing.
Definition: display.cpp:3026
static int hex_size()
Function which returns the size of a hex in pixels (from top tip to bottom tip or left edge to right ...
Definition: display.hpp:260
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...
Definition: display.cpp:599
void set_unit_mouse_overlay(editor_display &disp, const unit_type &u)
Editor action classes.
static double get_zoom_factor()
Returns the current zoom factor.
Definition: display.hpp:263
const std::string & flag_rgb() const
Definition: types.cpp:723
virtual void set_mouse_overlay(editor_display &disp) override
Set the mouse overlay for this action.
const unit_map & get_units() const
Definition: display.hpp:125
int viewing_side() const
Definition: display.hpp:107
unit_type_data unit_types
Definition: types.cpp:1481
surface scale_surface(const surface &surf, int w, int h)
Scale a surface using alpha-weighted modified bilinear filtering Note: causes artifacts with alpha gr...
Definition: utils.cpp:197
static std::string _(const char *str)
Definition: gettext.hpp:93
std::unique_ptr< editor_action > up_left(editor_display &disp, int x, int y) override
TODO.
std::shared_ptr< unit > unit_ptr
Definition: ptr.hpp:26
static unit_ptr create(const config &cfg, bool use_traits=false, const vconfig *vcfg=nullptr)
Initializes a unit from a config.
Definition: unit.hpp:190
A single unit type that the player may recruit.
Definition: types.hpp:45
void clear_tooltips()
Definition: tooltips.cpp:121
std::size_t size(const std::string &str)
Length in characters of a UTF-8 string.
Definition: unicode.cpp:87
const std::vector< unit_race::GENDER > & genders() const
The returned vector will not be empty, provided this has been built to the HELP_INDEXED status...
Definition: types.hpp:253
void adjust_surface_alpha(surface &surf, fixed_t amount)
Definition: utils.cpp:1087
std::unique_ptr< editor_action > click_left(editor_display &disp, int x, int y) override
TODO.
void update_brush_highlights(editor_display &disp, const map_location &hex)
Unconditionally update the brush highlights for the current tool when hex is the center location...
const std::string & id() const
The id for this unit_type.
Definition: types.hpp:144
void set_mouseover_hex_overlay(const surface &image)
mouseover_hex_overlay_ require a prerendered surface and is drawn underneath the mouse&#39;s location ...
Definition: display.hpp:448
Manage the empty-palette in the editor.
Definition: action.cpp:30
static std::string get_side_color_id(unsigned side)
Definition: team.cpp:973
Encapsulates the map of the game.
Definition: location.hpp:38
unit_iterator find(std::size_t id)
Definition: map.cpp:310
Base class for all editor actions.
Definition: action_base.hpp:41
int get_location_y(const map_location &loc) const
Definition: display.cpp:755
std::unique_ptr< editor_action > drag_end_left(editor_display &disp, int x, int y) override
Drag end replaces the unit when clicked left, or adjusts the facing when clicked right.
bool on_board(const map_location &loc) const
Tell if a location is on the map.
Definition: map.cpp:385
const std::string & image() const
Definition: types.hpp:179
int get_location_x(const map_location &loc) const
Functions to get the on-screen positions of hexes.
Definition: display.cpp:750
const gamemap & get_map() const
Definition: display.hpp:96
Contains the SDL_Rect helper code.
const Item & selected_fg_item() const
Return the currently selected foreground/background item.
void move(editor_display &disp, const map_location &hex) override
Mouse move (not a drag).
#define ERR_ED
Functions to load and save images from/to disk.
Container associating units to locations.
Definition: map.hpp:98
int add_tooltip(const SDL_Rect &rect, const std::string &message, const std::string &action, bool use_markup, const surface &foreground)
Definition: tooltips.cpp:176