mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-01-17 23:21:22 +00:00
Fan particle generators now suck less!
For the object... * Tag via its angle field * Number of objects to spawn per tic around it via its z field, if zero then just spawn at center * Is flipped if given MTF_OBJECTFLIP. Now there's a linedef type 15! * Tag is tag of object(s!) * Object type set via concatenation of frontside textures, MT_PARTICLE is default * The length of the linedef is the radius the particle is spawned out (zeroed if z field is 0) * Frontside x offset is speed upwards * Frontside y offset is number of degrees to turn each tic (zeroed if z field is 0) * Frontside floor and ceiling heights are the heights in which the particle is bound through some fun mathematics and/or BDSM Of course, not every story has a happy ending. * A_ParticleSpawn no longer accepts objects via its var1 because of how specialised it's gotten. Considering it can be set via abuse of actor->cvmem, I don't consider this an issue. Maybe you might disagree.
This commit is contained in:
parent
fc54ab5917
commit
2ffc06c0bc
3 changed files with 106 additions and 22 deletions
|
@ -3359,41 +3359,45 @@ void A_ScoreRise(mobj_t *actor)
|
|||
|
||||
// Function: A_ParticleSpawn
|
||||
//
|
||||
// Description: Spawns a particle at a specified interval
|
||||
// Description: Hyper-specialised function for spawning a particle for MT_PARTICLEGEN.
|
||||
//
|
||||
// var1 = type (if 0, defaults to MT_PARTICLE)
|
||||
// var1 = unused
|
||||
// var2 = unused
|
||||
//
|
||||
void A_ParticleSpawn(mobj_t *actor)
|
||||
{
|
||||
INT32 locvar1 = var1;
|
||||
fixed_t speed;
|
||||
mobjtype_t type;
|
||||
INT32 i = 0;
|
||||
mobj_t *spawn;
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
if (LUA_CallAction("A_ParticleSpawn", actor))
|
||||
return;
|
||||
#endif
|
||||
if (!actor->spawnpoint)
|
||||
{
|
||||
P_RemoveMobj(actor);
|
||||
if (!actor->health)
|
||||
return;
|
||||
|
||||
if ((actor->lastlook) && (actor->cvmem))
|
||||
{
|
||||
for (i = 0; i < actor->lastlook; i++)
|
||||
{
|
||||
spawn = P_SpawnMobj(actor->x + FixedMul(actor->friction, FINECOSINE(actor->angle>>ANGLETOFINESHIFT)),
|
||||
actor->y + FixedMul(actor->friction, FINESINE(actor->angle>>ANGLETOFINESHIFT)),
|
||||
actor->z,
|
||||
(mobjtype_t)actor->cvmem);
|
||||
P_SetScale(spawn, actor->scale);
|
||||
spawn->momz = actor->movefactor;
|
||||
spawn->destscale = spawn->scale/100;
|
||||
spawn->scalespeed = spawn->scale/actor->health;
|
||||
spawn->tics = (tic_t)actor->health;
|
||||
spawn->flags2 |= (actor->flags2 & MF2_OBJECTFLIP);
|
||||
spawn->angle += P_RandomKey(36)*ANG10; // irrelevant for default objects but might make sense for some custom ones
|
||||
if (spawn->frame & FF_ANIMATE)
|
||||
spawn->frame += P_RandomKey(spawn->state->var1);
|
||||
|
||||
actor->angle += actor->movedir;
|
||||
}
|
||||
actor->angle += (angle_t)actor->movecount;
|
||||
}
|
||||
|
||||
if (locvar1)
|
||||
type = (mobjtype_t)locvar1;
|
||||
else
|
||||
type = MT_PARTICLE;
|
||||
|
||||
speed = FixedMul((actor->spawnpoint->angle >> 12)<<FRACBITS, actor->scale);
|
||||
|
||||
spawn = P_SpawnMobj(actor->x, actor->y, actor->z, type);
|
||||
P_SetScale(spawn, actor->scale);
|
||||
spawn->momz = speed;
|
||||
spawn->destscale = FixedDiv(spawn->scale<<FRACBITS, 100<<FRACBITS);
|
||||
spawn->scalespeed = FixedDiv(((actor->spawnpoint->angle >> 8) & 63) << FRACBITS, 100<<FRACBITS);
|
||||
actor->tics = actor->spawnpoint->extrainfo + 1;
|
||||
}
|
||||
|
||||
// Function: A_BunnyHop
|
||||
|
|
79
src/p_mobj.c
79
src/p_mobj.c
|
@ -9303,6 +9303,85 @@ ML_NOCLIMB : Direction not controllable
|
|||
}
|
||||
break;
|
||||
}
|
||||
case MT_PARTICLEGEN:
|
||||
{
|
||||
fixed_t radius, speed, bottomheight, topheight;
|
||||
INT32 type, numdivisions, time, anglespeed;
|
||||
angle_t angledivision;
|
||||
size_t line;
|
||||
const size_t mthingi = (size_t)(mthing - mapthings);
|
||||
|
||||
for (line = 0; line < numlines; line++)
|
||||
{
|
||||
if (lines[line].special == 15 && lines[line].tag == mthing->angle)
|
||||
break;
|
||||
}
|
||||
|
||||
if (line == numlines)
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, "Particle generator (mapthing #%s) needs tagged to a #15 parameter line (trying to find tag %d).\n", sizeu1(mthingi), mthing->angle);
|
||||
return;
|
||||
}
|
||||
|
||||
if (sides[lines[line].sidenum[0]].toptexture)
|
||||
type = sides[lines[line].sidenum[0]].toptexture; // Set as object type in p_setup.c...
|
||||
else
|
||||
type = (INT32)MT_PARTICLE;
|
||||
|
||||
speed = abs(sides[lines[line].sidenum[0]].textureoffset);
|
||||
bottomheight = lines[line].frontsector->floorheight;
|
||||
topheight = lines[line].frontsector->ceilingheight - mobjinfo[(mobjtype_t)type].height;
|
||||
|
||||
numdivisions = (mthing->options >> ZSHIFT);
|
||||
|
||||
if (numdivisions)
|
||||
{
|
||||
radius = R_PointToDist2(lines[line].v1->x, lines[line].v1->y, lines[line].v2->x, lines[line].v2->y);
|
||||
anglespeed = (sides[lines[line].sidenum[0]].rowoffset >> FRACBITS) % 360;
|
||||
angledivision = 360/numdivisions;
|
||||
}
|
||||
else
|
||||
{
|
||||
numdivisions = 1; // Simple trick to make A_ParticleSpawn simpler.
|
||||
radius = 0;
|
||||
anglespeed = 0;
|
||||
angledivision = 0;
|
||||
}
|
||||
|
||||
if ((speed) && (topheight > bottomheight))
|
||||
time = (INT32)(FixedDiv((topheight - bottomheight), speed) >> FRACBITS);
|
||||
else
|
||||
time = 1; // There's no reasonable way to set it, so just show the object for one tic and move on.
|
||||
|
||||
if (mthing->options & MTF_OBJECTFLIP)
|
||||
{
|
||||
mobj->z = topheight;
|
||||
speed *= -1;
|
||||
}
|
||||
else
|
||||
mobj->z = bottomheight;
|
||||
|
||||
CONS_Debug(DBG_GAMELOGIC, "Particle Generator (mapthing #%s):\n"
|
||||
"Radius is %d\n"
|
||||
"Speed is %d\n"
|
||||
"Anglespeed is %d\n"
|
||||
"Numdivisions is %d\n"
|
||||
"Angledivision is %d\n"
|
||||
"Time is %d\n"
|
||||
"Type is %d\n",
|
||||
sizeu1(mthingi), radius, speed, anglespeed, numdivisions, angledivision, time, type);
|
||||
|
||||
mobj->angle = 0;
|
||||
mobj->movefactor = speed;
|
||||
mobj->lastlook = numdivisions;
|
||||
mobj->movedir = angledivision*ANG1;
|
||||
mobj->movecount = anglespeed*ANG1;
|
||||
mobj->health = time;
|
||||
mobj->friction = radius;
|
||||
mobj->cvmem = type;
|
||||
|
||||
break;
|
||||
}
|
||||
case MT_ROCKSPAWNER:
|
||||
mobj->threshold = mthing->angle;
|
||||
mobj->movecount = mthing->extrainfo;
|
||||
|
|
|
@ -1479,6 +1479,7 @@ static void P_LoadSideDefs2(lumpnum_t lumpnum)
|
|||
}
|
||||
|
||||
case 14: // Bustable block parameters
|
||||
case 15: // Fan particle spawner parameters
|
||||
case 425: // Calls P_SetMobjState on calling mobj
|
||||
case 434: // Custom Power
|
||||
case 442: // Calls P_SetMobjState on mobjs of a given type in the tagged sectors
|
||||
|
|
Loading…
Reference in a new issue