diff options
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 46 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 138 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.h | 12 | ||||
-rw-r--r-- | src/server/game/Server/Packets/MailPackets.cpp | 4 | ||||
-rw-r--r-- | src/server/game/Server/Packets/MovementPackets.cpp | 86 | ||||
-rw-r--r-- | src/server/game/Server/Packets/MovementPackets.h | 39 | ||||
-rw-r--r-- | src/server/game/Server/Protocol/Opcodes.cpp | 2 |
7 files changed, 202 insertions, 125 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index e2b38a50603..2c030d0c58a 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -4235,7 +4235,9 @@ void Player::ResurrectPlayer(float restore_percent, bool applySickness) setDeathState(ALIVE); - SetWaterWalking(false, true); + // add the flag to make sure opcode is always sent + AddUnitMovementFlag(MOVEMENTFLAG_WATERWALKING); + SetWaterWalking(false); if (!HasUnitState(UNIT_STATE_STUNNED)) SetRooted(false); @@ -23096,9 +23098,31 @@ void Player::SendInitialPacketsAfterAddToMap() if (HasAuraType(SPELL_AURA_MOD_STUN)) SetRooted(true); + WorldPackets::Movement::MoveSetCompoundState setCompoundState; // manual send package (have code in HandleEffect(this, AURA_EFFECT_HANDLE_SEND_FOR_CLIENT, true); that must not be re-applied. if (HasAuraType(SPELL_AURA_MOD_ROOT) || HasAuraType(SPELL_AURA_MOD_ROOT_2)) - SetRooted(true, true); + setCompoundState.StateChanges.emplace_back(SMSG_MOVE_ROOT, m_movementCounter++); + + if (HasAuraType(SPELL_AURA_FEATHER_FALL)) + setCompoundState.StateChanges.emplace_back(SMSG_MOVE_SET_FEATHER_FALL, m_movementCounter++); + + if (HasAuraType(SPELL_AURA_WATER_WALK)) + setCompoundState.StateChanges.emplace_back(SMSG_MOVE_SET_WATER_WALK, m_movementCounter++); + + if (HasAuraType(SPELL_AURA_HOVER)) + setCompoundState.StateChanges.emplace_back(SMSG_MOVE_SET_HOVERING, m_movementCounter++); + + if (HasAuraType(SPELL_AURA_CAN_TURN_WHILE_FALLING)) + setCompoundState.StateChanges.emplace_back(SMSG_MOVE_SET_CAN_TURN_WHILE_FALLING, m_movementCounter++); + + if (HasAura(SPELL_DH_DOUBLE_JUMP)) + setCompoundState.StateChanges.emplace_back(SMSG_MOVE_ENABLE_DOUBLE_JUMP, m_movementCounter++); + + if (!setCompoundState.StateChanges.empty()) + { + setCompoundState.MoverGUID = GetGUID(); + SendDirectMessage(setCompoundState.Write()); + } SendAurasForTarget(this); SendEnchantmentDurations(); // must be after add to map @@ -23452,24 +23476,6 @@ void Player::SendAurasForTarget(Unit* target) const if (!target || target->GetVisibleAuras().empty()) // speedup things return; - /*! Blizz sends certain movement packets sometimes even before CreateObject - These movement packets are usually found in SMSG_COMPRESSED_MOVES - */ - if (target->HasAuraType(SPELL_AURA_FEATHER_FALL)) - target->SetFeatherFall(true, true); - - if (target->HasAuraType(SPELL_AURA_WATER_WALK)) - target->SetWaterWalking(true, true); - - if (target->HasAuraType(SPELL_AURA_HOVER)) - target->SetHover(true, true); - - if (target->HasAuraType(SPELL_AURA_CAN_TURN_WHILE_FALLING)) - target->SetCanTurnWhileFalling(true, true); - - if (target->HasAura(SPELL_DH_DOUBLE_JUMP)) - target->SetDoubleJump(true, true); - Unit::VisibleAuraContainer const& visibleAuras = target->GetVisibleAuras(); WorldPackets::Spells::AuraUpdate update; diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 750643ec126..ca44e62923d 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -15372,25 +15372,22 @@ bool Unit::SetWalk(bool enable) return true; } -bool Unit::SetDisableGravity(bool disable, bool packetOnly /*= false*/) +bool Unit::SetDisableGravity(bool disable) { - if (!packetOnly) - { - if (disable == IsLevitating()) - return false; + if (disable == IsLevitating()) + return false; - if (disable) - { - AddUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY); - RemoveUnitMovementFlag(MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_SPLINE_ELEVATION); - SetFall(false); - } - else - { - RemoveUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY); - if (!HasUnitMovementFlag(MOVEMENTFLAG_CAN_FLY)) - SetFall(true); - } + if (disable) + { + AddUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY); + RemoveUnitMovementFlag(MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_SPLINE_ELEVATION); + SetFall(false); + } + else + { + RemoveUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY); + if (!HasUnitMovementFlag(MOVEMENTFLAG_CAN_FLY)) + SetFall(true); } static OpcodeServer const gravityOpcodeTable[2][2] = @@ -15503,18 +15500,15 @@ bool Unit::SetCanFly(bool enable) return true; } -bool Unit::SetWaterWalking(bool enable, bool packetOnly /*= false */) +bool Unit::SetWaterWalking(bool enable) { - if (!packetOnly) - { - if (enable == HasUnitMovementFlag(MOVEMENTFLAG_WATERWALKING)) - return false; + if (enable == HasUnitMovementFlag(MOVEMENTFLAG_WATERWALKING)) + return false; - if (enable) - AddUnitMovementFlag(MOVEMENTFLAG_WATERWALKING); - else - RemoveUnitMovementFlag(MOVEMENTFLAG_WATERWALKING); - } + if (enable) + AddUnitMovementFlag(MOVEMENTFLAG_WATERWALKING); + else + RemoveUnitMovementFlag(MOVEMENTFLAG_WATERWALKING); static OpcodeServer const waterWalkingOpcodeTable[2][2] = { @@ -15543,18 +15537,15 @@ bool Unit::SetWaterWalking(bool enable, bool packetOnly /*= false */) return true; } -bool Unit::SetFeatherFall(bool enable, bool packetOnly /*= false */) +bool Unit::SetFeatherFall(bool enable) { - if (!packetOnly) - { - if (enable == HasUnitMovementFlag(MOVEMENTFLAG_FALLING_SLOW)) - return false; + if (enable == HasUnitMovementFlag(MOVEMENTFLAG_FALLING_SLOW)) + return false; - if (enable) - AddUnitMovementFlag(MOVEMENTFLAG_FALLING_SLOW); - else - RemoveUnitMovementFlag(MOVEMENTFLAG_FALLING_SLOW); - } + if (enable) + AddUnitMovementFlag(MOVEMENTFLAG_FALLING_SLOW); + else + RemoveUnitMovementFlag(MOVEMENTFLAG_FALLING_SLOW); static OpcodeServer const featherFallOpcodeTable[2][2] = { @@ -15583,31 +15574,28 @@ bool Unit::SetFeatherFall(bool enable, bool packetOnly /*= false */) return true; } -bool Unit::SetHover(bool enable, bool packetOnly /*= false*/) +bool Unit::SetHover(bool enable) { - if (!packetOnly) - { - if (enable == HasUnitMovementFlag(MOVEMENTFLAG_HOVER)) - return false; + if (enable == HasUnitMovementFlag(MOVEMENTFLAG_HOVER)) + return false; - float hoverHeight = GetFloatValue(UNIT_FIELD_HOVERHEIGHT); + float hoverHeight = GetFloatValue(UNIT_FIELD_HOVERHEIGHT); - if (enable) - { - //! No need to check height on ascent - AddUnitMovementFlag(MOVEMENTFLAG_HOVER); - if (hoverHeight) - UpdateHeight(GetPositionZ() + hoverHeight); - } - else + if (enable) + { + //! No need to check height on ascent + AddUnitMovementFlag(MOVEMENTFLAG_HOVER); + if (hoverHeight) + UpdateHeight(GetPositionZ() + hoverHeight); + } + else + { + RemoveUnitMovementFlag(MOVEMENTFLAG_HOVER); + if (hoverHeight) { - RemoveUnitMovementFlag(MOVEMENTFLAG_HOVER); - if (hoverHeight) - { - float newZ = GetPositionZ() - hoverHeight; - UpdateAllowedPositionZ(GetPositionX(), GetPositionY(), newZ); - UpdateHeight(newZ); - } + float newZ = GetPositionZ() - hoverHeight; + UpdateAllowedPositionZ(GetPositionX(), GetPositionY(), newZ); + UpdateHeight(newZ); } } @@ -15709,18 +15697,15 @@ bool Unit::SetCanTransitionBetweenSwimAndFly(bool enable) return true; } -bool Unit::SetCanTurnWhileFalling(bool enable, bool packetOnly /*= false*/) +bool Unit::SetCanTurnWhileFalling(bool enable) { - if (!packetOnly) - { - if (enable == HasExtraUnitMovementFlag(MOVEMENTFLAG2_CAN_TURN_WHILE_FALLING)) - return false; + if (enable == HasExtraUnitMovementFlag(MOVEMENTFLAG2_CAN_TURN_WHILE_FALLING)) + return false; - if (enable) - AddExtraUnitMovementFlag(MOVEMENTFLAG2_CAN_TURN_WHILE_FALLING); - else - RemoveExtraUnitMovementFlag(MOVEMENTFLAG2_CAN_TURN_WHILE_FALLING); - } + if (enable) + AddExtraUnitMovementFlag(MOVEMENTFLAG2_CAN_TURN_WHILE_FALLING); + else + RemoveExtraUnitMovementFlag(MOVEMENTFLAG2_CAN_TURN_WHILE_FALLING); static OpcodeServer const canTurnWhileFallingOpcodeTable[2] = { @@ -15743,18 +15728,15 @@ bool Unit::SetCanTurnWhileFalling(bool enable, bool packetOnly /*= false*/) return true; } -bool Unit::SetDoubleJump(bool enable, bool packetOnly /*= false*/) +bool Unit::SetDoubleJump(bool enable) { - if (!packetOnly) - { - if (enable == HasExtraUnitMovementFlag(MOVEMENTFLAG2_DOUBLE_JUMP)) - return false; + if (enable == HasExtraUnitMovementFlag(MOVEMENTFLAG2_DOUBLE_JUMP)) + return false; - if (enable) - AddExtraUnitMovementFlag(MOVEMENTFLAG2_DOUBLE_JUMP); - else - RemoveExtraUnitMovementFlag(MOVEMENTFLAG2_DOUBLE_JUMP); - } + if (enable) + AddExtraUnitMovementFlag(MOVEMENTFLAG2_DOUBLE_JUMP); + else + RemoveExtraUnitMovementFlag(MOVEMENTFLAG2_DOUBLE_JUMP); static OpcodeServer const doubleJumpOpcodeTable[2] = { diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 58cab981dfc..a521a782a0d 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -1690,17 +1690,17 @@ class TC_GAME_API Unit : public WorldObject bool IsWalking() const { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_WALKING); } bool IsHovering() const { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_HOVER); } bool SetWalk(bool enable); - bool SetDisableGravity(bool disable, bool packetOnly = false); + bool SetDisableGravity(bool disable); 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); + bool SetWaterWalking(bool enable); + bool SetFeatherFall(bool enable); + bool SetHover(bool enable); bool SetCollision(bool disable); bool SetCanTransitionBetweenSwimAndFly(bool enable); - bool SetCanTurnWhileFalling(bool enable, bool packetOnly = false); - bool SetDoubleJump(bool enable, bool packetOnly = false); + bool SetCanTurnWhileFalling(bool enable); + bool SetDoubleJump(bool enable); void SendSetVehicleRecId(uint32 vehicleId); void SetInFront(WorldObject const* target); diff --git a/src/server/game/Server/Packets/MailPackets.cpp b/src/server/game/Server/Packets/MailPackets.cpp index f8922d5bbaf..472c33503cb 100644 --- a/src/server/game/Server/Packets/MailPackets.cpp +++ b/src/server/game/Server/Packets/MailPackets.cpp @@ -128,7 +128,7 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Mail::MailListEntry const data.WriteBits(entry.Body.size(), 13); data.FlushBits(); - for (auto const& att : entry.Attachments) + for (WorldPackets::Mail::MailAttachedItem const& att : entry.Attachments) data << att; if (entry.SenderCharacter) @@ -157,7 +157,7 @@ WorldPacket const* WorldPackets::Mail::MailListResult::Write() _worldPacket << uint32(Mails.size()); _worldPacket << int32(TotalNumRecords); - for (auto const& mail : Mails) + for (MailListEntry const& mail : Mails) _worldPacket << mail; return &_worldPacket; diff --git a/src/server/game/Server/Packets/MovementPackets.cpp b/src/server/game/Server/Packets/MovementPackets.cpp index 0a77af16b83..1a04aa52a50 100644 --- a/src/server/game/Server/Packets/MovementPackets.cpp +++ b/src/server/game/Server/Packets/MovementPackets.cpp @@ -532,22 +532,27 @@ WorldPacket const* WorldPackets::Movement::MoveTeleport::Write() return &_worldPacket; } +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Movement::MovementForce const& movementForce) +{ + data << movementForce.ID; + data << movementForce.Origin; + data << movementForce.Direction; + data << movementForce.TransportPosition; + data << movementForce.TransportID; + data << movementForce.Magnitude; + data.WriteBits(movementForce.Type, 2); + data.FlushBits(); + + return data; +} + WorldPacket const* WorldPackets::Movement::MoveUpdateTeleport::Write() { _worldPacket << *movementInfo; _worldPacket << int32(MovementForces.size()); for (WorldPackets::Movement::MovementForce const& force : MovementForces) - { - _worldPacket << force.ID; - _worldPacket << force.Origin; - _worldPacket << force.Direction; - _worldPacket << force.TransportPosition; - _worldPacket << force.TransportID; - _worldPacket << force.Magnitude; - _worldPacket.WriteBits(force.Type, 2); - _worldPacket.FlushBits(); - } + _worldPacket << force; _worldPacket.WriteBit(WalkSpeed.is_initialized()); _worldPacket.WriteBit(RunSpeed.is_initialized()); @@ -679,14 +684,7 @@ WorldPacket const* WorldPackets::Movement::MoveUpdateRemoveMovementForce::Write( WorldPacket const* WorldPackets::Movement::MoveUpdateApplyMovementForce::Write() { _worldPacket << *movementInfo; - _worldPacket << Force.ID; - _worldPacket << Force.Origin; - _worldPacket << Force.Direction; - _worldPacket << Force.TransportPosition; - _worldPacket << Force.TransportID; - _worldPacket << Force.Magnitude; - _worldPacket.WriteBits(Force.Type, 2); - _worldPacket.FlushBits(); + _worldPacket << Force; return &_worldPacket; } @@ -760,3 +758,55 @@ WorldPacket const* WorldPackets::Movement::ResumeToken::Write() return &_worldPacket; } + +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Movement::MoveSetCompoundState::MoveStateChange const& stateChange) +{ + data << uint16(stateChange.MessageID); + data << uint32(stateChange.SequenceIndex); + data.WriteBit(stateChange.Speed.is_initialized()); + data.WriteBit(stateChange.KnockBack.is_initialized()); + data.WriteBit(stateChange.VehicleRecID.is_initialized()); + data.WriteBit(stateChange.CollisionHeight.is_initialized()); + data.WriteBit(stateChange.MovementForce_.is_initialized()); + data.WriteBit(stateChange.Unknown.is_initialized()); + data.FlushBits(); + + if (stateChange.CollisionHeight) + { + data << float(stateChange.CollisionHeight->Height); + data << float(stateChange.CollisionHeight->Scale); + data.WriteBits(stateChange.CollisionHeight->Reason, 2); + data.FlushBits(); + } + + if (stateChange.Speed) + data << float(*stateChange.Speed); + + if (stateChange.KnockBack) + { + data << float(stateChange.KnockBack->HorzSpeed); + data << stateChange.KnockBack->Direction; + data << float(stateChange.KnockBack->InitVertSpeed); + } + + if (stateChange.VehicleRecID) + data << int32(*stateChange.VehicleRecID); + + if (stateChange.MovementForce_) + data << *stateChange.MovementForce_; + + if (stateChange.Unknown) + data << *stateChange.Unknown; + + return data; +} + +WorldPacket const* WorldPackets::Movement::MoveSetCompoundState::Write() +{ + _worldPacket << MoverGUID; + _worldPacket << uint32(StateChanges.size()); + for (MoveStateChange const& stateChange : StateChanges) + _worldPacket << stateChange; + + return &_worldPacket; +} diff --git a/src/server/game/Server/Packets/MovementPackets.h b/src/server/game/Server/Packets/MovementPackets.h index 1c21c034c86..83c53812ea3 100644 --- a/src/server/game/Server/Packets/MovementPackets.h +++ b/src/server/game/Server/Packets/MovementPackets.h @@ -536,6 +536,45 @@ namespace WorldPackets uint32 SequenceIndex = 1; uint32 Reason = 1; }; + + class MoveSetCompoundState final : public ServerPacket + { + public: + struct CollisionHeightInfo + { + float Height = 0.0f; + float Scale = 0.0f; + UpdateCollisionHeightReason Reason; + }; + + struct KnockBackInfo + { + float HorzSpeed = 0.0f; + G3D::Vector2 Direction; + float InitVertSpeed = 0.0f; + }; + + struct MoveStateChange + { + MoveStateChange(OpcodeServer messageId, uint32 sequenceIndex) : MessageID(messageId), SequenceIndex(sequenceIndex) { } + + uint16 MessageID = 0; + uint32 SequenceIndex = 0; + Optional<float> Speed; + Optional<KnockBackInfo> KnockBack; + Optional<int32> VehicleRecID; + Optional<CollisionHeightInfo> CollisionHeight; + Optional<MovementForce> MovementForce_; + Optional<ObjectGuid> Unknown; + }; + + MoveSetCompoundState() : ServerPacket(SMSG_MOVE_SET_COMPOUND_STATE, 4 + 1) { } + + WorldPacket const* Write() override; + + ObjectGuid MoverGUID; + std::vector<MoveStateChange> StateChanges; + }; } ByteBuffer& operator<<(ByteBuffer& data, Movement::MonsterSplineFilterKey const& monsterSplineFilterKey); diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index c242d9ee929..4fbc0b700fd 100644 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -1365,7 +1365,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_CAN_FLY, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_CAN_TURN_WHILE_FALLING, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_COLLISION_HEIGHT, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_COMPOUND_STATE, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_COMPOUND_STATE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_FEATHER_FALL, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_FLIGHT_BACK_SPEED, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_FLIGHT_SPEED, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); |