Merge branch 'challenges-continued' into 'master'

Updated Challenges Menu

See merge request KartKrew/Kart!971
This commit is contained in:
Oni 2023-02-25 04:37:02 +00:00
commit e1fd7bce99
12 changed files with 417 additions and 139 deletions

View file

@ -4359,7 +4359,7 @@ void G_LoadGameSettings(void)
}
#define GD_VERSIONCHECK 0xBA5ED123 // Change every major version, as usual
#define GD_VERSIONMINOR 0 // Change every format update
#define GD_VERSIONMINOR 1 // Change every format update
// G_LoadGameData
// Loads the main data file, which stores information such as emblems found, etc.
@ -4369,6 +4369,7 @@ void G_LoadGameData(void)
UINT32 versionID;
UINT8 versionMinor;
UINT8 rtemp;
boolean gridunusable = false;
savebuffer_t save = {0};
//For records
@ -4423,6 +4424,10 @@ void G_LoadGameData(void)
P_SaveBufferFree(&save);
I_Error("Game data is from the future! (expected %d, got %d)", GD_VERSIONMINOR, versionMinor);
}
if (versionMinor == 0)
{
gridunusable = true;
}
gamedata->totalplaytime = READUINT32(save.p);
gamedata->matchesplayed = READUINT32(save.p);
@ -4469,6 +4474,18 @@ void G_LoadGameData(void)
i += j;
}
if (gridunusable)
{
UINT16 burn = READUINT16(save.p); // Previous challengegridwidth
UINT8 height = (versionMinor > 0) ? CHALLENGEGRIDHEIGHT : 5;
save.p += (burn * height * sizeof(UINT8)); // Step over previous grid data
gamedata->challengegridwidth = 0;
Z_Free(gamedata->challengegrid);
gamedata->challengegrid = NULL;
}
else
{
gamedata->challengegridwidth = READUINT16(save.p);
Z_Free(gamedata->challengegrid);
if (gamedata->challengegridwidth)
@ -4485,6 +4502,7 @@ void G_LoadGameData(void)
{
gamedata->challengegrid = NULL;
}
}
gamedata->timesBeaten = READUINT32(save.p);

View file

@ -8037,7 +8037,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL, // missilestate
S_SPRK1, // deathstate
S_NULL, // xdeathstate
sfx_ncitem, // deathsound
sfx_None, // deathsound
1, // speed
16*FRACUNIT, // radius
30*FRACUNIT, // height

View file

