Profile fixes

- Less M_StartMessage spam
- Say "NEW" instead of "EMPTY" for new profile creation
- Use Eggman instead of Sonic for the Guest profile
- Instead of needing to hold X for 3 seconds to exit the test controls menu, you simply press nothing for 5 seconds.
- Add separate back option to controls menu.
- Started on the ability to use prefcolor as your profile color
- Allow guest online because there is literally already mechanics for having a player with no power level :V
This commit is contained in:
Sally Coolatta 2022-08-29 04:08:12 -04:00
parent 2b3d8dccf9
commit b388890647
5 changed files with 88 additions and 84 deletions

View file

@ -653,7 +653,7 @@ menuitem_t OPTIONS_ProfileControls[] = {
{IT_CONTROL, "OPEN TEAM CHAT", "Do we even have team gamemodes?",
NULL, {.routine = M_ProfileSetControl}, gc_teamtalk, 0},
{IT_CONTROL, "OPEN CONSOLE", "Also usable with ` on Keyboard.",
{IT_CONTROL, "OPEN CONSOLE", "Opens the developer options console.",
NULL, {.routine = M_ProfileSetControl}, gc_console, 0},
{IT_CONTROL, "LUA/A", "May be used by add-ons.",
@ -674,8 +674,11 @@ menuitem_t OPTIONS_ProfileControls[] = {
{IT_HEADER, "EXTRA", "",
NULL, {NULL}, 0, 0},
{IT_STRING | IT_CALL, "TRY MAPPINGS", "Only display the controller for testing.",
{IT_STRING | IT_CALL, "TRY MAPPINGS", "Test your controls.",
NULL, {.routine = M_ProfileTryController}, 0, 0},
{IT_STRING | IT_CALL, "BACK...", "Go back to profile setup.",
NULL, {.routine = M_GoBack}, 0, 0},
};

View file

@ -1227,7 +1227,7 @@ static void M_DrawCharSelectPreview(UINT8 num)
}
else if (dist == 2)
{
V_DrawCenteredFileString(px+26, py, 0, pr->version ? pr->profilename : "EMPTY");
V_DrawCenteredFileString(px+26, py, 0, pr->version ? pr->profilename : "NEW");
V_DrawScaledPatch(px, py, V_TRANSLUCENT, W_CachePatchName("FILEBACK", PU_CACHE));
}
else
@ -1235,7 +1235,7 @@ static void M_DrawCharSelectPreview(UINT8 num)
V_DrawScaledPatch(px, py, 0, W_CachePatchName("FILEBACK", PU_CACHE));
if (i != p->profilen || ((setup_animcounter/10) & 1))
V_DrawCenteredFileString(px+26, py, 0, pr->version ? pr->profilename : "EMPTY");
V_DrawCenteredFileString(px+26, py, 0, pr->version ? pr->profilename : "NEW");
}
py += 12;
}
@ -1366,11 +1366,11 @@ static void M_DrawProfileCard(INT32 x, INT32 y, boolean greyedout, profile_t *p)
INT32 skinnum = -1;
INT32 powerlevel = -1;
char pname[PROFILENAMELEN+1] = "empty";
char pname[PROFILENAMELEN+1] = "NEW";
if (p != NULL && p->version)
{
colormap = R_GetTranslationColormap(TC_DEFAULT, p->color, GTC_CACHE);
colormap = R_GetTranslationColormap(TC_DEFAULT, PR_GetProfileColor(p), GTC_CACHE);
strcpy(pname, p->profilename);
skinnum = R_SkinAvailable(p->skinname);
powerlevel = p->powerlevels[0]; // Only display race power level.
@ -2904,6 +2904,7 @@ void M_DrawProfileControls(void)
case IT_STRING:
V_DrawString(x, y+1, (i == itemOn ? highlightflags : 0), currentMenu->menuitems[i].text);
y += spacing;
break;
case IT_STRING2:

View file

@ -2057,7 +2057,7 @@ static void M_SetupProfileGridPos(setup_player_t *p)
alt++;
p->clonenum = alt;
p->color = pr->color;
p->color = PR_GetProfileColor(pr);
return; // we're done here
}
}
@ -3759,19 +3759,9 @@ void M_MPOptSelectInit(INT32 choice)
{
INT16 arrcpy[3][3] = {{0,68,0}, {0,12,0}, {0,74,0}};
UINT8 i = 0, j = 0; // To copy the array into the struct
const UINT8 pid = 0;
(void)choice;
// Don't allow guest profile online
if (cv_currprofile.value == 0)
{
M_StartMessage(M_GetText("Cannot play online with\nGuest Profile.\nMake a custom Profile and try again.\n\n(Press any key)"), NULL, MM_NOTHING);
S_StartSound(NULL, sfx_s3k7b);
M_SetMenuDelay(pid);
return;
}
mpmenu.modechoice = 0;
mpmenu.ticker = 0;
@ -4778,40 +4768,41 @@ void M_HandleProfileSelect(INT32 ch)
if (optionsmenu.profilen == 0) // Guest profile, you can't edit that one!
{
S_StartSound(NULL, sfx_s3k7b);
M_StartMessage(M_GetText("Guest Profile cannot be edited.\nTo change parameters,\ncreate a new Profile."), NULL, MM_NOTHING);
M_StartMessage(M_GetText("The Guest profile cannot be edited.\nCreate a new profile instead."), NULL, MM_NOTHING);
M_SetMenuDelay(pid);
return;
}
else if (optionsmenu.profilen == maxp && gamestate != GS_MENU)
{
S_StartSound(NULL, sfx_s3k7b);
M_StartMessage(M_GetText("Cannot create a New Profile\nmid-game. Return to the\nTitle Screen first."), NULL, MM_NOTHING);
M_StartMessage(M_GetText("Cannot create a new profile\nmid-game. Return to the\ntitle screen first."), NULL, MM_NOTHING);
M_SetMenuDelay(pid);
return;
}
S_StartSound(NULL, sfx_s3k5b);
M_StartEditProfile(MA_YES);
}
else
{
// We're on the profile selection screen.
if (optionsmenu.profilen == 0)
if (optionsmenu.profilen == maxp)
{
M_StartMessage(M_GetText("Are you sure you wish\nto use the Guest Profile?\nThis profile cannot be customised.\nIt is recommended to create\na new Profile instead.\n\n(Press A to confirm)"), FUNCPTRCAST(M_FirstPickProfile), MM_YESNO);
M_SetMenuDelay(pid);
return;
}
else if (optionsmenu.profilen == maxp)
{
M_StartMessage(M_GetText("Create a new Profile?\n\n(Press A to confirm)"), FUNCPTRCAST(M_StartEditProfile), MM_YESNO);
M_StartEditProfile(MA_YES);
M_SetMenuDelay(pid);
return;
}
else
{
M_StartMessage(M_GetText("Are you sure you wish to\nselect this profile?\n\n(Press A to confirm)"), FUNCPTRCAST(M_FirstPickProfile), MM_YESNO);
#if 0
if (optionsmenu.profilen == 0)
{
M_StartMessage(M_GetText("Are you sure you wish\nto use the Guest Profile?\nThis profile cannot be customised.\nIt is recommended to create\na new Profile instead.\n\n(Press A to confirm)"), FUNCPTRCAST(M_FirstPickProfile), MM_YESNO);
return;
}
#endif
M_FirstPickProfile(MA_YES);
M_SetMenuDelay(pid);
return;
}
@ -4836,6 +4827,15 @@ static boolean M_ProfileEditEnd(const UINT8 pid)
{
UINT8 i;
// Guest profile, you can't edit that one!
if (optionsmenu.profilen == 0)
{
S_StartSound(NULL, sfx_s3k7b);
M_StartMessage(M_GetText("Guest profile cannot be edited.\nCreate a new profile instead."), NULL, MM_NOTHING);
M_SetMenuDelay(pid);
return false;
}
// check if some profiles have the same name
for (i = 0; i < PR_GetNumProfiles(); i++)
{
@ -4847,21 +4847,13 @@ static boolean M_ProfileEditEnd(const UINT8 pid)
if (!(strcmp(optionsmenu.profile->profilename, check->profilename)))
{
S_StartSound(NULL, sfx_s3k7b);
M_StartMessage(M_GetText("Another Profile uses the same\nname identifier.\nPlease change the name\nof the Profile to save it."), NULL, MM_NOTHING);
M_StartMessage(M_GetText("Another profile uses the same name.\nThis must be changed to be able to save."), NULL, MM_NOTHING);
M_SetMenuDelay(pid);
return false;
}
}
}
if (optionsmenu.profilen == 0) // Guest profile, you can't edit that one!
{
S_StartSound(NULL, sfx_s3k7b);
M_StartMessage(M_GetText("Guest Profile cannot be edited.\nTo change parameters,\ncreate a new Profile."), NULL, MM_NOTHING);
M_SetMenuDelay(pid);
return false;
}
return true;
}
@ -5113,37 +5105,18 @@ void M_HandleProfileControls(void)
}
}
static void M_ProfileTryControllerResponse(INT32 choice)
{
if (choice == MA_YES)
{
optionsmenu.trycontroller = TICRATE*3;
// Apply these controls right now on P1's end.
memcpy(&gamecontrol[0], optionsmenu.tempcontrols, sizeof(gamecontroldefault));
}
}
void M_ProfileTryController(INT32 choice)
{
(void) choice;
(void)choice;
// I managed to softlock myself during testing lol.
if (!optionsmenu.tempcontrols[gc_x][0])
{
M_StartMessage(M_GetText("You need to bind a key to [X]\nto use this feature.\n"), NULL, MM_NOTHING);
return;
}
else
{
M_StartMessage(M_GetText("Your inputs will temporarily be\nremapped to match this Profile's settings.\nThe controller graphic will animate\nto show you what buttons are being pressed.\nIs this okay?\n\n(Press A to continue)"),
FUNCPTRCAST(M_ProfileTryControllerResponse), MM_YESNO);
return;
}
optionsmenu.trycontroller = TICRATE*5;
// Apply these controls right now on P1's end.
memcpy(&gamecontrol[0], optionsmenu.tempcontrols, sizeof(gamecontroldefault));
}
static void M_ProfileControlSaveResponse(INT32 choice)
{
if (choice == MA_YES)
{
SINT8 belongsto = PR_ProfileUsedBy(optionsmenu.profile);
@ -5171,21 +5144,24 @@ boolean M_ProfileControlsInputs(INT32 ch)
// By default, accept all inputs.
if (optionsmenu.trycontroller)
{
if (M_MenuButtonHeld(pid, MBT_X))
optionsmenu.trycontroller--;
if (menucmd[pid].dpad_ud || menucmd[pid].dpad_lr || menucmd[pid].buttons)
{
optionsmenu.trycontroller = 5*TICRATE;
}
else
optionsmenu.trycontroller = TICRATE*3;
{
optionsmenu.trycontroller--;
}
if (!optionsmenu.trycontroller)
if (optionsmenu.trycontroller == 0)
{
// Reset controls to that of the current profile.
profile_t *cpr = PR_GetProfile(cv_currprofile.value);
if (cpr == NULL)
cpr = PR_GetProfile(0); // Creating a profile at boot, revert to guest profile
memcpy(&gamecontrol[0], cpr->controls, sizeof(gamecontroldefault));
M_StartMessage(M_GetText("Your controls have been\nreverted to their previous state.\n\n(Press any key)"), NULL, MM_NOTHING);
}
return true;
}
@ -5212,13 +5188,9 @@ boolean M_ProfileControlsInputs(INT32 ch)
}
else if (M_MenuBackPressed(pid))
{
SINT8 usedby = PR_ProfileUsedBy(optionsmenu.profile);
if (usedby > -1 && cv_currprofile.value)
M_StartMessage(M_GetText(va("As this is Player %d's active Profile,\ncontrol changes will be applied \nimmediately upon exiting this menu.\nIs this okay?\n\n(Press A to confirm)", usedby+1)), FUNCPTRCAST(M_ProfileControlSaveResponse), MM_YESNO);
else
M_StartMessage(M_GetText("Exiting will save the control changes\nfor this Profile.\nIs this okay?\n\n(Press A to confirm)"), FUNCPTRCAST(M_ProfileControlSaveResponse), MM_YESNO);
//M_StartMessage(M_GetText("Exiting will save the control changes\nfor this Profile.\nIs this okay?\n\n(Press A to confirm)"), FUNCPTRCAST(M_ProfileControlSaveResponse), MM_YESNO);
// TODO: Add a graphic for controls saving, instead of obnoxious prompt.
M_ProfileControlSaveResponse(MA_YES);
optionsmenu.profile->kickstartaccel = cv_dummyprofilekickstart.value; // Make sure to save kickstart accel.
@ -5535,7 +5507,7 @@ void M_CheckProfileData(INT32 choice)
if (np < 2)
{
S_StartSound(NULL, sfx_s3k7b);
M_StartMessage("There are no custom Profiles.\n\n(Press any button)", NULL, MM_NOTHING);
M_StartMessage("There are no custom profiles.\n\n(Press any button)", NULL, MM_NOTHING);
return;
}
@ -5598,9 +5570,9 @@ void M_HandleProfileErase(INT32 choice)
else if (M_MenuConfirmPressed(pid))
{
if (optionsmenu.eraseprofilen == cv_currprofile.value)
M_StartMessage("This profile and all of\nits data will be erased.\nAre you sure you want to proceed?\nAs this is your currently loaded Profile,\ndeleting this Profile would also\nreturn you to the Title Screen\n\n(Press A to confirm)", FUNCPTRCAST(M_EraseProfileResponse), MM_YESNO);
M_StartMessage("This profile will be erased.\nAre you sure you want to proceed?\nDeleting this profile will also\nreturn you to the title screen.\n\n(Press A to confirm)", FUNCPTRCAST(M_EraseProfileResponse), MM_YESNO);
else
M_StartMessage("This profile and all of\nits data will be erased.\nAre you sure you want to proceed?\n\n(Press A to confirm)", FUNCPTRCAST(M_EraseProfileResponse), MM_YESNO);
M_StartMessage("This profile will be erased.\nAre you sure you want to proceed?\n\n(Press A to confirm)", FUNCPTRCAST(M_EraseProfileResponse), MM_YESNO);
M_SetMenuDelay(pid);
}

View file

@ -13,6 +13,7 @@
#include "d_main.h" // pandf
#include "k_profiles.h"
#include "z_zone.h"
#include "r_skins.h"
// List of all the profiles.
static profile_t *profilesList[MAXPROFILES+1]; // +1 because we're gonna add a default "GUEST' profile.
@ -201,19 +202,23 @@ void PR_LoadProfiles(void)
fread(profilesList[i], sizeof(profile_t), 1, f);
// Attempt to correct numerical footguns
if (profilesList[i]->color >= numskincolors
|| profilesList[i]->color == 0
if (profilesList[i]->color == SKINCOLOR_NONE)
{
; // Valid, even outside the bounds
}
else if (profilesList[i]->color >= numskincolors
|| skincolors[profilesList[i]->color].accessible == false)
{
profilesList[i]->color = PROFILEDEFAULTCOLOR;
}
if (profilesList[i]->followercolor == FOLLOWERCOLOR_MATCH
|| profilesList[i]->followercolor == FOLLOWERCOLOR_OPPOSITE)
{
; // Valid, even outside the bounds
}
else if (profilesList[i]->followercolor >= numskincolors
|| profilesList[i]->followercolor == 0
|| profilesList[i]->followercolor == SKINCOLOR_NONE
|| skincolors[profilesList[i]->followercolor].accessible == false)
{
profilesList[i]->followercolor = PROFILEDEFAULTFOLLOWERCOLOR;
@ -232,6 +237,25 @@ void PR_LoadProfiles(void)
}
}
skincolornum_t PR_GetProfileColor(profile_t *p)
{
if (p->color == SKINCOLOR_NONE)
{
// Get skin's prefcolor.
INT32 foundskin = R_SkinAvailable(p->skinname);
if (foundskin == -1)
{
// Return random default value
return SKINCOLOR_RED;
}
return skins[foundskin].prefcolor;
}
// Get exact color.
return p->color;
}
void PR_ApplyProfile(UINT8 profilenum, UINT8 playernum)
{
profile_t *p = PR_GetProfile(profilenum);
@ -245,7 +269,7 @@ void PR_ApplyProfile(UINT8 profilenum, UINT8 playernum)
}
CV_StealthSet(&cv_skin[playernum], p->skinname);
CV_StealthSetValue(&cv_playercolor[playernum], p->color);
CV_StealthSetValue(&cv_playercolor[playernum], PR_GetProfileColor(p));
CV_StealthSet(&cv_playername[playernum], p->playername);
// Followers

View file

@ -33,8 +33,8 @@
#define PROFILEDEFAULTNAME "guest"
#define PROFILEDEFAULTPNAME "Player"
#define PROFILEDEFAULTSKIN "sonic"
#define PROFILEDEFAULTCOLOR SKINCOLOR_SAPPHIRE
#define PROFILEDEFAULTSKIN "eggman"
#define PROFILEDEFAULTCOLOR SKINCOLOR_NONE
#define PROFILEDEFAULTFOLLOWER "none"
#define PROFILEDEFAULTFOLLOWERCOLOR FOLLOWERCOLOR_MATCH
@ -112,6 +112,10 @@ void PR_SaveProfiles(void);
// This also loads
void PR_LoadProfiles(void);
// PR_GetProfileColor(profile_t *p)
// Returns the profile's color, or the skin's prefcolor if set to none.
skincolornum_t PR_GetProfileColor(profile_t *p);
// PR_ApplyProfile(UINT8 profilenum, UINT8 playernum)
// Applies the given profile's settings to the given player.
void PR_ApplyProfile(UINT8 profilenum, UINT8 playernum);