Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 26 additions & 7 deletions WowPacketParser/Enums/CreatureStaticFlags.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,15 @@ public enum CreatureStaticFlags : uint
CanSwim = 0x10000000, // UnitFlags 0x8000 UNIT_FLAG_CAN_SWIM
Floating = 0x20000000, // sets DisableGravity movementflag on spawn/reset
MoreAudible = 0x40000000, // CREATURE_TYPE_FLAG_MORE_AUDIBLE
LargeAoi = 0x80000000 // UnitFlags2 0x200000
LargeAoi = 0x80000000, // UnitFlags2 0x200000

NonServerSide = (Sessile | CanSwim | Floating)
}

[Flags]
public enum CreatureStaticFlags2 : uint
{
NoPetScaling = 0x00000001,
NoPetScaling = 0x00000001,
ForcePartyMembersIntoCombat = 0x00000002, // Original description: Force Raid Combat
LockTappersToRaidOnDeath = 0x00000004, // "Lock Tappers To Raid On Death", toggleable by 'Set "RAID_LOCK_ON_DEATH" flag for unit(s)' action, CREATURE_FLAG_EXTRA_INSTANCE_BIND
SpellAttackable = 0x00000008, // CREATURE_TYPE_FLAG_SPELL_ATTACKABLE, original description(not valid anymore?): No Harmful Vertex Coloring
Expand Down Expand Up @@ -73,7 +75,9 @@ public enum CreatureStaticFlags2 : uint
CanSafeFall = 0x10000000, // Original description: No Collision
CanAssist = 0x20000000, // CREATURE_TYPE_FLAG_CAN_ASSIST, original description: Player Can Heal/Buff
NoSkillGains = 0x40000000, // CREATURE_FLAG_EXTRA_NO_SKILL_GAINS
NoPetBar = 0x80000000 // CREATURE_TYPE_FLAG_NO_PET_BAR
NoPetBar = 0x80000000, // CREATURE_TYPE_FLAG_NO_PET_BAR

NonServerSide = (HideBody)
}

[Flags]
Expand Down Expand Up @@ -110,7 +114,10 @@ public enum CreatureStaticFlags3 : uint
PetsAttackWith3DPathing = 0x10000000, // "Pets attack with 3d pathing (Kologarn)"
LinkAll = 0x20000000, // CREATURE_TYPE_FLAG_LINK_ALL
AiCanAutoTakeoffInCombat = 0x40000000,
AiCanAutoLandInCombat = 0x80000000
AiCanAutoLandInCombat = 0x80000000,

NonServerSide = (DoNotFadeIn | CannotSwim | AllowInteractionWhileInCombat |
CannotTurn)
}

[Flags]
Expand Down Expand Up @@ -147,7 +154,10 @@ public enum CreatureStaticFlags4 : uint
OnlyGenerateInitialThreat = 0x10000000,
DoNotTargetOnInteraction = 0x20000000, // CREATURE_TYPE_FLAG_DO_NOT_TARGET_ON_INTERACTION, original description: Doesn't change target on right click
DoNotRenderObjectName = 0x40000000, // CREATURE_TYPE_FLAG_DO_NOT_RENDER_OBJECT_NAME, original description: Hide name in world frame
QuestBoss = 0x80000000 // CREATURE_TYPE_FLAG_QUEST_BOSS
QuestBoss = 0x80000000, // CREATURE_TYPE_FLAG_QUEST_BOSS

NonServerSide = (NoBirthAnim | TreatAsRaidUnitForHelpfulSpells | IgnoreSpellMinRangeRestrictions |
PreventSwim | HideInCombatLog)
}

[Flags]
Expand Down Expand Up @@ -184,7 +194,10 @@ public enum CreatureStaticFlags5 : uint
NoPowerRegen = 0x10000000,
NoPetUnitFrame = 0x20000000,
NoInteractOnLeftClick = 0x40000000, // CREATURE_TYPEFLAGS_2_UNK6
GiveCriteriaKillCreditWhenCharmed = 0x80000000
GiveCriteriaKillCreditWhenCharmed = 0x80000000,

NonServerSide = (UntargetableByClient | UninteractibleIfHostile | InteractWhileHostile |
SuppressHighlightWhenTargetedOrMousedOver)
}

