Refactor item debris cloud

- The "cloud" is stationary and spawned on the item box
instead of the player. Still scales up with speed.
- Single particles are spawned behind the player. No
longer scales. Lasts longer but can end early if the
player slows down.
This commit is contained in:
James R 2022-09-20 05:24:48 -07:00
parent c2b2cd9a43
commit f6ef29cf03
6 changed files with 101 additions and 73 deletions

View file

@ -3279,10 +3279,8 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi
//}
"S_ITEM_DEBRIS",
"S_ITEM_DEBRIS_CLOUD_SPAWNER_INIT",
"S_ITEM_DEBRIS_CLOUD_SPAWNER1",
"S_ITEM_DEBRIS_CLOUD_SPAWNER2",
"S_ITEM_DEBRIS_CLOUD_SPAWNER3",
"S_ITEMICON",

View file

@ -3871,10 +3871,8 @@ state_t states[NUMSTATES] =
{SPR_RPOP, FF_FULLBRIGHT|3, 5, {NULL}, 0, 0, S_NULL}, // S_RANDOMITEMPOP4
{SPR_ITRI, FF_FULLBRIGHT, -1, {NULL}, 19, 1, S_NULL}, // S_ITEM_DEBRIS
{SPR_NULL, 0, 1, {NULL}, 0, 0, S_ITEM_DEBRIS_CLOUD_SPAWNER1}, // S_ITEM_DEBRIS_CLOUD_SPAWNER_INIT
{SPR_NULL, 0, 1, {A_Repeat}, 4, S_ITEM_DEBRIS_CLOUD_SPAWNER2, S_NULL}, // S_ITEM_DEBRIS_CLOUD_SPAWNER1
{SPR_NULL, 4, 2, {A_SpawnItemDebrisCloud}, 1, 10, S_ITEM_DEBRIS_CLOUD_SPAWNER3}, // S_ITEM_DEBRIS_CLOUD_SPAWNER2
{SPR_NULL, 4, 5, {A_SpawnItemDebrisCloud}, 0, 2, S_ITEM_DEBRIS_CLOUD_SPAWNER1}, // S_ITEM_DEBRIS_CLOUD_SPAWNER3
{SPR_NULL, 0, 0, {A_Repeat}, 16, S_ITEM_DEBRIS_CLOUD_SPAWNER2, S_NULL}, // S_ITEM_DEBRIS_CLOUD_SPAWNER1
{SPR_NULL, 0, 7, {A_SpawnItemDebrisCloud}, 20, 0, S_ITEM_DEBRIS_CLOUD_SPAWNER1}, // S_ITEM_DEBRIS_CLOUD_SPAWNER2
{SPR_NULL, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_ITEMICON
@ -23178,7 +23176,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
{ // MT_ITEM_DEBRIS_CLOUD_SPAWNER
-1, // doomednum
S_ITEM_DEBRIS_CLOUD_SPAWNER_INIT, // spawnstate
S_ITEM_DEBRIS_CLOUD_SPAWNER1, // spawnstate
1, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
@ -23199,7 +23197,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
0, // mass
0, // damage
sfx_None, // activesound
MF_NOSECTOR|MF_NOBLOCKMAP, // flags
MF_NOSECTOR|MF_NOBLOCKMAP|MF_RUNSPAWNFUNC, // flags
S_NULL // raisestate
},

View file

@ -4276,10 +4276,8 @@ typedef enum state
//}
S_ITEM_DEBRIS,
S_ITEM_DEBRIS_CLOUD_SPAWNER_INIT,
S_ITEM_DEBRIS_CLOUD_SPAWNER1,
S_ITEM_DEBRIS_CLOUD_SPAWNER2,
S_ITEM_DEBRIS_CLOUD_SPAWNER3,
S_ITEMICON,

View file

@ -16,7 +16,6 @@ boolean Obj_ShrinkLaserCollide(mobj_t *gun, mobj_t *victim);
void Obj_CreateShrinkPohbees(player_t *owner);
/* Item Debris */
fixed_t Obj_GetItemDebrisSpeed(mobj_t *collector, fixed_t min_speed);
void Obj_SpawnItemDebrisEffects(mobj_t *collectible, mobj_t *collector);
void Obj_ItemDebrisThink(mobj_t *debris);
fixed_t Obj_ItemDebrisBounce(mobj_t *debris, fixed_t momz);

View file

@ -4,6 +4,7 @@
#include "../k_kart.h"
#include "../k_objects.h"
#include "../p_local.h"
#include "../r_main.h"
#include "../s_sound.h"
// TODO: general function
@ -80,15 +81,52 @@ spawn_debris
static void
spawn_cloud
( mobj_t * collectible,
mobj_t * collector)
mobj_t * collector,
fixed_t base_speed)
{
mobj_t *spawner = P_SpawnMobjFromMobj(collectible,
0, 0, 0, MT_ITEM_DEBRIS_CLOUD_SPAWNER);
const fixed_t min_speed = 90 * collectible->scale;
P_SetTarget(&spawner->target, collector);
const fixed_t scale = FixedDiv(
max(base_speed, min_speed), min_speed);
S_StartSound(spawner, sfx_kc2e);
S_StartSound(spawner, sfx_s1c9);
const INT16 spacing =
(collectible->radius / 2) / collectible->scale;
INT32 i;
// Most of this code is from p_inter.c, MT_ITEMCAPSULE
// dust effects
for (i = 0; i < 10; i++)
{
mobj_t *puff = P_SpawnMobjFromMobj(
collectible,
P_RandomRange(-spacing, spacing) * FRACUNIT,
P_RandomRange(-spacing, spacing) * FRACUNIT,
P_RandomRange(0, 4 * spacing) * FRACUNIT,
MT_SPINDASHDUST
);
puff->color = collector->color;
puff->colorized = true;
puff->destscale = FixedMul(puff->destscale, scale);
P_SetScale(puff, puff->destscale);
puff->momz = puff->scale * P_MobjFlip(puff);
P_InitAngle(puff, R_PointToAngle2(
collectible->x,
collectible->y,
puff->x,
puff->y));
P_Thrust(puff, puff->angle, 3 * puff->scale);
puff->momx += collector->momx;
puff->momy += collector->momy;
puff->momz += collector->momz;
}
}
static void
@ -100,18 +138,6 @@ rotate3d (mobj_t *debris)
M_RandomKey(steps) * (ANGLE_MAX / steps);
}
fixed_t
Obj_GetItemDebrisSpeed
( mobj_t * collector,
fixed_t min_speed)
{
const fixed_t base_speed = FixedMul(
75 * mapobjectscale,
get_speed_ratio(collector));
return max(base_speed, min_speed);
}
void
Obj_SpawnItemDebrisEffects
( mobj_t * collectible,
@ -119,15 +145,22 @@ Obj_SpawnItemDebrisEffects
{
const fixed_t min_speed = 80 * collectible->scale;
const fixed_t speed =
Obj_GetItemDebrisSpeed(collector, min_speed);
fixed_t base_speed = FixedMul(75 * mapobjectscale,
get_speed_ratio(collector));
struct debris_config config = {
.origin = collectible,
.angle = K_MomentumAngle(collector),
.speed = speed,
.scale = FixedDiv(speed, min_speed),
};
struct debris_config config;
// Delayed effect for puffs of smoke that stick to and
// glide off of the player
mobj_t *spawner = P_SpawnMobjFromMobj(collectible,
0, 0, 0, MT_ITEM_DEBRIS_CLOUD_SPAWNER);
P_SetTarget(&spawner->target, collector);
config.origin = collectible;
config.angle = K_MomentumAngle(collector);
config.speed = max(base_speed, min_speed);
config.scale = FixedDiv(config.speed, min_speed);
config.type = DEBRIS_ALPHA;
@ -142,7 +175,10 @@ Obj_SpawnItemDebrisEffects
spawn_debris(&config, -(3*ANGLE_22h/4));
spawn_debris(&config, -(3*ANGLE_22h/2));
spawn_cloud(collectible, collector);
spawn_cloud(collectible, collector, base_speed);
S_StartSound(collectible, sfx_kc2e);
S_StartSound(collectible, sfx_s1c9);
}
void

View file

@ -14486,59 +14486,55 @@ void A_InvincSparkleRotate(mobj_t *actor)
// Function: A_SpawnItemDebrisCloud
//
// Description: Spawns a particle effect relative to the location of the actor
// Description: Spawns the poofs of an exploded item box. Target is a player to spawn the particles around.
//
// var1 = If 1, scale size and momentum by extravalue2 / frame.
// var2 = Number of particles to spawn.
// var1 = Copy extravalue2 / var1 fraction of target's momentum.
// var2 = unused
//
void
A_SpawnItemDebrisCloud (mobj_t *actor)
{
INT32 locvar1 = var1;
INT32 locvar2 = var2;
const fixed_t min_speed = 90 * actor->scale;
const INT16 spacing = (actor->radius / 2) / actor->scale;
fixed_t fade = FRACUNIT;
fixed_t scale_fade = FRACUNIT;
mobj_t *target = actor->target;
player_t *player;
fixed_t speed;
fixed_t scale;
fixed_t kartspeed;
fixed_t fade;
INT32 i;
if (target == NULL)
if (target == NULL || target->player == NULL)
{
return;
}
if (locvar1)
{
const UINT8 frame = (actor->frame & FF_FRAMEMASK);
fixed_t frac;
player = target->player;
kartspeed = K_GetKartSpeed(player, false, false);
if (frame == 0)
// Scale around >50% top speed
fade = FixedMul(locvar1, (FixedDiv(player->speed,
kartspeed) - FRACUNIT/2) * 2);
if (fade < 1)
{
return; // div by zero
fade = 1;
}
if (actor->extravalue2 > fade)
{
actor->extravalue2 = fade;
}
// MT_ITEM_DEBRIS_CLOUD_SPAWNER
// extravalue2 from A_Repeat
frac = fade / frame;
fade = actor->extravalue2 * frac;
scale_fade = fade + frac;
}
speed = Obj_GetItemDebrisSpeed(target, min_speed);
scale = 2 * FixedMul(FixedDiv(speed, min_speed), scale_fade);
fade = actor->extravalue2 * FRACUNIT / locvar1;
// Most of this code is from p_inter.c, MT_ITEMCAPSULE
// dust effects
for (i = 0; i < locvar2; i++)
{
const INT16 spacing =
(target->radius / 2) / target->scale;
mobj_t *puff = P_SpawnMobjFromMobj(
target,
P_RandomRange(-spacing, spacing) * FRACUNIT,
@ -14550,12 +14546,15 @@ A_SpawnItemDebrisCloud (mobj_t *actor)
puff->color = target->color;
puff->colorized = true;
puff->destscale = FixedMul(puff->destscale, scale);
P_SetScale(puff, puff->destscale);
puff->momz = puff->scale * P_MobjFlip(puff);
P_Thrust(puff, R_PointToAngle2(target->x, target->y, puff->x, puff->y), 3 * puff->scale);
P_InitAngle(puff, R_PointToAngle2(
target->x,
target->y,
puff->x,
puff->y));
P_Thrust(puff, puff->angle, 3 * puff->scale);
puff->momx += FixedMul(target->momx, fade);
puff->momy += FixedMul(target->momy, fade);