levelheader_t: relevantskin property

- On level load for GT_TUTORIAL:
    - Forces to requested skin (or Eggman if not specified).
        - Named `relevantskin` and not `tutorialskin` in case it's useful to use the same apparatus later for Adventure.
    - Also sets default skincolor and disables follower.
This commit is contained in:
toaster 2023-03-26 22:34:37 +01:00
parent 24d8b20124
commit e732f37258
4 changed files with 43 additions and 0 deletions

View file

@ -1122,6 +1122,11 @@ void readlevelheader(MYFILE *f, char * name)
deh_strlcpy(mapheaderinfo[num]->zonttl, word2,
sizeof(mapheaderinfo[num]->zonttl), va("Level header %d: zonetitle", num));
}
else if (fastcmp(word, "RELEVANTSKIN"))
{
deh_strlcpy(mapheaderinfo[num]->relevantskin, word2,
sizeof(mapheaderinfo[num]->relevantskin), va("Level header %d: relevantskin", num));
}
else if (fastcmp(word, "SCRIPTNAME"))
{
deh_strlcpy(mapheaderinfo[num]->scriptname, word2,

View file

@ -427,6 +427,7 @@ struct mapheader_t
UINT32 typeoflevel; ///< Combination of typeoflevel flags.
UINT8 numlaps; ///< Number of laps in circuit mode, unless overridden.
fixed_t gravity; ///< Map-wide gravity.
char relevantskin[SKINNAMESIZE+1]; ///< Skin to use for tutorial (if not provided, uses Eggman.)
// Music information
char musname[MAXMUSNAMES][7]; ///< Music tracks to play. First dimension is the track number, second is the music string. "" for no music.

View file

@ -389,6 +389,7 @@ static void P_ClearSingleMapHeaderInfo(INT16 num)
mapheaderinfo[num]->typeoflevel = 0;
mapheaderinfo[num]->gravity = DEFAULT_GRAVITY;
mapheaderinfo[num]->keywords[0] = '\0';
mapheaderinfo[num]->relevantskin[0] = '\0';
mapheaderinfo[num]->musname[0][0] = 0;
mapheaderinfo[num]->musname_size = 0;
mapheaderinfo[num]->positionmus[0] = '\0';
@ -7392,6 +7393,27 @@ static void P_InitCamera(void)
static void P_InitPlayers(void)
{
UINT8 i;
INT32 skin = -1;
// Are we forcing a character?
if (gametype == GT_TUTORIAL)
{
// Get skin from name.
if (mapheaderinfo[gamemap-1] && mapheaderinfo[gamemap-1]->relevantskin[0])
{
skin = R_SkinAvailable(mapheaderinfo[gamemap-1]->relevantskin);
}
else
{
skin = R_SkinAvailable(DEFAULTSKIN);
}
// Handle invalid case.
if (skin == -1)
{
skin = 0;
}
}
for (i = 0; i < MAXPLAYERS; i++)
{
@ -7400,6 +7422,15 @@ static void P_InitPlayers(void)
players[i].mo = NULL;
// If we're forcing a character, do it now.
if (skin != -1)
{
players[i].skin = skin;
players[i].skincolor = skins[skin].prefcolor;
players[i].followerskin = -1;
// followercolor can be left alone for hopefully obvious reasons
}
if (!(gametyperules & GTR_CIRCUIT) && K_PodiumSequence() == false)
{
G_DoReborn(i);

View file

@ -236,6 +236,12 @@ boolean R_SkinUsable(INT32 playernum, INT32 skinnum, boolean demoskins)
return true;
}
if (gametype == GT_TUTORIAL)
{
// Being forced to play as this character by the tutorial
return true;
}
// Determine if this character is supposed to be unlockable or not
if (useplayerstruct && demo.playback)
{