From b4bf10ed22c3df23cdefcb7b44b6689e41391b95 Mon Sep 17 00:00:00 2001 From: hondacrx Date: Mon, 29 Mar 2021 17:11:46 -0400 Subject: [PATCH] Core/Objects: Move personal summon handling from TemporarySummon/GameObject to WorldObject and check it using dedicated guid field Port From (https://github.com/TrinityCore/TrinityCore/commit/1082a6645e96c611b3145b5d6208fc4db6e4b2d3) --- Source/Game/Combat/ThreatManager.cs | 16 ++-------- Source/Game/Entities/GameObject/GameObject.cs | 5 ---- Source/Game/Entities/Object/WorldObject.cs | 30 +++++++++---------- Source/Game/Entities/TemporarySummon.cs | 14 --------- Source/Game/Maps/GridNotifiers.cs | 2 +- Source/Game/Maps/Map.cs | 6 ++-- Source/Game/Spells/SpellEffects.cs | 2 +- 7 files changed, 23 insertions(+), 52 deletions(-) diff --git a/Source/Game/Combat/ThreatManager.cs b/Source/Game/Combat/ThreatManager.cs index d0dbdddbe..4d3366d99 100644 --- a/Source/Game/Combat/ThreatManager.cs +++ b/Source/Game/Combat/ThreatManager.cs @@ -88,20 +88,10 @@ namespace Game.Combat Unit redirectTarget = victim.GetRedirectThreatTarget(); // If victim is personnal spawn, redirect all aggro to summoner - TempSummon tempSummonVictim = victim.ToTempSummon(); - if (tempSummonVictim) + 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 = Global.ObjAccessor.GetUnit(GetOwner(), victim.GetPrivateObjectOwner()); } // must check > 0.0f, otherwise dead loop diff --git a/Source/Game/Entities/GameObject/GameObject.cs b/Source/Game/Entities/GameObject/GameObject.cs index c5754241c..44ae4b4f9 100644 --- a/Source/Game/Entities/GameObject/GameObject.cs +++ b/Source/Game/Entities/GameObject/GameObject.cs @@ -2824,10 +2824,6 @@ namespace Game.Entities // There's many places not ready for dynamic spawns. This allows them to live on for now. void SetRespawnCompatibilityMode(bool mode = true) { m_respawnCompatibilityMode = mode; } public bool GetRespawnCompatibilityMode() { return m_respawnCompatibilityMode; } - - public void SetVisibleByUnitOnly(ObjectGuid unit) { m_visibleByUnitOnly = unit; } - public bool IsVisibleByUnitOnly() { return !m_visibleByUnitOnly.IsEmpty(); } - public ObjectGuid GetVisibleByUnitOnly() { return m_visibleByUnitOnly; } #region Fields protected GameObjectFieldData m_gameObjectData; @@ -2863,7 +2859,6 @@ namespace Game.Entities bool m_respawnCompatibilityMode; ushort _animKitId; uint _worldEffectID; - ObjectGuid m_visibleByUnitOnly; GameObjectState m_prevGoState; // What state to set whenever resetting diff --git a/Source/Game/Entities/Object/WorldObject.cs b/Source/Game/Entities/Object/WorldObject.cs index ae2ffd3dc..7cc60526d 100644 --- a/Source/Game/Entities/Object/WorldObject.cs +++ b/Source/Game/Entities/Object/WorldObject.cs @@ -1105,6 +1105,9 @@ namespace Game.Entities if (this == obj) return true; + if (!obj.GetPrivateObjectOwner().IsEmpty()) + return GetGUID() == obj.GetPrivateObjectOwner() || GetPrivateObjectOwner() == obj.GetPrivateObjectOwner(); + if (obj.IsNeverVisibleFor(this) || CanNeverSee(obj)) return false; @@ -1145,20 +1148,8 @@ namespace Game.Entities WorldObject viewpoint = this; Player player = ToPlayer(); if (player != null) - { viewpoint = player.GetViewpoint(); - Creature creature = obj.ToCreature(); - if (creature) - if (TempSummon.IsPersonalSummonOfAnotherPlayer(creature, GetGUID())) - return false; - } - - GameObject go = obj.ToGameObject(); - if ( go != null) - if (go.IsVisibleByUnitOnly() && GetGUID() != go.GetVisibleByUnitOnly()) - return false; - if (viewpoint == null) viewpoint = this; @@ -1423,7 +1414,7 @@ namespace Game.Entities return null; } - public TempSummon SummonCreature(uint entry, float x, float y, float z, float o = 0, TempSummonType despawnType = TempSummonType.ManualDespawn, uint despawnTime = 0, bool visibleBySummonerOnly = false) + public TempSummon SummonCreature(uint entry, float x, float y, float z, float o = 0, TempSummonType despawnType = TempSummonType.ManualDespawn, uint despawnTime = 0, bool personalSpawn = false) { if (x == 0.0f && y == 0.0f && z == 0.0f) GetClosePoint(out x, out y, out z, GetCombatReach()); @@ -1431,15 +1422,15 @@ namespace Game.Entities if (o == 0.0f) o = GetOrientation(); - return SummonCreature(entry, new Position(x, y, z, o), despawnType, despawnTime, 0, visibleBySummonerOnly); + return SummonCreature(entry, new Position(x, y, z, o), despawnType, despawnTime, 0, personalSpawn); } - public TempSummon SummonCreature(uint entry, Position pos, TempSummonType despawnType = TempSummonType.ManualDespawn, uint despawnTime = 0, uint vehId = 0, bool visibleBySummonerOnly = false) + public TempSummon SummonCreature(uint entry, Position pos, TempSummonType despawnType = TempSummonType.ManualDespawn, uint despawnTime = 0, uint vehId = 0, bool personalSpawn = false) { Map map = GetMap(); if (map != null) { - TempSummon summon = map.SummonCreature(entry, pos, null, despawnTime, ToUnit(), 0, vehId, visibleBySummonerOnly); + TempSummon summon = map.SummonCreature(entry, pos, null, despawnTime, ToUnit(), 0, vehId, personalSpawn); if (summon != null) { summon.SetTempSummonType(despawnType); @@ -1697,6 +1688,11 @@ namespace Game.Entities public virtual ushort GetMovementAnimKitId() { return 0; } public virtual ushort GetMeleeAnimKitId() { return 0; } + // Watcher + public bool IsPrivateObject() { return !_privateObjectOwner.IsEmpty(); } + public ObjectGuid GetPrivateObjectOwner() { return _privateObjectOwner; } + public void SetPrivateObjectOwner(ObjectGuid owner) { _privateObjectOwner = owner; } + public virtual string GetName(Locale locale = Locale.enUS) { return _name; } public void SetName(string name) { _name = name; } @@ -2383,6 +2379,8 @@ namespace Game.Entities NotifyFlags m_notifyflags; + ObjectGuid _privateObjectOwner; + public FlaggedArray m_stealth = new(2); public FlaggedArray m_stealthDetect = new(2); diff --git a/Source/Game/Entities/TemporarySummon.cs b/Source/Game/Entities/TemporarySummon.cs index d20425979..fad09c2ef 100644 --- a/Source/Game/Entities/TemporarySummon.cs +++ b/Source/Game/Entities/TemporarySummon.cs @@ -42,16 +42,6 @@ namespace Game.Entities { return !m_summonerGUID.IsEmpty() ? ObjectAccessor.GetCreature(this, m_summonerGUID) : null; } - - public static bool IsPersonalSummonOfAnotherPlayer(Creature summon, ObjectGuid playerToCheck) - { - TempSummon tempSummon = summon.ToTempSummon(); - if (tempSummon != null) - if (tempSummon.IsVisibleBySummonerOnly() && playerToCheck != tempSummon.GetSummonerGUID()) - return true; - - return false; - } public override void Update(uint diff) { @@ -290,15 +280,11 @@ namespace Game.Entities public uint GetTimer() { return m_timer; } - public void SetVisibleBySummonerOnly(bool visibleBySummonerOnly) { m_visibleBySummonerOnly = visibleBySummonerOnly; } - public bool IsVisibleBySummonerOnly() { return m_visibleBySummonerOnly; } - public SummonPropertiesRecord m_Properties; TempSummonType m_type; uint m_timer; uint m_lifetime; ObjectGuid m_summonerGUID; - bool m_visibleBySummonerOnly; } public class Minion : TempSummon diff --git a/Source/Game/Maps/GridNotifiers.cs b/Source/Game/Maps/GridNotifiers.cs index f5ac31636..65da2928b 100644 --- a/Source/Game/Maps/GridNotifiers.cs +++ b/Source/Game/Maps/GridNotifiers.cs @@ -2300,7 +2300,7 @@ namespace Game.Maps public bool Invoke(Creature u) { - if (u.GetDeathState() != DeathState.Dead && u.GetEntry() == i_entry && u.IsAlive() == i_alive && i_obj.IsWithinDistInMap(u, i_range) && !TempSummon.IsPersonalSummonOfAnotherPlayer(u, i_obj.GetGUID())) + if (u.GetDeathState() != DeathState.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; diff --git a/Source/Game/Maps/Map.cs b/Source/Game/Maps/Map.cs index d4e2d54ce..78946e91a 100644 --- a/Source/Game/Maps/Map.cs +++ b/Source/Game/Maps/Map.cs @@ -3913,7 +3913,7 @@ namespace Game.Maps } } - public TempSummon SummonCreature(uint entry, Position pos, SummonPropertiesRecord properties = null, uint duration = 0, Unit summoner = null, uint spellId = 0, uint vehId = 0, bool visibleBySummonerOnly = false) + public TempSummon SummonCreature(uint entry, Position pos, SummonPropertiesRecord properties = null, uint duration = 0, Unit summoner = null, uint spellId = 0, uint vehId = 0, bool personalSpawn = false) { var mask = UnitTypeMask.Summon; if (properties != null) @@ -3995,7 +3995,9 @@ namespace Game.Maps summon.SetCreatedBySpell(spellId); summon.SetHomePosition(pos); summon.InitStats(duration); - summon.SetVisibleBySummonerOnly(visibleBySummonerOnly); + + if (personalSpawn && summoner != null) + summon.SetPrivateObjectOwner(summoner.IsPrivateObject() ? summoner.GetPrivateObjectOwner() : summoner.GetGUID()); AddToMap(summon.ToCreature()); summon.InitSummon(); diff --git a/Source/Game/Spells/SpellEffects.cs b/Source/Game/Spells/SpellEffects.cs index 4bcc51b26..750a267c1 100644 --- a/Source/Game/Spells/SpellEffects.cs +++ b/Source/Game/Spells/SpellEffects.cs @@ -5211,7 +5211,7 @@ namespace Game.Spells go.SetRespawnTime(duration > 0 ? duration / Time.InMilliseconds : 0); go.SetSpellId(m_spellInfo.Id); - go.SetVisibleByUnitOnly(m_caster.GetGUID()); + go.SetPrivateObjectOwner(m_caster.GetGUID()); ExecuteLogEffectSummonObject(effIndex, go);