mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-02-12 19:31:41 +00:00
Merge pull request #649 from Azaezel/aiPlayer_utility
AIPlayer utility methods
This commit is contained in:
commit
1b06b0d92e
2 changed files with 126 additions and 20 deletions
|
|
@ -28,6 +28,8 @@
|
|||
#include "T3D/gameBase/moveManager.h"
|
||||
#include "console/engineAPI.h"
|
||||
|
||||
static U32 sAIPlayerLoSMask = TerrainObjectType | StaticShapeObjectType | StaticObjectType;
|
||||
|
||||
IMPLEMENT_CO_NETOBJECT_V1(AIPlayer);
|
||||
|
||||
ConsoleDocClass( AIPlayer,
|
||||
|
|
@ -417,28 +419,21 @@ 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) {
|
||||
throwCallback( "onTargetEnterLOS" );
|
||||
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
|
||||
|
|
@ -610,3 +605,112 @@ DefineEngineMethod( AIPlayer, getAimObject, S32, (),,
|
|||
GameBase* obj = object->getAimObject();
|
||||
return obj? obj->getId(): -1;
|
||||
}
|
||||
|
||||
bool AIPlayer::checkInLos(GameBase* target, bool _useMuzzle, bool _checkEnabled)
|
||||
{
|
||||
if (!isServerObject()) return false;
|
||||
if (!target)
|
||||
{
|
||||
target = mAimObject.getPointer();
|
||||
if (!target)
|
||||
return false;
|
||||
}
|
||||
if (_checkEnabled)
|
||||
{
|
||||
if (target->getTypeMask() & ShapeBaseObjectType)
|
||||
{
|
||||
ShapeBase *shapeBaseCheck = static_cast<ShapeBase *>(target);
|
||||
if (shapeBaseCheck)
|
||||
if (shapeBaseCheck->getDamageState() != Enabled) return false;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
RayInfo ri;
|
||||
|
||||
disableCollision();
|
||||
|
||||
S32 mountCount = target->getMountedObjectCount();
|
||||
for (S32 i = 0; i < mountCount; i++)
|
||||
{
|
||||
target->getMountedObject(i)->disableCollision();
|
||||
}
|
||||
|
||||
Point3F checkPoint ;
|
||||
if (_useMuzzle)
|
||||
getMuzzlePointAI(0, &checkPoint );
|
||||
else
|
||||
{
|
||||
MatrixF eyeMat;
|
||||
getEyeTransform(&eyeMat);
|
||||
eyeMat.getColumn(3, &checkPoint );
|
||||
}
|
||||
|
||||
bool hit = !gServerContainer.castRay(checkPoint, target->getBoxCenter(), sAIPlayerLoSMask, &ri);
|
||||
enableCollision();
|
||||
|
||||
for (S32 i = 0; i < mountCount; i++)
|
||||
{
|
||||
target->getMountedObject(i)->enableCollision();
|
||||
}
|
||||
return hit;
|
||||
}
|
||||
|
||||
DefineEngineMethod(AIPlayer, checkInLos, bool, (ShapeBase* obj, bool useMuzzle, bool checkEnabled),(NULL, false, false),
|
||||
"@brief Check whether an object is in line of sight.\n"
|
||||
"@obj Object to check. (If blank, it will check the current target).\n"
|
||||
"@useMuzzle Use muzzle position. Otherwise use eye position. (defaults to false).\n"
|
||||
"@checkEnabled check whether the object can take damage and if so is still alive.(Defaults to false)\n")
|
||||
{
|
||||
return object->checkInLos(obj, useMuzzle, checkEnabled);
|
||||
}
|
||||
|
||||
bool AIPlayer::checkInFoV(GameBase* target, F32 camFov, bool _checkEnabled)
|
||||
{
|
||||
if (!isServerObject()) return false;
|
||||
if (!target)
|
||||
{
|
||||
target = mAimObject.getPointer();
|
||||
if (!target)
|
||||
return false;
|
||||
}
|
||||
if (_checkEnabled)
|
||||
{
|
||||
if (target->getTypeMask() & ShapeBaseObjectType)
|
||||
{
|
||||
ShapeBase *shapeBaseCheck = static_cast<ShapeBase *>(target);
|
||||
if (shapeBaseCheck)
|
||||
if (shapeBaseCheck->getDamageState() != Enabled) return false;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
MatrixF cam = getTransform();
|
||||
Point3F camPos;
|
||||
VectorF camDir;
|
||||
|
||||
cam.getColumn(3, &camPos);
|
||||
cam.getColumn(1, &camDir);
|
||||
|
||||
camFov = mDegToRad(camFov) / 2;
|
||||
|
||||
Point3F shapePos = target->getBoxCenter();
|
||||
VectorF shapeDir = shapePos - camPos;
|
||||
// Test to see if it's within our viewcone, this test doesn't
|
||||
// actually match the viewport very well, should consider
|
||||
// projection and box test.
|
||||
shapeDir.normalize();
|
||||
F32 dot = mDot(shapeDir, camDir);
|
||||
return (dot > camFov);
|
||||
}
|
||||
|
||||
DefineEngineMethod(AIPlayer, checkInFoV, bool, (ShapeBase* obj, F32 fov, bool checkEnabled), (NULL, 45.0f, 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->checkInFoV(obj, fov, checkEnabled);
|
||||
}
|
||||
|
|
@ -80,6 +80,8 @@ public:
|
|||
void setAimLocation( const Point3F &location );
|
||||
Point3F getAimLocation() const { return mAimLocation; }
|
||||
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);
|
||||
|
||||
// Movement sets/gets
|
||||
void setMoveSpeed( const F32 speed );
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue