Starting work on adding new system for spawning animals; added A_FlickySpawn and level header "animallist"/"flickylist" parameter

No idea if this compiles yet (let alone if what is there works at all), just getting this out the way so I can work on certain other things *cough plane displacement cough*
This commit is contained in:
Monster Iestyn 2016-12-27 21:01:20 +00:00
parent 37c8ef6369
commit cecc1912fe
5 changed files with 132 additions and 0 deletions

View File

@ -990,6 +990,31 @@ static const struct {
{NULL, 0}
};
static const struct {
const char *name;
const mobjtype_t type;
} ANIMALTYPES[] = {
{"BLUEBIRD", MT_BIRD}, //MT_FLICKY_A},
{"RABBIT", MT_BUNNY}, //MT_FLICKY_B},
{"CHICKEN", MT_CHICKEN}, //MT_FLICKY_C},
//{"SEAL", MT_FLICKY_D},
//{"PIG", MT_FLICKY_E},
//{"CHIPMUNK", MT_FLICKY_F},
//{"PENGUIN", MT_FLICKY_G},
//{"FISH", MT_FLICKY_H},
//{"RAM", MT_FLICKY_I},
//{"PUFFIN", MT_FLICKY_J},
{"COW", MT_COW}, //MT_FLICKY_K},
{"RAT", MT_MOUSE}, //MT_FLICKY_L},
//{"BEAR", MT_FLICKY_M},
//{"DOVE", MT_FLICKY_N},
//{"CAT", MT_FLICKY_O},
//{"CANARY", MT_FLICKY_P},
//{"FLICKER", MT_FLICKER},
//{"SEED", MT_CDSEED},
{NULL, 0}
}
static void readlevelheader(MYFILE *f, INT32 num)
{
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
@ -1088,6 +1113,48 @@ static void readlevelheader(MYFILE *f, INT32 num)
// Now go to uppercase
strupr(word2);
// List of animals that are be freed in this level
if (fastcmp(word, "ANIMALLIST") || fastcmp(word, "FLICKYLIST"))
{
if (fastcmp(word2, "NONE"))
{
if (mapheaderinfo[num-1]->animals)
Z_Free(mapheaderinfo[num-1]->animals);
mapheaderinfo[num-1]->animals = NULL;
mapheaderinfo[num-1]->numAnimals = 0;
}
else
{
mapheaderinfo[num-1]->numAnimals = 0;
tmp = strtok(word2,",");
// count how many animals there are first
do {
for (i = 0; ANIMALTYPES[i].name; i++)
if (fastcmp(tmp, ANIMALTYPES[i].name))
break;
if (!TYPEOFLEVEL[i].name)
deh_warning("Level header %d: unknown animal type %s\n", num, tmp);
else
mapheaderinfo[num-1]->numAnimals++;
} while((tmp = strtok(NULL,",")) != NULL);
if (!mapheaderinfo[num-1]->numAnimals)
deh_warning("Level header %d: no valid animal types found\n", num);
else
{
mapheaderinfo[num-1]->animals = Z_Realloc(mapheaderinfo[num-1]->animals, sizeof(mobjtype_t) * mapheaderinfo[num-1]->numAnimals, PU_STATIC, NULL);
mapheaderinfo[num-1]->numAnimals = 0; // reset count
// now we add them to the list!
do {
for (i = 0; ANIMALTYPES[i].name; i++)
if (fastcmp(tmp, ANIMALTYPES[i].name))
break;
if (TYPEOFLEVEL[i].name)
mapheaderinfo[num-1]->animals[mapheaderinfo[num-1]->numAnimals++] = ANIMALTYPES[i].type;
} while((tmp = strtok(NULL,",")) != NULL);
}
}
}
// NiGHTS grades
if (fastncmp(word, "GRADES", 6))
{
@ -1845,6 +1912,7 @@ static actionpointer_t actionpointers[] =
{{A_BrakLobShot}, "A_BRAKLOBSHOT"},
{{A_NapalmScatter}, "A_NAPALMSCATTER"},
{{A_SpawnFreshCopy}, "A_SPAWNFRESHCOPY"},
{{A_FlickySpawn}, "A_FLICKYSPAWN"},
{{NULL}, "NONE"},

View File

@ -241,6 +241,10 @@ typedef struct
UINT8 levelflags; ///< LF_flags: merged eight booleans into one UINT8 for space, see below
UINT8 menuflags; ///< LF2_flags: options that affect record attack / nights mode menus
// Freed animals stuff.
UINT8 numAnimals; ///< Internal. For freed animal support.
mobjtype_t *animals; ///< List of freeable animals in this level. Allocated dynamically for space reasons. Be careful.
// NiGHTS stuff.
UINT8 numGradedMares; ///< Internal. For grade support.
nightsgrades_t *grades; ///< NiGHTS grades. Allocated dynamically for space reasons. Be careful.

View File

@ -214,6 +214,7 @@ void A_BrakFireShot();
void A_BrakLobShot();
void A_NapalmScatter();
void A_SpawnFreshCopy();
void A_FlickySpawn();
// ratio of states to sprites to mobj types is roughly 6 : 1 : 1
#define NUMMOBJFREESLOTS 256

View File

@ -242,6 +242,7 @@ void A_BrakFireShot(mobj_t *actor);
void A_BrakLobShot(mobj_t *actor);
void A_NapalmScatter(mobj_t *actor);
void A_SpawnFreshCopy(mobj_t *actor);
void A_FlickySpawn(mobj_t *actor);
//
// ENEMY THINKING
@ -10336,3 +10337,56 @@ void A_SpawnFreshCopy(mobj_t *actor)
if (newObject->info->seesound)
S_StartSound(newObject, newObject->info->seesound);
}
// Function: A_FlickySpawn
//
// Description: Flicky spawning function.
//
// var1:
// lower 16 bits: if 0, spawns random flicky based on level header. Else, spawns the designated thing type.
// upper 16 bits: if 0, no sound is played. Else, A_Scream is called.
// var2 = upwards thrust for spawned flicky
//
void A_FlickySpawn(mobj_t *actor)
{
INT32 locvar1 = var1;
INT32 locvar2 = var2;
mobj_t *flicky;
#ifdef HAVE_BLUA
if (LUA_CallAction("A_FlickySpawn", actor))
return;
#endif
if (mariomode) // No animals in Mario mode
return;
if (locvar1 >> 16) {
A_Scream(actor);
locvar1 &= 65535;
}
if (cv_soniccd.value)
locvar1 = MT_SEED;
else if (!locvar1) {
if (!mapheaderinfo[gamemap-1]->numAnimals)
return;
else {
INT32 prandom = P_RandomKey(mapheaderinfo[gamemap-1]->numAnimals);
locvar1 = mapheaderinfo[gamemap-1]->animals[prandom];
}
}
if (locvar1 == MT_SEED)
{
flicky = P_SpawnMobj(actor->x, actor->y, actor->z + (actor->height / 2) - FixedMul(mobjinfo[locvar1].height / 2, actor->scale), locvar1);
flicky->destscale = actor->scale;
P_SetScale(flicky,flicky->destscale);
return;
}
flicky = P_SpawnMobjFromMobj(actor, 0, 0, 0, locvar1);
flicky->angle = actor->angle;
P_SetObjectMomZ(flicky, (locvar2) ? locvar2 : 8*FRACUNIT, false);
P_LookForPlayers(flicky, true, false, 0);
flicky->movedir = P_RandomChance(FRACUNIT/2) ? -1 : 1;
flicky->fuse = P_RandomRange(595, 700); // originally 300, 350
}

View File

@ -223,6 +223,11 @@ static void P_ClearSingleMapHeaderInfo(INT16 i)
mapheaderinfo[num]->levelflags = 0;
DEH_WriteUndoline("MENUFLAGS", va("%d", mapheaderinfo[num]->menuflags), UNDO_NONE);
mapheaderinfo[num]->menuflags = 0;
// Animals. Nope, no delfile support here either
if (mapheaderinfo[i]->animals)
Z_Free(mapheaderinfo[i]->animals);
mapheaderinfo[num]->animals = NULL;
mapheaderinfo[num]->numAnimals = 0;
// TODO grades support for delfile (pfft yeah right)
P_DeleteGrades(num);
// an even further impossibility, delfile custom opts support