Horizon Official Technical Documentation
Horizon::Zone::Map Class Reference

The class Map is the representation of a map in the game. It contains all the cells and the grid holder. It also contains the A* pathfinder. It is the main class for the map. It is used to get the cells, the grid holder and the pathfinder, and perform a variety of operations on them. More...

#include <Map.hpp>

+ Inheritance diagram for Horizon::Zone::Map:
+ Collaboration diagram for Horizon::Zone::Map:

Public Member Functions

 Map (std::weak_ptr< GameLogicProcess >, std::string const &, uint16_t, uint16_t, std::vector< uint8_t > const &)
 
 ~Map ()
 
std::shared_ptr< GameLogicProcesscontainer ()
 
std::string const & get_name ()
 
int get_area ()
 
uint16_t get_width ()
 
uint16_t get_height ()
 
map_cell_types get_cell_type (MapCoords coords)
 
GridHolderTypegetGridHolder ()
 
template<class T >
bool ensure_grid_for_unit (T *unit, MapCoords coords)
 
template<class T , class CONTAINER >
void visit (int grid_x, int grid_y, GridReferenceContainerVisitor< T, CONTAINER > &visitor)
 
template<class T , class CONTAINER >
void visit (GridCoords const &lower_bound, GridCoords const &upper_bound, GridReferenceContainerVisitor< T, CONTAINER > &visitor)
 
template<class T , class CONTAINER >
void visit_in_range (MapCoords const &map_coords, GridReferenceContainerVisitor< T, CONTAINER > &visitor, uint16_t range=MAX_VIEW_RANGE)
 
AStar::Generatorget_pathfinder ()
 
bool has_obstruction_at (int16_t x, int16_t y)
 
MapCoords get_random_accessible_coordinates ()
 
MapCoords get_random_coordinates_in_walkable_range (uint16_t x, uint16_t y, int16_t min, int16_t max)
 
MapCoords get_random_coordinates_in_walkable_area (uint16_t x, uint16_t y, int16_t xs, int16_t ys)
 
void set_user_count (int32_t count)
 
int32_t get_user_count ()
 
void add_user_count ()
 
void sub_user_count ()
 
void add_item_drop (int item_id, MapCoords map_coords, int amount, int identified)
 
void add_item_drop (std::shared_ptr< item_entry_data > entry, int32_t amount, MapCoords map_coords)
 

Private Attributes

std::weak_ptr< GameLogicProcess_container
 
std::string _name {""}
 
uint16_t _width {0}
 
uint16_t _height {0}
 
GridCoords _max_grids
 
Cell _cells [MAX_CELLS_PER_MAP][MAX_CELLS_PER_MAP] {{0}}
 
GridHolderType _gridholder
 
AStar::Generator _pathfinder
 
int32_t _user_count { 0 }
 

Detailed Description

The class Map is the representation of a map in the game. It contains all the cells and the grid holder. It also contains the A* pathfinder. It is the main class for the map. It is used to get the cells, the grid holder and the pathfinder, and perform a variety of operations on them.

Parameters
_containerThe container that contains this map.
_nameThe name of the map.
_widthThe width of the map.
_heightThe height of the map.
_cellsThe cells of the map.
_gridholderThe grid holder of the map.
_pathfinderThe A* pathfinder of the map.
_obstructionsThe obstructions of the map.

Constructor & Destructor Documentation

◆ Map()

