Movement packets cleanup.

This commit is contained in:
tomrus88 2010-02-01 17:02:00 +03:00
parent 60f8b3874d
commit b85417df73
16 changed files with 436 additions and 485 deletions

View file

@ -900,16 +900,16 @@ Map::CreatureRelocation(Creature *creature, float x, float y, float z, float ang
if( old_cell.DiffCell(new_cell) || old_cell.DiffGrid(new_cell) )
{
#ifdef MANGOS_DEBUG
if((sLog.getLogFilter() & LOG_FILTER_CREATURE_MOVES)==0)
if((sLog.getLogFilter() & LOG_FILTER_CREATURE_MOVES) == 0)
sLog.outDebug("Creature (GUID: %u Entry: %u) added to moving list from grid[%u,%u]cell[%u,%u] to grid[%u,%u]cell[%u,%u].", creature->GetGUIDLow(), creature->GetEntry(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY());
#endif
AddCreatureToMoveList(creature,x,y,z,ang);
AddCreatureToMoveList(creature, x, y, z, ang);
// in diffcell/diffgrid case notifiers called at finishing move creature in Map::MoveAllCreaturesInMoveList
}
else
{
creature->Relocate(x, y, z, ang);
CreatureRelocationNotify(creature,new_cell,new_val);
CreatureRelocationNotify(creature, new_cell, new_val);
}
assert(CheckGridIntegrity(creature,true));
}
@ -919,7 +919,7 @@ void Map::AddCreatureToMoveList(Creature *c, float x, float y, float z, float an
if(!c)
return;
i_creaturesToMove[c] = CreatureMover(x,y,z,ang);
i_creaturesToMove[c] = CreatureMover(x, y, z, ang);
}
void Map::MoveAllCreaturesInMoveList()
@ -941,7 +941,7 @@ void Map::MoveAllCreaturesInMoveList()
{
// update pos
c->Relocate(cm.x, cm.y, cm.z, cm.ang);
CreatureRelocationNotify(c,new_cell,new_cell.cellPair());
CreatureRelocationNotify(c, new_cell, new_cell.cellPair());
}
else
{

View file

@ -267,7 +267,7 @@ void WorldSession::HandleLogoutRequestOpcode( WorldPacket & /*recv_data*/ )
if( GetPlayer()->isInCombat() || //...is in combat
GetPlayer()->duel || //...is in Duel
//...is jumping ...is falling
GetPlayer()->m_movementInfo.HasMovementFlag(MovementFlags(MOVEMENTFLAG_JUMPING | MOVEMENTFLAG_FALLING)))
GetPlayer()->m_movementInfo.HasMovementFlag(MovementFlags(MOVEFLAG_JUMPING | MOVEFLAG_FALLING)))
{
WorldPacket data( SMSG_LOGOUT_RESPONSE, (2+4) ) ;
data << (uint8)0xC;
@ -1523,9 +1523,7 @@ void WorldSession::HandleMoveSetCanFlyAckOpcode( WorldPacket & recv_data )
recv_data.read_skip<uint32>(); // unk
MovementInfo movementInfo;
movementInfo.guid = guid;
ReadMovementInfo(recv_data, &movementInfo);
MovementInfo movementInfo(recv_data);
recv_data.read_skip<float>(); // unk2

View file

@ -239,30 +239,28 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )
if(!recv_data.readPackGUID(guid))
return;
MovementInfo movementInfo;
movementInfo.guid = guid;
ReadMovementInfo(recv_data, &movementInfo);
MovementInfo movementInfo(recv_data);
/*----------------*/
if (!MaNGOS::IsValidMapCoord(movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o))
if (!MaNGOS::IsValidMapCoord(movementInfo.GetPos()->x, movementInfo.GetPos()->y, movementInfo.GetPos()->z, movementInfo.GetPos()->o))
{
recv_data.rpos(recv_data.wpos()); // prevent warnings spam
return;
}
/* handle special cases */
if (movementInfo.HasMovementFlag(MOVEMENTFLAG_ONTRANSPORT))
if (movementInfo.HasMovementFlag(MOVEFLAG_ONTRANSPORT))
{
// transports size limited
// (also received at zeppelin/lift leave by some reason with t_* as absolute in continent coordinates, can be safely skipped)
if( movementInfo.t_x > 50 || movementInfo.t_y > 50 || movementInfo.t_z > 100 )
if( movementInfo.GetTransportPos()->x > 50 || movementInfo.GetTransportPos()->y > 50 || movementInfo.GetTransportPos()->z > 100 )
{
recv_data.rpos(recv_data.wpos()); // prevent warnings spam
return;
}
if( !MaNGOS::IsValidMapCoord(movementInfo.x+movementInfo.t_x, movementInfo.y + movementInfo.t_y,
movementInfo.z + movementInfo.t_z, movementInfo.o + movementInfo.t_o) )
if( !MaNGOS::IsValidMapCoord(movementInfo.GetPos()->x + movementInfo.GetTransportPos()->x, movementInfo.GetPos()->y + movementInfo.GetTransportPos()->y,
movementInfo.GetPos()->z + movementInfo.GetTransportPos()->z, movementInfo.GetPos()->o + movementInfo.GetTransportPos()->o) )
{
recv_data.rpos(recv_data.wpos()); // prevent warnings spam
return;
@ -271,10 +269,10 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )
// if we boarded a transport, add us to it
if (plMover && !plMover->m_transport)
{
// elevators also cause the client to send MOVEMENTFLAG_ONTRANSPORT - just unmount if the guid can be found in the transport list
// elevators also cause the client to send MOVEFLAG_ONTRANSPORT - 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)->GetGUID() == movementInfo.t_guid)
if ((*iter)->GetGUID() == movementInfo.GetTransportGuid())
{
plMover->m_transport = (*iter);
(*iter)->AddPassenger(plMover);
@ -287,47 +285,43 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )
{
plMover->m_transport->RemovePassenger(plMover);
plMover->m_transport = NULL;
movementInfo.t_x = 0.0f;
movementInfo.t_y = 0.0f;
movementInfo.t_z = 0.0f;
movementInfo.t_o = 0.0f;
movementInfo.t_time = 0;
movementInfo.t_seat = -1;
movementInfo.SetTransportData(0, 0.0f, 0.0f, 0.0f, 0.0f, 0, -1);
}
// fall damage generation (ignore in flight case that can be triggered also at lags in moment teleportation to another map).
if (opcode == MSG_MOVE_FALL_LAND && plMover && !plMover->isInFlight())
plMover->HandleFall(movementInfo);
if (plMover && (movementInfo.HasMovementFlag(MOVEMENTFLAG_SWIMMING) != plMover->IsInWater()))
if (plMover && (movementInfo.HasMovementFlag(MOVEFLAG_SWIMMING) != plMover->IsInWater()))
{
// now client not include swimming flag in case jumping under water
plMover->SetInWater( !plMover->IsInWater() || plMover->GetBaseMap()->IsUnderWater(movementInfo.x, movementInfo.y, movementInfo.z) );
plMover->SetInWater( !plMover->IsInWater() || plMover->GetBaseMap()->IsUnderWater(movementInfo.GetPos()->x, movementInfo.GetPos()->y, movementInfo.GetPos()->z) );
}
/*----------------------*/
/* process position-change */
movementInfo.UpdateTime(getMSTime());
WorldPacket data(opcode, recv_data.size());
movementInfo.time = getMSTime();
movementInfo.guid = mover->GetGUID();
WriteMovementInfo(&data, &movementInfo);
data.appendPackGUID(mover->GetGUID()); // write guid
movementInfo.Write(data); // write data
GetPlayer()->SendMessageToSet(&data, false);
if(plMover) // nothing is charmed, or player charmed
{
plMover->SetPosition(movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o);
plMover->SetPosition(movementInfo.GetPos()->x, movementInfo.GetPos()->y, movementInfo.GetPos()->z, movementInfo.GetPos()->o);
plMover->m_movementInfo = movementInfo;
plMover->UpdateFallInformationIfNeed(movementInfo, opcode);
// after move info set
if ((opcode == MSG_MOVE_SET_WALK_MODE || opcode == MSG_MOVE_SET_RUN_MODE))
plMover->UpdateWalkMode(plMover,false);
plMover->UpdateWalkMode(plMover, false);
if(plMover->isMovingOrTurning())
plMover->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
if(movementInfo.z < -500.0f)
if(movementInfo.GetPos()->z < -500.0f)
{
if(plMover->InBattleGround()
&& plMover->GetBattleGround()
@ -361,7 +355,7 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )
else // creature charmed
{
if(mover->IsInWorld())
mover->GetMap()->CreatureRelocation((Creature*)mover, movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o);
mover->GetMap()->CreatureRelocation((Creature*)mover, movementInfo.GetPos()->x, movementInfo.GetPos()->y, movementInfo.GetPos()->z, movementInfo.GetPos()->o);
}
}
@ -387,9 +381,7 @@ void WorldSession::HandleForceSpeedChangeAck(WorldPacket &recv_data)
// continue parse packet
recv_data >> unk1; // counter or moveEvent
MovementInfo movementInfo;
movementInfo.guid = guid;
ReadMovementInfo(recv_data, &movementInfo);
MovementInfo movementInfo(recv_data);
recv_data >> newspeed;
/*----------------*/
@ -475,9 +467,7 @@ void WorldSession::HandleMoveNotActiveMover(WorldPacket &recv_data)
return;
}
MovementInfo mi;
mi.guid = old_mover_guid;
ReadMovementInfo(recv_data, &mi);
MovementInfo mi(recv_data);
_player->m_movementInfo = mi;
}
@ -500,9 +490,7 @@ void WorldSession::HandleDismissControlledVehicle(WorldPacket &recv_data)
if(!recv_data.readPackGUID(guid))
return;
MovementInfo mi;
mi.guid = guid;
ReadMovementInfo(recv_data, &mi);
MovementInfo mi(recv_data);
_player->m_movementInfo = mi;
@ -534,8 +522,7 @@ void WorldSession::HandleMoveKnockBackAck( WorldPacket & recv_data )
recv_data.read_skip<uint32>(); // unk
MovementInfo movementInfo;
ReadMovementInfo(recv_data, &movementInfo);
MovementInfo movementInfo(recv_data);
}
void WorldSession::HandleMoveHoverAck( WorldPacket& recv_data )
@ -548,8 +535,7 @@ void WorldSession::HandleMoveHoverAck( WorldPacket& recv_data )
recv_data.read_skip<uint32>(); // unk
MovementInfo movementInfo;
ReadMovementInfo(recv_data, &movementInfo);
MovementInfo movementInfo(recv_data);
recv_data.read_skip<uint32>(); // unk2
}
@ -564,8 +550,7 @@ void WorldSession::HandleMoveWaterWalkAck(WorldPacket& recv_data)
recv_data.read_skip<uint32>(); // unk
MovementInfo movementInfo;
ReadMovementInfo(recv_data, &movementInfo);
MovementInfo movementInfo(recv_data);
recv_data.read_skip<uint32>(); // unk2
}

