mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
As promised, Encore (alt)music
- `EncoreMusic` on mapheader
- Supports up to 3 alt musics, as with every other type
- Do not vape/nightcoreify if provided
- To avoid complicating the Alt Music logic too much, uses "side B" of the same Prison Egg CD
- That is to say, if there are 2 encore tracks and 3 normal tracks, the second Encore track will only play if you've gotten the CD associated with the second normal track
I haven't actually tested it *with* any Encore music, but I've triplechecked literally everywhere to make sure it didn't break standard play
This commit is contained in:
parent
0f6ddefe30
commit
6e46f97847
8 changed files with 112 additions and 18 deletions
|
|
@ -1242,6 +1242,30 @@ void readlevelheader(MYFILE *f, char * name)
|
|||
mapheaderinfo[num]->musname_size = j;
|
||||
}
|
||||
}
|
||||
else if (fastcmp(word, "ENCOREMUSIC"))
|
||||
{
|
||||
if (fastcmp(word2, "NONE"))
|
||||
{
|
||||
mapheaderinfo[num]->encoremusname[0][0] = 0; // becomes empty string
|
||||
mapheaderinfo[num]->encoremusname_size = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
UINT8 j = 0; // i was declared elsewhere
|
||||
tmp = strtok(word2, ",");
|
||||
do {
|
||||
if (j >= MAXMUSNAMES)
|
||||
break;
|
||||
deh_strlcpy(mapheaderinfo[num]->encoremusname[j], tmp,
|
||||
sizeof(mapheaderinfo[num]->encoremusname[j]), va("Level header %d: encore music", num));
|
||||
j++;
|
||||
} while ((tmp = strtok(NULL,",")) != NULL);
|
||||
|
||||
if (tmp != NULL)
|
||||
deh_warning("Level header %d: additional music slots past %d discarded", num, MAXMUSNAMES);
|
||||
mapheaderinfo[num]->encoremusname_size = j;
|
||||
}
|
||||
}
|
||||
else if (fastcmp(word, "ASSOCIATEDMUSIC"))
|
||||
{
|
||||
if (fastcmp(word2, "NONE"))
|
||||
|
|
|
|||
|
|
@ -515,10 +515,12 @@ struct mapheader_t
|
|||
|
||||
// Music information
|
||||
char musname[MAXMUSNAMES][7]; ///< Music tracks to play. First dimension is the track number, second is the music string. "" for no music.
|
||||
char encoremusname[MAXMUSNAMES][7]; ///< Music tracks to play in Encore. First dimension is the track number, second is the music string. "" for no music.
|
||||
UINT16 cache_muslock[MAXMUSNAMES-1]; ///< Cached Alt Music IDs
|
||||
char associatedmus[MAXMUSNAMES][7]; ///< Associated music tracks for sound test unlock.
|
||||
char positionmus[7]; ///< Custom Position track. Doesn't play in Encore or other fun game-controlled contexts
|
||||
UINT8 musname_size; ///< Number of music tracks defined
|
||||
UINT8 encoremusname_size; ///< Number of Encore music tracks defined
|
||||
UINT8 associatedmus_size; ///< Number of associated music tracks defined
|
||||
UINT16 mustrack; ///< Subsong to play. Only really relevant for music modules and specific formats supported by GME. 0 to ignore.
|
||||
UINT32 muspos; ///< Music position to jump to.
|
||||
|
|
|
|||
|
|
@ -1247,7 +1247,14 @@ void K_ResetCeremony(void)
|
|||
mapmusrng = 0;
|
||||
}
|
||||
|
||||
while (mapmusrng >= std::max<UINT8>(1, mapheaderinfo[gamemap-1]->musname_size))
|
||||
UINT8 limit = (encoremode && mapheaderinfo[gamemap-1]->encoremusname_size)
|
||||
? mapheaderinfo[gamemap-1]->encoremusname_size
|
||||
: mapheaderinfo[gamemap-1]->musname_size;
|
||||
|
||||
if (limit < 1)
|
||||
limit = 1;
|
||||
|
||||
while (mapmusrng >= limit)
|
||||
{
|
||||
mapmusrng--;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2507,12 +2507,36 @@ static int mapheaderinfo_get(lua_State *L)
|
|||
lua_rawseti(L, -2, 1 + i);
|
||||
}
|
||||
}
|
||||
else if (fastcmp(field,"encoremusname")) // we create a table here because it saves us from a userdata nightmare
|
||||
{
|
||||
UINT8 i;
|
||||
lua_createtable(L, header->encoremusname_size, 0);
|
||||
for (i = 0; i < header->encoremusname_size; i++)
|
||||
{
|
||||
lua_pushstring(L, header->encoremusname[i]);
|
||||
lua_rawseti(L, -2, 1 + i);
|
||||
}
|
||||
}
|
||||
else if (fastcmp(field,"associatedmus")) // we create a table here because it saves us from a userdata nightmare
|
||||
{
|
||||
UINT8 i;
|
||||
lua_createtable(L, header->associatedmus_size, 0);
|
||||
for (i = 0; i < header->associatedmus_size; i++)
|
||||
{
|
||||
lua_pushstring(L, header->associatedmus[i]);
|
||||
lua_rawseti(L, -2, 1 + i);
|
||||
}
|
||||
}
|
||||
else if (fastcmp(field,"mustrack"))
|
||||
lua_pushinteger(L, header->mustrack);
|
||||
else if (fastcmp(field,"muspos"))
|
||||
lua_pushinteger(L, header->muspos);
|
||||
else if (fastcmp(field,"musname_size"))
|
||||
lua_pushinteger(L, header->musname_size);
|
||||
else if (fastcmp(field,"encoremusname_size"))
|
||||
lua_pushinteger(L, header->encoremusname_size);
|
||||
else if (fastcmp(field,"associatedmus_size"))
|
||||
lua_pushinteger(L, header->associatedmus_size);
|
||||
else if (fastcmp(field,"weather"))
|
||||
lua_pushinteger(L, header->weather);
|
||||
else if (fastcmp(field,"skytexture"))
|
||||
|
|
|
|||
|
|
@ -1077,7 +1077,8 @@ static void M_PrecacheLevelLocks(void)
|
|||
if (map < nummapheaders
|
||||
&& mapheaderinfo[map])
|
||||
{
|
||||
for (j = 1; j < mapheaderinfo[map]->musname_size; j++)
|
||||
UINT8 greatersize = max(mapheaderinfo[map]->musname_size, mapheaderinfo[map]->encoremusname_size);
|
||||
for (j = 1; j < greatersize; j++)
|
||||
{
|
||||
if (mapheaderinfo[map]->cache_muslock[j - 1] != MAXUNLOCKABLES)
|
||||
{
|
||||
|
|
@ -1143,7 +1144,7 @@ static void M_PrecacheLevelLocks(void)
|
|||
|
||||
break;
|
||||
}
|
||||
if (j == mapheaderinfo[map]->musname_size)
|
||||
if (j == greatersize)
|
||||
CONS_Alert(CONS_ERROR, "Unlockable %u: Too many SECRET_ALTMUSICs associated with Level %s\n", i+1, mapheaderinfo[map]->lumpname);
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -103,7 +103,12 @@ public:
|
|||
return (1.f/encoremul);
|
||||
}
|
||||
|
||||
return encoremul;
|
||||
if (!nightcoreable
|
||||
|| mapheaderinfo[gamemap-1]->encoremusname_size == 0)
|
||||
{
|
||||
// We only vape if the level doesn't have alternate tracks.
|
||||
return encoremul;
|
||||
}
|
||||
}
|
||||
|
||||
return 1.f;
|
||||
|
|
|
|||
|
|
@ -446,6 +446,8 @@ static void P_ClearSingleMapHeaderInfo(INT16 num)
|
|||
|
||||
mapheaderinfo[num]->musname[0][0] = 0;
|
||||
mapheaderinfo[num]->musname_size = 0;
|
||||
mapheaderinfo[num]->encoremusname[0][0] = 0;
|
||||
mapheaderinfo[num]->encoremusname_size = 0;
|
||||
|
||||
for (i = 0; i < MAXMUSNAMES-1; i++)
|
||||
{
|
||||
|
|
@ -8194,6 +8196,9 @@ void P_ResetLevelMusic(void)
|
|||
UINT8 idx = 0;
|
||||
|
||||
mapheader_t* mapheader = mapheaderinfo[gamemap - 1];
|
||||
UINT8 truesize = (encoremode && mapheader->encoremusname_size)
|
||||
? mapheader->encoremusname_size
|
||||
: mapheader->musname_size;
|
||||
|
||||
// To keep RNG in sync, we will always pull from RNG, even if unused
|
||||
UINT32 random = P_Random(PR_MUSICSELECT);
|
||||
|
|
@ -8201,20 +8206,20 @@ void P_ResetLevelMusic(void)
|
|||
if (demo.playback)
|
||||
{
|
||||
// mapmusrng has already been set by the demo; just make sure it's valid
|
||||
if (mapmusrng >= mapheader->musname_size)
|
||||
if (mapmusrng >= truesize)
|
||||
{
|
||||
mapmusrng = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (mapheader->musname_size > 1)
|
||||
if (truesize > 1)
|
||||
{
|
||||
UINT8 tempmapmus[MAXMUSNAMES], tempmapmus_size = 1, i;
|
||||
|
||||
tempmapmus[0] = 0;
|
||||
|
||||
for (i = 1; i < mapheader->musname_size; i++)
|
||||
for (i = 1; i < truesize; i++)
|
||||
{
|
||||
if (mapheader->cache_muslock[i-1] < MAXUNLOCKABLES
|
||||
&& !M_CheckNetUnlockByID(mapheader->cache_muslock[i-1]))
|
||||
|
|
@ -8260,7 +8265,12 @@ void P_LoadLevelMusic(void)
|
|||
mapheader_t* mapheader = mapheaderinfo[gamemap-1];
|
||||
const char *music = mapheader->musname[0];
|
||||
|
||||
if (mapmusrng < mapheader->musname_size)
|
||||
if (encoremode && mapheader->encoremusname_size
|
||||
&& mapmusrng < mapheader->encoremusname_size)
|
||||
{
|
||||
music = mapheader->encoremusname[mapmusrng];
|
||||
}
|
||||
else if (mapmusrng < mapheader->musname_size)
|
||||
{
|
||||
music = mapheader->musname[mapmusrng];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1292,6 +1292,11 @@ static void S_InsertMapIntoSoundTestSequence(UINT16 map, musicdef_t ***tail)
|
|||
{
|
||||
S_InsertMusicAtSoundTestSequenceTail(mapheaderinfo[map]->associatedmus[i], map, ALTREF_REQUIRESBEATEN, tail);
|
||||
}
|
||||
|
||||
for (i = 0; i < mapheaderinfo[map]->encoremusname_size; i++)
|
||||
{
|
||||
S_InsertMusicAtSoundTestSequenceTail(mapheaderinfo[map]->encoremusname[i], map, i+MAXMUSNAMES, tail);
|
||||
}
|
||||
}
|
||||
|
||||
void S_PopulateSoundTestSequence(void)
|
||||
|
|
@ -1435,17 +1440,33 @@ static boolean S_SoundTestDefLocked(musicdef_t *def)
|
|||
&& !(header->records.mapvisited & MV_VISITED))
|
||||
return true;
|
||||
|
||||
// Associated music only when completed
|
||||
if ((def->sequence.altref == ALTREF_REQUIRESBEATEN)
|
||||
&& !(header->records.mapvisited & MV_BEATEN))
|
||||
return true;
|
||||
|
||||
if (def->sequence.altref != 0 && def->sequence.altref < header->musname_size)
|
||||
if (def->sequence.altref != 0)
|
||||
{
|
||||
// Alt music requires unlocking the alt
|
||||
if ((header->cache_muslock[def->sequence.altref - 1] < MAXUNLOCKABLES)
|
||||
&& gamedata->unlocked[header->cache_muslock[def->sequence.altref - 1]] == false)
|
||||
return true;
|
||||
if ((def->sequence.altref == ALTREF_REQUIRESBEATEN))
|
||||
{
|
||||
// Associated music only when completed
|
||||
if (!(header->records.mapvisited & MV_BEATEN))
|
||||
return true;
|
||||
}
|
||||
else if (def->sequence.altref < MAXMUSNAMES)
|
||||
{
|
||||
// Alt music requires unlocking the alt
|
||||
if ((header->cache_muslock[def->sequence.altref - 1] < MAXUNLOCKABLES)
|
||||
&& gamedata->unlocked[header->cache_muslock[def->sequence.altref - 1]] == false)
|
||||
return true;
|
||||
}
|
||||
else if (def->sequence.altref < MAXMUSNAMES*2)
|
||||
{
|
||||
// Encore!
|
||||
if (M_SecretUnlocked(SECRET_ENCORE, true) == false)
|
||||
return true;
|
||||
|
||||
// Side B of the same CD
|
||||
if (def->sequence.altref > MAXMUSNAMES
|
||||
&& (header->cache_muslock[def->sequence.altref - (1 + MAXMUSNAMES)] < MAXUNLOCKABLES)
|
||||
&& gamedata->unlocked[header->cache_muslock[def->sequence.altref - (1 + MAXMUSNAMES)]] == false)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Finally, do a full-fat map check.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue