From d755d6edb9d2ff2e911504732de2bef5fd6f815d Mon Sep 17 00:00:00 2001 From: Lat Date: Tue, 21 Feb 2023 16:16:34 +0100 Subject: [PATCH 01/16] Titlecard CEcho --- src/acs/call-funcs.cpp | 36 ++++++++++++++++++++++++++++++++++++ src/acs/call-funcs.hpp | 2 ++ src/acs/environment.cpp | 7 ++++++- src/g_game.c | 2 ++ src/hu_stuff.c | 41 +++++++++++++++++++++++++++++++++++++++++ src/hu_stuff.h | 4 ++++ src/lua_baselib.c | 14 +++++++++++++- src/p_setup.c | 1 + 8 files changed, 105 insertions(+), 2 deletions(-) diff --git a/src/acs/call-funcs.cpp b/src/acs/call-funcs.cpp index 3e7ca5040..780455f07 100644 --- a/src/acs/call-funcs.cpp +++ b/src/acs/call-funcs.cpp @@ -565,6 +565,25 @@ bool CallFunc_EndPrint(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Wo return false; } +/*-------------------------------------------------- + bool CallFunc_EndPrintTitlecard(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC) + + One of the ACS wrappers for Titlecard CEcho. This + version only prints if the activator is a + display player. +--------------------------------------------------*/ +bool CallFunc_EndPrintTitlecard(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC) +{ + (void)argV; + (void)argC; + + if (ACS_ActivatorIsLocal(thread) == true) + HU_DoTitlecardCEcho(thread->printBuf.data()); + + thread->printBuf.drop(); + return false; +} + /*-------------------------------------------------- bool CallFunc_PlayerCount(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC) @@ -935,6 +954,23 @@ bool CallFunc_EndPrintBold(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM return false; } +/*-------------------------------------------------- + bool CallFunc_EndPrintBoldTitlecard(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC) + + One of the ACS wrappers for Titlecard CEcho. This + version prints for all players. +--------------------------------------------------*/ +bool CallFunc_EndPrintBoldTitlecard(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC) +{ + (void)argV; + (void)argC; + + HU_DoTitlecardCEcho(thread->printBuf.data()); + + thread->printBuf.drop(); + return false; +} + /*-------------------------------------------------- bool CallFunc_PlayerTeam(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC) diff --git a/src/acs/call-funcs.hpp b/src/acs/call-funcs.hpp index 4bbe3eaec..9e634c0d9 100644 --- a/src/acs/call-funcs.hpp +++ b/src/acs/call-funcs.hpp @@ -55,6 +55,7 @@ bool CallFunc_ChangeCeiling(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSV bool CallFunc_LineSide(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC); bool CallFunc_ClearLineSpecial(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC); bool CallFunc_EndPrint(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC); +bool CallFunc_EndPrintTitlecard(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC); bool CallFunc_PlayerCount(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC); bool CallFunc_GameType(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC); bool CallFunc_GameSpeed(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC); @@ -65,6 +66,7 @@ bool CallFunc_SetLineTexture(ACSVM::Thread *thread, const ACSVM::Word *argV, ACS bool CallFunc_SetLineSpecial(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC); bool CallFunc_ThingSound(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC); bool CallFunc_EndPrintBold(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC); +bool CallFunc_EndPrintBoldTitlecard(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC); bool CallFunc_PlayerTeam(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC); bool CallFunc_PlayerRings(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC); bool CallFunc_PlayerScore(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC); diff --git a/src/acs/environment.cpp b/src/acs/environment.cpp index ad593e74b..28078967d 100644 --- a/src/acs/environment.cpp +++ b/src/acs/environment.cpp @@ -100,7 +100,12 @@ Environment::Environment() addCodeDataACS0(120, {"", 0, addCallFunc(CallFunc_PlayerRings)}); addCodeDataACS0(122, {"", 0, addCallFunc(CallFunc_PlayerScore)}); - + + // Lat: Titlecard CEcho. I'm not sure if I should be putting it here. + // @TODO: Confirm this is fine? + addCodeDataACS0( 123, {"", 0, addCallFunc(CallFunc_EndPrintTitlecard)}); + addCodeDataACS0( 124, {"", 0, addCallFunc(CallFunc_EndPrintBoldTitlecard)}); + // 136 to 137: Implemented by ACSVM // 157: Implemented by ACSVM diff --git a/src/g_game.c b/src/g_game.c index ecf088eaf..4ff66a88c 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3145,6 +3145,7 @@ void G_ExitLevel(void) // Remove CEcho text on round end. HU_ClearCEcho(); + HU_ClearTitlecardCEcho(); // Don't save demos immediately here! Let standings write first } @@ -4124,6 +4125,7 @@ void G_AfterIntermission(void) gamecomplete = 1; HU_ClearCEcho(); + HU_ClearTitlecardCEcho(); if (demo.playback) { diff --git a/src/hu_stuff.c b/src/hu_stuff.c index a457fe774..8521049a8 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -161,6 +161,11 @@ static tic_t cechotimer = 0; static tic_t cechoduration = 5*TICRATE; static INT32 cechoflags = 0; +static char tcechotext[48]; // the text is wide so only 48 chars should do. +static tic_t tcechotimer = 0; // goes up by 1 each frame this is active +static tic_t tcechoduration = 0; // Set automatically + + static tic_t resynch_ticker = 0; static huddrawlist_h luahuddrawlist_scores; @@ -1035,6 +1040,13 @@ void HU_Ticker(void) if (cechotimer) cechotimer--; + + if (tcechotimer) + { + tcechotimer++; + if (tcechotimer > tcechoduration) + tcechotimer = 0; + } if (gamestate != GS_LEVEL) { @@ -2000,6 +2012,15 @@ static void HU_DrawCEcho(void) } } +static void HU_DrawTitlecardCEcho(void) +{ + if (tcechotimer) + { + INT32 w = V_TitleCardStringWidth(tcechotext); + V_DrawTitleCardString(160 -w/2, 90, tcechotext, 0, false, tcechotimer, TICRATE*4); + } +} + // // demo info stuff // @@ -2145,6 +2166,9 @@ drawontop: if (cechotimer) HU_DrawCEcho(); + + if (tcechotimer) + HU_DrawTitlecardCEcho(); } //====================================================================== @@ -2598,3 +2622,20 @@ void HU_DoCEcho(const char *msg) cechotext[sizeof(cechotext) - 1] = '\0'; cechotimer = cechoduration; } + +// Simply set the timer to 0 to clear it. +// No need to bother clearing the buffer or anything. +void HU_ClearTitlecardCEcho(void) +{ + tcechotimer = 0; +} + +// Similar but for titlecard CEcho and also way less convoluted because I have no clue whatever the fuck they were trying above. +void HU_DoTitlecardCEcho(const char *msg) +{ + I_OutputMsg("%s\n", msg); // print to log + + strncpy(tcechotext, msg, sizeof(tcechotext)); + tcechotimer = 1; + tcechoduration = TICRATE*6 + strlen(tcechotext); +} \ No newline at end of file diff --git a/src/hu_stuff.h b/src/hu_stuff.h index 3e8233020..144e0e557 100644 --- a/src/hu_stuff.h +++ b/src/hu_stuff.h @@ -153,6 +153,10 @@ void HU_SetCEchoDuration(INT32 seconds); void HU_SetCEchoFlags(INT32 flags); void HU_DoCEcho(const char *msg); +// Titlecard CECHO shite +void HU_DoTitlecardCEcho(const char *msg); +void HU_ClearTitlecardCEcho(void); + // Demo playback info extern UINT32 hu_demotime; extern UINT32 hu_demolap; diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 4dead2615..654dc71d0 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -35,6 +35,7 @@ #include "k_menu.h" // Player Setup menu color stuff #include "p_spec.h" // P_StartQuake #include "i_system.h" // I_GetPreciseTime, I_GetPrecisePrecision +#include "hu_stuff.h" // for the cecho #include "lua_script.h" #include "lua_libs.h" @@ -3879,6 +3880,14 @@ static int lib_getTimeMicros(lua_State *L) return 1; } +static int lib_startTitlecardCecho(lua_State *L) +{ + const char *str = luaL_checkstring(L, 1); + HU_DoTitlecardCEcho(str); + + return 1; +} + static luaL_Reg lib[] = { {"print", lib_print}, {"chatprint", lib_chatprint}, @@ -4160,7 +4169,10 @@ static luaL_Reg lib[] = { {"K_InitBossHealthBar", lib_kInitBossHealthBar}, {"K_UpdateBossHealthBar", lib_kUpdateBossHealthBar}, {"K_DeclareWeakspot", lib_kDeclareWeakspot}, - + + // hu_stuff technically? + {"HU_DoTitlecardCEcho", lib_startTitlecardCecho}, + {NULL, NULL} }; diff --git a/src/p_setup.c b/src/p_setup.c index bedb39c78..ebc3a40cd 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -7515,6 +7515,7 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate) // Clear CECHO messages HU_ClearCEcho(); + HU_ClearTitlecardCEcho(); if (mapheaderinfo[gamemap-1]->runsoc[0] != '#') P_RunSOC(mapheaderinfo[gamemap-1]->runsoc); From 9f1e5d08c248c8016c3f1b9c7405dfc0c32c5b0a Mon Sep 17 00:00:00 2001 From: Lat Date: Tue, 21 Feb 2023 20:56:45 +0100 Subject: [PATCH 02/16] Allow multiple lines in titlecard cecho, overwrite cecho in ACS instead of making a new action --- src/acs/call-funcs.cpp | 41 ---------------------------- src/acs/call-funcs.hpp | 2 -- src/acs/environment.cpp | 5 ---- src/hu_stuff.c | 59 ++++++++++++++++++++++++++++++++++++++--- 4 files changed, 56 insertions(+), 51 deletions(-) diff --git a/src/acs/call-funcs.cpp b/src/acs/call-funcs.cpp index 780455f07..d3039dab9 100644 --- a/src/acs/call-funcs.cpp +++ b/src/acs/call-funcs.cpp @@ -555,28 +555,6 @@ bool CallFunc_EndPrint(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Wo (void)argV; (void)argC; - if (ACS_ActivatorIsLocal(thread) == true) - { - HU_SetCEchoDuration(5); - HU_DoCEcho(thread->printBuf.data()); - } - - thread->printBuf.drop(); - return false; -} - -/*-------------------------------------------------- - bool CallFunc_EndPrintTitlecard(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC) - - One of the ACS wrappers for Titlecard CEcho. This - version only prints if the activator is a - display player. ---------------------------------------------------*/ -bool CallFunc_EndPrintTitlecard(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC) -{ - (void)argV; - (void)argC; - if (ACS_ActivatorIsLocal(thread) == true) HU_DoTitlecardCEcho(thread->printBuf.data()); @@ -947,30 +925,11 @@ bool CallFunc_EndPrintBold(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM (void)argV; (void)argC; - HU_SetCEchoDuration(5); - HU_DoCEcho(thread->printBuf.data()); - - thread->printBuf.drop(); - return false; -} - -/*-------------------------------------------------- - bool CallFunc_EndPrintBoldTitlecard(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC) - - One of the ACS wrappers for Titlecard CEcho. This - version prints for all players. ---------------------------------------------------*/ -bool CallFunc_EndPrintBoldTitlecard(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC) -{ - (void)argV; - (void)argC; - HU_DoTitlecardCEcho(thread->printBuf.data()); thread->printBuf.drop(); return false; } - /*-------------------------------------------------- bool CallFunc_PlayerTeam(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC) diff --git a/src/acs/call-funcs.hpp b/src/acs/call-funcs.hpp index 9e634c0d9..4bbe3eaec 100644 --- a/src/acs/call-funcs.hpp +++ b/src/acs/call-funcs.hpp @@ -55,7 +55,6 @@ bool CallFunc_ChangeCeiling(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSV bool CallFunc_LineSide(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC); bool CallFunc_ClearLineSpecial(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC); bool CallFunc_EndPrint(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC); -bool CallFunc_EndPrintTitlecard(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC); bool CallFunc_PlayerCount(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC); bool CallFunc_GameType(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC); bool CallFunc_GameSpeed(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC); @@ -66,7 +65,6 @@ bool CallFunc_SetLineTexture(ACSVM::Thread *thread, const ACSVM::Word *argV, ACS bool CallFunc_SetLineSpecial(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC); bool CallFunc_ThingSound(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC); bool CallFunc_EndPrintBold(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC); -bool CallFunc_EndPrintBoldTitlecard(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC); bool CallFunc_PlayerTeam(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC); bool CallFunc_PlayerRings(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC); bool CallFunc_PlayerScore(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC); diff --git a/src/acs/environment.cpp b/src/acs/environment.cpp index 28078967d..b3093e3ed 100644 --- a/src/acs/environment.cpp +++ b/src/acs/environment.cpp @@ -101,11 +101,6 @@ Environment::Environment() addCodeDataACS0(122, {"", 0, addCallFunc(CallFunc_PlayerScore)}); - // Lat: Titlecard CEcho. I'm not sure if I should be putting it here. - // @TODO: Confirm this is fine? - addCodeDataACS0( 123, {"", 0, addCallFunc(CallFunc_EndPrintTitlecard)}); - addCodeDataACS0( 124, {"", 0, addCallFunc(CallFunc_EndPrintBoldTitlecard)}); - // 136 to 137: Implemented by ACSVM // 157: Implemented by ACSVM diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 8521049a8..a68f4857b 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -161,7 +161,7 @@ static tic_t cechotimer = 0; static tic_t cechoduration = 5*TICRATE; static INT32 cechoflags = 0; -static char tcechotext[48]; // the text is wide so only 48 chars should do. +static char tcechotext[1024]; // buffer for the titlecard text static tic_t tcechotimer = 0; // goes up by 1 each frame this is active static tic_t tcechoduration = 0; // Set automatically @@ -2016,8 +2016,59 @@ static void HU_DrawTitlecardCEcho(void) { if (tcechotimer) { - INT32 w = V_TitleCardStringWidth(tcechotext); - V_DrawTitleCardString(160 -w/2, 90, tcechotext, 0, false, tcechotimer, TICRATE*4); + INT32 i = 0; + INT32 y = (BASEVIDHEIGHT/2)-16; + INT32 pnumlines = 0; + INT32 timeroffset = 0; + + char *line; + char *echoptr; + char temp[1024]; + + for (i = 0; tcechotext[i] != '\0'; ++i) + if (tcechotext[i] == '\\') + pnumlines++; + + y -= (pnumlines-1)*16; + + // Prevent crashing because I'm sick of this + if (y < 0) + { + CONS_Alert(CONS_WARNING, "CEcho contained too many lines, not displaying\n"); + cechotimer = 0; + return; + } + + strcpy(temp, tcechotext); + echoptr = &temp[0]; + + while (*echoptr != '\0') + { + INT32 w; + INT32 timer = (INT32)(tcechotimer - timeroffset); + + if (timer <= 0) + return; // we don't care. + + line = strchr(echoptr, '\\'); + + if (line == NULL) + break; + + *line = '\0'; + + w = V_TitleCardStringWidth(echoptr); + V_DrawTitleCardString(BASEVIDWIDTH/2 -w/2, y, echoptr, 0, false, timer, TICRATE*4); + + y += 32; + + // offset the timer for the next line. + timeroffset += strlen(echoptr); + + // set the ptr to the \0 we made and advance it because we don't want an empty string. + echoptr = line; + echoptr++; + } } } @@ -2636,6 +2687,8 @@ void HU_DoTitlecardCEcho(const char *msg) I_OutputMsg("%s\n", msg); // print to log strncpy(tcechotext, msg, sizeof(tcechotext)); + strncat(tcechotext, "\\", sizeof(tcechotext) - strlen(tcechotext) - 1); + cechotext[sizeof(tcechotext) - 1] = '\0'; tcechotimer = 1; tcechoduration = TICRATE*6 + strlen(tcechotext); } \ No newline at end of file From 36113f2d475bb2013867965a8cd545d7cddab04f Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 21 Nov 2022 11:38:57 -0800 Subject: [PATCH 03/16] AngleDelta: return angle_t This function can return ANGLE_180, which when cast to a signed integer, is a negative value. --- src/tables.c | 2 +- src/tables.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tables.c b/src/tables.c index 8c4dc50e1..6a7b7645b 100644 --- a/src/tables.c +++ b/src/tables.c @@ -167,7 +167,7 @@ angle_t FixedAngle(fixed_t fa) return AngleAdj(cfa, cwf, ra); } -INT32 AngleDelta(angle_t a1, angle_t a2) +angle_t AngleDelta(angle_t a1, angle_t a2) { angle_t delta = a1 - a2; diff --git a/src/tables.h b/src/tables.h index ac3bfe8a5..f8947ab9e 100644 --- a/src/tables.h +++ b/src/tables.h @@ -110,7 +110,7 @@ FUNCMATH angle_t FixedAngle(fixed_t fa); // and with a factor, with +factor for (fa/factor) and -factor for (fa*factor) FUNCMATH angle_t FixedAngleC(fixed_t fa, fixed_t factor); // difference between two angle_t -FUNCMATH INT32 AngleDelta(angle_t a1, angle_t a2); +FUNCMATH angle_t AngleDelta(angle_t a1, angle_t a2); FUNCMATH INT32 AngleDeltaSigned(angle_t a1, angle_t a2); FUNCMATH float AngleToFloat(angle_t x); FUNCMATH angle_t FloatToAngle(float f); From ff15fc142b2ffad4e1f9033743671c48ca586079 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 21 Nov 2022 11:44:36 -0800 Subject: [PATCH 04/16] Add FSIN/FCOS, shortcuts to FINESINE/FINECOSINE --- src/tables.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/tables.h b/src/tables.h index f8947ab9e..1a1da82d3 100644 --- a/src/tables.h +++ b/src/tables.h @@ -27,7 +27,7 @@ extern "C" { #define FINEANGLES 8192 #define FINEMASK (FINEANGLES - 1) #define ANGLETOFINESHIFT 19 // 0x100000000 to 0x2000 -#define FINEANGLE_C(x) ((FixedAngle((x)*FRACUNIT)>>ANGLETOFINESHIFT) & FINEMASK) // ((x*(ANGLE_45/45))>>ANGLETOFINESHIFT) & FINEMASK +#define ANGLETOFINE(x) (((x)>>ANGLETOFINESHIFT) & FINEMASK) // Effective size is 10240. extern fixed_t finesine[5*FINEANGLES/4]; @@ -136,6 +136,10 @@ void FM_Rotate(matrix_t *dest, angle_t angle, fixed_t x, fixed_t y, fixed_t z); #define FINECOSINE(n) (finecosine[n]>>(FINE_FRACBITS-FRACBITS)) #define FINETANGENT(n) (finetangent[n]>>(FINE_FRACBITS-FRACBITS)) +// FSIN(ANGLE_90) = FRACUNIT +#define FSIN(n) FINESINE(ANGLETOFINE(n)) +#define FCOS(n) FINECOSINE(ANGLETOFINE(n)) + #ifdef __cplusplus } // extern "C" #endif From 290d3fd3e8be55af10e4a13f20adad8441a7a5d0 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 21 Nov 2022 19:06:25 -0800 Subject: [PATCH 05/16] Do not selectively reset mobj interpolation state at the beginning of P_MobjThinker Fixes P_MoveOrigin not interpolating if used before P_MobjThinker, i.e. during player think. These are reset at the start of a tic anyway, before anything else, with R_UpdateMobjInterpolators. --- src/p_mobj.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index d9920a928..5c2a8f724 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9743,14 +9743,6 @@ void P_MobjThinker(mobj_t *mobj) I_Assert(mobj != NULL); I_Assert(!P_MobjWasRemoved(mobj)); - // Set old position (for interpolation) - mobj->old_x = mobj->x; - mobj->old_y = mobj->y; - mobj->old_z = mobj->z; - mobj->old_angle = mobj->angle; - mobj->old_pitch = mobj->pitch; - mobj->old_roll = mobj->roll; - // Remove dead target/tracer. if (mobj->target && P_MobjWasRemoved(mobj->target)) P_SetTarget(&mobj->target, NULL); From 49bb2a377eda5e93da7ac3dd227c363f52854708 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 21 Nov 2022 16:23:32 -0800 Subject: [PATCH 06/16] Add P_SpawnItemLine, spawn a row of mapthings between two points --- src/p_mobj.c | 12 ++++++++++++ src/p_mobj.h | 1 + 2 files changed, 13 insertions(+) diff --git a/src/p_mobj.c b/src/p_mobj.c index 5c2a8f724..b9fa47a36 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -13726,6 +13726,18 @@ void P_SpawnItemPattern(mapthing_t *mthing) } } +void P_SpawnItemLine(mapthing_t *mt1, mapthing_t *mt2) +{ + const mobjtype_t type = P_GetMobjtype(mt1->type); + const fixed_t diameter = 2 * FixedMul(mobjinfo[type].radius, mapobjectscale); + const fixed_t dx = (mt2->x - mt1->x) * FRACUNIT; + const fixed_t dy = (mt2->y - mt1->y) * FRACUNIT; + const fixed_t dist = FixedHypot(dx, dy); + const angle_t angle = R_PointToAngle2(0, 0, dx, dy); + + P_SpawnSingularItemRow(mt1, type, (dist / diameter) + 1, diameter, 0, AngleFixed(angle) / FRACUNIT); +} + // // P_CheckMissileSpawn // Moves the missile forward a bit and possibly explodes it right there. diff --git a/src/p_mobj.h b/src/p_mobj.h index dd448841e..d5dc67a3e 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -530,6 +530,7 @@ fixed_t P_GetMapThingSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* mt mobj_t *P_SpawnMapThing(mapthing_t *mthing); void P_SpawnHoop(mapthing_t *mthing); void P_SpawnItemPattern(mapthing_t *mthing); +void P_SpawnItemLine(mapthing_t *mt1, mapthing_t *mt2); void P_SpawnHoopOfSomething(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32 number, mobjtype_t type, angle_t rotangle); void P_SpawnPrecipitation(void); void P_SpawnParaloop(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32 number, mobjtype_t type, statenum_t nstate, angle_t rotangle, boolean spawncenter); From 37edae71fa57f917144b3eb2a37d642f6013d0f9 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 21 Nov 2022 11:50:55 -0800 Subject: [PATCH 07/16] Clean up some code in p_setup.c --- src/p_setup.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 0c8ddef6b..d49e82348 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -700,10 +700,13 @@ static void P_SpawnMapThings(boolean spawnemblems) for (i = 0, mt = mapthings; i < nummapthings; i++, mt++) { - if (mt->type == 1700 // MT_AXIS - || mt->type == 1701 // MT_AXISTRANSFER - || mt->type == 1702) // MT_AXISTRANSFERLINE - continue; // These were already spawned + switch (mt->type) + { + case 1700: // MT_AXIS + case 1701: // MT_AXISTRANSFER + case 1702: // MT_AXISTRANSFERLINE + continue; // These were already spawned + } if (mt->type == mobjinfo[MT_BATTLECAPSULE].doomednum) continue; // This will spawn later @@ -5952,6 +5955,7 @@ static void P_ConvertBinaryLinedefTypes(void) lines[i].args[1] |= TMBOT_FORCEDIR; lines[i].args[2] = sides[lines[i].sidenum[0]].textureoffset / FRACUNIT; + break; default: break; } From 28b3006efd338e1fdad9ddd0c9afb62c89a18f71 Mon Sep 17 00:00:00 2001 From: toaster Date: Wed, 1 Mar 2023 13:41:25 +0000 Subject: [PATCH 08/16] K_DirectorSwitch: Don't let forced switches cause a G_ResetView update when directorinfo.active is false --- src/k_director.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/k_director.c b/src/k_director.c index b1513672c..dd2f55ad6 100644 --- a/src/k_director.c +++ b/src/k_director.c @@ -110,16 +110,16 @@ static boolean K_CanSwitchDirector(void) return false; } - if (!directorinfo.active) - { - return false; - } - return true; } static void K_DirectorSwitch(INT32 player, boolean force) { + if (!directorinfo.active) + { + return; + } + if (P_IsDisplayPlayer(&players[player])) { return; From 64792f30a2087a63077ac097185e82a903c5dbb9 Mon Sep 17 00:00:00 2001 From: Lat Date: Wed, 1 Mar 2023 15:48:40 +0100 Subject: [PATCH 09/16] Fix using cecho instead of tcecho for 1 line --- src/hu_stuff.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hu_stuff.c b/src/hu_stuff.c index a68f4857b..83d77cb44 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -2688,7 +2688,7 @@ void HU_DoTitlecardCEcho(const char *msg) strncpy(tcechotext, msg, sizeof(tcechotext)); strncat(tcechotext, "\\", sizeof(tcechotext) - strlen(tcechotext) - 1); - cechotext[sizeof(tcechotext) - 1] = '\0'; + tcechotext[sizeof(tcechotext) - 1] = '\0'; tcechotimer = 1; tcechoduration = TICRATE*6 + strlen(tcechotext); } \ No newline at end of file From 739d81f403c2187ebc07e6785f49f0d21976e8af Mon Sep 17 00:00:00 2001 From: toaster Date: Wed, 1 Mar 2023 15:00:35 +0000 Subject: [PATCH 10/16] G_BuildTiccmd: Fix not being able to use item button to toggle PF_WANTSTOJOIN --- src/g_game.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 9dc0b2fc8..be27e7360 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1179,9 +1179,18 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) K_ToggleDirector(false); } - if (M_MenuButtonPressed(forplayer, MBT_R)) + if (player->spectator == true) { - K_ToggleDirector(true); + // duplication of fire + if (G_PlayerInputDown(forplayer, gc_item, 0)) + { + cmd->buttons |= BT_ATTACK; + } + + if (M_MenuButtonPressed(forplayer, MBT_R)) + { + K_ToggleDirector(true); + } } goto aftercmdinput; From 5ef24e1a3ce445136131139c8757818532e60298 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 1 Mar 2023 07:23:56 -0800 Subject: [PATCH 11/16] Fix flashing tics flickering animation for light snake --- src/k_respawn.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/k_respawn.c b/src/k_respawn.c index 0997c2b40..4d3675490 100644 --- a/src/k_respawn.c +++ b/src/k_respawn.c @@ -344,7 +344,10 @@ static void K_MovePlayerToRespawnPoint(player_t *player) player->mo->momx = player->mo->momy = player->mo->momz = 0; - player->flashing = 2; + // 3 because this timer counts down afterward, in + // P_PlayerThink. flashing must be > 1 after it has + // counted down in order to flicker the player sprite. + player->flashing = 3; //player->nocontrol = max(2, player->nocontrol); if (leveltime % 8 == 0 && !mapreset) From 6e5a5bf92d66dde3eeb7462e180934e63a3de00c Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 1 Mar 2023 07:25:14 -0800 Subject: [PATCH 12/16] Apply flashing tics to RESPAWNST_DROP Applies flashing tics to the entire respawn state so you don't become vulnerable once you reach the waypoint. --- src/k_respawn.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/k_respawn.c b/src/k_respawn.c index 4d3675490..cb08408a2 100644 --- a/src/k_respawn.c +++ b/src/k_respawn.c @@ -816,6 +816,7 @@ void K_RespawnChecker(player_t *player) return; case RESPAWNST_DROP: player->mo->momx = player->mo->momy = 0; + player->flashing = 3; if (player->respawn.timer > 0) { player->mo->momz = 0; From 0cd260eed177c0943ed5145d2204173fc969d76a Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 1 Mar 2023 07:25:54 -0800 Subject: [PATCH 13/16] Don't let death type damage kill respawning player This includes death pits and instakill sectors. Does not affect direct P_KillMobj calls. --- src/p_inter.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/p_inter.c b/src/p_inter.c index 6e053a405..09f6349d6 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1911,6 +1911,12 @@ static boolean P_KillPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, { (void)source; + if (player->respawn.state != RESPAWNST_NONE) + { + K_DoInstashield(player); + return false; + } + if (!player->exiting && specialstageinfo.valid == true) { player->pflags |= PF_NOCONTEST; From 93f151fec92767cd0173204ce5403eba86f73165 Mon Sep 17 00:00:00 2001 From: toaster Date: Wed, 1 Mar 2023 15:27:48 +0000 Subject: [PATCH 14/16] Director HUD: Do a bit of cleanup - Add "Join" on L button. - "Becomes ". . .", "Cancel join", and has "[i/n]" appended (where n is cap and i is number of players in game) - Add colorisation when Director is active - Make an attempt at fixing splitscreen (I wasn't able to get director to ACTIVATE in splitscreen with two local clients so it's frustratingly untested) --- src/k_hud.c | 63 +++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 54 insertions(+), 9 deletions(-) diff --git a/src/k_hud.c b/src/k_hud.c index d53a39d95..683040065 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -4639,16 +4639,26 @@ K_drawMiniPing (void) } } -static void K_DrawDirectorButton(INT32 idx, const char *label, patch_t *kp[2]) +static void K_DrawDirectorButton(INT32 idx, const char *label, patch_t *kp[2], INT32 textflags) { - const INT32 flags = V_SNAPTORIGHT | V_SLIDEIN; - const INT32 textflags = flags | V_6WIDTHSPACE | V_ALLOWLOWERCASE; + INT32 flags = V_SNAPTORIGHT | V_SLIDEIN | V_SPLITSCREEN; const UINT8 anim_duration = 16; const UINT8 anim = (leveltime % (anim_duration * 2)) < anim_duration; - const INT32 x = BASEVIDWIDTH - 60; - const INT32 y = BASEVIDHEIGHT - 70 + (idx * 16); + INT32 x = (BASEVIDWIDTH/2) - 10; + INT32 y = (idx * 16); + + if (r_splitscreen <= 1) + { + x = BASEVIDWIDTH - 60; + if (r_splitscreen == 0) + { + y += BASEVIDHEIGHT - 78; + } + } + + textflags |= (flags | V_6WIDTHSPACE | V_ALLOWLOWERCASE); V_DrawScaledPatch(x, y - 4, flags, kp[anim]); V_DrawRightAlignedThinString(x - 2, y, textflags, label); @@ -4656,14 +4666,49 @@ static void K_DrawDirectorButton(INT32 idx, const char *label, patch_t *kp[2]) static void K_drawDirectorHUD(void) { + const INT32 p = (splitscreen_partied[consoleplayer] ? splitscreen_party[consoleplayer] : g_localplayers)[R_GetViewNumber()]; + const char *itemtxt = "Join"; + UINT8 offs = 0; + + UINT8 numingame = 0; + UINT8 i; + if (!LUA_HudEnabled(hud_textspectator)) { return; } - K_DrawDirectorButton(0, "Next Player", kp_button_a[0]); - K_DrawDirectorButton(1, "Prev Player", kp_button_x[0]); - K_DrawDirectorButton(2, "Director", kp_button_r); + for (i = 0; i < MAXPLAYERS; i++) + if (playeringame[i] && !players[i].spectator) + numingame++; + + if (numingame > 1 && r_splitscreen == 0) // simplifies things a lot + { + K_DrawDirectorButton(1, "Next Player", kp_button_a[0], 0); + K_DrawDirectorButton(2, "Prev Player", kp_button_x[0], 0); + offs = 2; + } + else + + if (p == -1 || !playeringame[p] || players[p].spectator == false) + { + return; + } + + K_DrawDirectorButton(offs + 1, "Director", kp_button_r, + (directorinfo.active ? V_YELLOWMAP : 0)); + + if (players[p].flashing) + itemtxt = ". . ."; + else if (players[p].pflags & PF_WANTSTOJOIN) + itemtxt = "Cancel Join"; + + if (cv_maxplayers.value) + { + itemtxt = va("%s [%d/%d]", itemtxt, numingame, cv_maxplayers.value); + } + + K_DrawDirectorButton(0, itemtxt, kp_button_l, 0); } static void K_drawDistributionDebugger(void) @@ -4984,7 +5029,7 @@ void K_drawKartHUD(void) K_drawMiniPing(); } - if (displayplayers[viewnum] != g_localplayers[viewnum]) + if (displayplayers[viewnum] != g_localplayers[viewnum] && !demo.playback) { K_drawDirectorHUD(); } From 393cf6e7f3a8a59b5171211ae332ec6c0d83b22c Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 1 Mar 2023 07:43:23 -0800 Subject: [PATCH 15/16] Don't let the player use the item button until completely finished respawning --- src/k_kart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/k_kart.c b/src/k_kart.c index 5d4c7eb5d..c58ee1d72 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -10099,7 +10099,7 @@ void K_UnsetItemOut(player_t *player) void K_MoveKartPlayer(player_t *player, boolean onground) { ticcmd_t *cmd = &player->cmd; - boolean ATTACK_IS_DOWN = ((cmd->buttons & BT_ATTACK) && !(player->oldcmd.buttons & BT_ATTACK)); + boolean ATTACK_IS_DOWN = ((cmd->buttons & BT_ATTACK) && !(player->oldcmd.buttons & BT_ATTACK) && (player->respawn.state == RESPAWNST_NONE)); boolean HOLDING_ITEM = (player->pflags & (PF_ITEMOUT|PF_EGGMANOUT)); boolean NO_HYUDORO = (player->stealingtimer == 0); From 36afe024c79f759caeb8c72dd571734a39f410fe Mon Sep 17 00:00:00 2001 From: toaster Date: Wed, 1 Mar 2023 16:06:12 +0000 Subject: [PATCH 16/16] Spurious else --- src/k_hud.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/k_hud.c b/src/k_hud.c index 683040065..8fd7607ec 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -4688,7 +4688,6 @@ static void K_drawDirectorHUD(void) K_DrawDirectorButton(2, "Prev Player", kp_button_x[0], 0); offs = 2; } - else if (p == -1 || !playeringame[p] || players[p].spectator == false) {