Map::Map ( std::weak_ptr< GameLogicProcess container,
std::string const &  name,
uint16_t  width,
uint16_t  height,
std::vector< uint8_t > const &  cells 
)
46: _container(container), _name(name), _width(width), _height(height),
48 _gridholder((width / MAX_CELLS_PER_GRID) + 1, (height / MAX_CELLS_PER_GRID) + 1), // add 1 because 0,0 is included.
49 _pathfinder(AStar::Generator(MapCoords(width, height), std::bind(&Map::has_obstruction_at, this, std::placeholders::_1, std::placeholders::_2), true, &AStar::Heuristic::manhattan))
50{
51 for (int y = height - 1; y >= 0; --y) {
52 for (int x = 0; x < width; ++x) {
53 _cells[x][y] = Cell(cells.at(y * width + x));
54 }
55 }
56}
Coordinates< MAX_CELLS_PER_MAP > MapCoords
Definition: GridDefinitions.hpp:83
#define MAX_CELLS_PER_GRID
Definition: GridDefinitions.hpp:65
Definition: AStar.hpp:99
static uint32_t manhattan(MapCoords source_, MapCoords target_)
Definition: AStar.hpp:55
uint16_t _height
Definition: Map.hpp:165
GridHolderType _gridholder
Definition: Map.hpp:168
std::string _name
Definition: Map.hpp:164
AStar::Generator _pathfinder
Definition: Map.hpp:169
bool has_obstruction_at(int16_t x, int16_t y)
Definition: Map.cpp:67
GridCoords _max_grids
Definition: Map.hpp:166
std::shared_ptr< GameLogicProcess > container()
Definition: Map.hpp:67
Cell _cells[MAX_CELLS_PER_MAP][MAX_CELLS_PER_MAP]
Definition: Map.hpp:167
std::weak_ptr< GameLogicProcess > _container
Definition: Map.hpp:163
uint16_t _width
Definition: Map.hpp:165
Definition: Cell.hpp:42

References _cells.

◆ ~Map()

Map::~Map ( )
59{
60 for (int y = _height - 1; y >= 0; --y) {
61 for (int x = 0; x < _width; ++x) {
62 _cells[x][y].~Cell();
63 }
64 }
65}
~Cell()
Definition: Cell.hpp:55

References _cells, _height, _width, and Horizon::Zone::Cell::~Cell().

+ Here is the call graph for this function:

Member Function Documentation

◆ add_item_drop() [1/2]

void Map::add_item_drop ( int  item_id,
MapCoords  map_coords,
int  amount,
int  identified 
)
96{
97 std::shared_ptr<const item_config_data> item_d = ItemDB->get_item_by_id(item_id);
98
99 if (item_d == nullptr) {
100 HLog(warning) << "Map::add_item_drop: Tried to drop non-existent item with ID: " << item_id << ".";
101 return;
102 }
103
104 int r = std::rand();
105
106 int64_t uuid = sZone->to_uuid(UNIT_ITEM, ++_last_np_unit_guid, 0, 0);
107 std::shared_ptr<Horizon::Zone::Units::Item> item = std::make_shared<Horizon::Zone::Units::Item>(uuid, shared_from_this(), map_coords, identified, amount, item_d);
108 item->initialize();
109
111 entry.guid = item->guid();
112 entry.item_id = item->config()->item_id;
113 entry.type = item->config()->type;
114 entry.is_identified = identified;
115 entry.x = item->map_coords().x();
116 entry.y = item->map_coords().y();
117 entry.amount = amount;
118 item->set_x_area((r & 3) * 3 + 3);
119 item->set_y_area(((r >> 2) & 3) * 3 + 3);
120 entry.x_area = item->x_area();
121 entry.y_area = item->y_area();
122 entry.show_drop_effect = item->config()->config.show_drop_effect;
123 entry.drop_effect_mode = item->config()->drop_effect_mode;
124 item->notify_nearby_players_of_item_drop(entry);
125
126 this->container()->get_resource_manager().add<RESOURCE_PRIORITY_TERTIARY>(item->uuid(), item);
127}
#define ItemDB
Definition: ItemDB.hpp:119
#define HLog(type)
Definition: Logger.hpp:122
@ RESOURCE_PRIORITY_TERTIARY
Definition: Server.hpp:81
@ UNIT_ITEM
Definition: UnitDefinitions.hpp:47
static std::atomic< int32_t > _last_np_unit_guid(NPC_START_GUID)
#define sZone
Definition: Zone.hpp:247
Definition: GridNotifiers.hpp:434
int guid
Definition: GridNotifiers.hpp:435
int show_drop_effect
Definition: GridNotifiers.hpp:436
int item_id
Definition: GridNotifiers.hpp:435
int y
Definition: GridNotifiers.hpp:435
int type
Definition: GridNotifiers.hpp:435
int drop_effect_mode
Definition: GridNotifiers.hpp:436
int x
Definition: GridNotifiers.hpp:435
int amount
Definition: GridNotifiers.hpp:435
int x_area
Definition: GridNotifiers.hpp:435
int is_identified
Definition: GridNotifiers.hpp:435
int y_area
Definition: GridNotifiers.hpp:435

