Core/Creatures: implemented most movement related static flags and migrated existing movement data into static flags
* implemented CREATURE_STATIC_FLAG_AQUATIC - creatures cannot leave liquids * implemented CREATURE_STATIC_FLAG_AMPHIBIOUS - creatures can enter and leave liquids but remain on the ocean floor when swimming is not enabled until engaged * implemented CREATURE_STATIC_FLAG_FLOATING - creatures have their gravity on spawn / reset disabled * implemented CREATURE_STATIC_FLAG_SESSILE - creatures are rooted in place * implemented CREATURE_STATIC_FLAG_CAN_SWIM - creature can swim in liquids * implemented CREATURE_STATIC_FLAG_3_CANNOT_SWIM - Amphibious creatures cannot toggle on swimming * implemented CREATURE_STATIC_FLAG_3_CANNOT_TURN - Creatures cannot turn at all * implemented CREATURE_STATIC_FLAG_4_PREVENT_SWIM - Amphibious creatures won't toggle on swimming until their victim starts leaving the ocean floor * partially implemented CREATURE_STATIC_FLAG_3_CANNOT_PENETRATE_WATER * deprecated CREATURE_FLAG_EXTRA_NO_MOVE_FLAGS_UPDATE as this flag was a hackfix to a wrong implementation that is now gone Port From (https://github.com/TrinityCore/TrinityCore/commit/c541eda54d7e0dddeec329a6beac2948e0b0a40b)
This commit is contained in:
@@ -72,7 +72,7 @@ namespace Framework.Constants
|
|||||||
Disallowed = (ServerControlled | NonAttackable | RemoveClientControl |
|
Disallowed = (ServerControlled | NonAttackable | RemoveClientControl |
|
||||||
PlayerControlled | Rename | Preparation | /* UNIT_FLAG_UNK_6 | */
|
PlayerControlled | Rename | Preparation | /* UNIT_FLAG_UNK_6 | */
|
||||||
NotAttackable1 | Looting | PetInCombat | PvpEnabling |
|
NotAttackable1 | Looting | PetInCombat | PvpEnabling |
|
||||||
NonAttackable2 | Pacified | Stunned |
|
CantSwim | CanSwim | NonAttackable2 | Pacified | Stunned |
|
||||||
InCombat | OnTaxi | Disarmed | Confused | Fleeing |
|
InCombat | OnTaxi | Disarmed | Confused | Fleeing |
|
||||||
Possessed | Skinnable | Mount | Unk28 |
|
Possessed | Skinnable | Mount | Unk28 |
|
||||||
PreventEmotesFromChatText | Sheathe | Immune),
|
PreventEmotesFromChatText | Sheathe | Immune),
|
||||||
@@ -118,7 +118,7 @@ namespace Framework.Constants
|
|||||||
Disallowed = (FeignDeath | IgnoreReputation | ComprehendLang |
|
Disallowed = (FeignDeath | IgnoreReputation | ComprehendLang |
|
||||||
MirrorImage | ForceMovement | DisarmOffhand |
|
MirrorImage | ForceMovement | DisarmOffhand |
|
||||||
DisablePredStats | AllowChangingTalents | DisarmRanged |
|
DisablePredStats | AllowChangingTalents | DisarmRanged |
|
||||||
/* UNIT_FLAG2_REGENERATE_POWER | */ RestrictPartyInteraction |
|
/* UNIT_FLAG2_REGENERATE_POWER | */ RestrictPartyInteraction | CannotTurn |
|
||||||
PreventSpellClick | /*InteractWhileHostile | */ /* Unk2 | */
|
PreventSpellClick | /*InteractWhileHostile | */ /* Unk2 | */
|
||||||
/* UNIT_FLAG2_PLAY_DEATH_ANIM | */ AllowCheatSpells | SuppressHighlightWhenTargetedOrMousedOver |
|
/* UNIT_FLAG2_PLAY_DEATH_ANIM | */ AllowCheatSpells | SuppressHighlightWhenTargetedOrMousedOver |
|
||||||
TreatAsRaidUnitForHelpfulSpells | LargeAoi | GiganticAoi | NoActions |
|
TreatAsRaidUnitForHelpfulSpells | LargeAoi | GiganticAoi | NoActions |
|
||||||
@@ -278,7 +278,7 @@ namespace Framework.Constants
|
|||||||
ImmuneToPc = 0x00000020, // UnitFlagImmuneToPc
|
ImmuneToPc = 0x00000020, // UnitFlagImmuneToPc
|
||||||
ImmuneToNpc = 0x00000040, // UnitFlagImmuneToNpc
|
ImmuneToNpc = 0x00000040, // UnitFlagImmuneToNpc
|
||||||
CanWieldLoot = 0x00000080,
|
CanWieldLoot = 0x00000080,
|
||||||
Sessile = 0x00000100, // CreatureTemplateMovement.Rooted = 1
|
Sessile = 0x00000100, // Rooted movementflag, creature is permanently rooted in place
|
||||||
Uninteractible = 0x00000200, // UnitFlagUninteractible
|
Uninteractible = 0x00000200, // UnitFlagUninteractible
|
||||||
NoAutomaticRegen = 0x00000400, // Creatures With That Flag Uses No UnitFlag2RegeneratePower
|
NoAutomaticRegen = 0x00000400, // Creatures With That Flag Uses No UnitFlag2RegeneratePower
|
||||||
DespawnInstantly = 0x00000800, // Creature Instantly Disappear When Killed
|
DespawnInstantly = 0x00000800, // Creature Instantly Disappear When Killed
|
||||||
@@ -289,7 +289,7 @@ namespace Framework.Constants
|
|||||||
BossMob = 0x00010000, // CreatureTypeFlagBossMob, Original Description: Raid Boss Mob
|
BossMob = 0x00010000, // CreatureTypeFlagBossMob, Original Description: Raid Boss Mob
|
||||||
CombatPing = 0x00020000,
|
CombatPing = 0x00020000,
|
||||||
Aquatic = 0x00040000, // Aka Water Only, CreatureTemplateMovement.Ground = 0
|
Aquatic = 0x00040000, // Aka Water Only, CreatureTemplateMovement.Ground = 0
|
||||||
Amphibious = 0x00080000, // CreatureTemplateMovement.Swim = 1
|
Amphibious = 0x00080000, // Creatures will be able to enter and leave water but can only move on the ocean floor when CREATURE_STATIC_FLAG_CAN_SWIM is not present
|
||||||
NoMeleeFlee = 0x00100000, // "No Melee (Flee)" Prevents melee (moves as-if feared, does not make creature passive)
|
NoMeleeFlee = 0x00100000, // "No Melee (Flee)" Prevents melee (moves as-if feared, does not make creature passive)
|
||||||
VisibleToGhosts = 0x00200000, // CreatureTypeFlagVisibleToGhosts
|
VisibleToGhosts = 0x00200000, // CreatureTypeFlagVisibleToGhosts
|
||||||
PvpEnabling = 0x00400000, // Old UnitFlagPvpEnabling, Now UnitBytes2OffsetPvpFlag From UnitFieldBytes2
|
PvpEnabling = 0x00400000, // Old UnitFlagPvpEnabling, Now UnitBytes2OffsetPvpFlag From UnitFieldBytes2
|
||||||
@@ -299,7 +299,7 @@ namespace Framework.Constants
|
|||||||
OnlyAttackPvpEnabling = 0x04000000, // "Only Attack Targets That Are Pvp Enabling"
|
OnlyAttackPvpEnabling = 0x04000000, // "Only Attack Targets That Are Pvp Enabling"
|
||||||
CallsGuards = 0x08000000, // Creature Will Summon A Guard If Player Is Within Its Aggro Range (Even If Creature Doesn'T Attack Per Se)
|
CallsGuards = 0x08000000, // Creature Will Summon A Guard If Player Is Within Its Aggro Range (Even If Creature Doesn'T Attack Per Se)
|
||||||
CanSwim = 0x10000000, // Unitflags 0x8000 UnitFlagCanSwim
|
CanSwim = 0x10000000, // Unitflags 0x8000 UnitFlagCanSwim
|
||||||
Floating = 0x20000000, // CreatureTemplateMovement.Flight = 1
|
Floating = 0x20000000, // sets DisableGravity movementflag on spawn/reset
|
||||||
MoreAudible = 0x40000000, // CreatureTypeFlagMoreAudible
|
MoreAudible = 0x40000000, // CreatureTypeFlagMoreAudible
|
||||||
LargeAoi = 0x80000000 // Unitflags2 0x200000
|
LargeAoi = 0x80000000 // Unitflags2 0x200000
|
||||||
}
|
}
|
||||||
@@ -526,7 +526,7 @@ namespace Framework.Constants
|
|||||||
NoXP = 0x40, // creature kill does not provide XP
|
NoXP = 0x40, // creature kill does not provide XP
|
||||||
Trigger = 0x80, // Trigger Creature
|
Trigger = 0x80, // Trigger Creature
|
||||||
NoTaunt = 0x100, // Creature Is Immune To Taunt Auras And 'attack me' effects
|
NoTaunt = 0x100, // Creature Is Immune To Taunt Auras And 'attack me' effects
|
||||||
NoMoveFlagsUpdate = 0x200, // Creature won't update movement flags
|
Unused9 = 0x200,
|
||||||
GhostVisibility = 0x400, // creature will only be visible to dead players
|
GhostVisibility = 0x400, // creature will only be visible to dead players
|
||||||
UseOffhandAttack = 0x800, // creature will use offhand attacks
|
UseOffhandAttack = 0x800, // creature will use offhand attacks
|
||||||
NoSellVendor = 0x1000, // players can't sell items to this vendor
|
NoSellVendor = 0x1000, // players can't sell items to this vendor
|
||||||
@@ -704,24 +704,6 @@ namespace Framework.Constants
|
|||||||
IdleInFormation = 0x200, // The member will follow the leader when pathing idly
|
IdleInFormation = 0x200, // The member will follow the leader when pathing idly
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum CreatureGroundMovementType
|
|
||||||
{
|
|
||||||
None,
|
|
||||||
Run,
|
|
||||||
Hover,
|
|
||||||
|
|
||||||
Max
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum CreatureFlightMovementType
|
|
||||||
{
|
|
||||||
None,
|
|
||||||
DisableGravity,
|
|
||||||
CanFly,
|
|
||||||
|
|
||||||
Max
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum CreatureChaseMovementType
|
public enum CreatureChaseMovementType
|
||||||
{
|
{
|
||||||
Run,
|
Run,
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ namespace Framework.Database
|
|||||||
PrepareStatement(WorldStatements.SEL_CREATURE_ADDON_BY_GUID, "SELECT guid FROM creature_addon WHERE guid = ?");
|
PrepareStatement(WorldStatements.SEL_CREATURE_ADDON_BY_GUID, "SELECT guid FROM creature_addon WHERE guid = ?");
|
||||||
PrepareStatement(WorldStatements.DEL_CREATURE, "DELETE FROM creature WHERE guid = ?");
|
PrepareStatement(WorldStatements.DEL_CREATURE, "DELETE FROM creature WHERE guid = ?");
|
||||||
PrepareStatement(WorldStatements.SEL_COMMANDS, "SELECT name, help FROM command");
|
PrepareStatement(WorldStatements.SEL_COMMANDS, "SELECT name, help FROM command");
|
||||||
PrepareStatement(WorldStatements.SEL_CREATURE_TEMPLATE, "SELECT entry, KillCredit1, KillCredit2, name, femaleName, subname, TitleAlt, IconName, RequiredExpansion, VignetteID, faction, npcflag, speed_walk, speed_run, scale, Classification, dmgschool, BaseAttackTime, RangeAttackTime, BaseVariance, RangeVariance, unit_class, unit_flags, unit_flags2, unit_flags3, family, trainer_class, type, VehicleId, AIName, MovementType, ctm.Ground, ctm.Swim, ctm.Flight, ctm.Rooted, ctm.Chase, ctm.Random, ctm.InteractionPauseTimer, ExperienceModifier, RacialLeader, movementId, WidgetSetID, WidgetSetUnitConditionID, RegenHealth, CreatureImmunitiesId, flags_extra, ScriptName, StringId FROM creature_template ct LEFT JOIN creature_template_movement ctm ON ct.entry = ctm.CreatureId WHERE entry = ? OR 1 = ?");
|
PrepareStatement(WorldStatements.SEL_CREATURE_TEMPLATE, "SELECT entry, KillCredit1, KillCredit2, name, femaleName, subname, TitleAlt, IconName, RequiredExpansion, VignetteID, faction, npcflag, speed_walk, speed_run, scale, Classification, dmgschool, BaseAttackTime, RangeAttackTime, BaseVariance, RangeVariance, unit_class, unit_flags, unit_flags2, unit_flags3, family, trainer_class, type, VehicleId, AIName, MovementType, ctm.HoverInitiallyEnabled, ctm.Chase, ctm.Random, ctm.InteractionPauseTimer, ExperienceModifier, RacialLeader, movementId, WidgetSetID, WidgetSetUnitConditionID, RegenHealth, CreatureImmunitiesId, flags_extra, ScriptName, StringId FROM creature_template ct LEFT JOIN creature_template_movement ctm ON ct.entry = ctm.CreatureId WHERE entry = ? OR 1 = ?");
|
||||||
PrepareStatement(WorldStatements.SEL_CREATURE_BY_ID, "SELECT guid FROM creature WHERE id = ?");
|
PrepareStatement(WorldStatements.SEL_CREATURE_BY_ID, "SELECT guid FROM creature WHERE id = ?");
|
||||||
PrepareStatement(WorldStatements.SEL_GAMEOBJECT_NEAREST, "SELECT guid, id, position_x, position_y, position_z, map, (POW(position_x - ?, 2) + POW(position_y - ?, 2) + POW(position_z - ?, 2)) AS order_ FROM gameobject WHERE map = ? AND (POW(position_x - ?, 2) + POW(position_y - ?, 2) + POW(position_z - ?, 2)) <= ? ORDER BY order_");
|
PrepareStatement(WorldStatements.SEL_GAMEOBJECT_NEAREST, "SELECT guid, id, position_x, position_y, position_z, map, (POW(position_x - ?, 2) + POW(position_y - ?, 2) + POW(position_z - ?, 2)) AS order_ FROM gameobject WHERE map = ? AND (POW(position_x - ?, 2) + POW(position_y - ?, 2) + POW(position_z - ?, 2)) <= ? ORDER BY order_");
|
||||||
PrepareStatement(WorldStatements.SEL_CREATURE_NEAREST, "SELECT guid, id, position_x, position_y, position_z, map, (POW(position_x - ?, 2) + POW(position_y - ?, 2) + POW(position_z - ?, 2)) AS order_ FROM creature WHERE map = ? AND (POW(position_x - ?, 2) + POW(position_y - ?, 2) + POW(position_z - ?, 2)) <= ? ORDER BY order_");
|
PrepareStatement(WorldStatements.SEL_CREATURE_NEAREST, "SELECT guid, id, position_x, position_y, position_z, map, (POW(position_x - ?, 2) + POW(position_y - ?, 2) + POW(position_z - ?, 2)) AS order_ FROM creature WHERE map = ? AND (POW(position_x - ?, 2) + POW(position_y - ?, 2) + POW(position_z - ?, 2)) <= ? ORDER BY order_");
|
||||||
|
|||||||
@@ -27,8 +27,6 @@ namespace Game.Entities
|
|||||||
// Regenerate health
|
// Regenerate health
|
||||||
bool _regenerateHealth; // Set on creation
|
bool _regenerateHealth; // Set on creation
|
||||||
|
|
||||||
bool _isMissingCanSwimFlagOutOfCombat;
|
|
||||||
|
|
||||||
uint? _defaultMountDisplayIdOverride;
|
uint? _defaultMountDisplayIdOverride;
|
||||||
int _creatureImmunitiesId;
|
int _creatureImmunitiesId;
|
||||||
uint _gossipMenuId;
|
uint _gossipMenuId;
|
||||||
|
|||||||
@@ -306,7 +306,7 @@ namespace Game.Entities
|
|||||||
|
|
||||||
SetFaction(cInfo.Faction);
|
SetFaction(cInfo.Faction);
|
||||||
|
|
||||||
ObjectManager.ChooseCreatureFlags(cInfo, out ulong npcFlags, out uint unitFlags, out uint unitFlags2, out uint unitFlags3, data);
|
ObjectManager.ChooseCreatureFlags(cInfo, out ulong npcFlags, out uint unitFlags, out uint unitFlags2, out uint unitFlags3, _staticFlags, data);
|
||||||
|
|
||||||
if (cInfo.FlagsExtra.HasAnyFlag(CreatureFlagsExtra.Worldevent))
|
if (cInfo.FlagsExtra.HasAnyFlag(CreatureFlagsExtra.Worldevent))
|
||||||
npcFlags |= Global.GameEventMgr.GetNPCFlag(this);
|
npcFlags |= Global.GameEventMgr.GetNPCFlag(this);
|
||||||
@@ -399,7 +399,7 @@ namespace Game.Entities
|
|||||||
|
|
||||||
SetIsCombatDisallowed(cInfo.FlagsExtra.HasFlag(CreatureFlagsExtra.CannotEnterCombat));
|
SetIsCombatDisallowed(cInfo.FlagsExtra.HasFlag(CreatureFlagsExtra.CannotEnterCombat));
|
||||||
|
|
||||||
InitializeMovementFlags();
|
InitializeMovementCapabilities();
|
||||||
|
|
||||||
LoadCreaturesAddon();
|
LoadCreaturesAddon();
|
||||||
LoadCreaturesSparringHealth();
|
LoadCreaturesSparringHealth();
|
||||||
@@ -419,7 +419,6 @@ namespace Game.Entities
|
|||||||
_staticFlags = flags;
|
_staticFlags = flags;
|
||||||
|
|
||||||
// Apply all other side effects of flag changes
|
// Apply all other side effects of flag changes
|
||||||
SetTemplateRooted(flags.HasFlag(CreatureStaticFlags.Sessile));
|
|
||||||
m_updateFlag.NoBirthAnim = flags.HasFlag(CreatureStaticFlags4.NoBirthAnim);
|
m_updateFlag.NoBirthAnim = flags.HasFlag(CreatureStaticFlags4.NoBirthAnim);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -437,7 +436,7 @@ namespace Game.Entities
|
|||||||
GetAI().JustAppeared();
|
GetAI().JustAppeared();
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateMovementFlags();
|
UpdateMovementCapabilities();
|
||||||
|
|
||||||
switch (m_deathState)
|
switch (m_deathState)
|
||||||
{
|
{
|
||||||
@@ -1062,8 +1061,6 @@ namespace Game.Entities
|
|||||||
if (!HasFlag(CreatureStaticFlags2.AllowMountedCombat))
|
if (!HasFlag(CreatureStaticFlags2.AllowMountedCombat))
|
||||||
Dismount();
|
Dismount();
|
||||||
|
|
||||||
RefreshCanSwimFlag();
|
|
||||||
|
|
||||||
if (IsPet() || IsGuardian()) // update pets' speed for catchup OOC speed
|
if (IsPet() || IsGuardian()) // update pets' speed for catchup OOC speed
|
||||||
{
|
{
|
||||||
UpdateSpeed(UnitMoveType.Run);
|
UpdateSpeed(UnitMoveType.Run);
|
||||||
@@ -1783,19 +1780,6 @@ namespace Game.Entities
|
|||||||
SetHealth((m_deathState == DeathState.Alive || m_deathState == DeathState.JustRespawned) ? curhealth : 0);
|
SetHealth((m_deathState == DeathState.Alive || m_deathState == DeathState.JustRespawned) ? curhealth : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoadTemplateRoot()
|
|
||||||
{
|
|
||||||
SetTemplateRooted(GetMovementTemplate().IsRooted());
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsTemplateRooted() { return _staticFlags.HasFlag(CreatureStaticFlags.Sessile); }
|
|
||||||
|
|
||||||
public void SetTemplateRooted(bool rooted)
|
|
||||||
{
|
|
||||||
_staticFlags.ApplyFlag(CreatureStaticFlags.Sessile, rooted);
|
|
||||||
SetControlled(rooted, UnitState.Root);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool HasQuest(uint questId)
|
public override bool HasQuest(uint questId)
|
||||||
{
|
{
|
||||||
return Global.ObjectMgr.GetCreatureQuestRelations(GetEntry()).HasQuest(questId);
|
return Global.ObjectMgr.GetCreatureQuestRelations(GetEntry()).HasQuest(questId);
|
||||||
@@ -2021,7 +2005,7 @@ namespace Game.Entities
|
|||||||
if (m_formation != null && m_formation.GetLeader() == this)
|
if (m_formation != null && m_formation.GetLeader() == this)
|
||||||
m_formation.FormationReset(true);
|
m_formation.FormationReset(true);
|
||||||
|
|
||||||
bool needsFalling = (IsFlying() || IsHovering()) && !IsUnderWater();
|
bool needsFalling = (IsFlying() || IsHovering()) && !IsUnderWater() && !HasUnitState(UnitState.Root);
|
||||||
SetHover(false, false);
|
SetHover(false, false);
|
||||||
SetDisableGravity(false, false);
|
SetDisableGravity(false, false);
|
||||||
|
|
||||||
@@ -2041,7 +2025,7 @@ namespace Game.Entities
|
|||||||
ResetPlayerDamageReq();
|
ResetPlayerDamageReq();
|
||||||
|
|
||||||
SetCannotReachTarget(false);
|
SetCannotReachTarget(false);
|
||||||
UpdateMovementFlags();
|
UpdateMovementCapabilities();
|
||||||
|
|
||||||
ClearUnitState(UnitState.AllErasable);
|
ClearUnitState(UnitState.AllErasable);
|
||||||
|
|
||||||
@@ -2050,7 +2034,7 @@ namespace Game.Entities
|
|||||||
CreatureData creatureData = GetCreatureData();
|
CreatureData creatureData = GetCreatureData();
|
||||||
CreatureTemplate cInfo = GetCreatureTemplate();
|
CreatureTemplate cInfo = GetCreatureTemplate();
|
||||||
|
|
||||||
ObjectManager.ChooseCreatureFlags(cInfo, out ulong npcFlags, out uint unitFlags, out uint unitFlags2, out uint unitFlags3, creatureData);
|
ObjectManager.ChooseCreatureFlags(cInfo, out ulong npcFlags, out uint unitFlags, out uint unitFlags2, out uint unitFlags3, _staticFlags, creatureData);
|
||||||
|
|
||||||
if (cInfo.FlagsExtra.HasAnyFlag(CreatureFlagsExtra.Worldevent))
|
if (cInfo.FlagsExtra.HasAnyFlag(CreatureFlagsExtra.Worldevent))
|
||||||
npcFlags |= Global.GameEventMgr.GetNPCFlag(this);
|
npcFlags |= Global.GameEventMgr.GetNPCFlag(this);
|
||||||
@@ -2500,7 +2484,7 @@ namespace Game.Entities
|
|||||||
dist += GetCombatReach() + victim.GetCombatReach();
|
dist += GetCombatReach() + victim.GetCombatReach();
|
||||||
|
|
||||||
// to prevent creatures in air ignore attacks because distance is already too high...
|
// to prevent creatures in air ignore attacks because distance is already too high...
|
||||||
if (GetMovementTemplate().IsFlightAllowed())
|
if (CanFly())
|
||||||
return victim.IsInDist2d(m_homePosition, dist);
|
return victim.IsInDist2d(m_homePosition, dist);
|
||||||
else
|
else
|
||||||
return victim.IsInDist(m_homePosition, dist);
|
return victim.IsInDist(m_homePosition, dist);
|
||||||
@@ -2525,23 +2509,15 @@ namespace Game.Entities
|
|||||||
CreatureAddon creatureAddon = GetCreatureAddon();
|
CreatureAddon creatureAddon = GetCreatureAddon();
|
||||||
if (creatureAddon == null)
|
if (creatureAddon == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
uint mountDisplayId = _defaultMountDisplayIdOverride.GetValueOrDefault(creatureAddon.mount);
|
uint mountDisplayId = _defaultMountDisplayIdOverride.GetValueOrDefault(creatureAddon.mount);
|
||||||
if ( mountDisplayId != 0)
|
if (mountDisplayId != 0)
|
||||||
Mount(creatureAddon.mount);
|
Mount(creatureAddon.mount);
|
||||||
|
|
||||||
SetStandState((UnitStandStateType)creatureAddon.standState);
|
SetStandState((UnitStandStateType)creatureAddon.standState);
|
||||||
ReplaceAllVisFlags((UnitVisFlags)creatureAddon.visFlags);
|
ReplaceAllVisFlags((UnitVisFlags)creatureAddon.visFlags);
|
||||||
SetAnimTier((AnimTier)creatureAddon.animTier, false);
|
SetAnimTier((AnimTier)creatureAddon.animTier, false);
|
||||||
|
|
||||||
//! Suspected correlation between UNIT_FIELD_BYTES_1, offset 3, value 0x2:
|
|
||||||
//! If no inhabittype_fly (if no MovementFlag_DisableGravity or MovementFlag_CanFly flag found in sniffs)
|
|
||||||
//! Check using InhabitType as movement flags are assigned dynamically
|
|
||||||
//! basing on whether the creature is in air or not
|
|
||||||
//! Set MovementFlag_Hover. Otherwise do nothing.
|
|
||||||
if (CanHover())
|
|
||||||
AddUnitMovementFlag(MovementFlag.Hover);
|
|
||||||
|
|
||||||
SetSheath((SheathState)creatureAddon.sheathState);
|
SetSheath((SheathState)creatureAddon.sheathState);
|
||||||
ReplaceAllPvpFlags((UnitPVPStateFlags)creatureAddon.pvpFlags);
|
ReplaceAllPvpFlags((UnitPVPStateFlags)creatureAddon.pvpFlags);
|
||||||
|
|
||||||
@@ -2686,52 +2662,38 @@ namespace Game.Entities
|
|||||||
|
|
||||||
bool IsSpawnedOnTransport() { return m_creatureData != null && m_creatureData.MapId != GetMapId(); }
|
bool IsSpawnedOnTransport() { return m_creatureData != null && m_creatureData.MapId != GetMapId(); }
|
||||||
|
|
||||||
void InitializeMovementFlags()
|
public void InitializeMovementCapabilities()
|
||||||
{
|
{
|
||||||
LoadTemplateRoot();
|
SetHover(GetMovementTemplate().IsHoverInitiallyEnabled());
|
||||||
|
SetDisableGravity(IsFloating());
|
||||||
|
SetControlled(IsSessile(), UnitState.Root);
|
||||||
|
|
||||||
// It does the same, for now
|
// If an amphibious creatures was swimming while engaged, disable swimming again
|
||||||
UpdateMovementFlags();
|
if (IsAmphibious() && !_staticFlags.HasFlag(CreatureStaticFlags.CanSwim))
|
||||||
|
RemoveUnitFlag(UnitFlags.CanSwim);
|
||||||
|
|
||||||
|
UpdateMovementCapabilities();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateMovementFlags()
|
public void UpdateMovementCapabilities()
|
||||||
{
|
{
|
||||||
// Do not update movement flags if creature is controlled by a player (charm/vehicle)
|
// Do not update movement flags if creature is controlled by a player (charm/vehicle)
|
||||||
if (m_playerMovingMe != null)
|
if (m_playerMovingMe != null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Creatures with CREATURE_FLAG_EXTRA_NO_MOVE_FLAGS_UPDATE should control MovementFlags in your own scripts
|
|
||||||
if (GetCreatureTemplate().FlagsExtra.HasAnyFlag(CreatureFlagsExtra.NoMoveFlagsUpdate))
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Set the movement flags if the creature is in that mode. (Only fly if actually in air, only swim if in water, etc)
|
// Set the movement flags if the creature is in that mode. (Only fly if actually in air, only swim if in water, etc)
|
||||||
float ground = GetFloorZ();
|
float ground = GetFloorZ();
|
||||||
|
|
||||||
bool canHover = CanHover();
|
bool isInAir = (MathFunctions.fuzzyGt(GetPositionZ(), ground + GetHoverOffset() + MapConst.GroundHeightTolerance) || MathFunctions.fuzzyLt(GetPositionZ(), ground - MapConst.GroundHeightTolerance)); // Can be underground too, prevent the falling
|
||||||
bool isInAir = (MathFunctions.fuzzyGt(GetPositionZ(), ground + (canHover ? m_unitData.HoverHeight : 0.0f) + MapConst.GroundHeightTolerance) || MathFunctions.fuzzyLt(GetPositionZ(), ground - MapConst.GroundHeightTolerance)); // Can be underground too, prevent the falling
|
|
||||||
|
|
||||||
if (GetMovementTemplate().IsFlightAllowed() && (isInAir || !GetMovementTemplate().IsGroundAllowed()) && !IsFalling())
|
|
||||||
{
|
|
||||||
if (GetMovementTemplate().Flight == CreatureFlightMovementType.CanFly)
|
|
||||||
SetCanFly(true);
|
|
||||||
else
|
|
||||||
SetDisableGravity(true);
|
|
||||||
|
|
||||||
if (!HasAuraType(AuraType.Hover) && GetMovementTemplate().Ground != CreatureGroundMovementType.Hover)
|
|
||||||
SetHover(false);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SetCanFly(false);
|
|
||||||
SetDisableGravity(false);
|
|
||||||
if (IsAlive() && (CanHover() || HasAuraType(AuraType.Hover)))
|
|
||||||
SetHover(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isInAir)
|
if (!isInAir)
|
||||||
SetFall(false);
|
SetFall(false);
|
||||||
|
|
||||||
SetSwim(CanSwim() && IsInWater());
|
// Some Amphibious creatures toggle swimming while engaged
|
||||||
|
if (IsAmphibious() && !HasUnitFlag(UnitFlags.CantSwim) && !HasUnitFlag(UnitFlags.CanSwim))
|
||||||
|
if (!IsSwimPrevented() || (GetVictim() != null && !GetVictim().IsOnOceanFloor()))
|
||||||
|
SetUnitFlag(UnitFlags.CanSwim);
|
||||||
|
|
||||||
|
SetSwim(IsInWater() && CanSwim());
|
||||||
}
|
}
|
||||||
|
|
||||||
public CreatureMovementData GetMovementTemplate()
|
public CreatureMovementData GetMovementTemplate()
|
||||||
@@ -2754,29 +2716,7 @@ namespace Game.Entities
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool CanEnterWater()
|
public override bool CanEnterWater() { return CanSwim() || IsAmphibious(); }
|
||||||
{
|
|
||||||
if (CanSwim())
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return GetMovementTemplate().IsSwimAllowed();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RefreshCanSwimFlag(bool recheck = false)
|
|
||||||
{
|
|
||||||
if (!_isMissingCanSwimFlagOutOfCombat || recheck)
|
|
||||||
_isMissingCanSwimFlagOutOfCombat = !HasUnitFlag(UnitFlags.CanSwim);
|
|
||||||
|
|
||||||
// Check if the creature has UNIT_FLAG_CAN_SWIM and add it if it's missing
|
|
||||||
// Creatures must be able to chase a target in water if they can enter water
|
|
||||||
if (_isMissingCanSwimFlagOutOfCombat && CanEnterWater())
|
|
||||||
SetUnitFlag(UnitFlags.CanSwim);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool HasCanSwimFlagOutOfCombat()
|
|
||||||
{
|
|
||||||
return !_isMissingCanSwimFlagOutOfCombat;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void AllLootRemovedFromCorpse()
|
public void AllLootRemovedFromCorpse()
|
||||||
{
|
{
|
||||||
@@ -3384,9 +3324,28 @@ namespace Game.Entities
|
|||||||
return GetCreatureTemplate().FlagsExtra.HasAnyFlag(CreatureFlagsExtra.Guard);
|
return GetCreatureTemplate().FlagsExtra.HasAnyFlag(CreatureFlagsExtra.Guard);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool CanWalk() { return GetMovementTemplate().IsGroundAllowed(); }
|
// Returns true if CREATURE_STATIC_FLAG_AQUATIC is set which strictly binds the creature to liquids
|
||||||
public override bool CanFly() { return GetMovementTemplate().IsFlightAllowed() || IsFlying(); }
|
public bool IsAquatic() { return _staticFlags.HasFlag(CreatureStaticFlags.Aquatic); }
|
||||||
bool CanHover() { return GetMovementTemplate().Ground == CreatureGroundMovementType.Hover || IsHovering(); }
|
|
||||||
|
// Returns true if CREATURE_STATIC_FLAG_AMPHIBIOUS is set which allows a creature to enter and leave liquids while sticking to the ocean floor. These creatures will become able to swim when engaged
|
||||||
|
public bool IsAmphibious() { return _staticFlags.HasFlag(CreatureStaticFlags.Amphibious); }
|
||||||
|
|
||||||
|
// Returns true if CREATURE_STATIC_FLAG_FLOATING is set which is disabling the gravity of the creature on spawn and reset
|
||||||
|
public bool IsFloating() { return _staticFlags.HasFlag(CreatureStaticFlags.Floating); }
|
||||||
|
|
||||||
|
// Returns true if CREATURE_STATIC_FLAG_SESSILE is set which permanently roots the creature in place
|
||||||
|
public bool IsSessile() { return _staticFlags.HasFlag(CreatureStaticFlags.Sessile); }
|
||||||
|
|
||||||
|
// Returns true if CREATURE_STATIC_FLAG_3_CANNOT_PENETRATE_WATER is set which does not allow the creature to go below liquid surfaces
|
||||||
|
public bool CannotPenetrateWater() { return _staticFlags.HasFlag(CreatureStaticFlags3.CannotPenetrateWater); }
|
||||||
|
|
||||||
|
// Returns true if CREATURE_STATIC_FLAG_3_CANNOT_SWIM is set which prevents 'Amphibious' creatures from swimming when engaged
|
||||||
|
public bool IsSwimDisabled() { return _staticFlags.HasFlag(CreatureStaticFlags3.CannotSwim); }
|
||||||
|
|
||||||
|
// Returns true if CREATURE_STATIC_FLAG_4_PREVENT_SWIM is set which prevents 'Amphibious' creatures from swimming when engaged until the victim is no longer on the ocean floor
|
||||||
|
public bool IsSwimPrevented() { return _staticFlags.HasFlag(CreatureStaticFlags4.PreventSwim); }
|
||||||
|
|
||||||
|
public override bool CanFly() { return IsFlying() || HasUnitMovementFlag(MovementFlag.CanFly); }
|
||||||
|
|
||||||
public bool IsDungeonBoss() { return (GetCreatureTemplate().FlagsExtra.HasAnyFlag(CreatureFlagsExtra.DungeonBoss)); }
|
public bool IsDungeonBoss() { return (GetCreatureTemplate().FlagsExtra.HasAnyFlag(CreatureFlagsExtra.DungeonBoss)); }
|
||||||
public override bool IsAffectedByDiminishingReturns() { return base.IsAffectedByDiminishingReturns() || GetCreatureTemplate().FlagsExtra.HasAnyFlag(CreatureFlagsExtra.AllDiminish); }
|
public override bool IsAffectedByDiminishingReturns() { return base.IsAffectedByDiminishingReturns() || GetCreatureTemplate().FlagsExtra.HasAnyFlag(CreatureFlagsExtra.AllDiminish); }
|
||||||
|
|||||||
@@ -279,38 +279,28 @@ namespace Game.Entities
|
|||||||
|
|
||||||
public class CreatureMovementData
|
public class CreatureMovementData
|
||||||
{
|
{
|
||||||
public CreatureGroundMovementType Ground;
|
public bool HoverInitiallyEnabled;
|
||||||
public CreatureFlightMovementType Flight;
|
|
||||||
public bool Swim;
|
|
||||||
public bool Rooted;
|
|
||||||
public CreatureChaseMovementType Chase;
|
public CreatureChaseMovementType Chase;
|
||||||
public CreatureRandomMovementType Random;
|
public CreatureRandomMovementType Random;
|
||||||
public uint InteractionPauseTimer;
|
public uint InteractionPauseTimer;
|
||||||
|
|
||||||
public CreatureMovementData()
|
public CreatureMovementData()
|
||||||
{
|
{
|
||||||
Ground = CreatureGroundMovementType.Run;
|
|
||||||
Flight = CreatureFlightMovementType.None;
|
|
||||||
Swim = true;
|
|
||||||
Rooted = false;
|
|
||||||
Chase = CreatureChaseMovementType.Run;
|
Chase = CreatureChaseMovementType.Run;
|
||||||
Random = CreatureRandomMovementType.Walk;
|
Random = CreatureRandomMovementType.Walk;
|
||||||
InteractionPauseTimer = WorldConfig.GetUIntValue(WorldCfg.CreatureStopForPlayer);
|
InteractionPauseTimer = WorldConfig.GetUIntValue(WorldCfg.CreatureStopForPlayer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsGroundAllowed() { return Ground != CreatureGroundMovementType.None; }
|
|
||||||
public bool IsSwimAllowed() { return Swim; }
|
|
||||||
public bool IsFlightAllowed() { return Flight != CreatureFlightMovementType.None; }
|
|
||||||
public bool IsRooted() { return Rooted; }
|
|
||||||
|
|
||||||
public CreatureChaseMovementType GetChase() { return Chase; }
|
public CreatureChaseMovementType GetChase() { return Chase; }
|
||||||
public CreatureRandomMovementType GetRandom() { return Random; }
|
public CreatureRandomMovementType GetRandom() { return Random; }
|
||||||
|
|
||||||
|
public bool IsHoverInitiallyEnabled() { return HoverInitiallyEnabled; }
|
||||||
|
|
||||||
public uint GetInteractionPauseTimer() { return InteractionPauseTimer; }
|
public uint GetInteractionPauseTimer() { return InteractionPauseTimer; }
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return $"Ground: {Ground}, Swim: {Swim}, Flight: {Flight} {(Rooted ? ", Rooted" : "")}, Chase: {Chase}, Random: {Random}, InteractionPauseTimer: {InteractionPauseTimer}";
|
return $"HoverInitiallyEnabled: {HoverInitiallyEnabled}, Chase: {Chase}, Random: {Random}, InteractionPauseTimer: {InteractionPauseTimer}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3752,7 +3752,18 @@ namespace Game.Entities
|
|||||||
|
|
||||||
public float GetMapWaterOrGroundLevel(float x, float y, float z, ref float ground)
|
public float GetMapWaterOrGroundLevel(float x, float y, float z, ref float ground)
|
||||||
{
|
{
|
||||||
return GetMap().GetWaterOrGroundLevel(GetPhaseShift(), x, y, z, ref ground, IsTypeMask(TypeMask.Unit) ? !ToUnit().HasAuraType(AuraType.WaterWalk) : false, GetCollisionHeight());
|
bool swimming = true;
|
||||||
|
Creature creature = ToCreature();
|
||||||
|
if (creature != null)
|
||||||
|
swimming = !creature.CannotPenetrateWater() && !creature.HasAuraType(AuraType.WaterWalk);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Unit unit = ToUnit();
|
||||||
|
if (unit != null)
|
||||||
|
swimming = !unit.HasAuraType(AuraType.WaterWalk);
|
||||||
|
}
|
||||||
|
|
||||||
|
return GetMap().GetWaterOrGroundLevel(GetPhaseShift(), x, y, z, ref ground, swimming, GetCollisionHeight());
|
||||||
}
|
}
|
||||||
|
|
||||||
public float GetMapHeight(float x, float y, float z, bool vmap = true, float distanceToSearch = MapConst.DefaultHeightSearch)
|
public float GetMapHeight(float x, float y, float z, bool vmap = true, float distanceToSearch = MapConst.DefaultHeightSearch)
|
||||||
|
|||||||
@@ -750,7 +750,7 @@ namespace Game.Entities
|
|||||||
SendMessageToSet(packet, true);
|
SendMessageToSet(packet, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsCreature() && updateAnimTier && IsAlive() && !HasUnitState(UnitState.Root) && !ToCreature().IsTemplateRooted())
|
if (IsCreature() && updateAnimTier && IsAlive() && !HasUnitState(UnitState.Root))
|
||||||
{
|
{
|
||||||
if (IsGravityDisabled())
|
if (IsGravityDisabled())
|
||||||
SetAnimTier(AnimTier.Fly);
|
SetAnimTier(AnimTier.Fly);
|
||||||
@@ -1138,7 +1138,7 @@ namespace Game.Entities
|
|||||||
SendMessageToSet(packet, true);
|
SendMessageToSet(packet, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsCreature() && updateAnimTier && IsAlive() && !HasUnitState(UnitState.Root) && !ToCreature().IsTemplateRooted())
|
if (IsCreature() && updateAnimTier && IsAlive() && !HasUnitState(UnitState.Root))
|
||||||
{
|
{
|
||||||
if (IsGravityDisabled())
|
if (IsGravityDisabled())
|
||||||
SetAnimTier(AnimTier.Fly);
|
SetAnimTier(AnimTier.Fly);
|
||||||
@@ -1186,12 +1186,25 @@ namespace Game.Entities
|
|||||||
{
|
{
|
||||||
return IsWithinDistInMap(target, distance) && !HasInArc(MathFunctions.TwoPi - arc, target);
|
return IsWithinDistInMap(target, distance) && !HasInArc(MathFunctions.TwoPi - arc, target);
|
||||||
}
|
}
|
||||||
public bool IsInAccessiblePlaceFor(Creature c)
|
public bool IsInAccessiblePlaceFor(Creature creature)
|
||||||
{
|
{
|
||||||
if (IsInWater())
|
// Aquatic creatures are not allowed to leave liquids
|
||||||
return c.CanEnterWater();
|
if (!IsInWater() && creature.IsAquatic())
|
||||||
else
|
return false;
|
||||||
return c.CanWalk() || c.CanFly();
|
|
||||||
|
// Underwater special case. Some creatures may not go below liquid surfaces
|
||||||
|
if (IsUnderWater() && creature.CannotPenetrateWater())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Water checks
|
||||||
|
if (IsInWater() && !creature.CanEnterWater())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Some creatures are tied to the ocean floor and cannot chase swimming targets.
|
||||||
|
if (!IsOnOceanFloor() && creature.IsUnderWater() && creature.HasUnitFlag(UnitFlags.CantSwim))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void NearTeleportTo(float x, float y, float z, float orientation, bool casting = false) { NearTeleportTo(new Position(x, y, z, orientation), casting); }
|
public void NearTeleportTo(float x, float y, float z, float orientation, bool casting = false) { NearTeleportTo(new Position(x, y, z, orientation), casting); }
|
||||||
@@ -1274,7 +1287,7 @@ namespace Game.Entities
|
|||||||
SetStunned(false);
|
SetStunned(false);
|
||||||
break;
|
break;
|
||||||
case UnitState.Root:
|
case UnitState.Root:
|
||||||
if (HasAuraType(AuraType.ModRoot) || HasAuraType(AuraType.ModRoot2) || HasAuraType(AuraType.ModRootDisableGravity) || GetVehicle() != null || (IsCreature() && ToCreature().IsTemplateRooted()))
|
if (HasAuraType(AuraType.ModRoot) || HasAuraType(AuraType.ModRoot2) || HasAuraType(AuraType.ModRootDisableGravity) || GetVehicle() != null || (IsCreature() && ToCreature().IsSessile()))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ClearUnitState(state);
|
ClearUnitState(state);
|
||||||
|
|||||||
@@ -412,10 +412,6 @@ namespace Game.Entities
|
|||||||
|
|
||||||
AddUnitState(UnitState.Charmed);
|
AddUnitState(UnitState.Charmed);
|
||||||
|
|
||||||
Creature creature = ToCreature();
|
|
||||||
if (creature != null)
|
|
||||||
creature.RefreshCanSwimFlag();
|
|
||||||
|
|
||||||
if (!IsPlayer() || !charmer.IsPlayer())
|
if (!IsPlayer() || !charmer.IsPlayer())
|
||||||
{
|
{
|
||||||
// AI will schedule its own change if appropriate
|
// AI will schedule its own change if appropriate
|
||||||
|
|||||||
@@ -84,11 +84,20 @@ namespace Game
|
|||||||
return cinfo.GetFirstInvisibleModel();
|
return cinfo.GetFirstInvisibleModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ChooseCreatureFlags(CreatureTemplate cInfo, out ulong npcFlag, out uint unitFlags, out uint unitFlags2, out uint unitFlags3, CreatureData data = null)
|
public static void ChooseCreatureFlags(CreatureTemplate cInfo, out ulong npcFlag, out uint unitFlags, out uint unitFlags2, out uint unitFlags3, CreatureStaticFlagsHolder staticFlags, CreatureData data = null)
|
||||||
{
|
{
|
||||||
npcFlag = data != null && data.npcflag.HasValue ? data.npcflag.Value : cInfo.Npcflag;
|
npcFlag = data != null && data.npcflag.HasValue ? data.npcflag.Value : cInfo.Npcflag;
|
||||||
|
|
||||||
unitFlags = data != null && data.unit_flags.HasValue ? data.unit_flags.Value : (uint)cInfo.UnitFlags;
|
unitFlags = data != null && data.unit_flags.HasValue ? data.unit_flags.Value : (uint)cInfo.UnitFlags;
|
||||||
|
if (staticFlags.HasFlag(CreatureStaticFlags.CanSwim))
|
||||||
|
unitFlags |= (uint)UnitFlags.CanSwim;
|
||||||
|
if (staticFlags.HasFlag(CreatureStaticFlags3.CannotSwim))
|
||||||
|
unitFlags |= (uint)UnitFlags.CantSwim;
|
||||||
|
|
||||||
unitFlags2 = data != null && data.unit_flags2.HasValue ? data.unit_flags2.Value : cInfo.UnitFlags2;
|
unitFlags2 = data != null && data.unit_flags2.HasValue ? data.unit_flags2.Value : cInfo.UnitFlags2;
|
||||||
|
if (staticFlags.HasFlag(CreatureStaticFlags3.CannotTurn))
|
||||||
|
unitFlags2 |= (uint)UnitFlags2.CannotTurn;
|
||||||
|
|
||||||
unitFlags3 = data != null && data.unit_flags3.HasValue ? data.unit_flags3.Value : cInfo.UnitFlags3;
|
unitFlags3 = data != null && data.unit_flags3.HasValue ? data.unit_flags3.Value : cInfo.UnitFlags3;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1814,36 +1823,27 @@ namespace Game
|
|||||||
creature.MovementType = fields.Read<uint>(30);
|
creature.MovementType = fields.Read<uint>(30);
|
||||||
|
|
||||||
if (!fields.IsNull(31))
|
if (!fields.IsNull(31))
|
||||||
creature.Movement.Ground = (CreatureGroundMovementType)fields.Read<byte>(31);
|
creature.Movement.HoverInitiallyEnabled = fields.Read<bool>(31);
|
||||||
|
|
||||||
if (!fields.IsNull(32))
|
if (!fields.IsNull(32))
|
||||||
creature.Movement.Swim = fields.Read<bool>(32);
|
creature.Movement.Chase = (CreatureChaseMovementType)fields.Read<byte>(32);
|
||||||
|
|
||||||
if (!fields.IsNull(33))
|
if (!fields.IsNull(33))
|
||||||
creature.Movement.Flight = (CreatureFlightMovementType)fields.Read<byte>(33);
|
creature.Movement.Random = (CreatureRandomMovementType)fields.Read<byte>(33);
|
||||||
|
|
||||||
if (!fields.IsNull(34))
|
if (!fields.IsNull(34))
|
||||||
creature.Movement.Rooted = fields.Read<bool>(34);
|
creature.Movement.InteractionPauseTimer = fields.Read<uint>(34);
|
||||||
|
|
||||||
if (!fields.IsNull(35))
|
creature.ModExperience = fields.Read<float>(35);
|
||||||
creature.Movement.Chase = (CreatureChaseMovementType)fields.Read<byte>(35);
|
creature.RacialLeader = fields.Read<bool>(36);
|
||||||
|
creature.MovementId = fields.Read<uint>(37);
|
||||||
if (!fields.IsNull(36))
|
creature.WidgetSetID = fields.Read<int>(38);
|
||||||
creature.Movement.Random = (CreatureRandomMovementType)fields.Read<byte>(36);
|
creature.WidgetSetUnitConditionID = fields.Read<int>(39);
|
||||||
|
creature.RegenHealth = fields.Read<bool>(40);
|
||||||
if (!fields.IsNull(37))
|
creature.CreatureImmunitiesId = fields.Read<int>(41);
|
||||||
creature.Movement.InteractionPauseTimer = fields.Read<uint>(37);
|
creature.FlagsExtra = (CreatureFlagsExtra)fields.Read<uint>(42);
|
||||||
|
creature.ScriptID = GetScriptId(fields.Read<string>(43));
|
||||||
creature.ModExperience = fields.Read<float>(38);
|
creature.StringId = fields.Read<string>(44);
|
||||||
creature.RacialLeader = fields.Read<bool>(39);
|
|
||||||
creature.MovementId = fields.Read<uint>(40);
|
|
||||||
creature.WidgetSetID = fields.Read<int>(41);
|
|
||||||
creature.WidgetSetUnitConditionID = fields.Read<int>(42);
|
|
||||||
creature.RegenHealth = fields.Read<bool>(43);
|
|
||||||
creature.CreatureImmunitiesId = fields.Read<int>(44);
|
|
||||||
creature.FlagsExtra = (CreatureFlagsExtra)fields.Read<uint>(45);
|
|
||||||
creature.ScriptID = GetScriptId(fields.Read<string>(46));
|
|
||||||
creature.StringId = fields.Read<string>(47);
|
|
||||||
|
|
||||||
creatureTemplateStorage[entry] = creature;
|
creatureTemplateStorage[entry] = creature;
|
||||||
}
|
}
|
||||||
@@ -2504,7 +2504,7 @@ namespace Game
|
|||||||
creatureMovementOverrides.Clear();
|
creatureMovementOverrides.Clear();
|
||||||
|
|
||||||
// Load the data from creature_movement_override and if NULL fallback to creature_template_movement
|
// Load the data from creature_movement_override and if NULL fallback to creature_template_movement
|
||||||
SQLResult result = DB.World.Query("SELECT cmo.SpawnId,COALESCE(cmo.Ground, ctm.Ground),COALESCE(cmo.Swim, ctm.Swim),COALESCE(cmo.Flight, ctm.Flight),COALESCE(cmo.Rooted, ctm.Rooted),COALESCE(cmo.Chase, ctm.Chase),COALESCE(cmo.Random, ctm.Random)," +
|
SQLResult result = DB.World.Query("SELECT cmo.SpawnId,COALESCE(cmo.HoverInitiallyEnabled, ctm.HoverInitiallyEnabled),COALESCE(cmo.Chase, ctm.Chase),COALESCE(cmo.Random, ctm.Random)," +
|
||||||
"COALESCE(cmo.InteractionPauseTimer, ctm.InteractionPauseTimer) FROM creature_movement_override AS cmo LEFT JOIN creature AS c ON c.guid = cmo.SpawnId LEFT JOIN creature_template_movement AS ctm ON ctm.CreatureId = c.id");
|
"COALESCE(cmo.InteractionPauseTimer, ctm.InteractionPauseTimer) FROM creature_movement_override AS cmo LEFT JOIN creature AS c ON c.guid = cmo.SpawnId LEFT JOIN creature_template_movement AS ctm ON ctm.CreatureId = c.id");
|
||||||
|
|
||||||
if (result.IsEmpty())
|
if (result.IsEmpty())
|
||||||
@@ -2524,19 +2524,13 @@ namespace Game
|
|||||||
|
|
||||||
CreatureMovementData movement = new();
|
CreatureMovementData movement = new();
|
||||||
if (!result.IsNull(1))
|
if (!result.IsNull(1))
|
||||||
movement.Ground = (CreatureGroundMovementType)result.Read<byte>(1);
|
movement.HoverInitiallyEnabled = result.Read<bool>(1);
|
||||||
if (!result.IsNull(2))
|
if (!result.IsNull(2))
|
||||||
movement.Swim = result.Read<bool>(2);
|
movement.Chase = (CreatureChaseMovementType)result.Read<byte>(2);
|
||||||
if (!result.IsNull(3))
|
if (!result.IsNull(3))
|
||||||
movement.Flight = (CreatureFlightMovementType)result.Read<byte>(3);
|
movement.Random = (CreatureRandomMovementType)result.Read<byte>(3);
|
||||||
if (!result.IsNull(4))
|
if (!result.IsNull(4))
|
||||||
movement.Rooted = result.Read<bool>(4);
|
movement.InteractionPauseTimer = result.Read<uint>(4);
|
||||||
if (!result.IsNull(5))
|
|
||||||
movement.Chase = (CreatureChaseMovementType)result.Read<byte>(5);
|
|
||||||
if (!result.IsNull(6))
|
|
||||||
movement.Random = (CreatureRandomMovementType)result.Read<byte>(6);
|
|
||||||
if (!result.IsNull(7))
|
|
||||||
movement.InteractionPauseTimer = result.Read<uint>(7);
|
|
||||||
|
|
||||||
CheckCreatureMovement("creature_movement_override", spawnId, movement);
|
CheckCreatureMovement("creature_movement_override", spawnId, movement);
|
||||||
|
|
||||||
@@ -2903,18 +2897,6 @@ namespace Game
|
|||||||
}
|
}
|
||||||
void CheckCreatureMovement(string table, ulong id, CreatureMovementData creatureMovement)
|
void CheckCreatureMovement(string table, ulong id, CreatureMovementData creatureMovement)
|
||||||
{
|
{
|
||||||
if (creatureMovement.Ground >= CreatureGroundMovementType.Max)
|
|
||||||
{
|
|
||||||
Log.outError(LogFilter.Sql, $"`{table}`.`Ground` wrong value ({creatureMovement.Ground}) for Id {id}, setting to Run.");
|
|
||||||
creatureMovement.Ground = CreatureGroundMovementType.Run;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (creatureMovement.Flight >= CreatureFlightMovementType.Max)
|
|
||||||
{
|
|
||||||
Log.outError(LogFilter.Sql, $"`{table}`.`Flight` wrong value ({creatureMovement.Flight}) for Id {id}, setting to None.");
|
|
||||||
creatureMovement.Flight = CreatureFlightMovementType.None;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (creatureMovement.Chase >= CreatureChaseMovementType.Max)
|
if (creatureMovement.Chase >= CreatureChaseMovementType.Max)
|
||||||
{
|
{
|
||||||
Log.outError(LogFilter.Sql, $"`{table}`.`Chase` wrong value ({creatureMovement.Chase}) for Id {id}, setting to Run.");
|
Log.outError(LogFilter.Sql, $"`{table}`.`Chase` wrong value ({creatureMovement.Chase}) for Id {id}, setting to Run.");
|
||||||
|
|||||||
@@ -60,11 +60,9 @@ namespace Game.AI
|
|||||||
|
|
||||||
if (movementInform && HasFlag(MovementGeneratorFlags.InformEnabled))
|
if (movementInform && HasFlag(MovementGeneratorFlags.InformEnabled))
|
||||||
{
|
{
|
||||||
if (!owner.HasCanSwimFlagOutOfCombat())
|
|
||||||
owner.RemoveUnitFlag(UnitFlags.CanSwim);
|
|
||||||
|
|
||||||
if (owner.IsStateRestoredOnEvade())
|
if (owner.IsStateRestoredOnEvade())
|
||||||
{
|
{
|
||||||
|
owner.InitializeMovementCapabilities();
|
||||||
owner.SetSpawnHealth();
|
owner.SetSpawnHealth();
|
||||||
owner.LoadCreaturesAddon();
|
owner.LoadCreaturesAddon();
|
||||||
owner.LoadCreaturesSparringHealth();
|
owner.LoadCreaturesSparringHealth();
|
||||||
|
|||||||
@@ -155,7 +155,7 @@ namespace Game.Movement
|
|||||||
BuildShortcut();
|
BuildShortcut();
|
||||||
bool path = _source.IsTypeId(TypeId.Unit) && _source.ToCreature().CanFly();
|
bool path = _source.IsTypeId(TypeId.Unit) && _source.ToCreature().CanFly();
|
||||||
|
|
||||||
bool waterPath = _source.IsTypeId(TypeId.Unit) && _source.ToCreature().CanSwim();
|
bool waterPath = _source.IsTypeId(TypeId.Unit) && _source.ToCreature().CanEnterWater();
|
||||||
if (waterPath)
|
if (waterPath)
|
||||||
{
|
{
|
||||||
// Check both start and end points, if they're both in water, then we can *safely* let the creature move
|
// Check both start and end points, if they're both in water, then we can *safely* let the creature move
|
||||||
@@ -850,7 +850,7 @@ namespace Game.Movement
|
|||||||
if (_source.IsTypeId(TypeId.Unit))
|
if (_source.IsTypeId(TypeId.Unit))
|
||||||
{
|
{
|
||||||
Creature creature = _source.ToCreature();
|
Creature creature = _source.ToCreature();
|
||||||
if (creature.CanWalk())
|
if (!creature.IsAquatic())
|
||||||
includeFlags |= NavTerrainFlag.Ground;
|
includeFlags |= NavTerrainFlag.Ground;
|
||||||
|
|
||||||
// creatures don't take environmental damage
|
// creatures don't take environmental damage
|
||||||
|
|||||||
@@ -2531,10 +2531,7 @@ namespace Game.Spells
|
|||||||
target.SetControlled(apply, UnitState.Root);
|
target.SetControlled(apply, UnitState.Root);
|
||||||
|
|
||||||
// Do not remove DisableGravity if there are more than this auraEffect of that kind on the unit or if it's a creature with DisableGravity on its movement template.
|
// Do not remove DisableGravity if there are more than this auraEffect of that kind on the unit or if it's a creature with DisableGravity on its movement template.
|
||||||
if (!apply
|
if (!apply && (target.HasAuraType(GetAuraType()) || target.HasAuraType(AuraType.ModRootDisableGravity) || (target.IsCreature() && target.ToCreature().IsFloating())))
|
||||||
&& (target.HasAuraType(GetAuraType())
|
|
||||||
|| target.HasAuraType(AuraType.ModStunDisableGravity)
|
|
||||||
|| (target.IsCreature() && target.ToCreature().GetMovementTemplate().Flight == CreatureFlightMovementType.DisableGravity)))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (target.SetDisableGravity(apply))
|
if (target.SetDisableGravity(apply))
|
||||||
@@ -2556,10 +2553,7 @@ namespace Game.Spells
|
|||||||
target.GetThreatManager().EvaluateSuppressed();
|
target.GetThreatManager().EvaluateSuppressed();
|
||||||
|
|
||||||
// Do not remove DisableGravity if there are more than this auraEffect of that kind on the unit or if it's a creature with DisableGravity on its movement template.
|
// Do not remove DisableGravity if there are more than this auraEffect of that kind on the unit or if it's a creature with DisableGravity on its movement template.
|
||||||
if (!apply
|
if (!apply && (target.HasAuraType(GetAuraType()) || target.HasAuraType(AuraType.ModStunDisableGravity) || (target.IsCreature() && target.ToCreature().IsFloating())))
|
||||||
&& (target.HasAuraType(GetAuraType())
|
|
||||||
|| target.HasAuraType(AuraType.ModStunDisableGravity)
|
|
||||||
|| (target.IsCreature() && target.ToCreature().GetMovementTemplate().Flight == CreatureFlightMovementType.DisableGravity)))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (target.SetDisableGravity(apply))
|
if (target.SetDisableGravity(apply))
|
||||||
|
|||||||
@@ -0,0 +1,80 @@
|
|||||||
|
-- Convert existing data to static flags. There may be some errors in conversion due to dirty unit flag that that's been dumped into the DB which needs manual fixups
|
||||||
|
|
||||||
|
-- CREATURE_STATIC_FLAG_CAN_SWIM
|
||||||
|
UPDATE `creature_template_difficulty` AS ctd LEFT JOIN `creature_template` AS ct ON ct.`entry` = ctd.`Entry`
|
||||||
|
SET ctd.`StaticFlags1`= ctd.`StaticFlags1` | 0x10000000
|
||||||
|
WHERE (ct.`unit_flags` & 0x00008000) != 0;
|
||||||
|
|
||||||
|
UPDATE `creature_template_difficulty` AS ctd LEFT JOIN `creature_template` AS ct ON ct.`entry` = ctd.`Entry`
|
||||||
|
SET ctd.`StaticFlags1`= ctd.`StaticFlags1` &~ 0x00000100
|
||||||
|
WHERE (ct.`unit_flags` & 0x00008000) != 0;
|
||||||
|
|
||||||
|
-- CREATURE_STATIC_FLAG_CANT_SWIM
|
||||||
|
UPDATE `creature_template_difficulty` AS ctd LEFT JOIN `creature_template` AS ct ON ct.`entry` = ctd.`Entry`
|
||||||
|
SET ctd.`StaticFlags1`= ctd.`StaticFlags1` | 0x00000100
|
||||||
|
WHERE (ct.`unit_flags` & 0x00004000) != 0;
|
||||||
|
|
||||||
|
UPDATE `creature_template_difficulty` AS ctd LEFT JOIN `creature_template` AS ct ON ct.`entry` = ctd.`Entry`
|
||||||
|
SET ctd.`StaticFlags1`= ctd.`StaticFlags1` &~ 0x10000000
|
||||||
|
WHERE (ct.`unit_flags` & 0x00004000) != 0;
|
||||||
|
|
||||||
|
-- CREATURE_STATIC_FLAG_AMPHIBIOUS
|
||||||
|
UPDATE `creature_template_difficulty` AS ctd
|
||||||
|
LEFT JOIN `creature_template_movement` AS ctm ON ctm.`CreatureId` = ctd.`Entry`
|
||||||
|
LEFT JOIN `creature_template` AS ct ON ct.`entry` = ctd.`Entry`
|
||||||
|
SET ctd.`StaticFlags1`= ctd.`StaticFlags1` | 0x00080000
|
||||||
|
WHERE ctm.`Ground`= 1 AND ctm.`Swim`= 1 AND (ct.`unit_flags` & 0x00008000) = 0;
|
||||||
|
|
||||||
|
-- CREATURE_STATIC_FLAG_SESSILE
|
||||||
|
UPDATE `creature_template_difficulty` AS ctd LEFT JOIN `creature_template_movement` AS ctm ON ctm.`CreatureId` = ctd.`Entry`
|
||||||
|
SET ctd.`StaticFlags1`= ctd.`StaticFlags1` | 0x00000100
|
||||||
|
WHERE ctm.`Rooted`= 1;
|
||||||
|
|
||||||
|
-- CREATURE_STATIC_FLAG_FLOATING
|
||||||
|
UPDATE `creature_template_difficulty` AS ctd LEFT JOIN `creature_template_movement` AS ctm ON ctm.`CreatureId` = ctd.`Entry`
|
||||||
|
SET ctd.`StaticFlags1`= ctd.`StaticFlags1` | 0x20000000
|
||||||
|
WHERE ctm.`Flight`!= 0;
|
||||||
|
|
||||||
|
-- CREATURE_STATIC_FLAG_AQUATIC
|
||||||
|
UPDATE `creature_template_difficulty` AS ctd LEFT JOIN `creature_template_movement` AS ctm ON ctm.`CreatureId` = ctd.`Entry`
|
||||||
|
SET ctd.`StaticFlags1`= ctd.`StaticFlags1` | 0x00040000
|
||||||
|
WHERE ctm.`Ground`= 0 AND ctm.`Swim`= 1;
|
||||||
|
|
||||||
|
-- CREATURE_STATIC_FLAG_3_CANNOT_TURN
|
||||||
|
UPDATE `creature_template_difficulty` AS ctd LEFT JOIN `creature_template` AS ct ON ct.`entry` = ctd.`Entry`
|
||||||
|
SET ctd.`StaticFlags3`= ctd.`StaticFlags3` | 0x02000000
|
||||||
|
WHERE (ct.`unit_flags2` & 0x00008000) != 0;
|
||||||
|
|
||||||
|
-- Remove unit flags that are now handled by static flags
|
||||||
|
UPDATE `creature_template` SET `unit_flags`= `unit_flags` &~ (0x00008000 | 0x00004000);
|
||||||
|
UPDATE `creature_template` SET `unit_flags2`= `unit_flags2` &~ 0x00008000;
|
||||||
|
|
||||||
|
-- Add new movement settings
|
||||||
|
ALTER TABLE `creature_template_movement`
|
||||||
|
ADD COLUMN `HoverInitiallyEnabled` TINYINT UNSIGNED NULL AFTER `CreatureId`;
|
||||||
|
|
||||||
|
UPDATE `creature_template_movement` SET `HoverInitiallyEnabled`= 1 WHERE `Ground` = 2;
|
||||||
|
|
||||||
|
ALTER TABLE `creature_movement_override`
|
||||||
|
ADD COLUMN `HoverInitiallyEnabled` TINYINT UNSIGNED NULL AFTER `SpawnId`;
|
||||||
|
|
||||||
|
UPDATE `creature_movement_override` SET `HoverInitiallyEnabled`= 1 WHERE `Ground` = 2;
|
||||||
|
|
||||||
|
-- Remove deprecated CREATURE_FLAG_EXTRA_NO_MOVE_FLAGS_UPDATE
|
||||||
|
UPDATE `creature_template` SET `flags_extra`= `flags_extra` &~ 0x200;
|
||||||
|
|
||||||
|
-- Conversion done. Drop old columns
|
||||||
|
ALTER TABLE `creature_movement_override`
|
||||||
|
DROP COLUMN `Ground`,
|
||||||
|
DROP COLUMN `Swim`,
|
||||||
|
DROP COLUMN `Flight`,
|
||||||
|
DROP COLUMN `Rooted`;
|
||||||
|
|
||||||
|
ALTER TABLE `creature_template_movement`
|
||||||
|
DROP COLUMN `Ground`,
|
||||||
|
DROP COLUMN `Swim`,
|
||||||
|
DROP COLUMN `Flight`,
|
||||||
|
DROP COLUMN `Rooted`;
|
||||||
|
|
||||||
|
-- Converted a couple script hacks to static flags where they belong
|
||||||
|
UPDATE `creature_template_difficulty` SET `StaticFlags1`= `StaticFlags1` | 0x00000100 WHERE `Entry` IN (37081, 38038);
|
||||||
Reference in New Issue
Block a user