Beispiel #1
0
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 = &currentCEG->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);
    }
}