DENG_EXTERN_C void Mobj_SpawnDamageParticleGen(mobj_t *mo, mobj_t *inflictor, int amount) { #ifdef __CLIENT__ if(!mo || !inflictor || amount <= 0) return; // Are particles allowed? //if(!useParticles) return; ded_ptcgen_t const *def = Def_GetDamageGenerator(mo->type); if(def) { Generator *gen = Mobj_Map(*mo).newGenerator(); if(!gen) return; // No more generators. gen->count = def->particles; gen->configureFromDef(def); gen->setUntriggered(); gen->spawnRateMultiplier = de::max(amount, 1); // Calculate appropriate center coordinates. gen->originAtSpawn[VX] += FLT2FIX(mo->origin[VX]); gen->originAtSpawn[VY] += FLT2FIX(mo->origin[VY]); gen->originAtSpawn[VZ] += FLT2FIX(mo->origin[VZ] + mo->height / 2); // Calculate launch vector. vec3f_t vecDelta; V3f_Set(vecDelta, inflictor->origin[VX] - mo->origin[VX], inflictor->origin[VY] - mo->origin[VY], (inflictor->origin[VZ] - inflictor->height / 2) - (mo->origin[VZ] + mo->height / 2)); vec3f_t vector; V3f_SetFixed(vector, gen->vector[VX], gen->vector[VY], gen->vector[VZ]); V3f_Sum(vector, vector, vecDelta); V3f_Normalize(vector); gen->vector[VX] = FLT2FIX(vector[VX]); gen->vector[VY] = FLT2FIX(vector[VY]); gen->vector[VZ] = FLT2FIX(vector[VZ]); // Is there a need to pre-simulate? gen->presimulate(def->preSim); } #else DENG2_UNUSED3(mo, inflictor, amount); #endif }
void Plane::spawnParticleGen(ded_ptcgen_t const *def) { //if(!useParticles) return; if(!def) return; // Plane we spawn relative to may not be this one. int relPlane = indexInSector(); if(def->flags & Generator::SpawnCeiling) relPlane = Sector::Ceiling; if(def->flags & Generator::SpawnFloor) relPlane = Sector::Floor; if(relPlane != indexInSector()) { sector().plane(relPlane).spawnParticleGen(def); return; } // Only planes in sectors with volume on the world X/Y axis can support generators. if(!sector().sideCount()) return; // Only one generator per plane. if(hasGenerator()) return; // Are we out of generators? Generator *gen = map().newGenerator(); if(!gen) return; gen->count = def->particles; // Size of source sector might determine count. if(def->flags & Generator::Density) { gen->spawnRateMultiplier = sector().roughArea() / (128 * 128); } else { gen->spawnRateMultiplier = 1; } // Initialize the particle generator. gen->configureFromDef(def); gen->plane = this; // Is there a need to pre-simulate? gen->presimulate(def->preSim); }
void Mobj_SpawnParticleGen(mobj_t *source, ded_ptcgen_t const *def) { #ifdef __CLIENT__ DENG2_ASSERT(def != 0 && source != 0); //if(!useParticles) return; Generator *gen = Mobj_Map(*source).newGenerator(); if(!gen) return; /*LOG_INFO("SpawnPtcGen: %s/%i (src:%s typ:%s mo:%p)") << def->state << (def - defs.ptcgens) << defs.states[source->state-states].id << defs.mobjs[source->type].id << source;*/ // Initialize the particle generator. gen->count = def->particles; // Size of source sector might determine count. if(def->flags & Generator::ScaledRate) { gen->spawnRateMultiplier = Mobj_BspLeafAtOrigin(*source).sectorPtr()->roughArea() / (128 * 128); } else { gen->spawnRateMultiplier = 1; } gen->configureFromDef(def); gen->source = source; gen->srcid = source->thinker.id; // Is there a need to pre-simulate? gen->presimulate(def->preSim); #else DENG2_UNUSED2(source, def); #endif }