feat(Scripts/Commands): Implement npc/gameobject load commands (#24644)

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
This commit is contained in:
Andrew
2026-02-08 08:36:35 -03:00
committed by GitHub
parent e0b50798a0
commit 2b563fc0e4
5 changed files with 428 additions and 0 deletions

View File

@@ -50,6 +50,7 @@ public:
{ "turn", HandleGameObjectTurnCommand, SEC_ADMINISTRATOR, Console::No },
{ "add temp", HandleGameObjectAddTempCommand, SEC_GAMEMASTER, Console::No },
{ "add", HandleGameObjectAddCommand, SEC_ADMINISTRATOR, Console::No },
{ "load", HandleGameObjectLoadCommand, SEC_ADMINISTRATOR, Console::Yes },
{ "set phase", HandleGameObjectSetPhaseCommand, SEC_ADMINISTRATOR, Console::No },
{ "set state", HandleGameObjectSetStateCommand, SEC_ADMINISTRATOR, Console::No },
{ "respawn", HandleGameObjectRespawn, SEC_GAMEMASTER, Console::No }
@@ -144,6 +145,64 @@ public:
return true;
}
static bool HandleGameObjectLoadCommand(ChatHandler* handler, GameObjectSpawnId spawnId)
{
if (!spawnId)
return false;
if (sObjectMgr->GetGameObjectData(spawnId))
{
handler->SendErrorMessage("Gameobject spawn {} is already loaded.", uint32(spawnId));
return false;
}
GameObjectData const* data = sObjectMgr->LoadGameObjectDataFromDB(spawnId);
if (!data)
{
handler->SendErrorMessage("Gameobject spawn {} not found in the database.", uint32(spawnId));
return false;
}
if (sPoolMgr->IsPartOfAPool<GameObject>(spawnId))
{
handler->SendErrorMessage("Gameobject spawn {} is part of a pool and cannot be manually loaded.", uint32(spawnId));
return false;
}
QueryResult eventResult = WorldDatabase.Query("SELECT guid FROM game_event_gameobject WHERE guid = {}", uint32(spawnId));
if (eventResult)
{
handler->SendErrorMessage("Gameobject spawn {} is managed by the game event system and cannot be manually loaded.", uint32(spawnId));
return false;
}
Map* map = sMapMgr->FindBaseNonInstanceMap(data->mapid);
if (!map)
{
handler->SendErrorMessage("Gameobject spawn {} is on a non-continent map (ID: {}). Only continent maps are supported.", uint32(spawnId), data->mapid);
return false;
}
GameObjectTemplate const* objectInfo = sObjectMgr->GetGameObjectTemplate(data->id);
if (!objectInfo)
{
handler->SendErrorMessage("Gameobject template not found for entry {}.", data->id);
return false;
}
GameObject* object = sObjectMgr->IsGameObjectStaticTransport(objectInfo->entry) ? new StaticTransport() : new GameObject();
if (!object->LoadGameObjectFromDB(spawnId, map, true))
{
delete object;
handler->SendErrorMessage("Failed to load gameobject spawn {}.", uint32(spawnId));
return false;
}
sObjectMgr->AddGameobjectToGrid(spawnId, data);
handler->PSendSysMessage("Gameobject spawn {} loaded successfully.", uint32(spawnId));
return true;
}
// add go, temp only
static bool HandleGameObjectAddTempCommand(ChatHandler* handler, GameObjectEntry objectId, Optional<uint64> spawntime)
{

View File

@@ -21,9 +21,11 @@
#include "CreatureGroups.h"
#include "GameTime.h"
#include "Language.h"
#include "MapMgr.h"
#include "ObjectMgr.h"
#include "Pet.h"
#include "Player.h"
#include "PoolMgr.h"
#include "TargetedMovementGenerator.h" // for HandleNpcUnFollowCommand
#include "Transport.h"
#include <string>
@@ -192,6 +194,7 @@ public:
{ "add", npcAddCommandTable },
{ "delete", npcDeleteCommandTable },
{ "follow", npcFollowCommandTable },
{ "load", HandleNpcLoadCommand, SEC_ADMINISTRATOR, Console::Yes },
{ "set", npcSetCommandTable }
};
static ChatCommandTable commandTable =
@@ -260,6 +263,57 @@ public:
return true;
}
static bool HandleNpcLoadCommand(ChatHandler* handler, CreatureSpawnId spawnId)
{
if (!spawnId)
return false;
if (sObjectMgr->GetCreatureData(spawnId))
{
handler->SendErrorMessage("Creature spawn {} is already loaded.", uint32(spawnId));
return false;
}
CreatureData const* data = sObjectMgr->LoadCreatureDataFromDB(spawnId);
if (!data)
{
handler->SendErrorMessage("Creature spawn {} not found in the database.", uint32(spawnId));
return false;
}
if (sPoolMgr->IsPartOfAPool<Creature>(spawnId))
{
handler->SendErrorMessage("Creature spawn {} is part of a pool and cannot be manually loaded.", uint32(spawnId));
return false;
}
QueryResult eventResult = WorldDatabase.Query("SELECT guid FROM game_event_creature WHERE guid = {}", uint32(spawnId));
if (eventResult)
{
handler->SendErrorMessage("Creature spawn {} is managed by the game event system and cannot be manually loaded.", uint32(spawnId));
return false;
}
Map* map = sMapMgr->FindBaseNonInstanceMap(data->mapid);
if (!map)
{
handler->SendErrorMessage("Creature spawn {} is on a non-continent map (ID: {}). Only continent maps are supported.", uint32(spawnId), data->mapid);
return false;
}
Creature* creature = new Creature();
if (!creature->LoadCreatureFromDB(spawnId, map, true, true))
{
delete creature;
handler->SendErrorMessage("Failed to load creature spawn {}.", uint32(spawnId));
return false;
}
sObjectMgr->AddCreatureToGrid(spawnId, data);
handler->PSendSysMessage("Creature spawn {} loaded successfully.", uint32(spawnId));
return true;
}
//add item in vendorlist
static bool HandleNpcAddVendorItemCommand(ChatHandler* handler, ItemTemplate const* item, Optional<uint32> mc, Optional<uint32> it, Optional<uint32> ec, Optional<bool> addMulti)
{