Entities/Unit: Nuke Map::ForceRespawn from orbit, with the following implications:

- .npc respawn no longer causes stupid things to happen (Fixes #23014)
- ::DeleteFromDB methods on Creature and GameObject rewritten to be as sensible as such a colossally stupid method can ever be. They're static now.
- .npc delete and .gobj delete ported to new argument handling, and rewritten as per above. They can no longer crash the server when used in instances, too. Yay for that.
- Adjusted various dusty cobwebbed hacks around the core (why does waypoint visualization use permanent spawns *shudder*) to still work too.
This commit is contained in:
Treeston
2019-07-08 11:33:09 +02:00
parent ec1a77bca2
commit 84b7b2e08e
12 changed files with 158 additions and 204 deletions

View File

@@ -46,6 +46,7 @@ EndScriptData */
bool HandleNpcSpawnGroup(ChatHandler* handler, char const* args);
bool HandleNpcDespawnGroup(ChatHandler* handler, char const* args);
using namespace Trinity::ChatCommands;
class gobject_commandscript : public CommandScript
{
public:
@@ -344,49 +345,35 @@ public:
}
//delete object by selection or guid
static bool HandleGameObjectDeleteCommand(ChatHandler* handler, char const* args)
static bool HandleGameObjectDeleteCommand(ChatHandler* handler, Variant<Hyperlink<gameobject>, ObjectGuid::LowType> spawnId)
{
// number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r
char* id = handler->extractKeyFromLink((char*)args, "Hgameobject");
if (!id)
return false;
ObjectGuid::LowType guidLow = atoul(id);
if (!guidLow)
return false;
Player const* const player = handler->GetSession()->GetPlayer();
// force respawn to make sure we find something
player->GetMap()->ForceRespawn(SPAWN_TYPE_GAMEOBJECT, guidLow);
GameObject* object = handler->GetObjectFromPlayerMapByDbGuid(guidLow);
if (!object)
if (GameObject* object = handler->GetObjectFromPlayerMapByDbGuid(spawnId))
{
handler->PSendSysMessage(LANG_COMMAND_OBJNOTFOUND, guidLow);
Player const* const player = handler->GetSession()->GetPlayer();
if (ObjectGuid ownerGuid = object->GetOwnerGUID())
{
Unit* owner = ObjectAccessor::GetUnit(*player, ownerGuid);
if (!owner || !ownerGuid.IsPlayer())
{
handler->PSendSysMessage(LANG_COMMAND_DELOBJREFERCREATURE, ownerGuid.GetCounter(), spawnId);
handler->SetSentErrorMessage(true);
return false;
}
owner->RemoveGameObject(object, false);
}
}
if (GameObject::DeleteFromDB(spawnId))
{
handler->PSendSysMessage(LANG_COMMAND_DELOBJMESSAGE, spawnId);
return true;
}
else
{
handler->PSendSysMessage(LANG_COMMAND_OBJNOTFOUND, spawnId);
handler->SetSentErrorMessage(true);
return false;
}
ObjectGuid ownerGuid = object->GetOwnerGUID();
if (ownerGuid)
{
Unit* owner = ObjectAccessor::GetUnit(*player, ownerGuid);
if (!owner || !ownerGuid.IsPlayer())
{
handler->PSendSysMessage(LANG_COMMAND_DELOBJREFERCREATURE, ownerGuid.GetCounter(), guidLow);
handler->SetSentErrorMessage(true);
return false;
}
owner->RemoveGameObject(object, false);
}
object->SetRespawnTime(0); // not save respawn time
object->Delete();
object->DeleteFromDB();
handler->PSendSysMessage(LANG_COMMAND_DELOBJMESSAGE, object->GetSpawnId());
return true;
}
//turn selected object

View File

@@ -1911,7 +1911,7 @@ public:
uint32 const gridId = Trinity::ComputeGridCoord(player->GetPositionX(), player->GetPositionY()).GetId();
for (RespawnInfo* info : data)
if (info->gridId == gridId)
player->GetMap()->ForceRespawn(info->type, info->spawnId);
player->GetMap()->RemoveRespawnTime(info, true);
}
return true;

View File

