From 729b7d81c386d2fa89ad12479f0f8e5d6fc50850 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sun, 8 Apr 2018 14:31:56 +0100 Subject: [PATCH 01/80] DEVMODE visual output messed with a bit. NOT in master this time. * DBG_PLAYER split out from DBG_DETAILED. (The difference I'm intending here is whether it's referring to stuff in the player struct, or stuff in the mobj struct.) * Function pointer for text so both modes can show the same stuff if it's not taking over the entire screen, and only show the "INFO NOT AVAILABLE AT THIS RESOLUTION" if it's in danger of going off the bottom. --- src/doomdef.h | 3 +- src/st_stuff.c | 249 +++++++++++++++++++++++++------------------------ 2 files changed, 127 insertions(+), 125 deletions(-) diff --git a/src/doomdef.h b/src/doomdef.h index 32771163e..d3fe9d3a2 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -446,7 +446,7 @@ extern INT32 cv_debug; #define DBG_BASIC 0x0001 #define DBG_DETAILED 0x0002 -#define DBG_RANDOMIZER 0x0004 +#define DBG_PLAYER 0x0004 #define DBG_RENDER 0x0008 #define DBG_NIGHTSBASIC 0x0010 #define DBG_NIGHTS 0x0020 @@ -456,6 +456,7 @@ extern INT32 cv_debug; #define DBG_MEMORY 0x0200 #define DBG_SETUP 0x0400 #define DBG_LUA 0x0800 +#define DBG_RANDOMIZER 0x1000 // ======================= // Misc stuff for later... diff --git a/src/st_stuff.c b/src/st_stuff.c index a513a028c..ac4ee60ea 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -455,7 +455,8 @@ static void ST_DrawNightsOverlayNum(fixed_t x /* right border */, fixed_t y, fix // Devmode information static void ST_drawDebugInfo(void) { - INT32 height = 0; + INT32 height = 0, h = 8, w = 18, lowh; + void (*textfunc)(INT32, INT32, INT32, const char *); if (!(stplyr->mo && cv_debug)) return; @@ -464,135 +465,135 @@ static void ST_drawDebugInfo(void) if ((moviemode == MM_GIF && cv_gif_downscale.value) || vid.dupx == 1) { - if (cv_debug & DBG_BASIC) - { - const fixed_t d = AngleFixed(stplyr->mo->angle); - V_DrawRightAlignedString(320, 0, VFLAGS, va("X: %6d", stplyr->mo->x>>FRACBITS)); - V_DrawRightAlignedString(320, 8, VFLAGS, va("Y: %6d", stplyr->mo->y>>FRACBITS)); - V_DrawRightAlignedString(320, 16, VFLAGS, va("Z: %6d", stplyr->mo->z>>FRACBITS)); - V_DrawRightAlignedString(320, 24, VFLAGS, va("A: %6d", FixedInt(d))); - - height += 4*9; - } - - if (cv_debug & (DBG_MEMORY|DBG_RANDOMIZER|DBG_DETAILED)) - { - V_DrawRightAlignedThinString(320, height, VFLAGS|V_REDMAP, "INFO NOT AVAILABLE"); - V_DrawRightAlignedThinString(320, 8+height, VFLAGS|V_REDMAP, "AT THIS RESOLUTION"); - } + textfunc = V_DrawRightAlignedString; + lowh = ((vid.height/vid.dupy) - 16); } else { -#define h 4 -#define dist 2 -#define V_DrawDebugLine(str) V_DrawRightAlignedSmallString(320, height, VFLAGS, str);\ - height += h - - if (cv_debug & DBG_MEMORY) - { - V_DrawDebugLine(va("Heap: %8sKB", sizeu1(Z_TotalUsage()>>10))); - - height += dist; - } - - if (cv_debug & DBG_RANDOMIZER) // randomizer testing - { - fixed_t peekres = P_RandomPeek(); - peekres *= 10000; // Change from fixed point - peekres >>= FRACBITS; // to displayable decimal - - V_DrawDebugLine(va("Init: %08x", P_GetInitSeed())); - V_DrawDebugLine(va("Seed: %08x", P_GetRandSeed())); - V_DrawDebugLine(va("== : .%04d", peekres)); - - height += dist; - } - - if (cv_debug & DBG_DETAILED) - { -#define V_DrawDebugFlag(f, str) V_DrawRightAlignedSmallString(w, height, VFLAGS|f, str);\ - w -= 9 - const fixed_t d = AngleFixed(stplyr->drawangle); - INT32 w = 320; - - V_DrawDebugLine(va("SHIELD: %5x", stplyr->powers[pw_shield])); - V_DrawDebugLine(va("SCALE: %5d%%", (stplyr->mo->scale*100)>>FRACBITS)); - V_DrawDebugLine(va("CARRY: %5x", stplyr->powers[pw_carry])); - V_DrawDebugLine(va("AIR: %4d, %3d", stplyr->powers[pw_underwater], stplyr->powers[pw_spacetime])); - V_DrawDebugLine(va("ABILITY: %3d, %3d", stplyr->charability, stplyr->charability2)); - V_DrawDebugLine(va("ACTIONSPD: %5d", stplyr->actionspd>>FRACBITS)); - V_DrawDebugLine(va("PEEL: %3d", stplyr->dashmode)); - V_DrawDebugLine(va("SCOREADD: %3d", stplyr->scoreadd)); - - // Flags - V_DrawDebugFlag(((stplyr->pflags & PF_SHIELDABILITY) ? V_GREENMAP : V_REDMAP), "SH"); - V_DrawDebugFlag(((stplyr->pflags & PF_THOKKED) ? V_GREENMAP : V_REDMAP), "TH"); - V_DrawDebugFlag(((stplyr->pflags & PF_STARTDASH) ? V_GREENMAP : V_REDMAP), "ST"); - V_DrawDebugFlag(((stplyr->pflags & PF_SPINNING) ? V_GREENMAP : V_REDMAP), "SP"); - V_DrawDebugFlag(((stplyr->pflags & PF_NOJUMPDAMAGE) ? V_GREENMAP : V_REDMAP), "ND"); - V_DrawDebugFlag(((stplyr->pflags & PF_JUMPED) ? V_GREENMAP : V_REDMAP), "JD"); - V_DrawDebugFlag(((stplyr->pflags & PF_STARTJUMP) ? V_GREENMAP : V_REDMAP), "SJ"); - V_DrawDebugFlag(0, "PF/SF:"); - height += h; - w = 320; - V_DrawDebugFlag(((stplyr->pflags & PF_INVIS) ? V_GREENMAP : V_REDMAP), "*I"); - V_DrawDebugFlag(((stplyr->pflags & PF_NOCLIP) ? V_GREENMAP : V_REDMAP), "*C"); - V_DrawDebugFlag(((stplyr->pflags & PF_GODMODE) ? V_GREENMAP : V_REDMAP), "*G"); - V_DrawDebugFlag(((stplyr->charflags & SF_SUPER) ? V_GREENMAP : V_REDMAP), "SU"); - V_DrawDebugFlag(((stplyr->pflags & PF_APPLYAUTOBRAKE) ? V_GREENMAP : V_REDMAP), "AA"); - V_DrawDebugFlag(((stplyr->pflags & PF_SLIDING) ? V_GREENMAP : V_REDMAP), "SL"); - V_DrawDebugFlag(((stplyr->pflags & PF_BOUNCING) ? V_GREENMAP : V_REDMAP), "BO"); - V_DrawDebugFlag(((stplyr->pflags & PF_GLIDING) ? V_GREENMAP : V_REDMAP), "GL"); - height += h; - - V_DrawDebugLine(va("CEILINGZ: %6d", stplyr->mo->ceilingz>>FRACBITS)); - V_DrawDebugLine(va("FLOORZ: %6d", stplyr->mo->floorz>>FRACBITS)); - - V_DrawDebugLine(va("CMOMX: %6d", stplyr->cmomx>>FRACBITS)); - V_DrawDebugLine(va("CMOMY: %6d", stplyr->cmomy>>FRACBITS)); - V_DrawDebugLine(va("PMOMZ: %6d", stplyr->mo->pmomz>>FRACBITS)); - - w = 320; - V_DrawDebugFlag(((stplyr->mo->eflags & MFE_APPLYPMOMZ) ? V_GREENMAP : V_REDMAP), "AP"); - V_DrawDebugFlag(((stplyr->mo->eflags & MFE_SPRUNG) ? V_GREENMAP : V_REDMAP), "SP"); - //V_DrawDebugFlag(((stplyr->mo->eflags & MFE_PUSHED) ? V_GREENMAP : V_REDMAP), "PU"); -- not relevant to players - V_DrawDebugFlag(((stplyr->mo->eflags & MFE_GOOWATER) ? V_GREENMAP : V_REDMAP), "GW"); - V_DrawDebugFlag(((stplyr->mo->eflags & MFE_VERTICALFLIP) ? V_GREENMAP : V_REDMAP), "VF"); - V_DrawDebugFlag(((stplyr->mo->eflags & MFE_JUSTSTEPPEDDOWN) ? V_GREENMAP : V_REDMAP), "JS"); - V_DrawDebugFlag(((stplyr->mo->eflags & MFE_UNDERWATER) ? V_GREENMAP : V_REDMAP), "UW"); - V_DrawDebugFlag(((stplyr->mo->eflags & MFE_TOUCHWATER) ? V_GREENMAP : V_REDMAP), "TW"); - V_DrawDebugFlag(((stplyr->mo->eflags & MFE_JUSTHITFLOOR) ? V_GREENMAP : V_REDMAP), "JH"); - V_DrawDebugFlag(((stplyr->mo->eflags & MFE_ONGROUND) ? V_GREENMAP : V_REDMAP), "OG"); - V_DrawDebugFlag(0, "MFE:"); - height += h; - - V_DrawDebugLine(va("MOMX: %6d", stplyr->rmomx>>FRACBITS)); - V_DrawDebugLine(va("MOMY: %6d", stplyr->rmomy>>FRACBITS)); - V_DrawDebugLine(va("MOMZ: %6d", stplyr->mo->momz>>FRACBITS)); - - V_DrawDebugLine(va("SPEED: %6d", stplyr->speed>>FRACBITS)); - - V_DrawDebugLine(va("DRAWANGLE: %6d", FixedInt(d))); - - height += dist; -#undef V_DrawDebugFlag - } - - if (cv_debug & DBG_BASIC) - { - const fixed_t d = AngleFixed(stplyr->mo->angle); - V_DrawDebugLine(va("X: %6d", stplyr->mo->x>>FRACBITS)); - V_DrawDebugLine(va("Y: %6d", stplyr->mo->y>>FRACBITS)); - V_DrawDebugLine(va("Z: %6d", stplyr->mo->z>>FRACBITS)); - V_DrawDebugLine(va("A: %6d", FixedInt(d))); - - //height += dist; - } + textfunc = V_DrawRightAlignedSmallString; + h /= 2; + w /= 2; + lowh = 0; } +#define V_DrawDebugLine(str) if (lowh && (height > lowh))\ + {\ + V_DrawRightAlignedThinString(320, 8+lowh, VFLAGS|V_REDMAP, "SOME INFO NOT VISIBLE");\ + return;\ + }\ + textfunc(320, height, VFLAGS, str);\ + height += h; + +#define V_DrawDebugFlag(f, str) textfunc(width, height, VFLAGS|f, str);\ + width -= w + + if (cv_debug & DBG_MEMORY) + { + V_DrawDebugLine(va("Heap: %8sKB", sizeu1(Z_TotalUsage()>>10))); + + height += h/2; + } + + if (cv_debug & DBG_RANDOMIZER) // randomizer testing + { + fixed_t peekres = P_RandomPeek(); + peekres *= 10000; // Change from fixed point + peekres >>= FRACBITS; // to displayable decimal + + V_DrawDebugLine(va("Init: %08x", P_GetInitSeed())); + V_DrawDebugLine(va("Seed: %08x", P_GetRandSeed())); + V_DrawDebugLine(va("== : .%04d", peekres)); + + height += h/2; + } + + if (cv_debug & DBG_PLAYER) + { + INT32 width = 320; + const fixed_t d = AngleFixed(stplyr->drawangle); + + V_DrawDebugLine(va("SHIELD: %5x", stplyr->powers[pw_shield])); + V_DrawDebugLine(va("SCALE: %5d%%", (stplyr->mo->scale*100)>>FRACBITS)); + V_DrawDebugLine(va("CARRY: %5x", stplyr->powers[pw_carry])); + V_DrawDebugLine(va("AIR: %4d, %3d", stplyr->powers[pw_underwater], stplyr->powers[pw_spacetime])); + V_DrawDebugLine(va("ABILITY: %3d, %3d", stplyr->charability, stplyr->charability2)); + V_DrawDebugLine(va("ACTIONSPD: %5d", stplyr->actionspd>>FRACBITS)); + V_DrawDebugLine(va("PEEL: %3d", stplyr->dashmode)); + V_DrawDebugLine(va("SCOREADD: %3d", stplyr->scoreadd)); + + // Flags + V_DrawDebugFlag(((stplyr->pflags & PF_SHIELDABILITY) ? V_GREENMAP : V_REDMAP), "SH"); + V_DrawDebugFlag(((stplyr->pflags & PF_THOKKED) ? V_GREENMAP : V_REDMAP), "TH"); + V_DrawDebugFlag(((stplyr->pflags & PF_STARTDASH) ? V_GREENMAP : V_REDMAP), "ST"); + V_DrawDebugFlag(((stplyr->pflags & PF_SPINNING) ? V_GREENMAP : V_REDMAP), "SP"); + V_DrawDebugFlag(((stplyr->pflags & PF_NOJUMPDAMAGE) ? V_GREENMAP : V_REDMAP), "ND"); + V_DrawDebugFlag(((stplyr->pflags & PF_JUMPED) ? V_GREENMAP : V_REDMAP), "JD"); + V_DrawDebugFlag(((stplyr->pflags & PF_STARTJUMP) ? V_GREENMAP : V_REDMAP), "SJ"); + V_DrawDebugFlag(0, "PF/SF:"); + height += h; + width = 320; + V_DrawDebugFlag(((stplyr->pflags & PF_INVIS) ? V_GREENMAP : V_REDMAP), "*I"); + V_DrawDebugFlag(((stplyr->pflags & PF_NOCLIP) ? V_GREENMAP : V_REDMAP), "*C"); + V_DrawDebugFlag(((stplyr->pflags & PF_GODMODE) ? V_GREENMAP : V_REDMAP), "*G"); + V_DrawDebugFlag(((stplyr->charflags & SF_SUPER) ? V_GREENMAP : V_REDMAP), "SU"); + V_DrawDebugFlag(((stplyr->pflags & PF_APPLYAUTOBRAKE) ? V_GREENMAP : V_REDMAP), "AA"); + V_DrawDebugFlag(((stplyr->pflags & PF_SLIDING) ? V_GREENMAP : V_REDMAP), "SL"); + V_DrawDebugFlag(((stplyr->pflags & PF_BOUNCING) ? V_GREENMAP : V_REDMAP), "BO"); + V_DrawDebugFlag(((stplyr->pflags & PF_GLIDING) ? V_GREENMAP : V_REDMAP), "GL"); + height += h; + + V_DrawDebugLine(va("DRAWANGLE: %6d", FixedInt(d))); + + height += h/2; + } + + if (cv_debug & DBG_DETAILED) + { + INT32 width = 320; + + V_DrawDebugLine(va("CEILINGZ: %6d", stplyr->mo->ceilingz>>FRACBITS)); + V_DrawDebugLine(va("FLOORZ: %6d", stplyr->mo->floorz>>FRACBITS)); + + V_DrawDebugLine(va("CMOMX: %6d", stplyr->cmomx>>FRACBITS)); + V_DrawDebugLine(va("CMOMY: %6d", stplyr->cmomy>>FRACBITS)); + V_DrawDebugLine(va("PMOMZ: %6d", stplyr->mo->pmomz>>FRACBITS)); + + width = 320; + V_DrawDebugFlag(((stplyr->mo->eflags & MFE_APPLYPMOMZ) ? V_GREENMAP : V_REDMAP), "AP"); + V_DrawDebugFlag(((stplyr->mo->eflags & MFE_SPRUNG) ? V_GREENMAP : V_REDMAP), "SP"); + //V_DrawDebugFlag(((stplyr->mo->eflags & MFE_PUSHED) ? V_GREENMAP : V_REDMAP), "PU"); -- not relevant to players + V_DrawDebugFlag(((stplyr->mo->eflags & MFE_GOOWATER) ? V_GREENMAP : V_REDMAP), "GW"); + V_DrawDebugFlag(((stplyr->mo->eflags & MFE_VERTICALFLIP) ? V_GREENMAP : V_REDMAP), "VF"); + V_DrawDebugFlag(((stplyr->mo->eflags & MFE_JUSTSTEPPEDDOWN) ? V_GREENMAP : V_REDMAP), "JS"); + V_DrawDebugFlag(((stplyr->mo->eflags & MFE_UNDERWATER) ? V_GREENMAP : V_REDMAP), "UW"); + V_DrawDebugFlag(((stplyr->mo->eflags & MFE_TOUCHWATER) ? V_GREENMAP : V_REDMAP), "TW"); + V_DrawDebugFlag(((stplyr->mo->eflags & MFE_JUSTHITFLOOR) ? V_GREENMAP : V_REDMAP), "JH"); + V_DrawDebugFlag(((stplyr->mo->eflags & MFE_ONGROUND) ? V_GREENMAP : V_REDMAP), "OG"); + V_DrawDebugFlag(0, "MFE:"); + height += h; + + V_DrawDebugLine(va("MOMX: %6d", stplyr->rmomx>>FRACBITS)); + V_DrawDebugLine(va("MOMY: %6d", stplyr->rmomy>>FRACBITS)); + V_DrawDebugLine(va("MOMZ: %6d", stplyr->mo->momz>>FRACBITS)); + + V_DrawDebugLine(va("SPEED: %6d", stplyr->speed>>FRACBITS)); + + height += h/2; + } + + if (cv_debug & DBG_BASIC) + { + const fixed_t d = AngleFixed(stplyr->mo->angle); + V_DrawDebugLine(va("X: %6d", stplyr->mo->x>>FRACBITS)); + V_DrawDebugLine(va("Y: %6d", stplyr->mo->y>>FRACBITS)); + V_DrawDebugLine(va("Z: %6d", stplyr->mo->z>>FRACBITS)); + V_DrawDebugLine(va("A: %6d", FixedInt(d))); + + //height += h/2; + } + +#undef V_DrawDebugFlag #undef V_DrawDebugLine -#undef dist -#undef h #undef VFLAGS } From 522fccaf2e507ac805d05de46d0d516cfb001c95 Mon Sep 17 00:00:00 2001 From: toaster Date: Wed, 13 Jun 2018 17:52:23 +0100 Subject: [PATCH 02/80] * Record attack tab-HUD tweaks. * Do not subtract a life when retrying if you have infinite lives. --- src/g_game.c | 2 +- src/hu_stuff.c | 20 ++++++++++++-------- src/st_stuff.c | 2 +- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index e5077fb21..2acafddb3 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1893,7 +1893,7 @@ void G_Ticker(boolean run) G_ClearRetryFlag(); // Costs a life to retry ... unless the player in question is dead already. - if (G_GametypeUsesLives() && players[consoleplayer].playerstate == PST_LIVE) + if (G_GametypeUsesLives() && players[consoleplayer].playerstate == PST_LIVE && players[consoleplayer].lives != 0x7f) players[consoleplayer].lives -= 1; G_DoReborn(consoleplayer); diff --git a/src/hu_stuff.c b/src/hu_stuff.c index a13801388..bc57931f5 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -1029,25 +1029,29 @@ UINT16 hu_demorings; static void HU_DrawDemoInfo(void) { - V_DrawString(4, 188-24, V_YELLOWMAP, va(M_GetText("%s's replay"), player_names[0])); + INT32 h = 188; + if (modeattacking == ATTACKING_NIGHTS) + h -= 12; + + V_DrawString(4, h-24, V_YELLOWMAP|V_ALLOWLOWERCASE, va(M_GetText("%s's replay"), player_names[0])); if (modeattacking) { - V_DrawString(4, 188-16, V_YELLOWMAP|V_MONOSPACE, "SCORE:"); - V_DrawRightAlignedString(120, 188-16, V_MONOSPACE, va("%d", hu_demoscore)); + V_DrawString(4, h-16, V_YELLOWMAP|V_MONOSPACE, "SCORE:"); + V_DrawRightAlignedString(120, h-16, V_MONOSPACE, va("%d", hu_demoscore)); - V_DrawString(4, 188- 8, V_YELLOWMAP|V_MONOSPACE, "TIME:"); + V_DrawString(4, h-8, V_YELLOWMAP|V_MONOSPACE, "TIME:"); if (hu_demotime != UINT32_MAX) - V_DrawRightAlignedString(120, 188- 8, V_MONOSPACE, va("%i:%02i.%02i", + V_DrawRightAlignedString(120, h-8, V_MONOSPACE, va("%i:%02i.%02i", G_TicsToMinutes(hu_demotime,true), G_TicsToSeconds(hu_demotime), G_TicsToCentiseconds(hu_demotime))); else - V_DrawRightAlignedString(120, 188- 8, V_MONOSPACE, "--:--.--"); + V_DrawRightAlignedString(120, h-8, V_MONOSPACE, "--:--.--"); if (modeattacking == ATTACKING_RECORD) { - V_DrawString(4, 188 , V_YELLOWMAP|V_MONOSPACE, "RINGS:"); - V_DrawRightAlignedString(120, 188 , V_MONOSPACE, va("%d", hu_demorings)); + V_DrawString(4, h, V_YELLOWMAP|V_MONOSPACE, "RINGS:"); + V_DrawRightAlignedString(120, h, V_MONOSPACE, va("%d", hu_demorings)); } } } diff --git a/src/st_stuff.c b/src/st_stuff.c index d5cc9cf29..2a7e0636a 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -2393,7 +2393,7 @@ static void ST_overlayDrawer(void) ) ST_drawTextHUD(); - if (modeattacking) + if (modeattacking && !hu_showscores) ST_drawInput(); ST_drawDebugInfo(); From 62927bbb76fc045a8c7a61606ac99f8086d003ac Mon Sep 17 00:00:00 2001 From: toaster Date: Thu, 14 Jun 2018 00:58:28 +0100 Subject: [PATCH 03/80] * Hold the pause button to restart a record attack run! * Obligatory GIF: https://cdn.discordapp.com/attachments/400761370800422922/456586705424875520/srb20047.gif * Show powerup display in singleplayer even while holding Game Status button. --- src/g_game.c | 54 +++++++++++++++++++++++++++++++++++++------------- src/g_game.h | 1 + src/hu_stuff.c | 23 +++++++++++++++++++++ src/m_menu.c | 6 +++--- src/m_menu.h | 4 +++- src/p_setup.c | 10 +++++++++- src/st_stuff.c | 8 +++++--- 7 files changed, 84 insertions(+), 22 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 2acafddb3..4463f55ce 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1672,7 +1672,7 @@ void G_DoLoadLevel(boolean resetplayer) CON_ClearHUD(); } -static INT32 pausedelay = 0; +INT32 pausedelay = 0; static INT32 camtoggledelay, camtoggledelay2 = 0; // @@ -1822,17 +1822,30 @@ boolean G_Responder(event_t *ev) if (ev->data1 == gamecontrol[gc_pause][0] || ev->data1 == gamecontrol[gc_pause][1]) { - if (!pausedelay) + if (modeattacking && !demoplayback && (gamestate == GS_LEVEL)) { - // don't let busy scripts prevent pausing - pausedelay = NEWTICRATE/7; + if (menuactive || pausedelay < 0 || leveltime < 2) + return true; - // command will handle all the checks for us - COM_ImmedExecute("pause"); - return true; + if (++pausedelay > (NEWTICRATE/3)) + { + pausedelay = INT32_MIN; + G_SetRetryFlag(); + return true; + } + pausedelay++; // counteract subsequent subtraction this frame } else - pausedelay = NEWTICRATE/7; + { + INT32 oldpausedelay = pausedelay; + pausedelay = (NEWTICRATE/7); + if (!oldpausedelay) + { + // command will handle all the checks for us + COM_ImmedExecute("pause"); + return true; + } + } } if (ev->data1 == gamecontrol[gc_camtoggle][0] || ev->data1 == gamecontrol[gc_camtoggle][1]) @@ -1892,11 +1905,16 @@ void G_Ticker(boolean run) { G_ClearRetryFlag(); - // Costs a life to retry ... unless the player in question is dead already. - if (G_GametypeUsesLives() && players[consoleplayer].playerstate == PST_LIVE && players[consoleplayer].lives != 0x7f) - players[consoleplayer].lives -= 1; + if (modeattacking) + M_ModeAttackRetry(0); + else + { + // Costs a life to retry ... unless the player in question is dead already. + if (G_GametypeUsesLives() && players[consoleplayer].playerstate == PST_LIVE && players[consoleplayer].lives != 0x7f) + players[consoleplayer].lives -= 1; - G_DoReborn(consoleplayer); + G_DoReborn(consoleplayer); + } } for (i = 0; i < MAXPLAYERS; i++) @@ -1994,8 +2012,13 @@ void G_Ticker(boolean run) if (run) { - if (pausedelay) - pausedelay--; + if (pausedelay && pausedelay != INT32_MIN) + { + if (pausedelay > 0) + pausedelay--; + else + pausedelay++; + } if (camtoggledelay) camtoggledelay--; @@ -2935,6 +2958,9 @@ static void G_DoCompleted(void) tokenlist = 0; // Reset the list + if (modeattacking && pausedelay) + pausedelay = 0; + gameaction = ga_nothing; if (metalplayback) diff --git a/src/g_game.h b/src/g_game.h index d6b41830e..3d04370aa 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -53,6 +53,7 @@ extern INT16 prevmap, nextmap; extern INT32 gameovertics; extern tic_t timeinmap; // Ticker for time spent in level (used for levelcard display) extern INT16 rw_maximums[NUM_WEAPONS]; +extern INT32 pausedelay; // used in game menu extern consvar_t cv_crosshair, cv_crosshair2; diff --git a/src/hu_stuff.c b/src/hu_stuff.c index bc57931f5..f4730005e 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -1120,6 +1120,29 @@ void HU_Drawer(void) V_DrawCenteredString(BASEVIDWIDTH/2, 180, V_YELLOWMAP | V_ALLOWLOWERCASE, resynch_text); } + + if (modeattacking && pausedelay > 1) + { + UINT8 strength = (pausedelay*10)/(NEWTICRATE/3); + INT32 y = hudinfo[HUD_LIVES].y - 13; + + if (strength > 9) + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 0); + else if (strength) + V_DrawFadeScreen(0, strength); + + if (players[consoleplayer].powers[pw_carry] == CR_NIGHTSMODE) + y -= 16; + else + { + if (players[consoleplayer].pflags & PF_AUTOBRAKE) + y -= 8; + if (players[consoleplayer].pflags & PF_ANALOGMODE) + y -= 8; + } + + V_DrawThinString(hudinfo[HUD_LIVES].x-2, y, hudinfo[HUD_LIVES].f|((leveltime & 2) ? V_SKYMAP : V_BLUEMAP), "RETRYING..."); + } } //====================================================================== diff --git a/src/m_menu.c b/src/m_menu.c index a866dac1b..5258f4b44 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -282,7 +282,6 @@ static void M_Statistics(INT32 choice); static void M_ReplayTimeAttack(INT32 choice); static void M_ChooseTimeAttack(INT32 choice); static void M_ChooseNightsAttack(INT32 choice); -static void M_ModeAttackRetry(INT32 choice); static void M_ModeAttackEndGame(INT32 choice); static void M_SetGuestReplay(INT32 choice); static void M_HandleChoosePlayerMenu(INT32 choice); @@ -1083,7 +1082,7 @@ static menuitem_t OP_ChangeControlsMenu[] = {IT_SPACE, NULL, NULL, NULL, 0}, // padding {IT_CALL | IT_STRING2, NULL, "Game Status", M_ChangeControl, gc_scores }, - {IT_CALL | IT_STRING2, NULL, "Pause", M_ChangeControl, gc_pause }, + {IT_CALL | IT_STRING2, NULL, "Pause / Run Retry", M_ChangeControl, gc_pause }, {IT_CALL | IT_STRING2, NULL, "Console", M_ChangeControl, gc_console }, {IT_HEADER, NULL, "Multiplayer", NULL, 0}, {IT_SPACE, NULL, NULL, NULL, 0}, // padding @@ -7841,9 +7840,10 @@ static void M_SetGuestReplay(INT32 choice) which(0); } -static void M_ModeAttackRetry(INT32 choice) +void M_ModeAttackRetry(INT32 choice) { (void)choice; + // todo -- maybe seperate this out and G_SetRetryFlag() here instead? is just calling this from the menu 100% safe? G_CheckDemoStatus(); // Cancel recording if (modeattacking == ATTACKING_RECORD) M_ChooseTimeAttack(0); diff --git a/src/m_menu.h b/src/m_menu.h index 9df56e897..c1e48912a 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -235,7 +235,7 @@ extern INT16 startmap; extern INT32 ultimate_selectable; extern INT16 char_on, startchar; -#define MAXSAVEGAMES 31 //note: last save game is "no save" +#define MAXSAVEGAMES 31 #define NOSAVESLOT 0 //slot where Play Without Saving appears #define BwehHehHe() S_StartSound(NULL, sfx_bewar1+M_RandomKey(4)) // Bweh heh he @@ -244,6 +244,8 @@ void M_ForceSaveSlotSelected(INT32 sslot); void M_CheatActivationResponder(INT32 ch); +void M_ModeAttackRetry(INT32 choice); + // Level select updating void Nextmap_OnChange(void); diff --git a/src/p_setup.c b/src/p_setup.c index a5544c26b..11e6b4ef7 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2728,7 +2728,9 @@ boolean P_SetupLevel(boolean skipprecip) // Special stage fade to white // This is handled BEFORE sounds are stopped. - if (rendermode != render_none && G_IsSpecialStage(gamemap)) + if (modeattacking && pausedelay == INT32_MIN) + ranspecialwipe = 2; + else if (rendermode != render_none && G_IsSpecialStage(gamemap)) { tic_t starttime = I_GetTime(); tic_t endtime = starttime + (3*TICRATE)/2; @@ -2778,6 +2780,12 @@ boolean P_SetupLevel(boolean skipprecip) F_RunWipe(wipedefs[wipe_level_toblack], false); } + if (ranspecialwipe == 2) + { + pausedelay = -NEWTICRATE; + S_StartSound(NULL, sfx_s3k73); + } + // Print "SPEEDING OFF TO [ZONE] [ACT 1]..." if (!titlemapinaction && rendermode != render_none) { diff --git a/src/st_stuff.c b/src/st_stuff.c index 2a7e0636a..698411533 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -2367,11 +2367,13 @@ static void ST_overlayDrawer(void) { ST_drawFirstPersonHUD(); if (cv_powerupdisplay.value) - ST_drawPowerupHUD(); + ST_drawPowerupHUD(); // same as it ever was... } else if (cv_powerupdisplay.value == 2) - ST_drawPowerupHUD(); + ST_drawPowerupHUD(); // same as it ever was... } + else if (!(netgame || multiplayer) && cv_powerupdisplay.value == 2) + ST_drawPowerupHUD(); // same as it ever was... #ifdef HAVE_BLUA if (!(netgame || multiplayer) || !hu_showscores) @@ -2393,7 +2395,7 @@ static void ST_overlayDrawer(void) ) ST_drawTextHUD(); - if (modeattacking && !hu_showscores) + if (modeattacking && !(demoplayback && hu_showscores)) ST_drawInput(); ST_drawDebugInfo(); From a3f7e07e4d25bfae5be7eafa7190ba23422cafd2 Mon Sep 17 00:00:00 2001 From: toaster Date: Thu, 14 Jun 2018 14:41:14 +0100 Subject: [PATCH 04/80] Improve retrying text presentation. * Now reads "HOLD TO RETRY...". * Behind the white flash. * Shows on button tap for about half a second. --- src/g_game.c | 4 +++- src/hu_stuff.c | 18 ++++++++++-------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 4463f55ce..2ee798cda 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1827,7 +1827,9 @@ boolean G_Responder(event_t *ev) if (menuactive || pausedelay < 0 || leveltime < 2) return true; - if (++pausedelay > (NEWTICRATE/3)) + if (pausedelay < 1+(NEWTICRATE/2)) + pausedelay = 1+(NEWTICRATE/2); + else if (++pausedelay > 1+(NEWTICRATE/2)+(NEWTICRATE/3)) { pausedelay = INT32_MIN; G_SetRetryFlag(); diff --git a/src/hu_stuff.c b/src/hu_stuff.c index f4730005e..7f66ade34 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -1121,16 +1121,11 @@ void HU_Drawer(void) V_DrawCenteredString(BASEVIDWIDTH/2, 180, V_YELLOWMAP | V_ALLOWLOWERCASE, resynch_text); } - if (modeattacking && pausedelay > 1) + if (modeattacking && pausedelay > 0) { - UINT8 strength = (pausedelay*10)/(NEWTICRATE/3); + INT32 strength = ((pausedelay - 1 - NEWTICRATE/2)*10)/(NEWTICRATE/3); INT32 y = hudinfo[HUD_LIVES].y - 13; - if (strength > 9) - V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 0); - else if (strength) - V_DrawFadeScreen(0, strength); - if (players[consoleplayer].powers[pw_carry] == CR_NIGHTSMODE) y -= 16; else @@ -1141,7 +1136,14 @@ void HU_Drawer(void) y -= 8; } - V_DrawThinString(hudinfo[HUD_LIVES].x-2, y, hudinfo[HUD_LIVES].f|((leveltime & 2) ? V_SKYMAP : V_BLUEMAP), "RETRYING..."); + V_DrawThinString(hudinfo[HUD_LIVES].x-2, y, + hudinfo[HUD_LIVES].f|((leveltime & 4) ? V_SKYMAP : V_BLUEMAP), + "HOLD TO RETRY..."); + + if (strength > 9) + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 0); + else if (strength > 0) + V_DrawFadeScreen(0, strength); } } From 255d5c6c9422d5934d9acfd2bc2767112ded8a9b Mon Sep 17 00:00:00 2001 From: toaster Date: Thu, 14 Jun 2018 20:17:31 +0100 Subject: [PATCH 05/80] * Level title movement begins before the fade in! * https://cdn.discordapp.com/attachments/400761370800422922/456833651645349888/srb20051.gif * Fix some wipe bugs. * Solved that thing where there was no fade between two back-to-back cutscenes. * Fixed there being no effective wipe between the end of the vanilla intro cutscene and the title screen. * Smoothed out the behaviour of titlemap fades to prevent conflicts. * [COMPLETELY UNRELATED] Kill the pause graphic and replace with a blue box with text in it, like what happens when the window loses focus. Much harder to miss. --- src/d_main.c | 124 +++++++++++++++++++++++++++---------------------- src/f_finale.c | 21 +++++++-- src/p_setup.c | 111 ++++++++++++++++++++++++++++++------------- src/p_user.c | 4 +- src/st_stuff.c | 20 ++++---- src/st_stuff.h | 3 ++ 6 files changed, 178 insertions(+), 105 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index a5e1a0254..ee946be48 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -283,7 +283,7 @@ static void D_Display(void) if (rendermode != render_none) { // Fade to black first - if (!(gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction)) // fades to black on its own timing, always + if ((wipegamestate != -2) // fades to black on its own timing, always && wipedefs[wipedefindex] != UINT8_MAX) { F_WipeStartScreen(); @@ -361,88 +361,95 @@ static void D_Display(void) break; } - // clean up border stuff - // see if the border needs to be initially drawn - if (gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction)) + // STUPID race condition... + if (wipegamestate == GS_INTRO && gamestate == GS_TITLESCREEN) + wipegamestate = -2; + else { - // draw the view directly + wipegamestate = gamestate; - if (!automapactive && !dedicated && cv_renderview.value) + // clean up border stuff + // see if the border needs to be initially drawn + if (gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction)) { - if (players[displayplayer].mo || players[displayplayer].playerstate == PST_DEAD) - { - topleft = screens[0] + viewwindowy*vid.width + viewwindowx; - objectsdrawn = 0; -#ifdef HWRENDER - if (rendermode != render_soft) - HWR_RenderPlayerView(0, &players[displayplayer]); - else -#endif - if (rendermode != render_none) - R_RenderPlayerView(&players[displayplayer]); - } + // draw the view directly - // render the second screen - if (splitscreen && players[secondarydisplayplayer].mo) + if (!automapactive && !dedicated && cv_renderview.value) { -#ifdef HWRENDER - if (rendermode != render_soft) - HWR_RenderPlayerView(1, &players[secondarydisplayplayer]); - else -#endif - if (rendermode != render_none) + if (players[displayplayer].mo || players[displayplayer].playerstate == PST_DEAD) { - viewwindowy = vid.height / 2; - M_Memcpy(ylookup, ylookup2, viewheight*sizeof (ylookup[0])); - topleft = screens[0] + viewwindowy*vid.width + viewwindowx; + objectsdrawn = 0; + #ifdef HWRENDER + if (rendermode != render_soft) + HWR_RenderPlayerView(0, &players[displayplayer]); + else + #endif + if (rendermode != render_none) + R_RenderPlayerView(&players[displayplayer]); + } - R_RenderPlayerView(&players[secondarydisplayplayer]); + // render the second screen + if (splitscreen && players[secondarydisplayplayer].mo) + { + #ifdef HWRENDER + if (rendermode != render_soft) + HWR_RenderPlayerView(1, &players[secondarydisplayplayer]); + else + #endif + if (rendermode != render_none) + { + viewwindowy = vid.height / 2; + M_Memcpy(ylookup, ylookup2, viewheight*sizeof (ylookup[0])); - viewwindowy = 0; - M_Memcpy(ylookup, ylookup1, viewheight*sizeof (ylookup[0])); + topleft = screens[0] + viewwindowy*vid.width + viewwindowx; + + R_RenderPlayerView(&players[secondarydisplayplayer]); + + viewwindowy = 0; + M_Memcpy(ylookup, ylookup1, viewheight*sizeof (ylookup[0])); + } + } + + // Image postprocessing effect + if (rendermode == render_soft) + { + if (postimgtype) + V_DoPostProcessor(0, postimgtype, postimgparam); + if (postimgtype2) + V_DoPostProcessor(1, postimgtype2, postimgparam2); } } - // Image postprocessing effect - if (rendermode == render_soft) + if (lastdraw) { - if (postimgtype) - V_DoPostProcessor(0, postimgtype, postimgparam); - if (postimgtype2) - V_DoPostProcessor(1, postimgtype2, postimgparam2); + if (rendermode == render_soft) + { + VID_BlitLinearScreen(screens[0], screens[1], vid.width*vid.bpp, vid.height, vid.width*vid.bpp, vid.rowbytes); + usebuffer = true; + } + lastdraw = false; } - } - if (lastdraw) - { - if (rendermode == render_soft) + if (gamestate == GS_LEVEL) { - VID_BlitLinearScreen(screens[0], screens[1], vid.width*vid.bpp, vid.height, vid.width*vid.bpp, vid.rowbytes); - usebuffer = true; + ST_Drawer(); + HU_Drawer(); } - lastdraw = false; + else + F_TitleScreenDrawer(); } - - if (gamestate == GS_LEVEL) - { - ST_Drawer(); - HU_Drawer(); - } - else - F_TitleScreenDrawer(); } // change gamma if needed // (GS_LEVEL handles this already due to level-specific palettes) - if (forcerefresh && gamestate != GS_LEVEL) + if (forcerefresh && !(gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction))) V_SetPalette(0); - wipegamestate = gamestate; - // draw pause pic if (paused && cv_showhud.value && (!menuactive || netgame)) { +#if 0 INT32 py; patch_t *patch; if (automapactive) @@ -451,6 +458,11 @@ static void D_Display(void) py = viewwindowy + 4; patch = W_CachePatchName("M_PAUSE", PU_CACHE); V_DrawScaledPatch(viewwindowx + (BASEVIDWIDTH - SHORT(patch->width))/2, py, 0, patch); +#else + INT32 y = ((automapactive) ? (32) : (BASEVIDHEIGHT/2)); + M_DrawTextBox((BASEVIDWIDTH/2) - (60), y - (16), 13, 2); + V_DrawCenteredString(BASEVIDWIDTH/2, y - (4), V_YELLOWMAP, "Game Paused"); +#endif } // vid size change is now finished if it was on... diff --git a/src/f_finale.c b/src/f_finale.c index db62ddf09..2b0c38542 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -29,6 +29,7 @@ #include "g_input.h" #include "console.h" #include "m_random.h" +#include "m_misc.h" // moviemode functionality #include "y_inter.h" #include "m_cond.h" #include "p_local.h" @@ -816,18 +817,27 @@ void F_IntroDrawer(void) // Stay on black for a bit. =) { - tic_t quittime; - quittime = I_GetTime() + NEWTICRATE*2; // Shortened the quit time, used to be 2 seconds - while (quittime > I_GetTime()) + tic_t nowtime, quittime, lasttime; + nowtime = lasttime = I_GetTime(); + quittime = nowtime + NEWTICRATE*2; // Shortened the quit time, used to be 2 seconds + while (quittime > nowtime) { + while (!((nowtime = I_GetTime()) - lasttime)) + I_Sleep(); + lasttime = nowtime; + I_OsPolling(); I_UpdateNoBlit(); M_Drawer(); // menu is drawn even on top of wipes I_FinishUpdate(); // Update the screen with the image Tails 06-19-2001 + + if (moviemode) // make sure we save frames for the white hold too + M_SaveFrame(); } } D_StartTitle(); + wipegamestate = GS_INTRO; return; } F_NewCutscene(introtext[++intro_scenenum]); @@ -1532,7 +1542,7 @@ void F_TitleScreenDrawer(void) if (!titlemapinaction) F_SkyScroll(titlescrollspeed); - // Don't draw outside of the title screewn, or if the patch isn't there. + // Don't draw outside of the title screen, or if the patch isn't there. if (!ttwing || (gamestate != GS_TITLESCREEN && gamestate != GS_WAITINGPLAYERS)) return; @@ -1877,6 +1887,9 @@ void F_StartCustomCutscene(INT32 cutscenenum, boolean precutscene, boolean reset G_SetGamestate(GS_CUTSCENE); + if (wipegamestate == GS_CUTSCENE) + wipegamestate = -1; + gameaction = ga_nothing; paused = false; CON_ToggleOff(); diff --git a/src/p_setup.c b/src/p_setup.c index 11e6b4ef7..a1ef08c5d 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -56,8 +56,11 @@ #include "filesrch.h" // refreshdirmenu -// wipes -#include "f_finale.h" +#ifdef HAVE_BLUA +#include "lua_hud.h" // level title +#endif + +#include "f_finale.h" // wipes #include "md5.h" // map MD5 @@ -2673,7 +2676,6 @@ boolean P_SetupLevel(boolean skipprecip) CON_Drawer(); // let the user know what we are going to do I_FinishUpdate(); // page flip or blit buffer - // Reset the palette if (rendermode != render_none) V_SetPaletteLump("PLAYPAL"); @@ -2726,6 +2728,9 @@ boolean P_SetupLevel(boolean skipprecip) // will be set by player think. players[consoleplayer].viewz = 1; + // Cancel all d_main.c fadeouts (keep fade in though). + wipegamestate = -2; + // Special stage fade to white // This is handled BEFORE sounds are stopped. if (modeattacking && pausedelay == INT32_MIN) @@ -2763,41 +2768,42 @@ boolean P_SetupLevel(boolean skipprecip) S_StopSounds(); S_ClearSfx(); - // As oddly named as this is, this handles music only. - // We should be fine starting it here. - /// ... as long as this isn't a titlemap transition, that is if (!titlemapinaction) + { + // As oddly named as this is, this handles music only. + // We should be fine starting it here. S_Start(); - // Let's fade to black here - // But only if we didn't do the special stage wipe - if (rendermode != render_none && !ranspecialwipe) - { - F_WipeStartScreen(); - V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); + // Let's fade to black here + // But only if we didn't do the special stage wipe + if (rendermode != render_none && !ranspecialwipe) + { + F_WipeStartScreen(); + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); - F_WipeEndScreen(); - F_RunWipe(wipedefs[wipe_level_toblack], false); - } + F_WipeEndScreen(); + F_RunWipe(wipedefs[wipe_level_toblack], false); + } - if (ranspecialwipe == 2) - { - pausedelay = -NEWTICRATE; - S_StartSound(NULL, sfx_s3k73); - } + if (ranspecialwipe == 2) + { + pausedelay = -NEWTICRATE; + S_StartSound(NULL, sfx_s3k73); + } - // Print "SPEEDING OFF TO [ZONE] [ACT 1]..." - if (!titlemapinaction && rendermode != render_none) - { - // Don't include these in the fade! - char tx[64]; - V_DrawSmallString(1, 191, V_ALLOWLOWERCASE, M_GetText("Speeding off to...")); - snprintf(tx, 63, "%s%s%s", - mapheaderinfo[gamemap-1]->lvlttl, - (mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE) ? "" : " ZONE", - (mapheaderinfo[gamemap-1]->actnum > 0) ? va(", Act %d",mapheaderinfo[gamemap-1]->actnum) : ""); - V_DrawSmallString(1, 195, V_ALLOWLOWERCASE, tx); - I_UpdateNoVsync(); + // Print "SPEEDING OFF TO [ZONE] [ACT 1]..." + if (rendermode != render_none) + { + // Don't include these in the fade! + char tx[64]; + V_DrawSmallString(1, 191, V_ALLOWLOWERCASE, M_GetText("Speeding off to...")); + snprintf(tx, 63, "%s%s%s", + mapheaderinfo[gamemap-1]->lvlttl, + (mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE) ? "" : " ZONE", + (mapheaderinfo[gamemap-1]->actnum > 0) ? va(", Act %d",mapheaderinfo[gamemap-1]->actnum) : ""); + V_DrawSmallString(1, 195, V_ALLOWLOWERCASE, tx); + I_UpdateNoVsync(); + } } #ifdef HAVE_BLUA @@ -3176,7 +3182,7 @@ boolean P_SetupLevel(boolean skipprecip) P_MapEnd(); // Remove the loading shit from the screen - if (rendermode != render_none) + if (rendermode != render_none && !titlemapinaction) V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (ranspecialwipe) ? 0 : 31); if (precache || dedicated) @@ -3227,6 +3233,45 @@ boolean P_SetupLevel(boolean skipprecip) #endif } + // Stage title! + if (rendermode != render_none + && (!titlemapinaction) + && ranspecialwipe != 2 + && *mapheaderinfo[gamemap-1]->lvlttl != '\0' +#ifdef HAVE_BLUA + && LUA_HudEnabled(hud_stagetitle) +#endif + ) + { + tic_t starttime = I_GetTime(); + tic_t endtime = starttime + (10*NEWTICRATERATIO); + tic_t nowtime = starttime; + tic_t lasttime = starttime; + while (nowtime < endtime) + { + // draw loop + while (!((nowtime = I_GetTime()) - lasttime)) + I_Sleep(); + lasttime = nowtime; + + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (ranspecialwipe) ? 0 : 31); + stplyr = &players[consoleplayer]; + ST_drawLevelTitle(nowtime - starttime); + if (splitscreen) + { + stplyr = &players[secondarydisplayplayer]; + ST_drawLevelTitle(nowtime - starttime); + } + + I_OsPolling(); + I_UpdateNoBlit(); + I_FinishUpdate(); // page flip or blit buffer + + if (moviemode) // make sure we save frames for the white hold too + M_SaveFrame(); + } + } + return true; } diff --git a/src/p_user.c b/src/p_user.c index 2bcb3bc6c..40e5f7a87 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -766,8 +766,8 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime) // Don't show before title card // Not consistency safe, but this only affects drawing - if (timeinmap + 40 < 110) - player->texttimer = (UINT8)(110 - timeinmap); + if (timeinmap + 40 < (110 - 70)) + player->texttimer = (UINT8)((110 - 70) - timeinmap); } player->powers[pw_carry] = CR_NIGHTSMODE; diff --git a/src/st_stuff.c b/src/st_stuff.c index 698411533..6f9b0c182 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -1113,7 +1113,7 @@ static void ST_drawInput(void) V_DrawThinString(x, y, hudinfo[HUD_LIVES].f|((leveltime & 4) ? V_YELLOWMAP : V_REDMAP), "BAD DEMO!!"); } -static void ST_drawLevelTitle(void) +void ST_drawLevelTitle(tic_t titletime) { char *lvlttl = mapheaderinfo[gamemap-1]->lvlttl; char *subttl = mapheaderinfo[gamemap-1]->subttl; @@ -1121,7 +1121,7 @@ static void ST_drawLevelTitle(void) INT32 lvlttly, zoney, lvlttlxpos, ttlnumxpos, zonexpos; INT32 subttlxpos = BASEVIDWIDTH/2; - if (!(timeinmap > 2 && timeinmap-3 < 110)) + if (!(titletime > 2 && titletime-3 < 110)) return; if (actnum > 0) @@ -1144,22 +1144,22 @@ static void ST_drawLevelTitle(void) #define MIDZONEY 105 #define MIDDIFF 4 - if (timeinmap < 10) + if (titletime < 10) { - fixed_t z = ((timeinmap - 3)< Date: Thu, 14 Jun 2018 22:23:20 +0100 Subject: [PATCH 06/80] * Make the OpenGL loading screen work with the fades better. * Make the closed captions not mess with fades, and improve their movement calculation. --- src/hardware/hw_bsp.c | 3 ++- src/p_setup.c | 7 +++++-- src/p_setup.h | 1 + src/screen.c | 8 +++++--- 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/hardware/hw_bsp.c b/src/hardware/hw_bsp.c index fa5bce308..04afb9be9 100644 --- a/src/hardware/hw_bsp.c +++ b/src/hardware/hw_bsp.c @@ -29,6 +29,7 @@ #include "../m_argv.h" #include "../i_video.h" #include "../w_wad.h" +#include "../p_setup.h" // levelfadecol // -------------------------------------------------------------------------- // This is global data for planes rendering @@ -644,7 +645,7 @@ static void WalkBSPNode(INT32 bspnum, poly_t *poly, UINT16 *leafnode, fixed_t *b sprintf(s, "%d%%", (++ls_percent)<<1); x = BASEVIDWIDTH/2; y = BASEVIDHEIGHT/2; - V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); // Black background to match fade in effect + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, levelfadecol); // Background to match fade in effect //V_DrawPatchFill(W_CachePatchName("SRB2BACK",PU_CACHE)); // SRB2 background, ehhh too bright. M_DrawTextBox(x-58, y-8, 13, 1); V_DrawString(x-50, y, V_YELLOWMAP, "Loading..."); diff --git a/src/p_setup.c b/src/p_setup.c index a1ef08c5d..43da5275b 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -103,6 +103,7 @@ side_t *sides; mapthing_t *mapthings; INT32 numstarposts; boolean levelloading; +UINT8 levelfadecol; // BLOCKMAP // Created from axis aligned bounding box @@ -2806,6 +2807,8 @@ boolean P_SetupLevel(boolean skipprecip) } } + levelfadecol = (ranspecialwipe) ? 0 : 31; + #ifdef HAVE_BLUA LUA_InvalidateLevel(); #endif @@ -3183,7 +3186,7 @@ boolean P_SetupLevel(boolean skipprecip) // Remove the loading shit from the screen if (rendermode != render_none && !titlemapinaction) - V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (ranspecialwipe) ? 0 : 31); + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, levelfadecol); if (precache || dedicated) R_PrecacheLevel(); @@ -3254,7 +3257,7 @@ boolean P_SetupLevel(boolean skipprecip) I_Sleep(); lasttime = nowtime; - V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (ranspecialwipe) ? 0 : 31); + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, levelfadecol); stplyr = &players[consoleplayer]; ST_drawLevelTitle(nowtime - starttime); if (splitscreen) diff --git a/src/p_setup.h b/src/p_setup.h index a42ac5b76..f3897d1e0 100644 --- a/src/p_setup.h +++ b/src/p_setup.h @@ -27,6 +27,7 @@ extern mapthing_t *deathmatchstarts[MAX_DM_STARTS]; extern INT32 numdmstarts, numcoopstarts, numredctfstarts, numbluectfstarts; extern boolean levelloading; +extern UINT8 levelfadecol; extern lumpnum_t lastloadedmaplumpnum; // for comparative savegame // diff --git a/src/screen.c b/src/screen.c index cd97b62fa..13c211724 100644 --- a/src/screen.c +++ b/src/screen.c @@ -442,14 +442,16 @@ void SCR_ClosedCaptions(void) boolean gamestopped = (paused || P_AutoPause()); INT32 basey = BASEVIDHEIGHT; + if (gamestate != wipegamestate) + return; + if (gamestate == GS_LEVEL) { if (splitscreen) basey -= 8; - else if (((maptol & TOL_NIGHTS) && (modeattacking == ATTACKING_NIGHTS)) + else if ((modeattacking == ATTACKING_NIGHTS) || (cv_powerupdisplay.value == 2) - || (cv_powerupdisplay.value == 1 && ((stplyr == &players[displayplayer] && !camera.chase) - || ((splitscreen && stplyr == &players[secondarydisplayplayer]) && !camera2.chase)))) + || (cv_powerupdisplay.value == 1 && !splitscreen && !camera.chase)) basey -= 16; } From 59d617d31fd09ceb50f645a0811c0ead5534aa6b Mon Sep 17 00:00:00 2001 From: toaster Date: Thu, 14 Jun 2018 22:23:55 +0100 Subject: [PATCH 07/80] Minor modifications to the intro text. --- src/f_finale.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/f_finale.c b/src/f_finale.c index 2b0c38542..30a14c080 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -317,7 +317,7 @@ void F_StartIntro(void) introtext[2] = M_GetText( "As it was about to drain the rings\n" "away from the planet, Sonic burst into\n" - "the Satellite and for what he thought\n" + "the control room and for what he thought\n" "would be the last time,\xB4 defeated\n" "Dr. Eggman.\n#"); @@ -327,11 +327,11 @@ void F_StartIntro(void) "return,\xB8 bringing an all new threat.\n#"); introtext[4] = M_GetText( - "\xA8""About once every year, a strange asteroid\n" + "\xA8""About every five years, a strange asteroid\n" "hovers around the planet.\xBF It suddenly\n" "appears from nowhere, circles around, and\n" "\xB6- just as mysteriously as it arrives -\xB6\n" - "vanishes after about one week.\xBF\n" + "vanishes after only one week.\xBF\n" "No one knows why it appears, or how.\n#"); introtext[5] = M_GetText( @@ -384,7 +384,7 @@ void F_StartIntro(void) "\xA5\"6...\xD2""5...\xD2""4...\"\xA8\xD2\n" "Sonic knew he was getting closer to the\n" "zone, and pushed himself harder.\xB4 Finally,\n" - "the mountain appeared in the horizon.\xD2\xD2\n" + "the mountain appeared on the horizon.\xD2\xD2\n" "\xA5\"3...\xD2""2...\xD2""1...\xD2""Zero.\"\n#"); introtext[11] = M_GetText( From f0618d5780240ab2b26743c0143aa9e888c0ee82 Mon Sep 17 00:00:00 2001 From: toaster Date: Fri, 15 Jun 2018 21:42:36 +0100 Subject: [PATCH 08/80] Correct some minor deficiencies in the hold-for-retry system in record attack. --- src/g_game.c | 4 +++- src/p_setup.c | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 2ee798cda..4e3e5f0c7 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1831,7 +1831,6 @@ boolean G_Responder(event_t *ev) pausedelay = 1+(NEWTICRATE/2); else if (++pausedelay > 1+(NEWTICRATE/2)+(NEWTICRATE/3)) { - pausedelay = INT32_MIN; G_SetRetryFlag(); return true; } @@ -1908,7 +1907,10 @@ void G_Ticker(boolean run) G_ClearRetryFlag(); if (modeattacking) + { + pausedelay = INT32_MIN; M_ModeAttackRetry(0); + } else { // Costs a life to retry ... unless the player in question is dead already. diff --git a/src/p_setup.c b/src/p_setup.c index 43da5275b..673541c84 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2734,7 +2734,7 @@ boolean P_SetupLevel(boolean skipprecip) // Special stage fade to white // This is handled BEFORE sounds are stopped. - if (modeattacking && pausedelay == INT32_MIN) + if (modeattacking && !demoplayback && (pausedelay == INT32_MIN)) ranspecialwipe = 2; else if (rendermode != render_none && G_IsSpecialStage(gamemap)) { @@ -2788,7 +2788,7 @@ boolean P_SetupLevel(boolean skipprecip) if (ranspecialwipe == 2) { - pausedelay = -NEWTICRATE; + pausedelay = -3; // preticker plus one S_StartSound(NULL, sfx_s3k73); } From f3baf608a243a8e83aa86216cee50a0cd944eed5 Mon Sep 17 00:00:00 2001 From: toaster Date: Sun, 17 Jun 2018 18:45:03 +0100 Subject: [PATCH 09/80] Revamp of addons menu search! * Instead of iterating through the folder every time you change the search query by one letter, iterate through the "coredirmenu" (the game's interpretation of the folder) instead. MUCH, much less likely to lag to fuck and back. * Hide a bit of complexity in filesrch.c instead of having the entire thing exposed to mess with. For example, closefilemenu() instead of manually freeing the struct each time. * Refactor some stuff. --- src/filesrch.c | 210 ++++++++++++++++++++++++++++++++++--------------- src/filesrch.h | 2 + src/m_menu.c | 21 ++--- 3 files changed, 155 insertions(+), 78 deletions(-) diff --git a/src/filesrch.c b/src/filesrch.c index 2b5493642..3e1e5891a 100644 --- a/src/filesrch.c +++ b/src/filesrch.c @@ -326,8 +326,8 @@ size_t menudepthleft = menudepth; char menusearch[MAXSTRINGLENGTH+1]; -char **dirmenu; -size_t sizedirmenu; +char **dirmenu, **coredirmenu; // core only local for this file +size_t sizedirmenu, sizecoredirmenu; // ditto size_t dir_on[menudepth]; UINT8 refreshdirmenu = 0; @@ -446,7 +446,7 @@ char exttable[NUM_EXT_TABLE][5] = { char filenamebuf[MAX_WADFILES][MAX_WADPATH]; -static boolean filemenusearch(char *haystack, char *needle) +static boolean filemenucmp(char *haystack, char *needle) { static char localhaystack[128]; strlcpy(localhaystack, haystack, 128); @@ -457,21 +457,126 @@ static boolean filemenusearch(char *haystack, char *needle) : (!strncmp(localhaystack, needle, menusearch[0]))); } -#define searchdir if (menusearch[0] && !filemenusearch(dent->d_name, localmenusearch))\ - {\ - rejected++;\ - continue;\ - }\ +void closefilemenu(boolean validsize) +{ + // search + if (dirmenu) + { + if (dirmenu != coredirmenu) + { + if (dirmenu[0] && ((UINT8)(dirmenu[0][DIR_TYPE]) == EXT_NORESULTS)) + { + Z_Free(dirmenu[0]); + dirmenu[0] = NULL; + } + Z_Free(dirmenu); + } + dirmenu = NULL; + sizedirmenu = 0; + } + + if (coredirmenu) + { + // core + if (validsize) + { + for (; sizecoredirmenu > 0; sizecoredirmenu--) + { + Z_Free(coredirmenu[sizecoredirmenu-1]); + coredirmenu[sizecoredirmenu-1] = NULL; + } + } + else + sizecoredirmenu = 0; + + Z_Free(coredirmenu); + coredirmenu = NULL; + } +} + +void searchfilemenu(char *tempname) +{ + size_t i, first; + char localmenusearch[MAXSTRINGLENGTH] = ""; + + if (dirmenu) + { + if (dirmenu != coredirmenu) + { + if (dirmenu[0] && ((UINT8)(dirmenu[0][DIR_TYPE]) == EXT_NORESULTS)) + { + Z_Free(dirmenu[0]); + dirmenu[0] = NULL; + } + //Z_Free(dirmenu); -- Z_Realloc later tho... + } + else + dirmenu = NULL; + } + + if (!menusearch[0]) + { + if (dirmenu) + Z_Free(dirmenu); + dirmenu = coredirmenu; + sizedirmenu = sizecoredirmenu; + if (tempname) + Z_Free(tempname); + return; + } + + strcpy(localmenusearch, menusearch+1); + if (!cv_addons_search_case.value) + strupr(localmenusearch); + + first = (((UINT8)(coredirmenu[0][DIR_TYPE]) == EXT_UP) ? 1 : 0); // skip UP... + + sizedirmenu = 0; + for (i = first; i < sizecoredirmenu; i++) + { + if (filemenucmp(coredirmenu[i]+DIR_STRING, localmenusearch)) + sizedirmenu++; + } + + if (!sizedirmenu) // no results... + { + if ((!(dirmenu = Z_Realloc(dirmenu, sizeof(char *), PU_STATIC, NULL))) + || !(dirmenu[0] = Z_StrDup(va("%c\13No results...", EXT_NORESULTS)))) + I_Error("Ran out of memory whilst preparing add-ons menu"); + sizedirmenu = 1; + if (tempname) + Z_Free(tempname); + return; + } + + if (!(dirmenu = Z_Realloc(dirmenu, sizedirmenu*sizeof(char *), PU_STATIC, NULL))) + I_Error("Ran out of memory whilst preparing add-ons menu"); + + sizedirmenu = 0; + for (i = first; i < sizecoredirmenu; i++) + { + if (filemenucmp(coredirmenu[i]+DIR_STRING, localmenusearch)) + { + dirmenu[sizedirmenu++] = coredirmenu[i]; // pointer reuse + if (tempname && !strcmp(coredirmenu[i]+DIR_STRING, tempname)) + dir_on[menudepthleft] = i; + } + } + + if (dir_on[menudepthleft] >= sizedirmenu) + dir_on[menudepthleft] = sizedirmenu-1; + + if (tempname) + Z_Free(tempname); +} boolean preparefilemenu(boolean samedepth) { DIR *dirhandle; struct dirent *dent; struct stat fsstat; - size_t pos = 0, folderpos = 0, numfolders = 0, rejected = 0; + size_t pos = 0, folderpos = 0, numfolders = 0; char *tempname = NULL; - boolean noresults = false; - char localmenusearch[MAXSTRINGLENGTH] = ""; if (samedepth) { @@ -481,20 +586,16 @@ boolean preparefilemenu(boolean samedepth) else menusearch[0] = menusearch[1] = 0; // clear search - for (; sizedirmenu > 0; sizedirmenu--) // clear out existing items + if (!(dirhandle = opendir(menupath))) // get directory { - Z_Free(dirmenu[sizedirmenu-1]); - dirmenu[sizedirmenu-1] = NULL; + closefilemenu(true); + return false; } - if (!(dirhandle = opendir(menupath))) // get directory - return false; - - if (menusearch[0]) + for (; sizecoredirmenu > 0; sizecoredirmenu--) // clear out existing items { - strcpy(localmenusearch, menusearch+1); - if (!cv_addons_search_case.value) - strupr(localmenusearch); + Z_Free(coredirmenu[sizecoredirmenu-1]); + coredirmenu[sizecoredirmenu-1] = NULL; } while (true) @@ -526,43 +627,42 @@ boolean preparefilemenu(boolean samedepth) if (!strcasecmp(exttable[ext], dent->d_name+len-5)) break; // extension comparison if (ext == NUM_EXT_TABLE) continue; // not an addfile-able (or exec-able) file } - searchdir; } else // directory - { - searchdir; numfolders++; - } - sizedirmenu++; + + sizecoredirmenu++; } } - if (!rejected && !sizedirmenu) + if (!sizecoredirmenu) { + closedir(dirhandle); + closefilemenu(false); if (tempname) Z_Free(tempname); - closedir(dirhandle); return false; } - if (((noresults = (menusearch[0] && !sizedirmenu))) - || (!menusearch[0] && menudepthleft != menudepth-1)) // Make room for UP... or search entry + if (menudepthleft != menudepth-1) // Make room for UP... { - sizedirmenu++; + sizecoredirmenu++; numfolders++; folderpos++; } - if (!(dirmenu = Z_Realloc(dirmenu, sizedirmenu*sizeof(char *), PU_STATIC, NULL))) + if (dirmenu && dirmenu == coredirmenu) + dirmenu = NULL; + + if (!(coredirmenu = Z_Realloc(coredirmenu, sizecoredirmenu*sizeof(char *), PU_STATIC, NULL))) { closedir(dirhandle); // just in case I_Error("Ran out of memory whilst preparing add-ons menu"); } - rejected = 0; rewinddir(dirhandle); - while ((pos+folderpos) < sizedirmenu) + while ((pos+folderpos) < sizecoredirmenu) { menupath[menupathindex[menudepthleft]] = 0; dent = readdir(dirhandle); @@ -588,14 +688,12 @@ boolean preparefilemenu(boolean samedepth) if (!S_ISDIR(fsstat.st_mode)) // file { - if (!((numfolders+pos) < sizedirmenu)) continue; // crash prevention + if (!((numfolders+pos) < sizecoredirmenu)) continue; // crash prevention for (; ext < NUM_EXT_TABLE; ext++) if (!strcasecmp(exttable[ext], dent->d_name+len-5)) break; // extension comparison if (ext == NUM_EXT_TABLE && !cv_addons_showall.value) continue; // not an addfile-able (or exec-able) file ext += EXT_START; // moving to be appropriate position - searchdir; - if (ext >= EXT_LOADSTART) { size_t i; @@ -628,10 +726,7 @@ boolean preparefilemenu(boolean samedepth) folder = 0; } else // directory - { - searchdir; len += (folder = 1); - } if (len > 255) len = 255; @@ -644,45 +739,30 @@ boolean preparefilemenu(boolean samedepth) if (folder) { strcpy(temp+len, "/"); - dirmenu[folderpos++] = temp; + coredirmenu[folderpos++] = temp; } else - dirmenu[numfolders + pos++] = temp; + coredirmenu[numfolders + pos++] = temp; } } closedir(dirhandle); - if (noresults) // no results - dirmenu[0] = Z_StrDup(va("%c\13No results...", EXT_NORESULTS)); - else if (!menusearch[0] &&menudepthleft != menudepth-1) // now for UP... entry - dirmenu[0] = Z_StrDup(va("%c\5UP...", EXT_UP)); + if ((menudepthleft != menudepth-1) // now for UP... entry + && !(coredirmenu[0] = Z_StrDup(va("%c\5UP...", EXT_UP)))) + I_Error("Ran out of memory whilst preparing add-ons menu"); menupath[menupathindex[menudepthleft]] = 0; - sizedirmenu = (numfolders+pos); // just in case things shrink between opening and rewind + sizecoredirmenu = (numfolders+pos); // just in case things shrink between opening and rewind - if (tempname) - { - size_t i; - for (i = 0; i < sizedirmenu; i++) - { - if (!strcmp(dirmenu[i]+DIR_STRING, tempname)) - { - dir_on[menudepthleft] = i; - break; - } - } - Z_Free(tempname); - } - - if (!sizedirmenu) + if (!sizecoredirmenu) { dir_on[menudepthleft] = 0; - Z_Free(dirmenu); + closefilemenu(false); return false; } - else if (dir_on[menudepthleft] >= sizedirmenu) - dir_on[menudepthleft] = sizedirmenu-1; + + searchfilemenu(tempname); return true; } diff --git a/src/filesrch.h b/src/filesrch.h index e88242698..4cfa40e6c 100644 --- a/src/filesrch.h +++ b/src/filesrch.h @@ -87,6 +87,8 @@ typedef enum REFRESHDIR_MAX = 32 } refreshdir_enum; +void closefilemenu(boolean validsize); +void searchfilemenu(char *tempname); boolean preparefilemenu(boolean samedepth); #endif // __FILESRCH_H__ diff --git a/src/m_menu.c b/src/m_menu.c index 5258f4b44..d23d5640f 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -5048,13 +5048,11 @@ static void M_DrawAddons(void) x -= (21 + 5 + 16); V_DrawSmallScaledPatch(x, y + 4, (menusearch[0] ? 0 : V_TRANSLUCENT), addonsp[NUM_EXT+4]); -#define CANSAVE (!modifiedgame || savemoddata) x = BASEVIDWIDTH - x - 16; - V_DrawSmallScaledPatch(x, y + 4, (CANSAVE ? 0 : V_TRANSLUCENT), addonsp[NUM_EXT+5]); + V_DrawSmallScaledPatch(x, y + 4, ((!modifiedgame || savemoddata) ? 0 : V_TRANSLUCENT), addonsp[NUM_EXT+5]); if (modifiedgame) V_DrawSmallScaledPatch(x, y + 4, 0, addonsp[NUM_EXT+3]); -#undef CANSAVE } #ifdef FIXUPO0 @@ -5119,11 +5117,15 @@ static void M_HandleAddons(INT32 choice) if (M_ChangeStringAddons(choice)) { - if (!preparefilemenu(true)) + char *tempname = NULL; + if (dirmenu && dirmenu[dir_on[menudepthleft]]) + tempname = Z_StrDup(dirmenu[dir_on[menudepthleft]]+DIR_STRING); // don't need to I_Error if can't make - not important, just QoL + searchfilemenu(tempname); + /*if (!preparefilemenu(true)) { UNEXIST; return; - } + }*/ } switch (choice) @@ -5242,14 +5244,7 @@ static void M_HandleAddons(INT32 choice) } if (exitmenu) { - for (; sizedirmenu > 0; sizedirmenu--) - { - Z_Free(dirmenu[sizedirmenu-1]); - dirmenu[sizedirmenu-1] = NULL; - } - - Z_Free(dirmenu); - dirmenu = NULL; + closefilemenu(true); // secrets disabled by addfile... MainMenu[secrets].status = (M_AnySecretUnlocked()) ? (IT_STRING | IT_CALL) : (IT_DISABLED); From 247f3e9b03e6e55bc02eae5df76fa75ea636ca3c Mon Sep 17 00:00:00 2001 From: toaster Date: Mon, 18 Jun 2018 11:22:57 +0100 Subject: [PATCH 10/80] Improve the tempname position-keeping behaviour significantly, hammering out a potential crash bug too. --- src/filesrch.c | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/src/filesrch.c b/src/filesrch.c index 3e1e5891a..b80681306 100644 --- a/src/filesrch.c +++ b/src/filesrch.c @@ -514,14 +514,32 @@ void searchfilemenu(char *tempname) dirmenu = NULL; } + first = (((UINT8)(coredirmenu[0][DIR_TYPE]) == EXT_UP) ? 1 : 0); // skip UP... + if (!menusearch[0]) { if (dirmenu) Z_Free(dirmenu); dirmenu = coredirmenu; sizedirmenu = sizecoredirmenu; + if (tempname) + { + for (i = first; i < sizedirmenu; i++) + { + if (!strcmp(dirmenu[i]+DIR_STRING, tempname)) + { + dir_on[menudepthleft] = i; + break; + } + } + + if (i == sizedirmenu) + dir_on[menudepthleft] = first; + Z_Free(tempname); + } + return; } @@ -529,8 +547,6 @@ void searchfilemenu(char *tempname) if (!cv_addons_search_case.value) strupr(localmenusearch); - first = (((UINT8)(coredirmenu[0][DIR_TYPE]) == EXT_UP) ? 1 : 0); // skip UP... - sizedirmenu = 0; for (i = first; i < sizecoredirmenu; i++) { @@ -544,6 +560,7 @@ void searchfilemenu(char *tempname) || !(dirmenu[0] = Z_StrDup(va("%c\13No results...", EXT_NORESULTS)))) I_Error("Ran out of memory whilst preparing add-ons menu"); sizedirmenu = 1; + dir_on[menudepthleft] = 0; if (tempname) Z_Free(tempname); return; @@ -557,17 +574,21 @@ void searchfilemenu(char *tempname) { if (filemenucmp(coredirmenu[i]+DIR_STRING, localmenusearch)) { - dirmenu[sizedirmenu++] = coredirmenu[i]; // pointer reuse if (tempname && !strcmp(coredirmenu[i]+DIR_STRING, tempname)) - dir_on[menudepthleft] = i; + { + dir_on[menudepthleft] = sizedirmenu; + Z_Free(tempname); + tempname = NULL; + } + dirmenu[sizedirmenu++] = coredirmenu[i]; // pointer reuse } } - if (dir_on[menudepthleft] >= sizedirmenu) - dir_on[menudepthleft] = sizedirmenu-1; - if (tempname) + { + dir_on[menudepthleft] = first; Z_Free(tempname); + } } boolean preparefilemenu(boolean samedepth) From 00d75840b662931efcca5f464dd98a4bdfbb7382 Mon Sep 17 00:00:00 2001 From: toaster Date: Mon, 18 Jun 2018 12:49:06 +0100 Subject: [PATCH 11/80] Not necessary on-topic devwork, but using global variables I developed in internal to make there less code repetition/iteration in the WAD limit checks. --- src/d_netcmd.c | 36 +++++++----------------------------- src/d_netfil.c | 9 ++------- src/w_wad.c | 4 +--- 3 files changed, 10 insertions(+), 39 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index e01178155..89f01c161 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -3081,26 +3081,14 @@ static void Command_Addfile(void) if (*p == '\\' || *p == '/' || *p == ':') break; ++p; + // check total packet size and no of files currently loaded + // See W_LoadWadFile in w_wad.c + if ((numwadfiles >= MAX_WADFILES) + || ((packetsizetally + nameonlylength(fn) + 22) > MAXFILENEEDED*sizeof(UINT8))) { - size_t packetsize = 0; - serverinfo_pak *dummycheck = NULL; - - // Shut the compiler up. - (void)dummycheck; - - // See W_LoadWadFile in w_wad.c - for (i = 0; i < numwadfiles; i++) - packetsize += nameonlylength(wadfiles[i]->filename) + 22; - - packetsize += nameonlylength(fn) + 22; - - if ((numwadfiles >= MAX_WADFILES) - || (packetsize > sizeof(dummycheck->fileneeded))) - { - CONS_Alert(CONS_ERROR, M_GetText("Too many files loaded to add %s\n"), fn); - return; - } + CONS_Alert(CONS_ERROR, M_GetText("Too many files loaded to add %s\n"), fn); + return; } WRITESTRINGN(buf_p,p,240); @@ -3150,11 +3138,6 @@ static void Got_RequestAddfilecmd(UINT8 **cp, INT32 playernum) boolean kick = false; boolean toomany = false; INT32 i; - size_t packetsize = 0; - serverinfo_pak *dummycheck = NULL; - - // Shut the compiler up. - (void)dummycheck; READSTRINGN(*cp, filename, 240); READMEM(*cp, md5sum, 16); @@ -3181,13 +3164,8 @@ static void Got_RequestAddfilecmd(UINT8 **cp, INT32 playernum) } // See W_LoadWadFile in w_wad.c - for (i = 0; i < numwadfiles; i++) - packetsize += nameonlylength(wadfiles[i]->filename) + 22; - - packetsize += nameonlylength(filename) + 22; - if ((numwadfiles >= MAX_WADFILES) - || (packetsize > sizeof(dummycheck->fileneeded))) + || ((packetsizetally + nameonlylength(filename) + 22) > MAXFILENEEDED*sizeof(UINT8))) toomany = true; else ncs = findfile(filename,md5sum,true); diff --git a/src/d_netfil.c b/src/d_netfil.c index 889de9466..ea95153b9 100644 --- a/src/d_netfil.c +++ b/src/d_netfil.c @@ -324,10 +324,6 @@ INT32 CL_CheckFiles(void) INT32 ret = 1; size_t packetsize = 0; size_t filestoget = 0; - serverinfo_pak *dummycheck = NULL; - - // Shut the compiler up. - (void)dummycheck; // if (M_CheckParm("-nofiles")) // return 1; @@ -371,8 +367,7 @@ INT32 CL_CheckFiles(void) } // See W_LoadWadFile in w_wad.c - for (i = 0; i < numwadfiles; i++) - packetsize += nameonlylength(wadfiles[i]->filename) + 22; + packetsize = packetsizetally; for (i = 1; i < fileneedednum; i++) { @@ -396,7 +391,7 @@ INT32 CL_CheckFiles(void) packetsize += nameonlylength(fileneeded[i].filename) + 22; if ((numwadfiles+filestoget >= MAX_WADFILES) - || (packetsize > sizeof(dummycheck->fileneeded))) + || (packetsize > MAXFILENEEDED*sizeof(UINT8))) return 3; filestoget++; diff --git a/src/w_wad.c b/src/w_wad.c index 1b0e501a6..46caef847 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -360,9 +360,7 @@ UINT16 W_InitFile(const char *filename) // see PutFileNeeded in d_netfil.c if ((important = !W_VerifyNMUSlumps(filename))) { - packetsize = packetsizetally; - - packetsize += nameonlylength(filename) + 22; + packetsize = packetsizetally + nameonlylength(filename) + 22; if (packetsize > MAXFILENEEDED*sizeof(UINT8)) { From bd3e9cc067d3cba347ccd2bbdb84968b161087f3 Mon Sep 17 00:00:00 2001 From: toaster Date: Mon, 18 Jun 2018 16:55:34 +0100 Subject: [PATCH 12/80] Major refinement of Add-ons menu! * Kill addonsresponselimit, which was a hacky solution to a stupid problem. Instead... * Allocate and consistently handle memory to store the name of an added file so we can reference it directly. * Replace the choice between ./ and a custom folder with the full, standard assortment of Default (usehome ? SRB2HOME : SRB2PATH), HOME (SRB2HOME), SRB2 (SRB2PATH) or Custom (cv_addons_folder.string). * Make these render as the name plus folder, since you can't go UP... from the top level. * Make the path seperators consistently system-based re PATHSEP. (Quite frankly, I'm surprised it even worked in the first place...) --- src/d_netcmd.c | 6 ++++ src/d_netfil.c | 9 +++--- src/filesrch.c | 24 ++++++++++----- src/filesrch.h | 1 + src/m_menu.c | 79 +++++++++++++++++++++++++------------------------- src/w_wad.c | 10 +++++++ 6 files changed, 79 insertions(+), 50 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 89f01c161..2ab0548a0 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -3318,6 +3318,9 @@ static void Command_Playintro_f(void) if (netgame) return; + if (dirmenu) + closefilemenu(true); + F_StartIntro(); } @@ -4076,6 +4079,9 @@ void Command_ExitGame_f(void) cv_debug = 0; emeralds = 0; + if (dirmenu) + closefilemenu(true); + if (!modeattacking) D_StartTitle(); } diff --git a/src/d_netfil.c b/src/d_netfil.c index ea95153b9..e43ad77e2 100644 --- a/src/d_netfil.c +++ b/src/d_netfil.c @@ -894,10 +894,11 @@ void nameonly(char *s) { ns = &(s[j+1]); len = strlen(ns); - if (false) - M_Memcpy(s, ns, len+1); - else - memmove(s, ns, len+1); +#if 0 + M_Memcpy(s, ns, len+1); +#else + memmove(s, ns, len+1); +#endif return; } } diff --git a/src/filesrch.c b/src/filesrch.c index b80681306..fe3fe240c 100644 --- a/src/filesrch.c +++ b/src/filesrch.c @@ -306,9 +306,14 @@ closedir (DIR * dirp) } #endif -static CV_PossibleValue_t addons_cons_t[] = {{0, "SRB2 Folder"}, /*{1, "HOME"}, {2, "SRB2 Folder"},*/ {3, "CUSTOM"}, {0, NULL}}; -consvar_t cv_addons_option = {"addons_option", "SRB2 Folder", CV_SAVE|CV_CALL, addons_cons_t, Addons_option_Onchange, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_addons_folder = {"addons_folder", "./", CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; +static CV_PossibleValue_t addons_cons_t[] = {{0, "Default"}, +#if 1 + {1, "HOME"}, {2, "SRB2"}, +#endif + {3, "CUSTOM"}, {0, NULL}}; + +consvar_t cv_addons_option = {"addons_option", "Default", CV_SAVE|CV_CALL, addons_cons_t, Addons_option_Onchange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_addons_folder = {"addons_folder", "", CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t addons_md5_cons_t[] = {{0, "Name"}, {1, "Contents"}, {0, NULL}}; consvar_t cv_addons_md5 = {"addons_md5", "Name", CV_SAVE, addons_md5_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -330,6 +335,7 @@ char **dirmenu, **coredirmenu; // core only local for this file size_t sizedirmenu, sizecoredirmenu; // ditto size_t dir_on[menudepth]; UINT8 refreshdirmenu = 0; +char *refreshdirname = NULL; size_t packetsizetally = 0; size_t mainwadstally = 0; @@ -362,9 +368,9 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want return FS_NOTFOUND; } - if (searchpath[searchpathindex[depthleft]-2] != '/') + if (searchpath[searchpathindex[depthleft]-2] != PATHSEP[0]) { - searchpath[searchpathindex[depthleft]-1] = '/'; + searchpath[searchpathindex[depthleft]-1] = PATHSEP[0]; searchpath[searchpathindex[depthleft]] = 0; } else @@ -406,7 +412,7 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want depthleft++; } - searchpath[searchpathindex[depthleft]-1]='/'; + searchpath[searchpathindex[depthleft]-1]=PATHSEP[0]; searchpath[searchpathindex[depthleft]]=0; } else if (!strcasecmp(searchname, dent->d_name)) @@ -492,6 +498,10 @@ void closefilemenu(boolean validsize) Z_Free(coredirmenu); coredirmenu = NULL; } + + if (refreshdirname) + Z_Free(refreshdirname); + refreshdirname = NULL; } void searchfilemenu(char *tempname) @@ -759,7 +769,7 @@ boolean preparefilemenu(boolean samedepth) strlcpy(temp+DIR_STRING, dent->d_name, len); if (folder) { - strcpy(temp+len, "/"); + strcpy(temp+len, PATHSEP); coredirmenu[folderpos++] = temp; } else diff --git a/src/filesrch.h b/src/filesrch.h index 4cfa40e6c..41dc80d13 100644 --- a/src/filesrch.h +++ b/src/filesrch.h @@ -40,6 +40,7 @@ extern char **dirmenu; extern size_t sizedirmenu; extern size_t dir_on[menudepth]; extern UINT8 refreshdirmenu; +extern char *refreshdirname; extern size_t packetsizetally; extern size_t mainwadstally; diff --git a/src/m_menu.c b/src/m_menu.c index d23d5640f..bdeee16ed 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -341,7 +341,6 @@ static void M_EraseData(INT32 choice); static void M_Addons(INT32 choice); static void M_AddonsOptions(INT32 choice); static patch_t *addonsp[NUM_EXT+6]; -static UINT8 addonsresponselimit = 0; #define numaddonsshown 4 @@ -2110,15 +2109,19 @@ static void M_GoBack(INT32 choice) if (!Playing() && netgame && multiplayer) { MSCloseUDPSocket(); // Clean up so we can re-open the connection later. - netgame = false; - multiplayer = false; + netgame = multiplayer = false; } if ((currentMenu->prevMenu == &MainDef) && (currentMenu == &SP_TimeAttackDef || currentMenu == &SP_NightsAttackDef)) { // D_StartTitle does its own wipe, since GS_TIMEATTACK is now a complete gamestate. - Z_Free(levelselect.rows); - levelselect.rows = NULL; + + if (levelselect.rows) + { + Z_Free(levelselect.rows); + levelselect.rows = NULL; + } + menuactive = false; D_StartTitle(); } @@ -4759,22 +4762,24 @@ static void M_Addons(INT32 choice) (void)choice; - /*if (cv_addons_option.value == 0) - pathname = srb2home; usehome ? srb2home : srb2path; +#if 1 + if (cv_addons_option.value == 0) + pathname = usehome ? srb2home : srb2path; else if (cv_addons_option.value == 1) pathname = srb2home; else if (cv_addons_option.value == 2) pathname = srb2path; - else*/ + else +#endif if (cv_addons_option.value == 3 && *cv_addons_folder.string != '\0') pathname = cv_addons_folder.string; strlcpy(menupath, pathname, 1024); menupathindex[(menudepthleft = menudepth-1)] = strlen(menupath) + 1; - if (menupath[menupathindex[menudepthleft]-2] != '/') + if (menupath[menupathindex[menudepthleft]-2] != PATHSEP[0]) { - menupath[menupathindex[menudepthleft]-1] = '/'; + menupath[menupathindex[menudepthleft]-1] = PATHSEP[0]; menupath[menupathindex[menudepthleft]] = 0; } else @@ -4868,11 +4873,7 @@ static char *M_AddonsHeaderPath(void) UINT32 len; static char header[1024]; - if (menupath[0] == '.') - strlcpy(header, va("SRB2 folder%s", menupath+1), 1024); - else - strcpy(header, menupath); - + strlcpy(header, va("%s folder%s", cv_addons_option.string, menupath+menupathindex[menudepth-1]-1), 1024); len = strlen(header); if (len > 34) { @@ -4889,6 +4890,15 @@ static char *M_AddonsHeaderPath(void) M_SetupNextMenu(MISC_AddonsDef.prevMenu);\ M_StartMessage(va("\x82%s\x80\nThis folder no longer exists!\nAborting to main menu.\n\n(Press a key)\n", M_AddonsHeaderPath()),NULL,MM_NOTHING) +#define CLEARNAME Z_Free(refreshdirname);\ + refreshdirname = NULL + +static void M_AddonsClearName(INT32 choice) +{ + CLEARNAME; + M_StopMessage(choice); +} + // returns whether to do message draw static boolean M_AddonsRefresh(void) { @@ -4900,35 +4910,35 @@ static boolean M_AddonsRefresh(void) if (refreshdirmenu & REFRESHDIR_ADDFILE) { - addonsresponselimit = 0; + char *message = NULL; if (refreshdirmenu & REFRESHDIR_NOTLOADED) { - char *message = NULL; S_StartSound(NULL, sfx_lose); if (refreshdirmenu & REFRESHDIR_MAX) - message = va("\x82%s\x80\nMaximum number of add-ons reached.\nThis file could not be loaded.\nIf you want to play with this add-on, restart the game to clear existing ones.\n\n(Press a key)\n", dirmenu[dir_on[menudepthleft]]+DIR_STRING); + message = va("\x82%s\x80\nMaximum number of add-ons reached.\nA file could not be loaded.\nIf you want to play with this add-on, restart the game to clear existing ones.\n\n(Press a key)\n", refreshdirname); else - message = va("\x82%s\x80\nThe file was not loaded.\nCheck the console log for more information.\n\n(Press a key)\n", dirmenu[dir_on[menudepthleft]]+DIR_STRING); - M_StartMessage(message,NULL,MM_NOTHING); - return true; + message = va("\x82%s\x80\nA file was not loaded.\nCheck the console log for more information.\n\n(Press a key)\n", refreshdirname); } - - if (refreshdirmenu & (REFRESHDIR_WARNING|REFRESHDIR_ERROR)) + else if (refreshdirmenu & (REFRESHDIR_WARNING|REFRESHDIR_ERROR)) { S_StartSound(NULL, sfx_skid); - M_StartMessage(va("\x82%s\x80\nThe file was loaded with %s.\nCheck the console log for more information.\n\n(Press a key)\n", dirmenu[dir_on[menudepthleft]]+DIR_STRING, ((refreshdirmenu & REFRESHDIR_ERROR) ? "errors" : "warnings")),NULL,MM_NOTHING); + message = va("\x82%s\x80\nA file was loaded with %s.\nCheck the console log for more information.\n\n(Press a key)\n", refreshdirname, ((refreshdirmenu & REFRESHDIR_ERROR) ? "errors" : "warnings")); + } + + if (message) + { + M_StartMessage(message,M_AddonsClearName,MM_EVENTHANDLER); return true; } S_StartSound(NULL, sfx_strpst); + CLEARNAME; } return false; } -#define offs 1 - #ifdef FIXUPO0 #pragma GCC optimize ("0") #endif @@ -4945,10 +4955,7 @@ static void M_DrawAddons(void) return; } - if (addonsresponselimit) - addonsresponselimit--; - - V_DrawCenteredString(BASEVIDWIDTH/2, 4+offs, 0, (Playing() + V_DrawCenteredString(BASEVIDWIDTH/2, 5, 0, (Playing() ? "\x85""Adding files mid-game may cause problems." : LOCATIONSTRING)); @@ -4970,7 +4977,7 @@ static void M_DrawAddons(void) // DRAW MENU x = currentMenu->x; - y = currentMenu->y + offs; + y = currentMenu->y + 1; //M_DrawLevelPlatterHeader(y - 16, M_AddonsHeaderPath(), true, true); -- wanted different width V_DrawString(x-21, (y - 16) + (lsheadingheight - 12), V_YELLOWMAP|V_ALLOWLOWERCASE, M_AddonsHeaderPath()); @@ -4978,7 +4985,7 @@ static void M_DrawAddons(void) V_DrawFill(x-21 + (MAXSTRINGLENGTH*8+6 - 1), (y - 16) + (lsheadingheight - 3), 1, 1, 26); V_DrawFill(x-21, (y - 16) + (lsheadingheight - 2), MAXSTRINGLENGTH*8+6, 1, 26); - V_DrawFill(x - 21, y - 1, MAXSTRINGLENGTH*8+6, (BASEVIDHEIGHT - currentMenu->y + 1 + offs) - (y - 1), 159); + V_DrawFill(x - 21, y - 1, MAXSTRINGLENGTH*8+6, (BASEVIDHEIGHT - currentMenu->y + 2) - (y - 1), 159); // get bottom... max = dir_on[menudepthleft] + numaddonsshown + 1; @@ -5034,7 +5041,7 @@ static void M_DrawAddons(void) if (max != (ssize_t)sizedirmenu) V_DrawString(19, y-12 + (skullAnimCounter/5), V_YELLOWMAP, "\x1B"); - y = BASEVIDHEIGHT - currentMenu->y + offs; + y = BASEVIDHEIGHT - currentMenu->y + 1; M_DrawTextBox(x - (21 + 5), y, MAXSTRINGLENGTH, 1); if (menusearch[0]) @@ -5059,8 +5066,6 @@ static void M_DrawAddons(void) #pragma GCC reset_options #endif -#undef offs - static void M_AddonExec(INT32 ch) { if (ch != 'y' && ch != KEY_ENTER) @@ -5112,9 +5117,6 @@ static void M_HandleAddons(INT32 choice) { boolean exitmenu = false; // exit to previous menu - if (addonsresponselimit) - return; - if (M_ChangeStringAddons(choice)) { char *tempname = NULL; @@ -5224,7 +5226,6 @@ static void M_HandleAddons(INT32 choice) case EXT_WAD: case EXT_PK3: COM_BufAddText(va("addfile %s%s", menupath, dirmenu[dir_on[menudepthleft]]+DIR_STRING)); - addonsresponselimit = 5; break; default: S_StartSound(NULL, sfx_lose); diff --git a/src/w_wad.c b/src/w_wad.c index 46caef847..320b65a3c 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -340,6 +340,16 @@ UINT16 W_InitFile(const char *filename) if (!(refreshdirmenu & REFRESHDIR_ADDFILE)) refreshdirmenu = REFRESHDIR_NORMAL|REFRESHDIR_ADDFILE; // clean out cons_alerts that happened earlier + if (refreshdirname) + Z_Free(refreshdirname); + if (dirmenu) + { + refreshdirname = Z_StrDup(filename); + nameonly(refreshdirname); + } + else + refreshdirname = NULL; + //CONS_Debug(DBG_SETUP, "Loading %s\n", filename); // // check if limit of active wadfiles From f18cfb11f3116a487e0ea25e9e482834dbe0f16f Mon Sep 17 00:00:00 2001 From: toaster Date: Mon, 18 Jun 2018 17:39:34 +0100 Subject: [PATCH 13/80] Some cvar fudging. * Turn off mlook and mousemove by default, as requested by Prime/Mystic. * Change all the analog cvar names (and hide them from the help function so they aren't so easily rediscovered) to invalidate 2.1-era copies of config.cfg, given I've seen a common sentiment is that they won't try the new controls at all and will just copy their old ones across, and I'd like to sabotage the deprecated feature. --- src/g_game.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 4e3e5f0c7..da3b38b56 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -320,19 +320,21 @@ static CV_PossibleValue_t joyaxis_cons_t[] = {{0, "None"}, consvar_t cv_crosshair = {"crosshair", "Cross", CV_SAVE, crosshair_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_crosshair2 = {"crosshair2", "Cross", CV_SAVE, crosshair_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_invertmouse = {"invertmouse", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_alwaysfreelook = {"alwaysmlook", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_alwaysfreelook = {"alwaysmlook", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_invertmouse2 = {"invertmouse2", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_alwaysfreelook2 = {"alwaysmlook2", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_mousemove = {"mousemove", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_mousemove2 = {"mousemove2", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_analog = {"analog", "Off", CV_CALL, CV_OnOff, Analog_OnChange, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_analog2 = {"analog2", "Off", CV_CALL, CV_OnOff, Analog2_OnChange, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_useranalog = {"useranalog", "Off", CV_SAVE|CV_CALL, CV_OnOff, UserAnalog_OnChange, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_useranalog2 = {"useranalog2", "Off", CV_SAVE|CV_CALL, CV_OnOff, UserAnalog2_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_mousemove = {"mousemove", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_mousemove2 = {"mousemove2", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -static CV_PossibleValue_t directionchar_cons_t[] = {{0, "Camera"}, {1, "Movement"}, {0, NULL}}; +// previously "analog", "analog2", "useranalog", and "useranalog2", invalidating 2.1-era copies of config.cfg +// changed because it'd be nice to see people try out our actually good controls with gamepads now autobrake exists +consvar_t cv_analog = {"sessionanalog", "Off", CV_CALL|CV_NOSHOWHELP, CV_OnOff, Analog_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_analog2 = {"sessionanalog2", "Off", CV_CALL|CV_NOSHOWHELP, CV_OnOff, Analog2_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_useranalog = {"configanalog", "Off", CV_SAVE|CV_CALL|CV_NOSHOWHELP, CV_OnOff, UserAnalog_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_useranalog2 = {"configanalog2", "Off", CV_SAVE|CV_CALL|CV_NOSHOWHELP, CV_OnOff, UserAnalog2_OnChange, 0, NULL, NULL, 0, 0, NULL}; // deez New User eXperiences +static CV_PossibleValue_t directionchar_cons_t[] = {{0, "Camera"}, {1, "Movement"}, {0, NULL}}; consvar_t cv_directionchar = {"directionchar", "Movement", CV_SAVE|CV_CALL, directionchar_cons_t, DirectionChar_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_directionchar2 = {"directionchar2", "Movement", CV_SAVE|CV_CALL, directionchar_cons_t, DirectionChar2_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_autobrake = {"autobrake", "On", CV_SAVE|CV_CALL, CV_OnOff, AutoBrake_OnChange, 0, NULL, NULL, 0, 0, NULL}; From c88bbda028a21a51058488ee0214ce925625f0a0 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Wed, 25 Jul 2018 22:19:07 +0100 Subject: [PATCH 14/80] fix visual studio complaining about negating an unsigned var --- src/hardware/hw_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index f23209379..d06cbc105 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5677,7 +5677,7 @@ static void HWR_DrawSkyBackground(player_t *player) dimensionmultiply = ((float)textures[texturetranslation[skytexture]]->width/256.0f); - v[0].sow = v[3].sow = ((float) (-angle) / ((ANGLE_90-1)*dimensionmultiply)); // left + v[0].sow = v[3].sow = (-1.0f * angle) / ((ANGLE_90-1)*dimensionmultiply); // left v[2].sow = v[1].sow = v[0].sow + (1.0f/dimensionmultiply); // right (or left + 1.0f) // use +angle and -1.0f above instead if you wanted old backwards behavior From e0e77d873bd44746246b15e6827b01a0c4082416 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Fri, 10 Aug 2018 18:24:31 -0400 Subject: [PATCH 15/80] Nights Drone mobj and state entries * New entries: NIGHTSDRONE_MAN, NIGHTSDRONE_SPARKLING * NIGHTSGOAL renamed to NIGHTSDRONE_GOAL * MT_NIGHTSDRONE repurposed as an invisble, no-gravity hitbox --- src/dehacked.c | 16 ++++++----- src/info.c | 74 +++++++++++++++++++++++++++++++++++++++++++------- src/info.h | 16 ++++++----- src/p_mobj.c | 4 +-- 4 files changed, 84 insertions(+), 26 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index fb0f958c3..5c2953a55 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -5952,8 +5952,8 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_TOAD", // Nights-specific stuff - "S_NIGHTSDRONE1", - "S_NIGHTSDRONE2", + "S_NIGHTSDRONE_MAN1", + "S_NIGHTSDRONE_MAN2", "S_NIGHTSDRONE_SPARKLING1", "S_NIGHTSDRONE_SPARKLING2", "S_NIGHTSDRONE_SPARKLING3", @@ -5970,10 +5970,10 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_NIGHTSDRONE_SPARKLING14", "S_NIGHTSDRONE_SPARKLING15", "S_NIGHTSDRONE_SPARKLING16", - "S_NIGHTSGOAL1", - "S_NIGHTSGOAL2", - "S_NIGHTSGOAL3", - "S_NIGHTSGOAL4", + "S_NIGHTSDRONE_GOAL1", + "S_NIGHTSDRONE_GOAL2", + "S_NIGHTSDRONE_GOAL3", + "S_NIGHTSDRONE_GOAL4", "S_NIGHTSPARKLE1", "S_NIGHTSPARKLE2", @@ -6825,7 +6825,9 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_AXISTRANSFER", "MT_AXISTRANSFERLINE", "MT_NIGHTSDRONE", - "MT_NIGHTSGOAL", + "MT_NIGHTSDRONE_MAN", + "MT_NIGHTSDRONE_SPARKLING", + "MT_NIGHTSDRONE_GOAL", "MT_NIGHTSPARKLE", "MT_NIGHTSLOOPHELPER", "MT_NIGHTSBUMPER", // NiGHTS Bumper diff --git a/src/info.c b/src/info.c index 782ab6381..00a0342c5 100644 --- a/src/info.c +++ b/src/info.c @@ -3239,8 +3239,8 @@ state_t states[NUMSTATES] = {SPR_TOAD, 0, -1, {NULL}, 0, 0, S_NULL}, // S_TOAD // Nights Drone - {SPR_NDRN, 0, -1, {NULL}, 0, 0, S_NIGHTSDRONE2}, // S_NIGHTSDRONE1 - {SPR_NDRN, 0, -1, {NULL}, 0, 0, S_NIGHTSDRONE1}, // S_NIGHTSDRONE2 + {SPR_NDRN, 0, -1, {NULL}, 0, 0, S_NIGHTSDRONE_MAN2}, // S_NIGHTSDRONE_MAN1 + {SPR_NDRN, 0, -1, {NULL}, 0, 0, S_NIGHTSDRONE_MAN1}, // S_NIGHTSDRONE_MAN2 // Sparkling point (RETURN TO THE GOAL, etc) {SPR_IVSP, 0, 1, {A_GhostMe}, 0, 0, S_NIGHTSDRONE_SPARKLING2}, // S_NIGHTSDRONE_SPARKLING1 @@ -3261,10 +3261,10 @@ state_t states[NUMSTATES] = {SPR_IVSP, 30, 1, {A_GhostMe}, 0, 0, S_NIGHTSDRONE_SPARKLING1}, // S_NIGHTSDRONE_SPARKLING16 // NiGHTS GOAL banner (inside the sparkles!) - {SPR_GOAL, 0, 4, {NULL}, 0, 0, S_NIGHTSGOAL2}, // S_NIGHTSGOAL1 - {SPR_GOAL, 1, 4, {NULL}, 0, 0, S_NIGHTSGOAL3}, // S_NIGHTSGOAL2 - {SPR_GOAL, 2, 4, {NULL}, 0, 0, S_NIGHTSGOAL4}, // S_NIGHTSGOAL3 - {SPR_GOAL, 3, 4, {NULL}, 0, 0, S_NIGHTSGOAL1}, // S_NIGHTSGOAL4 + {SPR_GOAL, 0, 4, {NULL}, 0, 0, S_NIGHTSDRONE_GOAL2}, // S_NIGHTSDRONE_GOAL1 + {SPR_GOAL, 1, 4, {NULL}, 0, 0, S_NIGHTSDRONE_GOAL3}, // S_NIGHTSDRONE_GOAL2 + {SPR_GOAL, 2, 4, {NULL}, 0, 0, S_NIGHTSDRONE_GOAL4}, // S_NIGHTSDRONE_GOAL3 + {SPR_GOAL, 3, 4, {NULL}, 0, 0, S_NIGHTSDRONE_GOAL1}, // S_NIGHTSDRONE_GOAL4 // Nights Sparkle {SPR_NSPK, FF_FULLBRIGHT, 140, {NULL}, 0, 0, S_NIGHTSPARKLE2}, // S_NIGHTSPARKLE1 @@ -16100,7 +16100,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = { // MT_NIGHTSDRONE 1703, // doomednum - S_NIGHTSDRONE1, // spawnstate + S_INVISIBLE, // spawnstate 120, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -16125,9 +16125,36 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_NIGHTSGOAL + { // MT_NIGHTSDRONE_MAN + -1, // doomednum + S_INVISIBLE, // spawnstate + 120, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 255, // painchance + sfx_None, // painsound + S_NIGHTSDRONE_MAN1, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 16*FRACUNIT, // radius + 56*FRACUNIT, // height + 1, // display offset + 1000, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + S_NULL // raisestate + }, + + { // MT_NIGHTSDRONE_SPARKLING -1, // doomednum - S_NIGHTSGOAL1, // spawnstate + S_INVISIBLE, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -16136,7 +16163,34 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // painstate 255, // painchance sfx_None, // painsound - S_NULL, // meleestate + S_NIGHTSDRONE_SPARKLING1, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 16*FRACUNIT, // radius + 56*FRACUNIT, // height + 1, // display offset + 1000, // mass + 0, // damage + sfx_None, // activesound + MF_NOGRAVITY|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + S_NULL // raisestate + }, + + { // MT_NIGHTSDRONE_GOAL + -1, // doomednum + S_INVISIBLE, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 255, // painchance + sfx_None, // painsound + S_NIGHTSDRONE_GOAL1, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate diff --git a/src/info.h b/src/info.h index dfd30bc5b..a386b199a 100644 --- a/src/info.h +++ b/src/info.h @@ -3305,8 +3305,8 @@ typedef enum state S_TOAD, // Nights-specific stuff - S_NIGHTSDRONE1, - S_NIGHTSDRONE2, + S_NIGHTSDRONE_MAN1, + S_NIGHTSDRONE_MAN2, S_NIGHTSDRONE_SPARKLING1, S_NIGHTSDRONE_SPARKLING2, S_NIGHTSDRONE_SPARKLING3, @@ -3323,10 +3323,10 @@ typedef enum state S_NIGHTSDRONE_SPARKLING14, S_NIGHTSDRONE_SPARKLING15, S_NIGHTSDRONE_SPARKLING16, - S_NIGHTSGOAL1, - S_NIGHTSGOAL2, - S_NIGHTSGOAL3, - S_NIGHTSGOAL4, + S_NIGHTSDRONE_GOAL1, + S_NIGHTSDRONE_GOAL2, + S_NIGHTSDRONE_GOAL3, + S_NIGHTSDRONE_GOAL4, S_NIGHTSPARKLE1, S_NIGHTSPARKLE2, @@ -4198,7 +4198,9 @@ typedef enum mobj_type MT_AXISTRANSFER, MT_AXISTRANSFERLINE, MT_NIGHTSDRONE, - MT_NIGHTSGOAL, + MT_NIGHTSDRONE_MAN, + MT_NIGHTSDRONE_SPARKLING, + MT_NIGHTSDRONE_GOAL, MT_NIGHTSPARKLE, MT_NIGHTSLOOPHELPER, MT_NIGHTSBUMPER, // NiGHTS Bumper diff --git a/src/p_mobj.c b/src/p_mobj.c index 4353e67c3..af409b8bf 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7848,7 +7848,7 @@ void P_MobjThinker(mobj_t *mobj) mobj->flags &= ~MF_NOGRAVITY; mobj->flags2 |= MF2_DONTDRAW; - P_SetMobjState(mobj, S_NIGHTSDRONE1); + //P_SetMobjState(mobj, S_NIGHTSDRONE); } } // Invisible/bouncing mode. @@ -7880,7 +7880,7 @@ void P_MobjThinker(mobj_t *mobj) mobj->z += (mobj->spawnpoint->options >> ZSHIFT)<target, P_SpawnMobjFromMobj(mobj, 0, 0, FRACUNIT, MT_NIGHTSGOAL)); + P_SetTarget(&mobj->target, P_SpawnMobjFromMobj(mobj, 0, 0, FRACUNIT, MT_NIGHTSDRONE_GOAL)); mobj->flags2 &= ~MF2_DONTDRAW; mobj->flags |= MF_NOGRAVITY; From 32c17b145441726a1ed2a5e2c98d5d48e802892b Mon Sep 17 00:00:00 2001 From: mazmazz Date: Fri, 10 Aug 2018 19:25:49 -0400 Subject: [PATCH 16/80] Basic implementation for player position correction to Drone center * player->drone mobj variable * P_MoveNiGHTSToDrone, will change later --- src/d_player.h | 1 + src/lua_playerlib.c | 9 +++++++++ src/p_inter.c | 1 + src/p_saveg.c | 17 +++++++++++++++++ src/p_setup.c | 2 +- src/p_user.c | 21 +++++++++++++++++++++ 6 files changed, 50 insertions(+), 1 deletion(-) diff --git a/src/d_player.h b/src/d_player.h index 7bee5f337..91cafa515 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -455,6 +455,7 @@ typedef struct player_s UINT8 drilldelay; boolean bonustime; // Capsule destroyed, now it's bonus time! mobj_t *capsule; // Go inside the capsule + mobj_t *drone; // Move center to the drone UINT8 mare; // Current mare // Statistical purposes. diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index ff62f2459..4fdf25fad 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -288,6 +288,8 @@ static int player_get(lua_State *L) lua_pushboolean(L, plr->bonustime); else if (fastcmp(field,"capsule")) LUA_PushUserdata(L, plr->capsule, META_MOBJ); + else if (fastcmp(field,"drone")) + LUA_PushUserdata(L, plr->drone, META_MOBJ); else if (fastcmp(field,"mare")) lua_pushinteger(L, plr->mare); else if (fastcmp(field,"marebegunat")) @@ -568,6 +570,13 @@ static int player_set(lua_State *L) mo = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ)); P_SetTarget(&plr->capsule, mo); } + else if (fastcmp(field,"drone")) + { + mobj_t *mo = NULL; + if (!lua_isnil(L, 3)) + mo = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ)); + P_SetTarget(&plr->drone, mo); + } else if (fastcmp(field,"mare")) plr->mare = (UINT8)luaL_checkinteger(L, 3); else if (fastcmp(field,"marebegunat")) diff --git a/src/p_inter.c b/src/p_inter.c index ce8bba6b6..688dc685d 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -794,6 +794,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (!(netgame || multiplayer) && !(player->powers[pw_carry] == CR_NIGHTSMODE)) P_SetTarget(&special->tracer, toucher); P_NightserizePlayer(player, special->health); // Transform! + P_SetTarget(&player->drone, special); // Mark the player as 'center into the drone' if (!spec) { if (toucher->tracer) // Move the ideya over to the drone! diff --git a/src/p_saveg.c b/src/p_saveg.c index 7cf437384..699b57a5c 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -57,6 +57,7 @@ typedef enum FIRSTAXIS = 0x10, SECONDAXIS = 0x20, FOLLOW = 0x40, + DRONE = 0x80, } player_saveflags; // @@ -226,6 +227,9 @@ static void P_NetArchivePlayers(void) if (players[i].followmobj) flags |= FOLLOW; + if (players[i].drone) + flags |= DRONE; + WRITEINT16(save_p, players[i].lastsidehit); WRITEINT16(save_p, players[i].lastlinehit); @@ -254,6 +258,9 @@ static void P_NetArchivePlayers(void) if (flags & FOLLOW) WRITEUINT32(save_p, players[i].followmobj->mobjnum); + if (flags & DRONE) + WRITEUINT32(save_p, players[i].drone->mobjnum); + WRITEFIXED(save_p, players[i].camerascale); WRITEFIXED(save_p, players[i].shieldscale); @@ -428,6 +435,9 @@ static void P_NetUnArchivePlayers(void) if (flags & FOLLOW) players[i].followmobj = (mobj_t *)(size_t)READUINT32(save_p); + if (flags & DRONE) + players[i].drone = (mobj_t *)(size_t)READUINT32(save_p); + players[i].camerascale = READFIXED(save_p); players[i].shieldscale = READFIXED(save_p); @@ -3099,6 +3109,13 @@ static void P_RelinkPointers(void) if (!P_SetTarget(&mobj->player->followmobj, P_FindNewPosition(temp))) CONS_Debug(DBG_GAMELOGIC, "followmobj not found on %d\n", mobj->type); } + if (mobj->player && mobj->player->drone) + { + temp = (UINT32)(size_t)mobj->player->drone; + mobj->player->drone = NULL; + if (!P_SetTarget(&mobj->player->drone, P_FindNewPosition(temp))) + CONS_Debug(DBG_GAMELOGIC, "drone not found on %d\n", mobj->type); + } } } } diff --git a/src/p_setup.c b/src/p_setup.c index c62f281b3..7e8d0fdb1 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2401,7 +2401,7 @@ static void P_LevelInitStuff(void) // unset ALL the pointers. P_SetTarget isn't needed here because if this // function is being called we're just going to clobber the data anyways players[i].mo = players[i].followmobj = players[i].awayviewmobj =\ - players[i].capsule = players[i].axis1 = players[i].axis2 = NULL; + players[i].capsule = players[i].axis1 = players[i].axis2 = players[i].drone = NULL; } } diff --git a/src/p_user.c b/src/p_user.c index fd09b0847..18e8e29ca 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -6095,6 +6095,20 @@ static void P_DoNiGHTSCapsule(player_t *player) player->capsule->extravalue1 = -1; } +// +// P_MoveNiGHTSToDrone +// +// Pull NiGHTS to the drone during Nightserizing +// +static void P_MoveNiGHTSToDrone(player_t *player) +{ + if (!player->drone) + return; + player->mo->momx = player->mo->momy = player->mo->momz = 0; + P_TeleportMove(player->mo, player->drone->x, player->drone->y, player->drone->z); + P_SetTarget(&player->drone, NULL); +} + // // P_NiGHTSMovement // @@ -7007,6 +7021,13 @@ static void P_MovePlayer(player_t *player) return; } + // Suck player into their drone + if (player->drone) + { + P_MoveNiGHTSToDrone(player); + return; + } + // Test revamped NiGHTS movement. if (player->powers[pw_carry] == CR_NIGHTSMODE) { From 7c0186bc97a4861830fb1efa2550d8826fea9797 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Fri, 10 Aug 2018 22:11:48 -0400 Subject: [PATCH 17/80] Drone de-coupling implementation * Visual elements and hitbox work as expected with scaling and OBJECTFLIP --- src/p_mobj.c | 159 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 100 insertions(+), 59 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index af409b8bf..8b49f140c 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7827,78 +7827,102 @@ void P_MobjThinker(mobj_t *mobj) } break; case MT_NIGHTSDRONE: - // GOAL mode? - if (mobj->state >= &states[S_NIGHTSDRONE_SPARKLING1] && mobj->state <= &states[S_NIGHTSDRONE_SPARKLING16]) { - INT32 i; - boolean bonustime = false; + mobj_t *goalpost = NULL; + mobj_t *sparkle = NULL; + mobj_t *droneman = NULL; - for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] && players[i].bonustime && players[i].powers[pw_carry] == CR_NIGHTSMODE) - { - bonustime = true; - break; - } - - if (!bonustime) + if (mobj->target && mobj->target->type == MT_NIGHTSDRONE_GOAL) { - CONS_Debug(DBG_NIGHTSBASIC, "Removing goal post\n"); - P_RemoveMobj(mobj->target); - P_SetTarget(&mobj->target, NULL); - - mobj->flags &= ~MF_NOGRAVITY; - mobj->flags2 |= MF2_DONTDRAW; - //P_SetMobjState(mobj, S_NIGHTSDRONE); + goalpost = mobj->target; + if (goalpost->target && goalpost->target->type == MT_NIGHTSDRONE_SPARKLING) + sparkle = goalpost->target; + if (goalpost->tracer && goalpost->tracer->type == MT_NIGHTSDRONE_MAN) + droneman = goalpost->tracer; } - } - // Invisible/bouncing mode. - else - { - INT32 i; - boolean bonustime = false; - // Bouncy bouncy! - mobj->angle += ANG10; - if (mobj->flags2 & MF2_DONTDRAW) - mobj->momz = 0; - else if (mobj->z <= mobj->floorz) - mobj->momz = 5*FRACUNIT; - - for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] && players[i].bonustime && players[i].powers[pw_carry] == CR_NIGHTSMODE) - { - bonustime = true; - break; - } - - if (bonustime) + // GOAL mode? + if (sparkle->state >= &states[S_NIGHTSDRONE_SPARKLING1] && sparkle->state <= &states[S_NIGHTSDRONE_SPARKLING16]) { - mobj->z = mobj->floorz + mobj->height; - mobj->angle = mobj->momz = 0; + INT32 i; + boolean bonustime = false; - if (mobj->spawnpoint) - mobj->z += (mobj->spawnpoint->options >> ZSHIFT)<target, P_SpawnMobjFromMobj(mobj, 0, 0, FRACUNIT, MT_NIGHTSDRONE_GOAL)); - - mobj->flags2 &= ~MF2_DONTDRAW; - mobj->flags |= MF_NOGRAVITY; - P_SetMobjState(mobj, S_NIGHTSDRONE_SPARKLING1); - } - else if (!G_IsSpecialStage(gamemap)) - { for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] && players[i].powers[pw_carry] != CR_NIGHTSMODE) + if (playeringame[i] && players[i].bonustime && players[i].powers[pw_carry] == CR_NIGHTSMODE) { - bonustime = true; // variable reuse + bonustime = true; + break; + } + + if (!bonustime) + { + CONS_Debug(DBG_NIGHTSBASIC, "Removing goal post\n"); + if (goalpost && goalpost->state != &states[S_INVISIBLE]) + P_SetMobjState(goalpost, S_INVISIBLE); + if (sparkle && sparkle->state != &states[S_INVISIBLE]) + P_SetMobjState(sparkle, S_INVISIBLE); + } + } + // Invisible/bouncing mode. + else + { + INT32 i; + boolean bonustime = false; + + // Bouncy bouncy! + droneman->angle += ANG10; + if (droneman->flags2 & MF2_DONTDRAW) + droneman->momz = 0; + else if (!(droneman->flags2 & MF2_OBJECTFLIP) + && droneman->z <= droneman->floorz) + droneman->momz = FixedMul(5*FRACUNIT, droneman->scale); + else if ((droneman->flags2 & MF2_OBJECTFLIP) + && droneman->z >= droneman->ceilingz - droneman->height) + droneman->momz = FixedMul(-5*FRACUNIT, droneman->scale); + + for (i = 0; i < MAXPLAYERS; i++) + if (playeringame[i] && players[i].bonustime && players[i].powers[pw_carry] == CR_NIGHTSMODE) + { + bonustime = true; break; } if (bonustime) - mobj->flags2 &= ~MF2_DONTDRAW; - else - mobj->flags2 |= MF2_DONTDRAW; + { + CONS_Debug(DBG_NIGHTSBASIC, "Adding goal post\n"); + if (droneman && droneman->state != &states[S_INVISIBLE]) + P_SetMobjState(droneman, S_INVISIBLE); + if (goalpost && goalpost->state == &states[S_INVISIBLE]) + P_SetMobjState(goalpost, mobjinfo[goalpost->type].meleestate); + if (sparkle && sparkle->state == &states[S_INVISIBLE]) + P_SetMobjState(sparkle, mobjinfo[sparkle->type].meleestate); + } + else if (!G_IsSpecialStage(gamemap)) + { + for (i = 0; i < MAXPLAYERS; i++) + if (playeringame[i] && players[i].powers[pw_carry] != CR_NIGHTSMODE) + { + bonustime = true; // variable reuse + break; + } + + if (bonustime) + { + // show droneman if at least one player is non-nights + if (goalpost && goalpost->state != &states[S_INVISIBLE]) + P_SetMobjState(goalpost, S_INVISIBLE); + if (sparkle && sparkle->state != &states[S_INVISIBLE]) + P_SetMobjState(sparkle, S_INVISIBLE); + if (droneman && droneman->state == &states[S_INVISIBLE]) + P_SetMobjState(droneman, mobjinfo[droneman->type].meleestate); + } + else + { + // else, hide it + if (droneman && droneman->state != &states[S_INVISIBLE]) + P_SetMobjState(droneman, S_INVISIBLE); + } + } } } break; @@ -10516,6 +10540,23 @@ ML_EFFECT4 : Don't clip inside the ground case MT_NIGHTSDRONE: if (mthing->angle > 0) mobj->health = mthing->angle; + + if (mthing->options & MTF_OBJECTFLIP) + { + mobj->eflags |= MFE_VERTICALFLIP; + mobj->flags2 |= MF2_OBJECTFLIP; + } + + // spawn visual components + { + mobj_t *goalpost = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_NIGHTSDRONE_GOAL); + mobj_t *sparkle = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_NIGHTSDRONE_SPARKLING); + mobj_t *droneman = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_NIGHTSDRONE_MAN); + + P_SetTarget(&mobj->target, goalpost); + P_SetTarget(&goalpost->target, sparkle); + P_SetTarget(&goalpost->tracer, droneman); + } break; case MT_HIVEELEMENTAL: if (mthing->extrainfo) From c9c021939369f358f92d9cfac7fdefc9b871f5f3 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Fri, 10 Aug 2018 23:49:02 -0400 Subject: [PATCH 18/80] ORBITEM CENTER states for A_OrbitNights target height offset --- src/dehacked.c | 13 +++++++++++++ src/info.c | 17 +++++++++++++++-- src/info.h | 13 +++++++++++++ 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 5c2953a55..fd289dc18 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -6041,11 +6041,24 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_ORBITEM6", "S_ORBITEM7", "S_ORBITEM8", + "S_ORBITEM1_CENTER", + "S_ORBITEM2_CENTER", + "S_ORBITEM3_CENTER", + "S_ORBITEM4_CENTER", + "S_ORBITEM5_CENTER", + "S_ORBITEM6_CENTER", + "S_ORBITEM7_CENTER", + "S_ORBITEM8_CENTER", "S_ORBIDYA1", "S_ORBIDYA2", "S_ORBIDYA3", "S_ORBIDYA4", "S_ORBIDYA5", + "S_ORBIDYA1_CENTER", + "S_ORBIDYA2_CENTER", + "S_ORBIDYA3_CENTER", + "S_ORBIDYA4_CENTER", + "S_ORBIDYA5_CENTER", // "Flicky" helper "S_NIGHTOPIANHELPER1", diff --git a/src/info.c b/src/info.c index 00a0342c5..195b2769b 100644 --- a/src/info.c +++ b/src/info.c @@ -3338,11 +3338,24 @@ state_t states[NUMSTATES] = {SPR_CEMG, FF_FULLBRIGHT|5, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM6}, // S_ORBITEM6 {SPR_CEMG, FF_FULLBRIGHT|6, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM7}, // S_ORBITEM7 {SPR_CEMG, FF_FULLBRIGHT|7, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM8}, // S_ORBITEM8 + {SPR_CEMG, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0x3000000, S_ORBITEM1_CENTER}, // S_ORBITEM1_CENTER + {SPR_CEMG, FF_FULLBRIGHT|1, 1, {A_OrbitNights}, ANG2*2, 0x3000000, S_ORBITEM2_CENTER}, // S_ORBITEM2_CENTER + {SPR_CEMG, FF_FULLBRIGHT|2, 1, {A_OrbitNights}, ANG2*2, 0x3000000, S_ORBITEM3_CENTER}, // S_ORBITEM3_CENTER + {SPR_CEMG, FF_FULLBRIGHT|3, 1, {A_OrbitNights}, ANG2*2, 0x3000000, S_ORBITEM4_CENTER}, // S_ORBITEM4_CENTER + {SPR_CEMG, FF_FULLBRIGHT|4, 1, {A_OrbitNights}, ANG2*2, 0x3000000, S_ORBITEM5_CENTER}, // S_ORBITEM5_CENTER + {SPR_CEMG, FF_FULLBRIGHT|5, 1, {A_OrbitNights}, ANG2*2, 0x3000000, S_ORBITEM6_CENTER}, // S_ORBITEM6_CENTER + {SPR_CEMG, FF_FULLBRIGHT|6, 1, {A_OrbitNights}, ANG2*2, 0x3000000, S_ORBITEM7_CENTER}, // S_ORBITEM7_CENTER + {SPR_CEMG, FF_FULLBRIGHT|7, 1, {A_OrbitNights}, ANG2*2, 0x3000000, S_ORBITEM8_CENTER}, // S_ORBITEM8_CENTER {SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBIDYA1}, // S_ORBIDYA1 {SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT|1, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBIDYA2}, // S_ORBIDYA2 {SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT|2, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBIDYA3}, // S_ORBIDYA3 {SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT|3, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBIDYA4}, // S_ORBIDYA4 {SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT|4, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBIDYA5}, // S_ORBIDYA5 + {SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0x3000000, S_ORBIDYA1_CENTER}, // S_ORBIDYA1_CENTER + {SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT|1, 1, {A_OrbitNights}, ANG2*2, 0x3000000, S_ORBIDYA2_CENTER}, // S_ORBIDYA2_CENTER + {SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT|2, 1, {A_OrbitNights}, ANG2*2, 0x3000000, S_ORBIDYA3_CENTER}, // S_ORBIDYA3_CENTER + {SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT|3, 1, {A_OrbitNights}, ANG2*2, 0x3000000, S_ORBIDYA4_CENTER}, // S_ORBIDYA4_CENTER + {SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT|4, 1, {A_OrbitNights}, ANG2*2, 0x3000000, S_ORBIDYA5_CENTER}, // S_ORBIDYA5_CENTER // Flicky helper for NiGHTS {SPR_FL01, 1, 1, {A_OrbitNights}, ANG2*2, 180 | 0x10000, S_NIGHTOPIANHELPER2}, // S_NIGHTOPIANHELPER1 @@ -14618,7 +14631,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_ORBITEM1, // meleestate S_ORBIDYA1, // missilestate S_XPLD1, // deathstate - S_NULL, // xdeathstate + S_ORBITEM1_CENTER, // xdeathstate sfx_s3k8a, // deathsound 8, // speed 8*FRACUNIT, // radius @@ -14628,7 +14641,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 0, // damage sfx_None, // activesound MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_SCENERY, // flags - S_NULL // raisestate + S_ORBIDYA1_CENTER // raisestate }, { // MT_LOCKON diff --git a/src/info.h b/src/info.h index a386b199a..11150a114 100644 --- a/src/info.h +++ b/src/info.h @@ -3394,11 +3394,24 @@ typedef enum state S_ORBITEM6, S_ORBITEM7, S_ORBITEM8, + S_ORBITEM1_CENTER, + S_ORBITEM2_CENTER, + S_ORBITEM3_CENTER, + S_ORBITEM4_CENTER, + S_ORBITEM5_CENTER, + S_ORBITEM6_CENTER, + S_ORBITEM7_CENTER, + S_ORBITEM8_CENTER, S_ORBIDYA1, S_ORBIDYA2, S_ORBIDYA3, S_ORBIDYA4, S_ORBIDYA5, + S_ORBIDYA1_CENTER, + S_ORBIDYA2_CENTER, + S_ORBIDYA3_CENTER, + S_ORBIDYA4_CENTER, + S_ORBIDYA5_CENTER, // "Flicky" helper S_NIGHTOPIANHELPER1, From b97037f6449666e76d23f25f70e9619f65b6fd35 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Fri, 10 Aug 2018 23:50:23 -0400 Subject: [PATCH 19/80] A_OrbitNights height offset by target height implementation --- src/p_enemy.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index 9235a1d0f..40adb9d4a 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -8542,12 +8542,16 @@ void A_ToggleFlameJet(mobj_t* actor) // Description: Used by Chaos Emeralds to orbit around Nights (aka Super Sonic.) // // var1 = Angle adjustment (aka orbit speed) -// var2 = Lower four bits: height offset, Upper 4 bits = set if object is Nightopian Helper +// var2: +// Lower 16 bits: height offset +// Upper 8 bits: set if object is Nightopian Helper +// Highest 8 bits: center height offset to target by this divisor // void A_OrbitNights(mobj_t* actor) { INT32 ofs = (var2 & 0xFFFF); - boolean ishelper = (var2 & 0xFFFF0000); + boolean ishelper = ((var2 >> 16) & 0xFF); + INT32 ofsdiv = var2 >> 24; #ifdef HAVE_BLUA if (LUA_CallAction("A_OrbitNights", actor)) return; @@ -8577,7 +8581,10 @@ void A_OrbitNights(mobj_t* actor) actor->x = actor->target->x + fc; actor->y = actor->target->y + fs; - actor->z = actor->target->z + fh + FixedMul(16*FRACUNIT, actor->scale); + if (ofsdiv) + actor->z = (actor->target->z + actor->target->height / ofsdiv) + fh + FixedMul(16*FRACUNIT, actor->scale); + else + actor->z = actor->target->z + fh + FixedMul(16*FRACUNIT, actor->scale); // Semi-lazy hack actor->angle = (angle_t)actor->extravalue1 + ANGLE_90; @@ -11636,4 +11643,4 @@ void A_CheckFlags2(mobj_t *actor) if (actor->flags2 & locvar1) P_SetMobjState(actor, (statenum_t)locvar2); -} \ No newline at end of file +} From 8154578fb653d7562de383e8962100833cd4add3 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 11 Aug 2018 00:09:02 -0400 Subject: [PATCH 20/80] Switch Ideya orbiting state to centered offset states when orbiting around Drone --- src/p_inter.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/p_inter.c b/src/p_inter.c index 688dc685d..f10d680dd 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -799,10 +799,18 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) { if (toucher->tracer) // Move the ideya over to the drone! { + statenum_t currentstate = toucher->tracer->state - states; mobj_t *hnext = special->hnext; P_SetTarget(&special->hnext, toucher->tracer); P_SetTarget(&special->hnext->hnext, hnext); // Buffalo buffalo Buffalo buffalo buffalo buffalo Buffalo buffalo. P_SetTarget(&special->hnext->target, special); + + // switch to centered orbit states + if (currentstate >= mobjinfo[MT_GOTEMERALD].missilestate + && currentstate <= mobjinfo[MT_GOTEMERALD].missilestate + 4) + P_SetMobjState(toucher->tracer, + mobjinfo[MT_GOTEMERALD].raisestate + currentstate - mobjinfo[MT_GOTEMERALD].missilestate); + P_SetTarget(&toucher->tracer, NULL); if (hnext) { @@ -814,8 +822,18 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (player->exiting) // ...then move it back? { mobj_t *hnext = special; + statenum_t currentstate; while ((hnext = hnext->hnext)) + { P_SetTarget(&hnext->target, toucher); + currentstate = hnext->state - states; + + // switch to regular orbit states + if (currentstate >= mobjinfo[MT_GOTEMERALD].raisestate + && currentstate <= mobjinfo[MT_GOTEMERALD].raisestate + 4) + P_SetMobjState(hnext, + mobjinfo[MT_GOTEMERALD].missilestate + currentstate - mobjinfo[MT_GOTEMERALD].raisestate); + } } return; } From 480c4f890db237d419d23dd24ff57e9d240ff676 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 11 Aug 2018 00:49:28 -0400 Subject: [PATCH 21/80] player->oldscale var for pre-Nightserize scale --- src/d_player.h | 1 + src/lua_playerlib.c | 4 ++++ src/p_saveg.c | 2 ++ src/p_setup.c | 4 ++-- 4 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index 91cafa515..9a7ddc089 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -457,6 +457,7 @@ typedef struct player_s mobj_t *capsule; // Go inside the capsule mobj_t *drone; // Move center to the drone UINT8 mare; // Current mare + fixed_t oldscale; // Pre-Nightserize scale // Statistical purposes. tic_t marebegunat; // Leveltime when mare begun diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index 4fdf25fad..4a5c690b0 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -292,6 +292,8 @@ static int player_get(lua_State *L) LUA_PushUserdata(L, plr->drone, META_MOBJ); else if (fastcmp(field,"mare")) lua_pushinteger(L, plr->mare); + else if (fastcmp(field,"oldscale")) + lua_pushfixed(L, plr->oldscale); else if (fastcmp(field,"marebegunat")) lua_pushinteger(L, plr->marebegunat); else if (fastcmp(field,"startedtime")) @@ -579,6 +581,8 @@ static int player_set(lua_State *L) } else if (fastcmp(field,"mare")) plr->mare = (UINT8)luaL_checkinteger(L, 3); + else if (fastcmp(field,"oldscale")) + plr->oldscale = luaL_checkfixed(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_saveg.c b/src/p_saveg.c index 699b57a5c..923f0b2ed 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -199,6 +199,7 @@ static void P_NetArchivePlayers(void) WRITEUINT8(save_p, players[i].drilldelay); WRITEUINT8(save_p, players[i].bonustime); WRITEUINT8(save_p, players[i].mare); + WRITEFIXED(save_p, players[i].oldscale); WRITEUINT32(save_p, players[i].marebegunat); WRITEUINT32(save_p, players[i].startedtime); @@ -394,6 +395,7 @@ 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].oldscale = READFIXED(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 7e8d0fdb1..b154789ab 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2385,8 +2385,8 @@ static void P_LevelInitStuff(void) players[i].texttimer = players[i].linkcount =\ players[i].linktimer = players[i].flyangle =\ players[i].anotherflyangle = players[i].nightstime =\ - players[i].mare = players[i].realtime =\ - players[i].exiting = 0; + players[i].mare = players[i].oldscale =\ + players[i].realtime = players[i].exiting = 0; // i guess this could be part of the above but i feel mildly uncomfortable implicitly casting players[i].gotcontinue = false; From d1a8e0baa0dce9ba848ff22a345a1aa995e0eb7f Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 11 Aug 2018 00:51:33 -0400 Subject: [PATCH 22/80] Scale player to Drone's scale on Nightserize, and reset scale on De-Nightserize * Also correct player's position to Z center of Drone hitbox on Nightserize --- src/p_inter.c | 2 +- src/p_user.c | 12 +++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index f10d680dd..99b43dbfd 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -793,8 +793,8 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) P_SwitchSpheresBonusMode(false); if (!(netgame || multiplayer) && !(player->powers[pw_carry] == CR_NIGHTSMODE)) P_SetTarget(&special->tracer, toucher); - P_NightserizePlayer(player, special->health); // Transform! P_SetTarget(&player->drone, special); // Mark the player as 'center into the drone' + P_NightserizePlayer(player, special->health); // Transform! if (!spec) { if (toucher->tracer) // Move the ideya over to the drone! diff --git a/src/p_user.c b/src/p_user.c index 18e8e29ca..22ac51df1 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -623,6 +623,10 @@ static void P_DeNightserizePlayer(player_t *player) break; } + if (player->mo->scale != player->oldscale) + player->mo->destscale = player->oldscale; + player->oldscale = 0; + // Restore from drowning music P_RestoreMusic(player); } @@ -640,7 +644,10 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime) return; if (player->powers[pw_carry] != CR_NIGHTSMODE) + { player->mo->height = P_GetPlayerHeight(player); // Just to make sure jumping into the drone doesn't result in a squashed hitbox. + player->oldscale = player->mo->scale; + } player->pflags &= ~(PF_USEDOWN|PF_JUMPDOWN|PF_ATTACKDOWN|PF_STARTDASH|PF_GLIDING|PF_JUMPED|PF_NOJUMPDAMAGE|PF_THOKKED|PF_SHIELDABILITY|PF_SPINNING|PF_DRILLING); player->homing = 0; @@ -765,6 +772,9 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime) player->texttimer = (UINT8)(110 - timeinmap); } + if (player->drone && player->drone->scale != player->mo->scale) + player->mo->destscale = player->drone->scale; + player->powers[pw_carry] = CR_NIGHTSMODE; } @@ -6105,7 +6115,7 @@ static void P_MoveNiGHTSToDrone(player_t *player) if (!player->drone) return; player->mo->momx = player->mo->momy = player->mo->momz = 0; - P_TeleportMove(player->mo, player->drone->x, player->drone->y, player->drone->z); + P_TeleportMove(player->mo, player->drone->x, player->drone->y, player->drone->z + player->drone->height/2 - player->mo->height/2); P_SetTarget(&player->drone, NULL); } From d0f0f475cedb8dbec834765f958ddc11b39122bd Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 11 Aug 2018 02:03:44 -0400 Subject: [PATCH 23/80] * Bounce Droneman within hitbox instead of floorz * Correct Droneman hiding so he always stays within hitbox even when invisible --- src/info.c | 2 +- src/p_mobj.c | 25 ++++++++++++++----------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/info.c b/src/info.c index 195b2769b..38ba0bdf6 100644 --- a/src/info.c +++ b/src/info.c @@ -16134,7 +16134,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 1000, // mass 0, // damage sfx_ideya, // activesound - MF_SPECIAL, // flags + MF_NOGRAVITY|MF_SPECIAL, // flags S_NULL // raisestate }, diff --git a/src/p_mobj.c b/src/p_mobj.c index 8b49f140c..8d6382f2f 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7871,13 +7871,11 @@ void P_MobjThinker(mobj_t *mobj) // Bouncy bouncy! droneman->angle += ANG10; - if (droneman->flags2 & MF2_DONTDRAW) - droneman->momz = 0; - else if (!(droneman->flags2 & MF2_OBJECTFLIP) - && droneman->z <= droneman->floorz) + if (!(droneman->flags2 & MF2_OBJECTFLIP) + && droneman->z <= mobj->z) droneman->momz = FixedMul(5*FRACUNIT, droneman->scale); else if ((droneman->flags2 & MF2_OBJECTFLIP) - && droneman->z >= droneman->ceilingz - droneman->height) + && droneman->z + droneman->height >= mobj->z + mobj->height) droneman->momz = FixedMul(-5*FRACUNIT, droneman->scale); for (i = 0; i < MAXPLAYERS; i++) @@ -7890,8 +7888,8 @@ void P_MobjThinker(mobj_t *mobj) if (bonustime) { CONS_Debug(DBG_NIGHTSBASIC, "Adding goal post\n"); - if (droneman && droneman->state != &states[S_INVISIBLE]) - P_SetMobjState(droneman, S_INVISIBLE); + if (droneman && !(droneman->flags2 & MF2_DONTDRAW)) + droneman->flags2 |= MF2_DONTDRAW; if (goalpost && goalpost->state == &states[S_INVISIBLE]) P_SetMobjState(goalpost, mobjinfo[goalpost->type].meleestate); if (sparkle && sparkle->state == &states[S_INVISIBLE]) @@ -7913,14 +7911,19 @@ void P_MobjThinker(mobj_t *mobj) P_SetMobjState(goalpost, S_INVISIBLE); if (sparkle && sparkle->state != &states[S_INVISIBLE]) P_SetMobjState(sparkle, S_INVISIBLE); - if (droneman && droneman->state == &states[S_INVISIBLE]) - P_SetMobjState(droneman, mobjinfo[droneman->type].meleestate); + if (droneman) + { + if (droneman->state != &states[mobjinfo[droneman->type].meleestate]) + P_SetMobjState(droneman, mobjinfo[droneman->type].meleestate); + if (droneman->flags2 & MF2_DONTDRAW) + droneman->flags2 &= ~MF2_DONTDRAW; + } } else { // else, hide it - if (droneman && droneman->state != &states[S_INVISIBLE]) - P_SetMobjState(droneman, S_INVISIBLE); + if (droneman && !(droneman->flags2 & MF2_DONTDRAW)) + droneman->flags2 |= MF2_DONTDRAW; } } } From c8dcb57e8340c163752e8542a567ddee0a4002ed Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 11 Aug 2018 12:06:17 -0400 Subject: [PATCH 24/80] Remove ORBIDYA CENTER states, we don't need 'em --- src/dehacked.c | 13 ------------- src/info.c | 17 ++--------------- src/info.h | 13 ------------- 3 files changed, 2 insertions(+), 41 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index fd289dc18..5c2953a55 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -6041,24 +6041,11 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_ORBITEM6", "S_ORBITEM7", "S_ORBITEM8", - "S_ORBITEM1_CENTER", - "S_ORBITEM2_CENTER", - "S_ORBITEM3_CENTER", - "S_ORBITEM4_CENTER", - "S_ORBITEM5_CENTER", - "S_ORBITEM6_CENTER", - "S_ORBITEM7_CENTER", - "S_ORBITEM8_CENTER", "S_ORBIDYA1", "S_ORBIDYA2", "S_ORBIDYA3", "S_ORBIDYA4", "S_ORBIDYA5", - "S_ORBIDYA1_CENTER", - "S_ORBIDYA2_CENTER", - "S_ORBIDYA3_CENTER", - "S_ORBIDYA4_CENTER", - "S_ORBIDYA5_CENTER", // "Flicky" helper "S_NIGHTOPIANHELPER1", diff --git a/src/info.c b/src/info.c index 38ba0bdf6..e6b4e8314 100644 --- a/src/info.c +++ b/src/info.c @@ -3338,24 +3338,11 @@ state_t states[NUMSTATES] = {SPR_CEMG, FF_FULLBRIGHT|5, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM6}, // S_ORBITEM6 {SPR_CEMG, FF_FULLBRIGHT|6, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM7}, // S_ORBITEM7 {SPR_CEMG, FF_FULLBRIGHT|7, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM8}, // S_ORBITEM8 - {SPR_CEMG, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0x3000000, S_ORBITEM1_CENTER}, // S_ORBITEM1_CENTER - {SPR_CEMG, FF_FULLBRIGHT|1, 1, {A_OrbitNights}, ANG2*2, 0x3000000, S_ORBITEM2_CENTER}, // S_ORBITEM2_CENTER - {SPR_CEMG, FF_FULLBRIGHT|2, 1, {A_OrbitNights}, ANG2*2, 0x3000000, S_ORBITEM3_CENTER}, // S_ORBITEM3_CENTER - {SPR_CEMG, FF_FULLBRIGHT|3, 1, {A_OrbitNights}, ANG2*2, 0x3000000, S_ORBITEM4_CENTER}, // S_ORBITEM4_CENTER - {SPR_CEMG, FF_FULLBRIGHT|4, 1, {A_OrbitNights}, ANG2*2, 0x3000000, S_ORBITEM5_CENTER}, // S_ORBITEM5_CENTER - {SPR_CEMG, FF_FULLBRIGHT|5, 1, {A_OrbitNights}, ANG2*2, 0x3000000, S_ORBITEM6_CENTER}, // S_ORBITEM6_CENTER - {SPR_CEMG, FF_FULLBRIGHT|6, 1, {A_OrbitNights}, ANG2*2, 0x3000000, S_ORBITEM7_CENTER}, // S_ORBITEM7_CENTER - {SPR_CEMG, FF_FULLBRIGHT|7, 1, {A_OrbitNights}, ANG2*2, 0x3000000, S_ORBITEM8_CENTER}, // S_ORBITEM8_CENTER {SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBIDYA1}, // S_ORBIDYA1 {SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT|1, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBIDYA2}, // S_ORBIDYA2 {SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT|2, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBIDYA3}, // S_ORBIDYA3 {SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT|3, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBIDYA4}, // S_ORBIDYA4 {SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT|4, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBIDYA5}, // S_ORBIDYA5 - {SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0x3000000, S_ORBIDYA1_CENTER}, // S_ORBIDYA1_CENTER - {SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT|1, 1, {A_OrbitNights}, ANG2*2, 0x3000000, S_ORBIDYA2_CENTER}, // S_ORBIDYA2_CENTER - {SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT|2, 1, {A_OrbitNights}, ANG2*2, 0x3000000, S_ORBIDYA3_CENTER}, // S_ORBIDYA3_CENTER - {SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT|3, 1, {A_OrbitNights}, ANG2*2, 0x3000000, S_ORBIDYA4_CENTER}, // S_ORBIDYA4_CENTER - {SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT|4, 1, {A_OrbitNights}, ANG2*2, 0x3000000, S_ORBIDYA5_CENTER}, // S_ORBIDYA5_CENTER // Flicky helper for NiGHTS {SPR_FL01, 1, 1, {A_OrbitNights}, ANG2*2, 180 | 0x10000, S_NIGHTOPIANHELPER2}, // S_NIGHTOPIANHELPER1 @@ -14631,7 +14618,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_ORBITEM1, // meleestate S_ORBIDYA1, // missilestate S_XPLD1, // deathstate - S_ORBITEM1_CENTER, // xdeathstate + S_NULL, // xdeathstate sfx_s3k8a, // deathsound 8, // speed 8*FRACUNIT, // radius @@ -14641,7 +14628,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 0, // damage sfx_None, // activesound MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_SCENERY, // flags - S_ORBIDYA1_CENTER // raisestate + S_NULL // raisestate }, { // MT_LOCKON diff --git a/src/info.h b/src/info.h index 11150a114..a386b199a 100644 --- a/src/info.h +++ b/src/info.h @@ -3394,24 +3394,11 @@ typedef enum state S_ORBITEM6, S_ORBITEM7, S_ORBITEM8, - S_ORBITEM1_CENTER, - S_ORBITEM2_CENTER, - S_ORBITEM3_CENTER, - S_ORBITEM4_CENTER, - S_ORBITEM5_CENTER, - S_ORBITEM6_CENTER, - S_ORBITEM7_CENTER, - S_ORBITEM8_CENTER, S_ORBIDYA1, S_ORBIDYA2, S_ORBIDYA3, S_ORBIDYA4, S_ORBIDYA5, - S_ORBIDYA1_CENTER, - S_ORBIDYA2_CENTER, - S_ORBIDYA3_CENTER, - S_ORBIDYA4_CENTER, - S_ORBIDYA5_CENTER, // "Flicky" helper S_NIGHTOPIANHELPER1, From 0fe41e06ffc3ee9bd80423122dc7d23e4563bce9 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 11 Aug 2018 12:06:50 -0400 Subject: [PATCH 25/80] Remove A_OrbitNights additional input offset on current target Z, don't need it --- src/p_enemy.c | 11 +++-------- src/p_inter.c | 23 +++-------------------- 2 files changed, 6 insertions(+), 28 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index 40adb9d4a..68d01c163 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -8544,14 +8544,12 @@ void A_ToggleFlameJet(mobj_t* actor) // var1 = Angle adjustment (aka orbit speed) // var2: // Lower 16 bits: height offset -// Upper 8 bits: set if object is Nightopian Helper -// Highest 8 bits: center height offset to target by this divisor +// Upper 16 bits: set if object is Nightopian Helper // void A_OrbitNights(mobj_t* actor) { INT32 ofs = (var2 & 0xFFFF); - boolean ishelper = ((var2 >> 16) & 0xFF); - INT32 ofsdiv = var2 >> 24; + boolean ishelper = var2 >> 16; #ifdef HAVE_BLUA if (LUA_CallAction("A_OrbitNights", actor)) return; @@ -8581,10 +8579,7 @@ void A_OrbitNights(mobj_t* actor) actor->x = actor->target->x + fc; actor->y = actor->target->y + fs; - if (ofsdiv) - actor->z = (actor->target->z + actor->target->height / ofsdiv) + fh + FixedMul(16*FRACUNIT, actor->scale); - else - actor->z = actor->target->z + fh + FixedMul(16*FRACUNIT, actor->scale); + actor->z = actor->target->z + fh + FixedMul(16*FRACUNIT, actor->scale); // Semi-lazy hack actor->angle = (angle_t)actor->extravalue1 + ANGLE_90; diff --git a/src/p_inter.c b/src/p_inter.c index 99b43dbfd..86c253e4c 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -799,19 +799,12 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) { if (toucher->tracer) // Move the ideya over to the drone! { - statenum_t currentstate = toucher->tracer->state - states; mobj_t *hnext = special->hnext; P_SetTarget(&special->hnext, toucher->tracer); P_SetTarget(&special->hnext->hnext, hnext); // Buffalo buffalo Buffalo buffalo buffalo buffalo Buffalo buffalo. - P_SetTarget(&special->hnext->target, special); - - // switch to centered orbit states - if (currentstate >= mobjinfo[MT_GOTEMERALD].missilestate - && currentstate <= mobjinfo[MT_GOTEMERALD].missilestate + 4) - P_SetMobjState(toucher->tracer, - mobjinfo[MT_GOTEMERALD].raisestate + currentstate - mobjinfo[MT_GOTEMERALD].missilestate); - + P_SetTarget(&special->hnext->target, special->target ? special->target : special); // goalpost P_SetTarget(&toucher->tracer, NULL); + if (hnext) { special->hnext->extravalue1 = (angle_t)(hnext->extravalue1 - 72*ANG1); @@ -821,19 +814,9 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) } if (player->exiting) // ...then move it back? { - mobj_t *hnext = special; - statenum_t currentstate; + mobj_t *hnext = special->target ? special->target : special; // goalpost while ((hnext = hnext->hnext)) - { P_SetTarget(&hnext->target, toucher); - currentstate = hnext->state - states; - - // switch to regular orbit states - if (currentstate >= mobjinfo[MT_GOTEMERALD].raisestate - && currentstate <= mobjinfo[MT_GOTEMERALD].raisestate + 4) - P_SetMobjState(hnext, - mobjinfo[MT_GOTEMERALD].missilestate + currentstate - mobjinfo[MT_GOTEMERALD].raisestate); - } } return; } From c99258b2e2236ac76e7df3cbf8208c731a54194e Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 11 Aug 2018 15:49:34 -0400 Subject: [PATCH 26/80] Make Drone hitbox height and player Z alignment configurable * Default hitbox height is 80 * Drone Thing parameter sets height to multiples of 32 * Player aligns by default to bottom+24 of hitbox (offsetted) * `MTF_OBJECTSPECIAL` aligns player to hitbox top * `MTF_EXTRA` aligns to hitbox center * `MTF_OBJECTSPECIAL|MTF_EXTRA` aligns to real bottom of hitbox * Goalpost and sparkle Z alignment is changed to reflect configurableness --- src/info.c | 6 +-- src/p_mobj.c | 147 +++++++++++++++++++++++++++++++++++++++++++++------ src/p_user.c | 33 +++++++++++- 3 files changed, 166 insertions(+), 20 deletions(-) diff --git a/src/info.c b/src/info.c index e6b4e8314..f1d78c85e 100644 --- a/src/info.c +++ b/src/info.c @@ -16116,7 +16116,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius - 56*FRACUNIT, // height + 80*FRACUNIT, // height 1, // display offset 1000, // mass 0, // damage @@ -16170,7 +16170,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius - 56*FRACUNIT, // height + 24*FRACUNIT, // height 1, // display offset 1000, // mass 0, // damage @@ -16197,7 +16197,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius - 56*FRACUNIT, // height + 24*FRACUNIT, // height -1, // display offset 1000, // mass 0, // damage diff --git a/src/p_mobj.c b/src/p_mobj.c index 8d6382f2f..1302ca977 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7866,16 +7866,44 @@ void P_MobjThinker(mobj_t *mobj) // Invisible/bouncing mode. else { + boolean flip = mobj->flags2 & MF2_OBJECTFLIP; + boolean topaligned = (mobj->flags & MF_SLIDEME) && !(mobj->flags & MF_GRENADEBOUNCE); + boolean middlealigned = (mobj->flags & MF_GRENADEBOUNCE) && !(mobj->flags & MF_SLIDEME); + boolean bottomoffsetted = !(mobj->flags & MF_SLIDEME) && !(mobj->flags & MF_GRENADEBOUNCE); + fixed_t droneboxmandiff = max(mobj->height - droneman->height, 0); + INT32 i; boolean bonustime = false; + fixed_t zcomp; + + if (!flip) + { + if (topaligned) + zcomp = droneboxmandiff + mobj->z; + else if (middlealigned) + zcomp = (droneboxmandiff / 2) + mobj->z; + else if (bottomoffsetted) + zcomp = mobj->z + FixedMul(24*FRACUNIT, mobj->scale); + else + zcomp = mobj->z; + } + else + { + if (topaligned) + zcomp = mobj->z; + else if (middlealigned) + zcomp = (droneboxmandiff / 2) + mobj->z; + else if (bottomoffsetted) + zcomp = mobj->z + droneboxmandiff - FixedMul(24*FRACUNIT, mobj->scale); + else + zcomp = mobj->z + droneboxmandiff; + } // Bouncy bouncy! droneman->angle += ANG10; - if (!(droneman->flags2 & MF2_OBJECTFLIP) - && droneman->z <= mobj->z) + if (!flip && droneman->z <= zcomp) droneman->momz = FixedMul(5*FRACUNIT, droneman->scale); - else if ((droneman->flags2 & MF2_OBJECTFLIP) - && droneman->z + droneman->height >= mobj->z + mobj->height) + else if (flip && droneman->z >= zcomp) droneman->momz = FixedMul(-5*FRACUNIT, droneman->scale); for (i = 0; i < MAXPLAYERS; i++) @@ -10541,24 +10569,111 @@ ML_EFFECT4 : Don't clip inside the ground mobj->threshold = mthing->angle >> 8; break; case MT_NIGHTSDRONE: - if (mthing->angle > 0) - mobj->health = mthing->angle; - - if (mthing->options & MTF_OBJECTFLIP) { - mobj->eflags |= MFE_VERTICALFLIP; - mobj->flags2 |= MF2_OBJECTFLIP; - } + boolean flip = mthing->options & MTF_OBJECTFLIP; + boolean topaligned = (mthing->options & MTF_OBJECTSPECIAL) && !(mthing->options & MTF_EXTRA); + boolean middlealigned = (mthing->options & MTF_EXTRA) && !(mthing->options & MTF_OBJECTSPECIAL); + boolean bottomoffsetted = !(mthing->options & MTF_OBJECTSPECIAL) && !(mthing->options & MTF_EXTRA); - // spawn visual components - { - mobj_t *goalpost = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_NIGHTSDRONE_GOAL); - mobj_t *sparkle = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_NIGHTSDRONE_SPARKLING); - mobj_t *droneman = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_NIGHTSDRONE_MAN); + fixed_t droneboxmandiff = max(mobj->height - mobjinfo[MT_NIGHTSDRONE_MAN].height, 0); + fixed_t dronemangoaldiff = max(mobjinfo[MT_NIGHTSDRONE_MAN].height - mobjinfo[MT_NIGHTSDRONE_GOAL].height, 0); + + INT16 timelimit = mthing->angle; + fixed_t hitboxheight = mthing->extrainfo * 32 * FRACUNIT; + fixed_t oldheight = mobj->height; + // if you want to use parameter for something else, do this instead: + // timelimit = mthing->angle & 0xFFF; hitboxheight = (mthing->extrainfo >> 12) * 32 * FRACUNIT; + fixed_t dronemanoffset, goaloffset, sparkleoffset; + + if (mthing->angle > 0) + mobj->health = timelimit; + + if (hitboxheight > 0) + mobj->height = hitboxheight; + else + mobj->height = mobjinfo[MT_NIGHTSDRONE].height; + + if (flip && mobj->height != oldheight) + P_TeleportMove(mobj, mobj->x, mobj->y, mobj->z - (mobj->height - oldheight)); + + if (!flip) + { + if (topaligned) // Align droneman to top of hitbox + { + dronemanoffset = droneboxmandiff; + goaloffset = dronemangoaldiff / 2 + dronemanoffset; + } + else if (middlealigned) // Align droneman to center of hitbox + { + dronemanoffset = droneboxmandiff / 2; + goaloffset = dronemangoaldiff / 2 + dronemanoffset; + } + else if (bottomoffsetted) + { + dronemanoffset = 24*FRACUNIT; + goaloffset = dronemangoaldiff + dronemanoffset; + } + else + { + dronemanoffset = 0; + goaloffset = dronemangoaldiff / 2 + dronemanoffset; + } + + sparkleoffset = goaloffset - FixedMul(15*FRACUNIT, mobj->scale); + } + else + { + mobj->eflags |= MFE_VERTICALFLIP; + mobj->flags2 |= MF2_OBJECTFLIP; + + if (topaligned) // Align droneman to top of hitbox + { + dronemanoffset = 0; + goaloffset = dronemangoaldiff / 2 + dronemanoffset; + } + else if (middlealigned) // Align droneman to center of hitbox + { + dronemanoffset = droneboxmandiff / 2; + goaloffset = dronemangoaldiff / 2 + dronemanoffset; + } + else if (bottomoffsetted) + { + dronemanoffset = droneboxmandiff - FixedMul(24*FRACUNIT, mobj->scale); + goaloffset = dronemangoaldiff + dronemanoffset; + } + else + { + dronemanoffset = droneboxmandiff; + goaloffset = dronemangoaldiff / 2 + dronemanoffset; + } + + sparkleoffset = goaloffset + FixedMul(15*FRACUNIT, mobj->scale); + } + + // spawn visual elements + mobj_t *goalpost = P_SpawnMobjFromMobj(mobj, 0, 0, goaloffset, MT_NIGHTSDRONE_GOAL); + mobj_t *sparkle = P_SpawnMobjFromMobj(mobj, 0, 0, sparkleoffset, MT_NIGHTSDRONE_SPARKLING); + mobj_t *droneman = P_SpawnMobjFromMobj(mobj, 0, 0, dronemanoffset, MT_NIGHTSDRONE_MAN); P_SetTarget(&mobj->target, goalpost); P_SetTarget(&goalpost->target, sparkle); P_SetTarget(&goalpost->tracer, droneman); + + // correct Z position + if (flip) + { + P_TeleportMove(goalpost, goalpost->x, goalpost->y, mobj->z + goaloffset); + P_TeleportMove(sparkle, sparkle->x, sparkle->y, mobj->z + sparkleoffset); + P_TeleportMove(droneman, droneman->x, droneman->y, mobj->z + dronemanoffset); + } + + // Remember position preference for later + if (topaligned) + mobj->flags |= MF_SLIDEME; + else if (middlealigned) + mobj->flags |= MF_GRENADEBOUNCE; + else if (!bottomoffsetted) + mobj->flags |= MF_SLIDEME | MF_GRENADEBOUNCE; } break; case MT_HIVEELEMENTAL: diff --git a/src/p_user.c b/src/p_user.c index 22ac51df1..8c50b5095 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -6114,8 +6114,39 @@ static void P_MoveNiGHTSToDrone(player_t *player) { if (!player->drone) return; + + boolean flip = player->drone->flags2 & MF2_OBJECTFLIP; + boolean topaligned = (player->drone->flags & MF_SLIDEME) && !(player->drone->flags & MF_GRENADEBOUNCE); + boolean middlealigned = (player->drone->flags & MF_GRENADEBOUNCE) && !(player->drone->flags & MF_SLIDEME); + boolean bottomoffsetted = !(player->drone->flags & MF_SLIDEME) && !(player->drone->flags & MF_GRENADEBOUNCE); + fixed_t droneboxmandiff = max(player->drone->height - player->mo->height, 0); + fixed_t zofs; + + if (!flip) + { + if (topaligned) + zofs = droneboxmandiff; + else if (middlealigned) + zofs = droneboxmandiff / 2; + else if (bottomoffsetted) + zofs = FixedMul(24*FRACUNIT, player->drone->scale); + else + zofs = 0; + } + else + { + if (topaligned) + zofs = 0; + else if (middlealigned) + zofs = droneboxmandiff / 2; + else if (bottomoffsetted) + zofs = droneboxmandiff - FixedMul(24*FRACUNIT, player->drone->scale); + else + zofs = droneboxmandiff; + } + player->mo->momx = player->mo->momy = player->mo->momz = 0; - P_TeleportMove(player->mo, player->drone->x, player->drone->y, player->drone->z + player->drone->height/2 - player->mo->height/2); + P_TeleportMove(player->mo, player->drone->x, player->drone->y, player->drone->z + zofs); P_SetTarget(&player->drone, NULL); } From 2c4f9d4776d010a6774218035df9b60bb73f72c1 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 11 Aug 2018 15:54:39 -0400 Subject: [PATCH 27/80] Don't need this line --- src/p_mobj.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 1302ca977..de2ed16ac 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8801,8 +8801,6 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) mobj->fuse += 30 * TICRATE; break; case MT_NIGHTSDRONE: - if (G_IsSpecialStage(gamemap)) - mobj->flags2 |= MF2_DONTDRAW; nummaprings = -1; // no perfect bonus, rings are free break; case MT_EGGCAPSULE: From 72b592888ff2324e2dd279e2afa9a2c522a42e8d Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 11 Aug 2018 20:49:16 -0400 Subject: [PATCH 28/80] Line fixes for visual element positioning # Conflicts: # src/p_mobj.c --- src/p_mobj.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index de2ed16ac..66608332c 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -10573,15 +10573,13 @@ ML_EFFECT4 : Don't clip inside the ground boolean middlealigned = (mthing->options & MTF_EXTRA) && !(mthing->options & MTF_OBJECTSPECIAL); boolean bottomoffsetted = !(mthing->options & MTF_OBJECTSPECIAL) && !(mthing->options & MTF_EXTRA); - fixed_t droneboxmandiff = max(mobj->height - mobjinfo[MT_NIGHTSDRONE_MAN].height, 0); - fixed_t dronemangoaldiff = max(mobjinfo[MT_NIGHTSDRONE_MAN].height - mobjinfo[MT_NIGHTSDRONE_GOAL].height, 0); - INT16 timelimit = mthing->angle; fixed_t hitboxheight = mthing->extrainfo * 32 * FRACUNIT; fixed_t oldheight = mobj->height; // if you want to use parameter for something else, do this instead: // timelimit = mthing->angle & 0xFFF; hitboxheight = (mthing->extrainfo >> 12) * 32 * FRACUNIT; - fixed_t dronemanoffset, goaloffset, sparkleoffset; + fixed_t oldheight = mobj->height; + fixed_t dronemanoffset, goaloffset, sparkleoffset, droneboxmandiff, dronemangoaldiff; if (mthing->angle > 0) mobj->health = timelimit; @@ -10591,6 +10589,9 @@ ML_EFFECT4 : Don't clip inside the ground else mobj->height = mobjinfo[MT_NIGHTSDRONE].height; + droneboxmandiff = max(mobj->height - mobjinfo[MT_NIGHTSDRONE_MAN].height, 0); + dronemangoaldiff = max(mobjinfo[MT_NIGHTSDRONE_MAN].height - mobjinfo[MT_NIGHTSDRONE_GOAL].height, 0); + if (flip && mobj->height != oldheight) P_TeleportMove(mobj, mobj->x, mobj->y, mobj->z - (mobj->height - oldheight)); From a4e3f8cbcfb510fb3be2697993dc136f507906d5 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 11 Aug 2018 19:40:26 -0400 Subject: [PATCH 29/80] NIGHTSDRONE visual element position syncing: XYZ and OBJECTFLIP --- src/p_mobj.c | 146 ++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 126 insertions(+), 20 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 66608332c..31d643fe5 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7828,10 +7828,19 @@ void P_MobjThinker(mobj_t *mobj) break; case MT_NIGHTSDRONE: { + // variable setup mobj_t *goalpost = NULL; mobj_t *sparkle = NULL; mobj_t *droneman = NULL; + boolean flip = mobj->flags2 & MF2_OBJECTFLIP; + boolean topaligned = (mobj->flags & MF_SLIDEME) && !(mobj->flags & MF_GRENADEBOUNCE); + boolean middlealigned = (mobj->flags & MF_GRENADEBOUNCE) && !(mobj->flags & MF_SLIDEME); + boolean bottomoffsetted = !(mobj->flags & MF_SLIDEME) && !(mobj->flags & MF_GRENADEBOUNCE); + boolean flipchanged = false; + + fixed_t dronemanoffset, goaloffset, sparkleoffset, droneboxmandiff, dronemangoaldiff; + if (mobj->target && mobj->target->type == MT_NIGHTSDRONE_GOAL) { goalpost = mobj->target; @@ -7841,6 +7850,108 @@ void P_MobjThinker(mobj_t *mobj) droneman = goalpost->tracer; } + if (!goalpost || !sparkle || !droneman) + break; + + // did NIGHTSDRONE position, scale, or flip change? all elements need to be synced + droneboxmandiff = max(mobj->height - droneman->height, 0); + dronemangoaldiff = max(droneman->height - goalpost->height, 0); + + if (!(goalpost->flags2 & MF2_OBJECTFLIP) && (mobj->flags2 & MF2_OBJECTFLIP)) + { + goalpost->eflags |= MFE_VERTICALFLIP; + goalpost->flags2 |= MF2_OBJECTFLIP; + sparkle->eflags |= MFE_VERTICALFLIP; + sparkle->flags2 |= MF2_OBJECTFLIP; + droneman->eflags |= MFE_VERTICALFLIP; + droneman->flags2 |= MF2_OBJECTFLIP; + flipchanged = true; + } + else if ((goalpost->flags2 & MF2_OBJECTFLIP) && !(mobj->flags2 & MF2_OBJECTFLIP)) + { + goalpost->eflags &= ~MFE_VERTICALFLIP; + goalpost->flags2 &= ~MF2_OBJECTFLIP; + sparkle->eflags &= ~MFE_VERTICALFLIP; + sparkle->flags2 &= ~MF2_OBJECTFLIP; + droneman->eflags &= ~MFE_VERTICALFLIP; + droneman->flags2 &= ~MF2_OBJECTFLIP; + flipchanged = true; + } + + if (goalpost->destscale != mobj->destscale || goalpost->movefactor != mobj->z || flipchanged) + { + goalpost->destscale = sparkle->destscale = droneman->destscale = mobj->destscale; + goalpost->movefactor = mobj->z; + + // straight copy-pasta from P_SpawnMapThing, case MT_NIGHTSDRONE + if (!flip) + { + if (topaligned) // Align droneman to top of hitbox + { + dronemanoffset = droneboxmandiff; + goaloffset = dronemangoaldiff / 2 + dronemanoffset; + } + else if (middlealigned) // Align droneman to center of hitbox + { + dronemanoffset = droneboxmandiff / 2; + goaloffset = dronemangoaldiff / 2 + dronemanoffset; + } + else if (bottomoffsetted) + { + dronemanoffset = 24*FRACUNIT; + goaloffset = dronemangoaldiff + dronemanoffset; + } + else + { + dronemanoffset = 0; + goaloffset = dronemangoaldiff / 2 + dronemanoffset; + } + + sparkleoffset = goaloffset - FixedMul(15*FRACUNIT, mobj->scale); + } + else + { + if (topaligned) // Align droneman to top of hitbox + { + dronemanoffset = 0; + goaloffset = dronemangoaldiff / 2 + dronemanoffset; + } + else if (middlealigned) // Align droneman to center of hitbox + { + dronemanoffset = droneboxmandiff / 2; + goaloffset = dronemangoaldiff / 2 + dronemanoffset; + } + else if (bottomoffsetted) + { + dronemanoffset = droneboxmandiff - FixedMul(24*FRACUNIT, mobj->scale); + goaloffset = dronemangoaldiff + dronemanoffset; + } + else + { + dronemanoffset = droneboxmandiff; + goaloffset = dronemangoaldiff / 2 + dronemanoffset; + } + + sparkleoffset = goaloffset + FixedMul(15*FRACUNIT, mobj->scale); + } + + P_TeleportMove(goalpost, mobj->x, mobj->y, mobj->z + FixedMul(goaloffset, mobj->scale)); + P_TeleportMove(sparkle, mobj->x, mobj->y, mobj->z + FixedMul(sparkleoffset, mobj->scale)); + } + else if (goalpost->x != mobj->x || goalpost->y != mobj->y) + { + P_TeleportMove(goalpost, mobj->x, mobj->y, goalpost->z); + P_TeleportMove(sparkle, mobj->x, mobj->y, goalpost->z); + } + + if (droneman->x != mobj->x || droneman->y != mobj->y) + { + // we just care about x/y positioning; z takes care of itself + P_TeleportMove(droneman, mobj->x, mobj->y, + droneman->z >= mobj->floorz && droneman->z <= mobj->ceilingz ? droneman->z : mobj->z); + } + + // now toggle states! // GOAL mode? if (sparkle->state >= &states[S_NIGHTSDRONE_SPARKLING1] && sparkle->state <= &states[S_NIGHTSDRONE_SPARKLING16]) { @@ -7866,16 +7977,12 @@ void P_MobjThinker(mobj_t *mobj) // Invisible/bouncing mode. else { - boolean flip = mobj->flags2 & MF2_OBJECTFLIP; - boolean topaligned = (mobj->flags & MF_SLIDEME) && !(mobj->flags & MF_GRENADEBOUNCE); - boolean middlealigned = (mobj->flags & MF_GRENADEBOUNCE) && !(mobj->flags & MF_SLIDEME); - boolean bottomoffsetted = !(mobj->flags & MF_SLIDEME) && !(mobj->flags & MF_GRENADEBOUNCE); fixed_t droneboxmandiff = max(mobj->height - droneman->height, 0); - INT32 i; boolean bonustime = false; fixed_t zcomp; + // Bouncy bouncy! if (!flip) { if (topaligned) @@ -7899,13 +8006,13 @@ void P_MobjThinker(mobj_t *mobj) zcomp = mobj->z + droneboxmandiff; } - // Bouncy bouncy! droneman->angle += ANG10; if (!flip && droneman->z <= zcomp) droneman->momz = FixedMul(5*FRACUNIT, droneman->scale); else if (flip && droneman->z >= zcomp) droneman->momz = FixedMul(-5*FRACUNIT, droneman->scale); + // state switching logic for (i = 0; i < MAXPLAYERS; i++) if (playeringame[i] && players[i].bonustime && players[i].powers[pw_carry] == CR_NIGHTSMODE) { @@ -7916,11 +8023,11 @@ void P_MobjThinker(mobj_t *mobj) if (bonustime) { CONS_Debug(DBG_NIGHTSBASIC, "Adding goal post\n"); - if (droneman && !(droneman->flags2 & MF2_DONTDRAW)) + if (!(droneman->flags2 & MF2_DONTDRAW)) droneman->flags2 |= MF2_DONTDRAW; - if (goalpost && goalpost->state == &states[S_INVISIBLE]) + if (goalpost->state == &states[S_INVISIBLE]) P_SetMobjState(goalpost, mobjinfo[goalpost->type].meleestate); - if (sparkle && sparkle->state == &states[S_INVISIBLE]) + if (sparkle->state == &states[S_INVISIBLE]) P_SetMobjState(sparkle, mobjinfo[sparkle->type].meleestate); } else if (!G_IsSpecialStage(gamemap)) @@ -7935,22 +8042,19 @@ void P_MobjThinker(mobj_t *mobj) if (bonustime) { // show droneman if at least one player is non-nights - if (goalpost && goalpost->state != &states[S_INVISIBLE]) + if (goalpost->state != &states[S_INVISIBLE]) P_SetMobjState(goalpost, S_INVISIBLE); - if (sparkle && sparkle->state != &states[S_INVISIBLE]) + if (sparkle->state != &states[S_INVISIBLE]) P_SetMobjState(sparkle, S_INVISIBLE); - if (droneman) - { - if (droneman->state != &states[mobjinfo[droneman->type].meleestate]) - P_SetMobjState(droneman, mobjinfo[droneman->type].meleestate); - if (droneman->flags2 & MF2_DONTDRAW) - droneman->flags2 &= ~MF2_DONTDRAW; - } + if (droneman->state != &states[mobjinfo[droneman->type].meleestate]) + P_SetMobjState(droneman, mobjinfo[droneman->type].meleestate); + if (droneman->flags2 & MF2_DONTDRAW) + droneman->flags2 &= ~MF2_DONTDRAW; } else { // else, hide it - if (droneman && !(droneman->flags2 & MF2_DONTDRAW)) + if (!(droneman->flags2 & MF2_DONTDRAW)) droneman->flags2 |= MF2_DONTDRAW; } } @@ -10575,7 +10679,6 @@ ML_EFFECT4 : Don't clip inside the ground INT16 timelimit = mthing->angle; fixed_t hitboxheight = mthing->extrainfo * 32 * FRACUNIT; - fixed_t oldheight = mobj->height; // if you want to use parameter for something else, do this instead: // timelimit = mthing->angle & 0xFFF; hitboxheight = (mthing->extrainfo >> 12) * 32 * FRACUNIT; fixed_t oldheight = mobj->height; @@ -10658,6 +10761,9 @@ ML_EFFECT4 : Don't clip inside the ground P_SetTarget(&goalpost->target, sparkle); P_SetTarget(&goalpost->tracer, droneman); + // Remember old Z position for correction detection + goalpost->movefactor = mobj->z; + // correct Z position if (flip) { From 4f9231b7a5f7351421b08d6e71590b950c6534bf Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 11 Aug 2018 22:13:33 -0400 Subject: [PATCH 30/80] Fix orbiting Ideya bug, now player gets them back again on exit --- src/p_inter.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index 86c253e4c..454f09591 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -799,17 +799,18 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) { if (toucher->tracer) // Move the ideya over to the drone! { - mobj_t *hnext = special->hnext; - P_SetTarget(&special->hnext, toucher->tracer); - P_SetTarget(&special->hnext->hnext, hnext); // Buffalo buffalo Buffalo buffalo buffalo buffalo Buffalo buffalo. - P_SetTarget(&special->hnext->target, special->target ? special->target : special); // goalpost + mobj_t *orbittarget = special->target ? special->target : special; + mobj_t *hnext = orbittarget->hnext; + P_SetTarget(&orbittarget->hnext, toucher->tracer); + P_SetTarget(&orbittarget->hnext->hnext, hnext); // Buffalo buffalo Buffalo buffalo buffalo buffalo Buffalo buffalo. + P_SetTarget(&orbittarget->hnext->target, orbittarget); // goalpost P_SetTarget(&toucher->tracer, NULL); if (hnext) { - special->hnext->extravalue1 = (angle_t)(hnext->extravalue1 - 72*ANG1); - if (special->hnext->extravalue1 > hnext->extravalue1) - special->hnext->extravalue1 -= (72*ANG1)/special->hnext->extravalue1; + orbittarget->hnext->extravalue1 = (angle_t)(hnext->extravalue1 - 72*ANG1); + if (orbittarget->hnext->extravalue1 > hnext->extravalue1) + orbittarget->hnext->extravalue1 -= (72*ANG1)/orbittarget->hnext->extravalue1; } } if (player->exiting) // ...then move it back? From 79c042ca0984add1e7ec79d34f294b65fc3f51a0 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 11 Aug 2018 22:41:58 -0400 Subject: [PATCH 31/80] NIGHTSDRONE visual element positioning now works with scaling --- src/p_mobj.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 31d643fe5..1e28ae1a4 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7935,8 +7935,8 @@ void P_MobjThinker(mobj_t *mobj) sparkleoffset = goaloffset + FixedMul(15*FRACUNIT, mobj->scale); } - P_TeleportMove(goalpost, mobj->x, mobj->y, mobj->z + FixedMul(goaloffset, mobj->scale)); - P_TeleportMove(sparkle, mobj->x, mobj->y, mobj->z + FixedMul(sparkleoffset, mobj->scale)); + P_TeleportMove(goalpost, mobj->x, mobj->y, mobj->z + goaloffset); + P_TeleportMove(sparkle, mobj->x, mobj->y, mobj->z + sparkleoffset); } else if (goalpost->x != mobj->x || goalpost->y != mobj->y) { From 0c8e1aa10ac70def05f9e0e5d4712bf462ab83a5 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 11 Aug 2018 23:15:28 -0400 Subject: [PATCH 32/80] When NIGHTSDRONE z changes, change DRONEMAN z as well --- src/p_mobj.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 1e28ae1a4..20af2e763 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7881,7 +7881,6 @@ void P_MobjThinker(mobj_t *mobj) if (goalpost->destscale != mobj->destscale || goalpost->movefactor != mobj->z || flipchanged) { goalpost->destscale = sparkle->destscale = droneman->destscale = mobj->destscale; - goalpost->movefactor = mobj->z; // straight copy-pasta from P_SpawnMapThing, case MT_NIGHTSDRONE if (!flip) @@ -7937,6 +7936,11 @@ void P_MobjThinker(mobj_t *mobj) P_TeleportMove(goalpost, mobj->x, mobj->y, mobj->z + goaloffset); P_TeleportMove(sparkle, mobj->x, mobj->y, mobj->z + sparkleoffset); + if (goalpost->movefactor != mobj->z) + { + P_TeleportMove(droneman, mobj->x, mobj->y, mobj->z + dronemanoffset); + goalpost->movefactor = mobj->z; + } } else if (goalpost->x != mobj->x || goalpost->y != mobj->y) { @@ -7945,11 +7949,10 @@ void P_MobjThinker(mobj_t *mobj) } if (droneman->x != mobj->x || droneman->y != mobj->y) - { - // we just care about x/y positioning; z takes care of itself + // More complex changes like Z, gravity, and flags are handled earlier. + // Here, we just care if only X/Y changes. P_TeleportMove(droneman, mobj->x, mobj->y, droneman->z >= mobj->floorz && droneman->z <= mobj->ceilingz ? droneman->z : mobj->z); - } // now toggle states! // GOAL mode? From 9bc9f96e0918ea8b8d222748d97ba83157f8a60a Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 11 Aug 2018 23:32:12 -0400 Subject: [PATCH 33/80] NIGHTSDRONE sync visual elements when changing mobj flags --- src/p_mobj.c | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 20af2e763..3aa68e521 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7853,7 +7853,7 @@ void P_MobjThinker(mobj_t *mobj) if (!goalpost || !sparkle || !droneman) break; - // did NIGHTSDRONE position, scale, or flip change? all elements need to be synced + // did NIGHTSDRONE position, scale, flip, or flags change? all elements need to be synced droneboxmandiff = max(mobj->height - droneman->height, 0); dronemangoaldiff = max(droneman->height - goalpost->height, 0); @@ -7878,7 +7878,10 @@ void P_MobjThinker(mobj_t *mobj) flipchanged = true; } - if (goalpost->destscale != mobj->destscale || goalpost->movefactor != mobj->z || flipchanged) + if (goalpost->destscale != mobj->destscale + || goalpost->movefactor != mobj->z + || flipchanged + || goalpost->threshold != (mobj->flags & (MF_SLIDEME | MF_GRENADEBOUNCE))) { goalpost->destscale = sparkle->destscale = droneman->destscale = mobj->destscale; @@ -7941,18 +7944,20 @@ void P_MobjThinker(mobj_t *mobj) P_TeleportMove(droneman, mobj->x, mobj->y, mobj->z + dronemanoffset); goalpost->movefactor = mobj->z; } + goalpost->threshold = mobj->flags & (MF_SLIDEME | MF_GRENADEBOUNCE); } - else if (goalpost->x != mobj->x || goalpost->y != mobj->y) + else { - P_TeleportMove(goalpost, mobj->x, mobj->y, goalpost->z); - P_TeleportMove(sparkle, mobj->x, mobj->y, goalpost->z); - } + if (goalpost->x != mobj->x || goalpost->y != mobj->y) + { + P_TeleportMove(goalpost, mobj->x, mobj->y, goalpost->z); + P_TeleportMove(sparkle, mobj->x, mobj->y, goalpost->z); + } - if (droneman->x != mobj->x || droneman->y != mobj->y) - // More complex changes like Z, gravity, and flags are handled earlier. - // Here, we just care if only X/Y changes. - P_TeleportMove(droneman, mobj->x, mobj->y, - droneman->z >= mobj->floorz && droneman->z <= mobj->ceilingz ? droneman->z : mobj->z); + if (droneman->x != mobj->x || droneman->y != mobj->y) + P_TeleportMove(droneman, mobj->x, mobj->y, + droneman->z >= mobj->floorz && droneman->z <= mobj->ceilingz ? droneman->z : mobj->z); + } // now toggle states! // GOAL mode? @@ -10764,9 +10769,6 @@ ML_EFFECT4 : Don't clip inside the ground P_SetTarget(&goalpost->target, sparkle); P_SetTarget(&goalpost->tracer, droneman); - // Remember old Z position for correction detection - goalpost->movefactor = mobj->z; - // correct Z position if (flip) { @@ -10782,6 +10784,10 @@ ML_EFFECT4 : Don't clip inside the ground mobj->flags |= MF_GRENADEBOUNCE; else if (!bottomoffsetted) mobj->flags |= MF_SLIDEME | MF_GRENADEBOUNCE; + + // Remember old Z position and flags for correction detection + goalpost->movefactor = mobj->z; + goalpost->threshold = mobj->flags & (MF_SLIDEME | MF_GRENADEBOUNCE); } break; case MT_HIVEELEMENTAL: From aecabb246d37e0fe741ace0f49b8d71db4278995 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 11 Aug 2018 23:53:07 -0400 Subject: [PATCH 34/80] Scale Ideyas when moving to/from NIGHTSDRONE and scaling changes to NIGHTSDRONE --- src/p_inter.c | 3 +++ src/p_mobj.c | 9 ++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/p_inter.c b/src/p_inter.c index 454f09591..e05f18364 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -801,11 +801,14 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) { mobj_t *orbittarget = special->target ? special->target : special; mobj_t *hnext = orbittarget->hnext; + P_SetTarget(&orbittarget->hnext, toucher->tracer); P_SetTarget(&orbittarget->hnext->hnext, hnext); // Buffalo buffalo Buffalo buffalo buffalo buffalo Buffalo buffalo. P_SetTarget(&orbittarget->hnext->target, orbittarget); // goalpost P_SetTarget(&toucher->tracer, NULL); + orbittarget->hnext->destscale = orbittarget->destscale; + if (hnext) { orbittarget->hnext->extravalue1 = (angle_t)(hnext->extravalue1 - 72*ANG1); diff --git a/src/p_mobj.c b/src/p_mobj.c index 3aa68e521..2450743b7 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7883,7 +7883,14 @@ void P_MobjThinker(mobj_t *mobj) || flipchanged || goalpost->threshold != (mobj->flags & (MF_SLIDEME | MF_GRENADEBOUNCE))) { - goalpost->destscale = sparkle->destscale = droneman->destscale = mobj->destscale; + if (goalpost->destscale != mobj->destscale) + { + goalpost->destscale = sparkle->destscale = droneman->destscale = mobj->destscale; + // get the orbiting ideyas and scale them too + mobj_t *hnext = goalpost; + while ((hnext = hnext->hnext)) + hnext->destscale = mobj->destscale; + } // straight copy-pasta from P_SpawnMapThing, case MT_NIGHTSDRONE if (!flip) From 43b790c26f83d0b4cc58bad1161beda7a060ca2f Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sun, 12 Aug 2018 01:07:26 -0400 Subject: [PATCH 35/80] A_OrbitNights make actor scale to target * Added `donotrescale` input to disable this behavior * Reverted previous commit changes for scaling Ideya because unneeded --- src/p_enemy.c | 9 +++++++-- src/p_inter.c | 2 -- src/p_mobj.c | 9 +-------- 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index 68d01c163..06223eb7a 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -8544,12 +8544,14 @@ void A_ToggleFlameJet(mobj_t* actor) // var1 = Angle adjustment (aka orbit speed) // var2: // Lower 16 bits: height offset -// Upper 16 bits: set if object is Nightopian Helper +// Bits 17-20: set if object is Nightopian Helper +// Bits 21-24: set to not sync scale to player // void A_OrbitNights(mobj_t* actor) { INT32 ofs = (var2 & 0xFFFF); - boolean ishelper = var2 >> 16; + boolean ishelper = (var2 & 0xF0000); + boolean donotrescale = (var2 & 0xF00000); #ifdef HAVE_BLUA if (LUA_CallAction("A_OrbitNights", actor)) return; @@ -8594,6 +8596,9 @@ void A_OrbitNights(mobj_t* actor) else actor->flags2 &= ~MF2_DONTDRAW; } + + if (!donotrescale && actor->destscale != actor->target->destscale) + actor->destscale = actor->target->destscale; } } diff --git a/src/p_inter.c b/src/p_inter.c index e05f18364..66c6bd852 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -807,8 +807,6 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) P_SetTarget(&orbittarget->hnext->target, orbittarget); // goalpost P_SetTarget(&toucher->tracer, NULL); - orbittarget->hnext->destscale = orbittarget->destscale; - if (hnext) { orbittarget->hnext->extravalue1 = (angle_t)(hnext->extravalue1 - 72*ANG1); diff --git a/src/p_mobj.c b/src/p_mobj.c index 2450743b7..3aa68e521 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7883,14 +7883,7 @@ void P_MobjThinker(mobj_t *mobj) || flipchanged || goalpost->threshold != (mobj->flags & (MF_SLIDEME | MF_GRENADEBOUNCE))) { - if (goalpost->destscale != mobj->destscale) - { - goalpost->destscale = sparkle->destscale = droneman->destscale = mobj->destscale; - // get the orbiting ideyas and scale them too - mobj_t *hnext = goalpost; - while ((hnext = hnext->hnext)) - hnext->destscale = mobj->destscale; - } + goalpost->destscale = sparkle->destscale = droneman->destscale = mobj->destscale; // straight copy-pasta from P_SpawnMapThing, case MT_NIGHTSDRONE if (!flip) From 8f50fbeb4fa9ef5759dc17f929e3922fb1828565 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sun, 12 Aug 2018 09:28:04 -0400 Subject: [PATCH 36/80] For safety, clear MF_SLIDEME and MF_GRENADEBOUNCE flags before using --- src/p_mobj.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/p_mobj.c b/src/p_mobj.c index 3aa68e521..fe78fa79d 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -10778,6 +10778,7 @@ ML_EFFECT4 : Don't clip inside the ground } // Remember position preference for later + mobj->flags &= ~(MF_SLIDEME | MF_GRENADEBOUNCE); if (topaligned) mobj->flags |= MF_SLIDEME; else if (middlealigned) From ce0b23a5769826118892ef42bb3e6387fc9ddb47 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sun, 12 Aug 2018 12:42:21 -0400 Subject: [PATCH 37/80] Set Drone hitbox radius by upmost 4 bits of Angle --- src/info.c | 2 +- src/p_mobj.c | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/info.c b/src/info.c index f1d78c85e..fc30011bf 100644 --- a/src/info.c +++ b/src/info.c @@ -16121,7 +16121,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 1000, // mass 0, // damage sfx_ideya, // activesound - MF_NOGRAVITY|MF_SPECIAL, // flags + MF_NOGRAVITY|MF_NOCLIP|MF_SPECIAL, // flags S_NULL // raisestate }, diff --git a/src/p_mobj.c b/src/p_mobj.c index fe78fa79d..5292ef15e 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -10685,16 +10685,18 @@ ML_EFFECT4 : Don't clip inside the ground boolean middlealigned = (mthing->options & MTF_EXTRA) && !(mthing->options & MTF_OBJECTSPECIAL); boolean bottomoffsetted = !(mthing->options & MTF_OBJECTSPECIAL) && !(mthing->options & MTF_EXTRA); - INT16 timelimit = mthing->angle; + INT16 timelimit = mthing->angle & 0xFFF; + fixed_t hitboxradius = (mthing->angle & 0xF000) * 32 * FRACUNIT; fixed_t hitboxheight = mthing->extrainfo * 32 * FRACUNIT; - // if you want to use parameter for something else, do this instead: - // timelimit = mthing->angle & 0xFFF; hitboxheight = (mthing->extrainfo >> 12) * 32 * FRACUNIT; fixed_t oldheight = mobj->height; fixed_t dronemanoffset, goaloffset, sparkleoffset, droneboxmandiff, dronemangoaldiff; - if (mthing->angle > 0) + if (timelimit > 0) mobj->health = timelimit; + if (hitboxradius > 0) + mobj->radius = hitboxradius; + if (hitboxheight > 0) mobj->height = hitboxheight; else From 4642c75025d76d54ddf6ec383c117414d45c1bf9 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sun, 12 Aug 2018 22:11:18 -0400 Subject: [PATCH 38/80] MT_IDEYAANCHOR info and spawn logic --- src/dehacked.c | 1 + src/info.c | 27 +++++++++++++++++++++++++++ src/info.h | 1 + src/p_mobj.c | 4 ++++ 4 files changed, 33 insertions(+) diff --git a/src/dehacked.c b/src/dehacked.c index 5c2953a55..e71b86774 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -6844,6 +6844,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_NIGHTSEXTRATIME", "MT_NIGHTSLINKFREEZE", "MT_EGGCAPSULE", + "MT_IDEYAANCHOR", "MT_NIGHTOPIANHELPER", // the actual helper object that orbits you "MT_PIAN", // decorative singing friend "MT_SHLEEP", // almost-decorative sleeping enemy diff --git a/src/info.c b/src/info.c index fc30011bf..9a94a697d 100644 --- a/src/info.c +++ b/src/info.c @@ -16638,6 +16638,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_IDEYAANCHOR + 1717, // doomednum + S_INVISIBLE, // spawnstate + 0, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 1*FRACUNIT, // radius + 2*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP|MF_NOGRAVITY, // flags + S_NULL // raisestate + }, + { // MT_NIGHTOPIANHELPER -1, // doomednum S_NIGHTOPIANHELPER1, // spawnstate diff --git a/src/info.h b/src/info.h index a386b199a..77ac06f7f 100644 --- a/src/info.h +++ b/src/info.h @@ -4217,6 +4217,7 @@ typedef enum mobj_type MT_NIGHTSEXTRATIME, MT_NIGHTSLINKFREEZE, MT_EGGCAPSULE, + MT_IDEYAANCHOR, MT_NIGHTOPIANHELPER, // the actual helper object that orbits you MT_PIAN, // decorative singing friend MT_SHLEEP, // almost-decorative sleeping enemy diff --git a/src/p_mobj.c b/src/p_mobj.c index 5292ef15e..235779770 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -10678,6 +10678,10 @@ ML_EFFECT4 : Don't clip inside the ground mobj->health = mthing->angle & 255; mobj->threshold = mthing->angle >> 8; break; + case MT_IDEYAANCHOR: + if (mthing->angle >= 0) + mobj->health = mthing->angle; + break; case MT_NIGHTSDRONE: { boolean flip = mthing->options & MTF_OBJECTFLIP; From 67ee9d082d5abffcbceffede847af7979d241028 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Mon, 13 Aug 2018 02:09:00 -0400 Subject: [PATCH 39/80] A_OrbitNights: Move `donotrescale` to bit 19 * For compat with `nights-ideyaspawn` --- src/p_enemy.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index 06223eb7a..7a2baccfd 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -8544,14 +8544,15 @@ void A_ToggleFlameJet(mobj_t* actor) // var1 = Angle adjustment (aka orbit speed) // var2: // Lower 16 bits: height offset -// Bits 17-20: set if object is Nightopian Helper -// Bits 21-24: set to not sync scale to player +// Bit 17: set if object is Nightopian Helper +// Bit 18: Unused +// Bit 19: set to not sync scale to player // void A_OrbitNights(mobj_t* actor) { INT32 ofs = (var2 & 0xFFFF); - boolean ishelper = (var2 & 0xF0000); - boolean donotrescale = (var2 & 0xF00000); + boolean ishelper = (var2 & 0x10000); + boolean donotrescale = (var2 & 0x40000); #ifdef HAVE_BLUA if (LUA_CallAction("A_OrbitNights", actor)) return; From 54cb7ddf329deed8ba12c26d6e6a8e1b19a29727 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Mon, 13 Aug 2018 02:17:07 -0400 Subject: [PATCH 40/80] Anchor Ideya logic # Conflicts: # src/p_enemy.c # src/p_inter.c --- src/p_enemy.c | 35 ++++++++++++++++++++++++++++------- src/p_inter.c | 43 ++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 68 insertions(+), 10 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index 7a2baccfd..c80b73c74 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -8543,21 +8543,42 @@ void A_ToggleFlameJet(mobj_t* actor) // // var1 = Angle adjustment (aka orbit speed) // var2: -// Lower 16 bits: height offset +// Bits 1-10: height offset, max 1023 +// Bits 11-16: X radius factor (max 63, default 20) // Bit 17: set if object is Nightopian Helper -// Bit 18: Unused -// Bit 19: set to not sync scale to player +// Bit 18: set to define X/Y/Z rotation factor +// Bits 19-20: Unused +// Bits 21-26: Y radius factor (max 63, default 32) +// Bits 27-32: Z radius factor (max 63, default 32) // +// If MF_GRENADEBOUNCE is flagged on mobj, use actor->threshold to define X/Y/Z radius factor, max 1023 each: +// Bits 1-10: X factor +// Bits 11-20: Y factor +// Bits 21-30: Z factor void A_OrbitNights(mobj_t* actor) { - INT32 ofs = (var2 & 0xFFFF); + INT32 ofs = (var2 & 0x3FF); boolean ishelper = (var2 & 0x10000); boolean donotrescale = (var2 & 0x40000); + INT32 xfactor = 32, yfactor = 32, zfactor = 20; #ifdef HAVE_BLUA if (LUA_CallAction("A_OrbitNights", actor)) return; #endif + if (actor->flags & MF_GRENADEBOUNCE) + { + xfactor = (actor->threshold & 0x3FF); + yfactor = (actor->threshold & 0xFFC00) >> 10; + zfactor = (actor->threshold & 0x3FF00000) >> 20; + } + else if (var2 & 0x20000) + { + xfactor = (var2 & 0xFC00) >> 10; + yfactor = (var2 & 0x3F00000) >> 20; + zfactor = (var2 & 0xFC000000) >> 26; + } + if (!actor->target || (actor->target->player && // if NiGHTS special stage and not NiGHTSmode. @@ -8576,9 +8597,9 @@ void A_OrbitNights(mobj_t* actor) const angle_t fa = (angle_t)actor->extravalue1 >> ANGLETOFINESHIFT; const angle_t ofa = ((angle_t)actor->extravalue1 + (ofs*ANG1)) >> ANGLETOFINESHIFT; - const fixed_t fc = FixedMul(FINECOSINE(fa),FixedMul(32*FRACUNIT, actor->scale)); - const fixed_t fh = FixedMul(FINECOSINE(ofa),FixedMul(20*FRACUNIT, actor->scale)); - const fixed_t fs = FixedMul(FINESINE(fa),FixedMul(32*FRACUNIT, actor->scale)); + const fixed_t fc = FixedMul(FINECOSINE(fa),FixedMul(xfactor*FRACUNIT, actor->scale)); + const fixed_t fh = FixedMul(FINECOSINE(ofa),FixedMul(zfactor*FRACUNIT, actor->scale)); + const fixed_t fs = FixedMul(FINESINE(fa),FixedMul(yfactor*FRACUNIT, actor->scale)); actor->x = actor->target->x + fc; actor->y = actor->target->y + fs; diff --git a/src/p_inter.c b/src/p_inter.c index 66c6bd852..b6cf5cf36 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -797,14 +797,47 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) P_NightserizePlayer(player, special->health); // Transform! if (!spec) { - if (toucher->tracer) // Move the ideya over to the drone! + if (toucher->tracer) // Move the ideya! { mobj_t *orbittarget = special->target ? special->target : special; - mobj_t *hnext = orbittarget->hnext; + mobj_t *hnext = orbittarget->hnext, *anchorpoint = NULL; + + if (toucher->tracer->type == MT_GOTEMERALD + && toucher->tracer->state-states >= S_ORBIDYA1 + && toucher->tracer->state-states <= S_ORBIDYA5) + { + mobj_t *mo2; + thinker_t *th; + UINT16 ideyanum = (toucher->tracer->state-states) - mobjinfo[MT_GOTEMERALD].missilestate; + + // scan the thinkers to find the corresponding anchorpoint + for (th = thinkercap.next; th != &thinkercap; th = th->next) + { + if (th->function.acp1 != (actionf_p1)P_MobjThinker) + continue; + + mo2 = (mobj_t *)th; + + if (mo2->type == MT_IDEYAANCHOR) + { + if(mo2->health == ideyanum) + { + anchorpoint = mo2; + break; + } + } + } + + if (anchorpoint) + { + toucher->tracer->flags |= MF_GRENADEBOUNCE; // custom radius factors + toucher->tracer->threshold = 8 << 20; // X factor 0, Y factor 0, Z factor 8 + } + } P_SetTarget(&orbittarget->hnext, toucher->tracer); P_SetTarget(&orbittarget->hnext->hnext, hnext); // Buffalo buffalo Buffalo buffalo buffalo buffalo Buffalo buffalo. - P_SetTarget(&orbittarget->hnext->target, orbittarget); // goalpost + P_SetTarget(&orbittarget->hnext->target, anchorpoint ? anchorpoint : orbittarget); // goalpost P_SetTarget(&toucher->tracer, NULL); if (hnext) @@ -818,7 +851,11 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) { mobj_t *hnext = special->target ? special->target : special; // goalpost while ((hnext = hnext->hnext)) + { + hnext->flags &= ~MF_GRENADEBOUNCE; + hnext->threshold = 0; P_SetTarget(&hnext->target, toucher); + } } return; } From 06bbafec2fbc035df9c20466139aedd714a055bc Mon Sep 17 00:00:00 2001 From: mazmazz Date: Mon, 13 Aug 2018 02:17:29 -0400 Subject: [PATCH 41/80] Ideya anchoring optimization --- src/p_inter.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index b6cf5cf36..9639ff078 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -797,7 +797,17 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) P_NightserizePlayer(player, special->health); // Transform! if (!spec) { - if (toucher->tracer) // Move the ideya! + if (player->exiting) // Move existing Ideyas back to player + { + mobj_t *hnext = special->target ? special->target : special; // goalpost + while ((hnext = hnext->hnext)) + { + hnext->flags &= ~MF_GRENADEBOUNCE; + hnext->threshold = 0; + P_SetTarget(&hnext->target, toucher); + } + } + else if (toucher->tracer) // Move the Ideya to an anchor! { mobj_t *orbittarget = special->target ? special->target : special; mobj_t *hnext = orbittarget->hnext, *anchorpoint = NULL; @@ -847,16 +857,6 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) orbittarget->hnext->extravalue1 -= (72*ANG1)/orbittarget->hnext->extravalue1; } } - if (player->exiting) // ...then move it back? - { - mobj_t *hnext = special->target ? special->target : special; // goalpost - while ((hnext = hnext->hnext)) - { - hnext->flags &= ~MF_GRENADEBOUNCE; - hnext->threshold = 0; - P_SetTarget(&hnext->target, toucher); - } - } return; } From bec3a6884c24a52a6f51633fdfa246ed08b2d985 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Mon, 13 Aug 2018 02:19:53 -0400 Subject: [PATCH 42/80] Make anchoring non-specific to Ideya states (now anchor anything!) # Conflicts: # src/p_inter.c --- src/p_inter.c | 42 ++++++++++++++++++------------------------ src/p_mobj.c | 1 + src/p_user.c | 2 ++ 3 files changed, 21 insertions(+), 24 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index 9639ff078..2b00a7987 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -811,38 +811,32 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) { mobj_t *orbittarget = special->target ? special->target : special; mobj_t *hnext = orbittarget->hnext, *anchorpoint = NULL; + mobj_t *mo2; + thinker_t *th; + UINT16 ideyanum = toucher->tracer->health; - if (toucher->tracer->type == MT_GOTEMERALD - && toucher->tracer->state-states >= S_ORBIDYA1 - && toucher->tracer->state-states <= S_ORBIDYA5) + // scan the thinkers to find the corresponding anchorpoint + for (th = thinkercap.next; th != &thinkercap; th = th->next) { - mobj_t *mo2; - thinker_t *th; - UINT16 ideyanum = (toucher->tracer->state-states) - mobjinfo[MT_GOTEMERALD].missilestate; + if (th->function.acp1 != (actionf_p1)P_MobjThinker) + continue; - // scan the thinkers to find the corresponding anchorpoint - for (th = thinkercap.next; th != &thinkercap; th = th->next) + mo2 = (mobj_t *)th; + + if (mo2->type == MT_IDEYAANCHOR) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) - continue; - - mo2 = (mobj_t *)th; - - if (mo2->type == MT_IDEYAANCHOR) + if(mo2->health == ideyanum) { - if(mo2->health == ideyanum) - { - anchorpoint = mo2; - break; - } + anchorpoint = mo2; + break; } } + } - if (anchorpoint) - { - toucher->tracer->flags |= MF_GRENADEBOUNCE; // custom radius factors - toucher->tracer->threshold = 8 << 20; // X factor 0, Y factor 0, Z factor 8 - } + if (anchorpoint) + { + toucher->tracer->flags |= MF_GRENADEBOUNCE; // custom radius factors + toucher->tracer->threshold = 8 << 20; // X factor 0, Y factor 0, Z factor 8 } P_SetTarget(&orbittarget->hnext, toucher->tracer); diff --git a/src/p_mobj.c b/src/p_mobj.c index 235779770..5b142cc6e 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9610,6 +9610,7 @@ void P_SpawnPlayer(INT32 playernum) if (p == players) // this is totally the wrong place to do this aaargh. { mobj_t *idya = P_SpawnMobjFromMobj(mobj, 0, 0, mobj->height, MT_GOTEMERALD); + idya->health = 0; // for identification P_SetTarget(&idya->target, mobj); P_SetMobjState(idya, mobjinfo[MT_GOTEMERALD].missilestate); P_SetTarget(&mobj->tracer, idya); diff --git a/src/p_user.c b/src/p_user.c index 8c50b5095..27e26e2c2 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -6055,6 +6055,7 @@ static void P_DoNiGHTSCapsule(player_t *player) UINT8 em = P_GetNextEmerald(); // Only give it to ONE person, and THAT player has to get to the goal! mobj_t *emmo = P_SpawnMobjFromMobj(player->mo, 0, 0, player->mo->height, MT_GOTEMERALD); + emmo->health = em; // for identification P_SetTarget(&emmo->target, player->mo); P_SetMobjState(emmo, mobjinfo[MT_GOTEMERALD].meleestate + em); P_SetTarget(&player->mo->tracer, emmo); @@ -6081,6 +6082,7 @@ static void P_DoNiGHTSCapsule(player_t *player) }*/ mobj_t *idya = P_SpawnMobjFromMobj(player->mo, 0, 0, player->mo->height, MT_GOTEMERALD); idya->extravalue2 = player->mare/5; + idya->health = player->mare + 1; // for identification P_SetTarget(&idya->target, player->mo); P_SetMobjState(idya, mobjinfo[MT_GOTEMERALD].missilestate + ((player->mare + 1) % 5)); P_SetTarget(&player->mo->tracer, idya); From 9f67ee1a891e9515616aa7962609fb5102553135 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Mon, 13 Aug 2018 03:18:23 -0400 Subject: [PATCH 43/80] MT_IDEYAANCHOR: Use type 1714 instead of 1717 --- src/info.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/info.c b/src/info.c index 9a94a697d..55d56eb5d 100644 --- a/src/info.c +++ b/src/info.c @@ -16639,7 +16639,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = }, { // MT_IDEYAANCHOR - 1717, // doomednum + 1714, // doomednum S_INVISIBLE, // spawnstate 0, // spawnhealth S_NULL, // seestate From 1bc5976534a7b104fcbffefec2cb70f2ab30f4e8 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Mon, 13 Aug 2018 04:49:32 -0400 Subject: [PATCH 44/80] Correct hitboxradius value; proper sparkle->z when moving x/y --- src/p_mobj.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 5292ef15e..2a3e8cc84 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7951,7 +7951,7 @@ void P_MobjThinker(mobj_t *mobj) if (goalpost->x != mobj->x || goalpost->y != mobj->y) { P_TeleportMove(goalpost, mobj->x, mobj->y, goalpost->z); - P_TeleportMove(sparkle, mobj->x, mobj->y, goalpost->z); + P_TeleportMove(sparkle, mobj->x, mobj->y, sparkle->z); } if (droneman->x != mobj->x || droneman->y != mobj->y) @@ -10686,7 +10686,7 @@ ML_EFFECT4 : Don't clip inside the ground boolean bottomoffsetted = !(mthing->options & MTF_OBJECTSPECIAL) && !(mthing->options & MTF_EXTRA); INT16 timelimit = mthing->angle & 0xFFF; - fixed_t hitboxradius = (mthing->angle & 0xF000) * 32 * FRACUNIT; + fixed_t hitboxradius = ((mthing->angle & 0xF000) >> 12) * 32 * FRACUNIT; fixed_t hitboxheight = mthing->extrainfo * 32 * FRACUNIT; fixed_t oldheight = mobj->height; fixed_t dronemanoffset, goaloffset, sparkleoffset, droneboxmandiff, dronemangoaldiff; From 6585ca3df3943ab93c110de583ae9f72dc40db71 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Mon, 13 Aug 2018 09:50:50 -0400 Subject: [PATCH 45/80] Make Drone visual elements react to height change --- src/p_mobj.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 2a3e8cc84..c7efd9081 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7880,6 +7880,7 @@ void P_MobjThinker(mobj_t *mobj) if (goalpost->destscale != mobj->destscale || goalpost->movefactor != mobj->z + || goalpost->friction != mobj->height || flipchanged || goalpost->threshold != (mobj->flags & (MF_SLIDEME | MF_GRENADEBOUNCE))) { @@ -7939,10 +7940,11 @@ void P_MobjThinker(mobj_t *mobj) P_TeleportMove(goalpost, mobj->x, mobj->y, mobj->z + goaloffset); P_TeleportMove(sparkle, mobj->x, mobj->y, mobj->z + sparkleoffset); - if (goalpost->movefactor != mobj->z) + if (goalpost->movefactor != mobj->z || goalpost->friction != mobj->height) { P_TeleportMove(droneman, mobj->x, mobj->y, mobj->z + dronemanoffset); goalpost->movefactor = mobj->z; + goalpost->friction = mobj->height; } goalpost->threshold = mobj->flags & (MF_SLIDEME | MF_GRENADEBOUNCE); } @@ -10790,6 +10792,7 @@ ML_EFFECT4 : Don't clip inside the ground // Remember old Z position and flags for correction detection goalpost->movefactor = mobj->z; + goalpost->friction = mobj->height; goalpost->threshold = mobj->flags & (MF_SLIDEME | MF_GRENADEBOUNCE); } break; From 1921cc485ebf8911a933a3da2a3495fc0aacfae0 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Tue, 14 Aug 2018 14:18:18 -0400 Subject: [PATCH 46/80] Fix issue where player cannot destroy the NiGHTS Capsule if they have not transformed to NiGHTS --- src/p_inter.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index ce8bba6b6..2f66949b6 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -958,8 +958,8 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (player->powers[pw_carry] == CR_NIGHTSMODE && !toucher->target) return; - if (toucher->tracer) - return; // Don't have multiple ideya + if (toucher->tracer && toucher->tracer->state-states > S_ORBIDYA1) + return; // Don't have multiple ideya, unless it's the first one given if (player->mare != special->threshold) // wrong mare return; From e3facccb9d624c4d390eddca99cc7e258676f852 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Tue, 14 Aug 2018 14:49:11 -0400 Subject: [PATCH 47/80] Ideya fixes when a player has more than one Ideya --- src/p_inter.c | 11 ++++++++--- src/p_mobj.c | 1 + src/p_user.c | 10 ++++++++++ 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index 2f66949b6..c5af9cb0b 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -799,10 +799,15 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (toucher->tracer) // Move the ideya over to the drone! { mobj_t *hnext = special->hnext; + P_SetTarget(&special->hnext, toucher->tracer); - P_SetTarget(&special->hnext->hnext, hnext); // Buffalo buffalo Buffalo buffalo buffalo buffalo Buffalo buffalo. + if (!special->hnext->hnext) + P_SetTarget(&special->hnext->hnext, hnext); // Buffalo buffalo Buffalo buffalo buffalo buffalo Buffalo buffalo. + else + P_SetTarget(&special->hnext->hnext->target, special); P_SetTarget(&special->hnext->target, special); P_SetTarget(&toucher->tracer, NULL); + if (hnext) { special->hnext->extravalue1 = (angle_t)(hnext->extravalue1 - 72*ANG1); @@ -958,8 +963,8 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (player->powers[pw_carry] == CR_NIGHTSMODE && !toucher->target) return; - if (toucher->tracer && toucher->tracer->state-states > S_ORBIDYA1) - return; // Don't have multiple ideya, unless it's the first one given + if (toucher->tracer && toucher->tracer->health > 0) + return; // Don't have multiple ideya, unless it's the first one given (health = 0) if (player->mare != special->threshold) // wrong mare return; diff --git a/src/p_mobj.c b/src/p_mobj.c index 4353e67c3..f8cc87db8 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9445,6 +9445,7 @@ void P_SpawnPlayer(INT32 playernum) if (p == players) // this is totally the wrong place to do this aaargh. { mobj_t *idya = P_SpawnMobjFromMobj(mobj, 0, 0, mobj->height, MT_GOTEMERALD); + idya->health = 0; // for identification P_SetTarget(&idya->target, mobj); P_SetMobjState(idya, mobjinfo[MT_GOTEMERALD].missilestate); P_SetTarget(&mobj->tracer, idya); diff --git a/src/p_user.c b/src/p_user.c index fd09b0847..991d10fea 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -6045,6 +6045,7 @@ static void P_DoNiGHTSCapsule(player_t *player) UINT8 em = P_GetNextEmerald(); // Only give it to ONE person, and THAT player has to get to the goal! mobj_t *emmo = P_SpawnMobjFromMobj(player->mo, 0, 0, player->mo->height, MT_GOTEMERALD); + emmo->health = em; // for identification P_SetTarget(&emmo->target, player->mo); P_SetMobjState(emmo, mobjinfo[MT_GOTEMERALD].meleestate + em); P_SetTarget(&player->mo->tracer, emmo); @@ -6071,8 +6072,17 @@ static void P_DoNiGHTSCapsule(player_t *player) }*/ mobj_t *idya = P_SpawnMobjFromMobj(player->mo, 0, 0, player->mo->height, MT_GOTEMERALD); idya->extravalue2 = player->mare/5; + idya->health = player->mare + 1; // for identification P_SetTarget(&idya->target, player->mo); P_SetMobjState(idya, mobjinfo[MT_GOTEMERALD].missilestate + ((player->mare + 1) % 5)); + + if (player->mo->tracer) + { + P_SetTarget(&idya->hnext, player->mo->tracer); + idya->extravalue1 = (angle_t)(player->mo->tracer->extravalue1 - 72*ANG1); + if (idya->extravalue1 > player->mo->tracer->extravalue1) + idya->extravalue1 -= (72*ANG1)/idya->extravalue1; + } P_SetTarget(&player->mo->tracer, idya); } for (i = 0; i < MAXPLAYERS; i++) From 0862aece9ff4f4e99d9726ea77c0a3153bd5da76 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Tue, 14 Aug 2018 17:21:49 -0400 Subject: [PATCH 48/80] Ideya fixes when a player has more than one Ideya # Conflicts: # src/p_inter.c --- src/p_inter.c | 11 +++++++---- src/p_mobj.c | 1 + src/p_user.c | 10 ++++++++++ 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index 66c6bd852..6378762ea 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -803,8 +803,11 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) mobj_t *hnext = orbittarget->hnext; P_SetTarget(&orbittarget->hnext, toucher->tracer); - P_SetTarget(&orbittarget->hnext->hnext, hnext); // Buffalo buffalo Buffalo buffalo buffalo buffalo Buffalo buffalo. - P_SetTarget(&orbittarget->hnext->target, orbittarget); // goalpost + if (!orbittarget->hnext->hnext) + P_SetTarget(&orbittarget->hnext->hnext, hnext); // Buffalo buffalo Buffalo buffalo buffalo buffalo Buffalo buffalo. + else + P_SetTarget(&orbittarget->hnext->hnext->target, orbittarget); + P_SetTarget(&orbittarget->hnext->target, orbittarget); P_SetTarget(&toucher->tracer, NULL); if (hnext) @@ -962,8 +965,8 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (player->powers[pw_carry] == CR_NIGHTSMODE && !toucher->target) return; - if (toucher->tracer) - return; // Don't have multiple ideya + if (toucher->tracer && toucher->tracer->health > 0) + return; // Don't have multiple ideya, unless it's the first one given (health = 0) if (player->mare != special->threshold) // wrong mare return; diff --git a/src/p_mobj.c b/src/p_mobj.c index c7efd9081..19c140d40 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9612,6 +9612,7 @@ void P_SpawnPlayer(INT32 playernum) if (p == players) // this is totally the wrong place to do this aaargh. { mobj_t *idya = P_SpawnMobjFromMobj(mobj, 0, 0, mobj->height, MT_GOTEMERALD); + idya->health = 0; // for identification P_SetTarget(&idya->target, mobj); P_SetMobjState(idya, mobjinfo[MT_GOTEMERALD].missilestate); P_SetTarget(&mobj->tracer, idya); diff --git a/src/p_user.c b/src/p_user.c index 8c50b5095..877910f25 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -6055,6 +6055,7 @@ static void P_DoNiGHTSCapsule(player_t *player) UINT8 em = P_GetNextEmerald(); // Only give it to ONE person, and THAT player has to get to the goal! mobj_t *emmo = P_SpawnMobjFromMobj(player->mo, 0, 0, player->mo->height, MT_GOTEMERALD); + emmo->health = em; // for identification P_SetTarget(&emmo->target, player->mo); P_SetMobjState(emmo, mobjinfo[MT_GOTEMERALD].meleestate + em); P_SetTarget(&player->mo->tracer, emmo); @@ -6081,8 +6082,17 @@ static void P_DoNiGHTSCapsule(player_t *player) }*/ mobj_t *idya = P_SpawnMobjFromMobj(player->mo, 0, 0, player->mo->height, MT_GOTEMERALD); idya->extravalue2 = player->mare/5; + idya->health = player->mare + 1; // for identification P_SetTarget(&idya->target, player->mo); P_SetMobjState(idya, mobjinfo[MT_GOTEMERALD].missilestate + ((player->mare + 1) % 5)); + + if (player->mo->tracer) + { + P_SetTarget(&idya->hnext, player->mo->tracer); + idya->extravalue1 = (angle_t)(player->mo->tracer->extravalue1 - 72*ANG1); + if (idya->extravalue1 > player->mo->tracer->extravalue1) + idya->extravalue1 -= (72*ANG1)/idya->extravalue1; + } P_SetTarget(&player->mo->tracer, idya); } for (i = 0; i < MAXPLAYERS; i++) From 655b590c069f84f3e48ea75b5397b54aaa1829fe Mon Sep 17 00:00:00 2001 From: mazmazz Date: Tue, 14 Aug 2018 17:28:51 -0400 Subject: [PATCH 49/80] Ideya fixes when a player has more than one Ideya # Conflicts: # src/p_inter.c # Conflicts: # src/p_inter.c --- src/p_inter.c | 11 +++++++---- src/p_user.c | 8 ++++++++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index 2b00a7987..a1dbdf9b9 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -840,8 +840,11 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) } P_SetTarget(&orbittarget->hnext, toucher->tracer); - P_SetTarget(&orbittarget->hnext->hnext, hnext); // Buffalo buffalo Buffalo buffalo buffalo buffalo Buffalo buffalo. - P_SetTarget(&orbittarget->hnext->target, anchorpoint ? anchorpoint : orbittarget); // goalpost + if (!orbittarget->hnext->hnext) + P_SetTarget(&orbittarget->hnext->hnext, hnext); // Buffalo buffalo Buffalo buffalo buffalo buffalo Buffalo buffalo. + else + P_SetTarget(&orbittarget->hnext->hnext->target, anchorpoint ? anchorpoint : orbittarget); + P_SetTarget(&orbittarget->hnext->target, anchorpoint ? anchorpoint : orbittarget); P_SetTarget(&toucher->tracer, NULL); if (hnext) @@ -993,8 +996,8 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (player->powers[pw_carry] == CR_NIGHTSMODE && !toucher->target) return; - if (toucher->tracer) - return; // Don't have multiple ideya + if (toucher->tracer && toucher->tracer->health > 0) + return; // Don't have multiple ideya, unless it's the first one given (health = 0) if (player->mare != special->threshold) // wrong mare return; diff --git a/src/p_user.c b/src/p_user.c index 27e26e2c2..877910f25 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -6085,6 +6085,14 @@ static void P_DoNiGHTSCapsule(player_t *player) idya->health = player->mare + 1; // for identification P_SetTarget(&idya->target, player->mo); P_SetMobjState(idya, mobjinfo[MT_GOTEMERALD].missilestate + ((player->mare + 1) % 5)); + + if (player->mo->tracer) + { + P_SetTarget(&idya->hnext, player->mo->tracer); + idya->extravalue1 = (angle_t)(player->mo->tracer->extravalue1 - 72*ANG1); + if (idya->extravalue1 > player->mo->tracer->extravalue1) + idya->extravalue1 -= (72*ANG1)/idya->extravalue1; + } P_SetTarget(&player->mo->tracer, idya); } for (i = 0; i < MAXPLAYERS; i++) From ac79f6975c58664e73d7d5f2bae32879b3539c0a Mon Sep 17 00:00:00 2001 From: mazmazz Date: Tue, 14 Aug 2018 17:48:14 -0400 Subject: [PATCH 50/80] Look for two anchorpoints if player has two Ideyas * Undid "optimization" of checking player->exiting first because the last Ideya's orbit won't be adjusted --- src/p_inter.c | 44 +++++++++++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index a1dbdf9b9..7e6dee859 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -797,24 +797,15 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) P_NightserizePlayer(player, special->health); // Transform! if (!spec) { - if (player->exiting) // Move existing Ideyas back to player - { - mobj_t *hnext = special->target ? special->target : special; // goalpost - while ((hnext = hnext->hnext)) - { - hnext->flags &= ~MF_GRENADEBOUNCE; - hnext->threshold = 0; - P_SetTarget(&hnext->target, toucher); - } - } - else if (toucher->tracer) // Move the Ideya to an anchor! + if (toucher->tracer) // Move the Ideya to an anchor! { mobj_t *orbittarget = special->target ? special->target : special; - mobj_t *hnext = orbittarget->hnext, *anchorpoint = NULL; + mobj_t *hnext = orbittarget->hnext, *anchorpoint = NULL, *anchorpoint2 = NULL; mobj_t *mo2; thinker_t *th; - UINT16 ideyanum = toucher->tracer->health; + // The player might have two Ideyas: toucher->tracer and toucher->tracer->hnext + // so handle their anchorpoints accordingly. // scan the thinkers to find the corresponding anchorpoint for (th = thinkercap.next; th != &thinkercap; th = th->next) { @@ -825,11 +816,14 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (mo2->type == MT_IDEYAANCHOR) { - if(mo2->health == ideyanum) - { + if (mo2->health == toucher->tracer->health) // do ideya numberes match? anchorpoint = mo2; + else if (toucher->tracer->hnext && mo2->health == toucher->tracer->hnext->health) + anchorpoint2 = mo2; + + if ((!toucher->tracer->hnext && anchorpoint) + || (toucher->tracer->hnext && anchorpoint && anchorpoint2)) break; - } } } @@ -839,11 +833,17 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) toucher->tracer->threshold = 8 << 20; // X factor 0, Y factor 0, Z factor 8 } + if (anchorpoint2) + { + toucher->tracer->hnext->flags |= MF_GRENADEBOUNCE; // custom radius factors + toucher->tracer->hnext->threshold = 8 << 20; // X factor 0, Y factor 0, Z factor 8 + } + P_SetTarget(&orbittarget->hnext, toucher->tracer); if (!orbittarget->hnext->hnext) P_SetTarget(&orbittarget->hnext->hnext, hnext); // Buffalo buffalo Buffalo buffalo buffalo buffalo Buffalo buffalo. else - P_SetTarget(&orbittarget->hnext->hnext->target, anchorpoint ? anchorpoint : orbittarget); + P_SetTarget(&orbittarget->hnext->hnext->target, anchorpoint2 ? anchorpoint2 : orbittarget); P_SetTarget(&orbittarget->hnext->target, anchorpoint ? anchorpoint : orbittarget); P_SetTarget(&toucher->tracer, NULL); @@ -854,6 +854,16 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) orbittarget->hnext->extravalue1 -= (72*ANG1)/orbittarget->hnext->extravalue1; } } + if (player->exiting) // ...then move it back? + { + mobj_t *hnext = special->target ? special->target : special; // goalpost + while ((hnext = hnext->hnext)) + { + hnext->flags &= ~MF_GRENADEBOUNCE; + hnext->threshold = 0; + P_SetTarget(&hnext->target, toucher); + } + } return; } From 9faace9e5d7bc6c41859e28b102ad32b711eafea Mon Sep 17 00:00:00 2001 From: mazmazz Date: Tue, 14 Aug 2018 19:17:34 -0400 Subject: [PATCH 51/80] capsule->extravalue2 tic timer --- src/p_mobj.c | 3 ++- src/p_user.c | 6 ++++-- 2 files changed, 6 insertions(+), 3 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 fd09b0847..a89deaa9e 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -5927,6 +5927,8 @@ static void P_DoNiGHTSCapsule(player_t *player) { INT32 i; + player->capsule->extravalue2++; + if (abs(player->mo->x-player->capsule->x) <= 2*FRACUNIT) { P_UnsetThingPosition(player->mo); @@ -6011,7 +6013,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) @@ -6088,7 +6090,7 @@ 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 From 56d8f47aaa5aa600a391ae4ef40e55a8dd26398d Mon Sep 17 00:00:00 2001 From: mazmazz Date: Tue, 14 Aug 2018 19:39:25 -0400 Subject: [PATCH 52/80] Nights capsule faster attract timing --- src/p_user.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index a89deaa9e..35274f7a9 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -5929,7 +5929,7 @@ static void P_DoNiGHTSCapsule(player_t *player) player->capsule->extravalue2++; - if (abs(player->mo->x-player->capsule->x) <= 2*FRACUNIT) + if (abs(player->mo->x-player->capsule->x) <= 3*FRACUNIT) { P_UnsetThingPosition(player->mo); player->mo->x = player->capsule->x; @@ -5937,7 +5937,7 @@ static void P_DoNiGHTSCapsule(player_t *player) player->mo->momx = 0; } - if (abs(player->mo->y-player->capsule->y) <= 2*FRACUNIT) + if (abs(player->mo->y-player->capsule->y) <= 3*FRACUNIT) { P_UnsetThingPosition(player->mo); player->mo->y = player->capsule->y; @@ -5952,19 +5952,19 @@ static void P_DoNiGHTSCapsule(player_t *player) } if (player->mo->x > player->capsule->x) - player->mo->momx = -2*FRACUNIT; + player->mo->momx = -3*FRACUNIT; else if (player->mo->x < player->capsule->x) - player->mo->momx = 2*FRACUNIT; + player->mo->momx = 3*FRACUNIT; if (player->mo->y > player->capsule->y) - player->mo->momy = -2*FRACUNIT; + player->mo->momy = -3*FRACUNIT; else if (player->mo->y < player->capsule->y) - player->mo->momy = 2*FRACUNIT; + player->mo->momy = 3*FRACUNIT; if (player->mo->z > player->capsule->z+(player->capsule->height/3)) - player->mo->momz = -2*FRACUNIT; + player->mo->momz = -3*FRACUNIT; else if (player->mo->z < player->capsule->z+(player->capsule->height/3)) - player->mo->momz = 2*FRACUNIT; + player->mo->momz = 3*FRACUNIT; if (player->powers[pw_carry] == CR_NIGHTSMODE) { From 7cdce4324b05a891259fd5c11afc82a795825333 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Tue, 14 Aug 2018 20:10:32 -0400 Subject: [PATCH 53/80] Attempt 1: Guesstimate sphere pop rate and use that as the Capsule handling duration --- src/p_mobj.c | 7 +++++-- src/p_user.c | 28 +++++++++++++++++++++++----- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index b88692d76..08b705de9 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8751,8 +8751,11 @@ 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; // 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 + 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 + mobj->lastlook = -1; + mobj->cusval = -1; + mobj->movecount = -1; break; case MT_REDTEAMRING: mobj->color = skincolor_redteam; diff --git a/src/p_user.c b/src/p_user.c index 35274f7a9..a6cefd85e 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -5995,14 +5995,32 @@ static void P_DoNiGHTSCapsule(player_t *player) && player->mo->y == player->capsule->y && player->mo->z == player->capsule->z+(player->capsule->height/3)) { + if (player->capsule->lastlook < 0) + { + INT32 popduration = max(60 - player->capsule->extravalue2, 1); + INT32 spherecount = min(player->spheres, player->capsule->health); + player->capsule->lastlook = max(FixedRound(FixedDiv(spherecount, popduration))/FRACUNIT, 1); + player->capsule->cusval = max(FixedFloor(FixedDiv(popduration, spherecount))/FRACUNIT, 1); + player->capsule->movecount = player->capsule->extravalue2; + } + if (player->spheres > 0) { - player->spheres--; - player->capsule->health--; - player->capsule->extravalue1++; + if (!((player->capsule->extravalue2 - player->capsule->movecount) % player->capsule->cusval)) + { + player->spheres -= player->capsule->lastlook; + player->capsule->health -= player->capsule->lastlook; + player->capsule->extravalue1 += player->capsule->lastlook; + } + + if (player->spheres < 0) + player->spheres = 0; + + if (player->capsule->health < 0) + player->capsule->health = 0; // Spawn a 'pop' for every 5 rings you deposit - if (!(player->capsule->extravalue1 % 5)) + if (!((player->capsule->extravalue2 - player->capsule->movecount) % 5)) S_StartSound(P_SpawnMobj(player->capsule->x + ((P_SignedRandom()/2)<capsule->y + ((P_SignedRandom()/2)<capsule->z + (player->capsule->height/2) + ((P_SignedRandom()/2)<texttimer = 4*TICRATE; player->textvar = 3; // Get more rings! player->capsule->reactiontime = 0; - player->capsule->extravalue1 = player->capsule->extravalue2 = -1; + player->capsule->extravalue1 = player->capsule->extravalue2 = player->capsule->lastlook = player->capsule->cusval = player->capsule->movecount = -1; } } else From 11075717449c5ca32634a848ea117899836a2020 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Wed, 15 Aug 2018 00:48:13 -0400 Subject: [PATCH 54/80] Checkpoint: Force Egg Capsule time at 60 tics --- src/p_user.c | 42 ++++++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index a6cefd85e..8a9d82c6c 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -5999,39 +5999,45 @@ static void P_DoNiGHTSCapsule(player_t *player) { INT32 popduration = max(60 - player->capsule->extravalue2, 1); INT32 spherecount = min(player->spheres, player->capsule->health); + player->capsule->extravalue1 = player->capsule->health - spherecount; player->capsule->lastlook = max(FixedRound(FixedDiv(spherecount, popduration))/FRACUNIT, 1); player->capsule->cusval = max(FixedFloor(FixedDiv(popduration, spherecount))/FRACUNIT, 1); player->capsule->movecount = player->capsule->extravalue2; } - if (player->spheres > 0) + if (player->capsule->extravalue2 - player->capsule->movecount < 60) { - if (!((player->capsule->extravalue2 - player->capsule->movecount) % player->capsule->cusval)) + if (!((player->capsule->extravalue2 - player->capsule->movecount) % player->capsule->cusval) + && player->capsule->health > player->capsule->extravalue1) { player->spheres -= player->capsule->lastlook; player->capsule->health -= player->capsule->lastlook; - player->capsule->extravalue1 += player->capsule->lastlook; + + if (player->spheres < 0) + player->spheres = 0; + + if (player->capsule->health < player->capsule->extravalue1) + player->capsule->health = player->capsule->extravalue1; } - if (player->spheres < 0) - player->spheres = 0; - - if (player->capsule->health < 0) - player->capsule->health = 0; - // Spawn a 'pop' for every 5 rings you deposit if (!((player->capsule->extravalue2 - player->capsule->movecount) % 5)) S_StartSound(P_SpawnMobj(player->capsule->x + ((P_SignedRandom()/2)<capsule->y + ((P_SignedRandom()/2)<capsule->z + (player->capsule->height/2) + ((P_SignedRandom()/2)<capsule->health > player->capsule->extravalue1) + player->capsule->health = player->capsule->extravalue1; if (player->capsule->health <= 0) { player->capsule->flags &= ~MF_NOGRAVITY; player->capsule->momz = 5*FRACUNIT; player->capsule->reactiontime = 0; - player->capsule->extravalue1 = player->capsule->extravalue2 = -1; + player->capsule->extravalue2 = -1; for (i = 0; i < MAXPLAYERS; i++) if (playeringame[i] && !player->exiting && players[i].mare == player->mare) @@ -6101,14 +6107,14 @@ static void P_DoNiGHTSCapsule(player_t *player) S_StartScreamSound(player->mo, sfx_ngdone); P_SwitchSpheresBonusMode(true); } - } - else - { - S_StartScreamSound(player->mo, sfx_lose); - player->texttimer = 4*TICRATE; - player->textvar = 3; // Get more rings! - player->capsule->reactiontime = 0; - player->capsule->extravalue1 = player->capsule->extravalue2 = player->capsule->lastlook = player->capsule->cusval = player->capsule->movecount = -1; + else + { + S_StartScreamSound(player->mo, sfx_lose); + player->texttimer = 4*TICRATE; + player->textvar = 3; // Get more rings! + player->capsule->reactiontime = 0; + player->capsule->extravalue1 = player->capsule->extravalue2 = player->capsule->lastlook = player->capsule->cusval = player->capsule->movecount = -1; + } } } else From 52e451aad58b1464bf1a3d4bd98809e81c2696a9 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Wed, 15 Aug 2018 12:22:46 -0400 Subject: [PATCH 55/80] Counter fix --- src/p_user.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index 56c0848de..87f32ccdb 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -6003,9 +6003,10 @@ static void P_DoNiGHTSCapsule(player_t *player) player->capsule->lastlook = max(FixedRound(FixedDiv(spherecount, popduration))/FRACUNIT, 1); player->capsule->cusval = max(FixedFloor(FixedDiv(popduration, spherecount))/FRACUNIT, 1); player->capsule->movecount = player->capsule->extravalue2; + player->capsule->cvmem = popduration; } - if (player->capsule->extravalue2 - player->capsule->movecount < 60) + if (player->capsule->extravalue2 - player->capsule->movecount < player->capsule->cvmem) { if (!((player->capsule->extravalue2 - player->capsule->movecount) % player->capsule->cusval) && player->capsule->health > player->capsule->extravalue1) From 59f71e4c48d5faa4fa8c5baf41b91aca7fedfac9 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Wed, 15 Aug 2018 12:29:06 -0400 Subject: [PATCH 56/80] Make camera further if on-foot and destroying the Egg Capsule --- src/p_user.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index 87f32ccdb..4219630ef 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -8927,7 +8927,8 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall // sets ideal cam pos if (twodlevel || (mo->flags2 & MF2_TWOD)) dist = 480<powers[pw_carry] == CR_NIGHTSMODE) + else if (player->powers[pw_carry] == CR_NIGHTSMODE + || ((maptol & TOL_NIGHTS) && player->capsule && player->capsule->reactiontime > 0 && player == &players[player->capsule->reactiontime-1])) dist = 320< Date: Wed, 15 Aug 2018 13:38:15 -0400 Subject: [PATCH 57/80] Fixed capsule timing logic * Force a total time, stretch out sphere deduction within that time * Make it more readable --- src/p_mobj.c | 9 ++++---- src/p_user.c | 63 ++++++++++++++++++++++++++++++++-------------------- 2 files changed, 43 insertions(+), 29 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index b5cb5de83..3a2498c07 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8751,11 +8751,10 @@ 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; // 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 - mobj->lastlook = -1; - mobj->cusval = -1; - mobj->movecount = -1; + mobj->reactiontime = 0; + mobj->extravalue1 = mobj->cvmem =\ + mobj->cusval = mobj->movecount =\ + mobj->lastlook = mobj->extravalue2 = -1; break; case MT_REDTEAMRING: mobj->color = skincolor_redteam; diff --git a/src/p_user.c b/src/p_user.c index 4219630ef..11d1681ba 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -5925,9 +5925,8 @@ static void P_NightsTransferPoints(player_t *player, fixed_t xspeed, fixed_t rad // static void P_DoNiGHTSCapsule(player_t *player) { - INT32 i; - - player->capsule->extravalue2++; + INT32 i, spherecount, totalduration, popduration, deductinterval, deductquantity, sphereresult, firstpoptic; + INT32 tictimer = ++player->capsule->extravalue2; if (abs(player->mo->x-player->capsule->x) <= 3*FRACUNIT) { @@ -5997,32 +5996,46 @@ static void P_DoNiGHTSCapsule(player_t *player) { if (player->capsule->lastlook < 0) { - INT32 popduration = max(60 - player->capsule->extravalue2, 1); - INT32 spherecount = min(player->spheres, player->capsule->health); - player->capsule->extravalue1 = player->capsule->health - spherecount; - player->capsule->lastlook = max(FixedRound(FixedDiv(spherecount, popduration))/FRACUNIT, 1); - player->capsule->cusval = max(FixedFloor(FixedDiv(popduration, spherecount))/FRACUNIT, 1); - player->capsule->movecount = player->capsule->extravalue2; - player->capsule->cvmem = popduration; + // Stretch the sphere deduction across the capsule time! + // 1. Force the remaining capsule time to `popduration` + // 2. Given `popduration` and `spherecount`, at what tic interval do we deduct spheres? `deductinterval` + // 3. And on each deduction, how many spheres do we deduct? `deductquantity` + // 4. Store the expected capsule health upon completion: `sphereresult` + spherecount = min(player->spheres, player->capsule->health); + totalduration = min(40 + spherecount, 60); + + popduration = player->capsule->extravalue1 = max(totalduration - tictimer, 1); + deductinterval = player->capsule->cvmem = max(FixedFloor(FixedDiv(popduration, spherecount))/FRACUNIT, 1); + deductquantity = player->capsule->cusval = max(FixedRound(FixedDiv(spherecount, popduration))/FRACUNIT, 1); + sphereresult = player->capsule->movecount = player->capsule->health - spherecount; + firstpoptic = player->capsule->lastlook = tictimer; + } + else + { + popduration = player->capsule->extravalue1; + deductinterval = player->capsule->cvmem; + deductquantity = player->capsule->cusval; + sphereresult = player->capsule->movecount; + firstpoptic = player->capsule->lastlook; } - if (player->capsule->extravalue2 - player->capsule->movecount < player->capsule->cvmem) + if (tictimer - firstpoptic < popduration) { - if (!((player->capsule->extravalue2 - player->capsule->movecount) % player->capsule->cusval) - && player->capsule->health > player->capsule->extravalue1) + if (!((tictimer - firstpoptic) % deductinterval) + && player->capsule->health > sphereresult) { - player->spheres -= player->capsule->lastlook; - player->capsule->health -= player->capsule->lastlook; + player->spheres -= deductquantity; + player->capsule->health -= deductquantity; if (player->spheres < 0) player->spheres = 0; - if (player->capsule->health < player->capsule->extravalue1) - player->capsule->health = player->capsule->extravalue1; + if (player->capsule->health < sphereresult) + player->capsule->health = sphereresult; } - // Spawn a 'pop' for every 5 rings you deposit - if (!((player->capsule->extravalue2 - player->capsule->movecount) % 5)) + // Spawn a 'pop' for every 5 tics + if (!((tictimer - firstpoptic) % 5)) S_StartSound(P_SpawnMobj(player->capsule->x + ((P_SignedRandom()/2)<capsule->y + ((P_SignedRandom()/2)<capsule->z + (player->capsule->height/2) + ((P_SignedRandom()/2)<capsule->health > player->capsule->extravalue1) - player->capsule->health = player->capsule->extravalue1; + if (player->capsule->health > sphereresult) + player->capsule->health = sphereresult; if (player->capsule->health <= 0) { player->capsule->flags &= ~MF_NOGRAVITY; player->capsule->momz = 5*FRACUNIT; player->capsule->reactiontime = 0; - player->capsule->extravalue2 = -1; + tictimer = -1; for (i = 0; i < MAXPLAYERS; i++) if (playeringame[i] && !player->exiting && players[i].mare == player->mare) @@ -6124,12 +6137,14 @@ static void P_DoNiGHTSCapsule(player_t *player) player->texttimer = 4*TICRATE; player->textvar = 3; // Get more rings! player->capsule->reactiontime = 0; - player->capsule->extravalue1 = player->capsule->extravalue2 = player->capsule->lastlook = player->capsule->cusval = player->capsule->movecount = -1; + player->capsule->extravalue1 = player->capsule->cvmem =\ + player->capsule->cusval = player->capsule->movecount =\ + player->capsule->lastlook = player->capsule->extravalue2 = -1; } } } else - player->capsule->extravalue1 = -1; + player->capsule->lastlook = -1; } // From ae0b7c9be8123b44f15084b8469f93864713a14e Mon Sep 17 00:00:00 2001 From: mazmazz Date: Wed, 15 Aug 2018 13:49:03 -0400 Subject: [PATCH 58/80] Fix issue where capsule immediately re-triggers if player gains rings during destruct --- src/p_user.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/p_user.c b/src/p_user.c index 11d1681ba..98b35ab4c 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -6046,6 +6046,10 @@ static void P_DoNiGHTSCapsule(player_t *player) if (player->capsule->health > sphereresult) player->capsule->health = sphereresult; + // did player somehow get more spheres? deduct that too + if (player->spheres > 0) + player->capsule->health -= player->spheres; + if (player->capsule->health <= 0) { player->capsule->flags &= ~MF_NOGRAVITY; From 45612f9add00eff05c54532fbddfef0432a5663c Mon Sep 17 00:00:00 2001 From: mazmazz Date: Wed, 15 Aug 2018 13:59:27 -0400 Subject: [PATCH 59/80] Recalc capsule timing when leaving the capsule during destruct sequence (somehow) * Would be nice to have more sophisticated behavior, e.g., resume the old timing; or drop out the capsule entirely. But how often is this case really going to happen? --- src/p_user.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 98b35ab4c..7d002561a 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -6147,8 +6147,10 @@ static void P_DoNiGHTSCapsule(player_t *player) } } } - else - player->capsule->lastlook = -1; + else if (player->capsule->lastlook > -1) + // We somehow moved out of the capsule (OBJECTPLACE?) + // So recalculate all the timings + player->capsule->lastlook = player->capsule->extravalue2 = -1; } // From c3cb08d7124222196ce004a016851765a266a520 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Wed, 15 Aug 2018 14:40:25 -0400 Subject: [PATCH 60/80] Reconcile spheres at end of destruct if you somehow gained or lost an unexpected # after timing calculations --- src/p_user.c | 36 +++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 7d002561a..8c5c253c5 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -5925,7 +5925,7 @@ static void P_NightsTransferPoints(player_t *player, fixed_t xspeed, fixed_t rad // static void P_DoNiGHTSCapsule(player_t *player) { - INT32 i, spherecount, totalduration, popduration, deductinterval, deductquantity, sphereresult, firstpoptic; + INT32 i, spherecount, totalduration, popduration, deductinterval, deductquantity, sphereresult, firstpoptic, startingspheres; INT32 tictimer = ++player->capsule->extravalue2; if (abs(player->mo->x-player->capsule->x) <= 3*FRACUNIT) @@ -6021,11 +6021,17 @@ static void P_DoNiGHTSCapsule(player_t *player) if (tictimer - firstpoptic < popduration) { - if (!((tictimer - firstpoptic) % deductinterval) - && player->capsule->health > sphereresult) + if (!((tictimer - firstpoptic) % deductinterval)) { - player->spheres -= deductquantity; - player->capsule->health -= deductquantity; + // Did you somehow get more spheres during destruct? + if (player->capsule->health <= sphereresult && player->spheres > 0 && player->capsule->health > 0) + sphereresult = max(sphereresult - player->spheres, 0); + + if (player->capsule->health > sphereresult && player->spheres > 0) + { + player->spheres -= deductquantity; + player->capsule->health -= deductquantity; + } if (player->spheres < 0) player->spheres = 0; @@ -6043,12 +6049,20 @@ static void P_DoNiGHTSCapsule(player_t *player) } else { - if (player->capsule->health > sphereresult) - player->capsule->health = sphereresult; - - // did player somehow get more spheres? deduct that too - if (player->spheres > 0) - player->capsule->health -= player->spheres; + if (player->spheres != 0 && player->capsule->health > 0) + { + if (player->spheres < player->capsule->health) + { + player->capsule->health -= player->spheres; + player->spheres = 0; + } + else + { + startingspheres = player->spheres - player->capsule->health; + player->capsule->health = 0; + player->spheres = startingspheres; + } + } if (player->capsule->health <= 0) { From 81dade0cc42bd6424a563ea3fad6633b65feee6d Mon Sep 17 00:00:00 2001 From: mazmazz Date: Wed, 15 Aug 2018 23:11:32 -0400 Subject: [PATCH 61/80] Force non-nights player into rolling animation when destructing capsule --- src/p_user.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/p_user.c b/src/p_user.c index 8c5c253c5..7d6c4d36b 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -5978,6 +5978,13 @@ static void P_DoNiGHTSCapsule(player_t *player) P_SetPlayerMobjState(player->mo, S_PLAY_NIGHTS_ATTACK); } } + else + { + if (!(player->pflags & PF_JUMPED) && !(player->pflags & PF_SPINNING)) + player->pflags |= PF_JUMPED; + if (player->panim != PA_ROLL) + P_SetPlayerMobjState(player->mo, S_PLAY_ROLL); + } if (G_IsSpecialStage(gamemap)) { // In special stages, share rings. Everyone gives up theirs to the capsule player always, because we can't have any individualism here! From d01ca9fe95320707d69dfb357e49448e6ed42d8a Mon Sep 17 00:00:00 2001 From: mazmazz Date: Thu, 16 Aug 2018 11:25:35 -0400 Subject: [PATCH 62/80] Make Ideya Anchor use parameter # instead of angle for Ideya ID --- src/p_mobj.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index d29603cbd..bd10b4591 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -10682,8 +10682,7 @@ ML_EFFECT4 : Don't clip inside the ground mobj->threshold = mthing->angle >> 8; break; case MT_IDEYAANCHOR: - if (mthing->angle >= 0) - mobj->health = mthing->angle; + mobj->health = mthing->extrainfo; break; case MT_NIGHTSDRONE: { From 73a66d22dfceb789acd589cb1177a83dd5c5deab Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 28 Aug 2018 20:57:43 +0100 Subject: [PATCH 63/80] At toaster's suggestion, have 2p control whether closed captioning is moved up if the powerup display is 1st person only --- src/screen.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/screen.c b/src/screen.c index afeffbdaa..8fc554cc8 100644 --- a/src/screen.c +++ b/src/screen.c @@ -451,8 +451,11 @@ void SCR_ClosedCaptions(void) basey -= 8; else if ((modeattacking == ATTACKING_NIGHTS) || (!(maptol & TOL_NIGHTS) - && ((cv_powerupdisplay.value == 2) - || (cv_powerupdisplay.value == 1 && !splitscreen && !camera.chase)))) + && ((cv_powerupdisplay.value == 2) // "Always" + || (cv_powerupdisplay.value == 1 // "First-person only" + && ((!splitscreen && !camera.chase) + || (splitscreen && !camera2.chase)) // in 2p mode, move up only if 2p's powerup display is on + )))) basey -= 16; } From 7db7a739d470291d29e870a68d8fbbc1dcc5109f Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Wed, 29 Aug 2018 21:31:15 +0100 Subject: [PATCH 64/80] Use INFLIVES macro in place of 0x7f for infinite lives check --- src/g_game.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/g_game.c b/src/g_game.c index 74acb7594..d3d8eeb25 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1914,7 +1914,7 @@ void G_Ticker(boolean run) else { // Costs a life to retry ... unless the player in question is dead already. - if (G_GametypeUsesLives() && players[consoleplayer].playerstate == PST_LIVE && players[consoleplayer].lives != 0x7f) + if (G_GametypeUsesLives() && players[consoleplayer].playerstate == PST_LIVE && players[consoleplayer].lives != INFLIVES) players[consoleplayer].lives -= 1; G_DoReborn(consoleplayer); From ceb0abb0814eb3d189e90fa36792eb4e4b148ea0 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Wed, 29 Aug 2018 22:07:38 +0100 Subject: [PATCH 65/80] Fix compiler complaints, remove a slipup of mine from when I was dealing with merge conflicts --- src/d_main.c | 2 +- src/m_menu.c | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index c71446398..a2a51d3ff 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -283,7 +283,7 @@ static void D_Display(void) if (rendermode != render_none) { // Fade to black first - if ((wipegamestate != -2) // fades to black on its own timing, always + if ((wipegamestate != (gamestate_t)-2) // fades to black on its own timing, always && wipedefs[wipedefindex] != UINT8_MAX) { F_WipeStartScreen(); diff --git a/src/m_menu.c b/src/m_menu.c index 956748f1c..ce82cb69b 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -4956,9 +4956,6 @@ static void M_DrawAddons(void) return; } - if (addonsresponselimit) - addonsresponselimit--; - if (Playing()) topstr = "\x85""Adding files mid-game may cause problems."; else if (savemoddata) From 4083ee9df748fe4268882ab9a54be85ca89f4cae Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 30 Aug 2018 20:08:17 +0100 Subject: [PATCH 66/80] Apparently I am blind and missed that splitscreen only CC offset that overrides the code for the other offset below --- src/screen.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/screen.c b/src/screen.c index 8fc554cc8..20b7134a1 100644 --- a/src/screen.c +++ b/src/screen.c @@ -452,10 +452,7 @@ void SCR_ClosedCaptions(void) else if ((modeattacking == ATTACKING_NIGHTS) || (!(maptol & TOL_NIGHTS) && ((cv_powerupdisplay.value == 2) // "Always" - || (cv_powerupdisplay.value == 1 // "First-person only" - && ((!splitscreen && !camera.chase) - || (splitscreen && !camera2.chase)) // in 2p mode, move up only if 2p's powerup display is on - )))) + || (cv_powerupdisplay.value == 1 && !camera.chase)))) // "First-person only" basey -= 16; } From c0ffbdafce4100d7e8fd8560bc8821b2e1d44b6c Mon Sep 17 00:00:00 2001 From: mazmazz Date: Fri, 7 Sep 2018 08:56:53 -0400 Subject: [PATCH 67/80] Revert "Ideya fixes when a player has more than one Ideya" This reverts commit e3facccb9d624c4d390eddca99cc7e258676f852. --- src/p_inter.c | 11 +++-------- src/p_mobj.c | 1 - src/p_user.c | 10 ---------- 3 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index 135dfa2e8..4c9bba896 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -799,15 +799,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (toucher->tracer) // Move the ideya over to the drone! { mobj_t *hnext = special->hnext; - P_SetTarget(&special->hnext, toucher->tracer); - if (!special->hnext->hnext) - P_SetTarget(&special->hnext->hnext, hnext); // Buffalo buffalo Buffalo buffalo buffalo buffalo Buffalo buffalo. - else - P_SetTarget(&special->hnext->hnext->target, special); + P_SetTarget(&special->hnext->hnext, hnext); // Buffalo buffalo Buffalo buffalo buffalo buffalo Buffalo buffalo. P_SetTarget(&special->hnext->target, special); P_SetTarget(&toucher->tracer, NULL); - if (hnext) { special->hnext->extravalue1 = (angle_t)(hnext->extravalue1 - 72*ANG1); @@ -966,8 +961,8 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (player->powers[pw_carry] == CR_NIGHTSMODE && !toucher->target) return; - if (toucher->tracer && toucher->tracer->health > 0) - return; // Don't have multiple ideya, unless it's the first one given (health = 0) + if (toucher->tracer && toucher->tracer->state-states > S_ORBIDYA1) + return; // Don't have multiple ideya, unless it's the first one given if (player->mare != special->threshold) // wrong mare return; diff --git a/src/p_mobj.c b/src/p_mobj.c index fb354e79b..6aec4bdd6 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9500,7 +9500,6 @@ void P_SpawnPlayer(INT32 playernum) if (p == players) // this is totally the wrong place to do this aaargh. { mobj_t *idya = P_SpawnMobjFromMobj(mobj, 0, 0, mobj->height, MT_GOTEMERALD); - idya->health = 0; // for identification P_SetTarget(&idya->target, mobj); P_SetMobjState(idya, mobjinfo[MT_GOTEMERALD].missilestate); P_SetTarget(&mobj->tracer, idya); diff --git a/src/p_user.c b/src/p_user.c index f471d567c..921bd95d9 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -6143,7 +6143,6 @@ static void P_DoNiGHTSCapsule(player_t *player) UINT8 em = P_GetNextEmerald(); // Only give it to ONE person, and THAT player has to get to the goal! mobj_t *emmo = P_SpawnMobjFromMobj(player->mo, 0, 0, player->mo->height, MT_GOTEMERALD); - emmo->health = em; // for identification P_SetTarget(&emmo->target, player->mo); P_SetMobjState(emmo, mobjinfo[MT_GOTEMERALD].meleestate + em); P_SetTarget(&player->mo->tracer, emmo); @@ -6170,17 +6169,8 @@ static void P_DoNiGHTSCapsule(player_t *player) }*/ mobj_t *idya = P_SpawnMobjFromMobj(player->mo, 0, 0, player->mo->height, MT_GOTEMERALD); idya->extravalue2 = player->mare/5; - idya->health = player->mare + 1; // for identification P_SetTarget(&idya->target, player->mo); P_SetMobjState(idya, mobjinfo[MT_GOTEMERALD].missilestate + ((player->mare + 1) % 5)); - - if (player->mo->tracer) - { - P_SetTarget(&idya->hnext, player->mo->tracer); - idya->extravalue1 = (angle_t)(player->mo->tracer->extravalue1 - 72*ANG1); - if (idya->extravalue1 > player->mo->tracer->extravalue1) - idya->extravalue1 -= (72*ANG1)/idya->extravalue1; - } P_SetTarget(&player->mo->tracer, idya); } for (i = 0; i < MAXPLAYERS; i++) From 3b39895e4fcc46cfdedee4afa776a5610b6ef677 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Fri, 7 Sep 2018 09:01:38 -0400 Subject: [PATCH 68/80] Stray nights-onfootfix line --- src/p_inter.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index 4c9bba896..9a05bae28 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -961,8 +961,8 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (player->powers[pw_carry] == CR_NIGHTSMODE && !toucher->target) return; - if (toucher->tracer && toucher->tracer->state-states > S_ORBIDYA1) - return; // Don't have multiple ideya, unless it's the first one given + if (toucher->tracer) + return; // Don't have multiple ideya if (player->mare != special->threshold) // wrong mare return; From 7a3eb31b57bf05f749f111031128926bca25e6a5 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sun, 9 Sep 2018 20:51:08 -0400 Subject: [PATCH 69/80] A number --- src/p_user.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index 921bd95d9..5bd76ede6 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -5974,7 +5974,7 @@ static void P_DoNiGHTSCapsule(player_t *player) player->mo->momy = 0; } - if (abs(player->mo->z - (player->capsule->z+(player->capsule->height/3))) <= 2*FRACUNIT) + if (abs(player->mo->z - (player->capsule->z+(player->capsule->height/3))) <= 3*FRACUNIT) { player->mo->z = player->capsule->z+(player->capsule->height/3); player->mo->momz = 0; From 6a6d32e7c2205e31fece4f202c75b3ed7cbd5a43 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sun, 23 Sep 2018 14:17:29 +0100 Subject: [PATCH 70/80] searchfilemenu: Replace first with 0 here as toaster suggested --- src/filesrch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/filesrch.c b/src/filesrch.c index fe3fe240c..c1abccde3 100644 --- a/src/filesrch.c +++ b/src/filesrch.c @@ -596,7 +596,7 @@ void searchfilemenu(char *tempname) if (tempname) { - dir_on[menudepthleft] = first; + dir_on[menudepthleft] = 0; Z_Free(tempname); } } From 0af071dbca8e51a2bd28ae7e3fde5693ef16e858 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Tue, 20 Nov 2018 20:23:48 -0500 Subject: [PATCH 71/80] build errors --- src/p_map.c | 2 +- src/y_inter.c | 11 +++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index 648bb2bcc..b4ace61c7 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -134,7 +134,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) { fixed_t vertispeed = spring->info->mass; fixed_t horizspeed = spring->info->damage; - boolean final; + boolean final = false; // Object was already sprung this tic if (object->eflags & MFE_SPRUNG) diff --git a/src/y_inter.c b/src/y_inter.c index 29e611730..1a1675fdd 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -1909,8 +1909,8 @@ static void Y_AwardCoopBonuses(void) } ptlives = min( - ((!ultimatemode && !modeattacking && players[i].lives != INFLIVES) ? max((players[i].score/50000) - (oldscore/50000), 0) : 0), - (mapheaderinfo[prevmap]->maxbonuslives < 0 ? INT32_MAX : mapheaderinfo[prevmap]->maxbonuslives)); + (INT32)((!ultimatemode && !modeattacking && players[i].lives != INFLIVES) ? max((INT32)((players[i].score/50000) - (oldscore/50000)), (INT32)0) : 0), + (INT32)(mapheaderinfo[prevmap]->maxbonuslives < 0 ? INT32_MAX : mapheaderinfo[prevmap]->maxbonuslives)); if (ptlives) P_GivePlayerLives(&players[i], ptlives); @@ -1955,10 +1955,9 @@ static void Y_AwardSpecialStageBonus(void) // grant extra lives right away since tally is faked ptlives = min( - ((!ultimatemode && !modeattacking && players[i].lives != INFLIVES) ? max((players[i].score/50000) - (oldscore/50000), 0) : 0), - (mapheaderinfo[prevmap]->maxbonuslives < 0 ? INT32_MAX : mapheaderinfo[prevmap]->maxbonuslives)); - if (ptlives) - P_GivePlayerLives(&players[i], ptlives); + (INT32)((!ultimatemode && !modeattacking && players[i].lives != INFLIVES) ? max((INT32)((players[i].score/50000) - (oldscore/50000)), (INT32)0) : 0), + (INT32)(mapheaderinfo[prevmap]->maxbonuslives < 0 ? INT32_MAX : mapheaderinfo[prevmap]->maxbonuslives)); + P_GivePlayerLives(&players[i], ptlives); if (i == consoleplayer) { From ddd357d27c78ffa3102505b46635e676eb2e85ac Mon Sep 17 00:00:00 2001 From: Marco Z Date: Tue, 20 Nov 2018 21:54:20 -0500 Subject: [PATCH 72/80] VC build fixes --- src/hardware/hw_main.c | 2 +- src/m_cheat.c | 2 +- src/p_saveg.c | 2 +- src/st_stuff.c | 9 +++++---- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 2e9e5726a..cb37c39ae 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5731,7 +5731,7 @@ static void HWR_DrawSkyBackground(player_t *player) dimensionmultiply = ((float)textures[texturetranslation[skytexture]]->width/256.0f); - v[0].sow = v[3].sow = ((float) (-angle) / ((ANGLE_90-1)*dimensionmultiply)); // left + v[0].sow = v[3].sow = ((float) (-(float)angle) / ((ANGLE_90-1)*dimensionmultiply)); // left v[2].sow = v[1].sow = v[0].sow + (1.0f/dimensionmultiply); // right (or left + 1.0f) // use +angle and -1.0f above instead if you wanted old backwards behavior diff --git a/src/m_cheat.c b/src/m_cheat.c index 473209350..79a52fe9f 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -571,7 +571,7 @@ void Command_Teleport_f(void) } else // scan the thinkers to find starposts... { - mobj_t *mo2; + mobj_t *mo2 = NULL; thinker_t *th; INT32 starpostmax = 0; diff --git a/src/p_saveg.c b/src/p_saveg.c index 6a07e513f..f0a8757c1 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -486,7 +486,7 @@ static UINT32 num_ffloors = 0; // for loading // But also check for equality and return the matching index static UINT32 CheckAddNetColormapToList(extracolormap_t *extra_colormap) { - extracolormap_t *exc, *exc_prev; + extracolormap_t *exc, *exc_prev = NULL; UINT32 i = 0; if (!net_colormaps) diff --git a/src/st_stuff.c b/src/st_stuff.c index 26d9678a3..4f628b078 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -1509,7 +1509,7 @@ static void ST_drawNiGHTSLink(void) else colornum = linkColor[mag][sel]; - aflag |= ((stplyr->linktimer < nightslinktics/3) + aflag |= ((stplyr->linktimer < (UINT32)nightslinktics/3) ? (9 - 9*stplyr->linktimer/(nightslinktics/3)) << V_ALPHASHIFT : 0); @@ -1613,11 +1613,12 @@ static void ST_drawNiGHTSHUD(void) #endif ST_DrawTopLeftOverlayPatch(16, 8, nbracket); if (G_IsSpecialStage(gamemap)) - ST_DrawTopLeftOverlayPatch(24, 16, ( #ifdef MANIASPHERES - (stplyr->bonustime && (leveltime & 4)) ? nssbon : + ST_DrawTopLeftOverlayPatch(24, 16, ( + (stplyr->bonustime && (leveltime & 4)) ? nssbon : nsshud)); +#else + ST_DrawTopLeftOverlayPatch(24, 16, (nsshud)); #endif - nsshud)); else ST_DrawTopLeftOverlayPatch(24, 16, *(((stplyr->bonustime) ? nbon : nhud)+((leveltime/2)%12))); From 8a9c10e633bae292c14e0f44d6a2e60787596c4a Mon Sep 17 00:00:00 2001 From: mazmazz Date: Tue, 20 Nov 2018 23:43:05 -0500 Subject: [PATCH 73/80] Hardcode Pause/Break key and change Pause default; show prompt in menu about Pause key --- src/g_game.c | 3 ++- src/g_input.c | 2 +- src/m_menu.c | 24 ++++++++++++++++++++++-- 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 95a76b95d..f7e7ae75a 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1800,7 +1800,8 @@ boolean G_Responder(event_t *ev) { case ev_keydown: if (ev->data1 == gamecontrol[gc_pause][0] - || ev->data1 == gamecontrol[gc_pause][1]) + || ev->data1 == gamecontrol[gc_pause][1] + || ev->data1 == KEY_PAUSE) { if (modeattacking && !demoplayback && (gamestate == GS_LEVEL)) { diff --git a/src/g_input.c b/src/g_input.c index 4f7296cd5..e17e359a7 100644 --- a/src/g_input.c +++ b/src/g_input.c @@ -709,7 +709,7 @@ void G_DefineDefaultControls(void) gamecontroldefault[i][gc_teamkey ][0] = 'y'; gamecontroldefault[i][gc_scores ][0] = KEY_TAB; gamecontroldefault[i][gc_console ][0] = KEY_CONSOLE; - gamecontroldefault[i][gc_pause ][0] = KEY_PAUSE; + gamecontroldefault[i][gc_pause ][0] = 'p'; } } diff --git a/src/m_menu.c b/src/m_menu.c index 46a7d94fc..ae868762a 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -9380,6 +9380,7 @@ static void M_DrawControl(void) #undef controlbuffer static INT32 controltochange; +static char controltochangetext[55]; static void M_ChangecontrolResponse(event_t *ev) { @@ -9387,8 +9388,8 @@ static void M_ChangecontrolResponse(event_t *ev) INT32 found; INT32 ch = ev->data1; - // ESCAPE cancels - if (ch != KEY_ESCAPE) + // ESCAPE cancels; dummy out PAUSE + if (ch != KEY_ESCAPE && ch != KEY_PAUSE) { switch (ev->type) @@ -9449,6 +9450,24 @@ static void M_ChangecontrolResponse(event_t *ev) } S_StartSound(NULL, sfx_strpst); } + else if (ch == KEY_PAUSE) + { + static char tmp[155]; + menu_t *prev = currentMenu->prevMenu; + + if (controltochange == gc_pause) + sprintf(tmp, M_GetText("The \x82Pause Key \x80is enabled, but \nit cannot be used to retry runs \nduring Record Attack. \n\nHit another key for\n%s\nESC for Cancel"), + controltochangetext); + else + sprintf(tmp, M_GetText("The \x82Pause Key \x80is enabled, but \nit is not configurable. \n\nHit another key for\n%s\nESC for Cancel"), + controltochangetext); + + M_StartMessage(tmp, M_ChangecontrolResponse, MM_EVENTHANDLER); + currentMenu->prevMenu = prev; + + S_StartSound(NULL, sfx_s3k42); + return; + } else S_StartSound(NULL, sfx_skid); @@ -9465,6 +9484,7 @@ static void M_ChangeControl(INT32 choice) controltochange = currentMenu->menuitems[choice].alphaKey; sprintf(tmp, M_GetText("Hit the new key for\n%s\nESC for Cancel"), currentMenu->menuitems[choice].text); + strncpy(controltochangetext, currentMenu->menuitems[choice].text, 55); M_StartMessage(tmp, M_ChangecontrolResponse, MM_EVENTHANDLER); } From 2acad7ad86a60d57fa9458e34e8824910e9fcc93 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Wed, 21 Nov 2018 11:10:18 -0500 Subject: [PATCH 74/80] Dont show Hold to Retry HUD when using Pause/Break key --- src/g_game.c | 2 ++ src/g_game.h | 1 + src/hu_stuff.c | 2 +- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/g_game.c b/src/g_game.c index f7e7ae75a..79c09f6b1 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1653,6 +1653,7 @@ void G_DoLoadLevel(boolean resetplayer) } INT32 pausedelay = 0; +boolean pausebreakkey = false; static INT32 camtoggledelay, camtoggledelay2 = 0; // @@ -1805,6 +1806,7 @@ boolean G_Responder(event_t *ev) { if (modeattacking && !demoplayback && (gamestate == GS_LEVEL)) { + pausebreakkey = (ev->data1 == KEY_PAUSE); if (menuactive || pausedelay < 0 || leveltime < 2) return true; diff --git a/src/g_game.h b/src/g_game.h index dc0c3619d..1e30831d8 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -54,6 +54,7 @@ extern INT32 gameovertics; extern tic_t timeinmap; // Ticker for time spent in level (used for levelcard display) extern INT16 rw_maximums[NUM_WEAPONS]; extern INT32 pausedelay; +extern boolean pausebreakkey; // used in game menu extern consvar_t cv_tutorialprompt; diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 26e50885a..6e17b939d 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -1132,7 +1132,7 @@ void HU_Drawer(void) V_DrawCenteredString(BASEVIDWIDTH/2, 180, V_YELLOWMAP | V_ALLOWLOWERCASE, resynch_text); } - if (modeattacking && pausedelay > 0) + if (modeattacking && pausedelay > 0 && !pausebreakkey) { INT32 strength = ((pausedelay - 1 - NEWTICRATE/2)*10)/(NEWTICRATE/3); INT32 y = hudinfo[HUD_LIVES].y - 13; From 9bdab67de6b46276f5449eb7866c90fc70177a9e Mon Sep 17 00:00:00 2001 From: mazmazz Date: Wed, 21 Nov 2018 11:21:17 -0500 Subject: [PATCH 75/80] Don't accept KEY_PAUSE for control console command --- src/g_input.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/g_input.c b/src/g_input.c index e17e359a7..2988d7c37 100644 --- a/src/g_input.c +++ b/src/g_input.c @@ -814,6 +814,8 @@ static void setcontrol(INT32 (*gc)[2], INT32 na) return; } keynum = G_KeyStringtoNum(COM_Argv(2)); + if (keynum == KEY_PAUSE) // fail silently; pause is hardcoded + return; G_CheckDoubleUsage(keynum); gc[numctrl][0] = keynum; From 250aab58895bdd5f775c86fa1d3aeff7b5c2565c Mon Sep 17 00:00:00 2001 From: mazmazz Date: Wed, 21 Nov 2018 20:30:26 -0500 Subject: [PATCH 76/80] Missed sign cast --- src/p_mobj.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 16969db59..f3d3de5ec 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7979,7 +7979,7 @@ void P_MobjThinker(mobj_t *mobj) || goalpost->movefactor != mobj->z || goalpost->friction != mobj->height || flipchanged - || goalpost->threshold != (mobj->flags & (MF_SLIDEME | MF_GRENADEBOUNCE))) + || goalpost->threshold != (INT32)(mobj->flags & (MF_SLIDEME | MF_GRENADEBOUNCE))) { goalpost->destscale = sparkle->destscale = droneman->destscale = mobj->destscale; From 40eda0e74911b37c27c0fcc7a8b48888ac0a96f1 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Tue, 14 Aug 2018 20:42:20 -0400 Subject: [PATCH 77/80] Nerf jumping --- src/p_user.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index 12a09a23e..b18b0927e 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -3965,7 +3965,7 @@ void P_DoJump(player_t *player, boolean soundandstate) } } else if (maptol & TOL_NIGHTS) - player->mo->momz = 24*FRACUNIT; + player->mo->momz = 18*FRACUNIT; else if (player->powers[pw_super]) { player->mo->momz = 13*FRACUNIT; @@ -4006,6 +4006,9 @@ void P_DoJump(player_t *player, boolean soundandstate) if (player->charflags & SF_MULTIABILITY && player->charability == CA_DOUBLEJUMP) factor -= max(0, player->secondjump * player->jumpfactor / ((player->actionspd >> FRACBITS) + 1)); // Reduce the jump height each time + if (maptol & TOL_NIGHTS) + factor = player->jumpfactor; // all skins jump the same + P_SetObjectMomZ(player->mo, FixedMul(factor, player->mo->momz), false); // Custom height // set just an eensy above the ground From 6a3b41ea6f0568e5964417f529d873fe3b4b043d Mon Sep 17 00:00:00 2001 From: mazmazz Date: Wed, 21 Nov 2018 21:21:36 -0500 Subject: [PATCH 78/80] Let skins jump their regular strength variances in NiGHTS --- 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 b18b0927e..3a8b09c76 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -4006,8 +4006,8 @@ void P_DoJump(player_t *player, boolean soundandstate) if (player->charflags & SF_MULTIABILITY && player->charability == CA_DOUBLEJUMP) factor -= max(0, player->secondjump * player->jumpfactor / ((player->actionspd >> FRACBITS) + 1)); // Reduce the jump height each time - if (maptol & TOL_NIGHTS) - factor = player->jumpfactor; // all skins jump the same + //if (maptol & TOL_NIGHTS) + // factor = player->jumpfactor; // all skins jump the same. if you nerf jumping abilities, you may want this. P_SetObjectMomZ(player->mo, FixedMul(factor, player->mo->momz), false); // Custom height From dd1ecb04cf7b886069237fb4d294089c769187a7 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Thu, 22 Nov 2018 11:28:32 -0500 Subject: [PATCH 79/80] Change camera control names to Look --- src/m_menu.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index ae868762a..c44d74eb4 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1075,10 +1075,10 @@ static menuitem_t OP_ChangeControlsMenu[] = {IT_CALL | IT_STRING2, NULL, "Spin", M_ChangeControl, gc_use }, {IT_HEADER, NULL, "Camera", NULL, 0}, {IT_SPACE, NULL, NULL, NULL, 0}, // padding - {IT_CALL | IT_STRING2, NULL, "Camera Up", M_ChangeControl, gc_lookup }, - {IT_CALL | IT_STRING2, NULL, "Camera Down", M_ChangeControl, gc_lookdown }, - {IT_CALL | IT_STRING2, NULL, "Camera Left", M_ChangeControl, gc_turnleft }, - {IT_CALL | IT_STRING2, NULL, "Camera Right", M_ChangeControl, gc_turnright }, + {IT_CALL | IT_STRING2, NULL, "Look Up", M_ChangeControl, gc_lookup }, + {IT_CALL | IT_STRING2, NULL, "Look Down", M_ChangeControl, gc_lookdown }, + {IT_CALL | IT_STRING2, NULL, "Look Left", M_ChangeControl, gc_turnleft }, + {IT_CALL | IT_STRING2, NULL, "Look Right", M_ChangeControl, gc_turnright }, {IT_CALL | IT_STRING2, NULL, "Center View", M_ChangeControl, gc_centerview }, {IT_CALL | IT_STRING2, NULL, "Toggle Mouselook", M_ChangeControl, gc_mouseaiming }, {IT_CALL | IT_STRING2, NULL, "Toggle Third-Person", M_ChangeControl, gc_camtoggle}, From 146dd52d240f891d54b552b8b6284d4e991951e2 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Thu, 22 Nov 2018 14:47:01 -0500 Subject: [PATCH 80/80] Smarter pause/break rejection for setcontrol --- src/g_input.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/g_input.c b/src/g_input.c index 2988d7c37..4686f57ce 100644 --- a/src/g_input.c +++ b/src/g_input.c @@ -814,13 +814,31 @@ static void setcontrol(INT32 (*gc)[2], INT32 na) return; } keynum = G_KeyStringtoNum(COM_Argv(2)); + if (keynum == KEY_PAUSE) // fail silently; pause is hardcoded - return; + { + if (na == 4) + { + na--; + keynum = G_KeyStringtoNum(COM_Argv(3)); + if (keynum == KEY_PAUSE) + return; + } + else + return; + } + G_CheckDoubleUsage(keynum); gc[numctrl][0] = keynum; if (na == 4) - gc[numctrl][1] = G_KeyStringtoNum(COM_Argv(3)); + { + keynum = G_KeyStringtoNum(COM_Argv(3)); + if (keynum != KEY_PAUSE) + gc[numctrl][1] = keynum; + else + gc[numctrl][1] = 0; + } else gc[numctrl][1] = 0; }