From 56d7f9ed389277bee8f8c6bf3590fa362e7cfd14 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Fri, 30 Mar 2018 14:22:59 -0400 Subject: [PATCH 01/14] Nights LE checkpoint --- src/p_map.c | 7 +++++-- src/p_spec.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ src/p_user.c | 4 ++++ 3 files changed, 57 insertions(+), 2 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index 6d1760596..8c58570c8 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -905,7 +905,7 @@ static boolean PIT_CheckThing(mobj_t *thing) P_SetTarget(&thing->target, tmthing); } - // Respawn rings and items + // NiGHTS lap logic if ((tmthing->type == MT_NIGHTSDRONE || thing->type == MT_NIGHTSDRONE) && (tmthing->player || thing->player)) { @@ -921,8 +921,11 @@ static boolean PIT_CheckThing(mobj_t *thing) ^ (droneobj->extravalue1 >= 90 && droneobj->extravalue1 <= 270) )) { - // Reload all the fancy ring stuff! + // Respawn rings and items P_ReloadRings(); + + // \todo store current lap in player mobj + P_RunNightsLapExecutors(pl->mo); } droneobj->extravalue1 = pl->anotherflyangle; droneobj->extravalue2 = (INT32)leveltime + TICRATE; diff --git a/src/p_spec.c b/src/p_spec.c index 0b005baff..b26fab821 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -5487,6 +5487,48 @@ static void P_RunLevelLoadExecutors(void) } } +// +// P_RunNightserizeExecutors +// +static void P_RunNightserizeExecutors(mobj_t *actor) +{ + size_t i; + + for (i = 0; i < numlines; i++) + { + if (lines[i].special == 323 || lines[i].special == 324) + P_RunTriggerLinedef(&lines[i], actor, NULL); + } +} + +// +// P_RunDeNightserizeExecutors +// +static void P_RunDeNightserizeExecutors(mobj_t *actor) +{ + size_t i; + + for (i = 0; i < numlines; i++) + { + if (lines[i].special == 325 || lines[i].special == 326) + P_RunTriggerLinedef(&lines[i], actor, NULL); + } +} + +// +// P_RunNightsLapExecutors +// +static void P_RunNightsLapExecutors(mobj_t *actor) +{ + size_t i; + + for (i = 0; i < numlines; i++) + { + if (lines[i].special == 327 || lines[i].special == 328) + P_RunTriggerLinedef(&lines[i], actor, NULL); + } +} + /** Before things are loaded, initialises certain stuff in case they're needed * by P_ResetDynamicSlopes or P_LoadThings. This was split off from * P_SpawnSpecials, in case you couldn't tell. @@ -6408,6 +6450,12 @@ void P_SpawnSpecials(INT32 fromnetsave) } break; + // NiGHTS trigger executors + case 323: + case 324: + case 325: + break; + case 399: // Linedef execute on map load // This is handled in P_RunLevelLoadExecutors. break; diff --git a/src/p_user.c b/src/p_user.c index f422e9b65..f4be0cf59 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -636,6 +636,8 @@ static void P_DeNightserizePlayer(player_t *player) // Restore from drowning music P_RestoreMusic(player); + + P_RunDeNightserizeExecutors(); } // @@ -771,6 +773,8 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime) } player->powers[pw_carry] = CR_NIGHTSMODE; + + P_RunNightserizeExecutors(player->mo); } pflags_t P_GetJumpFlags(player_t *player) From 637a4a844646754c412a9fc00419e02e78bbc280 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Fri, 30 Mar 2018 14:36:49 -0400 Subject: [PATCH 02/14] Add player_t marelap and marebonuslap, with logic --- src/d_player.h | 2 ++ src/lua_playerlib.c | 8 ++++++++ src/p_map.c | 17 ++++++++++++----- src/p_saveg.c | 4 ++++ src/p_setup.c | 1 + src/p_user.c | 2 ++ 6 files changed, 29 insertions(+), 5 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index e1350fe67..f919eddb0 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -455,6 +455,8 @@ typedef struct player_s boolean bonustime; // Capsule destroyed, now it's bonus time! mobj_t *capsule; // Go inside the capsule UINT8 mare; // Current mare + UINT8 marelap; // Current mare lap + UINT8 marebonuslap; // Current mare lap starting from bonus time // Statistical purposes. tic_t marebegunat; // Leveltime when mare begun diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index 12b2646d0..9b5aa6fdc 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -288,6 +288,10 @@ static int player_get(lua_State *L) LUA_PushUserdata(L, plr->capsule, META_MOBJ); else if (fastcmp(field,"mare")) lua_pushinteger(L, plr->mare); + else if (fastcmp(field,"marelap")) + lua_pushinteger(L, plr->marelap); + else if (fastcmp(field,"marebonuslap")) + lua_pushinteger(L, plr->marebonuslap); else if (fastcmp(field,"marebegunat")) lua_pushinteger(L, plr->marebegunat); else if (fastcmp(field,"startedtime")) @@ -564,6 +568,10 @@ static int player_set(lua_State *L) } else if (fastcmp(field,"mare")) plr->mare = (UINT8)luaL_checkinteger(L, 3); + else if (fastcmp(field,"marelap")) + plr->marelap = (UINT8)luaL_checkinteger(L, 3); + else if (fastcmp(field,"marebonuslap")) + plr->marebonuslap = (UINT8)luaL_checkinteger(L, 3); else if (fastcmp(field,"marebegunat")) plr->marebegunat = (tic_t)luaL_checkinteger(L, 3); else if (fastcmp(field,"startedtime")) diff --git a/src/p_map.c b/src/p_map.c index 6d1760596..565680e22 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -905,24 +905,31 @@ static boolean PIT_CheckThing(mobj_t *thing) P_SetTarget(&thing->target, tmthing); } - // Respawn rings and items + // NiGHTS lap logic if ((tmthing->type == MT_NIGHTSDRONE || thing->type == MT_NIGHTSDRONE) && (tmthing->player || thing->player)) { mobj_t *droneobj = (tmthing->type == MT_NIGHTSDRONE) ? tmthing : thing; player_t *pl = (droneobj == thing) ? tmthing->player : thing->player; - // Must be in bonus time, and must be NiGHTS, must wait about a second + // Must be NiGHTS, must wait about a second // must be flying in the SAME DIRECTION as the last time you came through. // not (your direction) xor (stored direction) // In other words, you can't u-turn and respawn rings near the drone. - if (pl->bonustime && (pl->powers[pw_carry] == CR_NIGHTSMODE) && (INT32)leveltime > droneobj->extravalue2 && ( + if ((pl->powers[pw_carry] == CR_NIGHTSMODE) && (INT32)leveltime > droneobj->extravalue2 && ( !(pl->anotherflyangle >= 90 && pl->anotherflyangle <= 270) ^ (droneobj->extravalue1 >= 90 && droneobj->extravalue1 <= 270) )) { - // Reload all the fancy ring stuff! - P_ReloadRings(); + pl->marelap++; + + if (pl->bonustime) + { + pl->marebonuslap++; + + // Respawn rings and items + P_ReloadRings(); + } } droneobj->extravalue1 = pl->anotherflyangle; droneobj->extravalue2 = (INT32)leveltime + TICRATE; diff --git a/src/p_saveg.c b/src/p_saveg.c index 029df08f4..59d1775a8 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -197,6 +197,8 @@ static void P_NetArchivePlayers(void) WRITEUINT8(save_p, players[i].drilldelay); WRITEUINT8(save_p, players[i].bonustime); WRITEUINT8(save_p, players[i].mare); + WRITEUINT8(save_p, players[i].marelap); + WRITEUINT8(save_p, players[i].marebonuslap); WRITEUINT32(save_p, players[i].marebegunat); WRITEUINT32(save_p, players[i].startedtime); @@ -384,6 +386,8 @@ static void P_NetUnArchivePlayers(void) players[i].drilldelay = READUINT8(save_p); players[i].bonustime = (boolean)READUINT8(save_p); players[i].mare = READUINT8(save_p); + players[i].marelap = READUINT8(save_p); + players[i].marebonuslap = READUINT8(save_p); players[i].marebegunat = READUINT32(save_p); players[i].startedtime = READUINT32(save_p); diff --git a/src/p_setup.c b/src/p_setup.c index a9fc57652..f3e92abce 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2350,6 +2350,7 @@ static void P_LevelInitStuff(void) players[i].linkcount = players[i].linktimer = 0; players[i].flyangle = players[i].anotherflyangle = 0; players[i].nightstime = players[i].mare = 0; + players[i].marelap = 0; players[i].marebonuslap = 0; P_SetTarget(&players[i].capsule, NULL); players[i].drillmeter = 40*20; diff --git a/src/p_user.c b/src/p_user.c index f422e9b65..c8f364193 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -399,6 +399,8 @@ boolean P_TransferToNextMare(player_t *player) CONS_Debug(DBG_NIGHTS, "Mare is %d\n", mare); player->mare = mare; + player->marelap = 0; + player->marebonuslap = 0; // scan the thinkers // to find the closest axis point From 3d72c105df07f59929b8cac0bdba7b9f8c43c5e6 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 31 Mar 2018 10:11:27 -0400 Subject: [PATCH 03/14] Initial checkpoint for NiGHTS LE triggers --- src/p_spec.c | 147 ++++++++++++++++++++++++++++++++++++--------------- src/p_spec.h | 3 ++ src/p_user.c | 7 +-- 3 files changed, 112 insertions(+), 45 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index b26fab821..a23374c13 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -1374,6 +1374,48 @@ void P_ChangeSectorTag(UINT32 sector, INT16 newtag) } } +// +// P_RunNightserizeExecutors +// +void P_RunNightserizeExecutors(mobj_t *actor) +{ + size_t i; + + for (i = 0; i < numlines; i++) + { + if (lines[i].special == 323 || lines[i].special == 324) + P_RunTriggerLinedef(&lines[i], actor, NULL); + } +} + +// +// P_RunDeNightserizeExecutors +// +void P_RunDeNightserizeExecutors(mobj_t *actor) +{ + size_t i; + + for (i = 0; i < numlines; i++) + { + if (lines[i].special == 325 || lines[i].special == 326) + P_RunTriggerLinedef(&lines[i], actor, NULL); + } +} + +// +// P_RunNightsLapExecutors +// +void P_RunNightsLapExecutors(mobj_t *actor) +{ + size_t i; + + for (i = 0; i < numlines; i++) + { + if (lines[i].special == 327 || lines[i].special == 328) + P_RunTriggerLinedef(&lines[i], actor, NULL); + } +} + /** Hashes the sector tags across the sectors and linedefs. * * \sa P_FindSectorFromTag, P_ChangeSectorTag @@ -1667,6 +1709,69 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller return false; } break; + case 323: // each time + case 324: // once + { // nightserize + INT32 mareinput = sides[triggerline->sidenum[0]].textureoffset>>FRACBITS; + INT32 lapinput = sides[triggerline->sidenum[0]].rowoffset>>FRACBITS; + BOOL ltemare = triggerline->flags & ML_NOCLIMB; + BOOL gtemare = triggerline->flags & ML_BLOCKMONSTERS; + BOOL ltelap = triggerline->flags & ML_EFFECT1; + BOOL gtelap = triggerline->flags & ML_EFFECT2; + BOOL lapfrombonustime = triggerline->flags & ML_EFFECT3; + BOOL doglobal = triggerline->flags & ML_EFFECT4; + BOOL donomares = triggerline->flags & ML_EFFECT5; // unused for nights lap + BOOL fromnonights = triggerline->flags & ML_BOUNCY; // unused for nights lap + + CONS_Printf("Trigger Nightserize %i\n", triggerline->special); + CONS_Printf("M-I %i | M-V %i | M-GTE %i | M-LTE %i | L-I %i | L-V %i/%i | L-GTE %i | L-LTE %i\n" + , mareinput, actor->player->mare, gtemare, ltemare + , lapinput, actor->player->marebonuslap, actor->player->marelap, gtelap, ltelap); + CONS_Printf("L-Bonus %i | Global %i | No Mares %i | From No NiGHTS %i\n", lapfrombonustime, doglobal, donomares, fromnonights); + } + break; + case 325: // each time + case 326: // once + { // denightserize + INT32 mareinput = sides[triggerline->sidenum[0]].textureoffset>>FRACBITS; + INT32 lapinput = sides[triggerline->sidenum[0]].rowoffset>>FRACBITS; + BOOL ltemare = triggerline->flags & ML_NOCLIMB; + BOOL gtemare = triggerline->flags & ML_BLOCKMONSTERS; + BOOL ltelap = triggerline->flags & ML_EFFECT1; + BOOL gtelap = triggerline->flags & ML_EFFECT2; + BOOL lapfrombonustime = triggerline->flags & ML_EFFECT3; + BOOL doglobal = triggerline->flags & ML_EFFECT4; + BOOL donomares = triggerline->flags & ML_EFFECT5; // all no nights // unused for nights lap + BOOL fromnonights = triggerline->flags & ML_BOUNCY; // unused for nights lap + + CONS_Printf("Trigger DeNightserize %i\n", triggerline->special); + CONS_Printf("M-I %i | M-V %i | M-GTE %i | M-LTE %i | L-I %i | L-V %i/%i | L-GTE %i | L-LTE %i\n" + , mareinput, actor->player->mare, gtemare, ltemare + , lapinput, actor->player->marebonuslap, actor->player->marelap, gtelap, ltelap); + CONS_Printf("L-Bonus %i | Global %i | No Mares %i | From No NiGHTS %i\n", lapfrombonustime, doglobal, donomares, fromnonights); + } + break; + case 327: // each time + case 328: // once + { // nights lap + INT32 mareinput = sides[triggerline->sidenum[0]].textureoffset>>FRACBITS; + INT32 lapinput = sides[triggerline->sidenum[0]].rowoffset>>FRACBITS; + BOOL ltemare = triggerline->flags & ML_NOCLIMB; + BOOL gtemare = triggerline->flags & ML_BLOCKMONSTERS; + BOOL ltelap = triggerline->flags & ML_EFFECT1; + BOOL gtelap = triggerline->flags & ML_EFFECT2; + BOOL lapfrombonustime = triggerline->flags & ML_EFFECT3; + BOOL doglobal = triggerline->flags & ML_EFFECT4; + BOOL donomares = triggerline->flags & ML_EFFECT5; // unused for nights lap + BOOL fromnonights = triggerline->flags & ML_BOUNCY; // unused for nights lap + + CONS_Printf("Trigger NiGHTS Lap %i\n", triggerline->special); + CONS_Printf("M-I %i | M-V %i | M-GTE %i | M-LTE %i | L-I %i | L-V %i/%i | L-GTE %i | L-LTE %i\n" + , mareinput, actor->player->mare, gtemare, ltemare + , lapinput, actor->player->marebonuslap, actor->player->marelap, gtelap, ltelap); + CONS_Printf("L-Bonus %i | Global %i | No Mares %i | From No NiGHTS %i\n", lapfrombonustime, doglobal, donomares, fromnonights); + } + break; default: break; } @@ -5487,48 +5592,6 @@ static void P_RunLevelLoadExecutors(void) } } -// -// P_RunNightserizeExecutors -// -static void P_RunNightserizeExecutors(mobj_t *actor) -{ - size_t i; - - for (i = 0; i < numlines; i++) - { - if (lines[i].special == 323 || lines[i].special == 324) - P_RunTriggerLinedef(&lines[i], actor, NULL); - } -} - -// -// P_RunDeNightserizeExecutors -// -static void P_RunDeNightserizeExecutors(mobj_t *actor) -{ - size_t i; - - for (i = 0; i < numlines; i++) - { - if (lines[i].special == 325 || lines[i].special == 326) - P_RunTriggerLinedef(&lines[i], actor, NULL); - } -} - -// -// P_RunNightsLapExecutors -// -static void P_RunNightsLapExecutors(mobj_t *actor) -{ - size_t i; - - for (i = 0; i < numlines; i++) - { - if (lines[i].special == 327 || lines[i].special == 328) - P_RunTriggerLinedef(&lines[i], actor, NULL); - } -} - /** Before things are loaded, initialises certain stuff in case they're needed * by P_ResetDynamicSlopes or P_LoadThings. This was split off from * P_SpawnSpecials, in case you couldn't tell. diff --git a/src/p_spec.h b/src/p_spec.h index c4e05e072..76ddc237c 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -66,6 +66,9 @@ void P_SwitchWeather(INT32 weathernum); boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller); void P_LinedefExecute(INT16 tag, mobj_t *actor, sector_t *caller); void P_ChangeSectorTag(UINT32 sector, INT16 newtag); +void P_RunNightserizeExecutors(mobj_t *actor); +void P_RunDeNightserizeExecutors(mobj_t *actor); +void P_RunNightsLapExecutors(mobj_t *actor); ffloor_t *P_GetFFloorByID(sector_t *sec, UINT16 id); diff --git a/src/p_user.c b/src/p_user.c index 54411b25a..befd91f63 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -639,7 +639,7 @@ static void P_DeNightserizePlayer(player_t *player) // Restore from drowning music P_RestoreMusic(player); - P_RunDeNightserizeExecutors(); + P_RunDeNightserizeExecutors(player->mo); } // @@ -774,9 +774,10 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime) player->texttimer = (UINT8)(110 - timeinmap); } - player->powers[pw_carry] = CR_NIGHTSMODE; - + // Do this before setting CR_NIGHTSMODE so we can tell if player was non-NiGHTS P_RunNightserizeExecutors(player->mo); + + player->powers[pw_carry] = CR_NIGHTSMODE; } pflags_t P_GetJumpFlags(player_t *player) From 9dc90f2df86da42e77be84cd08e8a1ee47dc89ee Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sun, 1 Apr 2018 08:23:59 -0400 Subject: [PATCH 04/14] Implement logic branching for NiGHTS LE triggers and add Bonus Time trigger --- src/p_spec.c | 179 +++++++++++++++++++++++++++++++++++---------------- src/p_spec.h | 1 + src/p_user.c | 1 + 3 files changed, 127 insertions(+), 54 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index a23374c13..9c3f3df7d 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -1416,6 +1416,20 @@ void P_RunNightsLapExecutors(mobj_t *actor) } } +// +// P_RunNightsBonusTimeExecutors +// +void P_RunNightsBonusTimeExecutors(mobj_t *actor) +{ + size_t i; + + for (i = 0; i < numlines; i++) + { + if (lines[i].special == 329 || lines[i].special == 330) + P_RunTriggerLinedef(&lines[i], actor, NULL); + } +} + /** Hashes the sector tags across the sectors and linedefs. * * \sa P_FindSectorFromTag, P_ChangeSectorTag @@ -1709,69 +1723,117 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller return false; } break; - case 323: // each time - case 324: // once + + // Let's do the NiGHTS triggers in one code block; they mostly have the same logic + case 323: // nightserize - each time + case 324: // nightserize - once + case 325: // denightserize - each time + case 326: // denightserize - once + case 327: // nights lap - each time + case 328: // nights lap - once + case 329: // nights bonus time - each time + case 330: // nights bonus time - once { // nightserize - INT32 mareinput = sides[triggerline->sidenum[0]].textureoffset>>FRACBITS; - INT32 lapinput = sides[triggerline->sidenum[0]].rowoffset>>FRACBITS; + UINT8 inputmare = max(0, min(255, sides[triggerline->sidenum[0]].textureoffset>>FRACBITS)); + UINT8 inputlap = max(0, min(255, sides[triggerline->sidenum[0]].rowoffset>>FRACBITS)); + BOOL ltemare = triggerline->flags & ML_NOCLIMB; BOOL gtemare = triggerline->flags & ML_BLOCKMONSTERS; BOOL ltelap = triggerline->flags & ML_EFFECT1; BOOL gtelap = triggerline->flags & ML_EFFECT2; - BOOL lapfrombonustime = triggerline->flags & ML_EFFECT3; - BOOL doglobal = triggerline->flags & ML_EFFECT4; - BOOL donomares = triggerline->flags & ML_EFFECT5; // unused for nights lap - BOOL fromnonights = triggerline->flags & ML_BOUNCY; // unused for nights lap - CONS_Printf("Trigger Nightserize %i\n", triggerline->special); - CONS_Printf("M-I %i | M-V %i | M-GTE %i | M-LTE %i | L-I %i | L-V %i/%i | L-GTE %i | L-LTE %i\n" - , mareinput, actor->player->mare, gtemare, ltemare - , lapinput, actor->player->marebonuslap, actor->player->marelap, gtelap, ltelap); - CONS_Printf("L-Bonus %i | Global %i | No Mares %i | From No NiGHTS %i\n", lapfrombonustime, doglobal, donomares, fromnonights); + BOOL lapfrombonustime = triggerline->flags & ML_EFFECT3; + BOOL perglobalinverse = triggerline->flags & ML_DONTPEGBOTTOM; + BOOL perglobal = !(triggerline->flags & ML_EFFECT4) && !perglobalinverse; + + BOOL donomares = triggerline->flags & ML_BOUNCY; // nightserize: run at end of level (no mares) + BOOL fromnonights = triggerline->flags & ML_TFERLINE; // nightserize: from non-nights // denightserize: all players no nights + + UINT8 currentmare = UINT8_MAX; + UINT8 currentlap = UINT8_MAX; + + // Do early returns for Nightserize + if (specialtype >= 323 && specialtype <= 324) + { + // run only when no mares are found + if (donomares && P_FindLowestMare() != UINT8_MAX) + return false; + + // run only if player is nightserizing from non-nights + if (fromnonights) + { + if (!actor->player) + return false; + else if (actor->player->powers[pw_carry] == CR_NIGHTSMODE) + return false; + } + } + + // Get current mare and lap (and check early return for DeNightserize) + if (perglobal || perglobalinverse + || (specialtype >= 325 && specialtype <= 326 && fromnonights)) + { + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i] || players[i].spectator) + continue; + + // denightserize: run only if all players are not nights + if (specialtype >= 325 && specialtype <= 326 && fromnonights + && players[i].powers[pw_carry] == CR_NIGHTSMODE) + return false; + + UINT8 lap = lapfrombonustime ? players[i].marebonuslap : players[i].marelap; + + // get highest mare/lap of players + if (perglobal) + { + if (players[i].mare > currentmare || currentmare == UINT8_MAX) + { + currentmare = players[i].mare; + currentlap = UINT8_MAX; + } + if (players[i].mare == currentmare + && (lap > currentlap || currentlap == UINT8_MAX)) + currentlap = lap; + } + // get lowest mare/lap of players + else if (perglobalinverse) + { + if (players[i].mare < currentmare || currentmare == UINT8_MAX) + { + currentmare = players[i].mare; + currentlap = UINT8_MAX; + } + if (players[i].mare == currentmare + && (lap < currentlap || currentlap == UINT8_MAX)) + currentlap = lap; + } + } + } + + // get current mare/lap from triggering player + if (!perglobal && !perglobalinverse) + { + if (!actor->player) + return false; + currentmare = actor->player->mare; + currentlap = lapfrombonustime ? actor->player->marebonuslap : actor->player->marelap; + } + + // Compare current mare/lap to input mare/lap based on rules + if (!(specialtype >= 323 && specialtype <= 324 && donomares) // don't return false if donomares and we got this far + && ((ltemare && currentmare > inputmare) + || (gtemare && currentmare < inputmare) + || (!ltemare && !gtemare && currentmare != inputmare) + || (ltelap && currentlap > inputlap) + || (gtelap && currentlap < inputlap) + || (!ltelap && !gtelap && currentlap != inputlap)) + ) + return false; } break; - case 325: // each time - case 326: // once - { // denightserize - INT32 mareinput = sides[triggerline->sidenum[0]].textureoffset>>FRACBITS; - INT32 lapinput = sides[triggerline->sidenum[0]].rowoffset>>FRACBITS; - BOOL ltemare = triggerline->flags & ML_NOCLIMB; - BOOL gtemare = triggerline->flags & ML_BLOCKMONSTERS; - BOOL ltelap = triggerline->flags & ML_EFFECT1; - BOOL gtelap = triggerline->flags & ML_EFFECT2; - BOOL lapfrombonustime = triggerline->flags & ML_EFFECT3; - BOOL doglobal = triggerline->flags & ML_EFFECT4; - BOOL donomares = triggerline->flags & ML_EFFECT5; // all no nights // unused for nights lap - BOOL fromnonights = triggerline->flags & ML_BOUNCY; // unused for nights lap - CONS_Printf("Trigger DeNightserize %i\n", triggerline->special); - CONS_Printf("M-I %i | M-V %i | M-GTE %i | M-LTE %i | L-I %i | L-V %i/%i | L-GTE %i | L-LTE %i\n" - , mareinput, actor->player->mare, gtemare, ltemare - , lapinput, actor->player->marebonuslap, actor->player->marelap, gtelap, ltelap); - CONS_Printf("L-Bonus %i | Global %i | No Mares %i | From No NiGHTS %i\n", lapfrombonustime, doglobal, donomares, fromnonights); - } - break; - case 327: // each time - case 328: // once - { // nights lap - INT32 mareinput = sides[triggerline->sidenum[0]].textureoffset>>FRACBITS; - INT32 lapinput = sides[triggerline->sidenum[0]].rowoffset>>FRACBITS; - BOOL ltemare = triggerline->flags & ML_NOCLIMB; - BOOL gtemare = triggerline->flags & ML_BLOCKMONSTERS; - BOOL ltelap = triggerline->flags & ML_EFFECT1; - BOOL gtelap = triggerline->flags & ML_EFFECT2; - BOOL lapfrombonustime = triggerline->flags & ML_EFFECT3; - BOOL doglobal = triggerline->flags & ML_EFFECT4; - BOOL donomares = triggerline->flags & ML_EFFECT5; // unused for nights lap - BOOL fromnonights = triggerline->flags & ML_BOUNCY; // unused for nights lap - - CONS_Printf("Trigger NiGHTS Lap %i\n", triggerline->special); - CONS_Printf("M-I %i | M-V %i | M-GTE %i | M-LTE %i | L-I %i | L-V %i/%i | L-GTE %i | L-LTE %i\n" - , mareinput, actor->player->mare, gtemare, ltemare - , lapinput, actor->player->marebonuslap, actor->player->marelap, gtelap, ltelap); - CONS_Printf("L-Bonus %i | Global %i | No Mares %i | From No NiGHTS %i\n", lapfrombonustime, doglobal, donomares, fromnonights); - } - break; default: break; } @@ -1900,6 +1962,10 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller || specialtype == 318 // Unlockable trigger - Once || specialtype == 320 // Unlockable - Once || specialtype == 321 || specialtype == 322 // Trigger on X calls - Continuous + Each Time + || specialtype == 324 // Nightserize - Once + || specialtype == 326 // DeNightserize - Once + || specialtype == 328 // Nights lap - Once + || specialtype == 330 // Nights Bonus Time - Once || specialtype == 399) // Level Load triggerline->special = 0; // Clear it out @@ -6517,6 +6583,11 @@ void P_SpawnSpecials(INT32 fromnetsave) case 323: case 324: case 325: + case 326: + case 327: + case 328: + case 329: + case 330: break; case 399: // Linedef execute on map load diff --git a/src/p_spec.h b/src/p_spec.h index 76ddc237c..5bcf25b7b 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -69,6 +69,7 @@ void P_ChangeSectorTag(UINT32 sector, INT16 newtag); void P_RunNightserizeExecutors(mobj_t *actor); void P_RunDeNightserizeExecutors(mobj_t *actor); void P_RunNightsLapExecutors(mobj_t *actor); +void P_RunNightsBonusTimeExecutors(mobj_t *actor); ffloor_t *P_GetFFloorByID(sector_t *sec, UINT16 id); diff --git a/src/p_user.c b/src/p_user.c index befd91f63..4de9759c1 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -6031,6 +6031,7 @@ static void P_DoNiGHTSCapsule(player_t *player) if (playeringame[i] && players[i].mare == player->mare) P_SetTarget(&players[i].capsule, NULL); // Remove capsule from everyone now that it is dead! S_StartScreamSound(player->mo, sfx_ngdone); + P_RunNightsBonusTimeExecutors(player->mo); } } else From 2c72c6e6602e1b8877c20f9500b7a4141c7f52d3 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Mon, 2 Apr 2018 08:11:28 -0400 Subject: [PATCH 05/14] Split NiGHTS LE trigger logic into P_CheckNightsTriggerLine This makes P_RunTriggerLinedef more readable because the logic is too different from the other triggers. Also replace BOOL with boolean --- src/p_spec.c | 213 +++++++++++++++++++++++++++------------------------ 1 file changed, 114 insertions(+), 99 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index 9c3f3df7d..4f6898658 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -1513,6 +1513,118 @@ static void P_AddExecutorDelay(line_t *line, mobj_t *mobj, sector_t *sector) P_AddThinker(&e->thinker); } +/** Used by P_RunTriggerLinedef to check a NiGHTS trigger linedef's conditions + * + * \param triggerline Trigger linedef to check conditions for; should NEVER be NULL. + * \param actor Object initiating the action; should not be NULL. + * \sa P_RunTriggerLinedef + */ +static boolean P_CheckNightsTriggerLine(line_t *triggerline, mobj_t *actor) +{ + INT16 specialtype = triggerline->special; + size_t i; + + UINT8 inputmare = max(0, min(255, sides[triggerline->sidenum[0]].textureoffset>>FRACBITS)); + UINT8 inputlap = max(0, min(255, sides[triggerline->sidenum[0]].rowoffset>>FRACBITS)); + + boolean ltemare = triggerline->flags & ML_NOCLIMB; + boolean gtemare = triggerline->flags & ML_BLOCKMONSTERS; + boolean ltelap = triggerline->flags & ML_EFFECT1; + boolean gtelap = triggerline->flags & ML_EFFECT2; + + boolean lapfrombonustime = triggerline->flags & ML_EFFECT3; + boolean perglobalinverse = triggerline->flags & ML_DONTPEGBOTTOM; + boolean perglobal = !(triggerline->flags & ML_EFFECT4) && !perglobalinverse; + + boolean donomares = triggerline->flags & ML_BOUNCY; // nightserize: run at end of level (no mares) + boolean fromnonights = triggerline->flags & ML_TFERLINE; // nightserize: from non-nights // denightserize: all players no nights + + UINT8 currentmare = UINT8_MAX; + UINT8 currentlap = UINT8_MAX; + + // Do early returns for Nightserize + if (specialtype >= 323 && specialtype <= 324) + { + // run only when no mares are found + if (donomares && P_FindLowestMare() != UINT8_MAX) + return false; + + // run only if player is nightserizing from non-nights + if (fromnonights) + { + if (!actor->player) + return false; + else if (actor->player->powers[pw_carry] == CR_NIGHTSMODE) + return false; + } + } + + // Get current mare and lap (and check early return for DeNightserize) + if (perglobal || perglobalinverse + || (specialtype >= 325 && specialtype <= 326 && fromnonights)) + { + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i] || players[i].spectator) + continue; + + // denightserize: run only if all players are not nights + if (specialtype >= 325 && specialtype <= 326 && fromnonights + && players[i].powers[pw_carry] == CR_NIGHTSMODE) + return false; + + UINT8 lap = lapfrombonustime ? players[i].marebonuslap : players[i].marelap; + + // get highest mare/lap of players + if (perglobal) + { + if (players[i].mare > currentmare || currentmare == UINT8_MAX) + { + currentmare = players[i].mare; + currentlap = UINT8_MAX; + } + if (players[i].mare == currentmare + && (lap > currentlap || currentlap == UINT8_MAX)) + currentlap = lap; + } + // get lowest mare/lap of players + else if (perglobalinverse) + { + if (players[i].mare < currentmare || currentmare == UINT8_MAX) + { + currentmare = players[i].mare; + currentlap = UINT8_MAX; + } + if (players[i].mare == currentmare + && (lap < currentlap || currentlap == UINT8_MAX)) + currentlap = lap; + } + } + } + + // get current mare/lap from triggering player + if (!perglobal && !perglobalinverse) + { + if (!actor->player) + return false; + currentmare = actor->player->mare; + currentlap = lapfrombonustime ? actor->player->marebonuslap : actor->player->marelap; + } + + // Compare current mare/lap to input mare/lap based on rules + if (!(specialtype >= 323 && specialtype <= 324 && donomares) // don't return false if donomares and we got this far + && ((ltemare && currentmare > inputmare) + || (gtemare && currentmare < inputmare) + || (!ltemare && !gtemare && currentmare != inputmare) + || (ltelap && currentlap > inputlap) + || (gtelap && currentlap < inputlap) + || (!ltelap && !gtelap && currentlap != inputlap)) + ) + return false; + + return true; +} + /** Used by P_LinedefExecute to check a trigger linedef's conditions * The linedef executor specials in the trigger linedef's sector are run if all conditions are met. * Return false cancels P_LinedefExecute, this happens if a condition is not met. @@ -1733,105 +1845,8 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller case 328: // nights lap - once case 329: // nights bonus time - each time case 330: // nights bonus time - once - { // nightserize - UINT8 inputmare = max(0, min(255, sides[triggerline->sidenum[0]].textureoffset>>FRACBITS)); - UINT8 inputlap = max(0, min(255, sides[triggerline->sidenum[0]].rowoffset>>FRACBITS)); - - BOOL ltemare = triggerline->flags & ML_NOCLIMB; - BOOL gtemare = triggerline->flags & ML_BLOCKMONSTERS; - BOOL ltelap = triggerline->flags & ML_EFFECT1; - BOOL gtelap = triggerline->flags & ML_EFFECT2; - - BOOL lapfrombonustime = triggerline->flags & ML_EFFECT3; - BOOL perglobalinverse = triggerline->flags & ML_DONTPEGBOTTOM; - BOOL perglobal = !(triggerline->flags & ML_EFFECT4) && !perglobalinverse; - - BOOL donomares = triggerline->flags & ML_BOUNCY; // nightserize: run at end of level (no mares) - BOOL fromnonights = triggerline->flags & ML_TFERLINE; // nightserize: from non-nights // denightserize: all players no nights - - UINT8 currentmare = UINT8_MAX; - UINT8 currentlap = UINT8_MAX; - - // Do early returns for Nightserize - if (specialtype >= 323 && specialtype <= 324) - { - // run only when no mares are found - if (donomares && P_FindLowestMare() != UINT8_MAX) - return false; - - // run only if player is nightserizing from non-nights - if (fromnonights) - { - if (!actor->player) - return false; - else if (actor->player->powers[pw_carry] == CR_NIGHTSMODE) - return false; - } - } - - // Get current mare and lap (and check early return for DeNightserize) - if (perglobal || perglobalinverse - || (specialtype >= 325 && specialtype <= 326 && fromnonights)) - { - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i] || players[i].spectator) - continue; - - // denightserize: run only if all players are not nights - if (specialtype >= 325 && specialtype <= 326 && fromnonights - && players[i].powers[pw_carry] == CR_NIGHTSMODE) - return false; - - UINT8 lap = lapfrombonustime ? players[i].marebonuslap : players[i].marelap; - - // get highest mare/lap of players - if (perglobal) - { - if (players[i].mare > currentmare || currentmare == UINT8_MAX) - { - currentmare = players[i].mare; - currentlap = UINT8_MAX; - } - if (players[i].mare == currentmare - && (lap > currentlap || currentlap == UINT8_MAX)) - currentlap = lap; - } - // get lowest mare/lap of players - else if (perglobalinverse) - { - if (players[i].mare < currentmare || currentmare == UINT8_MAX) - { - currentmare = players[i].mare; - currentlap = UINT8_MAX; - } - if (players[i].mare == currentmare - && (lap < currentlap || currentlap == UINT8_MAX)) - currentlap = lap; - } - } - } - - // get current mare/lap from triggering player - if (!perglobal && !perglobalinverse) - { - if (!actor->player) - return false; - currentmare = actor->player->mare; - currentlap = lapfrombonustime ? actor->player->marebonuslap : actor->player->marelap; - } - - // Compare current mare/lap to input mare/lap based on rules - if (!(specialtype >= 323 && specialtype <= 324 && donomares) // don't return false if donomares and we got this far - && ((ltemare && currentmare > inputmare) - || (gtemare && currentmare < inputmare) - || (!ltemare && !gtemare && currentmare != inputmare) - || (ltelap && currentlap > inputlap) - || (gtelap && currentlap < inputlap) - || (!ltelap && !gtelap && currentlap != inputlap)) - ) - return false; - } + if (!P_CheckNightsTriggerLine(triggerline, actor)) + return false; break; default: From 53503cd01f8212ef72e574b6c58156ca2d3455ae Mon Sep 17 00:00:00 2001 From: mazmazz Date: Mon, 2 Apr 2018 08:13:53 -0400 Subject: [PATCH 06/14] Slight fixes for NiGHTS LE Trigger logic --- src/p_spec.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index 4f6898658..fe9f8b18c 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -1549,6 +1549,10 @@ static boolean P_CheckNightsTriggerLine(line_t *triggerline, mobj_t *actor) if (donomares && P_FindLowestMare() != UINT8_MAX) return false; + // run only if there is a mare present + if (!donomares && P_FindLowestMare() == UINT8_MAX) + return false; + // run only if player is nightserizing from non-nights if (fromnonights) { @@ -1601,9 +1605,8 @@ static boolean P_CheckNightsTriggerLine(line_t *triggerline, mobj_t *actor) } } } - // get current mare/lap from triggering player - if (!perglobal && !perglobalinverse) + else if (!perglobal && !perglobalinverse) { if (!actor->player) return false; From f903d01bc142b1f59a21d7a00128430ab13b431f Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 7 Apr 2018 07:33:07 -0400 Subject: [PATCH 07/14] Add ML_DONPTEGTOP flag to Nights LE * Nightserize: Run only if player is already NiGHTS * DeNightserize: Run only if >0 players are NiGHTS --- src/p_spec.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index 590d97a5d..e628b853d 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -1539,6 +1539,7 @@ static boolean P_CheckNightsTriggerLine(line_t *triggerline, mobj_t *actor) boolean donomares = triggerline->flags & ML_BOUNCY; // nightserize: run at end of level (no mares) boolean fromnonights = triggerline->flags & ML_TFERLINE; // nightserize: from non-nights // denightserize: all players no nights + boolean fromnights = triggerline->flags & ML_DONTPEGTOP; // nightserize: from nights // denightserize: >0 players are nights UINT8 currentmare = UINT8_MAX; UINT8 currentlap = UINT8_MAX; @@ -1562,12 +1563,22 @@ static boolean P_CheckNightsTriggerLine(line_t *triggerline, mobj_t *actor) else if (actor->player->powers[pw_carry] == CR_NIGHTSMODE) return false; } + // run only if player is nightserizing from nights + else if (fromnights) + { + if (!actor->player) + return false; + else if (actor->player->powers[pw_carry] != CR_NIGHTSMODE) + return false; + } } // Get current mare and lap (and check early return for DeNightserize) if (perglobal || perglobalinverse - || (specialtype >= 325 && specialtype <= 326 && fromnonights)) + || (specialtype >= 325 && specialtype <= 326 && (fromnonights || fromnights))) { + UINT8 playersarenights = 0; + for (i = 0; i < MAXPLAYERS; i++) { if (!playeringame[i] || players[i].spectator) @@ -1578,6 +1589,11 @@ static boolean P_CheckNightsTriggerLine(line_t *triggerline, mobj_t *actor) && players[i].powers[pw_carry] == CR_NIGHTSMODE) return false; + // count number of nights players for denightserize return + if (specialtype >= 325 && specialtype <= 326 && fromnights + && players[i].powers[pw_carry] == CR_NIGHTSMODE) + playersarenights++; + UINT8 lap = lapfrombonustime ? players[i].marebonuslap : players[i].marelap; // get highest mare/lap of players @@ -1605,6 +1621,11 @@ static boolean P_CheckNightsTriggerLine(line_t *triggerline, mobj_t *actor) currentlap = lap; } } + + // denightserize: run only if >0 players are nights + if (specialtype >= 325 && specialtype <= 326 && fromnights + && playersarenights < 1) + return false; } // get current mare/lap from triggering player else if (!perglobal && !perglobalinverse) @@ -1839,8 +1860,6 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller return false; } break; - - // Let's do the NiGHTS triggers in one code block; they mostly have the same logic case 323: // nightserize - each time case 324: // nightserize - once case 325: // denightserize - each time From 872761e258a865ab5e269fb4a7f2cf291eb076a8 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Fri, 10 Aug 2018 17:12:26 -0400 Subject: [PATCH 08/14] Add lapbegunat and lapstartedtime player variables There is no lapfinishedtime because [mare]finishedtime refers to when Egg Capsule is destroyed. That concept does not apply to laps. --- src/d_player.h | 2 ++ src/lua_playerlib.c | 8 ++++++++ src/p_inter.c | 2 ++ src/p_map.c | 2 ++ src/p_saveg.c | 4 ++++ src/p_setup.c | 3 ++- src/p_user.c | 3 ++- 7 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index 498b7166d..648867b92 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -463,6 +463,8 @@ typedef struct player_s tic_t marebegunat; // Leveltime when mare begun tic_t startedtime; // Time which you started this mare with. tic_t finishedtime; // Time it took you to finish the mare (used for display) + tic_t lapbegunat; // Leveltime when lap begun + tic_t lapstartedtime; // Time which you started this lap with. INT16 finishedspheres; // The spheres you had left upon finishing the mare INT16 finishedrings; // The rings/stars you had left upon finishing the mare UINT32 marescore; // score for this nights stage diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index 7deefa7ff..114aa27b0 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -300,6 +300,10 @@ static int player_get(lua_State *L) lua_pushinteger(L, plr->startedtime); else if (fastcmp(field,"finishedtime")) lua_pushinteger(L, plr->finishedtime); + else if (fastcmp(field,"lapbegunat")) + lua_pushinteger(L, plr->lapbegunat); + else if (fastcmp(field,"lapstartedtime")) + lua_pushinteger(L, plr->lapstartedtime); else if (fastcmp(field,"finishedspheres")) lua_pushinteger(L, plr->finishedspheres); else if (fastcmp(field,"finishedrings")) @@ -588,6 +592,10 @@ static int player_set(lua_State *L) plr->startedtime = (tic_t)luaL_checkinteger(L, 3); else if (fastcmp(field,"finishedtime")) plr->finishedtime = (tic_t)luaL_checkinteger(L, 3); + else if (fastcmp(field,"lapbegunat")) + plr->lapbegunat = (tic_t)luaL_checkinteger(L, 3); + else if (fastcmp(field,"lapstartedtime")) + plr->lapstartedtime = (tic_t)luaL_checkinteger(L, 3); else if (fastcmp(field,"finishedspheres")) plr->finishedspheres = (INT16)luaL_checkinteger(L, 3); else if (fastcmp(field,"finishedrings")) diff --git a/src/p_inter.c b/src/p_inter.c index ce8bba6b6..e7590439e 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1134,6 +1134,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) { player->nightstime += special->info->speed; player->startedtime += special->info->speed; + player->lapstartedtime += special->info->speed; P_RestoreMusic(player); } else @@ -1143,6 +1144,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) { players[i].nightstime += special->info->speed; players[i].startedtime += special->info->speed; + players[i].lapstartedtime += special->info->speed; P_RestoreMusic(&players[i]); } if (special->info->deathsound != sfx_None) diff --git a/src/p_map.c b/src/p_map.c index 415e2bac1..7d3538573 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1114,6 +1114,8 @@ static boolean PIT_CheckThing(mobj_t *thing) )) { pl->marelap++; + pl->lapbegunat = leveltime; + pl->lapstartedtime = pl->nightstime; if (pl->bonustime) { diff --git a/src/p_saveg.c b/src/p_saveg.c index 2b48cc783..e18802f57 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -204,6 +204,8 @@ static void P_NetArchivePlayers(void) WRITEUINT32(save_p, players[i].marebegunat); WRITEUINT32(save_p, players[i].startedtime); WRITEUINT32(save_p, players[i].finishedtime); + WRITEUINT32(save_p, players[i].lapbegunat); + WRITEUINT32(save_p, players[i].lapstartedtime); WRITEINT16(save_p, players[i].finishedspheres); WRITEINT16(save_p, players[i].finishedrings); WRITEUINT32(save_p, players[i].marescore); @@ -397,6 +399,8 @@ static void P_NetUnArchivePlayers(void) players[i].marebegunat = READUINT32(save_p); players[i].startedtime = READUINT32(save_p); players[i].finishedtime = READUINT32(save_p); + players[i].lapbegunat = READUINT32(save_p); + players[i].lapstartedtime = READUINT32(save_p); players[i].finishedspheres = READINT16(save_p); players[i].finishedrings = READINT16(save_p); players[i].marescore = READUINT32(save_p); diff --git a/src/p_setup.c b/src/p_setup.c index e4b6034b1..4b10f431c 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2387,7 +2387,8 @@ static void P_LevelInitStuff(void) players[i].linktimer = players[i].flyangle =\ players[i].anotherflyangle = players[i].nightstime =\ players[i].mare = players[i].marelap =\ - players[i].marebonuslap = players[i].realtime =\ + players[i].marebonuslap = players[i].lapbegunat =\ + players[i].lapstartedtime = players[i].realtime =\ players[i].exiting = 0; // i guess this could be part of the above but i feel mildly uncomfortable implicitly casting diff --git a/src/p_user.c b/src/p_user.c index 99ecb8154..ddaa6384a 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -666,7 +666,7 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime) player->followitem = skins[DEFAULTNIGHTSSKIN].followitem; } - player->nightstime = player->startedtime = nighttime*TICRATE; + player->nightstime = player->startedtime = player->lapstartedtime = nightstime*TICRATE; player->bonustime = false; P_RestoreMusic(player); @@ -762,6 +762,7 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime) player->lastmarescore = player->marescore; player->marescore = 0; player->marebegunat = leveltime; + player->lapbegunat = leveltime; player->spheres = player->rings = 0; } From 62a6fe845dc92fd89962da4bcae6c6f1a5676b29 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Tue, 14 Aug 2018 10:48:50 -0400 Subject: [PATCH 09/14] Add ML_BOUNCY flag to Bonus Time executor to execute BEFORE the capsule is destroyed and player has enough spheres --- src/p_spec.c | 14 ++++++++------ src/p_spec.h | 2 +- src/p_user.c | 5 ++++- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index d4a2b45ce..3ea021bce 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -1420,13 +1420,15 @@ void P_RunNightsLapExecutors(mobj_t *actor) // // P_RunNightsBonusTimeExecutors // -void P_RunNightsBonusTimeExecutors(mobj_t *actor) +void P_RunNightsBonusTimeExecutors(mobj_t *actor, boolean preblowup) { size_t i; for (i = 0; i < numlines; i++) { - if (lines[i].special == 329 || lines[i].special == 330) + if ((lines[i].special == 329 || lines[i].special == 330) + && ((preblowup && (lines[i].flags & ML_BOUNCY)) + || (!preblowup && !(lines[i].flags & ML_BOUNCY)))) P_RunTriggerLinedef(&lines[i], actor, NULL); } } @@ -1574,8 +1576,8 @@ static boolean P_CheckNightsTriggerLine(line_t *triggerline, mobj_t *actor) } // Get current mare and lap (and check early return for DeNightserize) - if (perglobal || perglobalinverse - || (specialtype >= 325 && specialtype <= 326 && (fromnonights || fromnights))) + if (perglobal || perglobalinverse + || (specialtype >= 325 && specialtype <= 326 && (fromnonights || fromnights))) { UINT8 playersarenights = 0; @@ -1604,7 +1606,7 @@ static boolean P_CheckNightsTriggerLine(line_t *triggerline, mobj_t *actor) currentmare = players[i].mare; currentlap = UINT8_MAX; } - if (players[i].mare == currentmare + if (players[i].mare == currentmare && (lap > currentlap || currentlap == UINT8_MAX)) currentlap = lap; } @@ -1616,7 +1618,7 @@ static boolean P_CheckNightsTriggerLine(line_t *triggerline, mobj_t *actor) currentmare = players[i].mare; currentlap = UINT8_MAX; } - if (players[i].mare == currentmare + if (players[i].mare == currentmare && (lap < currentlap || currentlap == UINT8_MAX)) currentlap = lap; } diff --git a/src/p_spec.h b/src/p_spec.h index 5bcf25b7b..0767851e1 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -69,7 +69,7 @@ void P_ChangeSectorTag(UINT32 sector, INT16 newtag); void P_RunNightserizeExecutors(mobj_t *actor); void P_RunDeNightserizeExecutors(mobj_t *actor); void P_RunNightsLapExecutors(mobj_t *actor); -void P_RunNightsBonusTimeExecutors(mobj_t *actor); +void P_RunNightsBonusTimeExecutors(mobj_t *actor, boolean preblowup); ffloor_t *P_GetFFloorByID(sector_t *sec, UINT16 id); diff --git a/src/p_user.c b/src/p_user.c index 6b8901ac7..018387284 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -6014,6 +6014,9 @@ static void P_DoNiGHTSCapsule(player_t *player) { if (player->spheres > 0) { + if (player->capsule->extravalue1 <= 0 && player->spheres >= player->capsule->health) + P_RunNightsBonusTimeExecutors(player->mo, true); + player->spheres--; player->capsule->health--; player->capsule->extravalue1++; @@ -6099,7 +6102,7 @@ static void P_DoNiGHTSCapsule(player_t *player) P_SetTarget(&players[i].capsule, NULL); // Remove capsule from everyone now that it is dead! S_StartScreamSound(player->mo, sfx_ngdone); P_SwitchSpheresBonusMode(true); - P_RunNightsBonusTimeExecutors(player->mo); + P_RunNightsBonusTimeExecutors(player->mo, false); } } else From 8c57218027734564e459c743f57b29174489349d Mon Sep 17 00:00:00 2001 From: mazmazz Date: Tue, 14 Aug 2018 11:06:09 -0400 Subject: [PATCH 10/14] Alternate take on pre-blowup: Do it on first touching tic, instead of first ring pop * Use MT_EGGCAPSULE extravalue2 for tic timer --- src/p_mobj.c | 3 ++- src/p_user.c | 16 +++++++++------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 4353e67c3..b88692d76 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8751,7 +8751,8 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) nummaprings = -1; // no perfect bonus, rings are free break; case MT_EGGCAPSULE: - mobj->extravalue1 = -1; // timer for how long a player has been at the capsule + mobj->extravalue1 = -1; // sphere timer for how long a player has been at the capsule + mobj->extravalue2 = -1; // tic timer for how long a player has been at the capsule break; case MT_REDTEAMRING: mobj->color = skincolor_redteam; diff --git a/src/p_user.c b/src/p_user.c index 018387284..e3b6f2261 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -5946,6 +5946,8 @@ static void P_DoNiGHTSCapsule(player_t *player) { INT32 i; + player->capsule->extravalue2++; // tic counter + if (abs(player->mo->x-player->capsule->x) <= 2*FRACUNIT) { P_UnsetThingPosition(player->mo); @@ -6007,6 +6009,9 @@ static void P_DoNiGHTSCapsule(player_t *player) } } + if (player->capsule->extravalue2 <= 0 && player->spheres >= player->capsule->health) + P_RunNightsBonusTimeExecutors(player->mo, true); // run pre-blowup executors + // Time to blow it up! if (player->mo->x == player->capsule->x && player->mo->y == player->capsule->y @@ -6014,9 +6019,6 @@ static void P_DoNiGHTSCapsule(player_t *player) { if (player->spheres > 0) { - if (player->capsule->extravalue1 <= 0 && player->spheres >= player->capsule->health) - P_RunNightsBonusTimeExecutors(player->mo, true); - player->spheres--; player->capsule->health--; player->capsule->extravalue1++; @@ -6033,7 +6035,7 @@ static void P_DoNiGHTSCapsule(player_t *player) player->capsule->flags &= ~MF_NOGRAVITY; player->capsule->momz = 5*FRACUNIT; player->capsule->reactiontime = 0; - player->capsule->extravalue1 = -1; + player->capsule->extravalue1 = player->capsule->extravalue2 = -1; for (i = 0; i < MAXPLAYERS; i++) if (playeringame[i] && !player->exiting && players[i].mare == player->mare) @@ -6102,7 +6104,7 @@ static void P_DoNiGHTSCapsule(player_t *player) P_SetTarget(&players[i].capsule, NULL); // Remove capsule from everyone now that it is dead! S_StartScreamSound(player->mo, sfx_ngdone); P_SwitchSpheresBonusMode(true); - P_RunNightsBonusTimeExecutors(player->mo, false); + P_RunNightsBonusTimeExecutors(player->mo, false); // run post blow-up executors } } else @@ -6111,11 +6113,11 @@ static void P_DoNiGHTSCapsule(player_t *player) player->texttimer = 4*TICRATE; player->textvar = 3; // Get more rings! player->capsule->reactiontime = 0; - player->capsule->extravalue1 = -1; + player->capsule->extravalue1 = player->capsule->extravalue2 = -1; } } else - player->capsule->extravalue1 = -1; + player->capsule->extravalue1 = player->capsule->extravalue2 = -1; } // From 3f312ce114afbc5aabdbd5c52a8016bfd5dc9376 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Tue, 14 Aug 2018 12:00:37 -0400 Subject: [PATCH 11/14] Make Bonus Time Start executor into a general Egg Capsule Touch executor * Entrance/exit flags * Enough/not-enough-rings flags (with "doesn't matter" line option) --- src/p_spec.c | 11 +++++++---- src/p_spec.h | 2 +- src/p_user.c | 7 ++++--- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index 3ea021bce..617625fc1 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -1418,17 +1418,20 @@ void P_RunNightsLapExecutors(mobj_t *actor) } // -// P_RunNightsBonusTimeExecutors +// P_RunNightsCapsuleTouchExecutors // -void P_RunNightsBonusTimeExecutors(mobj_t *actor, boolean preblowup) +void P_RunNightsCapsuleTouchExecutors(mobj_t *actor, boolean entering, boolean enoughspheres) { size_t i; for (i = 0; i < numlines; i++) { if ((lines[i].special == 329 || lines[i].special == 330) - && ((preblowup && (lines[i].flags & ML_BOUNCY)) - || (!preblowup && !(lines[i].flags & ML_BOUNCY)))) + && ((entering && (lines[i].flags & ML_TFERLINE)) + || (!entering && !(lines[i].flags & ML_TFERLINE))) + && ((lines[i].flags & ML_DONTPEGTOP) + || (enoughspheres && !(lines[i].flags & ML_BOUNCY)) + || (!enoughspheres && (lines[i].flags & ML_BOUNCY)))) P_RunTriggerLinedef(&lines[i], actor, NULL); } } diff --git a/src/p_spec.h b/src/p_spec.h index 0767851e1..e0bcc18eb 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -69,7 +69,7 @@ void P_ChangeSectorTag(UINT32 sector, INT16 newtag); void P_RunNightserizeExecutors(mobj_t *actor); void P_RunDeNightserizeExecutors(mobj_t *actor); void P_RunNightsLapExecutors(mobj_t *actor); -void P_RunNightsBonusTimeExecutors(mobj_t *actor, boolean preblowup); +void P_RunNightsCapsuleTouchExecutors(mobj_t *actor, boolean entering, boolean enoughspheres); ffloor_t *P_GetFFloorByID(sector_t *sec, UINT16 id); diff --git a/src/p_user.c b/src/p_user.c index e3b6f2261..7e678fb61 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -6009,8 +6009,8 @@ static void P_DoNiGHTSCapsule(player_t *player) } } - if (player->capsule->extravalue2 <= 0 && player->spheres >= player->capsule->health) - P_RunNightsBonusTimeExecutors(player->mo, true); // run pre-blowup executors + if (player->capsule->extravalue2 <= 0) + P_RunNightsCapsuleTouchExecutors(player->mo, true, player->spheres >= player->capsule->health); // run capsule entrance executors // Time to blow it up! if (player->mo->x == player->capsule->x @@ -6104,7 +6104,7 @@ static void P_DoNiGHTSCapsule(player_t *player) P_SetTarget(&players[i].capsule, NULL); // Remove capsule from everyone now that it is dead! S_StartScreamSound(player->mo, sfx_ngdone); P_SwitchSpheresBonusMode(true); - P_RunNightsBonusTimeExecutors(player->mo, false); // run post blow-up executors + P_RunNightsCapsuleTouchExecutors(player->mo, false, true); // run capsule exit executors, and we destroyed it } } else @@ -6114,6 +6114,7 @@ static void P_DoNiGHTSCapsule(player_t *player) player->textvar = 3; // Get more rings! player->capsule->reactiontime = 0; player->capsule->extravalue1 = player->capsule->extravalue2 = -1; + P_RunNightsCapsuleTouchExecutors(player->mo, false, false); // run capsule exit executors, and we lacked rings } } else From efdf68477091392c4aa3522f375cba14a2c16b41 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Tue, 14 Aug 2018 12:48:00 -0400 Subject: [PATCH 12/14] Fix Capsule Entrance exec firing repeatedly --- src/p_user.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 7e678fb61..f202ff97f 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -6009,7 +6009,7 @@ static void P_DoNiGHTSCapsule(player_t *player) } } - if (player->capsule->extravalue2 <= 0) + if (player->capsule->extravalue2 <= 0 && player->capsule->health > 0) P_RunNightsCapsuleTouchExecutors(player->mo, true, player->spheres >= player->capsule->health); // run capsule entrance executors // Time to blow it up! @@ -6118,7 +6118,7 @@ static void P_DoNiGHTSCapsule(player_t *player) } } else - player->capsule->extravalue1 = player->capsule->extravalue2 = -1; + player->capsule->extravalue1 = -1; } // From c3703cfc246adb62c2b4939869539448b0eaa2c5 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Tue, 14 Aug 2018 14:57:58 -0400 Subject: [PATCH 13/14] Comments --- src/p_spec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index 617625fc1..66fedeab5 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -1871,8 +1871,8 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller case 326: // denightserize - once case 327: // nights lap - each time case 328: // nights lap - once - case 329: // nights bonus time - each time - case 330: // nights bonus time - once + case 329: // nights egg capsule touch - each time + case 330: // nights egg capsule touch - once if (!P_CheckNightsTriggerLine(triggerline, actor)) return false; break; From 61c84be70445c61c8907ca5bc647f574a5623342 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Tue, 14 Aug 2018 16:08:21 -0400 Subject: [PATCH 14/14] Fix bonus time quirk where lines are run if player->marebonuslap is 0 * Bonus laps start at 1, so if a line is looking for bonus laps, they should only be run at >= 1. --- src/p_spec.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/p_spec.c b/src/p_spec.c index 66fedeab5..e70aec650 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -1641,6 +1641,9 @@ static boolean P_CheckNightsTriggerLine(line_t *triggerline, mobj_t *actor) currentlap = lapfrombonustime ? actor->player->marebonuslap : actor->player->marelap; } + if (lapfrombonustime && !currentlap) + return false; // special case: player->marebonuslap is 0 until passing through on bonus time. Don't trigger lines looking for inputlap 0. + // Compare current mare/lap to input mare/lap based on rules if (!(specialtype >= 323 && specialtype <= 324 && donomares) // don't return false if donomares and we got this far && ((ltemare && currentmare > inputmare)