Mapheader Followers system

Replaces Flicky List system from 2.2.
Specify a list of comma-seperated Followers.
Not used by any systems in this commit, but important to store the data for later.
This commit is contained in:
toaster 2023-04-20 23:01:13 +01:00
parent 9eacdb4be4
commit 5f15736626
7 changed files with 70 additions and 112 deletions

View file

@ -187,7 +187,7 @@ void clear_levels(void)
// (no need to set num to 0, we're freeing the entire header shortly)
Z_Free(mapheaderinfo[nummapheaders]->customopts);
P_DeleteFlickies(nummapheaders);
P_DeleteHeaderFollowers(nummapheaders);
Z_Free(mapheaderinfo[nummapheaders]->mainrecord);
@ -1042,77 +1042,47 @@ void readlevelheader(MYFILE *f, char * name)
// Now go to uppercase
strupr(word2);
// List of flickies that are be freed in this map
if (fastcmp(word, "FLICKYLIST") || fastcmp(word, "ANIMALLIST"))
// List of followers that are be freed in this map
if (fastcmp(word, "FOLLOWERS"))
{
if (fastcmp(word2, "NONE"))
P_DeleteFlickies(num);
else if (fastcmp(word2, "DEMO"))
P_SetDemoFlickies(num);
else if (fastcmp(word2, "ALL"))
{
mobjtype_t tmpflickies[MAXFLICKIES];
for (mapheaderinfo[num]->numFlickies = 0;
((mapheaderinfo[num]->numFlickies < MAXFLICKIES) && FLICKYTYPES[mapheaderinfo[num]->numFlickies].type);
mapheaderinfo[num]->numFlickies++)
tmpflickies[mapheaderinfo[num]->numFlickies] = FLICKYTYPES[mapheaderinfo[num]->numFlickies].type;
if (mapheaderinfo[num]->numFlickies) // just in case...
{
size_t newsize = sizeof(mobjtype_t) * mapheaderinfo[num]->numFlickies;
mapheaderinfo[num]->flickies = Z_Realloc(mapheaderinfo[num]->flickies, newsize, PU_STATIC, NULL);
M_Memcpy(mapheaderinfo[num]->flickies, tmpflickies, newsize);
}
}
P_DeleteHeaderFollowers(num);
else if (fastcmp(word2, "DEFAULT"))
P_SetDefaultHeaderFollowers(num);
else
{
mobjtype_t tmpflickies[MAXFLICKIES];
mapheaderinfo[num]->numFlickies = 0;
INT16 tmpfollowers[MAXHEADERFOLLOWERS];
mapheaderinfo[num]->numFollowers = 0;
tmp = strtok(word2,",");
// get up to the first MAXFLICKIES flickies
// get up to the first MAXHEADERFOLLOWERS followers
do {
if (mapheaderinfo[num]->numFlickies == MAXFLICKIES) // never going to get above that number
if (mapheaderinfo[num]->numFollowers == MAXHEADERFOLLOWERS) // never going to get above that number
{
deh_warning("Level header %d: too many flickies\n", num);
deh_warning("Level header %d: too many followers\n", num);
break;
}
if (fastncmp(tmp, "MT_", 3)) // support for specified mobjtypes...
{
i = get_mobjtype(tmp);
if (!i)
i = K_FollowerAvailable(tmp);
if (i == -1)
{
//deh_warning("Level header %d: unknown flicky mobj type %s\n", num, tmp); -- no need for this line as get_mobjtype complains too
deh_warning("Level header %d: unknown follower selection %s\n", num, tmp);
continue;
}
tmpflickies[mapheaderinfo[num]->numFlickies] = i;
tmpfollowers[mapheaderinfo[num]->numFollowers] = i;
mapheaderinfo[num]->numFollowers++;
}
else // ...or a quick, limited selection of default flickies!
{
for (i = 0; FLICKYTYPES[i].name; i++)
if (fastcmp(tmp, FLICKYTYPES[i].name))
break;
if (!FLICKYTYPES[i].name)
{
deh_warning("Level header %d: unknown flicky selection %s\n", num, tmp);
continue;
}
tmpflickies[mapheaderinfo[num]->numFlickies] = FLICKYTYPES[i].type;
}
mapheaderinfo[num]->numFlickies++;
} while ((tmp = strtok(NULL,",")) != NULL);
if (mapheaderinfo[num]->numFlickies)
if (mapheaderinfo[num]->numFollowers)
{
size_t newsize = sizeof(mobjtype_t) * mapheaderinfo[num]->numFlickies;
mapheaderinfo[num]->flickies = Z_Realloc(mapheaderinfo[num]->flickies, newsize, PU_STATIC, NULL);
size_t newsize = sizeof(UINT16) * mapheaderinfo[num]->numFollowers;
mapheaderinfo[num]->followers = Z_Realloc(mapheaderinfo[num]->followers, newsize, PU_STATIC, NULL);
// now we add them to the list!
M_Memcpy(mapheaderinfo[num]->flickies, tmpflickies, newsize);
M_Memcpy(mapheaderinfo[num]->followers, tmpfollowers, newsize);
}
else
deh_warning("Level header %d: no valid flicky types found\n", num);
deh_warning("Level header %d: no valid follower types found\n", num);
}
}

