浏览代码

aicontroller:
in order to call derivatives of AIControllerData datablocks *without* requiring an accompanying AIController subclass as well, leverage the fastdelegate system for our resolver callbacks
additionally, don't try and repath in mid air
aigoal: initialize inange/infirinrange to false. use those to filter callbacks

AzaezelX 6 月之前
父节点
当前提交
32f9917ed2
共有 3 个文件被更改,包括 91 次插入41 次删除
  1. 61 37
      Engine/source/T3D/AI/AIController.cpp
  2. 26 1
      Engine/source/T3D/AI/AIController.h
  3. 4 3
      Engine/source/T3D/AI/AIGoal.h

+ 61 - 37
Engine/source/T3D/AI/AIController.cpp

@@ -138,17 +138,33 @@ bool AIController::getAIMove(Move* movePtr)
       else
       else
       {
       {
          if (getGoal()->getDist() > mControllerData->mFollowTolerance)
          if (getGoal()->getDist() > mControllerData->mFollowTolerance)
-            getNav()->repath();
-
-         if (getGoal()->getDist() < mControllerData->mFollowTolerance)
+         {
+            RayInfo info;
+            if (getAIInfo()->mObj->getContainer()->castRay(getAIInfo()->getPosition(), getAIInfo()->getPosition() - Point3F(0, 0, 0.001f), StaticShapeObjectType, &info))
+            {
+               getNav()->repath();
+            }
+            getGoal()->mInRange = false;
+         }
+         if (getGoal()->getDist() < mControllerData->mFollowTolerance && !getGoal()->mInRange)
          {
          {
             getNav()->clearPath();
             getNav()->clearPath();
             mMovement.mMoveState = ModeStop;
             mMovement.mMoveState = ModeStop;
+            getGoal()->mInRange = true;
             throwCallback("onTargetInRange");
             throwCallback("onTargetInRange");
          }
          }
-         else if (getGoal()->getDist() < mControllerData->mAttackRadius)
+         else
          {
          {
-            throwCallback("onTargetInFiringRange");
+            if (getGoal()->getDist() < mControllerData->mAttackRadius )
+            {
+               if (!getGoal()->mInFiringRange)
+               {
+                  getGoal()->mInFiringRange = true;
+                  throwCallback("onTargetInFiringRange");
+               }
+            }
+            else
+               getGoal()->mInFiringRange = false;
          }
          }
       }
       }
    }
    }
@@ -164,9 +180,9 @@ bool AIController::getAIMove(Move* movePtr)
       else
       else
          mMovement.mAimLocation = getNav()->mMoveDestination;
          mMovement.mAimLocation = getNav()->mMoveDestination;
 
 
-      mControllerData->resolveYaw(this, location, movePtr);
-      mControllerData->resolvePitch(this, location, movePtr);
-      mControllerData->resolveRoll(this, location, movePtr);
+      mControllerData->resolveYawPtr(this, location, movePtr);
+      mControllerData->resolvePitchPtr(this, location, movePtr);
+      mControllerData->resolveRollPtr(this, location, movePtr);
 
 
       if (mMovement.mMoveState != AIController::ModeStop)
       if (mMovement.mMoveState != AIController::ModeStop)
       {
       {
@@ -179,12 +195,14 @@ bool AIController::getAIMove(Move* movePtr)
          }
          }
          else
          else
          {
          {
-            mControllerData->resolveSpeed(this, location, movePtr);
-            mControllerData->resolveStuck(this);
+            mControllerData->resolveSpeedPtr(this, location, movePtr);
+            mControllerData->resolveStuckPtr(this);
          }
          }
       }
       }
    }
    }
 
 
+   mControllerData->resolveTriggerStatePtr(this, 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.
@@ -206,31 +224,6 @@ bool AIController::getAIMove(Move* movePtr)
       }
       }
    }
    }
 
 
-   /*
-   // Replicate the trigger state into the move so that
-   // triggers can be controlled from scripts.
-   for (U32 i = 0; i < MaxTriggerKeys; i++)
-      movePtr->trigger[i] = getImageTriggerState(i);
-   */
-
-#ifdef TORQUE_NAVIGATION_ENABLED
-   if (getNav()->mJump == AINavigation::Now)
-   {
-      movePtr->trigger[2] = true;
-      getNav()->mJump = AINavigation::None;
-   }
-   else if (getNav()->mJump == AINavigation::Ledge)
-   {
-      // If we're not touching the ground, jump!
-      RayInfo info;
-      if (!getAIInfo()->mObj->getContainer()->castRay(getAIInfo()->getPosition(), getAIInfo()->getPosition() - Point3F(0, 0, 0.4f), StaticShapeObjectType, &info))
-      {
-         movePtr->trigger[2] = true;
-         getNav()->mJump = AINavigation::None;
-      }
-   }
-#endif // TORQUE_NAVIGATION_ENABLED
-
    return true;
    return true;
 }
 }
 
 
