aiTurretShape.h
Engine/source/T3D/turret/aiTurretShape.h
Classes:
class
class
Public Defines
define
Detailed Description
Public Defines
AFX_REUSE_TURRETSHAPE_MASKBITS()
1 2//----------------------------------------------------------------------------- 3// Copyright (c) 2012 GarageGames, LLC 4// 5// Permission is hereby granted, free of charge, to any person obtaining a copy 6// of this software and associated documentation files (the "Software"), to 7// deal in the Software without restriction, including without limitation the 8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9// sell copies of the Software, and to permit persons to whom the Software is 10// furnished to do so, subject to the following conditions: 11// 12// The above copyright notice and this permission notice shall be included in 13// all copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21// IN THE SOFTWARE. 22//----------------------------------------------------------------------------- 23 24#ifndef _AITURRETSHAPE_H_ 25#define _AITURRETSHAPE_H_ 26 27#ifndef _TURRETSHAPE_H_ 28 #include "T3D/turret/turretShape.h" 29#endif 30 31 32//---------------------------------------------------------------------------- 33 34class AITurretShapeData: public TurretShapeData { 35 36 typedef TurretShapeData Parent; 37 38public: 39 enum Constants { 40 MaxStates = 31, ///< We get one less than state bits because of 41 /// the way data is packed. 42 NumStateBits = 5, 43 }; 44 45 struct StateData { 46 StateData(); 47 const char* name; ///< State name 48 49 /// @name Transition states 50 /// 51 /// @{ 52 53 /// 54 struct Transition { 55 S32 rest[2]; ///< NotAtRest/AtRest (NotStatic/Static) 56 S32 target[2]; ///< NoTarget/Target 57 S32 activated[2]; ///< Deactivated/Activated 58 S32 timeout; ///< Transition after delay 59 } transition; 60 61 /// @} 62 63 /// @name State attributes 64 /// @{ 65 66 bool fire; ///< Can only have one fire state 67 bool scan; ///< Perform a continuous scan looking for targets 68 bool scaleAnimation; ///< Scale animation to fit the state timeout 69 bool direction; ///< Animation direction 70 bool waitForTimeout; ///< Require the timeout to pass before advancing to the next 71 /// state. 72 F32 timeoutValue; ///< A timeout value; the effect of this value is determined 73 /// by the flags scaleAnimation and waitForTimeout 74 S32 sequence; ///< Main thread sequence ID. 75 /// 76 /// 77 const char* script; ///< Function on datablock to call when we enter this state; passed the id of 78 /// the imageSlot. 79 80 /// @} 81 }; 82 83 /// @name State Data 84 /// Individual state data used to initialize struct array 85 /// @{ 86 const char* stateName [MaxStates]; 87 88 const char* stateTransitionAtRest [MaxStates]; 89 const char* stateTransitionNotAtRest [MaxStates]; 90 const char* stateTransitionTarget [MaxStates]; 91 const char* stateTransitionNoTarget [MaxStates]; 92 const char* stateTransitionActivated [MaxStates]; 93 const char* stateTransitionDeactivated [MaxStates]; 94 const char* stateTransitionTimeout [MaxStates]; 95 F32 stateTimeoutValue [MaxStates]; 96 bool stateWaitForTimeout [MaxStates]; 97 98 bool stateFire [MaxStates]; 99 bool stateScan [MaxStates]; 100 101 bool stateScaleAnimation [MaxStates]; 102 bool stateDirection [MaxStates]; 103 const char* stateSequence [MaxStates]; 104 105 const char* stateScript [MaxStates]; 106 107 /// @} 108 109 /// @name State Array 110 /// 111 /// State array is initialized onAdd from the individual state 112 /// struct array elements. 113 /// 114 /// @{ 115 StateData state[MaxStates]; ///< Array of states. 116 bool statesLoaded; ///< Are the states loaded yet? 117 S32 fireState; ///< The ID of the fire state. 118 bool isAnimated; ///< This image contains at least one animated states 119 /// @} 120 121 F32 maxScanHeading; ///< Maximum heading angle from center to scan, in degrees 122 F32 maxScanPitch; ///< Maximum pitch angle from center to scan, in degrees 123 F32 maxScanDistance; ///< Maximum distance to scan to 124 125 S32 scanTickFrequency; ///< How often should we perform a scan 126 S32 scanTickFrequencyVariance; ///< Random amount that should be added to the scan tick frequency 127 128 F32 trackLostTargetTime; ///< How long after the turret has lost the target should it still track it (in seconds) 129 130 S32 scanNode; ///< The node on the shape we will scan from 131 S32 aimNode; ///< The node on the shape we will aim from 132 133 F32 maxWeaponRange; ///< Maximum range of the weapons, which may be different than the max scan distance 134 135 F32 weaponLeadVelocity; ///< Velocity used to lead target (if value <= 0, don't lead target). 136 137public: 138 AITurretShapeData(); 139 140 DECLARE_CONOBJECT(AITurretShapeData); 141 142 static void initPersistFields(); 143 144 virtual bool onAdd(); 145 virtual bool preload(bool server, String &errorStr); 146 147 virtual void packData(BitStream* stream); 148 virtual void unpackData(BitStream* stream); 149 150 S32 lookupState(const char* name); ///< Get a state by name. 151}; 152 153//---------------------------------------------------------------------------- 154 155// As shipped, AITurretShape plus the chain of classes it inherits from, consumes 156// all 32 mask-bits. AFX uses one additional mask-bit in GameBase, which pushes 157// AITurretShape over the mask-bit limit which will cause runtime crashes. As 158// a workaround, AFX modifies AITurretShape so that it reuses the TurretUpdateMask 159// defined by TurretShape rather than adding a unique TurretStateMask. This will 160// make AITurretShape's network updates slightly less efficient, but should be 161// acceptable for most uses of AITurretShape. If you plan to populate your levels 162// with many AITurretShape objects, consider restoring it to use of a unique 163// bit-mask, but if you do that, you will have to eliminate at use of at least one 164// bit by one of it's parent classes. (FYI ShapeBase uses 20 bits.) 165// 166// Comment out this define if you want AITurretShape to define it's own bit-mask. 167#define AFX_REUSE_TURRETSHAPE_MASKBITS 168class AITurretShape: public TurretShape 169{ 170 typedef TurretShape Parent; 171 172protected: 173 174#ifdef AFX_REUSE_TURRETSHAPE_MASKBITS 175 enum MaskBits { 176 TurretStateMask = Parent::TurretUpdateMask, 177 NextFreeMask = Parent::NextFreeMask 178 }; 179#else // ORIGINAL CODE 180 enum MaskBits { 181 TurretStateMask = Parent::NextFreeMask, 182 NextFreeMask = Parent::NextFreeMask << 1 183 }; 184#endif 185 186 struct TargetInfo 187 { 188 SimObjectPtr<ShapeBase> target; ///< Current target 189 Point3F lastPos; ///< The target's last known position 190 VectorF lastVel; ///< The target's last known velocity 191 SimTime lastSightTime; ///< The last time we saw the target 192 bool hadValidTarget; ///< Did we previously have a valid target? 193 194 TargetInfo() {reset();} 195 196 void reset() 197 { 198 target = NULL; 199 lastPos.zero(); 200 lastVel.zero(); 201 lastSightTime = 0; 202 hadValidTarget = false; 203 } 204 205 // Check if we currently have a valid target 206 bool isValid() const {return target != NULL;} 207 208 // Check if we used to have a target 209 bool hadTarget() const {return hadValidTarget;} 210 }; 211 212 // Static attributes 213 AITurretShapeData* mDataBlock; 214 215 F32 mScanHeading; 216 F32 mScanPitch; 217 F32 mScanDistance; 218 F32 mScanDistanceSquared; 219 Box3F mScanBox; 220 Box3F mTransformedScanBox; 221 222 S32 mScanTickFrequency; 223 S32 mScanTickFrequencyVariance; 224 S32 mTicksToNextScan; 225 226 F32 mWeaponRangeSquared; 227 F32 mWeaponLeadVelocitySquared; 228 229 SimSet mIgnoreObjects; ///< Ignore these objects when targeting 230 231 bool mScanForTargets; 232 bool mTrackTarget; 233 TargetInfo mTarget; ///< Information on the current target 234 235 SimObjectList mPotentialTargets; 236 237 AITurretShapeData::StateData *mState; 238 F32 mStateDelayTime; ///< Time till next state. 239 bool mStateActive; ///< Is the turret active? 240 TSThread *mStateAnimThread; 241 242 void _initState(); 243 void _updateTurretState(F32 dt); 244 245 /// Utility function to call state script functions on the datablock 246 /// @param function Function 247 void _scriptCallback(const char* function); 248 249 void _setScanBox(); 250 251 void _cleanupPotentialTargets(); 252 void _performScan(); 253 void _lostTarget(); 254 void _gainedTarget(ShapeBase* target); 255 void _trackTarget(F32 dt); 256 void _cleanupTargetAndTurret(); 257 bool _testTargetLineOfSight(Point3F& aimPoint, ShapeBase* target, Point3F& sightPoint); 258 259 /// ObjectRenderInst delegate hooked up in prepBatchRender 260 /// if GameBase::gShowBoundingBox is true. 261 void _renderScanner( ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *overrideMat ); 262 263public: 264 265 MatrixF mScanWorkspaceScanMat; 266 MatrixF mScanWorkspaceScanWorldMat; 267 268public: 269 270 AITurretShape(); 271 virtual ~AITurretShape(); 272 273 static void initPersistFields(); 274 275 bool onAdd(); 276 void onRemove(); 277 bool onNewDataBlock(GameBaseData *dptr, bool reload); 278 279 void addToIgnoreList(ShapeBase* obj); 280 void removeFromIgnoreList(ShapeBase* obj); 281 void clearIgnoreList(); 282 S32 ignoreListCount(); 283 SimObject* getIgnoreListObject(S32 index); 284 285 void setTurretStateName(const char* newState, bool force=false); 286 void setTurretState(U32 newState, bool force=false); 287 288 void activateTurret() {mStateActive = true;} 289 void deactivateTurret() {mStateActive = false;} 290 291 void startScanForTargets() {mScanForTargets = true;} 292 void stopScanForTargets() {mScanForTargets = false;} 293 294 void startTrackingTarget() {mTrackTarget = true;} 295 void stopTrackingTarget() {mTrackTarget = false;} 296 297 ShapeBase* getTarget() {return mTarget.target;} 298 bool hasTarget() {return mTarget.target != NULL;} 299 void resetTarget() {mTarget.reset();} 300 301 void addPotentialTarget(ShapeBase* shape); 302 303 void setWeaponLeadVelocity(F32 velocity) {mWeaponLeadVelocitySquared = velocity * velocity;} 304 F32 getWeaponLeadVelocity() {return mSqrt(mWeaponLeadVelocitySquared);} 305 306 void setAllGunsFiring(bool fire); 307 void setGunSlotFiring(S32 slot, bool fire); 308 309 virtual void setTransform(const MatrixF &mat); 310 void getScanTransform(MatrixF& mat); 311 void getAimTransform(MatrixF& mat); 312 313 F32 getMaxScanHeading() const {return mScanHeading;} 314 F32 getMaxScanPitch() const {return mScanPitch;} 315 F32 getMaxScanDistance() const {return mScanDistance;} 316 F32 getMaxScanDistanceSquared() const {return mScanDistanceSquared;} 317 318 void recenterTurret(); 319 320 virtual void processTick(const Move *move); 321 virtual void advanceTime(F32 dt); 322 323 virtual U32 packUpdate (NetConnection *conn, U32 mask, BitStream *stream); 324 virtual void unpackUpdate(NetConnection *conn, BitStream *stream); 325 326 void prepBatchRender( SceneRenderState *state, S32 mountedImageIndex ); 327 328 DECLARE_CONOBJECT(AITurretShape); 329}; 330 331#endif // _AITURRETSHAPE_H_ 332