Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Toggle main menu visibility
Loading...
Searching...
No Matches
CellImpl.h
Go to the documentation of this file.
1
/*
2
* This file is part of Project SkyFire https://www.projectskyfire.org.
3
* See LICENSE.md file for Copyright information
4
*/
5
6
#ifndef SKYFIRE_CELLIMPL_H
7
#define SKYFIRE_CELLIMPL_H
8
9
#include <cmath>
10
11
#include "
Cell.h
"
12
#include "
Map.h
"
13
#include "
Object.h
"
14
15
inline
Cell::Cell
(
CellCoord
const
& p)
16
{
17
data
.Part.grid_x = p.
x_coord
/
MAX_NUMBER_OF_CELLS
;
18
data
.Part.grid_y = p.
y_coord
/
MAX_NUMBER_OF_CELLS
;
19
data
.Part.cell_x = p.
x_coord
%
MAX_NUMBER_OF_CELLS
;
20
data
.Part.cell_y = p.
y_coord
%
MAX_NUMBER_OF_CELLS
;
21
data
.Part.nocreate = 0;
22
data
.Part.reserved = 0;
23
}
24
25
inline
Cell::Cell
(
float
x,
float
y)
26
{
27
CellCoord
p =
Skyfire::ComputeCellCoord
(x, y);
28
data
.Part.grid_x = p.
x_coord
/
MAX_NUMBER_OF_CELLS
;
29
data
.Part.grid_y = p.
y_coord
/
MAX_NUMBER_OF_CELLS
;
30
data
.Part.cell_x = p.
x_coord
%
MAX_NUMBER_OF_CELLS
;
31
data
.Part.cell_y = p.
y_coord
%
MAX_NUMBER_OF_CELLS
;
32
data
.Part.nocreate = 0;
33
data
.Part.reserved = 0;
34
}
35
36
inline
CellArea
Cell::CalculateCellArea
(
float
x,
float
y,
float
radius)
37
{
38
if
(radius <= 0.0f)
39
{
40
CellCoord
center =
Skyfire::ComputeCellCoord
(x, y).
normalize
();
41
return
CellArea
(center, center);
42
}
43
44
CellCoord
centerX =
Skyfire::ComputeCellCoord
(x - radius, y - radius).
normalize
();
45
CellCoord
centerY =
Skyfire::ComputeCellCoord
(x + radius, y + radius).
normalize
();
46
47
return
CellArea
(centerX, centerY);
48
}
49
50
template
<
class
T,
class
CONTAINER>
51
inline
void
Cell::Visit
(
CellCoord
const
& standing_cell,
TypeContainerVisitor<T, CONTAINER>
& visitor,
Map
& map,
float
radius,
float
x_off,
float
y_off)
const
52
{
53
if
(!standing_cell.
IsCoordValid
())
54
return
;
55
56
//no jokes here... Actually placing ASSERT() here was good idea, but
57
//we had some problems with DynamicObjects, which pass radius = 0.0f (DB issue?)
58
//maybe it is better to just return when radius <= 0.0f?
59
if
(radius <= 0.0f)
60
{
61
map.
Visit
(*
this
, visitor);
62
return
;
63
}
64
//lets limit the upper value for search radius
65
if
(radius >
SIZE_OF_GRIDS
)
66
radius =
SIZE_OF_GRIDS
;
67
68
//lets calculate object coord offsets from cell borders.
69
CellArea
area =
Cell::CalculateCellArea
(x_off, y_off, radius);
70
//if radius fits inside standing cell
71
if
(!area)
72
{
73
map.
Visit
(*
this
, visitor);
74
return
;
75
}
76
77
//visit all cells, found in CalculateCellArea()
78
//if radius is known to reach cell area more than 4x4 then we should call optimized VisitCircle
79
//currently this technique works with MAX_NUMBER_OF_CELLS 16 and higher, with lower values
80
//there are nothing to optimize because SIZE_OF_GRID_CELL is too big...
81
if
((area.
high_bound
.
x_coord
> (area.
low_bound
.
x_coord
+ 4)) && (area.
high_bound
.
y_coord
> (area.
low_bound
.
y_coord
+ 4)))
82
{
83
VisitCircle
(visitor, map, area.
low_bound
, area.
high_bound
);
84
return
;
85
}
86
87
//ALWAYS visit standing cell first!!! Since we deal with small radiuses
88
//it is very essential to call visitor for standing cell firstly...
89
map.
Visit
(*
this
, visitor);
90
91
// loop the cell range
92
for
(
uint32
x = area.
low_bound
.
x_coord
; x <= area.
high_bound
.
x_coord
; ++x)
93
{
94
for
(
uint32
y = area.
low_bound
.
y_coord
; y <= area.
high_bound
.
y_coord
; ++y)
95
{
96
CellCoord
cellCoord(x, y);
97
//lets skip standing cell since we already visited it
98
if
(cellCoord != standing_cell)
99
{
100
Cell
r_zone(cellCoord);
101
r_zone.
data
.
Part
.
nocreate
= this->
data
.Part.nocreate;
102
map.
Visit
(r_zone, visitor);
103
}
104
}
105
}
106
}
107
108
template
<
class
T,
class
CONTAINER>
109
inline
void
Cell::Visit
(
CellCoord
const
& standing_cell,
TypeContainerVisitor<T, CONTAINER>
& visitor,
Map
& map,
WorldObject
const
& obj,
float
radius)
const
110
{
111
//we should increase search radius by object's radius, otherwise
112
//we could have problems with huge creatures, which won't attack nearest players etc
113
Visit
(standing_cell, visitor, map, radius + obj.
GetObjectSize
(), obj.
GetPositionX
(), obj.
GetPositionY
());
114
}
115
116
template
<
class
T,
class
CONTAINER>
117
inline
void
Cell::VisitCircle
(
TypeContainerVisitor<T, CONTAINER>
& visitor,
Map
& map,
CellCoord
const
& begin_cell,
CellCoord
const
& end_cell)
const
118
{
119
//here is an algorithm for 'filling' circum-squared octagon
120
uint32
x_shift = (
uint32
)ceilf((end_cell.
x_coord
- begin_cell.
x_coord
) * 0.3f - 0.5f);
121
//lets calculate x_start/x_end coords for central strip...
122
const
uint32
x_start = begin_cell.
x_coord
+ x_shift;
123
const
uint32
x_end = end_cell.
x_coord
- x_shift;
124
125
//visit central strip with constant width...
126
for
(
uint32
x = x_start; x <= x_end; ++x)
127
{
128
for
(
uint32
y = begin_cell.
y_coord
; y <= end_cell.
y_coord
; ++y)
129
{
130
CellCoord
cellCoord(x, y);
131
Cell
r_zone(cellCoord);
132
r_zone.
data
.
Part
.
nocreate
= this->
data
.Part.nocreate;
133
map.
Visit
(r_zone, visitor);
134
}
135
}
136
137
//if x_shift == 0 then we have too small cell area, which were already
138
//visited at previous step, so just return from procedure...
139
if
(x_shift == 0)
140
return
;
141
142
uint32
y_start = end_cell.
y_coord
;
143
uint32
y_end = begin_cell.
y_coord
;
144
//now we are visiting borders of an octagon...
145
for
(
uint32
step = 1; step <= (x_start - begin_cell.
x_coord
); ++step)
146
{
147
//each step reduces strip height by 2 cells...
148
y_end += 1;
149
y_start -= 1;
150
for
(
uint32
y = y_start; y >= y_end; --y)
151
{
152
//we visit cells symmetrically from both sides, heading from center to sides and from up to bottom
153
//e.g. filling 2 trapezoids after filling central cell strip...
154
CellCoord
cellCoord_left(x_start - step, y);
155
Cell
r_zone_left(cellCoord_left);
156
r_zone_left.
data
.
Part
.
nocreate
= this->
data
.Part.nocreate;
157
map.
Visit
(r_zone_left, visitor);
158
159
//right trapezoid cell visit
160
CellCoord
cellCoord_right(x_end + step, y);
161
Cell
r_zone_right(cellCoord_right);
162
r_zone_right.
data
.
Part
.
nocreate
= this->
data
.Part.nocreate;
163
map.
Visit
(r_zone_right, visitor);
164
}
165
}
166
}
167
#endif
Cell.h
uint32
std::uint32_t uint32
Definition
Define.h:77
MAX_NUMBER_OF_CELLS
#define MAX_NUMBER_OF_CELLS
Definition
GridDefines.h:22
SIZE_OF_GRIDS
#define SIZE_OF_GRIDS
Definition
GridDefines.h:26
CellCoord
CoordPair< TOTAL_NUMBER_OF_CELLS_PER_MAP > CellCoord
Definition
GridDefines.h:158
Map.h
Object.h
Map
Definition
Map.h:238
Map::Visit
void Visit(const Cell &cell, TypeContainerVisitor< T, CONTAINER > &visitor)
Definition
Map.h:686
TypeContainerVisitor
Definition
TypeContainerVisitor.h:80
WorldObject
Definition
Object.h:610
WorldObject::GetObjectSize
float GetObjectSize() const
Definition
Object.cpp:3100
Skyfire::ComputeCellCoord
CellCoord ComputeCellCoord(float x, float y)
Definition
GridDefines.h:179
CellArea
Definition
Cell.h:20
CellArea::high_bound
CellCoord high_bound
Definition
Cell.h:33
CellArea::low_bound
CellCoord low_bound
Definition
Cell.h:32
Cell::nocreate
unsigned nocreate
Definition
Cell.h:91
Cell::Cell
Cell()
Definition
Cell.h:38
Cell::Part
struct Cell::@253100141177133252213152253303204033205331220256::@054333305236276154171230343071320200077322155341 Part
Cell::Visit
void Visit(CellCoord const &, TypeContainerVisitor< T, CONTAINER > &visitor, Map &, WorldObject const &, float) const
Definition
CellImpl.h:109
Cell::VisitCircle
void VisitCircle(TypeContainerVisitor< T, CONTAINER > &, Map &, CellCoord const &, CellCoord const &) const
Definition
CellImpl.h:117
Cell::data
union Cell::@253100141177133252213152253303204033205331220256 data
Cell::CalculateCellArea
static CellArea CalculateCellArea(float x, float y, float radius)
Definition
CellImpl.h:36
CoordPair::IsCoordValid
bool IsCoordValid() const
Definition
GridDefines.h:124
CoordPair::x_coord
uint32 x_coord
Definition
GridDefines.h:141
CoordPair::y_coord
uint32 y_coord
Definition
GridDefines.h:142
CoordPair::normalize
CoordPair & normalize()
Definition
GridDefines.h:129
Position::GetPositionX
float GetPositionX() const
Definition
Object.h:328
Position::GetPositionY
float GetPositionY() const
Definition
Object.h:329
src
server
game
Grids
Cells
CellImpl.h
Generated on
for Project SkyFire Core by
1.17.0