From f7cd8ce52ab4028c87939b94f6cde57bf74f974b Mon Sep 17 00:00:00 2001 From: Yaki Khadafi Date: Sun, 5 Aug 2012 22:46:48 +0300 Subject: [PATCH] Fix SMSG_UPDATE_OBJECT, SMSG_DESTROY_OBJECT, and some teleport opcodes Authors: Strawberry, Trinity, me Signed-off-by: Yaki Khadafi --- src/game/Corpse.cpp | 2 +- src/game/DynamicObject.cpp | 2 +- src/game/GameObject.cpp | 2 +- src/game/GridNotifiers.h | 2 +- src/game/Item.cpp | 2 +- src/game/Map.cpp | 6 +- src/game/MovementHandler.cpp | 6 +- src/game/Object.cpp | 382 ++++++++++++++++----------- src/game/Object.h | 1 - src/game/Opcodes.cpp | 8 +- src/game/Opcodes.h | 8 +- src/game/Player.cpp | 64 ++++- src/game/Player.h | 1 + src/game/Transports.cpp | 6 +- src/game/Unit.cpp | 19 +- src/game/Unit.h | 52 ++-- src/game/UpdateData.cpp | 34 +-- src/game/UpdateData.h | 22 +- src/game/movement/MoveSpline.cpp | 4 +- src/game/movement/MoveSplineFlag.h | 126 +++++---- src/game/movement/MoveSplineInit.cpp | 2 +- src/game/movement/packet_builder.cpp | 110 +++++--- src/game/movement/packet_builder.h | 3 +- src/game/movement/util.cpp | 104 ++++---- 24 files changed, 578 insertions(+), 390 deletions(-) diff --git a/src/game/Corpse.cpp b/src/game/Corpse.cpp index ed87495f8..94bfb2bac 100644 --- a/src/game/Corpse.cpp +++ b/src/game/Corpse.cpp @@ -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; diff --git a/src/game/DynamicObject.cpp b/src/game/DynamicObject.cpp index 7fbd85f86..18e98d7e6 100644 --- a/src/game/DynamicObject.cpp +++ b/src/game/DynamicObject.cpp @@ -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; } diff --git a/src/game/GameObject.cpp b/src/game/GameObject.cpp index c0bf88588..f68643cf6 100644 --- a/src/game/GameObject.cpp +++ b/src/game/GameObject.cpp @@ -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; diff --git a/src/game/GridNotifiers.h b/src/game/GridNotifiers.h index b2685c626..b0ec917d5 100644 --- a/src/game/GridNotifiers.h +++ b/src/game/GridNotifiers.h @@ -39,7 +39,7 @@ namespace MaNGOS GuidSet i_clientGUIDs; std::set 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 void Visit(GridRefManager& m); void Visit(CameraMapType& /*m*/) {} void Notify(void); diff --git a/src/game/Item.cpp b/src/game/Item.cpp index 96dbbcfc8..f0e7ef926 100644 --- a/src/game/Item.cpp +++ b/src/game/Item.cpp @@ -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; diff --git a/src/game/Map.cpp b/src/game/Map.cpp index 41dd6c3d5..f79c6c665 100644 --- a/src/game/Map.cpp +++ b/src/game/Map.cpp @@ -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()]; diff --git a/src/game/MovementHandler.cpp b/src/game/MovementHandler.cpp index 58fea3b34..fd391f2f5 100644 --- a/src/game/MovementHandler.cpp +++ b/src/game/MovementHandler.cpp @@ -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()) diff --git a/src/game/Object.cpp b/src/game/Object.cpp index aaab621d9..5599330ac 100644 --- a/src/game/Object.cpp +++ b/src/game/Object.cpp @@ -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 p = update_players.insert(UpdateDataMapType::value_type(pl, UpdateData())); + std::pair p = update_players.insert(UpdateDataMapType::value_type(pl, UpdateData(pl->GetMapId()))); MANGOS_ASSERT(p.second); iter = p.first; } diff --git a/src/game/Object.h b/src/game/Object.h index 450fc5fe1..87728f22d 100644 --- a/src/game/Object.h +++ b/src/game/Object.h @@ -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; diff --git a/src/game/Opcodes.cpp b/src/game/Opcodes.cpp index ddc65eb43..d924abc99 100644 --- a/src/game/Opcodes.cpp +++ b/src/game/Opcodes.cpp @@ -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 ); diff --git a/src/game/Opcodes.h b/src/game/Opcodes.h index f5a6b334e..73766e110 100644 --- a/src/game/Opcodes.h +++ b/src/game/Opcodes.h @@ -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, diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 83c5710c2..e6916e4f2 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -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) { diff --git a/src/game/Player.h b/src/game/Player.h index 7170295cb..786f63a9b 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -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) diff --git a/src/game/Transports.cpp b/src/game/Transports.cpp index 5bd9fb9f0..acd2a3d82 100644 --- a/src/game/Transports.cpp +++ b/src/game/Transports.cpp @@ -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); diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 83e889253..d059b24c0 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -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(); +} diff --git a/src/game/Unit.h b/src/game/Unit.h index 7c41f94db..e10cdca6d 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -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(); diff --git a/src/game/UpdateData.cpp b/src/game/UpdateData.cpp index d4a24d9ce..d69337b7a 100644 --- a/src/game/UpdateData.cpp +++ b/src/game/UpdateData.cpp @@ -26,7 +26,7 @@ #include "ObjectGuid.h" #include -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(0, pSize); - Compress(const_cast(packet->contents()) + sizeof(uint32), &destsize, (void*)buf.contents(), pSize); - if (destsize == 0) - return false; + // packet->put(0, pSize); + // Compress(const_cast(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; } diff --git a/src/game/UpdateData.h b/src/game/UpdateData.h index a9da30e13..b11cd4082 100644 --- a/src/game/UpdateData.h +++ b/src/game/UpdateData.h @@ -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; diff --git a/src/game/movement/MoveSpline.cpp b/src/game/movement/MoveSpline.cpp index 217b52f13..7d1ccc09b 100644 --- a/src/game/movement/MoveSpline.cpp +++ b/src/game/movement/MoveSpline.cpp @@ -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; diff --git a/src/game/movement/MoveSplineFlag.h b/src/game/movement/MoveSplineFlag.h index 8f330a31a..ebc04eeff 100644 --- a/src/game/movement/MoveSplineFlag.h +++ b/src/game/movement/MoveSplineFlag.h @@ -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() diff --git a/src/game/movement/MoveSplineInit.cpp b/src/game/movement/MoveSplineInit.cpp index d668645de..cdbb3e013 100644 --- a/src/game/movement/MoveSplineInit.cpp +++ b/src/game/movement/MoveSplineInit.cpp @@ -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)); diff --git a/src/game/movement/packet_builder.cpp b/src/game/movement/packet_builder.cpp index 752e99bb4..ca7513560 100644 --- a/src/game/movement/packet_builder.cpp +++ b/src/game/movement/packet_builder.cpp @@ -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(&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(&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(); } } diff --git a/src/game/movement/packet_builder.h b/src/game/movement/packet_builder.h index 7d91bdda7..cd6de5b22 100644 --- a/src/game/movement/packet_builder.h +++ b/src/game/movement/packet_builder.h @@ -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 diff --git a/src/game/movement/util.cpp b/src/game/movement/util.cpp index fcdc9f48e..74457cfc7 100644 --- a/src/game/movement/util.cpp +++ b/src/game/movement/util.cpp @@ -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