diff --git a/src/k_hud.c b/src/k_hud.c index 5211080a4..a278225dc 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -1876,7 +1876,7 @@ static void K_DrawKartPositionNum(INT32 num) while (num) { /* - + */ fx = K_DrawKartPositionNumPatch( @@ -1995,7 +1995,7 @@ static boolean K_drawKartPositionFaces(void) { flipflag = V_FLIP|V_VFLIP; // blonic flip xoff = yoff = 16; - } else + } else { flipflag = 0; xoff = yoff = 0; @@ -5324,3 +5324,24 @@ void K_drawKartHUD(void) K_DrawDirectorDebugger(); K_DrawGPRankDebugger(); } + +void K_DrawSticker(INT32 x, INT32 y, INT32 width, INT32 flags, boolean isSmall) +{ + patch_t *stickerEnd; + INT32 height; + + if (isSmall == true) + { + stickerEnd = W_CachePatchName("K_STIKE2", PU_CACHE); + height = 6; + } + else + { + stickerEnd = W_CachePatchName("K_STIKEN", PU_CACHE); + height = 11; + } + + V_DrawFixedPatch(x*FRACUNIT, y*FRACUNIT, FRACUNIT, flags, stickerEnd, NULL); + V_DrawFill(x, y, width, height, 24|flags); + V_DrawFixedPatch((x + width)*FRACUNIT, y*FRACUNIT, FRACUNIT, flags|V_FLIP, stickerEnd, NULL); +} diff --git a/src/k_hud.h b/src/k_hud.h index c16a45b69..df17214e2 100644 --- a/src/k_hud.h +++ b/src/k_hud.h @@ -46,6 +46,7 @@ void K_DrawLikeMapThumbnail(fixed_t x, fixed_t y, fixed_t width, UINT32 flags, p void K_drawTargetHUD(const vector3_t *origin, player_t *player); void K_drawButton(fixed_t x, fixed_t y, INT32 flags, patch_t *button[2], boolean pressed); void K_drawButtonAnim(INT32 x, INT32 y, INT32 flags, patch_t *button[2], tic_t animtic); +void K_DrawSticker(INT32 x, INT32 y, INT32 width, INT32 flags, boolean isSmall); extern patch_t *kp_capsuletarget_arrow[2][2]; extern patch_t *kp_capsuletarget_icon[2]; diff --git a/src/k_menu.h b/src/k_menu.h index 0175856ef..8eaf787a8 100644 --- a/src/k_menu.h +++ b/src/k_menu.h @@ -1238,13 +1238,16 @@ consvar_t *M_GetSoundTestVolumeCvar(void); #ifdef HAVE_DISCORDRPC extern struct discordrequestmenu_s { + tic_t ticker; tic_t confirmDelay; + tic_t confirmLength; boolean confirmAccept; boolean removeRequest; } discordrequestmenu; +void M_DrawDiscordRequests(void); void M_DiscordRequests(INT32 choice); -void M_DiscordRequestHandler(INT32 choice); +const char *M_GetDiscordName(discordRequest_t *r); #endif // These defines make it a little easier to make menus diff --git a/src/k_menudraw.c b/src/k_menudraw.c index 335a26a5e..ecb85d279 100644 --- a/src/k_menudraw.c +++ b/src/k_menudraw.c @@ -68,6 +68,10 @@ int snprintf(char *str, size_t n, const char *fmt, ...); //int vsnprintf(char *str, size_t n, const char *fmt, va_list ap); #endif +#ifdef HAVE_DISCORDRPC +#include "discord.h" +#endif + #define SKULLXOFF -32 #define LINEHEIGHT 16 #define STRINGHEIGHT 8 @@ -4082,7 +4086,7 @@ void M_DrawPause(void) y_data_t standings; memset(&standings, 0, sizeof (standings)); - standings.mainplayer = (demo.playback ? displayplayers[0] : consoleplayer); + standings.mainplayer = (demo.playback ? displayplayers[0] : consoleplayer); // See also G_GetNextMap, Y_CalculateMatchData if ( @@ -4900,7 +4904,7 @@ static void M_DrawChallengePreview(INT32 x, INT32 y) } V_DrawThinString(1, BASEVIDHEIGHT-(9+3), V_ALLOWLOWERCASE|V_6WIDTHSPACE, gtname); - + break; } case SECRET_ENCORE: @@ -5856,3 +5860,94 @@ void M_DrawSoundTest(void) V_DrawCharacter(cursorx - 4, currentMenu->y - 8 - (skullAnimCounter/5), '\x1B' | V_SNAPTOTOP|highlightflags, false); // up arrow } + +#ifdef HAVE_DISCORDRPC +void M_DrawDiscordRequests(void) +{ + discordRequest_t *curRequest = discordRequestList; + UINT8 *colormap; + patch_t *hand = NULL; + + const char *wantText = "...would like to join!"; + const char *acceptText = "Accept" ; + const char *declineText = "Decline"; + + INT32 x = 100; + INT32 y = 133; + + INT32 slide = 0; + INT32 maxYSlide = 18; + + if (discordrequestmenu.confirmDelay > 0) + { + if (discordrequestmenu.confirmAccept == true) + { + colormap = R_GetTranslationColormap(TC_DEFAULT, SKINCOLOR_GREEN, GTC_MENUCACHE); + hand = W_CachePatchName("K_LAPH02", PU_CACHE); + } + else + { + colormap = R_GetTranslationColormap(TC_DEFAULT, SKINCOLOR_RED, GTC_MENUCACHE); + hand = W_CachePatchName("K_LAPH03", PU_CACHE); + } + + slide = discordrequestmenu.confirmLength - discordrequestmenu.confirmDelay; + } + else + { + colormap = R_GetTranslationColormap(TC_DEFAULT, SKINCOLOR_GREY, GTC_MENUCACHE); + } + + V_DrawFixedPatch(56*FRACUNIT, 150*FRACUNIT, FRACUNIT, 0, W_CachePatchName("K_LAPE01", PU_CACHE), colormap); + + if (hand != NULL) + { + fixed_t handoffset = (4 - abs((signed)(skullAnimCounter - 4))) * FRACUNIT; + V_DrawFixedPatch(56*FRACUNIT, 150*FRACUNIT + handoffset, FRACUNIT, 0, hand, NULL); + } + + K_DrawSticker(x + (slide * 32), y - 2, V_ThinStringWidth(M_GetDiscordName(curRequest), V_ALLOWLOWERCASE|V_6WIDTHSPACE), 0, false); + V_DrawThinString(x + (slide * 32), y - 1, V_ALLOWLOWERCASE|V_6WIDTHSPACE|V_YELLOWMAP, M_GetDiscordName(curRequest)); + + K_DrawSticker(x, y + 12, V_ThinStringWidth(wantText, V_ALLOWLOWERCASE|V_6WIDTHSPACE), 0, true); + V_DrawThinString(x, y + 10, V_ALLOWLOWERCASE|V_6WIDTHSPACE, wantText); + + INT32 confirmButtonWidth = SHORT(kp_button_a[1][0]->width); + INT32 declineButtonWidth = SHORT(kp_button_b[1][0]->width); + INT32 altDeclineButtonWidth = SHORT(kp_button_x[1][0]->width); + INT32 acceptTextWidth = V_ThinStringWidth(acceptText, V_ALLOWLOWERCASE|V_6WIDTHSPACE); + INT32 declineTextWidth = V_ThinStringWidth(declineText, V_ALLOWLOWERCASE|V_6WIDTHSPACE); + INT32 stickerWidth = (confirmButtonWidth + declineButtonWidth + altDeclineButtonWidth + acceptTextWidth + declineTextWidth); + + K_DrawSticker(x, y + 26, stickerWidth, 0, true); + K_drawButtonAnim(x, y + 22, V_SNAPTORIGHT, kp_button_a[1], discordrequestmenu.ticker); + + INT32 xoffs = confirmButtonWidth; + + V_DrawThinString((x + xoffs), y + 24, V_ALLOWLOWERCASE|V_6WIDTHSPACE, acceptText); + xoffs += acceptTextWidth; + + K_drawButtonAnim((x + xoffs), y + 22, V_SNAPTORIGHT, kp_button_b[1], discordrequestmenu.ticker); + xoffs += declineButtonWidth; + + K_drawButtonAnim((x + xoffs), y + 22, V_SNAPTORIGHT, kp_button_x[1], discordrequestmenu.ticker); + xoffs += altDeclineButtonWidth; + + V_DrawThinString((x + xoffs), y + 24, V_ALLOWLOWERCASE|V_6WIDTHSPACE, declineText); + + y -= 18; + + while (curRequest->next != NULL) + { + INT32 ySlide = min(slide * 4, maxYSlide); + + curRequest = curRequest->next; + + K_DrawSticker(x, y - 1 + ySlide, V_ThinStringWidth(M_GetDiscordName(curRequest), V_ALLOWLOWERCASE|V_6WIDTHSPACE), 0, false); + V_DrawThinString(x, y + ySlide, V_ALLOWLOWERCASE|V_6WIDTHSPACE, M_GetDiscordName(curRequest)); + + y -= 12; + maxYSlide = 12; + } +} +#endif diff --git a/src/menus/transient/discord-requests.c b/src/menus/transient/discord-requests.c index d40558be2..4cb352d09 100644 --- a/src/menus/transient/discord-requests.c +++ b/src/menus/transient/discord-requests.c @@ -8,11 +8,71 @@ struct discordrequestmenu_s discordrequestmenu; +static void M_DiscordRequestHandler(INT32 choice) +{ + const UINT8 pid = 0; + (void)choice; + + if (discordrequestmenu.confirmDelay > 0) + return; + + if (M_MenuConfirmPressed(pid)) + { + Discord_Respond(discordRequestList->userID, DISCORD_REPLY_YES); + discordrequestmenu.confirmAccept = true; + discordrequestmenu.confirmDelay = discordrequestmenu.confirmLength; + S_StartSound(NULL, sfx_s3k63); + } + else if (M_MenuBackPressed(pid)) + { + Discord_Respond(discordRequestList->userID, DISCORD_REPLY_NO); + discordrequestmenu.confirmAccept = false; + discordrequestmenu.confirmDelay = discordrequestmenu.confirmLength; + S_StartSound(NULL, sfx_s3kb2); + } +} + static menuitem_t MISC_DiscordRequests[] = { {IT_NOTHING | IT_KEYHANDLER, NULL, NULL, NULL, {.routine = M_DiscordRequestHandler}, 0, 0}, }; +static void M_DiscordRequestTick(void) +{ + discordrequestmenu.ticker++; + + if (discordrequestmenu.confirmDelay > 0) + { + discordrequestmenu.confirmDelay--; + + if (discordrequestmenu.confirmDelay == 0) + { + discordrequestmenu.removeRequest = true; + } + } + + if (discordrequestmenu.removeRequest == true) + { + DRPC_RemoveRequest(discordRequestList); + + if (discordRequestList == NULL) + { + // No other requests + PAUSE_Main[mpause_discordrequests].status = IT_DISABLED; + + if (currentMenu->prevMenu) + { + M_SetupNextMenu(currentMenu->prevMenu, true); + itemOn = mpause_continue; + } + else + M_ClearMenus(true); + } + + discordrequestmenu.removeRequest = false; + } +} + menu_t MISC_DiscordRequestsDef = { sizeof(MISC_DiscordRequests) / sizeof(menuitem_t), &PAUSE_MainDef, @@ -23,44 +83,32 @@ menu_t MISC_DiscordRequestsDef = { 0, NULL, 0, 0, - NULL, - NULL, + M_DrawDiscordRequests, + M_DiscordRequestTick, NULL, NULL, NULL, }; - void M_DiscordRequestHandler(INT32 choice) -{ - const UINT8 pid = 0; - (void)choice; - - if (M_MenuConfirmPressed(pid)) - { - M_SetMenuDelay(pid); - - Discord_Respond(discordRequestList->userID, DISCORD_REPLY_YES); - discordrequestmenu.confirmAccept = true; - discordrequestmenu.confirmDelay = menucmd[pid].delay; - S_StartSound(NULL, sfx_s3k63); - } - else if (M_MenuBackPressed(pid)) - { - M_SetMenuDelay(pid); - - Discord_Respond(discordRequestList->userID, DISCORD_REPLY_NO); - discordrequestmenu.confirmAccept = false; - discordrequestmenu.confirmDelay = menucmd[pid].delay; - S_StartSound(NULL, sfx_s3kb2); - } -} - void M_DiscordRequests(INT32 choice) { (void)choice; + static const tic_t confirmLength = 3*TICRATE/4; - MISC_SoundTestDef.prevMenu = currentMenu; - M_SetupNextMenu(&MISC_DiscordRequestsDef, false); + discordrequestmenu.confirmLength = confirmLength; + MISC_DiscordRequestsDef.prevMenu = currentMenu; + M_SetupNextMenu(&MISC_DiscordRequestsDef, true); +} + +const char *M_GetDiscordName(discordRequest_t *r) +{ + if (r == NULL) + return ""; + + if (cv_discordstreamer.value) + return r->username; + + return va("%s#%s", r->username, r->discriminator); } #endif // HAVE_DISCORDRPC diff --git a/src/menus/transient/pause-game.c b/src/menus/transient/pause-game.c index eac460c2f..556aa2fd7 100644 --- a/src/menus/transient/pause-game.c +++ b/src/menus/transient/pause-game.c @@ -193,13 +193,6 @@ void M_OpenPauseMenu(void) } } -#ifdef HAVE_DISCORDRPC - if (discordRequestList) - { - PAUSE_Main[mpause_discordrequests].status = IT_STRING | IT_CALL; - } -#endif - G_ResetAllDeviceRumbles(); } @@ -225,6 +218,14 @@ void M_PauseTick(void) } else pausemenu.openoffset /= 2; + +#ifdef HAVE_DISCORDRPC + // Show discord requests menu option if any requests are pending + if (discordRequestList) + { + PAUSE_Main[mpause_discordrequests].status = IT_STRING | IT_CALL; + } +#endif } boolean M_PauseInputs(INT32 ch)