mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-01-10 16:52:16 +00:00
Merge branch 'hear-pain' into 'master'
Improved MKSC-style hit confirms See merge request KartKrew/Kart!659
This commit is contained in:
commit
ea3818d285
7 changed files with 97 additions and 65 deletions
|
|
@ -506,8 +506,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
|
||||
|
|
|
|||
100
src/k_kart.c
100
src/k_kart.c
|
|
@ -2824,91 +2824,107 @@ 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;
|
||||
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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},
|
||||
|
|
|
|||
|
|
@ -362,10 +362,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"))
|
||||
|
|
@ -722,10 +722,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"))
|
||||
|
|
|
|||
|
|
@ -2012,7 +2012,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);
|
||||
|
|
@ -2085,14 +2085,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))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -339,8 +339,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);
|
||||
|
|
@ -626,8 +626,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);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue