mirror of
https://github.com/araxiaonline/TrinityCore.git
synced 2026-06-20 23:11:56 -04:00
Core/PacketIO: Fixed unneccessary packet spam when units become visible for players
Before this change, one player starting to see any unit (CreateObject) would trigger sending root, feather fall, water walk, hover, can turn while falling and double jump status changes to ALL nearby players
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
float hoverHeight = GetFloatValue(UNIT_FIELD_HOVERHEIGHT);
|
||||
|
||||
if (enable)
|
||||
{
|
||||
if (enable == HasUnitMovementFlag(MOVEMENTFLAG_HOVER))
|
||||
return false;
|
||||
|
||||
float hoverHeight = GetFloatValue(UNIT_FIELD_HOVERHEIGHT);
|
||||
|
||||
if (enable)
|
||||
//! No need to check height on ascent
|
||||
AddUnitMovementFlag(MOVEMENTFLAG_HOVER);
|
||||
if (hoverHeight)
|
||||
UpdateHeight(GetPositionZ() + hoverHeight);
|
||||
}
|
||||
else
|
||||
{
|
||||
RemoveUnitMovementFlag(MOVEMENTFLAG_HOVER);
|
||||
if (hoverHeight)
|
||||
{
|
||||
//! No need to check height on ascent
|
||||
AddUnitMovementFlag(MOVEMENTFLAG_HOVER);
|
||||
if (hoverHeight)
|
||||
UpdateHeight(GetPositionZ() + hoverHeight);
|
||||
}
|
||||
else
|
||||
{
|
||||
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] =
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user