diff --git a/src/d_netcmd.c b/src/d_netcmd.c index ba5560802..233252536 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -939,6 +939,7 @@ void D_RegisterClientCommands(void) // g_input.c for (i = 0; i < MAXSPLITSCREENPLAYERS; i++) { + CV_RegisterVar(&cv_kickstartaccel[i]); CV_RegisterVar(&cv_turnaxis[i]); CV_RegisterVar(&cv_moveaxis[i]); CV_RegisterVar(&cv_brakeaxis[i]); @@ -1627,6 +1628,8 @@ void SendWeaponPref(UINT8 n) buf[0] = 0; // Player option cvars that need to be synched go HERE + if (cv_kickstartaccel[n].value) + buf[0] |= 1; SendNetXCmdForPlayer(n, XD_WEAPONPREF, buf, 1); } @@ -1635,11 +1638,13 @@ static void Got_WeaponPref(UINT8 **cp,INT32 playernum) { UINT8 prefs = READUINT8(*cp); - (void)prefs; - (void)playernum; - - //players[playernum].pflags &= ~(PF_FLIPCAM); // Player option cvars that need to be synched go HERE + players[playernum].pflags &= ~(PF_KICKSTARTACCEL); + if (prefs & 1) + players[playernum].pflags |= PF_KICKSTARTACCEL; + + // SEE ALSO g_demo.c + demo_extradata[playernum] |= DXD_WEAPONPREF; } static void Got_PowerLevel(UINT8 **cp,INT32 playernum) diff --git a/src/d_player.h b/src/d_player.h index f2883eaa2..b055f6d9f 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -67,48 +67,45 @@ typedef enum // True if button down last tic. PF_ATTACKDOWN = 1<<7, - PF_SPINDOWN = 1<<8, - PF_JUMPDOWN = 1<<9, - PF_WPNDOWN = 1<<10, + PF_ACCELDOWN = 1<<8, + PF_BRAKEDOWN = 1<<9, + PF_WPNDOWN = 1<<10, // unused // Unmoving states PF_STASIS = 1<<11, // Player is not allowed to move - PF_JUMPSTASIS = 1<<12, // and that includes jumping. - PF_FULLSTASIS = PF_STASIS|PF_JUMPSTASIS, + PF_JUMPSTASIS = 1<<12, // unused // SRB2Kart: Spectator that wants to join PF_WANTSTOJOIN = 1<<13, // Character action status - PF_STARTJUMP = 1<<14, - PF_JUMPED = 1<<15, - PF_NOJUMPDAMAGE = 1<<16, - - PF_SPINNING = 1<<17, - PF_STARTDASH = 1<<18, - - PF_THOKKED = 1<<19, - PF_SHIELDABILITY = 1<<20, - PF_GLIDING = 1<<21, - PF_BOUNCING = 1<<22, + PF_STARTJUMP = 1<<14, // unused + PF_JUMPED = 1<<15, // unused + PF_NOJUMPDAMAGE = 1<<16, // unused + PF_SPINNING = 1<<17, // unused + PF_STARTDASH = 1<<18, // unused + PF_THOKKED = 1<<19, // unused + PF_SHIELDABILITY = 1<<20, // unused + PF_GLIDING = 1<<21, // unused + PF_BOUNCING = 1<<22, // unused // Sliding (usually in water) like Labyrinth/Oil Ocean PF_SLIDING = 1<<23, // NiGHTS stuff - PF_TRANSFERTOCLOSEST = 1<<24, - PF_DRILLING = 1<<25, + PF_TRANSFERTOCLOSEST = 1<<24, // unused + PF_DRILLING = 1<<25, // unused // Gametype-specific stuff - PF_GAMETYPEOVER = 1<<26, // Race time over, or H&S out-of-game - PF_TAGIT = 1<<27, // The player is it! For Tag Mode + PF_GAMETYPEOVER = 1<<26, // Race time over + PF_TAGIT = 1<<27, // unused /*** misc ***/ - PF_FORCESTRAFE = 1<<28, // Turning inputs are translated into strafing inputs - PF_CANCARRY = 1<<29, // Can carry another player? + PF_KICKSTARTACCEL = 1<<28, // Accessibility feature - is accelerate in kickstart mode? + PF_CANCARRY = 1<<29, // unused PF_HITFINISHLINE = 1<<30, // Already hit the finish line this tic - // up to 1<<31 is free + // up to 1<<31 is free, but try to hit unused stuff first } pflags_t; typedef enum @@ -450,6 +447,9 @@ typedef enum //} +// for kickstartaccel +#define ACCEL_KICKSTART 35 + // player_t struct for all respawn variables typedef struct respawnvars_s { @@ -700,6 +700,8 @@ typedef struct player_s UINT8 typing_timer; // Counts down while keystrokes are not emitted UINT8 typing_duration; // How long since resumed timer + UINT8 kickstartaccel; + #ifdef HWRENDER fixed_t fovadd; // adjust FOV for hw rendering #endif diff --git a/src/d_ticcmd.h b/src/d_ticcmd.h index 17c41cfbf..226c8f4d8 100644 --- a/src/d_ticcmd.h +++ b/src/d_ticcmd.h @@ -26,17 +26,17 @@ // Button/action code definitions. typedef enum { - BT_ACCELERATE = 1, // Accelerate - BT_DRIFT = 1<<2, // Drift (direction is cmd->turning) - BT_BRAKE = 1<<3, // Brake - BT_ATTACK = 1<<4, // Use Item - BT_FORWARD = 1<<5, // Aim Item Forward - BT_BACKWARD = 1<<6, // Aim Item Backward - BT_LOOKBACK = 1<<7, // Look Backward + BT_ACCELERATE = 1, // Accelerate + BT_DRIFT = 1<<2, // Drift (direction is cmd->turning) + BT_BRAKE = 1<<3, // Brake + BT_ATTACK = 1<<4, // Use Item + BT_FORWARD = 1<<5, // Aim Item Forward + BT_BACKWARD = 1<<6, // Aim Item Backward + BT_LOOKBACK = 1<<7, // Look Backward BT_EBRAKEMASK = (BT_ACCELERATE|BT_BRAKE), - // free: 1<<8 to 1<<12 + // free: 1<<9 to 1<<12 // Lua garbage BT_CUSTOM1 = 1<<13, diff --git a/src/dehacked.c b/src/dehacked.c index 5d77e61dc..fb3608849 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -10645,17 +10645,13 @@ static const char *const PLAYERFLAG_LIST[] = { // True if button down last tic. "ATTACKDOWN", - "SPINDOWN", - "JUMPDOWN", + "ACCELDOWN", + "BRAKEDOWN", "WPNDOWN", // Unmoving states "STASIS", // Player is not allowed to move "JUMPSTASIS", // and that includes jumping. - // (we don't include FULLSTASIS here I guess because it's just those two together...?) - - // Did you get a time-over? - "TIMEOVER", // SRB2Kart: spectator that wants to join "WANTSTOJOIN", @@ -10664,10 +10660,8 @@ static const char *const PLAYERFLAG_LIST[] = { "STARTJUMP", "JUMPED", "NOJUMPDAMAGE", - "SPINNING", "STARTDASH", - "THOKKED", "SHIELDABILITY", "GLIDING", @@ -10681,13 +10675,13 @@ static const char *const PLAYERFLAG_LIST[] = { "DRILLING", // Gametype-specific stuff - "GAMETYPEOVER", // Race time over, or H&S out-of-game - "TAGIT", // The player is it! For Tag Mode + "GAMETYPEOVER", // Race time over + "TAGIT", /*** misc ***/ - "FORCESTRAFE", // Translate turn inputs into strafe inputs + "FORCESTRAFE", // Accessibility feature - is accelerate in kickstart mode? + "CANCARRY", "HITFINISHLINE", // Already hit the finish line this tic - "FINISHED", NULL // stop loop here. }; @@ -12183,8 +12177,6 @@ static fixed_t find_const(const char **rword) free(word); return (1<p += 32; // ok (32 because there's both the skin and the colour) if (ziptic & DXD_PLAYSTATE && READUINT8(g->p) != DXD_PST_PLAYING) I_Error("Ghost is not a record attack ghost PLAYSTATE"); //@TODO lmao don't blow up like this + if (ziptic & DXD_WEAPONPREF) + g->p++; // ditto } else if (ziptic == DW_RNG) g->p += 4; // RNG seed @@ -1983,7 +1999,12 @@ void G_BeginRecording(void) if (playeringame[p]) { player = &players[p]; - WRITEUINT8(demo_p, p | (player->spectator ? DEMO_SPECTATOR : 0)); + i = p; + if (player->pflags & PF_KICKSTARTACCEL) + i |= DEMO_KICKSTART; + if (player->spectator) + i |= DEMO_SPECTATOR; + WRITEUINT8(demo_p, i); // Name memset(name, 0, 16); @@ -2903,6 +2924,12 @@ void G_DoPlayDemo(char *defdemoname) while (p != 0xFF) { + players[p].pflags &= ~PF_KICKSTARTACCEL; + if (p & DEMO_KICKSTART) + { + players[p].pflags |= PF_KICKSTARTACCEL; + p &= ~DEMO_KICKSTART; + } spectator = false; if (p & DEMO_SPECTATOR) { @@ -3194,7 +3221,7 @@ void G_AddGhost(char *defdemoname) return; } - if (READUINT8(p) != 0) + if ((READUINT8(p) & ~DEMO_KICKSTART) != 0) { CONS_Alert(CONS_NOTICE, M_GetText("Failed to add ghost %s: Invalid player slot.\n"), pdemoname); Z_Free(pdemoname); diff --git a/src/g_demo.h b/src/g_demo.h index b4039434e..03d75cf4b 100644 --- a/src/g_demo.h +++ b/src/g_demo.h @@ -110,16 +110,17 @@ typedef enum extern UINT8 demo_extradata[MAXPLAYERS]; extern UINT8 demo_writerng; -#define DXD_RESPAWN 0x01 // "respawn" command in console -#define DXD_SKIN 0x02 // skin changed -#define DXD_NAME 0x04 // name changed -#define DXD_COLOR 0x08 // color changed -#define DXD_PLAYSTATE 0x10 // state changed between playing, spectating, or not in-game -#define DXD_FOLLOWER 0x20 // follower was changed +#define DXD_RESPAWN 0x01 // "respawn" command in console +#define DXD_SKIN 0x02 // skin changed +#define DXD_NAME 0x04 // name changed +#define DXD_COLOR 0x08 // color changed +#define DXD_PLAYSTATE 0x10 // state changed between playing, spectating, or not in-game +#define DXD_FOLLOWER 0x20 // follower was changed +#define DXD_WEAPONPREF 0x40 // netsynced playsim settings were changed -#define DXD_PST_PLAYING 0x01 +#define DXD_PST_PLAYING 0x01 #define DXD_PST_SPECTATING 0x02 -#define DXD_PST_LEFT 0x03 +#define DXD_PST_LEFT 0x03 // Record/playback tics void G_ReadDemoExtraData(void); diff --git a/src/g_game.c b/src/g_game.c index c6c831b76..9a766dc42 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -342,10 +342,11 @@ INT16 prevmap, nextmap; static UINT8 *savebuffer; -void SendWeaponPref(void); -void SendWeaponPref2(void); -void SendWeaponPref3(void); -void SendWeaponPref4(void); +static void kickstartaccel_OnChange(void); +static void kickstartaccel2_OnChange(void); +static void kickstartaccel3_OnChange(void); +static void kickstartaccel4_OnChange(void); +void SendWeaponPref(UINT8 n); static CV_PossibleValue_t joyaxis_cons_t[] = {{0, "None"}, {1, "X-Axis"}, {2, "Y-Axis"}, {-1, "X-Axis-"}, {-2, "Y-Axis-"}, @@ -405,6 +406,13 @@ consvar_t cv_resetspecialmusic = CVAR_INIT ("resetspecialmusic", "Yes", CV_SAVE, consvar_t cv_resume = CVAR_INIT ("resume", "Yes", CV_SAVE, CV_YesNo, NULL); +consvar_t cv_kickstartaccel[MAXSPLITSCREENPLAYERS] = { + CVAR_INIT ("kickstartaccel", "Off", CV_SAVE|CV_CALL, CV_OnOff, kickstartaccel_OnChange), + CVAR_INIT ("kickstartaccel2", "Off", CV_SAVE|CV_CALL, CV_OnOff, kickstartaccel2_OnChange), + CVAR_INIT ("kickstartaccel3", "Off", CV_SAVE|CV_CALL, CV_OnOff, kickstartaccel3_OnChange), + CVAR_INIT ("kickstartaccel4", "Off", CV_SAVE|CV_CALL, CV_OnOff, kickstartaccel4_OnChange) +}; + consvar_t cv_turnaxis[MAXSPLITSCREENPLAYERS] = { CVAR_INIT ("joyaxis_turn", "X-Axis", CV_SAVE, joyaxis_cons_t, NULL), CVAR_INIT ("joyaxis2_turn", "X-Axis", CV_SAVE, joyaxis_cons_t, NULL), @@ -1003,7 +1011,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) { // forward with key or button // SRB2kart - we use an accel/brake instead of forward/backward. axis = PlayerJoyAxis(ssplayer, AXISMOVE); - if (PlayerInputDown(ssplayer, gc_accelerate) || (gamepadjoystickmove && axis > 0) || player->kartstuff[k_sneakertimer]) + if (PlayerInputDown(ssplayer, gc_accelerate) || (gamepadjoystickmove && axis > 0)) { cmd->buttons |= BT_ACCELERATE; forward = MAXPLMOVE; // 50 @@ -1184,6 +1192,26 @@ ticcmd_t *G_MoveTiccmd(ticcmd_t* dest, const ticcmd_t* src, const size_t n) return dest; } +static void kickstartaccel_OnChange(void) +{ + SendWeaponPref(0); +} + +static void kickstartaccel2_OnChange(void) +{ + SendWeaponPref(1); +} + +static void kickstartaccel3_OnChange(void) +{ + SendWeaponPref(2); +} + +static void kickstartaccel4_OnChange(void) +{ + SendWeaponPref(3); +} + // // G_DoLoadLevel // @@ -2108,6 +2136,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) boolean eliminated; UINT16 nocontrol; INT32 khudfault; + INT32 kickstartaccel; score = players[player].score; marescore = players[player].marescore; @@ -2123,7 +2152,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) splitscreenindex = players[player].splitscreenindex; spectator = players[player].spectator; - pflags = (players[player].pflags & (PF_WANTSTOJOIN|PF_GAMETYPEOVER|PF_FAULT)); + pflags = (players[player].pflags & (PF_WANTSTOJOIN|PF_GAMETYPEOVER|PF_FAULT|PF_KICKSTARTACCEL)); playerangleturn = players[player].angleturn; // As long as we're not in multiplayer, carry over cheatcodes from map to map @@ -2177,6 +2206,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) spheres = 0; eliminated = false; wanted = 0; + kickstartaccel = 0; } else { @@ -2205,6 +2235,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) spheres = players[player].spheres; eliminated = players[player].eliminated; wanted = players[player].kartstuff[k_wanted]; + kickstartaccel = players[player].kickstartaccel; } if (!betweenmaps) @@ -2278,6 +2309,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) p->kartstuff[k_lastdraft] = -1; p->karthud[khud_fault] = khudfault; p->powers[pw_nocontrol] = nocontrol; + p->kickstartaccel = kickstartaccel; memcpy(&p->respawn, &respawn, sizeof (p->respawn)); @@ -2292,9 +2324,9 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) // Don't do anything immediately - p->pflags |= PF_SPINDOWN; + p->pflags |= PF_BRAKEDOWN; p->pflags |= PF_ATTACKDOWN; - p->pflags |= PF_JUMPDOWN; + p->pflags |= PF_ACCELDOWN; p->playerstate = PST_LIVE; p->panim = PA_STILL; // standing animation @@ -4446,7 +4478,7 @@ void G_InitNew(UINT8 pencoremode, const char *mapname, boolean resetplayer, bool memset(&players[i].respawn, 0, sizeof (players[i].respawn)); // The latter two should clear by themselves, but just in case - players[i].pflags &= ~(PF_GAMETYPEOVER|PF_FULLSTASIS|PF_FAULT); + players[i].pflags &= ~(PF_GAMETYPEOVER|PF_STASIS|PF_FAULT); // Clear cheatcodes too, just in case. players[i].pflags &= ~(PF_GODMODE|PF_NOCLIP|PF_INVIS); diff --git a/src/g_game.h b/src/g_game.h index 89156b82f..28321adc5 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -57,6 +57,7 @@ extern consvar_t cv_pauseifunfocused; extern consvar_t cv_invertmouse; +extern consvar_t cv_kickstartaccel[MAXSPLITSCREENPLAYERS]; extern consvar_t cv_turnaxis[MAXSPLITSCREENPLAYERS]; extern consvar_t cv_moveaxis[MAXSPLITSCREENPLAYERS]; extern consvar_t cv_brakeaxis[MAXSPLITSCREENPLAYERS]; diff --git a/src/k_hud.c b/src/k_hud.c index a26e29573..b40c16ae0 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -2200,6 +2200,63 @@ static void K_drawKartLapsAndRings(void) #undef RINGANIM_FLIPFRAME +static void K_drawKartAccessibilityIcons(INT32 fx) +{ + INT32 fy = LAPS_Y-25; + UINT8 col = 0, i, wid, fil; + INT32 splitflags = V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_SPLITSCREEN; + //INT32 step = 1; -- if there's ever more than one accessibility icon + + fx += LAPS_X; + + if (r_splitscreen < 2) // adjust to speedometer height + { + if (gametype == GT_BATTLE) + fy -= 4; + } + else + { + fy += 4; + if (!(stplyr == &players[displayplayers[0]] || stplyr == &players[displayplayers[2]])) // If we are not P1 or P3... + { + splitflags ^= (V_SNAPTOLEFT|V_SNAPTORIGHT); + fx = (BASEVIDWIDTH/2) - (fx + 10); + //step = -step; + } + } + + if (stplyr->pflags & PF_KICKSTARTACCEL) // just KICKSTARTACCEL right now, maybe more later + { + fil = 7-(stplyr->kickstartaccel*7)/ACCEL_KICKSTART; + i = 7; + + V_DrawFill(fx+4, fy-1, 2, 1, 31|V_SLIDEIN|splitflags); + V_DrawFill(fx, (fy-1)+8, 10, 1, 31|V_SLIDEIN|splitflags); + + while (i--) + { + wid = (i/2)+1; + V_DrawFill(fx+4-wid, fy+i, 2+(wid*2), 1, 31|V_SLIDEIN|splitflags); + if (fil) + { + if (i < fil) + col = 23; + else if (i == fil) + col = 3; + else + col = 5 + (i-fil)*2; + } + else if ((leveltime % 7) == i) + col = 0; + else + col = 3; + V_DrawFill(fx+5-wid, fy+i, (wid*2), 1, col|V_SLIDEIN|splitflags); + } + + //fx += step*12; + } +} + static void K_drawKartSpeedometer(void) { static fixed_t convSpeed; @@ -2249,6 +2306,8 @@ static void K_drawKartSpeedometer(void) V_DrawScaledPatch(LAPS_X+13, LAPS_Y-25 + battleoffset, V_HUDTRANS|V_SLIDEIN|splitflags, kp_facenum[numbers[1]]); V_DrawScaledPatch(LAPS_X+19, LAPS_Y-25 + battleoffset, V_HUDTRANS|V_SLIDEIN|splitflags, kp_facenum[numbers[2]]); V_DrawScaledPatch(LAPS_X+29, LAPS_Y-25 + battleoffset, V_HUDTRANS|V_SLIDEIN|splitflags, kp_speedometerlabel[labeln]); + + K_drawKartAccessibilityIcons(56); } static void K_drawBlueSphereMeter(void) @@ -4174,13 +4233,6 @@ void K_drawKartHUD(void) if (!stplyr->spectator && !demo.freecam) // Bottom of the screen elements, don't need in spectate mode { - // Draw the speedometer - if (cv_kartspeedometer.value && !r_splitscreen) - { - if (LUA_HudEnabled(hud_speedometer)) - K_drawKartSpeedometer(); - } - if (demo.title) // Draw title logo instead in demo.titles { INT32 x = BASEVIDWIDTH - 32, y = 128, offs; @@ -4231,6 +4283,16 @@ void K_drawKartHUD(void) K_drawKartBumpersOrKarma(); } + // Draw the speedometer and/or accessibility icons + if (cv_kartspeedometer.value && !r_splitscreen && (LUA_HudEnabled(hud_speedometer))) + { + K_drawKartSpeedometer(); + } + else + { + K_drawKartAccessibilityIcons((r_splitscreen > 1) ? 0 : 8); + } + if (gametyperules & GTR_SPHERES) { K_drawBlueSphereMeter(); diff --git a/src/k_kart.c b/src/k_kart.c index 90649b566..6621042d8 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -1902,19 +1902,19 @@ void K_KartMoveAnimation(player_t *player) const boolean onground = P_IsObjectOnGround(player->mo); - ticcmd_t *cmd = &player->cmd; - const boolean spinningwheels = (((cmd->buttons & BT_ACCELERATE) == BT_ACCELERATE) || (onground && player->speed > 0)); - const boolean lookback = ((cmd->buttons & BT_LOOKBACK) == BT_LOOKBACK); + UINT16 buttons = K_GetKartButtons(player); + const boolean spinningwheels = (((buttons & BT_ACCELERATE) == BT_ACCELERATE) || (onground && player->speed > 0)); + const boolean lookback = ((buttons & BT_LOOKBACK) == BT_LOOKBACK); SINT8 turndir = 0; SINT8 destGlanceDir = 0; SINT8 drift = player->kartstuff[k_drift]; - if (cmd->turning < -minturn) + if (player->cmd.turning < -minturn) { turndir = -1; } - else if (cmd->turning > minturn) + else if (player->cmd.turning > minturn) { turndir = 1; } @@ -2583,6 +2583,19 @@ UINT16 K_GetKartFlashing(player_t *player) return tics; } +boolean K_KartKickstart(player_t *player) +{ + return ((player->pflags & PF_KICKSTARTACCEL) + && (!K_PlayerUsesBotMovement(player)) + && (player->kickstartaccel >= ACCEL_KICKSTART)); +} + +UINT16 K_GetKartButtons(player_t *player) +{ + return (player->cmd.buttons | + (K_KartKickstart(player) ? BT_ACCELERATE : 0)); +} + SINT8 K_GetForwardMove(player_t *player) { SINT8 forwardmove = player->cmd.forwardmove; @@ -2602,6 +2615,13 @@ SINT8 K_GetForwardMove(player_t *player) return 0; } + if (K_KartKickstart(player)) // unlike the brute forward of sneakers, allow for backwards easing here + { + forwardmove += MAXPLMOVE; + if (forwardmove > MAXPLMOVE) + forwardmove = MAXPLMOVE; + } + return forwardmove; } @@ -5632,7 +5652,7 @@ player_t *K_FindJawzTarget(mobj_t *actor, player_t *source) } // Engine Sounds. -static void K_UpdateEngineSounds(player_t *player, ticcmd_t *cmd) +static void K_UpdateEngineSounds(player_t *player) { const INT32 numsnds = 13; @@ -5641,6 +5661,8 @@ static void K_UpdateEngineSounds(player_t *player, ticcmd_t *cmd) const UINT8 dampenval = 48; // 255 * 48 = close enough to FRACUNIT/6 + const UINT16 buttons = K_GetKartButtons(player); + INT32 class, s, w; // engine class number UINT8 volume = 255; @@ -5681,17 +5703,17 @@ static void K_UpdateEngineSounds(player_t *player, ticcmd_t *cmd) if (player->respawn.state == RESPAWNST_DROP) // Dropdashing { // Dropdashing - targetsnd = ((cmd->buttons & BT_ACCELERATE) ? 12 : 0); + targetsnd = ((buttons & BT_ACCELERATE) ? 12 : 0); } else if (K_PlayerEBrake(player) == true) { // Spindashing - targetsnd = ((cmd->buttons & BT_DRIFT) ? 12 : 0); + targetsnd = ((buttons & BT_DRIFT) ? 12 : 0); } else { // Average out the value of forwardmove and the speed that you're moving at. - targetsnd = (((6 * cmd->forwardmove) / 25) + ((player->speed / mapobjectscale) / 5)) / 2; + targetsnd = (((6 * K_GetForwardMove(player)) / 25) + ((player->speed / mapobjectscale) / 5)) / 2; } if (targetsnd < 0) { targetsnd = 0; } @@ -5989,7 +6011,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) { K_UpdateOffroad(player); K_UpdateDraft(player); - K_UpdateEngineSounds(player, cmd); // Thanks, VAda! + K_UpdateEngineSounds(player); // Thanks, VAda! // update boost angle if not spun out if (!player->kartstuff[k_spinouttimer] && !player->kartstuff[k_wipeoutslow]) @@ -6469,7 +6491,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) if (cmd->buttons & BT_DRIFT) { // Only allow drifting while NOT trying to do an spindash input. - if ((cmd->buttons & BT_EBRAKEMASK) != BT_EBRAKEMASK) + if ((K_GetKartButtons(player) & BT_EBRAKEMASK) != BT_EBRAKEMASK) { player->driftInput = true; } @@ -7022,7 +7044,7 @@ INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue) currentSpeed = R_PointToDist2(0, 0, player->mo->momx, player->mo->momy); if ((currentSpeed <= 0) // Not moving - && ((player->cmd.buttons & BT_EBRAKEMASK) != BT_EBRAKEMASK) // not e-braking + && ((K_GetKartButtons(player) & BT_EBRAKEMASK) != BT_EBRAKEMASK) // not e-braking && (player->respawn.state == RESPAWNST_NONE)) // Not respawning { return 0; @@ -7126,6 +7148,8 @@ static void K_KartDrift(player_t *player, boolean onground) const INT32 dstwo = dsone*2; const INT32 dsthree = dstwo*2; + const UINT16 buttons = K_GetKartButtons(player); + // Drifting is actually straffing + automatic turning. // Holding the Jump button will enable drifting. // (This comment is extremely funny) @@ -7332,8 +7356,8 @@ static void K_KartDrift(player_t *player, boolean onground) K_SpawnAIZDust(player); if (player->kartstuff[k_drift] - && ((player->cmd.buttons & BT_BRAKE) - || !(player->cmd.buttons & BT_ACCELERATE)) + && ((buttons & BT_BRAKE) + || !(buttons & BT_ACCELERATE)) && P_IsObjectOnGround(player->mo)) { if (!player->kartstuff[k_brakedrift]) @@ -7507,7 +7531,7 @@ static INT32 K_FlameShieldMax(player_t *player) boolean K_PlayerEBrake(player_t *player) { - return (player->cmd.buttons & BT_EBRAKEMASK) == BT_EBRAKEMASK + return (K_GetKartButtons(player) & BT_EBRAKEMASK) == BT_EBRAKEMASK && P_IsObjectOnGround(player->mo) == true && player->kartstuff[k_drift] == 0 && player->kartstuff[k_spinouttimer] == 0 @@ -7690,8 +7714,6 @@ static void K_AirFailsafe(player_t *player) const fixed_t maxSpeed = 6*player->mo->scale; const fixed_t thrustSpeed = 6*player->mo->scale; // 10*player->mo->scale - ticcmd_t *cmd = &player->cmd; - if (player->speed > maxSpeed // Above the max speed that you're allowed to use this technique. || player->respawn.state != RESPAWNST_NONE) // Respawning, you don't need this AND drop dash :V { @@ -7699,7 +7721,7 @@ static void K_AirFailsafe(player_t *player) return; } - if ((cmd->buttons & BT_ACCELERATE) || K_GetForwardMove(player) != 0) + if ((K_GetKartButtons(player) & BT_ACCELERATE) || K_GetForwardMove(player) != 0) { // Queue up later player->airFailsafe = true; @@ -7741,7 +7763,7 @@ void K_AdjustPlayerFriction(player_t *player) { player->mo->friction -= 1024; } - else if (player->speed > 0 && cmd->forwardmove < 0) + else if (player->speed > 0 && K_GetForwardMove(player) < 0) { player->mo->friction -= 512; } diff --git a/src/k_kart.h b/src/k_kart.h index 0e3aa0ff4..c91bba806 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -91,6 +91,8 @@ fixed_t K_GetKartSpeedFromStat(UINT8 kartspeed); fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower); fixed_t K_GetKartAccel(player_t *player); UINT16 K_GetKartFlashing(player_t *player); +boolean K_KartKickstart(player_t *player); +UINT16 K_GetKartButtons(player_t *player); SINT8 K_GetForwardMove(player_t *player); fixed_t K_3dKartMovement(player_t *player); boolean K_PlayerEBrake(player_t *player); diff --git a/src/k_respawn.c b/src/k_respawn.c index 71f5ccd0e..6018c2e54 100644 --- a/src/k_respawn.c +++ b/src/k_respawn.c @@ -654,7 +654,7 @@ static void K_DropDashWait(player_t *player) --------------------------------------------------*/ static void K_HandleDropDash(player_t *player) { - ticcmd_t *cmd = &player->cmd; + const UINT16 buttons = K_GetKartButtons(player); if (player->kartstuff[k_growshrinktimer] < 0) { @@ -679,7 +679,7 @@ static void K_HandleDropDash(player_t *player) // The old behavior was stupid and prone to accidental usage. // Let's rip off Mania instead, and turn this into a Drop Dash! - if ((cmd->buttons & BT_ACCELERATE) && !player->kartstuff[k_spinouttimer]) // Since we're letting players spin out on respawn, don't let them charge a dropdash in this state. (It wouldn't work anyway) + if ((buttons & BT_ACCELERATE) && !player->kartstuff[k_spinouttimer]) // Since we're letting players spin out on respawn, don't let them charge a dropdash in this state. (It wouldn't work anyway) { player->respawn.dropdash++; } @@ -704,7 +704,7 @@ static void K_HandleDropDash(player_t *player) } else { - if ((cmd->buttons & BT_ACCELERATE) && (player->respawn.dropdash >= TICRATE/4)) + if ((buttons & BT_ACCELERATE) && (player->respawn.dropdash >= TICRATE/4)) { S_StartSound(player->mo, sfx_s23c); player->kartstuff[k_startboost] = 50; diff --git a/src/lua_baselib.c b/src/lua_baselib.c index c400f01c5..035d930de 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -1491,17 +1491,6 @@ static int lib_pDoSpring(lua_State *L) // P_INTER //////////// -static int lib_pRemoveShield(lua_State *L) -{ - player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); - NOHUD - INLEVEL - if (!player) - return LUA_ErrInvalid(L, "player_t"); - P_RemoveShield(player); - return 0; -} - static int lib_pDamageMobj(lua_State *L) { mobj_t *target = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)), *inflictor = NULL, *source = NULL; @@ -3803,7 +3792,6 @@ static luaL_Reg lib[] = { {"P_DoSpring",lib_pDoSpring}, // p_inter - {"P_RemoveShield",lib_pRemoveShield}, {"P_DamageMobj",lib_pDamageMobj}, {"P_KillMobj",lib_pKillMobj}, {"P_PlayerRingBurst",lib_pPlayerRingBurst}, diff --git a/src/p_inter.c b/src/p_inter.c index 211250cb5..541d1a890 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1803,35 +1803,6 @@ static boolean P_KillPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, return true; } -void P_RemoveShield(player_t *player) -{ - if (player->powers[pw_shield] & SH_FORCE) - { // Multi-hit - if (player->powers[pw_shield] & SH_FORCEHP) - player->powers[pw_shield]--; - else - player->powers[pw_shield] &= SH_STACK; - } - else if (player->powers[pw_shield] & SH_NOSTACK) - { // First layer shields - if ((player->powers[pw_shield] & SH_NOSTACK) == SH_ARMAGEDDON) // Give them what's coming to them! - { - player->pflags |= PF_JUMPDOWN; - } - else - player->powers[pw_shield] &= SH_STACK; - } - else - { // Second layer shields - if (((player->powers[pw_shield] & SH_STACK) == SH_FIREFLOWER) && !player->powers[pw_super]) - { - player->mo->color = player->skincolor; - G_GhostAddColor((INT32) (player - players), GHC_NORMAL); - } - player->powers[pw_shield] = SH_NONE; - } -} - /** Damages an object, which may or may not be a player. * For melee attacks, source and inflictor are the same. * diff --git a/src/p_local.h b/src/p_local.h index 5fc1ab956..4182d0658 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -486,7 +486,6 @@ typedef struct BasicFF_s void P_ForceFeed(const player_t *player, INT32 attack, INT32 fade, tic_t duration, INT32 period); void P_ForceConstant(const BasicFF_t *FFInfo); void P_RampConstant(const BasicFF_t *FFInfo, INT32 Start, INT32 End); -void P_RemoveShield(player_t *player); void P_SpecialStageDamage(player_t *player, mobj_t *inflictor, mobj_t *source); boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype); void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damagetype); diff --git a/src/p_mobj.c b/src/p_mobj.c index 25a505821..6a58fc907 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6839,7 +6839,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) if ((!mobj->target || !mobj->target->health || !mobj->target->player || !P_IsObjectOnGround(mobj->target)) || !mobj->target->player->kartstuff[k_drift] || !mobj->target->player->kartstuff[k_brakedrift] || !((mobj->target->player->cmd.buttons & BT_BRAKE) - || !(mobj->target->player->cmd.buttons & BT_ACCELERATE))) // Letting go of accel functions about the same as brake-drifting + || (K_GetKartButtons(mobj->target->player) & BT_ACCELERATE))) // Letting go of accel functions about the same as brake-drifting { P_RemoveMobj(mobj); return false; diff --git a/src/p_saveg.c b/src/p_saveg.c index 367f21439..8f5a1c709 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -280,6 +280,8 @@ static void P_NetArchivePlayers(void) WRITEUINT8(save_p, players[i].typing_timer); WRITEUINT8(save_p, players[i].typing_duration); + WRITEUINT8(save_p, players[i].kickstartaccel); + // respawnvars_t WRITEUINT8(save_p, players[i].respawn.state); WRITEUINT32(save_p, K_GetWaypointHeapIndex(players[i].respawn.wp)); @@ -489,6 +491,8 @@ static void P_NetUnArchivePlayers(void) players[i].typing_timer = READUINT8(save_p); players[i].typing_duration = READUINT8(save_p); + players[i].kickstartaccel = READUINT8(save_p); + // respawnvars_t players[i].respawn.state = READUINT8(save_p); players[i].respawn.wp = (waypoint_t *)(size_t)READUINT32(save_p); diff --git a/src/p_spec.c b/src/p_spec.c index d0a8f085c..98ae6faf9 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -8763,12 +8763,8 @@ void T_Pusher(pusher_t *p) { if (p->slider && thing->player) { - pflags_t jumped = (thing->player->pflags & (PF_JUMPED|PF_NOJUMPDAMAGE)); P_ResetPlayer (thing->player); - if (jumped) - thing->player->pflags |= jumped; - thing->player->pflags |= PF_SLIDING; thing->angle = R_PointToAngle2 (0, 0, xspeed<<(FRACBITS-PUSH_FACTOR), yspeed<<(FRACBITS-PUSH_FACTOR)); diff --git a/src/p_user.c b/src/p_user.c index 912ce2f2a..7b79d5627 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -4324,6 +4324,19 @@ void P_PlayerThink(player_t *player) player->kartstuff[k_throwdir] = 0; } + // Accessibility - kickstart your acceleration + if (!(player->pflags & PF_KICKSTARTACCEL)) + player->kickstartaccel = 0; + else if (cmd->buttons & BT_ACCELERATE) + { + if (!player->exiting && !(player->pflags & PF_ACCELDOWN)) + player->kickstartaccel = 0; + else if (player->kickstartaccel < ACCEL_KICKSTART) + player->kickstartaccel++; + } + else if (player->kickstartaccel < ACCEL_KICKSTART) + player->kickstartaccel = 0; + #ifdef PARANOIA if (player->playerstate == PST_REBORN) I_Error("player %s is in PST_REBORN\n", sizeu1(playeri)); @@ -4501,10 +4514,10 @@ void P_PlayerThink(player_t *player) player->mo->movefactor = FRACUNIT; // We're not going to do any more with this, so let's change it back for the next frame. - // Unset statis flags after moving. + // Unset statis flag after moving. // In other words, if you manually set stasis via code, // it lasts for one tic. - player->pflags &= ~PF_FULLSTASIS; + player->pflags &= ~PF_STASIS; if (player->onconveyor == 1) player->onconveyor = 3; @@ -4550,11 +4563,16 @@ void P_PlayerThink(player_t *player) } #endif - // check for use - if (cmd->buttons & BT_BRAKE) - player->pflags |= PF_SPINDOWN; + // check for buttons + if (cmd->buttons & BT_ACCELERATE) + player->pflags |= PF_ACCELDOWN; else - player->pflags &= ~PF_SPINDOWN; + player->pflags &= ~PF_ACCELDOWN; + + if (cmd->buttons & BT_BRAKE) + player->pflags |= PF_BRAKEDOWN; + else + player->pflags &= ~PF_BRAKEDOWN; // Counters, time dependent power ups. // Time Bonus & Ring Bonus count settings