The Battle for Wesnoth  1.13.10+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
map_fragment.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2008 - 2017 by Tomasz Sniatowski <kailoran@gmail.com>
3  Part of the Battle for Wesnoth Project http://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 #define GETTEXT_DOMAIN "wesnoth-editor"
15 
17 
18 namespace editor {
19 
21  : items_()
22  , area_()
23 {
24 }
25 
26 map_fragment::map_fragment(const gamemap& map, const std::set<map_location>& area)
27  : items_()
28  , area_()
29 {
30  add_tiles(map, area);
31 }
32 
33 void map_fragment::add_tile(const gamemap& map, const map_location& loc)
34 {
35  if (area_.find(loc) == area_.end()) {
36  items_.emplace_back(map, loc);
37  area_.insert(loc);
38  }
39 }
40 
41 void map_fragment::add_tiles(const gamemap& map, const std::set<map_location>& locs)
42 {
43  for (const map_location& loc : locs) {
44  add_tile(map, loc);
45  }
46 }
47 
48 std::set<map_location> map_fragment::get_area() const
49 {
50  return area_;
51 }
52 
53 std::set<map_location> map_fragment::get_offset_area(const map_location& loc) const
54 {
55  std::set<map_location> result;
56  for (const tile_info& i : items_) {
57  result.insert(i.offset.vector_sum(loc));
58  }
59  return result;
60 }
61 
62 void map_fragment::paste_into(gamemap& map, const map_location& loc) const
63 {
64  for (const tile_info& i : items_) {
65  map.set_terrain(i.offset.vector_sum(loc), i.terrain);
66  }
67 }
68 
69 void map_fragment::shift(const map_location& offset)
70 {
71  for (tile_info& ti : items_) {
72  ti.offset.vector_sum_assign(offset);
73  }
74 }
75 
77 {
78  map_location sum(0, 0);
79  for (const tile_info& ti : items_) {
80  sum.vector_sum_assign(ti.offset);
81  }
82  if (items_.size() > 0) {
83  sum.x /= static_cast<int>(items_.size());
84  sum.y /= static_cast<int>(items_.size());
85  }
86  return sum;
87 }
88 
90 {
91  shift(center_of_mass().vector_negation());
92  area_.clear();
93  for (tile_info& ti : items_) {
94  area_.insert(ti.offset);
95  }
96 }
97 
99 {
100  area_.clear();
101  for (tile_info& ti : items_) {
103  int x = ti.offset.x;
104  int y = ti.offset.y;
105  // rotate the X-Y axes to SOUTH/SOUTH_EAST - SOUTH_WEST axes
106  // but if x is odd, simply using x/2 + x/2 will lack a step
107  l = l.get_direction(map_location::SOUTH, (x+is_odd(x))/2);
110  ti.offset = l;
111  area_.insert(l);
112  }
113  if (get_area().size() != items_.size()) {
114  throw editor_exception("Map fragment rotation resulted in duplicate entries");
115  }
116 }
117 
119 {
120  area_.clear();
121  for (tile_info& ti : items_) {
123  int x = ti.offset.x;
124  int y = ti.offset.y;
125  // rotate the X-Y axes to NORTH/NORTH_EAST - SOUTH_EAST axes'
126  // reverse of what the cw rotation does
127  l = l.get_direction(map_location::NORTH, (x-is_odd(x))/2);
130  ti.offset = l;
131  area_.insert(l);
132  }
133  if (get_area().size() != items_.size()) {
134  throw editor_exception("Map fragment rotation resulted in duplicate entries");
135  }
136 }
137 
139 {
140  for (tile_info& ti : items_) {
141  ti.offset.x = -ti.offset.x;
142  }
143  center_by_mass();
144 }
145 
147 {
148  for (tile_info& ti : items_) {
149  ti.offset.y = -ti.offset.y;
150  if (ti.offset.x % 2) {
151  ti.offset.y--;
152  }
153  }
154  center_by_mass();
155 }
156 
157 
159 {
160  return items_.empty();
161 }
162 
164 {
165  std::stringstream ss;
166  ss << "MF: ";
167  for (const tile_info& ti : items_) {
168  ss << "(" << ti.offset << ")";
169  }
170  ss << " -- ";
171  for (const map_location& loc : area_) {
172  ss << "(" << loc << ")";
173  }
174  return ss.str();
175 }
176 
177 } //end namespace editor
bool is_odd(T num)
Definition: math.hpp:34
std::vector< char_t > string
static const map_location & ZERO()
Old implementation:
Definition: location.hpp:215
void flip_horizontal()
Flip the map fragment horizontally.
void paste_into(gamemap &map, const map_location &loc) const
Paste the map fragment into the map, treating loc as the (0,0) point (offset).
std::string dump() const
Debug dump to a string.
void rotate_60_ccw()
Rotate the map fragment 60 degrees counter-clockwise around (0,0)
void set_terrain(const map_location &loc, const t_translation::terrain_code &terrain, const terrain_type_data::merge_mode mode=terrain_type_data::BOTH, bool replace_if_failed=false)
Clobbers over the terrain at location 'loc', with the given terrain.
Definition: map.cpp:381
std::set< map_location > get_offset_area(const map_location &offset) const
Get the area covered by this map fragment, shifted by an offset.
Encapsulates the map of the game.
Definition: map.hpp:34
Manage the empty-palette in the editor.
Definition: action.cpp:29
Encapsulates the map of the game.
Definition: location.hpp:40
size_t size(const utf8::string &str)
Length in characters of a UTF-8 string.
Definition: unicode.cpp:86
void flip_vertical()
Flip the map fragment vertically.
void shift(const map_location &offset)
Shift all tiles in the map fragment by the specified offset.
map_location center_of_mass() const
Get the center of the map fragment, mass-wise.
#define i
This represents a tile along with information about it, namely the terrain, possibly other informatio...
void add_tiles(const gamemap &map, const std::set< map_location > &loc)
Add many locations and pull their info from the map.
map_fragment()
Create an empty map fragment.
map_location & vector_sum_assign(const map_location &a)
Definition: location.hpp:236
map_location get_direction(DIRECTION d, unsigned int n=1u) const
Definition: location.hpp:257
std::set< map_location > area_
std::set< map_location > get_area() const
Get the area covered by this map fragment.
std::vector< tile_info > items_
The data of this map_fragment.
void center_by_mass()
Shift the map fragment so it is roughly centered around the (0,0) point, mass-wise.
void add_tile(const gamemap &map, const map_location &loc)
Add a single location and pull its info from the map.
void rotate_60_cw()
Rotate the map fragment 60 degrees clockwise around (0,0)