aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Entities/Creature/Creature.cpp36
-rw-r--r--src/server/game/Entities/Creature/Creature.h11
-rw-r--r--src/server/game/Entities/Player/Player.h1
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp7
-rw-r--r--src/server/game/Entities/Unit/Unit.h1
-rw-r--r--src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp3
-rw-r--r--src/server/game/Movement/PathGenerator.cpp2
7 files changed, 55 insertions, 6 deletions
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp
index 513137767a4..f33ed67c810 100644
--- a/src/server/game/Entities/Creature/Creature.cpp
+++ b/src/server/game/Entities/Creature/Creature.cpp
@@ -305,7 +305,7 @@ Creature::Creature(bool isWorldObject): Unit(isWorldObject), MapObject(), m_grou
m_defaultMovementType(IDLE_MOTION_TYPE), m_spawnId(UI64LIT(0)), m_equipmentId(0), m_originalEquipmentId(0), m_AlreadyCallAssistance(false), m_AlreadySearchedAssistance(false), m_cannotReachTarget(false), m_cannotReachTimer(0),
m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL), m_originalEntry(0), m_homePosition(), m_transportHomePosition(), m_creatureInfo(nullptr), m_creatureData(nullptr), _waypointPathId(0), _currentWaypointNodeInfo(0, 0),
m_formation(nullptr), m_triggerJustAppeared(true), m_respawnCompatibilityMode(false), _lastDamagedTime(0),
- _regenerateHealth(true), _regenerateHealthLock(false)
+ _regenerateHealth(true), _regenerateHealthLock(false), _isMissingSwimmingFlagOutOfCombat(false)
{
m_regenTimer = CREATURE_REGEN_INTERVAL;
@@ -2829,7 +2829,7 @@ void Creature::UpdateMovementFlags()
if (!isInAir)
RemoveUnitMovementFlag(MOVEMENTFLAG_FALLING);
- SetSwim(GetMovementTemplate().IsSwimAllowed() && IsInWater());
+ SetSwim(CanSwim() && IsInWater());
}
CreatureMovementData const& Creature::GetMovementTemplate() const
@@ -2840,6 +2840,36 @@ CreatureMovementData const& Creature::GetMovementTemplate() const
return GetCreatureTemplate()->Movement;
}
+bool Creature::CanSwim() const
+{
+ if (Unit::CanSwim())
+ return true;
+
+ if (IsPet())
+ return true;
+
+ return false;
+}
+
+bool Creature::CanEnterWater() const
+{
+ if (CanSwim())
+ return true;
+
+ return GetMovementTemplate().IsSwimAllowed();
+}
+
+void Creature::RefreshSwimmingFlag(bool recheck)
+{
+ if (!_isMissingSwimmingFlagOutOfCombat || recheck)
+ _isMissingSwimmingFlagOutOfCombat = !HasUnitFlag(UNIT_FLAG_CAN_SWIM);
+
+ // 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(UNIT_FLAG_CAN_SWIM);
+}
+
void Creature::AllLootRemovedFromCorpse()
{
if (loot.loot_type != LOOT_SKINNING && !IsPet() && GetCreatureTemplate()->SkinLootId && hasLootRecipient())
@@ -3418,6 +3448,8 @@ void Creature::AtEngage(Unit* target)
if (!(GetCreatureTemplate()->type_flags & CREATURE_TYPE_FLAG_MOUNTED_COMBAT_ALLOWED))
Dismount();
+ RefreshSwimmingFlag();
+
if (IsPet() || IsGuardian()) // update pets' speed for catchup OOC speed
{
UpdateSpeed(MOVE_RUN);
diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h
index 1a67853ebf1..61f3e64a41b 100644
--- a/src/server/game/Entities/Creature/Creature.h
+++ b/src/server/game/Entities/Creature/Creature.h
@@ -111,7 +111,8 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma
CreatureMovementData const& GetMovementTemplate() const;
bool CanWalk() const { return GetMovementTemplate().IsGroundAllowed(); }
- bool CanSwim() const override { return GetMovementTemplate().IsSwimAllowed() || IsPet(); }
+ bool CanSwim() const override;
+ bool CanEnterWater() const override;
bool CanFly() const override { return GetMovementTemplate().IsFlightAllowed() || IsFlying(); }
bool CanHover() const { return GetMovementTemplate().Ground == CreatureGroundMovementType::Hover || IsHovering(); }
@@ -369,6 +370,12 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma
void AtEngage(Unit* target) override;
void AtDisengage() override;
+ bool HasSwimmingFlagOutOfCombat() const
+ {
+ return !_isMissingSwimmingFlagOutOfCombat;
+ }
+ void RefreshSwimmingFlag(bool recheck = false);
+
std::string GetDebugInfo() const override;
protected:
@@ -452,6 +459,8 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma
// Regenerate health
bool _regenerateHealth; // Set on creation
bool _regenerateHealthLock; // Dynamically set
+
+ bool _isMissingSwimmingFlagOutOfCombat;
};
class TC_GAME_API AssistDelayEvent : public BasicEvent
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index f4f33fd9526..89b08802e4f 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -2623,6 +2623,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
void SendMovementSetCollisionHeight(float height, WorldPackets::Movement::UpdateCollisionHeightReason reason);
bool CanFly() const override { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_CAN_FLY); }
+ bool CanEnterWater() const override { return true; }
std::string GetMapAreaAndZoneString() const;
std::string GetCoordsMapAreaAndZoneString() const;
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 41efb7de14a..c103c41770d 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -3006,7 +3006,7 @@ bool Unit::isInBackInMap(Unit const* target, float distance, float arc) const
bool Unit::isInAccessiblePlaceFor(Creature const* c) const
{
if (IsInWater())
- return c->CanSwim();
+ return c->CanEnterWater();
else
return c->CanWalk() || c->CanFly();
}
@@ -11150,6 +11150,9 @@ bool Unit::SetCharmedBy(Unit* charmer, CharmType type, AuraApplication const* au
AddUnitState(UNIT_STATE_CHARMED);
+ if (Creature* creature = ToCreature())
+ creature->RefreshSwimmingFlag();
+
if ((GetTypeId() != TYPEID_PLAYER) || (charmer->GetTypeId() != TYPEID_PLAYER))
{
// AI will schedule its own change if appropriate
@@ -12107,7 +12110,7 @@ bool Unit::CanSwim() const
return true;
if (HasUnitFlag2(UnitFlags2(0x1000000)))
return false;
- if (IsPet() && HasUnitFlag(UNIT_FLAG_PET_IN_COMBAT))
+ if (HasUnitFlag(UNIT_FLAG_PET_IN_COMBAT))
return true;
return HasUnitFlag(UnitFlags(UNIT_FLAG_RENAME | UNIT_FLAG_CAN_SWIM));
}
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 655b8f4edaf..8c579aa29b1 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -1807,6 +1807,7 @@ class TC_GAME_API Unit : public WorldObject
virtual bool CanFly() const = 0;
bool IsFlying() const { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_FLYING | MOVEMENTFLAG_DISABLE_GRAVITY); }
bool IsFalling() const;
+ virtual bool CanEnterWater() const = 0;
virtual bool CanSwim() const;
float GetHoverOffset() const
diff --git a/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp
index 5e06c084028..c49c7cc1fdd 100644
--- a/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp
@@ -144,6 +144,9 @@ void HomeMovementGenerator<Creature>::DoFinalize(Creature* owner, bool active, b
if (movementInform && HasFlag(MOVEMENTGENERATOR_FLAG_INFORM_ENABLED))
{
+ if (!owner->HasSwimmingFlagOutOfCombat())
+ owner->RemoveUnitFlag(UNIT_FLAG_CAN_SWIM);
+
owner->SetSpawnHealth();
owner->LoadCreaturesAddon();
if (owner->IsVehicle())
diff --git a/src/server/game/Movement/PathGenerator.cpp b/src/server/game/Movement/PathGenerator.cpp
index 8519649bdf4..fb64779e70f 100644
--- a/src/server/game/Movement/PathGenerator.cpp
+++ b/src/server/game/Movement/PathGenerator.cpp
@@ -657,7 +657,7 @@ void PathGenerator::CreateFilter()
includeFlags |= NAV_GROUND; // walk
// creatures don't take environmental damage
- if (creature->CanSwim())
+ if (creature->CanEnterWater())
includeFlags |= (NAV_WATER | NAV_MAGMA_SLIME); // swim
}
else // assume Player