From c699807532e4ba34819da5c6c7d4a050e5846973 Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 19 Sep 2019 20:29:51 -0700 Subject: [PATCH 01/28] Also apply HUD translucency to FREE PLAY --- 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 10d772ba0..bf938232f 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -8634,7 +8634,7 @@ void K_drawKartFreePlay(UINT32 flashtime) return; V_DrawKartString((BASEVIDWIDTH - (LAPS_X+1)) - (12*9), // mirror the laps thingy - LAPS_Y+3, V_SNAPTOBOTTOM|V_SNAPTORIGHT, "FREE PLAY"); + LAPS_Y+3, V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_HUDTRANS, "FREE PLAY"); } static void K_drawDistributionDebugger(void) From c646d4d8d095954fb50c8b88be9094e79732dd94 Mon Sep 17 00:00:00 2001 From: Sryder Date: Thu, 14 May 2020 13:16:49 +0100 Subject: [PATCH 02/28] Remove now unsupported distros from deployer Add new supported distros to deployer --- .travis.yml | 106 ++++++++++++++++++++++++++-------------------------- 1 file changed, 53 insertions(+), 53 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4959e4d2d..f2693236b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -451,7 +451,31 @@ matrix: - p7zip-full - gcc-4.8 compiler: gcc-4.8 - dist: xenial + dist: focal + if: env(DPL_ENABLED) = "1" AND (env(_DPL_JOB_ENABLED) = "1" OR env(DPL_JOB_ENABLE_ALL) = "1") + AND (branch =~ /^.*deployer.*$/ OR (tag IS present AND env(DPL_TAG_ENABLED) = "1")) + AND env(DPL_TERMINATE_MAIN) != "1" + env: + - _DPL_JOB_ENABLED=1 + - _DPL_JOB_NAME=focal + - _DPL_DPUT_TARGET=1 + - _DPL_PACKAGE_SOURCE=1 + - PACKAGE_DISTRO=focal + - PACKAGE_SUBVERSION=~20.04focal + #gcc-4.8 (Ubuntu 4.8.5-2ubuntu1~14.04.1) 4.8.5 + - os: linux + addons: + apt: + packages: + - libsdl2-mixer-dev + - libpng-dev + - libgl1-mesa-dev + - libgme-dev + - libcurl4-openssl-dev + - p7zip-full + - gcc-4.8 + compiler: gcc-4.8 + dist: bionic if: env(DPL_ENABLED) = "1" AND (env(_DPL_JOB_ENABLED) = "1" OR env(DPL_JOB_ENABLE_ALL) = "1") AND (branch =~ /^.*deployer.*$/ OR (tag IS present AND env(DPL_TAG_ENABLED) = "1")) AND env(DPL_TERMINATE_MAIN) != "1" @@ -463,6 +487,30 @@ matrix: - PACKAGE_DISTRO=bionic - PACKAGE_SUBVERSION=~18.04bionic #gcc-4.8 (Ubuntu 4.8.5-2ubuntu1~14.04.1) 4.8.5 + - os: linux + addons: + apt: + packages: + - libsdl2-mixer-dev + - libpng-dev + - libgl1-mesa-dev + - libgme-dev + - libcurl4-openssl-dev + - p7zip-full + - gcc-4.8 + compiler: gcc-4.8 + dist: xenial + if: env(DPL_ENABLED) = "1" AND (env(_DPL_JOB_ENABLED) = "1" OR env(DPL_JOB_ENABLE_ALL) = "1") + AND (branch =~ /^.*deployer.*$/ OR (tag IS present AND env(DPL_TAG_ENABLED) = "1")) + AND env(DPL_TERMINATE_MAIN) != "1" + env: + - _DPL_JOB_ENABLED=1 + - _DPL_JOB_NAME=xenial + - _DPL_DPUT_TARGET=1 + - _DPL_PACKAGE_SOURCE=1 + - PACKAGE_DISTRO=xenial + - PACKAGE_SUBVERSION=~16.04xenial + #gcc-4.8 (Ubuntu 4.8.5-2ubuntu1~14.04.1) 4.8.5 - os: linux addons: apt: @@ -499,65 +547,17 @@ matrix: - p7zip-full - gcc-4.8 compiler: gcc-4.8 - dist: xenial + dist: bionic if: env(DPL_ENABLED) = "1" AND (env(_DPL_JOB_ENABLED) = "1" OR env(DPL_JOB_ENABLE_ALL) = "1") AND (branch =~ /^.*deployer.*$/ OR (tag IS present AND env(DPL_TAG_ENABLED) = "1")) AND env(DPL_TERMINATE_MAIN) != "1" env: - _DPL_JOB_ENABLED=1 - - _DPL_JOB_NAME=disco + - _DPL_JOB_NAME=eoan - _DPL_DPUT_TARGET=1 - _DPL_PACKAGE_SOURCE=1 - - PACKAGE_DISTRO=disco - - PACKAGE_SUBVERSION=~19.04disco - #gcc-4.8 (Ubuntu 4.8.5-2ubuntu1~14.04.1) 4.8.5 - - os: linux - addons: - apt: - packages: - - libsdl2-mixer-dev - - libpng-dev - - libgl1-mesa-dev - - libgme-dev - - libcurl4-openssl-dev - - p7zip-full - - gcc-4.8 - compiler: gcc-4.8 - dist: xenial - if: env(DPL_ENABLED) = "1" AND (env(_DPL_JOB_ENABLED) = "1" OR env(DPL_JOB_ENABLE_ALL) = "1") - AND (branch =~ /^.*deployer.*$/ OR (tag IS present AND env(DPL_TAG_ENABLED) = "1")) - AND env(DPL_TERMINATE_MAIN) != "1" - env: - - _DPL_JOB_ENABLED=1 - - _DPL_JOB_NAME=cosmic - - _DPL_DPUT_TARGET=1 - - _DPL_PACKAGE_SOURCE=1 - - PACKAGE_DISTRO=cosmic - - PACKAGE_SUBVERSION=~18.10cosmic - #gcc-4.8 (Ubuntu 4.8.5-2ubuntu1~14.04.1) 4.8.5 - - os: linux - addons: - apt: - packages: - - libsdl2-mixer-dev - - libpng-dev - - libgl1-mesa-dev - - libgme-dev - - libcurl4-openssl-dev - - p7zip-full - - gcc-4.8 - compiler: gcc-4.8 - dist: xenial - if: env(DPL_ENABLED) = "1" AND (env(_DPL_JOB_ENABLED) = "1" OR env(DPL_JOB_ENABLE_ALL) = "1") - AND (branch =~ /^.*deployer.*$/ OR (tag IS present AND env(DPL_TAG_ENABLED) = "1")) - AND env(DPL_TERMINATE_MAIN) != "1" - env: - - _DPL_JOB_ENABLED=1 - - _DPL_JOB_NAME=xenial - - _DPL_DPUT_TARGET=1 - - _DPL_PACKAGE_SOURCE=1 - - PACKAGE_DISTRO=xenial - - PACKAGE_SUBVERSION=~16.04xenial + - PACKAGE_DISTRO=eoan + - PACKAGE_SUBVERSION=~19.10eoan #gcc-4.8 (Ubuntu 4.8.5-2ubuntu1~14.04.1) 4.8.5 allow_failures: - compiler: clang-3.5 From 389e7d415df7e77af59f0858d4eb5d93b8fd67e8 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 12 May 2020 18:37:15 +0100 Subject: [PATCH 03/28] make savegamename in doomdef.h an extern, put the actual definition in d_main.c (cherry picked from commit 89cd756cd83e4a03a34d1f16da18142d8167d889) --- src/d_main.c | 2 ++ src/doomdef.h | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/d_main.c b/src/d_main.c index 15116b530..5acfb610a 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -143,6 +143,8 @@ boolean advancedemo; INT32 debugload = 0; #endif +char savegamename[256]; + #ifdef _arch_dreamcast char srb2home[256] = "/cd"; char srb2path[256] = "/cd"; diff --git a/src/doomdef.h b/src/doomdef.h index ed41e346e..392ba7605 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -506,7 +506,7 @@ void CONS_Debug(INT32 debugflags, const char *fmt, ...) FUNCDEBUG; // Things that used to be in dstrings.h #define SAVEGAMENAME "srb2sav" -char savegamename[256]; +extern char savegamename[256]; // m_misc.h #ifdef GETTEXT From 166b06b589a7b0c792149d6e416096420b7a5aab Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 12 May 2020 18:40:51 +0100 Subject: [PATCH 04/28] turn all non-extern variables in s_sound.h into externs (and put their real definitions in the .c file) (cherry picked from commit dab212dc56936dd92a935d0c81003ff1d35ee2ee) --- src/s_sound.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/s_sound.h b/src/s_sound.h index 2a904faff..eeb1f0ab0 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -236,7 +236,7 @@ void S_StopSoundByNum(sfxenum_t sfxnum); #ifdef MUSICSLOT_COMPATIBILITY // For compatibility with code/scripts relying on older versions // This is a list of all the "special" slot names and their associated numbers -const char *compat_special_music_slots[16]; +extern const char *compat_special_music_slots[16]; #endif #endif From f0fa25a24331d4f116958c5f29cf2703ffda86e3 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 12 May 2020 18:42:16 +0100 Subject: [PATCH 05/28] added missing extern keyword for ms_RoomId in mserv.h (the definition is already in the .c file in this case) (cherry picked from commit 064f4bcf349e9600552a0b99bd0fbfb3cbcf0958) --- src/mserv.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mserv.h b/src/mserv.h index 09cd4f089..8f8152a7c 100644 --- a/src/mserv.h +++ b/src/mserv.h @@ -68,7 +68,7 @@ extern consvar_t cv_masterserver, cv_servername; // < 0 to not connect (usually -1) (offline mode) // == 0 to show all rooms, not a valid hosting room // anything else is whatever room the MS assigns to that number (online mode) -INT16 ms_RoomId; +extern INT16 ms_RoomId; const char *GetMasterServerPort(void); const char *GetMasterServerIP(void); From 41f0f34d3534d90e5eb64188cf46c470dda7016f Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 15 May 2020 10:00:05 -0700 Subject: [PATCH 06/28] Add missing extern to colortranslations --- src/k_kart.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/k_kart.h b/src/k_kart.h index 2ba5d1bdc..86ae0fcc5 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -11,7 +11,7 @@ #define KART_FULLTURN 800 -UINT8 colortranslations[MAXTRANSLATIONS][16]; +extern UINT8 colortranslations[MAXTRANSLATIONS][16]; extern const char *KartColor_Names[MAXSKINCOLORS]; extern const UINT8 KartColor_Opposite[MAXSKINCOLORS*2]; void K_RainbowColormap(UINT8 *dest_colormap, UINT8 skincolor); From 4eb7540cb333d0b4e23f78fd1215cf2858d2966c Mon Sep 17 00:00:00 2001 From: Sryder Date: Sat, 16 May 2020 00:02:33 +0100 Subject: [PATCH 07/28] Use bionic to build focal version because it has GCC 4.8? --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index f2693236b..380145250 100644 --- a/.travis.yml +++ b/.travis.yml @@ -451,7 +451,7 @@ matrix: - p7zip-full - gcc-4.8 compiler: gcc-4.8 - dist: focal + dist: bionic if: env(DPL_ENABLED) = "1" AND (env(_DPL_JOB_ENABLED) = "1" OR env(DPL_JOB_ENABLE_ALL) = "1") AND (branch =~ /^.*deployer.*$/ OR (tag IS present AND env(DPL_TAG_ENABLED) = "1")) AND env(DPL_TERMINATE_MAIN) != "1" From ac314d5f34d401d42495f9b33571526d9276513e Mon Sep 17 00:00:00 2001 From: filpAM Date: Sat, 16 May 2020 00:20:52 +0000 Subject: [PATCH 08/28] Fix visplane getting allocated twice --- src/r_plane.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/r_plane.c b/src/r_plane.c index db5bfbda2..659481ec8 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -402,7 +402,7 @@ static visplane_t *new_visplane(unsigned hash) visplane_t *check = freetail; if (!check) { - check = calloc(2, sizeof (*check)); + check = calloc(1, sizeof (*check)); if (check == NULL) I_Error("%s: Out of memory", "new_visplane"); // FIXME: ugly } else From 5f6e3b0e0f47e862f05604a7e036becbcf5edd42 Mon Sep 17 00:00:00 2001 From: Hannu Hanhi Date: Tue, 31 Mar 2020 19:42:15 +0300 Subject: [PATCH 09/28] Fix wrong orientation some boost pads in ogl --- src/hardware/hw_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 1bad26ee1..c7ff5a4af 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -407,7 +407,7 @@ void HWR_RenderPlane(extrasubsector_t *xsub, boolean isceiling, fixed_t fixedhei if (angle) // Only needs to be done if there's an altered angle { - angle = (InvAngle(angle)+ANGLE_180)>>ANGLETOFINESHIFT; + angle = InvAngle(angle)>>ANGLETOFINESHIFT; // This needs to be done so that it scrolls in a different direction after rotation like software /*tempxsow = FLOAT_TO_FIXED(scrollx); @@ -439,7 +439,7 @@ void HWR_RenderPlane(extrasubsector_t *xsub, boolean isceiling, fixed_t fixedhei tempxsow = FLOAT_TO_FIXED(v3d->s); tempytow = FLOAT_TO_FIXED(v3d->t); v3d->s = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINECOSINE(angle)) - FixedMul(tempytow, FINESINE(angle)))); - v3d->t = (FIXED_TO_FLOAT(-FixedMul(tempxsow, FINESINE(angle)) - FixedMul(tempytow, FINECOSINE(angle)))); + v3d->t = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINESINE(angle)) + FixedMul(tempytow, FINECOSINE(angle)))); } //v3d->s = (float)(v3d->s - flatxref + scrollx); From ba706e8409f1002ac5b322eb72cc4cebaa17aa9e Mon Sep 17 00:00:00 2001 From: Sryder Date: Tue, 19 May 2020 20:45:49 +0100 Subject: [PATCH 10/28] Use xenial to build all the versions newer than trusty I'm not 100% sure why we can't use newer series to build the newer installers. But this seems to be what vanilla does --- .travis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 380145250..663498901 100644 --- a/.travis.yml +++ b/.travis.yml @@ -451,7 +451,7 @@ matrix: - p7zip-full - gcc-4.8 compiler: gcc-4.8 - dist: bionic + dist: xenial if: env(DPL_ENABLED) = "1" AND (env(_DPL_JOB_ENABLED) = "1" OR env(DPL_JOB_ENABLE_ALL) = "1") AND (branch =~ /^.*deployer.*$/ OR (tag IS present AND env(DPL_TAG_ENABLED) = "1")) AND env(DPL_TERMINATE_MAIN) != "1" @@ -475,7 +475,7 @@ matrix: - p7zip-full - gcc-4.8 compiler: gcc-4.8 - dist: bionic + dist: xenial if: env(DPL_ENABLED) = "1" AND (env(_DPL_JOB_ENABLED) = "1" OR env(DPL_JOB_ENABLE_ALL) = "1") AND (branch =~ /^.*deployer.*$/ OR (tag IS present AND env(DPL_TAG_ENABLED) = "1")) AND env(DPL_TERMINATE_MAIN) != "1" @@ -547,7 +547,7 @@ matrix: - p7zip-full - gcc-4.8 compiler: gcc-4.8 - dist: bionic + dist: xenial if: env(DPL_ENABLED) = "1" AND (env(_DPL_JOB_ENABLED) = "1" OR env(DPL_JOB_ENABLE_ALL) = "1") AND (branch =~ /^.*deployer.*$/ OR (tag IS present AND env(DPL_TAG_ENABLED) = "1")) AND env(DPL_TERMINATE_MAIN) != "1" From 8e39dfa5c6001814aa05e238744f45bd8b2add56 Mon Sep 17 00:00:00 2001 From: Sryder Date: Wed, 20 May 2020 11:37:38 +0100 Subject: [PATCH 11/28] D_ModifierKeyResponder is unused now so remove it. --- src/d_main.c | 31 +------------------------------ 1 file changed, 1 insertion(+), 30 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 5acfb610a..85b363e0e 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -187,35 +187,6 @@ UINT8 shiftdown = 0; // 0x1 left, 0x2 right UINT8 ctrldown = 0; // 0x1 left, 0x2 right UINT8 altdown = 0; // 0x1 left, 0x2 right boolean capslock = 0; // gee i wonder what this does. -// -// D_ModifierKeyResponder -// Sets global shift/ctrl/alt variables, never actually eats events -// -static inline void D_ModifierKeyResponder(event_t *ev) -{ - if (ev->type == ev_keydown || ev->type == ev_console) switch (ev->data1) - { - case KEY_LSHIFT: shiftdown |= 0x1; return; - case KEY_RSHIFT: shiftdown |= 0x2; return; - case KEY_LCTRL: ctrldown |= 0x1; return; - case KEY_RCTRL: ctrldown |= 0x2; return; - case KEY_LALT: altdown |= 0x1; return; - case KEY_RALT: altdown |= 0x2; return; - case KEY_CAPSLOCK: capslock = !capslock; return; - - default: return; - } - else if (ev->type == ev_keyup) switch (ev->data1) - { - case KEY_LSHIFT: shiftdown &= ~0x1; return; - case KEY_RSHIFT: shiftdown &= ~0x2; return; - case KEY_LCTRL: ctrldown &= ~0x1; return; - case KEY_RCTRL: ctrldown &= ~0x2; return; - case KEY_LALT: altdown &= ~0x1; return; - case KEY_RALT: altdown &= ~0x2; return; - default: return; - } -} // // D_ProcessEvents @@ -282,7 +253,7 @@ static void D_Display(void) { if (nodrawers) return; // for comparative timing/profiling - + // check for change of screen size (video mode) if (setmodeneeded && !wipe) SCR_SetMode(); // change video mode From b2674a3cd08eb2ccc2da58bb0dfc978d4b7cb2c3 Mon Sep 17 00:00:00 2001 From: Sryder Date: Wed, 20 May 2020 11:47:22 +0100 Subject: [PATCH 12/28] Initialise these to 0 just to stop GCC 4.4 from complaining. This should be okay since 0 generally means "nothing" for these, and they should always be set before being used later on. --- src/hardware/r_opengl/r_opengl.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 5dc460996..e0503ba07 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -823,7 +823,7 @@ EXPORT boolean HWRAPI(LoadShaders) (void) #ifdef GL_SHADERS GLuint gl_vertShader, gl_fragShader; GLint i, result; - + if (!pglUseProgram) return false; gl_customvertexshaders[0] = NULL; @@ -2002,11 +2002,11 @@ EXPORT void HWRAPI(RenderBatches) (int *sNumPolys, int *sNumVerts, int *sNumCall boolean stopFlag = false; boolean changeState = false; boolean changeShader = false; - GLuint nextShader; + GLuint nextShader = 0U; boolean changeTexture = false; - GLuint nextTexture; + GLuint nextTexture = 0U; boolean changePolyFlags = false; - FBITFIELD nextPolyFlags; + FBITFIELD nextPolyFlags = 0U; boolean changeSurfaceInfo = false; FSurfaceInfo nextSurfaceInfo; @@ -2307,7 +2307,7 @@ EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUI pglColor4ubv((GLubyte*)&pSurf->PolyColor.s); } - + // Tint color tint.red = byte2float[pSurf->TintColor.s.red]; tint.green = byte2float[pSurf->TintColor.s.green]; From 52c8ba5d494bc9641973ee415d6642d747273e7f Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Sat, 23 May 2020 16:21:26 -0400 Subject: [PATCH 13/28] Fix opengl crashing on startup due to lack of checks Also fixes the log file not being written to the home directory. --- src/hardware/r_opengl/r_opengl.c | 16 ++++++++-------- src/sdl/ogl_sdl.c | 16 ++++++++++++++++ 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index e0503ba07..eef723e51 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -143,7 +143,7 @@ static const GLfloat byte2float[256] = { // -----------------+ #ifdef DEBUG_TO_FILE -FILE *gllogstream; +FILE *gllogstream = NULL; #endif FUNCPRINTF void GL_DBG_Printf(const char *format, ...) @@ -152,14 +152,14 @@ FUNCPRINTF void GL_DBG_Printf(const char *format, ...) char str[4096] = ""; va_list arglist; - if (!gllogstream) - gllogstream = fopen("ogllog.txt", "w"); + if (gllogstream) + { + va_start(arglist, format); + vsnprintf(str, 4096, format, arglist); + va_end(arglist); - va_start(arglist, format); - vsnprintf(str, 4096, format, arglist); - va_end(arglist); - - fwrite(str, strlen(str), 1, gllogstream); + fwrite(str, strlen(str), 1, gllogstream); + } #else (void)format; #endif diff --git a/src/sdl/ogl_sdl.c b/src/sdl/ogl_sdl.c index b006047f5..eb8e12cbc 100644 --- a/src/sdl/ogl_sdl.c +++ b/src/sdl/ogl_sdl.c @@ -33,6 +33,7 @@ #endif #include "../doomdef.h" +#include "../d_main.h" #ifdef HWRENDER #include "../hardware/r_opengl/r_opengl.h" @@ -154,11 +155,26 @@ boolean OglSdlSurface(INT32 w, INT32 h) { INT32 cbpp = cv_scr_depth.value < 16 ? 16 : cv_scr_depth.value; static boolean first_init = false; + const char *gllogdir = NULL; oglflags = 0; if (!first_init) { + if (!gllogstream) + { + gllogdir = D_Home(); + +#ifdef DEBUG_TO_FILE +#ifdef DEFAULTDIR + if (gllogdir) + gllogstream = fopen(va("%s/"DEFAULTDIR"/ogllog.txt",gllogdir), "wt"); + else +#endif + gllogstream = fopen("./ogllog.txt", "wt"); +#endif + } + gl_version = pglGetString(GL_VERSION); gl_renderer = pglGetString(GL_RENDERER); gl_extensions = pglGetString(GL_EXTENSIONS); From d062a35a3a50b3a4c749806cc1f22fffddcb18eb Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Fri, 29 May 2020 01:04:51 -0400 Subject: [PATCH 14/28] Huge respawn overhaul - Moved respawn code to its own file - Reorganized a lot of the code related to respawning - As a result of the massive reorganization, I squashed several bugs. Most notably: mid-game joiners having weird spawns, being able to skip laps by respawning. - Respawn lightsnake no longer takes you straight to your nextwaypoint -- it now has a minimum distance forward that it tries to put you at when you respawn. --- src/CMakeLists.txt | 2 + src/Makefile | 1 + src/d_clisrv.c | 10 - src/d_clisrv.h | 5 - src/d_netcmd.c | 1 + src/d_player.h | 27 +- src/dehacked.c | 3 - src/g_game.c | 38 +-- src/k_kart.c | 411 +------------------------ src/k_kart.h | 3 +- src/k_respawn.c | 735 ++++++++++++++++++++++++++++++++++++++++++++ src/k_respawn.h | 72 +++++ src/lua_playerlib.c | 20 -- src/m_cheat.c | 10 +- src/p_enemy.c | 37 +-- src/p_inter.c | 6 +- src/p_map.c | 1 + src/p_mobj.c | 30 +- src/p_saveg.c | 16 +- src/p_setup.c | 8 +- src/p_spec.c | 2 +- src/p_telept.c | 11 +- src/p_user.c | 30 +- 23 files changed, 918 insertions(+), 561 deletions(-) create mode 100644 src/k_respawn.c create mode 100644 src/k_respawn.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ef704abd1..18d82515c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -165,6 +165,7 @@ set(SRB2_CORE_GAME_SOURCES k_pwrlv.c k_waypoint.c k_color.c + k_respawn.c p_local.h p_maputl.h @@ -184,6 +185,7 @@ set(SRB2_CORE_GAME_SOURCES k_pwrlv.h k_waypoint.h k_color.h + k_respawn.h ) if(NOT (CMAKE_CXX_COMPILER_ID MATCHES "Clang")) diff --git a/src/Makefile b/src/Makefile index 3d84095bd..60b0ac054 100644 --- a/src/Makefile +++ b/src/Makefile @@ -506,6 +506,7 @@ OBJS:=$(i_main_o) \ $(OBJDIR)/y_inter.o \ $(OBJDIR)/st_stuff.o \ $(OBJDIR)/k_kart.o \ + $(OBJDIR)/k_respawn.o\ $(OBJDIR)/k_collide.o\ $(OBJDIR)/k_color.o \ $(OBJDIR)/k_battle.o \ diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 4b805eab5..da80b29a4 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -611,12 +611,7 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i) rsp->weapondelay = LONG(players[i].weapondelay); rsp->tossdelay = LONG(players[i].tossdelay); - rsp->starpostx = SHORT(players[i].starpostx); - rsp->starposty = SHORT(players[i].starposty); - rsp->starpostz = SHORT(players[i].starpostz); rsp->starpostnum = LONG(players[i].starpostnum); - rsp->starposttime = (tic_t)LONG(players[i].starposttime); - rsp->starpostangle = (angle_t)LONG(players[i].starpostangle); rsp->maxlink = LONG(players[i].maxlink); rsp->dashspeed = (fixed_t)LONG(players[i].dashspeed); @@ -734,12 +729,7 @@ static void resynch_read_player(resynch_pak *rsp) players[i].weapondelay = LONG(rsp->weapondelay); players[i].tossdelay = LONG(rsp->tossdelay); - players[i].starpostx = SHORT(rsp->starpostx); - players[i].starposty = SHORT(rsp->starposty); - players[i].starpostz = SHORT(rsp->starpostz); players[i].starpostnum = LONG(rsp->starpostnum); - players[i].starposttime = (tic_t)LONG(rsp->starposttime); - players[i].starpostangle = (angle_t)LONG(rsp->starpostangle); players[i].maxlink = LONG(rsp->maxlink); players[i].dashspeed = (fixed_t)LONG(rsp->dashspeed); diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 974d6ee1b..e0d6cd892 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -252,12 +252,7 @@ typedef struct INT32 weapondelay; INT32 tossdelay; - INT16 starpostx; - INT16 starposty; - INT16 starpostz; INT32 starpostnum; - tic_t starposttime; - angle_t starpostangle; INT32 maxlink; fixed_t dashspeed; diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 989616199..718c6b614 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -51,6 +51,7 @@ #include "k_pwrlv.h" #include "y_inter.h" #include "k_color.h" +#include "k_respawn.h" #ifdef NETGAME_DEVMODE #define CV_RESTRICT CV_NETVAR diff --git a/src/d_player.h b/src/d_player.h index 2a8ec9046..60b5ca9bc 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -264,9 +264,6 @@ typedef enum k_position, // Used for Kart positions, mostly for deterministic stuff k_oldposition, // Used for taunting when you pass someone k_positiondelay, // Used for position number, so it can grow when passing/being passed - k_starpostflip, // the last starpost we hit requires flipping? - k_respawn, // Timer for the DEZ laser respawn effect - k_dropdash, // Charge up for respawn Drop Dash k_throwdir, // Held dir of controls; 1 = forward, 0 = none, -1 = backward (was "player->heldDir") k_instashield, // Instashield no-damage animation timer @@ -420,6 +417,20 @@ typedef enum RW_RAIL = 32 } ringweapons_t; +// player_t struct for all respawn variables +typedef struct respawnvars_s +{ + UINT8 respawnstate; // 0: not respawning, 1: heading towards respawn point, 2: about to drop + waypoint_t *wp; // Waypoint that we're going towards, NULL if the position isn't linked to one + INT32 pointx; // Respawn position coords to go towards + INT32 pointy; + INT32 pointz; + boolean flip; // Flip upside down or not + INT32 timer; // Time left on respawn animation once you're there + UINT32 distanceleft; // How far along the course to respawn you + INT32 dropdash; // Drop Dash charge timer +} respawnvars_t; + // ======================================================================== // PLAYER STRUCTURE // ======================================================================== @@ -466,6 +477,7 @@ typedef struct player_s INT16 rturn_max[MAXPREDICTTICS]; // Ditto but for full-right UINT32 distancetofinish; waypoint_t *nextwaypoint; + respawnvars_t respawnvars; // SRB2Kart: respawn info // Bit flags. // See pflags_t, above. @@ -531,6 +543,7 @@ typedef struct player_s INT16 totalring; // Total number of rings obtained for Race Mode tic_t realtime; // integer replacement for leveltime UINT8 laps; // Number of laps (optional) + INT32 starpostnum; // The number of the last starpost you hit //////////////////// // CTF Mode Stuff // @@ -541,14 +554,6 @@ typedef struct player_s INT32 weapondelay; // Delay (if any) to fire the weapon again INT32 tossdelay; // Delay (if any) to toss a flag/emeralds again - // Starpost information - INT16 starpostx; - INT16 starposty; - INT16 starpostz; - INT32 starpostnum; // The number of the last starpost you hit - tic_t starposttime; // Your time when you hit the starpost - angle_t starpostangle; // Angle that the starpost is facing - you respawn facing this way - ///////////////// // NiGHTS Stuff// ///////////////// diff --git a/src/dehacked.c b/src/dehacked.c index ba08d2e09..a5d58dc2c 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -8314,9 +8314,6 @@ static const char *const KARTSTUFF_LIST[] = { "POSITION", "OLDPOSITION", "POSITIONDELAY", - "STARPOSTFLIP", - "RESPAWN", - "DROPDASH", "THROWDIR", "INSTASHIELD", diff --git a/src/g_game.c b/src/g_game.c index 6e21f48d7..b58ac24ac 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -53,6 +53,7 @@ #include "k_battle.h" #include "k_pwrlv.h" #include "k_color.h" +#include "k_respawn.h" gameaction_t gameaction; gamestate_t gamestate = GS_NULL; @@ -1587,7 +1588,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) // SRB2kart - no additional angle if not moving if ((player->mo && player->speed > 0) // Moving || (leveltime > starttime && (cmd->buttons & BT_ACCELERATE && cmd->buttons & BT_BRAKE)) // Rubber-burn turn - || (player->kartstuff[k_respawn]) // Respawning + || (player->respawnvars.respawnstate != RESPAWNST_NONE) // Respawning || (player->spectator || objectplacing)) // Not a physical player lang += (cmd->angleturn<<16); @@ -2536,12 +2537,9 @@ static inline void G_PlayerFinishLevel(INT32 player) p->mo->flags2 &= ~MF2_SHADOW; // cancel invisibility P_FlashPal(p, 0, 0); // Resets - p->starpostangle = 0; - p->starposttime = 0; - p->starpostx = 0; - p->starposty = 0; - p->starpostz = 0; + p->starpostnum = 0; + memset(&p->respawnvars, 0, sizeof (p->respawnvars)); // SRB2kart: Increment the "matches played" counter. if (player == consoleplayer) @@ -2575,12 +2573,7 @@ void G_PlayerReborn(INT32 player) INT32 charflags; INT32 pflags; INT32 ctfteam; - INT32 starposttime; - INT16 starpostx; - INT16 starposty; - INT16 starpostz; INT32 starpostnum; - INT32 starpostangle; INT32 exiting; INT16 numboxes; INT16 totalring; @@ -2604,7 +2597,6 @@ void G_PlayerReborn(INT32 player) INT32 comebackpoints; INT32 wanted; INT32 rings; - INT32 respawnflip; boolean songcredit = false; score = players[player].score; @@ -2634,13 +2626,7 @@ void G_PlayerReborn(INT32 player) // charflags = players[player].charflags; - starposttime = players[player].starposttime; - starpostx = players[player].starpostx; - starposty = players[player].starposty; - starpostz = players[player].starpostz; starpostnum = players[player].starpostnum; - respawnflip = players[player].kartstuff[k_starpostflip]; //SRB2KART - starpostangle = players[player].starpostangle; mare = players[player].mare; bot = players[player].bot; @@ -2709,12 +2695,7 @@ void G_PlayerReborn(INT32 player) // p->charflags = charflags; - p->starposttime = starposttime; - p->starpostx = starpostx; - p->starposty = starposty; - p->starpostz = starpostz; p->starpostnum = starpostnum; - p->starpostangle = starpostangle; p->exiting = exiting; p->numboxes = numboxes; @@ -2739,7 +2720,6 @@ void G_PlayerReborn(INT32 player) p->kartstuff[k_wanted] = wanted; p->kartstuff[k_eggmanblame] = -1; p->kartstuff[k_lastdraft] = -1; - p->kartstuff[k_starpostflip] = respawnflip; // Don't do anything immediately p->pflags |= PF_USEDOWN; @@ -2772,7 +2752,9 @@ void G_PlayerReborn(INT32 player) S_ShowMusicCredit(); if (leveltime > (starttime + (TICRATE/2)) && !p->spectator) - p->kartstuff[k_respawn] = 48; // Respawn effect + { + K_DoIngameRespawn(p); + } if (gametype == GT_COOP) P_FindEmerald(); // scan for emeralds to hunt for @@ -4680,8 +4662,8 @@ void G_InitNew(UINT8 pencoremode, const char *mapname, boolean resetplayer, bool for (i = 0; i < MAXPLAYERS; i++) { players[i].playerstate = PST_REBORN; - players[i].starpostangle = players[i].starpostnum = players[i].starposttime = 0; - players[i].starpostx = players[i].starposty = players[i].starpostz = 0; + players[i].starpostnum = 0; + memset(&players[i].respawnvars, 0, sizeof (players[i].respawnvars)); #if 0 if (netgame || multiplayer) @@ -5203,7 +5185,7 @@ void G_ReadDemoTiccmd(ticcmd_t *cmd, INT32 playernum) // SRB2kart: Copy-pasted from ticcmd building, removes that crappy demo cam if (((players[displayplayers[0]].mo && players[displayplayers[0]].speed > 0) // Moving || (leveltime > starttime && (cmd->buttons & BT_ACCELERATE && cmd->buttons & BT_BRAKE)) // Rubber-burn turn - || (players[displayplayers[0]].kartstuff[k_respawn]) // Respawning + || (players[displayplayers[0]].respawnvars.respawnstate != RESPAWNST_NONE) // Respawning || (players[displayplayers[0]].spectator || objectplacing)) // Not a physical player && !(players[displayplayers[0]].kartstuff[k_spinouttimer] && (players[displayplayers[0]].kartstuff[k_sneakertimer] || players[displayplayers[0]].kartstuff[k_levelbooster]))) // Spinning and boosting cancels out spinout diff --git a/src/k_kart.c b/src/k_kart.c index d80cb8abb..36ff07cda 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -8,6 +8,7 @@ #include "k_battle.h" #include "k_pwrlv.h" #include "k_color.h" +#include "k_respawn.h" #include "doomdef.h" #include "hu_stuff.h" #include "g_game.h" @@ -962,8 +963,8 @@ void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid) || (mobj2->player && mobj2->player->playerstate != PST_LIVE)) return; - if ((mobj1->player && mobj1->player->kartstuff[k_respawn]) - || (mobj2->player && mobj2->player->kartstuff[k_respawn])) + if ((mobj1->player && mobj1->player->respawnvars.respawnstate != RESPAWNST_NONE) + || (mobj2->player && mobj2->player->respawnvars.respawnstate != RESPAWNST_NONE)) return; { // Don't bump if you're flashing @@ -1461,7 +1462,6 @@ void K_FlipFromObject(mobj_t *mo, mobj_t *master) mo->z += master->height - FixedMul(master->scale, mo->height); } -// These have to go earlier than its sisters because of K_RespawnChecker... void K_MatchGenericExtraFlags(mobj_t *mo, mobj_t *master) { // flipping @@ -1476,7 +1476,7 @@ void K_MatchGenericExtraFlags(mobj_t *mo, mobj_t *master) mo->eflags = (mo->eflags & ~MFE_DRAWONLYFORP4)|(master->eflags & MFE_DRAWONLYFORP4); } -static void K_SpawnDashDustRelease(player_t *player) +void K_SpawnDashDustRelease(player_t *player) { fixed_t newx; fixed_t newy; @@ -1535,362 +1535,6 @@ static void K_SpawnBrakeDriftSparks(player_t *player) // Be sure to update the m sparks->flags2 |= MF2_DONTDRAW; } -/** \brief Preps a player to respawn - - \param player player to respawn - - \return void -*/ -void K_DoIngameRespawn(player_t *player) -{ - if (!player->mo || P_MobjWasRemoved(player->mo)) - return; - - if (player->kartstuff[k_respawn]) - return; - - if (leveltime <= starttime) - return; - - if (player->nextwaypoint == NULL) // Starpost xyz not initalized(?) - { - UINT32 bestdist = UINT32_MAX; - mapthing_t *beststart = NULL; - UINT8 numstarts = 0; - - if (G_RaceGametype()) - { - numstarts = numcoopstarts; - } - else if (G_BattleGametype()) - { - numstarts = numdmstarts; - } - - if (numstarts > 0) - { - UINT8 i = 0; - - for (i = 0; i < numstarts; i++) - { - UINT32 dist = UINT32_MAX; - mapthing_t *checkstart = NULL; - - if (G_RaceGametype()) - { - checkstart = playerstarts[i]; - } - else if (G_BattleGametype()) - { - checkstart = deathmatchstarts[i]; - } - else - { - break; - } - - dist = (UINT32)P_AproxDistance((player->mo->x >> FRACBITS) - checkstart->x, - (player->mo->y >> FRACBITS) - checkstart->y); - - if (dist < bestdist) - { - beststart = checkstart; - bestdist = dist; - } - } - } - - if (beststart == NULL) - { - CONS_Alert(CONS_WARNING, "No respawn points!\n"); - } - else - { - sector_t *s; - fixed_t z = (beststart->options >> ZSHIFT); - - player->starpostx = beststart->x; - player->starposty = beststart->y; - s = R_PointInSubsector(beststart->x << FRACBITS, beststart->y << FRACBITS)->sector; - - if (beststart->options & MTF_OBJECTFLIP) - { - player->starpostz = ( -#ifdef ESLOPE - s->c_slope ? P_GetZAt(s->c_slope, beststart->x << FRACBITS, beststart->y << FRACBITS) : -#endif - s->ceilingheight) >> FRACBITS; - - if (z) - player->starpostz -= z; - - player->starpostz -= mobjinfo[MT_PLAYER].height; - player->kartstuff[k_starpostflip] = 1; - } - else - { - player->starpostz = ( -#ifdef ESLOPE - s->f_slope ? P_GetZAt(s->f_slope, beststart->x << FRACBITS, beststart->y << FRACBITS) : -#endif - s->floorheight) >> FRACBITS; - - if (z) - player->starpostz += z; - - player->kartstuff[k_starpostflip] = 0; - } - } - } - - player->mo->flags &= ~(MF_SOLID|MF_SHOOTABLE); - player->mo->flags |= MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOCLIPTHING|MF_NOGRAVITY; - player->mo->flags2 &= ~MF2_DONTDRAW; - - player->kartstuff[k_respawn] = 48; -} - -/** \brief Calculates the respawn timer and drop-boosting - - \param player player object passed from K_KartPlayerThink - - \return void -*/ -void K_RespawnChecker(player_t *player) -{ - ticcmd_t *cmd = &player->cmd; - - if (player->spectator) - return; - - if (player->kartstuff[k_respawn] > 1) - { - fixed_t destx = 0, desty = 0, destz = 0; - - player->mo->momx = player->mo->momy = player->mo->momz = 0; - player->powers[pw_flashing] = 2; - player->powers[pw_nocontrol] = 2; - - if (leveltime % 8 == 0 && !mapreset) - S_StartSound(player->mo, sfx_s3kcas); - - destx = (player->starpostx << FRACBITS); - desty = (player->starposty << FRACBITS); - destz = (player->starpostz << FRACBITS); - - if (player->kartstuff[k_starpostflip]) - { - // This variable is set from the settings of the best waypoint, thus this waypoint is FLIPPED as well. - // So we should flip the player in advance for it as well. - player->mo->flags2 |= MF2_OBJECTFLIP; - player->mo->eflags |= MFE_VERTICALFLIP; - destz -= (128 * mapobjectscale) + (player->mo->height); - } - else - { - // Ditto, but this waypoint isn't flipped, so make sure the player also isn't flipped! - player->mo->flags2 &= ~MF2_OBJECTFLIP; - player->mo->eflags &= ~MFE_VERTICALFLIP; - destz += (128 * mapobjectscale); - } - - if (player->mo->x != destx || player->mo->y != desty || player->mo->z != destz) - { - fixed_t step = 64*mapobjectscale; - fixed_t dist = P_AproxDistance(P_AproxDistance(player->mo->x - destx, player->mo->y - desty), player->mo->z - destz); - - if (dist <= step) // You're ready to respawn - { - P_TryMove(player->mo, destx, desty, true); - player->mo->z = destz; - } - else - { - fixed_t stepx = 0, stepy = 0, stepz = 0; - angle_t stepha = R_PointToAngle2(player->mo->x, player->mo->y, destx, desty); - angle_t stepva = R_PointToAngle2(0, player->mo->z, P_AproxDistance(player->mo->x - destx, player->mo->y - desty), destz); - fixed_t laserx = 0, lasery = 0, laserz = 0; - UINT8 lasersteps = 4; - - // Move toward the respawn point - stepx = FixedMul(FixedMul(FINECOSINE(stepha >> ANGLETOFINESHIFT), step), FINECOSINE(stepva >> ANGLETOFINESHIFT)); - stepy = FixedMul(FixedMul(FINESINE(stepha >> ANGLETOFINESHIFT), step), FINECOSINE(stepva >> ANGLETOFINESHIFT)); - stepz = FixedMul(FINESINE(stepva >> ANGLETOFINESHIFT), 2*step); - - P_TryMove(player->mo, player->mo->x + stepx, player->mo->y + stepy, true); - player->mo->z += stepz; - - // Spawn lasers along the path - laserx = player->mo->x + (stepx / 2); - lasery = player->mo->y + (stepy / 2); - laserz = player->mo->z + (stepz / 2); - dist = P_AproxDistance(P_AproxDistance(laserx - destx, lasery - desty), laserz - destz); - - if (dist > step/2) - { - while (lasersteps) - { - - stepha = R_PointToAngle2(laserx, lasery, destx, desty); - stepva = R_PointToAngle2(0, laserz, P_AproxDistance(laserx - destx, lasery - desty), destz); - - stepx = FixedMul(FixedMul(FINECOSINE(stepha >> ANGLETOFINESHIFT), step), FINECOSINE(stepva >> ANGLETOFINESHIFT)); - stepy = FixedMul(FixedMul(FINESINE(stepha >> ANGLETOFINESHIFT), step), FINECOSINE(stepva >> ANGLETOFINESHIFT)); - stepz = FixedMul(FINESINE(stepva >> ANGLETOFINESHIFT), 2*step); - - laserx += stepx; - lasery += stepy; - laserz += stepz; - dist = P_AproxDistance(P_AproxDistance(laserx - destx, lasery - desty), laserz - destz); - - if (dist <= step/2) - break; - - lasersteps--; - } - } - - if (lasersteps == 0) // Don't spawn them beyond the respawn point. - { - mobj_t *laser; - - laser = P_SpawnMobj(laserx, lasery, laserz + (player->mo->height / 2), MT_DEZLASER); - - if (laser && !P_MobjWasRemoved(laser)) - { - P_SetMobjState(laser, S_DEZLASER_TRAIL1); - if (player->mo->eflags & MFE_VERTICALFLIP) - laser->eflags |= MFE_VERTICALFLIP; - P_SetTarget(&laser->target, player->mo); - laser->angle = stepha + ANGLE_90; - P_SetScale(laser, (laser->destscale = FRACUNIT)); - } - } - } - } - else - { - player->kartstuff[k_respawn]--; - - player->mo->flags |= MF_SOLID|MF_SHOOTABLE; - player->mo->flags &= ~(MF_NOCLIPHEIGHT|MF_NOCLIPTHING|MF_NOGRAVITY); - if (!(player->pflags & PF_NOCLIP)) - player->mo->flags &= ~MF_NOCLIP; - - if (leveltime % 8 == 0) - { - INT32 i; - - for (i = 0; i < 8; i++) - { - mobj_t *laser; - angle_t newangle; - fixed_t newx, newy, newz; - - newangle = FixedAngle(((360/8)*i)*FRACUNIT); - newx = player->mo->x + P_ReturnThrustX(player->mo, newangle, 31 * player->mo->scale); - newy = player->mo->y + P_ReturnThrustY(player->mo, newangle, 31 * player->mo->scale); - if (player->mo->eflags & MFE_VERTICALFLIP) - newz = player->mo->z + player->mo->height; - else - newz = player->mo->z; - - laser = P_SpawnMobj(newx, newy, newz, MT_DEZLASER); - - if (laser && !P_MobjWasRemoved(laser)) - { - if (player->mo->eflags & MFE_VERTICALFLIP) - laser->eflags |= MFE_VERTICALFLIP; - P_SetTarget(&laser->target, player->mo); - laser->angle = newangle+ANGLE_90; - laser->momz = (8 * player->mo->scale) * P_MobjFlip(player->mo); - P_SetScale(laser, (laser->destscale = player->mo->scale)); - } - } - } - } - } - else if (player->kartstuff[k_respawn] == 1) - { - if (player->kartstuff[k_growshrinktimer] < 0) - { - player->mo->scalespeed = mapobjectscale/TICRATE; - player->mo->destscale = (6*mapobjectscale)/8; - if (cv_kartdebugshrink.value && !modeattacking && !player->bot) - player->mo->destscale = (6*player->mo->destscale)/8; - } - - if (!P_IsObjectOnGround(player->mo) && !mapreset) - { - player->powers[pw_flashing] = K_GetKartFlashing(player); - - // Sal: The old behavior was stupid and prone to accidental usage. - // Let's rip off Mania instead, and turn this into a Drop Dash! - - if (cmd->buttons & BT_ACCELERATE && !player->kartstuff[k_spinouttimer]) // Lat: Since we're letting players spin out on respawn, don't let them charge a dropdash in this state. (It wouldn't work anyway) - player->kartstuff[k_dropdash]++; - else - player->kartstuff[k_dropdash] = 0; - - if (player->kartstuff[k_dropdash] == TICRATE/4) - S_StartSound(player->mo, sfx_ddash); - - if ((player->kartstuff[k_dropdash] >= TICRATE/4) - && (player->kartstuff[k_dropdash] & 1)) - player->mo->colorized = true; - else - player->mo->colorized = false; - } - else - { - if ((cmd->buttons & BT_ACCELERATE) && (player->kartstuff[k_dropdash] >= TICRATE/4)) - { - S_StartSound(player->mo, sfx_s23c); - player->kartstuff[k_startboost] = 50; - K_SpawnDashDustRelease(player); - } - - player->mo->colorized = false; - player->kartstuff[k_dropdash] = 0; - player->kartstuff[k_respawn] = 0; - - //P_PlayRinglossSound(player->mo); - P_PlayerRingBurst(player, 3); - - if (G_BattleGametype()) - { - if (player->kartstuff[k_bumper] > 0) - { - if (player->kartstuff[k_bumper] == 1) - { - mobj_t *karmahitbox = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_KARMAHITBOX); // Player hitbox is too small!! - P_SetTarget(&karmahitbox->target, player->mo); - karmahitbox->destscale = player->mo->scale; - P_SetScale(karmahitbox, player->mo->scale); - CONS_Printf(M_GetText("%s lost all of their bumpers!\n"), player_names[player-players]); - } - player->kartstuff[k_bumper]--; - if (K_IsPlayerWanted(player)) - K_CalculateBattleWanted(); - } - - if (!player->kartstuff[k_bumper]) - { - player->kartstuff[k_comebacktimer] = comebacktime; - if (player->kartstuff[k_comebackmode] == 2) - { - mobj_t *poof = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_EXPLODE); - S_StartSound(poof, mobjinfo[MT_KARMAHITBOX].seesound); - player->kartstuff[k_comebackmode] = 0; - } - } - - K_CheckBumpers(); - } - } - } -} - /** \brief Handles the state changing for moving players, moved here to eliminate duplicate code \param player player data @@ -5198,7 +4842,7 @@ static void K_UpdateEngineSounds(player_t *player, ticcmd_t *cmd) #endif return; - if ((leveltime >= starttime-(2*TICRATE) && leveltime <= starttime) || (player->kartstuff[k_respawn] == 1)) // Startup boosts + if ((leveltime >= starttime-(2*TICRATE) && leveltime <= starttime) || (player->respawnvars.respawnstate == RESPAWNST_DROP)) // Startup boosts targetsnd = ((cmd->buttons & BT_ACCELERATE) ? 12 : 0); else targetsnd = (((6*cmd->forwardmove)/25) + ((player->speed / mapobjectscale)/5))/2; @@ -5599,7 +5243,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) } } - if (player->playerstate == PST_DEAD || player->kartstuff[k_respawn] > 1) // Ensure these are set correctly here + if (player->playerstate == PST_DEAD || (player->respawnvars.respawnstate == RESPAWNST_MOVE)) // Ensure these are set correctly here { player->mo->colorized = false; player->mo->color = player->skincolor; @@ -5775,7 +5419,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) if (player->kartstuff[k_invincibilitytimer]) player->kartstuff[k_invincibilitytimer]--; - if (!player->kartstuff[k_respawn] && player->kartstuff[k_growshrinktimer] != 0) + if ((player->respawnvars.respawnstate == RESPAWNST_NONE) && player->kartstuff[k_growshrinktimer] != 0) { if (player->kartstuff[k_growshrinktimer] > 0) player->kartstuff[k_growshrinktimer]--; @@ -5845,7 +5489,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) if (G_BattleGametype() && player->kartstuff[k_bumper] > 0 && !player->kartstuff[k_spinouttimer] && !player->kartstuff[k_squishedtimer] - && !player->kartstuff[k_respawn] && !player->powers[pw_flashing]) + && (player->respawnvars.respawnstate == RESPAWNST_DROP) && !player->powers[pw_flashing]) { player->kartstuff[k_wanted]++; if (battleovertime.enabled >= 10*TICRATE) @@ -5931,10 +5575,6 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) else player->kartstuff[k_jmp] = 0; - // Respawn Checker - if (player->kartstuff[k_respawn]) - K_RespawnChecker(player); - // Roulette Code K_KartItemRoulette(player, cmd); @@ -6169,36 +5809,13 @@ static waypoint_t *K_GetPlayerNextWaypoint(player_t *player) // Respawn point should only be updated when we're going to a nextwaypoint if ((updaterespawn) && + (player->respawnvars.respawnstate == RESPAWNST_NONE) && (bestwaypoint != NULL) && (bestwaypoint != player->nextwaypoint) && - (player->kartstuff[k_respawn] == 0) && - (K_GetWaypointIsSpawnpoint(bestwaypoint)) && // Don't try to respawn on waypoints that are marked with no respawn - (K_GetWaypointIsShortcut(bestwaypoint) == false) && (K_GetWaypointIsEnabled(bestwaypoint) == true)) + (K_GetWaypointIsSpawnpoint(bestwaypoint)) && + (K_GetWaypointIsEnabled(bestwaypoint) == true)) { - size_t i = 0U; - waypoint_t *aimwaypoint = NULL; - - player->starpostx = bestwaypoint->mobj->x >> FRACBITS; - player->starposty = bestwaypoint->mobj->y >> FRACBITS; - player->starpostz = bestwaypoint->mobj->z >> FRACBITS; - player->kartstuff[k_starpostflip] = (bestwaypoint->mobj->flags2 & MF2_OBJECTFLIP); - - // starpostangle is to the first valid nextwaypoint for simplicity - // if we reach the last waypoint and it's still not valid, just use it anyway. Someone needs to fix - // their map! - for (i = 0U; i < bestwaypoint->numnextwaypoints; i++) - { - aimwaypoint = bestwaypoint->nextwaypoints[i]; - - if ((i == bestwaypoint->numnextwaypoints - 1U) - || ((K_GetWaypointIsEnabled(aimwaypoint) == true) - && (K_GetWaypointIsSpawnpoint(aimwaypoint) == true))) - { - player->starpostangle = R_PointToAngle2( - bestwaypoint->mobj->x, bestwaypoint->mobj->y, aimwaypoint->mobj->x, aimwaypoint->mobj->y); - break; - } - } + player->respawnvars.wp = bestwaypoint; } } @@ -6281,7 +5898,7 @@ void K_UpdateDistanceFromFinishLine(player_t *const player) { if ((player != NULL) && (player->mo != NULL)) { - if (player->exiting) + if (player->exiting || player->spectator) { player->nextwaypoint = K_GetFinishLineWaypoint(); player->distancetofinish = 0U; @@ -6896,7 +6513,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) player->pflags |= PF_ATTACKDOWN; if (player && player->mo && player->mo->health > 0 && !player->spectator && !(player->exiting || mapreset) && leveltime > starttime - && player->kartstuff[k_spinouttimer] == 0 && player->kartstuff[k_squishedtimer] == 0 && player->kartstuff[k_respawn] == 0) + && player->kartstuff[k_spinouttimer] == 0 && player->kartstuff[k_squishedtimer] == 0 && (player->respawnvars.respawnstate == RESPAWNST_NONE)) { // First, the really specific, finicky items that function without the item being directly in your item slot. // Karma item dropping diff --git a/src/k_kart.h b/src/k_kart.h index 156fa3e80..647bdeda0 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -26,8 +26,7 @@ void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid) void K_KartPainEnergyFling(player_t *player); void K_FlipFromObject(mobj_t *mo, mobj_t *master); void K_MatchGenericExtraFlags(mobj_t *mo, mobj_t *master); -void K_DoIngameRespawn(player_t *player); -void K_RespawnChecker(player_t *player); +void K_SpawnDashDustRelease(player_t *player); void K_KartMoveAnimation(player_t *player); void K_KartPlayerHUDUpdate(player_t *player); void K_KartPlayerThink(player_t *player, ticcmd_t *cmd); diff --git a/src/k_respawn.c b/src/k_respawn.c new file mode 100644 index 000000000..7a828c59d --- /dev/null +++ b/src/k_respawn.c @@ -0,0 +1,735 @@ +// SONIC ROBO BLAST 2 KART +//----------------------------------------------------------------------------- +// Copyright (C) 2018-2020 by Kart Krew +// +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. +//----------------------------------------------------------------------------- +/// \file k_respawn.c +/// \brief Respawning logic + +#include "k_respawn.h" +#include "doomdef.h" +#include "d_player.h" +#include "k_kart.h" +#include "k_battle.h" +#include "g_game.h" +#include "p_local.h" +#include "p_tick.h" +#include "p_setup.h" +#include "r_main.h" +#include "s_sound.h" +#include "p_slopes.h" +#include "r_defs.h" + +/*-------------------------------------------------- + fixed_t K_RespawnOffset(player_t *player, boolean flip) + + See header file for description. +--------------------------------------------------*/ +fixed_t K_RespawnOffset(player_t *player, boolean flip) +{ + fixed_t z = 0; + + if (flip == true) + { + player->mo->flags2 |= MF2_OBJECTFLIP; + player->mo->eflags |= MFE_VERTICALFLIP; + z -= (128 * mapobjectscale) - (player->mo->height); + } + else + { + player->mo->flags2 &= ~MF2_OBJECTFLIP; + player->mo->eflags &= ~MFE_VERTICALFLIP; + z += (128 * mapobjectscale); + } + + return z; +} + +/*-------------------------------------------------- + static void K_RespawnAtWaypoint(player_t *player, waypoint_t *waypoint) + + Updates a player's respawn variables to go to the provided waypoint. + + Input Arguments:- + player - Player to preform for. + waypoint - Waypoint to respawn to. + + Return:- + None +--------------------------------------------------*/ +static void K_RespawnAtWaypoint(player_t *player, waypoint_t *waypoint) +{ + if (player == NULL || player->mo == NULL || P_MobjWasRemoved(player->mo)) + { + return; + } + + if (waypoint == NULL || waypoint->mobj == NULL || P_MobjWasRemoved(waypoint->mobj)) + { + return; + } + + player->respawnvars.pointx = waypoint->mobj->x; + player->respawnvars.pointy = waypoint->mobj->y; + player->respawnvars.pointz = waypoint->mobj->z; + player->respawnvars.flip = (waypoint->mobj->flags2 & MF2_OBJECTFLIP); + player->respawnvars.pointz += K_RespawnOffset(player, player->respawnvars.flip); +} + +/*-------------------------------------------------- + void K_DoIngameRespawn(player_t *player) + + See header file for description. +--------------------------------------------------*/ +void K_DoIngameRespawn(player_t *player) +{ + if (!player->mo || P_MobjWasRemoved(player->mo)) + { + return; + } + + if (player->respawnvars.respawnstate != RESPAWNST_NONE) + { + return; + } + + if (leveltime <= starttime) + { + return; + } + + player->kartstuff[k_ringboost] = 0; + player->kartstuff[k_driftboost] = 0; + player->kartstuff[k_drift] = 0; + player->kartstuff[k_driftcharge] = 0; + player->kartstuff[k_pogospring] = 0; + + // Set up respawn position if invalid + if (player->respawnvars.wp != NULL) + { + K_RespawnAtWaypoint(player, player->respawnvars.wp); + player->respawnvars.distanceleft = (RESPAWN_DIST * mapobjectscale) / FRACUNIT; + } + else + { + UINT32 bestdist = UINT32_MAX; + mapthing_t *beststart = NULL; + UINT8 numstarts = 0; + + if (G_RaceGametype()) + { + numstarts = numcoopstarts; + } + else if (G_BattleGametype()) + { + numstarts = numdmstarts; + } + + if (numstarts > 0) + { + UINT8 i = 0; + + for (i = 0; i < numstarts; i++) + { + UINT32 dist = UINT32_MAX; + mapthing_t *checkstart = NULL; + + if (G_RaceGametype()) + { + checkstart = playerstarts[i]; + } + else if (G_BattleGametype()) + { + checkstart = deathmatchstarts[i]; + } + else + { + break; + } + + dist = (UINT32)P_AproxDistance((player->mo->x >> FRACBITS) - checkstart->x, + (player->mo->y >> FRACBITS) - checkstart->y); + + if (dist < bestdist) + { + beststart = checkstart; + bestdist = dist; + } + } + } + + if (beststart == NULL) + { + CONS_Alert(CONS_WARNING, "No respawn points!\n"); + player->respawnvars.pointx = 0; + player->respawnvars.pointy = 0; + player->respawnvars.pointz = 0; + player->respawnvars.flip = false; + } + else + { + sector_t *s; + fixed_t z = (beststart->options >> ZSHIFT) * FRACUNIT; + + player->respawnvars.pointx = beststart->x << FRACBITS; + player->respawnvars.pointy = beststart->y << FRACBITS; + + s = R_PointInSubsector(beststart->x << FRACBITS, beststart->y << FRACBITS)->sector; + + player->respawnvars.flip = (beststart->options & MTF_OBJECTFLIP); + + if (player->respawnvars.flip == true) + { + player->respawnvars.pointz = ( +#ifdef ESLOPE + s->c_slope ? P_GetZAt(s->c_slope, player->respawnvars.pointx, player->respawnvars.pointy) : +#endif + s->ceilingheight); + + if (z != 0) + { + player->respawnvars.pointz -= z; + } + } + else + { + player->respawnvars.pointz = ( +#ifdef ESLOPE + s->f_slope ? P_GetZAt(s->f_slope, player->respawnvars.pointx, player->respawnvars.pointy) : +#endif + s->floorheight); + + if (z) + { + player->respawnvars.pointz += z; + } + } + } + + player->respawnvars.pointz += K_RespawnOffset(player, player->respawnvars.flip); + player->respawnvars.distanceleft = 0; + } + + player->respawnvars.timer = RESPAWN_TIME; + player->respawnvars.respawnstate = RESPAWNST_MOVE; +} + +/*-------------------------------------------------- + static size_t K_NextRespawnWaypointIndex(waypoint_t *waypoint) + + Returns the index for the next respawn waypoint. + + Input Arguments:- + waypoint - Waypoint to look after. + + Return:- + An table index for waypoint_t -> nextwaypoints. +--------------------------------------------------*/ +static size_t K_NextRespawnWaypointIndex(waypoint_t *waypoint) +{ + size_t i = 0U; + size_t newwaypoint = SIZE_MAX; + + // Set to the first valid nextwaypoint, for simplicity's sake. + // If we reach the last waypoint and it's still not valid, just use it anyway. Someone needs to fix their map! + for (i = 0U; i < waypoint->numnextwaypoints; i++) + { + newwaypoint = i; + + if ((i == waypoint->numnextwaypoints - 1U) + || ((K_GetWaypointIsEnabled(waypoint->nextwaypoints[newwaypoint]) == true) + && (K_GetWaypointIsSpawnpoint(waypoint->nextwaypoints[newwaypoint]) == true))) + { + break; + } + } + + return newwaypoint; +} + +/*-------------------------------------------------- + static void K_MovePlayerToRespawnPoint(player_t *player) + + Handles the movement state of the respawn animation. + + Input Arguments:- + player - Player to preform for. + + Return:- + None +--------------------------------------------------*/ +static void K_MovePlayerToRespawnPoint(player_t *player) +{ + const fixed_t realstepamt = (64 * mapobjectscale); + fixed_t stepamt = realstepamt; + + vertex_t dest, step, laser; + angle_t stepha, stepva; + fixed_t dist, fulldist; + + UINT8 lasersteps = 4; + UINT32 laserdist; + waypoint_t *laserwp; + boolean laserflip; + + player->mo->momx = player->mo->momy = player->mo->momz = 0; + + player->powers[pw_flashing] = 2; + player->powers[pw_nocontrol] = 2; + + if (leveltime % 8 == 0 && !mapreset) + { + S_StartSound(player->mo, sfx_s3kcas); + } + + dest.x = player->respawnvars.pointx; + dest.y = player->respawnvars.pointy; + dest.z = player->respawnvars.pointz; + + dist = P_AproxDistance(P_AproxDistance( + player->mo->x - dest.x, + player->mo->y - dest.y), + player->mo->z - dest.z + ); + + if (dist <= stepamt) + { + // Reduce by the amount we needed to get to this waypoint + stepamt -= dist; + + // We've reached the destination point, + P_UnsetThingPosition(player->mo); + player->mo->x = dest.x; + player->mo->y = dest.y; + player->mo->z = dest.z; + P_SetThingPosition(player->mo); + + // Find the next waypoint to head towards + if (player->respawnvars.wp != NULL) + { + size_t nwp = K_NextRespawnWaypointIndex(player->respawnvars.wp); + + if (nwp == SIZE_MAX) + { + player->respawnvars.respawnstate = RESPAWNST_DROP; + return; + } + + // Set angle, regardless of if we're done or not + player->frameangle = R_PointToAngle2( + player->mo->x, player->mo->y, + dest.x, dest.y + ); + + if ((player->respawnvars.distanceleft == 0) + && (K_GetWaypointIsSpawnpoint(player->respawnvars.wp) == true)) + { + // Alright buddy, that's the end of the ride. + player->respawnvars.respawnstate = RESPAWNST_DROP; + return; + } + + if (player->respawnvars.distanceleft > player->respawnvars.wp->nextwaypointdistances[nwp]) + { + player->respawnvars.distanceleft -= player->respawnvars.wp->nextwaypointdistances[nwp]; + } + else + { + player->respawnvars.distanceleft = 0; + } + + player->respawnvars.wp = player->respawnvars.wp->nextwaypoints[nwp]; + K_RespawnAtWaypoint(player, player->respawnvars.wp); + + dest.x = player->respawnvars.pointx; + dest.y = player->respawnvars.pointy; + dest.z = player->respawnvars.pointz; + } + else + { + // We can now drop! + player->respawnvars.respawnstate = RESPAWNST_DROP; + return; + } + } + + stepha = R_PointToAngle2( + player->mo->x, player->mo->y, + dest.x, dest.y + ); + + stepva = R_PointToAngle2( + 0, player->mo->z, + P_AproxDistance(player->mo->x - dest.x, player->mo->y - dest.y), dest.z + ); + + // Move toward the respawn point + player->frameangle = stepha; + + step.x = FixedMul(FixedMul(FINECOSINE(stepha >> ANGLETOFINESHIFT), stepamt), FINECOSINE(stepva >> ANGLETOFINESHIFT)); + step.y = FixedMul(FixedMul(FINESINE(stepha >> ANGLETOFINESHIFT), stepamt), FINECOSINE(stepva >> ANGLETOFINESHIFT)); + step.z = FixedMul(FINESINE(stepva >> ANGLETOFINESHIFT), 2*stepamt); + + if (stepamt > 0) + { + player->mo->momx = step.x; + player->mo->momy = step.y; + player->mo->momz = step.z; + } + + // NOW THEN, time for loads of dumb duplication! + // "Emulate" the rest of the path, that way we can spawn a particle a certain distance ahead of you. + + if (stepamt != realstepamt) + { + // Reset back to default + stepamt = realstepamt; + + step.x = FixedMul(FixedMul(FINECOSINE(stepha >> ANGLETOFINESHIFT), stepamt), FINECOSINE(stepva >> ANGLETOFINESHIFT)); + step.y = FixedMul(FixedMul(FINESINE(stepha >> ANGLETOFINESHIFT), stepamt), FINECOSINE(stepva >> ANGLETOFINESHIFT)); + step.z = FixedMul(FINESINE(stepva >> ANGLETOFINESHIFT), 2*stepamt); + } + + laserdist = player->respawnvars.distanceleft; + laserwp = player->respawnvars.wp; + laserflip = player->respawnvars.flip; + + laser.x = player->mo->x + (step.x / 2); + laser.y = player->mo->y + (step.y / 2); + laser.z = player->mo->z + (step.z / 2); + + dist = P_AproxDistance(P_AproxDistance( + laser.x - dest.x, + laser.y - dest.y), + laser.z - dest.z + ); + fulldist = dist + (laserdist * FRACUNIT); + + while (lasersteps > 0) + { + if (fulldist <= stepamt) + { + break; + } + + if (dist <= stepamt) + { + size_t lnwp; + + laser.x = dest.x; + laser.y = dest.y; + laser.z = dest.z; + + if (laserdist <= 0) + { + break; + } + + lnwp = K_NextRespawnWaypointIndex(laserwp); + if (lnwp == SIZE_MAX) + { + break; + } + + if (laserdist > laserwp->nextwaypointdistances[lnwp]) + { + laserdist -= laserwp->nextwaypointdistances[lnwp]; + } + else + { + laserdist = 0; + } + + laserwp = laserwp->nextwaypoints[lnwp]; + + dest.x = laserwp->mobj->x; + dest.y = laserwp->mobj->y; + dest.z = laserwp->mobj->z; + laserflip = (laserwp->mobj->flags2 & MF2_OBJECTFLIP); + + if (laserflip == true) + { + dest.z -= (128 * mapobjectscale) - (player->mo->height); + } + else + { + dest.z += (128 * mapobjectscale); + } + + stepamt -= dist; + + stepha = R_PointToAngle2(laser.x, laser.y, dest.x, dest.y); + stepva = R_PointToAngle2(0, laser.z, P_AproxDistance(laser.x - dest.x, laser.y - dest.y), dest.z); + + step.x = FixedMul(FixedMul(FINECOSINE(stepha >> ANGLETOFINESHIFT), stepamt), FINECOSINE(stepva >> ANGLETOFINESHIFT)); + step.y = FixedMul(FixedMul(FINESINE(stepha >> ANGLETOFINESHIFT), stepamt), FINECOSINE(stepva >> ANGLETOFINESHIFT)); + step.z = FixedMul(FINESINE(stepva >> ANGLETOFINESHIFT), 2*stepamt); + } + else if (stepamt != realstepamt) + { + // Reset back to default + stepamt = realstepamt; + + step.x = FixedMul(FixedMul(FINECOSINE(stepha >> ANGLETOFINESHIFT), stepamt), FINECOSINE(stepva >> ANGLETOFINESHIFT)); + step.y = FixedMul(FixedMul(FINESINE(stepha >> ANGLETOFINESHIFT), stepamt), FINECOSINE(stepva >> ANGLETOFINESHIFT)); + step.z = FixedMul(FINESINE(stepva >> ANGLETOFINESHIFT), 2*stepamt); + } + + if (stepamt > 0) + { + laser.x += step.x; + laser.y += step.y; + laser.z += step.z; + } + + dist = P_AproxDistance(P_AproxDistance( + laser.x - dest.x, + laser.y - dest.y), + laser.z - dest.z + ); + fulldist = dist + (laserdist * FRACUNIT); + + lasersteps--; + } + + if (lasersteps == 0) // Don't spawn them beyond the respawn point. + { + mobj_t *lasermo = P_SpawnMobj(laser.x, laser.y, laser.z + (player->mo->height / 2), MT_DEZLASER); + + if (lasermo && !P_MobjWasRemoved(lasermo)) + { + P_SetMobjState(lasermo, S_DEZLASER_TRAIL1); + + if (player->mo->eflags & MFE_VERTICALFLIP) + { + lasermo->eflags |= MFE_VERTICALFLIP; + } + + P_SetTarget(&lasermo->target, player->mo); + + lasermo->angle = stepha + ANGLE_90; + P_SetScale(lasermo, (lasermo->destscale = player->mo->scale)); + } + } +} + +/*-------------------------------------------------- + static void K_HandleDropDash(player_t *player) + + Handles the visuals for the waiting period, + before you're allowed to Drop Dash. + + Input Arguments:- + player - Player to preform for. + + Return:- + None +--------------------------------------------------*/ +static void K_DropDashWait(player_t *player) +{ + player->respawnvars.timer--; + + if (leveltime % 8 == 0) + { + const UINT8 ns = 8; + const angle_t sidediff = FixedAngle((360 / ns) * FRACUNIT); + UINT8 i; + + if (!mapreset) + { + S_StartSound(player->mo, sfx_s3kcas); + } + + for (i = 0; i < ns; i++) + { + const angle_t newangle = sidediff * i; + vertex_t spawn; + mobj_t *laser; + + spawn.x = player->mo->x + P_ReturnThrustX(player->mo, newangle, 31 * player->mo->scale); + spawn.y = player->mo->y + P_ReturnThrustY(player->mo, newangle, 31 * player->mo->scale); + + if (player->mo->eflags & MFE_VERTICALFLIP) + { + spawn.z = player->mo->z + player->mo->height; + } + else + { + spawn.z = player->mo->z; + } + + laser = P_SpawnMobj(spawn.x, spawn.y, spawn.z, MT_DEZLASER); + + if (laser && !P_MobjWasRemoved(laser)) + { + if (player->mo->eflags & MFE_VERTICALFLIP) + { + laser->eflags |= MFE_VERTICALFLIP; + } + + P_SetTarget(&laser->target, player->mo); + + laser->angle = newangle + ANGLE_90; + laser->momz = (8 * player->mo->scale) * P_MobjFlip(player->mo); + P_SetScale(laser, (laser->destscale = player->mo->scale)); + } + } + } +} + + +/*-------------------------------------------------- + static void K_HandleDropDash(player_t *player) + + Handles input for the Drop Dash maneuver. + + Input Arguments:- + player - Player to preform for. + + Return:- + None +--------------------------------------------------*/ +static void K_HandleDropDash(player_t *player) +{ + ticcmd_t *cmd = &player->cmd; + + if (player->kartstuff[k_growshrinktimer] < 0) + { + player->mo->scalespeed = mapobjectscale/TICRATE; + player->mo->destscale = (6*mapobjectscale)/8; + + if (cv_kartdebugshrink.value && !modeattacking && !player->bot) + { + player->mo->destscale = (6*player->mo->destscale)/8; + } + } + + if (!P_IsObjectOnGround(player->mo)) + { + if (mapreset) + { + return; + } + + player->powers[pw_flashing] = K_GetKartFlashing(player); + + // The old behavior was stupid and prone to accidental usage. + // Let's rip off Mania instead, and turn this into a Drop Dash! + + if ((cmd->buttons & BT_ACCELERATE) && !player->kartstuff[k_spinouttimer]) // Since we're letting players spin out on respawn, don't let them charge a dropdash in this state. (It wouldn't work anyway) + { + player->respawnvars.dropdash++; + } + else + { + player->respawnvars.dropdash = 0; + } + + if (player->respawnvars.dropdash == TICRATE/4) + { + S_StartSound(player->mo, sfx_ddash); + } + + if ((player->respawnvars.dropdash >= TICRATE/4) && (player->respawnvars.dropdash & 1)) + { + player->mo->colorized = true; + } + else + { + player->mo->colorized = false; + } + } + else + { + if ((cmd->buttons & BT_ACCELERATE) && (player->respawnvars.dropdash >= TICRATE/4)) + { + S_StartSound(player->mo, sfx_s23c); + player->kartstuff[k_startboost] = 50; + K_SpawnDashDustRelease(player); + } + + player->mo->colorized = false; + player->respawnvars.dropdash = 0; + + //P_PlayRinglossSound(player->mo); + P_PlayerRingBurst(player, 3); + + if (G_BattleGametype()) + { + if (player->kartstuff[k_bumper] > 0) + { + if (player->kartstuff[k_bumper] == 1) + { + mobj_t *karmahitbox = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_KARMAHITBOX); // Player hitbox is too small!! + P_SetTarget(&karmahitbox->target, player->mo); + karmahitbox->destscale = player->mo->scale; + P_SetScale(karmahitbox, player->mo->scale); + CONS_Printf(M_GetText("%s lost all of their bumpers!\n"), player_names[player-players]); + } + player->kartstuff[k_bumper]--; + if (K_IsPlayerWanted(player)) + K_CalculateBattleWanted(); + } + + if (!player->kartstuff[k_bumper]) + { + player->kartstuff[k_comebacktimer] = comebacktime; + if (player->kartstuff[k_comebackmode] == 2) + { + mobj_t *poof = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_EXPLODE); + S_StartSound(poof, mobjinfo[MT_KARMAHITBOX].seesound); + player->kartstuff[k_comebackmode] = 0; + } + } + + K_CheckBumpers(); + } + + player->respawnvars.respawnstate = RESPAWNST_NONE; + } +} + +/*-------------------------------------------------- + void K_RespawnChecker(player_t *player) + + See header file for description. +--------------------------------------------------*/ +void K_RespawnChecker(player_t *player) +{ + if (player->respawnvars.respawnstate == RESPAWNST_NONE) + { + return; + } + + if (player->spectator) + { + player->respawnvars.respawnstate = RESPAWNST_NONE; + return; + } + + switch (player->respawnvars.respawnstate) + { + case RESPAWNST_MOVE: + player->mo->momx = player->mo->momy = player->mo->momz = 0; + K_MovePlayerToRespawnPoint(player); + return; + case RESPAWNST_DROP: + player->mo->momx = player->mo->momy = 0; + if (player->respawnvars.timer > 0) + { + player->mo->momz = 0; + K_DropDashWait(player); + } + else + { + K_HandleDropDash(player); + } + return; + default: + player->respawnvars.respawnstate = RESPAWNST_NONE; + return; + } +} diff --git a/src/k_respawn.h b/src/k_respawn.h new file mode 100644 index 000000000..f72a8133a --- /dev/null +++ b/src/k_respawn.h @@ -0,0 +1,72 @@ +// SONIC ROBO BLAST 2 KART +//----------------------------------------------------------------------------- +// Copyright (C) 2018-2020 by Kart Krew +// +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. +//----------------------------------------------------------------------------- +/// \file k_respawn.h +/// \brief Respawning logic + +#ifndef __K_RESPAWN__ +#define __K_RESPAWN__ + +#include "k_waypoint.h" +#include "d_player.h" + +#define RESPAWN_DIST 1024 +#define RESPAWN_TIME 48 +#define RESPAWNST_NONE 0 +#define RESPAWNST_MOVE 1 +#define RESPAWNST_DROP 2 + +/*-------------------------------------------------- + fixed_t K_RespawnOffset(player_t *player, boolean flip); + + Updates the player's flip flags, and returns a + Z offset for respawning. + + Input Arguments:- + player - Player to preform this for. + flip - false for normal, true for gravity flip. + + Return:- + Z position offset. +--------------------------------------------------*/ + +fixed_t K_RespawnOffset(player_t *player, boolean flip); + + +/*-------------------------------------------------- + void K_DoIngameRespawn(player_t *player); + + Starts the respawning animation for the specified player, + updating their respawn variables in preparation. + + Input Arguments:- + player - Player to preform this for. + + Return:- + None +--------------------------------------------------*/ + +void K_DoIngameRespawn(player_t *player); + + +/*-------------------------------------------------- + void K_RespawnChecker(player_t *player); + + Thinker for the respawning animation. + + Input Arguments:- + player - Player to preform this for. + + Return:- + true if the player is not supposed to collide with geometry, + otherwise false. +--------------------------------------------------*/ + +void K_RespawnChecker(player_t *player); + +#endif diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index 356cdd329..d5a610576 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -294,18 +294,8 @@ static int player_get(lua_State *L) lua_pushinteger(L, plr->weapondelay); else if (fastcmp(field,"tossdelay")) lua_pushinteger(L, plr->tossdelay); - else if (fastcmp(field,"starpostx")) - lua_pushinteger(L, plr->starpostx); - else if (fastcmp(field,"starposty")) - lua_pushinteger(L, plr->starposty); - else if (fastcmp(field,"starpostz")) - lua_pushinteger(L, plr->starpostz); else if (fastcmp(field,"starpostnum")) lua_pushinteger(L, plr->starpostnum); - else if (fastcmp(field,"starposttime")) - lua_pushinteger(L, plr->starposttime); - else if (fastcmp(field,"starpostangle")) - lua_pushangle(L, plr->starpostangle); else if (fastcmp(field,"angle_pos")) lua_pushangle(L, plr->angle_pos); else if (fastcmp(field,"old_angle_pos")) @@ -544,18 +534,8 @@ static int player_set(lua_State *L) plr->weapondelay = (INT32)luaL_checkinteger(L, 3); else if (fastcmp(field,"tossdelay")) plr->tossdelay = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"starpostx")) - plr->starpostx = (INT16)luaL_checkinteger(L, 3); - else if (fastcmp(field,"starposty")) - plr->starposty = (INT16)luaL_checkinteger(L, 3); - else if (fastcmp(field,"starpostz")) - plr->starpostz = (INT16)luaL_checkinteger(L, 3); else if (fastcmp(field,"starpostnum")) plr->starpostnum = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"starposttime")) - plr->starposttime = (tic_t)luaL_checkinteger(L, 3); - else if (fastcmp(field,"starpostangle")) - plr->starpostangle = luaL_checkangle(L, 3); else if (fastcmp(field,"angle_pos")) plr->angle_pos = luaL_checkangle(L, 3); else if (fastcmp(field,"old_angle_pos")) diff --git a/src/m_cheat.c b/src/m_cheat.c index 894633eff..b10e6d282 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -682,13 +682,11 @@ void Command_Savecheckpoint_f(void) REQUIRE_INLEVEL; REQUIRE_SINGLEPLAYER; - players[consoleplayer].starposttime = players[consoleplayer].realtime; - players[consoleplayer].starpostx = players[consoleplayer].mo->x>>FRACBITS; - players[consoleplayer].starposty = players[consoleplayer].mo->y>>FRACBITS; - players[consoleplayer].starpostz = players[consoleplayer].mo->floorz>>FRACBITS; - players[consoleplayer].starpostangle = players[consoleplayer].mo->angle; + players[consoleplayer].respawnvars.pointx = players[consoleplayer].mo->x; + players[consoleplayer].respawnvars.pointy = players[consoleplayer].mo->y; + players[consoleplayer].respawnvars.pointz = players[consoleplayer].mo->floorz; - CONS_Printf(M_GetText("Temporary checkpoint created at %d, %d, %d\n"), players[consoleplayer].starpostx, players[consoleplayer].starposty, players[consoleplayer].starpostz); + CONS_Printf(M_GetText("Temporary checkpoint created at %d, %d, %d\n"), players[consoleplayer].respawnvars.pointx, players[consoleplayer].respawnvars.pointy, players[consoleplayer].respawnvars.pointz); } // Like M_GetAllEmeralds() but for console devmode junkies. diff --git a/src/p_enemy.c b/src/p_enemy.c index 4b5818f73..e3f04ae8c 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -26,6 +26,7 @@ #include "k_kart.h" // SRB2kart #include "k_waypoint.h" #include "k_battle.h" +#include "k_respawn.h" #ifdef HW3SOUND #include "hardware/hw3sound.h" @@ -5638,10 +5639,8 @@ void A_MixUp(mobj_t *actor) INT32 transspeed; //player speed // Starpost stuff - INT16 starpostx, starposty, starpostz; + fixed_t starpostx, starposty, starpostz; INT32 starpostnum; - tic_t starposttime; - angle_t starpostangle; INT32 mflags2; @@ -5680,22 +5679,20 @@ void A_MixUp(mobj_t *actor) z = players[one].mo->z; angle = players[one].mo->angle; - starpostx = players[one].starpostx; - starposty = players[one].starposty; - starpostz = players[one].starpostz; - starpostangle = players[one].starpostangle; + starpostx = players[one].respawnvars.pointx; + starposty = players[one].respawnvars.pointy; + starpostz = players[one].respawnvars.pointz; starpostnum = players[one].starpostnum; - starposttime = players[one].starposttime; mflags2 = players[one].mo->flags2; P_MixUp(players[one].mo, players[two].mo->x, players[two].mo->y, players[two].mo->z, players[two].mo->angle, - players[two].starpostx, players[two].starposty, players[two].starpostz, - players[two].starpostnum, players[two].starposttime, players[two].starpostangle, + players[two].respawnvars.pointx, players[two].respawnvars.pointy, players[two].respawnvars.pointz, + players[two].starpostnum, 0, 0, players[two].mo->flags2); P_MixUp(players[two].mo, x, y, z, angle, starpostx, starposty, starpostz, - starpostnum, starposttime, starpostangle, + starpostnum, 0, 0, mflags2); //flags set after mixup. Stupid P_ResetPlayer() takes away some of the flags we look for... @@ -5720,10 +5717,8 @@ void A_MixUp(mobj_t *actor) INT32 transspeed[MAXPLAYERS]; //player speed // Star post stuff - INT16 spposition[MAXPLAYERS][3]; + fixed_t spposition[MAXPLAYERS][3]; INT32 starpostnum[MAXPLAYERS]; - tic_t starposttime[MAXPLAYERS]; - angle_t starpostangle[MAXPLAYERS]; INT32 flags2[MAXPLAYERS]; @@ -5754,12 +5749,10 @@ void A_MixUp(mobj_t *actor) transspeed[counter] = players[i].speed; transtracer[counter] = players[i].mo->tracer; - spposition[counter][0] = players[i].starpostx; - spposition[counter][1] = players[i].starposty; - spposition[counter][2] = players[i].starpostz; + spposition[counter][0] = players[i].respawnvars.pointx; + spposition[counter][1] = players[i].respawnvars.pointy; + spposition[counter][2] = players[i].respawnvars.pointz; starpostnum[counter] = players[i].starpostnum; - starposttime[counter] = players[i].starposttime; - starpostangle[counter] = players[i].starpostangle; flags2[counter] = players[i].mo->flags2; @@ -5799,7 +5792,7 @@ void A_MixUp(mobj_t *actor) P_MixUp(players[i].mo, position[teleportfrom][0], position[teleportfrom][1], position[teleportfrom][2], anglepos[teleportfrom], spposition[teleportfrom][0], spposition[teleportfrom][1], spposition[teleportfrom][2], - starpostnum[teleportfrom], starposttime[teleportfrom], starpostangle[teleportfrom], + starpostnum[teleportfrom], 0, 0, flags2[teleportfrom]); //...flags after. same reasoning. @@ -8612,7 +8605,7 @@ void A_SPBChase(mobj_t *actor) if (players[i].mo->health <= 0) continue; // dead - if (players[i].kartstuff[k_respawn]) + if (players[i].respawnvars.respawnstate != RESPAWNST_NONE) continue;*/ // respawning if (players[i].kartstuff[k_position] < bestrank) @@ -8789,7 +8782,7 @@ void A_SPBChase(mobj_t *actor) actor->lastlook = -1; // Just make sure this is reset - if (!player || !player->mo || player->mo->health <= 0 || player->kartstuff[k_respawn]) + if (!player || !player->mo || player->mo->health <= 0 || (player->respawnvars.respawnstate != RESPAWNST_NONE)) { // No one there? Completely STOP. actor->momx = actor->momy = actor->momz = 0; diff --git a/src/p_inter.c b/src/p_inter.c index 0492c25af..06b0cffa8 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1428,8 +1428,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) case MT_STARPOST: if (player->bot) return; - // - // SRB2kart: make sure the player will have enough checkpoints to touch + if (circuitmap && special->health - player->starpostnum > 1) { // blatant reuse of a variable that's normally unused in circuit @@ -1449,11 +1448,8 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (player->starpostnum >= special->health) return; // Already hit this post - // Save the player's time and position. - player->starposttime = player->realtime; //this makes race mode's timers work correctly whilst not affecting sp -x player->starpostnum = special->health; - //S_StartSound(toucher, special->info->painsound); return; case MT_FAKEMOBILE: diff --git a/src/p_map.c b/src/p_map.c index fec884f66..62aed169a 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -26,6 +26,7 @@ #include "w_wad.h" #include "k_kart.h" // SRB2kart 011617 #include "k_collide.h" +#include "k_respawn.h" #include "hu_stuff.h" // SRB2kart #include "i_system.h" // SRB2kart diff --git a/src/p_mobj.c b/src/p_mobj.c index 6aaf6b414..35eea0e18 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -38,6 +38,7 @@ #include "k_kart.h" #include "k_battle.h" #include "k_color.h" +#include "k_respawn.h" // protos. //static CV_PossibleValue_t viewheight_cons_t[] = {{16, "MIN"}, {56, "MAX"}, {0, NULL}}; @@ -11877,7 +11878,7 @@ void P_SpawnPlayer(INT32 playernum) // Spawn with a pity shield if necessary. //P_DoPityCheck(p); - if (p->kartstuff[k_respawn] != 0) + if (p->respawnvars.respawnstate != RESPAWNST_NONE) p->mo->flags |= MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOCLIPTHING|MF_NOGRAVITY; if (G_BattleGametype()) // SRB2kart @@ -12025,16 +12026,12 @@ void P_MovePlayerToSpawn(INT32 playernum, mapthing_t *mthing) z = ceiling - mobjinfo[MT_PLAYER].height; if (mthing->options >> ZSHIFT) z -= ((mthing->options >> ZSHIFT) << FRACBITS); - if (p->kartstuff[k_respawn]) - z -= 128*mapobjectscale; } else { z = floor; if (mthing->options >> ZSHIFT) z += ((mthing->options >> ZSHIFT) << FRACBITS); - if (p->kartstuff[k_respawn]) - z += 128*mapobjectscale; } if (mthing->options & MTF_OBJECTFLIP) // flip the player! @@ -12046,6 +12043,11 @@ void P_MovePlayerToSpawn(INT32 playernum, mapthing_t *mthing) else z = floor; + if (p->respawnvars.respawnstate != RESPAWNST_NONE) + { + z += K_RespawnOffset(p, (mthing->options & MTF_OBJECTFLIP)); + } + if (z < floor) z = floor; else if (z > ceiling - mobjinfo[MT_PLAYER].height) @@ -12078,9 +12080,11 @@ void P_MovePlayerToStarpost(INT32 playernum) mobj_t *mobj = p->mo; I_Assert(mobj != NULL); + K_DoIngameRespawn(p); + P_UnsetThingPosition(mobj); - mobj->x = p->starpostx << FRACBITS; - mobj->y = p->starposty << FRACBITS; + mobj->x = p->respawnvars.pointx; + mobj->y = p->respawnvars.pointy; P_SetThingPosition(mobj); sector = R_PointInSubsector(mobj->x, mobj->y)->sector; @@ -12095,12 +12099,7 @@ void P_MovePlayerToStarpost(INT32 playernum) #endif sector->ceilingheight; - if (mobj->player->kartstuff[k_starpostflip]) - z = (p->starpostz<height; - else - z = (p->starpostz<player->kartstuff[k_starpostflip] = 0; + z = p->respawnvars.pointz; if (z < floor) z = floor; @@ -12114,12 +12113,7 @@ void P_MovePlayerToStarpost(INT32 playernum) if (mobj->z == mobj->floorz) mobj->eflags |= MFE_ONGROUND; - mobj->angle = p->starpostangle; - P_AfterPlayerSpawn(playernum); - - //if (!(netgame || multiplayer)) - // leveltime = p->starposttime; } #define MAXHUNTEMERALDS 64 diff --git a/src/p_saveg.c b/src/p_saveg.c index b423d0f17..f873c2fdf 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -188,6 +188,7 @@ static void P_NetArchivePlayers(void) WRITEINT16(save_p, players[i].totalring); WRITEUINT32(save_p, players[i].realtime); WRITEUINT8(save_p, players[i].laps); + WRITEINT32(save_p, players[i].starpostnum); //////////////////// // CTF Mode Stuff // @@ -198,13 +199,6 @@ static void P_NetArchivePlayers(void) WRITEINT32(save_p, players[i].weapondelay); WRITEINT32(save_p, players[i].tossdelay); - WRITEUINT32(save_p, players[i].starposttime); - WRITEINT16(save_p, players[i].starpostx); - WRITEINT16(save_p, players[i].starposty); - WRITEINT16(save_p, players[i].starpostz); - WRITEINT32(save_p, players[i].starpostnum); - WRITEANGLE(save_p, players[i].starpostangle); - WRITEANGLE(save_p, players[i].angle_pos); WRITEANGLE(save_p, players[i].old_angle_pos); @@ -368,6 +362,7 @@ static void P_NetUnArchivePlayers(void) players[i].totalring = READINT16(save_p); // Total number of rings obtained for Race Mode players[i].realtime = READUINT32(save_p); // integer replacement for leveltime players[i].laps = READUINT8(save_p); // Number of laps (optional) + players[i].starpostnum = READINT32(save_p); //////////////////// // CTF Mode Stuff // @@ -378,13 +373,6 @@ static void P_NetUnArchivePlayers(void) players[i].weapondelay = READINT32(save_p); players[i].tossdelay = READINT32(save_p); - players[i].starposttime = READUINT32(save_p); - players[i].starpostx = READINT16(save_p); - players[i].starposty = READINT16(save_p); - players[i].starpostz = READINT16(save_p); - players[i].starpostnum = READINT32(save_p); - players[i].starpostangle = READANGLE(save_p); - players[i].angle_pos = READANGLE(save_p); players[i].old_angle_pos = READANGLE(save_p); diff --git a/src/p_setup.c b/src/p_setup.c index cd1cabdc9..574fb9ec0 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3250,13 +3250,7 @@ boolean P_SetupLevel(boolean skipprecip) else // gametype is GT_COOP or GT_RACE { players[i].mo = NULL; - - if (players[i].starposttime) - { - G_SpawnPlayer(i, true); - } - else - G_SpawnPlayer(i, false); + G_SpawnPlayer(i, (players[i].starpostnum != 0)); } } diff --git a/src/p_spec.c b/src/p_spec.c index 1873199e4..1bc00cbf9 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -37,6 +37,7 @@ #include "k_kart.h" // SRB2kart #include "console.h" // CON_LogMessage +#include "k_respawn.h" #ifdef HW3SOUND #include "hardware/hw3sound.h" @@ -2111,7 +2112,6 @@ static void K_HandleLapIncrement(player_t *player) curlap = 0; } - player->starposttime = player->realtime; player->starpostnum = 0; if (P_IsDisplayPlayer(player)) diff --git a/src/p_telept.c b/src/p_telept.c index dcfbe3a0b..a78f95961 100644 --- a/src/p_telept.c +++ b/src/p_telept.c @@ -38,6 +38,9 @@ void P_MixUp(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle, const INT32 takeflags2 = MF2_TWOD|MF2_OBJECTFLIP; UINT8 i; + (void)starposttime; + (void)starpostangle; + // the move is ok, // so link the thing into its new position P_UnsetThingPosition(thing); @@ -92,11 +95,9 @@ void P_MixUp(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle, thing->player->speed = 0; // Starpost information - thing->player->starpostx = starpostx; - thing->player->starposty = starposty; - thing->player->starpostz = starpostz; - thing->player->starposttime = starposttime; - thing->player->starpostangle = starpostangle; + thing->player->respawnvars.pointx = starpostx; + thing->player->respawnvars.pointy = starposty; + thing->player->respawnvars.pointz = starpostz; thing->player->starpostnum = starpostnum; P_ResetPlayer(thing->player); diff --git a/src/p_user.c b/src/p_user.c index 036c8a471..a11e472b2 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -47,6 +47,7 @@ #include "m_cond.h" // M_UpdateUnlockablesAndExtraEmblems #include "k_kart.h" #include "console.h" // CON_LogMessage +#include "k_respawn.h" #ifdef HW3SOUND #include "hardware/hw3sound.h" @@ -5772,7 +5773,7 @@ static void P_MovePlayer(player_t *player) // Kart: store the current turn range for later use if ((player->mo && player->speed > 0) // Moving || (leveltime > starttime && (cmd->buttons & BT_ACCELERATE && cmd->buttons & BT_BRAKE)) // Rubber-burn turn - || (player->kartstuff[k_respawn]) // Respawning + || (player->respawnvars.respawnstate != RESPAWNST_NONE) // Respawning || (player->spectator || objectplacing)) // Not a physical player { player->lturn_max[leveltime%MAXPREDICTTICS] = K_GetKartTurnValue(player, KART_FULLTURN)+1; @@ -8607,19 +8608,34 @@ void P_PlayerThink(player_t *player) player->linkcount = 0; } - // Move around. - // Reactiontime is used to prevent movement - // for a bit after a teleport. - if (player->mo->reactiontime) + if (player->respawnvars.respawnstate != RESPAWNST_NONE) + { + K_RespawnChecker(player); + player->rmomx = player->rmomy = 0; + + if (player->respawnvars.respawnstate == RESPAWNST_DROP) + { + // Allows some turning + P_MovePlayer(player); + } + } + else if (player->mo->reactiontime) + { + // Reactiontime is used to prevent movement + // for a bit after a teleport. player->mo->reactiontime--; + } else if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT) { P_DoZoomTube(player); - player->rmomx = player->rmomy = 0; // no actual momentum from your controls + player->rmomx = player->rmomy = 0; P_ResetScore(player); } else + { + // Move around. P_MovePlayer(player); + } if (!player->mo) return; // P_MovePlayer removed player->mo. @@ -8796,7 +8812,7 @@ void P_PlayerThink(player_t *player) if (!(//player->pflags & PF_NIGHTSMODE || player->kartstuff[k_hyudorotimer] // SRB2kart - fixes Hyudoro not flashing when it should. || player->kartstuff[k_growshrinktimer] > 0 // Grow doesn't flash either. - || player->kartstuff[k_respawn] // Respawn timer (for drop dash effect) + || (player->respawnvars.respawnstate != RESPAWNST_NONE) // Respawn timer (for drop dash effect) || (player->pflags & PF_TIMEOVER) // NO CONTEST explosion || (G_BattleGametype() && player->kartstuff[k_bumper] <= 0 && player->kartstuff[k_comebacktimer]) || leveltime < starttime)) // Level intro From 087945914203750c5f8904bc71135579c0f4ad2f Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Fri, 29 May 2020 10:37:34 -0400 Subject: [PATCH 15/28] Add distance based on air time Using the respawn command gives you barely any distance, while flying off huge MGZ pits gives you a bunch. --- src/d_clisrv.c | 2 ++ src/d_clisrv.h | 1 + src/d_player.h | 3 ++- src/k_respawn.c | 3 ++- src/lua_playerlib.c | 4 ++++ src/p_saveg.c | 2 ++ src/p_user.c | 38 +++++++++++++++++--------------------- 7 files changed, 30 insertions(+), 23 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index da80b29a4..954416098 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -574,6 +574,7 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i) rsp->kartstuff[j] = LONG(players[i].kartstuff[j]); // SRB2kart rsp->frameangle = (angle_t)LONG(players[i].frameangle); // SRB2kart + rsp->airtime = (tic_t)LONG(players[i].airtime); // Score is resynched in the rspfirm resync packet rsp->health = 0; // resynched with mo health @@ -693,6 +694,7 @@ static void resynch_read_player(resynch_pak *rsp) players[i].kartstuff[j] = LONG(rsp->kartstuff[j]); // SRB2kart players[i].frameangle = (angle_t)LONG(rsp->frameangle); // SRB2kart + players[i].airtime = (tic_t)LONG(rsp->airtime); // Score is resynched in the rspfirm resync packet players[i].health = rsp->health; diff --git a/src/d_clisrv.h b/src/d_clisrv.h index e0d6cd892..f7ded4c2b 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -215,6 +215,7 @@ typedef struct INT32 kartstuff[NUMKARTSTUFF]; // SRB2kart angle_t frameangle; // SRB2kart + tic_t airtime; // Score is resynched in the confirm resync packet INT32 health; diff --git a/src/d_player.h b/src/d_player.h index 60b5ca9bc..1f510c035 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -477,7 +477,8 @@ typedef struct player_s INT16 rturn_max[MAXPREDICTTICS]; // Ditto but for full-right UINT32 distancetofinish; waypoint_t *nextwaypoint; - respawnvars_t respawnvars; // SRB2Kart: respawn info + respawnvars_t respawnvars; // Respawn info + tic_t airtime; // Keep track of how long you've been in the air // Bit flags. // See pflags_t, above. diff --git a/src/k_respawn.c b/src/k_respawn.c index 7a828c59d..524e21fc7 100644 --- a/src/k_respawn.c +++ b/src/k_respawn.c @@ -110,8 +110,9 @@ void K_DoIngameRespawn(player_t *player) // Set up respawn position if invalid if (player->respawnvars.wp != NULL) { + const UINT32 dist = RESPAWN_DIST + (player->airtime * 32); + player->respawnvars.distanceleft = (dist * mapobjectscale) / FRACUNIT; K_RespawnAtWaypoint(player, player->respawnvars.wp); - player->respawnvars.distanceleft = (RESPAWN_DIST * mapobjectscale) / FRACUNIT; } else { diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index d5a610576..1eb1e3d5f 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -216,6 +216,8 @@ static int player_get(lua_State *L) LUA_PushUserdata(L, plr->kartstuff, META_KARTSTUFF); else if (fastcmp(field,"frameangle")) lua_pushangle(L, plr->frameangle); + else if (fastcmp(field,"airtime")) + lua_pushinteger(L, plr->airtime); else if (fastcmp(field,"pflags")) lua_pushinteger(L, plr->pflags); else if (fastcmp(field,"panim")) @@ -473,6 +475,8 @@ static int player_set(lua_State *L) return NOSET; else if (fastcmp(field,"frameangle")) plr->frameangle = luaL_checkangle(L, 3); + else if (fastcmp(field,"airtime")) + plr->airtime = (tic_t)luaL_checkinteger(L, 3); else if (fastcmp(field,"kartspeed")) plr->kartspeed = (UINT8)luaL_checkinteger(L, 3); else if (fastcmp(field,"kartweight")) diff --git a/src/p_saveg.c b/src/p_saveg.c index f873c2fdf..e343cb651 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -278,6 +278,7 @@ static void P_NetArchivePlayers(void) WRITEUINT32(save_p, players[i].distancetofinish); WRITEUINT32(save_p, K_GetWaypointHeapIndex(players[i].nextwaypoint)); + WRITEUINT32(save_p, players[i].airtime); } } @@ -443,6 +444,7 @@ static void P_NetUnArchivePlayers(void) players[i].distancetofinish = READUINT32(save_p); players[i].nextwaypoint = (waypoint_t *)(size_t)READUINT32(save_p); + players[i].airtime = READUINT32(save_p); } } diff --git a/src/p_user.c b/src/p_user.c index a11e472b2..be0cd41db 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -8361,16 +8361,6 @@ void P_PlayerThink(player_t *player) player->awayviewtics = 0; // reset to zero } - /* - if (player->pflags & PF_GLIDING) - { - if (player->panim != PA_ABILITY) - P_SetPlayerMobjState(player->mo, S_PLAY_ABL1); - } - else if ((player->pflags & PF_JUMPED) && !player->powers[pw_super] && player->panim != PA_ROLL && player->charability2 == CA2_SPINDASH) - P_SetPlayerMobjState(player->mo, S_PLAY_ATK1); - */ - if (player->flashcount) player->flashcount--; @@ -8383,21 +8373,33 @@ void P_PlayerThink(player_t *player) // The timer might've reached zero, but we'll run the remote view camera anyway by setting it to -1. } + // Track airtime + if (P_IsObjectOnGround(player->mo)) + { + player->airtime = 0; + } + else + { + player->airtime++; + } + cmd = &player->cmd; // SRB2kart // Save the dir the player is holding // to allow items to be thrown forward or backward. if (cmd->buttons & BT_FORWARD) + { player->kartstuff[k_throwdir] = 1; + } else if (cmd->buttons & BT_BACKWARD) + { player->kartstuff[k_throwdir] = -1; + } else + { player->kartstuff[k_throwdir] = 0; - - // Add some extra randomization. - if (cmd->forwardmove) - P_RandomFixed(); + } #ifdef PARANOIA if (player->playerstate == PST_REBORN) @@ -8531,15 +8533,9 @@ void P_PlayerThink(player_t *player) // SRB2kart 010217 if (leveltime < starttime) - player->powers[pw_nocontrol] = 2; - /* - if ((gametype == GT_RACE || gametype == GT_COMPETITION) && leveltime < 4*TICRATE) { - cmd->buttons &= BT_BRAKE; // Remove all buttons except BT_BRAKE - cmd->forwardmove = 0; - cmd->sidemove = 0; + player->powers[pw_nocontrol] = 2; } - */ // Synchronizes the "real" amount of time spent in the level. if (!player->exiting) From 2bfe5c9dd2fe67bb67de9a860ea76bb49f539a3e Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Fri, 29 May 2020 11:41:39 -0400 Subject: [PATCH 16/28] Noclip properly --- src/p_mobj.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 35eea0e18..96a1c7a0c 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -3750,7 +3750,8 @@ static void P_PlayerMobjThinker(mobj_t *mobj) mobj->eflags &= ~MFE_JUSTSTEPPEDDOWN; // Zoom tube - if (mobj->tracer && mobj->tracer->type == MT_TUBEWAYPOINT) + if ((mobj->tracer && mobj->tracer->type == MT_TUBEWAYPOINT) + || (mobj->player->respawnvars.respawnstate == RESPAWNST_MOVE)) { P_UnsetThingPosition(mobj); mobj->x += mobj->momx; @@ -11878,9 +11879,6 @@ void P_SpawnPlayer(INT32 playernum) // Spawn with a pity shield if necessary. //P_DoPityCheck(p); - if (p->respawnvars.respawnstate != RESPAWNST_NONE) - p->mo->flags |= MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOCLIPTHING|MF_NOGRAVITY; - if (G_BattleGametype()) // SRB2kart { mobj_t *overheadarrow = P_SpawnMobj(mobj->x, mobj->y, mobj->z + P_GetPlayerHeight(p)+16*FRACUNIT, MT_PLAYERARROW); From cf1c7f9f10ccb29984a4edd59305c3b4241c11d4 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Fri, 29 May 2020 11:49:32 -0400 Subject: [PATCH 17/28] FULLY fix the respawn finish line exploit, by adding a "P_HitSpecialLines" function --- src/p_map.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/p_maputl.h | 1 + src/p_mobj.c | 1 + 3 files changed, 96 insertions(+) diff --git a/src/p_map.c b/src/p_map.c index 62aed169a..ad0464ffa 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -2992,6 +2992,100 @@ boolean P_SceneryTryMove(mobj_t *thing, fixed_t x, fixed_t y) return true; } +// +// PTR_GetSpecialLines +// +static boolean PTR_GetSpecialLines(intercept_t *in) +{ + line_t *ld; + + I_Assert(in->isaline); + + ld = in->d.line; + + if (!ld->backsector) + { + return true; + } + + if (P_SpecialIsLinedefCrossType(ld->special)) + { + add_spechit(ld); + } + + return true; +} + +// +// P_HitSpecialLines +// Finds all special lines in the provided path and tries to cross them. +// For zoom tubes and respawning, which noclip but need to cross finish lines. +// +void P_HitSpecialLines(mobj_t *thing, fixed_t x, fixed_t y, fixed_t momx, fixed_t momy) +{ + fixed_t leadx, leady; + fixed_t trailx, traily; + line_t *ld = NULL; + INT32 side = 0, oldside = 0; + + I_Assert(thing != NULL); +#ifdef PARANOIA + if (P_MobjWasRemoved(thing)) + I_Error("Previously-removed Thing of type %u crashes P_CheckPosition!", thing->type); +#endif + + // reset special lines + numspechitint = 0U; + numspechit = 0U; + + // trace along the three leading corners + if (momx > 0) + { + leadx = thing->x + thing->radius; + trailx = thing->x - thing->radius; + } + else + { + leadx = thing->x - thing->radius; + trailx = thing->x + thing->radius; + } + + if (momy > 0) + { + leady = thing->y + thing->radius; + traily = thing->y - thing->radius; + } + else + { + leady = thing->y - thing->radius; + traily = thing->y + thing->radius; + } + + P_PathTraverse(leadx, leady, leadx + momx, leady + momy, PT_ADDLINES, PTR_GetSpecialLines); + P_PathTraverse(trailx, leady, trailx + momx, leady + momy, PT_ADDLINES, PTR_GetSpecialLines); + P_PathTraverse(leadx, traily, leadx + momx, traily + momy, PT_ADDLINES, PTR_GetSpecialLines); + + spechitint_copyinto(); + + // remove any duplicates that may be in spechitint + spechitint_removedups(); + + // handle any of the special lines that were crossed + while (numspechitint--) + { + ld = &lines[spechitint[numspechitint]]; + side = P_PointOnLineSide(x + momx, y + momy, ld); + oldside = P_PointOnLineSide(x, y, ld); + if (side != oldside) + { + if (ld->special) + { + P_CrossSpecialLine(ld, oldside, thing); + } + } + } +} + // // P_ThingHeightClip // Takes a valid thing and adjusts the thing->floorz, diff --git a/src/p_maputl.h b/src/p_maputl.h index 1fcb68d4c..c8b628780 100644 --- a/src/p_maputl.h +++ b/src/p_maputl.h @@ -53,6 +53,7 @@ void P_UnsetPrecipThingPosition(precipmobj_t *thing); void P_SetPrecipitationThingPosition(precipmobj_t *thing); void P_CreatePrecipSecNodeList(precipmobj_t *thing, fixed_t x,fixed_t y); boolean P_SceneryTryMove(mobj_t *thing, fixed_t x, fixed_t y); +void P_HitSpecialLines(mobj_t *thing, fixed_t x, fixed_t y, fixed_t momx, fixed_t momy); extern fixed_t opentop, openbottom, openrange, lowfloor, highceiling; #ifdef ESLOPE diff --git a/src/p_mobj.c b/src/p_mobj.c index 96a1c7a0c..fcf05d12e 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -3753,6 +3753,7 @@ static void P_PlayerMobjThinker(mobj_t *mobj) if ((mobj->tracer && mobj->tracer->type == MT_TUBEWAYPOINT) || (mobj->player->respawnvars.respawnstate == RESPAWNST_MOVE)) { + P_HitSpecialLines(mobj, mobj->x, mobj->y, mobj->momx, mobj->momy); P_UnsetThingPosition(mobj); mobj->x += mobj->momx; mobj->y += mobj->momy; From 285de3357d84457d7839193bc3acfe5d64306778 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Fri, 29 May 2020 13:12:07 -0400 Subject: [PATCH 18/28] Add back to resynch & savegame, shorten names of a few variables --- src/d_clisrv.c | 44 +++++++++++++---- src/d_clisrv.h | 19 ++++++-- src/d_player.h | 14 +++--- src/g_game.c | 13 ++++-- src/k_kart.c | 18 +++---- src/k_respawn.c | 122 ++++++++++++++++++++++++------------------------ src/m_cheat.c | 8 ++-- src/p_enemy.c | 18 +++---- src/p_map.c | 16 +++---- src/p_mobj.c | 10 ++-- src/p_saveg.c | 38 +++++++++++---- src/p_telept.c | 6 +-- src/p_user.c | 8 ++-- 13 files changed, 198 insertions(+), 136 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 954416098..f47c4ddff 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -570,11 +570,6 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i) for (j = 0; j < NUMPOWERS; ++j) rsp->powers[j] = (UINT16)SHORT(players[i].powers[j]); - for (j = 0; j < NUMKARTSTUFF; ++j) - rsp->kartstuff[j] = LONG(players[i].kartstuff[j]); // SRB2kart - - rsp->frameangle = (angle_t)LONG(players[i].frameangle); // SRB2kart - rsp->airtime = (tic_t)LONG(players[i].airtime); // Score is resynched in the rspfirm resync packet rsp->health = 0; // resynched with mo health @@ -641,6 +636,23 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i) rsp->splitscreenindex = players[i].splitscreenindex; + // SRB2kart + for (j = 0; j < NUMKARTSTUFF; ++j) + rsp->kartstuff[j] = LONG(players[i].kartstuff[j]); + + rsp->frameangle = (angle_t)LONG(players[i].frameangle); + rsp->airtime = (tic_t)LONG(players[i].airtime); + + // respawnvars_t + rsp->respawn_state = players[i].respawn.state; + rsp->respawn_pointx = (fixed_t)LONG(players[i].respawn.pointx); + rsp->respawn_pointy = (fixed_t)LONG(players[i].respawn.pointy); + rsp->respawn_pointz = (fixed_t)LONG(players[i].respawn.pointz); + rsp->respawn_flip = players[i].respawn.flip; + rsp->respawn_timer = (tic_t)LONG(players[i].respawn.timer); + rsp->respawn_distanceleft = (UINT32)LONG(players[i].respawn.distanceleft); + rsp->respawn_dropdash = (tic_t)LONG(players[i].respawn.dropdash); + rsp->hasmo = false; //Transfer important mo information if the player has a body. //This lets us resync players even if they are dead. @@ -690,11 +702,6 @@ static void resynch_read_player(resynch_pak *rsp) for (j = 0; j < NUMPOWERS; ++j) players[i].powers[j] = (UINT16)SHORT(rsp->powers[j]); - for (j = 0; j < NUMKARTSTUFF; ++j) - players[i].kartstuff[j] = LONG(rsp->kartstuff[j]); // SRB2kart - - players[i].frameangle = (angle_t)LONG(rsp->frameangle); // SRB2kart - players[i].airtime = (tic_t)LONG(rsp->airtime); // Score is resynched in the rspfirm resync packet players[i].health = rsp->health; @@ -760,6 +767,23 @@ static void resynch_read_player(resynch_pak *rsp) players[i].splitscreenindex = rsp->splitscreenindex; + // SRB2kart + for (j = 0; j < NUMKARTSTUFF; ++j) + players[i].kartstuff[j] = LONG(rsp->kartstuff[j]); + + players[i].frameangle = (angle_t)LONG(rsp->frameangle); + players[i].airtime = (tic_t)LONG(rsp->airtime); + + // respawnvars_t + players[i].respawn.state = rsp->respawn_state; + players[i].respawn.pointx = (fixed_t)LONG(rsp->respawn_pointx); + players[i].respawn.pointy = (fixed_t)LONG(rsp->respawn_pointy); + players[i].respawn.pointz = (fixed_t)LONG(rsp->respawn_pointz); + players[i].respawn.flip = (boolean)rsp->respawn_flip; + players[i].respawn.timer = (tic_t)LONG(rsp->respawn_timer); + players[i].respawn.distanceleft = (UINT32)LONG(rsp->respawn_distanceleft); + players[i].respawn.dropdash = (tic_t)LONG(rsp->respawn_dropdash); + //We get a packet for each player in game. if (!playeringame[i]) return; diff --git a/src/d_clisrv.h b/src/d_clisrv.h index f7ded4c2b..cb8069f10 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -213,10 +213,6 @@ typedef struct UINT16 powers[NUMPOWERS]; - INT32 kartstuff[NUMKARTSTUFF]; // SRB2kart - angle_t frameangle; // SRB2kart - tic_t airtime; - // Score is resynched in the confirm resync packet INT32 health; SINT8 lives; @@ -281,6 +277,21 @@ typedef struct UINT8 splitscreenindex; + // SRB2kart + INT32 kartstuff[NUMKARTSTUFF]; + angle_t frameangle; + tic_t airtime; + + // respawnvars_t + UINT8 respawn_state; + fixed_t respawn_pointx; + fixed_t respawn_pointy; + fixed_t respawn_pointz; + boolean respawn_flip; + tic_t respawn_timer; + UINT32 respawn_distanceleft; + tic_t respawn_dropdash; + //player->mo stuff UINT8 hasmo; // Boolean diff --git a/src/d_player.h b/src/d_player.h index 1f510c035..1011d70f6 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -420,15 +420,15 @@ typedef enum // player_t struct for all respawn variables typedef struct respawnvars_s { - UINT8 respawnstate; // 0: not respawning, 1: heading towards respawn point, 2: about to drop + UINT8 state; // 0: not respawning, 1: heading towards respawn point, 2: about to drop waypoint_t *wp; // Waypoint that we're going towards, NULL if the position isn't linked to one - INT32 pointx; // Respawn position coords to go towards - INT32 pointy; - INT32 pointz; + fixed_t pointx; // Respawn position coords to go towards + fixed_t pointy; + fixed_t pointz; boolean flip; // Flip upside down or not - INT32 timer; // Time left on respawn animation once you're there + tic_t timer; // Time left on respawn animation once you're there UINT32 distanceleft; // How far along the course to respawn you - INT32 dropdash; // Drop Dash charge timer + tic_t dropdash; // Drop Dash charge timer } respawnvars_t; // ======================================================================== @@ -477,7 +477,7 @@ typedef struct player_s INT16 rturn_max[MAXPREDICTTICS]; // Ditto but for full-right UINT32 distancetofinish; waypoint_t *nextwaypoint; - respawnvars_t respawnvars; // Respawn info + respawnvars_t respawn; // Respawn info tic_t airtime; // Keep track of how long you've been in the air // Bit flags. diff --git a/src/g_game.c b/src/g_game.c index b58ac24ac..48b2dfa29 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1588,7 +1588,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) // SRB2kart - no additional angle if not moving if ((player->mo && player->speed > 0) // Moving || (leveltime > starttime && (cmd->buttons & BT_ACCELERATE && cmd->buttons & BT_BRAKE)) // Rubber-burn turn - || (player->respawnvars.respawnstate != RESPAWNST_NONE) // Respawning + || (player->respawn.state != RESPAWNST_NONE) // Respawning || (player->spectator || objectplacing)) // Not a physical player lang += (cmd->angleturn<<16); @@ -2539,7 +2539,7 @@ static inline void G_PlayerFinishLevel(INT32 player) P_FlashPal(p, 0, 0); // Resets p->starpostnum = 0; - memset(&p->respawnvars, 0, sizeof (p->respawnvars)); + memset(&p->respawn, 0, sizeof (p->respawn)); // SRB2kart: Increment the "matches played" counter. if (player == consoleplayer) @@ -2588,6 +2588,7 @@ void G_PlayerReborn(INT32 player) SINT8 pity; // SRB2kart + respawnvars_t respawn; INT32 itemtype; INT32 itemamount; INT32 itemroulette; @@ -2673,6 +2674,8 @@ void G_PlayerReborn(INT32 player) wanted = players[player].kartstuff[k_wanted]; } + memcpy(&respawn, &players[player].respawn, sizeof (respawn)); + p = &players[player]; memset(p, 0, sizeof (*p)); @@ -2721,6 +2724,8 @@ void G_PlayerReborn(INT32 player) p->kartstuff[k_eggmanblame] = -1; p->kartstuff[k_lastdraft] = -1; + memcpy(&p->respawn, &respawn, sizeof (p->respawn)); + // Don't do anything immediately p->pflags |= PF_USEDOWN; p->pflags |= PF_ATTACKDOWN; @@ -4663,7 +4668,7 @@ void G_InitNew(UINT8 pencoremode, const char *mapname, boolean resetplayer, bool { players[i].playerstate = PST_REBORN; players[i].starpostnum = 0; - memset(&players[i].respawnvars, 0, sizeof (players[i].respawnvars)); + memset(&players[i].respawn, 0, sizeof (players[i].respawn)); #if 0 if (netgame || multiplayer) @@ -5185,7 +5190,7 @@ void G_ReadDemoTiccmd(ticcmd_t *cmd, INT32 playernum) // SRB2kart: Copy-pasted from ticcmd building, removes that crappy demo cam if (((players[displayplayers[0]].mo && players[displayplayers[0]].speed > 0) // Moving || (leveltime > starttime && (cmd->buttons & BT_ACCELERATE && cmd->buttons & BT_BRAKE)) // Rubber-burn turn - || (players[displayplayers[0]].respawnvars.respawnstate != RESPAWNST_NONE) // Respawning + || (players[displayplayers[0]].respawn.state != RESPAWNST_NONE) // Respawning || (players[displayplayers[0]].spectator || objectplacing)) // Not a physical player && !(players[displayplayers[0]].kartstuff[k_spinouttimer] && (players[displayplayers[0]].kartstuff[k_sneakertimer] || players[displayplayers[0]].kartstuff[k_levelbooster]))) // Spinning and boosting cancels out spinout diff --git a/src/k_kart.c b/src/k_kart.c index 36ff07cda..e7fe69c2d 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -963,8 +963,8 @@ void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid) || (mobj2->player && mobj2->player->playerstate != PST_LIVE)) return; - if ((mobj1->player && mobj1->player->respawnvars.respawnstate != RESPAWNST_NONE) - || (mobj2->player && mobj2->player->respawnvars.respawnstate != RESPAWNST_NONE)) + if ((mobj1->player && mobj1->player->respawn.state != RESPAWNST_NONE) + || (mobj2->player && mobj2->player->respawn.state != RESPAWNST_NONE)) return; { // Don't bump if you're flashing @@ -4842,7 +4842,7 @@ static void K_UpdateEngineSounds(player_t *player, ticcmd_t *cmd) #endif return; - if ((leveltime >= starttime-(2*TICRATE) && leveltime <= starttime) || (player->respawnvars.respawnstate == RESPAWNST_DROP)) // Startup boosts + if ((leveltime >= starttime-(2*TICRATE) && leveltime <= starttime) || (player->respawn.state == RESPAWNST_DROP)) // Startup boosts targetsnd = ((cmd->buttons & BT_ACCELERATE) ? 12 : 0); else targetsnd = (((6*cmd->forwardmove)/25) + ((player->speed / mapobjectscale)/5))/2; @@ -5243,7 +5243,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) } } - if (player->playerstate == PST_DEAD || (player->respawnvars.respawnstate == RESPAWNST_MOVE)) // Ensure these are set correctly here + if (player->playerstate == PST_DEAD || (player->respawn.state == RESPAWNST_MOVE)) // Ensure these are set correctly here { player->mo->colorized = false; player->mo->color = player->skincolor; @@ -5419,7 +5419,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) if (player->kartstuff[k_invincibilitytimer]) player->kartstuff[k_invincibilitytimer]--; - if ((player->respawnvars.respawnstate == RESPAWNST_NONE) && player->kartstuff[k_growshrinktimer] != 0) + if ((player->respawn.state == RESPAWNST_NONE) && player->kartstuff[k_growshrinktimer] != 0) { if (player->kartstuff[k_growshrinktimer] > 0) player->kartstuff[k_growshrinktimer]--; @@ -5489,7 +5489,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) if (G_BattleGametype() && player->kartstuff[k_bumper] > 0 && !player->kartstuff[k_spinouttimer] && !player->kartstuff[k_squishedtimer] - && (player->respawnvars.respawnstate == RESPAWNST_DROP) && !player->powers[pw_flashing]) + && (player->respawn.state == RESPAWNST_DROP) && !player->powers[pw_flashing]) { player->kartstuff[k_wanted]++; if (battleovertime.enabled >= 10*TICRATE) @@ -5809,13 +5809,13 @@ static waypoint_t *K_GetPlayerNextWaypoint(player_t *player) // Respawn point should only be updated when we're going to a nextwaypoint if ((updaterespawn) && - (player->respawnvars.respawnstate == RESPAWNST_NONE) && + (player->respawn.state == RESPAWNST_NONE) && (bestwaypoint != NULL) && (bestwaypoint != player->nextwaypoint) && (K_GetWaypointIsSpawnpoint(bestwaypoint)) && (K_GetWaypointIsEnabled(bestwaypoint) == true)) { - player->respawnvars.wp = bestwaypoint; + player->respawn.wp = bestwaypoint; } } @@ -6513,7 +6513,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) player->pflags |= PF_ATTACKDOWN; if (player && player->mo && player->mo->health > 0 && !player->spectator && !(player->exiting || mapreset) && leveltime > starttime - && player->kartstuff[k_spinouttimer] == 0 && player->kartstuff[k_squishedtimer] == 0 && (player->respawnvars.respawnstate == RESPAWNST_NONE)) + && player->kartstuff[k_spinouttimer] == 0 && player->kartstuff[k_squishedtimer] == 0 && (player->respawn.state == RESPAWNST_NONE)) { // First, the really specific, finicky items that function without the item being directly in your item slot. // Karma item dropping diff --git a/src/k_respawn.c b/src/k_respawn.c index 524e21fc7..59476ca28 100644 --- a/src/k_respawn.c +++ b/src/k_respawn.c @@ -72,11 +72,11 @@ static void K_RespawnAtWaypoint(player_t *player, waypoint_t *waypoint) return; } - player->respawnvars.pointx = waypoint->mobj->x; - player->respawnvars.pointy = waypoint->mobj->y; - player->respawnvars.pointz = waypoint->mobj->z; - player->respawnvars.flip = (waypoint->mobj->flags2 & MF2_OBJECTFLIP); - player->respawnvars.pointz += K_RespawnOffset(player, player->respawnvars.flip); + player->respawn.pointx = waypoint->mobj->x; + player->respawn.pointy = waypoint->mobj->y; + player->respawn.pointz = waypoint->mobj->z; + player->respawn.flip = (waypoint->mobj->flags2 & MF2_OBJECTFLIP); + player->respawn.pointz += K_RespawnOffset(player, player->respawn.flip); } /*-------------------------------------------------- @@ -91,7 +91,7 @@ void K_DoIngameRespawn(player_t *player) return; } - if (player->respawnvars.respawnstate != RESPAWNST_NONE) + if (player->respawn.state != RESPAWNST_NONE) { return; } @@ -108,11 +108,11 @@ void K_DoIngameRespawn(player_t *player) player->kartstuff[k_pogospring] = 0; // Set up respawn position if invalid - if (player->respawnvars.wp != NULL) + if (player->respawn.wp != NULL) { const UINT32 dist = RESPAWN_DIST + (player->airtime * 32); - player->respawnvars.distanceleft = (dist * mapobjectscale) / FRACUNIT; - K_RespawnAtWaypoint(player, player->respawnvars.wp); + player->respawn.distanceleft = (dist * mapobjectscale) / FRACUNIT; + K_RespawnAtWaypoint(player, player->respawn.wp); } else { @@ -165,57 +165,57 @@ void K_DoIngameRespawn(player_t *player) if (beststart == NULL) { CONS_Alert(CONS_WARNING, "No respawn points!\n"); - player->respawnvars.pointx = 0; - player->respawnvars.pointy = 0; - player->respawnvars.pointz = 0; - player->respawnvars.flip = false; + player->respawn.pointx = 0; + player->respawn.pointy = 0; + player->respawn.pointz = 0; + player->respawn.flip = false; } else { sector_t *s; fixed_t z = (beststart->options >> ZSHIFT) * FRACUNIT; - player->respawnvars.pointx = beststart->x << FRACBITS; - player->respawnvars.pointy = beststart->y << FRACBITS; + player->respawn.pointx = beststart->x << FRACBITS; + player->respawn.pointy = beststart->y << FRACBITS; s = R_PointInSubsector(beststart->x << FRACBITS, beststart->y << FRACBITS)->sector; - player->respawnvars.flip = (beststart->options & MTF_OBJECTFLIP); + player->respawn.flip = (beststart->options & MTF_OBJECTFLIP); - if (player->respawnvars.flip == true) + if (player->respawn.flip == true) { - player->respawnvars.pointz = ( + player->respawn.pointz = ( #ifdef ESLOPE - s->c_slope ? P_GetZAt(s->c_slope, player->respawnvars.pointx, player->respawnvars.pointy) : + s->c_slope ? P_GetZAt(s->c_slope, player->respawn.pointx, player->respawn.pointy) : #endif s->ceilingheight); if (z != 0) { - player->respawnvars.pointz -= z; + player->respawn.pointz -= z; } } else { - player->respawnvars.pointz = ( + player->respawn.pointz = ( #ifdef ESLOPE - s->f_slope ? P_GetZAt(s->f_slope, player->respawnvars.pointx, player->respawnvars.pointy) : + s->f_slope ? P_GetZAt(s->f_slope, player->respawn.pointx, player->respawn.pointy) : #endif s->floorheight); if (z) { - player->respawnvars.pointz += z; + player->respawn.pointz += z; } } } - player->respawnvars.pointz += K_RespawnOffset(player, player->respawnvars.flip); - player->respawnvars.distanceleft = 0; + player->respawn.pointz += K_RespawnOffset(player, player->respawn.flip); + player->respawn.distanceleft = 0; } - player->respawnvars.timer = RESPAWN_TIME; - player->respawnvars.respawnstate = RESPAWNST_MOVE; + player->respawn.timer = RESPAWN_TIME; + player->respawn.state = RESPAWNST_MOVE; } /*-------------------------------------------------- @@ -286,9 +286,9 @@ static void K_MovePlayerToRespawnPoint(player_t *player) S_StartSound(player->mo, sfx_s3kcas); } - dest.x = player->respawnvars.pointx; - dest.y = player->respawnvars.pointy; - dest.z = player->respawnvars.pointz; + dest.x = player->respawn.pointx; + dest.y = player->respawn.pointy; + dest.z = player->respawn.pointz; dist = P_AproxDistance(P_AproxDistance( player->mo->x - dest.x, @@ -309,13 +309,13 @@ static void K_MovePlayerToRespawnPoint(player_t *player) P_SetThingPosition(player->mo); // Find the next waypoint to head towards - if (player->respawnvars.wp != NULL) + if (player->respawn.wp != NULL) { - size_t nwp = K_NextRespawnWaypointIndex(player->respawnvars.wp); + size_t nwp = K_NextRespawnWaypointIndex(player->respawn.wp); if (nwp == SIZE_MAX) { - player->respawnvars.respawnstate = RESPAWNST_DROP; + player->respawn.state = RESPAWNST_DROP; return; } @@ -325,34 +325,34 @@ static void K_MovePlayerToRespawnPoint(player_t *player) dest.x, dest.y ); - if ((player->respawnvars.distanceleft == 0) - && (K_GetWaypointIsSpawnpoint(player->respawnvars.wp) == true)) + if ((player->respawn.distanceleft == 0) + && (K_GetWaypointIsSpawnpoint(player->respawn.wp) == true)) { // Alright buddy, that's the end of the ride. - player->respawnvars.respawnstate = RESPAWNST_DROP; + player->respawn.state = RESPAWNST_DROP; return; } - if (player->respawnvars.distanceleft > player->respawnvars.wp->nextwaypointdistances[nwp]) + if (player->respawn.distanceleft > player->respawn.wp->nextwaypointdistances[nwp]) { - player->respawnvars.distanceleft -= player->respawnvars.wp->nextwaypointdistances[nwp]; + player->respawn.distanceleft -= player->respawn.wp->nextwaypointdistances[nwp]; } else { - player->respawnvars.distanceleft = 0; + player->respawn.distanceleft = 0; } - player->respawnvars.wp = player->respawnvars.wp->nextwaypoints[nwp]; - K_RespawnAtWaypoint(player, player->respawnvars.wp); + player->respawn.wp = player->respawn.wp->nextwaypoints[nwp]; + K_RespawnAtWaypoint(player, player->respawn.wp); - dest.x = player->respawnvars.pointx; - dest.y = player->respawnvars.pointy; - dest.z = player->respawnvars.pointz; + dest.x = player->respawn.pointx; + dest.y = player->respawn.pointy; + dest.z = player->respawn.pointz; } else { // We can now drop! - player->respawnvars.respawnstate = RESPAWNST_DROP; + player->respawn.state = RESPAWNST_DROP; return; } } @@ -394,9 +394,9 @@ static void K_MovePlayerToRespawnPoint(player_t *player) step.z = FixedMul(FINESINE(stepva >> ANGLETOFINESHIFT), 2*stepamt); } - laserdist = player->respawnvars.distanceleft; - laserwp = player->respawnvars.wp; - laserflip = player->respawnvars.flip; + laserdist = player->respawn.distanceleft; + laserwp = player->respawn.wp; + laserflip = player->respawn.flip; laser.x = player->mo->x + (step.x / 2); laser.y = player->mo->y + (step.y / 2); @@ -531,7 +531,7 @@ static void K_MovePlayerToRespawnPoint(player_t *player) --------------------------------------------------*/ static void K_DropDashWait(player_t *player) { - player->respawnvars.timer--; + player->respawn.timer--; if (leveltime % 8 == 0) { @@ -622,19 +622,19 @@ static void K_HandleDropDash(player_t *player) if ((cmd->buttons & BT_ACCELERATE) && !player->kartstuff[k_spinouttimer]) // Since we're letting players spin out on respawn, don't let them charge a dropdash in this state. (It wouldn't work anyway) { - player->respawnvars.dropdash++; + player->respawn.dropdash++; } else { - player->respawnvars.dropdash = 0; + player->respawn.dropdash = 0; } - if (player->respawnvars.dropdash == TICRATE/4) + if (player->respawn.dropdash == TICRATE/4) { S_StartSound(player->mo, sfx_ddash); } - if ((player->respawnvars.dropdash >= TICRATE/4) && (player->respawnvars.dropdash & 1)) + if ((player->respawn.dropdash >= TICRATE/4) && (player->respawn.dropdash & 1)) { player->mo->colorized = true; } @@ -645,7 +645,7 @@ static void K_HandleDropDash(player_t *player) } else { - if ((cmd->buttons & BT_ACCELERATE) && (player->respawnvars.dropdash >= TICRATE/4)) + if ((cmd->buttons & BT_ACCELERATE) && (player->respawn.dropdash >= TICRATE/4)) { S_StartSound(player->mo, sfx_s23c); player->kartstuff[k_startboost] = 50; @@ -653,7 +653,7 @@ static void K_HandleDropDash(player_t *player) } player->mo->colorized = false; - player->respawnvars.dropdash = 0; + player->respawn.dropdash = 0; //P_PlayRinglossSound(player->mo); P_PlayerRingBurst(player, 3); @@ -689,7 +689,7 @@ static void K_HandleDropDash(player_t *player) K_CheckBumpers(); } - player->respawnvars.respawnstate = RESPAWNST_NONE; + player->respawn.state = RESPAWNST_NONE; } } @@ -700,18 +700,18 @@ static void K_HandleDropDash(player_t *player) --------------------------------------------------*/ void K_RespawnChecker(player_t *player) { - if (player->respawnvars.respawnstate == RESPAWNST_NONE) + if (player->respawn.state == RESPAWNST_NONE) { return; } if (player->spectator) { - player->respawnvars.respawnstate = RESPAWNST_NONE; + player->respawn.state = RESPAWNST_NONE; return; } - switch (player->respawnvars.respawnstate) + switch (player->respawn.state) { case RESPAWNST_MOVE: player->mo->momx = player->mo->momy = player->mo->momz = 0; @@ -719,7 +719,7 @@ void K_RespawnChecker(player_t *player) return; case RESPAWNST_DROP: player->mo->momx = player->mo->momy = 0; - if (player->respawnvars.timer > 0) + if (player->respawn.timer > 0) { player->mo->momz = 0; K_DropDashWait(player); @@ -730,7 +730,7 @@ void K_RespawnChecker(player_t *player) } return; default: - player->respawnvars.respawnstate = RESPAWNST_NONE; + player->respawn.state = RESPAWNST_NONE; return; } } diff --git a/src/m_cheat.c b/src/m_cheat.c index b10e6d282..01e9ae5fa 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -682,11 +682,11 @@ void Command_Savecheckpoint_f(void) REQUIRE_INLEVEL; REQUIRE_SINGLEPLAYER; - players[consoleplayer].respawnvars.pointx = players[consoleplayer].mo->x; - players[consoleplayer].respawnvars.pointy = players[consoleplayer].mo->y; - players[consoleplayer].respawnvars.pointz = players[consoleplayer].mo->floorz; + players[consoleplayer].respawn.pointx = players[consoleplayer].mo->x; + players[consoleplayer].respawn.pointy = players[consoleplayer].mo->y; + players[consoleplayer].respawn.pointz = players[consoleplayer].mo->floorz; - CONS_Printf(M_GetText("Temporary checkpoint created at %d, %d, %d\n"), players[consoleplayer].respawnvars.pointx, players[consoleplayer].respawnvars.pointy, players[consoleplayer].respawnvars.pointz); + CONS_Printf(M_GetText("Temporary checkpoint created at %d, %d, %d\n"), players[consoleplayer].respawn.pointx, players[consoleplayer].respawn.pointy, players[consoleplayer].respawn.pointz); } // Like M_GetAllEmeralds() but for console devmode junkies. diff --git a/src/p_enemy.c b/src/p_enemy.c index e3f04ae8c..c5601ba4d 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -5679,15 +5679,15 @@ void A_MixUp(mobj_t *actor) z = players[one].mo->z; angle = players[one].mo->angle; - starpostx = players[one].respawnvars.pointx; - starposty = players[one].respawnvars.pointy; - starpostz = players[one].respawnvars.pointz; + starpostx = players[one].respawn.pointx; + starposty = players[one].respawn.pointy; + starpostz = players[one].respawn.pointz; starpostnum = players[one].starpostnum; mflags2 = players[one].mo->flags2; P_MixUp(players[one].mo, players[two].mo->x, players[two].mo->y, players[two].mo->z, players[two].mo->angle, - players[two].respawnvars.pointx, players[two].respawnvars.pointy, players[two].respawnvars.pointz, + players[two].respawn.pointx, players[two].respawn.pointy, players[two].respawn.pointz, players[two].starpostnum, 0, 0, players[two].mo->flags2); @@ -5749,9 +5749,9 @@ void A_MixUp(mobj_t *actor) transspeed[counter] = players[i].speed; transtracer[counter] = players[i].mo->tracer; - spposition[counter][0] = players[i].respawnvars.pointx; - spposition[counter][1] = players[i].respawnvars.pointy; - spposition[counter][2] = players[i].respawnvars.pointz; + spposition[counter][0] = players[i].respawn.pointx; + spposition[counter][1] = players[i].respawn.pointy; + spposition[counter][2] = players[i].respawn.pointz; starpostnum[counter] = players[i].starpostnum; flags2[counter] = players[i].mo->flags2; @@ -8605,7 +8605,7 @@ void A_SPBChase(mobj_t *actor) if (players[i].mo->health <= 0) continue; // dead - if (players[i].respawnvars.respawnstate != RESPAWNST_NONE) + if (players[i].respawn.state != RESPAWNST_NONE) continue;*/ // respawning if (players[i].kartstuff[k_position] < bestrank) @@ -8782,7 +8782,7 @@ void A_SPBChase(mobj_t *actor) actor->lastlook = -1; // Just make sure this is reset - if (!player || !player->mo || player->mo->health <= 0 || (player->respawnvars.respawnstate != RESPAWNST_NONE)) + if (!player || !player->mo || player->mo->health <= 0 || (player->respawn.state != RESPAWNST_NONE)) { // No one there? Completely STOP. actor->momx = actor->momy = actor->momz = 0; diff --git a/src/p_map.c b/src/p_map.c index ad0464ffa..fcbb2d692 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -3041,24 +3041,24 @@ void P_HitSpecialLines(mobj_t *thing, fixed_t x, fixed_t y, fixed_t momx, fixed_ // trace along the three leading corners if (momx > 0) { - leadx = thing->x + thing->radius; - trailx = thing->x - thing->radius; + leadx = x + thing->radius; + trailx = x - thing->radius; } else { - leadx = thing->x - thing->radius; - trailx = thing->x + thing->radius; + leadx = x - thing->radius; + trailx = x + thing->radius; } if (momy > 0) { - leady = thing->y + thing->radius; - traily = thing->y - thing->radius; + leady = y + thing->radius; + traily = y - thing->radius; } else { - leady = thing->y - thing->radius; - traily = thing->y + thing->radius; + leady = y - thing->radius; + traily = y + thing->radius; } P_PathTraverse(leadx, leady, leadx + momx, leady + momy, PT_ADDLINES, PTR_GetSpecialLines); diff --git a/src/p_mobj.c b/src/p_mobj.c index fcf05d12e..b1d00c0a5 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -3751,7 +3751,7 @@ static void P_PlayerMobjThinker(mobj_t *mobj) // Zoom tube if ((mobj->tracer && mobj->tracer->type == MT_TUBEWAYPOINT) - || (mobj->player->respawnvars.respawnstate == RESPAWNST_MOVE)) + || (mobj->player->respawn.state == RESPAWNST_MOVE)) { P_HitSpecialLines(mobj, mobj->x, mobj->y, mobj->momx, mobj->momy); P_UnsetThingPosition(mobj); @@ -12042,7 +12042,7 @@ void P_MovePlayerToSpawn(INT32 playernum, mapthing_t *mthing) else z = floor; - if (p->respawnvars.respawnstate != RESPAWNST_NONE) + if (p->respawn.state != RESPAWNST_NONE) { z += K_RespawnOffset(p, (mthing->options & MTF_OBJECTFLIP)); } @@ -12082,8 +12082,8 @@ void P_MovePlayerToStarpost(INT32 playernum) K_DoIngameRespawn(p); P_UnsetThingPosition(mobj); - mobj->x = p->respawnvars.pointx; - mobj->y = p->respawnvars.pointy; + mobj->x = p->respawn.pointx; + mobj->y = p->respawn.pointy; P_SetThingPosition(mobj); sector = R_PointInSubsector(mobj->x, mobj->y)->sector; @@ -12098,7 +12098,7 @@ void P_MovePlayerToStarpost(INT32 playernum) #endif sector->ceilingheight; - z = p->respawnvars.pointz; + z = p->respawn.pointz; if (z < floor) z = floor; diff --git a/src/p_saveg.c b/src/p_saveg.c index e343cb651..e854b4b42 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -141,10 +141,6 @@ static void P_NetArchivePlayers(void) for (j = 0; j < NUMPOWERS; j++) WRITEUINT16(save_p, players[i].powers[j]); - for (j = 0; j < NUMKARTSTUFF; j++) - WRITEINT32(save_p, players[i].kartstuff[j]); - - WRITEANGLE(save_p, players[i].frameangle); WRITEUINT8(save_p, players[i].playerstate); WRITEUINT32(save_p, players[i].pflags); @@ -270,15 +266,30 @@ static void P_NetArchivePlayers(void) WRITEUINT8(save_p, players[i].kartweight); // + for (j = 0; j < NUMKARTSTUFF; j++) + WRITEINT32(save_p, players[i].kartstuff[j]); + for (j = 0; j < MAXPREDICTTICS; j++) { WRITEINT16(save_p, players[i].lturn_max[j]); WRITEINT16(save_p, players[i].rturn_max[j]); } + WRITEANGLE(save_p, players[i].frameangle); WRITEUINT32(save_p, players[i].distancetofinish); WRITEUINT32(save_p, K_GetWaypointHeapIndex(players[i].nextwaypoint)); WRITEUINT32(save_p, players[i].airtime); + + // respawnvars_t + WRITEUINT8(save_p, players[i].respawn.state); + WRITEUINT32(save_p, K_GetWaypointHeapIndex(players[i].respawn.wp)); + WRITEFIXED(save_p, players[i].respawn.pointx); + WRITEFIXED(save_p, players[i].respawn.pointy); + WRITEFIXED(save_p, players[i].respawn.pointz); + WRITEUINT8(save_p, players[i].respawn.flip); + WRITEUINT32(save_p, players[i].respawn.timer); + WRITEUINT32(save_p, players[i].respawn.distanceleft); + WRITEUINT32(save_p, players[i].respawn.dropdash); } } @@ -316,10 +327,6 @@ static void P_NetUnArchivePlayers(void) for (j = 0; j < NUMPOWERS; j++) players[i].powers[j] = READUINT16(save_p); - for (j = 0; j < NUMKARTSTUFF; j++) - players[i].kartstuff[j] = READINT32(save_p); - - players[i].frameangle = READANGLE(save_p); players[i].playerstate = READUINT8(save_p); players[i].pflags = READUINT32(save_p); @@ -436,15 +443,30 @@ static void P_NetUnArchivePlayers(void) players[i].kartweight = READUINT8(save_p); // + for (j = 0; j < NUMKARTSTUFF; j++) + players[i].kartstuff[j] = READINT32(save_p); + for (j = 0; j < MAXPREDICTTICS; j++) { players[i].lturn_max[j] = READINT16(save_p); players[i].rturn_max[j] = READINT16(save_p); } + players[i].frameangle = READANGLE(save_p); players[i].distancetofinish = READUINT32(save_p); players[i].nextwaypoint = (waypoint_t *)(size_t)READUINT32(save_p); players[i].airtime = READUINT32(save_p); + + // respawnvars_t + players[i].respawn.state = READUINT8(save_p); + players[i].respawn.wp = (waypoint_t *)(size_t)READUINT32(save_p); + players[i].respawn.pointx = READFIXED(save_p); + players[i].respawn.pointy = READFIXED(save_p); + players[i].respawn.pointz = READFIXED(save_p); + players[i].respawn.flip = (boolean)READUINT8(save_p); + players[i].respawn.timer = READUINT32(save_p); + players[i].respawn.distanceleft = READUINT32(save_p); + players[i].respawn.dropdash = READUINT32(save_p); } } diff --git a/src/p_telept.c b/src/p_telept.c index a78f95961..5f834c596 100644 --- a/src/p_telept.c +++ b/src/p_telept.c @@ -95,9 +95,9 @@ void P_MixUp(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle, thing->player->speed = 0; // Starpost information - thing->player->respawnvars.pointx = starpostx; - thing->player->respawnvars.pointy = starposty; - thing->player->respawnvars.pointz = starpostz; + thing->player->respawn.pointx = starpostx; + thing->player->respawn.pointy = starposty; + thing->player->respawn.pointz = starpostz; thing->player->starpostnum = starpostnum; P_ResetPlayer(thing->player); diff --git a/src/p_user.c b/src/p_user.c index be0cd41db..5be3e779e 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -5773,7 +5773,7 @@ static void P_MovePlayer(player_t *player) // Kart: store the current turn range for later use if ((player->mo && player->speed > 0) // Moving || (leveltime > starttime && (cmd->buttons & BT_ACCELERATE && cmd->buttons & BT_BRAKE)) // Rubber-burn turn - || (player->respawnvars.respawnstate != RESPAWNST_NONE) // Respawning + || (player->respawn.state != RESPAWNST_NONE) // Respawning || (player->spectator || objectplacing)) // Not a physical player { player->lturn_max[leveltime%MAXPREDICTTICS] = K_GetKartTurnValue(player, KART_FULLTURN)+1; @@ -8604,12 +8604,12 @@ void P_PlayerThink(player_t *player) player->linkcount = 0; } - if (player->respawnvars.respawnstate != RESPAWNST_NONE) + if (player->respawn.state != RESPAWNST_NONE) { K_RespawnChecker(player); player->rmomx = player->rmomy = 0; - if (player->respawnvars.respawnstate == RESPAWNST_DROP) + if (player->respawn.state == RESPAWNST_DROP) { // Allows some turning P_MovePlayer(player); @@ -8808,7 +8808,7 @@ void P_PlayerThink(player_t *player) if (!(//player->pflags & PF_NIGHTSMODE || player->kartstuff[k_hyudorotimer] // SRB2kart - fixes Hyudoro not flashing when it should. || player->kartstuff[k_growshrinktimer] > 0 // Grow doesn't flash either. - || (player->respawnvars.respawnstate != RESPAWNST_NONE) // Respawn timer (for drop dash effect) + || (player->respawn.state != RESPAWNST_NONE) // Respawn timer (for drop dash effect) || (player->pflags & PF_TIMEOVER) // NO CONTEST explosion || (G_BattleGametype() && player->kartstuff[k_bumper] <= 0 && player->kartstuff[k_comebacktimer]) || leveltime < starttime)) // Level intro From eba79e77fcf64c03800982db9741977b6cf8a5a1 Mon Sep 17 00:00:00 2001 From: toaster Date: Sun, 31 May 2020 20:31:55 +0100 Subject: [PATCH 19/28] Serialise shadowscale. --- src/p_saveg.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/p_saveg.c b/src/p_saveg.c index 5aa988075..4e786a65f 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -955,10 +955,11 @@ typedef enum MD2_COLORIZED = 1<<9, MD2_WAYPOINTCAP = 1<<10, MD2_KITEMCAP = 1<<11, - MD2_ITNEXT = 1<<12 + MD2_ITNEXT = 1<<12, #ifdef ESLOPE - , MD2_SLOPE = 1<<13 + MD2_SLOPE = 1<<13, #endif + MD2_SHADOWSCALE = 1<<14, } mobj_diff2_t; typedef enum @@ -1155,6 +1156,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) if (mobj->standingslope) diff2 |= MD2_SLOPE; #endif + if (mobj->shadowscale) + diff2 |= MD2_SHADOWSCALE; if (mobj->colorized) diff2 |= MD2_COLORIZED; if (mobj == waypointcap) @@ -1284,6 +1287,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) #endif if (diff2 & MD2_COLORIZED) WRITEUINT8(save_p, mobj->colorized); + if (diff2 & MD2_SHADOWSCALE) + WRITEFIXED(save_p, mobj->shadowscale); WRITEUINT32(save_p, mobj->mobjnum); } @@ -2211,6 +2216,8 @@ static void LoadMobjThinker(actionf_p1 thinker) #endif if (diff2 & MD2_COLORIZED) mobj->colorized = READUINT8(save_p); + if (diff2 & MD2_SHADOWSCALE) + mobj->shadowscale = READFIXED(save_p); if (diff & MD_REDFLAG) { From d336f248602d1d2a6ac1e97272a6e09a0d209e96 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 1 Jun 2020 15:49:51 -0400 Subject: [PATCH 20/28] Move kart .o --- src/Makefile | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Makefile b/src/Makefile index 7039a082f..59b8dd382 100644 --- a/src/Makefile +++ b/src/Makefile @@ -505,15 +505,6 @@ OBJS:=$(i_main_o) \ $(OBJDIR)/hu_stuff.o \ $(OBJDIR)/y_inter.o \ $(OBJDIR)/st_stuff.o \ - $(OBJDIR)/k_kart.o \ - $(OBJDIR)/k_respawn.o\ - $(OBJDIR)/k_collide.o\ - $(OBJDIR)/k_color.o \ - $(OBJDIR)/k_battle.o \ - $(OBJDIR)/k_pwrlv.o \ - $(OBJDIR)/k_waypoint.o\ - $(OBJDIR)/k_pathfind.o\ - $(OBJDIR)/k_bheap.o \ $(OBJDIR)/m_aatree.o \ $(OBJDIR)/m_anigif.o \ $(OBJDIR)/m_argv.o \ @@ -563,6 +554,15 @@ OBJS:=$(i_main_o) \ $(OBJDIR)/i_tcp.o \ $(OBJDIR)/lzf.o \ $(OBJDIR)/vid_copy.o \ + $(OBJDIR)/k_kart.o \ + $(OBJDIR)/k_respawn.o\ + $(OBJDIR)/k_collide.o\ + $(OBJDIR)/k_color.o \ + $(OBJDIR)/k_battle.o \ + $(OBJDIR)/k_pwrlv.o \ + $(OBJDIR)/k_waypoint.o\ + $(OBJDIR)/k_pathfind.o\ + $(OBJDIR)/k_bheap.o \ $(OBJDIR)/k_bot.o \ $(OBJDIR)/k_botitem.o \ $(OBJDIR)/k_botsearch.o \ From ac1283bc9dfab6f181668e09d5621909ea738622 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 2 Jun 2020 13:30:36 -0400 Subject: [PATCH 21/28] Outdated comment --- src/k_respawn.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/k_respawn.h b/src/k_respawn.h index f72a8133a..81b5cea8d 100644 --- a/src/k_respawn.h +++ b/src/k_respawn.h @@ -63,8 +63,7 @@ void K_DoIngameRespawn(player_t *player); player - Player to preform this for. Return:- - true if the player is not supposed to collide with geometry, - otherwise false. + None --------------------------------------------------*/ void K_RespawnChecker(player_t *player); From e1d3111113a1c06ad6d64e90b17b59f11ed24a7e Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 2 Jun 2020 13:32:51 -0400 Subject: [PATCH 22/28] Remove && Not even sure how this compiled before :V --- src/p_saveg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_saveg.c b/src/p_saveg.c index f420c6f3e..bf2f532e1 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -3117,7 +3117,7 @@ static void P_RelinkPointers(void) if (!(mobj->itnext = P_FindNewPosition(temp))) CONS_Debug(DBG_GAMELOGIC, "itnext not found on %d\n", mobj->type); } - if (mobj->player) && + if (mobj->player) { if (mobj->player->capsule) { From 0f9872fc27b2ab81bf525639ca03402185411a7f Mon Sep 17 00:00:00 2001 From: Sryder Date: Wed, 3 Jun 2020 20:26:52 +0100 Subject: [PATCH 23/28] Draw radius for waypoint debug on "best" waypoint. Fix scale of waypoint connections on mapmobjscale maps --- src/dehacked.c | 2 ++ src/info.c | 5 ++++- src/info.h | 4 ++++ src/k_waypoint.c | 41 ++++++++++++++++++++++++++++++++++++++++- 4 files changed, 50 insertions(+), 2 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index ac7c213f7..f735b22e9 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -7100,6 +7100,8 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_BATTLECAPSULE_SUPPORT", "S_BATTLECAPSULE_SUPPORTFLY", + "S_EGOORB", + #ifdef SEENAMES "S_NAMECHECK", #endif diff --git a/src/info.c b/src/info.c index 6c695e705..8f6989247 100644 --- a/src/info.c +++ b/src/info.c @@ -69,7 +69,8 @@ char sprnames[NUMSPRITES + 1][5] = "ICEB","CNDL","DOCH","DUCK","GTRE","CHES","CHIM","DRGN","LZMN","PGSS", "ZTCH","MKMA","MKMP","RTCH","BOWL","BOWH","BRRL","BRRR","HRSE","TOAH", "BFRT","OFRT","RFRT","PFRT","ASPK","HBST","HBSO","HBSF","WBLZ","WBLN", - "FWRK","MXCL","RGSP","DRAF","GRES","OTFG","DBOS","XMS4","XMS5","VIEW" + "FWRK","MXCL","RGSP","DRAF","GRES","OTFG","DBOS","EGOO","XMS4","XMS5", + "VIEW" }; // Doesn't work with g++, needs actionf_p1 (don't modify this comment) @@ -3497,6 +3498,8 @@ state_t states[NUMSTATES] = {SPR_CAPS, 4, -1, {NULL}, 0, 0, S_NULL}, // S_BATTLECAPSULE_SUPPORT {SPR_CAPS, FF_ANIMATE|5, -1, {NULL}, 3, 1, S_NULL}, // S_BATTLECAPSULE_SUPPORTFLY + {SPR_EGOO, 0, 1, {NULL}, 0, 0, S_NULL}, // S_EGOO + #ifdef SEENAMES {SPR_NULL, 0, 1, {NULL}, 0, 0, S_NULL}, // S_NAMECHECK #endif diff --git a/src/info.h b/src/info.h index 2ccf6415a..a1db87946 100644 --- a/src/info.h +++ b/src/info.h @@ -796,6 +796,8 @@ typedef enum sprite SPR_DBOS, // Drift boost flame + SPR_EGOO, + // Xmas-specific sprites that don't fit aboxe SPR_XMS4, SPR_XMS5, @@ -4184,6 +4186,8 @@ typedef enum state S_BATTLECAPSULE_SUPPORT, S_BATTLECAPSULE_SUPPORTFLY, + S_EGOORB, + #ifdef SEENAMES S_NAMECHECK, #endif diff --git a/src/k_waypoint.c b/src/k_waypoint.c index 69b488dd6..2f43ea792 100644 --- a/src/k_waypoint.c +++ b/src/k_waypoint.c @@ -474,7 +474,7 @@ static void K_DebugWaypointsSpawnLine(waypoint_t *const waypoint1, waypoint_t *c spawnedmobj->state->tics = 1; spawnedmobj->frame = spawnedmobj->frame & ~FF_TRANSMASK; spawnedmobj->color = linkcolours[linkcolour]; - spawnedmobj->scale = FixedMul(FRACUNIT/4, FixedDiv((15 - ((leveltime + n) % 16))*FRACUNIT, 15*FRACUNIT)); + spawnedmobj->scale = FixedMul(spawnedmobj->scale, FixedMul(FRACUNIT/4, FixedDiv((15 - ((leveltime + n) % 16))*FRACUNIT, 15*FRACUNIT))); } x += stepx; @@ -483,6 +483,40 @@ static void K_DebugWaypointsSpawnLine(waypoint_t *const waypoint1, waypoint_t *c } while (n--); } +static void K_DebugWaypointDrawRadius(waypoint_t *waypoint) +{ + mobj_t *radiusOrb; + mobj_t *waypointmobj; + const INT32 numRadiusMobjs = 64; + INT32 i = 0; + angle_t spawnAngle = 0U; + fixed_t spawnX= 0; + fixed_t spawnY= 0; + fixed_t spawnZ= 0; + + I_Assert(waypoint != NULL); + I_Assert(waypoint->mobj != NULL); + + waypointmobj = waypoint->mobj; + + for (i = 0; i < numRadiusMobjs; i++) + { + spawnAngle = (ANGLE_MAX / numRadiusMobjs) * i; + + spawnZ = waypointmobj->z; + spawnX = waypointmobj->x + P_ReturnThrustX(waypointmobj, spawnAngle, waypointmobj->radius); + spawnY = waypointmobj->y + P_ReturnThrustY(waypointmobj, spawnAngle, waypointmobj->radius); + + radiusOrb = P_SpawnMobj(spawnX, spawnY, spawnZ, MT_SPARK); + P_SetMobjState(radiusOrb, S_THOK); + radiusOrb->state->nextstate = S_NULL; + radiusOrb->state->tics = 1; + radiusOrb->frame = radiusOrb->frame & ~FF_TRANSMASK; + radiusOrb->color = SKINCOLOR_PURPLE; + radiusOrb->scale = radiusOrb->scale / 4; + } +} + /*-------------------------------------------------- void K_DebugWaypointsVisualise(void) @@ -523,15 +557,20 @@ void K_DebugWaypointsVisualise(void) { if (waypoint->numnextwaypoints == 0 && waypoint->numprevwaypoints == 0) { + P_SetMobjState(debugmobj, S_EGOORB); debugmobj->color = SKINCOLOR_RED; + debugmobj->colorized = true; } else if (waypoint->numnextwaypoints == 0 || waypoint->numprevwaypoints == 0) { + P_SetMobjState(debugmobj, S_EGOORB); debugmobj->color = SKINCOLOR_YELLOW; + debugmobj->colorized = true; } else if (waypoint == players[displayplayers[0]].nextwaypoint) { debugmobj->color = SKINCOLOR_GREEN; + K_DebugWaypointDrawRadius(waypoint); } else { From 648fa66d825c6aeeb2b6e143c58a6878d9945df4 Mon Sep 17 00:00:00 2001 From: Sryder Date: Wed, 3 Jun 2020 20:29:13 +0100 Subject: [PATCH 24/28] Add function comment --- src/info.c | 2 +- src/k_waypoint.c | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/info.c b/src/info.c index 8f6989247..fcdeffcd6 100644 --- a/src/info.c +++ b/src/info.c @@ -3498,7 +3498,7 @@ state_t states[NUMSTATES] = {SPR_CAPS, 4, -1, {NULL}, 0, 0, S_NULL}, // S_BATTLECAPSULE_SUPPORT {SPR_CAPS, FF_ANIMATE|5, -1, {NULL}, 3, 1, S_NULL}, // S_BATTLECAPSULE_SUPPORTFLY - {SPR_EGOO, 0, 1, {NULL}, 0, 0, S_NULL}, // S_EGOO + {SPR_EGOO, 0, 1, {NULL}, 0, 0, S_NULL}, // S_EGOORB #ifdef SEENAMES {SPR_NULL, 0, 1, {NULL}, 0, 0, S_NULL}, // S_NAMECHECK diff --git a/src/k_waypoint.c b/src/k_waypoint.c index 2f43ea792..50ab94ef6 100644 --- a/src/k_waypoint.c +++ b/src/k_waypoint.c @@ -483,6 +483,14 @@ static void K_DebugWaypointsSpawnLine(waypoint_t *const waypoint1, waypoint_t *c } while (n--); } +/*-------------------------------------------------- + void K_DebugWaypointDrawRadius(waypoint_t *waypoint) + + Draw a debugging circle to represent a waypoint's radius + + Input Arguments:- + waypoint - A waypoint to draw the radius of +--------------------------------------------------*/ static void K_DebugWaypointDrawRadius(waypoint_t *waypoint) { mobj_t *radiusOrb; From 6620fa96f28e03d24425977e7b4b3ae47957302a Mon Sep 17 00:00:00 2001 From: Sryder Date: Wed, 3 Jun 2020 20:30:01 +0100 Subject: [PATCH 25/28] const pointer to waypoint --- src/k_waypoint.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/k_waypoint.c b/src/k_waypoint.c index 50ab94ef6..7d119498a 100644 --- a/src/k_waypoint.c +++ b/src/k_waypoint.c @@ -484,14 +484,14 @@ static void K_DebugWaypointsSpawnLine(waypoint_t *const waypoint1, waypoint_t *c } /*-------------------------------------------------- - void K_DebugWaypointDrawRadius(waypoint_t *waypoint) + void K_DebugWaypointDrawRadius(waypoint_t *const waypoint) Draw a debugging circle to represent a waypoint's radius Input Arguments:- waypoint - A waypoint to draw the radius of --------------------------------------------------*/ -static void K_DebugWaypointDrawRadius(waypoint_t *waypoint) +static void K_DebugWaypointDrawRadius(waypoint_t *const waypoint) { mobj_t *radiusOrb; mobj_t *waypointmobj; From e11101f69a66693f6dcde585becf3f553589567e Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 3 Jun 2020 17:08:41 -0700 Subject: [PATCH 26/28] Don't show ping if no one else is racing --- src/d_clisrv.c | 12 ++++++++++++ src/d_clisrv.h | 1 + src/sdl/i_video.c | 22 +++++++++++++++++++++- 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 37e39aadf..8f5b8c375 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -5736,6 +5736,18 @@ INT32 D_NumPlayers(void) return num; } +/** Return whether a player is a real person (not a CPU) and not spectating. + */ +boolean D_IsPlayerHumanAndGaming (INT32 player_number) +{ + player_t * player = &players[player_number]; + return ( + playeringame[player_number] && + ! player->spectator && + ! player->bot + ); +} + tic_t GetLag(INT32 node) { return gametic - nettics[node]; diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 1ef85b4f9..6b1acf60b 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -629,6 +629,7 @@ extern UINT8 playernode[MAXPLAYERS]; extern UINT8 playerconsole[MAXPLAYERS]; INT32 D_NumPlayers(void); +boolean D_IsPlayerHumanAndGaming(INT32 player_number); void D_ResetTiccmds(void); tic_t GetLag(INT32 node); diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 5713760e1..7630f705c 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -1375,6 +1375,8 @@ static inline boolean I_SkipFrame(void) // void I_FinishUpdate(void) { + int player; + if (rendermode == render_none) return; //Alam: No software or OpenGl surface @@ -1389,7 +1391,25 @@ void I_FinishUpdate(void) if (cv_showping.value && netgame && ( consoleplayer != serverplayer || ! server_lagless )) { - SCR_DisplayLocalPing(); + if (server_lagless) + { + if (consoleplayer != serverplayer) + SCR_DisplayLocalPing(); + } + else + { + for ( + player = 1; + player < MAXPLAYERS; + player++ + ){ + if (D_IsPlayerHumanAndGaming(player)) + { + SCR_DisplayLocalPing(); + break; + } + } + } } } From d13d923a922429f6c3b596db516fe995659c62bc Mon Sep 17 00:00:00 2001 From: Sryder Date: Thu, 4 Jun 2020 01:47:56 +0100 Subject: [PATCH 27/28] New water trail for skimming Out with the old splish splish. Bring on the SKKKKSSSSSSS --- src/dehacked.c | 20 +++++++++++++ src/info.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++-- src/info.h | 22 ++++++++++++++ src/p_user.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 194 insertions(+), 2 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index f735b22e9..48f561a32 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -7102,6 +7102,23 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_EGOORB", + "S_WATERTRAIL1", + "S_WATERTRAIL2", + "S_WATERTRAIL3", + "S_WATERTRAIL4", + "S_WATERTRAIL5", + "S_WATERTRAIL6", + "S_WATERTRAIL7", + "S_WATERTRAIL8", + "S_WATERTRAILUNDERLAY1", + "S_WATERTRAILUNDERLAY2", + "S_WATERTRAILUNDERLAY3", + "S_WATERTRAILUNDERLAY4", + "S_WATERTRAILUNDERLAY5", + "S_WATERTRAILUNDERLAY6", + "S_WATERTRAILUNDERLAY7", + "S_WATERTRAILUNDERLAY8", + #ifdef SEENAMES "S_NAMECHECK", #endif @@ -7914,6 +7931,9 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_BATTLECAPSULE", "MT_BATTLECAPSULE_PIECE", + "MT_WATERTRAIL", + "MT_WATERTRAILUNDERLAY", + #ifdef SEENAMES "MT_NAMECHECK", #endif diff --git a/src/info.c b/src/info.c index fcdeffcd6..795885f92 100644 --- a/src/info.c +++ b/src/info.c @@ -69,8 +69,8 @@ char sprnames[NUMSPRITES + 1][5] = "ICEB","CNDL","DOCH","DUCK","GTRE","CHES","CHIM","DRGN","LZMN","PGSS", "ZTCH","MKMA","MKMP","RTCH","BOWL","BOWH","BRRL","BRRR","HRSE","TOAH", "BFRT","OFRT","RFRT","PFRT","ASPK","HBST","HBSO","HBSF","WBLZ","WBLN", - "FWRK","MXCL","RGSP","DRAF","GRES","OTFG","DBOS","EGOO","XMS4","XMS5", - "VIEW" + "FWRK","MXCL","RGSP","DRAF","GRES","OTFG","DBOS","EGOO","WTRL","XMS4", + "XMS5","VIEW" }; // Doesn't work with g++, needs actionf_p1 (don't modify this comment) @@ -3500,6 +3500,24 @@ state_t states[NUMSTATES] = {SPR_EGOO, 0, 1, {NULL}, 0, 0, S_NULL}, // S_EGOORB + // Water Trail + {SPR_WTRL, FF_PAPERSPRITE , 2, {NULL}, 0, 0, S_NULL}, // S_WATERTRAIL1 + {SPR_WTRL, FF_PAPERSPRITE|1, 2, {NULL}, 0, 0, S_NULL}, // S_WATERTRAIL2 + {SPR_WTRL, FF_PAPERSPRITE|2, 2, {NULL}, 0, 0, S_NULL}, // S_WATERTRAIL3 + {SPR_WTRL, FF_PAPERSPRITE|3, 2, {NULL}, 0, 0, S_NULL}, // S_WATERTRAIL4 + {SPR_WTRL, FF_PAPERSPRITE|4, 2, {NULL}, 0, 0, S_NULL}, // S_WATERTRAIL5 + {SPR_WTRL, FF_PAPERSPRITE|5, 2, {NULL}, 0, 0, S_NULL}, // S_WATERTRAIL6 + {SPR_WTRL, FF_PAPERSPRITE|6, 2, {NULL}, 0, 0, S_NULL}, // S_WATERTRAIL7 + {SPR_WTRL, FF_PAPERSPRITE|7, 2, {NULL}, 0, 0, S_NULL}, // S_WATERTRAIL8 + {SPR_WTRL, FF_TRANS50|FF_PAPERSPRITE|8, 2, {NULL}, 0, 0, S_NULL}, // S_WATERTRAILUNDERLAY1 + {SPR_WTRL, FF_TRANS50|FF_PAPERSPRITE|9, 2, {NULL}, 0, 0, S_NULL}, // S_WATERTRAILUNDERLAY2 + {SPR_WTRL, FF_TRANS50|FF_PAPERSPRITE|10, 2, {NULL}, 0, 0, S_NULL}, // S_WATERTRAILUNDERLAY3 + {SPR_WTRL, FF_TRANS50|FF_PAPERSPRITE|11, 2, {NULL}, 0, 0, S_NULL}, // S_WATERTRAILUNDERLAY4 + {SPR_WTRL, FF_TRANS50|FF_PAPERSPRITE|12, 2, {NULL}, 0, 0, S_NULL}, // S_WATERTRAILUNDERLAY5 + {SPR_WTRL, FF_TRANS50|FF_PAPERSPRITE|13, 2, {NULL}, 0, 0, S_NULL}, // S_WATERTRAILUNDERLAY6 + {SPR_WTRL, FF_TRANS50|FF_PAPERSPRITE|14, 2, {NULL}, 0, 0, S_NULL}, // S_WATERTRAILUNDERLAY7 + {SPR_WTRL, FF_TRANS50|FF_PAPERSPRITE|15, 2, {NULL}, 0, 0, S_NULL}, // S_WATERTRAILUNDERLAY8 + #ifdef SEENAMES {SPR_NULL, 0, 1, {NULL}, 0, 0, S_NULL}, // S_NAMECHECK #endif @@ -20778,6 +20796,60 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_WATERTRAIL + -1, // doomednum + S_WATERTRAIL1, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // 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 + 48*FRACUNIT, // radius + 32*FRACUNIT, // height + 1, // display offset + 100, // mass + 1, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOCLIP|MF_NOGRAVITY|MF_SCENERY|MF_DONTENCOREMAP, // flags + S_NULL // raisestate + }, + + { // MT_WATERTRAILUNDERLAY + -1, // doomednum + S_WATERTRAILUNDERLAY1, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // 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 + 48*FRACUNIT, // radius + 32*FRACUNIT, // height + 0, // display offset + 100, // mass + 1, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOCLIP|MF_NOGRAVITY|MF_SCENERY|MF_DONTENCOREMAP, // flags + S_NULL // raisestate + }, + // ============================================================================================================================// #ifdef SEENAMES diff --git a/src/info.h b/src/info.h index a1db87946..183d1f941 100644 --- a/src/info.h +++ b/src/info.h @@ -798,6 +798,8 @@ typedef enum sprite SPR_EGOO, + SPR_WTRL, // Water Trail + // Xmas-specific sprites that don't fit aboxe SPR_XMS4, SPR_XMS5, @@ -4188,6 +4190,23 @@ typedef enum state S_EGOORB, + S_WATERTRAIL1, + S_WATERTRAIL2, + S_WATERTRAIL3, + S_WATERTRAIL4, + S_WATERTRAIL5, + S_WATERTRAIL6, + S_WATERTRAIL7, + S_WATERTRAIL8, + S_WATERTRAILUNDERLAY1, + S_WATERTRAILUNDERLAY2, + S_WATERTRAILUNDERLAY3, + S_WATERTRAILUNDERLAY4, + S_WATERTRAILUNDERLAY5, + S_WATERTRAILUNDERLAY6, + S_WATERTRAILUNDERLAY7, + S_WATERTRAILUNDERLAY8, + #ifdef SEENAMES S_NAMECHECK, #endif @@ -5017,6 +5036,9 @@ typedef enum mobj_type MT_BATTLECAPSULE, MT_BATTLECAPSULE_PIECE, + MT_WATERTRAIL, + MT_WATERTRAILUNDERLAY, + #ifdef SEENAMES MT_NAMECHECK, #endif diff --git a/src/p_user.c b/src/p_user.c index 28273ca82..0fdfd7120 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -6045,6 +6045,7 @@ static void P_MovePlayer(player_t *player) */ // If you're running fast enough, you can create splashes as you run in shallow water. +#if 0 if (!player->climbing && ((!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z + player->mo->height >= player->mo->watertop && player->mo->z <= player->mo->watertop) || (player->mo->eflags & MFE_VERTICALFLIP && player->mo->z + player->mo->height >= player->mo->waterbottom && player->mo->z <= player->mo->waterbottom)) @@ -6065,6 +6066,83 @@ static void P_MovePlayer(player_t *player) water->destscale = player->mo->scale; P_SetScale(water, player->mo->scale); } +#endif + + if (!player->climbing + && ((!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z + player->mo->height >= player->mo->watertop && player->mo->z <= player->mo->watertop) + || (player->mo->eflags & MFE_VERTICALFLIP && player->mo->z + player->mo->height >= player->mo->waterbottom && player->mo->z <= player->mo->waterbottom)) + && (player->speed > runspd || (player->pflags & PF_STARTDASH)) + && player->mo->momz == 0 && !(player->pflags & PF_SLIDING) && !player->spectator) + { + fixed_t trailScale = FixedMul(FixedDiv(player->speed - runspd, K_GetKartSpeed(player, false) - runspd), mapobjectscale); + fixed_t playerTopSpeed = K_GetKartSpeed(player, false); + + if (playerTopSpeed > runspd) + trailScale = FixedMul(FixedDiv(player->speed - runspd, playerTopSpeed - runspd), mapobjectscale); + else + trailScale = mapobjectscale; // Scaling is based off difference between runspeed and top speed + + if (trailScale > 0) + { + const angle_t forwardangle = R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy); + const fixed_t playerVisualRadius = player->mo->radius + 8*FRACUNIT; + const size_t numFrames = S_WATERTRAIL8 - S_WATERTRAIL1; + const statenum_t curOverlayFrame = S_WATERTRAIL1 + (leveltime % numFrames); + const statenum_t curUnderlayFrame = S_WATERTRAILUNDERLAY1 + (leveltime % numFrames); + fixed_t x1, x2, y1, y2; + mobj_t *water; + + x1 = player->mo->x + player->mo->momx + P_ReturnThrustX(player->mo, forwardangle + ANGLE_90, playerVisualRadius); + y1 = player->mo->y + player->mo->momy + P_ReturnThrustY(player->mo, forwardangle + ANGLE_90, playerVisualRadius); + x1 = x1 + P_ReturnThrustX(player->mo, forwardangle, playerVisualRadius); + y1 = y1 + P_ReturnThrustY(player->mo, forwardangle, playerVisualRadius); + + x2 = player->mo->x + player->mo->momx + P_ReturnThrustX(player->mo, forwardangle - ANGLE_90, playerVisualRadius); + y2 = player->mo->y + player->mo->momy + P_ReturnThrustY(player->mo, forwardangle - ANGLE_90, playerVisualRadius); + x2 = x2 + P_ReturnThrustX(player->mo, forwardangle, playerVisualRadius); + y2 = y2 + P_ReturnThrustY(player->mo, forwardangle, playerVisualRadius); + + // Left + // underlay + water = P_SpawnMobj(x1, y1, + ((player->mo->eflags & MFE_VERTICALFLIP) ? player->mo->waterbottom - FixedMul(mobjinfo[MT_WATERTRAILUNDERLAY].height, player->mo->scale) : player->mo->watertop), MT_WATERTRAILUNDERLAY); + water->angle = forwardangle - ANGLE_180 - ANGLE_22h; + water->destscale = trailScale; + P_SetScale(water, trailScale); + P_SetMobjState(water, curUnderlayFrame); + + // overlay + water = P_SpawnMobj(x1, y1, + ((player->mo->eflags & MFE_VERTICALFLIP) ? player->mo->waterbottom - FixedMul(mobjinfo[MT_WATERTRAIL].height, player->mo->scale) : player->mo->watertop), MT_WATERTRAIL); + water->angle = forwardangle - ANGLE_180 - ANGLE_22h; + water->destscale = trailScale; + P_SetScale(water, trailScale); + P_SetMobjState(water, curOverlayFrame); + + // Right + // Underlay + water = P_SpawnMobj(x2, y2, + ((player->mo->eflags & MFE_VERTICALFLIP) ? player->mo->waterbottom - FixedMul(mobjinfo[MT_WATERTRAILUNDERLAY].height, player->mo->scale) : player->mo->watertop), MT_WATERTRAILUNDERLAY); + water->angle = forwardangle - ANGLE_180 + ANGLE_22h; + water->destscale = trailScale; + P_SetScale(water, trailScale); + P_SetMobjState(water, curUnderlayFrame); + + // Overlay + water = P_SpawnMobj(x2, y2, + ((player->mo->eflags & MFE_VERTICALFLIP) ? player->mo->waterbottom - FixedMul(mobjinfo[MT_WATERTRAIL].height, player->mo->scale) : player->mo->watertop), MT_WATERTRAIL); + water->angle = forwardangle - ANGLE_180 + ANGLE_22h; + water->destscale = trailScale; + P_SetScale(water, trailScale); + P_SetMobjState(water, curOverlayFrame); + + if (!S_SoundPlaying(player->mo, sfx_s3kdbs)) + { + const INT32 volume = (min(trailScale, FRACUNIT) * 255) / FRACUNIT; + S_StartSoundAtVolume(player->mo, sfx_s3kdbs, volume); + } + } + } // Little water sound while touching water - just a nicety. if ((player->mo->eflags & MFE_TOUCHWATER) && !(player->mo->eflags & MFE_UNDERWATER) && !player->spectator) From 2f0e11c7c536cfe8f608ffd5087b4849c19f962d Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Thu, 4 Jun 2020 01:40:44 -0400 Subject: [PATCH 28/28] Make more exaggurated --- src/k_respawn.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/k_respawn.c b/src/k_respawn.c index 59476ca28..6c20c8f62 100644 --- a/src/k_respawn.c +++ b/src/k_respawn.c @@ -110,7 +110,7 @@ void K_DoIngameRespawn(player_t *player) // Set up respawn position if invalid if (player->respawn.wp != NULL) { - const UINT32 dist = RESPAWN_DIST + (player->airtime * 32); + const UINT32 dist = RESPAWN_DIST + (player->airtime * 48); player->respawn.distanceleft = (dist * mapobjectscale) / FRACUNIT; K_RespawnAtWaypoint(player, player->respawn.wp); }