References _last_np_unit_guid(), s_grid_notify_item_drop_entry::amount, container(), s_grid_notify_item_drop_entry::drop_effect_mode, s_grid_notify_item_drop_entry::guid, HLog, s_grid_notify_item_drop_entry::is_identified, s_grid_notify_item_drop_entry::item_id, ItemDB, RESOURCE_PRIORITY_TERTIARY, s_grid_notify_item_drop_entry::show_drop_effect, sZone, s_grid_notify_item_drop_entry::type, UNIT_ITEM, s_grid_notify_item_drop_entry::x, s_grid_notify_item_drop_entry::x_area, s_grid_notify_item_drop_entry::y, and s_grid_notify_item_drop_entry::y_area.

Referenced by Horizon::Zone::MapComponent::sync_data_types().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ add_item_drop() [2/2]

void Map::add_item_drop ( std::shared_ptr< item_entry_data entry,
int32_t  amount,
MapCoords  map_coords 
)
130{
131 int64_t uuid = sZone->to_uuid(UNIT_ITEM, ++_last_np_unit_guid, 0, 0);
132 std::shared_ptr<Horizon::Zone::Units::Item> floor_item = std::make_shared<Horizon::Zone::Units::Item>(uuid, entry, amount, shared_from_this(), map_coords);
133 floor_item->initialize();
134
136
137 int r = std::rand();
138
139 notif_config.guid = floor_item->guid();
140 notif_config.item_id = floor_item->config()->item_id;
141 notif_config.type = floor_item->config()->type;
142 notif_config.is_identified = floor_item->is_identified();
143 notif_config.x = floor_item->map_coords().x();
144 notif_config.y = floor_item->map_coords().y();
145 notif_config.amount = amount;
146 floor_item->set_x_area((r & 3) * 3 + 3);
147 floor_item->set_y_area(((r >> 2) & 3) * 3 + 3);
148 notif_config.x_area = floor_item->x_area();
149 notif_config.y_area = floor_item->y_area();
150 notif_config.show_drop_effect = floor_item->config()->config.show_drop_effect;
151 notif_config.drop_effect_mode = floor_item->config()->drop_effect_mode;
152
153 floor_item->notify_nearby_players_of_item_drop(notif_config);
154
155 this->container()->get_resource_manager().add<RESOURCE_PRIORITY_TERTIARY>(floor_item->uuid(), floor_item);
156}

References _last_np_unit_guid(), s_grid_notify_item_drop_entry::amount, container(), s_grid_notify_item_drop_entry::drop_effect_mode, s_grid_notify_item_drop_entry::guid, s_grid_notify_item_drop_entry::is_identified, s_grid_notify_item_drop_entry::item_id, RESOURCE_PRIORITY_TERTIARY, s_grid_notify_item_drop_entry::show_drop_effect, sZone, s_grid_notify_item_drop_entry::type, UNIT_ITEM, s_grid_notify_item_drop_entry::x, s_grid_notify_item_drop_entry::x_area, s_grid_notify_item_drop_entry::y, and s_grid_notify_item_drop_entry::y_area.

+ Here is the call graph for this function:

◆ add_user_count()

void Map::add_user_count ( )
80 {
81 _user_count++;
82 if (get_user_count() == 1)
83 container()->get_monster_spawn_agent().spawn_monsters(get_name());
84 HLog(debug) << "Map::add_user_count: " << get_user_count();
85}
std::string const & get_name()
Definition: Map.hpp:69
int32_t _user_count
Definition: Map.hpp:170
int32_t get_user_count()
Definition: Map.hpp:155

References _user_count, container(), get_name(), get_user_count(), and HLog.

+ Here is the call graph for this function:

◆ container()

std::shared_ptr< GameLogicProcess > Horizon::Zone::Map::container ( )
inline
67{ return _container.expired() == false ? _container.lock() : nullptr; }

