diff --git a/src/server/scripts/Commands/cs_gobject.cpp b/src/server/scripts/Commands/cs_gobject.cpp index 46db7cf4c..c23832e99 100644 --- a/src/server/scripts/Commands/cs_gobject.cpp +++ b/src/server/scripts/Commands/cs_gobject.cpp @@ -15,17 +15,21 @@ * with this program. If not, see . */ +#include "CellImpl.h" #include "Chat.h" #include "CommandScript.h" #include "GameEventMgr.h" #include "GameObject.h" #include "GameTime.h" +#include "GridNotifiers.h" +#include "GridNotifiersImpl.h" #include "Language.h" #include "MapMgr.h" #include "ObjectMgr.h" #include "Player.h" #include "PoolMgr.h" #include "Transport.h" +#include using namespace Acore::ChatCommands; @@ -497,6 +501,37 @@ public: Player* player = handler->GetSession()->GetPlayer(); + // Grid search - finds all game objects including temporary spawns + std::list gameobjects; + Acore::GameObjectInRangeCheck check(player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), distance); + Acore::GameObjectListSearcher searcher(player, gameobjects, check); + Cell::VisitObjects(player, searcher, distance); + + std::unordered_set gridSpawnIds; + + for (GameObject* go : gameobjects) + { + GameObjectTemplate const* gameObjectInfo = sObjectMgr->GetGameObjectTemplate(go->GetEntry()); + if (!gameObjectInfo) + continue; + + handler->PSendSysMessage(LANG_GO_LIST_CHAT, go->GetSpawnId(), go->GetEntry(), + go->GetSpawnId(), gameObjectInfo->name, + go->GetPositionX(), go->GetPositionY(), go->GetPositionZ(), + go->GetMapId(), "", ""); + + if (go->GetSpawnId()) + gridSpawnIds.insert(go->GetSpawnId()); + ++count; + } + + if (count > 0 && distance <= SIZE_OF_GRIDS) + { + handler->PSendSysMessage(LANG_COMMAND_NEAROBJMESSAGE, distance, count); + return true; + } + + // Fallback to DB query WorldDatabasePreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_GAMEOBJECT_NEAREST); stmt->SetData(0, player->GetPositionX()); stmt->SetData(1, player->GetPositionY()); @@ -515,6 +550,11 @@ public: { Field* fields = result->Fetch(); ObjectGuid::LowType guid = fields[0].Get(); + + // Skip entries already emitted via grid search + if (gridSpawnIds.count(guid)) + continue; + uint32 entry = fields[1].Get(); float x = fields[2].Get(); float y = fields[3].Get(); diff --git a/src/server/scripts/Commands/cs_npc.cpp b/src/server/scripts/Commands/cs_npc.cpp index e933d4be1..99f3973d8 100644 --- a/src/server/scripts/Commands/cs_npc.cpp +++ b/src/server/scripts/Commands/cs_npc.cpp @@ -15,11 +15,14 @@ * with this program. If not, see . */ +#include "CellImpl.h" #include "Chat.h" #include "CommandScript.h" #include "CreatureAI.h" #include "CreatureGroups.h" #include "GameTime.h" +#include "GridNotifiers.h" +#include "GridNotifiersImpl.h" #include "Language.h" #include "MapMgr.h" #include "ObjectMgr.h" @@ -29,6 +32,7 @@ #include "TargetedMovementGenerator.h" // for HandleNpcUnFollowCommand #include "Transport.h" #include +#include using namespace Acore::ChatCommands; @@ -728,6 +732,37 @@ public: Player* player = handler->GetSession()->GetPlayer(); + // Grid search - finds all creatures including temporary spawns + std::list creatures; + Acore::AllWorldObjectsInRange check(player, distance); + Acore::CreatureListSearcher searcher(player, creatures, check); + Cell::VisitObjects(player, searcher, distance); + + std::unordered_set gridSpawnIds; + + for (Creature* creature : creatures) + { + CreatureTemplate const* creatureTemplate = sObjectMgr->GetCreatureTemplate(creature->GetEntry()); + if (!creatureTemplate) + continue; + + handler->PSendSysMessage(LANG_CREATURE_LIST_CHAT, creature->GetSpawnId(), creature->GetEntry(), + creature->GetSpawnId(), creatureTemplate->Name, + creature->GetPositionX(), creature->GetPositionY(), creature->GetPositionZ(), + creature->GetMapId(), "", ""); + + if (creature->GetSpawnId()) + gridSpawnIds.insert(creature->GetSpawnId()); + ++count; + } + + if (count > 0 && distance <= SIZE_OF_GRIDS) + { + handler->PSendSysMessage(LANG_COMMAND_NEAR_NPC_MESSAGE, distance, count); + return true; + } + + // Fallback to DB query WorldDatabasePreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_CREATURE_NEAREST); stmt->SetData(0, player->GetPositionX()); stmt->SetData(1, player->GetPositionY()); @@ -746,6 +781,11 @@ public: { Field* fields = result->Fetch(); ObjectGuid::LowType guid = fields[0].Get(); + + // Skip entries already emitted via grid search + if (gridSpawnIds.count(guid)) + continue; + uint32 entry = fields[1].Get(); //uint32 entry2 = fields[2].Get(); //uint32 entry3 = fields[3].Get();