From 3ab092a6552f992963af763b11a72300d24c6121 Mon Sep 17 00:00:00 2001 From: hondacrx Date: Tue, 16 Nov 2021 13:23:42 -0500 Subject: [PATCH] Core/Spells: Implemented SummonPropertiesFlags: UseSummonerFaction & IgnoreSummonerPhase Port From (https://github.com/TrinityCore/TrinityCore/commit/a832435b9787c1997da87a124ff99bf06251aa07) --- Source/Framework/Constants/CliDBConst.cs | 62 ++++++++++------- Source/Game/DataStorage/Structs/S_Records.cs | 4 +- Source/Game/Entities/TemporarySummon.cs | 14 ++-- Source/Game/Entities/Transport.cs | 72 +++++++++++--------- Source/Game/Maps/Map.cs | 4 +- Source/Game/Spells/SpellEffects.cs | 27 ++++---- Source/Game/Spells/SpellManager.cs | 2 +- 7 files changed, 101 insertions(+), 84 deletions(-) diff --git a/Source/Framework/Constants/CliDBConst.cs b/Source/Framework/Constants/CliDBConst.cs index 938d3e806..1d1c3e42c 100644 --- a/Source/Framework/Constants/CliDBConst.cs +++ b/Source/Framework/Constants/CliDBConst.cs @@ -890,11 +890,11 @@ namespace Framework.Constants Arena = 0x80, // Arena, Both Instanced And World Arenas Capital = 0x100, // Main Capital City Flag City = 0x200, // Only For One Zone Named "City" (Where It Located?) - Outland = 0x400, // Expansion Zones? (Only Eye Of The Storm Not Have This Flag, But Have 0x00004000 Flag) + Outland = 0x400, // Expansion Zones? (Only Eye Of The Storm Not Have This Flag, But Have 0x4000 Flag) Sanctuary = 0x800, // Sanctuary Area (Pvp Disabled) NeedFly = 0x1000, // Unknown Unused1 = 0x2000, // Unused In 3.3.5a - Outland2 = 0x4000, // Expansion Zones? (Only Circle Of Blood Arena Not Have This Flag, But Have 0x00000400 Flag) + Outland2 = 0x4000, // Expansion Zones? (Only Circle Of Blood Arena Not Have This Flag, But Have 0x400 Flag) OutdoorPvp = 0x8000, // Pvp Objective Area? (Death'S Door Also Has This Flag Although It'S No Pvp Object Area) ArenaInstance = 0x10000, // Used By Instanced Arenas Only Unused2 = 0x20000, // Unused In 3.3.5a @@ -1724,31 +1724,41 @@ namespace Framework.Constants CannotUseGameObjects = 0x10000 } - public enum SummonPropFlags + public enum SummonPropertiesFlags : uint { - None = 0x00000000, // 1342 Spells In 3.0.3 - Unk1 = 0x00000001, // 75 Spells In 3.0.3, Something Unfriendly - Unk2 = 0x00000002, // 616 Spells In 3.0.3, Something Friendly - Unk3 = 0x00000004, // 22 Spells In 3.0.3, No Idea... - Unk4 = 0x00000008, // 49 Spells In 3.0.3, Some Mounts - PersonalSpawn = 0x00000010, // Only Visible to Summoner - Unk6 = 0x00000020, // 0 Spells In 3.3.5, Unused - Unk7 = 0x00000040, // 12 Spells In 3.0.3, No Idea - Unk8 = 0x00000080, // 4 Spells In 3.0.3, No Idea - Unk9 = 0x00000100, // 51 Spells In 3.0.3, No Idea, Many Quest Related - Unk10 = 0x00000200, // 51 Spells In 3.0.3, Something Defensive - Unk11 = 0x00000400, // 3 Spells, Requires Something Near? - Unk12 = 0x00000800, // 30 Spells In 3.0.3, No Idea - Unk13 = 0x00001000, // Lightwell, Jeeves, Gnomish Alarm-O-Bot, Build Vehicles(Wintergrasp) - Unk14 = 0x00002000, // Guides, Player Follows - Unk15 = 0x00004000, // Force Of Nature, Shadowfiend, Feral Spirit, Summon Water Elemental - Unk16 = 0x00008000, // Light/Dark Bullet, Soul/Fiery Consumption, Twisted Visage, Twilight Whelp. Phase Related? - PersonalGroupSpawn = 0x00010000, // Only Visible to Summoner's Group - Unk18 = 0x00020000, - Unk19 = 0x00040000, - Unk20 = 0x00080000, - Unk21 = 0x00100000, // Totems - Companion = 0x00200000 + None = 0x00, + AttackSummoner = 0x01, // NYI + HelpWhenSummonedInCombat = 0x02, // NYI + UseLevelOffset = 0x04, // NYI + DespawnOnSummonerDeath = 0x08, // NYI + OnlyVisibleToSummoner = 0x10, + CannotDismissPet = 0x20, // NYI + UseDemonTimeout = 0x40, // NYI + UnlimitedSummons = 0x80, // NYI + UseCreatureLevel = 0x100, // NYI + JoinSummonerSpawnGroup = 0x200, // NYI + DoNotToggle = 0x400, // NYI + DespawnWhenExpired = 0x800, // NYI + UseSummonerFaction = 0x1000, + DoNotFollowMountedSummoner = 0x2000, // NYI + SavePetAutocast = 0x4000, // NYI + IgnoreSummonerPhase = 0x8000, // Wild Only + OnlyVisibleToSummonerGroup = 0x10000, + DespawnOnSummonerLogout = 0x20000, // NYI + CastRideVehicleSpellOnSummoner = 0x40000, // NYI + GuardianActsLikePet = 0x80000, // NYI + DontSnapSessileToGround = 0x100000, // NYI + SummonFromBattlePetJournal = 0x200000, // NYI + UnitClutter = 0x400000, // NYI + DefaultNameColor = 0x800000, // NYI + UseOwnInvisibilityDetection = 0x1000000, // NYI. Ignore Owner's Invisibility Detection + DespawnWhenReplaced = 0x2000000, // NYI. Totem Slots Only + DespawnWhenTeleportingOutOfRange = 0x4000000, // NYI + SummonedAtGroupFormationPosition = 0x8000000, // NYI + DontDespawnOnSummonerDeath = 0x10000000, // NYI + UseTitleAsCreatureName = 0x20000000, // NYI + AttackableBySummoner = 0x40000000, // NYI + DontDismissWhenEncounterIsAborted = 0x80000000 // NYI } public enum TaxiNodeFlags : byte diff --git a/Source/Game/DataStorage/Structs/S_Records.cs b/Source/Game/DataStorage/Structs/S_Records.cs index a44bdf661..a1643c682 100644 --- a/Source/Game/DataStorage/Structs/S_Records.cs +++ b/Source/Game/DataStorage/Structs/S_Records.cs @@ -588,6 +588,8 @@ namespace Game.DataStorage public uint Faction; public SummonTitle Title; public int Slot; - public SummonPropFlags Flags; + public uint Flags; + + public SummonPropertiesFlags GetFlags() { return (SummonPropertiesFlags)Flags; } } } diff --git a/Source/Game/Entities/TemporarySummon.cs b/Source/Game/Entities/TemporarySummon.cs index 913fb32b5..a91e290b0 100644 --- a/Source/Game/Entities/TemporarySummon.cs +++ b/Source/Game/Entities/TemporarySummon.cs @@ -171,7 +171,6 @@ namespace Game.Entities if (owner != null && IsTrigger() && m_spells[0] != 0) { - SetFaction(owner.GetFaction()); SetLevel(owner.GetLevel()); if (owner.IsTypeId(TypeId.Player)) m_ControlledByPlayer = true; @@ -196,10 +195,13 @@ namespace Game.Entities } } - if (m_Properties.Faction != 0) - SetFaction(m_Properties.Faction); - else if (IsVehicle() && owner != null) // properties should be vehicle - SetFaction(owner.GetFaction()); + uint faction = m_Properties.Faction; + if (m_Properties.GetFlags().HasFlag(SummonPropertiesFlags.UseSummonerFaction)) // TODO: Determine priority between faction and flag + if (owner) + faction = owner.GetFaction(); + + if (faction != 0) + SetFaction(faction); } public virtual void InitSummon() @@ -307,7 +309,7 @@ namespace Game.Entities SetReactState(ReactStates.Passive); SetCreatorGUID(GetOwner().GetGUID()); - SetFaction(GetOwner().GetFaction()); + SetFaction(GetOwner().GetFaction());// TODO: Is this correct? Overwrite the use of SummonPropertiesFlags::UseSummonerFaction GetOwner().SetMinion(this, true); } diff --git a/Source/Game/Entities/Transport.cs b/Source/Game/Entities/Transport.cs index 6c146d60e..9f8819dca 100644 --- a/Source/Game/Entities/Transport.cs +++ b/Source/Game/Entities/Transport.cs @@ -217,7 +217,7 @@ namespace Game.Entities Global.ScriptMgr.OnRelocate(this, _currentFrame.Node.NodeIndex, _currentFrame.Node.ContinentID, _currentFrame.Node.Loc.X, _currentFrame.Node.Loc.Y, _currentFrame.Node.Loc.Z); - Log.outDebug(LogFilter.Transport, "Transport {0} ({1}) moved to node {2} {3} {4} {5} {6}", GetEntry(), GetName(), _currentFrame.Node.NodeIndex, _currentFrame.Node.ContinentID, + Log.outDebug(LogFilter.Transport, "Transport {0} ({1}) moved to node {2} {3} {4} {5} {6}", GetEntry(), GetName(), _currentFrame.Node.NodeIndex, _currentFrame.Node.ContinentID, _currentFrame.Node.Loc.X, _currentFrame.Node.Loc.Y, _currentFrame.Node.Loc.Z); // Departure event @@ -418,32 +418,32 @@ namespace Game.Entities case SummonCategory.Wild: case SummonCategory.Ally: case SummonCategory.Unk: + { + switch (properties.Title) { - switch (properties.Title) - { - case SummonTitle.Minion: - case SummonTitle.Guardian: - case SummonTitle.Runeblade: + case SummonTitle.Minion: + case SummonTitle.Guardian: + case SummonTitle.Runeblade: + mask = UnitTypeMask.Guardian; + break; + case SummonTitle.Totem: + case SummonTitle.LightWell: + mask = UnitTypeMask.Totem; + break; + case SummonTitle.Vehicle: + case SummonTitle.Mount: + mask = UnitTypeMask.Summon; + break; + case SummonTitle.Companion: + mask = UnitTypeMask.Minion; + break; + default: + if (properties.GetFlags().HasFlag(SummonPropertiesFlags.JoinSummonerSpawnGroup)) // Mirror Image, Summon Gargoyle mask = UnitTypeMask.Guardian; - break; - case SummonTitle.Totem: - case SummonTitle.LightWell: - mask = UnitTypeMask.Totem; - break; - case SummonTitle.Vehicle: - case SummonTitle.Mount: - mask = UnitTypeMask.Summon; - break; - case SummonTitle.Companion: - mask = UnitTypeMask.Minion; - break; - default: - if (properties.Flags.HasAnyFlag(SummonPropFlags.Unk10)) // Mirror Image, Summon Gargoyle - mask = UnitTypeMask.Guardian; - break; - } - break; + break; } + break; + } default: return null; } @@ -476,7 +476,11 @@ namespace Game.Entities if (!summon.Create(map.GenerateLowGuid(HighGuid.Creature), map, entry, new Position(x, y, z, o), null, vehId)) return null; - PhasingHandler.InheritPhaseShift(summon, summoner ? (WorldObject)summoner : this); + WorldObject phaseShiftOwner = this; + if (summoner != null && !(properties != null && properties.GetFlags().HasFlag(SummonPropertiesFlags.IgnoreSummonerPhase))) + phaseShiftOwner = summoner; + + PhasingHandler.InheritPhaseShift(summon, phaseShiftOwner); summon.SetCreatedBySpell(spellId); @@ -674,7 +678,7 @@ namespace Game.Entities z = nextFrame.Node.Loc.Z, o = nextFrame.InitialOrientation; - foreach(WorldObject obj in _passengers.ToList()) + foreach (WorldObject obj in _passengers.ToList()) { float destX, destY, destZ, destO; obj.m_movementInfo.transport.pos.GetPosition(out destX, out destY, out destZ, out destO); @@ -723,14 +727,14 @@ namespace Game.Entities switch (passenger.GetTypeId()) { case TypeId.Unit: - { - Creature creature = passenger.ToCreature(); - GetMap().CreatureRelocation(creature, x, y, z, o, false); - creature.GetTransportHomePosition(out x, out y, out z, out o); - CalculatePassengerPosition(ref x, ref y, ref z, ref o); - creature.SetHomePosition(x, y, z, o); - break; - } + { + Creature creature = passenger.ToCreature(); + GetMap().CreatureRelocation(creature, x, y, z, o, false); + creature.GetTransportHomePosition(out x, out y, out z, out o); + CalculatePassengerPosition(ref x, ref y, ref z, ref o); + creature.SetHomePosition(x, y, z, o); + break; + } case TypeId.Player: if (passenger.IsInWorld && !passenger.ToPlayer().IsBeingTeleported()) { diff --git a/Source/Game/Maps/Map.cs b/Source/Game/Maps/Map.cs index 97b19dd15..b04398b6a 100644 --- a/Source/Game/Maps/Map.cs +++ b/Source/Game/Maps/Map.cs @@ -3979,7 +3979,7 @@ namespace Game.Maps mask = UnitTypeMask.Minion; break; default: - if (Convert.ToBoolean(properties.Flags & SummonPropFlags.Unk10)) // Mirror Image, Summon Gargoyle + if (properties.GetFlags().HasFlag(SummonPropertiesFlags.JoinSummonerSpawnGroup)) // Mirror Image, Summon Gargoyle mask = UnitTypeMask.Guardian; break; } @@ -4016,7 +4016,7 @@ namespace Game.Maps return null; // Set the summon to the summoner's phase - if (summoner) + if (summoner != null && !(properties != null && properties.GetFlags().HasFlag(SummonPropertiesFlags.IgnoreSummonerPhase))) PhasingHandler.InheritPhaseShift(summon, summoner); summon.SetCreatedBySpell(spellId); diff --git a/Source/Game/Spells/SpellEffects.cs b/Source/Game/Spells/SpellEffects.cs index 22ada3a8a..d6d103803 100644 --- a/Source/Game/Spells/SpellEffects.cs +++ b/Source/Game/Spells/SpellEffects.cs @@ -1602,13 +1602,13 @@ namespace Game.Spells caster = m_originalCaster; ObjectGuid privateObjectOwner = caster.GetGUID(); - if (!properties.Flags.HasAnyFlag(SummonPropFlags.PersonalSpawn | SummonPropFlags.PersonalGroupSpawn)) + if (!properties.GetFlags().HasAnyFlag(SummonPropertiesFlags.OnlyVisibleToSummoner | SummonPropertiesFlags.OnlyVisibleToSummonerGroup)) privateObjectOwner = ObjectGuid.Empty; if (caster.IsPrivateObject()) privateObjectOwner = caster.GetPrivateObjectOwner(); - if (properties.Flags.HasAnyFlag(SummonPropFlags.PersonalGroupSpawn)) + if (properties.GetFlags().HasFlag(SummonPropertiesFlags.OnlyVisibleToSummonerGroup)) if (caster.IsPlayer() && m_originalCaster.ToPlayer().GetGroup()) privateObjectOwner = caster.ToPlayer().GetGroup().GetGUID(); @@ -1652,7 +1652,7 @@ namespace Game.Spells case SummonCategory.Wild: case SummonCategory.Ally: case SummonCategory.Unk: - if (Convert.ToBoolean(properties.Flags & SummonPropFlags.Unk10)) + if (properties.GetFlags().HasFlag(SummonPropertiesFlags.JoinSummonerSpawnGroup)) { SummonGuardian(effectInfo, entry, properties, numSummons, privateObjectOwner); break; @@ -1730,11 +1730,19 @@ namespace Game.Spells continue; if (properties.Control == SummonCategory.Ally) - { summon.SetOwnerGUID(caster.GetGUID()); - summon.SetFaction(caster.GetFaction()); + + uint faction = properties.Faction; + if (properties.GetFlags().HasFlag(SummonPropertiesFlags.UseSummonerFaction)) // TODO: Determine priority between faction and flag + { + Unit summoner = summon.GetSummoner(); + if (summoner != null) + faction = summoner.GetFaction(); } + if (faction != 0) + summon.SetFaction(faction); + ExecuteLogEffectSummonObject(effectInfo.Effect, summon); } return; @@ -1781,12 +1789,6 @@ namespace Game.Spells args.AddSpellMod(SpellValueMod.BasePoint0, basePoints); unitCaster.CastSpell(summon, spellId, args); - - uint faction = properties.Faction; - if (faction == 0) - faction = unitCaster.GetFaction(); - - summon.SetFaction(faction); break; } } @@ -4873,9 +4875,6 @@ namespace Game.Spells if (summon.HasUnitTypeMask(UnitTypeMask.Guardian)) ((Guardian)summon).InitStatsForLevel(level); - if (properties != null && properties.Control == SummonCategory.Ally) - summon.SetFaction(unitCaster.GetFaction()); - if (summon.HasUnitTypeMask(UnitTypeMask.Minion) && m_targets.HasDst()) ((Minion)summon).SetFollowAngle(unitCaster.GetAbsoluteAngle(summon.GetPosition())); diff --git a/Source/Game/Spells/SpellManager.cs b/Source/Game/Spells/SpellManager.cs index 645a65dcc..85c2805f2 100644 --- a/Source/Game/Spells/SpellManager.cs +++ b/Source/Game/Spells/SpellManager.cs @@ -2191,7 +2191,7 @@ namespace Game.Entities var summonProperties = CliDB.SummonPropertiesStorage.LookupByKey(effect.EffectMiscValue[1]); if (summonProperties != null) { - if (summonProperties.Slot == (int)SummonSlot.MiniPet && summonProperties.Flags.HasAnyFlag(SummonPropFlags.Companion)) + if (summonProperties.Slot == (int)SummonSlot.MiniPet && summonProperties.GetFlags().HasFlag(SummonPropertiesFlags.SummonFromBattlePetJournal)) { var battlePetSpecies = battlePetSpeciesByCreature.LookupByKey(effect.EffectMiscValue[0]); if (battlePetSpecies != null)