@@ -438,6 +431,15 @@ void AIControllerData::resolveSpeed(AIController* obj, Point3F location, Move* m
    }
    }
 }
 }
 
 
+void AIControllerData::resolveTriggerState(AIController* obj, Move* movePtr)
+{
+   //check for scripted overides
+   for (U32 slot = 0; slot < MaxTriggerKeys; slot++)
+   {      
+      movePtr->trigger[slot] = obj->mTriggerState.mMoveTriggers[slot];
+   }
+}
+
 void AIControllerData::resolveStuck(AIController* obj)
 void AIControllerData::resolveStuck(AIController* obj)
 {
 {
    if (obj->mMovement.mMoveState == AIController::ModeStop) return;
    if (obj->mMovement.mMoveState == AIController::ModeStop) return;
@@ -539,10 +541,10 @@ void AIPlayerControllerData::resolvePitch(AIController* obj, Point3F location, M
    Player* po = dynamic_cast<Player*>(obj->getAIInfo()->mObj.getPointer());
    Player* po = dynamic_cast<Player*>(obj->getAIInfo()->mObj.getPointer());
    if (!po) return;//not a player
    if (!po) return;//not a player
 
 
-   if (obj->getAim()->mObj || obj->getAim()->mPosSet || obj->mMovement.mMoveState != AIController::ModeStop)
+   if (obj->getAim() || obj->mMovement.mMoveState != AIController::ModeStop)
    {
    {
       // Next do pitch.
       // Next do pitch.
-      if (!obj->getAim()->mObj && !obj->getAim()->mPosSet)
+      if (!obj->getAim())
       {
       {
          // Level out if were just looking at our next way point.
          // Level out if were just looking at our next way point.
          Point3F headRotation = po->getHeadRotation();
          Point3F headRotation = po->getHeadRotation();
@@ -572,4 +574,26 @@ void AIPlayerControllerData::resolvePitch(AIController* obj, Point3F location, M
       movePtr->pitch = -headRotation.x;
       movePtr->pitch = -headRotation.x;
    }
    }
 }
 }
+
+void AIPlayerControllerData::resolveTriggerState(AIController* obj, Move* movePtr)
+{
+   Parent::resolveTriggerState(obj, movePtr);
+#ifdef TORQUE_NAVIGATION_ENABLED
+   if (obj->getNav()->mJump == AINavigation::Now)
+   {
+      movePtr->trigger[2] = true;
+      obj->getNav()->mJump = AINavigation::None;
+   }
+   else if (obj->getNav()->mJump == AINavigation::Ledge)
+   {
+      // If we're not touching the ground, jump!
+      RayInfo info;
+      if (!obj->getAIInfo()->mObj->getContainer()->castRay(obj->getAIInfo()->getPosition(), obj->getAIInfo()->getPosition() - Point3F(0, 0, 0.4f), StaticShapeObjectType, &info))
+      {
+         movePtr->trigger[2] = true;
+         obj->getNav()->mJump = AINavigation::None;
+      }
+   }
+#endif // TORQUE_NAVIGATION_ENABLED
+}
 #endif //_AICONTROLLER_H_
 #endif //_AICONTROLLER_H_

+ 26 - 1
Engine/source/T3D/AI/AIController.h

@@ -124,7 +124,7 @@ public:
       mCover = NULL;
       mCover = NULL;
       mMovement.mMoveState = ModeStop;
       mMovement.mMoveState = ModeStop;
    };
    };
-
+   
    DECLARE_CONOBJECT(AIController);
    DECLARE_CONOBJECT(AIController);
 };
 };
 
 
@@ -144,6 +144,13 @@ public:
       mMoveStuckTestDelay = 30;
       mMoveStuckTestDelay = 30;
       mLinkTypes = LinkData(AllFlags);
       mLinkTypes = LinkData(AllFlags);
       mNavSize = AINavigation::Regular;
       mNavSize = AINavigation::Regular;