View file

@ -31,31 +31,6 @@ char *FREE_MOBJS[NUMMOBJFREESLOTS];
char *FREE_SKINCOLORS[NUMCOLORFREESLOTS];
UINT8 used_spr[(NUMSPRITEFREESLOTS / 8) + 1]; // Bitwise flag for sprite freeslot in use! I would use ceil() here if I could, but it only saves 1 byte of memory anyway.
struct flickytypes_s FLICKYTYPES[] = {
{"BLUEBIRD", MT_FLICKY_01}, // Flicky (Flicky)
{"RABBIT", MT_FLICKY_02}, // Pocky (1)
{"CHICKEN", MT_FLICKY_03}, // Cucky (1)
{"SEAL", MT_FLICKY_04}, // Rocky (1)
{"PIG", MT_FLICKY_05}, // Picky (1)
{"CHIPMUNK", MT_FLICKY_06}, // Ricky (1)
{"PENGUIN", MT_FLICKY_07}, // Pecky (1)
{"FISH", MT_FLICKY_08}, // Nicky (CD)
{"RAM", MT_FLICKY_09}, // Flocky (CD)
{"PUFFIN", MT_FLICKY_10}, // Wicky (CD)
{"COW", MT_FLICKY_11}, // Macky (SRB2)
{"RAT", MT_FLICKY_12}, // Micky (2)
{"BEAR", MT_FLICKY_13}, // Becky (2)
{"DOVE", MT_FLICKY_14}, // Docky (CD)
{"CAT", MT_FLICKY_15}, // Nyannyan (Flicky)
{"CANARY", MT_FLICKY_16}, // Lucky (CD)
{"a", 0}, // End of normal flickies - a lower case character so will never fastcmp valid with uppercase tmp
//{"FLICKER", MT_FLICKER}, // Flacky (SRB2)
{"SPIDER", MT_SECRETFLICKY_01}, // Sticky (SRB2)
{"BAT", MT_SECRETFLICKY_02}, // Backy (SRB2)
{"SEED", MT_SEED}, // Seed (CD)
{NULL, 0}
};
// IMPORTANT!
// DO NOT FORGET TO SYNC THIS LIST WITH THE ACTIONNUM ENUM IN INFO.H
actionpointer_t actionpointers[] =

View file

@ -41,8 +41,6 @@ struct flickytypes_s {
const mobjtype_t type;
};
#define MAXFLICKIES 64
/** Action pointer for reading actions from Dehacked lumps.
*/
struct actionpointer_t

View file

@ -386,6 +386,7 @@ struct staffbrief_t
};
#define MAXMUSNAMES 3 // maximum definable music tracks per level
#define MAXHEADERFOLLOWERS 32
/** Map header information.
*/
@ -458,9 +459,9 @@ struct mapheader_t
boolean use_light_angle; ///< When false, wall lighting is evenly distributed. When true, wall lighting is directional.
angle_t light_angle; ///< Angle of directional wall lighting.
// Freed animal information
UINT8 numFlickies; ///< Internal. For freed flicky support.
mobjtype_t *flickies; ///< List of freeable flickies in this level. Allocated dynamically for space reasons. Be careful.
// Audience information
UINT8 numFollowers; ///< Internal. For audience support.
UINT16 *followers; ///< List of audience followers in this level. Allocated dynamically for space reasons. Be careful.
// Script information
char runsoc[33]; ///< SOC to execute at start of level (32 character limit instead of 63)

View file

