||This article or section is incomplete. It doesn't have all of the necessary core information on this topic. Please help the SRB2 Wiki by finishing this article.
A_NapalmScatter is an action that is used by Brak Eggman's napalm bombs to scatter a specific number of projectiles in a circle around the bomb after exploding. The lower 16 bits of Var1 is the Object type of the Objects to be thrown, the upper 16 bits of Var1 is the number of Objects to be thrown. The lower 16 bits of Var2 is the distance to toss the Objects, the upper 16 bits of Var2 determines the airtime in tics of the thrown Objects.
Code – A_NapalmScatter
// Function: A_NapalmScatter
// Description: Scatters a specific number of projectiles around in a circle.
// Intended for use with objects that are affected by gravity; would be kind of silly otherwise.
// Lower 16 bits: object # to lob (TODO: come up with a default)
// Upper 16 bits: Number to lob (default 8)
// Lower 16 bits: distance to toss them (No default - 0 does just that - but negatives will revert to 128)
// Upper 16 bits: airtime in tics (default 16)
void A_NapalmScatter(mobj_t *actor)
mobjtype_t typeOfShot = var1 & 0x0000FFFF; // Type
INT32 numToShoot = (var1 & 0xFFFF0000) >> 16; // How many
fixed_t distance = (var2 & 0x0000FFFF) << FRACBITS; // How far
fixed_t airtime = var2 & 0xFFFF0000; // How long until impact (assuming no obstacles)
fixed_t vx; // Horizontal momentum
fixed_t vy; // Vertical momentum
fixed_t g; // Gravity
INT32 i; // for-loop cursor
mobj_t *mo; // each and every spawned napalm burst
if (LUA_CallAction("A_NapalmScatter", actor))
// Some quick sanity-checking
if (typeOfShot >= NUMMOBJTYPES) // I'd add a <0 check, too, but 0x0000FFFF isn't negative in this case
typeOfShot = MT_NULL;
if (numToShoot <= 0) // Presumably you forgot to set var1 up; else, why are you calling this to shoot nothing?
numToShoot = 8;
else if (numToShoot > 8192) // If you seriously need this many objects spawned, stop and ask yourself "Why am I doing this?"
numToShoot = 8192;
if (distance < 0) // Presumably you thought this was an unsigned integer, you naive fool
distance = 32767<<FRACBITS;
if (airtime <= 0) // Same deal as distance I guess
airtime = 16<<FRACBITS;
// Look up actor's current gravity situation
g = FixedMul(gravity,(FixedDiv(*actor->subsector->sector->gravity>>FRACBITS, 1000)));
g = gravity;
// vy = (g*(airtime-1))/2
vy = FixedMul(g,(airtime-(1<<FRACBITS)))>>1;
// vx = distance/airtime
vx = FixedDiv(distance, airtime);
for (i = 0; i<numToShoot; i++)
const angle_t fa = (i*FINEANGLES/numToShoot) & FINEMASK;
mo = P_SpawnMobj(actor->x, actor->y, actor->z, typeOfShot);
P_SetTarget(&mo->target, actor->target); // Transfer target so Brak doesn't hit himself like an idiot
mo->angle = fa << ANGLETOFINESHIFT;
mo->momx = FixedMul(FINECOSINE(fa),vx);
mo->momy = FixedMul(FINESINE(fa),vx);
mo->momz = vy;