diff --git a/src/d_player.h b/src/d_player.h index d6175e3c9..6c5aa99b7 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -606,6 +606,9 @@ struct player_t UINT8 ringdelay; // (0 to 3) - 3 tic delay between every ring usage UINT16 ringboost; // Ring boost timer UINT16 superring; // Spawn rings on top of you every tic! + UINT8 nextringaward; // When should we spawn our next superring ring? + UINT8 ringvolume; // When consuming lots of rings, lower the sound a little. + UINT8 ringtransparency; // When consuming lots of rings, fade out the rings again. UINT8 curshield; // see kartshields_t UINT8 bubblecool; // Bubble Shield use cooldown diff --git a/src/doomdef.h b/src/doomdef.h index d2736cb50..fa0db8e47 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -562,9 +562,6 @@ extern int compuncommitted; /// Camera always has noclip. #define NOCLIPCAM -/// Other karma comeback modes -//#define OTHERKARMAMODES - #ifdef __cplusplus } // extern "C" #endif diff --git a/src/g_game.c b/src/g_game.c index 318cb486c..08f5617f8 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2518,6 +2518,9 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) p->eggmanblame = -1; p->nocontrol = nocontrol; p->kickstartaccel = kickstartaccel; + + p->ringvolume = 255; + p->ringtransparency = 255; p->spectatorreentry = spectatorreentry; p->grieftime = grieftime; diff --git a/src/k_kart.c b/src/k_kart.c index 99b379b35..82171b27b 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -3510,21 +3510,25 @@ angle_t K_MomentumAngle(mobj_t *mo) } } -void K_AwardPlayerRings(player_t *player, INT32 rings, boolean overload) +void K_AwardPlayerRings(player_t *player, UINT16 rings, boolean overload) { UINT16 superring; if (!overload) { INT32 totalrings = - RINGTOTAL(player) + (player->superring / 3); + RINGTOTAL(player) + (player->superring); /* capped at 20 rings */ if ((totalrings + rings) > 20) + { + if (totalrings >= 20) + return; // woah dont let that go negative buster rings = (20 - totalrings); + } } - superring = player->superring + (rings * 3); + superring = player->superring + rings; /* check if not overflow */ if (superring > player->superring) @@ -6997,17 +7001,24 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) if (player->superring) { - if (player->superring % 3 == 0) + player->nextringaward++; + UINT8 ringrate = 3 - min(2, player->superring / 20); // Used to consume fat stacks of cash faster. + if (player->nextringaward >= ringrate) { mobj_t *ring = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_RING); ring->extravalue1 = 1; // Ring collect animation timer ring->angle = player->mo->angle; // animation angle P_SetTarget(&ring->target, player->mo); // toucher for thinker player->pickuprings++; - if (player->superring <= 3) + if (player->superring == 1) ring->cvmem = 1; // play caching when collected + player->nextringaward = 0; + player->superring--; } - player->superring--; + } + else + { + player->nextringaward = 99; // Next time we need to award superring, spawn the first one instantly. } // Start at lap 1 when using old checkpoint system just to be safe. @@ -7021,6 +7032,21 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) if (player->hyudorotimer) player->hyudorotimer--; + if (player->ringvolume < MINRINGVOLUME) + player->ringvolume = MINRINGVOLUME; + else if (MAXRINGVOLUME - player->ringvolume < RINGVOLUMEREGEN) + player->ringvolume = MAXRINGVOLUME; + else + player->ringvolume += RINGVOLUMEREGEN; + + // :D + if (player->ringtransparency < MINRINGTRANSPARENCY) + player->ringtransparency = MINRINGTRANSPARENCY; + else if (MAXRINGTRANSPARENCY - player->ringtransparency < RINGTRANSPARENCYREGEN) + player->ringtransparency = MAXRINGTRANSPARENCY; + else + player->ringtransparency += RINGTRANSPARENCYREGEN; + if (player->sadtimer) player->sadtimer--; @@ -9025,6 +9051,20 @@ void K_MoveKartPlayer(player_t *player, boolean onground) { mobj_t *ring = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_RING); P_SetMobjState(ring, S_FASTRING1); + + if (P_IsDisplayPlayer(player)) + { + UINT8 startfade = 220; + UINT8 transfactor = 10 * (min(startfade, player->ringtransparency)) / startfade; + if (transfactor < 10) + { + transfactor = max(transfactor, 4); + ring->renderflags |= ((10-transfactor) << RF_TRANSSHIFT); + ring->renderflags |= RF_ADD; + } + } + player->ringtransparency -= RINGTRANSPARENCYUSEPENALTY; + ring->extravalue1 = 1; // Ring use animation timer ring->extravalue2 = 1; // Ring use animation flag ring->shadowscale = 0; diff --git a/src/k_kart.h b/src/k_kart.h index a0070fb09..8d14da255 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -48,6 +48,17 @@ typedef enum RESPAWNRS_PO, } respawnresult_e; +#define MAXRINGVOLUME 255 +#define MAXRINGTRANSPARENCY 255 +#define MINRINGVOLUME 100 +#define MINRINGTRANSPARENCY 100 +#define RINGVOLUMECOLLECTPENALTY 3 +#define RINGTRANSPARENCYCOLLECTPENALTY 0 +#define RINGVOLUMEUSEPENALTY 15 +#define RINGTRANSPARENCYUSEPENALTY 15 +#define RINGVOLUMEREGEN 1 +#define RINGTRANSPARENCYREGEN 3 + angle_t K_ReflectAngle(angle_t angle, angle_t against, fixed_t maxspeed, fixed_t yourspeed); void K_RegisterKartStuff(void); @@ -85,7 +96,7 @@ UINT8 K_RaceLapCount(INT16 mapNum); void K_KartPlayerThink(player_t *player, ticcmd_t *cmd); void K_KartPlayerAfterThink(player_t *player); angle_t K_MomentumAngle(mobj_t *mo); -void K_AwardPlayerRings(player_t *player, INT32 rings, boolean overload); +void K_AwardPlayerRings(player_t *player, UINT16 rings, boolean overload); void K_DoInstashield(player_t *player); void K_BattleAwardHit(player_t *player, player_t *victim, mobj_t *inflictor, UINT8 bumpersRemoved); void K_SpinPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 type); diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index 1da6247b5..23271c4fd 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -330,12 +330,20 @@ static int player_get(lua_State *L) lua_pushinteger(L, plr->ringboost); else if (fastcmp(field,"superring")) lua_pushinteger(L, plr->superring); + else if (fastcmp(field,"nextringaward")) + lua_pushinteger(L, plr->nextringaward); + else if (fastcmp(field,"ringvolume")) + lua_pushinteger(L, plr->ringvolume); + else if (fastcmp(field,"ringtransparency")) + lua_pushinteger(L, plr->ringtransparency); else if (fastcmp(field,"curshield")) lua_pushinteger(L, plr->curshield); else if (fastcmp(field,"bubblecool")) lua_pushinteger(L, plr->bubblecool); else if (fastcmp(field,"bubbleblowup")) lua_pushinteger(L, plr->bubbleblowup); + else if (fastcmp(field,"bubblepop")) + lua_pushinteger(L, plr->bubblepop); else if (fastcmp(field,"flamedash")) lua_pushinteger(L, plr->flamedash); else if (fastcmp(field,"flamemeter")) @@ -733,12 +741,20 @@ static int player_set(lua_State *L) plr->ringboost = luaL_checkinteger(L, 3); else if (fastcmp(field,"superring")) plr->superring = luaL_checkinteger(L, 3); + else if (fastcmp(field,"nextringaward")) + plr->nextringaward = luaL_checkinteger(L, 3); + else if (fastcmp(field,"ringvolume")) + plr->ringvolume = luaL_checkinteger(L, 3); + else if (fastcmp(field,"ringtransparency")) + plr->ringtransparency = luaL_checkinteger(L, 3); else if (fastcmp(field,"curshield")) plr->curshield = luaL_checkinteger(L, 3); else if (fastcmp(field,"bubblecool")) plr->bubblecool = luaL_checkinteger(L, 3); else if (fastcmp(field,"bubbleblowup")) plr->bubbleblowup = luaL_checkinteger(L, 3); + else if (fastcmp(field,"bubblepop")) + plr->bubblepop = luaL_checkinteger(L, 3); else if (fastcmp(field,"flamedash")) plr->flamedash = luaL_checkinteger(L, 3); else if (fastcmp(field,"flamemeter")) diff --git a/src/p_enemy.c b/src/p_enemy.c index 22977afcc..09a426c25 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -3581,7 +3581,9 @@ void A_AttractChase(mobj_t *actor) // Base add is 3 tics for 9,9, adds 1 tic for each point closer to the 1,1 end actor->target->player->ringboost += K_GetKartRingPower(actor->target->player, true) + 3; - S_StartSound(actor->target, sfx_s1b5); + S_StartSoundAtVolume(actor->target, sfx_s1b5, actor->target->player->ringvolume); + + actor->target->player->ringvolume -= RINGVOLUMEUSEPENALTY; P_KillMobj(actor, actor->target, actor->target, DMG_NORMAL); return; @@ -3608,7 +3610,10 @@ void A_AttractChase(mobj_t *actor) if (actor->cvmem) // caching S_StartSound(actor->target, sfx_s1c5); else - S_StartSound(actor->target, sfx_s227); + S_StartSoundAtVolume(actor->target, sfx_s227, actor->target->player->ringvolume); + + actor->target->player->ringvolume -= RINGVOLUMECOLLECTPENALTY; + actor->target->player->ringtransparency -= RINGTRANSPARENCYCOLLECTPENALTY; actor->target->player->pickuprings--; P_RemoveMobj(actor); diff --git a/src/p_inter.c b/src/p_inter.c index 0da52a23d..e9535877f 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -116,9 +116,7 @@ boolean P_CanPickupItem(player_t *player, UINT8 weapon) return false; if ((gametyperules & GTR_BUMPERS) // No bumpers in Match -#ifndef OTHERKARMAMODES && !weapon -#endif && player->bumper <= 0) return false; diff --git a/src/p_saveg.c b/src/p_saveg.c index 01c2b1b0b..0aa2cd3bb 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -299,6 +299,9 @@ static void P_NetArchivePlayers(savebuffer_t *save) WRITEUINT8(save->p, players[i].ringdelay); WRITEUINT16(save->p, players[i].ringboost); WRITEUINT16(save->p, players[i].superring); + WRITEUINT8(save->p, players[i].nextringaward); + WRITEUINT8(save->p, players[i].ringvolume); + WRITEUINT8(save->p, players[i].ringtransparency); WRITEUINT8(save->p, players[i].curshield); WRITEUINT8(save->p, players[i].bubblecool); @@ -601,6 +604,9 @@ static void P_NetUnArchivePlayers(savebuffer_t *save) players[i].ringdelay = READUINT8(save->p); players[i].ringboost = READUINT16(save->p);; players[i].superring = READUINT16(save->p); + players[i].nextringaward = READUINT8(save->p); + players[i].ringvolume = READUINT8(save->p); + players[i].ringtransparency = READUINT8(save->p); players[i].curshield = READUINT8(save->p); players[i].bubblecool = READUINT8(save->p);