diff --git a/src/k_kart.c b/src/k_kart.c index 6e0974105..1a6ba0d06 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -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); } } diff --git a/src/k_objects.h b/src/k_objects.h index 3ea63b8ce..a20798dac 100644 --- a/src/k_objects.h +++ b/src/k_objects.h @@ -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); diff --git a/src/objects/instawhip.c b/src/objects/instawhip.c index d2b38044f..64ddd8ae5 100644 --- a/src/objects/instawhip.c +++ b/src/objects/instawhip.c @@ -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; +} diff --git a/src/p_mobj.c b/src/p_mobj.c index f28575cf7..a4aa1d128 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -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: { diff --git a/src/r_spritefx.cpp b/src/r_spritefx.cpp index 098cc14e8..4db957880 100644 --- a/src/r_spritefx.cpp +++ b/src/r_spritefx.cpp @@ -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; }