From cecc1912fe170d70e21dcbaec7a8018490ea677b Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 27 Dec 2016 21:01:20 +0000 Subject: [PATCH] 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* --- src/dehacked.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/doomstat.h | 4 +++ src/info.h | 1 + src/p_enemy.c | 54 +++++++++++++++++++++++++++++++++++++++ src/p_setup.c | 5 ++++ 5 files changed, 132 insertions(+) diff --git a/src/dehacked.c b/src/dehacked.c index f45b05b04..1a8c5bc87 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -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"}, diff --git a/src/doomstat.h b/src/doomstat.h index 8072a1552..1a7c7b89d 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -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. diff --git a/src/info.h b/src/info.h index 932180ebf..5e10e6bf7 100644 --- a/src/info.h +++ b/src/info.h @@ -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 diff --git a/src/p_enemy.c b/src/p_enemy.c index 76a86d8b9..253a08f1f 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -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 +} diff --git a/src/p_setup.c b/src/p_setup.c index 6b4c37349..f0dfc52a1 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -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