References _container.

Referenced by add_item_drop(), add_user_count(), and sub_user_count().

+ Here is the caller graph for this function:

◆ ensure_grid_for_unit()

template<class T >
bool Horizon::Zone::Map::ensure_grid_for_unit ( T *  unit,
MapCoords  coords 
)
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}
#define MAX_GRIDS_PER_MAP
Definition: GridDefinitions.hpp:66
int16_t y() const
Definition: Coordinates.hpp:120
Coordinates< BLOCK_COUNT > scale() const
Definition: Coordinates.hpp:108
int16_t x() const
Definition: Coordinates.hpp:119
GridType & get_grid(int x, int y)
Definition: GridHolder.hpp:57

References _gridholder, GridHolder< ZONE_OBJECT_TYPES >::get_grid(), get_name(), MAX_CELLS_PER_GRID, MAX_GRIDS_PER_MAP, Coordinates< MAX_COORDINATES >::scale(), Coordinates< MAX_COORDINATES >::x(), and Coordinates< MAX_COORDINATES >::y().

+ Here is the call graph for this function:

◆ get_area()

int Horizon::Zone::Map::get_area ( )
inline
71{ return _width * _height; }

References _height, and _width.

◆ get_cell_type()

map_cell_types Horizon::Zone::Map::get_cell_type ( MapCoords  coords)
inline
76{ return _cells[coords.x()][coords.y()].get_type(); }
map_cell_types get_type()
Definition: Cell.hpp:61

References _cells, Horizon::Zone::Cell::get_type(), Coordinates< MAX_COORDINATES >::x(), and Coordinates< MAX_COORDINATES >::y().

+ Here is the call graph for this function:

◆ get_height()

uint16_t Horizon::Zone::Map::get_height ( )
inline
74{ return _height; }

References _height.

Referenced by Horizon::Zone::MapComponent::sync_data_types().

+ Here is the caller graph for this function:

◆ get_name()

std::string const & Horizon::Zone::Map::get_name ( )
inline
69{ return _name; }

References _name.

Referenced by add_user_count(), ensure_grid_for_unit(), sub_user_count(), and Horizon::Zone::MapComponent::sync_data_types().

+ Here is the caller graph for this function:

◆ get_pathfinder()

AStar::Generator & Horizon::Zone::Map::get_pathfinder ( )
inline
92{ return _pathfinder; }

References _pathfinder.

◆ get_random_accessible_coordinates()

MapCoords Horizon::Zone::Map::get_random_accessible_coordinates ( )
inline
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 }

References _height, _width, and has_obstruction_at().

+ Here is the call graph for this function:

◆ get_random_coordinates_in_walkable_area()

MapCoords Horizon::Zone::Map::get_random_coordinates_in_walkable_area ( uint16_t  x,
uint16_t  y,
int16_t  xs,
int16_t  ys 
)
inline
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 }

References _height, _width, and has_obstruction_at().

Referenced by Horizon::Zone::MapComponent::sync_data_types().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_random_coordinates_in_walkable_range()

MapCoords Horizon::Zone::Map::get_random_coordinates_in_walkable_range ( uint16_t  x,
uint16_t  y,
int16_t  min,
int16_t  max 
)
inline
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 }

References has_obstruction_at().

Referenced by Horizon::Zone::MapComponent::sync_data_types().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_user_count()

int32_t Horizon::Zone::Map::get_user_count ( )
inline
155{ return _user_count; }

References _user_count.

Referenced by add_user_count(), and sub_user_count().

+ Here is the caller graph for this function:

◆ get_width()

uint16_t Horizon::Zone::Map::get_width ( )
inline
73{ return _width; }

References _width.

Referenced by Horizon::Zone::MapComponent::sync_data_types().

+ Here is the caller graph for this function:

◆ getGridHolder()

GridHolderType & Horizon::Zone::Map::getGridHolder ( )
inline
78{ return _gridholder; }

References _gridholder.

◆ has_obstruction_at()

