Core/Movement: merged Collision height handling from 335 branch to reduce the probability that creatures are falling under the map
This commit is contained in:
1 parent
3357ae7940
commit
50a91bd590
16 files changed
+134
-138
No files matched your search
@@ -221,7 +221,7 @@ bool DynamicMapTree::isInLineOfSight(G3D::Vector3 const& startPos, G3D::Vector3
|
||||
|
||||
float DynamicMapTree::getHeight(float x, float y, float z, float maxSearchDist, PhaseShift const& phaseShift) const
|
||||
{
|
||||
G3D::Vector3 v(x, y, z + 0.5f);
|
||||
G3D::Vector3 v(x, y, z);
|
||||
G3D::Ray r(v, G3D::Vector3(0, 0, -1));
|
||||
DynamicTreeIntersectionCallback callback(phaseShift);
|
||||
impl->intersectZAllignedRay(r, callback, maxSearchDist);
|
||||
|
||||
@@ -2867,7 +2867,7 @@ void Creature::UpdateMovementFlags()
|
||||
// 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(GetPositionZMinusOffset(), ground + 0.05f) || G3D::fuzzyLt(GetPositionZMinusOffset(), ground - 0.05f)); // Can be underground too, prevent the falling
|
||||
bool isInAir = (G3D::fuzzyGt(GetPositionZMinusOffset(), ground + GROUND_HEIGHT_TOLERANCE) || G3D::fuzzyLt(GetPositionZMinusOffset(), ground - 0.05f)); // Can be underground too, prevent the falling
|
||||
|
||||
if (GetCreatureTemplate()->InhabitType & INHABIT_AIR && isInAir && !IsFalling())
|
||||
{
|
||||
|
||||
@@ -1289,7 +1289,7 @@ void WorldObject::_Create(ObjectGuid::LowType guidlow, HighGuid guidhigh, uint32
|
||||
void WorldObject::UpdatePositionData()
|
||||
{
|
||||
PositionFullTerrainStatus data;
|
||||
GetMap()->GetFullTerrainStatusForPosition(GetPhaseShift(), GetPositionX(), GetPositionY(), GetPositionZ(), data);
|
||||
GetMap()->GetFullTerrainStatusForPosition(GetPhaseShift(), GetPositionX(), GetPositionY(), GetPositionZ(), data, MAP_ALL_LIQUIDS);
|
||||
ProcessPositionDataChanged(data);
|
||||
}
|
||||
|
||||
@@ -1408,22 +1408,22 @@ bool WorldObject::IsInMap(const WorldObject* obj) const
|
||||
|
||||
bool WorldObject::IsWithinDist3d(float x, float y, float z, float dist) const
|
||||
{
|
||||
return IsInDist(x, y, z, dist);
|
||||
return IsInDist(x, y, z, dist + GetCombatReach());
|
||||
}
|
||||
|
||||
bool WorldObject::IsWithinDist3d(const Position* pos, float dist) const
|
||||
bool WorldObject::IsWithinDist3d(Position const* pos, float dist) const
|
||||
{
|
||||
return IsInDist(pos, dist);
|
||||
return IsInDist(pos, dist + GetCombatReach());
|
||||
}
|
||||
|
||||
bool WorldObject::IsWithinDist2d(float x, float y, float dist) const
|
||||
{
|
||||
return IsInDist2d(x, y, dist);
|
||||
return IsInDist2d(x, y, dist + GetCombatReach());
|
||||
}
|
||||
|
||||
bool WorldObject::IsWithinDist2d(const Position* pos, float dist) const
|
||||
bool WorldObject::IsWithinDist2d(Position const* pos, float dist) const
|
||||
{
|
||||
return IsInDist2d(pos, dist);
|
||||
return IsInDist2d(pos, dist + GetCombatReach());
|
||||
}
|
||||
|
||||
bool WorldObject::IsWithinDist(WorldObject const* obj, float dist2compare, bool is3D /*= true*/) const
|
||||
@@ -1438,7 +1438,7 @@ bool WorldObject::IsWithinDistInMap(WorldObject const* obj, float dist2compare,
|
||||
|
||||
Position WorldObject::GetHitSpherePointFor(Position const& dest) const
|
||||
{
|
||||
G3D::Vector3 vThis(GetPositionX(), GetPositionY(), GetPositionZ());
|
||||
G3D::Vector3 vThis(GetPositionX(), GetPositionY(), GetPositionZ() + GetCollisionHeight());
|
||||
G3D::Vector3 vObj(dest.GetPositionX(), dest.GetPositionY(), dest.GetPositionZ());
|
||||
G3D::Vector3 contactPoint = vThis + (vObj - vThis).directionOrZero() * std::min(dest.GetExactDist(GetPosition()), GetCombatReach());
|
||||
|
||||
@@ -1449,13 +1449,17 @@ bool WorldObject::IsWithinLOS(float ox, float oy, float oz, LineOfSightChecks ch
|
||||
{
|
||||
if (IsInWorld())
|
||||
{
|
||||
oz += GetCollisionHeight();
|
||||
float x, y, z;
|
||||
if (GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
GetPosition(x, y, z);
|
||||
z += GetCollisionHeight();
|
||||
}
|
||||
else
|
||||
GetHitSpherePointFor({ ox, oy, oz }, x, y, z);
|
||||
|
||||
return GetMap()->isInLineOfSight(GetPhaseShift(), x, y, z + 2.0f, ox, oy, oz + 2.0f, checks, ignoreFlags);
|
||||
return GetMap()->isInLineOfSight(GetPhaseShift(), x, y, z, ox, oy, oz, checks, ignoreFlags);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -1466,13 +1470,25 @@ bool WorldObject::IsWithinLOSInMap(const WorldObject* obj, LineOfSightChecks che
|
||||
if (!IsInMap(obj))
|
||||
return false;
|
||||
|
||||
float x, y, z;
|
||||
float ox, oy, oz;
|
||||
if (obj->GetTypeId() == TYPEID_PLAYER)
|
||||
obj->GetPosition(x, y, z);
|
||||
{
|
||||
obj->GetPosition(ox, oy, oz);
|
||||
oz += GetCollisionHeight();
|
||||
}
|
||||
else
|
||||
obj->GetHitSpherePointFor(GetPosition(), x, y, z);
|
||||
obj->GetHitSpherePointFor({ GetPositionX(), GetPositionY(), GetPositionZ() + GetCollisionHeight() }, ox, oy, oz);
|
||||
|
||||
return IsWithinLOS(x, y, z, checks, ignoreFlags);
|
||||
float x, y, z;
|
||||
if (GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
GetPosition(x, y, z);
|
||||
z += GetCollisionHeight();
|
||||
}
|
||||
else
|
||||
GetHitSpherePointFor({ obj->GetPositionX(), obj->GetPositionY(), obj->GetPositionZ() + obj->GetCollisionHeight() }, x, y, z);
|
||||
|
||||
return GetMap()->isInLineOfSight(GetPhaseShift(), x, y, z, ox, oy, oz, checks, ignoreFlags);
|
||||
}
|
||||
|
||||
void WorldObject::GetHitSpherePointFor(Position const& dest, float& x, float& y, float& z) const
|
||||
@@ -1630,9 +1646,7 @@ Position WorldObject::GetRandomPoint(const Position &srcPos, float distance) con
|
||||
|
||||
void WorldObject::UpdateGroundPositionZ(float x, float y, float &z) const
|
||||
{
|
||||
float new_z = GetMap()->GetHeight(GetPhaseShift(), x, y, z + 2.0f, true);
|
||||
if (new_z > INVALID_HEIGHT)
|
||||
z = new_z + 0.05f; // just to be sure that we are not a few pixel under the surface
|
||||
z = GetMapHeight(x, y, z);
|
||||
}
|
||||
|
||||
void WorldObject::UpdateAllowedPositionZ(float x, float y, float &z) const
|
||||
@@ -1652,8 +1666,8 @@ void WorldObject::UpdateAllowedPositionZ(float x, float y, float &z) const
|
||||
bool canSwim = ToCreature()->CanSwim();
|
||||
float ground_z = z;
|
||||
float max_z = canSwim
|
||||
? GetMap()->GetWaterOrGroundLevel(GetPhaseShift(), x, y, z, &ground_z, !ToUnit()->HasAuraType(SPELL_AURA_WATER_WALK))
|
||||
: ((ground_z = GetMap()->GetHeight(GetPhaseShift(), x, y, z, true)));
|
||||
? GetMapWaterOrGroundLevel(x, y, z, &ground_z)
|
||||
: (ground_z = GetMapHeight(x, y, z));
|
||||
if (max_z > INVALID_HEIGHT)
|
||||
{
|
||||
if (z > max_z)
|
||||
@@ -1664,7 +1678,7 @@ void WorldObject::UpdateAllowedPositionZ(float x, float y, float &z) const
|
||||
}
|
||||
else
|
||||
{
|
||||
float ground_z = GetMap()->GetHeight(GetPhaseShift(), x, y, z, true);
|
||||
float ground_z = GetMapHeight(x, y, z);
|
||||
if (z < ground_z)
|
||||
z = ground_z;
|
||||
}
|
||||
@@ -1676,7 +1690,7 @@ void WorldObject::UpdateAllowedPositionZ(float x, float y, float &z) const
|
||||
if (!ToPlayer()->CanFly())
|
||||
{
|
||||
float ground_z = z;
|
||||
float max_z = GetMap()->GetWaterOrGroundLevel(GetPhaseShift(), x, y, z, &ground_z, !ToUnit()->HasAuraType(SPELL_AURA_WATER_WALK));
|
||||
float max_z = GetMapWaterOrGroundLevel(x, y, z, &ground_z);
|
||||
if (max_z > INVALID_HEIGHT)
|
||||
{
|
||||
if (z > max_z)
|
||||
@@ -1687,7 +1701,7 @@ void WorldObject::UpdateAllowedPositionZ(float x, float y, float &z) const
|
||||
}
|
||||
else
|
||||
{
|
||||
float ground_z = GetMap()->GetHeight(GetPhaseShift(), x, y, z, true);
|
||||
float ground_z = GetMapHeight(x, y, z);
|
||||
if (z < ground_z)
|
||||
z = ground_z;
|
||||
}
|
||||
@@ -1695,7 +1709,7 @@ void WorldObject::UpdateAllowedPositionZ(float x, float y, float &z) const
|
||||
}
|
||||
default:
|
||||
{
|
||||
float ground_z = GetMap()->GetHeight(GetPhaseShift(), x, y, z, true);
|
||||
float ground_z = GetMapHeight(x, y, z);
|
||||
if (ground_z > INVALID_HEIGHT)
|
||||
z = ground_z;
|
||||
break;
|
||||
@@ -2476,8 +2490,8 @@ void WorldObject::MovePosition(Position &pos, float dist, float angle)
|
||||
return;
|
||||
}
|
||||
|
||||
ground = GetMap()->GetHeight(GetPhaseShift(), destx, desty, MAX_HEIGHT, true);
|
||||
floor = GetMap()->GetHeight(GetPhaseShift(), destx, desty, pos.m_positionZ, true);
|
||||
ground = GetMapHeight(destx, desty, MAX_HEIGHT);
|
||||
floor = GetMapHeight(destx, desty, pos.m_positionZ);
|
||||
destz = std::fabs(ground - pos.m_positionZ) <= std::fabs(floor - pos.m_positionZ) ? ground : floor;
|
||||
|
||||
float step = dist/10.0f;
|
||||
@@ -2489,8 +2503,8 @@ void WorldObject::MovePosition(Position &pos, float dist, float angle)
|
||||
{
|
||||
destx -= step * std::cos(angle);
|
||||
desty -= step * std::sin(angle);
|
||||
ground = GetMap()->GetHeight(GetPhaseShift(), destx, desty, MAX_HEIGHT, true);
|
||||
floor = GetMap()->GetHeight(GetPhaseShift(), destx, desty, pos.m_positionZ, true);
|
||||
ground = GetMapHeight(destx, desty, MAX_HEIGHT);
|
||||
floor = GetMapHeight(destx, desty, pos.m_positionZ);
|
||||
destz = std::fabs(ground - pos.m_positionZ) <= std::fabs(floor - pos.m_positionZ) ? ground : floor;
|
||||
}
|
||||
// we have correct destz now
|
||||
@@ -2507,38 +2521,13 @@ void WorldObject::MovePosition(Position &pos, float dist, float angle)
|
||||
pos.SetOrientation(GetOrientation());
|
||||
}
|
||||
|
||||
// @todo: replace with WorldObject::UpdateAllowedPositionZ
|
||||
float NormalizeZforCollision(WorldObject* obj, float x, float y, float z)
|
||||
{
|
||||
float ground = obj->GetMap()->GetHeight(obj->GetPhaseShift(), x, y, MAX_HEIGHT, true);
|
||||
float floor = obj->GetMap()->GetHeight(obj->GetPhaseShift(), x, y, z + 2.0f, true);
|
||||
float helper = std::fabs(ground - z) <= std::fabs(floor - z) ? ground : floor;
|
||||
if (z > helper) // must be above ground
|
||||
{
|
||||
if (Unit* unit = obj->ToUnit())
|
||||
{
|
||||
if (unit->CanFly())
|
||||
return z;
|
||||
}
|
||||
LiquidData liquid_status;
|
||||
ZLiquidStatus res = obj->GetMap()->GetLiquidStatus(obj->GetPhaseShift(), x, y, z, MAP_ALL_LIQUIDS, &liquid_status);
|
||||
if (res && liquid_status.level > helper) // water must be above ground
|
||||
{
|
||||
if (liquid_status.level > z) // z is underwater
|
||||
return z;
|
||||
else
|
||||
return std::fabs(liquid_status.level - z) <= std::fabs(helper - z) ? liquid_status.level : helper;
|
||||
}
|
||||
}
|
||||
return helper;
|
||||
}
|
||||
|
||||
void WorldObject::MovePositionToFirstCollision(Position &pos, float dist, float angle)
|
||||
{
|
||||
angle += GetOrientation();
|
||||
float destx, desty, destz;
|
||||
destx = pos.m_positionX + dist * std::cos(angle);
|
||||
desty = pos.m_positionY + dist * std::sin(angle);
|
||||
destz = pos.m_positionZ;
|
||||
|
||||
// Prevent invalid coordinates here, position is unchanged
|
||||
if (!Trinity::IsValidMapCoord(destx, desty))
|
||||
@@ -2547,9 +2536,9 @@ void WorldObject::MovePositionToFirstCollision(Position &pos, float dist, float
|
||||
return;
|
||||
}
|
||||
|
||||
destz = NormalizeZforCollision(this, destx, desty, pos.GetPositionZ());
|
||||
UpdateAllowedPositionZ(destx, desty, destz);
|
||||
bool col = VMAP::VMapFactory::createOrGetVMapManager()->getObjectHitPos(PhasingHandler::GetTerrainMapId(GetPhaseShift(), GetMap(), pos.m_positionX, pos.m_positionY),
|
||||
pos.m_positionX, pos.m_positionY, pos.m_positionZ + 0.5f, destx, desty, destz + 0.5f, destx, desty, destz, -0.5f);
|
||||
pos.m_positionX, pos.m_positionY, pos.m_positionZ, destx, desty, destz, destx, desty, destz, -0.5f);
|
||||
|
||||
// collision occured
|
||||
if (col)
|
||||
@@ -2561,7 +2550,7 @@ void WorldObject::MovePositionToFirstCollision(Position &pos, float dist, float
|
||||
}
|
||||
|
||||
// check dynamic collision
|
||||
col = GetMap()->getObjectHitPos(GetPhaseShift(), pos.m_positionX, pos.m_positionY, pos.m_positionZ + 0.5f, destx, desty, destz + 0.5f, destx, desty, destz, -0.5f);
|
||||
col = GetMap()->getObjectHitPos(GetPhaseShift(), pos.m_positionX, pos.m_positionY, pos.m_positionZ, destx, desty, destz, destx, desty, destz, -0.5f);
|
||||
|
||||
// Collided with a gameobject
|
||||
if (col)
|
||||
@@ -2580,7 +2569,7 @@ void WorldObject::MovePositionToFirstCollision(Position &pos, float dist, float
|
||||
{
|
||||
destx -= step * std::cos(angle);
|
||||
desty -= step * std::sin(angle);
|
||||
destz = NormalizeZforCollision(this, destx, desty, pos.GetPositionZ());
|
||||
UpdateAllowedPositionZ(destx, desty, destz);
|
||||
}
|
||||
// we have correct destz now
|
||||
else
|
||||
@@ -2592,7 +2581,7 @@ void WorldObject::MovePositionToFirstCollision(Position &pos, float dist, float
|
||||
|
||||
Trinity::NormalizeMapCoord(pos.m_positionX);
|
||||
Trinity::NormalizeMapCoord(pos.m_positionY);
|
||||
pos.m_positionZ = NormalizeZforCollision(this, destx, desty, pos.GetPositionZ());
|
||||
UpdateAllowedPositionZ(destx, desty, pos.m_positionZ);
|
||||
pos.SetOrientation(GetOrientation());
|
||||
}
|
||||
|
||||
@@ -2781,6 +2770,22 @@ float WorldObject::GetFloorZ() const
|
||||
return std::max<float>(m_staticFloorZ, GetMap()->GetGameObjectFloor(GetPhaseShift(), GetPositionX(), GetPositionY(), GetPositionZ()));
|
||||
}
|
||||
|
||||
float WorldObject::GetMapWaterOrGroundLevel(float x, float y, float z, float* ground/* = nullptr*/) const
|
||||
{
|
||||
if (Unit const* unit = ToUnit())
|
||||
return GetMap()->GetWaterOrGroundLevel(GetPhaseShift(), x, y, z, ground, !unit->HasAuraType(SPELL_AURA_WATER_WALK), GetCollisionHeight());
|
||||
|
||||
return z;
|
||||
}
|
||||
|
||||
float WorldObject::GetMapHeight(float x, float y, float z, bool vmap/* = true*/, float distanceToSearch/* = DEFAULT_HEIGHT_SEARCH*/) const
|
||||
{
|
||||
if (z != MAX_HEIGHT)
|
||||
z += GetCollisionHeight();
|
||||
|
||||
return GetMap()->GetHeight(GetPhaseShift(), x, y, z, vmap, distanceToSearch);
|
||||
}
|
||||
|
||||
template TC_GAME_API void WorldObject::GetGameObjectListWithEntryInGrid(std::list<GameObject*>&, uint32, float) const;
|
||||
template TC_GAME_API void WorldObject::GetGameObjectListWithEntryInGrid(std::deque<GameObject*>&, uint32, float) const;
|
||||
template TC_GAME_API void WorldObject::GetGameObjectListWithEntryInGrid(std::vector<GameObject*>&, uint32, float) const;
|
||||
|
||||
@@ -59,6 +59,8 @@ struct QuaternionData;
|
||||
|
||||
typedef std::unordered_map<Player*, UpdateData> UpdateDataMapType;
|
||||
|
||||
float const DEFAULT_COLLISION_HEIGHT = 2.03128f; // Most common value in dbc
|
||||
|
||||
class TC_GAME_API Object
|
||||
{
|
||||
public:
|
||||
@@ -471,6 +473,10 @@ class TC_GAME_API WorldObject : public Object, public WorldLocation
|
||||
virtual float GetStationaryO() const { return GetOrientation(); }
|
||||
|
||||
float GetFloorZ() const;
|
||||
virtual float GetCollisionHeight() const { return 0.0f; }
|
||||
|
||||
float GetMapWaterOrGroundLevel(float x, float y, float z, float* ground = nullptr) const;
|
||||
float GetMapHeight(float x, float y, float z, bool vmap = true, float distanceToSearch = 50.0f) const; // DEFAULT_HEIGHT_SEARCH in map.h
|
||||
|
||||
uint16 GetAIAnimKitId() const { return m_aiAnimKitId; }
|
||||
void SetAIAnimKitId(uint16 animKitId);
|
||||
|
||||
@@ -2062,7 +2062,7 @@ void Player::SetObjectScale(float scale)
|
||||
SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, scale * DEFAULT_WORLD_OBJECT_SIZE);
|
||||
SetFloatValue(UNIT_FIELD_COMBATREACH, scale * DEFAULT_COMBAT_REACH);
|
||||
if (IsInWorld())
|
||||
SendMovementSetCollisionHeight(scale * GetCollisionHeight(IsMounted()));
|
||||
SendMovementSetCollisionHeight(scale * GetCollisionHeight());
|
||||
}
|
||||
|
||||
bool Player::IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index, Unit* caster) const
|
||||
@@ -27981,39 +27981,6 @@ void Player::SendMovementSetCollisionHeight(float height)
|
||||
Movement::PacketSender(this, NULL_OPCODE, SMSG_MOVE_SET_COLLISION_HEIGHT, SMSG_MOVE_UPDATE_COLLISION_HEIGHT, &extra).Send();
|
||||
}
|
||||
|
||||
float Player::GetCollisionHeight(bool mounted) const
|
||||
{
|
||||
if (mounted)
|
||||
{
|
||||
CreatureDisplayInfoEntry const* mountDisplayInfo = sCreatureDisplayInfoStore.LookupEntry(GetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID));
|
||||
if (!mountDisplayInfo)
|
||||
return GetCollisionHeight(false);
|
||||
|
||||
CreatureModelDataEntry const* mountModelData = sCreatureModelDataStore.LookupEntry(mountDisplayInfo->ModelId);
|
||||
if (!mountModelData)
|
||||
return GetCollisionHeight(false);
|
||||
|
||||
CreatureDisplayInfoEntry const* displayInfo = sCreatureDisplayInfoStore.LookupEntry(GetNativeDisplayId());
|
||||
ASSERT(displayInfo);
|
||||
CreatureModelDataEntry const* modelData = sCreatureModelDataStore.LookupEntry(displayInfo->ModelId);
|
||||
ASSERT(modelData);
|
||||
|
||||
float scaleMod = GetObjectScale(); // 99% sure about this
|
||||
|
||||
return scaleMod * mountModelData->MountHeight + modelData->CollisionHeight * 0.5f;
|
||||
}
|
||||
else
|
||||
{
|
||||
//! Dismounting case - use basic default model data
|
||||
CreatureDisplayInfoEntry const* displayInfo = sCreatureDisplayInfoStore.LookupEntry(GetNativeDisplayId());
|
||||
ASSERT(displayInfo);
|
||||
CreatureModelDataEntry const* modelData = sCreatureModelDataStore.LookupEntry(displayInfo->ModelId);
|
||||
ASSERT(modelData);
|
||||
|
||||
return modelData->CollisionHeight;
|
||||
}
|
||||
}
|
||||
|
||||
std::string Player::GetMapAreaAndZoneString() const
|
||||
{
|
||||
uint32 areaId = GetAreaId();
|
||||
|
||||
@@ -2348,9 +2348,6 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
|
||||
|
||||
bool CanFly() const override { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_CAN_FLY); }
|
||||
|
||||
//! Return collision height sent to client
|
||||
float GetCollisionHeight(bool mounted) const;
|
||||
|
||||
std::string GetMapAreaAndZoneString() const;
|
||||
std::string GetCoordsMapAreaAndZoneString() const;
|
||||
|
||||
|
||||
@@ -8204,7 +8204,7 @@ void Unit::Mount(uint32 mount, uint32 VehicleId, uint32 creatureEntry)
|
||||
if (charm->GetTypeId() == TYPEID_UNIT)
|
||||
charm->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
|
||||
|
||||
player->SendMovementSetCollisionHeight(player->GetCollisionHeight(true));
|
||||
player->SendMovementSetCollisionHeight(player->GetCollisionHeight());
|
||||
}
|
||||
|
||||
RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_MOUNT);
|
||||
@@ -8221,7 +8221,7 @@ void Unit::Dismount()
|
||||
if (Player* thisPlayer = ToPlayer())
|
||||
{
|
||||
SendUpdateToSet();
|
||||
thisPlayer->SendMovementSetCollisionHeight(thisPlayer->GetCollisionHeight(false));
|
||||
thisPlayer->SendMovementSetCollisionHeight(thisPlayer->GetCollisionHeight());
|
||||
}
|
||||
|
||||
WorldPacket data(SMSG_DISMOUNT, 8);
|
||||
@@ -14806,6 +14806,30 @@ void Unit::Whisper(uint32 textId, Player* target, bool isBossWhisper /*= false*/
|
||||
target->SendDirectMessage(&data);
|
||||
}
|
||||
|
||||
float Unit::GetCollisionHeight() const
|
||||
{
|
||||
float scaleMod = GetObjectScale(); // 99% sure about this
|
||||
|
||||
if (IsMounted())
|
||||
{
|
||||
if (CreatureDisplayInfoEntry const* mountDisplayInfo = sCreatureDisplayInfoStore.LookupEntry(GetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID)))
|
||||
{
|
||||
if (CreatureModelDataEntry const* mountModelData = sCreatureModelDataStore.LookupEntry(mountDisplayInfo->ModelId))
|
||||
{
|
||||
CreatureDisplayInfoEntry const* displayInfo = sCreatureDisplayInfoStore.AssertEntry(GetNativeDisplayId());
|
||||
CreatureModelDataEntry const* modelData = sCreatureModelDataStore.AssertEntry(displayInfo->ModelId);
|
||||
return scaleMod * (mountModelData->MountHeight + modelData->CollisionHeight * 0.5f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//! Dismounting case - use basic default model data
|
||||
CreatureDisplayInfoEntry const* displayInfo = sCreatureDisplayInfoStore.AssertEntry(GetNativeDisplayId());
|
||||
CreatureModelDataEntry const* modelData = sCreatureModelDataStore.AssertEntry(displayInfo->ModelId);
|
||||
|
||||
return scaleMod * modelData->CollisionHeight;
|
||||
}
|
||||
|
||||
SpellInfo const* Unit::GetCastSpellInfo(SpellInfo const* spellInfo) const
|
||||
{
|
||||
Unit::AuraEffectList swaps = GetAuraEffectsByType(SPELL_AURA_OVERRIDE_ACTIONBAR_SPELLS);
|
||||
|
||||
@@ -1902,6 +1902,7 @@ class TC_GAME_API Unit : public WorldObject
|
||||
virtual void TextEmote(uint32 textId, WorldObject const* target = nullptr, bool isBossEmote = false);
|
||||
virtual void Whisper(uint32 textId, Player* target, bool isBossWhisper = false);
|
||||
|
||||
float GetCollisionHeight() const override;
|
||||
protected:
|
||||
explicit Unit (bool isWorldObject);
|
||||
|
||||
|
||||
@@ -2312,7 +2312,7 @@ float GridMap::getLiquidLevel(float x, float y) const
|
||||
}
|
||||
|
||||
// Get water state on map
|
||||
inline ZLiquidStatus GridMap::GetLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, LiquidData* data)
|
||||
inline ZLiquidStatus GridMap::GetLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, LiquidData* data, float collisionHeight)
|
||||
{
|
||||
// Check water type (if no water return)
|
||||
if (!_liquidGlobalFlags && !_liquidFlags)
|
||||
@@ -2378,7 +2378,7 @@ inline ZLiquidStatus GridMap::GetLiquidStatus(float x, float y, float z, uint8 R
|
||||
float ground_level = getHeight(x, y);
|
||||
|
||||
// Check water level and ground level
|
||||
if (liquid_level < ground_level || z < ground_level - 2)
|
||||
if (liquid_level < ground_level || z < ground_level)
|
||||
return LIQUID_MAP_NO_WATER;
|
||||
|
||||
// All ok in water -> store data
|
||||
@@ -2393,13 +2393,13 @@ inline ZLiquidStatus GridMap::GetLiquidStatus(float x, float y, float z, uint8 R
|
||||
// For speed check as int values
|
||||
float delta = liquid_level - z;
|
||||
|
||||
if (delta > 2.0f) // Under 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
|
||||
if (delta > -0.1f) // Walk on water
|
||||
return LIQUID_MAP_WATER_WALK;
|
||||
// Above water
|
||||
// Above water
|
||||
return LIQUID_MAP_ABOVE_WATER;
|
||||
}
|
||||
|
||||
@@ -2442,18 +2442,18 @@ bool Map::HasGrid(uint32 mapId, int32 gx, int32 gy) const
|
||||
return childMapItr != m_childTerrainMaps->end() && (*childMapItr)->GridMaps[gx][gy] && (*childMapItr)->GridMaps[gx][gy]->fileExists();
|
||||
}
|
||||
|
||||
float Map::GetWaterOrGroundLevel(PhaseShift const& phaseShift, float x, float y, float z, float* ground /*= nullptr*/, bool /*swim = false*/) const
|
||||
float Map::GetWaterOrGroundLevel(PhaseShift const& phaseShift, float x, float y, float z, float* ground /*= nullptr*/, bool /*swim = false*/, float collisionHeight /*= DEFAULT_COLLISION_HEIGHT*/) const
|
||||
{
|
||||
if (const_cast<Map*>(this)->GetGrid(x, y))
|
||||
{
|
||||
// we need ground level (including grid height version) for proper return water level in point
|
||||
float ground_z = GetHeight(phaseShift, x, y, z, true, 50.0f);
|
||||
float ground_z = GetHeight(phaseShift, x, y, z + collisionHeight, true, 50.0f);
|
||||
if (ground)
|
||||
*ground = ground_z;
|
||||
|
||||
LiquidData liquid_status;
|
||||
|
||||
ZLiquidStatus res = GetLiquidStatus(phaseShift, x, y, ground_z, MAP_ALL_LIQUIDS, &liquid_status);
|
||||
ZLiquidStatus res = GetLiquidStatus(phaseShift, x, y, ground_z, MAP_ALL_LIQUIDS, &liquid_status, collisionHeight);
|
||||
return res ? liquid_status.level : ground_z;
|
||||
}
|
||||
|
||||
@@ -2468,8 +2468,7 @@ float Map::GetStaticHeight(PhaseShift const& phaseShift, float x, float y, float
|
||||
if (GridMap* gmap = m_parentTerrainMap->GetGrid(terrainMapId, x, y))
|
||||
{
|
||||
float gridHeight = gmap->getHeight(x, y);
|
||||
// look from a bit higher pos to find the floor, ignore under surface case
|
||||
if (G3D::fuzzyGe(z, gridHeight - GROUND_HEIGHT_TOLERANCE))
|
||||
if (z > gridHeight)
|
||||
mapHeight = gridHeight;
|
||||
}
|
||||
|
||||
@@ -2478,7 +2477,7 @@ float Map::GetStaticHeight(PhaseShift const& phaseShift, float x, float y, float
|
||||
{
|
||||
VMAP::IVMapManager* vmgr = VMAP::VMapFactory::createOrGetVMapManager();
|
||||
if (vmgr->isHeightCalcEnabled())
|
||||
vmapHeight = vmgr->getHeight(terrainMapId, x, y, z + 2.0f, maxSearchDist); // look from a bit higher pos to find the floor
|
||||
vmapHeight = vmgr->getHeight(terrainMapId, x, y, z, maxSearchDist);
|
||||
}
|
||||
|
||||
// mapHeight set for any above raw ground Z or <= INVALID_HEIGHT
|
||||
@@ -2563,7 +2562,7 @@ void Map::GetZoneAndAreaId(PhaseShift const& phaseShift, uint32& zoneid, uint32&
|
||||
zoneid = area->zone;
|
||||
}
|
||||
|
||||
ZLiquidStatus Map::GetLiquidStatus(PhaseShift const& phaseShift, float x, float y, float z, uint8 ReqLiquidType, LiquidData* data) const
|
||||
ZLiquidStatus Map::GetLiquidStatus(PhaseShift const& phaseShift, float x, float y, float z, uint8 ReqLiquidType, LiquidData* data, float collisionHeight) const
|
||||
{
|
||||
ZLiquidStatus result = LIQUID_MAP_NO_WATER;
|
||||
VMAP::IVMapManager* vmgr = VMAP::VMapFactory::createOrGetVMapManager();
|
||||
@@ -2621,11 +2620,11 @@ ZLiquidStatus Map::GetLiquidStatus(PhaseShift const& phaseShift, float x, float
|
||||
float delta = liquid_level - z;
|
||||
|
||||
// Get position delta
|
||||
if (delta > 2.0f) // Under 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
|
||||
if (delta > -0.1f) // Walk on water
|
||||
return LIQUID_MAP_WATER_WALK;
|
||||
result = LIQUID_MAP_ABOVE_WATER;
|
||||
}
|
||||
@@ -2636,7 +2635,7 @@ ZLiquidStatus Map::GetLiquidStatus(PhaseShift const& phaseShift, float x, float
|
||||
if (GridMap* gmap = m_parentTerrainMap->GetGrid(terrainMapId, x, y))
|
||||
{
|
||||
LiquidData map_data;
|
||||
ZLiquidStatus map_result = gmap->GetLiquidStatus(x, y, z, ReqLiquidType, &map_data);
|
||||
ZLiquidStatus map_result = gmap->GetLiquidStatus(x, y, z, ReqLiquidType, &map_data, collisionHeight);
|
||||
// Not override LIQUID_MAP_ABOVE_WATER with LIQUID_MAP_NO_WATER:
|
||||
if (map_result != LIQUID_MAP_NO_WATER && (map_data.level > ground_level))
|
||||
{
|
||||
@@ -2655,7 +2654,7 @@ ZLiquidStatus Map::GetLiquidStatus(PhaseShift const& phaseShift, float x, float
|
||||
return result;
|
||||
}
|
||||
|
||||
void Map::GetFullTerrainStatusForPosition(PhaseShift const& phaseShift, float x, float y, float z, PositionFullTerrainStatus& data, uint8 reqLiquidType) const
|
||||
void Map::GetFullTerrainStatusForPosition(PhaseShift const& phaseShift, float x, float y, float z, PositionFullTerrainStatus& data, uint8 reqLiquidType, float collisionHeight) const
|
||||
{
|
||||
VMAP::IVMapManager* vmgr = VMAP::VMapFactory::createOrGetVMapManager();
|
||||
VMAP::AreaAndLiquidData vmapData;
|
||||
@@ -2758,7 +2757,7 @@ void Map::GetFullTerrainStatusForPosition(PhaseShift const& phaseShift, float x,
|
||||
data.liquidInfo->type_flags = 1 << liquidFlagType;
|
||||
|
||||
float delta = vmapData.liquidInfo->level - z;
|
||||
if (delta > 2.0f)
|
||||
if (delta > collisionHeight)
|
||||
data.liquidStatus = LIQUID_MAP_UNDER_WATER;
|
||||
else if (delta > 0.0f)
|
||||
data.liquidStatus = LIQUID_MAP_IN_WATER;
|
||||
@@ -2771,7 +2770,7 @@ void Map::GetFullTerrainStatusForPosition(PhaseShift const& phaseShift, float x,
|
||||
if (gmap && useGridLiquid)
|
||||
{
|
||||
LiquidData gridMapLiquid;
|
||||
ZLiquidStatus gridMapStatus = gmap->GetLiquidStatus(x, y, z, reqLiquidType, &gridMapLiquid);
|
||||
ZLiquidStatus gridMapStatus = gmap->GetLiquidStatus(x, y, z, reqLiquidType, &gridMapLiquid, collisionHeight);
|
||||
if (gridMapStatus != LIQUID_MAP_NO_WATER && (gridMapLiquid.level > vmapData.floorZ))
|
||||
{
|
||||
if (GetId() == 530 && gridMapLiquid.entry == 2)
|
||||
|
||||
@@ -247,7 +247,7 @@ public:
|
||||
uint16 getArea(float x, float y) const;
|
||||
inline float getHeight(float x, float y) const {return (this->*_gridGetHeight)(x, y);}
|
||||
float getLiquidLevel(float x, float y) const;
|
||||
ZLiquidStatus GetLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, LiquidData* data = 0);
|
||||
ZLiquidStatus GetLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, LiquidData* data = 0, float collisionHeight = 2.03128f); // DEFAULT_COLLISION_HEIGHT in Object.h
|
||||
bool fileExists() const { return _fileExists; }
|
||||
};
|
||||
|
||||
@@ -398,8 +398,8 @@ class TC_GAME_API Map : public GridRefManager<NGridType>
|
||||
// can return INVALID_HEIGHT if under z+2 z coord not found height
|
||||
float GetStaticHeight(PhaseShift const& phaseShift, float x, float y, float z, bool checkVMap = true, float maxSearchDist = DEFAULT_HEIGHT_SEARCH) const;
|
||||
|
||||
void GetFullTerrainStatusForPosition(PhaseShift const& phaseShift, float x, float y, float z, PositionFullTerrainStatus& data, uint8 reqLiquidType = MAP_ALL_LIQUIDS) const;
|
||||
ZLiquidStatus GetLiquidStatus(PhaseShift const& phaseShift, float x, float y, float z, uint8 ReqLiquidType, LiquidData* data = nullptr) const;
|
||||
void GetFullTerrainStatusForPosition(PhaseShift const& phaseShift, float x, float y, float z, PositionFullTerrainStatus& data, uint8 reqLiquidType = MAP_ALL_LIQUIDS, float collisionHeight = 2.03128f) const; // DEFAULT_COLLISION_HEIGHT in Object.h
|
||||
ZLiquidStatus GetLiquidStatus(PhaseShift const& phaseShift, float x, float y, float z, uint8 ReqLiquidType, LiquidData* data = nullptr, float collisionHeight = 2.03128f) const; // DEFAULT_COLLISION_HEIGHT in Object.h
|
||||
|
||||
uint32 GetAreaId(PhaseShift const& phaseShift, float x, float y, float z) const;
|
||||
uint32 GetAreaId(PhaseShift const& phaseShift, Position const& pos) const
|
||||
@@ -563,7 +563,7 @@ class TC_GAME_API Map : public GridRefManager<NGridType>
|
||||
BattlegroundMap* ToBattlegroundMap() { if (IsBattlegroundOrArena()) return reinterpret_cast<BattlegroundMap*>(this); else return nullptr; }
|
||||
BattlegroundMap const* ToBattlegroundMap() const { if (IsBattlegroundOrArena()) return reinterpret_cast<BattlegroundMap const*>(this); return nullptr; }
|
||||
|
||||
float GetWaterOrGroundLevel(PhaseShift const& phaseShift, float x, float y, float z, float* ground = nullptr, bool swim = false) const;
|
||||
float GetWaterOrGroundLevel(PhaseShift const& phaseShift, float x, float y, float z, float* ground = nullptr, bool swim = false, float collisionHeight = 2.03128f) const; // DEFAULT_COLLISION_HEIGHT in Object.h
|
||||
|
||||
float GetHeight(PhaseShift const& phaseShift, float x, float y, float z, bool vmap = true, float maxSearchDist = DEFAULT_HEIGHT_SEARCH) const { return std::max<float>(GetStaticHeight(phaseShift, x, y, z, vmap, maxSearchDist), GetGameObjectFloor(phaseShift, x, y, z, maxSearchDist)); }
|
||||
float GetHeight(PhaseShift const& phaseShift, Position const& pos, bool vmap = true, float maxSearchDist = DEFAULT_HEIGHT_SEARCH) const { return GetHeight(phaseShift, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), vmap, maxSearchDist); }
|
||||
|
||||
@@ -438,7 +438,9 @@ void MotionMaster::MoveJumpTo(float angle, float speedXY, float speedZ)
|
||||
|
||||
float moveTimeHalf = speedZ / Movement::gravity;
|
||||
float dist = 2 * moveTimeHalf * speedXY;
|
||||
_owner->GetClosePoint(x, y, z, _owner->GetCombatReach(), dist, angle);
|
||||
_owner->GetNearPoint2D(x, y, dist, _owner->GetOrientation() + angle);
|
||||
z = _owner->GetPositionZ();
|
||||
_owner->UpdateAllowedPositionZ(x, y, z);
|
||||
MoveJump(x, y, z, 0.0f, speedXY, speedZ);
|
||||
}
|
||||
|
||||
@@ -481,7 +483,7 @@ void MotionMaster::MoveCirclePath(float x, float y, float z, float radius, bool
|
||||
if (_owner->IsFlying())
|
||||
point.z = z;
|
||||
else
|
||||
point.z = _owner->GetMap()->GetHeight(_owner->GetPhaseShift(), point.x, point.y, z);
|
||||
point.z = _owner->GetMapHeight(point.x, point.y, z);
|
||||
|
||||
init.Path().push_back(point);
|
||||
}
|
||||
@@ -567,11 +569,11 @@ void MotionMaster::ResumeSplineChain(SplineChainResumeInfo const& info)
|
||||
void MotionMaster::MoveFall(uint32 id /*=0*/)
|
||||
{
|
||||
// use larger distance for vmap height search than in most other cases
|
||||
float tz = _owner->GetMap()->GetHeight(_owner->GetPhaseShift(), _owner->GetPositionX(), _owner->GetPositionY(), _owner->GetPositionZ(), true, MAX_FALL_DISTANCE);
|
||||
float tz = _owner->GetMapHeight(_owner->GetPositionX(), _owner->GetPositionY(), _owner->GetPositionZ(), true, MAX_FALL_DISTANCE);
|
||||
if (tz <= INVALID_HEIGHT)
|
||||
{
|
||||
TC_LOG_DEBUG("misc", "MotionMaster::MoveFall: unable to retrieve a proper height at map %u (x: %f, y: %f, z: %f).",
|
||||
_owner->GetMap()->GetId(), _owner->GetPositionX(), _owner->GetPositionY(), _owner->GetPositionZ());
|
||||
_owner->GetMap()->GetId(), _owner->GetPositionX(), _owner->GetPositionY(), _owner->GetPositionZ() + _owner->GetPositionZ());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -117,12 +117,7 @@ void FleeingMovementGenerator<T>::SetTargetLocation(T* owner)
|
||||
|
||||
// Add LOS check for target point
|
||||
Position mypos = owner->GetPosition();
|
||||
bool isInLOS = VMAP::VMapFactory::createOrGetVMapManager()->isInLineOfSight(
|
||||
PhasingHandler::GetTerrainMapId(owner->GetPhaseShift(), owner->GetMap(), mypos.m_positionX, mypos.m_positionY),
|
||||
mypos.m_positionX, mypos.m_positionY, mypos.m_positionZ + 2.0f, destination.m_positionX, destination.m_positionY,
|
||||
destination.m_positionZ + 2.0f, VMAP::ModelIgnoreFlags::Nothing);
|
||||
|
||||
if (!isInLOS)
|
||||
if (!owner->IsWithinLOS(destination.GetPositionX(), destination.GetPositionY(), destination.GetPositionZ()))
|
||||
{
|
||||
_timer.Reset(200);
|
||||
return;
|
||||
|
||||
@@ -186,7 +186,7 @@ void PathGenerator::BuildPolyPath(G3D::Vector3 const& startPos, G3D::Vector3 con
|
||||
// Check both start and end points, if they're both in water, then we can *safely* let the creature move
|
||||
for (uint32 i = 0; i < _pathPoints.size(); ++i)
|
||||
{
|
||||
ZLiquidStatus status = _sourceUnit->GetMap()->GetLiquidStatus(_sourceUnit->GetPhaseShift(), _pathPoints[i].x, _pathPoints[i].y, _pathPoints[i].z, MAP_ALL_LIQUIDS, nullptr);
|
||||
ZLiquidStatus status = _sourceUnit->GetMap()->GetLiquidStatus(_sourceUnit->GetPhaseShift(), _pathPoints[i].x, _pathPoints[i].y, _pathPoints[i].z, MAP_ALL_LIQUIDS, nullptr, _sourceUnit->GetCollisionHeight());
|
||||
// One of the points is not in the water, cancel movement.
|
||||
if (status == LIQUID_MAP_NO_WATER)
|
||||
{
|
||||
@@ -649,7 +649,7 @@ void PathGenerator::UpdateFilter()
|
||||
NavTerrainFlag PathGenerator::GetNavTerrain(float x, float y, float z)
|
||||
{
|
||||
LiquidData data;
|
||||
ZLiquidStatus liquidStatus = _sourceUnit->GetMap()->GetLiquidStatus(_sourceUnit->GetPhaseShift(), x, y, z, MAP_ALL_LIQUIDS, &data);
|
||||
ZLiquidStatus liquidStatus = _sourceUnit->GetMap()->GetLiquidStatus(_sourceUnit->GetPhaseShift(), x, y, z, MAP_ALL_LIQUIDS, &data, _sourceUnit->GetCollisionHeight());
|
||||
if (liquidStatus == LIQUID_MAP_NO_WATER)
|
||||
return NAV_GROUND;
|
||||
|
||||
|
||||
@@ -1329,10 +1329,10 @@ void Spell::SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplici
|
||||
float angle = float(rand_norm()) * static_cast<float>(M_PI * 35.0f / 180.0f) - static_cast<float>(M_PI * 17.5f / 180.0f);
|
||||
m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE, dist, angle);
|
||||
|
||||
float ground = m_caster->GetMap()->GetHeight(m_caster->GetPhaseShift(), x, y, z, true, 50.0f);
|
||||
float ground = m_caster->GetMapHeight(x, y, z);
|
||||
float liquidLevel = VMAP_INVALID_HEIGHT_VALUE;
|
||||
LiquidData liquidData;
|
||||
if (m_caster->GetMap()->GetLiquidStatus(m_caster->GetPhaseShift(), x, y, z, MAP_ALL_LIQUIDS, &liquidData))
|
||||
if (m_caster->GetMap()->GetLiquidStatus(m_caster->GetPhaseShift(), x, y, z, MAP_ALL_LIQUIDS, &liquidData, m_caster->GetCollisionHeight()))
|
||||
liquidLevel = liquidData.level;
|
||||
|
||||
if (liquidLevel <= ground) // When there is no liquid Map::GetWaterOrGroundLevel returns ground level
|
||||
|
||||
@@ -252,8 +252,8 @@ public:
|
||||
Map2ZoneCoordinates(zoneX, zoneY, zoneId);
|
||||
|
||||
Map const* map = object->GetMap();
|
||||
float groundZ = map->GetHeight(object->GetPhaseShift(), object->GetPositionX(), object->GetPositionY(), MAX_HEIGHT);
|
||||
float floorZ = map->GetHeight(object->GetPhaseShift(), object->GetPositionX(), object->GetPositionY(), object->GetPositionZ());
|
||||
float groundZ = object->GetMapHeight(object->GetPositionX(), object->GetPositionY(), MAX_HEIGHT);
|
||||
float floorZ = object->GetMapHeight(object->GetPositionX(), object->GetPositionY(), object->GetPositionZ());
|
||||
|
||||
GridCoord gridCoord = Trinity::ComputeGridCoord(object->GetPositionX(), object->GetPositionY());
|
||||
|
||||
@@ -296,7 +296,7 @@ public:
|
||||
zoneX, zoneY, groundZ, floorZ, haveMap, haveVMap, haveMMap);
|
||||
|
||||
LiquidData liquidStatus;
|
||||
ZLiquidStatus status = map->GetLiquidStatus(object->GetPhaseShift(), object->GetPositionX(), object->GetPositionY(), object->GetPositionZ(), MAP_ALL_LIQUIDS, &liquidStatus);
|
||||
ZLiquidStatus status = map->GetLiquidStatus(object->GetPhaseShift(), object->GetPositionX(), object->GetPositionY(), object->GetPositionZ(), MAP_ALL_LIQUIDS, &liquidStatus, object->GetCollisionHeight());
|
||||
|
||||
if (status)
|
||||
handler->PSendSysMessage(LANG_LIQUID_STATUS, liquidStatus.level, liquidStatus.depth_level, liquidStatus.entry, liquidStatus.type_flags, status);
|
||||
|
||||
+1
-1
@@ -649,7 +649,7 @@ struct boss_jormungarAI : public BossAI
|
||||
events.SetPhase(PHASE_SUBMERGED);
|
||||
events.ScheduleEvent(EVENT_EMERGE, 5*IN_MILLISECONDS, 0, PHASE_SUBMERGED);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->GetMotionMaster()->MovePoint(0, ToCCommonLoc[1].GetPositionX()+ frand(-40.0f, 40.0f), ToCCommonLoc[1].GetPositionY() + frand(-40.0f, 40.0f), ToCCommonLoc[1].GetPositionZ());
|
||||
me->GetMotionMaster()->MovePoint(0, ToCCommonLoc[1].GetPositionX()+ frand(-40.0f, 40.0f), ToCCommonLoc[1].GetPositionY() + frand(-40.0f, 40.0f), ToCCommonLoc[1].GetPositionZ() + me->GetCollisionHeight());
|
||||
WasMobile = !WasMobile;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user