* Use MovementInfo instead of manually extracting packets containing Movement Info

Also fix CREATURE_QUERY and GAMEOBJECT_QUERY opcodes
and handle fallout from moving readPackGUID
This commit is contained in:
shlainn 2011-09-27 00:24:13 +02:00
parent 23059350dd
commit 736d7116bf
6 changed files with 329 additions and 213 deletions

View File

@ -0,0 +1,115 @@
#ifndef _MOVEMENTINFO_H
#define _MOVEMENTINFO_H
enum MovementFlags
{
MOVEMENTFLAG_NONE = 0x00000000,
MOVEMENTFLAG_FORWARD = 0x00000001,
MOVEMENTFLAG_BACKWARD = 0x00000002,
MOVEMENTFLAG_STRAFE_LEFT = 0x00000004,
MOVEMENTFLAG_STRAFE_RIGHT = 0x00000008,
MOVEMENTFLAG_TURN_LEFT = 0x00000010,
MOVEMENTFLAG_TURN_RIGHT = 0x00000020,
MOVEMENTFLAG_PITCH_UP = 0x00000040,
MOVEMENTFLAG_PITCH_DOWN = 0x00000080,
MOVEMENTFLAG_WALK_MODE = 0x00000100, // Walking
MOVEMENTFLAG_ONTRANSPORT = 0x00000200,
MOVEMENTFLAG_LEVITATING = 0x00000400,
MOVEMENTFLAG_ROOT = 0x00000800,
MOVEMENTFLAG_FALLING = 0x00001000,
MOVEMENTFLAG_FALLINGFAR = 0x00002000,
MOVEMENTFLAG_PENDINGSTOP = 0x00004000,
MOVEMENTFLAG_PENDINGSTRAFESTOP = 0x00008000,
MOVEMENTFLAG_PENDINGFORWARD = 0x00010000,
MOVEMENTFLAG_PENDINGBACKWARD = 0x00020000,
MOVEMENTFLAG_PENDINGSTRAFELEFT = 0x00040000,
MOVEMENTFLAG_PENDINGSTRAFERIGHT = 0x00080000,
MOVEMENTFLAG_PENDINGROOT = 0x00100000,
MOVEMENTFLAG_SWIMMING = 0x00200000, // appears with fly flag also
MOVEMENTFLAG_ASCENDING = 0x00400000, // swim up also
MOVEMENTFLAG_DESCENDING = 0x00800000, // swim down also
MOVEMENTFLAG_CAN_FLY = 0x01000000, // can fly in 3.3?
MOVEMENTFLAG_FLYING = 0x02000000, // Actual flying mode
MOVEMENTFLAG_SPLINE_ELEVATION = 0x04000000, // used for flight paths
MOVEMENTFLAG_SPLINE_ENABLED = 0x08000000, // used for flight paths
MOVEMENTFLAG_WATERWALKING = 0x10000000, // prevent unit from falling through water
MOVEMENTFLAG_SAFE_FALL = 0x20000000, // active rogue safe fall spell (passive)
MOVEMENTFLAG_HOVER = 0x40000000
};
enum MovementFlags2
{
MOVEMENTFLAG2_NONE = 0x0000,
MOVEMENTFLAG2_UNK1 = 0x0001,
MOVEMENTFLAG2_UNK2 = 0x0002,
MOVEMENTFLAG2_UNK3 = 0x0004,
MOVEMENTFLAG2_FULLSPEEDTURNING = 0x0008,
MOVEMENTFLAG2_FULLSPEEDPITCHING = 0x0010,
MOVEMENTFLAG2_ALLOW_PITCHING = 0x0020,
MOVEMENTFLAG2_UNK4 = 0x0040,
MOVEMENTFLAG2_UNK5 = 0x0080,
MOVEMENTFLAG2_UNK6 = 0x0100,
MOVEMENTFLAG2_UNK7 = 0x0200,
MOVEMENTFLAG2_INTERP_MOVEMENT = 0x0400,
MOVEMENTFLAG2_INTERP_TURNING = 0x0800,
MOVEMENTFLAG2_INTERP_PITCHING = 0x1000,
MOVEMENTFLAG2_UNK8 = 0x2000,
MOVEMENTFLAG2_UNK9 = 0x4000,
MOVEMENTFLAG2_UNK10 = 0x8000,
MOVEMENTFLAG2_INTERP_MASK = MOVEMENTFLAG2_INTERP_MOVEMENT | MOVEMENTFLAG2_INTERP_TURNING | MOVEMENTFLAG2_INTERP_PITCHING
};
struct MovementInfo
{
static uint8 _c; //Version switch helper
// Read/Write methods
void Read(ByteBuffer &data);
void Write(ByteBuffer &data) const;
// common
uint32 flags;
uint16 flags2;
uint32 time;
WorldPosition pos;
// transport
uint64 t_guid;
WorldPosition t_pos;
uint32 t_time, t_time2;
uint8 t_seat;
// swimming and unk
float s_angle;
// last fall time
uint32 fallTime;
// jumping
float j_velocity, j_sinAngle, j_cosAngle, j_xyspeed;
// spline
float u_unk1;
MovementInfo()
{
flags = time = t_time = fallTime = flags2 = 0;
t_seat = 0;
s_angle = j_velocity = j_sinAngle = j_cosAngle = j_xyspeed = u_unk1 = 0.0f;
t_guid = 0;
}
void SetMovementFlags(uint32 _flags)
{
flags = _flags;
}
};
inline ByteBuffer& operator<< (ByteBuffer& buf, MovementInfo const& mi)
{
mi.Write(buf);
return buf;
}
inline ByteBuffer& operator>> (ByteBuffer& buf, MovementInfo& mi)
{
mi.Read(buf);
return buf;
}
#endif