[Flags]
Expand Down Expand Up @@ -221,7 +234,9 @@ public enum CreatureStaticFlags6 : uint
AiDontLeaveMeleeForRangedWhenTargetGetsRooted = 0x10000000,
DontUseCombatReachForChaining = 0x20000000,
DoNotPlayProceduralWoundAnim = 0x40000000,
ApplyProceduralWoundAnimToBase = 0x80000000 // TFLAG2_UNK14
ApplyProceduralWoundAnimToBase = 0x80000000, // TFLAG2_UNK14

NonServerSide = (0x00000000)
}

[Flags]
Expand All @@ -239,6 +254,8 @@ public enum CreatureStaticFlags7 : uint
InteractOnlyOnQuest = 0x00000200,
DisableKillCreditForOfflinePlayers = 0x00000400,
AiAdditionalPathing = 0x00080000,

NonServerSide = (0x00000000)
}

[Flags]
Expand All @@ -247,5 +264,7 @@ public enum CreatureStaticFlags8 : uint
ForceCloseInOnPathFailBehavior = 0x00000002,
Use2DChasingCalculation = 0x00000020,
UseFastClassicHeartbeat = 0x00000040,

NonServerSide = (0x00000000)
}
}
4 changes: 4 additions & 0 deletions WowPacketParser/Misc/MovementInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ public sealed class MovementInfo
{
public WowGuid MoverGuid;

public bool NoBirthAnim;

public bool PlayHoverAnim;

// NOTE: Do not use flag fields in a generic way to handle anything for producing spawns - different versions have different flags
public uint Flags;

Expand Down
49 changes: 39 additions & 10 deletions WowPacketParser/SQL/Builders/UnitMisc.cs
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,40 @@ public static string CreatureTemplateScalingDataWDB()
return SQLUtil.Compare(Settings.SQLOrderByKey ? Storage.CreatureTemplateDifficultiesWDB.OrderBy(x => x.Item1.Entry).ToArray() : Storage.CreatureTemplateDifficultiesWDB.ToArray(), templatesDb, StoreNameType.Unit);
}

public static bool IsCreatureSessile(ref Unit npc)
{
if (ClientVersion.Expansion == ClientType.WrathOfTheLichKing)
if (npc.Movement.Flags.HasAnyFlag(MovementFlag.Root))
return true;

if (ClientVersion.Expansion >= ClientType.Cataclysm && (ClientVersion.Branch != ClientBranch.Retail || ClientVersion.RemovedInVersion(ClientBranch.Retail, ClientVersionBuild.V12_1_0_69214)))
if (npc.Movement.Flags.HasAnyFlag(Enums.v4.MovementFlag.Root) && npc.Movement.Flags.HasAnyFlag(Enums.v4.MovementFlag.DisableGravity))
return true;

if (ClientVersion.AddedInVersion(ClientBranch.Retail, ClientVersionBuild.V12_1_0_69214))
if (npc.Movement.Flags64.HasAnyFlag(Enums.v12.MovementFlag.Root) && npc.Movement.Flags64.HasAnyFlag(Enums.v12.MovementFlag.DisableGravity))
return true;

return false;
}

public static bool IsCreatureFloating(ref Unit npc)
{
if (ClientVersion.Expansion == ClientType.WrathOfTheLichKing)
if (npc.Movement.Flags.HasAnyFlag(MovementFlag.DisableGravity))
return true;

if (ClientVersion.Expansion >= ClientType.Cataclysm && (ClientVersion.Branch != ClientBranch.Retail || ClientVersion.RemovedInVersion(ClientBranch.Retail, ClientVersionBuild.V12_1_0_69214)))
if (npc.Movement.PlayHoverAnim && npc.Movement.Flags.HasAnyFlag(Enums.v4.MovementFlag.DisableGravity))
return true;

if (ClientVersion.AddedInVersion(ClientBranch.Retail, ClientVersionBuild.V12_1_0_69214))
if (npc.Movement.PlayHoverAnim && npc.Movement.Flags64.HasAnyFlag(Enums.v12.MovementFlag.DisableGravity))
return true;

return false;
}

