diff --git a/src/cvars.cpp b/src/cvars.cpp index 5eb4c6a0b..85085e147 100644 --- a/src/cvars.cpp +++ b/src/cvars.cpp @@ -975,6 +975,7 @@ consvar_t cv_dummymenuplayer = MenuDummy("dummymenuplayer", "P1").onchange(Dummy consvar_t cv_dummyprofileautoroulette = MenuDummy("dummyprofileautoroulette", "Off").on_off(); consvar_t cv_dummyprofilefov = MenuDummy("dummyprofilefov", "100").min_max(70, 110); consvar_t cv_dummyprofilelitesteer = MenuDummy("dummyprofilelitesteer", "Off").on_off(); +consvar_t cv_dummyprofileautoring = MenuDummy("dummyprofileautoring", "Off").on_off(); consvar_t cv_dummyprofilekickstart = MenuDummy("dummyprofilekickstart", "Off").on_off(); consvar_t cv_dummyprofilename = MenuDummy("dummyprofilename", ""); consvar_t cv_dummyprofileplayername = MenuDummy("dummyprofileplayername", ""); @@ -1087,6 +1088,13 @@ consvar_t cv_litesteer[MAXSPLITSCREENPLAYERS] = { Player("litesteer4", "Off").on_off().onchange(weaponPrefChange4), }; +consvar_t cv_autoring[MAXSPLITSCREENPLAYERS] = { + Player("autoring", "Off").on_off().onchange(weaponPrefChange), + Player("autoring2", "Off").on_off().onchange(weaponPrefChange2), + Player("autoring3", "Off").on_off().onchange(weaponPrefChange3), + Player("autoring4", "Off").on_off().onchange(weaponPrefChange4), +}; + consvar_t cv_cam_dist[MAXSPLITSCREENPLAYERS] = { Player("cam_dist", "190").floating_point(), Player("cam2_dist", "190").floating_point(), diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 5853e7936..d887aaf73 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -1258,6 +1258,7 @@ enum { WP_SHRINKME = 1<<1, WP_AUTOROULETTE = 1<<2, WP_ANALOGSTICK = 1<<3, + WP_AUTORING = 1<<4, }; void WeaponPref_Send(UINT8 ssplayer) @@ -1276,6 +1277,9 @@ void WeaponPref_Send(UINT8 ssplayer) if (gamecontrolflags[ssplayer] & GCF_ANALOGSTICK) prefs |= WP_ANALOGSTICK; + if (cv_autoring[ssplayer].value) + prefs |= WP_AUTORING; + UINT8 buf[2]; buf[0] = prefs; buf[1] = cv_mindelay.value; @@ -1301,6 +1305,9 @@ void WeaponPref_Save(UINT8 **cp, INT32 playernum) if (player->pflags & PF_ANALOGSTICK) prefs |= WP_ANALOGSTICK; + if (player->pflags & PF_AUTORING) + prefs |= WP_AUTORING; + WRITEUINT8(*cp, prefs); } @@ -1311,7 +1318,7 @@ size_t WeaponPref_Parse(const UINT8 *bufstart, INT32 playernum) UINT8 prefs = READUINT8(p); - player->pflags &= ~(PF_KICKSTARTACCEL|PF_SHRINKME|PF_AUTOROULETTE); + player->pflags &= ~(PF_KICKSTARTACCEL|PF_SHRINKME|PF_AUTOROULETTE|PF_AUTORING); if (prefs & WP_KICKSTARTACCEL) player->pflags |= PF_KICKSTARTACCEL; @@ -1327,6 +1334,9 @@ size_t WeaponPref_Parse(const UINT8 *bufstart, INT32 playernum) else player->pflags &= ~PF_ANALOGSTICK; + if (prefs & WP_AUTORING) + player->pflags |= PF_AUTORING; + if (leveltime < 2) { // BAD HACK: No other place I tried to slot this in diff --git a/src/d_player.h b/src/d_player.h index c17b8d48d..be2e07ee1 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -109,7 +109,7 @@ typedef enum PF_TRUSTWAYPOINTS = 1<<15, // Do not activate lap cheat prevention next time finish line distance is updated PF_FREEZEWAYPOINTS = 1<<16, // Skip the next waypoint/finish line distance update - //1<<17 free, was previously itemflags stuff + PF_AUTORING = 1<<17, // Accessibility: Non-deterministic item box, no manual stop. PF_DRIFTINPUT = 1<<18, // Drifting! PF_GETSPARKS = 1<<19, // Can get sparks @@ -955,6 +955,7 @@ struct player_t UINT8 typing_duration; // How long since resumed timer UINT8 kickstartaccel; + boolean autoring; // did we autoring this tic? UINT8 stairjank; UINT8 topdriftheld; diff --git a/src/g_game.c b/src/g_game.c index c9fdfc91f..04daab555 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2251,7 +2251,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) totalring = players[player].totalring; xtralife = players[player].xtralife; - pflags = (players[player].pflags & (PF_WANTSTOJOIN|PF_KICKSTARTACCEL|PF_SHRINKME|PF_SHRINKACTIVE|PF_AUTOROULETTE|PF_ANALOGSTICK)); + pflags = (players[player].pflags & (PF_WANTSTOJOIN|PF_KICKSTARTACCEL|PF_SHRINKME|PF_SHRINKACTIVE|PF_AUTOROULETTE|PF_ANALOGSTICK|PF_AUTORING)); // SRB2kart memcpy(&itemRoulette, &players[player].itemRoulette, sizeof (itemRoulette)); diff --git a/src/g_game.h b/src/g_game.h index 335294950..ff49c49b4 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -99,6 +99,7 @@ extern consvar_t cv_pauseifunfocused; extern consvar_t cv_kickstartaccel[MAXSPLITSCREENPLAYERS]; extern consvar_t cv_autoroulette[MAXSPLITSCREENPLAYERS]; extern consvar_t cv_litesteer[MAXSPLITSCREENPLAYERS]; +extern consvar_t cv_autoring[MAXSPLITSCREENPLAYERS]; extern consvar_t cv_shrinkme[MAXSPLITSCREENPLAYERS]; extern consvar_t cv_deadzone[MAXSPLITSCREENPLAYERS]; diff --git a/src/k_hud.cpp b/src/k_hud.cpp index 4aa19ac05..cc03a30e7 100644 --- a/src/k_hud.cpp +++ b/src/k_hud.cpp @@ -212,6 +212,7 @@ static patch_t *kp_bossret[4]; static patch_t *kp_trickcool[2]; patch_t *kp_autoroulette; +patch_t *kp_autoring; patch_t *kp_capsuletarget_arrow[2][2]; patch_t *kp_capsuletarget_icon[2]; @@ -781,6 +782,7 @@ void K_LoadKartHUDGraphics(void) HU_UpdatePatch(&kp_trickcool[1], "K_COOL2"); HU_UpdatePatch(&kp_autoroulette, "A11YITEM"); + HU_UpdatePatch(&kp_autoring, "A11YRING"); sprintf(buffer, "K_BOSB0x"); for (i = 0; i < 8; i++) @@ -3250,6 +3252,19 @@ static void K_drawKartAccessibilityIcons(boolean gametypeinfoshown, INT32 fx) else fx += 12 + 1; } + + if (stplyr->pflags & PF_AUTORING) + { + if (mirror) + fx -= 14; + + V_DrawScaledPatch(fx, fy-1, V_SLIDEIN|splitflags, kp_autoring); + + if (mirror) + fx--; + else + fx += 14 + 1; + } } static void K_drawKartSpeedometer(boolean gametypeinfoshown) diff --git a/src/k_hud.h b/src/k_hud.h index a4e92c728..07cea4774 100644 --- a/src/k_hud.h +++ b/src/k_hud.h @@ -78,6 +78,7 @@ extern patch_t *kp_spraycantarget_far[2][6]; extern patch_t *kp_spraycantarget_near[2][6]; extern patch_t *kp_autoroulette; +extern patch_t *kp_autoring; extern patch_t *kp_button_a[2][2]; extern patch_t *kp_button_b[2][2]; diff --git a/src/k_kart.c b/src/k_kart.c index 9c71770ba..33fc20003 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -12606,7 +12606,28 @@ void K_MoveKartPlayer(player_t *player, boolean onground) // Ring boosting if (player->itemflags & IF_USERINGS) { - if ((cmd->buttons & BT_ATTACK) && !player->ringdelay && player->rings > 0) + // Auto-Ring + boolean autoring; + if ( + player->pflags & PF_AUTORING + && leveltime > starttime + && !(cmd->buttons & BT_BRAKE) + && K_GetKartButtons(player) + && P_IsObjectOnGround(player->mo) + && ( + player->rings > 18 + && FixedDiv(player->speed * 100, K_GetKartSpeed(player, false, true)) < 100*FRACUNIT + || player->rings > 9 + && FixedDiv(player->speed * 100, K_GetKartSpeed(player, false, true)) < 85*FRACUNIT + ||player->rings > 3 + && FixedDiv(player->speed * 100, K_GetKartSpeed(player, false, true)) < 35*FRACUNIT + ) + ) + player->autoring = true; + else + player->autoring = false; + + if (((cmd->buttons & BT_ATTACK) || player->autoring) && !player->ringdelay && player->rings > 0) { mobj_t *ring = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_RING); P_SetMobjState(ring, S_FASTRING1); @@ -12629,8 +12650,12 @@ void K_MoveKartPlayer(player_t *player, boolean onground) ring->shadowscale = 0; P_SetTarget(&ring->target, player->mo); // user player->rings--; - player->ringdelay = 3; + if (player->autoring && !(cmd->buttons & BT_ATTACK)) + player->ringdelay = 6; + else + player->ringdelay = 3; } + } // Other items else diff --git a/src/k_menu.h b/src/k_menu.h index feb465404..643170b62 100644 --- a/src/k_menu.h +++ b/src/k_menu.h @@ -1124,6 +1124,7 @@ extern consvar_t cv_dummyprofileplayername; extern consvar_t cv_dummyprofilekickstart; extern consvar_t cv_dummyprofileautoroulette; extern consvar_t cv_dummyprofilelitesteer; +extern consvar_t cv_dummyprofileautoring; extern consvar_t cv_dummyprofilerumble; extern consvar_t cv_dummyprofilefov; diff --git a/src/k_profiles.cpp b/src/k_profiles.cpp index 1076cfc78..3491d70fc 100644 --- a/src/k_profiles.cpp +++ b/src/k_profiles.cpp @@ -82,6 +82,7 @@ profile_t* PR_MakeProfile( newprofile->kickstartaccel = false; newprofile->autoroulette = false; newprofile->litesteer = false; + newprofile->autoring = false; newprofile->rumble = true; newprofile->fov = atoi(cv_dummyprofilefov.defaultvalue); @@ -103,6 +104,7 @@ profile_t* PR_MakeProfileFromPlayer(const char *prname, const char *pname, const newprofile->kickstartaccel = cv_kickstartaccel[pnum].value; newprofile->autoroulette = cv_autoroulette[pnum].value; newprofile->litesteer = cv_litesteer[pnum].value; + newprofile->autoring = cv_autoring[pnum].value; newprofile->rumble = cv_rumble[pnum].value; newprofile->fov = cv_fov[pnum].value / FRACUNIT; @@ -299,6 +301,7 @@ void PR_SaveProfiles(void) jsonprof.preferences.kickstartaccel = cprof->kickstartaccel; jsonprof.preferences.autoroulette = cprof->autoroulette; jsonprof.preferences.litesteer = cprof->litesteer; + jsonprof.preferences.autoring = cprof->autoring; jsonprof.preferences.rumble = cprof->rumble; jsonprof.preferences.fov = cprof->fov; @@ -473,6 +476,7 @@ void PR_LoadProfiles(void) newprof->kickstartaccel = jsprof.preferences.kickstartaccel; newprof->autoroulette = jsprof.preferences.autoroulette; newprof->litesteer = jsprof.preferences.litesteer; + newprof->autoring = jsprof.preferences.autoring; newprof->rumble = jsprof.preferences.rumble; newprof->fov = jsprof.preferences.fov; @@ -554,6 +558,7 @@ static void PR_ApplyProfile_Settings(profile_t *p, UINT8 playernum) CV_StealthSetValue(&cv_kickstartaccel[playernum], p->kickstartaccel); CV_StealthSetValue(&cv_autoroulette[playernum], p->autoroulette); CV_StealthSetValue(&cv_litesteer[playernum], p->litesteer); + CV_StealthSetValue(&cv_autoring[playernum], p->autoring); CV_StealthSetValue(&cv_rumble[playernum], p->rumble); CV_StealthSetValue(&cv_fov[playernum], p->fov); diff --git a/src/k_profiles.h b/src/k_profiles.h index 70d3abd68..247a08e9f 100644 --- a/src/k_profiles.h +++ b/src/k_profiles.h @@ -46,6 +46,7 @@ struct ProfilePreferencesJson bool kickstartaccel; bool autoroulette; bool litesteer; + bool autoring; bool rumble; uint8_t fov; tm test; @@ -55,6 +56,7 @@ struct ProfilePreferencesJson kickstartaccel, autoroulette, litesteer, + autoring, rumble, fov ) @@ -160,6 +162,7 @@ struct profile_t boolean kickstartaccel; // cv_kickstartaccel boolean autoroulette; // cv_autoroulette boolean litesteer; // cv_litesteer + boolean autoring; // cv_autoring boolean rumble; // cv_rumble UINT8 fov; // cv_fov diff --git a/src/menus/options-profiles-1.c b/src/menus/options-profiles-1.c index be2584e63..e7c31449c 100644 --- a/src/menus/options-profiles-1.c +++ b/src/menus/options-profiles-1.c @@ -102,6 +102,7 @@ void M_StartEditProfile(INT32 c) CV_StealthSetValue(&cv_dummyprofilekickstart, optionsmenu.profile->kickstartaccel); CV_StealthSetValue(&cv_dummyprofileautoroulette, optionsmenu.profile->autoroulette); CV_StealthSetValue(&cv_dummyprofilelitesteer, optionsmenu.profile->litesteer); + CV_StealthSetValue(&cv_dummyprofileautoring, optionsmenu.profile->autoring); CV_StealthSetValue(&cv_dummyprofilerumble, optionsmenu.profile->rumble); CV_StealthSetValue(&cv_dummyprofilefov, optionsmenu.profile->fov); } @@ -112,6 +113,7 @@ void M_StartEditProfile(INT32 c) CV_StealthSetValue(&cv_dummyprofilekickstart, 0); // off CV_StealthSetValue(&cv_dummyprofileautoroulette, 0); // off CV_StealthSetValue(&cv_dummyprofilelitesteer, 1); // on + CV_StealthSetValue(&cv_dummyprofileautoring, 0); // on CV_StealthSetValue(&cv_dummyprofilerumble, 1); // on CV_StealthSetValue(&cv_dummyprofilefov, 90); } diff --git a/src/menus/options-profiles-edit-1.c b/src/menus/options-profiles-edit-1.c index 9599ae456..93d44049a 100644 --- a/src/menus/options-profiles-edit-1.c +++ b/src/menus/options-profiles-edit-1.c @@ -98,6 +98,7 @@ static void M_ProfileEditApply(void) optionsmenu.profile->kickstartaccel = cv_dummyprofilekickstart.value; optionsmenu.profile->autoroulette = cv_dummyprofileautoroulette.value; optionsmenu.profile->litesteer = cv_dummyprofilelitesteer.value; + optionsmenu.profile->autoring = cv_dummyprofileautoring.value; optionsmenu.profile->rumble = cv_dummyprofilerumble.value; optionsmenu.profile->fov = cv_dummyprofilefov.value; @@ -109,6 +110,7 @@ static void M_ProfileEditApply(void) CV_SetValue(&cv_kickstartaccel[belongsto], cv_dummyprofilekickstart.value); CV_SetValue(&cv_autoroulette[belongsto], cv_dummyprofileautoroulette.value); CV_SetValue(&cv_litesteer[belongsto], cv_dummyprofilelitesteer.value); + CV_SetValue(&cv_autoring[belongsto], cv_dummyprofileautoring.value); CV_SetValue(&cv_rumble[belongsto], cv_dummyprofilerumble.value); CV_SetValue(&cv_fov[belongsto], cv_dummyprofilefov.value); } diff --git a/src/menus/options-profiles-edit-accessibility.cpp b/src/menus/options-profiles-edit-accessibility.cpp index 9a236dae8..14dd0643d 100644 --- a/src/menus/options-profiles-edit-accessibility.cpp +++ b/src/menus/options-profiles-edit-accessibility.cpp @@ -105,6 +105,9 @@ menuitem_t OPTIONS_ProfileAccessibility[] = { {IT_STRING | IT_CVAR, "Auto Roulette", "Item roulette auto-stops on a random result.", NULL, {.cvar = &cv_dummyprofileautoroulette}, 0, 0}, + {IT_STRING | IT_CVAR, "Auto Ring", "Auto-use rings to maintain momentum.", + NULL, {.cvar = &cv_dummyprofileautoring}, 0, 0}, + {IT_STRING | IT_CVAR, "Kickstart Accel", "Hold A to auto-accel. Tap it to cancel.", NULL, {.cvar = &cv_dummyprofilekickstart}, 0, 0}, diff --git a/src/p_saveg.c b/src/p_saveg.c index bef745fdb..6a54dfb58 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -565,6 +565,7 @@ static void P_NetArchivePlayers(savebuffer_t *save) WRITEUINT8(save->p, players[i].typing_duration); WRITEUINT8(save->p, players[i].kickstartaccel); + WRITEUINT8(save->p, players[i].autoring); WRITEUINT8(save->p, players[i].stairjank); WRITEUINT8(save->p, players[i].topdriftheld); @@ -1166,6 +1167,7 @@ static void P_NetUnArchivePlayers(savebuffer_t *save) players[i].typing_duration = READUINT8(save->p); players[i].kickstartaccel = READUINT8(save->p); + players[i].autoring = READUINT8(save->p); players[i].stairjank = READUINT8(save->p); players[i].topdriftheld = READUINT8(save->p);