@@ -125,6 +125,7 @@ bool HandleNpcDespawnGroup(ChatHandler* handler, char const* args)
return true;
}
using namespace Trinity::ChatCommands;
class npc_commandscript : public CommandScript
{
public:
@@ -415,48 +416,40 @@ public:
return true;
}
static bool HandleNpcDeleteCommand(ChatHandler* handler, char const* args)
static bool HandleNpcDeleteCommand(ChatHandler* handler, Optional<Variant<Hyperlink<creature>, ObjectGuid::LowType>> spawnIdArg)
{
Creature* creature = nullptr;
if (*args)
ObjectGuid::LowType spawnId;
if (spawnIdArg)
spawnId = *spawnIdArg;
else
{
// number or [name] Shift-click form |color|Hcreature:creature_guid|h[name]|h|r
char* cId = handler->extractKeyFromLink((char*)args, "Hcreature");
if (!cId)
Creature* creature = handler->getSelectedCreature();
if (!creature || creature->IsPet() || creature->IsTotem())
{
handler->SendSysMessage(LANG_SELECT_CREATURE);
handler->SetSentErrorMessage(true);
return false;
}
if (TempSummon* summon = creature->ToTempSummon())
{
summon->UnSummon();
handler->SendSysMessage(LANG_COMMAND_DELCREATMESSAGE);
return true;
}
spawnId = creature->GetSpawnId();
}
ObjectGuid::LowType lowguid = atoul(cId);
if (!lowguid)
return false;
// force respawn to make sure we find something
handler->GetSession()->GetPlayer()->GetMap()->ForceRespawn(SPAWN_TYPE_CREATURE, lowguid);
// then try to find it
creature = handler->GetCreatureFromPlayerMapByDbGuid(lowguid);
if (Creature::DeleteFromDB(spawnId))
{
handler->SendSysMessage(LANG_COMMAND_DELCREATMESSAGE);
return true;
}
else
creature = handler->getSelectedCreature();
if (!creature || creature->IsPet() || creature->IsTotem())
{
handler->SendSysMessage(LANG_SELECT_CREATURE);
handler->PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND, spawnId);
handler->SetSentErrorMessage(true);
return false;
}
if (TempSummon* summon = creature->ToTempSummon())
summon->UnSummon();
else
{
// Delete the creature
creature->CombatStop();
creature->DeleteFromDB();
creature->AddObjectToRemoveList();
}
handler->SendSysMessage(LANG_COMMAND_DELCREATMESSAGE);
return true;
}
//del item from vendor list

View File

@@ -632,21 +632,27 @@ public:
{
handler->PSendSysMessage("|cff00ff00DEBUG: wp modify del, PathID: |r|cff00ffff%u|r", pathid);
target->DeleteFromDB();
target->AddObjectToRemoveList();
if (Creature::DeleteFromDB(target->GetSpawnId()))
{
stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_WAYPOINT_DATA);
stmt->setUInt32(0, pathid);
stmt->setUInt32(1, point);
WorldDatabase.Execute(stmt);
stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_WAYPOINT_DATA);
stmt->setUInt32(0, pathid);
stmt->setUInt32(1, point);
WorldDatabase.Execute(stmt);
stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_WAYPOINT_DATA_POINT);
stmt->setUInt32(0, pathid);
stmt->setUInt32(1, point);
WorldDatabase.Execute(stmt);
stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_WAYPOINT_DATA_POINT);
stmt->setUInt32(0, pathid);
stmt->setUInt32(1, point);
WorldDatabase.Execute(stmt);
handler->PSendSysMessage(LANG_WAYPOINT_REMOVED);
return true;
handler->SendSysMessage(LANG_WAYPOINT_REMOVED);
return true;
}
else
{
handler->SendSysMessage(LANG_WAYPOINT_NOTREMOVED);
handler->SetSentErrorMessage(true);
return false;
}
} // del
if (show == "move")
@@ -658,8 +664,12 @@ public:
// What to do:
// Move the visual spawnpoint
// Respawn the owner of the waypoints
target->DeleteFromDB();
target->AddObjectToRemoveList();
if (!Creature::DeleteFromDB(target->GetSpawnId()))
{
handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT);
handler->SetSentErrorMessage(true);
return false;
}
// re-create
Creature* wpCreature = new Creature();
@@ -830,22 +840,10 @@ public:
{
Field* fields = result2->Fetch();
uint32 wpguid = fields[0].GetUInt32();
Creature* creature = handler->GetCreatureFromPlayerMapByDbGuid(wpguid);
if (!creature)
if (!Creature::DeleteFromDB(wpguid))
{
handler->PSendSysMessage(LANG_WAYPOINT_NOTREMOVED, wpguid);
hasError = true;
stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_CREATURE);
stmt->setUInt32(0, wpguid);
WorldDatabase.Execute(stmt);
}
else
{
creature->CombatStop();
creature->DeleteFromDB();
creature->AddObjectToRemoveList();
}
}
@@ -1028,21 +1026,10 @@ public:
Field* fields = result->Fetch();
ObjectGuid::LowType lowguid = fields[0].GetUInt32();
Creature* creature = handler->GetCreatureFromPlayerMapByDbGuid(lowguid);
if (!creature)
if (!Creature::DeleteFromDB(lowguid))
{
handler->PSendSysMessage(LANG_WAYPOINT_NOTREMOVED, lowguid);
hasError = true;
stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_CREATURE);
stmt->setUInt32(0, lowguid);
WorldDatabase.Execute(stmt);
}
else
{
creature->CombatStop();
creature->DeleteFromDB();
creature->AddObjectToRemoveList();
}
}
while (result->NextRow());