public static void UpdateCreatureStaticFlags(ref Unit npc, ref CreatureTemplateDifficulty creatureDifficulty)
{
if (npc.UnitData.Flags.HasAnyFlag(UnitFlags.CanSwim))
Expand Down Expand Up @@ -193,22 +227,17 @@ public static void UpdateCreatureStaticFlags(ref Unit npc, ref CreatureTemplateD
if (npc.UnitData.Flags3.HasAnyFlag(UnitFlags3.AllowInteractionWhileInCombat))
creatureDifficulty.StaticFlags3 |= CreatureStaticFlags3.AllowInteractionWhileInCombat;

if (npc.Movement.NoBirthAnim)
creatureDifficulty.StaticFlags4 |= CreatureStaticFlags4.NoBirthAnim;

// Not 100% reliable
// CreatureStaticFlags.ImmuneToPc - UnitFlags.ImmunePC
// CreatureStaticFlags.ImmuneToNpc - UnitFlags.ImmuneNPC
// CreatureStaticFlags.Uninteractible - UnitFlags.Uninteractible
if ((ClientVersion.Expansion == ClientType.WrathOfTheLichKing && npc.Movement.Flags.HasAnyFlag(MovementFlag.DisableGravity)) ||
(ClientVersion.Expansion >= ClientType.Cataclysm
&& (ClientVersion.Branch != ClientBranch.Retail
|| ClientVersion.RemovedInVersion(ClientBranch.Retail, ClientVersionBuild.V12_1_0_69214)) && npc.Movement.Flags.HasAnyFlag(Enums.v4.MovementFlag.DisableGravity)) ||
(ClientVersion.AddedInVersion(ClientBranch.Retail, ClientVersionBuild.V12_1_0_69214) && npc.Movement.Flags64.HasAnyFlag(Enums.v12.MovementFlag.DisableGravity)))
if (IsCreatureFloating(ref npc))
creatureDifficulty.StaticFlags1 |= CreatureStaticFlags.Floating;

if ((ClientVersion.Expansion == ClientType.WrathOfTheLichKing && npc.Movement.Flags.HasAnyFlag(MovementFlag.Root)) ||
(ClientVersion.Expansion >= ClientType.Cataclysm
&& (ClientVersion.Branch != ClientBranch.Retail
|| ClientVersion.RemovedInVersion(ClientBranch.Retail, ClientVersionBuild.V12_1_0_69214)) && npc.Movement.Flags.HasAnyFlag(Enums.v4.MovementFlag.Root)) ||
(ClientVersion.AddedInVersion(ClientBranch.Retail, ClientVersionBuild.V12_1_0_69214) && npc.Movement.Flags64.HasAnyFlag(Enums.v12.MovementFlag.Root)))
if (IsCreatureSessile(ref npc))
creatureDifficulty.StaticFlags1 |= CreatureStaticFlags.Sessile;

// Handled by creature_template_addon.visibilityDistanceType
Expand Down
35 changes: 34 additions & 1 deletion WowPacketParser/SQL/SQLDatabase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public static class SQLDatabase
public static Dictionary<int /*menuID*/, List<uint> /*npc_text ids*/> GossipMenuToNPCTexts { get; } = new();
public static Dictionary<int /*worldStateID*/, string> WorldStateNames { get; } = new();
public static Dictionary<(uint /*CreatureId*/, uint /*DifficultyID*/), CreatureTemplateDifficultyWDB> CreatureTemplateDifficultyWDBData = new();
public static Dictionary<(uint /*CreatureId*/, uint /*DifficultyID*/), CreatureTemplateDifficulty> CreatureTemplateDifficultyStaticFlagsData = new();
public static List<POIData> POIs { get; } = new List<POIData>();

private static readonly StoreNameType[] ObjectTypes =
Expand Down Expand Up @@ -293,7 +294,8 @@ private static void LoadCreatureTemplateDifficultyWDBData()
if (Settings.TargetedDatabase < TargetedDatabase.Dragonflight || !Settings.DBEnabled)
return;

string columns = "Entry, DifficultyID, HealthScalingExpansion, HealthModifier, ManaModifier, CreatureDifficultyID, TypeFlags, TypeFlags2";
string columns = "Entry, DifficultyID, HealthScalingExpansion, HealthModifier, ManaModifier, CreatureDifficultyID, TypeFlags, TypeFlags2, " +
"StaticFlags1, StaticFlags2, StaticFlags3, StaticFlags4, StaticFlags5, StaticFlags6, StaticFlags7, StaticFlags8";
string query = $"SELECT {columns} FROM {Settings.TDBDatabase}.creature_template_difficulty";

using (var command = SQLConnector.CreateCommand(query))
Expand All @@ -315,7 +317,23 @@ private static void LoadCreatureTemplateDifficultyWDBData()
TypeFlags = (CreatureTypeFlag)reader.GetUInt32("TypeFlags"),
TypeFlags2 = reader.GetUInt32("TypeFlags2")
};

var staticFlagsData = new CreatureTemplateDifficulty
{
Entry = data.Entry,
DifficultyID = data.DifficultyID,
StaticFlags1 = (CreatureStaticFlags)reader.GetUInt32("StaticFlags1"),
StaticFlags2 = (CreatureStaticFlags2)reader.GetUInt32("StaticFlags2"),
StaticFlags3 = (CreatureStaticFlags3)reader.GetUInt32("StaticFlags3"),
StaticFlags4 = (CreatureStaticFlags4)reader.GetUInt32("StaticFlags4"),
StaticFlags5 = (CreatureStaticFlags5)reader.GetUInt32("StaticFlags5"),
StaticFlags6 = (CreatureStaticFlags6)reader.GetUInt32("StaticFlags6"),
StaticFlags7 = (CreatureStaticFlags7)reader.GetUInt32("StaticFlags7"),
StaticFlags8 = (CreatureStaticFlags8)reader.GetUInt32("StaticFlags8")
};

CreatureTemplateDifficultyWDBData.Add((data.Entry.Value, data.DifficultyID.Value), data);
CreatureTemplateDifficultyStaticFlagsData.Add((data.Entry.Value, data.DifficultyID.Value), staticFlagsData);
}
}
}
Expand Down Expand Up @@ -360,7 +378,22 @@ public static void CheckCreatureTemplateDifficultyNonWDBFallbacks(ref CreatureTe

// entry with same difficulty already exists (wdb)
if (CreatureTemplateDifficultyWDBData.TryGetValue((sniffData.Entry.Value, difficulty), out var dbData))
{
sniffData.DifficultyID = dbData.DifficultyID;

// keep manually added serverside static flags
if (CreatureTemplateDifficultyStaticFlagsData.TryGetValue((sniffData.Entry.Value, difficulty), out var dbStaticFlagsData))
{
sniffData.StaticFlags1 |= dbStaticFlagsData.StaticFlags1 &~ CreatureStaticFlags.NonServerSide;
sniffData.StaticFlags2 |= dbStaticFlagsData.StaticFlags2 &~ CreatureStaticFlags2.NonServerSide;
sniffData.StaticFlags3 |= dbStaticFlagsData.StaticFlags3 &~ CreatureStaticFlags3.NonServerSide;
sniffData.StaticFlags4 |= dbStaticFlagsData.StaticFlags4 &~ CreatureStaticFlags4.NonServerSide;
sniffData.StaticFlags5 |= dbStaticFlagsData.StaticFlags5 &~ CreatureStaticFlags5.NonServerSide;
sniffData.StaticFlags6 |= dbStaticFlagsData.StaticFlags6 &~ CreatureStaticFlags6.NonServerSide;
sniffData.StaticFlags7 |= dbStaticFlagsData.StaticFlags7 &~ CreatureStaticFlags7.NonServerSide;
sniffData.StaticFlags8 |= dbStaticFlagsData.StaticFlags8 &~ CreatureStaticFlags8.NonServerSide;
}
}
// entry with same difficulty does not exist, check fallback difficulties recursively
else
{
Expand Down
4 changes: 2 additions & 2 deletions WowPacketParserModule.V11_0_0_55666/Parsers/UpdateHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -511,9 +511,9 @@ private static MovementInfo ReadMovementUpdateBlock(Packet packet, CreateObject
packet.ResetBitReader();

packet.ReadBit("HasPositionFragment", index);
packet.ReadBit("NoBirthAnim", index);
moveInfo.NoBirthAnim = packet.ReadBit("NoBirthAnim", index);
packet.ReadBit("EnablePortals", index);
packet.ReadBit("PlayHoverAnim", index);
moveInfo.PlayHoverAnim = packet.ReadBit("PlayHoverAnim", index);
if (ClientVersion.AddedInVersion(ClientVersionBuild.V11_2_0_62213))
packet.ReadBit("ThisIsYou", index);

Expand Down
4 changes: 2 additions & 2 deletions WowPacketParserModule.V12_0_0_65390/Parsers/UpdateHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -504,9 +504,9 @@ private static MovementInfo ReadMovementUpdateBlock(Packet packet, CreateObject
packet.ResetBitReader();

packet.ReadBit("HasPositionFragment", index);
packet.ReadBit("NoBirthAnim", index);
moveInfo.NoBirthAnim = packet.ReadBit("NoBirthAnim", index);
packet.ReadBit("EnablePortals", index);
packet.ReadBit("PlayHoverAnim", index);
moveInfo.PlayHoverAnim = packet.ReadBit("PlayHoverAnim", index);
packet.ReadBit("ThisIsYou", index);

var hasMovementUpdate = packet.ReadBit("HasMovementUpdate", index);
Expand Down
4 changes: 2 additions & 2 deletions WowPacketParserModule.V1_13_2_31446/Parsers/UpdateHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,9 @@ private static MovementInfo ReadMovementUpdateBlock(Packet packet, CreateObject

packet.ResetBitReader();

packet.ReadBit("NoBirthAnim", index);
moveInfo.NoBirthAnim = packet.ReadBit("NoBirthAnim", index);
packet.ReadBit("EnablePortals", index);
packet.ReadBit("PlayHoverAnim", index);
moveInfo.PlayHoverAnim = packet.ReadBit("PlayHoverAnim", index);

var hasMovementUpdate = packet.ReadBit("HasMovementUpdate", index);
var hasMovementTransport = packet.ReadBit("HasMovementTransport", index);
Expand Down
4 changes: 2 additions & 2 deletions WowPacketParserModule.V2_5_1_38707/Parsers/UpdateHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -279,9 +279,9 @@ private static MovementInfo ReadMovementUpdateBlock(Packet packet, WowGuid guid,

packet.ResetBitReader();

packet.ReadBit("NoBirthAnim", index);
moveInfo.NoBirthAnim = packet.ReadBit("NoBirthAnim", index);
packet.ReadBit("EnablePortals", index);
packet.ReadBit("PlayHoverAnim", index);
moveInfo.PlayHoverAnim = packet.ReadBit("PlayHoverAnim", index);

var hasMovementUpdate = packet.ReadBit("HasMovementUpdate", index);
var hasMovementTransport = packet.ReadBit("HasMovementTransport", index);
Expand Down
4 changes: 2 additions & 2 deletions WowPacketParserModule.V3_4_0_45166/Parsers/UpdateHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -374,9 +374,9 @@ private static MovementInfo ReadMovementUpdateBlock(Packet packet, CreateObject
packet.ResetBitReader();

packet.ReadBit("HasPositionFragment", index);
packet.ReadBit("NoBirthAnim", index);
moveInfo.NoBirthAnim = packet.ReadBit("NoBirthAnim", index);
packet.ReadBit("EnablePortals", index);
packet.ReadBit("PlayHoverAnim", index);
moveInfo.PlayHoverAnim = packet.ReadBit("PlayHoverAnim", index);

var hasMovementUpdate = packet.ReadBit("HasMovementUpdate", index);
var hasMovementTransport = packet.ReadBit("HasMovementTransport", index);
Expand Down
8 changes: 4 additions & 4 deletions WowPacketParserModule.V4_4_0_54481/Parsers/UpdateHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -315,9 +315,9 @@ private static MovementInfo ReadMovementUpdateBlock(Packet packet, WowGuid guid,

packet.ResetBitReader();

packet.ReadBit("NoBirthAnim", index);
moveInfo.NoBirthAnim = packet.ReadBit("NoBirthAnim", index);
packet.ReadBit("EnablePortals", index);
packet.ReadBit("PlayHoverAnim", index);
moveInfo.PlayHoverAnim = packet.ReadBit("PlayHoverAnim", index);

var hasMovementUpdate = packet.ReadBit("HasMovementUpdate", index);
var hasMovementTransport = packet.ReadBit("HasMovementTransport", index);
Expand Down Expand Up @@ -1199,9 +1199,9 @@ private static MovementInfo ReadMovementUpdateBlock(Packet packet, CreateObject
packet.ResetBitReader();

packet.ReadBit("HasPositionFragment", index);
packet.ReadBit("NoBirthAnim", index);
moveInfo.NoBirthAnim = packet.ReadBit("NoBirthAnim", index);
packet.ReadBit("EnablePortals", index);
packet.ReadBit("PlayHoverAnim", index);
moveInfo.PlayHoverAnim = packet.ReadBit("PlayHoverAnim", index);

var hasMovementUpdate = packet.ReadBit("HasMovementUpdate", index);
var hasMovementTransport = packet.ReadBit("HasMovementTransport", index);
Expand Down
Loading