//----------------------------------------------------------------------------- // Torque Game Engine // Copyright (C) GarageGames.com, Inc. //----------------------------------------------------------------------------- #ifndef _PROJECTILE_H_ #define _PROJECTILE_H_ #ifndef _GAMEBASE_H_ #include "game/gameBase.h" #endif #ifndef _TSSHAPE_H_ #include "ts/tsShape.h" #endif #ifndef _PLATFORMAUDIO_H_ #include "platform/platformAudio.h" #endif #include "lightingSystem/sgLightManager.h" #include "game/fx/particleEmitter.h" class ExplosionData; class SplashData; class DecalData; class ShapeBase; class TSShapeInstance; class TSThread; //-------------------------------------------------------------------------- /// Datablock for projectiles. This class is the base class for all other projectiles. class ProjectileData : public GameBaseData { typedef GameBaseData Parent; protected: bool onAdd(); public: // variables set in datablock definition: // Shape related const char* projectileShapeName; bool hasLight; F32 lightRadius; ColorF lightColor; bool hasWaterLight; ColorF waterLightColor; /// Set to true if it is a billboard and want it to always face the viewer, false otherwise bool faceViewer; Point3F scale; /// [0,1] scale of how much velocity should be inherited from the parent object F32 velInheritFactor; /// Speed of the projectile when fired F32 muzzleVelocity; /// Should it arc? bool isBallistic; /// How HIGH should it bounce (parallel to normal), [0,1] F32 bounceElasticity; /// How much momentum should be lost when it bounces (perpendicular to normal), [0,1] F32 bounceFriction; /// Should this projectile fall/rise different than a default object? F32 gravityMod; /// How long the projectile should exist before deleting itself U32 lifetime; // all times are internally represented as ticks /// How long it should not detonate on impact S32 armingDelay; // the values are converted on initialization with S32 fadeDelay; // the IRangeValidatorScaled field validator ExplosionData* explosion; // Explosion Datablock S32 explosionId; // Explosion ID ExplosionData* waterExplosion; // Water Explosion Datablock S32 waterExplosionId; // Water Explosion ID SplashData* splash; // Water Splash Datablock S32 splashId; // Water splash ID AudioProfile* sound; // Projectile Sound S32 soundId; // Projectile Sound ID enum DecalConstants { // Number of decals constant NumDecals = 6, }; DecalData* decals[NumDecals]; // Decal Datablocks S32 decalId[NumDecals]; // Decal IDs U32 decalCount; // # of loaded Decal Datablocks // variables set on preload: Resource projectileShape; S32 activateSeq; S32 maintainSeq; ParticleEmitterData* particleEmitter; S32 particleEmitterId; ParticleEmitterData* particleWaterEmitter; S32 particleWaterEmitterId; ProjectileData(); void packData(BitStream*); void unpackData(BitStream*); bool preload(bool server, char errorBuffer[256]); static void initPersistFields(); DECLARE_CONOBJECT(ProjectileData); }; DECLARE_CONSOLETYPE(ProjectileData) //-------------------------------------------------------------------------- /// Base class for all projectiles. class Projectile : public GameBase { typedef GameBase Parent; public: // Initial conditions enum ProjectileConstants { SourceIdTimeoutTicks = 7, // = 231 ms DeleteWaitTime = 500, ///< 500 ms delete timeout (for network transmission delays) ExcessVelDirBits = 7, MaxLivingTicks = 4095, }; enum UpdateMasks { BounceMask = Parent::NextFreeMask, ExplosionMask = Parent::NextFreeMask << 1, NextFreeMask = Parent::NextFreeMask << 2 }; protected: ProjectileData* mDataBlock; ParticleEmitter* mParticleEmitter; ParticleEmitter* mParticleWaterEmitter; AUDIOHANDLE mSoundHandle; Point3F mCurrPosition; Point3F mCurrVelocity; S32 mSourceObjectId; S32 mSourceObjectSlot; // Time related variables common to all projectiles, managed by processTick U32 mCurrTick; ///< Current time in ticks SimObjectPtr mSourceObject; ///< Actual pointer to the source object, times out after SourceIdTimeoutTicks // Rendering related variables TSShapeInstance* mProjectileShape; TSThread* mActivateThread; TSThread* mMaintainThread; Point3F mLastRenderPos; void registerLights(LightManager * lm, bool lightingScene); LightInfo mLight; bool mHidden; ///< set by the derived class, if true, projectile doesn't render F32 mFadeValue; ///< set in processTick, interpolation between fadeDelay and lifetime ///< in data block // Warping and back delta variables. Only valid on the client // Point3F mWarpStart; Point3F mWarpEnd; U32 mWarpTicksRemaining; Point3F mCurrDeltaBase; Point3F mCurrBackDelta; Point3F mExplosionPosition; Point3F mExplosionNormal; U32 mCollideHitType; bool onAdd(); void onRemove(); bool onNewDataBlock(GameBaseData *dptr); void processTick(const Move *move); void advanceTime(F32 dt); void interpolateTick(F32 delta); /// What to do once this projectile collides with something virtual void onCollision(const Point3F& p, const Point3F& n, SceneObject*); /// What to do when this projectile explodes virtual void explode(const Point3F& p, const Point3F& n, const U32 collideType ); /// Returns the velocity of the projectile Point3F getVelocity() const; void emitParticles(const Point3F&, const Point3F&, const Point3F&, const U32); void updateSound(); // Rendering void prepModelView ( SceneState *state); bool prepRenderImage ( SceneState *state, const U32 stateKey, const U32 startZone, const bool modifyBaseZoneState=false); void renderObject ( SceneState *state, SceneRenderImage *image); // These are stolen from the player class .. bool pointInWater( const Point3F &point ); ///< Tests to see if a point is in water U32 packUpdate (NetConnection *conn, U32 mask, BitStream *stream); void unpackUpdate(NetConnection *conn, BitStream *stream); public: F32 getUpdatePriority(CameraScopeQuery *focusObject, U32 updateMask, S32 updateSkips); Projectile(); ~Projectile(); DECLARE_CONOBJECT(Projectile); static void initPersistFields(); virtual bool calculateImpact(float simTime, Point3F& pointOfImpact, float& impactTime); static U32 smProjectileWarpTicks; protected: static const U32 csmStaticCollisionMask; static const U32 csmDynamicCollisionMask; static const U32 csmDamageableMask; }; #endif // _H_PROJECTILE