Răsfoiți Sursa

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.
Azaezel 9 ani în urmă
părinte
comite
ee83c8b66c
2 a modificat fișierele cu 79 adăugiri și 27 ștergeri
  1. 70 21
      Engine/source/T3D/aiPlayer.cpp
  2. 9 6
      Engine/source/T3D/aiPlayer.h

+ 70 - 21
Engine/source/T3D/aiPlayer.cpp

@@ -145,6 +145,9 @@ void AIPlayer::initPersistFields()
          "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");
 
+      addField( "AttackRadius", TypeF32, Offset( mAttackRadius, AIPlayer ), 
+         "@brief Distance considered in firing range for callback purposes.");
+      	  
    endGroup( "AI" );
 
 #ifdef TORQUE_NAVIGATION_ENABLED
@@ -372,6 +375,11 @@ bool AIPlayer::getAIMove(Move *movePtr)
             {
                clearPath();
                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 dist = mSqrt(xDiff*xDiff + yDiff*yDiff);
-            F32 maxDist = 5.0f;
+            F32 maxDist = mMoveTolerance*2;
             if (dist < maxDist)
                speed *= dist / maxDist;
             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
    // 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,
-            StaticShapeObjectType | StaticObjectType |
-            TerrainObjectType, &dummy)) {
-         if (mTargetInLOS) {
-            throwCallback( "onTargetExitLOS" );
-            mTargetInLOS = false;
-         }
-      }
-      else
-         if (!mTargetInLOS) {
+   if (mAimObject)
+   {
+      if (checkInLos(mAimObject.getPointer()))
+      {
+         if (!mTargetInLOS)
+         {
             throwCallback( "onTargetEnterLOS" );
             mTargetInLOS = true;
          }
    }
+      else if (mTargetInLOS)
+      {
+            throwCallback( "onTargetExitLOS" );
+            mTargetInLOS = false;
+         }
+      }
 
    // Replicate the trigger state into the move so that
    // triggers can be controlled from scripts.
@@ -591,6 +592,14 @@ bool AIPlayer::getAIMove(Move *movePtr)
    return true;
 }
 
+void AIPlayer::updateMove(const Move* move)  
+{  
+   if (!getControllingClient() && isGhost())  
+      return;  
+  
+   Parent::updateMove(move);  
+}
+
 /**
  * Utility function to throw callbacks. Callbacks always occure
  * on the datablock class.
@@ -720,6 +729,7 @@ bool AIPlayer::setPathDestination(const Point3F &pos)
    if(!getNavMesh())
    {
       //setMoveDestination(pos);
+      throwCallback("onPathFailed");
       return false;
    }
 
@@ -751,6 +761,7 @@ bool AIPlayer::setPathDestination(const Point3F &pos)
       mPathData.owned = true;
       // Skip node 0, which we are currently standing on.
       moveToNode(1);
+      throwCallback("onPathSuccess");
       return true;
    }
    else
@@ -758,7 +769,7 @@ bool AIPlayer::setPathDestination(const Point3F &pos)
       // Just move normally if we can't path.
       //setMoveDestination(pos, true);
       //return;
-      //throwCallback("onPathFailed");
+      throwCallback("onPathFailed");
       path->deleteObject();
       return false;
    }
@@ -846,6 +857,10 @@ DefineEngineMethod(AIPlayer, followObject, void, (SimObjectId obj, F32 radius),,
    "@param radius Maximum distance we let the target escape to.")
 {
    SceneObject *follow;
+   object->clearPath();
+   object->clearCover();
+   object->clearFollow();
+
    if(Sim::findObject(obj, follow))
       object->followObject(follow, radius);
 }
@@ -1348,3 +1363,37 @@ DefineEngineMethod( AIPlayer, clearMoveTriggers, void, ( ),,
 {
    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);
+}

+ 9 - 6
Engine/source/T3D/aiPlayer.h

@@ -49,6 +49,7 @@ private:
    MoveState mMoveState;
    F32 mMoveSpeed;
    F32 mMoveTolerance;                 // Distance from destination before we stop
+   F32 mAttackRadius;                  // Distance to trigger weaponry calcs
    Point3F mMoveDestination;           // Destination for movement
    Point3F mLastLocation;              // For stuck check
    F32 mMoveStuckTolerance;            // Distance tolerance on stuck check
@@ -96,8 +97,6 @@ private:
    /// Path we are currently following.
    PathData mPathData;
 
-   /// Clear out the current path.
-   void clearPath();
 
    /// Get the current path we're following.
    NavPath *getPath() { return mPathData.path; }
@@ -113,8 +112,6 @@ private:
    /// Current cover we're trying to get to.
    CoverData mCoverData;
 
-   /// Stop searching for cover.
-   void clearCover();
 
    /// Information about a target we're following.
    struct FollowData {
@@ -134,8 +131,6 @@ private:
    /// Current object we're following.
    FollowData mFollowData;
 
-   /// Stop following me!
-   void clearFollow();
 
    /// NavMesh we pathfind on.
    SimObjectPtr<NavMesh> mNavMesh;
@@ -160,6 +155,13 @@ public:
    void onRemove();
 
    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
    void setAimObject( GameBase *targetObject );
@@ -170,6 +172,7 @@ public:
    void clearAim();
    bool checkInLos(GameBase* target = NULL, bool _useMuzzle = false, bool _checkEnabled = false);
    bool checkInFoV(GameBase* target = NULL, F32 camFov = 45.0f, bool _checkEnabled = false);
+   F32 getTargetDistance(GameBase* target, bool _checkEnabled);
 
    // Movement sets/gets
    void setMoveSpeed( const F32 speed );