Core/Movement: ported most movement updates from master branch and corrected behavior of CREATURE_STATIC_FLAG_4_PREVENT_SWIM
This commit is contained in:
1 parent
83958342d9
commit
2953efb7a3
22 files changed
+279
-287
No files matched your search
@@ -0,0 +1,26 @@
|
||||
-- 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`;
|
||||
@@ -128,7 +128,8 @@ enum ZLiquidStatus : uint32
|
||||
LIQUID_MAP_ABOVE_WATER = 0x00000001,
|
||||
LIQUID_MAP_WATER_WALK = 0x00000002,
|
||||
LIQUID_MAP_IN_WATER = 0x00000004,
|
||||
LIQUID_MAP_UNDER_WATER = 0x00000008
|
||||
LIQUID_MAP_UNDER_WATER = 0x00000008,
|
||||
LIQUID_MAP_OCEAN_FLOOR = 0x00000010
|
||||
};
|
||||
|
||||
#define MAP_LIQUID_STATUS_SWIMMING (LIQUID_MAP_IN_WATER | LIQUID_MAP_UNDER_WATER)
|
||||
|
||||
@@ -76,7 +76,7 @@ void WorldDatabaseConnection::DoPrepareStatements()
|
||||
PrepareStatement(WORLD_SEL_WAYPOINT_SCRIPT_ID_BY_GUID, "SELECT id FROM waypoint_scripts WHERE guid = ?", CONNECTION_SYNCH);
|
||||
PrepareStatement(WORLD_DEL_CREATURE, "DELETE FROM creature WHERE guid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(WORLD_SEL_COMMANDS, "SELECT name, permission, help FROM command", CONNECTION_SYNCH);
|
||||
PrepareStatement(WORLD_SEL_CREATURE_TEMPLATE, "SELECT entry, difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, modelid1, modelid2, modelid3, modelid4, name, femaleName, subname, IconName, gossip_menu_id, minlevel, maxlevel, exp, exp_unk, faction, npcflag, speed_walk, speed_run, scale, `rank`, dmgschool, BaseAttackTime, RangeAttackTime, BaseVariance, RangeVariance, unit_class, unit_flags, unit_flags2, dynamicflags, family, trainer_class, type, type_flags, type_flags2, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, ctm.Ground, ctm.Swim, ctm.Flight, ctm.Rooted, ctm.Random, ctm.InteractionPauseTimer, HoverHeight, HealthModifier, HealthModifierExtra, ManaModifier, ManaModifierExtra, ArmorModifier, DamageModifier, ExperienceModifier, RacialLeader, movementId, RegenHealth, mechanic_immune_mask, spell_school_immune_mask, flags_extra, StaticFlags, StaticFlags2, StaticFlags3, StaticFlags4, StaticFlags5, ScriptName FROM creature_template ct LEFT JOIN creature_template_movement ctm ON ct.entry = ctm.CreatureId WHERE entry = ?", CONNECTION_SYNCH);
|
||||
PrepareStatement(WORLD_SEL_CREATURE_TEMPLATE, "SELECT entry, difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, modelid1, modelid2, modelid3, modelid4, name, femaleName, subname, IconName, gossip_menu_id, minlevel, maxlevel, exp, exp_unk, faction, npcflag, speed_walk, speed_run, scale, `rank`, dmgschool, BaseAttackTime, RangeAttackTime, BaseVariance, RangeVariance, unit_class, unit_flags, unit_flags2, dynamicflags, family, trainer_class, type, type_flags, type_flags2, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, ctm.HoverInitiallyEnabled, ctm.Random, ctm.InteractionPauseTimer, HoverHeight, HealthModifier, HealthModifierExtra, ManaModifier, ManaModifierExtra, ArmorModifier, DamageModifier, ExperienceModifier, RacialLeader, movementId, RegenHealth, mechanic_immune_mask, spell_school_immune_mask, flags_extra, StaticFlags, StaticFlags2, StaticFlags3, StaticFlags4, StaticFlags5, ScriptName FROM creature_template ct LEFT JOIN creature_template_movement ctm ON ct.entry = ctm.CreatureId WHERE entry = ?", CONNECTION_SYNCH);
|
||||
PrepareStatement(WORLD_SEL_WAYPOINT_SCRIPT_BY_ID, "SELECT guid, delay, command, datalong, datalong2, dataint, x, y, z, o FROM waypoint_scripts WHERE id = ?", CONNECTION_SYNCH);
|
||||
PrepareStatement(WORLD_SEL_CREATURE_BY_ID, "SELECT guid FROM creature WHERE id = ?", CONNECTION_SYNCH);
|
||||
PrepareStatement(WORLD_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_", CONNECTION_SYNCH);
|
||||
|
||||
@@ -145,7 +145,7 @@ void BattlegroundIC::PostUpdateImpl(uint32 diff)
|
||||
{
|
||||
if (siege->IsAlive())
|
||||
{
|
||||
if (siege->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE|UNIT_FLAG_CANNOT_SWIM|UNIT_FLAG_IMMUNE_TO_PC))
|
||||
if (siege->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_CANT_SWIM | UNIT_FLAG_IMMUNE_TO_PC))
|
||||
// following sniffs the vehicle always has UNIT_FLAG_CANNOT_SWIM
|
||||
siege->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_IMMUNE_TO_PC);
|
||||
else
|
||||
@@ -753,7 +753,7 @@ void BattlegroundIC::HandleCapturedNodes(ICNodePoint* node, bool recapture)
|
||||
|
||||
if (Creature* siegeEngine = GetBGCreature(siegeType))
|
||||
{
|
||||
siegeEngine->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE|UNIT_FLAG_CANNOT_SWIM);
|
||||
siegeEngine->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_CANT_SWIM);
|
||||
siegeEngine->SetImmuneToPC(true);
|
||||
siegeEngine->SetFaction(BG_IC_Factions[(node->faction == TEAM_ALLIANCE ? 0 : 1)]);
|
||||
}
|
||||
|
||||
@@ -368,14 +368,14 @@ bool CombatManager::UpdateOwnerCombatState() const
|
||||
|
||||
if (combatState)
|
||||
{
|
||||
_owner->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT);
|
||||
_owner->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT | UNIT_FLAG_PET_IN_COMBAT);
|
||||
_owner->AtEnterCombat();
|
||||
if (_owner->GetTypeId() != TYPEID_UNIT)
|
||||
_owner->AtEngage(GetAnyTarget());
|
||||
}
|
||||
else
|
||||
{
|
||||
_owner->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT);
|
||||
_owner->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT | UNIT_FLAG_PET_IN_COMBAT);
|
||||
_owner->AtExitCombat();
|
||||
if (_owner->GetTypeId() != TYPEID_UNIT)
|
||||
_owner->AtDisengage();
|
||||
|
||||
@@ -61,24 +61,18 @@
|
||||
VendorItemCount::VendorItemCount(uint32 _item, uint32 _count)
|
||||
: itemId(_item), count(_count), lastIncrementTime(GameTime::GetGameTime()) { }
|
||||
|
||||
CreatureMovementData::CreatureMovementData() : Ground(CreatureGroundMovementType::Run), Flight(CreatureFlightMovementType::None),
|
||||
Swim(true), Rooted(false), Random(CreatureRandomMovementType::Walk), InteractionPauseTimer(sWorld->getIntConfig(CONFIG_CREATURE_STOP_FOR_PLAYER)) { }
|
||||
CreatureMovementData::CreatureMovementData() : HoverInitiallyEnabled(false), Random(CreatureRandomMovementType::Walk), InteractionPauseTimer(sWorld->getIntConfig(CONFIG_CREATURE_STOP_FOR_PLAYER)) { }
|
||||
|
||||
|
||||
std::string CreatureMovementData::ToString() const
|
||||
{
|
||||
char const* const GroundStates[] = { "None", "Run", "Hover" };
|
||||
char const* const FlightStates[] = { "None", "DisableGravity", "CanFly" };
|
||||
char const* const RandomStates[] = { "Walk", "CanRun", "AlwaysRun" };
|
||||
|
||||
std::ostringstream str;
|
||||
str << std::boolalpha
|
||||
<< "Ground: " << GroundStates[AsUnderlyingType(Ground)]
|
||||
<< ", Swim: " << Swim
|
||||
<< ", Flight: " << FlightStates[AsUnderlyingType(Flight)]
|
||||
<< ", Random: " << RandomStates[AsUnderlyingType(Random)];
|
||||
if (Rooted)
|
||||
str << ", Rooted";
|
||||
<< ", HoverInitiallyEnabled: " << HoverInitiallyEnabled
|
||||
<< "Random: " << RandomStates[AsUnderlyingType(Random)];
|
||||
|
||||
str << ", InteractionPauseTimer: " << InteractionPauseTimer;
|
||||
|
||||
return str.str();
|
||||
@@ -589,8 +583,8 @@ bool Creature::UpdateEntry(uint32 entry, CreatureData const* data /*= nullptr*/,
|
||||
|
||||
SetFaction(cInfo->faction);
|
||||
|
||||
uint32 npcflag, unit_flags, dynamicflags;
|
||||
ObjectMgr::ChooseCreatureFlags(cInfo, npcflag, unit_flags, dynamicflags, data);
|
||||
uint32 npcflag, unit_flags, unit_flags2, dynamicflags;
|
||||
ObjectMgr::ChooseCreatureFlags(cInfo, npcflag, unit_flags, unit_flags2, dynamicflags, _staticFlags, data);
|
||||
|
||||
if (cInfo->flags_extra & CREATURE_FLAG_EXTRA_WORLDEVENT)
|
||||
SetUInt32Value(UNIT_NPC_FLAGS, npcflag | sGameEventMgr->GetNPCFlag(this));
|
||||
@@ -603,7 +597,7 @@ bool Creature::UpdateEntry(uint32 entry, CreatureData const* data /*= nullptr*/,
|
||||
unit_flags |= UNIT_FLAG_IN_COMBAT;
|
||||
|
||||
SetUInt32Value(UNIT_FIELD_FLAGS, unit_flags);
|
||||
SetUInt32Value(UNIT_FIELD_FLAGS_2, cInfo->unit_flags2);
|
||||
SetUInt32Value(UNIT_FIELD_FLAGS_2, cInfo->unit_flags2 | unit_flags2);
|
||||
|
||||
SetUInt32Value(UNIT_DYNAMIC_FLAGS, dynamicflags);
|
||||
|
||||
@@ -662,13 +656,12 @@ bool Creature::UpdateEntry(uint32 entry, CreatureData const* data /*= nullptr*/,
|
||||
ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, true);
|
||||
}
|
||||
|
||||
if (GetMovementTemplate().IsRooted())
|
||||
SetControlled(true, UNIT_STATE_ROOT);
|
||||
|
||||
if (cInfo->flags_extra & CREATURE_FLAG_EXTRA_NO_COMBAT)
|
||||
SetIgnoringCombat(true);
|
||||
|
||||
InitializeMovementFlags();
|
||||
InitializeMovementCapabilities();
|
||||
|
||||
LoadCreaturesAddon();
|
||||
LoadTemplateImmunities();
|
||||
|
||||
@@ -680,8 +673,7 @@ void Creature::ApplyAllStaticFlags(CreatureStaticFlagsHolder const& flags)
|
||||
{
|
||||
_staticFlags = flags;
|
||||
|
||||
// Apply all other side effects of flag changes
|
||||
SetTemplateRooted(flags.HasFlag(CREATURE_STATIC_FLAG_SESSILE));
|
||||
m_updateFlag.NoBirthAnim = flags.HasFlag(CREATURE_STATIC_FLAG_4_NO_BIRTH_ANIM);
|
||||
}
|
||||
|
||||
void Creature::Update(uint32 diff)
|
||||
@@ -694,7 +686,7 @@ void Creature::Update(uint32 diff)
|
||||
AI()->JustAppeared();
|
||||
}
|
||||
|
||||
UpdateMovementFlags(false);
|
||||
UpdateMovementCapabilities();
|
||||
|
||||
GetThreatManager().Update(diff);
|
||||
|
||||
@@ -1110,7 +1102,7 @@ bool Creature::SetDisableGravity(bool disable, bool packetOnly /*= false*/, bool
|
||||
if (!Unit::SetDisableGravity(disable, packetOnly, updateAnimationTier))
|
||||
return false;
|
||||
|
||||
if (updateAnimationTier && IsAlive() && !HasUnitState(UNIT_STATE_ROOT) && !GetMovementTemplate().IsRooted())
|
||||
if (updateAnimationTier && IsAlive() && !HasUnitState(UNIT_STATE_ROOT))
|
||||
{
|
||||
if (IsGravityDisabled())
|
||||
SetAnimationTier(AnimationTier::Fly);
|
||||
@@ -1132,7 +1124,7 @@ bool Creature::SetHover(bool enable, bool packetOnly /*= false*/, bool updateAni
|
||||
if (!Unit::SetHover(enable, packetOnly, updateAnimationTier))
|
||||
return false;
|
||||
|
||||
if (updateAnimationTier && IsAlive() && !HasUnitState(UNIT_STATE_ROOT) && !GetMovementTemplate().IsRooted())
|
||||
if (updateAnimationTier && IsAlive() && !HasUnitState(UNIT_STATE_ROOT))
|
||||
{
|
||||
if (IsGravityDisabled())
|
||||
SetAnimationTier(AnimationTier::Fly);
|
||||
@@ -1727,17 +1719,6 @@ void Creature::SetSpawnHealth()
|
||||
SetHealth((m_deathState == ALIVE || m_deathState == JUST_RESPAWNED) ? curhealth : 0);
|
||||
}
|
||||
|
||||
void Creature::LoadTemplateRoot()
|
||||
{
|
||||
SetTemplateRooted(GetMovementTemplate().IsRooted());
|
||||
}
|
||||
|
||||
void Creature::SetTemplateRooted(bool rooted)
|
||||
{
|
||||
_staticFlags.ApplyFlag(CREATURE_STATIC_FLAG_SESSILE, rooted);
|
||||
SetControlled(rooted, UNIT_STATE_ROOT);
|
||||
}
|
||||
|
||||
bool Creature::hasQuest(uint32 quest_id) const
|
||||
{
|
||||
return sObjectMgr->GetCreatureQuestRelations(GetEntry()).HasQuest(quest_id);
|
||||
@@ -1968,7 +1949,7 @@ void Creature::setDeathState(DeathState s)
|
||||
if (m_formation && m_formation->getLeader() == this)
|
||||
m_formation->FormationReset(true);
|
||||
|
||||
bool needsFalling = (IsFlying() || IsHovering()) && !IsUnderWater();
|
||||
bool needsFalling = (IsFlying() || IsHovering()) && !IsUnderWater() && !HasUnitState(UNIT_STATE_ROOT);
|
||||
SetHover(false, false);
|
||||
SetDisableGravity(false, false);
|
||||
|
||||
@@ -1988,7 +1969,7 @@ void Creature::setDeathState(DeathState s)
|
||||
ResetPlayerDamageReq();
|
||||
|
||||
SetCannotReachTarget(false);
|
||||
UpdateMovementFlags(true);
|
||||
UpdateMovementCapabilities();
|
||||
|
||||
ClearUnitState(UNIT_STATE_ALL_ERASABLE);
|
||||
|
||||
@@ -1997,11 +1978,12 @@ void Creature::setDeathState(DeathState s)
|
||||
CreatureData const* creatureData = GetCreatureData();
|
||||
CreatureTemplate const* cinfo = GetCreatureTemplate();
|
||||
|
||||
uint32 npcflag, unit_flags, dynamicflags;
|
||||
ObjectMgr::ChooseCreatureFlags(cinfo, npcflag, unit_flags, dynamicflags, creatureData);
|
||||
uint32 npcflag, unit_flags, unit_flags2, dynamicflags;
|
||||
ObjectMgr::ChooseCreatureFlags(cinfo, npcflag, unit_flags, unit_flags2, dynamicflags, _staticFlags, creatureData);
|
||||
|
||||
SetUInt32Value(UNIT_NPC_FLAGS, npcflag);
|
||||
SetUInt32Value(UNIT_FIELD_FLAGS, unit_flags);
|
||||
SetUInt32Value(UNIT_FIELD_FLAGS_2, cinfo->unit_flags2 | unit_flags2);
|
||||
SetUInt32Value(UNIT_DYNAMIC_FLAGS, dynamicflags);
|
||||
|
||||
SetMeleeDamageSchool(SpellSchools(cinfo->dmgschool));
|
||||
@@ -2527,7 +2509,7 @@ bool Creature::CanCreatureAttack(Unit const* victim, bool /*force*/) const
|
||||
dist += GetCombatReach() + victim->GetCombatReach();
|
||||
|
||||
// to prevent creatures in air ignore attacks because distance is already too high...
|
||||
if (GetMovementTemplate().IsFlightAllowed())
|
||||
if (CanFly())
|
||||
return victim->IsInDist2d(&m_homePosition, dist);
|
||||
else
|
||||
return victim->IsInDist(&m_homePosition, dist);
|
||||
@@ -2561,14 +2543,6 @@ bool Creature::LoadCreaturesAddon()
|
||||
SetAnimationTier(AnimationTier(creatureAddon->animTier));
|
||||
SetByteValue(UNIT_FIELD_BYTES_1, UNIT_BYTES_1_OFFSET_VIS_FLAG, creatureAddon->visFlags);
|
||||
|
||||
//! 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);
|
||||
|
||||
// UNIT_FIELD_BYTES_2 values
|
||||
SetSheath(SheathState(creatureAddon->sheathState));
|
||||
SetByteValue(UNIT_FIELD_BYTES_2, UNIT_BYTES_2_OFFSET_PVP_FLAG, creatureAddon->pvpFlags);
|
||||
@@ -2672,6 +2646,45 @@ void Creature::GetRespawnPosition(float &x, float &y, float &z, float* ori, floa
|
||||
}
|
||||
}
|
||||
|
||||
void Creature::InitializeMovementCapabilities()
|
||||
{
|
||||
SetHover(GetMovementTemplate().IsHoverInitiallyEnabled());
|
||||
SetDisableGravity(IsFloating());
|
||||
SetControlled(IsSessile(), UNIT_STATE_ROOT);
|
||||
|
||||
if (IsSwimPrevented())
|
||||
{
|
||||
SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_AI_WILL_ONLY_SWIM_IF_TARGET_SWIMS);
|
||||
SetSwim(false);
|
||||
}
|
||||
else
|
||||
RemoveFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_AI_WILL_ONLY_SWIM_IF_TARGET_SWIMS);
|
||||
|
||||
UpdateMovementCapabilities();
|
||||
}
|
||||
|
||||
void Creature::UpdateMovementCapabilities()
|
||||
{
|
||||
// Do not update movement flags if creature is controlled by a player (charm/vehicle)
|
||||
if (IsMovedByClient())
|
||||
return;
|
||||
|
||||
// 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();
|
||||
bool isInAir = (G3D::fuzzyGt(GetPositionZ(), ground + GetHoverOffset() + GROUND_HEIGHT_TOLERANCE) || G3D::fuzzyLt(GetPositionZ(), ground - GROUND_HEIGHT_TOLERANCE)); // Can be underground too, prevent the falling
|
||||
if (!isInAir)
|
||||
RemoveUnitMovementFlag(MOVEMENTFLAG_FALLING);
|
||||
|
||||
if (HasFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_AI_WILL_ONLY_SWIM_IF_TARGET_SWIMS))
|
||||
if (GetVictim() && GetVictim()->IsInWater() && !GetVictim()->IsOnOceanFloor())
|
||||
RemoveFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_AI_WILL_ONLY_SWIM_IF_TARGET_SWIMS);
|
||||
|
||||
if (IsInWater() && CanSwim())
|
||||
SetSwim(true);
|
||||
else if (!IsInWater()) // We do not want to disable swimming again when a creature is in water - may to lead some nasty bugs
|
||||
SetSwim(false);
|
||||
}
|
||||
|
||||
CreatureMovementData const& Creature::GetMovementTemplate() const
|
||||
{
|
||||
if (CreatureMovementData const* movementOverride = sObjectMgr->GetCreatureMovementOverride(m_spawnId))
|
||||
@@ -2691,25 +2704,6 @@ bool Creature::CanSwim() const
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Creature::CanEnterWater() const
|
||||
{
|
||||
if (CanSwim())
|
||||
return true;
|
||||
|
||||
return GetMovementTemplate().IsSwimAllowed();
|
||||
}
|
||||
|
||||
void Creature::RefreshSwimmingFlag(bool recheck)
|
||||
{
|
||||
if (!_isMissingSwimmingFlagOutOfCombat || recheck)
|
||||
_isMissingSwimmingFlagOutOfCombat = !HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SWIMMING);
|
||||
|
||||
// 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())
|
||||
SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SWIMMING);
|
||||
}
|
||||
|
||||
void Creature::InitializeCreatureMovementInfo(uint32 movementId)
|
||||
{
|
||||
if (CreatureMovementInfoOverride const* movementInfoOverride = sObjectMgr->GetCreatureMovementInfoOverride(movementId))
|
||||
@@ -3001,56 +2995,6 @@ float Creature::GetNativeObjectScale() const
|
||||
return GetCreatureTemplate()->scale;
|
||||
}
|
||||
|
||||
void Creature::InitializeMovementFlags()
|
||||
{
|
||||
LoadTemplateRoot();
|
||||
// It does the same, for now
|
||||
UpdateMovementFlags(true);
|
||||
}
|
||||
|
||||
void Creature::UpdateMovementFlags(bool initializeDBStates)
|
||||
{
|
||||
// Do not update movement flags if creature is controlled by a player (charm/vehicle)
|
||||
if (IsMovedByClient())
|
||||
return;
|
||||
|
||||
// Creatures with CREATURE_FLAG_EXTRA_NO_MOVE_FLAGS_UPDATE should control MovementFlags in your own scripts
|
||||
if (GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_NO_MOVE_FLAGS_UPDATE)
|
||||
return;
|
||||
|
||||
// These movement states are static and should only get applied when initializing a creature's entry (when spawning or transforming)
|
||||
if (initializeDBStates)
|
||||
{
|
||||
if (GetMovementTemplate().IsFlightAllowed())
|
||||
{
|
||||
if (GetMovementTemplate().IsGravityDisabled())
|
||||
SetDisableGravity(true);
|
||||
|
||||
if (GetMovementTemplate().CanFly())
|
||||
SetCanFly(true);
|
||||
}
|
||||
|
||||
if (GetMovementTemplate().IsGroundAllowed())
|
||||
{
|
||||
// Hovering always requires the creature to be alive to avoid visual issues. The IsAlive() check can be removed when respawn compatability has been removed.
|
||||
// @todo: sniffed spawn locations have applied hover offsets to the position z value so either substract them when parsing sniffs or skip the initial relocation from Unit::SetHover
|
||||
if (IsAlive() && GetMovementTemplate().IsHoverEnabled())
|
||||
SetHover(true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// These are realtime movement flag updates which are being updated per tick
|
||||
// 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();
|
||||
bool isInAir = (G3D::fuzzyGt(GetPositionZ(), ground + (IsHovering() ? GetFloatValue(UNIT_FIELD_HOVERHEIGHT) : 0.0f) + GROUND_HEIGHT_TOLERANCE) || G3D::fuzzyLt(GetPositionZ(), ground - GROUND_HEIGHT_TOLERANCE)); // Can be underground too, prevent the falling
|
||||
if (!isInAir)
|
||||
RemoveUnitMovementFlag(MOVEMENTFLAG_FALLING);
|
||||
}
|
||||
|
||||
SetSwim(CanSwim() && IsInWater());
|
||||
}
|
||||
|
||||
void Creature::SetObjectScale(float scale)
|
||||
{
|
||||
Unit::SetObjectScale(scale);
|
||||
@@ -3130,7 +3074,7 @@ void Creature::SetSpellFocus(Spell const* focusSpell, WorldObject const* target)
|
||||
_spellFocusInfo.FocusSpell = focusSpell;
|
||||
|
||||
// Block target based focusing when the attributes or unit flags say so.
|
||||
bool dontFaceTarget = spellInfo->HasAttribute(SPELL_ATTR5_AI_DOESNT_FACE_TARGET)|| spellInfo->HasAttribute(SPELL_ATTR1_TRACK_TARGET_IN_CHANNEL) || HasFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_DISABLE_TURN);
|
||||
bool dontFaceTarget = spellInfo->HasAttribute(SPELL_ATTR5_AI_DOESNT_FACE_TARGET)|| spellInfo->HasAttribute(SPELL_ATTR1_TRACK_TARGET_IN_CHANNEL) || HasFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_CANNOT_TURN);
|
||||
|
||||
ObjectGuid newTarget = (dontFaceTarget || target == this || target == nullptr) ? ObjectGuid::Empty : target->GetGUID();
|
||||
|
||||
@@ -3185,7 +3129,7 @@ void Creature::ReleaseSpellFocus(Spell const* focusSpell, bool withDelay)
|
||||
|
||||
if (IsPet()) // player pets do not use delay system
|
||||
{
|
||||
if (!HasFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_DISABLE_TURN))
|
||||
if (!HasFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_CANNOT_TURN))
|
||||
ReacquireSpellFocusTarget();
|
||||
}
|
||||
else // don't allow re-target right away to prevent visual bugs
|
||||
@@ -3204,7 +3148,7 @@ void Creature::ReacquireSpellFocusTarget()
|
||||
|
||||
SetGuidValue(UNIT_FIELD_TARGET, _spellFocusInfo.OriginalUnitTarget);
|
||||
|
||||
if (!HasFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_DISABLE_TURN))
|
||||
if (!HasFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_CANNOT_TURN))
|
||||
{
|
||||
if (_spellFocusInfo.OriginalUnitTarget)
|
||||
{
|
||||
@@ -3284,8 +3228,6 @@ void Creature::AtEngage(Unit* target)
|
||||
if (!(GetCreatureTemplate()->type_flags & CREATURE_TYPE_FLAG_MOUNTED_COMBAT_ALLOWED))
|
||||
Dismount();
|
||||
|
||||
RefreshSwimmingFlag();
|
||||
|
||||
MovementGeneratorType const movetype = GetMotionMaster()->GetCurrentMovementGeneratorType();
|
||||
if (movetype == WAYPOINT_MOTION_TYPE || movetype == CYCLIC_SPLINE_MOTION_TYPE || movetype == POINT_MOTION_TYPE || (IsAIEnabled() && AI()->IsEscorted()))
|
||||
SetHomePosition(GetPosition());
|
||||
|
||||
@@ -80,9 +80,6 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma
|
||||
void UpdateLevelDependantStats();
|
||||
void LoadEquipment(int8 id = 1, bool force = false);
|
||||
void SetSpawnHealth();
|
||||
void LoadTemplateRoot();
|
||||
bool IsTemplateRooted() const { return _staticFlags.HasFlag(CREATURE_STATIC_FLAG_SESSILE); }
|
||||
void SetTemplateRooted(bool rooted);
|
||||
|
||||
ObjectGuid::LowType GetSpawnId() const { return m_spawnId; }
|
||||
|
||||
@@ -99,12 +96,39 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma
|
||||
bool IsTrigger() const { return (GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_TRIGGER) != 0; }
|
||||
bool IsGuard() const { return (GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_GUARD) != 0; }
|
||||
|
||||
void InitializeMovementCapabilities();
|
||||
void UpdateMovementCapabilities();
|
||||
|
||||
CreatureMovementData const& GetMovementTemplate() const;
|
||||
bool CanWalk() const { return GetMovementTemplate().IsGroundAllowed(); }
|
||||
|
||||
// Returns true if CREATURE_STATIC_FLAG_AQUATIC is set which strictly binds the creature to liquids
|
||||
bool IsAquatic() const { return _staticFlags.HasFlag(CREATURE_STATIC_FLAG_AQUATIC); }
|
||||
|
||||
// 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
|
||||
bool IsAmphibious() const { return _staticFlags.HasFlag(CREATURE_STATIC_FLAG_AMPHIBIOUS); }
|
||||
|
||||
// Returns true if CREATURE_STATIC_FLAG_FLOATING is set which is disabling the gravity of the creature on spawn and reset
|
||||
bool IsFloating() const { return _staticFlags.HasFlag(CREATURE_STATIC_FLAG_FLOATING); }
|
||||
void SetFloating(bool floating) { _staticFlags.ApplyFlag(CREATURE_STATIC_FLAG_FLOATING, floating); SetDisableGravity(floating); }
|
||||
|
||||
// Returns true if CREATURE_STATIC_FLAG_SESSILE is set which permanently roots the creature in place
|
||||
bool IsSessile() const { return _staticFlags.HasFlag(CREATURE_STATIC_FLAG_SESSILE); }
|
||||
void SetSessile(bool sessile) { _staticFlags.ApplyFlag(CREATURE_STATIC_FLAG_SESSILE, sessile); SetControlled(sessile, UNIT_STATE_ROOT); }
|
||||
|
||||
// Returns true if CREATURE_STATIC_FLAG_3_CANNOT_PENETRATE_WATER is set which does not allow the creature to go below liquid surfaces
|
||||
bool CannotPenetrateWater() const { return _staticFlags.HasFlag(CREATURE_STATIC_FLAG_3_CANNOT_PENETRATE_WATER); }
|
||||
void SetCannotPenetrateWater(bool cannotPenetrateWater) { _staticFlags.ApplyFlag(CREATURE_STATIC_FLAG_3_CANNOT_PENETRATE_WATER, cannotPenetrateWater); }
|
||||
|
||||
// Returns true if CREATURE_STATIC_FLAG_3_CANNOT_SWIM is set which prevents 'Amphibious' creatures from swimming when engaged
|
||||
bool IsSwimDisabled() const { return _staticFlags.HasFlag(CREATURE_STATIC_FLAG_3_CANNOT_SWIM); }
|
||||
|
||||
// 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
|
||||
bool IsSwimPrevented() const { return _staticFlags.HasFlag(CREATURE_STATIC_FLAG_4_PREVENT_SWIM); }
|
||||
|
||||
bool CanSwim() const override;
|
||||
bool CanEnterWater() const override;
|
||||
bool CanFly() const override { return GetMovementTemplate().IsFlightAllowed() || IsFlying(); }
|
||||
bool CanHover() const { return GetMovementTemplate().IsHoverEnabled() || IsHovering(); }
|
||||
bool CanEnterWater() const override { return (CanSwim() || IsAmphibious()); };
|
||||
bool CanFly() const override { return (IsFlying() || HasUnitMovementFlag(MOVEMENTFLAG_CAN_FLY)); }
|
||||
|
||||
bool SetDisableGravity(bool disable, bool packetOnly = false, bool updateAnimationTier = true) override;
|
||||
bool SetHover(bool enable, bool packetOnly = false, bool updateAnimationTier = true) override;
|
||||
bool SetCanFly(bool enable, bool packetOnly = false) override;
|
||||
@@ -166,9 +190,6 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma
|
||||
|
||||
bool UpdateEntry(uint32 entry, CreatureData const* data = nullptr, bool updateLevel = true);
|
||||
|
||||
void InitializeMovementFlags();
|
||||
void UpdateMovementFlags(bool initializeDBStates);
|
||||
|
||||
bool UpdateStats(Stats stat) override;
|
||||
bool UpdateAllStats() override;
|
||||
void UpdateResistances(uint32 school) override;
|
||||
@@ -379,12 +400,6 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma
|
||||
bool HasStaticFlag(CreatureStaticFlags4 flag) const { return _staticFlags.HasFlag(flag); }
|
||||
bool HasStaticFlag(CreatureStaticFlags5 flag) const { return _staticFlags.HasFlag(flag); }
|
||||
|
||||
bool HasSwimmingFlagOutOfCombat() const
|
||||
{
|
||||
return !_isMissingSwimmingFlagOutOfCombat;
|
||||
}
|
||||
void RefreshSwimmingFlag(bool recheck = false);
|
||||
|
||||
CreatureMovementInfo const& GetCreatureMovementInfo() const { return _creatureMovementInfo; }
|
||||
|
||||
// Sets the the max health percentage threshold at which uncontrolled/unowned creatures can no longer deal damage to the creature
|
||||
|
||||
@@ -45,7 +45,7 @@ enum CreatureFlagsExtra : uint32
|
||||
CREATURE_FLAG_EXTRA_NO_XP_AT_KILL = 0x00000040, // creature kill not provide XP
|
||||
CREATURE_FLAG_EXTRA_TRIGGER = 0x00000080, // trigger creature
|
||||
CREATURE_FLAG_EXTRA_NO_TAUNT = 0x00000100, // creature is immune to taunt auras and effect attack me
|
||||
CREATURE_FLAG_EXTRA_NO_MOVE_FLAGS_UPDATE = 0x00000200, // creature won't update movement flags
|
||||
CREATURE_FLAG_EXTRA_UNUSED_9 = 0x00000200,
|
||||
CREATURE_FLAG_EXTRA_GHOST_VISIBILITY = 0x00000400, // creature will be only visible for dead players
|
||||
CREATURE_FLAG_EXTRA_USE_OFFHAND_ATTACK = 0x00000800, // creature will use offhand attacks
|
||||
CREATURE_FLAG_EXTRA_NO_SELL_VENDOR = 0x00001000, // players can't sell items to this vendor
|
||||
@@ -296,24 +296,6 @@ private:
|
||||
EnumFlag<CreatureStaticFlags5> _flags5;
|
||||
};
|
||||
|
||||
enum class CreatureGroundMovementType : uint8
|
||||
{
|
||||
None,
|
||||
Run,
|
||||
Hover,
|
||||
|
||||
Max
|
||||
};
|
||||
|
||||
enum class CreatureFlightMovementType : uint8
|
||||
{
|
||||
None,
|
||||
DisableGravity,
|
||||
CanFly,
|
||||
|
||||
Max
|
||||
};
|
||||
|
||||
enum class CreatureRandomMovementType : uint8
|
||||
{
|
||||
Walk,
|
||||
@@ -327,23 +309,14 @@ struct TC_GAME_API CreatureMovementData
|
||||
{
|
||||
CreatureMovementData();
|
||||
|
||||
CreatureGroundMovementType Ground;
|
||||
CreatureFlightMovementType Flight;
|
||||
bool Swim;
|
||||
bool Rooted;
|
||||
bool HoverInitiallyEnabled;
|
||||
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; }
|
||||
bool IsGravityDisabled() const { return Flight == CreatureFlightMovementType::DisableGravity; }
|
||||
bool CanFly() const { return Flight == CreatureFlightMovementType::CanFly; }
|
||||
bool IsHoverEnabled() const { return Ground == CreatureGroundMovementType::Hover; }
|
||||
|
||||
CreatureRandomMovementType GetRandom() const { return Random; }
|
||||
|
||||
bool IsHoverInitiallyEnabled() const { return HoverInitiallyEnabled; }
|
||||
|
||||
uint32 GetInteractionPauseTimer() const { return InteractionPauseTimer; }
|
||||
|
||||
std::string ToString() const;
|
||||
|
||||
@@ -3710,9 +3710,17 @@ float WorldObject::GetFloorZ() const
|
||||
|
||||
float WorldObject::GetMapWaterOrGroundLevel(float x, float y, float z, float* ground/* = nullptr*/) const
|
||||
{
|
||||
return GetMap()->GetWaterOrGroundLevel(GetPhaseShift(), x, y, z, ground,
|
||||
isType(TYPEMASK_UNIT) ? !static_cast<Unit const*>(this)->HasAuraType(SPELL_AURA_WATER_WALK) : false,
|
||||
GetCollisionHeight());
|
||||
bool swimming = [&]()
|
||||
{
|
||||
if (Creature const* creature = ToCreature())
|
||||
return (!creature->CannotPenetrateWater() && !creature->HasAuraType(SPELL_AURA_WATER_WALK));
|
||||
else if (Unit const* unit = ToUnit())
|
||||
return !unit->HasAuraType(SPELL_AURA_WATER_WALK);
|
||||
|
||||
return true;
|
||||
}();
|
||||
|
||||
return GetMap()->GetWaterOrGroundLevel(GetPhaseShift(), x, y, z, ground, swimming, GetCollisionHeight());
|
||||
}
|
||||
|
||||
float WorldObject::GetMapHeight(float x, float y, float z, bool vmap/* = true*/, float distanceToSearch/* = DEFAULT_HEIGHT_SEARCH*/) const
|
||||
|
||||
@@ -2940,10 +2940,23 @@ bool Unit::isInBackInMap(Unit const* target, float distance, float arc) const
|
||||
|
||||
bool Unit::isInAccessiblePlaceFor(Creature const* c) const
|
||||
{
|
||||
if (IsInWater())
|
||||
return c->CanEnterWater();
|
||||
else
|
||||
return c->CanWalk() || c->CanFly();
|
||||
// Aquatic creatures are not allowed to leave liquids
|
||||
if (!IsInWater() && c->IsAquatic())
|
||||
return false;
|
||||
|
||||
// Underwater special case. Some creatures may not go below liquid surfaces
|
||||
if (IsUnderWater() && c->CannotPenetrateWater())
|
||||
return false;
|
||||
|
||||
// Water checks
|
||||
if (IsInWater() && !c->CanEnterWater())
|
||||
return false;
|
||||
|
||||
// Some creatures are tied to the ocean floor and cannot chase swimming targets.
|
||||
if (!IsOnOceanFloor() && c->IsUnderWater() && c->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_CANT_SWIM))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Unit::IsInWater() const
|
||||
@@ -2956,6 +2969,11 @@ bool Unit::IsUnderWater() const
|
||||
return GetLiquidStatus() & LIQUID_MAP_UNDER_WATER;
|
||||
}
|
||||
|
||||
bool Unit::IsOnOceanFloor() const
|
||||
{
|
||||
return GetLiquidStatus() & LIQUID_MAP_OCEAN_FLOOR;
|
||||
}
|
||||
|
||||
void Unit::ProcessPositionDataChanged(PositionFullTerrainStatus const& data)
|
||||
{
|
||||
ZLiquidStatus oldLiquidStatus = GetLiquidStatus();
|
||||
@@ -8673,6 +8691,10 @@ void Unit::UpdatePetCombatState()
|
||||
{
|
||||
ASSERT(!IsPet()); // player pets do not use UNIT_FLAG_PET_IN_COMBAT for this purpose - but player pets should also never have minions of their own to call this
|
||||
|
||||
// UNIT_FLAG_PET_IN_COMBAT is set by default when the summoner is in combat by himself
|
||||
if (IsInCombat())
|
||||
return;
|
||||
|
||||
bool state = false;
|
||||
for (Unit* minion : m_Controlled)
|
||||
if (minion->IsInCombat())
|
||||
@@ -11325,7 +11347,7 @@ void Unit::SetControlled(bool apply, UnitState state)
|
||||
SetStunned(false);
|
||||
break;
|
||||
case UNIT_STATE_ROOT:
|
||||
if (HasAuraType(SPELL_AURA_MOD_ROOT) || GetVehicle() || (ToCreature() && ToCreature()->GetMovementTemplate().IsRooted()))
|
||||
if (HasAuraType(SPELL_AURA_MOD_ROOT) || GetVehicle() || (IsCreature() && ToCreature()->IsSessile()))
|
||||
return;
|
||||
|
||||
ClearUnitState(state);
|
||||
@@ -12972,15 +12994,15 @@ bool Unit::IsFalling() const
|
||||
bool Unit::CanSwim() const
|
||||
{
|
||||
// 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
|
||||
if (HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_CANNOT_SWIM))
|
||||
if (HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_CANT_SWIM))
|
||||
return false;
|
||||
if (HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED)) // is player
|
||||
return true;
|
||||
if (HasFlag(UNIT_FIELD_FLAGS_2, 0x1000000))
|
||||
if (HasFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_AI_WILL_ONLY_SWIM_IF_TARGET_SWIMS))
|
||||
return false;
|
||||
if (HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PET_IN_COMBAT))
|
||||
return true;
|
||||
return HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_RENAME | UNIT_FLAG_SWIMMING);
|
||||
return HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_RENAME | UNIT_FLAG_CAN_SWIM);
|
||||
}
|
||||
|
||||
void Unit::NearTeleportTo(Position const& pos, bool casting /*= false*/)
|
||||
|
||||
@@ -1124,6 +1124,7 @@ class TC_GAME_API Unit : public WorldObject
|
||||
|
||||
bool IsInWater() const;
|
||||
bool IsUnderWater() const;
|
||||
bool IsOnOceanFloor() const;
|
||||
bool isInAccessiblePlaceFor(Creature const* c) const;
|
||||
|
||||
void SendHealSpellLog(HealInfo& healInfo, bool critical = false);
|
||||
@@ -1715,10 +1716,7 @@ class TC_GAME_API Unit : public WorldObject
|
||||
virtual bool CanEnterWater() const = 0;
|
||||
virtual bool CanSwim() const;
|
||||
|
||||
float GetHoverOffset() const
|
||||
{
|
||||
return HasUnitMovementFlag(MOVEMENTFLAG_HOVER) ? GetFloatValue(UNIT_FIELD_HOVERHEIGHT) : 0.0f;
|
||||
}
|
||||
float GetHoverOffset() const { return HasUnitMovementFlag(MOVEMENTFLAG_HOVER) ? GetFloatValue(UNIT_FIELD_HOVERHEIGHT) : 0.0f; }
|
||||
|
||||
uint32 GetMovementCounterAndInc() { return m_movementCounter++; }
|
||||
uint32 GetMovementCounter() { return m_movementCounter; }
|
||||
|
||||
@@ -138,8 +138,8 @@ enum UnitFlags : uint32
|
||||
UNIT_FLAG_PET_IN_COMBAT = 0x00000800, // on player pets: whether the pet is chasing a target to attack || on other units: whether any of the unit's minions is in combat
|
||||
UNIT_FLAG_PVP = 0x00001000, // changed in 3.0.3
|
||||
UNIT_FLAG_SILENCED = 0x00002000, // silenced, 2.1.1
|
||||
UNIT_FLAG_CANNOT_SWIM = 0x00004000, // 2.0.8
|
||||
UNIT_FLAG_SWIMMING = 0x00008000, // shows swim animation in water
|
||||
UNIT_FLAG_CANT_SWIM = 0x00004000, // 2.0.8
|
||||
UNIT_FLAG_CAN_SWIM = 0x00008000, // shows swim animation in water
|
||||
UNIT_FLAG_NOT_ATTACKABLE_2 = 0x00010000,
|
||||
UNIT_FLAG_PACIFIED = 0x00020000, // 3.0.3 ok
|
||||
UNIT_FLAG_STUNNED = 0x00040000, // 3.0.3 ok
|
||||
@@ -176,11 +176,16 @@ enum UnitFlags2 : uint32
|
||||
UNIT_FLAG2_RESTRICT_PARTY_INTERACTION = 0x00001000, // Restrict interaction to party or raid
|
||||
UNIT_FLAG2_PREVENT_SPELL_CLICK = 0x00002000, // Prevent spellclick
|
||||
UNIT_FLAG2_ALLOW_ENEMY_INTERACT = 0x00004000,
|
||||
UNIT_FLAG2_DISABLE_TURN = 0x00008000,
|
||||
UNIT_FLAG2_CANNOT_TURN = 0x00008000,
|
||||
UNIT_FLAG2_UNK2 = 0x00010000,
|
||||
UNIT_FLAG2_PLAY_DEATH_ANIM = 0x00020000, // Plays special death animation upon death
|
||||
UNIT_FLAG2_ALLOW_CHEAT_SPELLS = 0x00040000, // Allows casting spells with AttributesEx7 & SPELL_ATTR7_IS_CHEAT_SPELL
|
||||
UNIT_FLAG2_SUPPRESS_HIGHLIGHT_WHEN_TARGETED_OR_MOUSED_OVER = 0x00080000, // Suppress highlight when targeted or moused over
|
||||
UNIT_FLAG2_TREAT_AS_RAID_UNIT_FOR_HELPFUL_SPELLS = 0x00100000, // Treat as Raid Unit For Helpful Spells (Instances ONLY)
|
||||
UNIT_FLAG2_LARGE_AOI = 0x00200000, // Large (AOI)
|
||||
UNIT_FLAG2_GIGANTIC_AOI = 0x00400000, // Gigantic (AOI)
|
||||
UNIT_FLAG2_NO_ACTIONS = 0x00800000,
|
||||
UNIT_FLAG2_AI_WILL_ONLY_SWIM_IF_TARGET_SWIMS = 0x01000000, // AI will only swim if target swims
|
||||
UNIT_FLAG2_DISABLE_UNIT_FRAME = 0x04000000, // Disables the unit frame when selecting the target
|
||||
UNIT_FLAG2_IGNORE_SPELL_MIN_RANGE_RESTRICTIONS = 0x08000000 // Allows spells with a min range restriction to be cast when closer than given range value
|
||||
};
|
||||
|
||||
@@ -433,11 +433,11 @@ void ObjectMgr::LoadCreatureTemplates()
|
||||
"dynamicflags, family, trainer_class, type, type_flags, type_flags2, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, "
|
||||
// 48 49 50 51 52 53 54 55 56 57 58 59 60 61
|
||||
"spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, "
|
||||
// 62 63 64 65 66 67 68 69 70 71 72
|
||||
"ctm.Ground, ctm.Swim, ctm.Flight, ctm.Rooted, ctm.Random, ctm.InteractionPauseTimer, HoverHeight, HealthModifier, HealthModifierExtra, ManaModifier, ManaModifierExtra, "
|
||||
// 73 74 75 76 77 78 79 80
|
||||
// 62 63 64 65 66 67 68 69
|
||||
"ctm.HoverInitiallyEnabled, ctm.Random, ctm.InteractionPauseTimer, HoverHeight, HealthModifier, HealthModifierExtra, ManaModifier, ManaModifierExtra, "
|
||||
// 70 71 72 73 74 75 76 77
|
||||
"ArmorModifier, DamageModifier, ExperienceModifier, RacialLeader, movementId, RegenHealth, mechanic_immune_mask, spell_school_immune_mask, "
|
||||
// 81 82 83 84 85 86 87
|
||||
// 78 79 80 81 82 83 84
|
||||
"flags_extra, StaticFlags, StaticFlags2, StaticFlags3, StaticFlags4, StaticFlags5, ScriptName FROM creature_template ct LEFT JOIN creature_template_movement ctm ON ct.entry = ctm.CreatureId");
|
||||
|
||||
if (!result)
|
||||
@@ -528,41 +528,32 @@ void ObjectMgr::LoadCreatureTemplate(Field* fields)
|
||||
creatureTemplate.AIName = fields[60].GetString();
|
||||
creatureTemplate.MovementType = uint32(fields[61].GetUInt8());
|
||||
if (!fields[62].IsNull())
|
||||
creatureTemplate.Movement.Ground = static_cast<CreatureGroundMovementType>(fields[62].GetUInt8());
|
||||
creatureTemplate.Movement.HoverInitiallyEnabled = fields[62].GetBool();
|
||||
|
||||
if (!fields[63].IsNull())
|
||||
creatureTemplate.Movement.Swim = fields[63].GetBool();
|
||||
creatureTemplate.Movement.Random = static_cast<CreatureRandomMovementType>(fields[63].GetUInt8());
|
||||
|
||||
if (!fields[64].IsNull())
|
||||
creatureTemplate.Movement.Flight = static_cast<CreatureFlightMovementType>(fields[64].GetUInt8());
|
||||
creatureTemplate.Movement.InteractionPauseTimer = fields[64].GetUInt32();
|
||||
|
||||
if (!fields[65].IsNull())
|
||||
creatureTemplate.Movement.Rooted = fields[65].GetBool();
|
||||
creatureTemplate.HoverHeight = fields[65].GetFloat();
|
||||
creatureTemplate.ModHealth = fields[66].GetFloat();
|
||||
creatureTemplate.ModHealthExtra = fields[67].GetFloat();
|
||||
creatureTemplate.ModMana = fields[68].GetFloat();
|
||||
creatureTemplate.ModManaExtra = fields[69].GetFloat();
|
||||
creatureTemplate.ModArmor = fields[70].GetFloat();
|
||||
creatureTemplate.ModDamage = fields[71].GetFloat();
|
||||
creatureTemplate.ModExperience = fields[72].GetFloat();
|
||||
|
||||
if (!fields[66].IsNull())
|
||||
creatureTemplate.Movement.Random = static_cast<CreatureRandomMovementType>(fields[66].GetUInt8());
|
||||
|
||||
if (!fields[67].IsNull())
|
||||
creatureTemplate.Movement.InteractionPauseTimer = fields[67].GetUInt32();
|
||||
|
||||
creatureTemplate.HoverHeight = fields[68].GetFloat();
|
||||
creatureTemplate.ModHealth = fields[69].GetFloat();
|
||||
creatureTemplate.ModHealthExtra = fields[70].GetFloat();
|
||||
creatureTemplate.ModMana = fields[71].GetFloat();
|
||||
creatureTemplate.ModManaExtra = fields[72].GetFloat();
|
||||
creatureTemplate.ModArmor = fields[73].GetFloat();
|
||||
creatureTemplate.ModDamage = fields[74].GetFloat();
|
||||
creatureTemplate.ModExperience = fields[75].GetFloat();
|
||||
|
||||
creatureTemplate.RacialLeader = fields[76].GetBool();
|
||||
creatureTemplate.movementId = fields[77].GetUInt32();
|
||||
creatureTemplate.RegenHealth = fields[78].GetBool();
|
||||
creatureTemplate.MechanicImmuneMask = fields[79].GetUInt32();
|
||||
creatureTemplate.SpellSchoolImmuneMask = fields[80].GetUInt32();
|
||||
creatureTemplate.flags_extra = fields[81].GetUInt32();
|
||||
creatureTemplate.StaticFlags = CreatureStaticFlagsHolder(CreatureStaticFlags(fields[82].GetUInt32()), CreatureStaticFlags2(fields[83].GetUInt32()),
|
||||
CreatureStaticFlags3(fields[84].GetUInt32()), CreatureStaticFlags4(fields[85].GetUInt32()), CreatureStaticFlags5(fields[86].GetUInt32()));
|
||||
creatureTemplate.ScriptID = GetScriptId(fields[87].GetCString());
|
||||
creatureTemplate.RacialLeader = fields[73].GetBool();
|
||||
creatureTemplate.movementId = fields[74].GetUInt32();
|
||||
creatureTemplate.RegenHealth = fields[75].GetBool();
|
||||
creatureTemplate.MechanicImmuneMask = fields[76].GetUInt32();
|
||||
creatureTemplate.SpellSchoolImmuneMask = fields[77].GetUInt32();
|
||||
creatureTemplate.flags_extra = fields[78].GetUInt32();
|
||||
creatureTemplate.StaticFlags = CreatureStaticFlagsHolder(CreatureStaticFlags(fields[79].GetUInt32()), CreatureStaticFlags2(fields[80].GetUInt32()),
|
||||
CreatureStaticFlags3(fields[81].GetUInt32()), CreatureStaticFlags4(fields[82].GetUInt32()), CreatureStaticFlags5(fields[83].GetUInt32()));
|
||||
creatureTemplate.ScriptID = GetScriptId(fields[84].GetCString());
|
||||
}
|
||||
|
||||
void ObjectMgr::LoadCreatureTemplateModels()
|
||||
@@ -1129,20 +1120,6 @@ void ObjectMgr::CheckCreatureTemplate(CreatureTemplate const* cInfo)
|
||||
|
||||
void ObjectMgr::CheckCreatureMovement(char const* table, uint64 id, CreatureMovementData& creatureMovement)
|
||||
{
|
||||
if (creatureMovement.Ground >= CreatureGroundMovementType::Max)
|
||||
{
|
||||
TC_LOG_ERROR("sql.sql", "`%s`.`Ground` wrong value (%u) for Id " UI64FMTD ", setting to Run.",
|
||||
table, uint32(creatureMovement.Ground), id);
|
||||
creatureMovement.Ground = CreatureGroundMovementType::Run;
|
||||
}
|
||||
|
||||
if (creatureMovement.Flight >= CreatureFlightMovementType::Max)
|
||||
{
|
||||
TC_LOG_ERROR("sql.sql", "`%s`.`Flight` wrong value (%u) for Id " UI64FMTD ", setting to None.",
|
||||
table, uint32(creatureMovement.Flight), id);
|
||||
creatureMovement.Flight = CreatureFlightMovementType::None;
|
||||
}
|
||||
|
||||
if (creatureMovement.Random >= CreatureRandomMovementType::Max)
|
||||
{
|
||||
TC_LOG_ERROR("sql.sql", "`%s`.`Random` wrong value (%u) for Id " UI64FMTD ", setting to Walk.",
|
||||
@@ -1513,10 +1490,7 @@ void ObjectMgr::LoadCreatureMovementOverrides()
|
||||
// Load the data from creature_movement_override and if NULL fallback to creature_template_movement
|
||||
QueryResult result = WorldDatabase.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.HoverInitiallyEnabled, ctm.HoverInitiallyEnabled),"
|
||||
"COALESCE(cmo.Random, ctm.Random),"
|
||||
"COALESCE(cmo.InteractionPauseTimer, ctm.InteractionPauseTimer) "
|
||||
"FROM creature_movement_override AS cmo "
|
||||
@@ -1541,17 +1515,11 @@ void ObjectMgr::LoadCreatureMovementOverrides()
|
||||
|
||||
CreatureMovementData& movement = _creatureMovementOverrides[spawnId];
|
||||
if (!fields[1].IsNull())
|
||||
movement.Ground = static_cast<CreatureGroundMovementType>(fields[1].GetUInt8());
|
||||
movement.HoverInitiallyEnabled = fields[1].GetBool();
|
||||
if (!fields[2].IsNull())
|
||||
movement.Swim = fields[2].GetBool();
|
||||
movement.Random = static_cast<CreatureRandomMovementType>(fields[3].GetUInt8());
|
||||
if (!fields[3].IsNull())
|
||||
movement.Flight = static_cast<CreatureFlightMovementType>(fields[3].GetUInt8());
|
||||
if (!fields[4].IsNull())
|
||||
movement.Rooted = fields[4].GetBool();
|
||||
if (!fields[5].IsNull())
|
||||
movement.Random = static_cast<CreatureRandomMovementType>(fields[6].GetUInt8());
|
||||
if (!fields[6].IsNull())
|
||||
movement.InteractionPauseTimer = fields[6].GetUInt32();
|
||||
movement.InteractionPauseTimer = fields[4].GetUInt32();
|
||||
|
||||
CheckCreatureMovement("creature_movement_override", spawnId, movement);
|
||||
} while (result->NextRow());
|
||||
@@ -1617,11 +1585,12 @@ CreatureModel const* ObjectMgr::ChooseDisplayId(CreatureTemplate const* cinfo, C
|
||||
return cinfo->GetFirstInvisibleModel();
|
||||
}
|
||||
|
||||
void ObjectMgr::ChooseCreatureFlags(CreatureTemplate const* cinfo, uint32& npcflag, uint32& unit_flags, uint32& dynamicflags, CreatureData const* data /*= nullptr*/)
|
||||
void ObjectMgr::ChooseCreatureFlags(CreatureTemplate const* cinfo, uint32& npcflag, uint32& unit_flags, uint32& unitFlags2, uint32& dynamicflags, CreatureStaticFlagsHolder const& staticFlags, CreatureData const* data /*= nullptr*/)
|
||||
{
|
||||
npcflag = cinfo->npcflag;
|
||||
unit_flags = cinfo->unit_flags;
|
||||
dynamicflags = cinfo->dynamicflags;
|
||||
unitFlags2 = 0;
|
||||
|
||||
if (data)
|
||||
{
|
||||
@@ -1634,6 +1603,18 @@ void ObjectMgr::ChooseCreatureFlags(CreatureTemplate const* cinfo, uint32& npcfl
|
||||
if (data->dynamicflags)
|
||||
dynamicflags = data->dynamicflags;
|
||||
}
|
||||
|
||||
if (staticFlags.HasFlag(CREATURE_STATIC_FLAG_CAN_SWIM))
|
||||
unit_flags |= UNIT_FLAG_CAN_SWIM;
|
||||
|
||||
if (staticFlags.HasFlag(CREATURE_STATIC_FLAG_3_CANNOT_SWIM))
|
||||
unit_flags |= UNIT_FLAG_CANT_SWIM;
|
||||
|
||||
if (staticFlags.HasFlag(CREATURE_STATIC_FLAG_3_CANNOT_TURN))
|
||||
unitFlags2 |= UNIT_FLAG2_CANNOT_TURN;
|
||||
|
||||
if (staticFlags.HasFlag(CREATURE_STATIC_FLAG_4_PREVENT_SWIM))
|
||||
unitFlags2 |= UNIT_FLAG2_AI_WILL_ONLY_SWIM_IF_TARGET_SWIMS;
|
||||
}
|
||||
|
||||
CreatureModelInfo const* ObjectMgr::GetCreatureModelRandomGender(CreatureModel* model, CreatureTemplate const* creatureTemplate) const
|
||||
|
||||
@@ -1015,7 +1015,7 @@ class TC_GAME_API ObjectMgr
|
||||
CreatureModelInfo const* GetCreatureModelInfo(uint32 modelId) const;
|
||||
CreatureModelInfo const* GetCreatureModelRandomGender(CreatureModel* model, CreatureTemplate const* creatureTemplate) const;
|
||||
static CreatureModel const* ChooseDisplayId(CreatureTemplate const* cinfo, CreatureData const* data = nullptr);
|
||||
static void ChooseCreatureFlags(CreatureTemplate const* cinfo, uint32& npcflag, uint32& unit_flags, uint32& dynamicflags, CreatureData const* data = nullptr);
|
||||
static void ChooseCreatureFlags(CreatureTemplate const* cinfo, uint32& npcflag, uint32& unit_flags, uint32& unitFlags2, uint32& dynamicflags, CreatureStaticFlagsHolder const& staticFlags, CreatureData const* data = nullptr);
|
||||
EquipmentInfo const* GetEquipmentInfo(uint32 entry, int8& id) const;
|
||||
CreatureAddon const* GetCreatureAddon(ObjectGuid::LowType lowguid) const;
|
||||
GameObjectAddon const* GetGameObjectAddon(ObjectGuid::LowType lowguid) const;
|
||||
|
||||
@@ -599,6 +599,8 @@ float GridMap::getLiquidLevel(float x, float y) const
|
||||
return _liquidMap[cx_int*_liquidWidth + cy_int];
|
||||
}
|
||||
|
||||
constexpr float GROUND_LEVEL_OFFSET_HACK = 0.02f; // due to floating point precision issues, we have to resort to a small hack to fix inconsistencies in liquids
|
||||
|
||||
// Get water state on map
|
||||
ZLiquidStatus GridMap::GetLiquidStatus(float x, float y, float z, Optional<map_liquidHeaderTypeFlags> ReqLiquidType, LiquidData* data, float collisionHeight) const
|
||||
{
|
||||
@@ -662,11 +664,11 @@ ZLiquidStatus GridMap::GetLiquidStatus(float x, float y, float z, Optional<map_l
|
||||
|
||||
// Get water level
|
||||
float liquid_level = _liquidMap ? _liquidMap[lx_int * _liquidWidth + ly_int] : _liquidLevel;
|
||||
// Get ground level (sub 0.2 for fix some errors)
|
||||
// Get ground level (sub 0.02 for fix some errors)
|
||||
float ground_level = getHeight(x, y);
|
||||
|
||||
// Check water level and ground level
|
||||
if (liquid_level < ground_level || z < ground_level)
|
||||
if (liquid_level < (ground_level - GROUND_LEVEL_OFFSET_HACK) || z < (ground_level - GROUND_LEVEL_OFFSET_HACK))
|
||||
return LIQUID_MAP_NO_WATER;
|
||||
|
||||
// All ok in water -> store data
|
||||
@@ -681,12 +683,18 @@ ZLiquidStatus GridMap::GetLiquidStatus(float x, float y, float z, Optional<map_l
|
||||
// For speed check as int values
|
||||
float delta = liquid_level - z;
|
||||
|
||||
uint32 status = LIQUID_MAP_ABOVE_WATER; // Above water
|
||||
|
||||
if (delta > collisionHeight) // Under water
|
||||
return LIQUID_MAP_UNDER_WATER;
|
||||
if (delta > 0.0f) // In water
|
||||
return LIQUID_MAP_IN_WATER;
|
||||
if (delta > -0.1f) // Walk on water
|
||||
return LIQUID_MAP_WATER_WALK;
|
||||
// Above water
|
||||
return LIQUID_MAP_ABOVE_WATER;
|
||||
status = LIQUID_MAP_UNDER_WATER;
|
||||
else if (delta > 0.0f) // In water
|
||||
status = LIQUID_MAP_IN_WATER;
|
||||
else if (delta > -0.1f) // Walk on water
|
||||
status = LIQUID_MAP_WATER_WALK;
|
||||
|
||||
if (status != LIQUID_MAP_ABOVE_WATER)
|
||||
if (std::fabs(ground_level - z) <= GROUND_HEIGHT_TOLERANCE)
|
||||
status |= LIQUID_MAP_OCEAN_FLOOR;
|
||||
|
||||
return static_cast<ZLiquidStatus>(status);
|
||||
}
|
||||
@@ -431,14 +431,19 @@ void TerrainInfo::GetFullTerrainStatusForPosition(PhaseShift const& phaseShift,
|
||||
data.liquidInfo->type_flags = map_liquidHeaderTypeFlags(1 << liquidFlagType);
|
||||
|
||||
float delta = wmoData->liquidInfo->level - z;
|
||||
uint32 status = LIQUID_MAP_ABOVE_WATER;
|
||||
if (delta > collisionHeight)
|
||||
data.liquidStatus = LIQUID_MAP_UNDER_WATER;
|
||||
status = LIQUID_MAP_UNDER_WATER;
|
||||
else if (delta > 0.0f)
|
||||
data.liquidStatus = LIQUID_MAP_IN_WATER;
|
||||
status = LIQUID_MAP_IN_WATER;
|
||||
else if (delta > -0.1f)
|
||||
data.liquidStatus = LIQUID_MAP_WATER_WALK;
|
||||
else
|
||||
data.liquidStatus = LIQUID_MAP_ABOVE_WATER;
|
||||
status = LIQUID_MAP_WATER_WALK;
|
||||
|
||||
if (status != LIQUID_MAP_ABOVE_WATER)
|
||||
if (std::fabs(wmoData->floorZ - z) <= GROUND_HEIGHT_TOLERANCE)
|
||||
status |= LIQUID_MAP_OCEAN_FLOOR;
|
||||
|
||||
data.liquidStatus = static_cast<ZLiquidStatus>(status);
|
||||
}
|
||||
// look up liquid data from grid map
|
||||
if (gmap && useGridLiquid)
|
||||
@@ -513,12 +518,23 @@ ZLiquidStatus TerrainInfo::GetLiquidStatus(PhaseShift const& phaseShift, uint32
|
||||
float delta = liquid_level - z;
|
||||
|
||||
// Get position delta
|
||||
uint32 status = LIQUID_MAP_ABOVE_WATER;
|
||||
if (delta > collisionHeight) // Under water
|
||||
return LIQUID_MAP_UNDER_WATER;
|
||||
if (delta > 0.0f) // In water
|
||||
return LIQUID_MAP_IN_WATER;
|
||||
if (delta > -0.1f) // Walk on water
|
||||
return LIQUID_MAP_WATER_WALK;
|
||||
status = LIQUID_MAP_UNDER_WATER;
|
||||
else if (delta > 0.0f) // In water
|
||||
status = LIQUID_MAP_IN_WATER;
|
||||
else if (delta > -0.1f) // Walk on water
|
||||
status = LIQUID_MAP_WATER_WALK;
|
||||
|
||||
if (status != LIQUID_MAP_ABOVE_WATER)
|
||||
{
|
||||
if (status != LIQUID_MAP_ABOVE_WATER)
|
||||
if (std::fabs(ground_level - z) <= GROUND_HEIGHT_TOLERANCE)
|
||||
status |= LIQUID_MAP_OCEAN_FLOOR;
|
||||
|
||||
return static_cast<ZLiquidStatus>(status);
|
||||
}
|
||||
|
||||
result = LIQUID_MAP_ABOVE_WATER;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,12 +81,9 @@ void HomeMovementGenerator<Creature>::DoFinalize(Creature* owner)
|
||||
{
|
||||
if (_arrived)
|
||||
{
|
||||
if (!owner->HasSwimmingFlagOutOfCombat())
|
||||
owner->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SWIMMING);
|
||||
|
||||
owner->ClearUnitState(UNIT_STATE_EVADE);
|
||||
owner->SetWalk(true);
|
||||
owner->UpdateMovementFlags(true);
|
||||
owner->InitializeMovementCapabilities();
|
||||
owner->LoadCreaturesAddon();
|
||||
if (owner->IsVehicle())
|
||||
owner->GetVehicleKit()->Reset(true);
|
||||
|
||||
@@ -191,7 +191,7 @@ void PathGenerator::BuildPolyPath(G3D::Vector3 const& startPos, G3D::Vector3 con
|
||||
BuildShortcut();
|
||||
bool path = _source->GetTypeId() == TYPEID_UNIT && _source->ToCreature()->CanFly();
|
||||
|
||||
bool waterPath = _source->GetTypeId() == TYPEID_UNIT && _source->ToCreature()->CanSwim();
|
||||
bool waterPath = _source->GetTypeId() == TYPEID_UNIT && _source->ToCreature()->CanEnterWater();
|
||||
if (waterPath)
|
||||
{
|
||||
// Check both start and end points, if they're both in water, then we can *safely* let the creature move
|
||||
@@ -670,7 +670,7 @@ void PathGenerator::CreateFilter()
|
||||
if (_source->GetTypeId() == TYPEID_UNIT)
|
||||
{
|
||||
Creature* creature = (Creature*)_source;
|
||||
if (creature->CanWalk())
|
||||
if (!creature->IsAquatic())
|
||||
includeFlags |= NAV_GROUND; // walk
|
||||
|
||||
// creatures don't take environmental damage
|
||||
@@ -696,7 +696,7 @@ void PathGenerator::UpdateFilter()
|
||||
|
||||
// allow creatures to cheat and use different movement types if they are moved
|
||||
// forcefully into terrain they can't normally move in
|
||||
if (const Unit* _sourceUnit = _source->ToUnit())
|
||||
if (Unit const* _sourceUnit = _source->ToUnit())
|
||||
{
|
||||
if (_sourceUnit->IsInWater() || _sourceUnit->IsUnderWater())
|
||||
{
|
||||
|
||||
@@ -135,8 +135,8 @@ EnumName<UnitFlags> const unitFlags[MAX_UNIT_FLAGS] =
|
||||
CREATE_NAMED_ENUM(UNIT_FLAG_PET_IN_COMBAT),
|
||||
CREATE_NAMED_ENUM(UNIT_FLAG_PVP),
|
||||
CREATE_NAMED_ENUM(UNIT_FLAG_SILENCED),
|
||||
CREATE_NAMED_ENUM(UNIT_FLAG_CANNOT_SWIM),
|
||||
CREATE_NAMED_ENUM(UNIT_FLAG_SWIMMING),
|
||||
CREATE_NAMED_ENUM(UNIT_FLAG_CANT_SWIM),
|
||||
CREATE_NAMED_ENUM(UNIT_FLAG_CAN_SWIM),
|
||||
CREATE_NAMED_ENUM(UNIT_FLAG_NOT_ATTACKABLE_2),
|
||||
CREATE_NAMED_ENUM(UNIT_FLAG_PACIFIED),
|
||||
CREATE_NAMED_ENUM(UNIT_FLAG_STUNNED),
|
||||
@@ -166,7 +166,7 @@ EnumName<CreatureFlagsExtra> const flagsExtra[] =
|
||||
CREATE_NAMED_ENUM(CREATURE_FLAG_EXTRA_NO_XP_AT_KILL),
|
||||
CREATE_NAMED_ENUM(CREATURE_FLAG_EXTRA_TRIGGER),
|
||||
CREATE_NAMED_ENUM(CREATURE_FLAG_EXTRA_NO_TAUNT),
|
||||
CREATE_NAMED_ENUM(CREATURE_FLAG_EXTRA_NO_MOVE_FLAGS_UPDATE),
|
||||
CREATE_NAMED_ENUM(CREATURE_FLAG_EXTRA_UNUSED_9),
|
||||
CREATE_NAMED_ENUM(CREATURE_FLAG_EXTRA_NO_SELL_VENDOR),
|
||||
CREATE_NAMED_ENUM(CREATURE_FLAG_EXTRA_NO_COMBAT),
|
||||
CREATE_NAMED_ENUM(CREATURE_FLAG_EXTRA_WORLDEVENT),
|
||||
|
||||
@@ -536,7 +536,7 @@ public:
|
||||
|
||||
me->RestoreFaction();
|
||||
CombatAI::Reset();
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SWIMMING);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_CAN_SWIM);
|
||||
}
|
||||
|
||||
void SpellHit(WorldObject* pCaster, SpellInfo const* pSpell) override
|
||||
@@ -631,7 +631,7 @@ public:
|
||||
}
|
||||
|
||||
me->SetImmuneToPC(false);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SWIMMING);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_CAN_SWIM);
|
||||
|
||||
player->CastSpell(me, SPELL_DUEL, false);
|
||||
player->CastSpell(player, SPELL_DUEL_FLAG, true);
|
||||
|
||||
@@ -348,7 +348,7 @@ class npc_shard_of_torment : public CreatureScript
|
||||
{
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_REMOVE_CLIENT_CONTROL | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_DISABLE_TURN);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_CANNOT_TURN);
|
||||
me->SetDisplayFromModel(1);
|
||||
_instance = creature->GetInstanceScript();
|
||||
}
|
||||
|
||||
@@ -282,10 +282,10 @@ class spell_varos_centrifuge_shield : public SpellScriptLoader
|
||||
if (Unit* caster = GetCaster())
|
||||
{
|
||||
// flags taken from sniffs
|
||||
if (caster->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SWIMMING | UNIT_FLAG_IMMUNE_TO_NPC | UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_UNK_6))
|
||||
if (caster->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_CAN_SWIM | UNIT_FLAG_IMMUNE_TO_NPC | UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_UNK_6))
|
||||
{
|
||||
caster->ToCreature()->SetReactState(REACT_PASSIVE);
|
||||
caster->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SWIMMING | UNIT_FLAG_UNK_6);
|
||||
caster->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_CAN_SWIM | UNIT_FLAG_UNK_6);
|
||||
caster->SetImmuneToAll(true, true);
|
||||
}
|
||||
}
|
||||
@@ -296,7 +296,7 @@ class spell_varos_centrifuge_shield : public SpellScriptLoader
|
||||
if (Unit* caster = GetCaster())
|
||||
{
|
||||
caster->ToCreature()->SetReactState(REACT_AGGRESSIVE);
|
||||
caster->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SWIMMING | UNIT_FLAG_UNK_6);
|
||||
caster->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_CAN_SWIM | UNIT_FLAG_UNK_6);
|
||||
caster->SetImmuneToAll(false);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user