📄 aiplayer.cc
字号:
if (!mAimObject && !mAimLocationSet) {
// Level out if were just looking at our next way point.
Point3F headRotation = getHeadRotation();
movePtr->pitch = -headRotation.x;
}
else {
// This should be adjusted to run from the
// eye point to the object's center position. Though this
// works well enough for now.
F32 vertDist = mAimLocation.z - location.z;
F32 horzDist = mSqrt(xDiff * xDiff + yDiff * yDiff);
F32 newPitch = mAtan( horzDist, vertDist ) - ( M_PI / 2.0f );
if (mFabs(newPitch) > 0.01) {
Point3F headRotation = getHeadRotation();
movePtr->pitch = newPitch - headRotation.x;
}
}
#ifdef TGE_RPG /// TGE_Move
if(mMoveState == ModeRound && mFabs(yawDiff) < m_fTurnRoundStep)
{
#ifdef TGE_RPG
onReachGoal();
#else
throwCallback("onRoundStop");
#endif
mMoveState = ModeStop;
}
}
#endif
}
else {
// Level out if we're not doing anything else
Point3F headRotation = getHeadRotation();
movePtr->pitch = -headRotation.x;
}
// Move towards the destination
if (mMoveState == ModeMove) {
//location = eye.getPosition();
F32 xDiff = mMoveDestination.x - location.x;
F32 yDiff = mMoveDestination.y - location.y;
// Check if we should mMove, or if we are 'close enough'
if (mFabs(xDiff) < mMoveTolerance && mFabs(yDiff) < mMoveTolerance) {
mMoveState = ModeStop;
#ifdef TGE_RPG
onReachGoal();
#else
throwCallback("onReachDestination");
#endif
}
else {
// Build move direction in world space
if (isZero(xDiff))
movePtr->y = (location.y > mMoveDestination.y)? -1 : 1;
else
if (isZero(yDiff))
movePtr->x = (location.x > mMoveDestination.x)? -1 : 1;
else
if (mFabs(xDiff) > mFabs(yDiff)) {
F32 value = mFabs(yDiff / xDiff);
movePtr->y = (location.y > mMoveDestination.y)? -value : value;
movePtr->x = (location.x > mMoveDestination.x)? -1 : 1;
}
else {
F32 value = mFabs(xDiff / yDiff);
movePtr->x = (location.x > mMoveDestination.x)? -value : value;
movePtr->y = (location.y > mMoveDestination.y)? -1 : 1;
}
// Rotate the move into object space (this really only needs
// a 2D matrix)
Point3F newMove;
MatrixF moveMatrix;
moveMatrix.set(EulerF(0, 0, -(rotation.z + movePtr->yaw)));
moveMatrix.mulV( Point3F( movePtr->x, movePtr->y, 0 ), &newMove );
movePtr->x = newMove.x;
movePtr->y = newMove.y;
Con::printf(" %g,%g (%g,%g) - (%g,%g)",newMove.x,newMove.y,mMoveDestination.x,mMoveDestination.y,location.x,location.y);
// Set movement speed. We'll slow down once we get close
// to try and stop on the spot...
if (mMoveSlowdown) {
F32 speed = mMoveSpeed;
F32 dist = mSqrt(xDiff*xDiff + yDiff*yDiff);
F32 maxDist = 2;
if (dist < maxDist)
speed *= dist / maxDist;
movePtr->x *= speed;
movePtr->y *= speed;
}
else {
movePtr->x *= mMoveSpeed;
movePtr->y *= mMoveSpeed;
}
// We should check to see if we are stuck...
if (location == mLastLocation) {
throwCallback("onMoveStuck");
mMoveState = ModeStop;
}
}
}
// Test for target location in sight if it's an object. The LOS is
// run from the eye position to the center of the object's bounding,
// which is not very accurate.
if (mAimObject) {
MatrixF eyeMat;
getEyeTransform(&eyeMat);
eyeMat.getColumn(3,&location);
Point3F targetLoc = mAimObject->getBoxCenter();
// This ray ignores non-static shapes. Cast Ray returns true
// if it hit something.
RayInfo dummy;
if (getContainer()->castRay( location, targetLoc,
InteriorObjectType | StaticShapeObjectType | StaticObjectType |
TerrainObjectType, &dummy)) {
if (mTargetInLOS) {
throwCallback( "onTargetExitLOS" );
mTargetInLOS = false;
}
}
else
if (!mTargetInLOS) {
throwCallback( "onTargetEnterLOS" );
mTargetInLOS = true;
}
}
// Replicate the trigger state into the move so that
// triggers can be controlled from scripts.
for( int i = 0; i < MaxTriggerKeys; i++ )
movePtr->trigger[i] = getImageTriggerState(i);
return true;
}
#ifdef TGE_RPG /// TGE_Move
/// TGE_Move
///------------------------------------------------
bool AIPlayer::getNextMove(Move &curMove)
{
if(mMoveState == ModeStop)
return false;
getAIMove(&curMove);
//curMove.x *= -1;
//curMove.y *= -1;
//Con::warnf("%f %f",curMove.x,curMove.y);
curMove.clamp();
return true;
}
void AIPlayer::onReachGoal()
{
if(m_nMoveType == MT_MOVETO || m_nMoveType == MT_ROUND)
{
if(!mAimObject.isNull())
{
RPGBase* pRPGBase;
GNpc* pNpc;
//Point3F posVec = mAimObject->getPosition() - getPosition();
//if(posVec.len() <= GameTSCtrl::ms_fTalkDistance)
{
pRPGBase = mAimObject->getRPGBase();
if(pRPGBase)
{
if(pRPGBase->IsNpc())
{
pNpc = dynamic_cast<GNpc*>(pRPGBase);
if(pNpc)
pNpc->ProcessTalk( dynamic_cast<GPlayer*>(getRPGBase()) );
}
}//if
}//if
mAimObject = NULL;
}//if
}//if(m_bMoveTo)
if(m_nMoveType == MT_MOVETO)
throwCallback("onReachDestination");
else if(m_nMoveType == MT_ROUND)
throwCallback("onRoundStop");
}
#endif
/**
* Utility function to throw callbacks. Callbacks always occure
* on the datablock class.
*
* @param name Name of script function to call
*/
void AIPlayer::throwCallback( const char *name )
{
Con::executef(getDataBlock(), 2, name, scriptThis());
}
///-----------------------------------------------------------------------
/// TGE_RPG
///-----------------------------------------------------------------------
U32 AIPlayer::packUpdate(NetConnection *con, U32 mask, BitStream *stream)
{
U32 retMask = Parent::packUpdate(con, mask, stream);
// if (stream->writeFlag((mask & MoveToMask)))
//{
// stream->writeCompressedPoint(m_ptMoveTo);
// stream->writeFlag(m_bMoveToSlowdown);
//}
return retMask;
}
void AIPlayer::unpackUpdate(NetConnection *con, BitStream *stream)
{
Parent::unpackUpdate(con,stream);
//MoveToMask
// if (stream->readFlag())
//{
// mMoveSlowdown = stream->readFlag();
// stream->readCompressedPoint(&mMoveDestination);
// mMoveState = ModeMove;
//}
}
// --------------------------------------------------------------------------------------------
// Console Functions
// --------------------------------------------------------------------------------------------
ConsoleMethod( AIPlayer, stop, void, 2, 2, "()"
"Stop moving.")
{
object->stopMove();
}
ConsoleMethod( AIPlayer, clearAim, void, 2, 2, "()"
"Stop aiming at anything.")
{
object->clearAim();
}
ConsoleMethod( AIPlayer, setMoveSpeed, void, 3, 3, "( float speed )"
"Sets the move speed for an AI object.")
{
object->setMoveSpeed( dAtof( argv[2] ) );
}
ConsoleMethod( AIPlayer, setMoveDestination, void, 3, 4, "(Point3F goal, bool slowDown=true)"
"Tells the AI to move to the location provided.")
{
Point3F v( 0.0f, 0.0f, 0.0f );
dSscanf( argv[2], "%g %g %g", &v.x, &v.y, &v.z );
bool slowdown = (argc > 3)? dAtob(argv[3]): true;
object->setMoveDestination( v, slowdown);
}
/// TGE_RPG
ConsoleMethod( AIPlayer, setMoveTo, void, 4, 5, "(Point3F goal,bool bPressDown, bool slowDown=true)"
"服务端AI型Player准备移动坐标")
{
Point3F v( 0.0f, 0.0f, 0.0f );
dSscanf( argv[2], "%g %g %g", &v.x, &v.y, &v.z );
bool bPressDown = dAtob(argv[3]);
bool slowdown = (argc > 4)? dAtob(argv[4]): false;
object->setMoveTo( v, slowdown,bPressDown);
}
ConsoleMethod( AIPlayer, getMoveDestination, const char *, 2, 2, "()"
"Returns the point the AI is set to move to.")
{
Point3F movePoint = object->getMoveDestination();
char *returnBuffer = Con::getReturnBuffer( 256 );
dSprintf( returnBuffer, 256, "%g %g %g", movePoint.x, movePoint.y, movePoint.z );
return returnBuffer;
}
ConsoleMethod( AIPlayer, setAimLocation, void, 3, 3, "( Point3F target )"
"Tells the AI to aim at the location provided.")
{
Point3F v( 0.0f,0.0f,0.0f );
dSscanf( argv[2], "%g %g %g", &v.x, &v.y, &v.z );
object->setAimLocation( v );
}
ConsoleMethod( AIPlayer, getAimLocation, const char *, 2, 2, "()"
"Returns the point the AI is aiming at.")
{
Point3F aimPoint = object->getAimLocation();
char *returnBuffer = Con::getReturnBuffer( 256 );
dSprintf( returnBuffer, 256, "%g %g %g", aimPoint.x, aimPoint.y, aimPoint.z );
return returnBuffer;
}
ConsoleMethod( AIPlayer, setAimObject, void, 3, 4, "( GameBase obj, [Point3F offset] )"
"Sets the bot's target object. Optionally set an offset from target location.")
{
Point3F off( 0.0f, 0.0f, 0.0f );
// Find the target
GameBase *targetObject;
if( Sim::findObject( argv[2], targetObject ) )
{
if (argc == 4)
dSscanf( argv[3], "%g %g %g", &off.x, &off.y, &off.z );
object->setAimObject( targetObject, off );
}
else
object->setAimObject( 0, off );
}
ConsoleMethod( AIPlayer, getAimObject, S32, 2, 2, "()"
"Gets the object the AI is targeting.")
{
GameBase* obj = object->getAimObject();
return obj? obj->getId(): -1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -