diff --git a/Source/Game/AI/CoreAI/CreatureAI.cs b/Source/Game/AI/CoreAI/CreatureAI.cs index b8946fbcd..fd3576b21 100644 --- a/Source/Game/AI/CoreAI/CreatureAI.cs +++ b/Source/Game/AI/CoreAI/CreatureAI.cs @@ -28,7 +28,7 @@ namespace Game.AI { public class CreatureAI : UnitAI { - bool _moveInLineOfSightLocked; + bool _moveInLOSLocked; List _boundary = new(); bool _negateBoundary; @@ -41,7 +41,7 @@ namespace Game.AI public CreatureAI(Creature _creature) : base(_creature) { me = _creature; - _moveInLineOfSightLocked = false; + _moveInLOSLocked = false; } public override void OnCharmed(bool isNew) @@ -101,12 +101,12 @@ namespace Game.AI public virtual void MoveInLineOfSight_Safe(Unit who) { - if (_moveInLineOfSightLocked) + if (_moveInLOSLocked) return; - _moveInLineOfSightLocked = true; + _moveInLOSLocked = true; MoveInLineOfSight(who); - _moveInLineOfSightLocked = false; + _moveInLOSLocked = false; } public virtual void MoveInLineOfSight(Unit who) @@ -366,7 +366,7 @@ namespace Game.AI // Called when the creature summon successfully other creature public virtual void JustSummoned(Creature summon) { } - public virtual void IsSummonedBy(Unit summoner) { } + public virtual void IsSummonedBy(WorldObject summoner) { } public virtual void SummonedCreatureDespawn(Creature summon) { } public virtual void SummonedCreatureDies(Creature summon, Unit killer) { } diff --git a/Source/Game/AI/CoreAI/GameObjectAI.cs b/Source/Game/AI/CoreAI/GameObjectAI.cs index 5affad8e2..26f36a327 100644 --- a/Source/Game/AI/CoreAI/GameObjectAI.cs +++ b/Source/Game/AI/CoreAI/GameObjectAI.cs @@ -101,5 +101,11 @@ namespace Game.AI // Called when spell hits a target public virtual void SpellHitTarget(Unit target, SpellInfo spellInfo) { } public virtual void SpellHitTargetGameObject(GameObject target, SpellInfo spellInfo) { } + + // Called when the gameobject summon successfully other creature + public virtual void JustSummoned(Creature summon) { } + + public virtual void SummonedCreatureDespawn(Creature summon) { } + public virtual void SummonedCreatureDies(Creature summon, Unit killer) { } } } diff --git a/Source/Game/AI/CoreAI/PassiveAI.cs b/Source/Game/AI/CoreAI/PassiveAI.cs index 367e3ca21..0d3aa2e65 100644 --- a/Source/Game/AI/CoreAI/PassiveAI.cs +++ b/Source/Game/AI/CoreAI/PassiveAI.cs @@ -119,7 +119,7 @@ namespace Game.AI { public TriggerAI(Creature c) : base(c) { } - public override void IsSummonedBy(Unit summoner) + public override void IsSummonedBy(WorldObject summoner) { if (me.m_spells[0] != 0) { diff --git a/Source/Game/AI/SmartScripts/SmartAI.cs b/Source/Game/AI/SmartScripts/SmartAI.cs index bbfc03dda..7d4de3549 100644 --- a/Source/Game/AI/SmartScripts/SmartAI.cs +++ b/Source/Game/AI/SmartScripts/SmartAI.cs @@ -689,9 +689,9 @@ namespace Game.AI GetScript().ProcessEventsFor(SmartEvents.ReceiveEmote, player, (uint)emoteId); } - public override void IsSummonedBy(Unit summoner) + public override void IsSummonedBy(WorldObject summoner) { - GetScript().ProcessEventsFor(SmartEvents.JustSummoned, summoner); + GetScript().ProcessEventsFor(SmartEvents.JustSummoned, summoner.ToUnit(), 0, 0, false, null, summoner.ToGameObject()); } public override void DamageDealt(Unit victim, ref uint damage, DamageEffectType damageType) diff --git a/Source/Game/AI/SmartScripts/SmartScript.cs b/Source/Game/AI/SmartScripts/SmartScript.cs index fa817c1d8..75c1d68ea 100644 --- a/Source/Game/AI/SmartScripts/SmartScript.cs +++ b/Source/Game/AI/SmartScripts/SmartScript.cs @@ -2944,7 +2944,7 @@ namespace Game.AI TempSummon tempSummon = _me.ToTempSummon(); if (tempSummon) { - Unit summoner = tempSummon.GetSummoner(); + WorldObject summoner = tempSummon.GetSummoner(); if (summoner) charmerOrOwnerGuid = summoner.GetGUID(); } @@ -2953,7 +2953,7 @@ namespace Game.AI if (charmerOrOwnerGuid.IsEmpty()) charmerOrOwnerGuid = _me.GetCreatorGUID(); - Unit owner = Global.ObjAccessor.GetUnit(_me, charmerOrOwnerGuid); + WorldObject owner = Global.ObjAccessor.GetWorldObject(_me, charmerOrOwnerGuid); if (owner != null) targets.Add(owner); } @@ -2967,7 +2967,7 @@ namespace Game.AI // Get owner of owner if (e.Target.owner.useCharmerOrOwner != 0 && !targets.Empty()) { - Unit owner = targets.First().ToUnit(); + WorldObject owner = targets.First(); targets.Clear(); Unit unitBase = Global.ObjAccessor.GetUnit(owner, owner.GetCharmerOrOwnerGUID()); diff --git a/Source/Game/Entities/Object/WorldObject.cs b/Source/Game/Entities/Object/WorldObject.cs index 8636394e0..547fdecf0 100644 --- a/Source/Game/Entities/Object/WorldObject.cs +++ b/Source/Game/Entities/Object/WorldObject.cs @@ -1415,7 +1415,7 @@ namespace Game.Entities Map map = GetMap(); if (map != null) { - TempSummon summon = map.SummonCreature(entry, pos, null, despawnTime, ToUnit(), spellId, vehId, privateObjectOwner); + TempSummon summon = map.SummonCreature(entry, pos, null, despawnTime, this, spellId, vehId, privateObjectOwner); if (summon != null) { summon.SetTempSummonType(despawnType); diff --git a/Source/Game/Entities/TemporarySummon.cs b/Source/Game/Entities/TemporarySummon.cs index 4cd3d8d65..5429ffde3 100644 --- a/Source/Game/Entities/TemporarySummon.cs +++ b/Source/Game/Entities/TemporarySummon.cs @@ -24,7 +24,7 @@ namespace Game.Entities { public class TempSummon : Creature { - public TempSummon(SummonPropertiesRecord properties, Unit owner, bool isWorldObject) : base(isWorldObject) + public TempSummon(SummonPropertiesRecord properties, WorldObject owner, bool isWorldObject) : base(isWorldObject) { m_Properties = properties; m_type = TempSummonType.ManualDespawn; @@ -33,15 +33,33 @@ namespace Game.Entities UnitTypeMask |= UnitTypeMask.Summon; } - public Unit GetSummoner() + public WorldObject GetSummoner() { - return !m_summonerGUID.IsEmpty() ? Global.ObjAccessor.GetUnit(this, m_summonerGUID) : null; + return !m_summonerGUID.IsEmpty() ? Global.ObjAccessor.GetWorldObject(this, m_summonerGUID) : null; } + public Unit GetSummonerUnit() + { + WorldObject summoner = GetSummoner(); + if (summoner != null) + return summoner.ToUnit(); + + return null; + } + public Creature GetSummonerCreatureBase() { return !m_summonerGUID.IsEmpty() ? ObjectAccessor.GetCreature(this, m_summonerGUID) : null; } + + public GameObject GetSummonerGameObject() + { + WorldObject summoner = GetSummoner(); + if (summoner != null) + return summoner.ToGameObject(); + + return null; + } public override void Update(uint diff) { @@ -167,8 +185,7 @@ namespace Game.Entities if (m_type == TempSummonType.ManualDespawn) m_type = (duration == 0) ? TempSummonType.DeadDespawn : TempSummonType.TimedDespawn; - Unit owner = GetSummoner(); - + Unit owner = GetSummonerUnit(); if (owner != null && IsTrigger() && m_spells[0] != 0) { SetLevel(owner.GetLevel()); @@ -206,11 +223,14 @@ namespace Game.Entities public virtual void InitSummon() { - Unit owner = GetSummoner(); + WorldObject owner = GetSummoner(); if (owner != null) { - if (owner.IsTypeId(TypeId.Unit) && owner.ToCreature().IsAIEnabled()) - owner.ToCreature().GetAI().JustSummoned(this); + if (owner.IsCreature()) + owner.ToCreature().GetAI()?.JustSummoned(this); + else if (owner.IsGameObject()) + owner.ToGameObject().GetAI()?.JustSummoned(this); + if (IsAIEnabled()) GetAI().IsSummonedBy(owner); } @@ -244,9 +264,14 @@ namespace Game.Entities return; } - Unit owner = GetSummoner(); - if (owner != null && owner.IsTypeId(TypeId.Unit) && owner.ToCreature().IsAIEnabled()) - owner.ToCreature().GetAI().SummonedCreatureDespawn(this); + WorldObject owner = GetSummoner(); + if (owner != null) + { + if (owner.IsCreature()) + owner.ToCreature().GetAI()?.SummonedCreatureDespawn(this); + else if (owner.IsGameObject()) + owner.ToGameObject().GetAI()?.SummonedCreatureDespawn(this); + } AddObjectToRemoveList(); } @@ -261,7 +286,7 @@ namespace Game.Entities int slot = m_Properties.Slot; if (slot > 0) { - Unit owner = GetSummoner(); + Unit owner = GetSummonerUnit(); if (owner != null) if (owner.m_SummonSlot[slot] == GetGUID()) owner.m_SummonSlot[slot].Clear(); diff --git a/Source/Game/Entities/Unit/Unit.Combat.cs b/Source/Game/Entities/Unit/Unit.Combat.cs index d88a6bfee..289b06ecb 100644 --- a/Source/Game/Entities/Unit/Unit.Combat.cs +++ b/Source/Game/Entities/Unit/Unit.Combat.cs @@ -876,10 +876,14 @@ namespace Game.Entities TempSummon summon = creature.ToTempSummon(); if (summon != null) { - Unit summoner = summon.GetSummoner(); + WorldObject summoner = summon.GetSummoner(); if (summoner != null) - if (summoner.IsTypeId(TypeId.Unit) && summoner.IsAIEnabled()) - summoner.ToCreature().GetAI().SummonedCreatureDies(creature, attacker); + { + if (summoner.IsCreature()) + summoner.ToCreature().GetAI()?.SummonedCreatureDies(creature, attacker); + else if (summoner.IsGameObject()) + summoner.ToGameObject().GetAI()?.SummonedCreatureDies(creature, attacker); + } } // Dungeon specific stuff, only applies to players killing creatures diff --git a/Source/Game/Globals/ObjectManager.cs b/Source/Game/Globals/ObjectManager.cs index 13eef2715..3f2f1bce4 100644 --- a/Source/Game/Globals/ObjectManager.cs +++ b/Source/Game/Globals/ObjectManager.cs @@ -10957,7 +10957,7 @@ namespace Game Unit summoner = null; // Check summoners for party if (clickee.IsSummon()) - summoner = clickee.ToTempSummon().GetSummoner(); + summoner = clickee.ToTempSummon().GetSummonerUnit(); if (summoner == null) summoner = clickee; diff --git a/Source/Game/Handlers/BattlePetHandler.cs b/Source/Game/Handlers/BattlePetHandler.cs index 078201e56..2e242349d 100644 --- a/Source/Game/Handlers/BattlePetHandler.cs +++ b/Source/Game/Handlers/BattlePetHandler.cs @@ -75,7 +75,7 @@ namespace Game response.CreatureID = summonedBattlePet.GetEntry(); response.Timestamp = summonedBattlePet.GetBattlePetCompanionNameTimestamp(); - Unit petOwner = summonedBattlePet.ToTempSummon().GetSummoner(); + Unit petOwner = summonedBattlePet.ToTempSummon().GetSummonerUnit(); if (!petOwner.IsPlayer()) { SendPacket(response); diff --git a/Source/Game/Maps/Map.cs b/Source/Game/Maps/Map.cs index 7d62ab3be..d9bd6e7e6 100644 --- a/Source/Game/Maps/Map.cs +++ b/Source/Game/Maps/Map.cs @@ -3947,7 +3947,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, ObjectGuid privateObjectOwner = default) + public TempSummon SummonCreature(uint entry, Position pos, SummonPropertiesRecord properties = null, uint duration = 0, WorldObject summoner = null, uint spellId = 0, uint vehId = 0, ObjectGuid privateObjectOwner = default) { var mask = UnitTypeMask.Summon; if (properties != null) @@ -3997,23 +3997,25 @@ namespace Game.Maps } } + Unit summonerUnit = summoner != null ? summoner.ToUnit() : null; + TempSummon summon; switch (mask) { case UnitTypeMask.Summon: - summon = new TempSummon(properties, summoner, false); + summon = new TempSummon(properties, summonerUnit, false); break; case UnitTypeMask.Guardian: - summon = new Guardian(properties, summoner, false); + summon = new Guardian(properties, summonerUnit, false); break; case UnitTypeMask.Puppet: - summon = new Puppet(properties, summoner); + summon = new Puppet(properties, summonerUnit); break; case UnitTypeMask.Totem: - summon = new Totem(properties, summoner); + summon = new Totem(properties, summonerUnit); break; case UnitTypeMask.Minion: - summon = new Minion(properties, summoner, false); + summon = new Minion(properties, summonerUnit, false); break; default: return null; diff --git a/Source/Game/Spells/Spell.cs b/Source/Game/Spells/Spell.cs index ba17e5199..162eee1e7 100644 --- a/Source/Game/Spells/Spell.cs +++ b/Source/Game/Spells/Spell.cs @@ -916,7 +916,7 @@ namespace Game.Spells TempSummon casterSummon = unitCaster.ToTempSummon(); if (casterSummon != null) { - Unit summoner = casterSummon.GetSummoner(); + WorldObject summoner = casterSummon.GetSummoner(); if (summoner != null) dest = new SpellDestination(summoner); } @@ -1059,7 +1059,7 @@ namespace Game.Spells Unit unitCaster = m_caster.ToUnit(); if (unitCaster != null) if (unitCaster.IsSummon()) - target = unitCaster.ToTempSummon().GetSummoner(); + target = unitCaster.ToTempSummon().GetSummonerUnit(); break; } case Targets.UnitVehicle: diff --git a/Source/Game/Spells/SpellEffects.cs b/Source/Game/Spells/SpellEffects.cs index 3a8ee6161..c49fe1c47 100644 --- a/Source/Game/Spells/SpellEffects.cs +++ b/Source/Game/Spells/SpellEffects.cs @@ -1707,7 +1707,7 @@ namespace Game.Spells uint faction = properties.Faction; if (properties.GetFlags().HasFlag(SummonPropertiesFlags.UseSummonerFaction)) // TODO: Determine priority between faction and flag { - Unit summoner = summon.GetSummoner(); + WorldObject summoner = summon.GetSummoner(); if (summoner != null) faction = summoner.GetFaction(); } diff --git a/Source/Scripts/Pets/Hunter.cs b/Source/Scripts/Pets/Hunter.cs index 3fa117d67..8e53cc259 100644 --- a/Source/Scripts/Pets/Hunter.cs +++ b/Source/Scripts/Pets/Hunter.cs @@ -72,7 +72,7 @@ namespace Scripts.Pets if (me.IsSummon() && !me.GetThreatManager().GetFixateTarget()) { // find new target - Unit summoner = me.ToTempSummon().GetSummoner(); + Unit summoner = me.ToTempSummon().GetSummonerUnit(); List targets = new(); foreach (var pair in summoner.GetCombatManager().GetPvPCombatRefs()) diff --git a/Source/Scripts/Pets/Priest.cs b/Source/Scripts/Pets/Priest.cs index 8bea44d4b..7cf313237 100644 --- a/Source/Scripts/Pets/Priest.cs +++ b/Source/Scripts/Pets/Priest.cs @@ -55,9 +55,13 @@ namespace Scripts.Pets { public npc_pet_pri_shadowfiend(Creature creature) : base(creature) { } - public override void IsSummonedBy(Unit summoner) + public override void IsSummonedBy(WorldObject summoner) { - if (summoner.HasAura(SpellIds.GlyphOfShadowFiend)) + Unit unitSummoner = summoner.ToUnit(); + if (unitSummoner == null) + return; + + if (unitSummoner.HasAura(SpellIds.GlyphOfShadowFiend)) DoCastAOE(SpellIds.ShadowFiendDeath); } } diff --git a/Source/Scripts/World/EmeraldDragons.cs b/Source/Scripts/World/EmeraldDragons.cs index 655ae5b09..cdc238b40 100644 --- a/Source/Scripts/World/EmeraldDragons.cs +++ b/Source/Scripts/World/EmeraldDragons.cs @@ -311,10 +311,14 @@ namespace Scripts.World.EmeraldDragons public npc_spirit_shade(Creature creature) : base(creature) { } - public override void IsSummonedBy(Unit summoner) + public override void IsSummonedBy(WorldObject summoner) { + Unit unitSummoner = summoner.ToUnit(); + if (unitSummoner == null) + return; + _summonerGuid = summoner.GetGUID(); - me.GetMotionMaster().MoveFollow(summoner, 0.0f, 0.0f); + me.GetMotionMaster().MoveFollow(unitSummoner, 0.0f, 0.0f); } public override void MovementInform(MovementGeneratorType moveType, uint data) diff --git a/Source/Scripts/World/NpcSpecial.cs b/Source/Scripts/World/NpcSpecial.cs index 290c26d62..70b88fd20 100644 --- a/Source/Scripts/World/NpcSpecial.cs +++ b/Source/Scripts/World/NpcSpecial.cs @@ -522,7 +522,7 @@ namespace Scripts.World.NpcSpecial return null; } - public void UpdateAI(uint diff) + public override void UpdateAI(uint diff) { base.UpdateAI(diff); @@ -2044,7 +2044,7 @@ namespace Scripts.World.NpcSpecial summonerGUID.Clear(); } - public override void IsSummonedBy(Unit summoner) + public override void IsSummonedBy(WorldObject summoner) { if (summoner.IsTypeId(TypeId.Player)) {