diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/AI/SmartScripts/SmartScript.cpp | 5 | ||||
-rw-r--r-- | src/server/game/Entities/Creature/TemporarySummon.cpp | 33 | ||||
-rw-r--r-- | src/server/game/Entities/Object/Object.cpp | 17 | ||||
-rw-r--r-- | src/server/game/Entities/Object/Object.h | 2 | ||||
-rw-r--r-- | src/server/scripts/Commands/cs_debug.cpp | 2 |
5 files changed, 36 insertions, 23 deletions
diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index 69090caae06..4c882799190 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -2531,12 +2531,11 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u { WorldObject* baseObject = GetBaseObject(); - auto doCreatePersonalClone = [&](Position const& position, Unit* owner) + auto doCreatePersonalClone = [&](Position const& position, Player* privateObjectOwner) { - ObjectGuid privateObjectOwner = owner->GetGUID(); if (Creature* summon = GetBaseObject()->SummonPersonalClone(position, TempSummonType(e.action.becomePersonalClone.type), Milliseconds(e.action.becomePersonalClone.duration), 0, 0, privateObjectOwner)) if (IsSmart(summon)) - ENSURE_AI(SmartAI, summon->AI())->SetTimedActionList(e, e.entryOrGuid, owner, e.event_id + 1); + ENSURE_AI(SmartAI, summon->AI())->SetTimedActionList(e, e.entryOrGuid, privateObjectOwner, e.event_id + 1); }; diff --git a/src/server/game/Entities/Creature/TemporarySummon.cpp b/src/server/game/Entities/Creature/TemporarySummon.cpp index 30d1bcb5ac0..21e613a2471 100644 --- a/src/server/game/Entities/Creature/TemporarySummon.cpp +++ b/src/server/game/Entities/Creature/TemporarySummon.cpp @@ -251,10 +251,13 @@ void TempSummon::UpdateObjectVisibilityOnCreate() boost::container::small_vector<WorldObject*, 2> objectsToUpdate; objectsToUpdate.push_back(this); - SmoothPhasing const* smoothPhasing = GetSmoothPhasing(); - if (WorldObject* original = GetSummoner()) - if (smoothPhasing && smoothPhasing->IsReplacing(original->GetGUID())) - objectsToUpdate.push_back(original); + if (SmoothPhasing const* smoothPhasing = GetSmoothPhasing()) + { + SmoothPhasingInfo const* infoForSeer = smoothPhasing->GetInfoForSeer(GetDemonCreatorGUID()); + if (infoForSeer && infoForSeer->ReplaceObject && smoothPhasing->IsReplacing(*infoForSeer->ReplaceObject)) + if (WorldObject* original = ObjectAccessor::GetWorldObject(*this, *infoForSeer->ReplaceObject)) + objectsToUpdate.push_back(original); + } Trinity::VisibleChangesNotifier notifier({ objectsToUpdate.data(), objectsToUpdate.data() + objectsToUpdate.size() }); Cell::VisitWorldObjects(this, notifier, GetVisibilityRange()); @@ -265,21 +268,27 @@ void TempSummon::UpdateObjectVisibilityOnDestroy() boost::container::small_vector<WorldObject*, 2> objectsToUpdate; objectsToUpdate.push_back(this); - WorldObject* original = GetSummoner(); - SmoothPhasing const* smoothPhasing = GetSmoothPhasing(); - if (original && smoothPhasing && smoothPhasing->IsReplacing(original->GetGUID())) + WorldObject* original = nullptr; + if (SmoothPhasing const* smoothPhasing = GetSmoothPhasing()) { - objectsToUpdate.push_back(original); + SmoothPhasingInfo const* infoForSeer = smoothPhasing->GetInfoForSeer(GetDemonCreatorGUID()); + if (infoForSeer && infoForSeer->ReplaceObject && smoothPhasing->IsReplacing(*infoForSeer->ReplaceObject)) + original = ObjectAccessor::GetWorldObject(*this, *infoForSeer->ReplaceObject); - // disable replacement without removing - it is still needed for next step (visibility update) - if (SmoothPhasing* originalSmoothPhasing = original->GetSmoothPhasing()) - originalSmoothPhasing->DisableReplacementForSeer(GetDemonCreatorGUID()); + if (original) + { + objectsToUpdate.push_back(original); + + // disable replacement without removing - it is still needed for next step (visibility update) + if (SmoothPhasing* originalSmoothPhasing = original->GetSmoothPhasing()) + originalSmoothPhasing->DisableReplacementForSeer(GetDemonCreatorGUID()); + } } Trinity::VisibleChangesNotifier notifier({ objectsToUpdate.data(), objectsToUpdate.data() + objectsToUpdate.size() }); Cell::VisitWorldObjects(this, notifier, GetVisibilityRange()); - if (original && smoothPhasing && smoothPhasing->IsReplacing(original->GetGUID())) + if (original) // original is only != nullptr when it was replaced if (SmoothPhasing* originalSmoothPhasing = original->GetSmoothPhasing()) originalSmoothPhasing->ClearViewerDependentInfo(GetDemonCreatorGUID()); } diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index 07b73e66697..5b167621aec 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -1838,11 +1838,14 @@ TempSummon* Map::SummonCreature(uint32 entry, Position const& pos, SummonPropert { if (summoner && smoothPhasingInfo->ReplaceObject) { - SmoothPhasingInfo originalSmoothPhasingInfo = *smoothPhasingInfo; - originalSmoothPhasingInfo.ReplaceObject = summon->GetGUID(); - summoner->GetOrCreateSmoothPhasing()->SetViewerDependentInfo(privateObjectOwner, originalSmoothPhasingInfo); + if (WorldObject* replacedObject = ObjectAccessor::GetWorldObject(*summoner, *smoothPhasingInfo->ReplaceObject)) + { + SmoothPhasingInfo originalSmoothPhasingInfo = *smoothPhasingInfo; + originalSmoothPhasingInfo.ReplaceObject = summon->GetGUID(); + replacedObject->GetOrCreateSmoothPhasing()->SetViewerDependentInfo(privateObjectOwner, originalSmoothPhasingInfo); - summon->SetDemonCreatorGUID(privateObjectOwner); + summon->SetDemonCreatorGUID(privateObjectOwner); + } } summon->GetOrCreateSmoothPhasing()->SetSingleInfo(*smoothPhasingInfo); @@ -1934,12 +1937,14 @@ TempSummon* WorldObject::SummonCreature(uint32 id, float x, float y, float z, fl return SummonCreature(id, { x,y,z,o }, despawnType, despawnTime, 0, 0, privateObjectOwner); } -TempSummon* WorldObject::SummonPersonalClone(Position const& pos, TempSummonType despawnType /*= TEMPSUMMON_MANUAL_DESPAWN*/, Milliseconds despawnTime /*= 0s*/, uint32 vehId /*= 0*/, uint32 spellId /*= 0*/, ObjectGuid privateObjectOwner /*= ObjectGuid::Empty*/) +TempSummon* WorldObject::SummonPersonalClone(Position const& pos, TempSummonType despawnType /*= TEMPSUMMON_MANUAL_DESPAWN*/, Milliseconds despawnTime /*= 0s*/, uint32 vehId /*= 0*/, uint32 spellId /*= 0*/, Player* privateObjectOwner /*= nullptr*/) { + ASSERT(privateObjectOwner); + if (Map* map = FindMap()) { SmoothPhasingInfo smoothPhasingInfo{GetGUID(), true, true}; - if (TempSummon* summon = map->SummonCreature(GetEntry(), pos, nullptr, despawnTime.count(), this, spellId, vehId, privateObjectOwner, &smoothPhasingInfo)) + if (TempSummon* summon = map->SummonCreature(GetEntry(), pos, nullptr, despawnTime.count(), privateObjectOwner, spellId, vehId, privateObjectOwner->GetGUID(), &smoothPhasingInfo)) { summon->SetTempSummonType(despawnType); return summon; diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index 0cf09067b07..68b2d5c7c0e 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -575,7 +575,7 @@ class TC_GAME_API WorldObject : public Object, public WorldLocation TempSummon* SummonCreature(uint32 entry, Position const& pos, TempSummonType despawnType = TEMPSUMMON_MANUAL_DESPAWN, Milliseconds despawnTime = 0s, uint32 vehId = 0, uint32 spellId = 0, ObjectGuid privateObjectOwner = ObjectGuid::Empty); TempSummon* SummonCreature(uint32 entry, float x, float y, float z, float o = 0, TempSummonType despawnType = TEMPSUMMON_MANUAL_DESPAWN, Milliseconds despawnTime = 0s, ObjectGuid privateObjectOwner = ObjectGuid::Empty); - TempSummon* SummonPersonalClone(Position const& pos, TempSummonType despawnType = TEMPSUMMON_MANUAL_DESPAWN, Milliseconds despawnTime = 0s, uint32 vehId = 0, uint32 spellId = 0, ObjectGuid privateObjectOwner = ObjectGuid::Empty); + TempSummon* SummonPersonalClone(Position const& pos, TempSummonType despawnType = TEMPSUMMON_MANUAL_DESPAWN, Milliseconds despawnTime = 0s, uint32 vehId = 0, uint32 spellId = 0, Player* privateObjectOwner = nullptr); GameObject* SummonGameObject(uint32 entry, Position const& pos, QuaternionData const& rot, Seconds respawnTime, GOSummonType summonType = GO_SUMMON_TIMED_OR_CORPSE_DESPAWN); GameObject* SummonGameObject(uint32 entry, float x, float y, float z, float ang, QuaternionData const& rot, Seconds respawnTime, GOSummonType summonType = GO_SUMMON_TIMED_OR_CORPSE_DESPAWN); Creature* SummonTrigger(float x, float y, float z, float ang, Milliseconds despawnTime, CreatureAI* (*GetAI)(Creature*) = nullptr); diff --git a/src/server/scripts/Commands/cs_debug.cpp b/src/server/scripts/Commands/cs_debug.cpp index d1f81fac578..c562990dec6 100644 --- a/src/server/scripts/Commands/cs_debug.cpp +++ b/src/server/scripts/Commands/cs_debug.cpp @@ -1720,7 +1720,7 @@ public: return false; Player* player = handler->GetSession()->GetPlayer(); - selection->SummonPersonalClone(player->GetPosition(), TEMPSUMMON_MANUAL_DESPAWN, 0s, 0, 0, player->GetGUID()); + selection->SummonPersonalClone(player->GetPosition(), TEMPSUMMON_MANUAL_DESPAWN, 0s, 0, 0, player); return true; } |