diff --git a/src/d_player.h b/src/d_player.h index 6ffddf859..e094fa306 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -154,6 +154,8 @@ typedef enum PF2_SERVERTEMPMUTE = 1<<10, // Haven't met gamestochat requirement PF2_SAMEFRAMESTUNG = 1<<11, // Goofy bullshit for tracking mutual ring sting PF2_UNSTINGABLE = 1<<12, // Was bumped out of spindash + PF2_GIMMESTARTAWARDS = 1<<13, // Need to apply non-first start awards on a 1 tic delay to prevent port priority + PF2_GIMMEFIRSTBLOOD = 1<<14, // And need to differentiate between First Blood and everything else! } pflags2_t; typedef enum @@ -755,6 +757,7 @@ struct player_t tic_t lastairtime; UINT16 bigwaypointgap; // timer counts down if finish line distance gap is too big to update waypoint UINT8 startboost; // (0 to 125) - Boost you get from start of race + UINT8 neostartboost; // Weaker partial startboost UINT8 dropdashboost; // Boost you get when holding A while respawning UINT8 aciddropdashboost; // acid dropdash diff --git a/src/k_hud.cpp b/src/k_hud.cpp index 69e5b3098..d234d1fb3 100644 --- a/src/k_hud.cpp +++ b/src/k_hud.cpp @@ -8004,8 +8004,16 @@ void K_drawKartHUD(void) std::string arrow = (ahead == 1 || ahead == -2) ? "(" : ")"; - // vibes offset - row.x(-35).colormap(skincolor).patch(R_CanShowSkinInDemo(skin) ? faceprefix[skin][FACE_MINIMAP] : kp_unknownminimap); + if (skin != -1) + { + // vibes offset + row.x(-35).colormap(skincolor).patch(R_CanShowSkinInDemo(skin) ? faceprefix[skin][FACE_MINIMAP] : kp_unknownminimap); + } + else + { + ahead = -1; + } + if (pos > 1) row.x(-35).font(Draw::Font::kPing).text(va("%d", pos)); diff --git a/src/k_kart.c b/src/k_kart.c index 6d418151b..82ca555b4 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -1562,7 +1562,7 @@ static boolean K_TryDraft(player_t *player, mobj_t *dest, fixed_t minDist, fixed if (dest->player != NULL) { // No tethering off of the guy who got the starting bonus :P - if (dest->player->startboost > 0) + if (dest->player->startboost > 0 || dest->player->neostartboost > 0) { return false; } @@ -3857,6 +3857,11 @@ static void K_GetKartBoostPower(player_t *player) ADDBOOST(FRACUNIT, 4*FRACUNIT, HANDLESCALING); // + 100% top speed, + 400% acceleration, +50% handling } + if (player->neostartboost) // Startup Boost + { + ADDBOOST(FRACUNIT/2, 2*FRACUNIT, HANDLESCALING/3); // + 50% top speed, + 200% acceleration, +no sliptide% handling + } + if (player->dropdashboost) // Drop dash { ADDBOOST(FRACUNIT/3, 4*FRACUNIT, HANDLESCALING); // + 33% top speed, + 400% acceleration, +50% handling @@ -10200,6 +10205,61 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) Music_Stop("position"); } + if (player->pflags2 & PF2_GIMMESTARTAWARDS) + { + UINT16 maxduration = 125; + UINT16 duration = FixedRescale(leveltime - starttime, 0, TICRATE*2, Easing_Linear, maxduration, 0); + + player->aciddropdashboost += duration; + S_StartSound(player->mo, sfx_s23c); + + if (duration) + { + K_SpawnDriftBoostExplosion(player, FixedRescale(duration, 0, maxduration, Easing_Linear, 1, 3)); + // K_SpawnDriftElectricSparks(player, SKINCOLOR_SILVER, false); + } + + // CONS_Printf("%d %s %d giving start award %d\n", leveltime, player_names[player - players], leveltime - starttime, duration); + } + + if (player->pflags2 & PF2_GIMMEFIRSTBLOOD) + { + if (K_InRaceDuel()) + { + K_SpawnDriftElectricSparks(player, player->skincolor, false); + K_SpawnAmps(player, 20, player->mo); + } + else + { + S_StartSound(player->mo, sfx_s23c); + player->startboost = 125; + + K_SpawnDriftBoostExplosion(player, 4); + K_SpawnDriftElectricSparks(player, SKINCOLOR_SILVER, false); + K_SpawnAmps(player, (K_InRaceDuel()) ? 20 : 20, player->mo); + + if (g_teamplay) + { + for (UINT8 j = 0; j < MAXPLAYERS; j++) + { + if (!playeringame[j] || players[j].spectator || !players[j].mo || P_MobjWasRemoved(players[j].mo)) + continue; + if (!G_SameTeam(player, &players[j])) + continue; + if (player == &players[j]) + continue; + K_SpawnAmps(&players[j], 10, player->mo); + } + } + } + + // CONS_Printf("%d %s giving first blood\n", leveltime, player_names[player - players]); + + rainbowstartavailable = false; + } + + player->pflags2 &= ~(PF2_GIMMESTARTAWARDS|PF2_GIMMEFIRSTBLOOD); + if (player->transfer) { if (player->fastfall) @@ -10692,6 +10752,12 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) { player->startboost--; } + + if (player->neostartboost > 0 && onground == true) + { + player->neostartboost--; + } + if (player->dropdashboost) player->dropdashboost--; diff --git a/src/k_kart.h b/src/k_kart.h index 9fbf43c29..1f8ea739e 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -57,6 +57,8 @@ Make sure this matches the actual number of states #define MINCOMBOFLOAT (mapobjectscale*1) #define MAXCOMBOTIME (TICRATE*4) +#define STARTBOOST_DURATION (125) + #define TIMEATTACK_START (TICRATE*10) #define LIGHTNING_CHARGE (TICRATE*2) diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index c5a17ba12..e6560d9bc 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -321,6 +321,8 @@ static int player_get(lua_State *L) lua_pushinteger(L, plr->gateSound); else if (fastcmp(field,"startboost")) lua_pushinteger(L, plr->startboost); + else if (fastcmp(field,"neostartboost")) + lua_pushinteger(L, plr->neostartboost); else if (fastcmp(field,"dropdashboost")) lua_pushinteger(L, plr->dropdashboost); else if (fastcmp(field,"aciddropdashboost")) @@ -994,6 +996,8 @@ static int player_set(lua_State *L) plr->gateSound = luaL_checkinteger(L, 3); else if (fastcmp(field,"startboost")) plr->startboost = luaL_checkinteger(L, 3); + else if (fastcmp(field,"neostartboost")) + plr->neostartboost = luaL_checkinteger(L, 3); else if (fastcmp(field,"dropdashboost")) plr->dropdashboost = luaL_checkinteger(L, 3); else if (fastcmp(field,"aciddropdashboost")) diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index d72668b51..fe7413c5a 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -467,6 +467,7 @@ static void P_NetArchivePlayers(savebuffer_t *save) WRITEUINT32(save->p, players[i].lastairtime); WRITEUINT16(save->p, players[i].bigwaypointgap); WRITEUINT8(save->p, players[i].startboost); + WRITEUINT8(save->p, players[i].neostartboost); WRITEUINT8(save->p, players[i].dropdashboost); WRITEUINT8(save->p, players[i].aciddropdashboost); @@ -1149,6 +1150,7 @@ static void P_NetUnArchivePlayers(savebuffer_t *save) players[i].lastairtime = READUINT32(save->p); players[i].bigwaypointgap = READUINT16(save->p); players[i].startboost = READUINT8(save->p); + players[i].neostartboost = READUINT8(save->p); players[i].dropdashboost = READUINT8(save->p); players[i].aciddropdashboost = READUINT8(save->p); diff --git a/src/p_spec.c b/src/p_spec.c index d23b19b7d..ea2f3a49c 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -1991,6 +1991,13 @@ static void K_HandleLapIncrement(player_t *player) S_StartSound(player->mo, sfx_s3kb2); } + player->karthud[khud_splitcolor] = 0; + player->karthud[khud_splitposition] = 1; + player->karthud[khud_splitskin] = -1; + player->karthud[khud_splittime] = (INT32)(starttime - leveltime); + player->karthud[khud_splittimer] = 3*TICRATE; + player->karthud[khud_splitwin] = -2; + return; } @@ -2060,38 +2067,35 @@ static void K_HandleLapIncrement(player_t *player) K_UpdateAllPlayerPositions(); // P_DoPlayerExit calls this } - if (rainbowstartavailable == true && player->mo->hitlag == 0) + if (!G_TimeAttackStart() && player->laps == 1 && lapisfresh) { - if (K_InRaceDuel()) + if (rainbowstartavailable) { - K_SpawnDriftElectricSparks(player, player->skincolor, false); - K_SpawnAmps(player, 20, player->mo); + // CONS_Printf("%d: %s gimme first blood\n", leveltime, player_names[player - players]); + player->pflags2 |= PF2_GIMMEFIRSTBLOOD; } else { - S_StartSound(player->mo, sfx_s23c); - player->startboost = 125; - - K_SpawnDriftBoostExplosion(player, 4); - K_SpawnDriftElectricSparks(player, SKINCOLOR_SILVER, false); - if (!G_TimeAttackStart()) - K_SpawnAmps(player, (K_InRaceDuel()) ? 20 : 20, player->mo); - - if (g_teamplay) - { - for (UINT8 j = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[j] || players[j].spectator || !players[j].mo || P_MobjWasRemoved(players[j].mo)) - continue; - if (!G_SameTeam(player, &players[j])) - continue; - if (player == &players[j]) - continue; - K_SpawnAmps(&players[j], 10, player->mo); - } - } + // CONS_Printf("%d: %s gimme start award\n", leveltime, player_names[player - players]); + player->pflags2 |= PF2_GIMMESTARTAWARDS; } + player->karthud[khud_splitcolor] = 0; + player->karthud[khud_splitposition] = 1; + player->karthud[khud_splitskin] = -1; + player->karthud[khud_splittime] = (INT32)(starttime - leveltime); + player->karthud[khud_splittimer] = 2*TICRATE; + player->karthud[khud_splitwin] = (rainbowstartavailable) ? 2 : 0; + } + + if (rainbowstartavailable == true && player->mo->hitlag == 0 && G_TimeAttackStart()) + { + S_StartSound(player->mo, sfx_s23c); + player->startboost = 125; + + K_SpawnDriftBoostExplosion(player, 4); + K_SpawnDriftElectricSparks(player, SKINCOLOR_SILVER, false); + rainbowstartavailable = false; }