From d0dbc0c3499a8aef804f94a5ab66810e8629c9d9 Mon Sep 17 00:00:00 2001 From: Ben Carter Date: Sun, 21 Jan 2024 21:12:53 -0500 Subject: [PATCH 1/4] Added NPCBot commands --- src/ElunaLuaEngine_SC.cpp | 1 + src/LuaEngine/CreatureMethods.h | 19 +++++++++++++++++++ src/LuaEngine/LuaFunctions.cpp | 8 ++++++++ 3 files changed, 28 insertions(+) diff --git a/src/ElunaLuaEngine_SC.cpp b/src/ElunaLuaEngine_SC.cpp index 803044c..301607b 100644 --- a/src/ElunaLuaEngine_SC.cpp +++ b/src/ElunaLuaEngine_SC.cpp @@ -237,6 +237,7 @@ class Eluna_AllMapScript : public AllMapScript public: Eluna_AllMapScript() : AllMapScript("Eluna_AllMapScript") { } + void OnBeforeCreateInstanceScript(InstanceMap* instanceMap, InstanceScript* instanceData, bool /*load*/, std::string /*data*/, uint32 /*completedEncounterMask*/) override { instanceData = sEluna->GetInstanceData(instanceMap); diff --git a/src/LuaEngine/CreatureMethods.h b/src/LuaEngine/CreatureMethods.h index cb85860..f1041cc 100644 --- a/src/LuaEngine/CreatureMethods.h +++ b/src/LuaEngine/CreatureMethods.h @@ -393,6 +393,25 @@ namespace LuaCreature return 1; } + /** -- NPCBOT Start */ +#if defined(AZEROTHCORE) + int IsNPCBot(lua_State* L, Creature* creature) + { + Eluna::Push(L, creature->IsNPCBot()); + return 1; + } + + int GetBotOwner(lua_State* L, Creature* creature) + { + if(!creature->IsNPCBot()) + return 0; + + Eluna::Push(L, creature->GetBotOwner()); + return 1; + } +#endif + /** -- NPCBot End */ + #if defined(TRINITY) || defined(AZEROTHCORE) /** * Returns `true` if the [Creature] is an invisible trigger, diff --git a/src/LuaEngine/LuaFunctions.cpp b/src/LuaEngine/LuaFunctions.cpp index ebf32d8..12e6e93 100644 --- a/src/LuaEngine/LuaFunctions.cpp +++ b/src/LuaEngine/LuaFunctions.cpp @@ -910,6 +910,14 @@ ElunaRegister CreatureMethods[] = { "MoveWaypoint", &LuaCreature::MoveWaypoint }, { "UpdateEntry", &LuaCreature::UpdateEntry }, + + /** -- NPCBOT Start */ +#if defined(AZEROTHCORE) + { "IsNPCBot", &LuaCreature::IsNPCBot }, + { "GetBotOwner", } +#endif + /** -- NPCBOT End */ + { NULL, NULL } }; From 4111d20bc37a954a5618d6cdb2eae457e1c99055 Mon Sep 17 00:00:00 2001 From: Ben Carter Date: Tue, 6 Feb 2024 17:59:00 -0500 Subject: [PATCH 2/4] Added support for new NPC Bot commands --- src/LuaEngine/CreatureMethods.h | 221 +++++++++++++++++++++++++++++++- src/LuaEngine/ElunaIncludes.h | 15 +++ src/LuaEngine/LuaFunctions.cpp | 21 ++- 3 files changed, 250 insertions(+), 7 deletions(-) diff --git a/src/LuaEngine/CreatureMethods.h b/src/LuaEngine/CreatureMethods.h index f1041cc..5c323d9 100644 --- a/src/LuaEngine/CreatureMethods.h +++ b/src/LuaEngine/CreatureMethods.h @@ -394,22 +394,233 @@ namespace LuaCreature } /** -- NPCBOT Start */ -#if defined(AZEROTHCORE) +// #if defined(AZEROTHCORE) + /** + * Return `true` if the [Creature] is a NPCBot, + * @return bool isNPCBot + */ int IsNPCBot(lua_State* L, Creature* creature) { Eluna::Push(L, creature->IsNPCBot()); return 1; } + /** + * Returns the [Creature]'s bot owner. + * @return [Player] botOwner + */ int GetBotOwner(lua_State* L, Creature* creature) { if(!creature->IsNPCBot()) return 0; - - Eluna::Push(L, creature->GetBotOwner()); + + bot_ai* ai = creature->GetBotAI(); + if (ai) { + Eluna::Push(L, ai->GetBotOwner()); + return 1; + } + else { + return 0; + } + } + + int GetBotOwnerGUID(lua_State* L, Creature* creature) + { + if(!creature->IsNPCBot()) + return 0; + + bot_ai* ai = creature->GetBotAI(); + if (ai) { + Eluna::Push(L, ai->GetBotOwnerGuid()); + return 1; + } + else { + return 0; + } + } + + /** + * Returns the [Creature]'s bot class. + * @return unint8 botClassID + */ + int GetBotClass(lua_State* L, Creature* creature) + { + if(!creature->IsNPCBot()) + return 0; + + Eluna::Push(L, creature->GetBotClass()); return 1; } -#endif + + /** + * Get the [Creature]'s bot roles Tank, Healer, Damage that are enabled as a mask. + * @return uint32 botRoles + */ + int GetBotRoles(lua_State* L, Creature* creature) + { + if(!creature->IsNPCBot()) + return 0; + + Eluna::Push(L, creature->GetBotRoles()); + return 1; + } + + /** + * Returns `true` if the [Creature] is has an assigned role as tank. + * @return bool isTank + */ + int IsBotTank(lua_State* L, Creature* creature) + { + if(!creature->IsNPCBot()) + return 0; + + bot_ai* ai = creature->GetBotAI(); + Eluna::Push(L, ai->IsTank()); + return 1; + } + /** + * Returns `true` if the [Creature] is has an assigned role as off-tank. + * @return bool isTank + */ + int IsBotOffTank(lua_State* L, Creature* creature) + { + if(!creature->IsNPCBot()) + return 0; + + bot_ai* ai = creature->GetBotAI(); + Eluna::Push(L, ai->IsOffTank()); + return 1; + } + + /** + * Returns `true` if the [Creature] is free and not assigned to a player + * @return bool isFree + */ + int IsFreeBot(lua_State* L, Creature* creature) + { + if(!creature->IsNPCBot()) + return 0; + + Eluna::Push(L, creature->IsFreeBot()); + return 1; + } + + /** + * Get the [Creature]'s bot average item level of equipped items. + * @return float botAverageItemLevel + */ + int GetBotAverageItemLevel(lua_State* L, Creature* creature) + { + if(!creature->IsNPCBot()) + return 0; + + Eluna::Push(L, creature->GetBotAverageItemLevel()); + return 1; + } + + int GetBotEquipment(lua_State* L, Creature* creature) + { + if(!creature->IsNPCBot()) + return 0; + + if(creature->IsFreeBot()) + return 0; + + uint32 slot = Eluna::CHECKVAL(L, 2); + Eluna::Push(L, creature->GetBotEquips(slot)); + return 1; + } + + int GetBotStat(lua_State* L, Creature* creature) + { + if(!creature->IsNPCBot()) + return 0; + + uint8 botstat = Eluna::CHECKVAL(L, 2); + Eluna::Push(L, creature->GetTotalBotStat(BotStatMods(botstat))); + + return 1; + } + + int BotEquipItem(lua_State* L, Creature* creature) + { + if(!creature->IsNPCBot()) + return 0; + + // If this bot is not owned by a player return. + if(creature->IsFreeBot()) + return 0; + + // if the entry passed in was an item object + Item* item = Eluna::CHECKOBJ(L, 2, false); + uint32 slot = Eluna::CHECKVAL(L, 3); + Player* owner = creature->GetBotOwner(); + + // If an item entry was passed in instead + if(!item) + { + uint32 itemid = Eluna::CHECKVAL(L, 2); + item = owner->GetItemByEntry(itemid); + } + + if(slot > EQUIPMENT_SLOT_END) + return 0; + + bool result = creature->EquipItem(slot, item, owner->GetGUID()); + Eluna::Push(L, result); + return 1; + } + + int BotCanEquipItem(lua_State* L, Creature* creature) + { + if(!creature->IsNPCBot()) + return 0; + + // If this bot is not owned by a player return. + if(creature->IsFreeBot()) + return 0; + + // if the entry passed in was an item object + uint32 entry = Eluna::CHECKVAL(L, 2); + uint32 slot = Eluna::CHECKVAL(L, 3); + + // If an item entry was passed in instead + if(entry) + { + const ItemTemplate* proto = eObjectMgr->GetItemTemplate(entry); + if(!proto) + return luaL_argerror(L, 1, "valid ItemEntry expected in BotCanEquipItem"); + + if(slot > EQUIPMENT_SLOT_END) + return luaL_argerror(L, 1, "valie slot expected in BotCanEquipItem"); + + bot_ai* ai = creature->GetBotAI(); + bool result = ai->CanEquip(proto, slot, true); + Eluna::Push(L, result); + + } + return 1; + } + + int BotUnequipItem(lua_State* L, Creature* creature) + { + if(!creature->IsNPCBot()) + return 0; + + // If this bot is not owned by a player return. + if(creature->IsFreeBot()) + return 0; + + uint32 slot = Eluna::CHECKVAL(L, 2); + Player* owner = creature->GetBotOwner(); + + bot_ai* ai = creature->GetBotAI(); + bool result = ai->UnequipItem(slot, owner->GetGUID()); + Eluna::Push(L, result); + return 1; + } + +// #endif /** -- NPCBot End */ #if defined(TRINITY) || defined(AZEROTHCORE) @@ -1025,7 +1236,7 @@ auto const& threatlist = creature->GetThreatMgr().GetThreatList(); creature->SetUInt32Value(UNIT_NPC_FLAGS, flags); return 0; } - + /** * Sets the [Creature]'s Unit flags to `flags`. * diff --git a/src/LuaEngine/ElunaIncludes.h b/src/LuaEngine/ElunaIncludes.h index 26f8c0c..c2993e4 100644 --- a/src/LuaEngine/ElunaIncludes.h +++ b/src/LuaEngine/ElunaIncludes.h @@ -80,6 +80,13 @@ #include "ArenaTeam.h" #endif +/** -- NPCBOT Start */ +#include "botdatamgr.h" +#include "botmgr.h" +#include "botcommon.h" +#include "bot_ai.h" +/** -- NPCBOT End */ + #ifndef CLASSIC typedef Opcodes OpcodesList; #endif @@ -120,6 +127,14 @@ typedef Opcodes OpcodesList; #define eObjectAccessor() ObjectAccessor:: #endif +/** -- NPCBOT Start */ +#if defined AZEROTHCORE +#define eBotMgr (sBotMgr) +#define eBotDataMgr (sBotDataMgr) +#endif +/** -- NPCBOT End */ + + #ifdef CATA #define NUM_MSG_TYPES NUM_OPCODE_HANDLERS #endif diff --git a/src/LuaEngine/LuaFunctions.cpp b/src/LuaEngine/LuaFunctions.cpp index 12e6e93..b75aa45 100644 --- a/src/LuaEngine/LuaFunctions.cpp +++ b/src/LuaEngine/LuaFunctions.cpp @@ -912,9 +912,26 @@ ElunaRegister CreatureMethods[] = /** -- NPCBOT Start */ -#if defined(AZEROTHCORE) +#if defined(AZEROTHCORE) + + // Getters & Flags { "IsNPCBot", &LuaCreature::IsNPCBot }, - { "GetBotOwner", } + { "GetBotOwner", &LuaCreature::GetBotOwner }, + { "GetBotOwnerGUID", &LuaCreature::GetBotOwnerGUID }, + { "GetBotClass", &LuaCreature::GetBotClass }, + { "GetBotRoles", &LuaCreature::GetBotRoles }, + { "IsBotTank", &LuaCreature::IsBotTank }, + { "IsBotOffTank", &LuaCreature::IsBotOffTank }, + { "IsFreeBot", &LuaCreature::IsFreeBot }, + { "GetBotAverageItemLevel", &LuaCreature::GetBotAverageItemLevel }, + { "GetBotEquipment", &LuaCreature::GetBotEquipment }, + { "GetBotStat", &LuaCreature::GetBotStat }, + + + // Setters + { "BotEquipItem", &LuaCreature::BotEquipItem }, + { "BotCanEquipItem", &LuaCreature::BotCanEquipItem }, + { "BotUnequipBotItem", &LuaCreature::BotUnequipItem }, #endif /** -- NPCBOT End */ From 23fb8017248c316089fb30e1d8450708f1479b4e Mon Sep 17 00:00:00 2001 From: Ben Carter Date: Thu, 8 Feb 2024 18:32:39 -0500 Subject: [PATCH 3/4] Added Talent Spec --- src/LuaEngine/CreatureMethods.h | 10 ++++++++++ src/LuaEngine/LuaFunctions.cpp | 1 + 2 files changed, 11 insertions(+) diff --git a/src/LuaEngine/CreatureMethods.h b/src/LuaEngine/CreatureMethods.h index 5c323d9..8167635 100644 --- a/src/LuaEngine/CreatureMethods.h +++ b/src/LuaEngine/CreatureMethods.h @@ -542,6 +542,16 @@ namespace LuaCreature return 1; } + int GetTalentSpec(lua_State* L, Creature* creature) + { + if(!creature->IsNPCBot()) + return 0; + + bot_ai* ai = creature->GetBotAI(); + Eluna::Push(L, ai->GetSpec()); + return 1; + } + int BotEquipItem(lua_State* L, Creature* creature) { if(!creature->IsNPCBot()) diff --git a/src/LuaEngine/LuaFunctions.cpp b/src/LuaEngine/LuaFunctions.cpp index b75aa45..c50aa5b 100644 --- a/src/LuaEngine/LuaFunctions.cpp +++ b/src/LuaEngine/LuaFunctions.cpp @@ -920,6 +920,7 @@ ElunaRegister CreatureMethods[] = { "GetBotOwnerGUID", &LuaCreature::GetBotOwnerGUID }, { "GetBotClass", &LuaCreature::GetBotClass }, { "GetBotRoles", &LuaCreature::GetBotRoles }, + { "GetTalentSpec", &LuaCreature::GetTalentSpec }, { "IsBotTank", &LuaCreature::IsBotTank }, { "IsBotOffTank", &LuaCreature::IsBotOffTank }, { "IsFreeBot", &LuaCreature::IsFreeBot }, From 93246b255163d88584c81bcfe1bf4e5a7be1803b Mon Sep 17 00:00:00 2001 From: Ben Carter Date: Sat, 10 Feb 2024 23:05:09 -0500 Subject: [PATCH 4/4] Added functions for getting raw bot data for stats and info --- src/LuaEngine/CreatureMethods.h | 16 ++++++++++++++++ src/LuaEngine/LuaFunctions.cpp | 1 + 2 files changed, 17 insertions(+) diff --git a/src/LuaEngine/CreatureMethods.h b/src/LuaEngine/CreatureMethods.h index 8167635..c87bb1b 100644 --- a/src/LuaEngine/CreatureMethods.h +++ b/src/LuaEngine/CreatureMethods.h @@ -630,6 +630,22 @@ namespace LuaCreature return 1; } + int GetBotDump(lua_State* L, Creature* creature) + { + if(!creature->IsNPCBot()) + return 0; + + bot_ai* ai = creature->GetBotAI(); + Player* owner = creature->GetBotOwner(); + const char* dump = ai->BotDump(owner, creature); + + if(!dump) + return luaL_argerror(L, 1, "BotDump failed for bot."); + + Eluna::Push(L, dump); + return 1; + } + // #endif /** -- NPCBot End */ diff --git a/src/LuaEngine/LuaFunctions.cpp b/src/LuaEngine/LuaFunctions.cpp index c50aa5b..ec34249 100644 --- a/src/LuaEngine/LuaFunctions.cpp +++ b/src/LuaEngine/LuaFunctions.cpp @@ -927,6 +927,7 @@ ElunaRegister CreatureMethods[] = { "GetBotAverageItemLevel", &LuaCreature::GetBotAverageItemLevel }, { "GetBotEquipment", &LuaCreature::GetBotEquipment }, { "GetBotStat", &LuaCreature::GetBotStat }, + { "GetBotDump", &LuaCreature::GetBotDump }, // Setters