mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-14 16:14:38 +00:00
Extacted AI tweaks:
attackradius - seperate value/callbacks to allow AI to be coded to move and shoot. slowdown triggered by 2x movetolerance rather than a fixed 5 untis. void AIPlayer::updateMove(const Move* move) - 'lag' correction. getTargetDistance - c side distance calculation with enabled option.
This commit is contained in:
parent
272e3138a0
commit
ee83c8b66c
2 changed files with 79 additions and 27 deletions
|
|
@ -145,6 +145,9 @@ void AIPlayer::initPersistFields()
|
||||||
"to accelerate to full speed without its initial slow start being considered as stuck.\n"
|
"to accelerate to full speed without its initial slow start being considered as stuck.\n"
|
||||||
"@note Set to zero to have the stuck test start immediately.\n");
|
"@note Set to zero to have the stuck test start immediately.\n");
|
||||||
|
|
||||||
|
addField( "AttackRadius", TypeF32, Offset( mAttackRadius, AIPlayer ),
|
||||||
|
"@brief Distance considered in firing range for callback purposes.");
|
||||||
|
|
||||||
endGroup( "AI" );
|
endGroup( "AI" );
|
||||||
|
|
||||||
#ifdef TORQUE_NAVIGATION_ENABLED
|
#ifdef TORQUE_NAVIGATION_ENABLED
|
||||||
|
|
@ -372,6 +375,11 @@ bool AIPlayer::getAIMove(Move *movePtr)
|
||||||
{
|
{
|
||||||
clearPath();
|
clearPath();
|
||||||
mMoveState = ModeStop;
|
mMoveState = ModeStop;
|
||||||
|
throwCallback("onTargetInRange");
|
||||||
|
}
|
||||||
|
else if((getPosition() - mFollowData.object->getPosition()).len() < mAttackRadius)
|
||||||
|
{
|
||||||
|
throwCallback("onTargetInFiringRange");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -499,7 +507,7 @@ bool AIPlayer::getAIMove(Move *movePtr)
|
||||||
{
|
{
|
||||||
F32 speed = mMoveSpeed;
|
F32 speed = mMoveSpeed;
|
||||||
F32 dist = mSqrt(xDiff*xDiff + yDiff*yDiff);
|
F32 dist = mSqrt(xDiff*xDiff + yDiff*yDiff);
|
||||||
F32 maxDist = 5.0f;
|
F32 maxDist = mMoveTolerance*2;
|
||||||
if (dist < maxDist)
|
if (dist < maxDist)
|
||||||
speed *= dist / maxDist;
|
speed *= dist / maxDist;
|
||||||
movePtr->x *= speed;
|
movePtr->x *= speed;
|
||||||
|
|
@ -539,29 +547,22 @@ bool AIPlayer::getAIMove(Move *movePtr)
|
||||||
// Test for target location in sight if it's an object. The LOS is
|
// 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,
|
// run from the eye position to the center of the object's bounding,
|
||||||
// which is not very accurate.
|
// which is not very accurate.
|
||||||
if (mAimObject) {
|
if (mAimObject)
|
||||||
MatrixF eyeMat;
|
{
|
||||||
getEyeTransform(&eyeMat);
|
if (checkInLos(mAimObject.getPointer()))
|
||||||
eyeMat.getColumn(3,&location);
|
{
|
||||||
Point3F targetLoc = mAimObject->getBoxCenter();
|
if (!mTargetInLOS)
|
||||||
|
{
|
||||||
// This ray ignores non-static shapes. Cast Ray returns true
|
|
||||||
// if it hit something.
|
|
||||||
RayInfo dummy;
|
|
||||||
if (getContainer()->castRay( location, targetLoc,
|
|
||||||
StaticShapeObjectType | StaticObjectType |
|
|
||||||
TerrainObjectType, &dummy)) {
|
|
||||||
if (mTargetInLOS) {
|
|
||||||
throwCallback( "onTargetExitLOS" );
|
|
||||||
mTargetInLOS = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if (!mTargetInLOS) {
|
|
||||||
throwCallback( "onTargetEnterLOS" );
|
throwCallback( "onTargetEnterLOS" );
|
||||||
mTargetInLOS = true;
|
mTargetInLOS = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (mTargetInLOS)
|
||||||
|
{
|
||||||
|
throwCallback( "onTargetExitLOS" );
|
||||||
|
mTargetInLOS = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Replicate the trigger state into the move so that
|
// Replicate the trigger state into the move so that
|
||||||
// triggers can be controlled from scripts.
|
// triggers can be controlled from scripts.
|
||||||
|
|
@ -591,6 +592,14 @@ bool AIPlayer::getAIMove(Move *movePtr)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AIPlayer::updateMove(const Move* move)
|
||||||
|
{
|
||||||
|
if (!getControllingClient() && isGhost())
|
||||||
|
return;
|
||||||
|
|
||||||
|
Parent::updateMove(move);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility function to throw callbacks. Callbacks always occure
|
* Utility function to throw callbacks. Callbacks always occure
|
||||||
* on the datablock class.
|
* on the datablock class.
|
||||||
|
|
@ -720,6 +729,7 @@ bool AIPlayer::setPathDestination(const Point3F &pos)
|
||||||
if(!getNavMesh())
|
if(!getNavMesh())
|
||||||
{
|
{
|
||||||
//setMoveDestination(pos);
|
//setMoveDestination(pos);
|
||||||
|
throwCallback("onPathFailed");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -751,6 +761,7 @@ bool AIPlayer::setPathDestination(const Point3F &pos)
|
||||||
mPathData.owned = true;
|
mPathData.owned = true;
|
||||||
// Skip node 0, which we are currently standing on.
|
// Skip node 0, which we are currently standing on.
|
||||||
moveToNode(1);
|
moveToNode(1);
|
||||||
|
throwCallback("onPathSuccess");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -758,7 +769,7 @@ bool AIPlayer::setPathDestination(const Point3F &pos)
|
||||||
// Just move normally if we can't path.
|
// Just move normally if we can't path.
|
||||||
//setMoveDestination(pos, true);
|
//setMoveDestination(pos, true);
|
||||||
//return;
|
//return;
|
||||||
//throwCallback("onPathFailed");
|
throwCallback("onPathFailed");
|
||||||
path->deleteObject();
|
path->deleteObject();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -846,6 +857,10 @@ DefineEngineMethod(AIPlayer, followObject, void, (SimObjectId obj, F32 radius),,
|
||||||
"@param radius Maximum distance we let the target escape to.")
|
"@param radius Maximum distance we let the target escape to.")
|
||||||
{
|
{
|
||||||
SceneObject *follow;
|
SceneObject *follow;
|
||||||
|
object->clearPath();
|
||||||
|
object->clearCover();
|
||||||
|
object->clearFollow();
|
||||||
|
|
||||||
if(Sim::findObject(obj, follow))
|
if(Sim::findObject(obj, follow))
|
||||||
object->followObject(follow, radius);
|
object->followObject(follow, radius);
|
||||||
}
|
}
|
||||||
|
|
@ -1348,3 +1363,37 @@ DefineEngineMethod( AIPlayer, clearMoveTriggers, void, ( ),,
|
||||||
{
|
{
|
||||||
object->clearMoveTriggers();
|
object->clearMoveTriggers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
F32 AIPlayer::getTargetDistance(GameBase* target, bool _checkEnabled)
|
||||||
|
{
|
||||||
|
if (!isServerObject()) return false;
|
||||||
|
if (!target)
|
||||||
|
{
|
||||||
|
target = mAimObject.getPointer();
|
||||||
|
if (!target)
|
||||||
|
return F32_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_checkEnabled)
|
||||||
|
{
|
||||||
|
if (target->getTypeMask() & ShapeBaseObjectType)
|
||||||
|
{
|
||||||
|
ShapeBase *shapeBaseCheck = static_cast<ShapeBase *>(target);
|
||||||
|
if (shapeBaseCheck)
|
||||||
|
if (shapeBaseCheck->getDamageState() != Enabled) return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return F32_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (getPosition() - target->getPosition()).len();
|
||||||
|
}
|
||||||
|
|
||||||
|
DefineEngineMethod(AIPlayer, getTargetDistance, bool, (ShapeBase* obj, bool checkEnabled), (NULL, false),
|
||||||
|
"@brief Check whether an object is within a specified veiw cone.\n"
|
||||||
|
"@obj Object to check. (If blank, it will check the current target).\n"
|
||||||
|
"@fov view angle in degrees.(Defaults to 45)\n"
|
||||||
|
"@checkEnabled check whether the object can take damage and if so is still alive.(Defaults to false)\n")
|
||||||
|
{
|
||||||
|
return object->getTargetDistance(obj, checkEnabled);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,7 @@ private:
|
||||||
MoveState mMoveState;
|
MoveState mMoveState;
|
||||||
F32 mMoveSpeed;
|
F32 mMoveSpeed;
|
||||||
F32 mMoveTolerance; // Distance from destination before we stop
|
F32 mMoveTolerance; // Distance from destination before we stop
|
||||||
|
F32 mAttackRadius; // Distance to trigger weaponry calcs
|
||||||
Point3F mMoveDestination; // Destination for movement
|
Point3F mMoveDestination; // Destination for movement
|
||||||
Point3F mLastLocation; // For stuck check
|
Point3F mLastLocation; // For stuck check
|
||||||
F32 mMoveStuckTolerance; // Distance tolerance on stuck check
|
F32 mMoveStuckTolerance; // Distance tolerance on stuck check
|
||||||
|
|
@ -96,8 +97,6 @@ private:
|
||||||
/// Path we are currently following.
|
/// Path we are currently following.
|
||||||
PathData mPathData;
|
PathData mPathData;
|
||||||
|
|
||||||
/// Clear out the current path.
|
|
||||||
void clearPath();
|
|
||||||
|
|
||||||
/// Get the current path we're following.
|
/// Get the current path we're following.
|
||||||
NavPath *getPath() { return mPathData.path; }
|
NavPath *getPath() { return mPathData.path; }
|
||||||
|
|
@ -113,8 +112,6 @@ private:
|
||||||
/// Current cover we're trying to get to.
|
/// Current cover we're trying to get to.
|
||||||
CoverData mCoverData;
|
CoverData mCoverData;
|
||||||
|
|
||||||
/// Stop searching for cover.
|
|
||||||
void clearCover();
|
|
||||||
|
|
||||||
/// Information about a target we're following.
|
/// Information about a target we're following.
|
||||||
struct FollowData {
|
struct FollowData {
|
||||||
|
|
@ -134,8 +131,6 @@ private:
|
||||||
/// Current object we're following.
|
/// Current object we're following.
|
||||||
FollowData mFollowData;
|
FollowData mFollowData;
|
||||||
|
|
||||||
/// Stop following me!
|
|
||||||
void clearFollow();
|
|
||||||
|
|
||||||
/// NavMesh we pathfind on.
|
/// NavMesh we pathfind on.
|
||||||
SimObjectPtr<NavMesh> mNavMesh;
|
SimObjectPtr<NavMesh> mNavMesh;
|
||||||
|
|
@ -160,6 +155,13 @@ public:
|
||||||
void onRemove();
|
void onRemove();
|
||||||
|
|
||||||
virtual bool getAIMove( Move *move );
|
virtual bool getAIMove( Move *move );
|
||||||
|
virtual void updateMove(const Move *move);
|
||||||
|
/// Clear out the current path.
|
||||||
|
void clearPath();
|
||||||
|
/// Stop searching for cover.
|
||||||
|
void clearCover();
|
||||||
|
/// Stop following me!
|
||||||
|
void clearFollow();
|
||||||
|
|
||||||
// Targeting and aiming sets/gets
|
// Targeting and aiming sets/gets
|
||||||
void setAimObject( GameBase *targetObject );
|
void setAimObject( GameBase *targetObject );
|
||||||
|
|
@ -170,6 +172,7 @@ public:
|
||||||
void clearAim();
|
void clearAim();
|
||||||
bool checkInLos(GameBase* target = NULL, bool _useMuzzle = false, bool _checkEnabled = false);
|
bool checkInLos(GameBase* target = NULL, bool _useMuzzle = false, bool _checkEnabled = false);
|
||||||
bool checkInFoV(GameBase* target = NULL, F32 camFov = 45.0f, bool _checkEnabled = false);
|
bool checkInFoV(GameBase* target = NULL, F32 camFov = 45.0f, bool _checkEnabled = false);
|
||||||
|
F32 getTargetDistance(GameBase* target, bool _checkEnabled);
|
||||||
|
|
||||||
// Movement sets/gets
|
// Movement sets/gets
|
||||||
void setMoveSpeed( const F32 speed );
|
void setMoveSpeed( const F32 speed );
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue