1 /* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */ 2 3 #ifndef PROJECTILE_HANDLER_H 4 #define PROJECTILE_HANDLER_H 5 6 #include <list> 7 #include <set> 8 #include <vector> 9 #include <stack> 10 11 #include "lib/gml/ThreadSafeContainers.h" 12 13 #include "Sim/Projectiles/ProjectileFunctors.h" 14 #include "System/float3.h" 15 #include "System/Platform/Threading.h" 16 17 // bypass id and event handling for unsynced projectiles (faster) 18 #define UNSYNCED_PROJ_NOEVENT 1 19 20 class CProjectile; 21 class CUnit; 22 class CFeature; 23 class CGroundFlash; 24 struct UnitDef; 25 struct FlyingPiece; 26 struct S3DOPrimitive; 27 struct S3DOPiece; 28 struct SS3OVertex; 29 30 31 32 typedef std::pair<CProjectile*, int> ProjectileMapValPair; 33 typedef std::pair<int, ProjectileMapValPair> ProjectileMapKeyPair; 34 typedef std::map<int, ProjectileMapValPair> ProjectileMap; 35 36 typedef ThreadListSim<std::list<CProjectile*>, std::set<CProjectile*>, CProjectile*, ProjectileDetacher> ProjectileContainer; 37 typedef ThreadListSimRender<std::list<CGroundFlash*>, std::set<CGroundFlash*>, CGroundFlash*> GroundFlashContainer; 38 39 typedef ThreadListSimRender<std::set<FlyingPiece*, FlyingPieceComparator>, void, FlyingPiece*> FlyingPieceContainer; 40 41 typedef ThreadMapRender<CProjectile*, int, ProjectileMapValPair, ProjectileIndexer> ProjectileRenderMap; 42 43 44 class CProjectileHandler 45 { 46 CR_DECLARE_STRUCT(CProjectileHandler) 47 48 public: 49 CProjectileHandler(); 50 ~CProjectileHandler(); 51 void Serialize(creg::ISerializer* s); 52 void PostLoad(); 53 GetMapPairBySyncedID(int id)54 inline const ProjectileMapValPair* GetMapPairBySyncedID(int id) const { 55 const ProjectileMap& projectileIDs = syncedProjectileIDs; 56 const ProjectileMap::const_iterator it = projectileIDs.find(id); 57 58 if (it == projectileIDs.end()) 59 return NULL; 60 61 return &(it->second); 62 } 63 GetMapPairByUnsyncedID(int id)64 inline const ProjectileMapValPair* GetMapPairByUnsyncedID(int id) const { 65 if (UNSYNCED_PROJ_NOEVENT) 66 return NULL; // unsynced projectiles have no IDs if UNSYNCED_PROJ_NOEVENT 67 68 const ProjectileMap& projectileIDs = unsyncedProjectileIDs; 69 const ProjectileMap::const_iterator it = projectileIDs.find(id); 70 71 if (it == projectileIDs.end()) 72 return NULL; 73 74 return &(it->second); 75 } 76 GetSyncedRenderProjectileIDs()77 ProjectileRenderMap& GetSyncedRenderProjectileIDs() { return syncedRenderProjectileIDs; } GetUnsyncedRenderProjectileIDs()78 ProjectileRenderMap& GetUnsyncedRenderProjectileIDs() { return unsyncedRenderProjectileIDs; } 79 80 void CheckUnitCollisions(CProjectile*, std::vector<CUnit*>&, const float3&, const float3&); 81 void CheckFeatureCollisions(CProjectile*, std::vector<CFeature*>&, const float3&, const float3&); 82 void CheckUnitFeatureCollisions(ProjectileContainer&); 83 void CheckGroundCollisions(ProjectileContainer&); 84 void CheckCollisions(); 85 SetMaxParticles(int value)86 void SetMaxParticles(int value) { maxParticles = value; } SetMaxNanoParticles(int value)87 void SetMaxNanoParticles(int value) { maxNanoParticles = value; } 88 89 void Update(); UpdateParticleSaturation()90 void UpdateParticleSaturation() { 91 particleSaturation = (maxParticles > 0)? (currentParticles / float(maxParticles)): 1.0f; 92 } 93 94 void AddProjectile(CProjectile* p); 95 void AddGroundFlash(CGroundFlash* flash); 96 void AddFlyingPiece(const float3& pos, const float3& speed, int team, const S3DOPiece* piece, const S3DOPrimitive* chunk); 97 void AddFlyingPiece(const float3& pos, const float3& speed, int team, int textureType, const SS3OVertex* chunk); 98 void AddNanoParticle(const float3&, const float3&, const UnitDef*, int team, bool highPriority); 99 void AddNanoParticle(const float3&, const float3&, const UnitDef*, int team, float radius, bool inverse, bool highPriority); 100 bool RenderAccess(const CProjectile *p) const; 101 102 public: 103 ProjectileContainer syncedProjectiles; // contains only projectiles that can change simulation state 104 ProjectileContainer unsyncedProjectiles; // contains only projectiles that cannot change simulation state 105 FlyingPieceContainer flyingPieces3DO; // unsynced 106 FlyingPieceContainer flyingPiecesS3O; // unsynced 107 GroundFlashContainer groundFlashes; // unsynced 108 109 int maxParticles; // different effects should start to cut down on unnececary(unsynced) particles when this number is reached 110 int maxNanoParticles; 111 int currentParticles; // number of particles weighted by how complex they are 112 int currentNanoParticles; 113 float particleSaturation; // currentParticles / maxParticles ratio 114 115 private: 116 void UpdateProjectileContainer(ProjectileContainer&, bool); 117 118 ProjectileRenderMap syncedRenderProjectileIDs; // same as syncedProjectileIDs, used by render thread 119 ProjectileRenderMap unsyncedRenderProjectileIDs; // same as unsyncedProjectileIDs, used by render thread 120 121 int maxUsedSyncedID; 122 int maxUsedUnsyncedID; 123 std::list<int> freeSyncedIDs; // available synced (weapon, piece) projectile ID's 124 std::list<int> freeUnsyncedIDs; // available unsynced projectile ID's 125 ProjectileMap syncedProjectileIDs; // ID ==> <projectile, allyteam> map for living synced projectiles 126 ProjectileMap unsyncedProjectileIDs; // ID ==> <projectile, allyteam> map for living unsynced projectiles 127 }; 128 129 130 extern CProjectileHandler* projectileHandler; 131 132 #endif /* PROJECTILE_HANDLER_H */ 133