bool CCustomExplosionGenerator::Explosion( unsigned int explosionID, const float3& pos, float damage, float radius, CUnit* owner, float gfxMod, CUnit* hit, const float3& dir ) { if (explosionID == -1U || explosionID >= explosionData.size()) { // invalid CEG ID return false; } const float groundHeight = ground->GetHeightReal(pos.x, pos.z); const float altitude = pos.y - groundHeight; unsigned int flags = GetFlagsFromHeight(pos.y, altitude); const bool groundExplosion = ((flags & CCustomExplosionGenerator::SPW_GROUND) != 0); if (hit) flags |= SPW_UNIT; else flags |= SPW_NO_UNIT; const CEGData& cegData = explosionData[explosionID]; const std::vector<ProjectileSpawnInfo>& spawnInfo = cegData.projectileSpawn; const GroundFlashInfo& groundFlash = cegData.groundFlash; for (int a = 0; a < spawnInfo.size(); a++) { const ProjectileSpawnInfo& psi = spawnInfo[a]; if (!(psi.flags & flags)) { continue; } // If we're saturated, spawn only synced projectiles. // Whether a class is synced is determined by the creg::CF_Synced flag. if (ph->particleSaturation > 1 && !(psi.flags & SPW_SYNCED)) { continue; } for (int c = 0; c < psi.count; c++) { CExpGenSpawnable* projectile = (CExpGenSpawnable*) (psi.projectileClass)->CreateInstance(); ExecuteExplosionCode(&psi.code[0], damage, (char*) projectile, c, dir, (psi.flags & SPW_SYNCED) != 0); projectile->Init(pos, owner); } } if (groundExplosion && (groundFlash.ttl > 0) && (groundFlash.flashSize > 1)) { new CStandardGroundFlash(pos, groundFlash.circleAlpha, groundFlash.flashAlpha, groundFlash.flashSize, groundFlash.circleGrowth, groundFlash.ttl, groundFlash.color); } if (cegData.useDefaultExplosions) { return CStdExplosionGenerator::Explosion(-1U, pos, damage, radius, owner, gfxMod, hit, dir); } return true; }
void CCustomExplosionGenerator::Explosion(const float3& pos, float damage, float radius, CUnit* owner, float gfxMod, CUnit* hit, const float3& dir) { if (currentCEG == cachedCEGs.end()) { // Explosion() called before Load()'ing a CEG (after // constructing a CCustomExplosionGenerator object) return; } float h2 = ground->GetHeight2(pos.x, pos.z); unsigned int flags = 0; if (pos.y - max(0.0f, h2) > 20) flags = SPW_AIR; else if (h2 < -3) flags = SPW_WATER; else if (pos.y < -15) flags = SPW_UNDERWATER; else flags = SPW_GROUND; if (hit) flags |= SPW_UNIT; else flags |= SPW_NO_UNIT; for (int a = 0; a < (currentCEG->second).projectileSpawn.size(); a++) { ProjectileSpawnInfo& psi = (currentCEG->second).projectileSpawn[a]; if (!(psi.flags & flags)) { continue; } // If we're saturated, spawn only synced projectiles. // Whether a class is synced is determined by the creg::CF_Synced flag. if (ph->particleSaturation > 1 && !(psi.flags & SPW_SYNCED)) { continue; } for (int c = 0; c < psi.count; c++) { CExpGenSpawnable* projectile = (CExpGenSpawnable*) (psi.projectileClass)->CreateInstance(); ExecuteExplosionCode(&psi.code[0], damage, (char*) projectile, c, dir); projectile->Init(pos, owner); } } const GroundFlashInfo& groundFlash = (currentCEG->second).groundFlash; if ((flags & SPW_GROUND) && groundFlash.ttl > 0) { new CStandardGroundFlash(pos, groundFlash.circleAlpha, groundFlash.flashAlpha, groundFlash.flashSize, groundFlash.circleGrowth, groundFlash.ttl, groundFlash.color); } if ((currentCEG->second).useDefaultExplosions) { CStdExplosionGenerator::Explosion(pos, damage, radius, owner, gfxMod, hit, dir); } }
void CCustomExplosionGenerator::Explosion(const float3& pos, float damage, float radius, CUnit* owner, float gfxMod, CUnit* hit, const float3& dir) { if (currentCEG == 0) { // Explosion() called before Load()'ing a CEG return; } float h2 = ground->GetHeight2(pos.x, pos.z); unsigned int flags = 0; if (pos.y - max(0.0f, h2) > 20) flags = SPW_AIR; else if (h2 < -3) flags = SPW_WATER; else if (pos.y < -15) flags = SPW_UNDERWATER; else flags = SPW_GROUND; if (hit) flags |= SPW_UNIT; else flags |= SPW_NO_UNIT; for (int a = 0; a < currentCEG->projectileSpawn.size(); a++) { ProjectileSpawnInfo* psi = ¤tCEG->projectileSpawn[a]; if (!(psi->flags & flags)) { continue; } for (int c = 0; c < psi->count; c++) { CExpGenSpawnable* projectile = (CExpGenSpawnable*) psi->projectileClass->CreateInstance(); ExecuteExplosionCode(&psi->code[0], damage, (char*) projectile, c, dir); projectile->Init(pos, owner); } } const GroundFlashInfo& groundFlash = currentCEG->groundFlash; if ((flags & SPW_GROUND) && groundFlash.ttl > 0) { SAFE_NEW CStandardGroundFlash(pos, groundFlash.circleAlpha, groundFlash.flashAlpha, groundFlash.flashSize, groundFlash.circleGrowth, groundFlash.ttl, groundFlash.color); } if (currentCEG->useDefaultExplosions) { CStdExplosionGenerator::Explosion(pos, damage, radius, owner, gfxMod, hit, dir); } }