diff --git a/src/d_player.h b/src/d_player.h index b325137ea..b70a315ed 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -668,6 +668,7 @@ struct player_t UINT16 superring; // You were awarded rings, and have this many of them left to spawn on yourself. UINT8 nextringaward; // When should we spawn our next superring ring? UINT16 ringvolume; // When consuming lots of rings, lower the sound a little. + UINT16 ringburst; // Queued number of rings to lose after hitlag ends UINT8 curshield; // see kartshields_t UINT8 bubblecool; // Bubble Shield use cooldown diff --git a/src/k_hitlag.c b/src/k_hitlag.c index fd682c4c1..4bb0d37f3 100644 --- a/src/k_hitlag.c +++ b/src/k_hitlag.c @@ -18,6 +18,7 @@ #include "m_random.h" #include "p_local.h" #include "r_main.h" +#include "s_sound.h" /*-------------------------------------------------- void K_AddHitLag(mobj_t *mo, INT32 tics, boolean fromDamage) @@ -129,13 +130,38 @@ static void K_SpawnSingleHitLagSpark( } } +/*-------------------------------------------------- + static void K_PlayHitLagSFX(mobj_t *victim, UINT8 tics) + + Plays a damage sound for a player. + + Input Arguments:- + victim - Object getting damaged. + tics - How long the hitlag was. + + Return:- + N/A +--------------------------------------------------*/ +static void K_PlayHitLagSFX(mobj_t *victim, UINT8 tics) +{ + sfxenum_t soundID = sfx_dmga1; + + if (P_Random(PR_DECORATION) & 1) // might want to use this set for some other scenario, instead of randomized? + { + soundID = sfx_dmgb1; + } + + soundID += ((tics * (NUM_HITLAG_SOUNDS - 1)) + (MAXHITLAGTICS >> 1)) / MAXHITLAGTICS; + S_StartSound(victim, soundID); +} + /*-------------------------------------------------- static void K_SpawnHitLagEFX(mobj_t *victim, mobj_t *inflictor, mobj_t *source, UINT8 tics) Spawns several hitlag sparks for damage. Input Arguments:- - victim - Object getting touched. + victim - Object getting damaged. inflictor - Object touching the victim. May be NULL. source - Object that inflictor came from. May be NULL or same as inflictor. tics - How long the hitlag was. @@ -152,6 +178,7 @@ static void K_SpawnHitLagEFX(mobj_t *victim, mobj_t *inflictor, mobj_t *source, I_Assert(P_MobjWasRemoved(victim) == false); + K_PlayHitLagSFX(victim, tics); P_StartQuakeFromMobj(tics, tics * 2 * mapobjectscale, 512 * mapobjectscale, victim); if (P_MobjWasRemoved(inflictor) == false) diff --git a/src/k_hitlag.h b/src/k_hitlag.h index cace7a964..fed3b75cc 100644 --- a/src/k_hitlag.h +++ b/src/k_hitlag.h @@ -23,6 +23,7 @@ extern "C" { #define MAXHITLAGTICS (30) #define HITLAGJITTERS (FRACUNIT / 20) #define NUM_HITLAG_STATES (9) +#define NUM_HITLAG_SOUNDS (4) /*-------------------------------------------------- void K_AddHitLag(mobj_t *mo, INT32 tics, boolean fromDamage); diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index dca270903..c30d0d54d 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -361,6 +361,8 @@ static int player_get(lua_State *L) lua_pushinteger(L, plr->nextringaward); else if (fastcmp(field,"ringvolume")) lua_pushinteger(L, plr->ringvolume); + else if (fastcmp(field,"ringburst")) + lua_pushinteger(L, plr->ringburst); else if (fastcmp(field,"curshield")) lua_pushinteger(L, plr->curshield); else if (fastcmp(field,"bubblecool")) @@ -775,6 +777,8 @@ static int player_set(lua_State *L) plr->nextringaward = luaL_checkinteger(L, 3); else if (fastcmp(field,"ringvolume")) plr->ringvolume = luaL_checkinteger(L, 3); + else if (fastcmp(field,"ringburst")) + plr->ringburst = luaL_checkinteger(L, 3); else if (fastcmp(field,"curshield")) plr->curshield = luaL_checkinteger(L, 3); else if (fastcmp(field,"bubblecool")) diff --git a/src/p_inter.c b/src/p_inter.c index 6176201ec..badd6d3a3 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2752,8 +2752,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da if (type != DMG_STING) player->flashing = K_GetKartFlashing(player); - P_PlayRinglossSound(target); - P_PlayerRingBurst(player, ringburst); + player->ringburst += ringburst; K_PopPlayerShield(player); player->instashield = 15; @@ -2829,6 +2828,9 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da return true; } +#define RING_LAYER_SIDE_SIZE (3) +#define RING_LAYER_SIZE (RING_LAYER_SIDE_SIZE * 2) + static void P_FlingBurst ( player_t *player, angle_t fa, @@ -2837,16 +2839,11 @@ static void P_FlingBurst fixed_t objScale, INT32 i) { - mobj_t *mo; - fixed_t ns; - fixed_t momxy = 5<> 1; - - mo = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, objType); + mobj_t *mo = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, objType); + P_SetTarget(&mo->target, player->mo); mo->threshold = 10; // not useful for spikes mo->fuse = objFuse; - P_SetTarget(&mo->target, player->mo); // We want everything from P_SpawnMobjFromMobj except scale. objScale = FixedMul(objScale, FixedDiv(mapobjectscale, player->mo->scale)); @@ -2857,27 +2854,20 @@ static void P_FlingBurst mo->destscale = mo->scale; } - /* - 0: 0 - 1: 1 = (1+1)/2 = 1 - 2: 1 = (2+1)/2 = 1 - 3: 2 = (3+1)/2 = 2 - 4: 2 = (4+1)/2 = 2 - 5: 3 = (4+1)/2 = 2 - */ - // Angle / height offset changes every other ring - momxy -= mx * FRACUNIT; - momz += mx * (2<mo->scale); - mo->momx = (mo->target->momx/2) + FixedMul(FINECOSINE(fa>>ANGLETOFINESHIFT), ns); - mo->momy = (mo->target->momy/2) + FixedMul(FINESINE(fa>>ANGLETOFINESHIFT), ns); + // Pitch offset changes every other ring + angle_t offset = ANGLE_90 / (RING_LAYER_SIDE_SIZE + 2); + angle_t fp = offset + (((i / 2) % RING_LAYER_SIDE_SIZE) * (offset * 3 >> 1)); - ns = FixedMul(momz, player->mo->scale); - mo->momz = (mo->target->momz/2) + ((ns) * P_MobjFlip(mo)); + const UINT8 layer = i / RING_LAYER_SIZE; + const fixed_t thrust = (13 * mo->scale) + (7 * mo->scale * layer); + mo->momx = (player->mo->momx / 2) + FixedMul(FixedMul(thrust, FINECOSINE(fp >> ANGLETOFINESHIFT)), FINECOSINE(fa >> ANGLETOFINESHIFT)); + mo->momy = (player->mo->momy / 2) + FixedMul(FixedMul(thrust, FINECOSINE(fp >> ANGLETOFINESHIFT)), FINESINE(fa >> ANGLETOFINESHIFT)); + mo->momz = (player->mo->momz / 2) + (FixedMul(thrust, FINESINE(fp >> ANGLETOFINESHIFT)) * P_MobjFlip(mo)); } /** Spills an injured player's rings. @@ -2889,7 +2879,7 @@ static void P_FlingBurst */ void P_PlayerRingBurst(player_t *player, INT32 num_rings) { - INT32 num_fling_rings; + INT32 spill_total, num_fling_rings; INT32 i; angle_t fa; @@ -2911,8 +2901,8 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings) else if (num_rings <= 0) return; - num_rings = -P_GivePlayerRings(player, -num_rings); - num_fling_rings = num_rings+min(0, player->rings); + spill_total = -P_GivePlayerRings(player, -num_rings); + num_fling_rings = spill_total + min(0, player->rings); // determine first angle fa = player->mo->angle + ((P_RandomByte(PR_ITEM_RINGS) & 1) ? -ANGLE_90 : ANGLE_90); @@ -2922,7 +2912,7 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings) P_FlingBurst(player, fa, MT_FLINGRING, 60*TICRATE, FRACUNIT, i); } - while (i < num_rings) + while (i < spill_total) { P_FlingBurst(player, fa, MT_DEBTSPIKE, 0, 3 * FRACUNIT / 2, i++); } diff --git a/src/p_mobj.c b/src/p_mobj.c index 599dd37e8..dc3dd037a 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -10031,6 +10031,14 @@ void P_MobjThinker(mobj_t *mobj) if (mobj->player != NULL && mobj->hitlag == 0 && (mobj->eflags & MFE_DAMAGEHITLAG)) { + if (mobj->player->ringburst > 0) + { + // Delayed ring loss + P_PlayRinglossSound(mobj); + P_PlayerRingBurst(mobj->player, mobj->player->ringburst); + mobj->player->ringburst = 0; + } + K_HandleDirectionalInfluence(mobj->player); } diff --git a/src/p_saveg.c b/src/p_saveg.c index 21414f22c..6c61e7f6a 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -468,6 +468,7 @@ static void P_NetArchivePlayers(savebuffer_t *save) WRITEUINT16(save->p, players[i].superring); WRITEUINT8(save->p, players[i].nextringaward); WRITEUINT8(save->p, players[i].ringvolume); + WRITEUINT16(save->p, players[i].ringburst); WRITEUINT8(save->p, players[i].curshield); WRITEUINT8(save->p, players[i].bubblecool); @@ -946,6 +947,7 @@ static void P_NetUnArchivePlayers(savebuffer_t *save) players[i].superring = READUINT16(save->p); players[i].nextringaward = READUINT8(save->p); players[i].ringvolume = READUINT8(save->p); + players[i].ringburst = READUINT16(save->p); players[i].curshield = READUINT8(save->p); players[i].bubblecool = READUINT8(save->p); diff --git a/src/sounds.c b/src/sounds.c index 18bfa26d9..e802d0664 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -1210,6 +1210,16 @@ sfxinfo_t S_sfx[NUMSFX] = {"rank", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Rank slam + // Damage sounds + {"dmga1", false, 255, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Damaged"}, + {"dmga2", false, 255, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Damaged"}, + {"dmga3", false, 255, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Damaged"}, + {"dmga4", false, 255, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Damaged"}, + {"dmgb1", false, 255, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Damaged"}, + {"dmgb2", false, 255, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Damaged"}, + {"dmgb3", false, 255, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Damaged"}, + {"dmgb4", false, 255, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Damaged"}, + // SRB2Kart - Engine sounds // Engine class A {"krta00", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR, ""}, diff --git a/src/sounds.h b/src/sounds.h index b9b0616e0..7c55906c0 100644 --- a/src/sounds.h +++ b/src/sounds.h @@ -1279,6 +1279,16 @@ typedef enum sfx_rank, + // Damage sounds + sfx_dmga1, + sfx_dmga2, + sfx_dmga3, + sfx_dmga4, + sfx_dmgb1, + sfx_dmgb2, + sfx_dmgb3, + sfx_dmgb4, + // Next up: UNIQUE ENGINE SOUNDS! Hoooooo boy... // Engine class A - Low Speed, Low Weight sfx_krta00,