From 8667aeb620ccf16cc4a1ed5dba6e5f480f4da6d2 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sat, 18 Dec 2021 21:23:41 -0500 Subject: [PATCH] Add footstep particles --- src/k_kart.c | 20 ++---- src/k_kart.h | 2 +- src/k_terrain.c | 164 ++++++++++++++++++++++++++++++++++++++++++++-- src/k_terrain.h | 16 +++++ src/lua_baselib.c | 3 +- src/p_user.c | 2 +- 6 files changed, 181 insertions(+), 26 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index c0f5909ec..fefc5387b 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -4346,7 +4346,7 @@ void K_SpawnSparkleTrail(mobj_t *mo) sparkle->color = mo->color; } -void K_SpawnWipeoutTrail(mobj_t *mo, boolean offroad) +void K_SpawnWipeoutTrail(mobj_t *mo) { mobj_t *dust; angle_t aoff; @@ -4373,13 +4373,6 @@ void K_SpawnWipeoutTrail(mobj_t *mo, boolean offroad) dust->destscale = mo->scale; P_SetScale(dust, mo->scale); K_FlipFromObject(dust, mo); - - if (offroad) // offroad effect - { - dust->momx = mo->momx/2; - dust->momy = mo->momy/2; - dust->momz = mo->momz/2; - } } void K_SpawnDraftDust(mobj_t *mo) @@ -6698,16 +6691,11 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) ghost->renderflags |= RF_DONTDRAW; } + // Could probably be moved somewhere else. + K_HandleFootstepParticles(player->mo); + if (P_IsObjectOnGround(player->mo)) { - // Offroad dust - if (player->boostpower < FRACUNIT) - { - K_SpawnWipeoutTrail(player->mo, true); - if (leveltime % 6 == 0) - S_StartSound(player->mo, sfx_cdfm70); - } - // Draft dust if (player->draftpower >= FRACUNIT) { diff --git a/src/k_kart.h b/src/k_kart.h index dffc1cedf..04d80fd05 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -76,7 +76,7 @@ void K_RunFinishLineBeam(void); UINT16 K_DriftSparkColor(player_t *player, INT32 charge); void K_SpawnBoostTrail(player_t *player); void K_SpawnSparkleTrail(mobj_t *mo); -void K_SpawnWipeoutTrail(mobj_t *mo, boolean offroad); +void K_SpawnWipeoutTrail(mobj_t *mo); void K_SpawnDraftDust(mobj_t *mo); void K_DriftDustHandling(mobj_t *spawner); void K_Squish(mobj_t *mo); diff --git a/src/k_terrain.c b/src/k_terrain.c index c2022d1b9..4f9f63cbf 100644 --- a/src/k_terrain.c +++ b/src/k_terrain.c @@ -20,6 +20,7 @@ #include "doomtype.h" #include "fastcmp.h" #include "m_fixed.h" +#include "m_random.h" #include "p_local.h" #include "p_mobj.h" #include "r_textures.h" @@ -41,6 +42,7 @@ static t_floor_t *terrainFloorDefs = NULL; static size_t numTerrainFloorDefs = 0; static size_t defaultTerrain = SIZE_MAX; +static size_t defaultOffroadFootstep = SIZE_MAX; /*-------------------------------------------------- size_t K_GetSplashHeapIndex(t_splash_t *splash) @@ -509,6 +511,114 @@ void K_SetDefaultFriction(mobj_t *mo) } } +/*-------------------------------------------------- + static void K_SpawnFootstepParticle(mobj_t *mo, t_footstep_t *fs) + + See header file for description. +--------------------------------------------------*/ +static void K_SpawnFootstepParticle(mobj_t *mo, t_footstep_t *fs) +{ + mobj_t *dust = NULL; + angle_t pushAngle = ANGLE_MAX; + angle_t tireAngle = ANGLE_MAX; + fixed_t momentum = INT32_MAX; + + if (mo->player != NULL) + { + tireAngle = (mo->player->drawangle + ANGLE_180); + } + else + { + tireAngle = (mo->angle + ANGLE_180); + } + + if ((leveltime / 2) & 1) + { + tireAngle -= ANGLE_45; + tireAngle -= P_RandomRange(0, ANGLE_11hh); + } + else + { + tireAngle += ANGLE_45; + tireAngle += P_RandomRange(0, ANGLE_11hh); + } + + pushAngle = K_MomentumAngle(mo) + ANGLE_180; + + dust = P_SpawnMobjFromMobj( + mo, + (P_RandomRange(-2, 2) * FRACUNIT) + (24 * FINECOSINE(tireAngle >> ANGLETOFINESHIFT)), + (P_RandomRange(-2, 2) * FRACUNIT) + (24 * FINESINE(tireAngle >> ANGLETOFINESHIFT)), + 0, fs->mobjType + ); + + P_SetTarget(&dust->target, mo); + dust->angle = K_MomentumAngle(mo); + + dust->destscale = FixedMul(mo->scale, fs->scale); + P_SetScale(dust, dust->destscale); + + dust->momx = mo->momx; + dust->momy = mo->momy; + dust->momz = mo->momz; + + momentum = P_AproxDistance(mo->momx, mo->momy) / 2; + dust->momx += FixedMul(momentum, FINECOSINE(pushAngle >> ANGLETOFINESHIFT)); + dust->momy += FixedMul(momentum, FINESINE(pushAngle >> ANGLETOFINESHIFT)); + dust->momz += (momentum / 16) * P_MobjFlip(mo); + + if (fs->color != SKINCOLOR_NONE) + { + dust->color = fs->color; + } + + if (fs->sfx != sfx_None && (leveltime % 6 == 0)) + { + S_StartSound(mo, fs->sfx); + } +} + +/*-------------------------------------------------- + void K_HandleFootstepParticles(mobj_t *mo) + + See header file for description. +--------------------------------------------------*/ +void K_HandleFootstepParticles(mobj_t *mo) +{ + t_footstep_t *fs = NULL; + + if (mo == NULL || P_MobjWasRemoved(mo) == true) + { + // Invalid object. + return; + } + + if (mo->terrain == NULL || mo->terrain->footstepID == SIZE_MAX) + { + // If no terrain, check for offroad. + // If we're in offroad, use the default particle. + + if (mo->player != NULL && mo->player->boostpower < FRACUNIT) + { + fs = K_GetFootstepByIndex(defaultOffroadFootstep); + } + } + else + { + fs = K_GetFootstepByIndex(mo->terrain->footstepID); + } + + if (fs == NULL || fs->mobjType == MT_NULL) + { + // No particles to spawn. + return; + } + + // Idea for later: if different spawning styles are desired, + // we can put a switch case here! + K_SpawnFootstepParticle(mo, fs); +} + /*-------------------------------------------------- static void K_FlagBoolean(UINT32 *inputFlags, UINT32 newFlag, char *val) @@ -550,6 +660,8 @@ static void K_SplashDefaults(t_splash_t *splash) { splash->mobjType = MT_NULL; splash->sfx = sfx_None; + splash->scale = FRACUNIT; + splash->color = SKINCOLOR_NONE; } /*-------------------------------------------------- @@ -590,11 +702,11 @@ static void K_ParseSplashParameter(size_t i, char *param, char *val) if (stricmp(param, "mobjType") == 0) { - splash->mobjType = get_mobjtype(val); + splash->mobjType = get_number(val) + 1; } else if (stricmp(param, "sfx") == 0) { - splash->sfx = get_sfx(val); + splash->sfx = get_number(val); } else if (stricmp(param, "scale") == 0) { @@ -602,7 +714,7 @@ static void K_ParseSplashParameter(size_t i, char *param, char *val) } else if (stricmp(param, "color") == 0) { - splash->color = get_skincolor(val); + splash->color = get_number(val); } } @@ -621,6 +733,8 @@ static void K_FootstepDefaults(t_footstep_t *footstep) { footstep->mobjType = MT_NULL; footstep->sfx = sfx_None; + footstep->scale = FRACUNIT; + footstep->color = SKINCOLOR_NONE; } /*-------------------------------------------------- @@ -661,11 +775,11 @@ static void K_ParseFootstepParameter(size_t i, char *param, char *val) if (stricmp(param, "mobjType") == 0) { - footstep->mobjType = get_mobjtype(val); + footstep->mobjType = get_number(val) + 1; } else if (stricmp(param, "sfx") == 0) { - footstep->sfx = get_sfx(val); + footstep->sfx = get_number(val); } else if (stricmp(param, "scale") == 0) { @@ -673,7 +787,7 @@ static void K_ParseFootstepParameter(size_t i, char *param, char *val) } else if (stricmp(param, "color") == 0) { - footstep->color = get_skincolor(val); + footstep->color = get_number(val); } } @@ -1090,6 +1204,7 @@ static boolean K_TERRAINLumpParser(UINT8 *data, size_t size) else { defaultTerrain = i; + CONS_Printf("DefaultTerrain set to '%s'\n", tkn); } } else @@ -1098,6 +1213,43 @@ static boolean K_TERRAINLumpParser(UINT8 *data, size_t size) valid = false; } } + else if (stricmp(tkn, "defaultOffroadFootstep") == 0) + { + Z_Free(tkn); + tkn = M_GetToken(NULL); + pos = M_GetTokenPos(); + + if (tkn && pos < size) + { + t_footstep_t *fs = NULL; + + for (i = 0; i < numFootstepDefs; i++) + { + fs = &footstepDefs[i]; + + if (stricmp(tkn, fs->name) == 0) + { + break; + } + } + + if (i == numFootstepDefs) + { + CONS_Alert(CONS_ERROR, "Invalid DefaultOffroadFootstep type.\n"); + valid = false; + } + else + { + defaultOffroadFootstep = i; + CONS_Printf("DefaultOffroadFootstep set to '%s'\n", tkn); + } + } + else + { + CONS_Alert(CONS_ERROR, "No DefaultOffroadFootstep type.\n"); + valid = false; + } + } else { CONS_Alert(CONS_ERROR, "Unknown field '%s' found in TERRAIN lump.\n", tkn); diff --git a/src/k_terrain.h b/src/k_terrain.h index d494f5edf..32921d393 100644 --- a/src/k_terrain.h +++ b/src/k_terrain.h @@ -394,6 +394,22 @@ void K_ProcessTerrainEffect(mobj_t *mo); void K_SetDefaultFriction(mobj_t *mo); +/*-------------------------------------------------- + void K_HandleFootstepParticles(mobj_t *mo); + + Spawns the footstep particles for an object's + terrain type. Intended to be called every tic. + + Input Arguments:- + mo - The object to spawn footsteps for. + + Return:- + None +--------------------------------------------------*/ + +void K_HandleFootstepParticles(mobj_t *mo); + + /*-------------------------------------------------- void K_InitTerrain(UINT16 wadNum); diff --git a/src/lua_baselib.c b/src/lua_baselib.c index e07c41bd4..7f410310c 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -3588,11 +3588,10 @@ static int lib_kSpawnSparkleTrail(lua_State *L) static int lib_kSpawnWipeoutTrail(lua_State *L) { mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); - boolean offroad = lua_optboolean(L, 2); NOHUD if (!mo) return LUA_ErrInvalid(L, "mobj_t"); - K_SpawnWipeoutTrail(mo, offroad); + K_SpawnWipeoutTrail(mo); return 0; } diff --git a/src/p_user.c b/src/p_user.c index 0cd83dfc7..5a065e8d5 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2265,7 +2265,7 @@ void P_MovePlayer(player_t *player) K_SpawnSparkleTrail(player->mo); if (player->wipeoutslow > 1 && (leveltime & 1)) - K_SpawnWipeoutTrail(player->mo, false); + K_SpawnWipeoutTrail(player->mo); K_DriftDustHandling(player->mo);