Instawhip Recharge VFX

- 3 splats spawn before the instawhip cooldown runs out
- Splats angle steeply outward in a triangle formation
- VFX is animated, animation runs out right when instawhip
  cooldown completely runs out
This commit is contained in:
James R 2023-06-18 00:32:33 -07:00
parent 96a3221dd3
commit aa82d8da77
5 changed files with 63 additions and 0 deletions

View file

@ -10780,6 +10780,11 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
whip->fuse = 12; // Changing instawhip animation duration? Look here
player->flashing = max(player->flashing, 12);
player->mo->momz += 4*mapobjectscale;
// Spawn in triangle formation
Obj_SpawnInstaWhipRecharge(player, 0);
Obj_SpawnInstaWhipRecharge(player, ANGLE_120);
Obj_SpawnInstaWhipRecharge(player, ANGLE_240);
}
}

View file

@ -2,6 +2,7 @@
#ifndef k_objects_H
#define k_objects_H
#include "tables.h" // angle_t
#include "taglist.h"
#ifdef __cplusplus
@ -109,6 +110,8 @@ boolean Obj_DropTargetMorphThink(mobj_t *morph);
/* Instawhip */
void Obj_InstaWhipThink(mobj_t *whip);
void Obj_SpawnInstaWhipRecharge(player_t *player, angle_t angleOffset);
void Obj_InstaWhipRechargeThink(mobj_t *mobj);
/* Block VFX */
void Obj_BlockRingThink(mobj_t *ring);

View file

@ -3,6 +3,9 @@
#include "../k_objects.h"
#include "../p_local.h"
#define recharge_target(o) ((o)->target)
#define recharge_offset(o) ((o)->movedir)
void Obj_InstaWhipThink (mobj_t *whip)
{
if (P_MobjWasRemoved(whip->target))
@ -40,3 +43,32 @@ void Obj_InstaWhipThink (mobj_t *whip)
whip->renderflags |= RF_DONTDRAW;
}
}
void Obj_SpawnInstaWhipRecharge(player_t *player, angle_t angleOffset)
{
mobj_t *x = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, MT_INSTAWHIP_RECHARGE);
x->tics = max(player->instaShieldCooldown - states[x->info->raisestate].tics, 0);
x->renderflags |= RF_SLOPESPLAT | RF_NOSPLATBILLBOARD;
P_SetTarget(&recharge_target(x), player->mo);
recharge_offset(x) = angleOffset;
}
void Obj_InstaWhipRechargeThink(mobj_t *x)
{
mobj_t *target = recharge_target(x);
if (P_MobjWasRemoved(target))
{
P_RemoveMobj(x);
return;
}
P_MoveOrigin(x, target->x, target->y, target->z + (target->height / 2));
P_InstaScale(x, 2 * target->scale);
x->angle = target->angle + recharge_offset(x);
// Flickers every other frame
x->renderflags ^= RF_DONTDRAW;
}

View file

@ -6681,6 +6681,14 @@ static void P_MobjSceneryThink(mobj_t *mobj)
return;
}
break;
case MT_INSTAWHIP_RECHARGE:
Obj_InstaWhipRechargeThink(mobj);
if (P_MobjWasRemoved(mobj))
{
return;
}
break;
case MT_VWREF:
case MT_VWREB:
{

View file

@ -9,6 +9,7 @@
/// \brief Special effects for sprite rendering
#include "d_player.h"
#include "info.h"
#include "p_tick.h"
#include "r_splats.h"
#include "r_things.h"
@ -42,5 +43,19 @@ INT32 R_ThingLightLevel(mobj_t* thing)
// mobj_t.standingslope must also be NULL.)
boolean R_SplatSlope(mobj_t* mobj, vector3_t position, pslope_t* slope)
{
switch (mobj->type)
{
case MT_INSTAWHIP_RECHARGE: {
// Create an acute angle
slope->o = position;
FV2_Load(&slope->d, FCOS(mobj->angle) / 2, FSIN(mobj->angle) / 2);
slope->zdelta = FRACUNIT;
return true;
}
default:
break;
}
return false;
}