mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-04-03 20:03:50 +00:00
chore(lua): refactor addon Lua engine API + progress docs
- Refactor Lua addon integration: - Update CMakeLists.txt for addon build paths - Enhance addons API headers and Lua engine interface - Add new Lua API addon modules (`lua_api_helpers`, `lua_api_registrations`, `lua_services`, `lua_action_api`, `lua_inventory_api`, `lua_quest_api`, `lua_social_api`, `lua_spell_api`, `lua_system_api`, `lua_unit_api`) - Update implementation in addon_manager.cpp, lua_engine.cpp, application.cpp, game_handler.cpp
This commit is contained in:
parent
6e02b4451c
commit
a916270a13
21 changed files with 6183 additions and 6700 deletions
|
|
@ -13,7 +13,7 @@ public:
|
|||
AddonManager();
|
||||
~AddonManager();
|
||||
|
||||
bool initialize(game::GameHandler* gameHandler);
|
||||
bool initialize(game::GameHandler* gameHandler, const LuaServices& services = {});
|
||||
void scanAddons(const std::string& addonsPath);
|
||||
void loadAllAddons();
|
||||
bool runScript(const std::string& code);
|
||||
|
|
@ -35,6 +35,7 @@ private:
|
|||
LuaEngine luaEngine_;
|
||||
std::vector<TocFile> addons_;
|
||||
game::GameHandler* gameHandler_ = nullptr;
|
||||
LuaServices luaServices_;
|
||||
std::string addonsPath_;
|
||||
|
||||
bool loadAddon(const TocFile& addon);
|
||||
|
|
|
|||
166
include/addons/lua_api_helpers.hpp
Normal file
166
include/addons/lua_api_helpers.hpp
Normal file
|
|
@ -0,0 +1,166 @@
|
|||
// lua_api_helpers.hpp — Shared helpers, lookup tables, and utility functions
|
||||
// used by all lua_*_api.cpp domain files.
|
||||
// Extracted from lua_engine.cpp as part of §5.1 (Tame LuaEngine).
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <chrono>
|
||||
#include <cstring>
|
||||
#include <algorithm>
|
||||
|
||||
#include "addons/lua_services.hpp"
|
||||
#include "game/game_handler.hpp"
|
||||
#include "game/entity.hpp"
|
||||
#include "game/update_field_table.hpp"
|
||||
#include "core/logger.hpp"
|
||||
|
||||
extern "C" {
|
||||
#include <lua.h>
|
||||
#include <lauxlib.h>
|
||||
#include <lualib.h>
|
||||
}
|
||||
|
||||
namespace wowee::addons {
|
||||
|
||||
// ---- String helper ----
|
||||
inline void toLowerInPlace(std::string& s) {
|
||||
for (char& c : s) c = static_cast<char>(std::tolower(static_cast<unsigned char>(c)));
|
||||
}
|
||||
|
||||
// ---- Lua return helpers — used 200+ times as guard/fallback returns ----
|
||||
inline int luaReturnNil(lua_State* L) { lua_pushnil(L); return 1; }
|
||||
inline int luaReturnZero(lua_State* L) { lua_pushnumber(L, 0); return 1; }
|
||||
inline int luaReturnFalse(lua_State* L){ lua_pushboolean(L, 0); return 1; }
|
||||
|
||||
// ---- Shared GetTime() epoch ----
|
||||
// All time-returning functions must use this same origin
|
||||
// so that addon calculations like (start + duration - GetTime()) are consistent.
|
||||
inline const auto& luaTimeEpoch() {
|
||||
static const auto epoch = std::chrono::steady_clock::now();
|
||||
return epoch;
|
||||
}
|
||||
|
||||
inline double luaGetTimeNow() {
|
||||
return std::chrono::duration<double>(std::chrono::steady_clock::now() - luaTimeEpoch()).count();
|
||||
}
|
||||
|
||||
// ---- Shared WoW class/race/power name tables (indexed by ID, element 0 = unknown) ----
|
||||
inline constexpr const char* kLuaClasses[] = {
|
||||
"","Warrior","Paladin","Hunter","Rogue","Priest",
|
||||
"Death Knight","Shaman","Mage","Warlock","","Druid"
|
||||
};
|
||||
inline constexpr const char* kLuaRaces[] = {
|
||||
"","Human","Orc","Dwarf","Night Elf","Undead",
|
||||
"Tauren","Gnome","Troll","","Blood Elf","Draenei"
|
||||
};
|
||||
inline constexpr const char* kLuaPowerNames[] = {
|
||||
"MANA","RAGE","FOCUS","ENERGY","HAPPINESS","","RUNIC_POWER"
|
||||
};
|
||||
|
||||
// ---- Quality hex strings ----
|
||||
// No alpha prefix — for item links
|
||||
inline constexpr const char* kQualHexNoAlpha[] = {
|
||||
"9d9d9d","ffffff","1eff00","0070dd","a335ee","ff8000","e6cc80","e6cc80"
|
||||
};
|
||||
// With ff alpha prefix — for Lua color returns
|
||||
inline constexpr const char* kQualHexAlpha[] = {
|
||||
"ff9d9d9d","ffffffff","ff1eff00","ff0070dd","ffa335ee","ffff8000","ffe6cc80","ff00ccff"
|
||||
};
|
||||
|
||||
// ---- Retrieve GameHandler pointer stored in Lua registry ----
|
||||
inline game::GameHandler* getGameHandler(lua_State* L) {
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, "wowee_game_handler");
|
||||
auto* gh = static_cast<game::GameHandler*>(lua_touserdata(L, -1));
|
||||
lua_pop(L, 1);
|
||||
return gh;
|
||||
}
|
||||
|
||||
// ---- Retrieve LuaServices pointer stored in Lua registry ----
|
||||
inline LuaServices* getLuaServices(lua_State* L) {
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, "wowee_lua_services");
|
||||
auto* svc = static_cast<LuaServices*>(lua_touserdata(L, -1));
|
||||
lua_pop(L, 1);
|
||||
return svc;
|
||||
}
|
||||
|
||||
// ---- Unit resolution helpers ----
|
||||
|
||||
// Read UNIT_FIELD_TARGET_LO/HI from an entity's update fields to get what it's targeting
|
||||
inline uint64_t getEntityTargetGuid(game::GameHandler* gh, uint64_t guid) {
|
||||
if (guid == 0) return 0;
|
||||
// If asking for the player's target, use direct accessor
|
||||
if (guid == gh->getPlayerGuid()) return gh->getTargetGuid();
|
||||
auto entity = gh->getEntityManager().getEntity(guid);
|
||||
if (!entity) return 0;
|
||||
const auto& fields = entity->getFields();
|
||||
auto loIt = fields.find(game::fieldIndex(game::UF::UNIT_FIELD_TARGET_LO));
|
||||
if (loIt == fields.end()) return 0;
|
||||
uint64_t targetGuid = loIt->second;
|
||||
auto hiIt = fields.find(game::fieldIndex(game::UF::UNIT_FIELD_TARGET_HI));
|
||||
if (hiIt != fields.end())
|
||||
targetGuid |= (static_cast<uint64_t>(hiIt->second) << 32);
|
||||
return targetGuid;
|
||||
}
|
||||
|
||||
// Resolve WoW unit IDs to GUID
|
||||
inline uint64_t resolveUnitGuid(game::GameHandler* gh, const std::string& uid) {
|
||||
if (uid == "player") return gh->getPlayerGuid();
|
||||
if (uid == "target") return gh->getTargetGuid();
|
||||
if (uid == "focus") return gh->getFocusGuid();
|
||||
if (uid == "mouseover") return gh->getMouseoverGuid();
|
||||
if (uid == "pet") return gh->getPetGuid();
|
||||
// Compound unit IDs: targettarget, focustarget, pettarget, mouseovertarget
|
||||
if (uid == "targettarget") return getEntityTargetGuid(gh, gh->getTargetGuid());
|
||||
if (uid == "focustarget") return getEntityTargetGuid(gh, gh->getFocusGuid());
|
||||
if (uid == "pettarget") return getEntityTargetGuid(gh, gh->getPetGuid());
|
||||
if (uid == "mouseovertarget") return getEntityTargetGuid(gh, gh->getMouseoverGuid());
|
||||
// party1-party4, raid1-raid40
|
||||
if (uid.rfind("party", 0) == 0 && uid.size() > 5) {
|
||||
int idx = 0;
|
||||
try { idx = std::stoi(uid.substr(5)); } catch (...) { return 0; }
|
||||
if (idx < 1 || idx > 4) return 0;
|
||||
const auto& pd = gh->getPartyData();
|
||||
// party members exclude self; index 1-based
|
||||
int found = 0;
|
||||
for (const auto& m : pd.members) {
|
||||
if (m.guid == gh->getPlayerGuid()) continue;
|
||||
if (++found == idx) return m.guid;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if (uid.rfind("raid", 0) == 0 && uid.size() > 4 && uid[4] != 'p') {
|
||||
int idx = 0;
|
||||
try { idx = std::stoi(uid.substr(4)); } catch (...) { return 0; }
|
||||
if (idx < 1 || idx > 40) return 0;
|
||||
const auto& pd = gh->getPartyData();
|
||||
if (idx <= static_cast<int>(pd.members.size()))
|
||||
return pd.members[idx - 1].guid;
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Resolve unit IDs (player, target, focus, mouseover, pet, targettarget, etc.) to entity
|
||||
inline game::Unit* resolveUnit(lua_State* L, const char* unitId) {
|
||||
auto* gh = getGameHandler(L);
|
||||
if (!gh || !unitId) return nullptr;
|
||||
std::string uid(unitId);
|
||||
toLowerInPlace(uid);
|
||||
|
||||
uint64_t guid = resolveUnitGuid(gh, uid);
|
||||
if (guid == 0) return nullptr;
|
||||
auto entity = gh->getEntityManager().getEntity(guid);
|
||||
if (!entity) return nullptr;
|
||||
return dynamic_cast<game::Unit*>(entity.get());
|
||||
}
|
||||
|
||||
// Find GroupMember data for a GUID (for party members out of entity range)
|
||||
inline const game::GroupMember* findPartyMember(game::GameHandler* gh, uint64_t guid) {
|
||||
if (!gh || guid == 0) return nullptr;
|
||||
for (const auto& m : gh->getPartyData().members) {
|
||||
if (m.guid == guid && m.hasPartyStats) return &m;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // namespace wowee::addons
|
||||
18
include/addons/lua_api_registrations.hpp
Normal file
18
include/addons/lua_api_registrations.hpp
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
// lua_api_registrations.hpp — Forward declarations for per-domain Lua API
|
||||
// registration functions. Called from LuaEngine::registerCoreAPI().
|
||||
// Extracted from lua_engine.cpp as part of §5.1 (Tame LuaEngine).
|
||||
#pragma once
|
||||
|
||||
struct lua_State;
|
||||
|
||||
namespace wowee::addons {
|
||||
|
||||
void registerUnitLuaAPI(lua_State* L);
|
||||
void registerSpellLuaAPI(lua_State* L);
|
||||
void registerInventoryLuaAPI(lua_State* L);
|
||||
void registerQuestLuaAPI(lua_State* L);
|
||||
void registerSocialLuaAPI(lua_State* L);
|
||||
void registerSystemLuaAPI(lua_State* L);
|
||||
void registerActionLuaAPI(lua_State* L);
|
||||
|
||||
} // namespace wowee::addons
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "addons/lua_services.hpp"
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
|
@ -27,6 +28,7 @@ public:
|
|||
bool executeString(const std::string& code);
|
||||
|
||||
void setGameHandler(game::GameHandler* handler);
|
||||
void setLuaServices(const LuaServices& services);
|
||||
|
||||
// Fire a WoW event to all registered Lua handlers.
|
||||
void fireEvent(const std::string& eventName,
|
||||
|
|
@ -55,6 +57,7 @@ public:
|
|||
private:
|
||||
lua_State* L_ = nullptr;
|
||||
game::GameHandler* gameHandler_ = nullptr;
|
||||
LuaServices luaServices_;
|
||||
LuaErrorCallback luaErrorCallback_;
|
||||
|
||||
void registerCoreAPI();
|
||||
|
|
|
|||
17
include/addons/lua_services.hpp
Normal file
17
include/addons/lua_services.hpp
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
// lua_services.hpp — Dependency-injected services for Lua bindings.
|
||||
// Replaces Application::getInstance() calls in domain API files (§5.2).
|
||||
#pragma once
|
||||
|
||||
namespace wowee::core { class Window; }
|
||||
namespace wowee::audio { class AudioCoordinator; }
|
||||
namespace wowee::game { class ExpansionRegistry; }
|
||||
|
||||
namespace wowee::addons {
|
||||
|
||||
struct LuaServices {
|
||||
core::Window* window = nullptr;
|
||||
audio::AudioCoordinator* audioCoordinator = nullptr;
|
||||
game::ExpansionRegistry* expansionRegistry = nullptr;
|
||||
};
|
||||
|
||||
} // namespace wowee::addons
|
||||
Loading…
Add table
Add a link
Reference in a new issue