View File

@ -3,6 +3,7 @@
#include "World.h"
#include "MovementMgr.h"
#include "Player.h"
#include "MovementInfo.h"
MovementMgr::MovementMgr()
{
@ -33,34 +34,18 @@ void MovementMgr::SetInstance(PseuInstance *inst)
void MovementMgr::_BuildPacket(uint16 opcode)
{
WorldPacket *wp = new WorldPacket(opcode,4+2+4+16); // it can be larger, if we are jumping, on transport or swimming
if(_instance->GetConf()->client > CLIENT_CLASSIC_WOW)
if(_instance->GetConf()->client > CLIENT_TBC)
wp->appendPackGUID(_mychar->GetGUID());
*wp << _moveFlags;
if(_instance->GetConf()->client > CLIENT_CLASSIC_WOW)
*wp << (uint16)0; // flags2 , safe to set 0 for now (shlainn)
*wp << getMSTime();
*wp << _mychar->GetPosition();
// TODO: transport not yet handled/done
if(_moveFlags & MOVEMENTFLAG_ONTRANSPORT)
{
*wp << (uint64)0; // transport guid
*wp << WorldPosition(); // transport position
*wp << getMSTime(); // transport time (??)
}
// TODO: swimming not yet done
if(_moveFlags & MOVEMENTFLAG_SWIMMING)
{
*wp << (float)0; // angle; 1.55=looking up, -1.55=looking down, 0=looking forward
}
*wp << (uint32)0; // last fall time (also used when jumping)
if(_moveFlags & MOVEMENTFLAG_PENDINGSTOP)
{
*wp << (float)0; //unk value, or as mangos calls it: j_unk ^^
*wp << sin(_mychar->GetO()+ (M_PI/2));
*wp << cos(_mychar->GetO()+ (M_PI/2));
*wp << _movespeed;
}
MovementInfo mi;
mi.SetMovementFlags(_moveFlags);
mi.time = getMSTime();
mi.pos = _mychar->GetPosition();
mi.fallTime = _falltime;
*wp << mi;
// TODO: transport not yet handled/done
// TODO: swimming not yet done
// TODO: jumping not done yet
// TODO: spline not yet done
DEBUG(logdebug("Move flags: 0x%X (packet: %u bytes)",_moveFlags,wp->size()));
@ -68,6 +53,8 @@ void MovementMgr::_BuildPacket(uint16 opcode)
_instance->GetWSession()->AddSendWorldPacket(wp);
_moved = true;
_optime = getMSTime();
_falltime = 0; //HACK!!!!
}
@ -173,6 +160,12 @@ void MovementMgr::MoveStop(void)
_BuildPacket(MSG_MOVE_STOP);
}
void MovementMgr::MoveFallLand(void)
{
Update(true);
_BuildPacket(MSG_MOVE_FALL_LAND);
}
void MovementMgr::MoveStartForward(void)
{
if(_moveFlags & MOVEMENTFLAG_FORWARD)

View File

@ -2,7 +2,7 @@
#define MOVEMENTMGR_H
#include "common.h"
#include "UpdateData.h"
#include "MovementInfo.h"
#define MOVE_HEARTBEAT_DELAY 500
#define MOVE_TURN_UPDATE_DIFF 0.15f // not sure about original/real value, but this seems good
@ -58,7 +58,7 @@ public:
bool IsTurning(void); // spinning around?
bool IsWalking(void); // walking straight forward/backward?
bool IsStrafing(void); // strafing left/right?
inline void SetFallTime(uint32 falltime){_falltime = falltime; }
private:
@ -71,6 +71,7 @@ private:
uint8 _movemode; // automatic or manual
float _movespeed; // current xy movement speed
float _jumptime;
uint32 _falltime;
UnitMoveType _movetype; // index used for speed selection
bool _moved;

View File

@ -10,6 +10,7 @@
#include "DynamicObject.h"
#include "ObjMgr.h"
#include "UpdateMask.h"
#include "MovementInfo.h"
void WorldSession::_HandleCompressedUpdateObjectOpcode(WorldPacket& recvPacket)
@ -51,7 +52,7 @@ void WorldSession::_HandleUpdateObjectOpcode(WorldPacket& recvPacket)
{
case UPDATETYPE_VALUES:
{
uguid = recvPacket.GetPackedGuid();
uguid = recvPacket.readPackGUID();
_ValuesUpdate(uguid,recvPacket);
}
break;
@ -77,7 +78,7 @@ void WorldSession::_HandleUpdateObjectOpcode(WorldPacket& recvPacket)
case UPDATETYPE_CREATE_OBJECT2: // will be sent when our very own character is created
case UPDATETYPE_CREATE_OBJECT: // will be sent on any other object creation
{
uguid = recvPacket.GetPackedGuid();
uguid = recvPacket.readPackGUID();
uint8 objtypeid;
recvPacket >> objtypeid;
logdebug("Create Object type %u with guid "I64FMT,objtypeid,uguid);
@ -199,7 +200,7 @@ void WorldSession::_HandleUpdateObjectOpcode(WorldPacket& recvPacket)
recvPacket >> usize;
for(uint16 i=0;i<usize;i++)
{
uguid = recvPacket.GetPackedGuid(); // not 100% sure if this is correct
uguid = recvPacket.readPackGUID(); // not 100% sure if this is correct
logdebug("GUID "I64FMT" out of range",uguid);
// call script just before object removal
@ -276,51 +277,32 @@ void WorldSession::_MovementUpdate(uint8 objtypeid, uint64 uguid, WorldPacket& r
mi.flags = 0; // not sure if its correct to set it to 0 (needs some starting flag?)
if(flags & UPDATEFLAG_LIVING)
{
recvPacket >> mi.flags;
if(client == CLIENT_TBC)
{
uint8 tempUnkFlags;
recvPacket >> tempUnkFlags;
mi.unkFlags = tempUnkFlags;
}
if(client == CLIENT_WOTLK)
recvPacket >> mi.unkFlags;
recvPacket>> mi.time;
recvPacket >> mi;
logdev("MovementUpdate: TypeID=%u GUID="I64FMT" pObj=%X flags=%x mi.flags=%x",objtypeid,uguid,obj,flags,mi.flags);
recvPacket >> mi.x >> mi.y >> mi.z >> mi.o;
logdev("FLOATS: x=%f y=%f z=%f o=%f",mi.x, mi.y, mi.z ,mi.o);
logdev("FLOATS: x=%f y=%f z=%f o=%f",mi.pos.x, mi.pos.y, mi.pos.z ,mi.pos.o);
if(obj && obj->IsWorldObject())
((WorldObject*)obj)->SetPosition(mi.x, mi.y, mi.z, mi.o);
((WorldObject*)obj)->SetPosition(mi.pos.x, mi.pos.y, mi.pos.z, mi.pos.o);
if(mi.flags & MOVEMENTFLAG_ONTRANSPORT)
{
mi.t_guid = recvPacket.GetPackedGuid();
recvPacket >> mi.t_x >> mi.t_y >> mi.t_z >> mi.t_o;
recvPacket >> mi.t_time; // added in 2.0.3
recvPacket >> mi.t_seat;
logdev("TRANSPORT @ mi.flags: guid="I64FMT" x=%f y=%f z=%f o=%f", mi.t_guid, mi.t_x, mi.t_y, mi.t_z, mi.t_o);
logdev("TRANSPORT @ mi.flags: guid="I64FMT" x=%f y=%f z=%f o=%f", mi.t_guid, mi.t_pos.x, mi.t_pos.y, mi.t_pos.z, mi.t_pos.o);
}
if((mi.flags & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING)) || (mi.unkFlags & 0x20)) //The last one is MOVEFLAG2_ALLOW_PITCHING in MaNGOS
if((mi.flags & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING)) || (mi.flags2 & MOVEMENTFLAG2_ALLOW_PITCHING))
{
recvPacket >> mi.s_angle;
logdev("MovementUpdate: MOVEMENTFLAG_SWIMMING or FLYING is set, angle = %f!", mi.s_angle);
}
recvPacket >> mi.fallTime;
logdev("MovementUpdate: FallTime = %u", mi.fallTime);
if(mi.flags & MOVEMENTFLAG_FALLING)
{
recvPacket >> mi.j_unk >> mi.j_sinAngle >> mi.j_cosAngle >> mi.j_xyspeed;
logdev("MovementUpdate: MOVEMENTFLAG_FALLING is set, unk=%f sinA=%f cosA=%f xyspeed=%f = %u", mi.j_unk, mi.j_sinAngle, mi.j_cosAngle, mi.j_xyspeed);
logdev("MovementUpdate: MOVEMENTFLAG_FALLING is set, velocity=%f sinA=%f cosA=%f xyspeed=%f = %u", mi.j_velocity, mi.j_sinAngle, mi.j_cosAngle, mi.j_xyspeed);
}
if(mi.flags & MOVEMENTFLAG_SPLINE_ELEVATION)
{
recvPacket >> mi.u_unk1;
logdev("MovementUpdate: MOVEMENTFLAG_SPLINE is set, got %u", mi.u_unk1);
}
@ -333,7 +315,7 @@ void WorldSession::_MovementUpdate(uint8 objtypeid, uint64 uguid, WorldPacket& r
logdev("MovementUpdate: Got speeds, walk=%f run=%f turn=%f", speedWalk, speedRun, speedTurn);
if(u)
{
u->SetPosition(mi.x, mi.y, mi.z, mi.o);
u->SetPosition(mi.pos.x, mi.pos.y, mi.pos.z, mi.pos.o);
u->SetSpeed(MOVE_WALK, speedWalk);
u->SetSpeed(MOVE_RUN, speedRun);
u->SetSpeed(MOVE_SWIMBACK, speedSwimBack);
@ -356,7 +338,7 @@ void WorldSession::_MovementUpdate(uint8 objtypeid, uint64 uguid, WorldPacket& r
{
if(flags & UPDATEFLAG_POSITION)
{
uint64 pguid = recvPacket.GetPackedGuid();
uint64 pguid = recvPacket.readPackGUID();
float x,y,z,o,sx,sy,sz,so;
recvPacket >> x >> y >> z;
recvPacket >> sx >> sy >> sz;
@ -408,7 +390,7 @@ void WorldSession::_MovementUpdate(uint8 objtypeid, uint64 uguid, WorldPacket& r
if(flags & UPDATEFLAG_HAS_TARGET)
{
uint64 unkguid = recvPacket.GetPackedGuid(); // MaNGOS sends uint8(0) always, but its probably be a packed guid
uint64 unkguid = recvPacket.readPackGUID(); // MaNGOS sends uint8(0) always, but its probably be a packed guid
logdev("MovementUpdate: UPDATEFLAG_FULLGUID is set, got "I64FMT, unkguid);
}
@ -540,3 +522,117 @@ void WorldSession::_QueryObjectInfo(uint64 guid)
}
}
void MovementInfo::Read(ByteBuffer &data)
{
data >> flags;
if(_c == CLIENT_WOTLK)
data >> flags2;
if(_c == CLIENT_TBC)
{
uint8 tempFlags2;
data >> tempFlags2;
flags2 = tempFlags2;
}
data >> time;
data >> pos.x;
data >> pos.y;
data >> pos.z;
data >> pos.o;
if(flags & (MOVEMENTFLAG_ONTRANSPORT))
{
if(_c < CLIENT_WOTLK)
data >> t_guid;
else
t_guid =data.readPackGUID();
data >> t_pos.x;
data >> t_pos.y;
data >> t_pos.z;
data >> t_pos.o;
if(_c > CLIENT_CLASSIC_WOW)
data >> t_time;
if(_c > CLIENT_TBC)
data >> t_seat;
if(_c > CLIENT_TBC && flags2 & MOVEMENTFLAG2_INTERP_MOVEMENT)
data >> t_time2;
}
if((flags & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING)) || (flags2 & MOVEMENTFLAG2_ALLOW_PITCHING))
{
data >> s_angle;
}
data >> fallTime;
if(flags & (MOVEMENTFLAG_FALLING))
{
data >> j_velocity;
data >> j_sinAngle;
data >> j_cosAngle;
data >> j_xyspeed;
}
if(flags & (MOVEMENTFLAG_SPLINE_ELEVATION))
{
data >> u_unk1;
}
}
void MovementInfo::Write(ByteBuffer &data) const
{
data << flags;
if(_c == CLIENT_WOTLK)
data << flags2;
if(_c == CLIENT_TBC)
{
data << (uint8)flags2;
}
data << time;
data << pos.x;
data << pos.y;
data << pos.z;
data << pos.o;
if(flags & (MOVEMENTFLAG_ONTRANSPORT))
{
if(_c < CLIENT_WOTLK)
data << t_guid;
else
data.appendPackGUID(t_guid);
data << t_pos.x;
data << t_pos.y;
data << t_pos.z;
data << t_pos.o;
if(_c > CLIENT_CLASSIC_WOW)
data << t_time;
if(_c > CLIENT_TBC)
data << t_seat;
if(_c > CLIENT_TBC && flags2 & MOVEMENTFLAG2_INTERP_MOVEMENT)
data << t_time2;
}
if((flags & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING)) || (flags2 & MOVEMENTFLAG2_ALLOW_PITCHING))
{
data << s_angle;
}
data << fallTime;
if(flags & (MOVEMENTFLAG_FALLING))
{
data << j_velocity;
data << j_sinAngle;
data << j_cosAngle;
data << j_xyspeed;
}
if(flags & (MOVEMENTFLAG_SPLINE_ELEVATION))
{
data << u_unk1;
}
}

View File

@ -35,78 +35,4 @@ enum OBJECT_UPDATE_FLAGS_6005 //UPDATEFLAGS with different meaning in 1.12.x
enum MovementFlags
{
MOVEMENTFLAG_NONE = 0x00000000,
MOVEMENTFLAG_FORWARD = 0x00000001,
MOVEMENTFLAG_BACKWARD = 0x00000002,
MOVEMENTFLAG_STRAFE_LEFT = 0x00000004,
MOVEMENTFLAG_STRAFE_RIGHT = 0x00000008,
MOVEMENTFLAG_TURN_LEFT = 0x00000010,
MOVEMENTFLAG_TURN_RIGHT = 0x00000020,
MOVEMENTFLAG_PITCH_UP = 0x00000040,
MOVEMENTFLAG_PITCH_DOWN = 0x00000080,
MOVEMENTFLAG_WALK_MODE = 0x00000100, // Walking
MOVEMENTFLAG_ONTRANSPORT = 0x00000200,
MOVEMENTFLAG_LEVITATING = 0x00000400,
MOVEMENTFLAG_ROOT = 0x00000800,
MOVEMENTFLAG_FALLING = 0x00001000,
MOVEMENTFLAG_FALLINGFAR = 0x00002000,
MOVEMENTFLAG_PENDINGSTOP = 0x00004000,
MOVEMENTFLAG_PENDINGSTRAFESTOP = 0x00008000,
MOVEMENTFLAG_PENDINGFORWARD = 0x00010000,
MOVEMENTFLAG_PENDINGBACKWARD = 0x00020000,
MOVEMENTFLAG_PENDINGSTRAFELEFT = 0x00040000,
MOVEMENTFLAG_PENDINGSTRAFERIGHT = 0x00080000,
MOVEMENTFLAG_PENDINGROOT = 0x00100000,
MOVEMENTFLAG_SWIMMING = 0x00200000, // appears with fly flag also
MOVEMENTFLAG_ASCENDING = 0x00400000, // swim up also
MOVEMENTFLAG_DESCENDING = 0x00800000, // swim down also
MOVEMENTFLAG_CAN_FLY = 0x01000000, // can fly in 3.3?
MOVEMENTFLAG_FLYING = 0x02000000, // Actual flying mode
MOVEMENTFLAG_SPLINE_ELEVATION = 0x04000000, // used for flight paths
MOVEMENTFLAG_SPLINE_ENABLED = 0x08000000, // used for flight paths
MOVEMENTFLAG_WATERWALKING = 0x10000000, // prevent unit from falling through water
MOVEMENTFLAG_SAFE_FALL = 0x20000000, // active rogue safe fall spell (passive)
MOVEMENTFLAG_HOVER = 0x40000000
};
struct MovementInfo
{
// common
uint32 flags;
uint16 unkFlags;
uint32 time;
float x, y, z, o;
// transport
uint64 t_guid;
float t_x, t_y, t_z, t_o;
uint32 t_time;
uint8 t_seat;
// swimming and unk
float s_angle;
// last fall time
uint32 fallTime;
// jumping
float j_unk, j_sinAngle, j_cosAngle, j_xyspeed;
// spline
float u_unk1;
MovementInfo()
{
flags = time = t_time = fallTime = unkFlags = 0;
t_seat = 0;
x = y = z = o = t_x = t_y = t_z = t_o = s_angle = j_unk = j_sinAngle = j_cosAngle = j_xyspeed = u_unk1 = 0.0f;
t_guid = 0;
}
void SetMovementFlags(uint32 _flags)
{
flags = _flags;
}
};
bool IsFloatField(uint8, uint32);
bool IsUInt64Field(uint8, uint32);
#endif
#endif

View File

@ -15,6 +15,8 @@
#include "RealmSession.h"
#include "WorldSession.h"
#include "MemoryDataHolder.h"
#include "MovementInfo.h"
#include "MovementMgr.h"
struct OpcodeHandler
{
@ -24,6 +26,7 @@ struct OpcodeHandler
uint32 Object::maxvalues[TYPEID_MAX];
UpdateField Object::updatefields[UPDATEFIELDS_NAME_COUNT];
uint8 MovementInfo::_c=CLIENT_UNKNOWN;
WorldSession::WorldSession(PseuInstance *in)
{
@ -41,6 +44,7 @@ WorldSession::WorldSession(PseuInstance *in)
//...
_SetupObjectFields();
MovementInfo::_c=in->GetConf()->client;
in->GetScripts()->RunScriptIfExists("_onworldsessioncreate");
@ -1049,7 +1053,7 @@ void WorldSession::_HandleNameQueryResponseOpcode(WorldPacket& recvPacket)
std::string pname;
uint32 prace, pgender, pclass;
if(GetInstance()->GetConf()->client > CLIENT_CLASSIC_WOW)
pguid = recvPacket.GetPackedGuid();
pguid = recvPacket.readPackGUID();
else
recvPacket >> pguid;
recvPacket >> pname >> realm >> prace >> pgender >> pclass;
@ -1099,22 +1103,15 @@ void WorldSession::_HandleGroupInviteOpcode(WorldPacket& recvPacket)
void WorldSession::_HandleMovementOpcode(WorldPacket& recvPacket)
{
uint32 flags, time, unk32;
float x, y, z, o;
uint64 guid;
uint16 flags2;
guid = recvPacket.GetPackedGuid();
recvPacket >> flags;
if(GetInstance()->GetConf()->client > CLIENT_CLASSIC_WOW)
{
recvPacket >> flags2;
}
recvPacket >> time >> x >> y >> z >> o >> unk32;
DEBUG(logdebug("MOVE: "I64FMT" -> time=%u flags=0x%X x=%.4f y=%.4f z=%.4f o=%.4f",guid,time,flags,x,y,z,o));
MovementInfo mi;
guid = recvPacket.readPackGUID();
recvPacket >> mi;
DEBUG(logdebug("MOVE: "I64FMT" -> time=%u flags=0x%X x=%.4f y=%.4f z=%.4f o=%.4f",guid,mi.time,mi.flags,mi.pos.x,mi.pos.y,mi.pos.z,mi.pos.o));
Object *obj = objmgr.GetObj(guid);
if(obj && obj->IsWorldObject())
{
((WorldObject*)obj)->SetPosition(x,y,z,o);
((WorldObject*)obj)->SetPosition(mi.pos.x,mi.pos.y,mi.pos.z,mi.pos.o);
}
//TODO: Eval rest of Packet!!
}
@ -1122,10 +1119,10 @@ void WorldSession::_HandleMovementOpcode(WorldPacket& recvPacket)
void WorldSession::_HandleSetSpeedOpcode(WorldPacket& recvPacket)
{
uint64 guid;
float x, y, z, o, speed;
uint32 unk32, movetype;
uint16 unk16;
float speed;
uint32 movetype;
MovementInfo mi;
switch(recvPacket.GetOpcode())
{
case MSG_MOVE_SET_WALK_SPEED:
@ -1169,19 +1166,15 @@ void WorldSession::_HandleSetSpeedOpcode(WorldPacket& recvPacket)
return;
}
guid = recvPacket.GetPackedGuid();
recvPacket >> unk32;
recvPacket >> unk16;
recvPacket >> unk32; /* getMSTime()*/
recvPacket >> x >> y >> z >> o;
recvPacket >> unk32; // falltime
guid = recvPacket.readPackGUID();
recvPacket >> mi;
recvPacket >> speed;
Object *obj = objmgr.GetObj(guid);
if(obj && obj->IsUnit())
{
((Unit*)obj)->SetSpeed(movetype, speed);
((Unit*)obj)->SetPosition(x, y, z, o);
((Unit*)obj)->SetPosition(mi.pos.x, mi.pos.y, mi.pos.z, mi.pos.o);
}
}
@ -1235,7 +1228,7 @@ void WorldSession::_HandleForceSetSpeedOpcode(WorldPacket& recvPacket)
return;
}
guid = recvPacket.GetPackedGuid();
guid = recvPacket.readPackGUID();
recvPacket >> unk32;
if (movetype == MOVE_RUN)
recvPacket >> unk8;
@ -1250,58 +1243,44 @@ void WorldSession::_HandleForceSetSpeedOpcode(WorldPacket& recvPacket)
void WorldSession::_HandleTelePortAckOpcode(WorldPacket& recvPacket)
{
uint32 unk32,time, flags; // movement flags
uint32 unk32;
uint64 guid;
uint16 unk16;
float x, y, z, o;
MovementInfo mi;
guid = recvPacket.readPackGUID();
recvPacket >> unk32 >> mi;
guid = recvPacket.GetPackedGuid();
recvPacket >> unk32 >> flags;
if(GetInstance()->GetConf()->client > CLIENT_CLASSIC_WOW)
recvPacket >> unk16;
recvPacket >> time >> x >> y >> z >> o;
if(GetInstance()->GetConf()->client > CLIENT_CLASSIC_WOW)
recvPacket >> unk32;
logdetail("Got teleported, data: x: %f, y: %f, z: %f, o: %f, guid: "I64FMT, mi.pos.x, mi.pos.y, mi.pos.z, mi.pos.o, guid);
logdetail("Got teleported, data: x: %f, y: %f, z: %f, o: %f, guid: "I64FMT, x, y, z, o, guid);
WorldPacket wp(MSG_MOVE_TELEPORT_ACK,8+4+4);
if(GetInstance()->GetConf()->client > CLIENT_CLASSIC_WOW)
wp.appendPackGUID(guid); //GUID must be packed!
else
wp << guid;
wp << (uint32)0 << (uint32)getMSTime();
SendWorldPacket(wp);
// TODO: put this into a capsule class later, that autodetects movement flags etc.
WorldPacket response(MSG_MOVE_FALL_LAND,4+2+4+4+4+4+4+4);
if(GetInstance()->GetConf()->client > CLIENT_CLASSIC_WOW)
response.appendPackGUID(guid);
response << uint32(0);//flags
if(GetInstance()->GetConf()->client > CLIENT_CLASSIC_WOW)
response << (uint16)0;//flags2
response << (uint32)getMSTime() << x << y << z << o << uint32(100); // simulate 100 msec fall time
SendWorldPacket(response);
_world->UpdatePos(x,y);
_world->UpdatePos(mi.pos.x,mi.pos.y);
_world->Update();
if(MyCharacter *my = GetMyChar())
{
my->SetPosition(x,y,z,o);
my->SetPosition(mi.pos.x,mi.pos.y,mi.pos.z,mi.pos.o);
}
WorldPacket wp(MSG_MOVE_TELEPORT_ACK,8+4+4);
if(GetInstance()->GetConf()->client > CLIENT_TBC)
wp.appendPackGUID(guid); //GUID must be packed!
else
wp << guid;
wp << (uint32)0 << (uint32)getMSTime(); //First value is some counter
SendWorldPacket(wp);
_world->GetMoveMgr()->SetFallTime(100);
_world->GetMoveMgr()->MoveFallLand();
if(GetInstance()->GetScripts()->ScriptExists("_onteleport"))
{
CmdSet Set;
Set.defaultarg = "false"; // teleported to other map = false
Set.arg[0] = DefScriptTools::toString(guid);
Set.arg[1] = DefScriptTools::toString(x);
Set.arg[2] = DefScriptTools::toString(y);
Set.arg[3] = DefScriptTools::toString(z);
Set.arg[4] = DefScriptTools::toString(o);
Set.arg[5] = DefScriptTools::toString(flags);
Set.arg[1] = DefScriptTools::toString(mi.pos.x);
Set.arg[2] = DefScriptTools::toString(mi.pos.y);
Set.arg[3] = DefScriptTools::toString(mi.pos.z);
Set.arg[4] = DefScriptTools::toString(mi.pos.o);
Set.arg[5] = DefScriptTools::toString(mi.flags);
GetInstance()->GetScripts()->RunScriptIfExists("_onteleport");
}
}
@ -1328,12 +1307,6 @@ void WorldSession::_HandleNewWorldOpcode(WorldPacket& recvPacket)
wp << GetGuid();
SendWorldPacket(wp);
// TODO: put this into a capsule class later, that autodetects movement flags etc.
WorldPacket response(MSG_MOVE_FALL_LAND,4+2+4+4+4+4+4+4);
response << uint32(0) << (uint16)0; // no flags; unk
response <<(uint32)getMSTime(); // time correct?
response << x << y << z << o << uint32(100); // simulate 100 msec fall time
SendWorldPacket(response);
@ -1349,6 +1322,9 @@ void WorldSession::_HandleNewWorldOpcode(WorldPacket& recvPacket)
my->ClearSpells(); // will be resent by server
my->SetPosition(x,y,z,o,mapid);
}
_world->GetMoveMgr()->SetFallTime(100);
_world->GetMoveMgr()->MoveFallLand();//Must be sent after character was set to new position
// TODO: need to switch to SCENESTATE_LOGINSCREEN here, and after everything is loaded, back to SCENESTATE_WORLD
@ -1385,7 +1361,7 @@ void WorldSession::_HandleCastSuccessOpcode(WorldPacket& recvPacket)
uint32 spellId;
uint64 casterGuid;
casterGuid = recvPacket.GetPackedGuid();
casterGuid = recvPacket.readPackGUID();
recvPacket >> spellId;
if (GetMyChar()->GetGUID() == casterGuid)
@ -1695,8 +1671,11 @@ void WorldSession::_HandleCreatureQueryResponseOpcode(WorldPacket& recvPacket)
recvPacket >> ct->rank;
if(GetInstance()->GetConf()->client > CLIENT_CLASSIC_WOW)
{
for(uint32 i = 0; i < MAX_KILL_CREDIT; i++)
recvPacket >> ct->killCredit[i];
if(GetInstance()->GetConf()->client == CLIENT_WOTLK)
{
for(uint32 i = 0; i < MAX_KILL_CREDIT; i++)
recvPacket >> ct->killCredit[i];
}
recvPacket >> ct->displayid_A;
recvPacket >> ct->displayid_H;
recvPacket >> ct->displayid_AF;
@ -1704,9 +1683,12 @@ void WorldSession::_HandleCreatureQueryResponseOpcode(WorldPacket& recvPacket)
recvPacket >> unkf;
recvPacket >> unkf;
recvPacket >> ct->RacialLeader;
for(uint32 i = 0; i < 4; i++)
recvPacket >> ct->questItems[i];
recvPacket >> ct->movementId;
if(GetInstance()->GetConf()->client == CLIENT_WOTLK)
{
for(uint32 i = 0; i < 4; i++)
recvPacket >> ct->questItems[i];
recvPacket >> ct->movementId;
}
}
else
{
@ -1764,8 +1746,11 @@ void WorldSession::_HandleGameobjectQueryResponseOpcode(WorldPacket& recvPacket)
if(GetInstance()->GetConf()->client > CLIENT_CLASSIC_WOW)
{
recvPacket >> go->size;
for(uint32 i = 0; i < 4; i++)
recvPacket >> go->questItems[i];
if(GetInstance()->GetConf()->client > CLIENT_TBC)
{
for(uint32 i = 0; i < 4; i++)
recvPacket >> go->questItems[i];
}
}
std::stringstream ss;
ss << "Got info for gameobject " << entry << ":" << go->name;
@ -1808,7 +1793,7 @@ void WorldSession::_HandleCharCreateOpcode(WorldPacket& recvPacket)
void WorldSession::_HandleMonsterMoveOpcode(WorldPacket& recvPacket)
{
uint64 guid;
guid = recvPacket.GetPackedGuid();
guid = recvPacket.readPackGUID();
Object* obj = objmgr.GetObj(guid);
if (!obj || !obj->IsWorldObject())
@ -1817,7 +1802,7 @@ void WorldSession::_HandleMonsterMoveOpcode(WorldPacket& recvPacket)
uint8 unk, type;
uint32 time, flags, movetime, waypoints;
float x, y, z;
if(GetInstance()->GetConf()->client > CLIENT_CLASSIC_WOW)
if(GetInstance()->GetConf()->client > CLIENT_TBC)
recvPacket >> unk;
recvPacket >> x >> y >> z >> time >> type;