@ -46,7 +46,6 @@ void K_DrawMapThumbnail(INT32 x, INT32 y, INT32 width, UINT32 flags, UINT16 map,
void K_DrawLikeMapThumbnail(INT32 x, INT32 y, INT32 width, UINT32 flags, patch_t *patch, UINT8 *colormap);
void K_drawTargetHUD(const vector3_t *origin, player_t *player);
extern patch_t *kp_facehighlight[8];
extern patch_t *kp_capsuletarget_arrow[2][2];
extern patch_t *kp_capsuletarget_icon[2];
extern patch_t *kp_capsuletarget_far[2];

View file

@ -1137,6 +1137,8 @@ void M_DrawAddons(void);
#define CC_ANIM 3
#define CC_MAX 4
#define TILEFLIP_MAX 16
// Keep track of some pause menu data for visual goodness.
extern struct challengesmenu_s {
@ -1151,7 +1153,7 @@ extern struct challengesmenu_s {
SINT8 row, hilix, focusx;
UINT8 col, hiliy;
UINT8 *extradata;
challengegridextradata_t *extradata;
boolean pending;
boolean requestnew;

View file

@ -1479,7 +1479,7 @@ static void M_DrawCharSelectPreview(UINT8 num)
static void M_DrawCharSelectExplosions(boolean charsel, INT16 basex, INT16 basey)
{
UINT8 i;
INT16 quadx = 0, quady = 0;
INT16 quadx = 2, quady = 2, mul = 22;
for (i = 0; i < CSEXPLOSIONS; i++)
{
@ -1495,13 +1495,14 @@ static void M_DrawCharSelectExplosions(boolean charsel, INT16 basex, INT16 basey
{
quadx = 4 * (setup_explosions[i].x / 3);
quady = 4 * (setup_explosions[i].y / 3);
mul = 16;
}
colormap = R_GetTranslationColormap(TC_DEFAULT, setup_explosions[i].color, GTC_MENUCACHE);
V_DrawMappedPatch(
basex + (setup_explosions[i].x*16) + quadx - 6,
basey + (setup_explosions[i].y*16) + quady - 6,
basex + (setup_explosions[i].x*mul) + quadx - 6,
basey + (setup_explosions[i].y*mul) + quady - 6,
0, W_CachePatchName(va("CHCNFRM%d", frame), PU_CACHE),
colormap
);
@ -4516,10 +4517,11 @@ static void M_DrawChallengeTile(INT16 i, INT16 j, INT32 x, INT32 y, boolean hili
{
unlockable_t *ref = NULL;
patch_t *pat = missingpat;
UINT8 *colormap = NULL;
fixed_t siz;
UINT8 *colormap = NULL, *bgmap = NULL;
fixed_t siz, accordion;
UINT8 id, num;
UINT32 edgelength;
boolean unlockedyet;
boolean categoryside;
id = (i * CHALLENGEGRIDHEIGHT) + j;
num = gamedata->challengegrid[id];
@ -4533,18 +4535,116 @@ static void M_DrawChallengeTile(INT16 i, INT16 j, INT32 x, INT32 y, boolean hili
// Okay, this is what we want to draw.
ref = &unlockables[num];
edgelength = (ref->majorunlock ? 30 : 14);
unlockedyet = !((gamedata->unlocked[num] == false)
|| (challengesmenu.pending && num == challengesmenu.currentunlock && challengesmenu.unlockanim <= UNLOCKTIME));
// ...unless we simply aren't unlocked yet.
if ((gamedata->unlocked[num] == false)
|| (challengesmenu.pending && num == challengesmenu.currentunlock && challengesmenu.unlockanim <= UNLOCKTIME))
// If we aren't unlocked yet, return early.
if (!unlockedyet)
{
V_DrawFill(x+1, y+1, edgelength, edgelength,
((challengesmenu.extradata[id] == CHE_HINT) ? 132 : 11));
UINT32 flags = 0;
if (challengesmenu.extradata[id].flags != CHE_HINT)
{
colormap = R_GetTranslationColormap(TC_BLINK, SKINCOLOR_BLACK, GTC_CACHE);
flags = V_SUBTRACT|V_90TRANS;
}
pat = W_CachePatchName(
va("UN_HNT%c%c",
(hili && !colormap) ? '1' : '2',
ref->majorunlock ? 'B' : 'A'
),
PU_CACHE);
V_DrawFixedPatch(
x*FRACUNIT, y*FRACUNIT,
FRACUNIT,
flags, pat,
colormap
);
pat = missingpat;
colormap = NULL;
goto drawborder;
}
if (ref->icon != NULL && ref->icon[0])
accordion = FRACUNIT;
if (challengesmenu.extradata[id].flip != 0
&& challengesmenu.extradata[id].flip != (TILEFLIP_MAX/2))
{
angle_t bad = (FixedAngle((fixed_t)(challengesmenu.extradata[id].flip) * (360*FRACUNIT/TILEFLIP_MAX)) >> ANGLETOFINESHIFT) & FINEMASK;
accordion = FINECOSINE(bad);
if (accordion < 0)
accordion = -accordion;
}
pat = W_CachePatchName(
(ref->majorunlock ? "UN_BORDB" : "UN_BORDA"),
PU_CACHE);
bgmap = R_GetTranslationColormap(TC_DEFAULT, SKINCOLOR_SILVER, GTC_MENUCACHE);
V_DrawStretchyFixedPatch(
(x*FRACUNIT) + (SHORT(pat->width)*(FRACUNIT-accordion)/2), y*FRACUNIT,
accordion,
FRACUNIT,
0, pat,
bgmap
);
pat = missingpat;
categoryside = (challengesmenu.extradata[id].flip <= TILEFLIP_MAX/4
|| challengesmenu.extradata[id].flip > (3*TILEFLIP_MAX)/4);
if (categoryside)
{
char categoryid = '8';
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_MASTERBOTS:
case SECRET_HARDSPEED:
case SECRET_ENCORE:
categoryid = '5';
break;
case SECRET_ALTTITLE:
case SECRET_SOUNDTEST:
categoryid = '6';
break;
case SECRET_TIMEATTACK:
case SECRET_BREAKTHECAPSULES:
case SECRET_SPECIALATTACK:
categoryid = '7';
break;
}
pat = W_CachePatchName(va("UN_RR0%c%c",
categoryid,
(ref->majorunlock) ? 'B' : 'A'),
PU_CACHE);
if (pat == missingpat)
{
pat = W_CachePatchName(va("UN_RR0%c%c",
categoryid,
(ref->majorunlock) ? 'A' : 'B'),
PU_CACHE);
}
}
else if (ref->icon != NULL && ref->icon[0])
{
pat = W_CachePatchName(ref->icon, PU_CACHE);
if (ref->color != SKINCOLOR_NONE && ref->color < numskincolors)
@ -4552,7 +4652,10 @@ static void M_DrawChallengeTile(INT16 i, INT16 j, INT32 x, INT32 y, boolean hili
colormap = R_GetTranslationColormap(TC_DEFAULT, ref->color, GTC_MENUCACHE);
}
}
else switch (ref->type)
else
{
UINT8 iconid = 0;
switch (ref->type)
{
case SECRET_SKIN:
{
@ -4575,35 +4678,84 @@ static void M_DrawChallengeTile(INT16 i, INT16 j, INT32 x, INT32 y, boolean hili
}
break;
}
/*case SECRET_MASTERBOTS:
iconid = 4;
break;*/
case SECRET_HARDSPEED:
iconid = 3;
break;
case SECRET_ENCORE:
iconid = 5;
break;
case SECRET_ALTTITLE:
iconid = 6;
break;
case SECRET_SOUNDTEST:
iconid = 1;
break;
case SECRET_TIMEATTACK:
iconid = 7;
break;
case SECRET_BREAKTHECAPSULES:
iconid = 8;
break;
case SECRET_SPECIALATTACK:
iconid = 9;
break;
default:
{
pat = W_CachePatchName(va("UN_RR00%c", ref->majorunlock ? 'B' : 'A'), PU_CACHE);
if (ref->color != SKINCOLOR_NONE && ref->color < numskincolors)
if (!colormap && ref->color != SKINCOLOR_NONE && ref->color < numskincolors)
{
//CONS_Printf(" color for %d is %s\n", num, skincolors[unlockables[num].color].name);
colormap = R_GetTranslationColormap(TC_RAINBOW, ref->color, GTC_MENUCACHE);
}
break;
}
}
if (pat == missingpat)
{
pat = W_CachePatchName(va("UN_IC%02u%c",
iconid,
ref->majorunlock ? 'B' : 'A'),
PU_CACHE);
if (pat == missingpat)
{
pat = W_CachePatchName(va("UN_IC%02u%c",
iconid,
ref->majorunlock ? 'A' : 'B'),
PU_CACHE);
}
}
}
siz = (SHORT(pat->width) << FRACBITS);
siz = FixedDiv(((ref->majorunlock) ? 32 : 16) << FRACBITS, siz);
V_SetClipRect(
(x+1) << FRACBITS, (y+1) << FRACBITS,
edgelength << FRACBITS, edgelength << FRACBITS,
0
);
V_DrawFixedPatch(
x*FRACUNIT, y*FRACUNIT,
siz,
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),
0, pat,
colormap
);
V_ClearClipRect();
}
else
{
V_DrawStretchyFixedPatch(
((x + 2)*FRACUNIT) + (16*(FRACUNIT-accordion)/2), (y + 2)*FRACUNIT,
FixedDiv(16*accordion, siz),
FixedDiv(16 << FRACBITS, siz),
0, pat,
colormap
);
}
drawborder:
if (!hili)
@ -4611,13 +4763,24 @@ drawborder:
return;
}
{
boolean maj = (ref != NULL && ref->majorunlock);
char buffer[9];
sprintf(buffer, "UN_RETA1");
buffer[6] = maj ? 'B' : 'A';
buffer[7] = (skullAnimCounter/5) ? '2' : '1';
pat = W_CachePatchName(buffer, PU_CACHE);
colormap = R_GetTranslationColormap(TC_DEFAULT, cv_playercolor[0].value, GTC_MENUCACHE);
V_DrawFixedPatch(
x*FRACUNIT, y*FRACUNIT,
((ref != NULL && ref->majorunlock) ? FRACUNIT*2 : FRACUNIT),
0, kp_facehighlight[(challengesmenu.ticker / 4) % 8],
NULL
FRACUNIT,
0, pat,
colormap
);
}
}
static void M_DrawChallengePreview(INT32 x, INT32 y)
{
@ -4819,6 +4982,9 @@ static void M_DrawChallengePreview(INT32 x, INT32 y)
}
}
#define challengetransparentstrength 8
#define challengesgridstep 22
void M_DrawChallenges(void)
{
INT32 x = currentMenu->x, explodex, selectx;
@ -4828,8 +4994,25 @@ void M_DrawChallenges(void)
INT16 offset;
{
patch_t *bg = W_CachePatchName("BGUNLCK2", PU_CACHE);
#define questionslow 4 // slows down the scroll by this factor
#define questionloop (questionslow*100) // modulo
INT32 questionoffset = (challengesmenu.ticker % questionloop);
patch_t *bg = W_CachePatchName("BGUNLCKG", PU_CACHE);
patch_t *qm = W_CachePatchName("BGUNLSC", PU_CACHE);
// Background gradient
V_DrawFixedPatch(0, 0, FRACUNIT, 0, bg, NULL);
// Scrolling question mark overlay
V_DrawFixedPatch(
-((160 + questionoffset)*FRACUNIT)/questionslow,
-(4*FRACUNIT) - (245*(FixedDiv((questionloop - questionoffset)*FRACUNIT, questionloop*FRACUNIT))),
FRACUNIT,
V_MODULATE,
qm,
NULL);
#undef questionslow
#undef questionloop
}
if (gamedata->challengegrid == NULL || challengesmenu.extradata == NULL)
@ -4838,43 +5021,45 @@ void M_DrawChallenges(void)
goto challengedesc;
}
x -= 16;
V_DrawFadeFill(0, y-2, BASEVIDWIDTH, 90, 0, 31, challengetransparentstrength);
x -= (challengesgridstep-1);
x += challengesmenu.offset;
if (challengegridloops)
{
if (!challengesmenu.col && challengesmenu.hilix)
x -= gamedata->challengegridwidth*16;
x -= gamedata->challengegridwidth*challengesgridstep;
i = challengesmenu.col + challengesmenu.focusx;
explodex = x - (i*16);
explodex = x - (i*challengesgridstep);
while (x < BASEVIDWIDTH-16)
while (x < BASEVIDWIDTH-challengesgridstep)
{
i = (i + 1) % gamedata->challengegridwidth;
x += 16;
x += challengesgridstep;
}
}
else
{
if (gamedata->challengegridwidth & 1)
x += 8;
x += (challengesgridstep/2);
i = gamedata->challengegridwidth-1;
explodex = x - (i*16)/2;
x += (i*16)/2;
explodex = x - (i*challengesgridstep)/2;
x += (i*challengesgridstep)/2;
}
selectx = explodex + (challengesmenu.hilix*16);
selectx = explodex + (challengesmenu.hilix*challengesgridstep);
while (i >= 0 && x >= -32)
while (i >= 0 && x >= -(challengesgridstep*2))
{
y = currentMenu->y-16;
y = currentMenu->y-challengesgridstep;
for (j = 0; j < CHALLENGEGRIDHEIGHT; j++)
{
y += 16;
y += challengesgridstep;
if (challengesmenu.extradata[(i * CHALLENGEGRIDHEIGHT) + j] & CHE_DONTDRAW)
if (challengesmenu.extradata[(i * CHALLENGEGRIDHEIGHT) + j].flags & CHE_DONTDRAW)
{
continue;
}
@ -4887,7 +5072,7 @@ void M_DrawChallenges(void)
M_DrawChallengeTile(i, j, x, y, false);
}
x -= 16;
x -= challengesgridstep;
i--;
if (challengegridloops && i < 0)
{
@ -4903,7 +5088,7 @@ void M_DrawChallenges(void)
challengesmenu.hilix,
challengesmenu.hiliy,
selectx,
currentMenu->y + (challengesmenu.hiliy*16),
currentMenu->y + (challengesmenu.hiliy*challengesgridstep),
true);
M_DrawCharSelectExplosions(false, explodex, currentMenu->y);
@ -4922,6 +5107,12 @@ challengedesc:
{
y = 120;
V_DrawScaledPatch(0, y,
(10-challengetransparentstrength)<<V_ALPHASHIFT,
W_CachePatchName("MENUHINT", PU_CACHE));
V_DrawFadeFill(0, y+27, BASEVIDWIDTH, BASEVIDHEIGHT - (y+27), 0, 31, challengetransparentstrength);
if (challengesmenu.currentunlock < MAXUNLOCKABLES)
{
str = unlockables[challengesmenu.currentunlock].name;
@ -4953,7 +5144,7 @@ challengedesc:
&& challengesmenu.currentunlock < MAXUNLOCKABLES
&& ((gamedata->unlocked[challengesmenu.currentunlock] == true)
|| ((challengesmenu.extradata != NULL)
&& (challengesmenu.extradata[i] & CHE_HINT))
&& (challengesmenu.extradata[i].flags & CHE_HINT))
)
)
{
@ -4961,6 +5152,9 @@ challengedesc:
}
}
#undef challengetransparentstrength
#undef challengesgridstep
// Statistics menu
#define STATSSTEP 10

View file

@ -1,5 +1,6 @@
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 2022-2023 by Vivian "toaster" Grannell.
// Copyright (C) 2012-2016 by Matthew "Kaito Sinclaire" Walsh.
// Copyright (C) 2012-2020 by Sonic Team Junior.
//
@ -259,28 +260,34 @@ quickcheckagain:
}
}
UINT8 *M_ChallengeGridExtraData(void)
void M_UpdateChallengeGridExtraData(challengegridextradata_t *extradata)
{
UINT8 i, j, num, id, tempid, work;
UINT8 *extradata;
boolean idchange;
if (!gamedata->challengegrid)
if (gamedata->challengegrid == NULL)
{
return NULL;
return;
}
extradata = Z_Malloc(
(gamedata->challengegridwidth * CHALLENGEGRIDHEIGHT * sizeof(UINT8)),
PU_STATIC, NULL);
if (!extradata)
if (extradata == NULL)
{
I_Error("M_ChallengeGridExtraData: was not able to allocate extradata");
return;
}
//CONS_Printf(" --- \n");
// Pre-wipe flags.
for (i = 0; i < gamedata->challengegridwidth; i++)
{
for (j = 0; j < CHALLENGEGRIDHEIGHT; j++)
{
id = (i * CHALLENGEGRIDHEIGHT) + j;
extradata[id].flags = CHE_NONE;
}
}
// Populate extra data.
for (i = 0; i < gamedata->challengegridwidth; i++)
{
for (j = 0; j < CHALLENGEGRIDHEIGHT; j++)
@ -289,8 +296,6 @@ UINT8 *M_ChallengeGridExtraData(void)
num = gamedata->challengegrid[id];
idchange = false;
extradata[id] = CHE_NONE;
// Empty spots in the grid are always unconnected.
if (num >= MAXUNLOCKABLES)
{
@ -304,13 +309,13 @@ UINT8 *M_ChallengeGridExtraData(void)
work = gamedata->challengegrid[tempid];
if (work == num)
{
extradata[id] = CHE_CONNECTEDUP;
extradata[id].flags = CHE_CONNECTEDUP;
// Get the id to write extra hint data to.
// This check is safe because extradata's order of population
if (extradata[tempid] & CHE_CONNECTEDLEFT)
if (extradata[tempid].flags & CHE_CONNECTEDLEFT)
{
extradata[id] |= CHE_CONNECTEDLEFT;
extradata[id].flags |= CHE_CONNECTEDLEFT;
//CONS_Printf(" %d - %d above %d is invalid, check to left\n", num, tempid, id);
if (i > 0)
{
@ -327,14 +332,14 @@ UINT8 *M_ChallengeGridExtraData(void)
id = tempid;
idchange = true;
if (extradata[id] == CHE_HINT)
if (extradata[id].flags == CHE_HINT)
{
continue;
}
}
else if (work < MAXUNLOCKABLES && gamedata->unlocked[work])
{
extradata[id] = CHE_HINT;
extradata[id].flags = CHE_HINT;
}
}
@ -356,11 +361,11 @@ UINT8 *M_ChallengeGridExtraData(void)
{
//CONS_Printf(" %d - %d to left of %d is valid\n", work, tempid, id);
// If we haven't already updated our id, it's the one to our left.
if (extradata[id] == CHE_HINT)
if (extradata[id].flags == CHE_HINT)
{
extradata[tempid] = CHE_HINT;
extradata[tempid].flags = CHE_HINT;
}
extradata[id] = CHE_CONNECTEDLEFT;
extradata[id].flags = CHE_CONNECTEDLEFT;
id = tempid;
}
/*else
@ -368,13 +373,13 @@ UINT8 *M_ChallengeGridExtraData(void)
}
else if (work < MAXUNLOCKABLES && gamedata->unlocked[work])
{
extradata[id] = CHE_HINT;
extradata[id].flags = CHE_HINT;
continue;
}
}
// Since we're not modifying id past this point, the conditions become much simpler.
if (extradata[id] == CHE_HINT)
if ((extradata[id].flags & (CHE_HINT|CHE_DONTDRAW)) == CHE_HINT)
{
continue;
}
@ -391,7 +396,7 @@ UINT8 *M_ChallengeGridExtraData(void)
}
else if (work < MAXUNLOCKABLES && gamedata->unlocked[work])
{
extradata[id] = CHE_HINT;
extradata[id].flags = CHE_HINT;
continue;
}
}
@ -414,14 +419,12 @@ UINT8 *M_ChallengeGridExtraData(void)
}
else if (work < MAXUNLOCKABLES && gamedata->unlocked[work])
{
extradata[id] = CHE_HINT;
extradata[id].flags = CHE_HINT;
continue;
}
}
}
}
return extradata;
}
void M_AddRawCondition(UINT8 set, UINT8 id, conditiontype_t c, INT32 r, INT16 x1, INT16 x2)
@ -909,7 +912,7 @@ boolean M_UpdateUnlockablesAndExtraEmblems(boolean loud)
{
if (loud)
{
S_StartSound(NULL, sfx_ncitem);
S_StartSound(NULL, sfx_achiev);
}
return true;
}

View file

@ -1,5 +1,6 @@
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 2022-2023 by Vivian "toaster" Grannell.
// Copyright (C) 2012-2016 by Matthew "Kaito Sinclaire" Walsh.
// Copyright (C) 2012-2020 by Sonic Team Junior.
//
@ -138,7 +139,7 @@ typedef enum
#define MAXEMBLEMS 512
#define MAXUNLOCKABLES MAXCONDITIONSETS
#define CHALLENGEGRIDHEIGHT 5
#define CHALLENGEGRIDHEIGHT 4
#ifdef DEVELOP
#define CHALLENGEGRIDLOOPWIDTH 3
#else
@ -192,12 +193,21 @@ void M_NewGameDataStruct(void);
// Challenges menu stuff
void M_PopulateChallengeGrid(void);
UINT8 *M_ChallengeGridExtraData(void);
struct challengegridextradata_t
{
UINT8 flags;
UINT8 flip;
};
void M_UpdateChallengeGridExtraData(challengegridextradata_t *extradata);
#define CHE_NONE 0
#define CHE_HINT 1
#define CHE_CONNECTEDLEFT (1<<1)
#define CHE_CONNECTEDUP (1<<2)
#define CHE_DONTDRAW (CHE_CONNECTEDLEFT|CHE_CONNECTEDUP)
char *M_BuildConditionSetString(UINT8 unlockid);
#define DESCRIPTIONWIDTH 170

View file

@ -72,7 +72,7 @@ static void M_ChallengesAutoFocus(UINT8 unlockid, boolean fresh)
continue;
}
if (challengesmenu.extradata[i] & CHE_CONNECTEDLEFT)
if (challengesmenu.extradata[i].flags & CHE_CONNECTEDLEFT)
{
// no need to check for CHE_CONNECTEDUP in linear iteration
continue;
@ -84,6 +84,16 @@ static void M_ChallengesAutoFocus(UINT8 unlockid, boolean fresh)
challengesmenu.col = challengesmenu.hilix = i/CHALLENGEGRIDHEIGHT;
challengesmenu.row = challengesmenu.hiliy = i%CHALLENGEGRIDHEIGHT;
// Begin animation
if (challengesmenu.extradata[i].flip == 0)
{
challengesmenu.extradata[i].flip =
(challengesmenu.pending
? (TILEFLIP_MAX/2)
: 1
);
}
if (fresh)
{
// We're just entering the menu. Immediately jump to the desired position...
@ -174,7 +184,12 @@ menu_t *M_InterruptMenuWithChallenges(menu_t *desiredmenu)
M_PopulateChallengeGrid();
if (gamedata->challengegrid)
challengesmenu.extradata = M_ChallengeGridExtraData();
{
challengesmenu.extradata = Z_Calloc(
(gamedata->challengegridwidth * CHALLENGEGRIDHEIGHT * sizeof(challengegridextradata_t)),
PU_STATIC, NULL);
M_UpdateChallengeGridExtraData(challengesmenu.extradata);
}
memset(setup_explosions, 0, sizeof(setup_explosions));
memset(&challengesmenu.unlockcount, 0, sizeof(challengesmenu.unlockcount));
@ -256,7 +271,8 @@ void M_Challenges(INT32 choice)
void M_ChallengesTick(void)
{
const UINT8 pid = 0;
UINT8 i, newunlock = MAXUNLOCKABLES;
UINT16 i;
UINT8 newunlock = MAXUNLOCKABLES;
// Ticking
challengesmenu.ticker++;
@ -270,6 +286,29 @@ void M_ChallengesTick(void)
challengesmenu.unlockcount[CC_ANIM]--;
M_CupSelectTick();
// Update tile flip state.
if (challengesmenu.extradata != NULL)
{
UINT16 id = (challengesmenu.hilix * CHALLENGEGRIDHEIGHT) + challengesmenu.hiliy;
boolean seeeveryone = M_MenuButtonHeld(pid, MBT_R);
boolean allthewaythrough;
UINT8 maxflip;
for (i = 0; i < (CHALLENGEGRIDHEIGHT * gamedata->challengegridwidth); i++)
{
allthewaythrough = (!seeeveryone && !challengesmenu.pending && i != id);
maxflip = ((seeeveryone || !allthewaythrough) ? (TILEFLIP_MAX/2) : TILEFLIP_MAX);
if ((seeeveryone || (challengesmenu.extradata[i].flip > 0))
&& (challengesmenu.extradata[i].flip != maxflip))
{
challengesmenu.extradata[i].flip++;
if (challengesmenu.extradata[i].flip >= TILEFLIP_MAX)
{
challengesmenu.extradata[i].flip = 0;
}
}
}
}
if (challengesmenu.pending)
{
// Pending mode.
@ -318,11 +357,15 @@ void M_ChallengesTick(void)
challengesmenu.unlockcount[CC_TALLY]++;
challengesmenu.unlockcount[CC_ANIM]++;
Z_Free(challengesmenu.extradata);
if ((challengesmenu.extradata = M_ChallengeGridExtraData()))
if (challengesmenu.extradata)
{
unlockable_t *ref = &unlockables[challengesmenu.currentunlock];
UINT16 bombcolor = SKINCOLOR_NONE;
unlockable_t *ref;
UINT16 bombcolor;
M_UpdateChallengeGridExtraData(challengesmenu.extradata);
ref = &unlockables[challengesmenu.currentunlock];
bombcolor = SKINCOLOR_NONE;
if (ref->color != SKINCOLOR_NONE && ref->color < numskincolors)
{
@ -413,8 +456,7 @@ boolean M_ChallengesInputs(INT32 ch)
gamedata->challengegrid = NULL;
gamedata->challengegridwidth = 0;
M_PopulateChallengeGrid();
Z_Free(challengesmenu.extradata);
challengesmenu.extradata = M_ChallengeGridExtraData();
M_UpdateChallengeGridExtraData(challengesmenu.extradata);
M_ChallengesAutoFocus(challengesmenu.currentunlock, true);
@ -461,8 +503,8 @@ boolean M_ChallengesInputs(INT32 ch)
}
if (!(challengesmenu.extradata[
(challengesmenu.col * CHALLENGEGRIDHEIGHT)
+ challengesmenu.row]
& CHE_CONNECTEDUP))
+ challengesmenu.row
].flags & CHE_CONNECTEDUP))
{
break;
}
@ -475,8 +517,8 @@ boolean M_ChallengesInputs(INT32 ch)
{
i = (challengesmenu.extradata[
(challengesmenu.col * CHALLENGEGRIDHEIGHT)
+ challengesmenu.row]
& CHE_CONNECTEDUP) ? 2 : 1;
+ challengesmenu.row
].flags & CHE_CONNECTEDUP) ? 2 : 1;
while (i > 0)
{
if (challengesmenu.row > 0)
@ -516,8 +558,8 @@ boolean M_ChallengesInputs(INT32 ch)
if (!(challengesmenu.extradata[
(challengesmenu.col * CHALLENGEGRIDHEIGHT)
+ challengesmenu.row]
& CHE_CONNECTEDLEFT))
+ challengesmenu.row
].flags & CHE_CONNECTEDLEFT))
{
break;
}
@ -531,8 +573,8 @@ boolean M_ChallengesInputs(INT32 ch)
{
i = (challengesmenu.extradata[
(challengesmenu.col * CHALLENGEGRIDHEIGHT)
+ challengesmenu.row]
& CHE_CONNECTEDLEFT) ? 2 : 1;
+ challengesmenu.row
].flags & CHE_CONNECTEDLEFT) ? 2 : 1;
while (i > 0)
{
// Slide the focus counter to movement, if we can.
@ -570,12 +612,12 @@ boolean M_ChallengesInputs(INT32 ch)
{
// Adjust highlight coordinates up/to the left for large tiles.
if (challengesmenu.hiliy > 0 && (challengesmenu.extradata[i] & CHE_CONNECTEDUP))
if (challengesmenu.hiliy > 0 && (challengesmenu.extradata[i].flags & CHE_CONNECTEDUP))
{
challengesmenu.hiliy--;
}
if ((challengesmenu.extradata[i] & CHE_CONNECTEDLEFT))
if ((challengesmenu.extradata[i].flags & CHE_CONNECTEDLEFT))
{
if (challengesmenu.hilix > 0)
{
@ -586,8 +628,14 @@ boolean M_ChallengesInputs(INT32 ch)
challengesmenu.hilix = gamedata->challengegridwidth-1;
}
}
i = (challengesmenu.hilix * CHALLENGEGRIDHEIGHT) + challengesmenu.hiliy;
}
// Begin animation
if (challengesmenu.extradata[i].flip == 0)
challengesmenu.extradata[i].flip++;
return true;
}

View file

@ -552,7 +552,8 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
if (P_IsLocalPlayer(player) && !gamedata->collected[special->health-1])
{
gamedata->collected[special->health-1] = gotcollected = true;
M_UpdateUnlockablesAndExtraEmblems(true);
if (!M_UpdateUnlockablesAndExtraEmblems(true))
S_StartSound(NULL, sfx_ncitem);
G_SaveGameData();
}

View file

@ -1101,6 +1101,7 @@ sfxinfo_t S_sfx[NUMSFX] =
{"typri1", false, 64, 16, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // SA2 boss typewriting 1
{"typri2", false, 64, 16, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // SA2 final boss-type typewriting
{"eggspr", false, 64, 16, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Sonic Unleashed Trap Spring
{"achiev", false, 204, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Achievement"},
// SRB2Kart - Drop target sounds
{"kdtrg1", false, 64, 16, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Low energy, SF_X8AWAYSOUND

View file

@ -1168,6 +1168,7 @@ typedef enum
sfx_typri1,
sfx_typri2,
sfx_eggspr,
sfx_achiev,
// SRB2Kart - Drop target sounds
sfx_kdtrg1,

View file

@ -209,6 +209,7 @@ TYPEDEF (conditionset_t);
TYPEDEF (emblem_t);
TYPEDEF (unlockable_t);
TYPEDEF (gamedata_t);
TYPEDEF (challengegridextradata_t);
// m_dllist.h
TYPEDEF (mdllistitem_t);