* Get to direction to follow to go from \a from to \a to. * * @param from The origin. * @param to The destination. * @return The direction. */
| 340 | * @return The direction. |
| 341 | */ |
| 342 | int8 Tile_GetDirection(tile32 from, tile32 to) |
| 343 | { |
| 344 | static const uint16 orientationOffsets[] = {0x40, 0x80, 0x0, 0xC0}; |
| 345 | static const int32 directions[] = { |
| 346 | 0x3FFF, 0x28BC, 0x145A, 0xD8E, 0xA27, 0x81B, 0x6BD, 0x5C3, 0x506, 0x474, 0x3FE, 0x39D, 0x34B, 0x306, 0x2CB, 0x297, |
| 347 | 0x26A, 0x241, 0x21D, 0x1FC, 0x1DE, 0x1C3, 0x1AB, 0x194, 0x17F, 0x16B, 0x159, 0x148, 0x137, 0x128, 0x11A, 0x10C |
| 348 | }; |
| 349 | |
| 350 | int32 dx; |
| 351 | int32 dy; |
| 352 | uint16 i; |
| 353 | int32 gradient; |
| 354 | uint16 baseOrientation; |
| 355 | bool invert; |
| 356 | uint16 quadrant = 0; |
| 357 | |
| 358 | dx = to.x - from.x; |
| 359 | dy = to.y - from.y; |
| 360 | |
| 361 | if (abs(dx) + abs(dy) > 8000) { |
| 362 | dx /= 2; |
| 363 | dy /= 2; |
| 364 | } |
| 365 | |
| 366 | if (dy <= 0) { |
| 367 | quadrant |= 0x2; |
| 368 | dy = -dy; |
| 369 | } |
| 370 | |
| 371 | if (dx < 0) { |
| 372 | quadrant |= 0x1; |
| 373 | dx = -dx; |
| 374 | } |
| 375 | |
| 376 | baseOrientation = orientationOffsets[quadrant]; |
| 377 | invert = false; |
| 378 | gradient = 0x7FFF; |
| 379 | |
| 380 | if (dx >= dy) { |
| 381 | if (dy != 0) gradient = (dx << 8) / dy; |
| 382 | } else { |
| 383 | invert = true; |
| 384 | if (dx != 0) gradient = (dy << 8) / dx; |
| 385 | } |
| 386 | |
| 387 | for (i = 0; i < lengthof(directions); i++) { |
| 388 | if (directions[i] <= gradient) break; |
| 389 | } |
| 390 | |
| 391 | if (!invert) i = 64 - i; |
| 392 | |
| 393 | if (quadrant == 0 || quadrant == 3) return (baseOrientation + 64 - i) & 0xFF; |
| 394 | |
| 395 | return (baseOrientation + i) & 0xFF; |
| 396 | } |
| 397 | |
| 398 | /** |
| 399 | * Move to the given orientation looking from the current position. |
no outgoing calls
no test coverage detected