The Battle for Wesnoth  1.15.2+dev
mouse_action_unit.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2008 - 2018 by Fabian Mueller <fabianmueller5@gmx.de>
3  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 #define GETTEXT_DOMAIN "wesnoth-editor"
16 
19 
21 #include "formula/string_utils.hpp"
23 #include "tooltips.hpp"
24 #include "gettext.hpp"
25 
26 #include "map/location.hpp"
27 #include "sdl/rect.hpp"
28 #include "team.hpp"
29 #include "units/unit.hpp"
30 #include "units/map.hpp"
31 
32 namespace editor {
33 
34 
36 {
37  if (hex != previous_move_hex_) {
38 
39  update_brush_highlights(disp, hex);
40 
41  std::set<map_location> adjacent_set;
42  adjacent_loc_array_t adjacent;
43  get_adjacent_tiles(previous_move_hex_, adjacent.data());
44 
45  for (unsigned i = 0; i < adjacent.size(); i++)
46  adjacent_set.insert(adjacent[i]);
47 
48  disp.invalidate(adjacent_set);
49  previous_move_hex_ = hex;
50 
51  const unit_map& units = disp.get_units();
52  const unit_map::const_unit_iterator unit_it = units.find(hex);
53  if (unit_it != units.end()) {
54 
55  disp.set_mouseover_hex_overlay(nullptr);
56 
57  SDL_Rect rect;
58  rect.x = disp.get_location_x(hex);
59  rect.y = disp.get_location_y(hex);
60  rect.h = disp.hex_size();
61  rect.w = disp.hex_size();
62  std::stringstream str;
63  const auto& recruits = unit_it->recruits();
64  std::vector<t_string> recruit_type_names;
65  std::transform(recruits.begin(), recruits.end(), std::back_inserter(recruit_type_names),
66  [](const std::string& type_id) -> t_string {
67  const unit_type *new_unit_type = unit_types.find(type_id);
68  if(!new_unit_type) return VGETTEXT("(Unknown unit type: $type)", { { "type", type_id } });
69  return new_unit_type->type_name();
70  }
71  );
72  str << _("Identifier: ") << unit_it->id() << "\n"
73  << _("Name: ") << unit_it->name() << "\n"
74  << _("Type: ") << unit_it->type_name() << "\n"
75  << _("Level: ") << unit_it->level() << "\n"
76  << _("Cost: ") << unit_it->cost() << "\n"
77  << _("Recruit: ") << utils::join(recruit_type_names) << "\n";
79  tooltips::add_tooltip(rect, str.str());
80  }
81  else {
82  set_mouse_overlay(disp);
83  }
84  }
85 }
86 
88 {
89  start_hex_ = disp.hex_clicked_on(x, y);
90  if (!disp.get_map().on_board(start_hex_)) {
91  return nullptr;
92  }
93 
94  const unit_map& units = disp.get_units();
95  const unit_map::const_unit_iterator unit_it = units.find(start_hex_);
96  if (unit_it != units.end())
97  set_unit_mouse_overlay(disp, unit_it->type());
98 
99  click_ = true;
100  return nullptr;
101 }
102 
103 editor_action* mouse_action_unit::drag_left(editor_display& disp, int x, int y, bool& /*partial*/, editor_action* /*last_undo*/)
104 {
105  map_location hex = disp.hex_clicked_on(x, y);
106  click_ = (hex == start_hex_);
107  return nullptr;
108 }
109 
111 {
112  if (!click_) return nullptr;
113  click_ = false;
114  map_location hex = disp.hex_clicked_on(x, y);
115  if (!disp.get_map().on_board(hex)) {
116  return nullptr;
117  }
118 
120 
121  // Does this serve a purpose other than making sure the type is built?
122  // (Calling unit_types.build_unit_type(type) would now accomplish that
123  // with less overhead.)
124  const std::string& type_id = type.id();
125  const unit_type *new_unit_type = unit_types.find(type_id);
126  if (!new_unit_type) {
127  //TODO rewrite the error message.
128  ERR_ED << "create unit dialog returned inexistent or unusable unit_type id '" << type_id << "'" << std::endl;
129  return nullptr;
130  }
131 
132  const unit_type &ut = *new_unit_type;
133  unit_race::GENDER gender = ut.genders().front();
134 
135  unit_ptr new_unit = unit::create(ut, disp.viewing_side(), true, gender);
136  editor_action* action = new editor_action_unit(hex, *new_unit);
137  return action;
138 }
139 
141 {
142  if (click_) return nullptr;
143  editor_action* action = nullptr;
144 
145  map_location hex = disp.hex_clicked_on(x, y);
146  if (!disp.get_map().on_board(hex))
147  return nullptr;
148 
149  const unit_map& units = disp.get_units();
150  const unit_map::const_unit_iterator unit_it = units.find(start_hex_);
151  if (unit_it == units.end())
152  return nullptr;
153 
154  action = new editor_action_unit_replace(start_hex_, hex);
155  return action;
156 }
157 
158 /*
159 editor_action* mouse_action_unit::click_right(editor_display& disp, int x, int y)
160 {
161  map_location hex = disp.hex_clicked_on(x, y);
162  start_hex_ = hex;
163  previous_move_hex_ = hex;
164 
165  const unit_map& units = disp.units();
166  const unit_map::const_unit_iterator unit_it = units.find(start_hex_);
167 
168  if (unit_it != units.end()) {
169  old_direction_ = unit_it->facing();
170  }
171 
172  click_ = true;
173  return nullptr;
174 }
175 */
176 
177 //editor_action* mouse_action_unit::drag_right(editor_display& disp, int x, int y, bool& /*partial*/, editor_action* /*last_undo*/)
178 //{
179 // map_location hex = disp.hex_clicked_on(x, y);
180 // if (previous_move_hex_ == hex)
181 // return nullptr;
182 //
183 // click_ = (start_hex_ == hex);
184 // previous_move_hex_ = hex;
185 //
186 // const unit_map& units = disp.units();
187 //
188 // const unit_map::const_unit_iterator unit_it = units.find(start_hex_);
189 // if (unit_it != units.end()) {
190 // for (map_location::DIRECTION new_direction = map_location::NORTH;
191 // new_direction <= map_location::NORTH_WEST;
192 // new_direction = map_location::DIRECTION(new_direction +1)){
193 // if (unit_it->get_location().get_direction(new_direction, 1) == hex) {
194 // return new editor_action_unit_facing(start_hex_, new_direction, old_direction_);
195 // }
196 // }
197 // }
198 //
199 // return nullptr;
200 //}
201 
202 //editor_action* mouse_action_unit::up_right(editor_display& disp, int /*x*/, int /*y*/)
203 //{
204 // if (!click_) return nullptr;
205 // click_ = false;
206 //
207 // const unit_map& units = disp.units();
208 // const unit_map::const_unit_iterator unit_it = units.find(start_hex_);
209 // if (unit_it != units.end()) {
210 // return new editor_action_unit_delete(start_hex_);
211 // }
212 //
213 // return nullptr;
214 //}
215 
216 //editor_action* mouse_action_unit::drag_end_right(editor_display& disp, int x, int y)
217 //{
218 // if (click_) return nullptr;
219 //
220 // map_location hex = disp.hex_clicked_on(x, y);
221 // if (!disp.get_map().on_board(hex))
222 // return nullptr;
223 //
224 // if(new_direction_ != old_direction_) {
225 //
226 // const unit_map& units = disp.units();
227 // const unit_map::const_unit_iterator unit_it = units.find(start_hex_);
228 // if (unit_it != units.end()) {
229 // return new editor_action_unit_facing(start_hex_, new_direction_, old_direction_);
230 // }
231 // }
232 //
233 // return nullptr;
234 //}
235 
236 
238 {
240  set_unit_mouse_overlay(disp, u);
241 }
242 
244 {
245 
246  std::stringstream filename;
247  filename << u.image() << "~RC(" << u.flag_rgb() << '>'
248  << team::get_side_color_id(disp.viewing_side()) << ')';
249 
250  surface image(image::get_image(filename.str()));
251  uint8_t alpha = 196;
252  //TODO don't hardcode
253  int size = 72;
254  //int size = image->w;
255  int zoom = static_cast<int>(size * disp.get_zoom_factor());
256 
257  // Add the alpha factor and scale the image
258  adjust_surface_alpha(image, alpha);
259  image = scale_surface(image, zoom, zoom);
260  disp.set_mouseover_hex_overlay(image);
261 }
262 
263 
264 } //end namespace editor
virtual void set_mouse_overlay(editor_display &disp)
Set the mouse overlay for this action.
surface get_image(const image::locator &i_locator, TYPE type)
function to get the surface corresponding to an image.
Definition: picture.cpp:875
editor_action * drag_left(editor_display &disp, int x, int y, bool &partial, editor_action *last_undo)
Drag operation.
unit_iterator end()
Definition: map.hpp:415
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:1270
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:474
bool invalidate(const map_location &loc)
Function to invalidate a specific tile for redrawing.
Definition: display.cpp:2998
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:255
std::string join(const T &v, const std::string &s=",")
Generates a new string joining container items in a list.
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:593
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:258
const std::string & flag_rgb() const
Definition: types.cpp:746
const unit_map & get_units() const
Definition: display.hpp:121
int viewing_side() const
Definition: display.hpp:103
unit_type_data unit_types
Definition: types.cpp:1528
bool on_board(const map_location &loc) const
Tell if a location is on the map.
Definition: map.cpp:377
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:196
-file sdl_utils.hpp
static unit_ptr create(const config &cfg, bool use_traits=false, const vconfig *vcfg=nullptr)
Initializes a unit from a config.
Definition: unit.hpp:155
A single unit type that the player may recruit.
Definition: types.hpp:42
void clear_tooltips()
Definition: tooltips.cpp:120
void move(editor_display &disp, const map_location &hex)
Mouse move (not a drag).
static UNUSEDNOWARN std::string _(const char *str)
Definition: gettext.hpp:91
std::size_t size(const std::string &str)
Length in characters of a UTF-8 string.
Definition: unicode.cpp:86
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:240
void adjust_surface_alpha(surface &surf, fixed_t amount)
Definition: utils.cpp:1086
const t_string & type_name() const
The name of the unit in the current language setting.
Definition: types.hpp:135
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:138
editor_action * click_left(editor_display &disp, int x, int y)
TODO.
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:443
Manage the empty-palette in the editor.
Definition: action.cpp:29
std::array< map_location, 6 > adjacent_loc_array_t
Definition: location.hpp:170
editor_action * up_left(editor_display &disp, int x, int y)
TODO.
static std::string get_side_color_id(unsigned side)
Definition: team.cpp:960
Encapsulates the map of the game.
Definition: location.hpp:42
unit_iterator find(std::size_t id)
Definition: map.cpp:311
editor_action * drag_end_left(editor_display &disp, int x, int y)
Drag end replaces the unit when clicked left, or adjusts the facing when clicked right.
std::size_t i
Definition: function.cpp:933
place a new unit on the map
Definition: action_unit.hpp:37
Base class for all editor actions.
Definition: action_base.hpp:40
int get_location_y(const map_location &loc) const
Definition: display.cpp:749
#define VGETTEXT(msgid,...)
Handy wrappers around interpolate_variables_into_string and gettext.
const std::string & image() const
Definition: types.hpp:163
int get_location_x(const map_location &loc) const
Functions to get the on-screen positions of hexes.
Definition: display.cpp:744
const gamemap & get_map() const
Definition: display.hpp:92
boost::intrusive_ptr< unit > unit_ptr
Definition: ptr.hpp:29
Contains the SDL_Rect helper code.
const Item & selected_fg_item() const
Return the currently selected foreground/background item.
#define ERR_ED
this module manages the cache of images.
Container associating units to locations.
Definition: map.hpp:99
int add_tooltip(const SDL_Rect &rect, const std::string &message, const std::string &action, bool use_markup, const surface &foreground)
Definition: tooltips.cpp:175