📄 aiplayer.cc
字号:
//-----------------------------------------------------------------------------
// Torque Game Engine
// Copyright (C) GarageGames.com, Inc.
//-----------------------------------------------------------------------------
#include "game/aiPlayer.h"
#include "console/consoleInternal.h"
#include "core/realComp.h"
#include "math/mMatrix.h"
#include "game/moveManager.h"
#include "core/bitStream.h"
#ifdef TGE_RPG
#include "rpg/gobjects/RPGBase.h"
#include "rpg/gobjects/GNpc.h"
#include "rpg/gobjects/GPlayer.h"
#include "game/gameTSCtrl.h"
using namespace RPG;
#endif
IMPLEMENT_CO_NETOBJECT_V1(AIPlayer);
/**
* Constructor
*/
AIPlayer::AIPlayer()
{
mMoveDestination.set( 0.0f, 0.0f, 0.0f );
mMoveSpeed = 1.0f;
mMoveTolerance = 0.25f;
mMoveSlowdown = true;
m_bPressDown = false;
mMoveState = ModeStop;
mAimObject = 0;
mAimLocationSet = false;
mTargetInLOS = false;
mAimOffset = Point3F(0.0f, 0.0f, 0.0f);
mTypeMask |= AIObjectType;
m_fTurnRoundStep = M_PI_DIV180 * 10; //10度
//m_bMoveTo = FALSE;
#ifdef TGE_RPG
m_nMoveType = MT_NONE;
#endif
}
/**
* Destructor
*/
AIPlayer::~AIPlayer()
{
}
/**
* Sets the speed at which this AI moves
*
* @param speed Speed to move, default player was 10
*/
void AIPlayer::setMoveSpeed( F32 speed )
{
mMoveSpeed = getMax(0.0f, getMin( 1.0f, speed ));
}
/**
* Stops movement for this AI
*/
void AIPlayer::stopMove()
{
mMoveState = ModeStop;
}
/**
* Sets how far away from the move location is considered
* "on target"
*
* @param tolerance Movement tolerance for error
*/
void AIPlayer::setMoveTolerance( const F32 tolerance )
{
#ifdef TGE_RPG
mMoveTolerance = tolerance * 0.25f;
#else
mMoveTolerance = getMax( 0.1f, tolerance );
#endif
}
/**
* Sets the location for the bot to run to
*
* @param location Point to run to
*/
void AIPlayer::setMoveDestination( const Point3F &location, bool slowdown )
{
mMoveDestination = location;
mMoveState = ModeMove;
mMoveSlowdown = slowdown;
#ifdef TGE_RPG /// TGE_Move
m_bPressDown = false;
/// 目标须在一定距离外,方可起步走动
m_nMoveType = MT_DESTINATION;
MatrixF eye;
getEyeTransform(&eye);
Point3F pos = eye.getPosition();
//Point3F rotation = getRotation();
F32 xDiff = mMoveDestination.x - pos.x;
F32 yDiff = mMoveDestination.y - pos.y;
F32 fTolerance = mMoveTolerance*4;
F32 fTolerance2 = mMoveTolerance;
if (mFabs(xDiff) < fTolerance2 && mFabs(yDiff) < fTolerance2)
{
mMoveState = ModeStop;
throwCallback("onReachDestination");
}
else if (mFabs(xDiff) < fTolerance && mFabs(yDiff) < fTolerance)
{
mMoveState = ModeRound;
}
#endif
}
#ifdef TGE_RPG /// TGE_Move
/// TGE_RPG
void AIPlayer::setMoveTo( const Point3F &location, bool slowdown ,bool bPressDown)
{
/// bPressDown表Mouse一直按着;为了避免快速到达目标点,而停止动画播放
/// 在bPressDown为true时,目标点将沿着同一方向移动
//mMoveDestination = location;
//mAimObject = NULL;
mMoveSlowdown = slowdown;
m_bPressDown = bPressDown;
m_nMoveType = MT_MOVETO;
//mAimObject = NULL;
/// 目标须在一定距离外,方可起步走动
MatrixF eye;
getEyeTransform(&eye);
Point3F pos = eye.getPosition();
F32 xDiff = location.x - pos.x;
F32 yDiff = location.y - pos.y;
if(bPressDown)
{
mMoveState = ModeMove;
/// 如果一直按下,差距离放大
do{
xDiff *= 100;
yDiff *= 100;
}while(mFabs(xDiff) < mMoveTolerance || mFabs(yDiff) < mMoveTolerance);
}
else
{
F32 fTolerance4 = mMoveTolerance*4;
F32 fTolerance2 = mMoveTolerance;
F32 xAbs = mFabs(xDiff);
F32 yAbs = mFabs(yDiff);
if (xAbs < fTolerance2 && yAbs < fTolerance2)
mMoveState = ModeStop;
else if (xAbs < fTolerance4 && yAbs < fTolerance4)
mMoveState = ModeRound;
else
mMoveState = ModeMove;
}
mMoveDestination.x = pos.x + xDiff;
mMoveDestination.y = pos.y + yDiff;
}
void AIPlayer::faceTo(const Point3F &ptFace,bool bFaceMe)
{
m_nMoveType = MT_ROUND;
mMoveState = ModeRound;
mAimLocationSet = true;
mAimOffset = Point3F(0.0f, 0.0f, 0.0f);
if(!bFaceMe)
{
mAimLocation = getPosition();
Point3F vec = mAimLocation - ptFace;
mAimLocation.x += vec.x;
mAimLocation.y += vec.y;
}
else
mAimLocation = ptFace;
}
#endif
/**
* Sets the object the bot is targeting
*
* @param targetObject The object to target
*/
void AIPlayer::setAimObject( GameBase *targetObject )
{
#ifdef TGE_RPG
m_nMoveType = MT_AIM;
#endif
mAimObject = targetObject;
mTargetInLOS = false;
mAimOffset = Point3F(0.0f, 0.0f, 0.0f);
}
/**
* Sets the object the bot is targeting and an offset to add to target location
*
* @param targetObject The object to target
* @param offset The offest from the target location to aim at
*/
void AIPlayer::setAimObject( GameBase *targetObject, Point3F offset )
{
#ifdef TGE_RPG
m_nMoveType = MT_AIM;
#endif
mAimObject = targetObject;
mTargetInLOS = false;
mAimOffset = offset;
}
/**
* Sets the location for the bot to aim at
*
* @param location Point to aim at
*/
void AIPlayer::setAimLocation( const Point3F &location )
{
#ifdef TGE_RPG
m_nMoveType = MT_AIMLOC;
#endif
mAimObject = 0;
mAimLocationSet = true;
mAimLocation = location;
mAimOffset = Point3F(0.0f, 0.0f, 0.0f);
}
/**
* Clears the aim location and sets it to the bot's
* current destination so he looks where he's going
*/
void AIPlayer::clearAim()
{
mAimObject = 0;
mAimLocationSet = false;
mAimOffset = Point3F(0.0f, 0.0f, 0.0f);
}
/**
* This method calculates the moves for the AI player
*
* @param movePtr Pointer to move the move list into
*/
bool AIPlayer::getAIMove(Move *movePtr)
{
*movePtr = NullMove;
// Use the eye as the current position.
MatrixF eye;
getEyeTransform(&eye);
Point3F location = eye.getPosition();
Point3F rotation = getRotation();
// Orient towards the aim point, aim object, or towards
// our destination.
#ifdef TGE_RPG /// TGE_Move
if (mAimObject || mAimLocationSet|| mMoveState == ModeMove || mMoveState == ModeRound)
#else
if (mAimObject || mAimLocationSet|| mMoveState == ModeMove)
#endif
{
#ifdef TGE_RPG
if(m_nMoveType == MT_MOVETO)
mAimLocation = mMoveDestination;
else if(m_nMoveType != MT_ROUND)
{
if(mAimObject)
mAimLocation = mAimObject->getPosition() + mAimOffset;
else if(!mAimLocationSet)
mAimLocation = mMoveDestination;
}
#else
// Update the aim position if we're aiming for an object
if (mAimObject)
mAimLocation = mAimObject->getPosition() + mAimOffset;
else
if (!mAimLocationSet)
mAimLocation = mMoveDestination;
#endif
F32 xDiff = mAimLocation.x - location.x;
F32 yDiff = mAimLocation.y - location.y;
if (!isZero(xDiff) || !isZero(yDiff)) {
// First do Yaw
// use the cur yaw between -Pi and Pi
F32 curYaw = rotation.z;
while (curYaw > M_2PI)
curYaw -= M_2PI;
while (curYaw < -M_2PI)
curYaw += M_2PI;
// find the yaw offset
F32 newYaw = mAtan( xDiff, yDiff );
F32 yawDiff = newYaw - curYaw;
// make it between 0 and 2PI
if( yawDiff < 0.0f )
yawDiff += M_2PI;
else if( yawDiff >= M_2PI )
yawDiff -= M_2PI;
// now make sure we take the short way around the circle
if( yawDiff > M_PI )
yawDiff -= M_2PI;
else if( yawDiff < -M_PI )
yawDiff += M_2PI;
/// AIPlayer增加转身起步处理
#ifdef TGE_RPG
movePtr->yaw = mFabs(yawDiff) < m_fTurnRoundStep? yawDiff : (yawDiff< 0? -m_fTurnRoundStep : m_fTurnRoundStep);
#else
movePtr->yaw = yawDiff;
#endif
// Next do pitch.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -