Fix SMSG_UPDATE_OBJECT, SMSG_DESTROY_OBJECT, and some teleport opcodes

Authors: Strawberry, Trinity, me
Signed-off-by: Yaki Khadafi <elsoldollo@gmail.com>
This commit is contained in:
Yaki Khadafi 2012-08-05 22:46:48 +03:00 committed by Antz
parent 39dda4bc4c
commit f7cd8ce52a
24 changed files with 578 additions and 390 deletions

View file

@ -32,7 +32,7 @@ Corpse::Corpse(CorpseType type) : WorldObject()
m_objectType |= TYPEMASK_CORPSE;
m_objectTypeId = TYPEID_CORPSE;
m_updateFlag = (UPDATEFLAG_HIGHGUID | UPDATEFLAG_HAS_POSITION | UPDATEFLAG_POSITION);
m_updateFlag = UPDATEFLAG_POSITION;
m_valuesCount = CORPSE_END;

View file

@ -33,7 +33,7 @@ DynamicObject::DynamicObject() : WorldObject()
m_objectType |= TYPEMASK_DYNAMICOBJECT;
m_objectTypeId = TYPEID_DYNAMICOBJECT;
m_updateFlag = (UPDATEFLAG_HIGHGUID | UPDATEFLAG_HAS_POSITION | UPDATEFLAG_POSITION);
m_updateFlag = UPDATEFLAG_HAS_POSITION;
m_valuesCount = DYNAMICOBJECT_END;
}

View file

@ -48,7 +48,7 @@ GameObject::GameObject() : WorldObject(),
m_objectType |= TYPEMASK_GAMEOBJECT;
m_objectTypeId = TYPEID_GAMEOBJECT;
m_updateFlag = (UPDATEFLAG_HIGHGUID | UPDATEFLAG_HAS_POSITION | UPDATEFLAG_POSITION | UPDATEFLAG_ROTATION);
m_updateFlag = UPDATEFLAG_HAS_POSITION | UPDATEFLAG_ROTATION;
m_valuesCount = GAMEOBJECT_END;
m_respawnTime = 0;

View file

@ -39,7 +39,7 @@ namespace MaNGOS
GuidSet i_clientGUIDs;
std::set<WorldObject*> i_visibleNow;
explicit VisibleNotifier(Camera& c) : i_camera(c), i_clientGUIDs(c.GetOwner()->m_clientGUIDs) {}
explicit VisibleNotifier(Camera &c) : i_camera(c), i_clientGUIDs(c.GetOwner()->m_clientGUIDs), i_data(c.GetOwner()->GetMapId()) {}
template<class T> void Visit(GridRefManager<T>& m);
void Visit(CameraMapType& /*m*/) {}
void Notify(void);

View file

@ -361,7 +361,7 @@ Item::Item()
m_objectType |= TYPEMASK_ITEM;
m_objectTypeId = TYPEID_ITEM;
m_updateFlag = UPDATEFLAG_HIGHGUID;
m_updateFlag = 0;
m_valuesCount = ITEM_END;
m_slot = 0;

View file

@ -887,7 +887,7 @@ void Map::SendInitSelf(Player* player)
{
DETAIL_LOG("Creating player data for himself %u", player->GetGUIDLow());
UpdateData data;
UpdateData data(player->GetMapId());
// attach to player data current transport data
if (Transport* transport = player->GetTransport())
@ -924,7 +924,7 @@ void Map::SendInitTransports(Player* player)
if (tmap.find(player->GetMapId()) == tmap.end())
return;
UpdateData transData;
UpdateData transData(player->GetMapId());
MapManager::TransportSet& tset = tmap[player->GetMapId()];
@ -951,7 +951,7 @@ void Map::SendRemoveTransports(Player* player)
if (tmap.find(player->GetMapId()) == tmap.end())
return;
UpdateData transData;
UpdateData transData(player->GetMapId());
MapManager::TransportSet& tset = tmap[player->GetMapId()];

View file

@ -516,7 +516,7 @@ bool WorldSession::VerifyMovementInfo(MovementInfo const& movementInfo, ObjectGu
if (!MaNGOS::IsValidMapCoord(movementInfo.GetPos()->x, movementInfo.GetPos()->y, movementInfo.GetPos()->z, movementInfo.GetPos()->o))
return false;
if (movementInfo.HasMovementFlag(MOVEFLAG_ONTRANSPORT))
if (movementInfo.GetTransportGuid())
{
// transports size limited
// (also received at zeppelin/lift leave by some reason with t_* as absolute in continent coordinates, can be safely skipped)
@ -541,11 +541,11 @@ void WorldSession::HandleMoverRelocation(MovementInfo& movementInfo)
if (Player* plMover = mover->GetTypeId() == TYPEID_PLAYER ? (Player*)mover : NULL)
{
if (movementInfo.HasMovementFlag(MOVEFLAG_ONTRANSPORT))
if (movementInfo.GetTransportGuid())
{
if (!plMover->m_transport)
{
// elevators also cause the client to send MOVEFLAG_ONTRANSPORT - just unmount if the guid can be found in the transport list
// elevators also cause the client to send transport guid - just unmount if the guid can be found in the transport list
for (MapManager::TransportSet::const_iterator iter = sMapMgr.m_Transports.begin(); iter != sMapMgr.m_Transports.end(); ++iter)
{
if ((*iter)->GetObjectGuid() == movementInfo.GetTransportGuid())

View file

@ -121,18 +121,6 @@ void Object::SendForcedObjectUpdate()
}
}
void Object::BuildMovementUpdateBlock(UpdateData* data, uint16 flags) const
{
ByteBuffer buf(500);
buf << uint8(UPDATETYPE_MOVEMENT);
buf << GetPackGUID();
BuildMovementUpdate(&buf, flags);
data->AddUpdateBlock(buf);
}
void Object::BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* target) const
{
if (!target)
@ -200,7 +188,7 @@ void Object::BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* target) c
void Object::SendCreateUpdateToPlayer(Player* player)
{
// send create update to player
UpdateData upd;
UpdateData upd(player->GetMapId());
WorldPacket packet;
BuildCreateUpdateBlockForPlayer(&upd, player);
@ -239,171 +227,263 @@ void Object::DestroyForPlayer(Player* target, bool anim) const
target->GetSession()->SendPacket(&data);
}
void Object::BuildMovementUpdate(ByteBuffer* data, uint16 updateFlags) const
void Object::BuildMovementUpdate(ByteBuffer * data, uint16 updateFlags) const
{
// uint16 moveFlags2 = (isType(TYPEMASK_UNIT) ? ((Unit*)this)->m_movementInfo.GetMovementFlags2() : MOVEFLAG2_NONE);
ObjectGuid Guid = GetObjectGuid();
*data << uint16(updateFlags); // update flags
data->WriteBit(false);
data->WriteBit(false);
data->WriteBit(updateFlags & UPDATEFLAG_ROTATION);
data->WriteBit(updateFlags & UPDATEFLAG_ANIM_KITS); // AnimKits
data->WriteBit(updateFlags & UPDATEFLAG_HAS_ATTACKING_TARGET);
data->WriteBit(updateFlags & UPDATEFLAG_SELF);
data->WriteBit(updateFlags & UPDATEFLAG_VEHICLE);
data->WriteBit(updateFlags & UPDATEFLAG_LIVING);
data->WriteBits(0, 24); // Byte Counter
data->WriteBit(false);
data->WriteBit(updateFlags & UPDATEFLAG_POSITION); // flags & UPDATEFLAG_HAS_POSITION Game Object Position
data->WriteBit(updateFlags & UPDATEFLAG_HAS_POSITION); // Stationary Position
data->WriteBit(false);
data->WriteBit(false);
data->WriteBit(updateFlags & UPDATEFLAG_TRANSPORT);
// 0x20
if (updateFlags & UPDATEFLAG_LIVING)
{
Unit* unit = ((Unit*)this);
Unit const* unit = (Unit const*)this;
if (GetTypeId() == TYPEID_PLAYER)
bool hasTransport = unit->m_movementInfo.GetTransportGuid();
bool isSplineEnabled = unit->IsSplineEnabled();
bool hasPitch = ((unit->m_movementInfo.GetMovementFlags() & (MOVEFLAG_SWIMMING | MOVEFLAG_FLYING)) ||
(unit->m_movementInfo.GetMovementFlags2() & MOVEFLAG2_ALLOW_PITCHING));
bool haveFallData = unit->m_movementInfo.GetMovementFlags2() & MOVEFLAG2_INTERP_TURNING;
bool hasFallDirection = unit->m_movementInfo.GetMovementFlags() & MOVEFLAG_FALLING;
bool hasElevation = unit->m_movementInfo.GetMovementFlags() & MOVEFLAG_SPLINE_ELEVATION;
bool hasOrientation = GetTypeId() != TYPEID_ITEM && GetTypeId() != TYPEID_CONTAINER;
data->WriteBit(!(unit->m_movementInfo.GetMovementFlags()));
data->WriteBit(!hasOrientation);
data->WriteGuidMask<7, 3, 2>(Guid);
if(unit->m_movementInfo.GetMovementFlags())
data->WriteBits(unit->m_movementInfo.GetMovementFlags(), 30);
data->WriteBit(false);
data->WriteBit(!hasPitch);
data->WriteBit(isSplineEnabled);
data->WriteBit(haveFallData);
data->WriteBit(!hasElevation);
data->WriteGuidMask<5>(Guid);
data->WriteBit(hasTransport);
data->WriteBit(false); // hasTimeStamp == true
if (hasTransport)
{
Player* player = ((Player*)unit);
if (player->GetTransport())
player->m_movementInfo.AddMovementFlag(MOVEFLAG_ONTRANSPORT);
else
player->m_movementInfo.RemoveMovementFlag(MOVEFLAG_ONTRANSPORT);
ObjectGuid tGuid = unit->m_movementInfo.GetTransportGuid();
data->WriteGuidMask<1>(tGuid);
data->WriteBit(false); // hasTransportTime2 == false
data->WriteGuidMask<4, 0, 6>(tGuid);
data->WriteBit(false); // hasTransportTime3 == false
data->WriteGuidMask<7, 5, 3, 2>(tGuid);
}
// Update movement info time
unit->m_movementInfo.UpdateTime(WorldTimer::getMSTime());
// Write movement info
unit->m_movementInfo.Write(*data);
data->WriteGuidMask<4>(Guid);
// Unit speeds
*data << float(unit->GetSpeed(MOVE_WALK));
*data << float(unit->GetSpeed(MOVE_RUN));
*data << float(unit->GetSpeed(MOVE_RUN_BACK));
*data << float(unit->GetSpeed(MOVE_SWIM));
*data << float(unit->GetSpeed(MOVE_SWIM_BACK));
*data << float(unit->GetSpeed(MOVE_FLIGHT));
*data << float(unit->GetSpeed(MOVE_FLIGHT_BACK));
*data << float(unit->GetSpeed(MOVE_TURN_RATE));
*data << float(unit->GetSpeed(MOVE_PITCH_RATE));
if (isSplineEnabled)
{
data->WriteBit(true); // writeBits == true
Movement::PacketBuilder::WriteCreateBits(*unit->movespline, *data);
}
// 0x08000000
if (unit->m_movementInfo.GetMovementFlags() & MOVEFLAG_SPLINE_ENABLED)
Movement::PacketBuilder::WriteCreate(*unit->movespline, *data);
data->WriteGuidMask<6>(Guid);
if (haveFallData)
data->WriteBit(hasFallDirection);
data->WriteGuidMask<0, 1>(Guid);
data->WriteBit(false); // Unknown 4.3.3
data->WriteBit(!unit->m_movementInfo.GetMovementFlags2());
if(unit->m_movementInfo.GetMovementFlags2())
data->WriteBits(unit->m_movementInfo.GetMovementFlags2(), 12);
}
else
{
if (updateFlags & UPDATEFLAG_POSITION)
{
*data << uint8(0); // unk PGUID!
*data << float(((WorldObject*)this)->GetPositionX());
*data << float(((WorldObject*)this)->GetPositionY());
*data << float(((WorldObject*)this)->GetPositionZ());
*data << float(((WorldObject*)this)->GetPositionX());
*data << float(((WorldObject*)this)->GetPositionY());
*data << float(((WorldObject*)this)->GetPositionZ());
*data << float(((WorldObject*)this)->GetOrientation());
if (GetTypeId() == TYPEID_CORPSE)
*data << float(((WorldObject*)this)->GetOrientation());
else
*data << float(0);
}
else
if (updateFlags & UPDATEFLAG_POSITION)
{
Unit const* unit = (Unit const*)this;
ObjectGuid transGuid = unit->m_movementInfo.GetTransportGuid();
data->WriteGuidMask<5>(transGuid);
data->WriteBit(false); // Has GO transport time 3 == false
data->WriteGuidMask<0, 3, 6, 1, 4, 2>(transGuid);
data->WriteBit(false); // Has GO transport time 2 == false
data->WriteGuidMask<7>(transGuid);
}
if (updateFlags & UPDATEFLAG_HAS_ATTACKING_TARGET)
{
ObjectGuid guid;
if (Unit *victim = ((Unit*)this)->getVictim())
guid = victim->GetObjectGuid();
data->WriteGuidMask<2, 7, 0, 4, 5, 6, 1, 3>(guid);
}
if (updateFlags & UPDATEFLAG_ANIM_KITS)
{
data->WriteBit(true); // hasAnimKit0 == false
data->WriteBit(true); // hasAnimKit1 == false
data->WriteBit(true); // hasAnimKit2 == false
}
data->FlushBits();
if (updateFlags & UPDATEFLAG_LIVING)
{
Unit const* unit = (Unit const*)this;
bool hasTransport = unit->m_movementInfo.GetTransportGuid();
bool isSplineEnabled = unit->IsSplineEnabled();
bool hasPitch = ((unit->m_movementInfo.GetMovementFlags() & (MOVEFLAG_SWIMMING | MOVEFLAG_FLYING)) ||
(unit->m_movementInfo.GetMovementFlags2() & MOVEFLAG2_ALLOW_PITCHING));
bool hasFallData = unit->m_movementInfo.GetMovementFlags2() & MOVEFLAG2_INTERP_TURNING;
bool hasFallDirection = unit->m_movementInfo.GetMovementFlags() & MOVEFLAG_FALLING;
bool hasElevation = unit->m_movementInfo.GetMovementFlags() & MOVEFLAG_SPLINE_ELEVATION;
bool hasOrientation = GetTypeId() != TYPEID_ITEM && GetTypeId() != TYPEID_CONTAINER;
data->WriteGuidBytes<4>(Guid);
*data << unit->GetSpeed(MOVE_RUN_BACK);
if (hasFallData)
{
// 0x40
if (updateFlags & UPDATEFLAG_HAS_POSITION)
if (hasFallDirection)
{
// 0x02
if (updateFlags & UPDATEFLAG_TRANSPORT && ((GameObject*)this)->GetGoType() == GAMEOBJECT_TYPE_MO_TRANSPORT)
{
*data << float(0);
*data << float(0);
*data << float(0);
*data << float(((WorldObject*)this)->GetOrientation());
}
else
{
*data << float(((WorldObject*)this)->GetPositionX());
*data << float(((WorldObject*)this)->GetPositionY());
*data << float(((WorldObject*)this)->GetPositionZ());
*data << float(((WorldObject*)this)->GetOrientation());
}
*data << (float)unit->m_movementInfo.GetJumpInfo().cosAngle;
*data << (float)unit->m_movementInfo.GetJumpInfo().xyspeed;
*data << (float)unit->m_movementInfo.GetJumpInfo().sinAngle;
}
}
}
// 0x8
if (updateFlags & UPDATEFLAG_LOWGUID)
{
switch (GetTypeId())
*data << (uint32)unit->m_movementInfo.GetFallTime();
*data << (float)unit->m_movementInfo.GetJumpInfo().velocity;
}
*data << unit->GetSpeed(MOVE_SWIM_BACK);
if (hasElevation)
*data << unit->m_movementInfo.GetSplineElevation();
if (isSplineEnabled)
Movement::PacketBuilder::WriteCreateBytes(*unit->movespline, *data);
*data << unit->GetPositionZ();
data->WriteGuidBytes<5>(Guid);
if (hasTransport)
{
case TYPEID_OBJECT:
case TYPEID_ITEM:
case TYPEID_CONTAINER:
case TYPEID_GAMEOBJECT:
case TYPEID_DYNAMICOBJECT:
case TYPEID_CORPSE:
*data << uint32(GetGUIDLow()); // GetGUIDLow()
break;
case TYPEID_UNIT:
*data << uint32(0x0000000B); // unk, can be 0xB or 0xC
break;
case TYPEID_PLAYER:
if (updateFlags & UPDATEFLAG_SELF)
*data << uint32(0x0000002F); // unk, can be 0x15 or 0x22
else
*data << uint32(0x00000008); // unk, can be 0x7 or 0x8
break;
default:
*data << uint32(0x00000000); // unk
break;
ObjectGuid tGuid = unit->m_movementInfo.GetTransportGuid();
uint8 guidBytes[] = { 5, 7, 3, 0, 1, 6, 2, 4 };
data->WriteGuidBytes<5, 7>(tGuid);
*data << unit->m_movementInfo.GetTransportTime();
*data << unit->m_movementInfo.GetTransportPos()->o;
//if (hasTransportTime2)
// *data << uint32(...);
*data << unit->m_movementInfo.GetTransportPos()->y;
*data << unit->m_movementInfo.GetTransportPos()->x;
data->WriteGuidBytes<3>(tGuid);
*data << unit->m_movementInfo.GetTransportPos()->z;
data->WriteGuidBytes<0>(tGuid);
//if (hasTransportTime3)
// *data << uint32(...);
*data << unit->m_movementInfo.GetTransportSeat();
data->WriteGuidBytes<1, 6, 2, 4>(tGuid);
}
*data << unit->GetPositionX();
*data << unit->GetSpeed(MOVE_PITCH_RATE);
data->WriteGuidBytes<3, 0>(Guid);
*data << unit->GetSpeed(MOVE_SWIM);
*data << unit->GetPositionY();
data->WriteGuidBytes<7, 1, 2>(Guid);
*data << unit->GetSpeed(MOVE_WALK);
*data << uint32(WorldTimer::getMSTime());
*data << unit->GetSpeed(MOVE_FLIGHT_BACK);
data->WriteGuidBytes<6>(Guid);
*data << unit->GetSpeed(MOVE_TURN_RATE);
if (hasOrientation)
*data << unit->GetOrientation();
*data << unit->GetSpeed(MOVE_RUN);
if(hasPitch)
*data << unit->m_movementInfo.GetPitch();
*data << unit->GetSpeed(MOVE_FLIGHT);
}
// 0x10
if (updateFlags & UPDATEFLAG_HIGHGUID)
{
switch (GetTypeId())
{
case TYPEID_OBJECT:
case TYPEID_ITEM:
case TYPEID_CONTAINER:
case TYPEID_GAMEOBJECT:
case TYPEID_DYNAMICOBJECT:
case TYPEID_CORPSE:
*data << uint32(GetObjectGuid().GetHigh()); // GetGUIDHigh()
break;
case TYPEID_UNIT:
*data << uint32(0x0000000B); // unk, can be 0xB or 0xC
break;
case TYPEID_PLAYER:
if (updateFlags & UPDATEFLAG_SELF)
*data << uint32(0x0000002F); // unk, can be 0x15 or 0x22
else
*data << uint32(0x00000008); // unk, can be 0x7 or 0x8
break;
default:
*data << uint32(0x00000000); // unk
break;
}
}
// 0x4
if (updateFlags & UPDATEFLAG_HAS_ATTACKING_TARGET) // packed guid (current target guid)
{
if (((Unit*)this)->getVictim())
*data << ((Unit*)this)->getVictim()->GetPackGUID();
else
data->appendPackGUID(0);
}
// 0x2
if (updateFlags & UPDATEFLAG_TRANSPORT)
{
*data << uint32(WorldTimer::getMSTime()); // ms time
}
// 0x80
if (updateFlags & UPDATEFLAG_VEHICLE)
{
*data << uint32(((Unit*)this)->GetVehicleInfo()->GetEntry()->m_ID); // vehicle id
*data << float(((WorldObject*)this)->GetOrientation());
*data << uint32(((Unit*)this)->GetVehicleInfo()->GetEntry()->m_ID); // vehicle id
}
// 0x200
if (updateFlags & UPDATEFLAG_ROTATION)
if (updateFlags & UPDATEFLAG_POSITION)
{
*data << int64(((GameObject*)this)->GetPackedWorldRotation());
Unit const* unit = (Unit const*)this;
ObjectGuid transGuid = unit->m_movementInfo.GetTransportGuid();
data->WriteGuidMask<0, 5>(transGuid);
//if (hasGoTransportTime3)
// *data << uint32(...);
data->WriteGuidMask<3>(transGuid);
*data << float(unit->m_movementInfo.GetTransportPos()->x);
data->WriteGuidMask<4, 6, 1>(transGuid);
*data << uint32(unit->m_movementInfo.GetTransportTime());
*data << float(unit->m_movementInfo.GetTransportPos()->y);
data->WriteGuidMask<2, 7>(transGuid);
*data << float(unit->m_movementInfo.GetTransportPos()->z);
*data << int8(unit->m_movementInfo.GetTransportSeat());
*data << float(unit->m_movementInfo.GetTransportPos()->o);
//if (hasGoTransportTime2)
// *data << uint32(...);
}
if(updateFlags & UPDATEFLAG_ROTATION)
*data << int64(((GameObject*)this)->GetPackedWorldRotation());
if (updateFlags & UPDATEFLAG_HAS_POSITION)
{
*data << ((WorldObject*)this)->GetOrientation();
*data << ((WorldObject*)this)->GetPositionX();
*data << ((WorldObject*)this)->GetPositionY();
*data << ((WorldObject*)this)->GetPositionZ();
}
if (updateFlags & UPDATEFLAG_HAS_ATTACKING_TARGET)
{
ObjectGuid guid;
if (Unit* victim = ((Unit*)this)->getVictim())
guid = victim->GetObjectGuid();
data->WriteGuidBytes<4, 0, 3, 5, 7, 6, 2, 1>(guid);
}
//if (updateFlags & UPDATEFLAG_ANIM_KITS)
// *data << uint16(0) << uint16(0) << uint16(0);
if(updateFlags & UPDATEFLAG_TRANSPORT)
*data << uint32(WorldTimer::getMSTime());
}
void Object::BuildValuesUpdate(uint8 updatetype, ByteBuffer* data, UpdateMask* updateMask, Player* target) const
@ -905,7 +985,7 @@ void Object::BuildUpdateDataForPlayer(Player* pl, UpdateDataMapType& update_play
if (iter == update_players.end())
{
std::pair<UpdateDataMapType::iterator, bool> p = update_players.insert(UpdateDataMapType::value_type(pl, UpdateData()));
std::pair<UpdateDataMapType::iterator, bool> p = update_players.insert(UpdateDataMapType::value_type(pl, UpdateData(pl->GetMapId())));
MANGOS_ASSERT(p.second);
iter = p.first;
}

View file

@ -168,7 +168,6 @@ class MANGOS_DLL_SPEC Object
void BuildValuesUpdateBlockForPlayer(UpdateData* data, Player* target) const;
void BuildOutOfRangeUpdateBlock(UpdateData* data) const;
void BuildMovementUpdateBlock(UpdateData* data, uint16 flags = 0) const;
virtual void DestroyForPlayer(Player* target, bool anim = false) const;

View file

@ -107,7 +107,7 @@ void InitializeOpcodes()
OPCODE(SMSG_CHAR_ENUM, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
OPCODE(SMSG_CHAR_DELETE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
OPCODE(CMSG_PLAYER_LOGIN, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandlePlayerLoginOpcode );
//OPCODE(SMSG_NEW_WORLD, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
OPCODE(SMSG_NEW_WORLD, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//OPCODE(SMSG_TRANSFER_PENDING, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//OPCODE(SMSG_TRANSFER_ABORTED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//OPCODE(SMSG_CHARACTER_LOGIN_FAILED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
@ -214,8 +214,8 @@ void InitializeOpcodes()
//OPCODE(CMSG_CHANNEL_UNBAN, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelUnbanOpcode );
//OPCODE(CMSG_CHANNEL_ANNOUNCEMENTS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelAnnouncementsOpcode);
//OPCODE(CMSG_CHANNEL_MODERATE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelModerateOpcode );
//OPCODE(SMSG_UPDATE_OBJECT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//OPCODE(SMSG_DESTROY_OBJECT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
OPCODE(SMSG_UPDATE_OBJECT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
OPCODE(SMSG_DESTROY_OBJECT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//OPCODE(CMSG_USE_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleUseItemOpcode );
//OPCODE(CMSG_OPEN_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleOpenItemOpcode );
//OPCODE(CMSG_READ_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleReadItemOpcode );
@ -242,7 +242,7 @@ void InitializeOpcodes()
//OPCODE(MSG_MOVE_SET_RUN_MODE, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
//OPCODE(MSG_MOVE_SET_WALK_MODE, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
//OPCODE(MSG_MOVE_TOGGLE_LOGGING, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
//OPCODE(MSG_MOVE_TELEPORT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
OPCODE(MSG_MOVE_TELEPORT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
//OPCODE(MSG_MOVE_TELEPORT_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
//OPCODE(MSG_MOVE_TELEPORT_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMoveTeleportAckOpcode );
//OPCODE(MSG_MOVE_TOGGLE_FALL_LOGGING, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );

View file

@ -101,7 +101,7 @@ enum Opcodes
SMSG_CHAR_ENUM = 0x10B0,
SMSG_CHAR_DELETE = 0x0304,
CMSG_PLAYER_LOGIN = 0x05B1,
SMSG_NEW_WORLD = 0x103F,
SMSG_NEW_WORLD = 0x79B1,
SMSG_TRANSFER_PENDING = 0x1040,
SMSG_TRANSFER_ABORTED = 0x1041,
SMSG_CHARACTER_LOGIN_FAILED = 0x1042,
@ -208,8 +208,8 @@ enum Opcodes
CMSG_CHANNEL_UNBAN = 0x10A7,
CMSG_CHANNEL_ANNOUNCEMENTS = 0x10A8,
CMSG_CHANNEL_MODERATE = 0x10A9,
SMSG_UPDATE_OBJECT = 0x10AA,
SMSG_DESTROY_OBJECT = 0x10AB,
SMSG_UPDATE_OBJECT = 0x4715,
SMSG_DESTROY_OBJECT = 0x4724,
CMSG_USE_ITEM = 0x10AC,
CMSG_OPEN_ITEM = 0x10AD,
CMSG_READ_ITEM = 0x10AE,
@ -236,7 +236,7 @@ enum Opcodes
MSG_MOVE_SET_RUN_MODE = 0x10C3,
MSG_MOVE_SET_WALK_MODE = 0x10C4,
MSG_MOVE_TOGGLE_LOGGING = 0x10C5,
MSG_MOVE_TELEPORT = 0x10C6,
MSG_MOVE_TELEPORT = 0x55A0,
MSG_MOVE_TELEPORT_CHEAT = 0x10C7,
MSG_MOVE_TELEPORT_ACK = 0x10C8,
MSG_MOVE_TOGGLE_FALL_LOGGING = 0x10C9,

View file

@ -1647,6 +1647,38 @@ uint8 Player::GetChatTag() const
return tag;
}
void Player::SendTeleportPacket(float oldX, float oldY, float oldZ, float oldO)
{
ObjectGuid guid = GetObjectGuid();
ObjectGuid transportGuid = m_movementInfo.GetTransportGuid();
WorldPacket data(MSG_MOVE_TELEPORT, 38);
data.WriteGuidMask<6, 0, 3, 2>(guid);
data.WriteBit(0); // unknown
data.WriteBit(!transportGuid.IsEmpty());
data.WriteGuidMask<1>(guid);
if (transportGuid)
data.WriteGuidMask<1, 3, 2, 5, 0, 7, 6, 4>(transportGuid);
data.WriteGuidMask<4, 7, 5>(guid);
if (transportGuid)
data.WriteGuidBytes<5, 6, 1, 7, 0, 2, 4, 3>(transportGuid);
data << uint32(0); // counter
data.WriteGuidBytes<1, 2, 3, 5>(guid);
data << float(GetPositionX());
data.WriteGuidBytes<4>(guid);
data << float(GetOrientation());
data.WriteGuidBytes<7>(guid);
data << float(GetPositionZ());
data.WriteGuidBytes<0, 6>(guid);
data << float(GetPositionY());
Relocate(oldX, oldY, oldZ, oldO);
SendDirectMessage(&data);
}
bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options)
{
if (!MapManager::IsValidMapCoord(mapid, x, y, z, orientation))
@ -1740,9 +1772,11 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
// near teleport, triggering send MSG_MOVE_TELEPORT_ACK from client at landing
if (!GetSession()->PlayerLogout())
{
WorldPacket data;
BuildTeleportAckMsg(data, x, y, z, orientation);
GetSession()->SendPacket(&data);
float oldX, oldY, oldZ;
float oldO = GetOrientation();
GetPosition(oldX, oldY, oldZ);;
Relocate(x, y, z, orientation);
SendTeleportPacket(oldX, oldY, oldZ, oldO);
}
}
else
@ -1812,12 +1846,14 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
{
// send transfer packet to display load screen
WorldPacket data(SMSG_TRANSFER_PENDING, (4 + 4 + 4));
data << uint32(mapid);
data.WriteBit(0); // unknown
if (m_transport)
{
data << uint32(m_transport->GetEntry());
data << uint32(GetMapId());
data << uint32(m_transport->GetEntry());
}
data << uint32(mapid);
GetSession()->SendPacket(&data);
}
@ -1851,23 +1887,27 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
if (!GetSession()->PlayerLogout())
{
// transfer finished, inform client to start load
WorldPacket data(SMSG_NEW_WORLD, (20));
data << uint32(mapid);
WorldPacket data(SMSG_NEW_WORLD, 20);
if (m_transport)
{
data << float(m_movementInfo.GetTransportPos()->x);
data << float(m_movementInfo.GetTransportPos()->y);
data << float(m_movementInfo.GetTransportPos()->z);
data << float(m_movementInfo.GetTransportPos()->o);
data << float(m_movementInfo.GetTransportPos()->z);
}
else
{
data << float(final_x);
data << float(final_y);
data << float(final_z);
data << float(final_o);
data << float(final_z);
}
data << uint32(mapid);
if (m_transport)
data << float(m_movementInfo.GetTransportPos()->y);
else
data << float(final_y);
GetSession()->SendPacket(&data);
SendSavedInstances();
}
@ -20817,7 +20857,7 @@ void Player::UpdateForQuestWorldObjects()
if (m_clientGUIDs.empty())
return;
UpdateData udata;
UpdateData udata(GetMapId());
WorldPacket packet;
for (GuidSet::const_iterator itr = m_clientGUIDs.begin(); itr != m_clientGUIDs.end(); ++itr)
{

View file

@ -1054,6 +1054,7 @@ class MANGOS_DLL_SPEC Player : public Unit
void AddToWorld() override;
void RemoveFromWorld() override;
void SendTeleportPacket(float oldX, float oldY, float oldZ, float oldO);
bool TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options = 0);
bool TeleportTo(WorldLocation const& loc, uint32 options = 0)

View file

@ -144,7 +144,7 @@ void MapManager::LoadTransports()
Transport::Transport() : GameObject()
{
m_updateFlag = (UPDATEFLAG_TRANSPORT | UPDATEFLAG_HIGHGUID | UPDATEFLAG_HAS_POSITION | UPDATEFLAG_ROTATION);
m_updateFlag = (UPDATEFLAG_TRANSPORT | UPDATEFLAG_HAS_POSITION | UPDATEFLAG_ROTATION);
}
bool Transport::Create(uint32 guidlow, uint32 mapid, float x, float y, float z, float ang, uint8 animprogress, uint16 dynamicHighValue)
@ -552,7 +552,7 @@ void Transport::UpdateForMap(Map const* targetMap)
{
if (this != itr->getSource()->GetTransport())
{
UpdateData transData;
UpdateData transData(itr->getSource()->GetMapId());
BuildCreateUpdateBlockForPlayer(&transData, itr->getSource());
WorldPacket packet;
transData.BuildPacket(&packet);
@ -562,7 +562,7 @@ void Transport::UpdateForMap(Map const* targetMap)
}
else
{
UpdateData transData;
UpdateData transData(GetMapId());
BuildOutOfRangeUpdateBlock(&transData);
WorldPacket out_packet;
transData.BuildPacket(&out_packet);

View file

@ -80,7 +80,8 @@ void MovementInfo::Read(ByteBuffer& data)
data >> pos.z;
data >> pos.o;
if (HasMovementFlag(MOVEFLAG_ONTRANSPORT))
// comment, anyway movementInfo read/write system will be reimplemented soon
//if (HasMovementFlag(MOVEFLAG_ONTRANSPORT))
{
data >> t_guid.ReadAsPacked();
data >> t_pos.x;
@ -111,7 +112,7 @@ void MovementInfo::Read(ByteBuffer& data)
if (HasMovementFlag(MOVEFLAG_SPLINE_ELEVATION))
{
data >> u_unk1;
data >> splineElevation;
}
}
@ -125,7 +126,8 @@ void MovementInfo::Write(ByteBuffer& data) const
data << pos.z;
data << pos.o;
if (HasMovementFlag(MOVEFLAG_ONTRANSPORT))
// comment, anyway movementInfo read/write system will be reimplemented soon
//if (HasMovementFlag(MOVEFLAG_ONTRANSPORT))
{
data << t_guid.WriteAsPacked();
data << t_pos.x;
@ -156,7 +158,7 @@ void MovementInfo::Write(ByteBuffer& data) const
if (HasMovementFlag(MOVEFLAG_SPLINE_ELEVATION))
{
data << u_unk1;
data << splineElevation;
}
}
@ -191,7 +193,7 @@ Unit::Unit() :
m_objectType |= TYPEMASK_UNIT;
m_objectTypeId = TYPEID_UNIT;
m_updateFlag = (UPDATEFLAG_HIGHGUID | UPDATEFLAG_LIVING | UPDATEFLAG_HAS_POSITION);
m_updateFlag = UPDATEFLAG_LIVING;
m_attackTimer[BASE_ATTACK] = 0;
m_attackTimer[OFF_ATTACK] = 0;
@ -11040,6 +11042,11 @@ void Unit::UpdateSplineMovement(uint32 t_diff)
void Unit::DisableSpline()
{
m_movementInfo.RemoveMovementFlag(MovementFlags(MOVEFLAG_SPLINE_ENABLED | MOVEFLAG_FORWARD));
m_movementInfo.RemoveMovementFlag(MOVEFLAG_FORWARD);
movespline->_Interrupt();
}
bool Unit::IsSplineEnabled() const
{
return !movespline->Finalized();
}

View file

@ -611,28 +611,27 @@ enum MovementFlags
MOVEFLAG_PITCH_UP = 0x00000040,
MOVEFLAG_PITCH_DOWN = 0x00000080,
MOVEFLAG_WALK_MODE = 0x00000100, // Walking
MOVEFLAG_ONTRANSPORT = 0x00000200,
MOVEFLAG_LEVITATING = 0x00000400,
MOVEFLAG_ROOT = 0x00000800,
MOVEFLAG_FALLING = 0x00001000,
MOVEFLAG_FALLINGFAR = 0x00002000,
MOVEFLAG_PENDINGSTOP = 0x00004000,
MOVEFLAG_PENDINGSTRAFESTOP = 0x00008000,
MOVEFLAG_PENDINGFORWARD = 0x00010000,
MOVEFLAG_PENDINGBACKWARD = 0x00020000,
MOVEFLAG_PENDINGSTRAFELEFT = 0x00040000,
MOVEFLAG_PENDINGSTRAFERIGHT = 0x00080000,
MOVEFLAG_PENDINGROOT = 0x00100000,
MOVEFLAG_SWIMMING = 0x00200000, // appears with fly flag also
MOVEFLAG_ASCENDING = 0x00400000, // swim up also
MOVEFLAG_DESCENDING = 0x00800000, // swim down also
MOVEFLAG_CAN_FLY = 0x01000000, // can fly in 3.3?
MOVEFLAG_FLYING = 0x02000000, // Actual flying mode
MOVEFLAG_SPLINE_ELEVATION = 0x04000000, // used for flight paths
MOVEFLAG_SPLINE_ENABLED = 0x08000000, // used for flight paths
MOVEFLAG_WATERWALKING = 0x10000000, // prevent unit from falling through water
MOVEFLAG_SAFE_FALL = 0x20000000, // active rogue safe fall spell (passive)
MOVEFLAG_HOVER = 0x40000000
MOVEFLAG_LEVITATING = 0x00000200,
MOVEFLAG_ROOT = 0x00000400,
MOVEFLAG_FALLING = 0x00000800,
MOVEFLAG_FALLINGFAR = 0x00001000,
MOVEFLAG_PENDINGSTOP = 0x00002000,
MOVEFLAG_PENDINGSTRAFESTOP = 0x00004000,
MOVEFLAG_PENDINGFORWARD = 0x00008000,
MOVEFLAG_PENDINGBACKWARD = 0x00010000,
MOVEFLAG_PENDINGSTRAFELEFT = 0x00020000,
MOVEFLAG_PENDINGSTRAFERIGHT = 0x00040000,
MOVEFLAG_PENDINGROOT = 0x00080000,
MOVEFLAG_SWIMMING = 0x00100000, // appears with fly flag also
MOVEFLAG_ASCENDING = 0x00200000, // swim up also
MOVEFLAG_DESCENDING = 0x00400000, // swim down also
MOVEFLAG_CAN_FLY = 0x00800000, // can fly in 3.3?
MOVEFLAG_FLYING = 0x01000000, // Actual flying mode
MOVEFLAG_SPLINE_ELEVATION = 0x02000000, // used for flight paths
MOVEFLAG_WATERWALKING = 0x04000000, // prevent unit from falling through water
MOVEFLAG_SAFE_FALL = 0x08000000, // active rogue safe fall spell (passive)
MOVEFLAG_HOVER = 0x10000000,
MOVEFLAG_LOCAL_DIRTY = 0x20000000,
};
// flags that use in movement check for example at spell casting
@ -673,7 +672,7 @@ class MovementInfo
{
public:
MovementInfo() : moveFlags(MOVEFLAG_NONE), moveFlags2(MOVEFLAG2_NONE), time(0),
t_time(0), t_seat(-1), t_time2(0), s_pitch(0.0f), fallTime(0), u_unk1(0.0f) {}
t_time(0), t_seat(-1), t_time2(0), s_pitch(0.0f), fallTime(0), splineElevation(0.0f) {}
// Read/Write methods
void Read(ByteBuffer& data);
@ -725,6 +724,9 @@ class MovementInfo
};
JumpInfo const& GetJumpInfo() const { return jump; }
float GetSplineElevation() const { return splineElevation; }
float GetPitch() const { return s_pitch; }
private:
// common
uint32 moveFlags; // see enum MovementFlags
@ -744,7 +746,7 @@ class MovementInfo
// jumping
JumpInfo jump;
// spline
float u_unk1;
float splineElevation;
};
inline ByteBuffer& operator<< (ByteBuffer& buf, MovementInfo const& mi)
@ -1913,6 +1915,8 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
bool IsLinkingEventTrigger() const { return m_isCreatureLinkingTrigger; }
bool IsSplineEnabled() const;
protected:
explicit Unit();

View file

@ -26,7 +26,7 @@
#include "ObjectGuid.h"
#include <zlib/zlib.h>
UpdateData::UpdateData() : m_blockCount(0)
UpdateData::UpdateData(uint16 map) : m_blockCount(0), m_map(map)
{
}
@ -108,12 +108,13 @@ bool UpdateData::BuildPacket(WorldPacket* packet)
ByteBuffer buf(4 + (m_outOfRangeGUIDs.empty() ? 0 : 1 + 4 + 9 * m_outOfRangeGUIDs.size()) + m_data.wpos());
buf << (uint32)(!m_outOfRangeGUIDs.empty() ? m_blockCount + 1 : m_blockCount);
buf << uint16(m_map);
buf << uint32(!m_outOfRangeGUIDs.empty() ? m_blockCount + 1 : m_blockCount);
if (!m_outOfRangeGUIDs.empty())
{
buf << (uint8) UPDATETYPE_OUT_OF_RANGE_OBJECTS;
buf << (uint32) m_outOfRangeGUIDs.size();
buf << uint8(UPDATETYPE_OUT_OF_RANGE_OBJECTS);
buf << uint32(m_outOfRangeGUIDs.size());
for (GuidSet::const_iterator i = m_outOfRangeGUIDs.begin(); i != m_outOfRangeGUIDs.end(); ++i)
buf << i->WriteAsPacked();
@ -123,20 +124,20 @@ bool UpdateData::BuildPacket(WorldPacket* packet)
size_t pSize = buf.wpos(); // use real used data size
if (pSize > 100) // compress large packets
{
uint32 destsize = compressBound(pSize);
packet->resize(destsize + sizeof(uint32));
//if (pSize > 100) // compress large packets
//{
// uint32 destsize = compressBound(pSize);
// packet->resize(destsize + sizeof(uint32));
packet->put<uint32>(0, pSize);
Compress(const_cast<uint8*>(packet->contents()) + sizeof(uint32), &destsize, (void*)buf.contents(), pSize);
if (destsize == 0)
return false;
// packet->put<uint32>(0, pSize);
// Compress(const_cast<uint8*>(packet->contents()) + sizeof(uint32), &destsize, (void*)buf.contents(), pSize);
// if (destsize == 0)
// return false;
packet->resize(destsize + sizeof(uint32));
packet->SetOpcode(SMSG_COMPRESSED_UPDATE_OBJECT);
}
else // send small packets without compression
// packet->resize(destsize + sizeof(uint32));
// packet->SetOpcode(SMSG_COMPRESSED_UPDATE_OBJECT);
//}
//else // send small packets without compression
{
packet->append(buf);
packet->SetOpcode(SMSG_UPDATE_OBJECT);
@ -150,4 +151,5 @@ void UpdateData::Clear()
m_data.clear();
m_outOfRangeGUIDs.clear();
m_blockCount = 0;
m_map = 0;
}

View file

@ -27,11 +27,9 @@ class WorldPacket;
enum ObjectUpdateType
{
UPDATETYPE_VALUES = 0,
UPDATETYPE_MOVEMENT = 1,
UPDATETYPE_CREATE_OBJECT = 2,
UPDATETYPE_CREATE_OBJECT2 = 3,
UPDATETYPE_OUT_OF_RANGE_OBJECTS = 4,
UPDATETYPE_NEAR_OBJECTS = 5
UPDATETYPE_CREATE_OBJECT = 1,
UPDATETYPE_CREATE_OBJECT2 = 2,
UPDATETYPE_OUT_OF_RANGE_OBJECTS = 3,
};
enum ObjectUpdateFlags
@ -40,19 +38,24 @@ enum ObjectUpdateFlags
UPDATEFLAG_SELF = 0x0001,
UPDATEFLAG_TRANSPORT = 0x0002,
UPDATEFLAG_HAS_ATTACKING_TARGET = 0x0004,
UPDATEFLAG_LOWGUID = 0x0008,
UPDATEFLAG_HIGHGUID = 0x0010,
UPDATEFLAG_UNK = 0x0008,
UPDATEFLAG_LOW = 0x0010,
UPDATEFLAG_LIVING = 0x0020,
UPDATEFLAG_HAS_POSITION = 0x0040,
UPDATEFLAG_VEHICLE = 0x0080,
UPDATEFLAG_POSITION = 0x0100,
UPDATEFLAG_ROTATION = 0x0200
UPDATEFLAG_ROTATION = 0x0200,
UPDATEFLAG_UNK1 = 0x0400,
UPDATEFLAG_ANIM_KITS = 0x0800,
UPDATEFLAG_TRANSPORT_ARR = 0x1000,
UPDATEFLAG_ENABLE_PORTALS = 0x2000,
UPDATEFLAG_UNK2 = 0x4000,
};
class UpdateData
{
public:
UpdateData();
UpdateData(uint16 mapId);
void AddOutOfRangeGUID(GuidSet& guids);
void AddOutOfRangeGUID(ObjectGuid const& guid);
@ -64,6 +67,7 @@ class UpdateData
GuidSet const& GetOutOfRangeGUIDs() const { return m_outOfRangeGUIDs; }
protected:
uint16 m_map;
uint32 m_blockCount;
GuidSet m_outOfRangeGUIDs;
ByteBuffer m_data;

View file

@ -177,7 +177,7 @@ namespace Movement
// init parabolic / animation
// spline initialized, duration known and i able to compute parabolic acceleration
if (args.flags & (MoveSplineFlag::Parabolic | MoveSplineFlag::Animation))
if (args.flags & (MoveSplineFlag::Trajectory | MoveSplineFlag::Animation))
{
effect_start_time = Duration() * args.time_perc;
if (args.flags.parabolic && effect_start_time < Duration())
@ -205,7 +205,7 @@ namespace Movement
return false;\
}
CHECK(path.size() > 1);
CHECK(velocity > 0.f);
CHECK(velocity > 0.1f);
CHECK(time_perc >= 0.f && time_perc <= 1.f);
// CHECK(_checkPathBounds());
return true;

View file

@ -35,47 +35,51 @@ namespace Movement
public:
enum eFlags
{
None = 0x00000000,
// x00-xFF(first byte) used as animation Ids storage in pair with Animation flag
Done = 0x00000100,
Falling = 0x00000200, // Affects elevation computation, can't be combined with Parabolic flag
No_Spline = 0x00000400,
Parabolic = 0x00000800, // Affects elevation computation, can't be combined with Falling flag
Walkmode = 0x00001000,
Flying = 0x00002000, // Smooth movement(Catmullrom interpolation mode), flying animation
OrientationFixed = 0x00004000, // Model orientation fixed
Final_Point = 0x00008000,
Final_Target = 0x00010000,
Final_Angle = 0x00020000,
Catmullrom = 0x00040000, // Used Catmullrom interpolation mode
Cyclic = 0x00080000, // Movement by cycled spline
Enter_Cycle = 0x00100000, // Everytimes appears with cyclic flag in monster move packet, erases first spline vertex after first cycle done
Animation = 0x00200000, // Plays animation after some time passed
Frozen = 0x00400000, // Will never arrive
Unknown5 = 0x00800000,
Unknown6 = 0x01000000,
Unknown7 = 0x02000000,
Unknown8 = 0x04000000,
OrientationInversed = 0x08000000,
Unknown10 = 0x10000000,
Unknown11 = 0x20000000,
Unknown12 = 0x40000000,
Unknown13 = 0x80000000,
None = 0x00000000,
// x00-xF(first byte) used as animation Ids storage in pair with Animation flag
Unknown1 = 0x00000010, // NOT VERIFIED
Done = 0x00000020,
Falling = 0x00000040, // Affects elevation computation, can't be combined with Trajectory flag
No_Spline = 0x00000080,
Unknown2 = 0x00000100, // NOT VERIFIED
Flying = 0x00000200, // Smooth movement(Catmullrom interpolation mode), flying animation
OrientationFixed = 0x00000400, // Model orientation fixed
Catmullrom = 0x00000800, // Used Catmullrom interpolation mode
Cyclic = 0x00001000, // Movement by cycled spline
Enter_Cycle = 0x00002000, // Everytimes appears with cyclic flag in monster move packet, erases first spline vertex after first cycle done
Frozen = 0x00004000, // Will never arrive
TransportEnter = 0x00008000,
TransportExit = 0x00010000,
Unknown3 = 0x00020000, // NOT VERIFIED
Unknown4 = 0x00040000, // NOT VERIFIED
OrientationInversed = 0x00080000,
Unknown5 = 0x00100000, // NOT VERIFIED
Walkmode = 0x00200000,
UncompressedPath = 0x00400000,
Unknown6 = 0x00800000, // NOT VERIFIED
Animation = 0x01000000, // Plays animation after some time passed
Trajectory = 0x02000000, // Affects elevation computation, can't be combined with Falling flag
Final_Point = 0x04000000,
Final_Target = 0x08000000,
Final_Angle = 0x10000000,
Unknown7 = 0x20000000, // NOT VERIFIED
Unknown8 = 0x40000000, // NOT VERIFIED
Unknown9 = 0x80000000, // NOT VERIFIED
// Masks
Mask_Final_Facing = Final_Point | Final_Target | Final_Angle,
// animation ids stored here, see AnimType enum, used with Animation flag
Mask_Animations = 0xFF,
Mask_Animations = 0xF,
// flags that shouldn't be appended into SMSG_MONSTER_MOVE\SMSG_MONSTER_MOVE_TRANSPORT packet, should be more probably
Mask_No_Monster_Move = Mask_Final_Facing | Mask_Animations | Done,
// CatmullRom interpolation mode used
Mask_CatmullRom = Flying | Catmullrom,
Mask_CatmullRom = Catmullrom,
// Unused, not suported flags
Mask_Unused = No_Spline | Enter_Cycle | Frozen | Unknown5 | Unknown6 | Unknown7 | Unknown8 | Unknown10 | Unknown11 | Unknown12 | Unknown13,
Mask_Unused = No_Spline | Enter_Cycle | Frozen | UncompressedPath | Unknown1 | Unknown2 | Unknown3 | Unknown4 | Unknown5 | Unknown6 | Unknown7 | Unknown8 | Unknown9,
};
inline uint32& raw() { return (uint32&) * this;}
inline const uint32& raw() const { return (const uint32&) * this;}
inline uint32& raw() { return (uint32&)*this;}
inline const uint32& raw() const { return (const uint32&)*this;}
MoveSplineFlag() { raw() = 0; }
MoveSplineFlag(uint32 f) { raw() = f; }
@ -99,40 +103,46 @@ namespace Movement
void operator &= (uint32 f) { raw() &= f;}
void operator |= (uint32 f) { raw() |= f;}
void EnableAnimation(uint8 anim) { raw() = (raw() & ~(Mask_Animations | Falling | Parabolic)) | Animation | anim;}
void EnableParabolic() { raw() = (raw() & ~(Mask_Animations | Falling | Animation)) | Parabolic;}
void EnableFalling() { raw() = (raw() & ~(Mask_Animations | Parabolic | Animation)) | Falling;}
void EnableAnimation(uint8 anim) { raw() = (raw() & ~(Mask_Animations | Falling | Trajectory)) | Animation | anim;}
void EnableParabolic() { raw() = (raw() & ~(Mask_Animations | Falling | Animation)) | Trajectory;}
void EnableFalling() { raw() = (raw() & ~(Mask_Animations | Trajectory | Animation))| Falling;}
void EnableFlying() { raw() = (raw() & ~Catmullrom) | Flying; }
void EnableCatmullRom() { raw() = (raw() & ~Flying) | Catmullrom; }
void EnableFacingPoint() { raw() = (raw() & ~Mask_Final_Facing) | Final_Point;}
void EnableFacingAngle() { raw() = (raw() & ~Mask_Final_Facing) | Final_Angle;}
void EnableFacingTarget() { raw() = (raw() & ~Mask_Final_Facing) | Final_Target;}
void EnableTransportEnter() { raw() = (raw() & ~TransportExit) | TransportEnter; }
void EnableTransportExit() { raw() = (raw() & ~TransportEnter) | TransportExit; }
uint8 animId : 8;
bool done : 1;
bool falling : 1;
bool no_spline : 1;
bool parabolic : 1;
bool walkmode : 1;
bool flying : 1;
bool orientationFixed : 1;
bool final_point : 1;
bool final_target : 1;
bool final_angle : 1;
bool catmullrom : 1;
bool cyclic : 1;
bool enter_cycle : 1;
bool animation : 1;
bool frozen : 1;
bool unknown5 : 1;
bool unknown6 : 1;
bool unknown7 : 1;
bool unknown8 : 1;
uint8 animId : 4;
bool unknown1 : 1;
bool done : 1;
bool falling : 1;
bool no_spline : 1;
bool unknown2 : 1;
bool flying : 1;
bool orientationFixed : 1;
bool catmullrom : 1;
bool cyclic : 1;
bool enter_cycle : 1;
bool frozen : 1;
bool transportEnter : 1;
bool transportExit : 1;
bool unknown3 : 1;
bool unknown4 : 1;
bool orientationInversed : 1;
bool unknown10 : 1;
bool unknown11 : 1;
bool unknown12 : 1;
bool unknown13 : 1;
bool unknown5 : 1;
bool walkmode : 1;
bool uncompressedPath : 1;
bool unknown6 : 1;
bool animation : 1;
bool parabolic : 1;
bool final_point : 1;
bool final_target : 1;
bool final_angle : 1;
bool unknown7 : 1;
bool unknown8 : 1;
bool unknown9 : 1;
};
#if defined( __GNUC__ )
#pragma pack()

View file

@ -76,7 +76,7 @@ namespace Movement
else
moveFlags &= ~MOVEFLAG_WALK_MODE;
moveFlags |= (MOVEFLAG_SPLINE_ENABLED | MOVEFLAG_FORWARD);
moveFlags |= MOVEFLAG_FORWARD;
if (args.velocity == 0.f)
args.velocity = unit.GetSpeed(SelectSpeedType(moveFlags));

View file

@ -19,6 +19,7 @@
#include "packet_builder.h"
#include "MoveSpline.h"
#include "WorldPacket.h"
#include "../Creature.h"
namespace Movement
{
@ -146,44 +147,85 @@ namespace Movement
WriteLinearPath(spline, data);
}
void PacketBuilder::WriteCreate(const MoveSpline& move_spline, ByteBuffer& data)
void PacketBuilder::WriteCreateBits(const MoveSpline& move_spline, ByteBuffer& data)
{
// WriteClientStatus(mov,data);
// data.append<float>(&mov.m_float_values[SpeedWalk], SpeedMaxCount);
// if (mov.SplineEnabled())
MoveSplineFlag splineFlags = move_spline.splineflags;
uint32 nodes = move_spline.getPath().size();
bool hasSplineStartTime = move_spline.splineflags & (MoveSplineFlag::Trajectory | MoveSplineFlag::Animation);
bool hasSplineVerticalAcceleration = (move_spline.splineflags & MoveSplineFlag::Trajectory) && move_spline.effect_start_time < move_spline.Duration();
data.WriteBits(uint8(move_spline.spline.mode()), 2);
data.WriteBit(hasSplineStartTime);
data.WriteBits(nodes, 22);
switch (move_spline.splineflags & MoveSplineFlag::Mask_Final_Facing)
{
MoveSplineFlag splineFlags = move_spline.splineflags;
data << splineFlags.raw();
if (splineFlags.final_angle)
case MoveSplineFlag::Final_Target:
{
data << move_spline.facing.angle;
data.WriteBits(2, 2);
data.WriteGuidMask<4, 3, 7, 2, 6, 1, 0, 5>(ObjectGuid(move_spline.facing.target));
break;
}
else if (splineFlags.final_target)
{
data << move_spline.facing.target;
}
else if (splineFlags.final_point)
{
data << move_spline.facing.f.x << move_spline.facing.f.y << move_spline.facing.f.z;
}
data << move_spline.timePassed();
data << move_spline.Duration();
data << move_spline.GetId();
data << float(1.f); // splineInfo.duration_mod; added in 3.1
data << float(1.f); // splineInfo.duration_mod_next; added in 3.1
data << move_spline.vertical_acceleration; // added in 3.1
data << move_spline.effect_start_time; // added in 3.1
uint32 nodes = move_spline.getPath().size();
data << nodes;
data.append<Vector3>(&move_spline.getPath()[0], nodes);
data << uint8(move_spline.spline.mode()); // added in 3.1
data << (move_spline.isCyclic() ? Vector3::zero() : move_spline.FinalDestination());
case MoveSplineFlag::Final_Angle:
data.WriteBits(0, 2);
break;
case MoveSplineFlag::Final_Point:
data.WriteBits(1, 2);
break;
default:
data.WriteBits(3, 2);
break;
}
data.WriteBit(hasSplineVerticalAcceleration);
data.WriteBits(move_spline.splineflags.raw(), 25);
}
void PacketBuilder::WriteCreateBytes(const MoveSpline& move_spline, ByteBuffer& data)
{
MoveSplineFlag splineFlags = move_spline.splineflags;
uint32 nodes = move_spline.getPath().size();
bool hasSplineStartTime = move_spline.splineflags & (MoveSplineFlag::Trajectory | MoveSplineFlag::Animation);
bool hasSplineVerticalAcceleration = (move_spline.splineflags & MoveSplineFlag::Trajectory) && move_spline.effect_start_time < move_spline.Duration();
if (hasSplineVerticalAcceleration)
data << move_spline.vertical_acceleration; // added in 3.1
data << move_spline.timePassed();
if (move_spline.splineflags & MoveSplineFlag::Final_Angle)
data << move_spline.facing.angle;
else if (move_spline.splineflags & MoveSplineFlag::Final_Target)
data.WriteGuidBytes<5, 3, 7, 1, 6, 4, 2, 0>(ObjectGuid(move_spline.facing.target));
for (uint32 i = 0; i < nodes; ++i)
{
data << move_spline.getPath()[i].z;
data << move_spline.getPath()[i].x;
data << move_spline.getPath()[i].y;
}
if (move_spline.splineflags & MoveSplineFlag::Final_Point)
data << move_spline.facing.f.x << move_spline.facing.f.z << move_spline.facing.f.y;
data << float(1.f);
data << move_spline.Duration();
if (hasSplineStartTime)
data << move_spline.effect_start_time; // added in 3.1
data << float(1.f);
if (!move_spline.isCyclic())
{
Vector3 dest = move_spline.FinalDestination();
data << float(dest.z);
data << float(dest.x);
data << float(dest.y);
}
else
data << Vector3::zero();
data << move_spline.GetId();
}
}

View file

@ -31,7 +31,8 @@ namespace Movement
public:
static void WriteMonsterMove(const MoveSpline& mov, WorldPacket& data);
static void WriteCreate(const MoveSpline& mov, ByteBuffer& data);
static void WriteCreateBits(const MoveSpline& mov, ByteBuffer& data);
static void WriteCreateBytes(const MoveSpline& mov, ByteBuffer& data);
};
}
#endif // MANGOSSERVER_PACKET_BUILDER_H

View file

@ -112,31 +112,29 @@ namespace Movement
STR(Pitch_Down), // 0x00000080,
STR(Walk), // 0x00000100, // Walking
STR(Ontransport), // 0x00000200,
STR(Levitation), // 0x00000400,
STR(Root), // 0x00000800,
STR(Falling), // 0x00001000,
STR(Fallingfar), // 0x00002000,
STR(Pendingstop), // 0x00004000,
STR(PendingSTRafestop), // 0x00008000,
STR(Pendingforward), // 0x00010000,
STR(Pendingbackward), // 0x00020000,
STR(PendingSTRafeleft), // 0x00040000,
STR(PendingSTRaferight), // 0x00080000,
STR(Pendingroot), // 0x00100000,
STR(Swimming), // 0x00200000, // Appears With Fly Flag Also
STR(Ascending), // 0x00400000, // Swim Up Also
STR(Descending), // 0x00800000, // Swim Down Also
STR(Can_Fly), // 0x01000000, // Can Fly In 3.3?
STR(Flying), // 0x02000000, // Actual Flying Mode
STR(Spline_Elevation), // 0x04000000, // Used For Flight Paths
STR(Spline_Enabled), // 0x08000000, // Used For Flight Paths
STR(Waterwalking), // 0x10000000, // Prevent Unit From Falling Through Water
STR(Safe_Fall), // 0x20000000, // Active Rogue Safe Fall Spell (Passive)
STR(Hover), // 0x40000000
STR(Unknown13), // 0x80000000
STR(Unk1),
STR(Unk2),
STR(Levitation), // 0x00000200,
STR(Root), // 0x00000400,
STR(Falling), // 0x00000800,
STR(Fallingfar), // 0x00001000,
STR(Pendingstop), // 0x00002000,
STR(PendingSTRafestop), // 0x00004000,
STR(Pendingforward), // 0x00008000,
STR(Pendingbackward), // 0x00010000,
STR(PendingSTRafeleft), // 0x00020000,
STR(PendingSTRaferight), // 0x00040000,
STR(Pendingroot), // 0x00080000,
STR(Swimming), // 0x00100000, // Appears With Fly Flag Also
STR(Ascending), // 0x00200000, // Swim Up Also
STR(Descending), // 0x00400000, // Swim Down Also
STR(Can_Fly), // 0x00800000, // Can Fly In 3.3?
STR(Flying), // 0x01000000, // Actual Flying Mode
STR(Spline_Elevation), // 0x02000000, // Used For Flight Paths
STR(Waterwalking), // 0x04000000, // Prevent Unit From Falling Through Water
STR(Safe_Fall), // 0x08000000, // Active Rogue Safe Fall Spell (Passive)
STR(Hover), // 0x10000000,
STR(Unknown11), // 0x20000000
STR(NoStrafe),
STR(NoJumping),
STR(Unk3),
STR(Fullspeedturning),
STR(Fullspeedpitching),
@ -159,34 +157,34 @@ namespace Movement
STR(AnimBit2), // 0x00000002,
STR(AnimBit3), // 0x00000004,
STR(AnimBit4), // 0x00000008,
STR(AnimBit5), // 0x00000010,
STR(AnimBit6), // 0x00000020,
STR(AnimBit7), // 0x00000040,
STR(AnimBit8), // 0x00000080,
STR(Done), // 0x00000100,
STR(Falling), // 0x00000200, // Not Compartible With Trajectory Movement
STR(No_Spline), // 0x00000400,
STR(Trajectory), // 0x00000800, // Not Compartible With Fall Movement
STR(Walkmode), // 0x00001000,
STR(Flying), // 0x00002000, // Smooth Movement(Catmullrom Interpolation Mode), Flying Animation
STR(Knockback), // 0x00004000, // Model Orientation Fixed
STR(Final_Point), // 0x00008000,
STR(Final_Target), // 0x00010000,
STR(Final_Angle), // 0x00020000,
STR(Catmullrom), // 0x00040000, // Used Catmullrom Interpolation Mode
STR(Cyclic), // 0x00080000, // Movement By Cycled Spline
STR(Enter_Cycle), // 0x00100000, // Everytime Appears With Cyclic Flag In Monster Move Packet
STR(Animation), // 0x00200000, // Animationid (0...3), Uint32 Time, Not Compartible With Trajectory And Fall Movement
STR(Unknown4), // 0x00400000, // Disables Movement By Path
STR(Unknown5), // 0x00800000,
STR(Unknown6), // 0x01000000,
STR(Unknown7), // 0x02000000,
STR(Unknown8), // 0x04000000,
STR(OrientationInversed), // 0x08000000, // Appears With Runmode Flag, Nodes ),// 1, Handles Orientation
STR(Unknown10), // 0x10000000,
STR(Unknown11), // 0x20000000,
STR(Unknown12), // 0x40000000,
STR(Unknown13), // 0x80000000,
STR(Unknown1), // 0x00000010,
STR(Done), // 0x00000020,
STR(Falling), // 0x00000040, // Not Compartible With Trajectory Movement
STR(No_Spline), // 0x00000080,
STR(Unknown2), // 0x00000100,
STR(Flying), // 0x00000200, // Smooth Movement(Catmullrom Interpolation Mode), Flying Animation
STR(Knockback), // 0x00000400, // Model Orientation Fixed
STR(Catmullrom), // 0x00000800, // Used Catmullrom Interpolation Mode
STR(Cyclic), // 0x00001000, // Movement By Cycled Spline
STR(Enter_Cycle), // 0x00002000, // Everytime Appears With Cyclic Flag In Monster Move Packet
STR(Frozen), // 0x00004000,
STR(TransportEnter),// 0x00008000
STR(TransportExit),// 0x00010000,
STR(Unknown3), // 0x00020000,
STR(Unknown4), // 0x00040000,
STR(OrientationInversed), // 0x00080000, // Appears With Runmode Flag, Nodes ),// 1, Handles Orientation
STR(Unknown5), // 0x00100000
STR(Walkmode), // 0x00200000,
STR(UncompressedPath), // 0x00400000
STR(Unknown6), // 0x00800000
STR(Animation), // 0x01000000, // Animationid (0...3), Uint32 Time, Not Compartible With Trajectory And Fall Movement
STR(Trajectory), // 0x02000000, // Not Compartible With Fall Movement
STR(Final_Point), // 0x04000000,
STR(Final_Target), // 0x08000000,
STR(Final_Angle), // 0x10000000,
STR(Unknown7), // 0x20000000,
STR(Unknown8), // 0x40000000,
STR(Unknown9), // 0x80000000,
};
template<class Flags, int N>