Core/Objects: Move personal summon handling from TemporarySummon/GameObject to WorldObject and check it using dedicated guid field

This commit is contained in:
Matan Shukry
2021-03-28 20:22:05 +02:00
committed by Shauren
parent 7885bdf8af
commit 1082a6645e
10 changed files with 30 additions and 56 deletions
+3 -12
View File
@@ -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
+10 -16
View File
@@ -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)
+12 -4
View File
@@ -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;
+1 -1
View File
@@ -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);
+1 -1
View File
@@ -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);