View file

@ -95,7 +95,6 @@ Object::~Object( )
if(m_uint32Values)
{
//DEBUG_LOG("Object desctr 1 check (%p)",(void*)this);
delete [] m_uint32Values;
delete [] m_uint32Values_mirror;
@ -116,23 +115,24 @@ void Object::_InitValues()
void Object::_Create( uint32 guidlow, uint32 entry, HighGuid guidhigh )
{
if(!m_uint32Values) _InitValues();
if(!m_uint32Values)
_InitValues();
uint64 guid = MAKE_NEW_GUID(guidlow, entry, guidhigh);
SetUInt64Value( OBJECT_FIELD_GUID, guid );
SetUInt32Value( OBJECT_FIELD_TYPE, m_objectType );
SetUInt64Value(OBJECT_FIELD_GUID, guid);
SetUInt32Value(OBJECT_FIELD_TYPE, m_objectType);
m_PackGUID.wpos(0);
m_PackGUID.appendPackGUID(GetGUID());
}
void Object::BuildMovementUpdateBlock(UpdateData * data, uint32 flags ) const
void Object::BuildMovementUpdateBlock(UpdateData * data, uint16 flags ) const
{
ByteBuffer buf(500);
buf << uint8( UPDATETYPE_MOVEMENT );
buf << uint8(UPDATETYPE_MOVEMENT);
buf.append(GetPackGUID());
BuildMovementUpdate(&buf, flags, 0x00000000);
BuildMovementUpdate(&buf, flags);
data->AddUpdateBlock(buf);
}
@ -142,15 +142,14 @@ void Object::BuildCreateUpdateBlockForPlayer(UpdateData *data, Player *target) c
if(!target)
return;
uint8 updatetype = UPDATETYPE_CREATE_OBJECT;
uint16 flags = m_updateFlag;
uint32 flags2 = 0;
uint8 updatetype = UPDATETYPE_CREATE_OBJECT;
uint16 updateFlags = m_updateFlag;
/** lower flag1 **/
if(target == this) // building packet for yourself
flags |= UPDATEFLAG_SELF;
updateFlags |= UPDATEFLAG_SELF;
if(flags & UPDATEFLAG_HAS_POSITION)
if(updateFlags & UPDATEFLAG_HAS_POSITION)
{
// UPDATETYPE_CREATE_OBJECT2 dynamic objects, corpses...
if(isType(TYPEMASK_DYNAMICOBJECT) || isType(TYPEMASK_CORPSE) || isType(TYPEMASK_PLAYER))
@ -172,7 +171,7 @@ void Object::BuildCreateUpdateBlockForPlayer(UpdateData *data, Player *target) c
updatetype = UPDATETYPE_CREATE_OBJECT2;
break;
case GAMEOBJECT_TYPE_TRANSPORT:
flags |= UPDATEFLAG_TRANSPORT;
updateFlags |= UPDATEFLAG_TRANSPORT;
break;
default:
break;
@ -182,22 +181,22 @@ void Object::BuildCreateUpdateBlockForPlayer(UpdateData *data, Player *target) c
if(isType(TYPEMASK_UNIT))
{
if(((Unit*)this)->getVictim())
flags |= UPDATEFLAG_HAS_ATTACKING_TARGET;
updateFlags |= UPDATEFLAG_HAS_ATTACKING_TARGET;
}
}
//sLog.outDebug("BuildCreateUpdate: update-type: %u, object-type: %u got flags: %X, flags2: %X", updatetype, m_objectTypeId, flags, flags2);
//sLog.outDebug("BuildCreateUpdate: update-type: %u, object-type: %u got updateFlags: %X", updatetype, m_objectTypeId, updateFlags);
ByteBuffer buf(500);
buf << (uint8)updatetype;
buf << uint8(updatetype);
buf.append(GetPackGUID());
buf << (uint8)m_objectTypeId;
buf << uint8(m_objectTypeId);
BuildMovementUpdate(&buf, flags, flags2);
BuildMovementUpdate(&buf, updateFlags);
UpdateMask updateMask;
updateMask.SetCount( m_valuesCount );
_SetCreateBits( &updateMask, target );
updateMask.SetCount(m_valuesCount);
_SetCreateBits(&updateMask, target);
BuildValuesUpdate(updatetype, &buf, &updateMask, target);
data->AddUpdateBlock(buf);
}
@ -217,13 +216,13 @@ void Object::BuildValuesUpdateBlockForPlayer(UpdateData *data, Player *target) c
{
ByteBuffer buf(500);
buf << (uint8) UPDATETYPE_VALUES;
buf << uint8(UPDATETYPE_VALUES);
buf.append(GetPackGUID());
UpdateMask updateMask;
updateMask.SetCount( m_valuesCount );
updateMask.SetCount(m_valuesCount);
_SetUpdateBits( &updateMask, target );
_SetUpdateBits(&updateMask, target);
BuildValuesUpdate(UPDATETYPE_VALUES, &buf, &updateMask, target);
data->AddUpdateBlock(buf);
@ -241,12 +240,12 @@ void Object::DestroyForPlayer( Player *target, bool anim ) const
WorldPacket data(SMSG_DESTROY_OBJECT, 8);
data << uint64(GetGUID());
data << uint8(anim ? 1 : 0); // WotLK (bool), may be despawn animation
target->GetSession()->SendPacket( &data );
target->GetSession()->SendPacket(&data);
}
void Object::BuildMovementUpdate(ByteBuffer * data, uint16 updateFlags, uint32 moveFlags) const
void Object::BuildMovementUpdate(ByteBuffer * data, uint16 updateFlags) const
{
uint16 moveFlags2 = ((GetTypeId() == TYPEID_PLAYER) ? ((Player*)this)->m_movementInfo.moveFlags2 : MOVEFLAG2_NONE);
uint16 moveFlags2 = (isType(TYPEMASK_UNIT) ? ((Unit*)this)->m_movementInfo.GetMovementFlags2() : MOVEFLAG2_NONE);
if(GetTypeId() == TYPEID_UNIT)
if(((Creature*)this)->isVehicle())
@ -257,162 +256,97 @@ void Object::BuildMovementUpdate(ByteBuffer * data, uint16 updateFlags, uint32 m
// 0x20
if (updateFlags & UPDATEFLAG_LIVING)
{
Unit *unit = ((Unit*)this);
switch(GetTypeId())
{
case TYPEID_UNIT:
{
moveFlags = MOVEMENTFLAG_NONE;
unit->m_movementInfo.SetMovementFlags(MOVEFLAG_NONE);
// disabled, makes them run-in-same-place before movement generator updated once.
/*if (((Creature*)this)->hasUnitState(UNIT_STAT_MOVING))
moveFlags |= MOVEMENTFLAG_FORWARD;*/ // not set if not really moving
/*if (((Creature*)unit)->hasUnitState(UNIT_STAT_MOVING))
unit->m_movementInfo.SetMovementFlags(MOVEFLAG_FORWARD);*/
if (((Creature*)this)->canFly())
if (((Creature*)unit)->canFly())
{
moveFlags |= MOVEMENTFLAG_LEVITATING; // (ok) most seem to have this
// (ok) most seem to have this
unit->m_movementInfo.AddMovementFlag(MOVEFLAG_LEVITATING);
if (!((Creature*)this)->hasUnitState(UNIT_STAT_MOVING))
moveFlags |= MOVEMENTFLAG_FLY_UNK1; // (ok) possibly some "hover" mode
if (!((Creature*)unit)->hasUnitState(UNIT_STAT_MOVING))
{
// (ok) possibly some "hover" mode
unit->m_movementInfo.AddMovementFlag(MOVEFLAG_FLY_UNK1);
}
else
{
if (((Creature*)this)->IsMounted())
moveFlags |= MOVEMENTFLAG_FLYING;// seems to be often when mounted
/* for further research
else
moveFlags |= MOVEMENTFLAG_FLYING2;// not seen, but work on some, even if not "correct"
*/
if (((Creature*)unit)->IsMounted())
{
// seems to be often when mounted
unit->m_movementInfo.AddMovementFlag(MOVEFLAG_FLYING);
}
}
}
}
break;
case TYPEID_PLAYER:
{
moveFlags = ((Player*)this)->m_movementInfo.GetMovementFlags();
Player *player = ((Player*)unit);
if(((Player*)this)->GetTransport())
moveFlags |= MOVEMENTFLAG_ONTRANSPORT;
if(player->GetTransport())
player->m_movementInfo.AddMovementFlag(MOVEFLAG_ONTRANSPORT);
else
moveFlags &= ~MOVEMENTFLAG_ONTRANSPORT;
player->m_movementInfo.RemoveMovementFlag(MOVEFLAG_ONTRANSPORT);
// remove unknown, unused etc flags for now
moveFlags &= ~MOVEMENTFLAG_SPLINE2; // will be set manually
player->m_movementInfo.RemoveMovementFlag(MOVEFLAG_SPLINE2);
if(((Player*)this)->isInFlight())
if(player->isInFlight())
{
ASSERT(((Player*)this)->GetMotionMaster()->GetCurrentMovementGeneratorType() == FLIGHT_MOTION_TYPE);
moveFlags = (MOVEMENTFLAG_FORWARD | MOVEMENTFLAG_SPLINE2);
ASSERT(player->GetMotionMaster()->GetCurrentMovementGeneratorType() == FLIGHT_MOTION_TYPE);
player->m_movementInfo.AddMovementFlag(MOVEFLAG_FORWARD);
player->m_movementInfo.AddMovementFlag(MOVEFLAG_SPLINE2);
}
}
break;
}
*data << uint32(moveFlags); // movement flags
*data << uint16(moveFlags2); // moveFlags2
*data << uint32(getMSTime()); // time (in milliseconds)
// Update movement info time
unit->m_movementInfo.UpdateTime(getMSTime());
// Write movement info
unit->m_movementInfo.Write(*data);
// position
*data << float(((WorldObject*)this)->GetPositionX());
*data << float(((WorldObject*)this)->GetPositionY());
*data << float(((WorldObject*)this)->GetPositionZ());
*data << float(((WorldObject*)this)->GetOrientation());
// 0x00000200
if(moveFlags & MOVEMENTFLAG_ONTRANSPORT)
{
if(GetTypeId() == TYPEID_PLAYER)
{
data->append(((Player*)this)->GetTransport()->GetPackGUID());
*data << float(((Player*)this)->GetTransOffsetX());
*data << float(((Player*)this)->GetTransOffsetY());
*data << float(((Player*)this)->GetTransOffsetZ());
*data << float(((Player*)this)->GetTransOffsetO());
*data << uint32(((Player*)this)->GetTransTime());
*data << int8(((Player*)this)->GetTransSeat());
if(moveFlags2 & MOVEFLAG2_UNK1)
*data << uint32(0); // unkTime, added in 3.3.0
}
else
{
//MaNGOS currently not have support for other than player on transport
*data << uint8(0);
*data << float(0) << float(0) << float(0) << float(0);
*data << uint32(0);
*data << uint8(-1);
if(moveFlags2 & MOVEFLAG2_UNK1)
*data << uint32(0); // unkTime, added in 3.3.0
}
}
// 0x02200000
if((moveFlags & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING)) || (moveFlags2 & MOVEFLAG2_ALLOW_PITCHING))
{
if(GetTypeId() == TYPEID_PLAYER)
*data << float(((Player*)this)->m_movementInfo.s_pitch);
else
*data << float(0); // is't part of movement packet, we must store and send it...
}
if(GetTypeId() == TYPEID_PLAYER)
*data << uint32(((Player*)this)->m_movementInfo.fallTime);
else
*data << uint32(0); // last fall time
// 0x00001000
if(moveFlags & MOVEMENTFLAG_JUMPING)
{
if(GetTypeId() == TYPEID_PLAYER)
{
*data << float(((Player*)this)->m_movementInfo.j_velocity);
*data << float(((Player*)this)->m_movementInfo.j_sinAngle);
*data << float(((Player*)this)->m_movementInfo.j_cosAngle);
*data << float(((Player*)this)->m_movementInfo.j_xyspeed);
}
else
{
*data << float(0);
*data << float(0);
*data << float(0);
*data << float(0);
}
}
// 0x04000000
if(moveFlags & MOVEMENTFLAG_SPLINE)
{
if(GetTypeId() == TYPEID_PLAYER)
*data << float(((Player*)this)->m_movementInfo.u_unk1);
else
*data << float(0);
}
*data << float(((Unit*)this)->GetSpeed(MOVE_WALK));
*data << float(((Unit*)this)->GetSpeed(MOVE_RUN));
*data << float(((Unit*)this)->GetSpeed(MOVE_SWIM_BACK));
*data << float(((Unit*)this)->GetSpeed(MOVE_SWIM));
*data << float(((Unit*)this)->GetSpeed(MOVE_RUN_BACK));
*data << float(((Unit*)this)->GetSpeed(MOVE_FLIGHT));
*data << float(((Unit*)this)->GetSpeed(MOVE_FLIGHT_BACK));
*data << float(((Unit*)this)->GetSpeed(MOVE_TURN_RATE));
*data << float(((Unit*)this)->GetSpeed(MOVE_PITCH_RATE));
// Unit speeds
*data << float(unit->GetSpeed(MOVE_WALK));
*data << float(unit->GetSpeed(MOVE_RUN));
*data << float(unit->GetSpeed(MOVE_SWIM_BACK));
*data << float(unit->GetSpeed(MOVE_SWIM));
*data << float(unit->GetSpeed(MOVE_RUN_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));
// 0x08000000
if(moveFlags & MOVEMENTFLAG_SPLINE2)
if(unit->m_movementInfo.GetMovementFlags() & MOVEFLAG_SPLINE2)
{
if(GetTypeId() != TYPEID_PLAYER)
{
sLog.outDebug("_BuildMovementUpdate: MOVEMENTFLAG_SPLINE2 for non-player");
sLog.outDebug("_BuildMovementUpdate: MOVEFLAG_SPLINE2 for non-player");
return;
}
if(!((Player*)this)->isInFlight())
Player *player = ((Player*)unit);
if(!player->isInFlight())
{
sLog.outDebug("_BuildMovementUpdate: MOVEMENTFLAG_SPLINE2 but not in flight");
sLog.outDebug("_BuildMovementUpdate: MOVEFLAG_SPLINE2 but not in flight");
return;
}
ASSERT(((Player*)this)->GetMotionMaster()->GetCurrentMovementGeneratorType() == FLIGHT_MOTION_TYPE);
ASSERT(player->GetMotionMaster()->GetCurrentMovementGeneratorType() == FLIGHT_MOTION_TYPE);
FlightPathMovementGenerator *fmg = (FlightPathMovementGenerator*)(((Player*)this)->GetMotionMaster()->top());
FlightPathMovementGenerator *fmg = (FlightPathMovementGenerator*)(player->GetMotionMaster()->top());
uint32 flags3 = MONSTER_MOVE_SPLINE_FLY;
@ -442,7 +376,7 @@ void Object::BuildMovementUpdate(ByteBuffer * data, uint16 updateFlags, uint32 m
Path &path = fmg->GetPath();
float x, y, z;
((Player*)this)->GetPosition(x, y, z);
player->GetPosition(x, y, z);
uint32 inflighttime = uint32(path.GetPassedLength(fmg->GetCurrentNode(), x, y, z) * 32);
uint32 traveltime = uint32(path.GetTotalLength() * 32);
@ -1167,6 +1101,27 @@ void WorldObject::_Create( uint32 guidlow, HighGuid guidhigh, uint32 phaseMask )
m_phaseMask = phaseMask;
}
void WorldObject::Relocate(float x, float y, float z, float orientation)
{
m_positionX = x;
m_positionY = y;
m_positionZ = z;
m_orientation = orientation;
if(isType(TYPEMASK_UNIT))
((Unit*)this)->m_movementInfo.ChangePosition(x, y, z, orientation);
}
void WorldObject::Relocate(float x, float y, float z)
{
m_positionX = x;
m_positionY = y;
m_positionZ = z;
if(isType(TYPEMASK_UNIT))
((Unit*)this)->m_movementInfo.ChangePosition(x, y, z, GetOrientation());
}
uint32 WorldObject::GetZoneId() const
{
return GetBaseMap()->GetZoneId(m_positionX, m_positionY, m_positionZ);

View file

@ -154,7 +154,7 @@ class MANGOS_DLL_SPEC Object
void BuildValuesUpdateBlockForPlayer( UpdateData *data, Player *target ) const;
void BuildOutOfRangeUpdateBlock( UpdateData *data ) const;
void BuildMovementUpdateBlock( UpdateData * data, uint32 flags = 0 ) const;
void BuildMovementUpdateBlock( UpdateData * data, uint16 flags = 0 ) const;
virtual void DestroyForPlayer( Player *target, bool anim = false ) const;
@ -288,7 +288,7 @@ class MANGOS_DLL_SPEC Object
void ApplyModFlag64( uint16 index, uint64 flag, bool apply)
{
if(apply) SetFlag64(index,flag); else RemoveFlag64(index,flag);
if(apply) SetFlag64(index,flag); else RemoveFlag64(index, flag);
}
void ClearUpdateMask(bool remove);
@ -312,7 +312,7 @@ class MANGOS_DLL_SPEC Object
virtual void _SetCreateBits(UpdateMask *updateMask, Player *target) const;
void BuildMovementUpdate(ByteBuffer * data, uint16 updateFlags, uint32 moveFlags ) const;
void BuildMovementUpdate(ByteBuffer * data, uint16 updateFlags) const;
void BuildValuesUpdate(uint8 updatetype, ByteBuffer *data, UpdateMask *updateMask, Player *target ) const;
void BuildUpdateDataForPlayer(Player* pl, UpdateDataMapType& update_players);
@ -358,20 +358,8 @@ class MANGOS_DLL_SPEC WorldObject : public Object
void _Create( uint32 guidlow, HighGuid guidhigh, uint32 phaseMask);
void Relocate(float x, float y, float z, float orientation)
{
m_positionX = x;
m_positionY = y;
m_positionZ = z;
m_orientation = orientation;
}
void Relocate(float x, float y, float z)
{
m_positionX = x;
m_positionY = y;
m_positionZ = z;
}
void Relocate(float x, float y, float z, float orientation);
void Relocate(float x, float y, float z);
void SetOrientation(float orientation) { m_orientation = orientation; }

View file

@ -1651,18 +1651,13 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
{
m_transport->RemovePassenger(this);
m_transport = NULL;
m_movementInfo.t_x = 0.0f;
m_movementInfo.t_y = 0.0f;
m_movementInfo.t_z = 0.0f;
m_movementInfo.t_o = 0.0f;
m_movementInfo.t_seat = -1;
m_movementInfo.t_time = 0;
m_movementInfo.SetTransportData(0, 0.0f, 0.0f, 0.0f, 0.0f, 0, -1);
}
// The player was ported to another map and looses the duel immediately.
// We have to perform this check before the teleport, otherwise the
// ObjectAccessor won't find the flag.
if (duel && GetMapId()!=mapid)
if (duel && GetMapId() != mapid)
{
GameObject* obj = GetMap()->GetGameObject(GetUInt64Value(PLAYER_DUEL_ARBITER));
if (obj)
@ -1670,7 +1665,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
}
// reset movement flags at teleport, because player will continue move with these flags after teleport
m_movementInfo.SetMovementFlags(MOVEMENTFLAG_NONE);
m_movementInfo.SetMovementFlags(MOVEFLAG_NONE);
if ((GetMapId() == mapid) && (!m_transport))
{
@ -1692,7 +1687,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
if (!(options & TELE_TO_NOT_UNSUMMON_PET))
{
//same map, only remove pet if out of range for new position
if(pet && !pet->IsWithinDist3d(x,y,z,GetMap()->GetVisibilityDistance()))
if(pet && !pet->IsWithinDist3d(x, y, z, GetMap()->GetVisibilityDistance()))
UnsummonPetTemporaryIfAny();
}
@ -1784,18 +1779,27 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
data << uint32(mapid);
if (m_transport)
{
data << m_transport->GetEntry() << GetMapId();
data << uint32(m_transport->GetEntry());
data << uint32(GetMapId());
}
GetSession()->SendPacket(&data);
data.Initialize(SMSG_NEW_WORLD, (20));
if (m_transport)
{
data << (uint32)mapid << m_movementInfo.t_x << m_movementInfo.t_y << m_movementInfo.t_z << m_movementInfo.t_o;
data << uint32(mapid);
data << float(m_movementInfo.GetTransportPos()->x);
data << float(m_movementInfo.GetTransportPos()->y);
data << float(m_movementInfo.GetTransportPos()->z);
data << float(m_movementInfo.GetTransportPos()->o);
}
else
{
data << (uint32)mapid << (float)x << (float)y << (float)z << (float)orientation;
data << uint32(mapid);
data << float(x);
data << float(y);
data << float(z);
data << float(orientation);
}
GetSession()->SendPacket( &data );
SendSavedInstances();
@ -1813,15 +1817,15 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
if(m_transport)
{
final_x += m_movementInfo.t_x;
final_y += m_movementInfo.t_y;
final_z += m_movementInfo.t_z;
final_o += m_movementInfo.t_o;
final_x += m_movementInfo.GetTransportPos()->x;
final_y += m_movementInfo.GetTransportPos()->y;
final_z += m_movementInfo.GetTransportPos()->z;
final_o += m_movementInfo.GetTransportPos()->o;
}
m_teleport_dest = WorldLocation(mapid, final_x, final_y, final_z, final_o);
SetFallInformation(0, final_z);
// if the player is saved before worldportack (at logout for example)
// if the player is saved before worldport ack (at logout for example)
// this will be used instead of the current location in SaveToDB
// move packet sent by client always after far teleport
@ -14721,12 +14725,7 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
transGUID = 0;
m_movementInfo.t_x = 0.0f;
m_movementInfo.t_y = 0.0f;
m_movementInfo.t_z = 0.0f;
m_movementInfo.t_o = 0.0f;
m_movementInfo.t_time = 0;
m_movementInfo.t_seat = -1;
m_movementInfo.SetTransportData(0, 0.0f, 0.0f, 0.0f, 0.0f, 0, -1);
}
_LoadBGData(holder->GetResult(PLAYER_LOGIN_QUERY_LOADBGDATA));
@ -14780,29 +14779,21 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
if (transGUID != 0)
{
m_movementInfo.t_x = fields[27].GetFloat();
m_movementInfo.t_y = fields[28].GetFloat();
m_movementInfo.t_z = fields[29].GetFloat();
m_movementInfo.t_o = fields[30].GetFloat();
m_movementInfo.SetTransportData(transGUID, fields[27].GetFloat(), fields[28].GetFloat(), fields[29].GetFloat(), fields[30].GetFloat(), 0, -1);
if( !MaNGOS::IsValidMapCoord(
GetPositionX()+m_movementInfo.t_x,GetPositionY()+m_movementInfo.t_y,
GetPositionZ()+m_movementInfo.t_z,GetOrientation()+m_movementInfo.t_o) ||
GetPositionX() + m_movementInfo.GetTransportPos()->x, GetPositionY() + m_movementInfo.GetTransportPos()->y,
GetPositionZ() + m_movementInfo.GetTransportPos()->z, GetOrientation() + m_movementInfo.GetTransportPos()->o) ||
// transport size limited
m_movementInfo.t_x > 50 || m_movementInfo.t_y > 50 || m_movementInfo.t_z > 50 )
m_movementInfo.GetTransportPos()->x > 50 || m_movementInfo.GetTransportPos()->y > 50 || m_movementInfo.GetTransportPos()->z > 50 )
{
sLog.outError("Player (guidlow %d) have invalid transport coordinates (X: %f Y: %f Z: %f O: %f). Teleport to default race/class locations.",
guid,GetPositionX()+m_movementInfo.t_x,GetPositionY()+m_movementInfo.t_y,
GetPositionZ()+m_movementInfo.t_z,GetOrientation()+m_movementInfo.t_o);
guid, GetPositionX() + m_movementInfo.GetTransportPos()->x, GetPositionY() + m_movementInfo.GetTransportPos()->y,
GetPositionZ() + m_movementInfo.GetTransportPos()->z, GetOrientation() + m_movementInfo.GetTransportPos()->o);
RelocateToHomebind();
m_movementInfo.t_x = 0.0f;
m_movementInfo.t_y = 0.0f;
m_movementInfo.t_z = 0.0f;
m_movementInfo.t_o = 0.0f;
m_movementInfo.t_time = 0;
m_movementInfo.t_seat = -1;
m_movementInfo.SetTransportData(0, 0.0f, 0.0f, 0.0f, 0.0f, 0, -1);
transGUID = 0;
}
@ -14836,12 +14827,7 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
RelocateToHomebind();
m_movementInfo.t_x = 0.0f;
m_movementInfo.t_y = 0.0f;
m_movementInfo.t_z = 0.0f;
m_movementInfo.t_o = 0.0f;
m_movementInfo.t_time = 0;
m_movementInfo.t_seat = -1;
m_movementInfo.SetTransportData(0, 0.0f, 0.0f, 0.0f, 0.0f, 0, -1);
transGUID = 0;
}
@ -16199,10 +16185,10 @@ void Player::SaveToDB()
ss << m_resetTalentsCost << ", ";
ss << (uint64)m_resetTalentsTime << ", ";
ss << finiteAlways(m_movementInfo.t_x) << ", ";
ss << finiteAlways(m_movementInfo.t_y) << ", ";
ss << finiteAlways(m_movementInfo.t_z) << ", ";
ss << finiteAlways(m_movementInfo.t_o) << ", ";
ss << finiteAlways(m_movementInfo.GetTransportPos()->x) << ", ";
ss << finiteAlways(m_movementInfo.GetTransportPos()->y) << ", ";
ss << finiteAlways(m_movementInfo.GetTransportPos()->z) << ", ";
ss << finiteAlways(m_movementInfo.GetTransportPos()->o) << ", ";
if (m_transport)
ss << m_transport->GetGUIDLow();
else
@ -18883,7 +18869,7 @@ void Player::SendInitialPacketsBeforeAddToMap()
// set fly flag if in fly form or taxi flight to prevent visually drop at ground in showup moment
if(HasAuraType(SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED) || HasAuraType(SPELL_AURA_FLY) || isInFlight())
m_movementInfo.AddMovementFlag(MOVEMENTFLAG_FLYING);
m_movementInfo.AddMovementFlag(MOVEFLAG_FLYING);
m_mover = this;
}
@ -20182,7 +20168,7 @@ void Player::EnterVehicle(Vehicle *vehicle)
data.Initialize(MSG_MOVE_TELEPORT_ACK, 30);
data.append(GetPackGUID());
data << uint32(0); // counter?
data << uint32(MOVEMENTFLAG_ONTRANSPORT); // transport
data << uint32(MOVEFLAG_ONTRANSPORT); // transport
data << uint16(0); // special flags
data << uint32(getMSTime()); // time
data << vehicle->GetPositionX(); // x
@ -20231,7 +20217,7 @@ void Player::ExitVehicle(Vehicle *vehicle)
WorldPacket data(MSG_MOVE_TELEPORT_ACK, 30);
data.append(GetPackGUID());
data << uint32(0); // counter?
data << uint32(MOVEMENTFLAG_FLY_UNK1); // fly unk
data << uint32(MOVEFLAG_FLY_UNK1); // fly unk
data << uint16(0x40); // special flags
data << uint32(getMSTime()); // time
data << vehicle->GetPositionX(); // x
@ -20244,7 +20230,7 @@ void Player::ExitVehicle(Vehicle *vehicle)
RemovePetActionBar();
// maybe called at dummy aura remove?
// CastSpell(this, 45472, true); // Parachute
// CastSpell(this, 45472, true); // Parachute
}
bool Player::isTotalImmune()
@ -20616,7 +20602,7 @@ uint8 Player::CanEquipUniqueItem( ItemPrototype const* itemProto, uint8 except_s
void Player::HandleFall(MovementInfo const& movementInfo)
{
// calculate total z distance of the fall
float z_diff = m_lastFallZ - movementInfo.z;
float z_diff = m_lastFallZ - movementInfo.GetPos()->z;
sLog.outDebug("zDiff = %f", z_diff);
//Players with low fall distance, Feather Fall or physical immunity (charges used) are ignored
@ -20634,8 +20620,8 @@ void Player::HandleFall(MovementInfo const& movementInfo)
{
uint32 damage = (uint32)(damageperc * GetMaxHealth()*sWorld.getRate(RATE_DAMAGE_FALL));
float height = movementInfo.z;
UpdateGroundPositionZ(movementInfo.x,movementInfo.y,height);
float height = movementInfo.GetPos()->z;
UpdateGroundPositionZ(movementInfo.GetPos()->x, movementInfo.GetPos()->y, height);
if (damage > 0)
{
@ -20656,7 +20642,7 @@ void Player::HandleFall(MovementInfo const& movementInfo)
}
//Z given by moveinfo, LastZ, FallTime, WaterZ, MapZ, Damage, Safefall reduction
DEBUG_LOG("FALLDAMAGE z=%f sz=%f pZ=%f FallTime=%d mZ=%f damage=%d SF=%d" , movementInfo.z, height, GetPositionZ(), movementInfo.fallTime, height, damage, safe_fall);
DEBUG_LOG("FALLDAMAGE z=%f sz=%f pZ=%f FallTime=%d mZ=%f damage=%d SF=%d" , movementInfo.GetPos()->z, height, GetPositionZ(), movementInfo.GetFallTime(), height, damage, safe_fall);
}
}
}
@ -20920,16 +20906,16 @@ void Player::UpdateKnownCurrencies(uint32 itemId, bool apply)
if(CurrencyTypesEntry const* ctEntry = sCurrencyTypesStore.LookupEntry(itemId))
{
if(apply)
SetFlag64(PLAYER_FIELD_KNOWN_CURRENCIES,(UI64LIT(1) << (ctEntry->BitIndex-1)));
SetFlag64(PLAYER_FIELD_KNOWN_CURRENCIES, (UI64LIT(1) << (ctEntry->BitIndex - 1)));
else
RemoveFlag64(PLAYER_FIELD_KNOWN_CURRENCIES,(UI64LIT(1) << (ctEntry->BitIndex-1)));
RemoveFlag64(PLAYER_FIELD_KNOWN_CURRENCIES, (UI64LIT(1) << (ctEntry->BitIndex - 1)));
}
}
void Player::UpdateFallInformationIfNeed( MovementInfo const& minfo,uint16 opcode )
{
if (m_lastFallTime >= minfo.fallTime || m_lastFallZ <=minfo.z || opcode == MSG_MOVE_FALL_LAND)
SetFallInformation(minfo.fallTime, minfo.z);
if (m_lastFallTime >= minfo.GetFallTime() || m_lastFallZ <= minfo.GetPos()->z || opcode == MSG_MOVE_FALL_LAND)
SetFallInformation(minfo.GetFallTime(), minfo.GetPos()->z);
}
void Player::UnsummonPetTemporaryIfAny()

View file

@ -45,13 +45,15 @@ struct Mail;
class Channel;
class DynamicObject;
class Creature;
class Pet;
class PlayerMenu;
class Transport;
class UpdateMask;
class SpellCastTargets;
class PlayerSocial;
class Vehicle;
class InstanceSave;
class Spell;
class Item;
typedef std::deque<Mail*> PlayerMails;
@ -610,11 +612,6 @@ struct SkillStatusData
typedef UNORDERED_MAP<uint32, SkillStatusData> SkillStatusMap;
class Quest;
class Spell;
class Item;
class WorldSession;
enum PlayerSlots
{
// first slot for item stored (in any way in player m_items data)
@ -779,89 +776,7 @@ enum ArenaTeamInfoType
ARENA_TEAM_END = 7
};
// used in most movement packets (send and received)
enum MovementFlags
{
MOVEMENTFLAG_NONE = 0x00000000,
MOVEMENTFLAG_FORWARD = 0x00000001,
MOVEMENTFLAG_BACKWARD = 0x00000002,
MOVEMENTFLAG_STRAFE_LEFT = 0x00000004,
MOVEMENTFLAG_STRAFE_RIGHT = 0x00000008,
MOVEMENTFLAG_LEFT = 0x00000010,
MOVEMENTFLAG_RIGHT = 0x00000020,
MOVEMENTFLAG_PITCH_UP = 0x00000040,
MOVEMENTFLAG_PITCH_DOWN = 0x00000080,
MOVEMENTFLAG_WALK_MODE = 0x00000100, // Walking
MOVEMENTFLAG_ONTRANSPORT = 0x00000200, // Used for flying on some creatures
MOVEMENTFLAG_LEVITATING = 0x00000400,
MOVEMENTFLAG_FLY_UNK1 = 0x00000800,
MOVEMENTFLAG_JUMPING = 0x00001000,
MOVEMENTFLAG_FALLING = 0x00002000,
MOVEMENTFLAG_UNK4 = 0x00004000,
// 0x8000, 0x10000, 0x20000, 0x40000, 0x80000, 0x100000
MOVEMENTFLAG_SWIMMING = 0x00200000, // appears with fly flag also
MOVEMENTFLAG_FLY_UP = 0x00400000, // swim up also
MOVEMENTFLAG_FLY_DOWN = 0x00800000, // swim down also
MOVEMENTFLAG_CAN_FLY = 0x01000000, // can fly in 3.3?
MOVEMENTFLAG_FLYING = 0x02000000, // Actual flying mode
MOVEMENTFLAG_SPLINE = 0x04000000, // used for flight paths
MOVEMENTFLAG_SPLINE2 = 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_UNK3 = 0x40000000
};
struct MovementInfo
{
// common
uint64 guid;
uint32 flags; // see enum MovementFlags
uint16 moveFlags2;
uint32 time;
float x, y, z, o;
// transport
uint64 t_guid;
float t_x, t_y, t_z, t_o;
uint32 t_time;
int8 t_seat;
uint32 t_time2;
// swimming and unknown
float s_pitch;
// last fall time
uint32 fallTime;
// jumping
float j_velocity, j_sinAngle, j_cosAngle, j_xyspeed;
// spline
float u_unk1;
MovementInfo()
{
flags = MOVEMENTFLAG_NONE;
time = t_time = t_time2 = fallTime = 0;
moveFlags2 = 0;
x = y = z = o = t_x = t_y = t_z = t_o = s_pitch = j_velocity = j_sinAngle = j_cosAngle = j_xyspeed = u_unk1 = 0.0f;
t_guid = 0;
}
void AddMovementFlag(MovementFlags f) { flags |= f; }
void RemoveMovementFlag(MovementFlags f) { flags &= ~f; }
bool HasMovementFlag(MovementFlags f) const { return flags & f; }
MovementFlags GetMovementFlags() const { return MovementFlags(flags); }
void SetMovementFlags(MovementFlags f) { flags = f; }
};
// flags that use in movement check for example at spell casting
MovementFlags const movementFlagsMask = MovementFlags(
MOVEMENTFLAG_FORWARD |MOVEMENTFLAG_BACKWARD |MOVEMENTFLAG_STRAFE_LEFT |MOVEMENTFLAG_STRAFE_RIGHT|
MOVEMENTFLAG_PITCH_UP|MOVEMENTFLAG_PITCH_DOWN|MOVEMENTFLAG_FLY_UNK1 |
MOVEMENTFLAG_JUMPING |MOVEMENTFLAG_FALLING |MOVEMENTFLAG_FLY_UP |
MOVEMENTFLAG_FLYING |MOVEMENTFLAG_SPLINE
);
MovementFlags const movementOrTurningFlagsMask = MovementFlags(
movementFlagsMask | MOVEMENTFLAG_LEFT | MOVEMENTFLAG_RIGHT
);
class InstanceSave;
enum RestType
{
@ -1013,8 +928,6 @@ class MANGOS_DLL_SPEC PlayerTaxi
std::ostringstream& operator<< (std::ostringstream& ss, PlayerTaxi const& taxi);
class Player;
/// Holder for BattleGround data
struct BGData
{
@ -2156,7 +2069,6 @@ class MANGOS_DLL_SPEC Player : public Unit
/*********************************************************/
/*** VARIOUS SYSTEMS ***/
/*********************************************************/
MovementInfo m_movementInfo;
bool HasMovementFlag(MovementFlags f) const; // for script access to m_movementInfo.HasMovementFlag
void UpdateFallInformationIfNeed(MovementInfo const& minfo,uint16 opcode);
Unit *m_mover;
@ -2172,8 +2084,8 @@ class MANGOS_DLL_SPEC Player : public Unit
bool isMoving() const { return m_movementInfo.HasMovementFlag(movementFlagsMask); }
bool isMovingOrTurning() const { return m_movementInfo.HasMovementFlag(movementOrTurningFlagsMask); }
bool CanFly() const { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_CAN_FLY); }
bool IsFlying() const { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_FLYING); }
bool CanFly() const { return m_movementInfo.HasMovementFlag(MOVEFLAG_CAN_FLY); }
bool IsFlying() const { return m_movementInfo.HasMovementFlag(MOVEFLAG_FLYING); }
bool IsKnowHowFlyIn(uint32 mapid, uint32 zone) const;
void SetClientControl(Unit* target, uint8 allowMove);
@ -2189,12 +2101,12 @@ class MANGOS_DLL_SPEC Player : public Unit
Transport * GetTransport() const { return m_transport; }
void SetTransport(Transport * t) { m_transport = t; }
float GetTransOffsetX() const { return m_movementInfo.t_x; }
float GetTransOffsetY() const { return m_movementInfo.t_y; }
float GetTransOffsetZ() const { return m_movementInfo.t_z; }
float GetTransOffsetO() const { return m_movementInfo.t_o; }
uint32 GetTransTime() const { return m_movementInfo.t_time; }
int8 GetTransSeat() const { return m_movementInfo.t_seat; }
float GetTransOffsetX() const { return m_movementInfo.GetTransportPos()->x; }
float GetTransOffsetY() const { return m_movementInfo.GetTransportPos()->y; }
float GetTransOffsetZ() const { return m_movementInfo.GetTransportPos()->z; }
float GetTransOffsetO() const { return m_movementInfo.GetTransportPos()->o; }
uint32 GetTransTime() const { return m_movementInfo.GetTransportTime(); }
int8 GetTransSeat() const { return m_movementInfo.GetTransportSeat(); }
uint32 GetSaveTimer() const { return m_nextSave; }
void SetSaveTimer(uint32 timer) { m_nextSave = timer; }
@ -2208,8 +2120,8 @@ class MANGOS_DLL_SPEC Player : public Unit
void SaveRecallPosition();
void SetHomebindToCurrentPos();
void RelocateToHomebind() { SetLocationMapId(m_homebindMapId); Relocate(m_homebindX,m_homebindY,m_homebindZ); }
bool TeleportToHomebind(uint32 options = 0) { return TeleportTo(m_homebindMapId, m_homebindX, m_homebindY, m_homebindZ, GetOrientation(),options); }
void RelocateToHomebind() { SetLocationMapId(m_homebindMapId); Relocate(m_homebindX, m_homebindY, m_homebindZ); }
bool TeleportToHomebind(uint32 options = 0) { return TeleportTo(m_homebindMapId, m_homebindX, m_homebindY, m_homebindZ, GetOrientation(), options); }
// currently visible objects at player client
typedef std::set<uint64> ClientGUIDs;

