diff --git a/src/doomstat.h b/src/doomstat.h index f3955e39..40295d25 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -329,7 +329,7 @@ extern UINT16 emeralds; #define EMERALD7 64 #define ALL7EMERALDS(v) ((v & (EMERALD1|EMERALD2|EMERALD3|EMERALD4|EMERALD5|EMERALD6|EMERALD7)) == (EMERALD1|EMERALD2|EMERALD3|EMERALD4|EMERALD5|EMERALD6|EMERALD7)) -extern INT32 nummaprings; //keep track of spawned rings/coins +extern INT32 nummaprings, nummapboxes, numgotboxes; //keep track of spawned rings/coins/battle mode items /** Time attack information, currently a very small structure. */ diff --git a/src/g_game.c b/src/g_game.c index d73e90d0..6d9e4f74 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -179,6 +179,10 @@ UINT32 bluescore, redscore; // CTF and Team Match team scores // ring count... for PERFECT! INT32 nummaprings = 0; +// box respawning in battle mode +INT32 nummapboxes = 0; +INT32 numgotboxes = 0; + // Elminates unnecessary searching. boolean CheckForBustableBlocks; boolean CheckForBouncySector; diff --git a/src/p_enemy.c b/src/p_enemy.c index 9957f15e..90cda70e 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -8134,6 +8134,9 @@ void A_ItemPop(mobj_t *actor) remains->flags2 &= ~MF2_AMBUSH; + if (gametype != GT_RACE) + numgotboxes++; + P_RemoveMobj(actor); } diff --git a/src/p_local.h b/src/p_local.h index 48db93c2..235aaa27 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -201,6 +201,7 @@ extern size_t iquehead, iquetail; extern consvar_t cv_gravity, cv_viewheight; void P_RespawnSpecials(void); +void P_RespawnBattleSpecials(void); mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type); diff --git a/src/p_mobj.c b/src/p_mobj.c index 152f42fb..9597a5d8 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8420,6 +8420,10 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) case MT_COIN: case MT_BLUEBALL: nummaprings++; + break; + case MT_RANDOMITEM: + nummapboxes++; + break; default: break; } @@ -8799,7 +8803,7 @@ void P_RemoveSavegameMobj(mobj_t *mobj) } static CV_PossibleValue_t respawnitemtime_cons_t[] = {{1, "MIN"}, {300, "MAX"}, {0, NULL}}; -consvar_t cv_itemrespawntime = {"respawnitemtime", "5", CV_NETVAR|CV_CHEAT, respawnitemtime_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_itemrespawntime = {"respawnitemtime", "3", CV_NETVAR|CV_CHEAT, respawnitemtime_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_itemrespawn = {"respawnitem", "On", CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t flagtime_cons_t[] = {{0, "MIN"}, {300, "MAX"}, {0, NULL}}; consvar_t cv_flagtime = {"flagtime", "30", CV_NETVAR|CV_CHEAT, flagtime_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -9011,6 +9015,12 @@ void P_RespawnSpecials(void) mobj_t *mo = NULL; mapthing_t *mthing = NULL; + if (gametype != GT_RACE) // Battle Mode vers + { + P_RespawnBattleSpecials(); + return; + } + // only respawn items when cv_itemrespawn is on if (!cv_itemrespawn.value) return; @@ -9092,6 +9102,97 @@ void P_RespawnSpecials(void) iquetail = (iquetail+1)&(ITEMQUESIZE-1); } +// +// P_RespawnBattleSpecials +// +void P_RespawnBattleSpecials(void) +{ + fixed_t x, y, z; + subsector_t *ss; + mobj_t *mo = NULL; + mapthing_t *mthing = NULL; + + // only respawn items when cv_itemrespawn is on + if (!cv_itemrespawn.value) + return; + + // Didn't collect enough boxes + if (numgotboxes < nummapboxes) + return; + + // wait a teeeensy bit after collecting everything + if (leveltime - itemrespawntime[iquehead-1] < (tic_t)cv_itemrespawntime.value*TICRATE) + return; + + while (iquehead != iquetail) // respawn EVERYTHING in que! + { + mthing = itemrespawnque[iquetail]; + +#ifdef PARANOIA + if (!mthing) + I_Error("itemrespawnque[iquetail] is NULL!"); +#endif + + if (mthing) + { + mobjtype_t i; + x = mthing->x << FRACBITS; + y = mthing->y << FRACBITS; + ss = R_PointInSubsector(x, y); + + // find which type to spawn + for (i = 0; i < NUMMOBJTYPES; i++) + if (mthing->type == mobjinfo[i].doomednum) + break; + + //CTF rings should continue to respawn as normal rings outside of CTF. + if (gametype != GT_CTF) + { + if (i == MT_REDTEAMRING || i == MT_BLUETEAMRING) + i = MT_RING; + } + + if (mthing->options & MTF_OBJECTFLIP) + { + z = ( +#ifdef ESLOPE + ss->sector->c_slope ? P_GetZAt(ss->sector->c_slope, x, y) : +#endif + ss->sector->ceilingheight) - (mthing->options >> ZSHIFT) * FRACUNIT; + if (mthing->options & MTF_AMBUSH + && (i == MT_RING || i == MT_REDTEAMRING || i == MT_BLUETEAMRING || i == MT_COIN || P_WeaponOrPanel(i))) + z -= 24*FRACUNIT; + z -= mobjinfo[i].height; // Don't forget the height! + } + else + { + z = ( +#ifdef ESLOPE + ss->sector->f_slope ? P_GetZAt(ss->sector->f_slope, x, y) : +#endif + ss->sector->floorheight) + (mthing->options >> ZSHIFT) * FRACUNIT; + if (mthing->options & MTF_AMBUSH + && (i == MT_RING || i == MT_REDTEAMRING || i == MT_BLUETEAMRING || i == MT_COIN || P_WeaponOrPanel(i))) + z += 24*FRACUNIT; + } + + mo = P_SpawnMobj(x, y, z, i); + mo->spawnpoint = mthing; + mo->angle = ANGLE_45 * (mthing->angle/45); + + if (mthing->options & MTF_OBJECTFLIP) + { + mo->eflags |= MFE_VERTICALFLIP; + mo->flags2 |= MF2_OBJECTFLIP; + } + } + // pull it from the que + iquetail = (iquetail+1)&(ITEMQUESIZE-1); + } + + numgotboxes = 0; +} + // // P_SpawnPlayer // Called when a player is spawned on the level. diff --git a/src/p_setup.c b/src/p_setup.c index 42ad4697..aa569471 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2154,6 +2154,8 @@ static void P_LevelInitStuff(void) tokenbits = 0; runemeraldmanager = false; nummaprings = 0; + nummapboxes = 0; + numgotboxes = 0; // emerald hunt hunt1 = hunt2 = hunt3 = NULL;