Core/Objects: Move personal summon handling from TemporarySummon/GameObject to WorldObject and check it using dedicated guid field
This commit is contained in:
@@ -454,19 +454,10 @@ void ThreatManager::doAddThreat(Unit* victim, float threat)
|
||||
Unit* redirectTarget = victim->GetRedirectThreatTarget();
|
||||
|
||||
// If victim is personnal spawn, redirect all aggro to summoner
|
||||
if (TempSummon* tempSummonVictim = victim->ToTempSummon())
|
||||
if (victim->IsPrivateObject() && GetOwner()->IsPrivateObject() && GetOwner()->CanSeeOrDetect(victim))
|
||||
{
|
||||
if (tempSummonVictim->IsVisibleBySummonerOnly())
|
||||
{
|
||||
// Personnal Spawns from same summoner can aggro each other
|
||||
if (!GetOwner()->ToTempSummon() ||
|
||||
!GetOwner()->ToTempSummon()->IsVisibleBySummonerOnly() ||
|
||||
tempSummonVictim->GetSummonerGUID() != GetOwner()->ToTempSummon()->GetSummonerGUID())
|
||||
{
|
||||
redirectThreadPct = 100;
|
||||
redirectTarget = tempSummonVictim->GetSummoner();
|
||||
}
|
||||
}
|
||||
redirectThreadPct = 100;
|
||||
redirectTarget = ObjectAccessor::GetUnit(*GetOwner(), victim->GetPrivateObjectOwner());
|
||||
}
|
||||
|
||||
// must check > 0.0f, otherwise dead loop
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
TempSummon::TempSummon(SummonPropertiesEntry const* properties, Unit* owner, bool isWorldObject) :
|
||||
Creature(isWorldObject), m_Properties(properties), m_type(TEMPSUMMON_MANUAL_DESPAWN),
|
||||
m_timer(0), m_lifetime(0), m_visibleBySummonerOnly(false)
|
||||
m_timer(0), m_lifetime(0)
|
||||
{
|
||||
if (owner)
|
||||
m_summonerGUID = owner->GetGUID();
|
||||
@@ -44,15 +44,6 @@ Creature* TempSummon::GetSummonerCreatureBase() const
|
||||
return !m_summonerGUID.IsEmpty() ? ObjectAccessor::GetCreature(*this, m_summonerGUID) : nullptr;
|
||||
}
|
||||
|
||||
bool TempSummon::IsPersonalSummonOfAnotherPlayer(Creature const* summon, ObjectGuid playerToCheck)
|
||||
{
|
||||
if (TempSummon const* tempSummon = summon->ToTempSummon())
|
||||
if (tempSummon->IsVisibleBySummonerOnly() && playerToCheck != tempSummon->GetSummonerGUID())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void TempSummon::Update(uint32 diff)
|
||||
{
|
||||
Creature::Update(diff);
|
||||
|
||||
@@ -59,17 +59,12 @@ class TC_GAME_API TempSummon : public Creature
|
||||
TempSummonType const& GetSummonType() { return m_type; }
|
||||
uint32 GetTimer() const { return m_timer; }
|
||||
|
||||
void SetVisibleBySummonerOnly(bool visibleBySummonerOnly) { m_visibleBySummonerOnly = visibleBySummonerOnly; }
|
||||
bool IsVisibleBySummonerOnly() const { return m_visibleBySummonerOnly; }
|
||||
static bool IsPersonalSummonOfAnotherPlayer(Creature const* summon, ObjectGuid playerToCheck);
|
||||
|
||||
SummonPropertiesEntry const* const m_Properties;
|
||||
private:
|
||||
TempSummonType m_type;
|
||||
uint32 m_timer;
|
||||
uint32 m_lifetime;
|
||||
ObjectGuid m_summonerGUID;
|
||||
bool m_visibleBySummonerOnly;
|
||||
};
|
||||
|
||||
class TC_GAME_API Minion : public TempSummon
|
||||
|
||||
@@ -107,7 +107,7 @@ QuaternionData QuaternionData::fromEulerAnglesZYX(float Z, float Y, float X)
|
||||
}
|
||||
|
||||
GameObject::GameObject() : WorldObject(false), MapObject(),
|
||||
m_model(nullptr), m_goValue(), m_AI(nullptr), m_respawnCompatibilityMode(false), _animKitId(0), _worldEffectID(0), m_visibleByUnitOnly()
|
||||
m_model(nullptr), m_goValue(), m_AI(nullptr), m_respawnCompatibilityMode(false), _animKitId(0), _worldEffectID(0)
|
||||
{
|
||||
m_objectType |= TYPEMASK_GAMEOBJECT;
|
||||
m_objectTypeId = TYPEID_GAMEOBJECT;
|
||||
|
||||
@@ -319,10 +319,6 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject>
|
||||
void AIM_Destroy();
|
||||
bool AIM_Initialize();
|
||||
|
||||
void SetVisibleByUnitOnly(ObjectGuid unit) { m_visibleByUnitOnly = unit; }
|
||||
bool IsVisibleByUnitOnly() const { return !m_visibleByUnitOnly.IsEmpty(); }
|
||||
ObjectGuid GetVisibleByUnitOnly() const { return m_visibleByUnitOnly; }
|
||||
|
||||
UF::UpdateField<UF::GameObjectData, 0, TYPEID_GAMEOBJECT> m_gameObjectData;
|
||||
|
||||
protected:
|
||||
@@ -380,6 +376,5 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject>
|
||||
bool m_respawnCompatibilityMode;
|
||||
uint16 _animKitId;
|
||||
uint32 _worldEffectID;
|
||||
ObjectGuid m_visibleByUnitOnly;
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -1416,6 +1416,9 @@ bool WorldObject::CanSeeOrDetect(WorldObject const* obj, bool ignoreStealth, boo
|
||||
if (this == obj)
|
||||
return true;
|
||||
|
||||
if (!obj->GetPrivateObjectOwner().IsEmpty())
|
||||
return GetGUID() == obj->GetPrivateObjectOwner() || GetPrivateObjectOwner() == obj->GetPrivateObjectOwner();
|
||||
|
||||
if (obj->IsNeverVisibleFor(this) || CanNeverSee(obj))
|
||||
return false;
|
||||
|
||||
@@ -1451,18 +1454,8 @@ bool WorldObject::CanSeeOrDetect(WorldObject const* obj, bool ignoreStealth, boo
|
||||
|
||||
WorldObject const* viewpoint = this;
|
||||
if (Player const* player = ToPlayer())
|
||||
{
|
||||
viewpoint = player->GetViewpoint();
|
||||
|
||||
if (Creature const* creature = obj->ToCreature())
|
||||
if (TempSummon::IsPersonalSummonOfAnotherPlayer(creature, GetGUID()))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (GameObject const* go = obj->ToGameObject())
|
||||
if (go->IsVisibleByUnitOnly() && GetGUID() != go->GetVisibleByUnitOnly())
|
||||
return false;
|
||||
|
||||
if (!viewpoint)
|
||||
viewpoint = this;
|
||||
|
||||
@@ -1687,7 +1680,7 @@ void WorldObject::AddObjectToRemoveList()
|
||||
map->AddObjectToRemoveList(this);
|
||||
}
|
||||
|
||||
TempSummon* Map::SummonCreature(uint32 entry, Position const& pos, SummonPropertiesEntry const* properties /*= nullptr*/, uint32 duration /*= 0*/, Unit* summoner /*= nullptr*/, uint32 spellId /*= 0*/, uint32 vehId /*= 0*/, bool visibleBySummonerOnly /*= false*/)
|
||||
TempSummon* Map::SummonCreature(uint32 entry, Position const& pos, SummonPropertiesEntry const* properties /*= nullptr*/, uint32 duration /*= 0*/, Unit* summoner /*= nullptr*/, uint32 spellId /*= 0*/, uint32 vehId /*= 0*/, bool personalSpawn /*= false*/)
|
||||
{
|
||||
uint32 mask = UNIT_MASK_SUMMON;
|
||||
if (properties)
|
||||
@@ -1773,7 +1766,8 @@ TempSummon* Map::SummonCreature(uint32 entry, Position const& pos, SummonPropert
|
||||
|
||||
summon->InitStats(duration);
|
||||
|
||||
summon->SetVisibleBySummonerOnly(visibleBySummonerOnly);
|
||||
if (personalSpawn && summoner)
|
||||
summon->SetPrivateObjectOwner(summoner->IsPrivateObject() ? summoner->GetPrivateObjectOwner() : summoner->GetGUID());
|
||||
|
||||
AddToMap(summon->ToCreature());
|
||||
summon->InitSummon();
|
||||
@@ -1829,11 +1823,11 @@ Scenario* WorldObject::GetScenario() const
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
TempSummon* WorldObject::SummonCreature(uint32 entry, Position const& pos, TempSummonType despawnType /*= TEMPSUMMON_MANUAL_DESPAWN*/, uint32 despawnTime /*= 0*/, uint32 vehId /*= 0*/, bool visibleBySummonerOnly /*= false*/)
|
||||
TempSummon* WorldObject::SummonCreature(uint32 entry, Position const& pos, TempSummonType despawnType /*= TEMPSUMMON_MANUAL_DESPAWN*/, uint32 despawnTime /*= 0*/, uint32 vehId /*= 0*/, bool personalSpawn /* = false */)
|
||||
{
|
||||
if (Map* map = FindMap())
|
||||
{
|
||||
if (TempSummon* summon = map->SummonCreature(entry, pos, nullptr, despawnTime, ToUnit(), 0, vehId, visibleBySummonerOnly))
|
||||
if (TempSummon* summon = map->SummonCreature(entry, pos, nullptr, despawnTime, ToUnit(), 0, vehId, personalSpawn))
|
||||
{
|
||||
summon->SetTempSummonType(despawnType);
|
||||
return summon;
|
||||
@@ -1843,13 +1837,13 @@ TempSummon* WorldObject::SummonCreature(uint32 entry, Position const& pos, TempS
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
TempSummon* WorldObject::SummonCreature(uint32 id, float x, float y, float z, float o /*= 0*/, TempSummonType despawnType /*= TEMPSUMMON_MANUAL_DESPAWN*/, uint32 despawnTime /*= 0*/, bool visibleBySummonerOnly /*= false*/)
|
||||
TempSummon* WorldObject::SummonCreature(uint32 id, float x, float y, float z, float o /*= 0*/, TempSummonType despawnType /*= TEMPSUMMON_MANUAL_DESPAWN*/, uint32 despawnTime /*= 0*/, bool personalSpawn /* = false */)
|
||||
{
|
||||
if (!x && !y && !z)
|
||||
GetClosePoint(x, y, z, GetCombatReach());
|
||||
if (!o)
|
||||
o = GetOrientation();
|
||||
return SummonCreature(id, { x,y,z,o }, despawnType, despawnTime, 0, visibleBySummonerOnly);
|
||||
return SummonCreature(id, { x,y,z,o }, despawnType, despawnTime, 0, personalSpawn);
|
||||
}
|
||||
|
||||
GameObject* WorldObject::SummonGameObject(uint32 entry, Position const& pos, QuaternionData const& rot, uint32 respawnTime)
|
||||
|
||||
@@ -366,7 +366,7 @@ class GridObject
|
||||
GridReference<T> _gridRef;
|
||||
};
|
||||
|
||||
template <class T_VALUES, class T_FLAGS, class FLAG_TYPE, uint8 ARRAY_SIZE>
|
||||
template <class T_VALUES, class T_FLAGS, class FLAG_TYPE, size_t ARRAY_SIZE>
|
||||
class FlaggedValuesArray32
|
||||
{
|
||||
public:
|
||||
@@ -518,9 +518,9 @@ class TC_GAME_API WorldObject : public Object, public WorldLocation
|
||||
|
||||
Scenario* GetScenario() const;
|
||||
|
||||
TempSummon* SummonCreature(uint32 entry, Position const& pos, TempSummonType despawnType = TEMPSUMMON_MANUAL_DESPAWN, uint32 despawnTime = 0, uint32 vehId = 0, bool visibleBySummonerOnly = false);
|
||||
TempSummon* SummonCreature(uint32 entry, Position const& pos, TempSummonType despawnType, Milliseconds const& despawnTime, uint32 vehId = 0, bool visibleBySummonerOnly = false) { return SummonCreature(entry, pos, despawnType, uint32(despawnTime.count()), vehId, visibleBySummonerOnly); }
|
||||
TempSummon* SummonCreature(uint32 entry, float x, float y, float z, float o = 0, TempSummonType despawnType = TEMPSUMMON_MANUAL_DESPAWN, uint32 despawnTime = 0, bool visibleBySummonerOnly = false);
|
||||
TempSummon* SummonCreature(uint32 entry, Position const& pos, TempSummonType despawnType = TEMPSUMMON_MANUAL_DESPAWN, uint32 despawnTime = 0, uint32 vehId = 0, bool personalSpawn = false);
|
||||
TempSummon* SummonCreature(uint32 entry, Position const& pos, TempSummonType despawnType, Milliseconds const& despawnTime, uint32 vehId = 0, bool personalSpawn = false) { return SummonCreature(entry, pos, despawnType, uint32(despawnTime.count()), vehId, personalSpawn); }
|
||||
TempSummon* SummonCreature(uint32 entry, float x, float y, float z, float o = 0, TempSummonType despawnType = TEMPSUMMON_MANUAL_DESPAWN, uint32 despawnTime = 0, bool personalSpawn = false);
|
||||
GameObject* SummonGameObject(uint32 entry, Position const& pos, QuaternionData const& rot, uint32 respawnTime /* s */);
|
||||
GameObject* SummonGameObject(uint32 entry, float x, float y, float z, float ang, QuaternionData const& rot, uint32 respawnTime /* s */);
|
||||
Creature* SummonTrigger(float x, float y, float z, float ang, uint32 dur, CreatureAI* (*GetAI)(Creature*) = nullptr);
|
||||
@@ -595,6 +595,11 @@ class TC_GAME_API WorldObject : public Object, public WorldLocation
|
||||
virtual uint16 GetMovementAnimKitId() const { return 0; }
|
||||
virtual uint16 GetMeleeAnimKitId() const { return 0; }
|
||||
|
||||
// Watcher
|
||||
bool IsPrivateObject() const { return !_privateObjectOwner.IsEmpty(); }
|
||||
ObjectGuid GetPrivateObjectOwner() const { return _privateObjectOwner; }
|
||||
void SetPrivateObjectOwner(ObjectGuid const& owner) { _privateObjectOwner = owner; }
|
||||
|
||||
protected:
|
||||
std::string m_name;
|
||||
bool m_isActive;
|
||||
@@ -631,6 +636,9 @@ class TC_GAME_API WorldObject : public Object, public WorldLocation
|
||||
int32 _dbPhase;
|
||||
|
||||
uint16 m_notifyflags;
|
||||
|
||||
ObjectGuid _privateObjectOwner;
|
||||
|
||||
virtual bool _IsWithinDist(WorldObject const* obj, float dist2compare, bool is3D, bool incOwnRadius = true, bool incTargetRadius = true) const;
|
||||
|
||||
bool CanNeverSee(WorldObject const* obj) const;
|
||||
|
||||
@@ -1313,7 +1313,7 @@ namespace Trinity
|
||||
|
||||
bool operator()(Creature* u)
|
||||
{
|
||||
if (u->getDeathState() != DEAD && u->GetEntry() == i_entry && u->IsAlive() == i_alive && i_obj.IsWithinDistInMap(u, i_range) && !TempSummon::IsPersonalSummonOfAnotherPlayer(u, i_obj.GetGUID()))
|
||||
if (u->getDeathState() != DEAD && u->GetEntry() == i_entry && u->IsAlive() == i_alive && i_obj.IsWithinDistInMap(u, i_range) && u->CanSeeOrDetect(&i_obj))
|
||||
{
|
||||
i_range = i_obj.GetDistance(u); // use found unit range as new range limit for next check
|
||||
return true;
|
||||
|
||||
@@ -512,7 +512,7 @@ class TC_GAME_API Map : public GridRefManager<NGridType>
|
||||
|
||||
void UpdateIteratorBack(Player* player);
|
||||
|
||||
TempSummon* SummonCreature(uint32 entry, Position const& pos, SummonPropertiesEntry const* properties = nullptr, uint32 duration = 0, Unit* summoner = nullptr, uint32 spellId = 0, uint32 vehId = 0, bool visibleOnlyBySummoner = false);
|
||||
TempSummon* SummonCreature(uint32 entry, Position const& pos, SummonPropertiesEntry const* properties = nullptr, uint32 duration = 0, Unit* summoner = nullptr, uint32 spellId = 0, uint32 vehId = 0, bool personalSpawn = false);
|
||||
void SummonCreatureGroup(uint8 group, std::list<TempSummon*>* list = nullptr);
|
||||
AreaTrigger* GetAreaTrigger(ObjectGuid const& guid);
|
||||
Conversation* GetConversation(ObjectGuid const& guid);
|
||||
|
||||
@@ -5398,7 +5398,7 @@ void Spell::EffectSummonPersonalGameObject(SpellEffIndex effIndex)
|
||||
|
||||
go->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
|
||||
go->SetSpellId(m_spellInfo->Id);
|
||||
go->SetVisibleByUnitOnly(m_caster->GetGUID());
|
||||
go->SetPrivateObjectOwner(m_caster->GetGUID());
|
||||
|
||||
ExecuteLogEffectSummonObject(effIndex, go);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user