From 01af5127c827f71a1bfabdab92a35962aa620284 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sun, 4 Sep 2022 14:23:51 -0400 Subject: [PATCH 1/2] Improved pain then hit confirm sound - The pain + hit confirm delay is done for all players, instead of only the damaged player. - The player who got the hit also gets to hear their pain sound at full volume. - Changed the code so that your hit confirm sound effect will no longer be interrupted if the player who got hit left the game. --- src/d_player.h | 4 +- src/k_kart.c | 94 +++++++++++++++++++++++++-------------------- src/k_kart.h | 5 ++- src/lua_baselib.c | 23 +++++++++-- src/lua_playerlib.c | 16 ++++---- src/p_inter.c | 6 +-- src/p_saveg.c | 8 ++-- 7 files changed, 91 insertions(+), 65 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index 85eec2e3e..bf92758f8 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -504,8 +504,8 @@ typedef struct player_s SINT8 lastjawztarget; // (-1 to 15) - Last person you target with jawz, for playing the target switch sfx UINT8 jawztargetdelay; // (0 to 5) - Delay for Jawz target switching, to make it less twitchy - UINT8 confirmInflictor; // Player ID that dealt damage to you - UINT8 confirmInflictorDelay; // Delay before playing the sound + UINT8 confirmVictim; // Player ID that you dealt damage to + UINT8 confirmVictimDelay; // Delay before playing the sound UINT8 trickpanel; // Trick panel state UINT8 tricktime; // Increases while you're tricking. You can't input any trick until it's reached a certain threshold diff --git a/src/k_kart.c b/src/k_kart.c index 189b946cd..52ac8c12c 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -2824,91 +2824,101 @@ void K_PlayOvertakeSound(mobj_t *source) K_RegularVoiceTimers(source->player); } -void K_PlayPainSound(mobj_t *source) +void K_PlayPainSound(mobj_t *source, mobj_t *other) { sfxenum_t pick = P_RandomKey(2); // Gotta roll the RNG every time this is called for sync reasons + sfxenum_t sfx_id = ((skin_t *)source->skin)->soundsid[S_sfx[sfx_khurt1 + pick].skinsound]; + boolean alwaysHear = false; + + if (other != NULL && P_MobjWasRemoved(other) == false && other->player != NULL) + { + alwaysHear = P_IsDisplayPlayer(other->player); + } + if (cv_kartvoices.value) - S_StartSound(source, sfx_khurt1 + pick); + { + S_StartSound(alwaysHear ? NULL : source, sfx_id); + } K_RegularVoiceTimers(source->player); } -void K_PlayHitEmSound(mobj_t *source, mobj_t *victim) +void K_PlayHitEmSound(mobj_t *source, mobj_t *other) { - const boolean victimIsLocal = (victim != NULL && P_IsDisplayPlayer(victim->player) == true); + sfxenum_t sfx_id = ((skin_t *)source->skin)->soundsid[S_sfx[sfx_khitem].skinsound]; + boolean alwaysHear = false; - if (source->player->follower) + if (other != NULL && P_MobjWasRemoved(other) == false && other->player != NULL) { - follower_t fl = followers[source->player->followerskin]; - source->player->follower->movecount = fl.hitconfirmtime; // movecount is used to play the hitconfirm animation for followers. + alwaysHear = P_IsDisplayPlayer(other->player); } if (cv_kartvoices.value) { - if (victimIsLocal == false) - { - S_StartSound(source, sfx_khitem); - } - } - else - { - S_StartSound(source, sfx_s1c9); // The only lost gameplay functionality with voices disabled + S_StartSound(alwaysHear ? NULL : source, sfx_id); } K_RegularVoiceTimers(source->player); +} - if (victim != NULL && victim->player != NULL) +void K_TryHurtSoundExchange(mobj_t *victim, mobj_t *attacker) +{ + if (victim == NULL || P_MobjWasRemoved(victim) == true || victim->player == NULL) { - victim->player->confirmInflictor = source->player - players; - victim->player->confirmInflictorDelay = TICRATE/2; + return; } + + // In a perfect world we could move this here, but there's + // a few niche situations where we want a pain sound from + // the victim, but no confirm sound from the attacker. + // (ex: DMG_STING) + + //K_PlayPainSound(victim, attacker); + + if (attacker == NULL || P_MobjWasRemoved(attacker) == true || attacker->player == NULL) + { + return; + } + + attacker->player->confirmVictim = (victim->player - players); + attacker->player->confirmVictimDelay = TICRATE/2; } void K_PlayPowerGloatSound(mobj_t *source) { if (cv_kartvoices.value) + { S_StartSound(source, sfx_kgloat); + } K_RegularVoiceTimers(source->player); } static void K_HandleDelayedHitByEm(player_t *player) { - if (player->confirmInflictorDelay == 0) + if (player->confirmVictimDelay == 0) { return; } - player->confirmInflictorDelay--; + player->confirmVictimDelay--; - if (player->confirmInflictorDelay == 0 - && P_IsDisplayPlayer(player) == true - && cv_kartvoices.value) + if (player->confirmVictimDelay == 0) { - player_t *inflictor = NULL; + mobj_t *victim = NULL; - if (player->confirmInflictor >= MAXPLAYERS) + if (player->confirmVictim < MAXPLAYERS && playeringame[player->confirmVictim]) { - return; + player_t *victimPlayer = &players[player->confirmVictim]; + + if (victimPlayer != NULL && victimPlayer->spectator == false) + { + victim = victimPlayer->mo; + } } - if (!playeringame[player->confirmInflictor]) - { - return; - } - - inflictor = &players[player->confirmInflictor]; - if (inflictor == NULL || inflictor->spectator) - { - return; - } - - if (inflictor->mo != NULL && P_MobjWasRemoved(inflictor->mo) == false) - { - sfxenum_t sfx_id = ((skin_t *)inflictor->mo->skin)->soundsid[S_sfx[sfx_khitem].skinsound]; - S_StartSound(NULL, sfx_id); - } + K_PlayHitEmSound(player->mo, victim); } } diff --git a/src/k_kart.h b/src/k_kart.h index 00c36ea76..bab501200 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -154,8 +154,9 @@ void K_HandleDirectionalInfluence(player_t *player); void K_PlayAttackTaunt(mobj_t *source); void K_PlayBoostTaunt(mobj_t *source); void K_PlayOvertakeSound(mobj_t *source); -void K_PlayPainSound(mobj_t *source); -void K_PlayHitEmSound(mobj_t *source, mobj_t *victim); +void K_PlayPainSound(mobj_t *source, mobj_t *other); +void K_PlayHitEmSound(mobj_t *source, mobj_t *other); +void K_TryHurtSoundExchange(mobj_t *victim, mobj_t *attacker); void K_PlayPowerGloatSound(mobj_t *source); fixed_t K_ItemScaleForPlayer(player_t *player); diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 301665e45..e172ea978 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -3339,23 +3339,37 @@ static int lib_kOvertakeSound(lua_State *L) static int lib_kPainSound(lua_State *L) { mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); + mobj_t *other = NULL; NOHUD if (!mobj->player) return luaL_error(L, "K_PlayPainSound: mobj_t isn't a player object."); //Nothing bad would happen if we let it run the func, but telling why it ain't doing anything is helpful. - K_PlayPainSound(mobj); + if (!lua_isnone(L, 2) && lua_isuserdata(L, 2)) + other = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ)); + K_PlayPainSound(mobj, other); return 0; } static int lib_kHitEmSound(lua_State *L) { mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); - mobj_t *victim = NULL; + mobj_t *other = NULL; NOHUD if (!mobj->player) return luaL_error(L, "K_PlayHitEmSound: mobj_t isn't a player object."); //Nothing bad would happen if we let it run the func, but telling why it ain't doing anything is helpful. if (!lua_isnone(L, 2) && lua_isuserdata(L, 2)) - victim = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ)); - K_PlayHitEmSound(mobj, victim); + other = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ)); + K_PlayHitEmSound(mobj, other); + return 0; +} + +static int lib_kTryHurtSoundExchange(lua_State *L) +{ + mobj_t *victim = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); + mobj_t *attacker = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ)); + NOHUD + if (!victim->player) + return luaL_error(L, "K_TryHurtSoundExchange: mobj_t isn't a player object."); //Nothing bad would happen if we let it run the func, but telling why it ain't doing anything is helpful. + K_TryHurtSoundExchange(victim, attacker); return 0; } @@ -4037,6 +4051,7 @@ static luaL_Reg lib[] = { {"K_PlayLossSound", lib_kLossSound}, {"K_PlayPainSound", lib_kPainSound}, {"K_PlayHitEmSound", lib_kHitEmSound}, + {"K_TryHurtSoundExchange", lib_kTryHurtSoundExchange}, {"K_IsPlayerLosing",lib_kIsPlayerLosing}, {"K_IsPlayerWanted",lib_kIsPlayerWanted}, {"K_KartBouncing",lib_kKartBouncing}, diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index 1d5f6bee7..e166a9b07 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -360,10 +360,10 @@ static int player_get(lua_State *L) lua_pushinteger(L, plr->lastjawztarget); else if (fastcmp(field,"jawztargetdelay")) lua_pushinteger(L, plr->jawztargetdelay); - else if (fastcmp(field,"confirmInflictor")) - lua_pushinteger(L, plr->confirmInflictor); - else if (fastcmp(field,"confirmInflictorDelay")) - lua_pushinteger(L, plr->confirmInflictorDelay); + else if (fastcmp(field,"confirmVictim")) + lua_pushinteger(L, plr->confirmVictim); + else if (fastcmp(field,"confirmVictimDelay")) + lua_pushinteger(L, plr->confirmVictimDelay); else if (fastcmp(field,"glanceDir")) lua_pushinteger(L, plr->glanceDir); else if (fastcmp(field,"trickpanel")) @@ -718,10 +718,10 @@ static int player_set(lua_State *L) plr->lastjawztarget = luaL_checkinteger(L, 3); else if (fastcmp(field,"jawztargetdelay")) plr->jawztargetdelay = luaL_checkinteger(L, 3); - else if (fastcmp(field,"confirmInflictor")) - plr->confirmInflictor = luaL_checkinteger(L, 3); - else if (fastcmp(field,"confirmInflictorDelay")) - plr->confirmInflictorDelay = luaL_checkinteger(L, 3); + else if (fastcmp(field,"confirmVictim")) + plr->confirmVictim = luaL_checkinteger(L, 3); + else if (fastcmp(field,"confirmVictimDelay")) + plr->confirmVictimDelay = luaL_checkinteger(L, 3); else if (fastcmp(field,"glanceDir")) plr->glanceDir = luaL_checkinteger(L, 3); else if (fastcmp(field,"trickpanel")) diff --git a/src/p_inter.c b/src/p_inter.c index 0974e11d7..880e1ef7d 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2010,7 +2010,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da source->player->invincibilitytimer += kinvextend; } - K_PlayHitEmSound(source, target); + K_TryHurtSoundExchange(target, source); K_BattleAwardHit(source->player, player, inflictor, takeBumpers); K_TakeBumpersFromPlayer(source->player, player, takeBumpers); @@ -2083,14 +2083,14 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da player->flashing = K_GetKartFlashing(player); } - P_PlayRinglossSound(player->mo); + P_PlayRinglossSound(target); if (ringburst > 0) { P_PlayerRingBurst(player, ringburst); } - K_PlayPainSound(player->mo); + K_PlayPainSound(target, source); if ((hardhit == true) || (cv_kartdebughuddrop.value && !modeattacking)) { diff --git a/src/p_saveg.c b/src/p_saveg.c index 5569f24d5..689da4386 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -337,8 +337,8 @@ static void P_NetArchivePlayers(void) WRITESINT8(save_p, players[i].lastjawztarget); WRITEUINT8(save_p, players[i].jawztargetdelay); - WRITEUINT8(save_p, players[i].confirmInflictor); - WRITEUINT8(save_p, players[i].confirmInflictorDelay); + WRITEUINT8(save_p, players[i].confirmVictim); + WRITEUINT8(save_p, players[i].confirmVictimDelay); WRITEUINT8(save_p, players[i].trickpanel); WRITEUINT8(save_p, players[i].tricktime); @@ -622,8 +622,8 @@ static void P_NetUnArchivePlayers(void) players[i].lastjawztarget = READSINT8(save_p); players[i].jawztargetdelay = READUINT8(save_p); - players[i].confirmInflictor = READUINT8(save_p); - players[i].confirmInflictorDelay = READUINT8(save_p); + players[i].confirmVictim = READUINT8(save_p); + players[i].confirmVictimDelay = READUINT8(save_p); players[i].trickpanel = READUINT8(save_p); players[i].tricktime = READUINT8(save_p); From 98ec1779d95a9897b06254e24e2ad0581c921489 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 5 Sep 2022 11:30:12 -0400 Subject: [PATCH 2/2] Reimplement follower hit confirm --- src/k_kart.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/k_kart.c b/src/k_kart.c index 52ac8c12c..92a83902d 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -2883,6 +2883,12 @@ void K_TryHurtSoundExchange(mobj_t *victim, mobj_t *attacker) attacker->player->confirmVictim = (victim->player - players); attacker->player->confirmVictimDelay = TICRATE/2; + + if (attacker->player->follower != NULL) + { + const follower_t *fl = &followers[attacker->player->followerskin]; + attacker->player->follower->movecount = fl->hitconfirmtime; // movecount is used to play the hitconfirm animation for followers. + } } void K_PlayPowerGloatSound(mobj_t *source)