mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-02-25 04:55:54 +00:00
refactor(Core/Creature): Remove Inhabit Type (#9272)
This is in reference to issue: https://github.com/azerothcore/azerothcore-wotlk/issues/4361 This is comprised of a cherry pick and partial tc cherry pick:592516ae69dbadb6369c34cfa69efd12de860b4aa22bc236eb
This commit is contained in:
@@ -55,6 +55,31 @@
|
||||
// see: https://github.com/azerothcore/azerothcore-wotlk/issues/9766
|
||||
#include "GridNotifiersImpl.h"
|
||||
|
||||
CreatureMovementData::CreatureMovementData() : Ground(CreatureGroundMovementType::Run), Flight(CreatureFlightMovementType::None),
|
||||
Swim(true), Rooted(false), Chase(CreatureChaseMovementType::Run),
|
||||
Random(CreatureRandomMovementType::Walk), InteractionPauseTimer(sWorld->getIntConfig(CONFIG_CREATURE_STOP_FOR_PLAYER)) {}
|
||||
|
||||
std::string CreatureMovementData::ToString() const
|
||||
{
|
||||
constexpr std::array<char const*, 3> GroundStates = {"None", "Run", "Hover"};
|
||||
constexpr std::array<char const*, 3> FlightStates = {"None", "DisableGravity", "CanFly"};
|
||||
constexpr std::array<char const*, 3> ChaseStates = {"Run", "CanWalk", "AlwaysWalk"};
|
||||
constexpr std::array<char const*, 3> RandomStates = {"Walk", "CanRun", "AlwaysRun"};
|
||||
|
||||
std::ostringstream str;
|
||||
str << std::boolalpha
|
||||
<< "Ground: " << GroundStates[AsUnderlyingType(Ground)]
|
||||
<< ", Swim: " << Swim
|
||||
<< ", Flight: " << FlightStates[AsUnderlyingType(Flight)]
|
||||
<< ", Chase: " << ChaseStates[AsUnderlyingType(Chase)]
|
||||
<< ", Random: " << RandomStates[AsUnderlyingType(Random)];
|
||||
if (Rooted)
|
||||
str << ", Rooted";
|
||||
str << ", InteractionPauseTimer: " << InteractionPauseTimer;
|
||||
|
||||
return str.str();
|
||||
}
|
||||
|
||||
TrainerSpell const* TrainerSpellData::Find(uint32 spell_id) const
|
||||
{
|
||||
TrainerSpellMap::const_iterator itr = spellList.find(spell_id);
|
||||
@@ -541,7 +566,7 @@ bool Creature::UpdateEntry(uint32 Entry, const CreatureData* data, bool changele
|
||||
ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, true);
|
||||
}
|
||||
|
||||
if (cInfo->InhabitType & INHABIT_ROOT)
|
||||
if (GetMovementTemplate().IsRooted())
|
||||
{
|
||||
SetControlled(true, UNIT_STATE_ROOT);
|
||||
}
|
||||
@@ -2452,7 +2477,7 @@ bool Creature::CanCreatureAttack(Unit const* victim, bool skipDistCheck) const
|
||||
else
|
||||
{
|
||||
// to prevent creatures in air ignore attacks because distance is already too high...
|
||||
if (GetCreatureTemplate()->InhabitType & INHABIT_AIR)
|
||||
if (GetMovementTemplate().IsFlightAllowed())
|
||||
return victim->IsInDist2d(&m_homePosition, dist);
|
||||
else
|
||||
return victim->IsInDist(&m_homePosition, dist);
|
||||
@@ -2500,7 +2525,7 @@ bool Creature::LoadCreaturesAddon(bool reload)
|
||||
//! 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 (GetByteValue(UNIT_FIELD_BYTES_1, 3) & UNIT_BYTE1_FLAG_HOVER /*&& !(GetCreatureTemplate()->InhabitType & INHABIT_AIR)*/)
|
||||
if (CanHover())
|
||||
AddUnitMovementFlag(MOVEMENTFLAG_HOVER);
|
||||
}
|
||||
|
||||
@@ -2731,6 +2756,14 @@ void Creature::GetRespawnPosition(float& x, float& y, float& z, float* ori, floa
|
||||
*dist = 0;
|
||||
}
|
||||
|
||||
CreatureMovementData const& Creature::GetMovementTemplate() const
|
||||
{
|
||||
if (CreatureMovementData const* movementOverride = sObjectMgr->GetCreatureMovementOverride(m_spawnId))
|
||||
return *movementOverride;
|
||||
|
||||
return GetCreatureTemplate()->Movement;
|
||||
}
|
||||
|
||||
void Creature::AllLootRemovedFromCorpse()
|
||||
{
|
||||
if (loot.loot_type != LOOT_SKINNING && !IsPet() && GetCreatureTemplate()->SkinLootId && hasLootRecipient())
|
||||
@@ -2937,8 +2970,6 @@ bool Creature::SetDisableGravity(bool disable, bool packetOnly/*=false*/)
|
||||
if (!packetOnly && !Unit::SetDisableGravity(disable))
|
||||
return false;
|
||||
|
||||
applyInhabitFlags();
|
||||
|
||||
if (m_movedByPlayer)
|
||||
{
|
||||
WorldPacket data(disable ? SMSG_MOVE_GRAVITY_DISABLE : SMSG_MOVE_GRAVITY_ENABLE, 12);
|
||||
@@ -2962,23 +2993,6 @@ bool Creature::SetDisableGravity(bool disable, bool packetOnly/*=false*/)
|
||||
return true;
|
||||
}
|
||||
|
||||
void Creature::applyInhabitFlags()
|
||||
{
|
||||
if (IsAlive() && !HasUnitState(UNIT_STATE_ROOT) && !HasUnitMovementFlag(MOVEMENTFLAG_ROOT))
|
||||
{
|
||||
if (IsLevitating())
|
||||
{
|
||||
SetByteValue(UNIT_FIELD_BYTES_1, UNIT_BYTES_1_OFFSET_ANIM_TIER, UNIT_BYTE1_FLAG_FLY);
|
||||
}
|
||||
else if (IsHovering())
|
||||
{
|
||||
SetByteValue(UNIT_FIELD_BYTES_1, UNIT_BYTES_1_OFFSET_ANIM_TIER, UNIT_BYTE1_FLAG_HOVER);
|
||||
}
|
||||
else
|
||||
SetByteValue(UNIT_FIELD_BYTES_1, UNIT_BYTES_1_OFFSET_ANIM_TIER, UNIT_BYTE1_FLAG_GROUND);
|
||||
}
|
||||
}
|
||||
|
||||
bool Creature::SetSwim(bool enable)
|
||||
{
|
||||
if (!Unit::SetSwim(enable))
|
||||
@@ -3016,7 +3030,7 @@ bool Creature::CanEnterWater() const
|
||||
if (CanSwim())
|
||||
return true;
|
||||
|
||||
return GetCreatureTemplate()->InhabitType & INHABIT_WATER;
|
||||
return GetMovementTemplate().IsSwimAllowed();
|
||||
}
|
||||
|
||||
void Creature::RefreshSwimmingFlag(bool recheck)
|
||||
@@ -3063,14 +3077,6 @@ bool Creature::SetCanFly(bool enable, bool /*packetOnly*/ /* = false */)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Creature::CanFly() const
|
||||
{
|
||||
if (Unit::IsFlying())
|
||||
return true;
|
||||
|
||||
return GetCreatureTemplate()->InhabitType & INHABIT_AIR;
|
||||
}
|
||||
|
||||
bool Creature::SetWaterWalking(bool enable, bool packetOnly /* = false */)
|
||||
{
|
||||
if (!packetOnly && !Unit::SetWaterWalking(enable))
|
||||
@@ -3132,22 +3138,6 @@ bool Creature::SetHover(bool enable, bool packetOnly /*= false*/)
|
||||
if (!packetOnly && !Unit::SetHover(enable))
|
||||
return false;
|
||||
|
||||
applyInhabitFlags();
|
||||
|
||||
if (m_movedByPlayer)
|
||||
{
|
||||
WorldPacket data(enable ? SMSG_MOVE_SET_HOVER : SMSG_MOVE_UNSET_HOVER, 12);
|
||||
data << GetPackGUID();
|
||||
data << uint32(0); //! movement counter
|
||||
m_movedByPlayer->ToPlayer()->SendDirectMessage(&data);
|
||||
|
||||
data.Initialize(MSG_MOVE_HOVER, 64);
|
||||
data << GetPackGUID();
|
||||
BuildMovementPacket(&data);
|
||||
m_movedByPlayer->ToPlayer()->SendMessageToSet(&data, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!movespline->Initialized())
|
||||
return true;
|
||||
|
||||
@@ -3217,76 +3207,33 @@ void Creature::UpdateMovementFlags()
|
||||
if (info->flags_extra & CREATURE_FLAG_EXTRA_NO_MOVE_FLAGS_UPDATE)
|
||||
return;
|
||||
|
||||
float z = GetPositionZ();
|
||||
float ground = GetFloorZ();
|
||||
|
||||
bool isInAir = false;
|
||||
bool Swim = false;
|
||||
|
||||
bool canHover = CanHover();
|
||||
bool isInAir = (G3D::fuzzyGt(GetPositionZ(), ground + (canHover ? GetFloatValue(UNIT_FIELD_HOVERHEIGHT) : 0.0f) + GROUND_HEIGHT_TOLERANCE) || G3D::fuzzyLt(GetPositionZ(), ground - GROUND_HEIGHT_TOLERANCE)); // Can be underground too, prevent the falling
|
||||
|
||||
LiquidData const& liquidData = GetLiquidData();
|
||||
if (liquidData.Status == LIQUID_MAP_NO_WATER)
|
||||
if (GetMovementTemplate().IsFlightAllowed() && isInAir && !IsFalling())
|
||||
{
|
||||
if (ground > INVALID_HEIGHT)
|
||||
isInAir = G3D::fuzzyGt(z, ground + (canHover ? GetFloatValue(UNIT_FIELD_HOVERHEIGHT) : 0.0f) + GROUND_HEIGHT_TOLERANCE) || G3D::fuzzyLt(z, ground - GROUND_HEIGHT_TOLERANCE); // Can be underground too, prevent the falling
|
||||
if (GetMovementTemplate().Flight == CreatureFlightMovementType::CanFly)
|
||||
SetCanFly(true);
|
||||
else
|
||||
isInAir = true;
|
||||
SetDisableGravity(true);
|
||||
|
||||
if (!HasAuraType(SPELL_AURA_HOVER))
|
||||
SetHover(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (liquidData.Status)
|
||||
{
|
||||
case LIQUID_MAP_ABOVE_WATER:
|
||||
isInAir = true;
|
||||
break;
|
||||
case LIQUID_MAP_WATER_WALK:
|
||||
isInAir = true;
|
||||
[[fallthrough]];
|
||||
case LIQUID_MAP_IN_WATER:
|
||||
Swim = z - liquidData.DepthLevel > GetCollisionHeight() * 0.75f; // Shallow water at ~75% of collision height
|
||||
break;
|
||||
case LIQUID_MAP_UNDER_WATER:
|
||||
Swim = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
SetCanFly(false);
|
||||
SetDisableGravity(false);
|
||||
if (IsAlive() && (CanHover() || HasAuraType(SPELL_AURA_HOVER)))
|
||||
SetHover(true);
|
||||
}
|
||||
|
||||
SetSwim(CanSwim() && Swim);
|
||||
if (!isInAir)
|
||||
RemoveUnitMovementFlag(MOVEMENTFLAG_FALLING);
|
||||
|
||||
if (info->InhabitType & INHABIT_AIR)
|
||||
{
|
||||
if (isInAir && !IsFalling())
|
||||
{
|
||||
if (info->InhabitType & INHABIT_GROUND)
|
||||
{
|
||||
SetCanFly(true);
|
||||
SetByteValue(UNIT_FIELD_BYTES_1, UNIT_BYTES_1_OFFSET_ANIM_TIER, UNIT_BYTE1_FLAG_FLY);
|
||||
}
|
||||
else
|
||||
SetDisableGravity(true);
|
||||
|
||||
if (!HasAuraType(SPELL_AURA_HOVER))
|
||||
SetHover(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetCanFly(false);
|
||||
SetDisableGravity(false);
|
||||
|
||||
if (info->InhabitType & INHABIT_GROUND)
|
||||
{
|
||||
SetByteValue(UNIT_FIELD_BYTES_1, UNIT_BYTES_1_OFFSET_ANIM_TIER, UNIT_BYTE1_FLAG_GROUND);
|
||||
}
|
||||
|
||||
if (IsAlive() && (CanHover() || HasAuraType(SPELL_AURA_HOVER)))
|
||||
SetHover(true);
|
||||
}
|
||||
}
|
||||
else if (!HasUnitMovementFlag(MOVEMENTFLAG_CAN_FLY | MOVEMENTFLAG_DISABLE_GRAVITY) && IsAlive() && (CanHover() || HasAuraType(SPELL_AURA_HOVER)))
|
||||
SetHover(true);
|
||||
SetSwim(CanSwim() && IsInWater());
|
||||
}
|
||||
|
||||
void Creature::SetObjectScale(float scale)
|
||||
|
||||
@@ -74,11 +74,15 @@ public:
|
||||
[[nodiscard]] bool IsCivilian() const { return GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_CIVILIAN; }
|
||||
[[nodiscard]] bool IsTrigger() const { return GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_TRIGGER; }
|
||||
[[nodiscard]] bool IsGuard() const { return GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_GUARD; }
|
||||
[[nodiscard]] bool CanWalk() const { return GetCreatureTemplate()->InhabitType & INHABIT_GROUND; }
|
||||
CreatureMovementData const& GetMovementTemplate() const;
|
||||
[[nodiscard]] bool CanWalk() const { return GetMovementTemplate().IsGroundAllowed(); }
|
||||
[[nodiscard]] bool CanSwim() const override;
|
||||
[[nodiscard]] bool CanEnterWater() const override;
|
||||
[[nodiscard]] bool CanFly() const override;
|
||||
[[nodiscard]] bool CanHover() const { return m_originalAnimTier & UNIT_BYTE1_FLAG_HOVER || IsHovering(); }
|
||||
[[nodiscard]] bool CanFly() const override { return GetMovementTemplate().IsFlightAllowed() || IsFlying(); }
|
||||
[[nodiscard]] bool CanHover() const { return GetMovementTemplate().Ground == CreatureGroundMovementType::Hover || IsHovering(); }
|
||||
|
||||
MovementGeneratorType GetDefaultMovementType() const override { return m_defaultMovementType; }
|
||||
void SetDefaultMovementType(MovementGeneratorType mgt) { m_defaultMovementType = mgt; }
|
||||
|
||||
void SetReactState(ReactStates st) { m_reactState = st; }
|
||||
[[nodiscard]] ReactStates GetReactState() const { return m_reactState; }
|
||||
@@ -261,9 +265,6 @@ public:
|
||||
bool IsMoveInLineOfSightDisabled() { return m_moveInLineOfSightDisabled; }
|
||||
bool IsMoveInLineOfSightStrictlyDisabled() { return m_moveInLineOfSightStrictlyDisabled; }
|
||||
|
||||
[[nodiscard]] MovementGeneratorType GetDefaultMovementType() const { return m_defaultMovementType; }
|
||||
void SetDefaultMovementType(MovementGeneratorType mgt) { m_defaultMovementType = mgt; }
|
||||
|
||||
void RemoveCorpse(bool setSpawnTime = true, bool skipVisibility = false);
|
||||
|
||||
void DespawnOrUnsummon(Milliseconds msTimeToDespawn, Seconds forcedRespawnTimer);
|
||||
@@ -462,7 +463,6 @@ private:
|
||||
|
||||
uint32 m_assistanceTimer;
|
||||
|
||||
void applyInhabitFlags();
|
||||
};
|
||||
|
||||
class AssistDelayEvent : public BasicEvent
|
||||
|
||||
@@ -86,6 +86,92 @@ enum CreatureFlagsExtra : uint32
|
||||
CREATURE_FLAG_EXTRA_DB_ALLOWED = (0xFFFFFFFF & ~(CREATURE_FLAG_EXTRA_UNUSED | CREATURE_FLAG_EXTRA_DUNGEON_BOSS)) // SKIP
|
||||
};
|
||||
|
||||
enum class CreatureGroundMovementType : uint8
|
||||
{
|
||||
None,
|
||||
Run,
|
||||
Hover,
|
||||
|
||||
Max
|
||||
};
|
||||
|
||||
enum class CreatureFlightMovementType : uint8
|
||||
{
|
||||
None,
|
||||
DisableGravity,
|
||||
CanFly,
|
||||
|
||||
Max
|
||||
};
|
||||
|
||||
enum class CreatureChaseMovementType : uint8
|
||||
{
|
||||
Run,
|
||||
CanWalk,
|
||||
AlwaysWalk,
|
||||
|
||||
Max
|
||||
};
|
||||
|
||||
enum class CreatureRandomMovementType : uint8
|
||||
{
|
||||
Walk,
|
||||
CanRun,
|
||||
AlwaysRun,
|
||||
|
||||
Max
|
||||
};
|
||||
|
||||
struct CreatureMovementData
|
||||
{
|
||||
CreatureMovementData();
|
||||
|
||||
CreatureGroundMovementType Ground;
|
||||
CreatureFlightMovementType Flight;
|
||||
bool Swim;
|
||||
bool Rooted;
|
||||
CreatureChaseMovementType Chase;
|
||||
CreatureRandomMovementType Random;
|
||||
uint32 InteractionPauseTimer;
|
||||
|
||||
bool IsGroundAllowed() const
|
||||
{
|
||||
return Ground != CreatureGroundMovementType::None;
|
||||
}
|
||||
|
||||
bool IsSwimAllowed() const
|
||||
{
|
||||
return Swim;
|
||||
}
|
||||
|
||||
bool IsFlightAllowed() const
|
||||
{
|
||||
return Flight != CreatureFlightMovementType::None;
|
||||
}
|
||||
|
||||
bool IsRooted() const
|
||||
{
|
||||
return Rooted;
|
||||
}
|
||||
|
||||
CreatureChaseMovementType GetChase() const
|
||||
{
|
||||
return Chase;
|
||||
}
|
||||
|
||||
CreatureRandomMovementType GetRandom() const
|
||||
{
|
||||
return Random;
|
||||
}
|
||||
|
||||
uint32 GetInteractionPauseTimer() const
|
||||
{
|
||||
return InteractionPauseTimer;
|
||||
}
|
||||
|
||||
std::string ToString() const;
|
||||
};
|
||||
|
||||
// from `creature_template` table
|
||||
struct CreatureTemplate
|
||||
{
|
||||
@@ -138,7 +224,7 @@ struct CreatureTemplate
|
||||
uint32 maxgold;
|
||||
std::string AIName;
|
||||
uint32 MovementType;
|
||||
uint32 InhabitType;
|
||||
CreatureMovementData Movement;
|
||||
float HoverHeight;
|
||||
float ModHealth;
|
||||
float ModMana;
|
||||
|
||||
@@ -234,6 +234,7 @@ Player::Player(WorldSession* session): Unit(true), m_mover(this)
|
||||
|
||||
m_MirrorTimerFlags = UNDERWATER_NONE;
|
||||
m_MirrorTimerFlagsLast = UNDERWATER_NONE;
|
||||
m_isInWater = false;
|
||||
m_drunkTimer = 0;
|
||||
m_deathTimer = 0;
|
||||
m_deathExpireTime = 0;
|
||||
@@ -2087,6 +2088,24 @@ bool Player::IsFalling() const
|
||||
return GetPositionZ() < m_lastFallZ && !IsInFlight();
|
||||
}
|
||||
|
||||
void Player::SetInWater(bool apply)
|
||||
{
|
||||
if (m_isInWater == apply)
|
||||
return;
|
||||
|
||||
//define player in water by opcodes
|
||||
//move player's guid into HateOfflineList of those mobs
|
||||
//which can't swim and move guid back into ThreatList when
|
||||
//on surface.
|
||||
//TODO: exist also swimming mobs, and function must be symmetric to enter/leave water
|
||||
m_isInWater = apply;
|
||||
|
||||
// remove auras that need water/land
|
||||
RemoveAurasWithInterruptFlags(apply ? AURA_INTERRUPT_FLAG_NOT_ABOVEWATER : AURA_INTERRUPT_FLAG_NOT_UNDERWATER);
|
||||
|
||||
getHostileRefMgr().updateThreatTables();
|
||||
}
|
||||
|
||||
bool Player::IsInAreaTriggerRadius(const AreaTrigger* trigger) const
|
||||
{
|
||||
static const float delta = 5.0f;
|
||||
|
||||
@@ -1086,6 +1086,9 @@ public:
|
||||
|
||||
static bool BuildEnumData(PreparedQueryResult result, WorldPacket* data);
|
||||
|
||||
void SetInWater(bool apply);
|
||||
|
||||
[[nodiscard]] bool IsInWater() const override { return m_isInWater; }
|
||||
[[nodiscard]] bool IsFalling() const;
|
||||
bool IsInAreaTriggerRadius(const AreaTrigger* trigger) const;
|
||||
|
||||
@@ -2915,6 +2918,7 @@ private:
|
||||
int32 m_MirrorTimer[MAX_TIMERS];
|
||||
uint8 m_MirrorTimerFlags;
|
||||
uint8 m_MirrorTimerFlagsLast;
|
||||
bool m_isInWater;
|
||||
|
||||
// Current teleport data
|
||||
WorldLocation teleportStore_dest;
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include "InstanceScript.h"
|
||||
#include "Log.h"
|
||||
#include "MapMgr.h"
|
||||
#include "MovementGenerator.h"
|
||||
#include "MoveSpline.h"
|
||||
#include "MoveSplineInit.h"
|
||||
#include "ObjectAccessor.h"
|
||||
@@ -3777,13 +3778,14 @@ bool Unit::isInAccessiblePlaceFor(Creature const* c) const
|
||||
return false;
|
||||
}
|
||||
|
||||
// In water or jumping in water
|
||||
if (IsInWater() || (GetLiquidData().Status == LIQUID_MAP_ABOVE_WATER && (IsFalling() || (ToPlayer() && ToPlayer()->IsFalling()))))
|
||||
if (IsInWater())
|
||||
{
|
||||
return IsUnderWater() ? c->CanEnterWater() : (c->CanEnterWater() || c->CanFly());
|
||||
return c->CanEnterWater();
|
||||
}
|
||||
else
|
||||
{
|
||||
return c->CanWalk() || c->CanFly();
|
||||
}
|
||||
|
||||
return c->CanWalk() || c->CanFly() || (c->CanSwim() && IsInWater());
|
||||
}
|
||||
|
||||
void Unit::ProcessPositionDataChanged(PositionFullTerrainStatus const& data)
|
||||
@@ -13578,28 +13580,29 @@ void Unit::UpdateSpeed(UnitMoveType mtype, bool forced)
|
||||
case MOVE_RUN:
|
||||
case MOVE_SWIM:
|
||||
case MOVE_FLIGHT:
|
||||
{
|
||||
// Set creature speed rate
|
||||
if (GetTypeId() == TYPEID_UNIT)
|
||||
speed *= ToCreature()->GetCreatureTemplate()->speed_run; // at this point, MOVE_WALK is never reached
|
||||
|
||||
// Normalize speed by 191 aura SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED if need
|
||||
/// @todo possible affect only on MOVE_RUN
|
||||
if (int32 normalization = GetMaxPositiveAuraModifier(SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED))
|
||||
{
|
||||
if (GetTypeId() == TYPEID_UNIT)
|
||||
if (Creature* creature = ToCreature())
|
||||
{
|
||||
speed *= ToCreature()->GetCreatureTemplate()->speed_run; // at this point, MOVE_WALK is never reached
|
||||
uint32 immuneMask = creature->GetCreatureTemplate()->MechanicImmuneMask;
|
||||
if (immuneMask & (1 << (MECHANIC_SNARE - 1)) || immuneMask & (1 << (MECHANIC_DAZE - 1)))
|
||||
break;
|
||||
}
|
||||
|
||||
// Normalize speed by 191 aura SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED if need
|
||||
// TODO: possible affect only on MOVE_RUN
|
||||
if (int32 normalization = GetMaxPositiveAuraModifier(SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED))
|
||||
{
|
||||
// Use speed from aura
|
||||
float max_speed = normalization / (IsControlledByPlayer() ? playerBaseMoveSpeed[mtype] : baseMoveSpeed[mtype]);
|
||||
|
||||
// Xinef: normal movement speed - multiply by creature db modifer
|
||||
if (GetTypeId() == TYPEID_UNIT)
|
||||
max_speed *= ToCreature()->GetCreatureTemplate()->speed_run;
|
||||
|
||||
if (speed > max_speed)
|
||||
speed = max_speed;
|
||||
}
|
||||
break;
|
||||
// Use speed from aura
|
||||
float max_speed = normalization / (IsControlledByPlayer() ? playerBaseMoveSpeed[mtype] : baseMoveSpeed[mtype]);
|
||||
if (speed > max_speed)
|
||||
speed = max_speed;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -16039,6 +16042,11 @@ void Unit::SendPetAIReaction(ObjectGuid guid)
|
||||
|
||||
///----------End of Pet responses methods----------
|
||||
|
||||
MovementGeneratorType Unit::GetDefaultMovementType() const
|
||||
{
|
||||
return IDLE_MOTION_TYPE;
|
||||
}
|
||||
|
||||
void Unit::StopMoving()
|
||||
{
|
||||
ClearUnitState(UNIT_STATE_MOVING);
|
||||
@@ -16058,6 +16066,26 @@ void Unit::StopMoving()
|
||||
init.Stop();
|
||||
}
|
||||
|
||||
void Unit::PauseMovement(uint32 timer /* = 0*/, uint8 slot /* = 0*/)
|
||||
{
|
||||
if (slot >= MAX_MOTION_SLOT)
|
||||
return;
|
||||
|
||||
if (MovementGenerator* movementGenerator = GetMotionMaster()->GetMotionSlot(slot))
|
||||
movementGenerator->Pause(timer);
|
||||
|
||||
StopMoving();
|
||||
}
|
||||
|
||||
void Unit::ResumeMovement(uint32 timer /* = 0*/, uint8 slot /* = 0*/)
|
||||
{
|
||||
if (slot >= MAX_MOTION_SLOT)
|
||||
return;
|
||||
|
||||
if (MovementGenerator* movementGenerator = GetMotionMaster()->GetMotionSlot(slot))
|
||||
movementGenerator->Resume(timer);
|
||||
}
|
||||
|
||||
void Unit::StopMovingOnCurrentPos() // pussywizard
|
||||
{
|
||||
ClearUnitState(UNIT_STATE_MOVING);
|
||||
@@ -17649,8 +17677,16 @@ bool Unit::SetCharmedBy(Unit* charmer, CharmType type, AuraApplication const* au
|
||||
|
||||
if (GetTypeId() == TYPEID_UNIT)
|
||||
{
|
||||
if (MovementGenerator* movementGenerator = GetMotionMaster()->GetMotionSlot(MOTION_SLOT_IDLE))
|
||||
{
|
||||
movementGenerator->Pause(0);
|
||||
}
|
||||
|
||||
GetMotionMaster()->Clear(MOTION_SLOT_ACTIVE);
|
||||
|
||||
StopMoving();
|
||||
|
||||
ToCreature()->AI()->OnCharmed(true);
|
||||
GetMotionMaster()->MoveIdle();
|
||||
|
||||
// Xinef: If creature can fly, add normal player flying flag (fixes speed)
|
||||
if (charmer->GetTypeId() == TYPEID_PLAYER && ToCreature()->CanFly())
|
||||
@@ -19107,7 +19143,7 @@ bool Unit::CanSwim() const
|
||||
return true;
|
||||
if (HasFlag(UNIT_FIELD_FLAGS_2, 0x1000000))
|
||||
return false;
|
||||
if (IsPet() && HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PET_IN_COMBAT))
|
||||
if (HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PET_IN_COMBAT))
|
||||
return true;
|
||||
return HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_RENAME | UNIT_FLAG_SWIMMING);
|
||||
}
|
||||
|
||||
@@ -2345,10 +2345,13 @@ public:
|
||||
|
||||
MotionMaster* GetMotionMaster() { return i_motionMaster; }
|
||||
[[nodiscard]] const MotionMaster* GetMotionMaster() const { return i_motionMaster; }
|
||||
[[nodiscard]] virtual MovementGeneratorType GetDefaultMovementType() const;
|
||||
|
||||
[[nodiscard]] bool IsStopped() const { return !(HasUnitState(UNIT_STATE_MOVING)); }
|
||||
void StopMoving();
|
||||
void StopMovingOnCurrentPos();
|
||||
virtual void PauseMovement(uint32 timer = 0, uint8 slot = 0); // timer in ms
|
||||
void ResumeMovement(uint32 timer = 0, uint8 slot = 0);
|
||||
|
||||
void AddUnitMovementFlag(uint32 f) { m_movementInfo.flags |= f; }
|
||||
void RemoveUnitMovementFlag(uint32 f) { m_movementInfo.flags &= ~f; }
|
||||
|
||||
Reference in New Issue
Block a user