aiTurretShape.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  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. #ifndef _AITURRETSHAPE_H_
  23. #define _AITURRETSHAPE_H_
  24. #ifndef _TURRETSHAPE_H_
  25. #include "T3D/turret/turretShape.h"
  26. #endif
  27. //----------------------------------------------------------------------------
  28. class AITurretShapeData: public TurretShapeData {
  29. typedef TurretShapeData Parent;
  30. public:
  31. enum Constants {
  32. MaxStates = 31, ///< We get one less than state bits because of
  33. /// the way data is packed.
  34. NumStateBits = 5,
  35. };
  36. struct StateData {
  37. StateData();
  38. const char* name; ///< State name
  39. /// @name Transition states
  40. ///
  41. /// @{
  42. ///
  43. struct Transition {
  44. S32 rest[2]; ///< NotAtRest/AtRest (NotStatic/Static)
  45. S32 target[2]; ///< NoTarget/Target
  46. S32 activated[2]; ///< Deactivated/Activated
  47. S32 timeout; ///< Transition after delay
  48. } transition;
  49. /// @}
  50. /// @name State attributes
  51. /// @{
  52. bool fire; ///< Can only have one fire state
  53. bool scan; ///< Perform a continuous scan looking for targets
  54. bool scaleAnimation; ///< Scale animation to fit the state timeout
  55. bool direction; ///< Animation direction
  56. bool waitForTimeout; ///< Require the timeout to pass before advancing to the next
  57. /// state.
  58. F32 timeoutValue; ///< A timeout value; the effect of this value is determined
  59. /// by the flags scaleAnimation and waitForTimeout
  60. S32 sequence; ///< Main thread sequence ID.
  61. ///
  62. ///
  63. const char* script; ///< Function on datablock to call when we enter this state; passed the id of
  64. /// the imageSlot.
  65. /// @}
  66. };
  67. /// @name State Data
  68. /// Individual state data used to initialize struct array
  69. /// @{
  70. const char* stateName [MaxStates];
  71. const char* stateTransitionAtRest [MaxStates];
  72. const char* stateTransitionNotAtRest [MaxStates];
  73. const char* stateTransitionTarget [MaxStates];
  74. const char* stateTransitionNoTarget [MaxStates];
  75. const char* stateTransitionActivated [MaxStates];
  76. const char* stateTransitionDeactivated [MaxStates];
  77. const char* stateTransitionTimeout [MaxStates];
  78. F32 stateTimeoutValue [MaxStates];
  79. bool stateWaitForTimeout [MaxStates];
  80. bool stateFire [MaxStates];
  81. bool stateScan [MaxStates];
  82. bool stateScaleAnimation [MaxStates];
  83. bool stateDirection [MaxStates];
  84. const char* stateSequence [MaxStates];
  85. const char* stateScript [MaxStates];
  86. /// @}
  87. /// @name State Array
  88. ///
  89. /// State array is initialized onAdd from the individual state
  90. /// struct array elements.
  91. ///
  92. /// @{
  93. StateData state[MaxStates]; ///< Array of states.
  94. bool statesLoaded; ///< Are the states loaded yet?
  95. S32 fireState; ///< The ID of the fire state.
  96. bool isAnimated; ///< This image contains at least one animated states
  97. /// @}
  98. F32 maxScanHeading; ///< Maximum heading angle from center to scan, in degrees
  99. F32 maxScanPitch; ///< Maximum pitch angle from center to scan, in degrees
  100. F32 maxScanDistance; ///< Maximum distance to scan to
  101. S32 scanTickFrequency; ///< How often should we perform a scan
  102. S32 scanTickFrequencyVariance; ///< Random amount that should be added to the scan tick frequency
  103. F32 trackLostTargetTime; ///< How long after the turret has lost the target should it still track it (in seconds)
  104. S32 scanNode; ///< The node on the shape we will scan from
  105. S32 aimNode; ///< The node on the shape we will aim from
  106. F32 maxWeaponRange; ///< Maximum range of the weapons, which may be different than the max scan distance
  107. F32 weaponLeadVelocity; ///< Velocity used to lead target (if value <= 0, don't lead target).
  108. public:
  109. AITurretShapeData();
  110. DECLARE_CONOBJECT(AITurretShapeData);
  111. static void initPersistFields();
  112. virtual bool onAdd();
  113. virtual bool preload(bool server, String &errorStr);
  114. virtual void packData(BitStream* stream);
  115. virtual void unpackData(BitStream* stream);
  116. S32 lookupState(const char* name); ///< Get a state by name.
  117. };
  118. //----------------------------------------------------------------------------
  119. // As shipped, AITurretShape plus the chain of classes it inherits from, consumes
  120. // all 32 mask-bits. AFX uses one additional mask-bit in GameBase, which pushes
  121. // AITurretShape over the mask-bit limit which will cause runtime crashes. As
  122. // a workaround, AFX modifies AITurretShape so that it reuses the TurretUpdateMask
  123. // defined by TurretShape rather than adding a unique TurretStateMask. This will
  124. // make AITurretShape's network updates slightly less efficient, but should be
  125. // acceptable for most uses of AITurretShape. If you plan to populate your levels
  126. // with many AITurretShape objects, consider restoring it to use of a unique
  127. // bit-mask, but if you do that, you will have to eliminate at use of at least one
  128. // bit by one of it's parent classes. (FYI ShapeBase uses 20 bits.)
  129. //
  130. // Comment out this define if you want AITurretShape to define it's own bit-mask.
  131. #define AFX_REUSE_TURRETSHAPE_MASKBITS
  132. class AITurretShape: public TurretShape
  133. {
  134. typedef TurretShape Parent;
  135. protected:
  136. #ifdef AFX_REUSE_TURRETSHAPE_MASKBITS
  137. enum MaskBits {
  138. TurretStateMask = Parent::TurretUpdateMask,
  139. NextFreeMask = Parent::NextFreeMask
  140. };
  141. #else // ORIGINAL CODE
  142. enum MaskBits {
  143. TurretStateMask = Parent::NextFreeMask,
  144. NextFreeMask = Parent::NextFreeMask << 1
  145. };
  146. #endif
  147. struct TargetInfo
  148. {
  149. SimObjectPtr<ShapeBase> target; ///< Current target
  150. Point3F lastPos; ///< The target's last known position
  151. VectorF lastVel; ///< The target's last known velocity
  152. SimTime lastSightTime; ///< The last time we saw the target
  153. bool hadValidTarget; ///< Did we previously have a valid target?
  154. TargetInfo() {reset();}
  155. void reset()
  156. {
  157. target = NULL;
  158. lastPos.zero();
  159. lastVel.zero();
  160. lastSightTime = 0;
  161. hadValidTarget = false;
  162. }
  163. // Check if we currently have a valid target
  164. bool isValid() const {return target != NULL;}
  165. // Check if we used to have a target
  166. bool hadTarget() const {return hadValidTarget;}
  167. };
  168. // Static attributes
  169. AITurretShapeData* mDataBlock;
  170. F32 mScanHeading;
  171. F32 mScanPitch;
  172. F32 mScanDistance;
  173. F32 mScanDistanceSquared;
  174. Box3F mScanBox;
  175. Box3F mTransformedScanBox;
  176. S32 mScanTickFrequency;
  177. S32 mScanTickFrequencyVariance;
  178. S32 mTicksToNextScan;
  179. F32 mWeaponRangeSquared;
  180. F32 mWeaponLeadVelocitySquared;
  181. SimSet mIgnoreObjects; ///< Ignore these objects when targeting
  182. bool mScanForTargets;
  183. bool mTrackTarget;
  184. TargetInfo mTarget; ///< Information on the current target
  185. SimObjectList mPotentialTargets;
  186. AITurretShapeData::StateData *mState;
  187. F32 mStateDelayTime; ///< Time till next state.
  188. bool mStateActive; ///< Is the turret active?
  189. TSThread *mStateAnimThread;
  190. void _initState();
  191. void _updateTurretState(F32 dt);
  192. /// Utility function to call state script functions on the datablock
  193. /// @param function Function
  194. void _scriptCallback(const char* function);
  195. void _setScanBox();
  196. void _cleanupPotentialTargets();
  197. void _performScan();
  198. void _lostTarget();
  199. void _gainedTarget(ShapeBase* target);
  200. void _trackTarget(F32 dt);
  201. void _cleanupTargetAndTurret();
  202. bool _testTargetLineOfSight(Point3F& aimPoint, ShapeBase* target, Point3F& sightPoint);
  203. /// ObjectRenderInst delegate hooked up in prepBatchRender
  204. /// if GameBase::gShowBoundingBox is true.
  205. void _renderScanner( ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *overrideMat );
  206. public:
  207. MatrixF mScanWorkspaceScanMat;
  208. MatrixF mScanWorkspaceScanWorldMat;
  209. public:
  210. AITurretShape();
  211. virtual ~AITurretShape();
  212. static void initPersistFields();
  213. bool onAdd();
  214. void onRemove();
  215. bool onNewDataBlock(GameBaseData *dptr, bool reload);
  216. void addToIgnoreList(ShapeBase* obj);
  217. void removeFromIgnoreList(ShapeBase* obj);
  218. void clearIgnoreList();
  219. S32 ignoreListCount();
  220. SimObject* getIgnoreListObject(S32 index);
  221. void setTurretStateName(const char* newState, bool force=false);
  222. void setTurretState(U32 newState, bool force=false);
  223. void activateTurret() {mStateActive = true;}
  224. void deactivateTurret() {mStateActive = false;}
  225. void startScanForTargets() {mScanForTargets = true;}
  226. void stopScanForTargets() {mScanForTargets = false;}
  227. void startTrackingTarget() {mTrackTarget = true;}
  228. void stopTrackingTarget() {mTrackTarget = false;}
  229. ShapeBase* getTarget() {return mTarget.target;}
  230. bool hasTarget() {return mTarget.target != NULL;}
  231. void resetTarget() {mTarget.reset();}
  232. void addPotentialTarget(ShapeBase* shape);
  233. void setWeaponLeadVelocity(F32 velocity) {mWeaponLeadVelocitySquared = velocity * velocity;}
  234. F32 getWeaponLeadVelocity() {return mSqrt(mWeaponLeadVelocitySquared);}
  235. void setAllGunsFiring(bool fire);
  236. void setGunSlotFiring(S32 slot, bool fire);
  237. virtual void setTransform(const MatrixF &mat);
  238. void getScanTransform(MatrixF& mat);
  239. void getAimTransform(MatrixF& mat);
  240. F32 getMaxScanHeading() const {return mScanHeading;}
  241. F32 getMaxScanPitch() const {return mScanPitch;}
  242. F32 getMaxScanDistance() const {return mScanDistance;}
  243. F32 getMaxScanDistanceSquared() const {return mScanDistanceSquared;}
  244. void recenterTurret();
  245. virtual void processTick(const Move *move);
  246. virtual void advanceTime(F32 dt);
  247. virtual U32 packUpdate (NetConnection *conn, U32 mask, BitStream *stream);
  248. virtual void unpackUpdate(NetConnection *conn, BitStream *stream);
  249. void prepBatchRender( SceneRenderState *state, S32 mountedImageIndex );
  250. DECLARE_CONOBJECT(AITurretShape);
  251. };
  252. #endif // _AITURRETSHAPE_H_