View file

@ -2890,7 +2890,7 @@ void Spell::update(uint32 difftime)
// check if the player caster has moved before the spell finished
if ((m_caster->GetTypeId() == TYPEID_PLAYER && m_timer != 0) &&
(m_castPositionX != m_caster->GetPositionX() || m_castPositionY != m_caster->GetPositionY() || m_castPositionZ != m_caster->GetPositionZ()) &&
(m_spellInfo->Effect[0] != SPELL_EFFECT_STUCK || !((Player*)m_caster)->m_movementInfo.HasMovementFlag(MOVEMENTFLAG_FALLING)))
(m_spellInfo->Effect[0] != SPELL_EFFECT_STUCK || !((Player*)m_caster)->m_movementInfo.HasMovementFlag(MOVEFLAG_FALLING)))
{
// always cancel for channeled spells
if( m_spellState == SPELL_STATE_CASTING )
@ -2922,7 +2922,7 @@ void Spell::update(uint32 difftime)
if( m_caster->GetTypeId() == TYPEID_PLAYER )
{
// check if player has jumped before the channeling finished
if(((Player*)m_caster)->m_movementInfo.HasMovementFlag(MOVEMENTFLAG_JUMPING))
if(((Player*)m_caster)->m_movementInfo.HasMovementFlag(MOVEFLAG_JUMPING))
cancel();
// check for incapacitating player states
@ -4026,7 +4026,7 @@ SpellCastResult Spell::CheckCast(bool strict)
if( m_caster->GetTypeId() == TYPEID_PLAYER && ((Player*)m_caster)->isMoving() )
{
// skip stuck spell to allow use it in falling case and apply spell limitations at movement
if( (!((Player*)m_caster)->m_movementInfo.HasMovementFlag(MOVEMENTFLAG_FALLING) || m_spellInfo->Effect[0] != SPELL_EFFECT_STUCK) &&
if( (!((Player*)m_caster)->m_movementInfo.HasMovementFlag(MOVEFLAG_FALLING) || m_spellInfo->Effect[0] != SPELL_EFFECT_STUCK) &&
(IsAutoRepeat() || (m_spellInfo->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED) != 0) )
return SPELL_FAILED_MOVING;
}

View file

@ -3819,7 +3819,7 @@ void Aura::HandleAuraModStun(bool apply, bool Real)
m_target->StopMoving();
else
{
((Player*)m_target)->m_movementInfo.SetMovementFlags(MOVEMENTFLAG_NONE);
((Player*)m_target)->m_movementInfo.SetMovementFlags(MOVEFLAG_NONE);
m_target->SetStandState(UNIT_STAND_STATE_STAND);// in 1.5 client
}
@ -4097,7 +4097,7 @@ void Aura::HandleAuraModRoot(bool apply, bool Real)
m_target->SendMessageToSet(&data, true);
//Clear unit movement flags
((Player*)m_target)->m_movementInfo.SetMovementFlags(MOVEMENTFLAG_NONE);
((Player*)m_target)->m_movementInfo.SetMovementFlags(MOVEFLAG_NONE);
}
else
m_target->StopMoving();

View file

@ -347,8 +347,7 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
if(!recvPacket.readPackGUID(guid))
return;
MovementInfo movementInfo;
ReadMovementInfo(recvPacket, &movementInfo);
MovementInfo movementInfo(recvPacket);
}
}

