AIAimTarget.cpp 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #include "AIAimTarget.h"
  23. #include "AIController.h"
  24. static U32 sAILoSMask = TerrainObjectType | StaticShapeObjectType | StaticObjectType;
  25. F32 AIAimTarget::getTargetDistance(SceneObject* target, bool _checkEnabled)
  26. {
  27. if (!target)
  28. {
  29. target = mObj.getPointer();
  30. if (!target)
  31. return F32_MAX;
  32. }
  33. if (_checkEnabled)
  34. {
  35. if (target->getTypeMask() & ShapeBaseObjectType)
  36. {
  37. ShapeBase* shapeBaseCheck = static_cast<ShapeBase*>(target);
  38. if (shapeBaseCheck)
  39. if (shapeBaseCheck->getDamageState() != ShapeBase::Enabled) return false;
  40. }
  41. else
  42. return F32_MAX;
  43. }
  44. return (getPosition() - target->getPosition()).len();
  45. }
  46. bool AIAimTarget::checkInLos(SceneObject* target, bool _useMuzzle, bool _checkEnabled)
  47. {
  48. ShapeBase* sbo = dynamic_cast<ShapeBase*>(getCtrl()->getAIInfo()->mObj.getPointer());
  49. if (!target)
  50. {
  51. target = dynamic_cast<ShapeBase*>(mObj.getPointer());
  52. if (!target)
  53. return false;
  54. }
  55. if (_checkEnabled)
  56. {
  57. if (target->getTypeMask() & ShapeBaseObjectType)
  58. {
  59. ShapeBase* shapeBaseCheck = static_cast<ShapeBase*>(target);
  60. if (shapeBaseCheck)
  61. if (shapeBaseCheck->getDamageState() != ShapeBase::Enabled) return false;
  62. }
  63. else
  64. return false;
  65. }
  66. RayInfo ri;
  67. sbo->disableCollision();
  68. S32 mountCount = target->getMountedObjectCount();
  69. for (S32 i = 0; i < mountCount; i++)
  70. {
  71. target->getMountedObject(i)->disableCollision();
  72. }
  73. Point3F checkPoint;
  74. if (_useMuzzle)
  75. sbo->getMuzzlePoint(0, &checkPoint);
  76. else
  77. {
  78. MatrixF eyeMat;
  79. sbo->getEyeTransform(&eyeMat);
  80. eyeMat.getColumn(3, &checkPoint);
  81. }
  82. bool hit = !gServerContainer.castRay(checkPoint, target->getBoxCenter(), sAILoSMask, &ri);
  83. sbo->enableCollision();
  84. for (S32 i = 0; i < mountCount; i++)
  85. {
  86. target->getMountedObject(i)->enableCollision();
  87. }
  88. return hit;
  89. }
  90. bool AIAimTarget::checkInFoV(SceneObject* target, F32 camFov, bool _checkEnabled)
  91. {
  92. ShapeBase* sbo = dynamic_cast<ShapeBase*>(getCtrl()->getAIInfo()->mObj.getPointer());
  93. if (!target)
  94. {
  95. target = dynamic_cast<ShapeBase*>(mObj.getPointer());
  96. if (!target)
  97. return false;
  98. }
  99. if (_checkEnabled)
  100. {
  101. if (target->getTypeMask() & ShapeBaseObjectType)
  102. {
  103. ShapeBase* shapeBaseCheck = static_cast<ShapeBase*>(target);
  104. if (shapeBaseCheck)
  105. if (shapeBaseCheck->getDamageState() != ShapeBase::Enabled) return false;
  106. }
  107. else
  108. return false;
  109. }
  110. MatrixF cam = sbo->getTransform();
  111. Point3F camPos;
  112. VectorF camDir;
  113. cam.getColumn(3, &camPos);
  114. cam.getColumn(1, &camDir);
  115. camFov = mDegToRad(camFov) / 2;
  116. Point3F shapePos = target->getBoxCenter();
  117. VectorF shapeDir = shapePos - camPos;
  118. // Test to see if it's within our viewcone, this test doesn't
  119. // actually match the viewport very well, should consider
  120. // projection and box test.
  121. shapeDir.normalize();
  122. F32 dot = mDot(shapeDir, camDir);
  123. return (dot > mCos(camFov));
  124. }
  125. DefineEngineMethod(AIController, setAimLocation, void, (Point3F target), ,
  126. "@brief Tells the AIPlayer to aim at the location provided.\n\n"
  127. "@param target An \"x y z\" position in the game world to target.\n\n"
  128. "@see getAimLocation()\n")
  129. {
  130. object->setAim(target);
  131. }
  132. DefineEngineMethod(AIController, getAimLocation, Point3F, (), ,
  133. "@brief Returns the point the AIPlayer is aiming at.\n\n"
  134. "This will reflect the position set by setAimLocation(), "
  135. "or the position of the object that the bot is now aiming at. "
  136. "If the bot is not aiming at anything, this value will "
  137. "change to whatever point the bot's current line-of-sight intercepts."
  138. "@return World space coordinates of the object AI is aiming at. Formatted as \"X Y Z\".\n\n"
  139. "@see setAimLocation()\n"
  140. "@see setAimObject()\n")
  141. {
  142. return object->getAim()->getPosition();
  143. }
  144. DefineEngineMethod(AIController, setAimObject, void, (const char* objName, Point3F offset), (Point3F::Zero), "( GameBase obj, [Point3F offset] )"
  145. "Sets the bot's target object. Optionally set an offset from target location."
  146. "@hide")
  147. {
  148. // Find the target
  149. SceneObject* targetObject;
  150. if (Sim::findObject(objName, targetObject))
  151. {
  152. object->setAim(targetObject, 0.0f, offset);
  153. }
  154. else
  155. object->setAim(0, 0.0f, offset);
  156. }
  157. DefineEngineMethod(AIController, clearAim, void, (), , "clears the bot's target.")
  158. {
  159. object->clearAim();
  160. }
  161. DefineEngineMethod(AIController, getAimObject, S32, (), ,
  162. "@brief Gets the object the AIPlayer is targeting.\n\n"
  163. "@return Returns -1 if no object is being aimed at, "
  164. "or the SimObjectID of the object the AIPlayer is aiming at.\n\n"
  165. "@see setAimObject()\n")
  166. {
  167. SceneObject* obj = dynamic_cast<GameBase*>(object->getAim()->mObj.getPointer());
  168. return obj ? obj->getId() : -1;
  169. }
  170. DefineEngineMethod(AIController, getTargetDistance, F32, (SceneObject* obj, bool checkEnabled), (nullAsType<SceneObject*>(), false),
  171. "@brief The distance to a given target.\n"
  172. "@obj Object to check. (If blank, it will check the current target).\n"
  173. "@checkEnabled check whether the object can take damage and if so is still alive.(Defaults to false)\n")
  174. {
  175. return object->getAim()->getTargetDistance(obj, checkEnabled);
  176. }
  177. DefineEngineMethod(AIController, checkInLos, bool, (SceneObject* obj, bool useMuzzle, bool checkEnabled), (nullAsType<ShapeBase*>(), false, false),
  178. "@brief Check whether an object is in line of sight.\n"
  179. "@obj Object to check. (If blank, it will check the current target).\n"
  180. "@useMuzzle Use muzzle position. Otherwise use eye position. (defaults to false).\n"
  181. "@checkEnabled check whether the object can take damage and if so is still alive.(Defaults to false)\n")
  182. {
  183. return object->getAim()->checkInLos(obj, useMuzzle, checkEnabled);
  184. }
  185. DefineEngineMethod(AIController, checkInFoV, bool, (SceneObject* obj, F32 fov, bool checkEnabled), (nullAsType<ShapeBase*>(), 45.0f, false),
  186. "@brief Check whether an object is within a specified veiw cone.\n"
  187. "@obj Object to check. (If blank, it will check the current target).\n"
  188. "@fov view angle in degrees.(Defaults to 45)\n"
  189. "@checkEnabled check whether the object can take damage and if so is still alive.(Defaults to false)\n")
  190. {
  191. return object->getAim()->checkInFoV(obj, fov, checkEnabled);
  192. }