aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTreeston <treeston.mmoc@gmail.com>2017-08-02 22:05:40 +0200
committerTreeston <treeston.mmoc@gmail.com>2017-08-02 22:05:40 +0200
commit759357049cdbe9a2f97bbab6e61299cd65ba1bec (patch)
tree46e1547a07ca64206b9548ad0f22dcef3bef33c2 /src
parentc70b328eda8331a32b3fc7cc08af5e8b004d0705 (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.cpp9
-rw-r--r--src/server/scripts/Commands/cs_npc.cpp59
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;
}