From a89977ad99f3338ed0919fcc500e33a54ae40f6b Mon Sep 17 00:00:00 2001 From: hondacrx Date: Tue, 24 May 2022 18:20:46 -0400 Subject: [PATCH] Core/Unit: Fix movement hiccups in water Port From (https://github.com/TrinityCore/TrinityCore/commit/6b242eee130f1ac405187a03cefaf595d857ad99) --- .../Game/Entities/Creature/Creature.Fields.cs | 2 + Source/Game/Entities/Creature/Creature.cs | 40 ++++++++++++++++++- Source/Game/Entities/Player/Player.cs | 1 + Source/Game/Entities/Unit/Unit.Movement.cs | 5 ++- Source/Game/Entities/Unit/Unit.Pets.cs | 4 ++ .../Game/Movement/Generators/HomeMovement.cs | 3 ++ .../Game/Movement/Generators/PathGenerator.cs | 2 +- 7 files changed, 52 insertions(+), 5 deletions(-) diff --git a/Source/Game/Entities/Creature/Creature.Fields.cs b/Source/Game/Entities/Creature/Creature.Fields.cs index 9f2fe3919..f10170d92 100644 --- a/Source/Game/Entities/Creature/Creature.Fields.cs +++ b/Source/Game/Entities/Creature/Creature.Fields.cs @@ -36,6 +36,8 @@ namespace Game.Entities bool _regenerateHealth; // Set on creation bool _regenerateHealthLock; // Dynamically set + bool _isMissingSwimmingFlagOutOfCombat; + public ulong m_PlayerDamageReq; public float m_SightDistance; public float m_CombatDistance; diff --git a/Source/Game/Entities/Creature/Creature.cs b/Source/Game/Entities/Creature/Creature.cs index cccb47c65..0389b79c6 100644 --- a/Source/Game/Entities/Creature/Creature.cs +++ b/Source/Game/Entities/Creature/Creature.cs @@ -1074,6 +1074,8 @@ namespace Game.Entities if (!GetCreatureTemplate().TypeFlags.HasAnyFlag(CreatureTypeFlags.MountedCombatAllowed)) Dismount(); + RefreshSwimmingFlag(); + if (IsPet() || IsGuardian()) // update pets' speed for catchup OOC speed { UpdateSpeed(UnitMoveType.Run); @@ -2533,7 +2535,7 @@ namespace Game.Entities if (!isInAir) SetFall(false); - SetSwim(GetMovementTemplate().IsSwimAllowed() && IsInWater()); + SetSwim(CanSwim() && IsInWater()); } public CreatureMovementData GetMovementTemplate() @@ -2544,6 +2546,41 @@ namespace Game.Entities return GetCreatureTemplate().Movement; } + + public override bool CanSwim() + { + if (base.CanSwim()) + return true; + + if (IsPet()) + return true; + + return false; + } + + bool CanEnterWater() + { + if (CanSwim()) + return true; + + return GetMovementTemplate().IsSwimAllowed(); + } + + public void RefreshSwimmingFlag(bool recheck = false) + { + if (!_isMissingSwimmingFlagOutOfCombat || recheck) + _isMissingSwimmingFlagOutOfCombat = !HasUnitFlag(UnitFlags.CanSwim); + + // Check if the creature has UNIT_FLAG_SWIMMING and add it if it's missing + // Creatures must be able to chase a target in water if they can enter water + if (_isMissingSwimmingFlagOutOfCombat && CanEnterWater()) + AddUnitFlag(UnitFlags.CanSwim); + } + + public bool HasSwimmingFlagOutOfCombat() + { + return !_isMissingSwimmingFlagOutOfCombat; + } public void AllLootRemovedFromCorpse() { @@ -3082,7 +3119,6 @@ namespace Game.Entities } public bool CanWalk() { return GetMovementTemplate().IsGroundAllowed(); } - public override bool CanSwim() { return GetMovementTemplate().IsSwimAllowed() || IsPet();} public override bool CanFly() { return GetMovementTemplate().IsFlightAllowed() || IsFlying(); } bool CanHover() { return GetMovementTemplate().Ground == CreatureGroundMovementType.Hover || IsHovering(); } diff --git a/Source/Game/Entities/Player/Player.cs b/Source/Game/Entities/Player/Player.cs index 017bd928e..0cac0b2bc 100644 --- a/Source/Game/Entities/Player/Player.cs +++ b/Source/Game/Entities/Player/Player.cs @@ -4679,6 +4679,7 @@ namespace Game.Entities } public override bool CanFly() { return m_movementInfo.HasMovementFlag(MovementFlag.CanFly); } + public override CanEnterWater() { return true; } public Pet GetPet() { diff --git a/Source/Game/Entities/Unit/Unit.Movement.cs b/Source/Game/Entities/Unit/Unit.Movement.cs index be6d6d512..b1b86ad6f 100644 --- a/Source/Game/Entities/Unit/Unit.Movement.cs +++ b/Source/Game/Entities/Unit/Unit.Movement.cs @@ -49,6 +49,7 @@ namespace Game.Entities { return m_movementInfo.HasMovementFlag(MovementFlag.Falling | MovementFlag.FallingFar) || MoveSpline.IsFalling(); } + public virtual bool CanEnterWater() { return false; } public virtual bool CanSwim() { // Mirror client behavior, if this method returns false then client will not use swimming animation and for players will apply gravity as if there was no water @@ -58,7 +59,7 @@ namespace Game.Entities return true; if (HasUnitFlag2((UnitFlags2)0x1000000)) return false; - if (IsPet() && HasUnitFlag(UnitFlags.PetInCombat)) + if (HasUnitFlag(UnitFlags.PetInCombat)) return true; return HasUnitFlag(UnitFlags.Rename | UnitFlags.CanSwim); @@ -1133,7 +1134,7 @@ namespace Game.Entities public bool IsInAccessiblePlaceFor(Creature c) { if (IsInWater()) - return c.CanSwim(); + return c.CanEnterWater(); else return c.CanWalk() || c.CanFly(); } diff --git a/Source/Game/Entities/Unit/Unit.Pets.cs b/Source/Game/Entities/Unit/Unit.Pets.cs index 1635eaaf8..55d354113 100644 --- a/Source/Game/Entities/Unit/Unit.Pets.cs +++ b/Source/Game/Entities/Unit/Unit.Pets.cs @@ -417,6 +417,10 @@ namespace Game.Entities AddUnitState(UnitState.Charmed); + Creature creature = ToCreature(); + if (creature != null) + creature.RefreshSwimmingFlag(); + if (!IsPlayer() || !charmer.IsPlayer()) { // AI will schedule its own change if appropriate diff --git a/Source/Game/Movement/Generators/HomeMovement.cs b/Source/Game/Movement/Generators/HomeMovement.cs index 585116f18..b5d3a5858 100644 --- a/Source/Game/Movement/Generators/HomeMovement.cs +++ b/Source/Game/Movement/Generators/HomeMovement.cs @@ -74,6 +74,9 @@ namespace Game.AI if (movementInform && HasFlag(MovementGeneratorFlags.InformEnabled)) { + if (!owner.HasSwimmingFlagOutOfCombat()) + owner.RemoveUnitFlag(UnitFlags.CanSwim); + owner.SetSpawnHealth(); owner.LoadCreaturesAddon(); if (owner.IsVehicle()) diff --git a/Source/Game/Movement/Generators/PathGenerator.cs b/Source/Game/Movement/Generators/PathGenerator.cs index f4ab9acca..78e0d7b99 100644 --- a/Source/Game/Movement/Generators/PathGenerator.cs +++ b/Source/Game/Movement/Generators/PathGenerator.cs @@ -868,7 +868,7 @@ namespace Game.Movement includeFlags |= NavTerrainFlag.Ground; // creatures don't take environmental damage - if (creature.CanSwim()) + if (creature.CanEnterWater()) includeFlags |= (NavTerrainFlag.Water | NavTerrainFlag.MagmaSlime); } else