bool Map::has_obstruction_at ( int16_t  x,
int16_t  y 
)
68{
69 if (x < 0 || y < 0 || x > _width || y > _height)
70 return true;
71
72 Cell c = _cells[x][y];
73
74 if (!c.isWalkable())
75 return true;
76
77 return false;
78}
bool isWalkable()
Definition: Cell.hpp:87

References _cells, _height, _width, and Horizon::Zone::Cell::isWalkable().

Referenced by get_random_accessible_coordinates(), get_random_coordinates_in_walkable_area(), get_random_coordinates_in_walkable_range(), and Horizon::Zone::MapComponent::sync_data_types().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ set_user_count()

void Horizon::Zone::Map::set_user_count ( int32_t  count)
inline
154{ _user_count = count; }
size_t count(GridTypeListContainer< SPECIFIC_TYPE > const &elements, SPECIFIC_TYPE *)
Definition: GridReferenceContainer.hpp:100

References _user_count, and GridTypeListIterator::count().

+ Here is the call graph for this function:

◆ sub_user_count()

void Map::sub_user_count ( )
87 {
88 _user_count--;
89 if (get_user_count() == 0)
90 container()->get_monster_spawn_agent().despawn_monsters(get_name());
91 HLog(debug) << "Map::sub_user_count: " << get_user_count();
92}

References _user_count, container(), get_name(), get_user_count(), and HLog.

+ Here is the call graph for this function:

◆ visit() [1/2]

template<class T , class CONTAINER >
void Horizon::Zone::Map::visit ( GridCoords const &  lower_bound,
GridCoords const &  upper_bound,
GridReferenceContainerVisitor< T, CONTAINER > &  visitor 
)
inline
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}
void visit(int grid_x, int grid_y, GridReferenceContainerVisitor< T, CONTAINER > &visitor)
Definition: Map.hpp:195

References Coordinates< MAX_COORDINATES >::x(), and Coordinates< MAX_COORDINATES >::y().

+ Here is the call graph for this function:

◆ visit() [2/2]

template<class T , class CONTAINER >
void Horizon::Zone::Map::visit ( int  grid_x,
int  grid_y,
GridReferenceContainerVisitor< T, CONTAINER > &  visitor 
)
inline
196{
197 Grid<AllUnitTypes> &g = _gridholder.get_grid(grid_x, grid_y);
198 g.visit(visitor);
199}
void visit(GridReferenceContainerVisitor< VISITOR, GridReferenceContainer< GRID_OBJECT_TYPES > > &visitor)
Definition: Grid.hpp:61

References Grid< GRID_OBJECT_TYPES >::visit().

+ Here is the call graph for this function:

◆ visit_in_range()

template<class T , class CONTAINER >
void Horizon::Zone::Map::visit_in_range ( MapCoords const &  map_coords,
GridReferenceContainerVisitor< T, CONTAINER > &  visitor,
uint16_t  range = MAX_VIEW_RANGE 
)
inline
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}
#define MAX_CELLS_PER_MAP
Definition: GridDefinitions.hpp:67
Coordinates< BOUNDS > at_range(int range) const
Definition: Coordinates.hpp:91

References Coordinates< MAX_COORDINATES >::at_range(), MAX_CELLS_PER_GRID, MAX_CELLS_PER_MAP, MAX_GRIDS_PER_MAP, and Coordinates< MAX_COORDINATES >::scale().

+ Here is the call graph for this function:

Member Data Documentation

◆ _cells

Cell Horizon::Zone::Map::_cells[MAX_CELLS_PER_MAP][MAX_CELLS_PER_MAP] {{0}}
private

◆ _container

std::weak_ptr<GameLogicProcess> Horizon::Zone::Map::_container
private

Referenced by container().

◆ _gridholder

GridHolderType Horizon::Zone::Map::_gridholder
private

◆ _height

◆ _max_grids

GridCoords Horizon::Zone::Map::_max_grids
private

◆ _name

std::string Horizon::Zone::Map::_name {""}
private

Referenced by get_name().

◆ _pathfinder

AStar::Generator Horizon::Zone::Map::_pathfinder
private

Referenced by get_pathfinder().

◆ _user_count

int32_t Horizon::Zone::Map::_user_count { 0 }
private

◆ _width


The documentation for this class was generated from the following files: