diff options
author | Treeston <treeston.mmoc@gmail.com> | 2017-08-02 22:05:40 +0200 |
---|---|---|
committer | Treeston <treeston.mmoc@gmail.com> | 2017-08-02 22:05:40 +0200 |
commit | 759357049cdbe9a2f97bbab6e61299cd65ba1bec (patch) | |
tree | 46e1547a07ca64206b9548ad0f22dcef3bef33c2 /src | |
parent | c70b328eda8331a32b3fc7cc08af5e8b004d0705 (diff) |
Scripts/Commands: Fix some quirkiness and potential crashes with live DB modification commands (npc move and npc delete), which are horrible and should be deleted anyway.
Fixes #20104.
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Entities/Creature/Creature.cpp | 9 | ||||
-rw-r--r-- | src/server/scripts/Commands/cs_npc.cpp | 59 |
2 files changed, 38 insertions, 30 deletions
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index bcca31ed94e..e500d575ab0 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -1612,9 +1612,13 @@ void Creature::DeleteFromDB() return; } + // remove any scheduled respawns GetMap()->RemoveRespawnTime(SPAWN_TYPE_CREATURE, m_spawnId); + + // delete data from memory sObjectMgr->DeleteCreatureData(m_spawnId); + // delete data and all its associations from DB SQLTransaction trans = WorldDatabase.BeginTransaction(); PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_CREATURE); @@ -1639,6 +1643,11 @@ void Creature::DeleteFromDB() trans->Append(stmt); WorldDatabase.CommitTransaction(trans); + + // then delete any active instances of the creature + auto const& range = GetMap()->GetCreatureBySpawnIdStore().equal_range(m_spawnId); + for (auto it = range.first; it != range.second; ++it) + it->second->AddObjectToRemoveList(); } bool Creature::IsInvisibleDueToDespawn() const diff --git a/src/server/scripts/Commands/cs_npc.cpp b/src/server/scripts/Commands/cs_npc.cpp index cf63419303d..2f527cd5e99 100644 --- a/src/server/scripts/Commands/cs_npc.cpp +++ b/src/server/scripts/Commands/cs_npc.cpp @@ -876,7 +876,9 @@ public: if (!player) return false; - if (!creature) + if (creature) + lowguid = creature->GetSpawnId(); + else { // number or [name] Shift-click form |color|Hcreature:creature_guid|h[name]|h|r char* cId = handler->extractKeyFromLink((char*)args, "Hcreature"); @@ -884,48 +886,45 @@ public: return false; lowguid = atoul(cId); - - // Attempting creature load from DB data - CreatureData const* data = sObjectMgr->GetCreatureData(lowguid); - if (!data) - { - handler->PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND, lowguid); - handler->SetSentErrorMessage(true); - return false; - } - - if (player->GetMapId() != data->spawnPoint.GetMapId()) - { - handler->PSendSysMessage(LANG_COMMAND_CREATUREATSAMEMAP, lowguid); - handler->SetSentErrorMessage(true); - return false; - } } - else - lowguid = creature->GetSpawnId(); + // Attempting creature load from DB data + CreatureData const* data = sObjectMgr->GetCreatureData(lowguid); + if (!data) + { + handler->PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND, lowguid); + handler->SetSentErrorMessage(true); + return false; + } - if (creature) + if (player->GetMapId() != data->spawnPoint.GetMapId()) { - sObjectMgr->NewOrExistCreatureData(creature->GetSpawnId()).spawnPoint.Relocate(*player); - creature->UpdatePosition(*player); - creature->GetMotionMaster()->Initialize(); - if (creature->IsAlive()) // dead creature will reset movement generator at respawn - { - creature->setDeathState(JUST_DIED); - creature->Respawn(); - } + handler->PSendSysMessage(LANG_COMMAND_CREATUREATSAMEMAP, lowguid); + handler->SetSentErrorMessage(true); + return false; } - PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_CREATURE_POSITION); + // update position in memory + const_cast<CreatureData*>(data)->spawnPoint.Relocate(*player); + // update position in DB + PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_CREATURE_POSITION); stmt->setFloat(0, player->GetPositionX()); stmt->setFloat(1, player->GetPositionY()); stmt->setFloat(2, player->GetPositionZ()); stmt->setFloat(3, player->GetOrientation()); stmt->setUInt32(4, lowguid); - WorldDatabase.Execute(stmt); + // respawn selected creature at the new location + if (creature) + { + if (creature->IsAlive()) + creature->setDeathState(JUST_DIED); + creature->Respawn(true); + if (!creature->GetRespawnCompatibilityMode()) + creature->AddObjectToRemoveList(); + } + handler->PSendSysMessage(LANG_COMMAND_CREATUREMOVED); return true; } |