View file

@ -190,16 +190,15 @@ void WorldSession::HandleMoveSplineDoneOpcode(WorldPacket& recv_data)
if(!recv_data.readPackGUID(guid))
return;
MovementInfo movementInfo; // used only for proper packet read
ReadMovementInfo(recv_data, &movementInfo);
MovementInfo movementInfo(recv_data); // used only for proper packet read
recv_data.read_skip<uint32>(); // unk
// in taxi flight packet received in 2 case:
// 1) end taxi path in far (multi-node) flight
// 2) switch from one map to other in case multim-map taxi path
// we need proccess only (1)
// 2) switch from one map to other in case multi-map taxi path
// we need process only (1)
uint32 curDest = GetPlayer()->m_taxi.GetTaxiDestination();
if(!curDest)
return;

View file

@ -112,7 +112,7 @@ inline float Traveller<Player>::Speed()
if (i_traveller.isInFlight())
return PLAYER_FLIGHT_SPEED;
else
return i_traveller.GetSpeed(i_traveller.m_movementInfo.HasMovementFlag(MOVEMENTFLAG_WALK_MODE) ? MOVE_WALK : MOVE_RUN);
return i_traveller.GetSpeed(i_traveller.m_movementInfo.HasMovementFlag(MOVEFLAG_WALK_MODE) ? MOVE_WALK : MOVE_RUN);
}
template<>
@ -137,7 +137,7 @@ inline void Traveller<Player>::Relocation(float x, float y, float z, float orien
template<>
inline void Traveller<Player>::MoveTo(float x, float y, float z, uint32 t)
{
//Only send MOVEMENTFLAG_WALK_MODE, client has strange issues with other move flags
//Only send MOVEFLAG_WALK_MODE, client has strange issues with other move flags
i_traveller.SendMonsterMove(x, y, z, 0, MONSTER_MOVE_WALK, t);
}

View file

@ -63,7 +63,7 @@ float baseMoveSpeed[MAX_MOVE_TYPE] =
3.14f // MOVE_PITCH_RATE
};
// Used for prepare can/can`t triggr aura
// Used for prepare can/can`t trigger aura
static bool InitTriggerAuraData();
// Define can trigger auras
static bool isTriggerAura[TOTAL_AURAS];
@ -72,6 +72,118 @@ static bool isNonTriggerAura[TOTAL_AURAS];
// Prepare lists
static bool procPrepared = InitTriggerAuraData();
MovementInfo::MovementInfo(WorldPacket &data)
{
// Init fields
moveFlags = MOVEFLAG_NONE;
moveFlags2 = MOVEFLAG2_NONE;
time = 0;
t_guid = 0;
t_time = 0;
t_seat = -1;
t_time2 = 0;
s_pitch = 0.0f;
fallTime = 0;
j_velocity = j_sinAngle = j_cosAngle = j_xyspeed = 0.0f;
u_unk1 = 0.0f;
// Read actual data
Read(data);
}
void MovementInfo::Read(ByteBuffer &data)
{
data >> moveFlags;
data >> moveFlags2;
data >> time;
data >> pos.x;
data >> pos.y;
data >> pos.z;
data >> pos.o;
if(HasMovementFlag(MOVEFLAG_ONTRANSPORT))
{
if(!data.readPackGUID(t_guid))
return;
data >> t_pos.x;
data >> t_pos.y;
data >> t_pos.z;
data >> t_pos.o;
data >> t_time;
data >> t_seat;
if(moveFlags2 & MOVEFLAG2_UNK1)
data >> t_time2;
}
if((HasMovementFlag(MovementFlags(MOVEFLAG_SWIMMING | MOVEFLAG_FLYING))) || (moveFlags2 & MOVEFLAG2_ALLOW_PITCHING))
{
data >> s_pitch;
}
data >> fallTime;
if(HasMovementFlag(MOVEFLAG_JUMPING))
{
data >> j_velocity;
data >> j_sinAngle;
data >> j_cosAngle;
data >> j_xyspeed;
}
if(HasMovementFlag(MOVEFLAG_SPLINE))
{
data >> u_unk1;
}
}
void MovementInfo::Write(ByteBuffer &data)
{
data << moveFlags;
data << moveFlags2;
data << time;
data << pos.x;
data << pos.y;
data << pos.z;
data << pos.o;
if(HasMovementFlag(MOVEFLAG_ONTRANSPORT))
{
data.appendPackGUID(t_guid);
data << t_pos.x;
data << t_pos.y;
data << t_pos.z;
data << t_pos.o;
data << t_time;
data << t_seat;
if(moveFlags2 & MOVEFLAG2_UNK1)
data << t_time2;
}
if((HasMovementFlag(MovementFlags(MOVEFLAG_SWIMMING | MOVEFLAG_FLYING))) || (moveFlags2 & MOVEFLAG2_ALLOW_PITCHING))
{
data << s_pitch;
}
data << fallTime;
if(HasMovementFlag(MOVEFLAG_JUMPING))
{
data << j_velocity;
data << j_sinAngle;
data << j_cosAngle;
data << j_xyspeed;
}
if(HasMovementFlag(MOVEFLAG_SPLINE))
{
data << u_unk1;
}
}
Unit::Unit()
: WorldObject(), i_motionMaster(this), m_ThreatManager(this), m_HostileRefManager(this)
{
@ -321,7 +433,7 @@ void Unit::BuildHeartBeatMsg(WorldPacket *data) const
{
MovementFlags move_flags = GetTypeId()==TYPEID_PLAYER
? ((Player const*)this)->m_movementInfo.GetMovementFlags()
: MOVEMENTFLAG_NONE;
: MOVEFLAG_NONE;
data->Initialize(MSG_MOVE_HEARTBEAT, 32);
data->append(GetPackGUID());
@ -10442,7 +10554,7 @@ void Unit::UpdateWalkMode(Unit* source, bool self)
else if (self)
{
bool on = source->GetTypeId() == TYPEID_PLAYER
? ((Player*)source)->HasMovementFlag(MOVEMENTFLAG_WALK_MODE)
? ((Player*)source)->HasMovementFlag(MOVEFLAG_WALK_MODE)
: ((Creature*)source)->HasMonsterMoveFlag(MONSTER_MOVE_WALK);
if (on)
@ -12408,7 +12520,7 @@ void Unit::SetFeignDeath(bool apply, uint64 const& casterGUID, uint32 spellID)
if(GetTypeId() != TYPEID_PLAYER)
StopMoving();
else
((Player*)this)->m_movementInfo.SetMovementFlags(MOVEMENTFLAG_NONE);
((Player*)this)->m_movementInfo.SetMovementFlags(MOVEFLAG_NONE);
// blizz like 2.0.x
SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_29);

View file

@ -650,6 +650,50 @@ enum MonsterMovementFlags
MONSTER_MOVE_SPLINE_FLY = 0x00003000, // fly by points
};
// used in most movement packets (send and received)
enum MovementFlags
{
MOVEFLAG_NONE = 0x00000000,
MOVEFLAG_FORWARD = 0x00000001,
MOVEFLAG_BACKWARD = 0x00000002,
MOVEFLAG_STRAFE_LEFT = 0x00000004,
MOVEFLAG_STRAFE_RIGHT = 0x00000008,
MOVEFLAG_LEFT = 0x00000010,
MOVEFLAG_RIGHT = 0x00000020,
MOVEFLAG_PITCH_UP = 0x00000040,
MOVEFLAG_PITCH_DOWN = 0x00000080,
MOVEFLAG_WALK_MODE = 0x00000100, // Walking
MOVEFLAG_ONTRANSPORT = 0x00000200, // Used for flying on some creatures
MOVEFLAG_LEVITATING = 0x00000400,
MOVEFLAG_FLY_UNK1 = 0x00000800,
MOVEFLAG_JUMPING = 0x00001000,
MOVEFLAG_FALLING = 0x00002000,
MOVEFLAG_UNK4 = 0x00004000,
// 0x8000, 0x10000, 0x20000, 0x40000, 0x80000, 0x100000
MOVEFLAG_SWIMMING = 0x00200000, // appears with fly flag also
MOVEFLAG_FLY_UP = 0x00400000, // swim up also
MOVEFLAG_FLY_DOWN = 0x00800000, // swim down also
MOVEFLAG_CAN_FLY = 0x01000000, // can fly in 3.3?
MOVEFLAG_FLYING = 0x02000000, // Actual flying mode
MOVEFLAG_SPLINE = 0x04000000, // used for flight paths
MOVEFLAG_SPLINE2 = 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_UNK3 = 0x40000000
};
// flags that use in movement check for example at spell casting
MovementFlags const movementFlagsMask = MovementFlags(
MOVEFLAG_FORWARD |MOVEFLAG_BACKWARD |MOVEFLAG_STRAFE_LEFT |MOVEFLAG_STRAFE_RIGHT|
MOVEFLAG_PITCH_UP|MOVEFLAG_PITCH_DOWN|MOVEFLAG_FLY_UNK1 |
MOVEFLAG_JUMPING |MOVEFLAG_FALLING |MOVEFLAG_FLY_UP |
MOVEFLAG_FLYING |MOVEFLAG_SPLINE
);
MovementFlags const movementOrTurningFlagsMask = MovementFlags(
movementFlagsMask | MOVEFLAG_LEFT | MOVEFLAG_RIGHT
);
enum MovementFlags2
{
MOVEFLAG2_NONE = 0x0000,
@ -668,6 +712,75 @@ enum SplineMoveFlags // possibly exactly
SPLINE_MOVE_FLAG_FACING = 0x00020000,
};
struct Position
{
Position() : x(0.0f), y(0.0f), z(0.0f), o(0.0f) {}
float x, y, z, o;
};
class MovementInfo
{
public:
MovementInfo() : moveFlags(MOVEFLAG_NONE), moveFlags2(MOVEFLAG2_NONE), time(0), t_guid(0),
t_time(0), t_seat(-1), t_time2(0), s_pitch(0.0f), fallTime(0), j_velocity(0.0f), j_sinAngle(0.0f),
j_cosAngle(0.0f), j_xyspeed(0.0f), u_unk1(0.0f) {}
MovementInfo(WorldPacket &data);
// Read/Write methods
void Read(ByteBuffer &data);
void Write(ByteBuffer &data);
// Movement flags manipulations
void AddMovementFlag(MovementFlags f) { moveFlags |= f; }
void RemoveMovementFlag(MovementFlags f) { moveFlags &= ~f; }
bool HasMovementFlag(MovementFlags f) const { return moveFlags & f; }
MovementFlags GetMovementFlags() const { return MovementFlags(moveFlags); }
void SetMovementFlags(MovementFlags f) { moveFlags = f; }
MovementFlags2 GetMovementFlags2() const { return MovementFlags2(moveFlags2); }
// Position manipulations
Position const *GetPos() const { return &pos; }
void SetTransportData(uint64 guid, float x, float y, float z, float o, uint32 time, int8 seat)
{
t_guid = guid;
t_pos.x = x;
t_pos.y = y;
t_pos.z = z;
t_pos.o = z;
t_time = time;
t_seat = seat;
}
uint64 GetTransportGuid() const { return t_guid; }
Position const *GetTransportPos() const { return &t_pos; }
int8 GetTransportSeat() const { return t_seat; }
uint32 GetTransportTime() const { return t_time; }
uint32 GetFallTime() const { return fallTime; }
void ChangePosition(float x, float y, float z, float o) { pos.x = x; pos.y = y; pos.z = z; pos.o = o; }
void UpdateTime(uint32 _time) { time = _time; }
private:
// common
uint32 moveFlags; // see enum MovementFlags
uint16 moveFlags2; // see enum MovementFlags2
uint32 time;
Position pos;
// transport
uint64 t_guid;
Position t_pos;
uint32 t_time;
int8 t_seat;
uint32 t_time2;
// swimming and flying
float s_pitch;
// last fall time
uint32 fallTime;
// jumping
float j_velocity, j_sinAngle, j_cosAngle, j_xyspeed;
// spline
float u_unk1;
};
enum DiminishingLevels
{
DIMINISHING_LEVEL_1 = 0,
@ -1235,7 +1348,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
bool isAlive() const { return (m_deathState == ALIVE); };
bool isDead() const { return ( m_deathState == DEAD || m_deathState == CORPSE ); };
DeathState getDeathState() { return m_deathState; };
virtual void setDeathState(DeathState s); // overwrited in Creature/Player/Pet
virtual void setDeathState(DeathState s); // overwritten in Creature/Player/Pet
uint64 GetOwnerGUID() const { return GetUInt64Value(UNIT_FIELD_SUMMONEDBY); }
void SetOwnerGUID(uint64 owner) { SetUInt64Value(UNIT_FIELD_SUMMONEDBY, owner); }
@ -1636,6 +1749,9 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
void AddPetAura(PetAura const* petSpell);
void RemovePetAura(PetAura const* petSpell);
// Movement info
MovementInfo m_movementInfo;
protected:
explicit Unit ();

View file

@ -721,101 +721,6 @@ void WorldSession::SaveTutorialsData()
m_TutorialsChanged = false;
}
void WorldSession::ReadMovementInfo(WorldPacket &data, MovementInfo *mi)
{
data >> mi->flags;
data >> mi->moveFlags2;
data >> mi->time;
data >> mi->x;
data >> mi->y;
data >> mi->z;
data >> mi->o;
if(mi->HasMovementFlag(MOVEMENTFLAG_ONTRANSPORT))
{
if(!data.readPackGUID(mi->t_guid))
return;
data >> mi->t_x;
data >> mi->t_y;
data >> mi->t_z;
data >> mi->t_o;
data >> mi->t_time;
data >> mi->t_seat;
if(mi->moveFlags2 & MOVEFLAG2_UNK1)
data >> mi->t_time2;
}
if((mi->HasMovementFlag(MovementFlags(MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING))) || (mi->moveFlags2 & MOVEFLAG2_ALLOW_PITCHING))
{
data >> mi->s_pitch;
}
data >> mi->fallTime;
if(mi->HasMovementFlag(MOVEMENTFLAG_JUMPING))
{
data >> mi->j_velocity;
data >> mi->j_sinAngle;
data >> mi->j_cosAngle;
data >> mi->j_xyspeed;
}
if(mi->HasMovementFlag(MOVEMENTFLAG_SPLINE))
{
data >> mi->u_unk1;
}
}
void WorldSession::WriteMovementInfo(WorldPacket *data, MovementInfo *mi)
{
data->appendPackGUID(mi->guid);
*data << mi->flags;
*data << mi->moveFlags2;
*data << mi->time;
*data << mi->x;
*data << mi->y;
*data << mi->z;
*data << mi->o;
if(mi->HasMovementFlag(MOVEMENTFLAG_ONTRANSPORT))
{
data->appendPackGUID(mi->t_guid);
*data << mi->t_x;
*data << mi->t_y;
*data << mi->t_z;
*data << mi->t_o;
*data << mi->t_time;
*data << mi->t_seat;
if(mi->moveFlags2 & MOVEFLAG2_UNK1)
*data << mi->t_time2;
}
if((mi->HasMovementFlag(MovementFlags(MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING))) || (mi->moveFlags2 & MOVEFLAG2_ALLOW_PITCHING))
{
*data << mi->s_pitch;
}
*data << mi->fallTime;
if(mi->HasMovementFlag(MOVEMENTFLAG_JUMPING))
{
*data << mi->j_velocity;
*data << mi->j_sinAngle;
*data << mi->j_cosAngle;
*data << mi->j_xyspeed;
}
if(mi->HasMovementFlag(MOVEMENTFLAG_SPLINE))
{
*data << mi->u_unk1;
}
}
void WorldSession::ReadAddonsInfo(WorldPacket &data)
{
if (data.rpos() + 4 > data.size())

View file

@ -29,7 +29,6 @@
struct ItemPrototype;
struct AuctionEntry;
struct DeclinedName;
struct MovementInfo;
class Creature;
class Item;
@ -122,9 +121,6 @@ class MANGOS_DLL_SPEC WorldSession
void ReadAddonsInfo(WorldPacket &data);
void SendAddonsInfo();
void ReadMovementInfo(WorldPacket &data, MovementInfo *mi);
void WriteMovementInfo(WorldPacket *data, MovementInfo *mi);
void SendPacket(WorldPacket const* packet);
void SendNotification(const char *format,...) ATTR_PRINTF(2,3);
void SendNotification(int32 string_id,...);