From f20a7e4db2d6287815bda99d6cb91f233d329292 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 18 Jun 2023 00:46:32 -0700 Subject: [PATCH 1/5] A_PlaySound: var2 lower 16 bits == 2, play from actor target --- src/p_enemy.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index 17aa6ea71..c21afb34d 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -7221,13 +7221,14 @@ void A_ChangeRollAngleAbsolute(mobj_t *actor) // // var1 = sound # to play // var2: -// lower 16 bits = If 1, play sound using calling object as origin. If 0, play sound without an origin +// lower 16 bits = If 1, play sound using calling object as origin. If 2, use target. If 0, play sound without an origin // upper 16 bits = If 1, do not play sound during preticker. // void A_PlaySound(mobj_t *actor) { INT32 locvar1 = var1; INT32 locvar2 = var2; + mobj_t *origin = NULL; if (LUA_CallAction(A_PLAYSOUND, actor)) return; @@ -7235,7 +7236,18 @@ void A_PlaySound(mobj_t *actor) if (leveltime < 2 && (locvar2 >> 16)) return; - S_StartSound((locvar2 & 65535) ? actor : NULL, locvar1); + switch (locvar2 & 65535) + { + case 1: + origin = actor; + break; + + case 2: + origin = actor->target; + break; + } + + S_StartSound(origin, locvar1); } // Function: A_FindTarget From f98319a98cc6812bb14cca6ca40d4df09f715cf8 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 18 Jun 2023 00:11:01 -0700 Subject: [PATCH 2/5] Add R_SplatSlope, function to set slope of splat during rendering Slope set by R_SplatSlope is only effective if floorspriteslope or standingslope is not already being used. --- src/r_splats.c | 4 ++++ src/r_spritefx.cpp | 15 +++++++++++++++ src/r_things.h | 1 + 3 files changed, 20 insertions(+) diff --git a/src/r_splats.c b/src/r_splats.c index bfd0197ca..c2aae1a93 100644 --- a/src/r_splats.c +++ b/src/r_splats.c @@ -141,6 +141,7 @@ static void rasterize_segment_tex(INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT32 void R_DrawFloorSplat(vissprite_t *spr) { floorsplat_t splat; + pslope_t localslope; mobj_t *mobj = spr->mobj; fixed_t tr_x, tr_y, rot_x, rot_y, rot_z; @@ -258,6 +259,9 @@ void R_DrawFloorSplat(vissprite_t *spr) if (standingslope && (renderflags & RF_OBJECTSLOPESPLAT)) splat.slope = standingslope; + + if (!splat.slope && R_SplatSlope(mobj, (vector3_t){splat.x, splat.y, splat.z}, &localslope)) + splat.slope = &localslope; } // Translate diff --git a/src/r_spritefx.cpp b/src/r_spritefx.cpp index 448c65974..098cc14e8 100644 --- a/src/r_spritefx.cpp +++ b/src/r_spritefx.cpp @@ -10,6 +10,7 @@ #include "d_player.h" #include "p_tick.h" +#include "r_splats.h" #include "r_things.h" INT32 R_ThingLightLevel(mobj_t* thing) @@ -29,3 +30,17 @@ INT32 R_ThingLightLevel(mobj_t* thing) return lightlevel; } + +// Use this function to set the slope of a splat sprite. +// +// slope->o, slope->d and slope->zdelta must be set, none of +// the other fields on pslope_t are used. +// +// Return true if you want the slope to be used. The object +// must have RF_SLOPESPLAT and mobj_t.floorspriteslope must be +// NULL. (If RF_OBJECTSLOPESPLAT is set, then +// mobj_t.standingslope must also be NULL.) +boolean R_SplatSlope(mobj_t* mobj, vector3_t position, pslope_t* slope) +{ + return false; +} diff --git a/src/r_things.h b/src/r_things.h index 78b6c013e..2737ded62 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -94,6 +94,7 @@ boolean R_ThingIsFullDark (mobj_t *thing); boolean R_ThingIsFlashing(mobj_t *thing); INT32 R_ThingLightLevel(mobj_t *thing); +boolean R_SplatSlope(mobj_t *thing, vector3_t position, pslope_t *slope); // -------------- // MASKED DRAWING From 96a3221dd3d9a127aeb7dfc6764dcdfde7f2bd73 Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 17 Jun 2023 23:41:00 -0700 Subject: [PATCH 3/5] Add Instawhip Recharge states --- src/deh_tables.c | 5 +++++ src/info.c | 32 ++++++++++++++++++++++++++++++++ src/info.h | 6 ++++++ 3 files changed, 43 insertions(+) diff --git a/src/deh_tables.c b/src/deh_tables.c index e44c6cb52..ddbae5cbf 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -3288,6 +3288,10 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi "S_SLIPTIDEZIP", "S_INSTAWHIP", + "S_INSTAWHIP_RECHARGE1", + "S_INSTAWHIP_RECHARGE2", + "S_INSTAWHIP_RECHARGE3", + "S_INSTAWHIP_RECHARGE4", "S_BLOCKRING", "S_BLOCKBODY", @@ -5336,6 +5340,7 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t "MT_SLIPTIDEZIP", "MT_INSTAWHIP", + "MT_INSTAWHIP_RECHARGE", "MT_BLOCKRING", "MT_BLOCKBODY", diff --git a/src/info.c b/src/info.c index cbe5556a3..7d1c0023c 100644 --- a/src/info.c +++ b/src/info.c @@ -556,6 +556,7 @@ char sprnames[NUMSPRITES + 1][5] = "SLPT", // Sliptide zip indicator "IWHP", // Instawhip + "WPRE", // Instawhip Recharge "GRNG", // Guard ring "GBDY", // Guard body @@ -3955,6 +3956,10 @@ state_t states[NUMSTATES] = {SPR_SLPT, FF_PAPERSPRITE|0, -1, {NULL}, 0, 0, S_NULL}, // S_SLIPTIDEZIP {SPR_IWHP, FF_FLOORSPRITE|FF_ANIMATE|0, -1, {NULL}, 6, 2, S_NULL}, // S_INSTAWHIP + {SPR_NULL, 0, 1, {NULL}, 0, 0, S_INSTAWHIP_RECHARGE2}, // S_INSTAWHIP_RECHARGE1 + {SPR_NULL, 0, 0, {A_PlaySound}, sfx_s3ka0, 2, S_INSTAWHIP_RECHARGE3}, // S_INSTAWHIP_RECHARGE2 + {SPR_WPRE, FF_FULLBRIGHT|FF_FLOORSPRITE|FF_ANIMATE|0, 36, {NULL}, 17, 2, S_INSTAWHIP_RECHARGE4}, // S_INSTAWHIP_RECHARGE3 + {SPR_NULL, 0, 0, {A_PlaySound}, sfx_s3k7c, 2, S_NULL}, // S_INSTAWHIP_RECHARGE4 {SPR_GRNG, FF_FULLBRIGHT|FF_PAPERSPRITE|0, -1, {NULL}, 0, 0, S_NULL}, // S_BLOCKRING {SPR_GBDY, FF_FULLBRIGHT|FF_ANIMATE|0, -1, {NULL}, 4, 2, S_NULL}, // S_BLOCKBODY @@ -22711,6 +22716,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_INSTAWHIP_RECHARGE + -1, // doomednum + S_INSTAWHIP_RECHARGE1, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 90*FRACUNIT, // radius + 90*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_SCENERY|MF_NOCLIPTHING|MF_DONTENCOREMAP|MF_NOSQUISH, // flags + S_INSTAWHIP_RECHARGE3 // raisestate + }, + { // MT_BLOCKRING -1, // doomednum S_BLOCKRING, // spawnstate diff --git a/src/info.h b/src/info.h index 566e23eab..a203dbc3d 100644 --- a/src/info.h +++ b/src/info.h @@ -1109,6 +1109,7 @@ typedef enum sprite SPR_SLPT, // Sliptide zip indicator SPR_IWHP, // Instawhip + SPR_WPRE, // Instawhip Recharge SPR_GRNG, // Guard ring SPR_GBDY, // Guard body @@ -4366,6 +4367,10 @@ typedef enum state S_SLIPTIDEZIP, S_INSTAWHIP, + S_INSTAWHIP_RECHARGE1, + S_INSTAWHIP_RECHARGE2, + S_INSTAWHIP_RECHARGE3, + S_INSTAWHIP_RECHARGE4, S_BLOCKRING, S_BLOCKBODY, @@ -6449,6 +6454,7 @@ typedef enum mobj_type MT_SLIPTIDEZIP, MT_INSTAWHIP, + MT_INSTAWHIP_RECHARGE, MT_BLOCKRING, MT_BLOCKBODY, From aa82d8da77d39ce6a912d9c108fbce9ef9967062 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 18 Jun 2023 00:32:33 -0700 Subject: [PATCH 4/5] 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 --- src/k_kart.c | 5 +++++ src/k_objects.h | 3 +++ src/objects/instawhip.c | 32 ++++++++++++++++++++++++++++++++ src/p_mobj.c | 8 ++++++++ src/r_spritefx.cpp | 15 +++++++++++++++ 5 files changed, 63 insertions(+) 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; } From bebf9ebed7d61628c88eb77772b8d3f5965941fa Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 18 Jun 2023 01:34:30 -0700 Subject: [PATCH 5/5] A_PlaySound: var2 lower 16 bits == 2, play from actor if actor target is NULL --- src/p_enemy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index c21afb34d..9f6f5c490 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -7243,7 +7243,7 @@ void A_PlaySound(mobj_t *actor) break; case 2: - origin = actor->target; + origin = actor->target ? actor->target : actor; break; }