diff --git a/Engine/source/T3D/AI/AIController.cpp b/Engine/source/T3D/AI/AIController.cpp index 2e46a8d4b..fa9befa03 100644 --- a/Engine/source/T3D/AI/AIController.cpp +++ b/Engine/source/T3D/AI/AIController.cpp @@ -138,17 +138,33 @@ bool AIController::getAIMove(Move* movePtr) else { 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(); mMovement.mMoveState = ModeStop; + getGoal()->mInRange = true; 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 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) { @@ -179,12 +195,14 @@ bool AIController::getAIMove(Move* movePtr) } 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 // run from the eye position to the center of the object's bounding, // 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; } @@ -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) { if (obj->mMovement.mMoveState == AIController::ModeStop) return; @@ -539,10 +541,10 @@ void AIPlayerControllerData::resolvePitch(AIController* obj, Point3F location, M Player* po = dynamic_cast(obj->getAIInfo()->mObj.getPointer()); 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. - if (!obj->getAim()->mObj && !obj->getAim()->mPosSet) + if (!obj->getAim()) { // Level out if were just looking at our next way point. Point3F headRotation = po->getHeadRotation(); @@ -572,4 +574,26 @@ void AIPlayerControllerData::resolvePitch(AIController* obj, Point3F location, M 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_ diff --git a/Engine/source/T3D/AI/AIController.h b/Engine/source/T3D/AI/AIController.h index 140eb030b..78c7cb86b 100644 --- a/Engine/source/T3D/AI/AIController.h +++ b/Engine/source/T3D/AI/AIController.h @@ -124,7 +124,7 @@ public: mCover = NULL; mMovement.mMoveState = ModeStop; }; - + DECLARE_CONOBJECT(AIController); }; @@ -144,6 +144,13 @@ public: mMoveStuckTestDelay = 30; mLinkTypes = LinkData(AllFlags); 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() {}; @@ -158,10 +165,22 @@ public: /// Types of link we can use. LinkData mLinkTypes; AINavigation::NavSize mNavSize; + Delegate resolveYawPtr; void resolveYaw(AIController* obj, Point3F location, Move* movePtr); + + Delegate resolvePitchPtr; void resolvePitch(AIController* obj, Point3F location, Move* movePtr) {}; + + Delegate resolveRollPtr; void resolveRoll(AIController* obj, Point3F location, Move* movePtr); + + Delegate resolveSpeedPtr; void resolveSpeed(AIController* obj, Point3F location, Move* movePtr); + + Delegate resolveTriggerStatePtr; + void resolveTriggerState(AIController* obj, Move* movePtr); + + Delegate resolveStuckPtr; void resolveStuck(AIController* obj); }; @@ -170,7 +189,13 @@ class AIPlayerControllerData : public AIControllerData typedef AIControllerData Parent; public: + AIPlayerControllerData() + { + resolvePitchPtr.bind(this, &AIPlayerControllerData::resolvePitch); + resolveTriggerStatePtr.bind(this, &AIPlayerControllerData::resolveTriggerState); + } void resolvePitch(AIController* obj, Point3F location, Move* movePtr); + void resolveTriggerState(AIController* obj, Move* movePtr); DECLARE_CONOBJECT(AIPlayerControllerData); }; #endif // TORQUE_NAVIGATION_ENABLED diff --git a/Engine/source/T3D/AI/AIGoal.h b/Engine/source/T3D/AI/AIGoal.h index ba5096bd7..e8a22b873 100644 --- a/Engine/source/T3D/AI/AIGoal.h +++ b/Engine/source/T3D/AI/AIGoal.h @@ -27,9 +27,10 @@ struct AIGoal : public AIInfo { typedef AIInfo Parent; + bool mInRange, mInFiringRange; AIGoal() = delete; - AIGoal(AIController* controller): Parent(controller) {}; - AIGoal(AIController* controller, SimObjectPtr 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 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