|
| 1 | +// This file is part of ClassicAPI. |
| 2 | +// |
| 3 | +// ClassicAPI is free software: you can redistribute it and/or modify it under the terms |
| 4 | +// of the GNU General Public License as published by the Free Software Foundation, either |
| 5 | +// version 3 of the License, or (at your option) any later version. |
| 6 | +// |
| 7 | +// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY |
| 8 | +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |
| 9 | +// PURPOSE. See the GNU General Public License for more details. |
| 10 | +// |
| 11 | +// You should have received a copy of the GNU General Public License along with |
| 12 | +// ClassicAPI. If not, see <https://www.gnu.org/licenses/>. |
| 13 | + |
| 14 | +// `C_Map.GetMapWorldSize([areaID])` — the world size (in yards) of a zone, |
| 15 | +// as `width, height`. This is the physical extent the map represents: the |
| 16 | +// span of the `WorldMapArea.dbc` placement rect. Modern addons use it to |
| 17 | +// convert map-relative percents to yard distances (e.g. tracking-range |
| 18 | +// rings, "X yards away" readouts). |
| 19 | +// |
| 20 | +// With a numeric `areaID` (AreaTable id — the same identity |
| 21 | +// `C_Map.GetBestMapForUnit` returns and `C_Map.GetMapOverlays` accepts), |
| 22 | +// returns that zone's size. With no argument, returns the world map's |
| 23 | +// currently viewed zone (same resolution `GetMapOverlays()` uses with no |
| 24 | +// arg). Returns nothing (→ nil, nil) when the zone can't be resolved. |
| 25 | +// |
| 26 | +// WoW's world axes are +X north, +Y west; the WorldMapArea rect bounds |
| 27 | +// them as locTop/locBottom (world X) and locLeft/locRight (world Y). Map |
| 28 | +// width is the horizontal (east-west) extent and height the vertical |
| 29 | +// (north-south): |
| 30 | +// width = locLeft - locRight (world Y span) |
| 31 | +// height = locTop - locBottom (world X span) |
| 32 | +// The same spans are the denominators in the world→map percent transform |
| 33 | +// (see `Map::AreaTriggers`), so a point's `mapX% * width / 100` is its |
| 34 | +// offset in yards from the zone's east edge, and likewise for height. |
| 35 | + |
| 36 | +#include "Game.h" |
| 37 | +#include "Offsets.h" |
| 38 | +#include "dbc/Lookup.h" |
| 39 | +#include "map/Area.h" |
| 40 | + |
| 41 | +#include <cstdint> |
| 42 | + |
| 43 | +namespace Map::WorldSize { |
| 44 | + |
| 45 | +namespace { |
| 46 | + |
| 47 | +int __fastcall Script_GetMapWorldSize(void *L) { |
| 48 | + const int row = Game::Lua::IsNumber(L, 1) |
| 49 | + ? Map::Area::RowForAreaID( |
| 50 | + static_cast<uint32_t>(Game::Lua::ToNumber(L, 1))) |
| 51 | + : Map::Area::CurrentViewRow(); |
| 52 | + |
| 53 | + Game::Lua::SetTop(L, 0); |
| 54 | + if (row <= 0) |
| 55 | + return 0; // no values -> nil, nil |
| 56 | + |
| 57 | + const uint8_t *rec = DBC::Record(Offsets::VAR_WORLDMAP_AREA_RECORDS, |
| 58 | + Offsets::VAR_WORLDMAP_AREA_COUNT, |
| 59 | + static_cast<uint32_t>(row)); |
| 60 | + if (rec == nullptr) |
| 61 | + return 0; |
| 62 | + |
| 63 | + const float left = *reinterpret_cast<const float *>(rec + Offsets::OFF_WMA_LOC_LEFT); |
| 64 | + const float right = *reinterpret_cast<const float *>(rec + Offsets::OFF_WMA_LOC_RIGHT); |
| 65 | + const float top = *reinterpret_cast<const float *>(rec + Offsets::OFF_WMA_LOC_TOP); |
| 66 | + const float bottom = *reinterpret_cast<const float *>(rec + Offsets::OFF_WMA_LOC_BOTTOM); |
| 67 | + |
| 68 | + Game::Lua::PushNumber(L, static_cast<double>(left) - right); // width (world Y span) |
| 69 | + Game::Lua::PushNumber(L, static_cast<double>(top) - bottom); // height (world X span) |
| 70 | + return 2; |
| 71 | +} |
| 72 | + |
| 73 | +void RegisterLuaFunctions() { |
| 74 | + Game::Lua::RegisterTableFunction("C_Map", "GetMapWorldSize", |
| 75 | + &Script_GetMapWorldSize); |
| 76 | +} |
| 77 | + |
| 78 | +const Game::ModuleAutoRegister _autoreg{&RegisterLuaFunctions}; |
| 79 | + |
| 80 | +} // namespace |
| 81 | + |
| 82 | +} // namespace Map::WorldSize |
0 commit comments