📄 interface.cpp.svn-base
字号:
{
if(m_returnX !=0.0f && m_returnY != 0.0f)
{
return m_Unit->GetDistanceSq(m_returnX,m_returnY,m_returnZ);
}
}
return 0.0f;
}
/************************************************************************************************************
SendMoveToPacket:
Comments: Some comments on the SMSG_MONSTER_MOVE packet:
the uint8 field:
0: Default known
1: Don't move known
2: there is an extra 3 floats, also known as a vector unknown
3: there is an extra uint64 most likely a guid. unknown
4: there is an extra float that causes the orientation to be set. known
note: when this field is 1.
there is no need to send the next 3 uint32's as they are'nt used by the client
the MoveFlags:
0x00000000 - Walk
0x00000100 -
0x00000200 -
some comments on that 0x00000300 - = 0x00000100 | 0x00000200
waypoints:
TODO.... as they somehow seemed to be changed long time ago..
*************************************************************************************************************/
void AIInterface::SendMoveToPacket(float toX, float toY, float toZ, float toO, uint32 time, uint32 MoveFlags)
{
//this should NEVER be called directly !!!!!!
//use MoveTo()
#ifndef USING_BIG_ENDIAN
StackWorldPacket<60> data(SMSG_MONSTER_MOVE);
#else
WorldPacket data(SMSG_MONSTER_MOVE, 60);
#endif
data << m_Unit->GetNewGUID();
data << m_Unit->GetPositionX() << m_Unit->GetPositionY() << m_Unit->GetPositionZ();
data << getMSTime();
// Check if we have an orientation
if(toO != 0.0f)
{
data << uint8(4);
data << toO;
} else {
data << uint8(0);
}
data << MoveFlags;
data << time;
data << uint32(1); // 1 waypoint
data << toX << toY << toZ;
#ifndef ENABLE_COMPRESSED_MOVEMENT_FOR_MONSTERS
bool self = m_Unit->GetTypeId() == TYPEID_PLAYER;
m_Unit->SendMessageToSet( &data, self );
#else
if( m_Unit->GetTypeId() == TYPEID_PLAYER )
static_cast<Player*>(m_Unit)->GetSession()->SendPacket(&data);
for(set<Player*>::iterator itr = m_Unit->GetInRangePlayerSetBegin(); itr != m_Unit->GetInRangePlayerSetEnd(); ++itr)
{
if( (*itr)->GetPositionNC().Distance2DSq( m_Unit->GetPosition() ) >= World::m_movementCompressThresholdMONSTERs )
(*itr)->AppendMovementData( SMSG_MONSTER_MOVE, data.GetSize(), (const uint8*)data.GetBufferPointer() );
else
(*itr)->GetSession()->SendPacket(&data);
}
#endif
}
/*
void AIInterface::SendMoveToSplinesPacket(std::list<Waypoint> wp, bool )
{
if(!m_canMove)
{
return;
}
WorldPacket data;
uint8 DontMove = 0;
uint32 travelTime = 0;
for(std::list<Waypoint>::iterator i = wp.begin(); i != wp.end(); i++)
{
travelTime += i->time;
}
data.Initialize( SMSG_MONSTER_MOVE );
data << m_Unit->GetNewGUID();
data << m_Unit->GetPositionX() << m_Unit->GetPositionY() << m_Unit->GetPositionZ();
data << getMSTime();
data << uint8(DontMove);
data << uint32( ? 0x00000100 : 0x00000000);
data << travelTime;
data << (uint32)wp.size();
for(std::list<Waypoint>::iterator i = wp.begin(); i != wp.end(); i++)
{
data << i->x;
data << i->y;
data << i->z;
}
m_Unit->SendMessageToSet( &data, false );
}
*/
bool AIInterface::StopMovement(uint32 time)
{
m_moveTimer = time; //set pause after stopping
m_MONSTERState = STOPPED;
m_destinationX = m_destinationY = m_destinationZ = 0;
m_nextPosX = m_nextPosY = m_nextPosZ = 0;
m_timeMoved = 0;
m_timeToMove = 0;
WorldPacket data(26);
data.SetOpcode(SMSG_MONSTER_MOVE);
data << m_Unit->GetNewGUID();
data << m_Unit->GetPositionX() << m_Unit->GetPositionY() << m_Unit->GetPositionZ();
data << getMSTime();
data << uint8(1); // "DontMove = 1"
m_Unit->SendMessageToSet( &data, false );
return true;
}
void AIInterface::MoveTo(float x, float y, float z, float o)
{
m_sourceX = m_Unit->GetPositionX();
m_sourceY = m_Unit->GetPositionY();
m_sourceZ = m_Unit->GetPositionZ();
if(!m_canMove || m_Unit->IsStunned())
{
StopMovement(0); //Just Stop
return;
}
m_nextPosX = x;
m_nextPosY = y;
m_nextPosZ = z;
if(m_MONSTERState != MOVING)
UpdateMove();
}
bool AIInterface::Ising()
{
if(m_move)
return true;
/*float z = m_Unit->GetMapMgr()->GetLandHeight(m_Unit->GetPositionX(), m_Unit->GetPositionY());
if(z)
{
if(m_Unit->GetPositionZ() >= (z + 1.0f)) //not on ground? Oo
{
return true;
}
}
return false;*/
if( m_Unit->GetTypeId() == TYPEID_PLAYER )
return static_cast< Player* >( m_Unit )->Cheat;
return false;
}
uint32 AIInterface::getMoveFlags()
{
uint32 MoveFlags = 0;
if(m_move == true) //
{
m_Speed = m_Unit->m_Speed*0.001f;
MoveFlags = 0x300;
}
else if(m_moveSprint == true) //Sprint
{
m_Speed = (m_Unit->m_Speed+5.0f)*0.001f;
MoveFlags = 0x100;
}
else if(m_move == true) //
{
m_Speed = m_Unit->m_Speed*0.001f;
MoveFlags = 0x100;
}
/* else //Walk
{
m_Speed = m_Unit->m_walkSpeed*0.001f;
MoveFlags = 0x000;
}*/
m_walkSpeed = m_Unit->m_walkSpeed*0.001f;//move distance per ms time
return MoveFlags;
}
void AIInterface::UpdateMove()
{
//this should NEVER be called directly !!!!!!
//use MoveTo()
float distance = m_Unit->CalcDistance(m_nextPosX,m_nextPosY,m_nextPosZ);
if(distance < DISTANCE_TO_SMALL_TO_WALK) return; //we don't want little movements here and there
m_destinationX = m_nextPosX;
m_destinationY = m_nextPosY;
m_destinationZ = m_nextPosZ;
/*if(m_move != true)
{
if(m_Unit->GetMapMgr())
{
float adt_Z = m_Unit->GetMapMgr()->GetLandHeight(m_destinationX, m_destinationY);
if(fabsf(adt_Z - m_destinationZ) < 3.0f)
m_destinationZ = adt_Z;
}
}*/
m_nextPosX = m_nextPosY = m_nextPosZ = 0;
uint32 moveTime;
if(m_move)
moveTime = (uint32) (distance / m_Speed);
else if(m_move)
moveTime = (uint32) (distance / m_Speed);
else moveTime = (uint32) (distance / m_walkSpeed);
m_totalMoveTime = moveTime;
if(m_Unit->GetTypeId() == TYPEID_UNIT)
{
MONSTER *MONSTER = static_cast<MONSTER*>(m_Unit);
// check if we're returning to our respawn location. if so, reset back to default
// orientation
if(MONSTER->GetSpawnX() == m_destinationX &&
MONSTER->GetSpawnY() == m_destinationY)
{
float o = MONSTER->GetSpawnO();
MONSTER->SetOrientation(o);
} else {
// Calculate the angle to our next position
float dx = (float)m_destinationX - m_Unit->GetPositionX();
float dy = (float)m_destinationY - m_Unit->GetPositionY();
if(dy != 0.0f)
{
float angle = atan2(dy, dx);
m_Unit->SetOrientation(angle);
}
}
}
SendMoveToPacket(m_destinationX, m_destinationY, m_destinationZ, m_Unit->GetOrientation(), moveTime, getMoveFlags());
m_timeToMove = moveTime;
m_timeMoved = 0;
if(m_moveTimer == 0)
{
m_moveTimer = UNIT_MOVEMENT_INTERPOLATE_INTERVAL; // update every few msecs
}
m_MONSTERState = MOVING;
}
void AIInterface::SendCurrentMove(Player* plyr/*uint64 guid*/)
{
if(m_destinationX == 0.0f && m_destinationY == 0.0f && m_destinationZ == 0.0f) return; //invalid move
ByteBuffer *splineBuf = new ByteBuffer(20*4);
*splineBuf << uint32(0); // spline flags
*splineBuf << uint32((m_totalMoveTime - m_timeToMove)+m_moveTimer); //Time Passed (start Position) //should be generated/save
*splineBuf << uint32(m_totalMoveTime); //Total Time //should be generated/save
*splineBuf << uint32(0); //Unknown
*splineBuf << uint32(4); //Spline Count // lets try this
*splineBuf << m_sourceX << m_sourceY << m_sourceZ;
*splineBuf << m_Unit->GetPositionX() << m_Unit->GetPositionY() << m_Unit->GetPositionZ();
*splineBuf << m_destinationX << m_destinationY << m_destinationZ;
*splineBuf << m_destinationX << m_destinationY << m_destinationZ;
*splineBuf << m_destinationX << m_destinationY << m_destinationZ;
plyr->AddSplinePacket(m_Unit->GetGUID(), splineBuf);
//This should only be called by Players AddInRangeObject() ONLY
//using guid cuz when i atempted to use pointer the player was deleted when this event was called some times
//Player* plyr = World::GetPlayer(guid);
//if(!plyr) return;
/*if(m_destinationX == 0.0f && m_destinationY == 0.0f && m_destinationZ == 0.0f) return; //invalid move
uint32 moveTime = m_timeToMove-m_timeMoved;
//uint32 moveTime = (m_timeToMove-m_timeMoved)+m_moveTimer;
WorldPacket data(50);
data.SetOpcode( SMSG_MONSTER_MOVE );
data << m_Unit->GetNewGUID();
data << m_Unit->GetPositionX() << m_Unit->GetPositionY() << m_Unit->GetPositionZ();
data << getMSTime();
data << uint8(0);
data << getMoveFlags();
//float distance = m_Unit->CalcDistance(m_destinationX, m_destinationY, m_destinationZ);
//uint32 moveTime = (uint32) (distance / m_Speed);
data << moveTime;
data << uint32(1); //Number of Waypoints
data << m_destinationX << m_destinationY << m_destinationZ;
plyr->GetSession()->SendPacket(&data);*/
}
bool AIInterface::setInFront(Unit* target) // not the best way to do it, though
{
//angle the object has to face
float angle = m_Unit->calcAngle(m_Unit->GetPositionX(), m_Unit->GetPositionY(), target->GetPositionX(), target->GetPositionY() );
//Change angle slowly 2000ms to turn 180 deg around
if(angle > 180) angle += 90;
else angle -= 90; //angle < 180
m_Unit->getEasyAngle(angle);
//Convert from degrees to radians (180 deg = PI rad)
float orientation = angle / float(180 / M_PI);
//Update Orentation Server Side
m_Unit->SetPosition(m_Unit->GetPositionX(), m_Unit->GetPositionY(), m_Unit->GetPositionZ(), orientation);
return m_Unit->isInFront(target);
}
bool AIInterface::addWayPoint(WayPoint* wp)
{
if(!m_waypoints)
m_waypoints = new WayPointMap ;
if(!wp)
return false;
if(wp->id <= 0)
return false; //not valid id
if(m_waypoints->size() <= wp->id)
m_waypoints->resize(wp->id+1);
if((*m_waypoints)[wp->id] == NULL)
{
(*m_waypoints)[wp->id] = wp;
return true;
}
return false;
}
void AIInterface::changeWayPointID(uint32 oldwpid, uint32 newwpid)
{
if(!m_waypoints)return;
if(newwpid <= 0)
return; //not valid id
if(newwpid > m_waypoints->size())
return; //not valid id
if(oldwpid > m_waypoints->size())
return;
if(newwpid == oldwpid)
return; //same spot
//already wp with that id ?
WayPoint* originalwp = getWayPoint(newwpid);
if(!originalwp)
return;
WayPoint* oldwp = getWayPoint(oldwpid);
if(!oldwp)
return;
oldwp->id = newwpid;
originalwp->id = oldwpid;
(*m_waypoints)[oldwp->id] = oldwp;
(*m_waypoints)[originalwp->id] = originalwp;
//SaveAll to db
saveWayPoints();
}
void AIInterface::deleteWayPoint(uint32 wpid)
{
if(!m_waypoints)return;
if(wpid <= 0)
return; //not valid id
if(wpid > m_waypoints->size())
return; //not valid id
WayPointMap new_waypoints;
uint32 newpid = 1;
for(WayPointMap::iterator itr = m_waypoints->begin(); itr != m_waypoints->end(); ++itr)
{
if((*itr) == NULL || (*itr)->id == wpid)
{
if((*itr) != NULL)
delete ((*itr));
continue;
}
new_waypoints.push_back(*itr);
}
m_waypoints->clear();
m_waypoints->push_back(NULL); // waypoint 0
for(WayPointMap::iterator itr = new_waypoints.begin(); itr != new_waypoints.end(); ++itr)
{
(*itr)->id = newpid++;
m_waypoints->push_back(*itr);
}
saveWayPoints();
}
bool AIInterface::showWayPoints(Player* pPlayer, bool Backwards)
{
if(!m_waypoints)
return false;
//wpid of 0 == all
WayPointMap::const_iterator itr;
if(m_WayPointsShowing == true)
return false;
m_WayPointsShowing = true;
WayPoint* wp = NULL;
for (itr = m_waypoints->begin(); itr != m_waypoints->end(); itr++)
{
if( (*itr) != NULL )
{
wp = *itr;
//Create
MONSTER* pWayPoint = new MONSTER((uint64)HIGHGUID_TYPE_WAYPOINT << 32 | wp->id);
pWayPoint->CreateWayPoint(wp->id,pPlayer->GetMapId(),wp->x,wp->y,wp->z,0);
pWayPoint->SetUInt32Value(OBJECT_FIELD_ENTRY, 300000);
pWayPoint->SetFloatValue(OBJECT_FIELD_SCALE_X, 0.5f);
if(Backwards)
{
uint32 DisplayID = (wp->backwardskinid == 0)? GetUnit()->GetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID) : wp->backwardskinid;
pWayPoint->SetUInt32Value(UNIT_FIELD_DISPLAYID, DisplayID);
pWayPoint->SetUInt32Value(UNIT_NPC_EMOTESTATE, wp->backwardemoteid);
}
else
{
uint32 DisplayID = (wp->forwardskinid == 0)? GetUnit()->GetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID) : wp->forwardskinid;
pWayPoint->SetUInt32Value(UNIT_FIELD_DISPLAYID, DisplayID);
pWayPoint->SetUInt32Value(UNIT_NPC_EMOTESTATE, wp->forwardemoteid);
}
pWayPoint->SetUInt32Value(UNIT_FIELD_LEVEL, wp->id);
pWayPoint->SetUInt32Value(UNIT_NPC_FLAGS, 0);
pWayPoint->SetUInt32Value(UNIT_FIELD_AURA+32, 8326); //invisable & deathworld look
pWayPoint->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE , pPlayer->GetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE));
pWayPoint->SetUInt32V
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -