Merge branch 'challenges-bonnus' into 'master'

Challenges Bonnus

See merge request kart-krew-dev/ring-racers-internal!2738
This commit is contained in:
Oni VelocitOni 2025-08-19 19:39:29 +00:00
commit f8f4d6cfd6
14 changed files with 726 additions and 266 deletions

View file

@ -1051,7 +1051,14 @@ static void SendNameAndColor(const UINT8 n)
WRITESTRINGN(p, cv_playername[n].zstring, MAXPLAYERNAME);
WRITEUINT16(p, sendColor);
WRITEUINT8(p, (UINT8)cv_skin[n].value);
WRITEINT16(p, (INT16)cv_follower[n].value);
if (horngoner)
{
WRITEINT16(p, (-1));
}
else
{
WRITEINT16(p, (INT16)cv_follower[n].value);
}
//CONS_Printf("Sending follower id %d\n", (INT16)cv_follower[n].value);
WRITEUINT16(p, sendFollowerColor);

View file

@ -32,6 +32,8 @@ follower_t followers[MAXFOLLOWERS];
INT32 numfollowercategories;
followercategory_t followercategories[MAXFOLLOWERCATEGORIES];
boolean horngoner = false;
CV_PossibleValue_t Followercolor_cons_t[MAXSKINCOLORS+3]; // +3 to account for "Match", "Opposite" & NULL
/*--------------------------------------------------

View file

@ -115,6 +115,8 @@ struct followercategory_t
extern INT32 numfollowercategories;
extern followercategory_t followercategories[MAXFOLLOWERCATEGORIES];
extern boolean horngoner;
/*--------------------------------------------------
INT32 K_FollowerAvailable(const char *name)

View file

@ -1526,7 +1526,7 @@ static void K_initKartHUD(void)
}
}
void K_DrawMapThumbnail(fixed_t x, fixed_t y, fixed_t width, UINT32 flags, UINT16 map, const UINT8 *colormap)
void K_DrawMapThumbnail2(fixed_t x, fixed_t y, fixed_t width, UINT32 flags, UINT16 map, const UINT8 *colormap, fixed_t accordion)
{
patch_t *PictureOfLevel = NULL;
@ -1543,58 +1543,79 @@ void K_DrawMapThumbnail(fixed_t x, fixed_t y, fixed_t width, UINT32 flags, UINT1
PictureOfLevel = static_cast<patch_t*>(mapheaderinfo[map]->thumbnailPic);
}
K_DrawLikeMapThumbnail(x, y, width, flags, PictureOfLevel, colormap);
K_DrawLikeMapThumbnail(x, y, width, flags, PictureOfLevel, colormap, accordion);
}
void K_DrawLikeMapThumbnail(fixed_t x, fixed_t y, fixed_t width, UINT32 flags, patch_t *patch, const UINT8 *colormap)
void K_DrawLikeMapThumbnail(fixed_t x, fixed_t y, fixed_t width, UINT32 flags, patch_t *patch, const UINT8 *colormap, fixed_t accordion)
{
if (flags & V_FLIP)
x += width;
fixed_t scale = FixedDiv(width, (320 << FRACBITS));
V_DrawFixedPatch(
if (flags & V_FLIP)
x += FixedMul(width, accordion);
V_DrawStretchyFixedPatch(
x, y,
FixedDiv(width, (320 << FRACBITS)),
FixedMul(scale, accordion),
scale,
flags,
patch,
colormap
);
}
void K_DrawMapAsFace(INT32 x, INT32 y, UINT32 flags, UINT16 map, const UINT8 *colormap)
void K_DrawMapAsFace(INT32 x, INT32 y, UINT32 flags, UINT16 map, const UINT8 *colormap, fixed_t accordion, INT32 scalefactor)
{
const fixed_t iconHeight = (14 << FRACBITS);
const fixed_t iconHeight = ((16 * scalefactor) - 2) << FRACBITS;
const fixed_t iconWidth = (iconHeight * 320) / 200;
INT32 unit = 1;
fixed_t mul = FRACUNIT;
INT32 dup = 1;
if (flags & V_NOSCALESTART)
{
unit = (vid.dupx < vid.dupy ? vid.dupx : vid.dupy);
dup = (vid.dupx < vid.dupy ? vid.dupx : vid.dupy);
mul = 1;
}
INT32 hdup = (dup * accordion);
V_DrawFill(
x,
y,
16 * unit,
16 * unit,
(16 * scalefactor * hdup)/FRACUNIT,
16 * scalefactor * dup,
(flags & ~V_FLIP)
);
INT32 xclip = ((16 * scalefactor) - 2) * dup * mul;
if (flags & V_NOSCALESTART)
{
hdup /= FRACUNIT;
}
else
{
hdup = FixedMul(hdup, mul);
xclip = FixedMul(xclip, accordion);
}
dup *= mul;
V_SetClipRect(
(x + unit) * mul,
(y + unit) * mul,
(14 * unit) * mul,
(14 * unit) * mul,
(x * mul) + hdup,
(y * mul) + dup,
xclip,
((16 * scalefactor) - 2) * dup,
(flags & ~V_FLIP)
);
K_DrawMapThumbnail(
((x + unit) * FRACUNIT) - (iconWidth - iconHeight)/2,
((y + unit) * FRACUNIT),
K_DrawMapThumbnail2(
(x * mul) + hdup - FixedMul(iconWidth - iconHeight, accordion)/2,
(y * mul) + dup,
iconWidth,
flags,
map,
colormap
colormap,
accordion
);
V_ClearClipRect();

View file

@ -58,9 +58,10 @@ INT32 K_drawKartMicroTime(const char *todrawtext, INT32 workx, INT32 worky, INT3
void K_drawKart2PTimestamp(void);
void K_drawKart4PTimestamp(void);
void K_drawEmeraldWin(boolean overlay);
void K_DrawMapThumbnail(fixed_t x, fixed_t y, fixed_t width, UINT32 flags, UINT16 map, const UINT8 *colormap);
void K_DrawLikeMapThumbnail(fixed_t x, fixed_t y, fixed_t width, UINT32 flags, patch_t *patch, const UINT8 *colormap);
void K_DrawMapAsFace(INT32 x, INT32 y, UINT32 flags, UINT16 map, const UINT8 *colormap);
void K_DrawMapThumbnail2(fixed_t x, fixed_t y, fixed_t width, UINT32 flags, UINT16 map, const UINT8 *colormap, fixed_t accordion);
#define K_DrawMapThumbnail(x, y, w, f, m, c) K_DrawMapThumbnail2(x, y, w, f, m, c, FRACUNIT)
void K_DrawLikeMapThumbnail(fixed_t x, fixed_t y, fixed_t width, UINT32 flags, patch_t *patch, const UINT8 *colormap, fixed_t accordion);
void K_DrawMapAsFace(INT32 x, INT32 y, UINT32 flags, UINT16 map, const UINT8 *colormap, fixed_t accordion, INT32 unit);
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);

View file

@ -1428,6 +1428,8 @@ typedef enum
#define CHAOHOLD_END (3)
#define CHAOHOLD_PADDING (CHAOHOLD_BEGIN + CHAOHOLD_END)
#define EASEOFFHORN 50
extern struct timeattackmenu_s {
tic_t ticker; // How long the menu's been open for
@ -1461,11 +1463,14 @@ extern struct challengesmenu_s {
UINT16 tutorialfound;
boolean requestflip;
UINT16 nowplayingtile;
UINT16 unlockcount[CMC_MAX];
UINT8 fade;
UINT8 hornposting;
boolean cache_secondrowlocked;
patch_t *tile_category[10][2];

View file

@ -1862,6 +1862,9 @@ static boolean M_DrawFollowerSprite(INT16 x, INT16 y, INT32 num, boolean charfli
follower_t *fl;
UINT8 rotation = (charflip ? 1 : 7);
if (horngoner)
return false;
if (p != NULL)
followernum = p->followern;
else
@ -2406,7 +2409,7 @@ void M_DrawProfileCard(INT32 x, INT32 y, boolean greyedout, profile_t *p)
V_DrawMappedPatch(x+14, y+66, 0, faceprefix[skinnum][FACE_RANK], ccolormap);
}
if (fln >= 0)
if (!horngoner && fln >= 0)
{
UINT16 fcol = K_GetEffectiveFollowerColor(
p->followercolor,
@ -6722,7 +6725,6 @@ static void M_DrawChallengeTile(INT16 i, INT16 j, INT32 x, INT32 y, UINT8 *flash
fixed_t siz, accordion;
UINT16 id, num;
boolean unlockedyet;
boolean categoryside;
id = (i * CHALLENGEGRIDHEIGHT) + j;
num = gamedata->challengegrid[id];
@ -6797,20 +6799,88 @@ static void M_DrawChallengeTile(INT16 i, INT16 j, INT32 x, INT32 y, UINT8 *flash
accordion = FRACUNIT;
if (challengesmenu.extradata[id].flip != 0
boolean categoryside = (challengesmenu.extradata[id].flip == 0);
if (!categoryside // optimised, this is not the true value with anything but instaflip
&& challengesmenu.extradata[id].flip != (TILEFLIP_MAX/2))
{
angle_t bad = (FixedAngle(FixedMul(challengesmenu.extradata[id].flip * FRACUNIT + rendertimefrac, 360*FRACUNIT/TILEFLIP_MAX)) >> ANGLETOFINESHIFT) & FINEMASK;
accordion = FINECOSINE(bad);
fixed_t bad = challengesmenu.extradata[id].flip * FRACUNIT + rendertimefrac;
angle_t worse = (FixedAngle(FixedMul(bad, 360*FRACUNIT/TILEFLIP_MAX)) >> ANGLETOFINESHIFT) & FINEMASK;
accordion = FINECOSINE(worse);
if (accordion < 0)
accordion = -accordion;
// NOW we set it in an interp-friendly way
categoryside = (bad <= FRACUNIT*TILEFLIP_MAX/4
|| bad > (3*FRACUNIT*TILEFLIP_MAX)/4);
}
pat = W_CachePatchName(
(ref->majorunlock ? "UN_BORDB" : "UN_BORDA"),
PU_CACHE);
bgmap = R_GetTranslationColormap(TC_DEFAULT, SKINCOLOR_SILVER, GTC_MENUCACHE);
UINT8 iconid = 0;
{
UINT16 bcol = SKINCOLOR_SILVER;
switch (ref->type)
{
case SECRET_SKIN:
bcol = SKINCOLOR_NOVA;
iconid = 1;
break;
case SECRET_FOLLOWER:
if (horngoner)
{
bcol = SKINCOLOR_BLACK;
}
else
{
bcol = SKINCOLOR_SAPPHIRE;
iconid = 2;
}
break;
case SECRET_COLOR:
//bcol = SKINCOLOR_SILVER;
iconid = 3;
break;
case SECRET_CUP:
bcol = SKINCOLOR_GOLD;
iconid = 4;
break;
case SECRET_MAP:
bcol = SKINCOLOR_PURPLE;
iconid = 8;
break;
case SECRET_HARDSPEED:
case SECRET_MASTERMODE:
case SECRET_ENCORE:
bcol = SKINCOLOR_RUBY;
iconid = 5;
break;
case SECRET_ONLINE:
case SECRET_ADDONS:
case SECRET_EGGTV:
case SECRET_SOUNDTEST:
case SECRET_ALTTITLE:
bcol = SKINCOLOR_BLUEBERRY;
iconid = 6;
break;
case SECRET_TIMEATTACK:
case SECRET_PRISONBREAK:
case SECRET_SPECIALATTACK:
case SECRET_SPBATTACK:
bcol = SKINCOLOR_PERIDOT;
iconid = 7;
break;
case SECRET_ALTMUSIC:
bcol = SKINCOLOR_MAGENTA;
iconid = 9;
break;
}
bgmap = R_GetTranslationColormap(TC_DEFAULT, bcol, GTC_MENUCACHE);
}
V_DrawStretchyFixedPatch(
(x*FRACUNIT) + (SHORT(pat->width)*(FRACUNIT-accordion)/2), y*FRACUNIT,
@ -6822,65 +6892,25 @@ static void M_DrawChallengeTile(INT16 i, INT16 j, INT32 x, INT32 y, UINT8 *flash
pat = missingpat;
categoryside = (challengesmenu.extradata[id].flip <= TILEFLIP_MAX/4
|| challengesmenu.extradata[id].flip > (3*TILEFLIP_MAX)/4);
#ifdef DEVELOP
if (cv_debugchallenges.value)
{
// Show the content of every tile without needing to
// flip them.
// Show the content of every tile without needing to flip them.
categoryside = false;
}
#endif
if (categoryside)
if (horngoner && ref->type == SECRET_FOLLOWER)
goto drawborder;
else if (categoryside)
{
char categoryid = '0';
colormap = bgmap;
switch (ref->type)
{
case SECRET_SKIN:
categoryid = '1';
break;
case SECRET_FOLLOWER:
categoryid = '2';
break;
case SECRET_COLOR:
categoryid = '3';
break;
case SECRET_CUP:
categoryid = '4';
break;
case SECRET_MAP:
categoryid = '8';
break;
case SECRET_HARDSPEED:
case SECRET_MASTERMODE:
case SECRET_ENCORE:
categoryid = '5';
break;
case SECRET_ONLINE:
case SECRET_ADDONS:
case SECRET_EGGTV:
case SECRET_SOUNDTEST:
case SECRET_ALTTITLE:
categoryid = '6';
break;
case SECRET_TIMEATTACK:
case SECRET_PRISONBREAK:
case SECRET_SPECIALATTACK:
case SECRET_SPBATTACK:
categoryid = '7';
break;
case SECRET_ALTMUSIC:
categoryid = '9';
break;
}
pat = challengesmenu.tile_category[categoryid - '0'][ref->majorunlock ? 1 : 0];
colormap = R_GetTranslationColormap(TC_DEFAULT, SKINCOLOR_SILVER, GTC_MENUCACHE);
// iconid is already prepopulated because we had to draw the border
pat = challengesmenu.tile_category[iconid][ref->majorunlock ? 1 : 0];
if (pat == missingpat)
{
pat = challengesmenu.tile_category[categoryid - '0'][ref->majorunlock ? 0 : 1];
pat = challengesmenu.tile_category[iconid][ref->majorunlock ? 0 : 1];
}
}
else if (ref->icon != NULL && ref->icon[0])
@ -6893,7 +6923,7 @@ static void M_DrawChallengeTile(INT16 i, INT16 j, INT32 x, INT32 y, UINT8 *flash
}
else
{
UINT8 iconid = 0;
iconid = 0; // reuse
switch (ref->type)
{
case SECRET_SKIN:
@ -6930,8 +6960,42 @@ static void M_DrawChallengeTile(INT16 i, INT16 j, INT32 x, INT32 y, UINT8 *flash
}
case SECRET_MAP:
iconid = 14;
{
UINT16 mapnum = M_UnlockableMapNum(ref);
if (mapnum < nummapheaders && mapheaderinfo[mapnum]
&& (
( // Check for visitation
(mapheaderinfo[mapnum]->menuflags & LF2_NOVISITNEEDED)
|| (mapheaderinfo[mapnum]->records.mapvisited & MV_VISITED)
) && ( // Check for completion
!(mapheaderinfo[mapnum]->menuflags & LF2_FINISHNEEDED)
|| (mapheaderinfo[mapnum]->records.mapvisited & MV_BEATEN)
)
))
{
if (ref->majorunlock)
{
K_DrawMapAsFace(
(x + 5) + (32*(FRACUNIT-accordion))/(2*FRACUNIT), (y + 5),
tileflags,
mapnum,
NULL, accordion, 2
);
}
else
{
K_DrawMapAsFace(
(x + 2) + (16*(FRACUNIT-accordion))/(2*FRACUNIT), (y + 2),
tileflags,
mapnum,
NULL, accordion, 1
);
}
pat = NULL;
}
iconid = 0; //14; -- This one suits a little better for "go complete this level normally"
break;
}
case SECRET_ALTMUSIC:
iconid = 16;
break;
@ -7001,29 +7065,32 @@ static void M_DrawChallengeTile(INT16 i, INT16 j, INT32 x, INT32 y, UINT8 *flash
}
}
siz = (SHORT(pat->width) << FRACBITS);
if (pat)
{
siz = (SHORT(pat->width) << FRACBITS);
if (!siz)
; // prevent div/0
else if (ref->majorunlock)
{
V_DrawStretchyFixedPatch(
((x + 5)*FRACUNIT) + (32*(FRACUNIT-accordion)/2), (y + 5)*FRACUNIT,
FixedDiv(32*accordion, siz),
FixedDiv(32 << FRACBITS, siz),
tileflags, pat,
colormap
);
}
else
{
V_DrawStretchyFixedPatch(
((x + 2)*FRACUNIT) + (16*(FRACUNIT-accordion)/2), (y + 2)*FRACUNIT,
FixedDiv(16*accordion, siz),
FixedDiv(16 << FRACBITS, siz),
tileflags, pat,
colormap
);
if (!siz)
; // prevent div/0
else if (ref->majorunlock)
{
V_DrawStretchyFixedPatch(
((x + 5)*FRACUNIT) + (32*(FRACUNIT-accordion))/2, (y + 5)*FRACUNIT,
FixedDiv(32*accordion, siz),
FixedDiv(32 << FRACBITS, siz),
tileflags, pat,
colormap
);
}
else
{
V_DrawStretchyFixedPatch(
((x + 2)*FRACUNIT) + (16*(FRACUNIT-accordion))/2, (y + 2)*FRACUNIT,
FixedDiv(16*accordion, siz),
FixedDiv(16 << FRACBITS, siz),
tileflags, pat,
colormap
);
}
}
drawborder:
@ -7154,7 +7221,7 @@ void M_DrawCharacterIconAndEngine(INT32 x, INT32 y, UINT8 skin, UINT8 *colormap,
V_DrawFill(x+16 + (s*5), y + (w*5), 6, 6, 0);
}
static void M_DrawChallengePreview(INT32 x, INT32 y)
static const char* M_DrawChallengePreview(INT32 x, INT32 y)
{
unlockable_t *ref = NULL;
UINT8 *colormap = NULL;
@ -7162,12 +7229,9 @@ static void M_DrawChallengePreview(INT32 x, INT32 y)
if (challengesmenu.currentunlock >= MAXUNLOCKABLES)
{
return;
return NULL;
}
// Okay, this is what we want to draw.
ref = &unlockables[challengesmenu.currentunlock];
// Funny question mark?
if (!gamedata->unlocked[challengesmenu.currentunlock])
{
@ -7179,7 +7243,7 @@ static void M_DrawChallengePreview(INT32 x, INT32 y)
if (!sprdef->numframes)
{
return;
return NULL;
}
useframe = (challengesmenu.ticker / 2) % sprdef->numframes;
@ -7193,9 +7257,14 @@ static void M_DrawChallengePreview(INT32 x, INT32 y)
}
V_DrawFixedPatch(x*FRACUNIT, (y+2)*FRACUNIT, FRACUNIT, addflags, patch, NULL);
return;
return NULL;
}
// Okay, this is what we want to draw.
ref = &unlockables[challengesmenu.currentunlock];
const char *actiontext = NULL;
switch (ref->type)
{
case SECRET_SKIN:
@ -7207,6 +7276,19 @@ static void M_DrawChallengePreview(INT32 x, INT32 y)
colormap = R_GetTranslationColormap(skin, skins[skin]->prefcolor, GTC_MENUCACHE);
M_DrawCharacterSprite(x, y, skin, SPR2_STIN, 7, 0, 0, colormap);
y = (BASEVIDHEIGHT-14);
if (setup_numplayers <= 1 && cv_lastprofile[0].value != PROFILE_GUEST)
{
profile_t *pr = PR_GetProfile(cv_lastprofile[0].value);
actiontext = (pr && strcmp(pr->skinname, skins[skin]->name))
? "<a> <sky>Set on Profile"
: "<a_pressed> <gray>Set on Profile";
y -= 14;
}
for (i = 0; i < skin; i++)
{
if (!R_SkinUsable(-1, i, false))
@ -7220,7 +7302,7 @@ static void M_DrawChallengePreview(INT32 x, INT32 y)
break;
}
M_DrawCharacterIconAndEngine(4, BASEVIDHEIGHT-(4+16), i, colormap, skin);
M_DrawCharacterIconAndEngine(4, y-6, i, colormap, skin);
}
break;
}
@ -7235,6 +7317,11 @@ static void M_DrawChallengePreview(INT32 x, INT32 y)
colormap = R_GetTranslationColormap(TC_BLINK, SKINCOLOR_BLACK, GTC_MENUCACHE);
M_DrawCharacterSprite(x, y, skin, SPR2_STIN, 7, 0, 0, colormap);
if (horngoner)
{
return "<a_pressed> <gray>MISSING.";
}
// Draw follower next to them
if (fskin != -1)
{
@ -7242,9 +7329,69 @@ static void M_DrawChallengePreview(INT32 x, INT32 y)
colormap = R_GetTranslationColormap(TC_DEFAULT, col, GTC_MENUCACHE);
M_DrawFollowerSprite(x - 16, y, fskin, false, 0, colormap, NULL);
y = (BASEVIDHEIGHT-14);
if (setup_numplayers <= 1 && cv_lastprofile[0].value != PROFILE_GUEST)
{
profile_t *pr = PR_GetProfile(cv_lastprofile[0].value);
if (pr && strcmp(pr->follower, followers[fskin].name))
{
actiontext = (followers[fskin].hornsound == sfx_melody)
? "<a> <aqua>Set on Profile"
: "<a> <sky>Set on Profile";
}
}
if (!actiontext)
{
if (followers[fskin].hornsound == sfx_melody)
{
actiontext = "<a_animated> <aqua>Play Ancient Melody?";
}
else if (challengesmenu.hornposting >= EASEOFFHORN)
actiontext = "<a> <red>Time to die";
else if (challengesmenu.hornposting >= (EASEOFFHORN-5))
{
if (challengesmenu.hornposting == EASEOFFHORN)
actiontext = "Time to die";
else
actiontext = "I asked politely";
actiontext = va("%s%s",
(M_MenuConfirmPressed(0)
? "<a_pressed> <yellow>"
: "<a> <red>"
), actiontext
);
}
else if (challengesmenu.hornposting >= (EASEOFFHORN-10))
{
actiontext = M_MenuConfirmPressed(0)
? "<a_pressed> <yellow>Ease off the horn"
: "<a> <orange>Ease off the horn";
}
else switch (challengesmenu.hornposting % 4)
{
default:
actiontext = "<a_animated> <sky>Say hello";
break;
case 1:
actiontext = "<a_animated> <sky>Express your feelings";
break;
case 2:
actiontext = "<a_animated> <sky>Celebrate victory";
break;
case 3:
actiontext = "<a_animated> <sky>Announce you are pressing horn";
break;
}
}
y -= 14;
if (followers[fskin].category < numfollowercategories)
{
V_DrawFixedPatch(4*FRACUNIT, (BASEVIDHEIGHT-(4+16))*FRACUNIT,
V_DrawFixedPatch(4*FRACUNIT, (y - 6)*FRACUNIT,
FRACUNIT,
0, W_CachePatchName(followercategories[followers[fskin].category].icon, PU_CACHE),
NULL);
@ -7264,6 +7411,16 @@ static void M_DrawChallengePreview(INT32 x, INT32 y)
// Draw reference for character bathed in coloured slime
M_DrawCharacterSprite(x, y, skin, SPR2_STIN, 7, 0, 0, colormap);
if (setup_numplayers <= 1 && cv_lastprofile[0].value != PROFILE_GUEST)
{
profile_t *pr = PR_GetProfile(cv_lastprofile[0].value);
actiontext = (pr && pr->color != colorid)
? "<a> <sky>Set on Profile"
: "<a_pressed> <gray>Set on Profile";
}
break;
}
case SECRET_CUP:
@ -7346,6 +7503,8 @@ static void M_DrawChallengePreview(INT32 x, INT32 y)
const char *gtname = "Find your prize...";
UINT16 mapnum = M_UnlockableMapNum(ref);
y = (BASEVIDHEIGHT-14);
if (mapnum >= nummapheaders
|| mapheaderinfo[mapnum] == NULL
|| mapheaderinfo[mapnum]->menuflags & LF2_HIDEINMENU)
@ -7389,7 +7548,13 @@ static void M_DrawChallengePreview(INT32 x, INT32 y)
guessgt = GT_SPECIAL;
}
if (guessgt == GT_SPECIAL && !M_SecretUnlocked(SECRET_SPECIALATTACK, true))
if (setup_numplayers <= 1 && guessgt == GT_TUTORIAL)
{
// Only for 1p
actiontext = "<a_animated> <orange>Play Tutorial";
gtname = NULL;
}
else if (guessgt == GT_SPECIAL && !M_SecretUnlocked(SECRET_SPECIALATTACK, true))
{
gtname = "???";
}
@ -7409,7 +7574,10 @@ static void M_DrawChallengePreview(INT32 x, INT32 y)
NULL);
}
V_DrawThinString(1, BASEVIDHEIGHT-(9+3), 0, gtname);
if (gtname)
{
V_DrawThinString(4, y, 0, gtname);
}
break;
}
@ -7519,8 +7687,8 @@ static void M_DrawChallengePreview(INT32 x, INT32 y)
}
case SECRET_ALTTITLE:
{
x = 8;
y = BASEVIDHEIGHT-16;
x = 4;
y = BASEVIDHEIGHT-14;
V_DrawGamemodeString(x, y - 33, 0, R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_PLAGUE, GTC_MENUCACHE), M_UseAlternateTitleScreen() ? "On" : "Off");
K_DrawGameControl(x, y, 0, "<a_animated> Toggle", 0, TINY_FONT, 0);
@ -7537,7 +7705,7 @@ static void M_DrawChallengePreview(INT32 x, INT32 y)
if (map >= nummapheaders
|| !mapheaderinfo[map])
{
return;
break;
}
UINT8 musicid;
@ -7549,78 +7717,104 @@ static void M_DrawChallengePreview(INT32 x, INT32 y)
if (musicid == MAXMUSNAMES)
{
return;
break;
}
spritedef_t *sprdef = &sprites[SPR_ALTM];
spriteframe_t *sprframe;
patch_t *patch;
UINT32 addflags = 0;
const char *tune = "challenge_altmusic";
x -= 10;
y += 15;
SINT8 pushed = 0;
const boolean epossible = (M_SecretUnlocked(SECRET_ENCORE, true)
&& musicid < mapheaderinfo[map]->encoremusname_size);
if (sprdef->numframes)
if (challengesmenu.nowplayingtile == ((challengesmenu.hilix * CHALLENGEGRIDHEIGHT) + challengesmenu.hiliy)
&& Music_Playing(tune))
{
sprframe = &sprdef->spriteframes[0];
patch = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE);
if (sprframe->flip & 1) // Only for first sprite
{
addflags ^= V_FLIP; // This sprite is left/right flipped!
}
V_DrawFixedPatch(x*FRACUNIT, (y+2)*FRACUNIT, FRACUNIT/2, addflags, patch, NULL);
const char *song = Music_Song(tune);
if (epossible
&& strcmp(song, mapheaderinfo[map]->encoremusname[musicid]) == 0)
pushed = -1;
else if (musicid < mapheaderinfo[map]->musname_size
&& strcmp(song, mapheaderinfo[map]->musname[musicid]) == 0)
pushed = 1;
}
x = 8;
y = BASEVIDHEIGHT-16;
const boolean thismusplaying = Music_Playing("challenge_altmusic");
boolean pushed = false;
const char *song = NULL;
if (M_SecretUnlocked(SECRET_ENCORE, true)
&& musicid < mapheaderinfo[map]->encoremusname_size)
// Draw CD
{
if (thismusplaying)
spritedef_t *sprdef = &sprites[SPR_ALTM];
spriteframe_t *sprframe;
patch_t *patch = NULL;
UINT32 addflags = 0;
x -= 10;
y += 15;
if (sprdef->numframes)
{
song = Music_Song("challenge_altmusic");
pushed = strcmp(song, mapheaderinfo[map]->encoremusname[musicid]) == 0;
#ifdef ROTSPRITE
spriteinfo_t *sprinfo = &spriteinfo[SPR_ALTM];
INT32 rollangle = 0;
if (pushed != 0)
{
rollangle = (Music_Elapsed(tune) % (ROTANGLES/2))*2;
if (rendertimefrac >= FRACUNIT/2)
{
// A fun interp ability: inbetweens
rollangle++;
}
if (pushed > 0)
{
rollangle = ((ROTANGLES-1) - rollangle);
}
}
#endif
sprframe = &sprdef->spriteframes[0];
#ifdef ROTSPRITE
if (rollangle)
{
patch = Patch_GetRotatedSprite(sprframe, 0, 0, (sprframe->flip & 1), false, sprinfo, rollangle);
}
#endif
if (!patch)
{
patch = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE);
if (sprframe->flip & 1) // Only for first sprite
{
addflags ^= V_FLIP; // This sprite is left/right flipped!
}
}
V_DrawFixedPatch(x*FRACUNIT, (y+2)*FRACUNIT, FRACUNIT/2, addflags, patch, NULL);
}
if (!pushed)
K_DrawGameControl(x, y, 0, "<l> <sky>E Side", 0, TINY_FONT, 0);
else
K_DrawGameControl(x, y, 0, "<l_pressed> <gray>E Side", 0, TINY_FONT, 0);
// K_drawButton(x&FRACUNIT, y*FRACUNIT, 0, kp_button_l, pushed);
// x += SHORT(kp_button_l[0]->width);
// V_DrawThinString(x, y + 1, (pushed ? V_GRAYMAP : highlightflags), "E Side");
x = 8;
y -= 10;
}
if (musicid < mapheaderinfo[map]->musname_size)
{
if (pushed || !thismusplaying)
{
pushed = false;
}
else
{
if (!song)
song = Music_Song("challenge_altmusic");
pushed = strcmp(song, mapheaderinfo[map]->musname[musicid]) == 0;
}
actiontext = (pushed > 0)
? "<a_animated> <sky>Stop CD"
: "<a_animated> <sky>Play CD";
}
if (!pushed)
K_DrawGameControl(x, y, 0, "<a> <sky>Play CD", 0, TINY_FONT, 0);
if (epossible)
{
const char *secondtext = (pushed < 0)
? "<l_animated> <magenta>E Stop"
: "<l_animated> <magenta>E Side";
if (actiontext)
{
// weird encoded height
actiontext = va("\x1""%s\n%s",
(pushed < 0)
? "<l_animated> <magenta>E Stop"
: "<l_animated> <magenta>E Side",
actiontext
);
}
else
K_DrawGameControl(x, y, 0, "<a_pressed> <gray>Play CD", 0, TINY_FONT, 0);
// K_drawButton(x*FRACUNIT, y*FRACUNIT, 0, kp_button_a[1], pushed);
// x += SHORT(kp_button_a[1][0]->width);
// V_DrawThinString(x, y + 1, (pushed ? V_GRAYMAP : highlightflags), "Play CD");
{
actiontext = secondtext;
}
}
}
default:
@ -7630,7 +7824,7 @@ static void M_DrawChallengePreview(INT32 x, INT32 y)
}
if (specialmap == NEXTMAP_INVALID || !ref)
return;
return actiontext;
x -= 50;
y = 146+2;
@ -7678,6 +7872,8 @@ static void M_DrawChallengePreview(INT32 x, INT32 y)
W_CachePatchName("K_LAPE02", PU_CACHE),
colormap);
}
return actiontext;
}
#define challengesgridstep 22
@ -7914,11 +8110,6 @@ static void M_DrawChallengeScrollBar(UINT8 *flashmap)
V_DrawFill(barx + hilix, bary-1, hiliw, 1, 0);
V_DrawFill(barx + hilix, bary+barh, hiliw, 1, 0);
INT32 mindiscouragement = 2; // skipping major unlocks is just a LITTLE cringe
if (challengesmenu.unlockcount[CMC_PERCENT] == 100
&& challengesmenu.unlockcount[CMC_MAJORSKIPPED] == 0)
mindiscouragement = 1; // so someone looking for 101% isn't hunting forever
// unbounded so that we can do the last remaining completionamount draw
nextstep = numincolumn = completionamount = skiplevel = 0;
for (i = 0; ; i++)
@ -7932,7 +8123,7 @@ static void M_DrawChallengeScrollBar(UINT8 *flashmap)
if (completionamount >= numincolumn)
{
// If any have been skipped, we subtract a little for awareness...
completionamount = (skiplevel >= mindiscouragement) ? 9 : 10;
completionamount = skiplevel ? 9 : 10;
}
else
{
@ -7969,6 +8160,14 @@ static void M_DrawChallengeScrollBar(UINT8 *flashmap)
}
#endif
if (i == challengesmenu.nowplayingtile && Music_Playing("challenge_altmusic"))
{
V_DrawFill(barx + hilix, bary, hiliw, barh, (challengesmenu.ticker & 2) ? 177 : 122);
// The now-playing fill overrides everything else.
completionamount = -1;
}
if (completionamount == -1)
continue;
@ -7978,9 +8177,9 @@ static void M_DrawChallengeScrollBar(UINT8 *flashmap)
unlockable_t *ref = &unlockables[gamedata->challengegrid[i]];
if (skiplevel < 2 && M_Achieved(ref->conditionset - 1) == false)
if (!skiplevel && M_Achieved(ref->conditionset - 1) == false)
{
skiplevel = ref->majorunlock ? 2 : 1;
skiplevel = 1;
}
}
@ -8231,9 +8430,10 @@ challengedesc:
y = BASEVIDHEIGHT-16;
// Unlock preview
M_DrawChallengePreview(x, y);
const char *actiontext = M_DrawChallengePreview(x, y);
// Conditions for unlock
// { -- please don't call va() anywhere between here...
i = (challengesmenu.hilix * CHALLENGEGRIDHEIGHT) + challengesmenu.hiliy;
if (challengesmenu.unlockcondition != NULL
@ -8246,6 +8446,25 @@ challengedesc:
{
V_DrawCenteredThinString(BASEVIDWIDTH/2, 120 + 32, 0, challengesmenu.unlockcondition);
}
// Extracted from M_DrawCharSelectPreview for ordering reasons
if (actiontext && actiontext[0])
{
x = 4;
y = (BASEVIDHEIGHT-14);
if (actiontext[0] < '\x5')
{
// weird encoded height, supports max 5 rows
y -= (13 * actiontext[0]);
actiontext++;
}
K_DrawGameControl(
x, y, 0,
actiontext,
0, TINY_FONT, 0
);
// } -- ...and here (since actiontext needs it)
}
}
#undef challengetransparentstrength

View file

@ -705,7 +705,7 @@ static void Y_DrawVoteThumbnail(fixed_t center_x, fixed_t center_y, fixed_t widt
fy + fh - whiteSq + dupy,
flags | V_NOSCALESTART | ((encore == true) ? V_FLIP : 0),
g_voteLevels[v][0],
NULL
NULL, FRACUNIT, 1
);
}
}

View file

@ -1655,7 +1655,12 @@ boolean M_CheckCondition(condition_t *cn, player_t *player)
case UC_TOTALMEDALS: // Requires number of emblems >= x
return (M_GotEnoughMedals(cn->requirement));
case UC_EMBLEM: // Requires emblem x to be obtained
return gamedata->collected[cn->requirement-1];
{
INT32 i = cn->requirement-1;
if (i >= 0 && i < numemblems && emblemlocations[i].type != ET_NONE)
return gamedata->collected[cn->requirement-1];
return false;
}
case UC_UNLOCKABLE: // Requires unlockable x to be obtained
return gamedata->unlocked[cn->requirement-1];
case UC_CONDITIONSET: // requires condition set x to already be achieved
@ -3204,7 +3209,7 @@ static boolean M_CheckUnlockConditions(player_t *player)
{
UINT32 i;
conditionset_t *c;
boolean ret;
boolean ret = false;
for (i = 0; i < MAXCONDITIONSETS; ++i)
{

View file

@ -82,6 +82,10 @@ static void M_UpdateChallengeGridVisuals(void)
challengesmenu.unlockcount[CMC_UNLOCKED] = 0;
challengesmenu.unlockcount[CMC_TOTAL] = 0;
challengesmenu.unlockcount[CMC_KEYED] = 0;
challengesmenu.unlockcount[CMC_MAJORSKIPPED] = 0;
//#define MAJORDISTINCTION -- The "basic" medal is basically never seen because Major challenges are usually completed last before 101%. Correct that with this
for (i = 0; i < MAXUNLOCKABLES; i++)
{
@ -106,12 +110,14 @@ static void M_UpdateChallengeGridVisuals(void)
challengesmenu.unlockcount[CMC_KEYED]++;
#ifdef MAJORDISTINCTION
if (unlockables[i].majorunlock == false)
{
continue;
}
challengesmenu.unlockcount[CMC_MAJORSKIPPED]++;
#endif
}
challengesmenu.unlockcount[CMC_PERCENT] =
@ -125,7 +131,9 @@ static void M_UpdateChallengeGridVisuals(void)
challengesmenu.unlockcount[CMC_MEDALFILLED] =
(medalheight * (
challengesmenu.unlockcount[CMC_UNLOCKED]
#ifdef MAJORDISTINCTION
- challengesmenu.unlockcount[CMC_MAJORSKIPPED]
#endif
)) / challengesmenu.unlockcount[CMC_TOTAL];
if (challengesmenu.unlockcount[CMC_PERCENT] == 100)
@ -135,7 +143,10 @@ static void M_UpdateChallengeGridVisuals(void)
challengesmenu.unlockcount[CMC_MEDALID] = 2;
challengesmenu.unlockcount[CMC_PERCENT]++; // 101%
}
else if (challengesmenu.unlockcount[CMC_MAJORSKIPPED] == 0)
else
#ifdef MAJORDISTINCTION
if (challengesmenu.unlockcount[CMC_MAJORSKIPPED] == 0)
#endif
{
challengesmenu.unlockcount[CMC_MEDALID] = 1;
}
@ -364,10 +375,13 @@ menu_t *M_InterruptMenuWithChallenges(menu_t *desiredmenu)
if ((challengesmenu.pending = (newunlock != MAXUNLOCKABLES)))
{
Music_StopAll();
MISC_ChallengesDef.prevMenu = desiredmenu;
if (desiredmenu && desiredmenu != &MISC_ChallengesDef)
{
MISC_ChallengesDef.prevMenu = desiredmenu;
}
}
if (challengesmenu.pending || desiredmenu == NULL)
if (challengesmenu.pending || desiredmenu == &MISC_ChallengesDef)
{
static boolean firstopen = true;
@ -379,10 +393,12 @@ menu_t *M_InterruptMenuWithChallenges(menu_t *desiredmenu)
challengesmenu.tutorialfound = NEXTMAP_INVALID;
challengesmenu.chaokeyhold = 0;
challengesmenu.unlockcondition = NULL;
challengesmenu.hornposting = 0;
if (firstopen)
{
challengesmenu.currentunlock = MAXUNLOCKABLES;
challengesmenu.nowplayingtile = UINT16_MAX;
firstopen = false;
}
@ -402,9 +418,14 @@ menu_t *M_InterruptMenuWithChallenges(menu_t *desiredmenu)
if (challengesmenu.pending)
M_ChallengesAutoFocus(newunlock, true);
else if (newunlock >= MAXUNLOCKABLES && gamedata->pendingkeyrounds > 0
&& (gamedata->chaokeys < GDMAX_CHAOKEYS))
challengesmenu.chaokeyadd = true;
else
{
if (newunlock >= MAXUNLOCKABLES && gamedata->pendingkeyrounds > 0
&& (gamedata->chaokeys < GDMAX_CHAOKEYS))
challengesmenu.chaokeyadd = true;
M_ChallengesAutoFocus(UINT16_MAX, true);
}
M_CacheChallengeTiles();
@ -418,17 +439,24 @@ void M_Challenges(INT32 choice)
{
(void)choice;
M_InterruptMenuWithChallenges(NULL);
M_InterruptMenuWithChallenges(&MISC_ChallengesDef);
MISC_ChallengesDef.prevMenu = currentMenu;
if (gamedata->challengegrid != NULL && !challengesmenu.pending)
{
M_ChallengesAutoFocus(UINT16_MAX, true);
}
M_SetupNextMenu(&MISC_ChallengesDef, false);
}
static void M_CloseChallenges(void)
{
Music_Stop("challenge_altmusic");
challengesmenu.nowplayingtile = UINT16_MAX;
Z_Free(challengesmenu.extradata);
challengesmenu.extradata = NULL;
Z_Free(challengesmenu.unlockcondition);
challengesmenu.unlockcondition = NULL;
}
boolean M_CanKeyHiliTile(void)
{
// No tile data?
@ -569,13 +597,20 @@ void M_ChallengesTick(void)
{
UINT16 id = (challengesmenu.hilix * CHALLENGEGRIDHEIGHT) + challengesmenu.hiliy;
boolean seeeveryone = challengesmenu.requestflip;
boolean allthewaythrough;
boolean allthewaythrough = allthewaythrough = (!seeeveryone && !challengesmenu.pending);
UINT8 maxflip;
if (id == challengesmenu.nowplayingtile)
{
// Don't permit the active song to stop spinning
id = UINT16_MAX;
}
for (i = 0; i < (CHALLENGEGRIDHEIGHT * gamedata->challengegridwidth); i++)
{
allthewaythrough = (!seeeveryone && !challengesmenu.pending && i != id);
maxflip = ((seeeveryone || !allthewaythrough) ? (TILEFLIP_MAX/2) : TILEFLIP_MAX);
if ((seeeveryone || (i == id) || (challengesmenu.extradata[i].flip > 0))
maxflip = ((allthewaythrough && i != id) ? TILEFLIP_MAX : (TILEFLIP_MAX/2));
if ((seeeveryone || (i == id) || (i == challengesmenu.nowplayingtile) || (challengesmenu.extradata[i].flip > 0))
&& (challengesmenu.extradata[i].flip != maxflip))
{
challengesmenu.extradata[i].flip++;
@ -943,19 +978,12 @@ boolean M_ChallengesInputs(INT32 ch)
{
if (M_MenuBackPressed(pid) || start)
{
Music_Stop("challenge_altmusic");
currentMenu->prevMenu = M_SpecificMenuRestore(currentMenu->prevMenu);
M_GoBack(0);
M_SetMenuDelay(pid);
Z_Free(challengesmenu.extradata);
challengesmenu.extradata = NULL;
if (challengesmenu.unlockcondition)
Z_Free(challengesmenu.unlockcondition);
challengesmenu.unlockcondition = NULL;
M_CloseChallenges();
return true;
}
@ -1137,8 +1165,56 @@ boolean M_ChallengesInputs(INT32 ch)
if (challengesmenu.currentunlock < MAXUNLOCKABLES
&& gamedata->unlocked[challengesmenu.currentunlock])
{
unlockable_t *ref = &unlockables[challengesmenu.currentunlock];
boolean forceflip = false;
switch (unlockables[challengesmenu.currentunlock].type)
{
case SECRET_MAP:
{
// Only for 1p
if (setup_numplayers <= 1 && M_MenuConfirmPressed(pid))
{
// Map exists...
UINT16 mapnum = M_UnlockableMapNum(ref);
if (mapnum < nummapheaders && mapheaderinfo[mapnum])
{
// is tutorial...
INT32 guessgt = G_GuessGametypeByTOL(mapheaderinfo[mapnum]->typeoflevel);
if (guessgt == GT_TUTORIAL)
{
M_SetMenuDelay(pid);
multiplayer = true;
restoreMenu = currentMenu;
restorelevellist = levellist;
// mild hack
levellist.newgametype = guessgt;
levellist.netgame = false;
M_MenuToLevelPreamble(0, false);
D_MapChange(
mapnum+1,
guessgt,
false,
true,
1,
false,
false
);
M_CloseChallenges();
M_ClearMenus(true);
return false; // DO NOT
}
}
}
break;
}
case SECRET_ALTTITLE:
{
if (M_MenuConfirmPressed(pid))
@ -1147,6 +1223,103 @@ boolean M_ChallengesInputs(INT32 ch)
CV_AddValue(&cv_alttitle, 1);
S_StartSound(NULL, sfx_s3kc3s);
M_SetMenuDelay(pid);
forceflip = true;
}
break;
}
case SECRET_SKIN:
{
if (setup_numplayers <= 1 && cv_lastprofile[0].value != PROFILE_GUEST && M_MenuConfirmPressed(pid))
{
INT32 skin = M_UnlockableSkinNum(ref);
if (skin != -1)
{
profile_t *pr = PR_GetProfile(cv_lastprofile[0].value);
if (pr && strcmp(pr->skinname, skins[skin]->name))
{
strcpy(pr->skinname, skins[skin]->name);
CV_Set(&cv_skin[0], skins[skin]->name);
S_StartSound(NULL, sfx_s3k63);
S_StartSound(NULL, skins[skin]->soundsid[S_sfx[sfx_kattk1].skinsound]);
M_SetMenuDelay(pid);
forceflip = true;
}
}
}
break;
}
case SECRET_FOLLOWER:
{
if (!horngoner && M_MenuConfirmPressed(pid))
{
INT32 fskin = M_UnlockableFollowerNum(ref);
if (fskin != -1)
{
if (setup_numplayers <= 1 && cv_lastprofile[0].value != PROFILE_GUEST)
{
profile_t *pr = PR_GetProfile(cv_lastprofile[0].value);
if (pr && strcmp(pr->follower, followers[fskin].name))
{
strcpy(pr->follower, followers[fskin].name);
CV_Set(&cv_follower[0], followers[fskin].name);
challengesmenu.hornposting = 0;
S_StartSound(NULL, sfx_s3k63);
forceflip = true;
}
}
if (!forceflip)
challengesmenu.hornposting++;
if (challengesmenu.hornposting > EASEOFFHORN)
{
challengesmenu.hornposting = 0;
horngoner = true;
S_StartSound(NULL, sfx_s3k72);
}
else
{
S_StartSound(NULL, followers[fskin].hornsound);
}
M_SetMenuDelay(pid);
forceflip = true;
}
}
break;
}
case SECRET_COLOR:
{
if (setup_numplayers <= 1 && cv_lastprofile[0].value != PROFILE_GUEST && M_MenuConfirmPressed(pid))
{
INT32 colorid = M_UnlockableColorNum(ref);
if (colorid != SKINCOLOR_NONE)
{
profile_t *pr = PR_GetProfile(cv_lastprofile[0].value);
if (pr && pr->color != colorid)
{
pr->color = colorid;
CV_SetValue(&cv_playercolor[0], colorid);
if (setup_numplayers)
{
G_SetPlayerGamepadIndicatorToPlayerColor(0);
}
S_StartSound(NULL, sfx_s3k63);
M_SetMenuDelay(pid);
forceflip = true;
}
}
}
break;
}
@ -1167,7 +1340,7 @@ boolean M_ChallengesInputs(INT32 ch)
{
const char *trymusname = NULL;
UINT16 map = M_UnlockableMapNum(&unlockables[challengesmenu.currentunlock]);
UINT16 map = M_UnlockableMapNum(ref);
if (map >= nummapheaders
|| !mapheaderinfo[map])
{
@ -1196,15 +1369,18 @@ boolean M_ChallengesInputs(INT32 ch)
if (trymusname)
{
if (!Music_Playing("challenge_altmusic")
|| strcmp(Music_Song("challenge_altmusic"), trymusname))
const char *tune = "challenge_altmusic";
if (!Music_Playing(tune)
|| strcmp(Music_Song(tune), trymusname))
{
Music_Remap("challenge_altmusic", trymusname);
Music_Play("challenge_altmusic");
Music_Remap(tune, trymusname);
Music_Play(tune);
challengesmenu.nowplayingtile = (challengesmenu.hilix * CHALLENGEGRIDHEIGHT) + challengesmenu.hiliy;
}
else
{
Music_Stop("challenge_altmusic");
Music_Stop(tune);
challengesmenu.nowplayingtile = UINT16_MAX;
}
M_SetMenuDelay(pid);
@ -1217,6 +1393,16 @@ boolean M_ChallengesInputs(INT32 ch)
break;
}
if (forceflip)
{
UINT16 id = (challengesmenu.hilix * CHALLENGEGRIDHEIGHT) + challengesmenu.hiliy;
// This construction helps pressing too early
if (challengesmenu.extradata[id].flip <= TILEFLIP_MAX/2)
{
challengesmenu.extradata[id].flip = 1 + (TILEFLIP_MAX/2);
}
}
return true;
}
}

View file

@ -109,6 +109,11 @@ static void M_ProfileEditApply(void)
if (belongsto > -1 && belongsto < MAXSPLITSCREENPLAYERS)
{
PR_ApplyProfileToggles(optionsmenu.profilen, belongsto);
if (gamestate == GS_MENU)
{
// Safe to apply skin, etc here.
PR_ApplyProfileLight(optionsmenu.profilen, belongsto);
}
}
// Reapply player 1's real profile ID.

View file

@ -304,47 +304,6 @@ void M_CharacterSelectInit(void)
memset(setup_explosions, 0, sizeof(setup_explosions));
setup_animcounter = 0;
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
{
// Default to no follower / match colour.
setup_player[i].followern = -1;
setup_player[i].followercategory = -1;
setup_player[i].followercolor = SKINCOLOR_NONE;
setup_player[i].profilen_slide.start = 0;
setup_player[i].profilen_slide.dist = 0;
// If we're on prpfile select, skip straight to CSSTEP_CHARS
// do the same if we're midgame, but make sure to consider splitscreen properly.
if (optionsmenu.profile && i == 0)
{
setup_player[i].profilen = optionsmenu.profilen;
//PR_ApplyProfileLight(setup_player[i].profilen, 0);
M_SetupProfileGridPos(&setup_player[i]);
setup_player[i].mdepth = CSSTEP_CHARS;
}
else
{
// Set default selected profile to the last used profile for each player:
// (Make sure we don't overshoot it somehow if we deleted profiles or whatnot)
setup_player[i].profilen = min(cv_lastprofile[i].value, PR_GetNumProfiles());
if (gamestate != GS_MENU && i <= splitscreen)
{
M_SetupMidGameGridPos(&setup_player[i], i);
setup_player[i].mdepth = CSSTEP_CHARS;
}
else
{
// Un-set devices
G_SetDeviceForPlayer(i, -1);
#ifdef CHARSELECT_DEVICEDEBUG
CONS_Printf("M_CharacterSelectInit: Device for %d set to %d\n", i, -1);
#endif
}
}
}
for (i = 0; i < numskins; i++)
{
UINT8 x = skins[i]->kartspeed-1;
@ -391,6 +350,47 @@ void M_CharacterSelectInit(void)
}
setup_page = 0;
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
{
// Default to no follower / match colour.
setup_player[i].followern = -1;
setup_player[i].followercategory = -1;
setup_player[i].followercolor = SKINCOLOR_NONE;
setup_player[i].profilen_slide.start = 0;
setup_player[i].profilen_slide.dist = 0;
// If we're on prpfile select, skip straight to CSSTEP_CHARS
// do the same if we're midgame, but make sure to consider splitscreen properly.
if (optionsmenu.profile && i == 0)
{
setup_player[i].profilen = optionsmenu.profilen;
//PR_ApplyProfileLight(setup_player[i].profilen, 0);
M_SetupProfileGridPos(&setup_player[i]);
setup_player[i].mdepth = CSSTEP_CHARS;
}
else
{
// Set default selected profile to the last used profile for each player:
// (Make sure we don't overshoot it somehow if we deleted profiles or whatnot)
setup_player[i].profilen = min(cv_lastprofile[i].value, PR_GetNumProfiles());
if (gamestate != GS_MENU && i <= splitscreen)
{
M_SetupMidGameGridPos(&setup_player[i], i);
setup_player[i].mdepth = CSSTEP_CHARS;
}
else
{
// Un-set devices
G_SetDeviceForPlayer(i, -1);
#ifdef CHARSELECT_DEVICEDEBUG
CONS_Printf("M_CharacterSelectInit: Device for %d set to %d\n", i, -1);
#endif
}
}
}
}
@ -777,7 +777,7 @@ static boolean M_HandleBeginningColors(setup_player_t *p)
static void M_HandleBeginningFollowers(setup_player_t *p)
{
if (setup_numfollowercategories == 0)
if (horngoner || setup_numfollowercategories == 0)
{
p->followern = -1;
M_HandlePlayerFinalise(p);
@ -1392,7 +1392,9 @@ static void M_MPConfirmCharacterSelection(void)
CV_StealthSetValue(&cv_playercolor[i], col);
// follower
if (setup_player[i].followern < 0)
if (horngoner)
;
else if (setup_player[i].followern < 0)
CV_StealthSet(&cv_follower[i], "None");
else
CV_StealthSet(&cv_follower[i], followers[setup_player[i].followern].name);
@ -1457,9 +1459,12 @@ void M_CharacterSelectTick(void)
strcpy(optionsmenu.profile->skinname, skins[setup_player[0].skin]->name);
optionsmenu.profile->color = setup_player[0].color;
// save follower
strcpy(optionsmenu.profile->follower, followers[setup_player[0].followern].name);
optionsmenu.profile->followercolor = setup_player[0].followercolor;
if (!horngoner) // so you don't lose your choice after annoying the game
{
// save follower
strcpy(optionsmenu.profile->follower, followers[setup_player[0].followern].name);
optionsmenu.profile->followercolor = setup_player[0].followercolor;
}
// reset setup_player
memset(setup_player, 0, sizeof(setup_player));
@ -1475,7 +1480,9 @@ void M_CharacterSelectTick(void)
CV_StealthSet(&cv_skin[i], skins[setup_player[i].skin]->name);
CV_StealthSetValue(&cv_playercolor[i], setup_player[i].color);
if (setup_player[i].followern < 0)
if (horngoner)
;
else if (setup_player[i].followern < 0)
CV_StealthSet(&cv_follower[i], "None");
else
CV_StealthSet(&cv_follower[i], followers[setup_player[i].followern].name);

View file

@ -8099,7 +8099,7 @@ static void P_InitPlayers(void)
skin = 0;
}
if (netgame)
if (netgame || horngoner)
; // shouldn't happen but at least attempt to sync if it does
else for (i = 0; i < numfollowers; i++)
{

View file

@ -1615,7 +1615,7 @@ void Y_RoundQueueDrawer(y_data_t *standings, INT32 offset, boolean doanimations,
x - 9, y - 13,
(baseflags|((menuqueue.entries[i].encore) ? V_FLIP : 0)),
menuqueue.entries[i].mapnum,
NULL
NULL, FRACUNIT, 1
);
x += 24;