@ -10234,13 +10234,8 @@ mobj_t *P_InternalFlickySpawn(mobj_t *actor, mobjtype_t flickytype, fixed_t momz
if (!flickytype)
{
if (!mapheaderinfo[gamemap-1] || !mapheaderinfo[gamemap-1]->numFlickies) // No mapheader, no shoes, no service.
return NULL;
else
{
INT32 prandom = P_RandomKey(PR_UNDEFINED, mapheaderinfo[gamemap-1]->numFlickies);
flickytype = mapheaderinfo[gamemap-1]->flickies[prandom];
}
// The flicky list system has been removed, so no backups are possible.
return NULL;
}
if (moveforward)

View file

@ -347,31 +347,50 @@ FUNCNORETURN static ATTRNORETURN void CorruptMapError(const char *msg)
I_Error("Invalid or corrupt map.\nLook in log file or text console for technical details.");
}
/** Sets a header's flickies to be equivalent to the original Freed Animals
/** Sets a header's followers to the default list
*
* \param i The header to set flickies for
* \param i The header to set followers for
*/
void P_SetDemoFlickies(INT16 i)
void P_SetDefaultHeaderFollowers(UINT16 i)
{
mapheaderinfo[i]->numFlickies = 5;
mapheaderinfo[i]->flickies = Z_Realloc(mapheaderinfo[i]->flickies, 5*sizeof(mobjtype_t), PU_STATIC, NULL);
mapheaderinfo[i]->flickies[0] = MT_FLICKY_02/*MT_BUNNY*/;
mapheaderinfo[i]->flickies[1] = MT_FLICKY_01/*MT_BIRD*/;
mapheaderinfo[i]->flickies[2] = MT_FLICKY_12/*MT_MOUSE*/;
mapheaderinfo[i]->flickies[3] = MT_FLICKY_11/*MT_COW*/;
mapheaderinfo[i]->flickies[4] = MT_FLICKY_03/*MT_CHICKEN*/;
static INT16 defaultfollowers[MAXHEADERFOLLOWERS];
static UINT8 validdefaultfollowers = 0;
if (validdefaultfollowers == 0)
{
const char *defaultfollowernames[] =
{
"Flicky",
"Chao",
NULL
};
for (validdefaultfollowers = 0; defaultfollowernames[validdefaultfollowers]; validdefaultfollowers++)
{
defaultfollowers[validdefaultfollowers] = K_FollowerAvailable(defaultfollowernames[validdefaultfollowers]);
}
I_Assert(validdefaultfollowers != 0);
}
mapheaderinfo[i]->followers = Z_Realloc(mapheaderinfo[i]->followers, sizeof(UINT16) * validdefaultfollowers, PU_STATIC, NULL);
for (mapheaderinfo[i]->numFollowers = 0; mapheaderinfo[i]->numFollowers < validdefaultfollowers; mapheaderinfo[i]->numFollowers++)
{
mapheaderinfo[i]->followers[mapheaderinfo[i]->numFollowers] = defaultfollowers[mapheaderinfo[i]->numFollowers];
}
}
/** Clears a header's flickies
/** Clears a header's followers
*
* \param i The header to clear flickies for
* \param i The header to clear followers for
*/
void P_DeleteFlickies(INT16 i)
void P_DeleteHeaderFollowers(UINT16 i)
{
if (mapheaderinfo[i]->flickies)
Z_Free(mapheaderinfo[i]->flickies);
mapheaderinfo[i]->flickies = NULL;
mapheaderinfo[i]->numFlickies = 0;
if (mapheaderinfo[i]->followers)
Z_Free(mapheaderinfo[i]->followers);
mapheaderinfo[i]->followers = NULL;
mapheaderinfo[i]->numFollowers = 0;
}
#define NUMLAPS_DEFAULT 3
@ -419,10 +438,10 @@ static void P_ClearSingleMapHeaderInfo(INT16 num)
mapheaderinfo[num]->light_contrast = 16;
mapheaderinfo[num]->use_light_angle = false;
mapheaderinfo[num]->light_angle = 0;
#if 1 // equivalent to "FlickyList = DEMO"
P_SetDemoFlickies(num);
#else // equivalent to "FlickyList = NONE"
P_DeleteFlickies(num);
#if 1 // equivalent to "Followers = DEFAULT"
P_SetDefaultHeaderFollowers(num);
#else
P_DeleteHeaderFollowers(num);
#endif
mapheaderinfo[num]->mapvisited = 0;
@ -486,7 +505,7 @@ void P_AllocMapHeader(INT16 i)
mapheaderinfo[i]->ghostCount = 0;
mapheaderinfo[i]->cup = NULL;
mapheaderinfo[i]->mainrecord = NULL;
mapheaderinfo[i]->flickies = NULL;
mapheaderinfo[i]->followers = NULL;
nummapheaders++;
}
P_ClearSingleMapHeaderInfo(i);

View file

@ -144,8 +144,8 @@ boolean P_ApplyLightOffsetFine(UINT8 baselightlevel);
size_t P_PrecacheLevelFlats(void);
void P_AllocMapHeader(INT16 i);
void P_SetDemoFlickies(INT16 i);
void P_DeleteFlickies(INT16 i);
void P_SetDefaultHeaderFollowers(UINT16 i);
void P_DeleteHeaderFollowers(UINT16 i);
// Needed for NiGHTS
void P_ReloadRings(void);