From 11575d6d39c4d4175e96d550bf7ed73ce7f8d4b1 Mon Sep 17 00:00:00 2001 From: hondacrx Date: Tue, 30 May 2023 05:08:45 -0400 Subject: [PATCH] Core/Creatures: Allow summons to be initialized properly when summoner is not in world yet Port From (https://github.com/TrinityCore/TrinityCore/commit/7881f0ef5ff79b691a5abb9cd727755f49afba47) --- Source/Game/Entities/TemporarySummon.cs | 62 ++++++++++++------------- Source/Game/Entities/Totem.cs | 6 +-- Source/Game/Entities/Transport.cs | 4 +- Source/Game/Maps/Map.cs | 4 +- 4 files changed, 37 insertions(+), 39 deletions(-) diff --git a/Source/Game/Entities/TemporarySummon.cs b/Source/Game/Entities/TemporarySummon.cs index 4177b9705..311c3e37b 100644 --- a/Source/Game/Entities/TemporarySummon.cs +++ b/Source/Game/Entities/TemporarySummon.cs @@ -164,7 +164,7 @@ namespace Game.Entities } } - public virtual void InitStats(uint duration) + public virtual void InitStats(WorldObject summoner, uint duration) { Cypher.Assert(!IsPet()); @@ -174,13 +174,11 @@ namespace Game.Entities if (m_type == TempSummonType.ManualDespawn) m_type = (duration == 0) ? TempSummonType.DeadDespawn : TempSummonType.TimedDespawn; - Unit owner = GetSummonerUnit(); - if (owner != null && IsTrigger() && m_spells[0] != 0) - if (owner.IsTypeId(TypeId.Player)) - m_ControlledByPlayer = true; - - if (owner != null && owner.IsPlayer()) + if (summoner != null && summoner.IsPlayer()) { + if (IsTrigger() && m_spells[0] != 0) + m_ControlledByPlayer = true; + CreatureSummonedData summonedData = Global.ObjectMgr.GetCreatureSummonedData(GetEntry()); if (summonedData != null) { @@ -196,27 +194,28 @@ namespace Game.Entities if (m_Properties == null) return; - if (owner != null) + Unit unitSummoner = summoner?.ToUnit(); + if (unitSummoner != null) { int slot = m_Properties.Slot; if (slot > 0) { - if (!owner.m_SummonSlot[slot].IsEmpty() && owner.m_SummonSlot[slot] != GetGUID()) + if (!unitSummoner.m_SummonSlot[slot].IsEmpty() && unitSummoner.m_SummonSlot[slot] != GetGUID()) { - Creature oldSummon = GetMap().GetCreature(owner.m_SummonSlot[slot]); + Creature oldSummon = GetMap().GetCreature(unitSummoner.m_SummonSlot[slot]); if (oldSummon != null && oldSummon.IsSummon()) oldSummon.ToTempSummon().UnSummon(); } - owner.m_SummonSlot[slot] = GetGUID(); + unitSummoner.m_SummonSlot[slot] = GetGUID(); } if (!m_Properties.GetFlags().HasFlag(SummonPropertiesFlags.UseCreatureLevel)) - SetLevel(owner.GetLevel()); + SetLevel(unitSummoner.GetLevel()); } uint faction = m_Properties.Faction; - if (owner && m_Properties.GetFlags().HasFlag(SummonPropertiesFlags.UseSummonerFaction)) // TODO: Determine priority between faction and flag - faction = owner.GetFaction(); + if (summoner != null && m_Properties.GetFlags().HasFlag(SummonPropertiesFlags.UseSummonerFaction)) // TODO: Determine priority between faction and flag + faction = summoner.GetFaction(); if (faction != 0) SetFaction(faction); @@ -225,18 +224,17 @@ namespace Game.Entities RemoveNpcFlag(NPCFlags.WildBattlePet); } - public virtual void InitSummon() + public virtual void InitSummon(WorldObject summoner) { - WorldObject owner = GetSummoner(); - if (owner != null) + if (summoner != null) { - if (owner.IsCreature()) - owner.ToCreature().GetAI()?.JustSummoned(this); - else if (owner.IsGameObject()) - owner.ToGameObject().GetAI()?.JustSummoned(this); + if (summoner.IsCreature()) + summoner.ToCreature().GetAI()?.JustSummoned(this); + else if (summoner.IsGameObject()) + summoner.ToGameObject().GetAI()?.JustSummoned(this); if (IsAIEnabled()) - GetAI().IsSummonedBy(owner); + GetAI().IsSummonedBy(summoner); } } @@ -396,9 +394,9 @@ namespace Game.Entities InitCharmInfo(); } - public override void InitStats(uint duration) + public override void InitStats(WorldObject summoner, uint duration) { - base.InitStats(duration); + base.InitStats(summoner, duration); SetReactState(ReactStates.Passive); @@ -490,9 +488,9 @@ namespace Game.Entities } } - public override void InitStats(uint duration) + public override void InitStats(WorldObject summoner, uint duration) { - base.InitStats(duration); + base.InitStats(summoner, duration); InitStatsForLevel(GetOwner().GetLevel()); @@ -502,9 +500,9 @@ namespace Game.Entities SetReactState(ReactStates.Aggressive); } - public override void InitSummon() + public override void InitSummon(WorldObject summoner) { - base.InitSummon(); + base.InitSummon(summoner); if (GetOwner().IsTypeId(TypeId.Player) && GetOwner().GetMinionGUID() == GetGUID() && GetOwner().GetCharmedGUID().IsEmpty()) @@ -1086,17 +1084,17 @@ namespace Game.Entities UnitTypeMask |= UnitTypeMask.Puppet; } - public override void InitStats(uint duration) + public override void InitStats(WorldObject summoner, uint duration) { - base.InitStats(duration); + base.InitStats(summoner, duration); SetLevel(GetOwner().GetLevel()); SetReactState(ReactStates.Passive); } - public override void InitSummon() + public override void InitSummon(WorldObject summoner) { - base.InitSummon(); + base.InitSummon(summoner); if (!SetCharmedBy(GetOwner(), CharmType.Possess)) Cypher.Assert(false); } diff --git a/Source/Game/Entities/Totem.cs b/Source/Game/Entities/Totem.cs index 959239fe5..3ff4680a0 100644 --- a/Source/Game/Entities/Totem.cs +++ b/Source/Game/Entities/Totem.cs @@ -37,7 +37,7 @@ namespace Game.Entities } - public override void InitStats(uint duration) + public override void InitStats(WorldObject summoner, uint duration) { // client requires SMSG_TOTEM_CREATED to be sent before adding to world and before removing old totem Player owner = GetOwner().ToPlayer(); @@ -61,7 +61,7 @@ namespace Game.Entities Log.outDebug(LogFilter.Misc, $"Totem with entry {GetEntry()}, does not have a specialized model for spell {m_unitData.CreatedBySpell} and race {owner.GetRace()}. Set to default."); } - base.InitStats(duration); + base.InitStats(summoner, duration); // Get spell cast by totem SpellInfo totemSpell = Global.SpellMgr.GetSpellInfo(GetSpell(), GetMap().GetDifficultyID()); @@ -72,7 +72,7 @@ namespace Game.Entities m_duration = duration; } - public override void InitSummon() + public override void InitSummon(WorldObject summoner) { if (m_type == TotemType.Passive && GetSpell() != 0) CastSpell(this, GetSpell(), true); diff --git a/Source/Game/Entities/Transport.cs b/Source/Game/Entities/Transport.cs index 88087ab77..cd7afc7d1 100644 --- a/Source/Game/Entities/Transport.cs +++ b/Source/Game/Entities/Transport.cs @@ -532,14 +532,14 @@ namespace Game.Entities // because the current GameObjectModel cannot be moved without recreating summon.AddUnitState(UnitState.IgnorePathfinding); - summon.InitStats(duration); + summon.InitStats(summoner, duration); if (!map.AddToMap(summon)) return null; _staticPassengers.Add(summon); - summon.InitSummon(); + summon.InitSummon(summoner); summon.SetTempSummonType(summonType); return summon; diff --git a/Source/Game/Maps/Map.cs b/Source/Game/Maps/Map.cs index 60f113140..24c3d98dd 100644 --- a/Source/Game/Maps/Map.cs +++ b/Source/Game/Maps/Map.cs @@ -3679,7 +3679,7 @@ namespace Game.Maps summon.SetCreatedBySpell(spellId); summon.SetHomePosition(pos); - summon.InitStats(duration); + summon.InitStats(summoner, duration); summon.SetPrivateObjectOwner(privateObjectOwner); if (smoothPhasingInfo != null) @@ -3710,7 +3710,7 @@ namespace Game.Maps return null; } - summon.InitSummon(); + summon.InitSummon(summoner); // call MoveInLineOfSight for nearby creatures AIRelocationNotifier notifier = new(summon);