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