22 #ifndef ULTIMA8_MISC_DIRECTIONUTIL_H 23 #define ULTIMA8_MISC_DIRECTIONUTIL_H 25 #include "ultima/ultima8/misc/direction.h" 26 #include "ultima/ultima8/ultima8.h" 27 #include "math/utils.h" 37 inline int Direction_XFactor(Direction dir) {
38 static const int _x_fact[] = { 0, +1, +1, +1, 0, -1, -1, -1 };
39 static const int _x_fact16[] = { 0, +1, +1, +2, +1, +2, +1, +1, 0, -1, -1, -2, -1, -2, -1, -1, 0 };
41 assert((
int)dir >= 0 && (
int)dir < 16);
44 return _x_fact[(int)dir / 2];
46 return _x_fact16[(int)dir];
49 inline int Direction_YFactor(Direction dir) {
50 static const int _y_fact[] = { -1, -1, 0, +1, +1, +1, 0, -1 };
51 static const int _y_fact16[] = { -1, -2, -1, -1, 0, +1, +1, +2, +1, +2, +1, +1, 0, -1, -1, -2, 0 };
53 assert((
int)dir >= 0 && (
int)dir < 16);
56 return _y_fact[(int)dir / 2];
58 return _y_fact16[(int)dir];
62 inline int32 Direction_ToCentidegrees(Direction dir) {
63 return static_cast<int>(dir) * 2250;
67 inline Direction Direction_FromCentidegrees(int32 cds) {
68 return static_cast<Direction
>(((cds + 1125) / 2250) % 16);
80 inline Direction Direction_Get(
int deltay,
int deltax, DirectionMode dirmode) {
82 return deltay > 0 ? dir_northwest : dir_southeast;
84 if (dirmode == dirmode_8dirs) {
85 int dydx = (1024 * deltay) / deltax;
88 return dydx <= 424 ? dir_northeast : dydx <= 2472 ? dir_north
91 return dydx <= 424 ? dir_southwest : dydx <= 2472 ? dir_south
94 return dydx >= -424 ? dir_northeast : dydx >= -2472 ? dir_east
97 return dydx >= -424 ? dir_southwest : dydx >= -2472 ? dir_west
100 double angle = Math::rad2deg(atan2(deltay, deltax));
101 if (angle < -168.75)
return dir_southwest;
102 else if (angle < -146.25)
return dir_ssw;
103 else if (angle < -123.75)
return dir_south;
104 else if (angle < -101.25)
return dir_sse;
105 else if (angle < -78.75)
return dir_southeast;
106 else if (angle < -56.25)
return dir_ese;
107 else if (angle < -33.75)
return dir_east;
108 else if (angle < -11.25)
return dir_ene;
109 else if (angle < 11.25)
return dir_northeast;
110 else if (angle < 33.75)
return dir_nne;
111 else if (angle < 56.25)
return dir_north;
112 else if (angle < 78.75)
return dir_nnw;
113 else if (angle < 101.25)
return dir_northwest;
114 else if (angle < 123.75)
return dir_wnw;
115 else if (angle < 146.25)
return dir_west;
116 else if (angle < 168.75)
return dir_wsw;
117 return dir_southwest;
122 inline Direction Direction_GetWorldDir(
int deltay,
int deltax, DirectionMode dirmode) {
124 if (deltay == 0)
return dir_northeast;
125 return deltay > 0 ? dir_south : dir_north;
128 if (dirmode == dirmode_8dirs) {
129 int dydx = (1024 * deltay) / deltax;
133 return dydx <= 424 ? dir_east : dydx <= 2472 ? dir_southeast : dir_south;
135 return dydx <= 424 ? dir_west : dydx <= 2472 ? dir_northwest : dir_north;
137 return dydx >= -424 ? dir_east : dydx >= -2472 ? dir_northeast : dir_north;
139 return dydx >= -424 ? dir_west : dydx >= -2472 ? dir_southwest : dir_south;
141 double angle = Math::rad2deg(atan2(deltay, deltax));
142 if (angle < -168.75)
return dir_west;
143 else if (angle < -146.25)
return dir_wnw;
144 else if (angle < -123.75)
return dir_northwest;
145 else if (angle < -101.25)
return dir_nnw;
146 else if (angle < -78.75)
return dir_north;
147 else if (angle < -56.25)
return dir_nne;
148 else if (angle < -33.75)
return dir_northeast;
149 else if (angle < -11.25)
return dir_ene;
150 else if (angle < 11.25)
return dir_east;
151 else if (angle < 33.75)
return dir_ese;
152 else if (angle < 56.25)
return dir_southeast;
153 else if (angle < 78.75)
return dir_sse;
154 else if (angle < 101.25)
return dir_south;
155 else if (angle < 123.75)
return dir_ssw;
156 else if (angle < 146.25)
return dir_southwest;
157 else if (angle < 168.75)
return dir_wsw;
164 inline Direction Direction_GetWorldDirInRange(
int deltay,
int deltax, DirectionMode dirmode, Direction mindir, Direction maxdir) {
165 int ndirs = (dirmode == dirmode_8dirs ? 8 : 16);
166 Direction dir = Direction_GetWorldDir(deltay, deltax, dirmode);
168 if ((dir < mindir) || (dir > maxdir)) {
169 int32 dmin1 = dir - mindir;
170 int32 dmin2 = mindir - dir;
172 dmin1 = dmin1 + ndirs;
175 dmin2 = dmin2 + ndirs;
177 int32 dist_to_min =
MIN(dmin1, dmin2);
179 int dmax1 = dir - maxdir;
180 int dmax2 = maxdir - dir;
182 dmax1 = dmax1 + ndirs;
185 dmax2 = dmax2 + ndirs;
187 int32 dist_to_max =
MIN(dmax1, dmax2);
189 if (dist_to_min < dist_to_max) {
199 inline Direction Direction_Invert(Direction dir) {
200 assert(dir != dir_current);
202 case dir_north:
return dir_south;
203 case dir_nne:
return dir_ssw;
204 case dir_northeast:
return dir_southwest;
205 case dir_ene:
return dir_wsw;
206 case dir_east:
return dir_west;
207 case dir_ese:
return dir_wnw;
208 case dir_southeast:
return dir_northwest;
209 case dir_sse:
return dir_nnw;
210 case dir_south:
return dir_north;
211 case dir_ssw:
return dir_nne;
212 case dir_southwest:
return dir_northeast;
213 case dir_wsw:
return dir_ene;
214 case dir_west:
return dir_east;
215 case dir_wnw:
return dir_ese;
216 case dir_northwest:
return dir_southeast;
217 case dir_nnw:
return dir_sse;
218 default:
return dir_north;
223 inline Direction Direction_OneLeft(Direction dir, DirectionMode mode) {
224 if (mode == dirmode_8dirs)
225 return static_cast<Direction
>((
static_cast<int>(dir) + 14) % 16);
227 return static_cast<Direction
>((
static_cast<int>(dir) + 15) % 16);
231 inline Direction Direction_OneRight(Direction dir, DirectionMode mode) {
232 if (mode == dirmode_8dirs)
233 return static_cast<Direction
>((
static_cast<int>(dir) + 2) % 16);
235 return static_cast<Direction
>((
static_cast<int>(dir) + 1) % 16);
238 inline Direction Direction_TurnByDelta(Direction dir,
int delta, DirectionMode mode) {
240 for (
int i = 0; i < delta; i++)
241 dir = Direction_OneRight(dir, mode);
242 }
else if (delta < 0) {
243 for (
int i = 0; i < -delta; i++)
244 dir = Direction_OneLeft(dir, mode);
251 inline int Direction_GetShorterTurnDelta(Direction from, Direction to) {
252 if ((from - to + 16) % 16 < 8)
257 inline uint32 Direction_ToUsecodeDir(Direction dir) {
259 return static_cast<int32
>(dir / 2);
261 return static_cast<int32
>(dir);
265 inline Direction Direction_FromUsecodeDir(uint32 dir) {
267 return static_cast<Direction
>(dir * 2);
269 return static_cast<Direction
>(dir);
Definition: detection.h:27
T MIN(T a, T b)
Definition: util.h:61