diff options
-rw-r--r-- | src/server/game/Entities/Creature/Creature.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Entities/Object/Object.cpp | 7 | ||||
-rw-r--r-- | src/server/game/Entities/Object/Object.h | 1 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 11 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.h | 1 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 38 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.h | 15 | ||||
-rw-r--r-- | src/server/game/Handlers/CharacterHandler.cpp | 6 | ||||
-rw-r--r-- | src/server/game/Handlers/MiscHandler.cpp | 12 | ||||
-rw-r--r-- | src/server/game/Movement/MotionMaster.cpp | 5 | ||||
-rw-r--r-- | src/server/game/Server/WorldSession.cpp | 3 |
11 files changed, 66 insertions, 35 deletions
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index 779cffadf28..a957f0fb5ba 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -2507,7 +2507,7 @@ void Creature::UpdateMovementFlags() } if (!isInAir) - RemoveUnitMovementFlag(MOVEMENTFLAG_FALLING); + SetFall(false); SetSwim(GetCreatureTemplate()->InhabitType & INHABIT_WATER && IsInWater()); } diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index e8bbf09eab1..591c83ab71f 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -397,8 +397,7 @@ void Object::BuildMovementUpdate(ByteBuffer* data, uint16 flags) const hasTransportTime2 = self->HasExtraUnitMovementFlag(MOVEMENTFLAG2_INTERPOLATED_MOVEMENT); hasPitch = ((movementFlags & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING)) || (movementFlagsExtra & MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING)); - hasFallDirection = movementFlags & MOVEMENTFLAG_FALLING; - hasFallData = hasFallDirection; // FallDirection implies that FallData is set as well + hasFallData = hasFallDirection = movementFlags & MOVEMENTFLAG_FALLING; hasSplineElevation = movementFlags & MOVEMENTFLAG_SPLINE_ELEVATION; movementFlags &= MOVEMENTFLAG_MASK_CREATURE_ALLOWED; @@ -412,9 +411,9 @@ void Object::BuildMovementUpdate(ByteBuffer* data, uint16 flags) const if (movementFlags) data->WriteBits(movementFlags, 30); - data->WriteBit(0); + data->WriteBit(hasSpline && GetTypeId() == TYPEID_PLAYER); // Has spline (from MovementInfo) data->WriteBit(!hasPitch); // Has pitch - data->WriteBit(hasSpline); // Has spline data + data->WriteBit(hasSpline); // Has spline data (independent) data->WriteBit(hasFallData); // Has fall data data->WriteBit(!hasSplineElevation); // Has spline elevation data->WriteBit(guid[5]); diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index 5a95c051968..0dbd92d19f5 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -492,7 +492,6 @@ struct MovementInfo // swimming/flying float pitch; - // jumping struct JumpInfo { diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index c0b7b889753..41a75f424ae 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -27418,7 +27418,7 @@ void Player::ReadMovementInfo(WorldPacket& data, MovementInfo* mi, Movement::Ext break; case MSEPitch: if (mi->bits.hasPitch) - data >> mi->pitch; + mi->pitch = G3D::wrap(data.read<float>(), float(-M_PI), float(M_PI)); break; case MSEFallTime: if (mi->bits.hasFallData) @@ -27539,5 +27539,14 @@ void Player::ReadMovementInfo(WorldPacket& data, MovementInfo* mi, Movement::Ext REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY | MOVEMENTFLAG_CAN_FLY) && mi->HasMovementFlag(MOVEMENTFLAG_FALLING), MOVEMENTFLAG_FALLING); + REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_FALLING) && (!mi->bits.hasFallData || !mi->bits.hasFallDirection), MOVEMENTFLAG_FALLING); + + REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_SPLINE_ELEVATION) && + (!mi->bits.hasSplineElevation || G3D::fuzzyEq(mi->splineElevation, 0.0f)), MOVEMENTFLAG_SPLINE_ELEVATION); + + // Client first checks if spline elevation != 0, then verifies flag presence + if (mi->bits.hasSplineElevation) + mi->AddMovementFlag(MOVEMENTFLAG_SPLINE_ELEVATION); + #undef REMOVE_VIOLATING_FLAGS } diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 9d070cf60da..561fad0d903 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -1246,7 +1246,6 @@ class Player : public Unit, public GridObject<Player> bool IsInWater() const { return m_isInWater; } bool IsUnderWater() const; - bool IsFalling() { return GetPositionZ() < m_lastFallZ; } void SendInitialPacketsBeforeAddToMap(); void SendInitialPacketsAfterAddToMap(); diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 79267c94bfc..7a13a661004 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -16009,16 +16009,14 @@ bool Unit::SetDisableGravity(bool disable, bool packetOnly /*= false*/) if (disable) { AddUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY); - RemoveUnitMovementFlag(MOVEMENTFLAG_FALLING); + RemoveUnitMovementFlag(MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_SPLINE_ELEVATION); + SetFall(false); } else { RemoveUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY); if (!HasUnitMovementFlag(MOVEMENTFLAG_CAN_FLY)) - { - m_movementInfo.SetFallTime(0); - AddUnitMovementFlag(MOVEMENTFLAG_FALLING); - } + SetFall(true); } } @@ -16030,6 +16028,28 @@ bool Unit::SetDisableGravity(bool disable, bool packetOnly /*= false*/) return true; } +bool Unit::SetFall(bool enable) +{ + if (enable == HasUnitMovementFlag(MOVEMENTFLAG_FALLING)) + return false; + + if (enable) + { + AddUnitMovementFlag(MOVEMENTFLAG_FALLING); + m_movementInfo.SetFallTime(0); + m_movementInfo.bits.hasFallData = true; + m_movementInfo.bits.hasFallDirection = true; + } + else + { + RemoveUnitMovementFlag(MOVEMENTFLAG_FALLING | MOVEMENTFLAG_FALLING_FAR); + m_movementInfo.bits.hasFallDirection = false; + // Do not remove hasFallData marker + } + + return true; +} + bool Unit::SetSwim(bool enable) { if (enable == HasUnitMovementFlag(MOVEMENTFLAG_SWIMMING)) @@ -16056,16 +16076,14 @@ bool Unit::SetCanFly(bool enable) if (enable) { AddUnitMovementFlag(MOVEMENTFLAG_CAN_FLY); - RemoveUnitMovementFlag(MOVEMENTFLAG_FALLING); + RemoveUnitMovementFlag(MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_SPLINE_ELEVATION); + SetFall(false); } else { RemoveUnitMovementFlag(MOVEMENTFLAG_CAN_FLY | MOVEMENTFLAG_MASK_MOVING_FLY); if (!IsLevitating()) - { - m_movementInfo.SetFallTime(0); - AddUnitMovementFlag(MOVEMENTFLAG_FALLING); - } + SetFall(true); } if (enable) diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 27fb8e83546..e068d1165e0 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -1610,13 +1610,14 @@ class Unit : public WorldObject bool IsLevitating() const { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY); } bool IsWalking() const { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_WALKING); } - virtual bool SetWalk(bool enable); - virtual bool SetDisableGravity(bool disable, bool packetOnly = false); - virtual bool SetSwim(bool enable); - virtual bool SetCanFly(bool enable); - virtual bool SetWaterWalking(bool enable, bool packetOnly = false); - virtual bool SetFeatherFall(bool enable, bool packetOnly = false); - virtual bool SetHover(bool enable, bool packetOnly = false); + bool SetWalk(bool enable); + bool SetDisableGravity(bool disable, bool packetOnly = false); + bool SetFall(bool enable); + bool SetSwim(bool enable); + bool SetCanFly(bool enable); + bool SetWaterWalking(bool enable, bool packetOnly = false); + bool SetFeatherFall(bool enable, bool packetOnly = false); + bool SetHover(bool enable, bool packetOnly = false); void SetInFront(WorldObject const* target); void SetFacingTo(float ori); diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index 92864a0f279..15676d17c43 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -1049,9 +1049,11 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder) if (pCurrChar->m_deathState != ALIVE) { // not blizz like, we must correctly save and load player instead... - if (pCurrChar->getRace() == RACE_NIGHTELF) + if (pCurrChar->getRace() == RACE_NIGHTELF && !pCurrChar->HasAura(20584)) pCurrChar->CastSpell(pCurrChar, 20584, true, 0);// auras SPELL_AURA_INCREASE_SPEED(+speed in wisp form), SPELL_AURA_INCREASE_SWIM_SPEED(+swim speed in wisp form), SPELL_AURA_TRANSFORM (to wisp form) - pCurrChar->CastSpell(pCurrChar, 8326, true, 0); // auras SPELL_AURA_GHOST, SPELL_AURA_INCREASE_SPEED(why?), SPELL_AURA_INCREASE_SWIM_SPEED(why?) + + if (!pCurrChar->HasAura(8326)) + pCurrChar->CastSpell(pCurrChar, 8326, true, 0); // auras SPELL_AURA_GHOST, SPELL_AURA_INCREASE_SPEED(why?), SPELL_AURA_INCREASE_SWIM_SPEED(why?) pCurrChar->SetWaterWalking(true); } diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index 6b3959a7df3..5ad39188fbd 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -382,7 +382,7 @@ void WorldSession::HandleLogoutRequestOpcode(WorldPacket& /*recvData*/) uint32 reason = 0; if (GetPlayer()->IsInCombat() && !canLogoutInCombat) reason = 1; - else if (GetPlayer()->m_movementInfo.HasMovementFlag(MOVEMENTFLAG_FALLING | MOVEMENTFLAG_FALLING_FAR)) + else if (GetPlayer()->IsFalling()) reason = 3; // is jumping or falling else if (GetPlayer()->duel || GetPlayer()->HasAura(9454)) // is dueling or frozen by GM via freeze command reason = 2; // FIXME - Need the correct value @@ -2004,6 +2004,16 @@ void WorldSession::HandleObjectUpdateFailedOpcode(WorldPacket& recvPacket) WorldObject* obj = ObjectAccessor::GetWorldObject(*GetPlayer(), guid); TC_LOG_ERROR(LOG_FILTER_NETWORKIO, "Object update failed for object " UI64FMTD " (%s) for player %s (%u)", uint64(guid), obj ? obj->GetName().c_str() : "object-not-found", GetPlayerName().c_str(), GetGuidLow()); + + // If create object failed for current player then client will be stuck on loading screen + if (_player->GetGUID() == guid) + { + LogoutPlayer(true); + return; + } + + // Pretend we've never seen this object + _player->m_clientGUIDs.erase(guid); } void WorldSession::HandleSaveCUFProfiles(WorldPacket& recvPacket) diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp index e9b0087712b..00ec1b7fa65 100644 --- a/src/server/game/Movement/MotionMaster.cpp +++ b/src/server/game/Movement/MotionMaster.cpp @@ -394,10 +394,7 @@ void MotionMaster::MoveFall(uint32 id /*=0*/) return; if (_owner->GetTypeId() == TYPEID_PLAYER) - { - _owner->AddUnitMovementFlag(MOVEMENTFLAG_FALLING); - _owner->m_movementInfo.SetFallTime(0); - } + _owner->SetFall(true); Movement::MoveSplineInit init(_owner); init.MoveTo(_owner->GetPositionX(), _owner->GetPositionY(), tz, false); diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index 42cf9803ab3..1b4762330c4 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -142,10 +142,7 @@ WorldSession::WorldSession(uint32 id, WorldSocket* sock, AccountTypes sec, uint8 _compressionStream->next_in = NULL; int32 z_res = deflateInit(_compressionStream, sWorld->getIntConfig(CONFIG_COMPRESSION)); if (z_res != Z_OK) - { TC_LOG_ERROR(LOG_FILTER_NETWORKIO, "Can't initialize packet compression (zlib: deflateInit) Error code: %i (%s)", z_res, zError(z_res)); - return; - } } /// WorldSession destructor |