From ee83c8b66c4cf66a62b4102635578d3967664aae Mon Sep 17 00:00:00 2001 From: Azaezel Date: Fri, 4 Dec 2015 11:24:20 -0600 Subject: [PATCH] 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. --- Engine/source/T3D/aiPlayer.cpp | 91 ++++++++++++++++++++++++++-------- Engine/source/T3D/aiPlayer.h | 15 +++--- 2 files changed, 79 insertions(+), 27 deletions(-) diff --git a/Engine/source/T3D/aiPlayer.cpp b/Engine/source/T3D/aiPlayer.cpp index 8992c2c55..bf00484e4 100644 --- a/Engine/source/T3D/aiPlayer.cpp +++ b/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(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); +} diff --git a/Engine/source/T3D/aiPlayer.h b/Engine/source/T3D/aiPlayer.h index d693314eb..08707c0b8 100644 --- a/Engine/source/T3D/aiPlayer.h +++ b/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 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 );