Horizon Official Technical Documentation
Map.hpp
Go to the documentation of this file.
1/***************************************************
2 * _ _ _ *
3 * | | | | (_) *
4 * | |_| | ___ _ __ _ _______ _ __ *
5 * | _ |/ _ \| '__| |_ / _ \| '_ \ *
6 * | | | | (_) | | | |/ / (_) | | | | *
7 * \_| |_/\___/|_| |_/___\___/|_| |_| *
8 ***************************************************
9 * This file is part of Horizon (c).
10 *
11 * Copyright (c) 2019 Sagun K. (sagunxp@gmail.com).
12 * Copyright (c) 2019 Horizon Dev Team.
13 *
14 * Base Author - Sagun K. (sagunxp@gmail.com)
15 *
16 * This library is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation, either version 3 of the License, or
19 * (at your option) any later version.
20 *
21 * This library is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this library. If not, see <http://www.gnu.org/licenses/>.
28 **************************************************/
29
30#ifndef HORIZON_ZONE_GAME_MAP_HPP
31#define HORIZON_ZONE_GAME_MAP_HPP
32
33#include "Path/AStar.hpp"
41
42namespace Horizon
43{
44namespace Zone
45{
46 namespace Units
47 {
48 class Item;
49 }
50 class GameLogicProcess;
61class Map : public std::enable_shared_from_this<Map>
62{
63public:
64 Map(std::weak_ptr<GameLogicProcess>, std::string const &, uint16_t, uint16_t, std::vector<uint8_t> const &);
65 ~Map();
66
67 std::shared_ptr<GameLogicProcess> container() { return _container.expired() == false ? _container.lock() : nullptr; }
68
69 std::string const &get_name() { return _name; }
70
71 int get_area() { return _width * _height; }
72
73 uint16_t get_width() { return _width; }
74 uint16_t get_height() { return _height; }
75
76 map_cell_types get_cell_type(MapCoords coords) { return _cells[coords.x()][coords.y()].get_type(); }
77
79
80 template <class T>
81 bool ensure_grid_for_unit(T *unit, MapCoords coords);
82
83 template<class T, class CONTAINER>
84 void visit(int grid_x, int grid_y, GridReferenceContainerVisitor<T, CONTAINER> &visitor);
85
86 template<class T, class CONTAINER>
87 void visit(GridCoords const &lower_bound, GridCoords const &upper_bound, GridReferenceContainerVisitor<T, CONTAINER> &visitor);
88
89 template<class T, class CONTAINER>
90 void visit_in_range(MapCoords const &map_coords, GridReferenceContainerVisitor<T, CONTAINER> &visitor, uint16_t range = MAX_VIEW_RANGE);
91
93
94 bool has_obstruction_at(int16_t x, int16_t y);
95
97 {
98 int16_t x = 0;
99 int16_t y = 0;
100
101 do {
102 x = rand() % _width;
103 y = rand() % _height;
104 } while (has_obstruction_at(x, y));
105
106 return { x, y };
107 }
108
109 MapCoords get_random_coordinates_in_walkable_range(uint16_t x, uint16_t y, int16_t min, int16_t max)
110 {
111 int a = 0, b = 0;
112 int r = std::rand();
113 int d = r % (max - min + 1) + min;
114 int i = 0;
115
116 do {
117 a = r % (d * 2 + 1) - d;
118 b = r / (d * 2 + 1) % (d * 2 + 1) - d;
119
120 a += x;
121 b += y;
122 i++;
123 } while(has_obstruction_at(a, b) && i < 20);
124
125 if (i == 20) return MapCoords(0, 0);
126
127 return MapCoords(a, b);
128 }
129
130 MapCoords get_random_coordinates_in_walkable_area(uint16_t x, uint16_t y, int16_t xs, int16_t ys)
131 {
132 std::vector<MapCoords> available_cells;
133
134 assert(xs >= 0);
135 assert(ys >= 0);
136
137 for (int i = std::max(x - xs, 0); i < std::min(x + xs, (int) _width); i++) {
138 for (int j = std::max(y - ys, 0); j < std::min(y + ys,(int) _height); j++) {
139 if (i == x && j == y)
140 continue;
141 if (!has_obstruction_at(i, j))
142 available_cells.push_back(MapCoords(i, j));
143 }
144 }
145
146 if (available_cells.size() == 0)
147 return MapCoords(0, 0);
148
149 int rnd = rand() % available_cells.size();
150
151 return available_cells.at(rnd);
152 }
153
155 int32_t get_user_count() { return _user_count; }
156
157 void add_user_count();
158 void sub_user_count();
159
160 void add_item_drop(int item_id, MapCoords map_coords, int amount, int identified);
161 void add_item_drop(std::shared_ptr<item_entry_data> entry, int32_t amount, MapCoords map_coords);
162private:
163 std::weak_ptr<GameLogicProcess> _container;
164 std::string _name{""};
165 uint16_t _width{0}, _height{0};
170 int32_t _user_count{ 0 };
171};
172}
173}
174
175template <class T>
177{
178 std::string const &new_map_name = unit->map()->get_name();
179 GridCoords new_gcoords = mcoords.scale<MAX_CELLS_PER_GRID, MAX_GRIDS_PER_MAP>();
180
181 if (new_map_name.compare(get_name()) == 0 && unit->grid_coords() == new_gcoords)
182 return false;
183
184 if (unit->has_valid_grid_reference())
185 unit->remove_grid_reference();
186
187 unit->set_grid_coords(new_gcoords);
188
189 _gridholder.get_grid(new_gcoords.x(), new_gcoords.y()).add_object(unit);
190
191 return true;
192}
193
194template<class T, class CONTAINER>
196{
197 Grid<AllUnitTypes> &g = _gridholder.get_grid(grid_x, grid_y);
198 g.visit(visitor);
199}
200
201template<class T, class CONTAINER>
203{
204 MapCoords lower_bounds = map_coords.at_range<MAX_CELLS_PER_MAP>(-range);
205 MapCoords upper_bounds = map_coords.at_range<MAX_CELLS_PER_MAP>(range);
206
207 visit(lower_bounds.scale<MAX_CELLS_PER_GRID, MAX_GRIDS_PER_MAP>(), upper_bounds.scale<MAX_CELLS_PER_GRID, MAX_GRIDS_PER_MAP>(), visitor);
208}
209
210template<class T, class CONTAINER>
211inline void Horizon::Zone::Map::visit(GridCoords const &lower_bound, GridCoords const &upper_bound, GridReferenceContainerVisitor<T, CONTAINER> &visitor)
212{
213 // Visit all grids in the map, from top to bottom, left to right
214 // This is done to ensure that the visitor is called in the same order as the grids are stored in the map
215 // This is important for the GridReferenceContainerVisitor, which will add the grid references to a container
216 // The container will then be iterated over in the same order as the grids were visited
217 // This ensures that the entities are visited in the container in the same order as they are stored in the map
218 // We visit all ranges - 0,0 to maximum grids in a map
219 // (the upper range as well, i.e. if the map is 10x10 grids, we visit 0,0 to 10,10 and not 9x9)
220 for (int y = lower_bound.y(); y <= upper_bound.y(); y++) {
221 for (int x = lower_bound.x(); x <= upper_bound.x(); x++) {
222 visit(x, y, visitor);
223 }
224 }
225}
226
227#endif /* HORIZON_ZONE_GAME_MAP_HPP */
#define MAX_GRIDS_PER_MAP
Definition: GridDefinitions.hpp:66
Coordinates< MAX_CELLS_PER_MAP > MapCoords
Definition: GridDefinitions.hpp:83
#define MAX_CELLS_PER_GRID
Definition: GridDefinitions.hpp:65
#define MAX_CELLS_PER_MAP
Definition: GridDefinitions.hpp:67
#define MAX_VIEW_RANGE
Definition: Horizon.hpp:59
map_cell_types
Definition: MapDefinitions.hpp:34
int16_t y() const
Definition: Coordinates.hpp:120
Coordinates< BLOCK_COUNT > scale() const
Definition: Coordinates.hpp:108
Coordinates< BOUNDS > at_range(int range) const
Definition: Coordinates.hpp:91
int16_t x() const
Definition: Coordinates.hpp:119
GridType & get_grid(int x, int y)
Definition: GridHolder.hpp:57
Definition: GridReferenceContainerVisitor.hpp:70
void visit(GridReferenceContainerVisitor< VISITOR, GridReferenceContainer< GRID_OBJECT_TYPES > > &visitor)
Definition: Grid.hpp:61
Definition: AStar.hpp:99
The class Map is the representation of a map in the game. It contains all the cells and the grid hold...
Definition: Map.hpp:62
uint16_t _height
Definition: Map.hpp:165
void add_item_drop(int item_id, MapCoords map_coords, int amount, int identified)
Definition: Map.cpp:95
map_cell_types get_cell_type(MapCoords coords)
Definition: Map.hpp:76
GridHolderType _gridholder
Definition: Map.hpp:168
std::string _name
Definition: Map.hpp:164
AStar::Generator _pathfinder
Definition: Map.hpp:169
std::string const & get_name()
Definition: Map.hpp:69
uint16_t get_width()
Definition: Map.hpp:73
bool has_obstruction_at(int16_t x, int16_t y)
Definition: Map.cpp:67
GridCoords _max_grids
Definition: Map.hpp:166
bool ensure_grid_for_unit(T *unit, MapCoords coords)
Definition: Map.hpp:176
void visit(int grid_x, int grid_y, GridReferenceContainerVisitor< T, CONTAINER > &visitor)
Definition: Map.hpp:195
std::shared_ptr< GameLogicProcess > container()
Definition: Map.hpp:67
Cell _cells[MAX_CELLS_PER_MAP][MAX_CELLS_PER_MAP]
Definition: Map.hpp:167
GridHolderType & getGridHolder()
Definition: Map.hpp:78
MapCoords get_random_coordinates_in_walkable_area(uint16_t x, uint16_t y, int16_t xs, int16_t ys)
Definition: Map.hpp:130
uint16_t get_height()
Definition: Map.hpp:74
MapCoords get_random_accessible_coordinates()
Definition: Map.hpp:96
AStar::Generator & get_pathfinder()
Definition: Map.hpp:92
void set_user_count(int32_t count)
Definition: Map.hpp:154
~Map()
Definition: Map.cpp:58
std::weak_ptr< GameLogicProcess > _container
Definition: Map.hpp:163
int get_area()
Definition: Map.hpp:71
void add_user_count()
Definition: Map.cpp:80
int32_t _user_count
Definition: Map.hpp:170
uint16_t _width
Definition: Map.hpp:165
Map(std::weak_ptr< GameLogicProcess >, std::string const &, uint16_t, uint16_t, std::vector< uint8_t > const &)
Definition: Map.cpp:45
MapCoords get_random_coordinates_in_walkable_range(uint16_t x, uint16_t y, int16_t min, int16_t max)
Definition: Map.hpp:109
int32_t get_user_count()
Definition: Map.hpp:155
void sub_user_count()
Definition: Map.cpp:87
void visit_in_range(MapCoords const &map_coords, GridReferenceContainerVisitor< T, CONTAINER > &visitor, uint16_t range=MAX_VIEW_RANGE)
Definition: Map.hpp:202
size_t count(GridTypeListContainer< SPECIFIC_TYPE > const &elements, SPECIFIC_TYPE *)
Definition: GridReferenceContainer.hpp:100
Definition: Element.hpp:7
Definition: Cell.hpp:42
map_cell_types get_type()
Definition: Cell.hpp:61