+
+      resolveYawPtr.bind(this, &AIControllerData::resolveYaw);
+      resolvePitchPtr.bind(this, &AIControllerData::resolvePitch);
+      resolveRollPtr.bind(this, &AIControllerData::resolveRoll);
+      resolveSpeedPtr.bind(this, &AIControllerData::resolveSpeed);
+      resolveTriggerStatePtr.bind(this, &AIControllerData::resolveTriggerState);
+      resolveStuckPtr.bind(this, &AIControllerData::resolveStuck);
    };
    };
    ~AIControllerData() {};
    ~AIControllerData() {};
 
 
@@ -158,10 +165,22 @@ public:
    /// Types of link we can use.
    /// Types of link we can use.
    LinkData mLinkTypes;
    LinkData mLinkTypes;
    AINavigation::NavSize mNavSize;
    AINavigation::NavSize mNavSize;
+   Delegate<void(AIController* obj, Point3F location, Move* movePtr)> resolveYawPtr;
    void resolveYaw(AIController* obj, Point3F location, Move* movePtr);
    void resolveYaw(AIController* obj, Point3F location, Move* movePtr);
+
+   Delegate<void(AIController* obj, Point3F location, Move* movePtr)> resolvePitchPtr;
    void resolvePitch(AIController* obj, Point3F location, Move* movePtr) {};
    void resolvePitch(AIController* obj, Point3F location, Move* movePtr) {};
+
+   Delegate<void(AIController* obj, Point3F location, Move* movePtr)> resolveRollPtr;
    void resolveRoll(AIController* obj, Point3F location, Move* movePtr);
    void resolveRoll(AIController* obj, Point3F location, Move* movePtr);
+
+   Delegate<void(AIController* obj, Point3F location, Move* movePtr)> resolveSpeedPtr;
    void resolveSpeed(AIController* obj, Point3F location, Move* movePtr);
    void resolveSpeed(AIController* obj, Point3F location, Move* movePtr);
+
+   Delegate<void(AIController* obj, Move* movePtr)> resolveTriggerStatePtr;
+   void resolveTriggerState(AIController* obj, Move* movePtr);
+
+   Delegate<void(AIController* obj)> resolveStuckPtr;
    void resolveStuck(AIController* obj);
    void resolveStuck(AIController* obj);
 };
 };
 
 
@@ -170,7 +189,13 @@ class AIPlayerControllerData : public AIControllerData
    typedef AIControllerData Parent;
    typedef AIControllerData Parent;
 
 
 public:
 public:
+   AIPlayerControllerData()
+   {
+      resolvePitchPtr.bind(this, &AIPlayerControllerData::resolvePitch);
+      resolveTriggerStatePtr.bind(this, &AIPlayerControllerData::resolveTriggerState);
+   }
    void resolvePitch(AIController* obj, Point3F location, Move* movePtr);
    void resolvePitch(AIController* obj, Point3F location, Move* movePtr);
+   void resolveTriggerState(AIController* obj, Move* movePtr);
    DECLARE_CONOBJECT(AIPlayerControllerData);
    DECLARE_CONOBJECT(AIPlayerControllerData);
 };
 };
 #endif // TORQUE_NAVIGATION_ENABLED
 #endif // TORQUE_NAVIGATION_ENABLED

+ 4 - 3
Engine/source/T3D/AI/AIGoal.h

@@ -27,9 +27,10 @@
 struct AIGoal : public AIInfo
 struct AIGoal : public AIInfo
 {
 {
    typedef AIInfo Parent;
    typedef AIInfo Parent;
+   bool mInRange, mInFiringRange;
    AIGoal() = delete;
    AIGoal() = delete;
-   AIGoal(AIController* controller): Parent(controller) {};
-   AIGoal(AIController* controller, SimObjectPtr<SceneObject> objIn, F32 radIn) : Parent(controller, objIn, radIn) {};
-   AIGoal(AIController* controller, Point3F pointIn, F32 radIn) : Parent(controller, pointIn, radIn) {};
+   AIGoal(AIController* controller) : Parent(controller) { mInRange = mInFiringRange = false; };
+   AIGoal(AIController* controller, SimObjectPtr<SceneObject> objIn, F32 radIn) : Parent(controller, objIn, radIn) { mInRange = mInFiringRange = false; };
+   AIGoal(AIController* controller, Point3F pointIn, F32 radIn) : Parent(controller, pointIn, radIn) { mInRange = mInFiringRange = false; };
 };
 };
 #endif
 #endif