From 8aced572c985b4ab2155565270ec67a6c074ce69 Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 15 May 2020 18:11:05 -0700 Subject: [PATCH 001/143] Some experimental commands to use auth when downloading from HTTP sources --- src/d_clisrv.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/d_netfil.c | 33 ++++++++++++++++++++++ src/d_netfil.h | 11 ++++++++ 3 files changed, 118 insertions(+) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 652ffbcb8..66477bbe0 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -3200,6 +3200,76 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum) } } +#ifdef HAVE_CURL +/** Add a login for HTTP downloads. If the + * user/password is missing, remove it. + * + * \sa Command_list_http_logins + */ +static void Command_set_http_login (void) +{ + HTTP_login *login; + HTTP_login **prev_next; + + if (COM_Argc() < 2) + { + CONS_Printf( + "set_http_login [user:password]: Set or remove a login to " + "authenticate HTTP downloads.\n" + ); + return; + } + + login = CURLGetLogin(COM_Argv(1), &prev_next); + + if (COM_Argc() == 2) + { + if (login) + { + (*prev_next) = login->next; + CONS_Printf("Login for '%s' removed.\n", login->url); + Z_Free(login); + } + } + else + { + if (login) + Z_Free(login->auth); + else + { + login = ZZ_Alloc(sizeof *login); + login->url = Z_StrDup(COM_Argv(1)); + } + + login->auth = Z_StrDup(COM_Argv(2)); + + login->next = curl_logins; + curl_logins = login; + } +} + +/** List logins for HTTP downloads. + * + * \sa Command_set_http_login + */ +static void Command_list_http_logins (void) +{ + HTTP_login *login; + + for ( + login = curl_logins; + login; + login = login->next + ){ + CONS_Printf( + "'%s' -> '%s'\n", + login->url, + login->auth + ); + } +} +#endif/*HAVE_CURL*/ + static CV_PossibleValue_t netticbuffer_cons_t[] = {{0, "MIN"}, {3, "MAX"}, {0, NULL}}; consvar_t cv_netticbuffer = {"netticbuffer", "1", CV_SAVE, netticbuffer_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -3241,6 +3311,10 @@ void D_ClientServerInit(void) COM_AddCommand("reloadbans", Command_ReloadBan); COM_AddCommand("connect", Command_connect); COM_AddCommand("nodes", Command_Nodes); +#ifdef HAVE_CURL + COM_AddCommand("set_http_login", Command_set_http_login); + COM_AddCommand("list_http_logins", Command_list_http_logins); +#endif #ifdef PACKETDROP COM_AddCommand("drop", Command_Drop); COM_AddCommand("droprate", Command_Droprate); diff --git a/src/d_netfil.c b/src/d_netfil.c index 3dc9da68c..006f775b4 100644 --- a/src/d_netfil.c +++ b/src/d_netfil.c @@ -1062,6 +1062,9 @@ int curlprogress_callback(void *clientp, double dltotal, double dlnow, double ul void CURLPrepareFile(const char* url, int dfilenum) { + HTTP_login *login; + char *final_url; + #ifdef PARANOIA if (M_CheckParm("-nodownload")) I_Error("Attempted to download files in -nodownload mode"); @@ -1090,6 +1093,13 @@ void CURLPrepareFile(const char* url, int dfilenum) curl_easy_setopt(http_handle, CURLOPT_USERAGENT, va("SRB2Kart/v%d.%d.%d", VERSION/100, VERSION%100, SUBVERSION)); // Set user agent as some servers won't accept invalid user agents. + // Authenticate if the user so wishes + curl_easy_getinfo(http_handle, CURLINFO_EFFECTIVE_URL, &final_url); + login = CURLGetLogin(final_url, NULL); + + if (login) + curl_easy_setopt(http_handle, CURLOPT_USERPWD, login->auth); + // Follow a redirect request, if sent by the server. curl_easy_setopt(http_handle, CURLOPT_FOLLOWLOCATION, 1L); @@ -1189,4 +1199,27 @@ void CURLGetFile(void) curl_global_cleanup(); } } + +HTTP_login * +CURLGetLogin (const char *url, HTTP_login ***return_prev_next) +{ + HTTP_login * login; + HTTP_login ** prev_next; + + for ( + prev_next = &curl_logins; + ( login = (*prev_next)); + prev_next = &login->next + ){ + if (strcmp(login->url, url) == 0) + { + if (return_prev_next) + (*return_prev_next) = prev_next; + + return login; + } + } + + return NULL; +} #endif diff --git a/src/d_netfil.h b/src/d_netfil.h index f37df371f..ef414b88b 100644 --- a/src/d_netfil.h +++ b/src/d_netfil.h @@ -58,6 +58,16 @@ extern INT32 lastfilenum; extern boolean curl_failedwebdownload; extern boolean curl_running; extern INT32 curl_transfers; + +typedef struct HTTP_login HTTP_login; + +struct HTTP_login +{ + char * url; + char * auth; + HTTP_login * next; +} +*curl_logins; #endif UINT8 *PutFileNeeded(UINT16 firstfile); @@ -93,6 +103,7 @@ size_t nameonlylength(const char *s); #ifdef HAVE_CURL void CURLPrepareFile(const char* url, int dfilenum); void CURLGetFile(void); +HTTP_login * CURLGetLogin (const char *url, HTTP_login ***return_prev_next); #endif #endif // __D_NETFIL__ From 12bd9370c2f1ce9561ccba3859d18220dd6559d2 Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 15 May 2020 19:04:03 -0700 Subject: [PATCH 002/143] I forgot extern, now I am the clown --- src/d_netfil.c | 1 + src/d_netfil.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/d_netfil.c b/src/d_netfil.c index 006f775b4..446f38145 100644 --- a/src/d_netfil.c +++ b/src/d_netfil.c @@ -124,6 +124,7 @@ static UINT32 curl_origfilesize; static UINT32 curl_origtotalfilesize; static char *curl_realname = NULL; fileneeded_t *curl_curfile = NULL; +HTTP_login *curl_logins; #endif /** Fills a serverinfo packet with information about wad files loaded. diff --git a/src/d_netfil.h b/src/d_netfil.h index ef414b88b..913a2119a 100644 --- a/src/d_netfil.h +++ b/src/d_netfil.h @@ -61,7 +61,7 @@ extern INT32 curl_transfers; typedef struct HTTP_login HTTP_login; -struct HTTP_login +extern struct HTTP_login { char * url; char * auth; From 0de597892eb1488c5359c768fbd19391de0f38c7 Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 16 May 2020 21:03:37 -0700 Subject: [PATCH 003/143] Whoops I used the url to the file instead of the http_source --- src/d_netfil.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/d_netfil.c b/src/d_netfil.c index 446f38145..d2a6fe550 100644 --- a/src/d_netfil.c +++ b/src/d_netfil.c @@ -1064,7 +1064,6 @@ int curlprogress_callback(void *clientp, double dltotal, double dlnow, double ul void CURLPrepareFile(const char* url, int dfilenum) { HTTP_login *login; - char *final_url; #ifdef PARANOIA if (M_CheckParm("-nodownload")) @@ -1095,11 +1094,12 @@ void CURLPrepareFile(const char* url, int dfilenum) curl_easy_setopt(http_handle, CURLOPT_USERAGENT, va("SRB2Kart/v%d.%d.%d", VERSION/100, VERSION%100, SUBVERSION)); // Set user agent as some servers won't accept invalid user agents. // Authenticate if the user so wishes - curl_easy_getinfo(http_handle, CURLINFO_EFFECTIVE_URL, &final_url); - login = CURLGetLogin(final_url, NULL); + login = CURLGetLogin(url, NULL); if (login) + { curl_easy_setopt(http_handle, CURLOPT_USERPWD, login->auth); + } // Follow a redirect request, if sent by the server. curl_easy_setopt(http_handle, CURLOPT_FOLLOWLOCATION, 1L); From c9b17c456dd8df6c855b25ba1eac8422d63e48d5 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Wed, 29 Jul 2020 09:30:29 -0400 Subject: [PATCH 004/143] Re-attempt at hitlag I remember when I tried to fix wolfs' branch I was having issues, but this ended up working pretty much fine? Don't remember why the old branch was messed up though (it was simply too old & not substantial enough to try and work off of imo) --- src/k_collide.c | 3 +++ src/lua_mobjlib.c | 8 ++++++++ src/p_map.c | 6 ++++++ src/p_mobj.c | 8 ++++++++ src/p_mobj.h | 2 ++ src/p_saveg.c | 11 +++++++++-- src/p_user.c | 5 +++++ src/r_things.c | 14 +++++++++++--- 8 files changed, 52 insertions(+), 5 deletions(-) diff --git a/src/k_collide.c b/src/k_collide.c index 1921e3d38..e2fa2e9d4 100644 --- a/src/k_collide.c +++ b/src/k_collide.c @@ -48,6 +48,7 @@ boolean K_OrbinautJawzCollide(mobj_t *t1, mobj_t *t2) P_DamageMobj(t2, t1, t1->target, 1); K_KartBouncing(t2, t1, false, false); S_StartSound(t2, sfx_s3k7b); + t2->hitlag = TICRATE; } damageitem = true; @@ -99,6 +100,8 @@ boolean K_OrbinautJawzCollide(mobj_t *t1, mobj_t *t2) else t1->z += t1->height; + t1->hitlag = TICRATE; + S_StartSound(t1, t1->info->deathsound); P_KillMobj(t1, t2, t2); diff --git a/src/lua_mobjlib.c b/src/lua_mobjlib.c index 3c85c358b..a1d7eee60 100644 --- a/src/lua_mobjlib.c +++ b/src/lua_mobjlib.c @@ -87,6 +87,7 @@ enum mobj_e { mobj_standingslope, #endif mobj_colorized, + mobj_hitlag, mobj_shadowscale, mobj_whiteshadow, mobj_sprxoff, @@ -156,6 +157,7 @@ static const char *const mobj_opt[] = { "standingslope", #endif "colorized", + "hitlag", "shadowscale", "whiteshadow", "sprxoff", @@ -375,6 +377,9 @@ static int mobj_get(lua_State *L) case mobj_colorized: lua_pushboolean(L, mo->colorized); break; + case mobj_hitlag: + lua_pushinteger(L, mo->hitlag); + break; case mobj_shadowscale: lua_pushfixed(L, mo->shadowscale); break; @@ -710,6 +715,9 @@ static int mobj_set(lua_State *L) case mobj_colorized: mo->colorized = luaL_checkboolean(L, 3); break; + case mobj_hitlag: + mo->hitlag = luaL_checkinteger(L, 3); + break; case mobj_shadowscale: mo->shadowscale = luaL_checkfixed(L, 3); break; diff --git a/src/p_map.c b/src/p_map.c index 4ef258ebb..69a638ce4 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -2598,6 +2598,12 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) if (radius < mapobjectscale) radius = mapobjectscale; + if (thing->hitlag > 0) + { + // Do not move during hitlag + return false; + } + do { if (thing->flags & MF_NOCLIP) { tryx = x; diff --git a/src/p_mobj.c b/src/p_mobj.c index 734a6e3f3..806fccf50 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6392,6 +6392,12 @@ void P_MobjThinker(mobj_t *mobj) if (mobj->flags & MF_NOTHINK) return; + if (mobj->hitlag > 0) + { + mobj->hitlag--; + return; + } + // Remove dead target/tracer. if (mobj->target && P_MobjWasRemoved(mobj->target)) P_SetTarget(&mobj->target, NULL); @@ -10875,6 +10881,8 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) mobj->colorized = false; + mobj->hitlag = 0; + // Set shadowscale here, before spawn hook so that Lua can change it P_DefaultMobjShadowScale(mobj); diff --git a/src/p_mobj.h b/src/p_mobj.h index dbb3f4d58..75a6bf3b8 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -410,6 +410,8 @@ typedef struct mobj_s fixed_t sprxoff, spryoff, sprzoff; // Sprite offsets in real space, does NOT affect position or collision + INT32 hitlag; + // WARNING: New fields must be added separately to savegame and Lua. } mobj_t; diff --git a/src/p_saveg.c b/src/p_saveg.c index c197b5a3c..5085f2644 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -1000,6 +1000,7 @@ typedef enum #endif MD2_SHADOWSCALE = 1<<14, MD2_DRAWFLAGS = 1<<15, + MD2_HITLAG = 1<<16 } mobj_diff2_t; typedef enum @@ -1196,12 +1197,14 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) if (mobj->standingslope) diff2 |= MD2_SLOPE; #endif + if (mobj->colorized) + diff2 |= MD2_COLORIZED; if (mobj->shadowscale) diff2 |= MD2_SHADOWSCALE; if (mobj->drawflags) diff2 |= MD2_DRAWFLAGS; - if (mobj->colorized) - diff2 |= MD2_COLORIZED; + if (mobj->hitlag) + diff2 |= MD2_HITLAG; if (mobj == waypointcap) diff2 |= MD2_WAYPOINTCAP; if (mobj == kitemcap) @@ -1342,6 +1345,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) WRITEUINT16(save_p, df); } + if (diff2 & MD2_HITLAG) + WRITEINT32(save_p, mobj->hitlag); WRITEUINT32(save_p, mobj->mobjnum); } @@ -2273,6 +2278,8 @@ static void LoadMobjThinker(actionf_p1 thinker) mobj->shadowscale = READFIXED(save_p); if (diff2 & MD2_DRAWFLAGS) mobj->drawflags = READUINT16(save_p); + if (diff2 & MD2_HITLAG) + mobj->hitlag = READINT32(save_p); if (diff & MD_REDFLAG) { diff --git a/src/p_user.c b/src/p_user.c index 8d6014926..3750c1378 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -8677,6 +8677,11 @@ void P_PlayerThink(player_t *player) } #endif + if (player->mo->hitlag > 0) + { + return; + } + if (player->awayviewmobj && P_MobjWasRemoved(player->awayviewmobj)) { P_SetTarget(&player->awayviewmobj, NULL); // remove awayviewmobj asap if invalid diff --git a/src/r_things.c b/src/r_things.c index 05672ae4d..fb12fcb4b 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1429,9 +1429,9 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale, // static void R_ProjectSprite(mobj_t *thing) { - const fixed_t thingxpos = thing->x + thing->sprxoff; - const fixed_t thingypos = thing->y + thing->spryoff; - const fixed_t thingzpos = thing->z + thing->sprzoff; + fixed_t thingxpos = thing->x + thing->sprxoff; + fixed_t thingypos = thing->y + thing->spryoff; + fixed_t thingzpos = thing->z + thing->sprzoff; fixed_t tr_x, tr_y; fixed_t gxt, gyt; @@ -1468,6 +1468,14 @@ static void R_ProjectSprite(mobj_t *thing) INT32 light = 0; fixed_t this_scale = thing->scale; + // hitlag vibrating + if (thing->hitlag > 0 && (leveltime & 1)) + { + thingxpos += thing->momx; + thingypos += thing->momy; + thingzpos += thing->momz; + } + // transform the origin point tr_x = thingxpos - viewx; tr_y = thingypos - viewy; From 1bec6945eefe61addafcd187269479a73734e663 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Wed, 29 Jul 2020 11:26:24 -0400 Subject: [PATCH 005/143] Ease hitlag vibration over time --- src/p_mobj.h | 2 +- src/r_things.c | 15 +++++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/p_mobj.h b/src/p_mobj.h index 75a6bf3b8..8ba15af84 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -410,7 +410,7 @@ typedef struct mobj_s fixed_t sprxoff, spryoff, sprzoff; // Sprite offsets in real space, does NOT affect position or collision - INT32 hitlag; + INT32 hitlag; // Sal-style hit lag, straight from Captain Fetch's jowls // WARNING: New fields must be added separately to savegame and Lua. } mobj_t; diff --git a/src/r_things.c b/src/r_things.c index fb12fcb4b..708e9e146 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1469,11 +1469,18 @@ static void R_ProjectSprite(mobj_t *thing) fixed_t this_scale = thing->scale; // hitlag vibrating - if (thing->hitlag > 0 && (leveltime & 1)) + if (thing->hitlag > 0) { - thingxpos += thing->momx; - thingypos += thing->momy; - thingzpos += thing->momz; + fixed_t mul = (thing->hitlag * FRACUNIT) / (TICRATE); + + if (leveltime & 1) + { + mul = -mul; + } + + thingxpos += FixedMul(thing->momx, mul); + thingypos += FixedMul(thing->momy, mul); + thingzpos += FixedMul(thing->momz, mul); } // transform the origin point From 0cb123f74e45675cfada023cb009b777fe2c4215 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Fri, 31 Jul 2020 00:07:24 -0400 Subject: [PATCH 006/143] Apply to more things, make the timing more reasonable --- src/k_collide.c | 46 ++++++++++++++++++++++------------------------ src/r_things.c | 2 +- 2 files changed, 23 insertions(+), 25 deletions(-) diff --git a/src/k_collide.c b/src/k_collide.c index e2fa2e9d4..26863f493 100644 --- a/src/k_collide.c +++ b/src/k_collide.c @@ -41,6 +41,7 @@ boolean K_OrbinautJawzCollide(mobj_t *t1, mobj_t *t2) { // Melt item S_StartSound(t2, sfx_s3k43); + t2->hitlag += 3; } else { @@ -48,7 +49,7 @@ boolean K_OrbinautJawzCollide(mobj_t *t1, mobj_t *t2) P_DamageMobj(t2, t1, t1->target, 1); K_KartBouncing(t2, t1, false, false); S_StartSound(t2, sfx_s3k7b); - t2->hitlag = TICRATE; + t2->hitlag += 10; } damageitem = true; @@ -59,10 +60,7 @@ boolean K_OrbinautJawzCollide(mobj_t *t1, mobj_t *t2) || t2->type == MT_BALLHOG) { // Other Item Damage - if (t2->eflags & MFE_VERTICALFLIP) - t2->z -= t2->height; - else - t2->z += t2->height; + t2->hitlag += 10; S_StartSound(t2, t2->info->deathsound); P_KillMobj(t2, t1, t1); @@ -89,18 +87,14 @@ boolean K_OrbinautJawzCollide(mobj_t *t1, mobj_t *t2) { // Shootable damage P_DamageMobj(t2, t2, t1->target, 1); + t2->hitlag += 10; damageitem = true; } if (damageitem) { // This Item Damage - if (t1->eflags & MFE_VERTICALFLIP) - t1->z -= t1->height; - else - t1->z += t1->height; - - t1->hitlag = TICRATE; + t1->hitlag += 10; S_StartSound(t1, t1->info->deathsound); P_KillMobj(t1, t2, t2); @@ -147,11 +141,13 @@ boolean K_BananaBallhogCollide(mobj_t *t1, mobj_t *t2) { // Melt item S_StartSound(t2, sfx_s3k43); + t2->hitlag += 3; } else { // Player Damage K_SpinPlayer(t2->player, t1->target, 0, t1, (t1->type == MT_BANANA || t1->type == MT_BANANA_SHIELD)); + t2->hitlag += 5; } damageitem = true; @@ -162,10 +158,7 @@ boolean K_BananaBallhogCollide(mobj_t *t1, mobj_t *t2) || t2->type == MT_BALLHOG) { // Other Item Damage - if (t2->eflags & MFE_VERTICALFLIP) - t2->z -= t2->height; - else - t2->z += t2->height; + t2->hitlag += 10; S_StartSound(t2, t2->info->deathsound); P_KillMobj(t2, t1, t1); @@ -181,16 +174,14 @@ boolean K_BananaBallhogCollide(mobj_t *t1, mobj_t *t2) { // Shootable damage P_DamageMobj(t2, t2, t1->target, 1); + t2->hitlag += 10; damageitem = true; } if (damageitem) { // This Item Damage - if (t1->eflags & MFE_VERTICALFLIP) - t1->z -= t1->height; - else - t1->z += t1->height; + t1->hitlag += 10; S_StartSound(t1, t1->info->deathsound); P_KillMobj(t1, t2, t2); @@ -303,10 +294,7 @@ boolean K_MineCollide(mobj_t *t1, mobj_t *t2) P_KillMobj(t1, t2, t2); // Other Item Damage - if (t2->eflags & MFE_VERTICALFLIP) - t2->z -= t2->height; - else - t2->z += t2->height; + t2->hitlag += 10; S_StartSound(t2, t2->info->deathsound); P_KillMobj(t2, t1, t1); @@ -333,9 +321,15 @@ boolean K_MineExplosionCollide(mobj_t *t1, mobj_t *t2) return true; if (t1->state == &states[S_MINEEXPLOSION1]) + { K_ExplodePlayer(t2->player, t1->target, t1); + t2->hitlag += 10; + } else + { K_SpinPlayer(t2->player, t1->target, 0, t1, false); + t2->hitlag += 5; + } } else if (t2->flags & MF_SHOOTABLE) { @@ -363,12 +357,16 @@ boolean K_KitchenSinkCollide(mobj_t *t1, mobj_t *t2) I_OutputMsg("%s was hit by a kitchen sink.\n", player_names[t2->player-players]); P_DamageMobj(t2, t1, t1->target, 10000); P_KillMobj(t1, t2, t2); + t1->hitlag += 10; + t2->hitlag += 10; } else if (t2->flags & MF_SHOOTABLE) { // Shootable damage P_KillMobj(t2, t2, t1->target); - // This item damage + t2->hitlag += 10; + // This Item Damage + t1->hitlag += 10; P_KillMobj(t1, t2, t2); } diff --git a/src/r_things.c b/src/r_things.c index e999e55bc..806326d1f 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1487,7 +1487,7 @@ static void R_ProjectSprite(mobj_t *thing) // hitlag vibrating if (thing->hitlag > 0) { - fixed_t mul = (thing->hitlag * FRACUNIT) / (TICRATE); + fixed_t mul = (thing->hitlag * FRACUNIT) / 5; if (leveltime & 1) { From 0db881d058edddd24b642e0684fbaf391e3ce8be Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Fri, 31 Jul 2020 22:29:08 -0400 Subject: [PATCH 007/143] Allow hitting players who are flashing, but are still in hitlag --- src/k_collide.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/k_collide.c b/src/k_collide.c index 26863f493..7931322b5 100644 --- a/src/k_collide.c +++ b/src/k_collide.c @@ -30,7 +30,7 @@ boolean K_OrbinautJawzCollide(mobj_t *t1, mobj_t *t2) if (t2->player) { - if (t2->player->powers[pw_flashing] + if ((t2->player->powers[pw_flashing] > 0 && t2->hitlag == 0) && !(t1->type == MT_ORBINAUT || t1->type == MT_JAWZ || t1->type == MT_JAWZ_DUD)) return true; @@ -130,7 +130,7 @@ boolean K_BananaBallhogCollide(mobj_t *t1, mobj_t *t2) if (t2->player) { - if (t2->player->powers[pw_flashing]) + if (t2->player->powers[pw_flashing] > 0 && t2->hitlag == 0) return true; // Banana snipe! @@ -277,7 +277,7 @@ boolean K_MineCollide(mobj_t *t1, mobj_t *t2) if (t2->player) { - if (t2->player->powers[pw_flashing]) + if (t2->player->powers[pw_flashing] > 0 && t2->hitlag == 0) return true; // Bomb punting @@ -317,7 +317,7 @@ boolean K_MineExplosionCollide(mobj_t *t1, mobj_t *t2) { if (t2->player) { - if (t2->player->powers[pw_flashing]) + if (t2->player->powers[pw_flashing] > 0 && t2->hitlag == 0) return true; if (t1->state == &states[S_MINEEXPLOSION1]) @@ -347,7 +347,7 @@ boolean K_KitchenSinkCollide(mobj_t *t1, mobj_t *t2) if (t2->player) { - if (t2->player->powers[pw_flashing]) + if (t2->player->powers[pw_flashing] > 0 && t2->hitlag == 0) return true; S_StartSound(NULL, sfx_bsnipe); // let all players hear it. From a8908d22cfe6d393a10af4d80361beba39aec703 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sat, 1 Aug 2020 01:14:18 -0400 Subject: [PATCH 008/143] K_SetHitlagForObjects, sets hitlag based on speed --- src/k_collide.c | 45 ++++++++++++++++++++----------------- src/k_kart.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++ src/k_kart.h | 2 ++ src/p_map.c | 18 +++++++++++++++ 4 files changed, 104 insertions(+), 20 deletions(-) diff --git a/src/k_collide.c b/src/k_collide.c index 7931322b5..454ff9527 100644 --- a/src/k_collide.c +++ b/src/k_collide.c @@ -41,15 +41,14 @@ boolean K_OrbinautJawzCollide(mobj_t *t1, mobj_t *t2) { // Melt item S_StartSound(t2, sfx_s3k43); - t2->hitlag += 3; } else { // Player Damage + K_SetHitLagForObjects(t1, t2, 10); P_DamageMobj(t2, t1, t1->target, 1); K_KartBouncing(t2, t1, false, false); S_StartSound(t2, sfx_s3k7b); - t2->hitlag += 10; } damageitem = true; @@ -60,8 +59,7 @@ boolean K_OrbinautJawzCollide(mobj_t *t1, mobj_t *t2) || t2->type == MT_BALLHOG) { // Other Item Damage - t2->hitlag += 10; - + K_SetHitLagForObjects(t1, t2, 10); S_StartSound(t2, t2->info->deathsound); P_KillMobj(t2, t1, t1); @@ -74,6 +72,7 @@ boolean K_OrbinautJawzCollide(mobj_t *t1, mobj_t *t2) } else if (t2->type == MT_SSMINE_SHIELD || t2->type == MT_SSMINE) { + K_SetHitLagForObjects(t1, t2, 10); damageitem = true; // Bomb death P_KillMobj(t2, t1, t1); @@ -85,17 +84,15 @@ boolean K_OrbinautJawzCollide(mobj_t *t1, mobj_t *t2) } else if (t2->flags & MF_SHOOTABLE) { + K_SetHitLagForObjects(t1, t2, 10); // Shootable damage P_DamageMobj(t2, t2, t1->target, 1); - t2->hitlag += 10; damageitem = true; } if (damageitem) { // This Item Damage - t1->hitlag += 10; - S_StartSound(t1, t1->info->deathsound); P_KillMobj(t1, t2, t2); @@ -141,13 +138,12 @@ boolean K_BananaBallhogCollide(mobj_t *t1, mobj_t *t2) { // Melt item S_StartSound(t2, sfx_s3k43); - t2->hitlag += 3; } else { // Player Damage + K_SetHitLagForObjects(t1, t2, 2); K_SpinPlayer(t2->player, t1->target, 0, t1, (t1->type == MT_BANANA || t1->type == MT_BANANA_SHIELD)); - t2->hitlag += 5; } damageitem = true; @@ -158,7 +154,7 @@ boolean K_BananaBallhogCollide(mobj_t *t1, mobj_t *t2) || t2->type == MT_BALLHOG) { // Other Item Damage - t2->hitlag += 10; + K_SetHitLagForObjects(t1, t2, 10); S_StartSound(t2, t2->info->deathsound); P_KillMobj(t2, t1, t1); @@ -173,15 +169,15 @@ boolean K_BananaBallhogCollide(mobj_t *t1, mobj_t *t2) else if (t2->flags & MF_SHOOTABLE) { // Shootable damage + K_SetHitLagForObjects(t1, t2, 10); P_DamageMobj(t2, t2, t1->target, 1); - t2->hitlag += 10; damageitem = true; } if (damageitem) { // This Item Damage - t1->hitlag += 10; + K_SetHitLagForObjects(t1, t2, 10); S_StartSound(t1, t1->info->deathsound); P_KillMobj(t1, t2, t2); @@ -283,19 +279,25 @@ boolean K_MineCollide(mobj_t *t1, mobj_t *t2) // Bomb punting if ((t1->state >= &states[S_SSMINE1] && t1->state <= &states[S_SSMINE4]) || (t1->state >= &states[S_SSMINE_DEPLOY8] && t1->state <= &states[S_SSMINE_DEPLOY13])) + { + K_SetHitLagForObjects(t1, t2, 10); P_KillMobj(t1, t2, t2); + } else + { + K_SetHitLagForObjects(t1, t2, 2); K_PuntMine(t1, t2); + } } else if (t2->type == MT_ORBINAUT || t2->type == MT_JAWZ || t2->type == MT_JAWZ_DUD || t2->type == MT_ORBINAUT_SHIELD || t2->type == MT_JAWZ_SHIELD) { + K_SetHitLagForObjects(t1, t2, 10); + // Bomb death P_KillMobj(t1, t2, t2); // Other Item Damage - t2->hitlag += 10; - S_StartSound(t2, t2->info->deathsound); P_KillMobj(t2, t1, t1); @@ -304,6 +306,7 @@ boolean K_MineCollide(mobj_t *t1, mobj_t *t2) } else if (t2->flags & MF_SHOOTABLE) { + K_SetHitLagForObjects(t1, t2, 10); // Bomb death P_KillMobj(t1, t2, t2); // Shootable damage @@ -322,18 +325,19 @@ boolean K_MineExplosionCollide(mobj_t *t1, mobj_t *t2) if (t1->state == &states[S_MINEEXPLOSION1]) { + K_SetHitLagForObjects(t1, t2, 10); K_ExplodePlayer(t2->player, t1->target, t1); - t2->hitlag += 10; } else { + K_SetHitLagForObjects(t1, t2, 2); K_SpinPlayer(t2->player, t1->target, 0, t1, false); - t2->hitlag += 5; } } else if (t2->flags & MF_SHOOTABLE) { // Shootable damage + K_SetHitLagForObjects(t1, t2, 10); P_DamageMobj(t2, t2, t1->target, 1); } @@ -350,23 +354,24 @@ boolean K_KitchenSinkCollide(mobj_t *t1, mobj_t *t2) if (t2->player->powers[pw_flashing] > 0 && t2->hitlag == 0) return true; + K_SetHitLagForObjects(t1, t2, 10); + S_StartSound(NULL, sfx_bsnipe); // let all players hear it. + HU_SetCEchoFlags(0); HU_SetCEchoDuration(5); HU_DoCEcho(va("%s\\was hit by a kitchen sink.\\\\\\\\", player_names[t2->player-players])); I_OutputMsg("%s was hit by a kitchen sink.\n", player_names[t2->player-players]); + P_DamageMobj(t2, t1, t1->target, 10000); P_KillMobj(t1, t2, t2); - t1->hitlag += 10; - t2->hitlag += 10; } else if (t2->flags & MF_SHOOTABLE) { + K_SetHitLagForObjects(t1, t2, 10); // Shootable damage P_KillMobj(t2, t2, t1->target); - t2->hitlag += 10; // This Item Damage - t1->hitlag += 10; P_KillMobj(t1, t2, t2); } diff --git a/src/k_kart.c b/src/k_kart.c index 0af1ec658..4b02fc4d1 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -2343,6 +2343,65 @@ fixed_t K_3dKartMovement(player_t *player, boolean onground) return finalspeed; } +angle_t K_MomentumAngle(mobj_t *mo) +{ + if (mo->momx || mo->momy) + { + return R_PointToAngle2(0, 0, mo->momx, mo->momy); + } + else + { + return mo->angle; // default to facing angle, rather than 0 + } +} + +void K_SetHitLagForObjects(mobj_t *mo1, mobj_t *mo2, INT32 tics) +{ + const fixed_t ticaddfactor = mapobjectscale * 4; + + const fixed_t mo1speed = P_AproxDistance(P_AproxDistance(mo1->momx, mo1->momy), mo1->momz); + const fixed_t mo2speed = P_AproxDistance(P_AproxDistance(mo2->momx, mo2->momy), mo2->momz); + const fixed_t speeddiff = abs(mo1speed - mo2speed); + + //const angle_t mo1angle = K_MomentumAngle(mo1); + //const angle_t mo2angle = K_MomentumAngle(mo2); + + //angle_t anglediff = mo1angle - mo2angle; + fixed_t anglemul = FRACUNIT; + + INT32 tics1 = tics; + INT32 tics2 = tics; + + //if (anglediff > ANGLE_180) + //{ + //anglediff = InvAngle(anglediff); + //} + + //anglemul = FRACUNIT/2 + (FixedAngle(ANGLE_180 - anglediff) / 90); // x0.5 at 0, x1.5 at 90, x2.5 at 180 + + tics1 += FixedMul(speeddiff, anglemul) / ticaddfactor; // FixedMul(ticaddfactor, max(1, FRACUNIT + (mo2->scale - mo1->scale))); + tics2 += FixedMul(speeddiff, anglemul) / ticaddfactor; + + if (mo1->player && !mo2->player) + { + if (mo1->player->powers[pw_flashing] > 0 + || mo1->player->kartstuff[k_invincibilitytimer] > 0 + || mo1->player->kartstuff[k_growshrinktimer] > 0) + tics1 = 0; + } + + if (mo2->player && !mo1->player) + { + if (mo2->player->powers[pw_flashing] > 0 + || mo2->player->kartstuff[k_invincibilitytimer] > 0 + || mo2->player->kartstuff[k_growshrinktimer] > 0) + tics2 = 0; + } + + mo1->hitlag += tics1; + mo2->hitlag += tics2; +} + void K_DoInstashield(player_t *player) { mobj_t *layera; diff --git a/src/k_kart.h b/src/k_kart.h index d44be14f4..4529a4563 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -37,6 +37,8 @@ void K_KartMoveAnimation(player_t *player); void K_KartPlayerHUDUpdate(player_t *player); void K_KartPlayerThink(player_t *player, ticcmd_t *cmd); void K_KartPlayerAfterThink(player_t *player); +angle_t K_MomentumAngle(mobj_t *mo); +void K_SetHitLagForObjects(mobj_t *mo1, mobj_t *mo2, INT32 tics); void K_DoInstashield(player_t *player); void K_SpinPlayer(player_t *player, mobj_t *source, INT32 type, mobj_t *inflictor, boolean trapitem); void K_SquishPlayer(player_t *player, mobj_t *source, mobj_t *inflictor); diff --git a/src/p_map.c b/src/p_map.c index 69a638ce4..4b2283020 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1306,19 +1306,37 @@ static boolean PIT_CheckThing(mobj_t *thing) && !(thing->z + thing->height < tmthing->z || thing->z > tmthing->z + tmthing->height)) { if (tmthing->scale > thing->scale + (mapobjectscale/8)) // SRB2kart - Handle squishes first! + { + K_SetHitLagForObjects(tmthing, thing, 10); K_SquishPlayer(thing->player, tmthing, tmthing); + } else if (thing->scale > tmthing->scale + (mapobjectscale/8)) + { + K_SetHitLagForObjects(thing, tmthing, 10); K_SquishPlayer(tmthing->player, thing, tmthing); + } else if (tmthing->player->kartstuff[k_invincibilitytimer] && !thing->player->kartstuff[k_invincibilitytimer]) // SRB2kart - Then invincibility! + { + K_SetHitLagForObjects(tmthing, thing, 10); P_DamageMobj(thing, tmthing, tmthing, 1); + } else if (thing->player->kartstuff[k_invincibilitytimer] && !tmthing->player->kartstuff[k_invincibilitytimer]) + { + K_SetHitLagForObjects(thing, tmthing, 10); P_DamageMobj(tmthing, thing, thing, 1); + } else if ((tmthing->player->kartstuff[k_flamedash] && tmthing->player->kartstuff[k_itemtype] == KITEM_FLAMESHIELD) && !(thing->player->kartstuff[k_flamedash] && thing->player->kartstuff[k_itemtype] == KITEM_FLAMESHIELD)) // SRB2kart - Then flame shield! + { + K_SetHitLagForObjects(tmthing, thing, 10); P_DamageMobj(thing, tmthing, tmthing, 1); + } else if ((thing->player->kartstuff[k_flamedash] && thing->player->kartstuff[k_itemtype] == KITEM_FLAMESHIELD) && !(tmthing->player->kartstuff[k_flamedash] && tmthing->player->kartstuff[k_itemtype] == KITEM_FLAMESHIELD)) // SRB2kart - Then flame shield! + { + K_SetHitLagForObjects(tmthing, thing, 10); P_DamageMobj(tmthing, thing, thing, 1); + } /*if (G_BattleGametype() && (!G_GametypeHasTeams() || tmthing->player->ctfteam != thing->player->ctfteam)) { From 3dc2f4804fa081bd5775a73015adb1d52643c90e Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sun, 2 Aug 2020 10:26:29 -0400 Subject: [PATCH 009/143] Angle & scale now impact how long you're in hitlag --- src/k_collide.c | 44 +++++++++++++++++++------------- src/k_kart.c | 68 ++++++++++++++++++++++++++++++++++--------------- src/k_kart.h | 2 +- src/p_map.c | 12 ++++----- src/r_things.c | 2 +- 5 files changed, 83 insertions(+), 45 deletions(-) diff --git a/src/k_collide.c b/src/k_collide.c index 454ff9527..d6e457474 100644 --- a/src/k_collide.c +++ b/src/k_collide.c @@ -45,7 +45,7 @@ boolean K_OrbinautJawzCollide(mobj_t *t1, mobj_t *t2) else { // Player Damage - K_SetHitLagForObjects(t1, t2, 10); + K_SetHitLagForObjects(t1, t2, 10, false); P_DamageMobj(t2, t1, t1->target, 1); K_KartBouncing(t2, t1, false, false); S_StartSound(t2, sfx_s3k7b); @@ -59,7 +59,7 @@ boolean K_OrbinautJawzCollide(mobj_t *t1, mobj_t *t2) || t2->type == MT_BALLHOG) { // Other Item Damage - K_SetHitLagForObjects(t1, t2, 10); + K_SetHitLagForObjects(t1, t2, 10, false); S_StartSound(t2, t2->info->deathsound); P_KillMobj(t2, t1, t1); @@ -72,7 +72,7 @@ boolean K_OrbinautJawzCollide(mobj_t *t1, mobj_t *t2) } else if (t2->type == MT_SSMINE_SHIELD || t2->type == MT_SSMINE) { - K_SetHitLagForObjects(t1, t2, 10); + K_SetHitLagForObjects(t1, t2, 10, false); damageitem = true; // Bomb death P_KillMobj(t2, t1, t1); @@ -84,7 +84,7 @@ boolean K_OrbinautJawzCollide(mobj_t *t1, mobj_t *t2) } else if (t2->flags & MF_SHOOTABLE) { - K_SetHitLagForObjects(t1, t2, 10); + K_SetHitLagForObjects(t1, t2, 10, false); // Shootable damage P_DamageMobj(t2, t2, t1->target, 1); damageitem = true; @@ -142,7 +142,17 @@ boolean K_BananaBallhogCollide(mobj_t *t1, mobj_t *t2) else { // Player Damage - K_SetHitLagForObjects(t1, t2, 2); + if (t1->type == MT_BALLHOG || (t1->type == MT_BANANA && t1->health > 1)) + { + // Long hitlag + K_SetHitLagForObjects(t1, t2, 10, false); + } + else + { + // Short hitlag + K_SetHitLagForObjects(t1, t2, 2, true); + } + K_SpinPlayer(t2->player, t1->target, 0, t1, (t1->type == MT_BANANA || t1->type == MT_BANANA_SHIELD)); } @@ -154,7 +164,7 @@ boolean K_BananaBallhogCollide(mobj_t *t1, mobj_t *t2) || t2->type == MT_BALLHOG) { // Other Item Damage - K_SetHitLagForObjects(t1, t2, 10); + K_SetHitLagForObjects(t1, t2, 10, false); S_StartSound(t2, t2->info->deathsound); P_KillMobj(t2, t1, t1); @@ -169,7 +179,7 @@ boolean K_BananaBallhogCollide(mobj_t *t1, mobj_t *t2) else if (t2->flags & MF_SHOOTABLE) { // Shootable damage - K_SetHitLagForObjects(t1, t2, 10); + K_SetHitLagForObjects(t1, t2, 10, false); P_DamageMobj(t2, t2, t1->target, 1); damageitem = true; } @@ -177,7 +187,7 @@ boolean K_BananaBallhogCollide(mobj_t *t1, mobj_t *t2) if (damageitem) { // This Item Damage - K_SetHitLagForObjects(t1, t2, 10); + K_SetHitLagForObjects(t1, t2, 10, false); S_StartSound(t1, t1->info->deathsound); P_KillMobj(t1, t2, t2); @@ -280,19 +290,19 @@ boolean K_MineCollide(mobj_t *t1, mobj_t *t2) if ((t1->state >= &states[S_SSMINE1] && t1->state <= &states[S_SSMINE4]) || (t1->state >= &states[S_SSMINE_DEPLOY8] && t1->state <= &states[S_SSMINE_DEPLOY13])) { - K_SetHitLagForObjects(t1, t2, 10); + K_SetHitLagForObjects(t1, t2, 10, false); P_KillMobj(t1, t2, t2); } else { - K_SetHitLagForObjects(t1, t2, 2); + K_SetHitLagForObjects(t1, t2, 2, true); K_PuntMine(t1, t2); } } else if (t2->type == MT_ORBINAUT || t2->type == MT_JAWZ || t2->type == MT_JAWZ_DUD || t2->type == MT_ORBINAUT_SHIELD || t2->type == MT_JAWZ_SHIELD) { - K_SetHitLagForObjects(t1, t2, 10); + K_SetHitLagForObjects(t1, t2, 10, false); // Bomb death P_KillMobj(t1, t2, t2); @@ -306,7 +316,7 @@ boolean K_MineCollide(mobj_t *t1, mobj_t *t2) } else if (t2->flags & MF_SHOOTABLE) { - K_SetHitLagForObjects(t1, t2, 10); + K_SetHitLagForObjects(t1, t2, 10, false); // Bomb death P_KillMobj(t1, t2, t2); // Shootable damage @@ -325,19 +335,19 @@ boolean K_MineExplosionCollide(mobj_t *t1, mobj_t *t2) if (t1->state == &states[S_MINEEXPLOSION1]) { - K_SetHitLagForObjects(t1, t2, 10); + K_SetHitLagForObjects(t1, t2, 10, false); K_ExplodePlayer(t2->player, t1->target, t1); } else { - K_SetHitLagForObjects(t1, t2, 2); + K_SetHitLagForObjects(t1, t2, 2, true); K_SpinPlayer(t2->player, t1->target, 0, t1, false); } } else if (t2->flags & MF_SHOOTABLE) { // Shootable damage - K_SetHitLagForObjects(t1, t2, 10); + K_SetHitLagForObjects(t1, t2, 10, false); P_DamageMobj(t2, t2, t1->target, 1); } @@ -354,7 +364,7 @@ boolean K_KitchenSinkCollide(mobj_t *t1, mobj_t *t2) if (t2->player->powers[pw_flashing] > 0 && t2->hitlag == 0) return true; - K_SetHitLagForObjects(t1, t2, 10); + K_SetHitLagForObjects(t1, t2, 10, false); S_StartSound(NULL, sfx_bsnipe); // let all players hear it. @@ -368,7 +378,7 @@ boolean K_KitchenSinkCollide(mobj_t *t1, mobj_t *t2) } else if (t2->flags & MF_SHOOTABLE) { - K_SetHitLagForObjects(t1, t2, 10); + K_SetHitLagForObjects(t1, t2, 10, false); // Shootable damage P_KillMobj(t2, t2, t1->target); // This Item Damage diff --git a/src/k_kart.c b/src/k_kart.c index 94942abf7..5495c0130 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -2375,39 +2375,63 @@ angle_t K_MomentumAngle(mobj_t *mo) } } -void K_SetHitLagForObjects(mobj_t *mo1, mobj_t *mo2, INT32 tics) +void K_SetHitLagForObjects(mobj_t *mo1, mobj_t *mo2, INT32 tics, boolean fixed) { - const fixed_t ticaddfactor = mapobjectscale * 4; - - const fixed_t mo1speed = P_AproxDistance(P_AproxDistance(mo1->momx, mo1->momy), mo1->momz); - const fixed_t mo2speed = P_AproxDistance(P_AproxDistance(mo2->momx, mo2->momy), mo2->momz); - const fixed_t speeddiff = abs(mo1speed - mo2speed); - - //const angle_t mo1angle = K_MomentumAngle(mo1); - //const angle_t mo2angle = K_MomentumAngle(mo2); - - //angle_t anglediff = mo1angle - mo2angle; - fixed_t anglemul = FRACUNIT; - INT32 tics1 = tics; INT32 tics2 = tics; - //if (anglediff > ANGLE_180) - //{ - //anglediff = InvAngle(anglediff); - //} + if (fixed == false) + { + const fixed_t ticaddfactor = mapobjectscale * 8; + const INT32 mintics = tics; - //anglemul = FRACUNIT/2 + (FixedAngle(ANGLE_180 - anglediff) / 90); // x0.5 at 0, x1.5 at 90, x2.5 at 180 + const fixed_t mo1speed = P_AproxDistance(P_AproxDistance(mo1->momx, mo1->momy), mo1->momz); + const fixed_t mo2speed = P_AproxDistance(P_AproxDistance(mo2->momx, mo2->momy), mo2->momz); + const fixed_t speeddiff = mo2speed - mo1speed; - tics1 += FixedMul(speeddiff, anglemul) / ticaddfactor; // FixedMul(ticaddfactor, max(1, FRACUNIT + (mo2->scale - mo1->scale))); - tics2 += FixedMul(speeddiff, anglemul) / ticaddfactor; + const fixed_t scalediff = mo2->scale - mo1->scale; + + const angle_t mo1angle = K_MomentumAngle(mo1); + const angle_t mo2angle = K_MomentumAngle(mo2); + + angle_t anglediff = mo1angle - mo2angle; + fixed_t anglemul = FRACUNIT; + + if (anglediff > ANGLE_180) + { + anglediff = InvAngle(anglediff); + } + + anglemul = FRACUNIT + (AngleFixed(anglediff) / 180); // x1.0 at 0, x1.5 at 90, x2.0 at 180 + + /* + CONS_Printf("anglemul: %f\n", FIXED_TO_FLOAT(anglemul)); + CONS_Printf("speeddiff: %f\n", FIXED_TO_FLOAT(speeddiff)); + CONS_Printf("scalediff: %f\n", FIXED_TO_FLOAT(scalediff)); + */ + + tics1 += FixedMul(speeddiff, FixedMul(anglemul, FRACUNIT + scalediff)) / ticaddfactor; + tics2 += FixedMul(-speeddiff, FixedMul(anglemul, FRACUNIT - scalediff)) / ticaddfactor; + + if (tics1 < mintics) + { + tics1 = mintics; + } + + if (tics2 < mintics) + { + tics2 = mintics; + } + } if (mo1->player && !mo2->player) { if (mo1->player->powers[pw_flashing] > 0 || mo1->player->kartstuff[k_invincibilitytimer] > 0 || mo1->player->kartstuff[k_growshrinktimer] > 0) + { tics1 = 0; + } } if (mo2->player && !mo1->player) @@ -2415,9 +2439,13 @@ void K_SetHitLagForObjects(mobj_t *mo1, mobj_t *mo2, INT32 tics) if (mo2->player->powers[pw_flashing] > 0 || mo2->player->kartstuff[k_invincibilitytimer] > 0 || mo2->player->kartstuff[k_growshrinktimer] > 0) + { tics2 = 0; + } } + //CONS_Printf("tics1: %d, tics2: %d\n", tics1, tics2); + mo1->hitlag += tics1; mo2->hitlag += tics2; } diff --git a/src/k_kart.h b/src/k_kart.h index b2ab04c23..f632da842 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -40,7 +40,7 @@ void K_KartPlayerHUDUpdate(player_t *player); void K_KartPlayerThink(player_t *player, ticcmd_t *cmd); void K_KartPlayerAfterThink(player_t *player); angle_t K_MomentumAngle(mobj_t *mo); -void K_SetHitLagForObjects(mobj_t *mo1, mobj_t *mo2, INT32 tics); +void K_SetHitLagForObjects(mobj_t *mo1, mobj_t *mo2, INT32 tics, boolean fixed); void K_DoInstashield(player_t *player); void K_SpinPlayer(player_t *player, mobj_t *source, INT32 type, mobj_t *inflictor, boolean trapitem); void K_SquishPlayer(player_t *player, mobj_t *source, mobj_t *inflictor); diff --git a/src/p_map.c b/src/p_map.c index 4b2283020..5d4f4c8fe 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1307,34 +1307,34 @@ static boolean PIT_CheckThing(mobj_t *thing) { if (tmthing->scale > thing->scale + (mapobjectscale/8)) // SRB2kart - Handle squishes first! { - K_SetHitLagForObjects(tmthing, thing, 10); + K_SetHitLagForObjects(tmthing, thing, 10, false); K_SquishPlayer(thing->player, tmthing, tmthing); } else if (thing->scale > tmthing->scale + (mapobjectscale/8)) { - K_SetHitLagForObjects(thing, tmthing, 10); + K_SetHitLagForObjects(thing, tmthing, 10, false); K_SquishPlayer(tmthing->player, thing, tmthing); } else if (tmthing->player->kartstuff[k_invincibilitytimer] && !thing->player->kartstuff[k_invincibilitytimer]) // SRB2kart - Then invincibility! { - K_SetHitLagForObjects(tmthing, thing, 10); + K_SetHitLagForObjects(tmthing, thing, 10, false); P_DamageMobj(thing, tmthing, tmthing, 1); } else if (thing->player->kartstuff[k_invincibilitytimer] && !tmthing->player->kartstuff[k_invincibilitytimer]) { - K_SetHitLagForObjects(thing, tmthing, 10); + K_SetHitLagForObjects(thing, tmthing, 10, false); P_DamageMobj(tmthing, thing, thing, 1); } else if ((tmthing->player->kartstuff[k_flamedash] && tmthing->player->kartstuff[k_itemtype] == KITEM_FLAMESHIELD) && !(thing->player->kartstuff[k_flamedash] && thing->player->kartstuff[k_itemtype] == KITEM_FLAMESHIELD)) // SRB2kart - Then flame shield! { - K_SetHitLagForObjects(tmthing, thing, 10); + K_SetHitLagForObjects(tmthing, thing, 10, false); P_DamageMobj(thing, tmthing, tmthing, 1); } else if ((thing->player->kartstuff[k_flamedash] && thing->player->kartstuff[k_itemtype] == KITEM_FLAMESHIELD) && !(tmthing->player->kartstuff[k_flamedash] && tmthing->player->kartstuff[k_itemtype] == KITEM_FLAMESHIELD)) // SRB2kart - Then flame shield! { - K_SetHitLagForObjects(tmthing, thing, 10); + K_SetHitLagForObjects(tmthing, thing, 10, false); P_DamageMobj(tmthing, thing, thing, 1); } diff --git a/src/r_things.c b/src/r_things.c index 806326d1f..bea298e71 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1487,7 +1487,7 @@ static void R_ProjectSprite(mobj_t *thing) // hitlag vibrating if (thing->hitlag > 0) { - fixed_t mul = (thing->hitlag * FRACUNIT) / 5; + fixed_t mul = thing->hitlag * (FRACUNIT / 20); if (leveltime & 1) { From 31b99de407861f116ba03c089df8d98a6d7440b2 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sun, 2 Aug 2020 11:40:21 -0400 Subject: [PATCH 010/143] Use K_MomentumAngle for all instances of needing momentum angle for an object This means we will never ever have any "standing still defaults to angle 0" issues again :) --- src/k_kart.c | 28 +++++++++++----------------- src/p_enemy.c | 6 +++--- src/p_map.c | 2 +- src/p_mobj.c | 13 +++++-------- src/p_spec.c | 8 +++----- src/p_user.c | 4 ++-- 6 files changed, 25 insertions(+), 36 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 5495c0130..e56618120 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -1450,8 +1450,8 @@ static void K_UpdateDraft(player_t *player) continue; #ifndef EASYDRAFTTEST - yourangle = R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy); - theirangle = R_PointToAngle2(0, 0, players[i].mo->momx, players[i].mo->momy); + yourangle = K_MomentumAngle(player->mo); + theirangle = K_MomentumAngle(players[i].mo); diff = R_PointToAngle2(player->mo->x, player->mo->y, players[i].mo->x, players[i].mo->y) - yourangle; if (diff > ANGLE_180) @@ -2019,7 +2019,7 @@ void K_PlayPowerGloatSound(mobj_t *source) void K_MomentumToFacing(player_t *player) { - angle_t dangle = player->mo->angle - R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy); + angle_t dangle = player->mo->angle - K_MomentumAngle(player->mo); if (dangle > ANGLE_180) dangle = InvAngle(dangle); @@ -3445,7 +3445,7 @@ static void K_SpawnAIZDust(player_t *player) if (player->speed <= K_GetKartSpeed(player, false)) return; - travelangle = R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy); + travelangle = K_MomentumAngle(player->mo); //S_StartSound(player->mo, sfx_s3k47); { @@ -3716,7 +3716,7 @@ void K_DriftDustHandling(mobj_t *spawner) if (P_AproxDistance(spawner->momx, spawner->momy) < 5*spawner->scale) return; - anglediff = abs((signed)(spawner->angle - R_PointToAngle2(0, 0, spawner->momx, spawner->momy))); + anglediff = abs((signed)(spawner->angle - K_MomentumAngle(spawner))); } if (anglediff > ANGLE_180) @@ -4018,7 +4018,7 @@ static mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t map void K_PuntMine(mobj_t *thismine, mobj_t *punter) { - angle_t fa = R_PointToAngle2(0, 0, punter->momx, punter->momy) >> ANGLETOFINESHIFT; + angle_t fa = K_MomentumAngle(punter) >> ANGLETOFINESHIFT; fixed_t z = 30*mapobjectscale + punter->momz; fixed_t spd; mobj_t *mine; @@ -5604,7 +5604,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) MT_FASTLINE); P_SetTarget(&fast->target, player->mo); - fast->angle = R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy); + fast->angle = K_MomentumAngle(player->mo); fast->momx = 3*player->mo->momx/4; fast->momy = 3*player->mo->momy/4; fast->momz = 3*player->mo->momz/4; @@ -6154,18 +6154,12 @@ static waypoint_t *K_GetPlayerNextWaypoint(player_t *player) { boolean finishlinehack = false; angle_t playerangle = player->mo->angle; - angle_t momangle = player->mo->angle; + angle_t momangle = K_MomentumAngle(player->mo); angle_t angletowaypoint = R_PointToAngle2(player->mo->x, player->mo->y, waypoint->mobj->x, waypoint->mobj->y); angle_t angledelta = ANGLE_MAX; angle_t momdelta = ANGLE_MAX; - if (player->mo->momx != 0 || player->mo->momy != 0) - { - // Defaults to facing angle if you're not moving. - momangle = R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy); - } - angledelta = playerangle - angletowaypoint; if (angledelta > ANGLE_180) { @@ -6664,7 +6658,7 @@ static void K_KartDrift(player_t *player, boolean onground) { if (player->kartstuff[k_driftcharge] < 0 || player->kartstuff[k_driftcharge] >= dsone) { - angle_t pushdir = R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy); + angle_t pushdir = K_MomentumAngle(player->mo); S_StartSound(player->mo, sfx_s23c); //K_SpawnDashDustRelease(player); @@ -7045,7 +7039,7 @@ static void K_KartSpindash(player_t *player) mobj_t *grease; grease = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_TIREGREASE); P_SetTarget(&grease->target, player->mo); - grease->angle = R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy); + grease->angle = K_MomentumAngle(player->mo); grease->extravalue1 = i; } } @@ -7615,7 +7609,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) if (!onground) { P_Thrust( - player->mo, R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy), + player->mo, K_MomentumAngle(player->mo), FixedMul(player->mo->scale, K_GetKartGameSpeedScalar(gamespeed)) ); } diff --git a/src/p_enemy.c b/src/p_enemy.c index 80189f8e7..3d3735204 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -8393,7 +8393,7 @@ void A_JawzChase(mobj_t *actor) if (!actor->tracer) { - actor->angle = R_PointToAngle2(0, 0, actor->momx, actor->momy); + actor->angle = K_MomentumAngle(actor); } P_Thrust(actor, actor->angle, thrustamount); @@ -8525,7 +8525,7 @@ static void SpawnSPBAIZDust(mobj_t *mo, INT32 dir) if (mo->eflags & MFE_VERTICALFLIP) sz = mo->ceilingz; - travelangle = R_PointToAngle2(0, 0, mo->momx, mo->momy); + travelangle = K_MomentumAngle(mo); if (leveltime & 1 && abs(mo->z - sz) < FRACUNIT*64) { newx = mo->x + P_ReturnThrustX(mo, travelangle - (dir*ANGLE_45), FixedMul(24*FRACUNIT, mo->scale)); @@ -8555,7 +8555,7 @@ static void SpawnSPBSpeedLines(mobj_t *actor) MT_FASTLINE); P_SetTarget(&fast->target, actor); - fast->angle = R_PointToAngle2(0, 0, actor->momx, actor->momy); + fast->angle = K_MomentumAngle(actor); fast->color = SKINCOLOR_RED; fast->colorized = true; K_MatchGenericExtraFlags(fast, actor); diff --git a/src/p_map.c b/src/p_map.c index 5d4f4c8fe..aeed64748 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -344,7 +344,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) mobj_t *grease; grease = P_SpawnMobj(object->x, object->y, object->z, MT_TIREGREASE); P_SetTarget(&grease->target, object); - grease->angle = R_PointToAngle2(0, 0, object->momx, object->momy); + grease->angle = K_MomentumAngle(object); grease->extravalue1 = i; } } diff --git a/src/p_mobj.c b/src/p_mobj.c index 027e597c6..da4aecee3 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8001,7 +8001,7 @@ void P_MobjThinker(mobj_t *mobj) frictionsafety = FRACUNIT; } - mobj->angle = R_PointToAngle2(0, 0, mobj->momx, mobj->momy); + mobj->angle = K_MomentumAngle(mobj); if (mobj->health <= 5) { INT32 i; @@ -8103,7 +8103,7 @@ void P_MobjThinker(mobj_t *mobj) thrustamount = beatfriction + FixedDiv(mobj->movefactor - currentspeed, frictionsafety); } - mobj->angle = R_PointToAngle2(0, 0, mobj->momx, mobj->momy); + mobj->angle = K_MomentumAngle(mobj); P_Thrust(mobj, mobj->angle, thrustamount); if (P_MobjTouchingSectorSpecial(mobj, 3, 1, true)) @@ -8266,7 +8266,7 @@ void P_MobjThinker(mobj_t *mobj) //mobj->angle = mobj->target->angle; { - angle_t angle = R_PointToAngle2(0, 0, mobj->target->momx, mobj->target->momy); + angle_t angle = K_MomentumAngle(mobj->target); fixed_t nudge; mobj->angle = angle; @@ -8545,7 +8545,7 @@ void P_MobjThinker(mobj_t *mobj) z += mobj->target->height; if (mobj->target->momx || mobj->target->momy) - ang = R_PointToAngle2(0, 0, mobj->target->momx, mobj->target->momy); + ang = K_MomentumAngle(mobj->target); if (mobj->extravalue1) ang = (signed)(ang - off); @@ -8841,10 +8841,7 @@ void P_MobjThinker(mobj_t *mobj) } P_TeleportMove(mobj, destx, desty, mobj->target->z); - if (mobj->target->momx || mobj->target->momy) - mobj->angle = R_PointToAngle2(0, 0, mobj->target->momx, mobj->target->momy); - else - mobj->angle = mobj->target->angle; + mobj->angle = K_MomentumAngle(mobj->target); if (underlayst != S_NULL) { diff --git a/src/p_spec.c b/src/p_spec.c index 1e3c30299..326ae930f 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -4021,8 +4021,7 @@ DoneSection2: { const fixed_t hscale = mapobjectscale + (mapobjectscale - player->mo->scale); const fixed_t minspeed = 24*hscale; - angle_t pushangle = FixedHypot(player->mo->momx, player->mo->momy) ? R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy) : player->mo->angle; - // if we have no speed for SOME REASON, use the player's angle, otherwise we'd be forcefully thrusted to what I can only assume is angle 0 + angle_t pushangle = K_MomentumAngle(player->mo); if (player->mo->eflags & MFE_SPRUNG) break; @@ -4044,8 +4043,7 @@ DoneSection2: const fixed_t hscale = mapobjectscale + (mapobjectscale - player->mo->scale); const fixed_t minspeed = 24*hscale; const fixed_t maxspeed = 28*hscale; - angle_t pushangle = FixedHypot(player->mo->momx, player->mo->momy) ? R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy) : player->mo->angle; - // if we have no speed for SOME REASON, use the player's angle, otherwise we'd be forcefully thrusted to what I can only assume is angle 0 + angle_t pushangle = K_MomentumAngle(player->mo); if (player->mo->eflags & MFE_SPRUNG) break; @@ -4087,7 +4085,7 @@ DoneSection2: } lineangle = K_ReflectAngle( - R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy), lineangle, + K_MomentumAngle(player->mo), lineangle, playerspeed, linespeed ); diff --git a/src/p_user.c b/src/p_user.c index 3750c1378..684a00e5c 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -6061,7 +6061,7 @@ static void P_MovePlayer(player_t *player) if (trailScale > 0) { - const angle_t forwardangle = R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy); + const angle_t forwardangle = K_MomentumAngle(player->mo); 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); @@ -8530,7 +8530,7 @@ static void P_HandleFollower(player_t *player) player->follower->drawflags |= MFD_DONTDRAW; if (player->speed && (player->follower->momx || player->follower->momy)) - player->follower->angle = R_PointToAngle2(0, 0, player->follower->momx, player->follower->momy); + player->follower->angle = K_MomentumAngle(player->follower); // if we're moving let's make the angle the direction we're moving towards. This is to avoid drifting / reverse looking awkward. // Make sure the follower itself is also moving however, otherwise we'll be facing angle 0 From 70eec29992379e06e2985a8ef6883e0b13d6e67e Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 28 Sep 2020 11:58:24 -0700 Subject: [PATCH 011/143] Mute music instead of pausing if lose focus --- src/s_sound.c | 6 +++--- src/sdl/i_video.c | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/s_sound.c b/src/s_sound.c index 225863211..ea0a1bbe7 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -1952,7 +1952,7 @@ static boolean S_PlayMusic(boolean looping, UINT32 fadeinms) S_InitMusicVolume(); // switch between digi and sequence volume if (window_notinfocus && !cv_playmusicifunfocused.value) - I_PauseSong(); + I_SetMusicVolume(0); return true; } @@ -2418,9 +2418,9 @@ static void PlayMusicIfUnfocused_OnChange(void) if (window_notinfocus) { if (cv_playmusicifunfocused.value) - I_PauseSong(); + I_SetMusicVolume(0); else - I_ResumeSong(); + S_InitMusicVolume(); } } diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 37eedf147..2858e9b6f 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -625,7 +625,7 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt) window_notinfocus = false; if (!paused) - I_ResumeSong(); //resume it + S_InitMusicVolume(); if (cv_gamesounds.value) S_EnableSound(); @@ -641,7 +641,7 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt) // Tell game we lost focus, pause music window_notinfocus = true; if (!cv_playmusicifunfocused.value) - I_PauseSong(); + I_SetMusicVolume(0); if (!cv_playsoundifunfocused.value) S_DisableSound(); From f7a4667bc3f745f48e66352c8c3012e957b21584 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 30 Sep 2020 03:55:16 -0700 Subject: [PATCH 012/143] Use STUN instead of curl to fetch the public IP address for Discord RFC 5389 is a standard protocol that can be used for this instead of ip4.me. I may have gone overboard on the CSPRNG... It was fun though. --- src/Makefile | 4 +- src/d_clisrv.h | 1 + src/d_netcmd.c | 4 + src/discord.c | 138 +++++++++--------------------- src/i_tcp.c | 8 ++ src/m_swap.h | 17 ++-- src/stun.c | 222 +++++++++++++++++++++++++++++++++++++++++++++++++ src/stun.h | 20 +++++ 8 files changed, 305 insertions(+), 109 deletions(-) create mode 100644 src/stun.c create mode 100644 src/stun.h diff --git a/src/Makefile b/src/Makefile index fb859a339..da96f0cf1 100644 --- a/src/Makefile +++ b/src/Makefile @@ -440,8 +440,8 @@ endif ifdef HAVE_DISCORDRPC LIBS+=-ldiscord-rpc -CFLAGS+=-DHAVE_DISCORDRPC -OBJS+=$(OBJDIR)/discord.o +CFLAGS+=-DHAVE_DISCORDRPC -DUSE_STUN +OBJS+=$(OBJDIR)/discord.o $(OBJDIR)/stun.o endif ifndef NO_LUA diff --git a/src/d_clisrv.h b/src/d_clisrv.h index b88e7936b..b7fc56ec9 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -502,6 +502,7 @@ extern INT32 mapchangepending; // Points inside doomcom extern doomdata_t *netbuffer; +extern consvar_t cv_stunserver; extern consvar_t cv_httpsource; extern consvar_t cv_showjoinaddress; extern consvar_t cv_playbackspeed; diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 4a90de333..84c1045a1 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -714,6 +714,10 @@ void D_RegisterServerCommands(void) CV_RegisterVar(&cv_dummyconsvar); +#ifdef USE_STUN + CV_RegisterVar(&cv_stunserver); +#endif + CV_RegisterVar(&cv_discordinvites); RegisterNetXCmd(XD_DISCORD, Got_DiscordInfo); } diff --git a/src/discord.c b/src/discord.c index b3798e291..4f72b714a 100644 --- a/src/discord.c +++ b/src/discord.c @@ -12,9 +12,7 @@ #ifdef HAVE_DISCORDRPC -#ifdef HAVE_CURL -#include -#endif // HAVE_CURL +#include #include "i_system.h" #include "d_clisrv.h" @@ -27,6 +25,8 @@ #include "mserv.h" // cv_advertise #include "z_zone.h" #include "byteptr.h" +#include "stun.h" +#include "i_tcp.h" // current_port #include "discord.h" #include "doomdef.h" @@ -45,16 +45,7 @@ struct discordInfo_s discordInfo; discordRequest_t *discordRequestList = NULL; -#ifdef HAVE_CURL -struct SelfIPbuffer -{ - CURL *curl; - char *pointer; - size_t length; -}; - static char self_ip[IP_SIZE]; -#endif // HAVE_CURL /*-------------------------------------------------- static char *DRPC_XORIPString(const char *input) @@ -335,39 +326,23 @@ void DRPC_Init(void) DRPC_UpdatePresence(); } -#ifdef HAVE_CURL /*-------------------------------------------------- - static size_t DRPC_WriteServerIP(char *s, size_t size, size_t n, void *userdata) + static void DRPC_GotServerIP(UINT32 address) - Writing function for use with curl. Only intended to be used with simple text. + Callback triggered by successful STUN response. Input Arguments:- - s - Data to write - size - Always 1. - n - Length of data - userdata - Passed in from CURLOPT_WRITEDATA, intended to be SelfIPbuffer + address - IPv4 address of this machine, in network byte order. Return:- - Number of bytes wrote in this pass. + None --------------------------------------------------*/ -static size_t DRPC_WriteServerIP(char *s, size_t size, size_t n, void *userdata) +static void DRPC_GotServerIP(UINT32 address) { - struct SelfIPbuffer *buffer; - size_t newlength; - - buffer = userdata; - - newlength = buffer->length + size*n; - buffer->pointer = realloc(buffer->pointer, newlength+1); - - memcpy(buffer->pointer + buffer->length, s, size*n); - - buffer->pointer[newlength] = '\0'; - buffer->length = newlength; - - return size*n; + const unsigned char * p = (const unsigned char *)&address; + sprintf(self_ip, "%u.%u.%u.%u:%u", p[0], p[1], p[2], p[3], current_port); + DRPC_UpdatePresence(); } -#endif // HAVE_CURL /*-------------------------------------------------- static const char *DRPC_GetServerIP(void) @@ -387,64 +362,21 @@ static const char *DRPC_GetServerIP(void) { // We're not the server, so we could successfully get the IP! // No need to do anything else :) - return address; + sprintf(self_ip, "%s:%u", address, current_port); + return self_ip; } } -#ifdef HAVE_CURL - // This is a little bit goofy, but - // there's practically no good way to get your own public IP address, - // so we've gotta break out curl for this :V - if (!self_ip[0]) - { - CURL *curl; - - curl_global_init(CURL_GLOBAL_ALL); - curl = curl_easy_init(); - - if (curl) - { - // The API to get your public IP address from. - // Picked because it's stupid simple and it's been up for a long time. - const char *api = "http://ip4only.me/api/"; - - struct SelfIPbuffer buffer; - CURLcode success; - - buffer.length = 0; - buffer.pointer = malloc(buffer.length+1); - buffer.pointer[0] = '\0'; - - curl_easy_setopt(curl, CURLOPT_URL, api); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, DRPC_WriteServerIP); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, &buffer); - - success = curl_easy_perform(curl); - - if (success == CURLE_OK) - { - char *tmp; - tmp = strtok(buffer.pointer, ","); - - if (!strcmp(tmp, "IPv4")) // ensure correct type of IP - { - tmp = strtok(NULL, ","); - strncpy(self_ip, tmp, IP_SIZE); // Yay, we have the IP :) - } - } - - free(buffer.pointer); - curl_easy_cleanup(curl); - } - - curl_global_cleanup(); - } - if (self_ip[0]) + { return self_ip; + } else -#endif // HAVE_CURL - return NULL; // Could not get your IP for whatever reason, so we cannot do Discord invites + { + // There happens to be a good way to get it after all! :D + STUN_bind(DRPC_GotServerIP); + return NULL; + } } /*-------------------------------------------------- @@ -510,19 +442,6 @@ void DRPC_UpdatePresence(void) // Server info if (netgame) { - if (cv_advertise.value) - { - discordPresence.state = "Public"; - } - else - { - discordPresence.state = "Private"; - } - - discordPresence.partyId = server_context; // Thanks, whoever gave us Mumble support, for implementing the EXACT thing Discord wanted for this field! - discordPresence.partySize = D_NumPlayers(); // Players in server - discordPresence.partyMax = discordInfo.maxPlayers; // Max players - if (DRPC_InvitesAreAllowed() == true) { const char *join; @@ -536,7 +455,24 @@ void DRPC_UpdatePresence(void) joinSecretSet = true; } + else + { + return; + } } + + if (cv_advertise.value) + { + discordPresence.state = "Public"; + } + else + { + discordPresence.state = "Private"; + } + + discordPresence.partyId = server_context; // Thanks, whoever gave us Mumble support, for implementing the EXACT thing Discord wanted for this field! + discordPresence.partySize = D_NumPlayers(); // Players in server + discordPresence.partyMax = discordInfo.maxPlayers; // Max players } else { diff --git a/src/i_tcp.c b/src/i_tcp.c index 1f1cf4f22..ba973494f 100644 --- a/src/i_tcp.c +++ b/src/i_tcp.c @@ -182,6 +182,7 @@ static UINT8 UPNP_support = TRUE; #include "d_netfil.h" #include "i_tcp.h" #include "m_argv.h" +#include "stun.h" #include "doomstat.h" @@ -612,6 +613,13 @@ static boolean SOCK_Get(void) (void *)&fromaddress, &fromlen); if (c != ERRSOCKET) { +#ifdef USE_STUN + if (STUN_got_response(doomcom->data, c)) + { + return false; + } +#endif + // find remote node number for (j = 1; j <= MAXNETNODES; j++) //include LAN { diff --git a/src/m_swap.h b/src/m_swap.h index 2d42f6138..c1e5e39b7 100644 --- a/src/m_swap.h +++ b/src/m_swap.h @@ -16,16 +16,12 @@ #include "endian.h" -// Endianess handling. -// WAD files are stored little endian. -#ifdef SRB2_BIG_ENDIAN - -#define SHORT(x) ((INT16)(\ +#define SWAP_SHORT(x) ((INT16)(\ (((UINT16)(x) & (UINT16)0x00ffU) << 8) \ | \ (((UINT16)(x) & (UINT16)0xff00U) >> 8))) \ -#define LONG(x) ((INT32)(\ +#define SWAP_LONG(x) ((INT32)(\ (((UINT32)(x) & (UINT32)0x000000ffUL) << 24) \ | \ (((UINT32)(x) & (UINT32)0x0000ff00UL) << 8) \ @@ -34,9 +30,18 @@ | \ (((UINT32)(x) & (UINT32)0xff000000UL) >> 24))) +// Endianess handling. +// WAD files are stored little endian. +#ifdef SRB2_BIG_ENDIAN +#define SHORT SWAP_SHORT +#define LONG SWAP_LONG +#define MSBF_SHORT(x) ((INT16)(x)) +#define MSBF_LONG(x) ((INT32)(x)) #else #define SHORT(x) ((INT16)(x)) #define LONG(x) ((INT32)(x)) +#define MSBF_SHORT SWAP_SHORT +#define MSBF_LONG SWAP_LONG #endif #endif diff --git a/src/stun.c b/src/stun.c new file mode 100644 index 000000000..96f95d41a --- /dev/null +++ b/src/stun.c @@ -0,0 +1,222 @@ +// SONIC ROBO BLAST 2 KART +//----------------------------------------------------------------------------- +// Copyright (C) 2020 by James R. +// +// 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 stun.c +/// \brief RFC 5389 client implementation to fetch external IP address. + +/* https://tools.ietf.org/html/rfc5389 */ + +#if defined (__linux__) +#include +#elif defined (_WIN32) +//#include +#elif defined (__APPLE__) +#include +#else +#error "Need CSPRNG." +#endif + +#include "doomdef.h" +#include "d_clisrv.h" +#include "command.h" +#include "i_net.h" +#include "stun.h" + +/* https://gist.github.com/zziuni/3741933 */ +/* I can only trust google to keep their shit up :y */ +consvar_t cv_stunserver = { + "stunserver", "stun.l.google.com:19302", CV_SAVE, NULL, + NULL, 0, NULL, NULL, 0, 0, NULL/* C90 moment */ +}; + +static stun_callback_t stun_callback; + +/* 18.4 STUN UDP and TCP Port Numbers */ + +#define STUN_PORT "3478" + +/* 6. STUN Message Structure */ + +#define BIND_REQUEST 0x0001 +#define BIND_RESPONSE 0x0101 + +static const UINT32 MAGIC_COOKIE = MSBF_LONG (0x2112A442); + +static char transaction_id[12]; + +/* 18.2 STUN Attribute Registry */ + +#define XOR_MAPPED_ADDRESS 0x0020 + +/* 15.1 MAPPED-ADDRESS */ + +#define STUN_IPV4 0x01 + +static SINT8 +STUN_node (void) +{ + SINT8 node; + + char * const colon = strchr(cv_stunserver.zstring, ':'); + + const char * const host = cv_stunserver.zstring; + const char * const port = &colon[1]; + + I_Assert(I_NetMakeNodewPort != NULL); + + if (colon != NULL) + { + *colon = '\0'; + + node = I_NetMakeNodewPort(host, port); + + *colon = ':'; + } + else + { + node = I_NetMakeNodewPort(host, STUN_PORT); + } + + return node; +} + +void +STUN_bind (stun_callback_t callback) +{ + /* 6. STUN Message Structure */ + + const UINT16 type = MSBF_SHORT (BIND_REQUEST); + + const SINT8 node = STUN_node(); + + doomcom->remotenode = node; + doomcom->datalength = 20; + +#if defined (__linux__) + getrandom(transaction_id, 12U, 0U); +#elif defined (_WIN32) + //RtlGenRandom(transaction_id, 12UL); +#elif defined (__APPLE__) + CCRandomGenerateBytes(stun_transcation_id, 12U); +#elif defined (__FreeBSD__) || defined (__NetBSD__) || defined (__OpenBSD__) + arc4random_buf(transaction_id, 12U); +#endif + + memcpy(&doomcom->data[0], &type, 2U); + memset(&doomcom->data[2], 0, 2U); + memcpy(&doomcom->data[4], &MAGIC_COOKIE, 4U); + memcpy(&doomcom->data[8], transaction_id, 12U); + + stun_callback = callback; + + I_NetSend(); + Net_CloseConnection(node);/* will handle response at I_NetGet */ +} + +static size_t +STUN_xor_mapped_address (const char * const value) +{ + const UINT32 xaddr = *(const UINT32 *)&value[4]; + const UINT32 addr = xaddr ^ MAGIC_COOKIE; + + (*stun_callback)(addr); + + return 0U; +} + +static size_t +align4 (size_t n) +{ + return n + n % 4U; +} + +static size_t +STUN_parse_attribute (const char * const attribute) +{ + /* 15. STUN Attributes */ + const UINT16 type = MSBF_SHORT (*(const UINT16 *)&attribute[0]); + const UINT16 length = MSBF_SHORT (*(const UINT16 *)&attribute[2]); + + /* 15.2 XOR-MAPPED-ADDRESS */ + if ( + type == XOR_MAPPED_ADDRESS && + length == 8U && + (unsigned char)attribute[5] == STUN_IPV4 + ){ + return STUN_xor_mapped_address(&attribute[4]); + } + + return align4(4U + length); +} + +boolean +STUN_got_response +( + const char * const buffer, + const size_t size +){ + const char * const end = &buffer[size]; + + const char * p = &buffer[20]; + + UINT16 type; + UINT16 length; + + /* + Check for STUN response. + + Header is 20 bytes. + XOR-MAPPED-ADDRESS attribute is required. + Each attribute has a 2 byte header. + The XOR-MAPPED-ADDRESS attribute also has a 8 byte value. + This totals 10 bytes for the attribute. + */ + + if (size < 30U || stun_callback == NULL) + { + return false; + } + + /* 6. STUN Message Structure */ + + if ( + *(const UINT32 *)&buffer[4] == MAGIC_COOKIE && + memcmp(&buffer[8], transaction_id, 12U) == 0 + ){ + type = MSBF_SHORT (*(const UINT16 *)&buffer[0]); + length = MSBF_SHORT (*(const UINT16 *)&buffer[2]); + + if ( + (type >> 14) == 0U && + (length & 0x02) == 0U && + (20U + length) <= size + ){ + if (type == BIND_RESPONSE) + { + do + { + length = STUN_parse_attribute(p); + + if (length == 0U) + { + break; + } + + p += length; + } + while (p < end) ; + } + + stun_callback = NULL; + + return true; + } + } + + return false; +} diff --git a/src/stun.h b/src/stun.h new file mode 100644 index 000000000..de23aeb42 --- /dev/null +++ b/src/stun.h @@ -0,0 +1,20 @@ +// SONIC ROBO BLAST 2 KART +//----------------------------------------------------------------------------- +// Copyright (C) 2020 by James R. +// +// 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 stun.h +/// \brief RFC 5389 client implementation to fetch external IP address. + +#ifndef KART_STUN_H +#define KART_STUN_H + +typedef void (*stun_callback_t)(UINT32 address); + +void STUN_bind (stun_callback_t); +boolean STUN_got_response (const char * const buffer, const size_t size); + +#endif/*KART_STUN_H*/ From cf73df38b43eca9c19cee0adc6b0df67746bca18 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 30 Sep 2020 12:21:33 -0700 Subject: [PATCH 013/143] Use rand_s for Windoze unsigned int is always 4 bytes on windows btw, so this should align properly. --- src/stun.c | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/src/stun.c b/src/stun.c index 96f95d41a..dbcfe58e8 100644 --- a/src/stun.c +++ b/src/stun.c @@ -14,7 +14,7 @@ #if defined (__linux__) #include #elif defined (_WIN32) -//#include +#define _CRT_RAND_S #elif defined (__APPLE__) #include #else @@ -85,6 +85,28 @@ STUN_node (void) return node; } +static void +csprng +( + void * const buffer, + const size_t size +){ +#if defined (_WIN32) + size_t o; + + for (o = 0; o < size; o += sizeof (unsigned int)) + { + rand_s((unsigned int *)&((char *)buffer)[o]); + } +#elif defined (__linux__) + getrandom(buffer, size, 0U); +#elif defined (__APPLE__) + CCRandomGenerateBytes(buffer, size); +#elif defined (__FreeBSD__) || defined (__NetBSD__) || defined (__OpenBSD__) + arc4random_buf(buffer, size); +#endif +} + void STUN_bind (stun_callback_t callback) { @@ -97,15 +119,7 @@ STUN_bind (stun_callback_t callback) doomcom->remotenode = node; doomcom->datalength = 20; -#if defined (__linux__) - getrandom(transaction_id, 12U, 0U); -#elif defined (_WIN32) - //RtlGenRandom(transaction_id, 12UL); -#elif defined (__APPLE__) - CCRandomGenerateBytes(stun_transcation_id, 12U); -#elif defined (__FreeBSD__) || defined (__NetBSD__) || defined (__OpenBSD__) - arc4random_buf(transaction_id, 12U); -#endif + csprng(transaction_id, 12U); memcpy(&doomcom->data[0], &type, 2U); memset(&doomcom->data[2], 0, 2U); From 186cdea8d5b23d6e1c11db58e0a0d65a72a0676a Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 30 Sep 2020 12:42:53 -0700 Subject: [PATCH 014/143] Reset asksent before CL_ASKJOIN It gets pushed forward for ASKINFO. --- src/d_clisrv.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 88fdb35a8..f27d19ce9 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -2263,7 +2263,10 @@ static boolean CL_ServerConnectionSearchTicker(tic_t *asksent) cl_mode = CL_CHECKFILES; } else + { cl_mode = CL_ASKJOIN; // files need not be checked for the server. + *asksent = 0; + } return true; } From 8a7044a4ef4549f2c3d905a96d8e55e2afab501d Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 30 Sep 2020 21:15:49 -0700 Subject: [PATCH 015/143] Add STUN to CMakeLists.txt --- src/CMakeLists.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c43464b78..9854567e2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -364,8 +364,9 @@ if(${SRB2_CONFIG_HAVE_DISCORDRPC}) if(${DISCORDRPC_FOUND}) set(SRB2_HAVE_DISCORDRPC ON) add_definitions(-DHAVE_DISCORDRPC) - set(SRB2_DISCORDRPC_SOURCES discord.c) - set(SRB2_DISCORDRPC_HEADERS discord.h) + add_definitions(-DUSE_STUN) + set(SRB2_DISCORDRPC_SOURCES discord.c stun.c) + set(SRB2_DISCORDRPC_HEADERS discord.h stun.h) prepend_sources(SRB2_DISCORDRPC_SOURCES) prepend_sources(SRB2_DISCORDRPC_HEADERS) source_group("Discord Rich Presence" FILES ${SRB2_DISCORDRPC_SOURCES} ${SRB2_DISCORDRPC_HEADERS}) From 67df3cdb12ca86c7a6c68ae49182c37acf35c4f2 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 7 Oct 2020 16:06:49 -0700 Subject: [PATCH 016/143] Download files that were found with wrong checksum --- src/d_netfil.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d_netfil.c b/src/d_netfil.c index c9bfb4ea7..950608c42 100644 --- a/src/d_netfil.c +++ b/src/d_netfil.c @@ -430,7 +430,7 @@ INT32 CL_CheckFiles(void) for (i = 0; i < fileneedednum; i++) { - if (fileneeded[i].status == FS_NOTFOUND || fileneeded[i].status == FS_FALLBACK) + if (fileneeded[i].status == FS_NOTFOUND || fileneeded[i].status == FS_MD5SUMBAD || fileneeded[i].status == FS_FALLBACK) downloadrequired = true; if (fileneeded[i].status == FS_FOUND || fileneeded[i].status == FS_NOTFOUND) From c59d456772029b166c8231282fb50a883d2e0143 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 7 Oct 2020 16:09:21 -0700 Subject: [PATCH 017/143] Count any files not already loaded toward filestoload? --- src/d_netfil.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d_netfil.c b/src/d_netfil.c index 950608c42..1a5b9e41e 100644 --- a/src/d_netfil.c +++ b/src/d_netfil.c @@ -433,7 +433,7 @@ INT32 CL_CheckFiles(void) if (fileneeded[i].status == FS_NOTFOUND || fileneeded[i].status == FS_MD5SUMBAD || fileneeded[i].status == FS_FALLBACK) downloadrequired = true; - if (fileneeded[i].status == FS_FOUND || fileneeded[i].status == FS_NOTFOUND) + if (fileneeded[i].status != FS_OPEN) filestoload++; if (fileneeded[i].status != FS_NOTCHECKED) //since we're running this over multiple tics now, its possible for us to come across files checked in previous tics From 7ce53ac1045b75184c45e9771bd7e43d3ef631a2 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Thu, 22 Oct 2020 02:52:33 -0400 Subject: [PATCH 018/143] Add blue spheres Doesn't have animations, and doesn't have stat-specific buffs. But it's already a massive improvement --- src/d_clisrv.c | 2 ++ src/d_clisrv.h | 1 + src/d_player.h | 1 + src/doomstat.h | 32 ++++++++++++------------ src/g_game.c | 10 +++++--- src/info.c | 30 +++++++++++------------ src/info.h | 2 +- src/k_kart.c | 21 +++++++++++++++- src/lua_playerlib.c | 4 +++ src/p_floor.c | 2 +- src/p_inter.c | 14 ++++++++++- src/p_mobj.c | 59 +++++++++++++++++++++------------------------ src/p_saveg.c | 2 ++ 13 files changed, 111 insertions(+), 69 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index bbf115124..867a3e006 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -545,6 +545,7 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i) // Score is resynched in the rspfirm resync packet rsp->rings = SHORT(players[i].rings); + rsp->spheres = SHORT(players[i].spheres); rsp->lives = players[i].lives; rsp->lostlife = players[i].lostlife; rsp->continues = players[i].continues; @@ -689,6 +690,7 @@ static void resynch_read_player(resynch_pak *rsp) // Score is resynched in the rspfirm resync packet players[i].rings = SHORT(rsp->rings); + players[i].spheres = SHORT(rsp->spheres); players[i].lives = rsp->lives; players[i].lostlife = rsp->lostlife; players[i].continues = rsp->continues; diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 2f1caa82e..573c98dc8 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -214,6 +214,7 @@ typedef struct // Score is resynched in the confirm resync packet INT16 rings; + INT16 spheres; SINT8 lives; boolean lostlife; SINT8 continues; diff --git a/src/d_player.h b/src/d_player.h index 283196e4d..36829fecc 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -497,6 +497,7 @@ typedef struct player_s // player's ring count INT16 rings; + INT16 spheres; // Power ups. invinc and invis are tic counters. UINT16 powers[NUMPOWERS]; diff --git a/src/doomstat.h b/src/doomstat.h index 7356a8c18..675318c22 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -461,30 +461,30 @@ enum GameTypeRules { // Race rules GTR_CIRCUIT = 1, // Enables the finish line, laps, and the waypoint system. - GTR_RINGS = 1<<1, // Rings will be spawned in this mode. (Don't get too cheeky, ring sting is still enabled :]) GTR_BOTS = 1<<2, // Allows bots in this gametype. Combine with BotTiccmd hooks to make bots support your gametype. // Battle gametype rules - GTR_BUMPERS = 1<<3, // Enables the bumper health system - GTR_WANTED = 1<<4, // Enables the wanted anti-camping system - GTR_KARMA = 1<<5, // Enables the Karma system if you're out of bumpers - GTR_ITEMARROWS = 1<<6, // Show item box arrows above players - GTR_CAPSULES = 1<<7, // Enables the wanted anti-camping system - GTR_BATTLESTARTS = 1<<8, // Use Battle Mode start positions. + GTR_SPHERES = 1<<3, // Replaces rings with blue spheres + GTR_BUMPERS = 1<<4, // Enables the bumper health system + GTR_WANTED = 1<<5, // Enables the wanted anti-camping system + GTR_KARMA = 1<<6, // Enables the Karma system if you're out of bumpers + GTR_ITEMARROWS = 1<<7, // Show item box arrows above players + GTR_CAPSULES = 1<<8, // Enables the wanted anti-camping system + GTR_BATTLESTARTS = 1<<9, // Use Battle Mode start positions. - GTR_POINTLIMIT = 1<<9, // Reaching point limit ends the round - GTR_TIMELIMIT = 1<<10, // Reaching time limit ends the round - GTR_OVERTIME = 1<<11, // Allow overtime behavior + GTR_POINTLIMIT = 1<<10, // Reaching point limit ends the round + GTR_TIMELIMIT = 1<<11, // Reaching time limit ends the round + GTR_OVERTIME = 1<<12, // Allow overtime behavior // Custom gametype rules - GTR_TEAMS = 1<<12, // Teams are forced on - GTR_NOTEAMS = 1<<13, // Teams are forced off - GTR_TEAMSTARTS = 1<<14, // Use team-based start positions + GTR_TEAMS = 1<<13, // Teams are forced on + GTR_NOTEAMS = 1<<14, // Teams are forced off + GTR_TEAMSTARTS = 1<<15, // Use team-based start positions // Grand Prix rules - GTR_CAMPAIGN = 1<<15, // Handles cup-based progression - GTR_LIVES = 1<<16, // Lives system, players are forced to spectate during Game Over. - GTR_SPECIALBOTS = 1<<17, // Bot difficulty gets stronger between rounds, and the rival system is enabled. + GTR_CAMPAIGN = 1<<16, // Handles cup-based progression + GTR_LIVES = 1<<17, // Lives system, players are forced to spectate during Game Over. + GTR_SPECIALBOTS = 1<<18, // Bot difficulty gets stronger between rounds, and the rival system is enabled. // free: to and including 1<<31 }; diff --git a/src/g_game.c b/src/g_game.c index 6757fb2af..7b91c0e85 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2056,6 +2056,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) UINT8 botdifficulty; INT16 rings; + INT16 spheres; angle_t playerangleturn; UINT8 botdiffincrease; @@ -2140,7 +2141,8 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) itemamount = 0; growshrinktimer = 0; bumper = ((gametyperules & GTR_BUMPERS) ? K_StartingBumperCount() : 0); - rings = ((gametyperules & GTR_RINGS) ? 5 : 0); + rings = ((gametyperules & GTR_SPHERES) ? 0 : 5); + spheres = 0; comebackpoints = 0; wanted = 0; } @@ -2168,6 +2170,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) bumper = players[player].kartstuff[k_bumper]; rings = players[player].rings; + spheres = players[player].spheres; comebackpoints = players[player].kartstuff[k_comebackpoints]; wanted = players[player].kartstuff[k_wanted]; } @@ -2216,6 +2219,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) p->bot = bot; p->botvars.difficulty = botdifficulty; p->rings = rings; + p->spheres = spheres; p->botvars.diffincrease = botdiffincrease; p->botvars.rival = botrival; p->xtralife = xtralife; @@ -2788,9 +2792,9 @@ const char *Gametype_ConstantNames[NUMGAMETYPES] = UINT32 gametypedefaultrules[NUMGAMETYPES] = { // Race - GTR_CIRCUIT|GTR_RINGS|GTR_BOTS, + GTR_CIRCUIT|GTR_BOTS, // Battle - GTR_BUMPERS|GTR_WANTED|GTR_KARMA|GTR_ITEMARROWS|GTR_CAPSULES|GTR_BATTLESTARTS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_OVERTIME + GTR_SPHERES|GTR_BUMPERS|GTR_WANTED|GTR_KARMA|GTR_ITEMARROWS|GTR_CAPSULES|GTR_BATTLESTARTS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_OVERTIME }; // diff --git a/src/info.c b/src/info.c index 6d5bac1ea..d73c13010 100644 --- a/src/info.c +++ b/src/info.c @@ -135,7 +135,7 @@ char sprnames[NUMSPRITES + 1][5] = "TOKE", // Special Stage Token "RFLG", // Red CTF Flag "BFLG", // Blue CTF Flag - //"SPHR", // Sphere + "BSPH", // Sphere "NCHP", // NiGHTS chip "NSTR", // NiGHTS star "EMBM", // Emblem @@ -1800,19 +1800,19 @@ state_t states[NUMSTATES] = {SPR_RING, 22, 1, {NULL}, 0, 0, S_FASTRING1}, // S_FASTRING12 // Blue Sphere for special stages - {SPR_SPHR, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_BLUESPHERE - {SPR_SPHR, FF_FULLBRIGHT + {SPR_BSPH, FF_SEMIBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_BLUESPHERE + {SPR_BSPH, FF_FULLBRIGHT #ifdef MANIASPHERES |FF_ANIMATE|FF_RANDOMANIM #endif , -1, {NULL}, 1, 4, S_NULL}, // S_BLUESPHEREBONUS - {SPR_SPHR, 0, 20, {NULL}, 0, 0, S_NULL}, // S_BLUESPHERESPARK + {SPR_BSPH, 0, 20, {NULL}, 0, 0, S_NULL}, // S_BLUESPHERESPARK // Bomb Sphere - {SPR_SPHR, FF_FULLBRIGHT|3, 2, {NULL}, 0, 0, S_BOMBSPHERE2}, // S_BOMBSPHERE1 - {SPR_SPHR, FF_FULLBRIGHT|4, 1, {NULL}, 0, 0, S_BOMBSPHERE3}, // S_BOMBSPHERE2 - {SPR_SPHR, FF_FULLBRIGHT|5, 2, {NULL}, 0, 0, S_BOMBSPHERE4}, // S_BOMBSPHERE3 - {SPR_SPHR, FF_FULLBRIGHT|4, 1, {NULL}, 0, 0, S_BOMBSPHERE1}, // S_BOMBSPHERE4 + {SPR_BSPH, FF_FULLBRIGHT|3, 2, {NULL}, 0, 0, S_BOMBSPHERE2}, // S_BOMBSPHERE1 + {SPR_BSPH, FF_FULLBRIGHT|4, 1, {NULL}, 0, 0, S_BOMBSPHERE3}, // S_BOMBSPHERE2 + {SPR_BSPH, FF_FULLBRIGHT|5, 2, {NULL}, 0, 0, S_BOMBSPHERE4}, // S_BOMBSPHERE3 + {SPR_BSPH, FF_FULLBRIGHT|4, 1, {NULL}, 0, 0, S_BOMBSPHERE1}, // S_BOMBSPHERE4 // NiGHTS Chip {SPR_NCHP, FF_FULLBRIGHT|FF_ANIMATE, -1, {NULL}, 15, 2, S_NULL}, // S_NIGHTSCHIP @@ -7923,29 +7923,29 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = }, { // MT_BLUESPHERE - 1706, // doomednum + -1, // doomednum S_BLUESPHERE, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound - MT_FLINGBLUESPHERE, // reactiontime + MT_FLINGBLUESPHERE, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_BLUESPHERESPARK, // deathstate + S_NULL, // deathstate S_NULL, // xdeathstate sfx_s3k65, // deathsound 38*FRACUNIT, // speed - 16*FRACUNIT, // radius - 24*FRACUNIT, // height + 48*FRACUNIT, // radius + 48*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage sfx_None, // activesound - MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_DONTENCOREMAP, // flags S_BLUESPHEREBONUS // raisestate }, @@ -7962,7 +7962,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_BLUESPHERESPARK, // deathstate + S_NULL, // deathstate S_NULL, // xdeathstate sfx_s3k65, // deathsound 38*FRACUNIT, // speed diff --git a/src/info.h b/src/info.h index e7d53cb5b..4e235c1ba 100644 --- a/src/info.h +++ b/src/info.h @@ -406,7 +406,7 @@ typedef enum sprite SPR_TOKE, // Special Stage Token SPR_RFLG, // Red CTF Flag SPR_BFLG, // Blue CTF Flag - //SPR_SPHR, // Sphere + SPR_BSPH, // Sphere SPR_NCHP, // NiGHTS chip SPR_NSTR, // NiGHTS star SPR_EMBM, // Emblem diff --git a/src/k_kart.c b/src/k_kart.c index 4352ce5c5..a5595b24f 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -897,7 +897,7 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd) // SPECIAL CASE No. 4: // Being in ring debt occasionally forces Super Ring on you if you mashed - if ((gametyperules & GTR_RINGS) && mashed && player->rings < 0 && cv_superring.value) + if (!(gametyperules & GTR_SPHERES) && mashed && player->rings < 0 && cv_superring.value) { INT32 debtamount = min(20, abs(player->rings)); if (P_RandomChance((debtamount*FRACUNIT)/20)) @@ -2221,6 +2221,12 @@ fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower) finalspeed = K_GetKartSpeedFromStat(kartspeed); + if (player->spheres > 0) + { + fixed_t sphereAdd = (FRACUNIT/80); // 50% at max + finalspeed = FixedMul(finalspeed, FRACUNIT + (sphereAdd * player->spheres)); + } + if (K_PlayerUsesBotMovement(player)) { // Give top speed a buff for bots, since it's a fairly weak stat without drifting @@ -2261,6 +2267,11 @@ fixed_t K_GetKartAccel(player_t *player) //k_accel += 3 * (9 - kartspeed); // 36 - 60 k_accel += 4 * (9 - kartspeed); // 32 - 64 + if (player->spheres > 0) + { + fixed_t sphereAdd = (FRACUNIT/10); // 500% at max + k_accel = FixedMul(k_accel, FRACUNIT + (sphereAdd * player->spheres)); + } if (K_PlayerUsesBotMovement(player)) { @@ -5614,6 +5625,14 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) else if (player->rings < -20) player->rings = -20; + if ((leveltime % TICRATE) == 0) + player->spheres--; + + if (player->spheres > 40) + player->spheres = 40; + else if (player->spheres < 0) + player->spheres = 0; + if (player->kartstuff[k_ringdelay]) player->kartstuff[k_ringdelay]--; diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index 5b6251e80..119fab345 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -209,6 +209,8 @@ static int player_get(lua_State *L) lua_pushangle(L, plr->drawangle); else if (fastcmp(field,"rings")) lua_pushinteger(L, plr->rings); + else if (fastcmp(field,"spheres")) + lua_pushinteger(L, plr->spheres); else if (fastcmp(field,"powers")) LUA_PushUserdata(L, plr->powers, META_POWERS); else if (fastcmp(field,"kartstuff")) @@ -476,6 +478,8 @@ static int player_set(lua_State *L) plr->drawangle = luaL_checkangle(L, 3); else if (fastcmp(field,"rings")) plr->rings = (INT32)luaL_checkinteger(L, 3); + else if (fastcmp(field,"spheres")) + plr->spheres = (INT32)luaL_checkinteger(L, 3); else if (fastcmp(field,"powers")) return NOSET; else if (fastcmp(field,"pflags")) diff --git a/src/p_floor.c b/src/p_floor.c index f8f7fef2d..0ad27d580 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -2371,7 +2371,7 @@ void EV_MarioBlock(ffloor_t *rover, sector_t *sector, mobj_t *puncher) P_SetThingPosition(thing); if (thing->flags & MF_SHOOTABLE) P_DamageMobj(thing, puncher, puncher, 1, DMG_NORMAL); - else if (thing->type == MT_RING || thing->type == MT_COIN || thing->type == MT_RANDOMITEM) + else if (thing->type == MT_RING || thing->type == MT_RANDOMITEM) { thing->momz = FixedMul(3*FRACUNIT, thing->scale); P_TouchSpecialThing(thing, puncher, false); diff --git a/src/p_inter.c b/src/p_inter.c index e408c1d27..730e7388d 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -553,6 +553,18 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) return; + case MT_BLUESPHERE: + if (!(P_CanPickupItem(player, 0))) + return; + + // Reached the cap, don't waste 'em! + if (player->spheres >= 40) + return; + + special->momx = special->momy = special->momz = 0; + player->spheres++; + break; + // Secret emblem thingy case MT_EMBLEM: { @@ -2000,7 +2012,7 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings) fixed_t momxy = 5<shadowscale = FRACUNIT/2; break; case MT_DRIFTCLIP: @@ -9205,8 +9196,6 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) mobj->color = skincolor_blueteam; break; case MT_RING: - case MT_COIN: - case MT_NIGHTSSTAR: if (nummaprings >= 0) nummaprings++; break; @@ -9564,10 +9553,7 @@ void P_RemoveMobj(mobj_t *mobj) // Rings only, please! if (mobj->spawnpoint && (mobj->type == MT_RING - || mobj->type == MT_COIN - || mobj->type == MT_NIGHTSSTAR - || mobj->type == MT_REDTEAMRING - || mobj->type == MT_BLUETEAMRING) + || mobj->type == MT_BLUESPHERE) && !(mobj->flags2 & MF2_DONTRESPAWN)) { itemrespawnque[iquehead] = mobj->spawnpoint; @@ -9979,22 +9965,29 @@ void P_RespawnSpecials(void) pcount++; } - if (pcount == 1) // No respawn when alone - return; - else if (pcount > 1) + if (gametyperules & GTR_SPHERES) { - time = (120 - ((pcount-2) * 10))*TICRATE; - - // If the map is longer or shorter than 3 laps, then adjust ring respawn to account for this. - // 5 lap courses would have more retreaded ground, while 2 lap courses would have less. - if ((mapheaderinfo[gamemap-1]->numlaps != 3) - && !(mapheaderinfo[gamemap-1]->levelflags & LF_SECTIONRACE)) - time = (time * 3) / max(1, mapheaderinfo[gamemap-1]->numlaps); - - if (time < 10*TICRATE) + time = ((MAXPLAYERS+1) - pcount) * (2*TICRATE); + } + else + { + if (pcount == 1) // No respawn when alone + return; + else if (pcount > 1) { - // Ensure it doesn't go into absurdly low values - time = 10*TICRATE; + time = (120 - ((pcount-2) * 10))*TICRATE; + + // If the map is longer or shorter than 3 laps, then adjust ring respawn to account for this. + // 5 lap courses would have more retreaded ground, while 2 lap courses would have less. + if ((mapheaderinfo[gamemap-1]->numlaps != 3) + && !(mapheaderinfo[gamemap-1]->levelflags & LF_SECTIONRACE)) + time = (time * 3) / max(1, mapheaderinfo[gamemap-1]->numlaps); + + if (time < 10*TICRATE) + { + // Ensure it doesn't go into absurdly low values + time = 10*TICRATE; + } } } @@ -10410,6 +10403,7 @@ fixed_t P_GetMapThingSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* mt case MT_SPIKEBALL: case MT_EMBLEM: case MT_RING: + case MT_BLUESPHERE: offset += mthing->options & MTF_AMBUSH ? 24*mapobjectscale : 0; break; @@ -10516,8 +10510,11 @@ static boolean P_AllowMobjSpawn(mapthing_t* mthing, mobjtype_t i) static mobjtype_t P_GetMobjtypeSubstitute(mapthing_t *mthing, mobjtype_t i) { - // Don't need this for Kart YET! (void)mthing; + + if ((gametyperules & GTR_SPHERES) && (i == MT_RING)) + return MT_BLUESPHERE; + return i; } diff --git a/src/p_saveg.c b/src/p_saveg.c index e2988e4d3..375c37120 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -109,6 +109,7 @@ static void P_NetArchivePlayers(void) WRITEANGLE(save_p, players[i].awayviewaiming); WRITEINT32(save_p, players[i].awayviewtics); WRITEINT16(save_p, players[i].rings); + WRITEINT16(save_p, players[i].spheres); for (j = 0; j < NUMPOWERS; j++) WRITEUINT16(save_p, players[i].powers[j]); @@ -302,6 +303,7 @@ static void P_NetUnArchivePlayers(void) players[i].awayviewaiming = READANGLE(save_p); players[i].awayviewtics = READINT32(save_p); players[i].rings = READINT16(save_p); + players[i].spheres = READINT16(save_p); for (j = 0; j < NUMPOWERS; j++) players[i].powers[j] = READUINT16(save_p); From 7430df5f4f42ce7e84df5a5f38d1b7a039172b37 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Thu, 22 Oct 2020 05:36:36 -0400 Subject: [PATCH 019/143] Fix time limit, make overtime kill you instantly and close in faster, remove minimum radius Radius SHOULD be doubled to 8192 to be reasonable... but something gets severely messed up, makes me MAD --- src/d_main.c | 5 ++ src/d_netcmd.c | 7 +-- src/info.c | 2 +- src/k_battle.c | 164 +++++++++++++++++-------------------------------- src/k_battle.h | 2 +- src/k_kart.c | 18 ++---- src/p_inter.c | 14 ++--- src/p_saveg.c | 6 +- 8 files changed, 80 insertions(+), 138 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index bc46fc0a3..f01633eaa 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1544,6 +1544,11 @@ void D_SRB2Main(void) CON_Init(); + memset(timelimits, 0, sizeof(timelimits)); + memset(pointlimits, 0, sizeof(pointlimits)); + + timelimits[GT_BATTLE] = 2; + D_RegisterServerCommands(); D_RegisterClientCommands(); // be sure that this is called before D_CheckNetGame R_RegisterEngineStuff(); diff --git a/src/d_netcmd.c b/src/d_netcmd.c index a93e86ac0..6e5d245da 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -460,8 +460,7 @@ consvar_t cv_scrambleonchange = {"scrambleonchange", "Off", CV_NETVAR, teamscram consvar_t cv_itemfinder = {"itemfinder", "Off", CV_CALL|CV_NOSHOWHELP, CV_OnOff, ItemFinder_OnChange, 0, NULL, NULL, 0, 0, NULL}; // Scoring type options -static CV_PossibleValue_t overtime_cons_t[] = {{0, "No"}, {1, "Yes"}, {2, "Super"}, {0, NULL}}; -consvar_t cv_overtime = {"overtime", "Yes", CV_NETVAR|CV_CHEAT, overtime_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_overtime = {"overtime", "Yes", CV_NETVAR|CV_CHEAT, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_rollingdemos = {"rollingdemos", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -4311,8 +4310,8 @@ static void TimeLimit_OnChange(void) if (cv_timelimit.value != 0) { - CONS_Printf(M_GetText("Levels will end after %d second%s.\n"),cv_timelimit.value,cv_timelimit.value == 1 ? "" : "s"); // Graue 11-17-2003 - timelimitintics = cv_timelimit.value * TICRATE; + CONS_Printf(M_GetText("Levels will end after %d minute%s.\n"),cv_timelimit.value,cv_timelimit.value == 1 ? "" : "s"); // Graue 11-17-2003 + timelimitintics = cv_timelimit.value * (60*TICRATE); // Note the deliberate absence of any code preventing // pointlimit and timelimit from being set simultaneously. diff --git a/src/info.c b/src/info.c index d73c13010..d71631dd1 100644 --- a/src/info.c +++ b/src/info.c @@ -4996,7 +4996,7 @@ state_t states[NUMSTATES] = {SPR_GRES, FF_ANIMATE|FF_PAPERSPRITE, -1, {NULL}, 2, 4, S_NULL}, // S_TIREGREASE {SPR_OTFG, FF_FULLBRIGHT|FF_TRANS50, TICRATE, {NULL}, 0, 0, S_NULL}, // S_OVERTIMEFOG - {SPR_OTFG, 2|FF_FULLBRIGHT|FF_PAPERSPRITE, 1, {NULL}, 0, 0, S_NULL}, // S_OVERTIMEORB + {SPR_OTFG, 1|FF_FULLBRIGHT|FF_PAPERSPRITE, 1, {NULL}, 0, 0, S_NULL}, // S_OVERTIMEORB {SPR_OTFG, 1|FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_NULL}, // S_OVERTIMEBEAM {SPR_CAPS, FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_BATTLECAPSULE_SIDE1 diff --git a/src/k_battle.c b/src/k_battle.c index 98cc10a3b..dda33d553 100644 --- a/src/k_battle.c +++ b/src/k_battle.c @@ -279,110 +279,47 @@ void K_CheckBumpers(void) #define MAXPLANESPERSECTOR (MAXFFLOORS+1)*2 -static void K_SpawnOvertimeParticles(fixed_t x, fixed_t y, fixed_t scale, mobjtype_t type, boolean ceiling) +static void K_SpawnOvertimeParticles(fixed_t x, fixed_t y, fixed_t scale, mobjtype_t type) { UINT8 i; - fixed_t flatz[MAXPLANESPERSECTOR]; - boolean flip[MAXPLANESPERSECTOR]; - UINT8 numflats = 0; - mobj_t *mo; - subsector_t *ss = R_PointInSubsectorOrNull(x, y); - sector_t *sec; - if (!ss) - return; - sec = ss->sector; - - // convoluted stuff JUST to get all of the planes we need to draw orbs on :V - - for (i = 0; i < MAXPLANESPERSECTOR; i++) - flip[i] = false; - - if (sec->floorpic != skyflatnum) + for (i = 0; i <= r_splitscreen; i++) { - flatz[numflats] = P_GetZAt(sec->f_slope, x, y, sec->floorheight); - numflats++; - } - if (sec->ceilingpic != skyflatnum && ceiling) - { - flatz[numflats] = P_GetZAt(sec->c_slope, x, y, sec->ceilingheight) - FixedMul(mobjinfo[type].height, scale); - flip[numflats] = true; - numflats++; - } + player_t *player = &players[displayplayers[i]]; + mobj_t *mo; + INT32 f = 0; - if (sec->ffloors) - { - ffloor_t *rover; - for (rover = sec->ffloors; rover; rover = rover->next) + if (player == NULL || player->mo == NULL || P_MobjWasRemoved(player->mo) == true) { - if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER)) - continue; - if (*rover->toppic != skyflatnum) - { - flatz[numflats] = P_GetZAt(*rover->t_slope, x, y, *rover->topheight); - numflats++; - } - if (*rover->bottompic != skyflatnum && ceiling) - { - flatz[numflats] = P_GetZAt(*rover->b_slope, x, y, *rover->bottomheight); - flip[numflats] = true; - numflats++; - } - } - } - - if (numflats <= 0) // no flats - return; - - for (i = 0; i < numflats; i++) - { - mo = P_SpawnMobj(x, y, flatz[i], type); - - // Lastly, if this can see the skybox mobj, then... we just wasted our time :V - if (skyboxmo[0] && !P_MobjWasRemoved(skyboxmo[0])) - { - const fixed_t sbz = skyboxmo[0]->z; - fixed_t checkz = sec->floorheight; - - while (checkz < sec->ceilingheight) - { - P_TeleportMove(skyboxmo[0], skyboxmo[0]->x, skyboxmo[0]->y, checkz); - if (P_CheckSight(skyboxmo[0], mo)) - { - P_RemoveMobj(mo); - break; - } - else - checkz += 32*mapobjectscale; - } - - P_TeleportMove(skyboxmo[0], skyboxmo[0]->x, skyboxmo[0]->y, sbz); - - if (P_MobjWasRemoved(mo)) - continue; + continue; } + mo = P_SpawnMobj(x, y, player->mo->z + (player->mo->height / 2), type); P_SetScale(mo, scale); - if (flip[i]) + if (player->mo->eflags & MFE_VERTICALFLIP) { mo->flags2 |= MF2_OBJECTFLIP; mo->eflags |= MFE_VERTICALFLIP; } - switch(type) + mo->drawflags |= (MFD_DONTDRAW & ~(K_GetPlayerDontDrawFlag(player))); + + switch (type) { case MT_OVERTIMEFOG: - mo->destscale = 8*mo->scale; - mo->momz = P_RandomRange(1,8)*mo->scale; + mo->destscale = 8 * mo->scale; + mo->momz = P_RandomRange(1,8) * mo->scale; break; case MT_OVERTIMEORB: - //mo->destscale = mo->scale/4; - mo->frame += ((leveltime/4) % 8); - /*if (battleovertime.enabled < 10*TICRATE) - mo->drawflags |= MFD_SHADOW;*/ mo->angle = R_PointToAngle2(mo->x, mo->y, battleovertime.x, battleovertime.y) + ANGLE_90; - mo->z += P_RandomRange(0,48) * mo->scale; + + if (leveltime & 1) + f = 3; + else + f = (leveltime / 2) % 3; + + mo->frame += f; break; default: break; @@ -394,7 +331,7 @@ static void K_SpawnOvertimeParticles(fixed_t x, fixed_t y, fixed_t scale, mobjty void K_RunBattleOvertime(void) { - UINT16 i, j; + UINT32 i, j; if (battleovertime.enabled < 10*TICRATE) { @@ -404,14 +341,20 @@ void K_RunBattleOvertime(void) if (battleovertime.enabled == 10*TICRATE) S_StartSound(NULL, sfx_kc40); } - else + else if (battleovertime.radius > 0) { - if (battleovertime.radius > battleovertime.minradius) - battleovertime.radius -= mapobjectscale; + if (battleovertime.radius > 4*mapobjectscale) + battleovertime.radius -= 4*mapobjectscale; else - battleovertime.radius = battleovertime.minradius; + battleovertime.radius = 0; } + if (battleovertime.radius <= 0) + { + return; + } + + /* if (leveltime & 1) { UINT8 transparency = tr_trans50; @@ -430,43 +373,50 @@ void K_RunBattleOvertime(void) beam->frame |= transparency<>FRACBITS / 2));*/ - for (i = 0; i < 16; i++) { j = 0; + while (j < 32) // max attempts { - fixed_t x = battleovertime.x + ((P_RandomRange(-64,64) * 128)<kartstuff[k_bumper] > 0 && !P_PlayerInPain(player) && !player->powers[pw_flashing]) { player->kartstuff[k_wanted]++; - if (battleovertime.enabled >= 10*TICRATE) + + if ((battleovertime.enabled >= 10*TICRATE) && (P_AproxDistance(player->mo->x - battleovertime.x, player->mo->y - battleovertime.y) - (player->mo->radius * 2)) > battleovertime.radius) { - if (P_AproxDistance(player->mo->x - battleovertime.x, player->mo->y - battleovertime.y) > battleovertime.radius) - { - player->kartstuff[k_killfield]++; - if (player->kartstuff[k_killfield] > 4*TICRATE) - { - P_DamageMobj(player->mo, NULL, NULL, 1, DMG_NORMAL); - //player->kartstuff[k_killfield] = 1; - } - } - else if (player->kartstuff[k_killfield] > 0) - player->kartstuff[k_killfield]--; + P_KillMobj(player->mo, NULL, NULL, DMG_NORMAL); + player->kartstuff[k_bumper] = 0; } } - else if (player->kartstuff[k_killfield] > 0) - player->kartstuff[k_killfield]--; if (P_IsObjectOnGround(player->mo)) player->kartstuff[k_waterskip] = 0; diff --git a/src/p_inter.c b/src/p_inter.c index 730e7388d..7a778a3ab 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -726,7 +726,7 @@ void P_TouchStarPost(mobj_t *post, player_t *player, boolean snaptopost) } // Easily make it so that overtime works offline -//#define TESTOVERTIMEINFREEPLAY +#define TESTOVERTIMEINFREEPLAY /** Checks if the level timer is over the timelimit and the round should end, * unless you are in overtime. In which case leveltime may stretch out beyond @@ -743,9 +743,6 @@ void P_CheckTimeLimit(void) if (!cv_timelimit.value) return; - if (!(multiplayer || netgame)) - return; - if (battlecapsules) // capsules override any time limit settings return; @@ -766,6 +763,7 @@ void P_CheckTimeLimit(void) { if (!playeringame[i] || players[i].spectator) continue; + if (foundone) { #endif @@ -779,6 +777,8 @@ void P_CheckTimeLimit(void) P_RespawnBattleBoxes(); // FORCE THESE TO BE RESPAWNED FOR THIS!!!!!!! // Find us an item box to center on. + // TO DO: DON'T do this, instead use a specialized center point object + // just use 0,0 if it's not found for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { mobj_t *thismo; @@ -809,15 +809,15 @@ void P_CheckTimeLimit(void) return; } - item->threshold = 70; // Set constant respawn + //item->threshold = 70; // Set constant respawn battleovertime.x = item->x; battleovertime.y = item->y; battleovertime.z = item->z; - battleovertime.radius = 4096*mapobjectscale; - battleovertime.minradius = (cv_overtime.value == 2 ? 40 : 512) * mapobjectscale; + battleovertime.radius = 4096 * mapobjectscale; battleovertime.enabled = 1; S_StartSound(NULL, sfx_kc47); } + return; #ifndef TESTOVERTIMEINFREEPLAY } diff --git a/src/p_saveg.c b/src/p_saveg.c index 375c37120..509d18ec4 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -4116,8 +4116,7 @@ static void P_NetArchiveMisc(void) // battleovertime_t WRITEUINT16(save_p, battleovertime.enabled); - WRITEFIXED(save_p, battleovertime.radius); - WRITEFIXED(save_p, battleovertime.minradius); + WRITEUINT16(save_p, battleovertime.radius); WRITEFIXED(save_p, battleovertime.x); WRITEFIXED(save_p, battleovertime.y); WRITEFIXED(save_p, battleovertime.z); @@ -4250,8 +4249,7 @@ static inline boolean P_NetUnArchiveMisc(void) // battleovertime_t battleovertime.enabled = READUINT16(save_p); - battleovertime.radius = READFIXED(save_p); - battleovertime.minradius = READFIXED(save_p); + battleovertime.radius = READUINT16(save_p); battleovertime.x = READFIXED(save_p); battleovertime.y = READFIXED(save_p); battleovertime.z = READFIXED(save_p); From 9ad88cdfa9fc5c44fe8d295d1af0d8a8980272e1 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Thu, 22 Oct 2020 17:38:06 -0400 Subject: [PATCH 020/143] Add center point mobj, polish the visual a bit more, reduce the speed that the barrier shrinks --- src/dehacked.c | 12 ++-- src/info.c | 56 +++++------------ src/info.h | 16 ++--- src/k_battle.c | 165 ++++++++++++++++++++++--------------------------- src/k_kart.c | 17 ++++- src/p_inter.c | 52 +++++++--------- 6 files changed, 141 insertions(+), 177 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 2d7b58ac9..c57b8f5bf 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -9286,9 +9286,10 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_TIREGREASE", - "S_OVERTIMEFOG", - "S_OVERTIMEORB", - "S_OVERTIMEBEAM", + "S_OVERTIME_BULB1", + "S_OVERTIME_BULB2", + "S_OVERTIME_LASER", + "S_OVERTIME_CENTER", "S_BATTLECAPSULE_SIDE1", "S_BATTLECAPSULE_SIDE2", @@ -10382,9 +10383,8 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_SPBDUST", "MT_TIREGREASE", - "MT_OVERTIMEFOG", - "MT_OVERTIMEORB", - "MT_OVERTIMEBEAM", + "MT_OVERTIME_PARTICLE", + "MT_OVERTIME_CENTER", "MT_BATTLECAPSULE", "MT_BATTLECAPSULE_PIECE", diff --git a/src/info.c b/src/info.c index d71631dd1..16bd03331 100644 --- a/src/info.c +++ b/src/info.c @@ -713,7 +713,9 @@ char sprnames[NUMSPRITES + 1][5] = "DRAF", "GRES", - "OTFG", + "OTBU", + "OTLS", + "OTCP", "DBOS", // Drift boost flame @@ -4995,9 +4997,10 @@ state_t states[NUMSTATES] = {SPR_GRES, FF_ANIMATE|FF_PAPERSPRITE, -1, {NULL}, 2, 4, S_NULL}, // S_TIREGREASE - {SPR_OTFG, FF_FULLBRIGHT|FF_TRANS50, TICRATE, {NULL}, 0, 0, S_NULL}, // S_OVERTIMEFOG - {SPR_OTFG, 1|FF_FULLBRIGHT|FF_PAPERSPRITE, 1, {NULL}, 0, 0, S_NULL}, // S_OVERTIMEORB - {SPR_OTFG, 1|FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_NULL}, // S_OVERTIMEBEAM + {SPR_OTBU, FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_NULL}, // S_OVERTIME_BULB1 + {SPR_OTBU, FF_FULLBRIGHT|2, 1, {NULL}, 0, 0, S_NULL}, // S_OVERTIME_BULB2 + {SPR_OTLS, FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_NULL}, // S_OVERTIME_LASER + {SPR_OTCP, 0, -1, {NULL}, 0, 0, S_NULL}, // S_OVERTIME_CENTER {SPR_CAPS, FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_BATTLECAPSULE_SIDE1 {SPR_CAPS, FF_PAPERSPRITE|1, -1, {NULL}, 0, 0, S_NULL}, // S_BATTLECAPSULE_SIDE2 @@ -28402,9 +28405,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_OVERTIMEFOG + { // MT_OVERTIME_PARTICLE -1, // doomednum - S_OVERTIMEFOG, // spawnstate + S_NULL, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -28420,8 +28423,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // deathsound 0, // speed 16<mo == NULL || P_MobjWasRemoved(player->mo) == true) { continue; } - mo = P_SpawnMobj(x, y, player->mo->z + (player->mo->height / 2), type); - P_SetScale(mo, scale); - if (player->mo->eflags & MFE_VERTICALFLIP) { - mo->flags2 |= MF2_OBJECTFLIP; - mo->eflags |= MFE_VERTICALFLIP; + zpos = player->mo->z + player->mo->height; + } + else + { + zpos = player->mo->z; } - mo->drawflags |= (MFD_DONTDRAW & ~(K_GetPlayerDontDrawFlag(player))); + flip = P_MobjFlip(player->mo); - switch (type) + for (j = 0; j < 3; j++) { - case MT_OVERTIMEFOG: - mo->destscale = 8 * mo->scale; - mo->momz = P_RandomRange(1,8) * mo->scale; - break; - case MT_OVERTIMEORB: - mo->angle = R_PointToAngle2(mo->x, mo->y, battleovertime.x, battleovertime.y) + ANGLE_90; + mobj_t *mo = P_SpawnMobj(x, y, zpos, MT_OVERTIME_PARTICLE); - if (leveltime & 1) - f = 3; - else - f = (leveltime / 2) % 3; + if (player->mo->eflags & MFE_VERTICALFLIP) + { + mo->flags2 |= MF2_OBJECTFLIP; + mo->eflags |= MFE_VERTICALFLIP; + } - mo->frame += f; - break; - default: - break; + mo->angle = R_PointToAngle2(mo->x, mo->y, battleovertime.x, battleovertime.y) + ANGLE_90; + mo->drawflags |= (MFD_DONTDRAW & ~(K_GetPlayerDontDrawFlag(player))); + + P_SetScale(mo, scale); + + switch (j) + { + case 0: + P_SetMobjState(mo, S_OVERTIME_BULB1); + + if (leveltime & 1) + mo->frame += 1; + + //P_SetScale(mo, mapobjectscale); + zpos += 35 * mo->scale * flip; + break; + case 1: + P_SetMobjState(mo, S_OVERTIME_LASER); + + if (leveltime & 1) + mo->frame += 3; + else + mo->frame += (leveltime / 2) % 3; + + //P_SetScale(mo, scale); + zpos += 346 * mo->scale * flip; + break; + case 2: + P_SetMobjState(mo, S_OVERTIME_BULB2); + + if (leveltime & 1) + mo->frame += 1; + + //P_SetScale(mo, mapobjectscale); + break; + default: + I_Error("Bruh moment has occured\n"); + return; + } } } } @@ -331,8 +360,6 @@ static void K_SpawnOvertimeParticles(fixed_t x, fixed_t y, fixed_t scale, mobjty void K_RunBattleOvertime(void) { - UINT32 i, j; - if (battleovertime.enabled < 10*TICRATE) { battleovertime.enabled++; @@ -343,81 +370,35 @@ void K_RunBattleOvertime(void) } else if (battleovertime.radius > 0) { - if (battleovertime.radius > 4*mapobjectscale) - battleovertime.radius -= 4*mapobjectscale; + if (battleovertime.radius > 2*mapobjectscale) + battleovertime.radius -= 2*mapobjectscale; else battleovertime.radius = 0; } - if (battleovertime.radius <= 0) - { - return; - } - - /* - if (leveltime & 1) - { - UINT8 transparency = tr_trans50; - - if (!splitscreen && players[displayplayers[0]].mo) - { - INT32 dist = P_AproxDistance(battleovertime.x-players[displayplayers[0]].mo->x, battleovertime.y-players[displayplayers[0]].mo->y); - transparency = max(0, NUMTRANSMAPS - ((256 + (dist>>FRACBITS)) / 256)); - } - - if (transparency < NUMTRANSMAPS) - { - mobj_t *beam = P_SpawnMobj(battleovertime.x, battleovertime.y, battleovertime.z + (mobjinfo[MT_RANDOMITEM].height/2), MT_OVERTIMEBEAM); - P_SetScale(beam, beam->scale*2); - if (transparency > 0) - beam->frame |= transparency< 0) { const fixed_t pi = (22 * FRACUNIT) / 7; // loose approximation, this doesn't need to be incredibly precise - fixed_t scale = mapobjectscale + (battleovertime.radius / 2048); - fixed_t sprwidth = 64 * scale; + const UINT32 orbs = 32; + const angle_t angoff = ANGLE_MAX / orbs; + const UINT8 spriteSpacing = 128; + fixed_t circumference = FixedMul(pi, battleovertime.radius * 2); - UINT32 orbs = circumference / sprwidth; - angle_t angoff = ANGLE_MAX / orbs; + fixed_t scale = max(circumference / spriteSpacing / orbs, mapobjectscale); + + fixed_t size = FixedMul(mobjinfo[MT_OVERTIME_PARTICLE].radius, scale); + fixed_t posOffset = max(battleovertime.radius - size, 0); + + UINT32 i; for (i = 0; i < orbs; i++) { - angle_t ang = (i * angoff); - fixed_t size = FixedMul(mobjinfo[MT_OVERTIMEORB].radius, mapobjectscale); + angle_t ang = (i * angoff) + FixedAngle((leveltime * FRACUNIT) / 4); - fixed_t x = battleovertime.x + P_ReturnThrustX(NULL, ang, battleovertime.radius + size); - fixed_t y = battleovertime.y + P_ReturnThrustY(NULL, ang, battleovertime.radius + size); + fixed_t x = battleovertime.x + P_ReturnThrustX(NULL, ang, posOffset); + fixed_t y = battleovertime.y + P_ReturnThrustY(NULL, ang, posOffset); - K_SpawnOvertimeParticles(x, y, mapobjectscale, MT_OVERTIMEORB); - } - } - - if (battleovertime.enabled < 10*TICRATE) - return; - - for (i = 0; i < 16; i++) - { - j = 0; - - while (j < 32) // max attempts - { - fixed_t scale = 4*mapobjectscale; - - fixed_t x = battleovertime.x + (P_RandomRange(-64,64) * scale); - fixed_t y = battleovertime.y + (P_RandomRange(-64,64) * scale); - - fixed_t closestdist = battleovertime.radius + (8 * FixedMul(mobjinfo[MT_OVERTIMEFOG].radius, scale)); - - j++; - - if (P_AproxDistance(x - battleovertime.x, y - battleovertime.y) < closestdist) - continue; - - K_SpawnOvertimeParticles(x, y, scale, MT_OVERTIMEFOG); - break; + K_SpawnOvertimeLaser(x, y, scale); } } } diff --git a/src/k_kart.c b/src/k_kart.c index 5393504d6..f7954307e 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -5751,10 +5751,21 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) { player->kartstuff[k_wanted]++; - if ((battleovertime.enabled >= 10*TICRATE) && (P_AproxDistance(player->mo->x - battleovertime.x, player->mo->y - battleovertime.y) - (player->mo->radius * 2)) > battleovertime.radius) + if (battleovertime.enabled >= 10*TICRATE) { - P_KillMobj(player->mo, NULL, NULL, DMG_NORMAL); - player->kartstuff[k_bumper] = 0; + fixed_t distanceToBarrier = 0; + + if (battleovertime.radius > 0) + { + distanceToBarrier = R_PointToDist2(player->mo->x, player->mo->y, battleovertime.x, battleovertime.y) - (player->mo->radius * 2); + } + + if (distanceToBarrier > battleovertime.radius) + { + //P_KillMobj(player->mo, NULL, NULL, DMG_NORMAL); + player->kartstuff[k_bumper] = 0; + P_DamageMobj(player->mo, NULL, NULL, 1, DMG_NORMAL); + } } } diff --git a/src/p_inter.c b/src/p_inter.c index 7a778a3ab..b610ec692 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -726,7 +726,7 @@ void P_TouchStarPost(mobj_t *post, player_t *player, boolean snaptopost) } // Easily make it so that overtime works offline -#define TESTOVERTIMEINFREEPLAY +//#define TESTOVERTIMEINFREEPLAY /** Checks if the level timer is over the timelimit and the round should end, * unless you are in overtime. In which case leveltime may stretch out beyond @@ -743,8 +743,10 @@ void P_CheckTimeLimit(void) if (!cv_timelimit.value) return; +#ifndef TESTOVERTIMEINFREEPLAY if (battlecapsules) // capsules override any time limit settings return; +#endif if (!(gametyperules & GTR_TIMELIMIT)) return; @@ -770,51 +772,43 @@ void P_CheckTimeLimit(void) // Initiate the kill zone if (!battleovertime.enabled) { - INT32 b = 0; thinker_t *th; - mobj_t *item = NULL; + mobj_t *center = NULL; - P_RespawnBattleBoxes(); // FORCE THESE TO BE RESPAWNED FOR THIS!!!!!!! - - // Find us an item box to center on. - // TO DO: DON'T do this, instead use a specialized center point object - // just use 0,0 if it's not found for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { mobj_t *thismo; + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) continue; + thismo = (mobj_t *)th; - if (thismo->type != MT_RANDOMITEM) - continue; - if (thismo->threshold == 69) // Disappears - continue; - - b++; - - // Only select items that are on the ground, ignore ones in the air. Ambush flag inverts this rule. - if ((!P_IsObjectOnGround(thismo)) != (thismo->flags2 & MF2_AMBUSH)) - continue; - - if (item == NULL || (b < nummapboxes && P_RandomChance(((nummapboxes-b)*FRACUNIT)/nummapboxes))) // This is to throw off the RNG some - item = thismo; - if (b >= nummapboxes) // end early if we've found them all already + if (thismo->type == MT_OVERTIME_CENTER) + { + center = thismo; break; + } } - if (item == NULL) // no item found, could happen if every item is in the air or has ambush flag, or the map has none + if (center == NULL || P_MobjWasRemoved(center)) { - CONS_Alert(CONS_WARNING, "No usuable items for Battle overtime!\n"); - return; + CONS_Alert(CONS_WARNING, "No center point for overtime!\n"); + + battleovertime.x = 0; + battleovertime.y = 0; + battleovertime.z = 0; + } + else + { + battleovertime.x = center->x; + battleovertime.y = center->y; + battleovertime.z = center->z; } - //item->threshold = 70; // Set constant respawn - battleovertime.x = item->x; - battleovertime.y = item->y; - battleovertime.z = item->z; battleovertime.radius = 4096 * mapobjectscale; battleovertime.enabled = 1; + S_StartSound(NULL, sfx_kc47); } From 344acfece27f74126be7a23cb485f4c566c6362f Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Thu, 22 Oct 2020 17:51:18 -0400 Subject: [PATCH 021/143] Make laser transparent before it's active --- src/k_battle.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/k_battle.c b/src/k_battle.c index 9e5ff867b..ddbf649bd 100644 --- a/src/k_battle.c +++ b/src/k_battle.c @@ -339,6 +339,9 @@ static void K_SpawnOvertimeLaser(fixed_t x, fixed_t y, fixed_t scale) //P_SetScale(mo, scale); zpos += 346 * mo->scale * flip; + + if (battleovertime.enabled < 10*TICRATE) + mo->drawflags |= MFD_TRANS50; break; case 2: P_SetMobjState(mo, S_OVERTIME_BULB2); From f5788b34e691590da26c207bb20d2ae9e153bb57 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Thu, 22 Oct 2020 21:25:40 -0400 Subject: [PATCH 022/143] Fix players not being able to turn in certain scenarios --- src/p_user.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 3bc6471e6..2a67d8360 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -461,15 +461,9 @@ UINT8 P_FindHighestLap(void) // boolean P_PlayerInPain(player_t *player) { - if (player->kartstuff[k_spinouttimer] || player->kartstuff[k_squishedtimer] || player->respawn.state != RESPAWNST_NONE) + if (player->kartstuff[k_spinouttimer] || player->kartstuff[k_squishedtimer]) return true; - if (gametyperules & GTR_KARMA) - { - if (player->kartstuff[k_bumper] <= 0 && player->kartstuff[k_comebacktimer]) - return true; - } - return false; } From 69e4a1c59f508f156c7b66a19a81aed3b07667bc Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Thu, 22 Oct 2020 22:15:07 -0400 Subject: [PATCH 023/143] Blue sphere jiggle physics --- src/dehacked.c | 39 ++++++++++++++++++++++++++++++++--- src/info.c | 55 ++++++++++++++++++++++++++++++++++++++------------ src/info.h | 37 +++++++++++++++++++++++++++++++-- 3 files changed, 113 insertions(+), 18 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index c57b8f5bf..fb6772499 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -6173,10 +6173,43 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_FASTRING11", "S_FASTRING12", - // Blue Sphere for special stages + // Blue Sphere "S_BLUESPHERE", - "S_BLUESPHEREBONUS", - "S_BLUESPHERESPARK", + "S_BLUESPHERE_SPAWN", + + "S_BLUESPHERE_BOUNCE1", + "S_BLUESPHERE_BOUNCE2", + + "S_BLUESPHERE_BOUNCE3", + "S_BLUESPHERE_BOUNCE4", + + "S_BLUESPHERE_BOUNCE5", + "S_BLUESPHERE_BOUNCE6", + "S_BLUESPHERE_BOUNCE7", + "S_BLUESPHERE_BOUNCE8", + + "S_BLUESPHERE_BOUNCE9", + "S_BLUESPHERE_BOUNCE10", + "S_BLUESPHERE_BOUNCE11", + "S_BLUESPHERE_BOUNCE12", + + "S_BLUESPHERE_BOUNCE13", + "S_BLUESPHERE_BOUNCE14", + "S_BLUESPHERE_BOUNCE15", + "S_BLUESPHERE_BOUNCE16", + "S_BLUESPHERE_BOUNCE17", + "S_BLUESPHERE_BOUNCE18", + "S_BLUESPHERE_BOUNCE19", + "S_BLUESPHERE_BOUNCE20", + + "S_BLUESPHERE_BOUNCE21", + "S_BLUESPHERE_BOUNCE22", + "S_BLUESPHERE_BOUNCE23", + "S_BLUESPHERE_BOUNCE24", + "S_BLUESPHERE_BOUNCE25", + "S_BLUESPHERE_BOUNCE26", + "S_BLUESPHERE_BOUNCE27", + "S_BLUESPHERE_BOUNCE28", // Bomb Sphere "S_BOMBSPHERE1", diff --git a/src/info.c b/src/info.c index 16bd03331..812aa2a18 100644 --- a/src/info.c +++ b/src/info.c @@ -1801,14 +1801,43 @@ state_t states[NUMSTATES] = {SPR_RING, 20, 1, {NULL}, 0, 0, S_FASTRING12}, // S_FASTRING11 {SPR_RING, 22, 1, {NULL}, 0, 0, S_FASTRING1}, // S_FASTRING12 - // Blue Sphere for special stages - {SPR_BSPH, FF_SEMIBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_BLUESPHERE - {SPR_BSPH, FF_FULLBRIGHT -#ifdef MANIASPHERES - |FF_ANIMATE|FF_RANDOMANIM -#endif - , -1, {NULL}, 1, 4, S_NULL}, // S_BLUESPHEREBONUS - {SPR_BSPH, 0, 20, {NULL}, 0, 0, S_NULL}, // S_BLUESPHERESPARK + // Blue Sphere + {SPR_BSPH, FF_SEMIBRIGHT|2, TICRATE, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE1}, // S_BLUESPHERE + {SPR_BSPH, FF_SEMIBRIGHT|2, TICRATE, {A_SetRandomTics}, 1, TICRATE, S_BLUESPHERE_BOUNCE1}, // S_BLUESPHERE_SPAWN + + {SPR_BSPH, FF_SEMIBRIGHT, 1, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE2}, // S_BLUESPHERE_BOUNCE1 + {SPR_BSPH, FF_SEMIBRIGHT|4, 1, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE3}, // S_BLUESPHERE_BOUNCE2 + + {SPR_BSPH, FF_SEMIBRIGHT, 1, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE4}, // S_BLUESPHERE_BOUNCE3 + {SPR_BSPH, FF_SEMIBRIGHT|4, 1, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE5}, // S_BLUESPHERE_BOUNCE4 + + {SPR_BSPH, FF_SEMIBRIGHT, 1, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE6}, // S_BLUESPHERE_BOUNCE5 + {SPR_BSPH, FF_SEMIBRIGHT|2, 1, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE7}, // S_BLUESPHERE_BOUNCE6 + {SPR_BSPH, FF_SEMIBRIGHT|4, 1, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE8}, // S_BLUESPHERE_BOUNCE7 + {SPR_BSPH, FF_SEMIBRIGHT|2, 1, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE9}, // S_BLUESPHERE_BOUNCE8 + + {SPR_BSPH, FF_SEMIBRIGHT, 1, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE10}, // S_BLUESPHERE_BOUNCE9 + {SPR_BSPH, FF_SEMIBRIGHT|2, 1, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE11}, // S_BLUESPHERE_BOUNCE10 + {SPR_BSPH, FF_SEMIBRIGHT|4, 1, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE12}, // S_BLUESPHERE_BOUNCE11 + {SPR_BSPH, FF_SEMIBRIGHT|2, 1, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE13}, // S_BLUESPHERE_BOUNCE12 + + {SPR_BSPH, FF_SEMIBRIGHT, 2, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE14}, // S_BLUESPHERE_BOUNCE13 + {SPR_BSPH, FF_SEMIBRIGHT|1, 2, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE15}, // S_BLUESPHERE_BOUNCE14 + {SPR_BSPH, FF_SEMIBRIGHT|2, 2, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE16}, // S_BLUESPHERE_BOUNCE15 + {SPR_BSPH, FF_SEMIBRIGHT|3, 2, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE17}, // S_BLUESPHERE_BOUNCE16 + {SPR_BSPH, FF_SEMIBRIGHT|4, 2, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE18}, // S_BLUESPHERE_BOUNCE17 + {SPR_BSPH, FF_SEMIBRIGHT|3, 4, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE19}, // S_BLUESPHERE_BOUNCE18 + {SPR_BSPH, FF_SEMIBRIGHT|2, 4, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE20}, // S_BLUESPHERE_BOUNCE19 + {SPR_BSPH, FF_SEMIBRIGHT|1, 4, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE21}, // S_BLUESPHERE_BOUNCE20 + + {SPR_BSPH, FF_SEMIBRIGHT, 6, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE22}, // S_BLUESPHERE_BOUNCE21 + {SPR_BSPH, FF_SEMIBRIGHT|1, 6, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE23}, // S_BLUESPHERE_BOUNCE22 + {SPR_BSPH, FF_SEMIBRIGHT|2, 6, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE24}, // S_BLUESPHERE_BOUNCE23 + {SPR_BSPH, FF_SEMIBRIGHT|3, 9, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE25}, // S_BLUESPHERE_BOUNCE24 + {SPR_BSPH, FF_SEMIBRIGHT|4, 9, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE26}, // S_BLUESPHERE_BOUNCE25 + {SPR_BSPH, FF_SEMIBRIGHT|3, 9, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE27}, // S_BLUESPHERE_BOUNCE26 + {SPR_BSPH, FF_SEMIBRIGHT|2, 9, {NULL}, 0, 0, S_BLUESPHERE_BOUNCE28}, // S_BLUESPHERE_BOUNCE27 + {SPR_BSPH, FF_SEMIBRIGHT|1, 9, {NULL}, 0, 0, S_BLUESPHERE}, // S_BLUESPHERE_BOUNCE28 // Bomb Sphere {SPR_BSPH, FF_FULLBRIGHT|3, 2, {NULL}, 0, 0, S_BOMBSPHERE2}, // S_BOMBSPHERE1 @@ -7927,7 +7956,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = { // MT_BLUESPHERE -1, // doomednum - S_BLUESPHERE, // spawnstate + S_BLUESPHERE_SPAWN, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -7948,13 +7977,13 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 100, // mass 0, // damage sfx_None, // activesound - MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_DONTENCOREMAP, // flags - S_BLUESPHEREBONUS // raisestate + MF_RUNSPAWNFUNC|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_DONTENCOREMAP, // flags + S_NULL // raisestate }, { // MT_FLINGBLUESPHERE -1, // doomednum - S_BLUESPHERE, // spawnstate + S_BLUESPHERE_SPAWN, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -7976,7 +8005,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 0, // damage sfx_None, // activesound MF_SLIDEME|MF_SPECIAL, // flags - S_BLUESPHEREBONUS // raisestate + S_NULL // raisestate }, { // MT_BOMBSPHERE diff --git a/src/info.h b/src/info.h index cc8876f32..b56f436b2 100644 --- a/src/info.h +++ b/src/info.h @@ -2018,8 +2018,41 @@ typedef enum state // Blue Sphere for special stages S_BLUESPHERE, - S_BLUESPHEREBONUS, - S_BLUESPHERESPARK, + S_BLUESPHERE_SPAWN, + + S_BLUESPHERE_BOUNCE1, + S_BLUESPHERE_BOUNCE2, + + S_BLUESPHERE_BOUNCE3, + S_BLUESPHERE_BOUNCE4, + + S_BLUESPHERE_BOUNCE5, + S_BLUESPHERE_BOUNCE6, + S_BLUESPHERE_BOUNCE7, + S_BLUESPHERE_BOUNCE8, + + S_BLUESPHERE_BOUNCE9, + S_BLUESPHERE_BOUNCE10, + S_BLUESPHERE_BOUNCE11, + S_BLUESPHERE_BOUNCE12, + + S_BLUESPHERE_BOUNCE13, + S_BLUESPHERE_BOUNCE14, + S_BLUESPHERE_BOUNCE15, + S_BLUESPHERE_BOUNCE16, + S_BLUESPHERE_BOUNCE17, + S_BLUESPHERE_BOUNCE18, + S_BLUESPHERE_BOUNCE19, + S_BLUESPHERE_BOUNCE20, + + S_BLUESPHERE_BOUNCE21, + S_BLUESPHERE_BOUNCE22, + S_BLUESPHERE_BOUNCE23, + S_BLUESPHERE_BOUNCE24, + S_BLUESPHERE_BOUNCE25, + S_BLUESPHERE_BOUNCE26, + S_BLUESPHERE_BOUNCE27, + S_BLUESPHERE_BOUNCE28, // Bomb Sphere S_BOMBSPHERE1, From 362c98e5d604200ebcb237b223110be842390dba Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Fri, 23 Oct 2020 02:42:04 -0400 Subject: [PATCH 024/143] Add blue sphere meter --- src/k_hud.c | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/src/k_hud.c b/src/k_hud.c index 42c7fd7c2..ee33034a6 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -50,6 +50,7 @@ static patch_t *kp_bumperstickerwide; static patch_t *kp_capsulesticker; static patch_t *kp_capsulestickerwide; static patch_t *kp_karmasticker; +static patch_t *kp_spheresticker; static patch_t *kp_splitkarmabomb; static patch_t *kp_timeoutsticker; @@ -174,6 +175,7 @@ void K_LoadKartHUDGraphics(void) kp_capsulesticker = W_CachePatchName("K_STCAPN", PU_HUDGFX); kp_capsulestickerwide = W_CachePatchName("K_STCAPW", PU_HUDGFX); kp_karmasticker = W_CachePatchName("K_STKARM", PU_HUDGFX); + kp_spheresticker = W_CachePatchName("K_STBSMT", PU_HUDGFX); kp_splitkarmabomb = W_CachePatchName("K_SPTKRM", PU_HUDGFX); kp_timeoutsticker = W_CachePatchName("K_STTOUT", PU_HUDGFX); @@ -1951,7 +1953,7 @@ static void K_drawKartSpeedometer(void) UINT8 labeln = 0; UINT8 numbers[3]; INT32 splitflags = V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_SPLITSCREEN; - UINT8 battleoffset = 0; + INT32 battleoffset = 0; if (!stplyr->exiting) // Keep the same speed value as when you crossed the finish line! { @@ -1986,7 +1988,7 @@ static void K_drawKartSpeedometer(void) numbers[2] = (convSpeed % 10); if (gametype == GT_BATTLE) - battleoffset = 8; + battleoffset = -4; V_DrawScaledPatch(LAPS_X, LAPS_Y-25 + battleoffset, V_HUDTRANS|V_SLIDEIN|splitflags, kp_speedometersticker); V_DrawScaledPatch(LAPS_X+7, LAPS_Y-25 + battleoffset, V_HUDTRANS|V_SLIDEIN|splitflags, kp_facenum[numbers[0]]); @@ -1995,6 +1997,34 @@ static void K_drawKartSpeedometer(void) V_DrawScaledPatch(LAPS_X+29, LAPS_Y-25 + battleoffset, V_HUDTRANS|V_SLIDEIN|splitflags, kp_speedometerlabel[labeln]); } +static void K_drawBlueSphereMeter(void) +{ + const UINT8 maxBars = 4; + const UINT8 segColors[] = {73, 64, 52, 54, 55, 35, 34, 33, 202, 180, 181, 182, 164, 165, 166, 153, 152}; + const UINT8 sphere = max(min(stplyr->spheres, 40), 0); + + UINT8 numBars = min((sphere / 10), maxBars); + UINT8 color = segColors[(sphere * sizeof(segColors)) / (40 + 1)]; + INT32 x = LAPS_X + 25; + UINT8 i; + + V_DrawScaledPatch(LAPS_X, LAPS_Y - 22, V_HUDTRANS|V_SLIDEIN|V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_SPLITSCREEN, kp_spheresticker); + + for (i = 0; i <= numBars; i++) + { + UINT8 segLen = 10; + + if (i == numBars) + { + segLen = (sphere % 10); + } + + V_DrawFill(x, LAPS_Y - 16, segLen, 6, color | V_HUDTRANS|V_SLIDEIN|V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_SPLITSCREEN); + + x += 15; + } +} + static void K_drawKartBumpersOrKarma(void) { UINT8 *colormap = R_GetTranslationColormap(TC_DEFAULT, stplyr->skincolor, GTC_CACHE); @@ -3995,6 +4025,11 @@ void K_drawKartHUD(void) if (LUA_HudEnabled(hud_gametypeinfo)) K_drawKartBumpersOrKarma(); } + + if (gametyperules & GTR_SPHERES) + { + K_drawBlueSphereMeter(); + } } // Draw the countdowns after everything else. From ffe4f4a400453d1c8d93770e64710e160395de60 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Fri, 23 Oct 2020 03:05:10 -0400 Subject: [PATCH 025/143] Fix leftover from old code causing desync --- 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 509d18ec4..8b2a31726 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -4116,7 +4116,7 @@ static void P_NetArchiveMisc(void) // battleovertime_t WRITEUINT16(save_p, battleovertime.enabled); - WRITEUINT16(save_p, battleovertime.radius); + WRITEFIXED(save_p, battleovertime.radius); WRITEFIXED(save_p, battleovertime.x); WRITEFIXED(save_p, battleovertime.y); WRITEFIXED(save_p, battleovertime.z); From 6c2884b7d6d86883eb3c8088ef651c837b758e2a Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Fri, 23 Oct 2020 16:40:34 -0400 Subject: [PATCH 026/143] Fix leftover from old code causing desync, part 2 --- 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 8b2a31726..c9797000e 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -4249,7 +4249,7 @@ static inline boolean P_NetUnArchiveMisc(void) // battleovertime_t battleovertime.enabled = READUINT16(save_p); - battleovertime.radius = READUINT16(save_p); + battleovertime.radius = READFIXED(save_p); battleovertime.x = READFIXED(save_p); battleovertime.y = READFIXED(save_p); battleovertime.z = READFIXED(save_p); From 81a3a1c108124adead1d31440532d3bb9d1e87f8 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sat, 24 Oct 2020 09:18:28 -0400 Subject: [PATCH 027/143] Steal bumpers from other players on any hit --- src/d_netcmd.c | 4 +-- src/k_kart.c | 97 +++++++++++++++++++++++++++++--------------------- src/k_kart.h | 6 ++-- src/p_inter.c | 39 +++++++++++--------- src/p_map.c | 16 ++++----- 5 files changed, 90 insertions(+), 72 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 6e5d245da..1b0806832 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -4310,15 +4310,13 @@ static void TimeLimit_OnChange(void) if (cv_timelimit.value != 0) { - CONS_Printf(M_GetText("Levels will end after %d minute%s.\n"),cv_timelimit.value,cv_timelimit.value == 1 ? "" : "s"); // Graue 11-17-2003 + CONS_Printf(M_GetText("Rounds will end after %d minute%s.\n"),cv_timelimit.value,cv_timelimit.value == 1 ? "" : "s"); // Graue 11-17-2003 timelimitintics = cv_timelimit.value * (60*TICRATE); // Note the deliberate absence of any code preventing // pointlimit and timelimit from being set simultaneously. // Some people might like to use them together. It works. } - else if (netgame || multiplayer) - CONS_Printf(M_GetText("Time limit disabled\n")); #ifdef HAVE_DISCORDRPC DRPC_UpdatePresence(); diff --git a/src/k_kart.c b/src/k_kart.c index f7954307e..6e3d11a9a 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -1036,7 +1036,7 @@ fixed_t K_GetMobjWeight(mobj_t *mobj, mobj_t *against) return FixedMul(weight, mobj->scale); } -void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid) +boolean K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid) { mobj_t *fx; fixed_t momdifx, momdify; @@ -1045,16 +1045,16 @@ void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid) fixed_t mass1, mass2; if (!mobj1 || !mobj2) - return; + return false; // Don't bump when you're being reborn if ((mobj1->player && mobj1->player->playerstate != PST_LIVE) || (mobj2->player && mobj2->player->playerstate != PST_LIVE)) - return; + return false; if ((mobj1->player && mobj1->player->respawn.state != RESPAWNST_NONE) || (mobj2->player && mobj2->player->respawn.state != RESPAWNST_NONE)) - return; + return false; { // Don't bump if you're flashing INT32 flash; @@ -1064,7 +1064,7 @@ void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid) { if (mobj1->player->powers[pw_flashing] < flash-1) mobj1->player->powers[pw_flashing]++; - return; + return false; } flash = K_GetKartFlashing(mobj2->player); @@ -1072,7 +1072,7 @@ void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid) { if (mobj2->player->powers[pw_flashing] < flash-1) mobj2->player->powers[pw_flashing]++; - return; + return false; } } @@ -1080,13 +1080,13 @@ void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid) if (mobj1->player && mobj1->player->kartstuff[k_justbumped]) { mobj1->player->kartstuff[k_justbumped] = bumptime; - return; + return false; } if (mobj2->player && mobj2->player->kartstuff[k_justbumped]) { mobj2->player->kartstuff[k_justbumped] = bumptime; - return; + return false; } mass1 = K_GetMobjWeight(mobj1, mobj2); @@ -1104,8 +1104,10 @@ void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid) disty = (mobj1->y + mobj2->momy*3) - (mobj2->y + mobj1->momy*3); if (distx == 0 && disty == 0) + { // if there's no distance between the 2, they're directly on top of each other, don't run this - return; + return false; + } { // Normalize distance to the sum of the two objects' radii, since in a perfect world that would be the distance at the point of collision... fixed_t dist = P_AproxDistance(distx, disty); @@ -1142,7 +1144,7 @@ void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid) if (dot >= 0) { // They're moving away from each other - return; + return false; } force = FixedDiv(dot, FixedMul(distx, distx)+FixedMul(disty, disty)); @@ -1233,6 +1235,8 @@ void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid) P_PlayerRingBurst(mobj2->player, 1); } } + + return true; } /** \brief Checks that the player is on an offroad subsector for realsies. Also accounts for line riding to prevent cheese. @@ -2413,11 +2417,14 @@ void K_BattleHitPlayer(player_t *player, player_t *victim, UINT8 points, boolean } } -void K_RemoveBumper(player_t *player, mobj_t *inflictor, mobj_t *source) +void K_RemoveBumper(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 amount) { UINT8 score = 1; boolean trapitem = false; + if (amount <= 0) + return; + if (!(gametyperules & GTR_BUMPERS)) return; @@ -2436,7 +2443,7 @@ void K_RemoveBumper(player_t *player, mobj_t *inflictor, mobj_t *source) { if (K_IsPlayerWanted(player)) score = 3; - else if ((gametyperules & GTR_BUMPERS) && player->kartstuff[k_bumper] == 1) + else if ((gametyperules & GTR_BUMPERS) && (player->kartstuff[k_bumper] <= amount)) score = 2; } @@ -2447,7 +2454,7 @@ void K_RemoveBumper(player_t *player, mobj_t *inflictor, mobj_t *source) if (player->kartstuff[k_bumper] > 0) { - if (player->kartstuff[k_bumper] == 1) + if (player->kartstuff[k_bumper] <= amount) { 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); @@ -2456,14 +2463,15 @@ void K_RemoveBumper(player_t *player, mobj_t *inflictor, mobj_t *source) CONS_Printf(M_GetText("%s lost all of their bumpers!\n"), player_names[player-players]); } - player->kartstuff[k_bumper]--; + player->kartstuff[k_bumper] -= amount; if (K_IsPlayerWanted(player)) K_CalculateBattleWanted(); } - if (player->kartstuff[k_bumper] == 0) + if (player->kartstuff[k_bumper] <= 0) { + player->kartstuff[k_bumper] = 0; player->kartstuff[k_comebacktimer] = comebacktime; if (player->kartstuff[k_comebackmode] == 2) @@ -2587,59 +2595,68 @@ void K_DebtStingPlayer(player_t *player, mobj_t *source) P_SetPlayerMobjState(player->mo, S_KART_SPINOUT); } -void K_StealBumper(player_t *player, player_t *victim) +void K_StealBumper(player_t *player, player_t *victim, UINT8 amount) { + INT32 intendedamount = player->kartstuff[k_bumper] + amount; INT32 newbumper; angle_t newangle, diff; fixed_t newx, newy; mobj_t *newmo; + if (amount <= 0) + return; + if (!(gametyperules & GTR_BUMPERS)) return; if (netgame && player->kartstuff[k_bumper] <= 0) CONS_Printf(M_GetText("%s is back in the game!\n"), player_names[player-players]); - newbumper = player->kartstuff[k_bumper]; - if (newbumper <= 1) - diff = 0; - else - diff = FixedAngle(360*FRACUNIT/newbumper); + while (player->kartstuff[k_bumper] < intendedamount) + { + newbumper = player->kartstuff[k_bumper]; + if (newbumper <= 1) + diff = 0; + else + diff = FixedAngle(360*FRACUNIT/newbumper); - newangle = player->mo->angle; - newx = player->mo->x + P_ReturnThrustX(player->mo, newangle + ANGLE_180, 64*FRACUNIT); - newy = player->mo->y + P_ReturnThrustY(player->mo, newangle + ANGLE_180, 64*FRACUNIT); + newangle = player->mo->angle; + newx = player->mo->x + P_ReturnThrustX(player->mo, newangle + ANGLE_180, 64*FRACUNIT); + newy = player->mo->y + P_ReturnThrustY(player->mo, newangle + ANGLE_180, 64*FRACUNIT); - newmo = P_SpawnMobj(newx, newy, player->mo->z, MT_BATTLEBUMPER); - newmo->threshold = newbumper; - P_SetTarget(&newmo->tracer, victim->mo); - P_SetTarget(&newmo->target, player->mo); - newmo->angle = (diff * (newbumper-1)); - newmo->color = victim->skincolor; + newmo = P_SpawnMobj(newx, newy, player->mo->z, MT_BATTLEBUMPER); + newmo->threshold = newbumper; + P_SetTarget(&newmo->tracer, victim->mo); + P_SetTarget(&newmo->target, player->mo); + newmo->angle = (diff * (newbumper-1)); + newmo->color = victim->skincolor; - if (newbumper+1 < 2) - P_SetMobjState(newmo, S_BATTLEBUMPER3); - else if (newbumper+1 < 3) - P_SetMobjState(newmo, S_BATTLEBUMPER2); - else - P_SetMobjState(newmo, S_BATTLEBUMPER1); + if (newbumper+1 < 2) + P_SetMobjState(newmo, S_BATTLEBUMPER3); + else if (newbumper+1 < 3) + P_SetMobjState(newmo, S_BATTLEBUMPER2); + else + P_SetMobjState(newmo, S_BATTLEBUMPER1); + + player->kartstuff[k_bumper]++; + } S_StartSound(player->mo, sfx_3db06); - player->kartstuff[k_bumper]++; player->kartstuff[k_comebackpoints] = 0; player->powers[pw_flashing] = K_GetKartFlashing(player); player->kartstuff[k_comebacktimer] = comebacktime; - /*victim->powers[pw_flashing] = K_GetKartFlashing(victim); - victim->kartstuff[k_comebacktimer] = comebacktime;*/ + /* + victim->powers[pw_flashing] = K_GetKartFlashing(victim); + victim->kartstuff[k_comebacktimer] = comebacktime; + */ victim->kartstuff[k_instashield] = 15; if (cv_kartdebughuddrop.value && !modeattacking) K_DropItems(victim); else K_DropHnextList(victim, false); - return; } // source is the mobj that originally threw the bomb that exploded etc. diff --git a/src/k_kart.h b/src/k_kart.h index d45a69570..2d682511a 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -27,7 +27,7 @@ UINT8 K_FindUseodds(player_t *player, fixed_t mashed, UINT32 pdis, UINT8 bestbum INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed, boolean spbrush, boolean bot, boolean rival); INT32 K_GetShieldFromItem(INT32 item); fixed_t K_GetMobjWeight(mobj_t *mobj, mobj_t *against); -void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid); +boolean 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); @@ -41,12 +41,12 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd); void K_KartPlayerAfterThink(player_t *player); void K_DoInstashield(player_t *player); void K_BattleHitPlayer(player_t *player, player_t *victim, UINT8 points, boolean reducewanted); -void K_RemoveBumper(player_t *player, mobj_t *inflictor, mobj_t *source); +void K_RemoveBumper(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 amount); void K_SpinPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 type); void K_SquishPlayer(player_t *player, mobj_t *inflictor, mobj_t *source); void K_ExplodePlayer(player_t *player, mobj_t *inflictor, mobj_t *source); void K_DebtStingPlayer(player_t *player, mobj_t *source); -void K_StealBumper(player_t *player, player_t *victim); +void K_StealBumper(player_t *player, player_t *victim, UINT8 amount); void K_SpawnKartExplosion(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32 number, mobjtype_t type, angle_t rotangle, boolean spawncenter, boolean ghostit, mobj_t *source); void K_SpawnMineExplosion(mobj_t *source, UINT8 color); UINT16 K_DriftSparkColor(player_t *player, INT32 charge); diff --git a/src/p_inter.c b/src/p_inter.c index b610ec692..6fd7d28c1 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -349,7 +349,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) special->target->player->kartstuff[k_comebackpoints]++; if (special->target->player->kartstuff[k_comebackpoints] >= 2) - K_StealBumper(special->target->player, player); + K_StealBumper(special->target->player, player, 1); special->target->player->kartstuff[k_comebacktimer] = comebacktime; player->kartstuff[k_itemroulette] = 1; @@ -384,7 +384,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) special->target->player->karthud[khud_yougotem] = 2*TICRATE; if (special->target->player->kartstuff[k_comebackpoints] >= 2) - K_StealBumper(special->target->player, player); + K_StealBumper(special->target->player, player, 1); special->target->player->kartstuff[k_comebacktimer] = comebacktime; @@ -726,7 +726,7 @@ void P_TouchStarPost(mobj_t *post, player_t *player, boolean snaptopost) } // Easily make it so that overtime works offline -//#define TESTOVERTIMEINFREEPLAY +#define TESTOVERTIMEINFREEPLAY /** Checks if the level timer is over the timelimit and the round should end, * unless you are in overtime. In which case leveltime may stretch out beyond @@ -1661,12 +1661,11 @@ static boolean P_KillPlayer(player_t *player, UINT8 type) return false; } - K_RemoveBumper(player, NULL, NULL); - switch (type) { case DMG_DEATHPIT: // Respawn kill types + K_RemoveBumper(player, NULL, NULL, 1); K_DoIngameRespawn(player); return false; default: @@ -1674,12 +1673,11 @@ static boolean P_KillPlayer(player_t *player, UINT8 type) break; } + K_RemoveBumper(player, NULL, NULL, player->kartstuff[k_bumper]); + player->pflags &= ~PF_SLIDING; player->powers[pw_carry] = CR_NONE; - // Get rid of shield - player->powers[pw_shield] = SH_NONE; - player->mo->color = player->skincolor; player->mo->colorized = false; @@ -1692,7 +1690,7 @@ static boolean P_KillPlayer(player_t *player, UINT8 type) P_SetPlayerMobjState(player->mo, player->mo->info->deathstate); - if (type == DMG_TIMEOVER) + if ((type == DMG_TIMEOVER) && (gametype == GT_RACE)) { mobj_t *boom; @@ -1851,7 +1849,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da { if (gametyperules & GTR_BUMPERS) { - if ((player->kartstuff[k_bumper] <= 0 && player->kartstuff[k_comebacktimer]) || player->kartstuff[k_comebackmode] == 1) + if ((player->kartstuff[k_bumper] <= 0 && player->kartstuff[k_comebacktimer]) || (player->kartstuff[k_comebackmode] == 1)) { // No bumpers, can't be hurt K_DoInstashield(player); @@ -1889,17 +1887,20 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da // We successfully hit 'em! if (type != DMG_STING) { + UINT8 bumpadd = 1; + + if (damagetype & DMG_STEAL) + { + bumpadd = 2; + } + if (source && source != player->mo && source->player) { K_PlayHitEmSound(source); - - if (damagetype & DMG_STEAL) - { - K_StealBumper(source->player, player); - } + K_StealBumper(source->player, player, bumpadd); } - K_RemoveBumper(player, inflictor, source); + K_RemoveBumper(player, inflictor, source, bumpadd); } player->kartstuff[k_sneakertimer] = player->kartstuff[k_numsneakers] = 0; @@ -1930,11 +1931,17 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da } if (type != DMG_STING) + { player->powers[pw_flashing] = K_GetKartFlashing(player); + } P_PlayRinglossSound(player->mo); + if (ringburst > 0) + { P_PlayerRingBurst(player, ringburst); + } + K_PlayPainSound(player->mo); if ((type == DMG_EXPLODE) || (cv_kartdebughuddrop.value && !modeattacking)) diff --git a/src/p_map.c b/src/p_map.c index 10f048e77..4a33b5427 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1322,17 +1322,13 @@ static boolean PIT_CheckThing(mobj_t *thing) if (thing->player->kartstuff[k_pogospring]) P_DamageMobj(tmthing, thing, thing, 1, DMG_WIPEOUT|DMG_STEAL); } - - if ((gametyperules & GTR_BUMPERS)) + else if (thing->player->kartstuff[k_sneakertimer] && !(tmthing->player->kartstuff[k_sneakertimer]) && !(thing->player->powers[pw_flashing])) // Don't steal bumpers while intangible { - if (thing->player->kartstuff[k_sneakertimer] && !(tmthing->player->kartstuff[k_sneakertimer]) && !(thing->player->powers[pw_flashing])) // Don't steal bumpers while intangible - { - P_DamageMobj(tmthing, thing, thing, 1, DMG_WIPEOUT|DMG_STEAL); - } - else if (tmthing->player->kartstuff[k_sneakertimer] && !(thing->player->kartstuff[k_sneakertimer]) && !(tmthing->player->powers[pw_flashing])) - { - P_DamageMobj(thing, tmthing, tmthing, 1, DMG_WIPEOUT|DMG_STEAL); - } + P_DamageMobj(tmthing, thing, thing, 1, DMG_WIPEOUT|DMG_STEAL); + } + else if (tmthing->player->kartstuff[k_sneakertimer] && !(thing->player->kartstuff[k_sneakertimer]) && !(tmthing->player->powers[pw_flashing])) + { + P_DamageMobj(thing, tmthing, tmthing, 1, DMG_WIPEOUT|DMG_STEAL); } K_KartBouncing(mo1, mo2, zbounce, false); From cc1268cdf37e8d266a05e6ff9199cd03ec90c90c Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sat, 24 Oct 2020 09:18:43 -0400 Subject: [PATCH 028/143] Lost bit of the commit --- src/p_inter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_inter.c b/src/p_inter.c index 6fd7d28c1..82a11f3df 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -321,7 +321,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) special->target->player->karthud[khud_yougotem] = 2*TICRATE; if (special->target->player->kartstuff[k_comebackpoints] >= 2) - K_StealBumper(special->target->player, player); + K_StealBumper(special->target->player, player, 1); special->target->player->kartstuff[k_comebacktimer] = comebacktime; From 0969ca1af928438dd9c0ead327faf39bc1dbae8a Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sat, 24 Oct 2020 11:27:42 -0400 Subject: [PATCH 029/143] Karma bombs rework - Fixed the bugs with them in our last netgame - Karma bombs are no longer slippery or have stat changes - Karma bombs cannot pick up spheres. Their remaining spheres before they died are removed 1 per tic. - Karma bombs are out of the game permanently when touching the overtime barrier - When successfully hurting another player, instead of getting 0.5 bumpers, they steal ALL of the opponent's bumpers, effectively swapping places with them. One bumper is lost in the process, meaning bumpers are slowly flitered out the more people need to come back. - Removed karma items/eggboxes... hopefully this is temporary and we can bring them back later, but currently we don't have a design for how they should work under the new rules :x. They are still in the code behind the `OTHERKARMAMODES` define - Bumpers & comeback timer are now player_t variables instead of kartstuff shit - eliminated boolean on player_t for checking when a player touched the barrier --- src/d_clisrv.c | 8 +++ src/d_clisrv.h | 3 + src/d_player.h | 3 + src/doomdef.h | 3 + src/g_game.c | 16 +++--- src/k_battle.c | 12 ++-- src/k_collide.c | 10 +++- src/k_hud.c | 95 +++++++++++++------------------ src/k_kart.c | 139 ++++++++++++++++++++++------------------------ src/k_kart.h | 2 +- src/lua_baselib.c | 3 +- src/p_enemy.c | 8 +-- src/p_inter.c | 113 ++++++++++++++++++------------------- src/p_map.c | 4 +- src/p_mobj.c | 32 +++++------ src/p_saveg.c | 8 +++ src/p_user.c | 2 +- 17 files changed, 235 insertions(+), 226 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 867a3e006..a3764913e 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -616,6 +616,10 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i) rsp->airtime = (tic_t)LONG(players[i].airtime); + rsp->bumpers = SHORT(players[i].bumpers); + rsp->karmadelay = SHORT(players[i].karmadelay); + rsp->eliminated = players[i].eliminated; + // respawnvars_t rsp->respawn_state = players[i].respawn.state; rsp->respawn_pointx = (fixed_t)LONG(players[i].respawn.pointx); @@ -760,6 +764,10 @@ static void resynch_read_player(resynch_pak *rsp) players[i].airtime = (tic_t)LONG(rsp->airtime); + players[i].bumpers = SHORT(rsp->bumpers); + players[i].karmadelay = SHORT(rsp->karmadelay); + players[i].eliminated = rsp->eliminated; + // respawnvars_t players[i].respawn.state = rsp->respawn_state; players[i].respawn.pointx = (fixed_t)LONG(rsp->respawn_pointx); diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 573c98dc8..4adfda142 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -281,6 +281,9 @@ typedef struct // SRB2kart INT32 kartstuff[NUMKARTSTUFF]; tic_t airtime; + INT16 bumpers; + INT16 karmadelay; + boolean eliminated; // respawnvars_t UINT8 respawn_state; diff --git a/src/d_player.h b/src/d_player.h index 36829fecc..77e5e35a3 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -509,6 +509,9 @@ typedef struct player_s waypoint_t *nextwaypoint; respawnvars_t respawn; // Respawn info tic_t airtime; // Keep track of how long you've been in the air + INT16 bumpers; + INT16 karmadelay; + boolean eliminated; // Bit flags. // See pflags_t, above. diff --git a/src/doomdef.h b/src/doomdef.h index b1960b507..6cfbd7105 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -655,6 +655,9 @@ extern const char *compdate, *comptime, *comprevision, *compbranch; /// Camera always has noclip. #define NOCLIPCAM +/// Other karma comeback modes +//#define OTHERKARMAMODES + /// MIDI support is really shitty -- we don't use it anyway, so lets throw it behind a define #define NO_MIDI diff --git a/src/g_game.c b/src/g_game.c index 7b91c0e85..40f8a9b67 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1575,7 +1575,7 @@ boolean G_CouldView(INT32 playernum) // I don't know if we want this actually, but I'll humor the suggestion anyway if ((gametyperules & GTR_BUMPERS) && !demo.playback) { - if (player->kartstuff[k_bumper] <= 0) + if (player->bumpers <= 0) return false; } @@ -2072,9 +2072,9 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) INT32 roulettetype; INT32 growshrinktimer; INT32 bumper; - INT32 comebackpoints; INT32 wanted; boolean songcredit = false; + boolean eliminated; score = players[player].score; marescore = players[player].marescore; @@ -2143,7 +2143,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) bumper = ((gametyperules & GTR_BUMPERS) ? K_StartingBumperCount() : 0); rings = ((gametyperules & GTR_SPHERES) ? 0 : 5); spheres = 0; - comebackpoints = 0; + eliminated = false; wanted = 0; } else @@ -2168,10 +2168,10 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) else growshrinktimer = 0; - bumper = players[player].kartstuff[k_bumper]; + bumper = players[player].bumpers; rings = players[player].rings; spheres = players[player].spheres; - comebackpoints = players[player].kartstuff[k_comebackpoints]; + eliminated = players[player].eliminated; wanted = players[player].kartstuff[k_wanted]; } @@ -2230,9 +2230,9 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) p->kartstuff[k_itemtype] = itemtype; p->kartstuff[k_itemamount] = itemamount; p->kartstuff[k_growshrinktimer] = growshrinktimer; - p->kartstuff[k_bumper] = bumper; - p->kartstuff[k_comebackpoints] = comebackpoints; - p->kartstuff[k_comebacktimer] = comebacktime; + p->bumpers = bumper; + p->karmadelay = comebacktime; + p->eliminated = eliminated; p->kartstuff[k_wanted] = wanted; p->kartstuff[k_eggmanblame] = -1; p->kartstuff[k_lastdraft] = -1; diff --git a/src/k_battle.c b/src/k_battle.c index ddbf649bd..518ae260f 100644 --- a/src/k_battle.c +++ b/src/k_battle.c @@ -89,24 +89,24 @@ void K_CalculateBattleWanted(void) numplaying++; - if (players[i].kartstuff[k_bumper] <= 0) // Not alive, so don't do anything else + if (players[i].bumpers <= 0) // Not alive, so don't do anything else continue; numingame++; - if (bestbumper == -1 || players[i].kartstuff[k_bumper] > bestbumper) + if (bestbumper == -1 || players[i].bumpers > bestbumper) { - bestbumper = players[i].kartstuff[k_bumper]; + bestbumper = players[i].bumpers; bestbumperplayer = i; } - else if (players[i].kartstuff[k_bumper] == bestbumper) + else if (players[i].bumpers == bestbumper) bestbumperplayer = -1; // Tie, no one has best bumper. for (j = 0; j < MAXPLAYERS; j++) { if (!playeringame[j] || players[j].spectator) continue; - if (players[j].kartstuff[k_bumper] <= 0) + if (players[j].bumpers <= 0) continue; if (j == i) continue; @@ -230,7 +230,7 @@ void K_CheckBumpers(void) numingame++; winnerscoreadd += players[i].marescore; - if (players[i].kartstuff[k_bumper] <= 0) // if you don't have any bumpers, you're probably not a winner + if (players[i].bumpers <= 0) // if you don't have any bumpers, you're probably not a winner { nobumpers = true; continue; diff --git a/src/k_collide.c b/src/k_collide.c index 56747a47f..963ec4e64 100644 --- a/src/k_collide.c +++ b/src/k_collide.c @@ -219,11 +219,15 @@ boolean K_EggItemCollide(mobj_t *t1, mobj_t *t2) if (!P_CanPickupItem(t2->player, 2)) return true; - if ((gametyperules & GTR_BUMPERS) && t2->player->kartstuff[k_bumper] <= 0) + if ((gametyperules & GTR_BUMPERS) && t2->player->bumpers <= 0) { - if (t2->player->kartstuff[k_comebackmode] || t2->player->kartstuff[k_comebacktimer]) +#ifdef OTHERKARMAMODES + if (t2->player->kartstuff[k_comebackmode] || t2->player->karmadelay) return true; t2->player->kartstuff[k_comebackmode] = 2; +#else + return true; +#endif } else { @@ -253,7 +257,7 @@ boolean K_EggItemCollide(mobj_t *t1, mobj_t *t2) if (t1->target && t1->target->player) { - if ((gametyperules & GTR_CIRCUIT) || t1->target->player->kartstuff[k_bumper] > 0) + if ((gametyperules & GTR_CIRCUIT) || t1->target->player->bumpers > 0) t2->player->kartstuff[k_eggmanblame] = t1->target->player-players; else t2->player->kartstuff[k_eggmanblame] = t2->player-players; diff --git a/src/k_hud.c b/src/k_hud.c index ee33034a6..73e656fcb 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -1609,10 +1609,10 @@ static boolean K_drawKartPositionFaces(void) if (LUA_HudEnabled(hud_battlebumpers)) { - if (gametype == GT_BATTLE && players[rankplayer[i]].kartstuff[k_bumper] > 0) + if (gametype == GT_BATTLE && players[rankplayer[i]].bumpers > 0) { V_DrawMappedPatch(bumperx-2, Y, V_HUDTRANS|V_SLIDEIN|V_SNAPTOLEFT, kp_tinybumper[0], colormap); - for (j = 1; j < players[rankplayer[i]].kartstuff[k_bumper]; j++) + for (j = 1; j < players[rankplayer[i]].bumpers; j++) { bumperx += 5; V_DrawMappedPatch(bumperx, Y, V_HUDTRANS|V_SLIDEIN|V_SNAPTOLEFT, kp_tinybumper[1], colormap); @@ -1624,7 +1624,7 @@ static boolean K_drawKartPositionFaces(void) if (i == strank) V_DrawScaledPatch(FACE_X, Y, V_HUDTRANS|V_SLIDEIN|V_SNAPTOLEFT, kp_facehighlight[(leveltime / 4) % 8]); - if (gametype == GT_BATTLE && players[rankplayer[i]].kartstuff[k_bumper] <= 0) + if (gametype == GT_BATTLE && players[rankplayer[i]].bumpers <= 0) V_DrawScaledPatch(FACE_X-4, Y-3, V_HUDTRANS|V_SLIDEIN|V_SNAPTOLEFT, kp_ranknobumpers); else { @@ -1722,11 +1722,11 @@ void K_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, IN colormap = R_GetTranslationColormap(players[tab[i].num].skin, players[tab[i].num].mo->color, GTC_CACHE); V_DrawMappedPatch(x, y-4, 0, faceprefix[players[tab[i].num].skin][FACE_RANK], colormap); - /*if (gametype == GT_BATTLE && players[tab[i].num].kartstuff[k_bumper] > 0) -- not enough space for this + /*if (gametype == GT_BATTLE && players[tab[i].num].bumpers > 0) -- not enough space for this { INT32 bumperx = x+19; V_DrawMappedPatch(bumperx-2, y-4, 0, kp_tinybumper[0], colormap); - for (j = 1; j < players[tab[i].num].kartstuff[k_bumper]; j++) + for (j = 1; j < players[tab[i].num].bumpers; j++) { bumperx += 5; V_DrawMappedPatch(bumperx, y-4, 0, kp_tinybumper[1], colormap); @@ -1737,7 +1737,7 @@ void K_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, IN if (tab[i].num == whiteplayer) V_DrawScaledPatch(x, y-4, 0, kp_facehighlight[(leveltime / 4) % 8]); - if (gametype == GT_BATTLE && players[tab[i].num].kartstuff[k_bumper] <= 0) + if (gametype == GT_BATTLE && players[tab[i].num].bumpers <= 0) V_DrawScaledPatch(x-4, y-7, 0, kp_ranknobumpers); else { @@ -2088,37 +2088,28 @@ static void K_drawKartBumpersOrKarma(void) } else { - if (stplyr->kartstuff[k_bumper] <= 0) + INT32 maxbumper = K_StartingBumperCount(); + V_DrawMappedPatch(fx+1, fy-2, V_HUDTRANS|V_SLIDEIN|splitflags, kp_rankbumper, colormap); + + if (stplyr->bumpers > 9 || maxbumper > 9) { - V_DrawMappedPatch(fx+1, fy-2, V_HUDTRANS|V_SLIDEIN|splitflags, kp_splitkarmabomb, colormap); - V_DrawScaledPatch(fx+13, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_facenum[(stplyr->kartstuff[k_comebackpoints]) % 10]); - V_DrawScaledPatch(fx+27, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_facenum[2]); + UINT8 ln[2]; + ln[0] = ((abs(stplyr->bumpers) / 10) % 10); + ln[1] = (abs(stplyr->bumpers) % 10); + + V_DrawScaledPatch(fx+13, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font[ln[0]]); + V_DrawScaledPatch(fx+17, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font[ln[1]]); + + ln[0] = ((abs(maxbumper) / 10) % 10); + ln[1] = (abs(maxbumper) % 10); + + V_DrawScaledPatch(fx+27, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font[ln[0]]); + V_DrawScaledPatch(fx+31, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font[ln[1]]); } else { - INT32 maxbumper = K_StartingBumperCount(); - V_DrawMappedPatch(fx+1, fy-2, V_HUDTRANS|V_SLIDEIN|splitflags, kp_rankbumper, colormap); - - if (stplyr->kartstuff[k_bumper] > 9 || maxbumper > 9) - { - UINT8 ln[2]; - ln[0] = ((abs(stplyr->kartstuff[k_bumper]) / 10) % 10); - ln[1] = (abs(stplyr->kartstuff[k_bumper]) % 10); - - V_DrawScaledPatch(fx+13, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font[ln[0]]); - V_DrawScaledPatch(fx+17, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font[ln[1]]); - - ln[0] = ((abs(maxbumper) / 10) % 10); - ln[1] = (abs(maxbumper) % 10); - - V_DrawScaledPatch(fx+27, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font[ln[0]]); - V_DrawScaledPatch(fx+31, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font[ln[1]]); - } - else - { - V_DrawScaledPatch(fx+13, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_facenum[(stplyr->kartstuff[k_bumper]) % 10]); - V_DrawScaledPatch(fx+27, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_facenum[(maxbumper) % 10]); - } + V_DrawScaledPatch(fx+13, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_facenum[(stplyr->bumpers) % 10]); + V_DrawScaledPatch(fx+27, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_facenum[(maxbumper) % 10]); } } } @@ -2134,22 +2125,14 @@ static void K_drawKartBumpersOrKarma(void) } else { - if (stplyr->kartstuff[k_bumper] <= 0) - { - V_DrawMappedPatch(LAPS_X, LAPS_Y, V_HUDTRANS|V_SLIDEIN|splitflags, kp_karmasticker, colormap); - V_DrawKartString(LAPS_X+47, LAPS_Y+3, V_HUDTRANS|V_SLIDEIN|splitflags, va("%d/2", stplyr->kartstuff[k_comebackpoints])); - } + INT32 maxbumper = K_StartingBumperCount(); + + if (stplyr->bumpers > 9 && maxbumper > 9) + V_DrawMappedPatch(LAPS_X, LAPS_Y, V_HUDTRANS|V_SLIDEIN|splitflags, kp_bumperstickerwide, colormap); else - { - INT32 maxbumper = K_StartingBumperCount(); + V_DrawMappedPatch(LAPS_X, LAPS_Y, V_HUDTRANS|V_SLIDEIN|splitflags, kp_bumpersticker, colormap); - if (stplyr->kartstuff[k_bumper] > 9 && maxbumper > 9) - V_DrawMappedPatch(LAPS_X, LAPS_Y, V_HUDTRANS|V_SLIDEIN|splitflags, kp_bumperstickerwide, colormap); - else - V_DrawMappedPatch(LAPS_X, LAPS_Y, V_HUDTRANS|V_SLIDEIN|splitflags, kp_bumpersticker, colormap); - - V_DrawKartString(LAPS_X+47, LAPS_Y+3, V_HUDTRANS|V_SLIDEIN|splitflags, va("%d/%d", stplyr->kartstuff[k_bumper], maxbumper)); - } + V_DrawKartString(LAPS_X+47, LAPS_Y+3, V_HUDTRANS|V_SLIDEIN|splitflags, va("%d/%d", stplyr->bumpers, maxbumper)); } } } @@ -2894,7 +2877,7 @@ static void K_drawKartMinimap(void) if (i != displayplayers[0] || r_splitscreen) { - if (gametype == GT_BATTLE && players[i].kartstuff[k_bumper] <= 0) + if (gametype == GT_BATTLE && players[i].bumpers <= 0) continue; if (players[i].kartstuff[k_hyudorotimer] > 0) @@ -3330,9 +3313,9 @@ static void K_drawBattleFullscreen(void) else K_drawKartFinish(); } - else if (stplyr->kartstuff[k_bumper] <= 0 && stplyr->kartstuff[k_comebacktimer] && comeback && !stplyr->spectator && drawcomebacktimer) + else if (stplyr->bumpers <= 0 && stplyr->karmadelay && comeback && !stplyr->spectator && drawcomebacktimer) { - UINT16 t = stplyr->kartstuff[k_comebacktimer]/(10*TICRATE); + UINT16 t = stplyr->karmadelay/(10*TICRATE); INT32 txoff, adjust = (r_splitscreen > 1) ? 4 : 6; // normal string is 8, kart string is 12, half of that for ease INT32 ty = (BASEVIDHEIGHT/2)+66; @@ -3362,11 +3345,11 @@ static void K_drawBattleFullscreen(void) V_DrawFixedPatch(x< 1) - V_DrawString(x-txoff, ty, 0, va("%d", stplyr->kartstuff[k_comebacktimer]/TICRATE)); + V_DrawString(x-txoff, ty, 0, va("%d", stplyr->karmadelay/TICRATE)); else { V_DrawFixedPatch(x<kartstuff[k_comebacktimer]/TICRATE)); + V_DrawKartString(x-txoff, ty, 0, va("%d", stplyr->karmadelay/TICRATE)); } } @@ -3787,8 +3770,8 @@ static void K_drawDistributionDebugger(void) if (!playeringame[i] || players[i].spectator) continue; pingame++; - if (players[i].kartstuff[k_bumper] > bestbumper) - bestbumper = players[i].kartstuff[k_bumper]; + if (players[i].bumpers > bestbumper) + bestbumper = players[i].bumpers; } // lovely double loop...... @@ -3911,8 +3894,8 @@ void K_drawKartHUD(void) battlefullscreen = ((gametype == GT_BATTLE) && (stplyr->exiting - || (stplyr->kartstuff[k_bumper] <= 0 - && stplyr->kartstuff[k_comebacktimer] + || (stplyr->bumpers <= 0 + && stplyr->karmadelay && comeback && stplyr->playerstate == PST_LIVE))); diff --git a/src/k_kart.c b/src/k_kart.c index 6e3d11a9a..80d9546d1 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -207,7 +207,7 @@ boolean K_IsPlayerLosing(player_t *player) INT32 winningpos = 1; UINT8 i, pcount = 0; - if (battlecapsules && player->kartstuff[k_bumper] <= 0) + if (battlecapsules && player->bumpers <= 0) return true; // DNF in break the capsules if (player->kartstuff[k_position] == 1) @@ -456,7 +456,7 @@ INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed, boolean spbrush, if (!playeringame[i] || players[i].spectator) continue; - if (!(gametyperules & GTR_BUMPERS) || players[i].kartstuff[k_bumper]) + if (!(gametyperules & GTR_BUMPERS) || players[i].bumpers) pingame++; if (players[i].exiting) @@ -735,8 +735,8 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd) pingame++; if (players[i].exiting) dontforcespb = true; - if (players[i].kartstuff[k_bumper] > bestbumper) - bestbumper = players[i].kartstuff[k_bumper]; + if (players[i].bumpers > bestbumper) + bestbumper = players[i].bumpers; } // No forced SPB in 1v1s, it has to be randomly rolled @@ -2218,12 +2218,8 @@ fixed_t K_GetKartSpeedFromStat(UINT8 kartspeed) fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower) { fixed_t finalspeed; - UINT8 kartspeed = player->kartspeed; - if ((gametyperules & (GTR_BUMPERS|GTR_KARMA)) == (GTR_BUMPERS|GTR_KARMA) && player->kartstuff[k_bumper] <= 0) - kartspeed = 1; - - finalspeed = K_GetKartSpeedFromStat(kartspeed); + finalspeed = K_GetKartSpeedFromStat(player->kartspeed); if (player->spheres > 0) { @@ -2234,7 +2230,7 @@ fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower) if (K_PlayerUsesBotMovement(player)) { // Give top speed a buff for bots, since it's a fairly weak stat without drifting - fixed_t speedmul = ((kartspeed-1) * FRACUNIT / 8) / 10; // +10% for speed 9 + fixed_t speedmul = ((player->kartspeed-1) * FRACUNIT / 8) / 10; // +10% for speed 9 if (player->botvars.rival == true) { @@ -2263,13 +2259,9 @@ fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower) fixed_t K_GetKartAccel(player_t *player) { fixed_t k_accel = 32; // 36; - UINT8 kartspeed = player->kartspeed; - if ((gametyperules & (GTR_BUMPERS|GTR_KARMA)) == (GTR_BUMPERS|GTR_KARMA) && player->kartstuff[k_bumper] <= 0) - kartspeed = 1; - - //k_accel += 3 * (9 - kartspeed); // 36 - 60 - k_accel += 4 * (9 - kartspeed); // 32 - 64 + //k_accel += 3 * (9 - player->kartspeed); // 36 - 60 + k_accel += 4 * (9 - player->kartspeed); // 32 - 64 if (player->spheres > 0) { @@ -2417,7 +2409,7 @@ void K_BattleHitPlayer(player_t *player, player_t *victim, UINT8 points, boolean } } -void K_RemoveBumper(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 amount) +void K_RemoveBumper(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 amount, boolean force) { UINT8 score = 1; boolean trapitem = false; @@ -2428,8 +2420,11 @@ void K_RemoveBumper(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 a if (!(gametyperules & GTR_BUMPERS)) return; - if (player->powers[pw_flashing] || P_PlayerInPain(player)) - return; + if (force == false) + { + if (player->powers[pw_flashing] || P_PlayerInPain(player)) + return; + } if (inflictor && !P_MobjWasRemoved(inflictor)) { @@ -2443,7 +2438,7 @@ void K_RemoveBumper(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 a { if (K_IsPlayerWanted(player)) score = 3; - else if ((gametyperules & GTR_BUMPERS) && (player->kartstuff[k_bumper] <= amount)) + else if ((gametyperules & GTR_BUMPERS) && (player->bumpers <= amount)) score = 2; } @@ -2452,9 +2447,9 @@ void K_RemoveBumper(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 a K_BattleHitPlayer(source->player, player, score, trapitem); } - if (player->kartstuff[k_bumper] > 0) + if (player->bumpers > 0) { - if (player->kartstuff[k_bumper] <= amount) + if (player->bumpers <= amount) { 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); @@ -2463,16 +2458,16 @@ void K_RemoveBumper(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 a CONS_Printf(M_GetText("%s lost all of their bumpers!\n"), player_names[player-players]); } - player->kartstuff[k_bumper] -= amount; + player->bumpers -= amount; if (K_IsPlayerWanted(player)) K_CalculateBattleWanted(); } - if (player->kartstuff[k_bumper] <= 0) + if (player->bumpers <= 0) { - player->kartstuff[k_bumper] = 0; - player->kartstuff[k_comebacktimer] = comebacktime; + player->bumpers = 0; + player->karmadelay = comebacktime; if (player->kartstuff[k_comebackmode] == 2) { @@ -2597,7 +2592,7 @@ void K_DebtStingPlayer(player_t *player, mobj_t *source) void K_StealBumper(player_t *player, player_t *victim, UINT8 amount) { - INT32 intendedamount = player->kartstuff[k_bumper] + amount; + INT32 intendedamount = player->bumpers + amount; INT32 newbumper; angle_t newangle, diff; fixed_t newx, newy; @@ -2609,12 +2604,12 @@ void K_StealBumper(player_t *player, player_t *victim, UINT8 amount) if (!(gametyperules & GTR_BUMPERS)) return; - if (netgame && player->kartstuff[k_bumper] <= 0) + if (netgame && player->bumpers <= 0) CONS_Printf(M_GetText("%s is back in the game!\n"), player_names[player-players]); - while (player->kartstuff[k_bumper] < intendedamount) + while (player->bumpers < intendedamount) { - newbumper = player->kartstuff[k_bumper]; + newbumper = player->bumpers; if (newbumper <= 1) diff = 0; else @@ -2638,18 +2633,17 @@ void K_StealBumper(player_t *player, player_t *victim, UINT8 amount) else P_SetMobjState(newmo, S_BATTLEBUMPER1); - player->kartstuff[k_bumper]++; + player->bumpers++; } S_StartSound(player->mo, sfx_3db06); - player->kartstuff[k_comebackpoints] = 0; player->powers[pw_flashing] = K_GetKartFlashing(player); - player->kartstuff[k_comebacktimer] = comebacktime; + player->karmadelay = comebacktime; /* victim->powers[pw_flashing] = K_GetKartFlashing(victim); - victim->kartstuff[k_comebacktimer] = comebacktime; + victim->karmadelay = comebacktime; */ victim->kartstuff[k_instashield] = 15; @@ -3194,7 +3188,7 @@ void K_SpawnBoostTrail(player_t *player) if (!P_IsObjectOnGround(player->mo) || player->kartstuff[k_hyudorotimer] != 0 - || ((gametyperules & GTR_BUMPERS) && player->kartstuff[k_bumper] <= 0 && player->kartstuff[k_comebacktimer])) + || ((gametyperules & GTR_BUMPERS) && player->bumpers <= 0 && player->karmadelay)) return; if (player->mo->eflags & MFE_VERTICALFLIP) @@ -3878,7 +3872,7 @@ static void K_DoHyudoroSteal(player_t *player) // Can steal from this player && (gametype == GT_RACE //&& players[i].kartstuff[k_position] < player->kartstuff[k_position]) - || ((gametyperules & GTR_BUMPERS) && players[i].kartstuff[k_bumper] > 0)) + || ((gametyperules & GTR_BUMPERS) && players[i].bumpers > 0)) // Has an item && (players[i].kartstuff[k_itemtype] @@ -4958,7 +4952,7 @@ player_t *K_FindJawzTarget(mobj_t *actor, player_t *source) thisang = InvAngle(thisang); // Jawz only go after the person directly ahead of you in race... sort of literally now! - if (gametype == GT_RACE) + if (gametyperules & GTR_CIRCUIT) { // Don't go for people who are behind you if (thisang > ANGLE_67h) @@ -4982,7 +4976,7 @@ player_t *K_FindJawzTarget(mobj_t *actor, player_t *source) continue; // Don't pay attention to dead players - if (player->kartstuff[k_bumper] <= 0) + if (player->bumpers <= 0) continue; // Z pos too high/low @@ -5259,7 +5253,7 @@ void K_KartPlayerHUDUpdate(player_t *player) player->karthud[khud_ringspblock] = (leveltime % 14); // reset to normal anim next time } - if ((gametyperules & GTR_BUMPERS) && (player->exiting || player->kartstuff[k_comebacktimer])) + if ((gametyperules & GTR_BUMPERS) && (player->exiting || player->karmadelay)) { if (player->exiting) { @@ -5272,9 +5266,9 @@ void K_KartPlayerHUDUpdate(player_t *player) } else { - if (player->kartstuff[k_comebacktimer] < 6*TICRATE) + if (player->karmadelay < 6*TICRATE) player->karthud[khud_cardanimation] -= ((164-player->karthud[khud_cardanimation])/8)+1; - else if (player->kartstuff[k_comebacktimer] < 9*TICRATE) + else if (player->karmadelay < 9*TICRATE) player->karthud[khud_cardanimation] += ((164-player->karthud[khud_cardanimation])/8)+1; } @@ -5627,14 +5621,6 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) if (player->kartstuff[k_wipeoutslow] >= 1) player->mo->friction = ORIG_FRICTION; player->kartstuff[k_wipeoutslow] = 0; - if (!comeback) - player->kartstuff[k_comebacktimer] = comebacktime; - else if (player->kartstuff[k_comebacktimer]) - { - player->kartstuff[k_comebacktimer]--; - if (P_IsDisplayPlayer(player) && player->kartstuff[k_bumper] <= 0 && player->kartstuff[k_comebacktimer] <= 0) - comebackshowninfo = true; // client has already seen the message - } } if (player->rings > 20) @@ -5642,14 +5628,34 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) else if (player->rings < -20) player->rings = -20; - if ((leveltime % TICRATE) == 0) + if ((gametyperules & GTR_BUMPERS) && (player->bumpers <= 0)) + { + // Deplete 1 every tic when removed from the game. player->spheres--; + } + else + { + // Deplete 1 every second when playing. + if ((leveltime % TICRATE) == 0) + player->spheres--; + } if (player->spheres > 40) player->spheres = 40; else if (player->spheres < 0) player->spheres = 0; + if (comeback == false || !(gametyperules & GTR_KARMA) || player->eliminated == true) + { + player->karmadelay = comebacktime; + } + else if (player->karmadelay > 0 && !P_PlayerInPain(player)) + { + player->karmadelay--; + if (P_IsDisplayPlayer(player) && player->bumpers <= 0 && player->karmadelay <= 0) + comebackshowninfo = true; // client has already seen the message + } + if (player->kartstuff[k_ringdelay]) player->kartstuff[k_ringdelay]--; @@ -5764,7 +5770,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) K_KartPlayerHUDUpdate(player); - if ((gametyperules & GTR_BUMPERS) && player->kartstuff[k_bumper] > 0 && !P_PlayerInPain(player) && !player->powers[pw_flashing]) + if ((gametyperules & GTR_BUMPERS) && player->bumpers > 0 && !P_PlayerInPain(player) && !player->powers[pw_flashing]) { player->kartstuff[k_wanted]++; @@ -5779,9 +5785,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) if (distanceToBarrier > battleovertime.radius) { - //P_KillMobj(player->mo, NULL, NULL, DMG_NORMAL); - player->kartstuff[k_bumper] = 0; - P_DamageMobj(player->mo, NULL, NULL, 1, DMG_NORMAL); + P_DamageMobj(player->mo, NULL, NULL, 1, DMG_TIMEOVER); } } } @@ -5794,7 +5798,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) if (player->kartstuff[k_eggmanexplode]) { - if (player->spectator || (gametype == GT_BATTLE && !player->kartstuff[k_bumper])) + if (player->spectator || (gametype == GT_BATTLE && !player->bumpers)) player->kartstuff[k_eggmanexplode] = 0; else { @@ -5837,7 +5841,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) K_FlameDashLeftoverSmoke(player->mo); } - if (player->kartstuff[k_comebacktimer]) + if (player->karmadelay) player->kartstuff[k_comebackmode] = 0; if (P_IsObjectOnGround(player->mo) && player->kartstuff[k_pogospring]) @@ -6411,10 +6415,7 @@ INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue) INT32 K_GetKartDriftSparkValue(player_t *player) { - UINT8 kartspeed = (gametype == GT_BATTLE && player->kartstuff[k_bumper] <= 0) - ? 1 - : player->kartspeed; - return (26*4 + kartspeed*2 + (9 - player->kartweight))*8; + return (26*4 + player->kartspeed*2 + (9 - player->kartweight))*8; } /* @@ -6732,8 +6733,8 @@ void K_KartUpdatePosition(player_t *player) { // I have less points than but the same bumpers as this player OR // I have less bumpers than this player - if ((players[i].kartstuff[k_bumper] == player->kartstuff[k_bumper] && players[i].marescore > player->marescore) - || (players[i].kartstuff[k_bumper] > player->kartstuff[k_bumper])) + if ((players[i].bumpers == player->bumpers && players[i].marescore > player->marescore) + || (players[i].bumpers > player->bumpers)) position++; } } @@ -6936,12 +6937,6 @@ void K_AdjustPlayerFriction(player_t *player) } */ - // Karma ice physics - if (gametype == GT_BATTLE && player->kartstuff[k_bumper] <= 0) - { - player->mo->friction += 1228; - } - // Water gets ice physics too if (player->mo->eflags & (MFE_UNDERWATER|MFE_TOUCHWATER)) { @@ -7061,7 +7056,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) newitem->fuse = 15*TICRATE; // selected randomly. player->kartstuff[k_comebackmode] = 0; - player->kartstuff[k_comebacktimer] = comebacktime; + player->karmadelay = comebacktime; S_StartSound(player->mo, sfx_s254); } } @@ -7650,14 +7645,14 @@ void K_MoveKartPlayer(player_t *player, boolean onground) player->mo->drawflags &= ~MFD_DONTDRAW; } - if (gametype == GT_BATTLE && player->kartstuff[k_bumper] <= 0) // dead in match? you da bomb + if (gametype == GT_BATTLE && player->bumpers <= 0) // dead in match? you da bomb { K_DropItems(player); //K_StripItems(player); K_StripOther(player); player->mo->drawflags |= MFD_SHADOW; - player->powers[pw_flashing] = player->kartstuff[k_comebacktimer]; + player->powers[pw_flashing] = player->karmadelay; } - else if (gametype == GT_RACE || player->kartstuff[k_bumper] > 0) + else if (gametype == GT_RACE || player->bumpers > 0) { player->mo->drawflags &= ~(MFD_TRANSMASK|MFD_BRIGHTMASK); } diff --git a/src/k_kart.h b/src/k_kart.h index 2d682511a..0a4765b32 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -41,7 +41,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd); void K_KartPlayerAfterThink(player_t *player); void K_DoInstashield(player_t *player); void K_BattleHitPlayer(player_t *player, player_t *victim, UINT8 points, boolean reducewanted); -void K_RemoveBumper(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 amount); +void K_RemoveBumper(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 amount, boolean force); void K_SpinPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 type); void K_SquishPlayer(player_t *player, mobj_t *inflictor, mobj_t *source); void K_ExplodePlayer(player_t *player, mobj_t *inflictor, mobj_t *source); diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 9ddbd868e..a7bad0390 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -3382,12 +3382,13 @@ static int lib_kStealBumper(lua_State *L) { player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); player_t *victim = *((player_t **)luaL_checkudata(L, 2, META_PLAYER)); + UINT8 amount = (UINT8)luaL_optinteger(L, 3, 1); NOHUD if (!player) return LUA_ErrInvalid(L, "player_t"); if (!victim) return LUA_ErrInvalid(L, "player_t"); - K_StealBumper(player, victim); + K_StealBumper(player, victim, amount); return 0; } diff --git a/src/p_enemy.c b/src/p_enemy.c index 605ba24b0..fe7bd65aa 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -4428,7 +4428,7 @@ static inline boolean PIT_GrenadeRing(mobj_t *thing) return true; if (thing->player && (thing->player->kartstuff[k_hyudorotimer] - || ((gametyperules & GTR_BUMPERS) && thing->player && thing->player->kartstuff[k_bumper] <= 0 && thing->player->kartstuff[k_comebacktimer]))) + || ((gametyperules & GTR_BUMPERS) && thing->player && thing->player->bumpers <= 0 && thing->player->karmadelay))) return true; // see if it went over / under @@ -4493,7 +4493,7 @@ static inline boolean PIT_MineExplode(mobj_t *thing) if (netgame && thing->player && thing->player->spectator) return true; - if ((gametyperules & GTR_BUMPERS) && grenade->target && grenade->target->player && grenade->target->player->kartstuff[k_bumper] <= 0 && thing == grenade->target) + if ((gametyperules & GTR_BUMPERS) && grenade->target && grenade->target->player && grenade->target->player->bumpers <= 0 && thing == grenade->target) return true; // see if it went over / under @@ -8641,7 +8641,7 @@ void A_ItemPop(mobj_t *actor) if (actor->info->deathsound) S_StartSound(remains, actor->info->deathsound); - if (!((gametyperules & GTR_BUMPERS) && actor->target->player->kartstuff[k_bumper] <= 0)) + if (!((gametyperules & GTR_BUMPERS) && actor->target->player->bumpers <= 0)) actor->target->player->kartstuff[k_itemroulette] = 1; remains->flags2 &= ~MF2_AMBUSH; @@ -9707,7 +9707,7 @@ void A_ReaperThinker(mobj_t *actor) continue; player = &players[i]; - if (player && player->mo && player->kartstuff[k_bumper] && player->score >= maxscore) + if (player && player->mo && player->bumpers && player->score >= maxscore) { targetplayermo = player->mo; maxscore = player->score; diff --git a/src/p_inter.c b/src/p_inter.c index 82a11f3df..c23221ae1 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -111,7 +111,7 @@ boolean P_CanPickupItem(player_t *player, UINT8 weapon) if (player->exiting || mapreset) return false; - /*if ((gametyperules & GTR_BUMPERS) && player->kartstuff[k_bumper] <= 0) // No bumpers in Match + /*if ((gametyperules & GTR_BUMPERS) && player->bumpers <= 0) // No bumpers in Match return false;*/ if (weapon) @@ -235,7 +235,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (!P_CanPickupItem(player, 3) || (player->kartstuff[k_itemamount] && player->kartstuff[k_itemtype] != special->threshold)) return; - if ((gametyperules & GTR_BUMPERS) && player->kartstuff[k_bumper] <= 0) + if ((gametyperules & GTR_BUMPERS) && player->bumpers <= 0) return; player->kartstuff[k_itemtype] = special->threshold; @@ -256,11 +256,15 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (!P_CanPickupItem(player, 1)) return; - if ((gametyperules & GTR_BUMPERS) && player->kartstuff[k_bumper] <= 0) + if ((gametyperules & GTR_BUMPERS) && player->bumpers <= 0) { - if (player->kartstuff[k_comebackmode] || player->kartstuff[k_comebacktimer]) +#ifdef OTHERKARMAMODES + if (player->kartstuff[k_comebackmode] || player->karmadelay) return; player->kartstuff[k_comebackmode] = 1; +#else + return; +#endif } special->momx = special->momy = special->momz = 0; @@ -272,7 +276,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) return; if (player == special->target->player) return; - if (player->kartstuff[k_bumper] <= 0) + if (player->bumpers <= 0) return; if (special->target->player->exiting || player->exiting) return; @@ -280,53 +284,41 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (P_PlayerInPain(special->target->player)) return; + if (special->target->player->karmadelay > 0) + return; + +#ifdef OTHERKARMAMODES if (!special->target->player->kartstuff[k_comebackmode]) { - if (player->kartstuff[k_growshrinktimer] || player->kartstuff[k_squishedtimer] - || player->kartstuff[k_hyudorotimer] || P_PlayerInPain(player) - || player->kartstuff[k_invincibilitytimer] || player->powers[pw_flashing]) - return; - else +#endif { - mobj_t *boom = P_SpawnMobj(special->target->x, special->target->y, special->target->z, MT_BOOMEXPLODE); - UINT8 ptadd = (K_IsPlayerWanted(player) ? 2 : 1); + mobj_t *boom; + + if (P_DamageMobj(toucher, special, special->target, 1, DMG_EXPLODE) == false) + { + return; + } + + boom = P_SpawnMobj(special->target->x, special->target->y, special->target->z, MT_BOOMEXPLODE); boom->scale = special->target->scale; boom->destscale = special->target->scale; boom->momz = 5*FRACUNIT; + if (special->target->color) boom->color = special->target->color; else boom->color = SKINCOLOR_KETCHUP; + S_StartSound(boom, special->info->attacksound); - if (player->kartstuff[k_bumper] == 1) // If you have only one bumper left, and see if it's a 1v1 - { - INT32 numingame = 0; + K_StealBumper(special->target->player, player, max(1, player->bumpers-1)); // bumpers-1 to slowly remove bumpers from the economy + K_RemoveBumper(player, special->target, special->target, player->bumpers, true); - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i] || players[i].spectator || players[i].kartstuff[k_bumper] <= 0) - continue; - numingame++; - } - - if (numingame <= 2) // If so, then an extra karma point so they are 100% certain to switch places; it's annoying to end matches with a bomb kill - ptadd++; - } - - special->target->player->kartstuff[k_comebackpoints] += ptadd; - - if (ptadd > 1) - special->target->player->karthud[khud_yougotem] = 2*TICRATE; - - if (special->target->player->kartstuff[k_comebackpoints] >= 2) - K_StealBumper(special->target->player, player, 1); - - special->target->player->kartstuff[k_comebacktimer] = comebacktime; - - P_DamageMobj(toucher, special, special->target, 1, DMG_EXPLODE); + special->target->player->karthud[khud_yougotem] = 2*TICRATE; + special->target->player->karmadelay = comebacktime; } +#ifdef OTHERKARMAMODES } else if (special->target->player->kartstuff[k_comebackmode] == 1 && P_CanPickupItem(player, 1)) { @@ -350,7 +342,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (special->target->player->kartstuff[k_comebackpoints] >= 2) K_StealBumper(special->target->player, player, 1); - special->target->player->kartstuff[k_comebacktimer] = comebacktime; + special->target->player->karmadelay = comebacktime; player->kartstuff[k_itemroulette] = 1; player->kartstuff[k_roulettetype] = 1; @@ -362,13 +354,13 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) S_StartSound(poof, special->info->seesound); - if (player->kartstuff[k_bumper] == 1) // If you have only one bumper left, and see if it's a 1v1 + if (player->bumpers == 1) // If you have only one bumper left, and see if it's a 1v1 { INT32 numingame = 0; for (i = 0; i < MAXPLAYERS; i++) { - if (!playeringame[i] || players[i].spectator || players[i].kartstuff[k_bumper] <= 0) + if (!playeringame[i] || players[i].spectator || players[i].bumpers <= 0) continue; numingame++; } @@ -386,7 +378,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (special->target->player->kartstuff[k_comebackpoints] >= 2) K_StealBumper(special->target->player, player, 1); - special->target->player->kartstuff[k_comebacktimer] = comebacktime; + special->target->player->karmadelay = comebacktime; K_DropItems(player); //K_StripItems(player); //K_StripOther(player); @@ -404,6 +396,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) special->target->player->kartstuff[k_eggmanblame] = -1; } +#endif return; case MT_SPB: if ((special->target == toucher || special->target == toucher->target) && (special->threshold > 0)) @@ -474,7 +467,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) S_StartSound(special, sfx_s1a2); return; case MT_CDUFO: // SRB2kart - if (special->fuse || !P_CanPickupItem(player, 1) || ((gametyperules & GTR_BUMPERS) && player->kartstuff[k_bumper] <= 0)) + if (special->fuse || !P_CanPickupItem(player, 1) || ((gametyperules & GTR_BUMPERS) && player->bumpers <= 0)) return; player->kartstuff[k_itemroulette] = 1; @@ -561,6 +554,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (player->spheres >= 40) return; + // Not alive + if ((gametyperules & GTR_BUMPERS) && (player->bumpers <= 0)) + return; + special->momx = special->momy = special->momz = 0; player->spheres++; break; @@ -1665,7 +1662,7 @@ static boolean P_KillPlayer(player_t *player, UINT8 type) { case DMG_DEATHPIT: // Respawn kill types - K_RemoveBumper(player, NULL, NULL, 1); + K_RemoveBumper(player, NULL, NULL, 1, true); K_DoIngameRespawn(player); return false; default: @@ -1673,8 +1670,6 @@ static boolean P_KillPlayer(player_t *player, UINT8 type) break; } - K_RemoveBumper(player, NULL, NULL, player->kartstuff[k_bumper]); - player->pflags &= ~PF_SLIDING; player->powers[pw_carry] = CR_NONE; @@ -1690,17 +1685,23 @@ static boolean P_KillPlayer(player_t *player, UINT8 type) P_SetPlayerMobjState(player->mo, player->mo->info->deathstate); - if ((type == DMG_TIMEOVER) && (gametype == GT_RACE)) + if (type == DMG_TIMEOVER) { - mobj_t *boom; + if (gametyperules & GTR_CIRCUIT) + { + mobj_t *boom; - player->mo->flags |= (MF_NOGRAVITY|MF_NOCLIP); - player->mo->drawflags |= MFD_DONTDRAW; + player->mo->flags |= (MF_NOGRAVITY|MF_NOCLIP); + player->mo->drawflags |= MFD_DONTDRAW; - boom = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_FZEROBOOM); - boom->scale = player->mo->scale; - boom->angle = player->mo->angle; - P_SetTarget(&boom->target, player->mo); + boom = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_FZEROBOOM); + boom->scale = player->mo->scale; + boom->angle = player->mo->angle; + P_SetTarget(&boom->target, player->mo); + } + + K_RemoveBumper(player, NULL, NULL, player->bumpers, true); + player->eliminated = true; } return true; @@ -1849,9 +1850,9 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da { if (gametyperules & GTR_BUMPERS) { - if ((player->kartstuff[k_bumper] <= 0 && player->kartstuff[k_comebacktimer]) || (player->kartstuff[k_comebackmode] == 1)) + if ((player->bumpers <= 0 && player->karmadelay) || (player->kartstuff[k_comebackmode] == 1)) { - // No bumpers, can't be hurt + // No bumpers & in WAIT, can't be hurt K_DoInstashield(player); return false; } @@ -1900,7 +1901,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da K_StealBumper(source->player, player, bumpadd); } - K_RemoveBumper(player, inflictor, source, bumpadd); + K_RemoveBumper(player, inflictor, source, bumpadd, false); } player->kartstuff[k_sneakertimer] = player->kartstuff[k_numsneakers] = 0; diff --git a/src/p_map.c b/src/p_map.c index 4a33b5427..f213c2d37 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1294,8 +1294,8 @@ static boolean PIT_CheckThing(mobj_t *thing) } if ((gametyperules & GTR_BUMPERS) - && ((thing->player->kartstuff[k_bumper] && !tmthing->player->kartstuff[k_bumper]) - || (tmthing->player->kartstuff[k_bumper] && !thing->player->kartstuff[k_bumper]))) + && ((thing->player->bumpers && !tmthing->player->bumpers) + || (tmthing->player->bumpers && !thing->player->bumpers))) { return true; } diff --git a/src/p_mobj.c b/src/p_mobj.c index 9957f4114..7eecebb62 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -5286,10 +5286,10 @@ static void P_MobjSceneryThink(mobj_t *mobj) else ang = FixedAngle(mobj->info->speed); - if (mobj->target->player->kartstuff[k_bumper] <= 1) + if (mobj->target->player->bumpers <= 1) diff = 0; else - diff = FixedAngle(360*FRACUNIT/mobj->target->player->kartstuff[k_bumper]); + diff = FixedAngle(360*FRACUNIT/mobj->target->player->bumpers); ang = (ang*leveltime) + (diff * (mobj->threshold-1)); @@ -5318,9 +5318,9 @@ static void P_MobjSceneryThink(mobj_t *mobj) else mobj->color = mobj->target->color; // but do so if it belongs to you :B - if (mobj->target->player->kartstuff[k_bumper] < 2) + if (mobj->target->player->bumpers < 2) P_SetMobjState(mobj, S_BATTLEBUMPER3); - else if (mobj->target->player->kartstuff[k_bumper] < 3) + else if (mobj->target->player->bumpers < 3) P_SetMobjState(mobj, S_BATTLEBUMPER2); else P_SetMobjState(mobj, S_BATTLEBUMPER1); @@ -5338,7 +5338,7 @@ static void P_MobjSceneryThink(mobj_t *mobj) } // Was this so hard? - if (mobj->target->player->kartstuff[k_bumper] <= mobj->threshold) + if (mobj->target->player->bumpers <= mobj->threshold) { P_RemoveMobj(mobj); return; @@ -5363,7 +5363,7 @@ static void P_MobjSceneryThink(mobj_t *mobj) mobj->color = mobj->target->color; K_MatchGenericExtraFlags(mobj, mobj->target); - if ((gametype == GT_RACE || mobj->target->player->kartstuff[k_bumper] <= 0) + if ((gametype == GT_RACE || mobj->target->player->bumpers <= 0) #if 1 // Set to 0 to test without needing to host || (P_IsDisplayPlayer(mobj->target->player)) #endif @@ -7019,7 +7019,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) statenum_t state = (mobj->state-states); if (!mobj->target || !mobj->target->health || !mobj->target->player || mobj->target->player->spectator - || (gametype == GT_RACE || mobj->target->player->kartstuff[k_bumper])) + || (gametype == GT_RACE || mobj->target->player->bumpers)) { P_RemoveMobj(mobj); return false; @@ -7040,11 +7040,11 @@ static boolean P_MobjRegularThink(mobj_t *mobj) mobj->radius = 24*mobj->target->scale; mobj->height = 2*mobj->radius; - if (mobj->target->player->kartstuff[k_comebacktimer] > 0) + if (mobj->target->player->karmadelay > 0) { if (state < S_PLAYERBOMB1 || state > S_PLAYERBOMB20) P_SetMobjState(mobj, S_PLAYERBOMB1); - if (mobj->target->player->kartstuff[k_comebacktimer] < TICRATE && (leveltime & 1)) + if (mobj->target->player->karmadelay < TICRATE && (leveltime & 1)) mobj->drawflags &= ~MFD_DONTDRAW; else mobj->drawflags |= MFD_DONTDRAW; @@ -10153,22 +10153,22 @@ void P_SpawnPlayer(INT32 playernum) P_SetScale(overheadarrow, mobj->destscale); if (p->spectator && pcount > 1) // HEY! No being cheap... - p->kartstuff[k_bumper] = 0; - else if (p->kartstuff[k_bumper] > 0 || leveltime < 1 + p->bumpers = 0; + else if (p->bumpers > 0 || leveltime < 1 || (p->jointime <= 1 && pcount <= 1)) { if (leveltime < 1 || (p->jointime <= 1 && pcount <= 1)) // Start of the map? - p->kartstuff[k_bumper] = K_StartingBumperCount(); // Reset those bumpers! + p->bumpers = K_StartingBumperCount(); // Reset those bumpers! - if (p->kartstuff[k_bumper]) + if (p->bumpers) { - angle_t diff = FixedAngle(360*FRACUNIT/p->kartstuff[k_bumper]); + angle_t diff = FixedAngle(360*FRACUNIT/p->bumpers); angle_t newangle = mobj->angle; fixed_t newx = mobj->x + P_ReturnThrustX(mobj, newangle + ANGLE_180, 64*FRACUNIT); fixed_t newy = mobj->y + P_ReturnThrustY(mobj, newangle + ANGLE_180, 64*FRACUNIT); mobj_t *mo; - for (i = 0; i < p->kartstuff[k_bumper]; i++) + for (i = 0; i < p->bumpers; i++) { mo = P_SpawnMobj(newx, newy, mobj->z, MT_BATTLEBUMPER); mo->threshold = i; @@ -10182,7 +10182,7 @@ void P_SpawnPlayer(INT32 playernum) } } } - else if (p->kartstuff[k_bumper] <= 0) + else if (p->bumpers <= 0) { mobj_t *karmahitbox = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_KARMAHITBOX); // Player hitbox is too small!! P_SetTarget(&karmahitbox->target, mobj); diff --git a/src/p_saveg.c b/src/p_saveg.c index c9797000e..b3ea81ecd 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -255,6 +255,10 @@ static void P_NetArchivePlayers(void) WRITEUINT32(save_p, K_GetWaypointHeapIndex(players[i].nextwaypoint)); WRITEUINT32(save_p, players[i].airtime); + WRITEINT16(save_p, players[i].bumpers); + WRITEINT16(save_p, players[i].karmadelay); + WRITEUINT8(save_p, players[i].eliminated); + // respawnvars_t WRITEUINT8(save_p, players[i].respawn.state); WRITEUINT32(save_p, K_GetWaypointHeapIndex(players[i].respawn.wp)); @@ -441,6 +445,10 @@ static void P_NetUnArchivePlayers(void) players[i].nextwaypoint = (waypoint_t *)(size_t)READUINT32(save_p); players[i].airtime = READUINT32(save_p); + players[i].bumpers = READINT16(save_p); + players[i].karmadelay = READINT16(save_p); + players[i].eliminated = (boolean)READUINT8(save_p); + // respawnvars_t players[i].respawn.state = READUINT8(save_p); players[i].respawn.wp = (waypoint_t *)(size_t)READUINT32(save_p); diff --git a/src/p_user.c b/src/p_user.c index 2a67d8360..9cf365ab5 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -4515,7 +4515,7 @@ void P_PlayerThink(player_t *player) || player->kartstuff[k_growshrinktimer] > 0 // Grow doesn't flash either. || (player->respawn.state != RESPAWNST_NONE) // Respawn timer (for drop dash effect) || (player->pflags & PF_GAMETYPEOVER) // NO CONTEST explosion - || ((gametyperules & GTR_BUMPERS) && player->kartstuff[k_bumper] <= 0 && player->kartstuff[k_comebacktimer]) + || ((gametyperules & GTR_BUMPERS) && player->bumpers <= 0 && player->karmadelay) || leveltime < starttime)) // Level intro { if (player->powers[pw_flashing] > 0 && player->powers[pw_flashing] < K_GetKartFlashing(player) From c92871d31722085a5e172422ca406310159585e2 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sat, 24 Oct 2020 11:28:02 -0400 Subject: [PATCH 030/143] Fix name tags showing for dead or invisible players --- src/k_hud.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/k_hud.c b/src/k_hud.c index 73e656fcb..b3ea7cd29 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -2555,6 +2555,18 @@ static void K_drawKartNameTags(void) continue; } + if (ntplayer->mo->drawflags & K_GetPlayerDontDrawFlag(stplyr)) + { + // Invisible on this screen + continue; + } + + if ((gametyperules & GTR_BUMPERS) && (ntplayer->bumpers <= 0)) + { + // Dead in Battle + continue; + } + if (!P_CheckSight(stplyr->mo, ntplayer->mo)) { // Can't see From dc7fe0bd586431222f7d12ac80987e0cec2ae1cd Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sat, 24 Oct 2020 11:33:07 -0400 Subject: [PATCH 031/143] Fix overtime barrier not applying to bombs/flashing players --- src/k_kart.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 80d9546d1..af66c739b 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -5770,23 +5770,23 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) K_KartPlayerHUDUpdate(player); - if ((gametyperules & GTR_BUMPERS) && player->bumpers > 0 && !P_PlayerInPain(player) && !player->powers[pw_flashing]) + if ((gametyperules & GTR_WANTED) && player->bumpers > 0 && !P_PlayerInPain(player) && !player->powers[pw_flashing]) { player->kartstuff[k_wanted]++; + } - if (battleovertime.enabled >= 10*TICRATE) + if (battleovertime.enabled >= 10*TICRATE) + { + fixed_t distanceToBarrier = 0; + + if (battleovertime.radius > 0) { - fixed_t distanceToBarrier = 0; + distanceToBarrier = R_PointToDist2(player->mo->x, player->mo->y, battleovertime.x, battleovertime.y) - (player->mo->radius * 2); + } - if (battleovertime.radius > 0) - { - distanceToBarrier = R_PointToDist2(player->mo->x, player->mo->y, battleovertime.x, battleovertime.y) - (player->mo->radius * 2); - } - - if (distanceToBarrier > battleovertime.radius) - { - P_DamageMobj(player->mo, NULL, NULL, 1, DMG_TIMEOVER); - } + if (distanceToBarrier > battleovertime.radius) + { + P_DamageMobj(player->mo, NULL, NULL, 1, DMG_TIMEOVER); } } From 5504cb8ceeb9d6fbdf6994f22c34922354563ab7 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sat, 24 Oct 2020 11:46:56 -0400 Subject: [PATCH 032/143] Don't show comeback timer & screen fade after you've been eliminated --- src/k_hud.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/k_hud.c b/src/k_hud.c index b3ea7cd29..ff689f7f2 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -3904,11 +3904,12 @@ void K_drawKartHUD(void) return; } - battlefullscreen = ((gametype == GT_BATTLE) + battlefullscreen = ((gametyperules & (GTR_BUMPERS|GTR_KARMA)) == (GTR_BUMPERS|GTR_KARMA) && (stplyr->exiting || (stplyr->bumpers <= 0 - && stplyr->karmadelay - && comeback + && stplyr->karmadelay > 0 + && stplyr->eliminated == false + && comeback == true && stplyr->playerstate == PST_LIVE))); if (!demo.title && (!battlefullscreen || r_splitscreen)) From 5db7b337d9ca6ed9472e3512a37f4e45175ab04b Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sat, 24 Oct 2020 21:45:35 -0400 Subject: [PATCH 033/143] Speed up sphere respawn --- src/p_mobj.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 96086a849..11cd407b9 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9967,7 +9967,11 @@ void P_RespawnSpecials(void) if (gametyperules & GTR_SPHERES) { - time = ((MAXPLAYERS+1) - pcount) * (2*TICRATE); + if (pcount > 2) + time -= (5*TICRATE) * (pcount-2); + + if (time < 5*TICRATE) + time = 5*TICRATE; } else { @@ -9975,7 +9979,7 @@ void P_RespawnSpecials(void) return; else if (pcount > 1) { - time = (120 - ((pcount-2) * 10))*TICRATE; + time = (120 - ((pcount-2) * 10)) * TICRATE; // If the map is longer or shorter than 3 laps, then adjust ring respawn to account for this. // 5 lap courses would have more retreaded ground, while 2 lap courses would have less. From 449d1df014352f47964afe7dd9525343e338c2f0 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sat, 24 Oct 2020 21:46:23 -0400 Subject: [PATCH 034/143] Remove flashing tics increase in Battle --- src/k_kart.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 0a4d06b29..58c2d5f65 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -2288,9 +2288,6 @@ UINT16 K_GetKartFlashing(player_t *player) tics += (tics/8) * (player->kartspeed); - if (gametype == GT_BATTLE) - tics *= 2; - return tics; } From ed6787ae4dd358d2e2eb62686ab6b413f81364a0 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sun, 25 Oct 2020 14:42:23 -0400 Subject: [PATCH 035/143] remove lj's thing --- src/d_clisrv.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 21eb83d74..0e1d58098 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -6136,12 +6136,12 @@ void NetUpdate(void) firstticstosend = gametic; for (i = 0; i < MAXNETNODES; i++) if (nodeingame[i] && nettics[i] < firstticstosend) - { + //{ firstticstosend = nettics[i]; - if (maketic + 1 >= nettics[i] + BACKUPTICS) - Net_ConnectionTimeout(i); - } + //if (maketic + 1 >= nettics[i] + BACKUPTICS) + //Net_ConnectionTimeout(i); + //} // Don't erase tics not acknowledged counts = realtics; From 5f0658e6ca700bb248cb06552b00523c0feeae59 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sun, 25 Oct 2020 16:07:33 -0400 Subject: [PATCH 036/143] The barrier won't do anything if they've already been eliminated --- 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 4a62e9a78..cc9824722 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -5765,7 +5765,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) player->kartstuff[k_wanted]++; } - if (battleovertime.enabled >= 10*TICRATE) + if ((battleovertime.enabled >= 10*TICRATE) && (player->eliminated == false)) { fixed_t distanceToBarrier = 0; From 6a2ace3067939fec8ef1cc9d1b51703627836c91 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 25 Oct 2020 13:12:08 -0700 Subject: [PATCH 037/143] Fix compiler warning --- src/k_battle.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/k_battle.c b/src/k_battle.c index 518ae260f..3b4a0e95f 100644 --- a/src/k_battle.c +++ b/src/k_battle.c @@ -382,7 +382,7 @@ void K_RunBattleOvertime(void) if (battleovertime.radius > 0) { const fixed_t pi = (22 * FRACUNIT) / 7; // loose approximation, this doesn't need to be incredibly precise - const UINT32 orbs = 32; + const INT32 orbs = 32; const angle_t angoff = ANGLE_MAX / orbs; const UINT8 spriteSpacing = 128; From 4570757c4eaaebf174c9c911e53cfd503c298a47 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 25 Oct 2020 15:42:14 -0700 Subject: [PATCH 038/143] Fix item respawn time underflow --- src/p_mobj.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index b1b415114..c9cf27b87 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9945,7 +9945,7 @@ mobjtype_t P_GetMobjtype(UINT16 mthingtype) void P_RespawnSpecials(void) { UINT8 p, pcount = 0; - tic_t time = 30*TICRATE; // Respawn things in empty dedicated servers + INT32 time = 30*TICRATE; // Respawn things in empty dedicated servers mapthing_t *mthing = NULL; if (!(gametyperules & GTR_CIRCUIT) && numgotboxes >= (4*nummapboxes/5)) // Battle Mode respawns all boxes in a different way @@ -9993,7 +9993,7 @@ void P_RespawnSpecials(void) return; // the first item in the queue is the first to respawn - if (leveltime - itemrespawntime[iquetail] < time) + if (leveltime - itemrespawntime[iquetail] < (tic_t)time) return; mthing = itemrespawnque[iquetail]; From 62139f144a65c93b7a8233e21b480bfdf252c081 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 26 Oct 2020 22:20:02 -0400 Subject: [PATCH 039/143] Paper item spawners Code is a little horrendous in a few places but I will hopefully fix later :V --- src/dehacked.c | 2 + src/doomstat.h | 33 ++++++------ src/g_game.c | 2 +- src/info.c | 27 ++++++++++ src/info.h | 2 + src/k_battle.c | 123 ++++++++++++++++++++++++++++++++++++++++++++- src/k_battle.h | 1 + src/k_kart.c | 133 +++++++++++++++++++++++++++++++++++++++++++------ src/k_kart.h | 1 + src/p_mobj.c | 3 ++ src/p_tick.c | 6 +++ 11 files changed, 298 insertions(+), 35 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 1fa855c9a..cc0c336d3 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -10430,6 +10430,8 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_WATERTRAIL", "MT_WATERTRAILUNDERLAY", + "MT_PAPERITEMSPOT", + #ifdef SEENAMES "MT_NAMECHECK", #endif diff --git a/src/doomstat.h b/src/doomstat.h index b8d82f379..57738aaa2 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -459,27 +459,28 @@ enum GameTypeRules GTR_BOTS = 1<<2, // Allows bots in this gametype. Combine with BotTiccmd hooks to make bots support your gametype. // Battle gametype rules - GTR_SPHERES = 1<<3, // Replaces rings with blue spheres - GTR_BUMPERS = 1<<4, // Enables the bumper health system - GTR_WANTED = 1<<5, // Enables the wanted anti-camping system - GTR_KARMA = 1<<6, // Enables the Karma system if you're out of bumpers - GTR_ITEMARROWS = 1<<7, // Show item box arrows above players - GTR_CAPSULES = 1<<8, // Enables the wanted anti-camping system - GTR_BATTLESTARTS = 1<<9, // Use Battle Mode start positions. + GTR_BUMPERS = 1<<3, // Enables the bumper health system + GTR_SPHERES = 1<<4, // Replaces rings with blue spheres + GTR_PAPERITEMS = 1<<5, // Replaces item boxes with paper item spawners + GTR_WANTED = 1<<6, // Enables the wanted anti-camping system + GTR_KARMA = 1<<7, // Enables the Karma system if you're out of bumpers + GTR_ITEMARROWS = 1<<8, // Show item box arrows above players + GTR_CAPSULES = 1<<9, // Enables the wanted anti-camping system + GTR_BATTLESTARTS = 1<<10, // Use Battle Mode start positions. - GTR_POINTLIMIT = 1<<10, // Reaching point limit ends the round - GTR_TIMELIMIT = 1<<11, // Reaching time limit ends the round - GTR_OVERTIME = 1<<12, // Allow overtime behavior + GTR_POINTLIMIT = 1<<11, // Reaching point limit ends the round + GTR_TIMELIMIT = 1<<12, // Reaching time limit ends the round + GTR_OVERTIME = 1<<13, // Allow overtime behavior // Custom gametype rules - GTR_TEAMS = 1<<13, // Teams are forced on - GTR_NOTEAMS = 1<<14, // Teams are forced off - GTR_TEAMSTARTS = 1<<15, // Use team-based start positions + GTR_TEAMS = 1<<14, // Teams are forced on + GTR_NOTEAMS = 1<<15, // Teams are forced off + GTR_TEAMSTARTS = 1<<16, // Use team-based start positions // Grand Prix rules - GTR_CAMPAIGN = 1<<16, // Handles cup-based progression - GTR_LIVES = 1<<17, // Lives system, players are forced to spectate during Game Over. - GTR_SPECIALBOTS = 1<<18, // Bot difficulty gets stronger between rounds, and the rival system is enabled. + GTR_CAMPAIGN = 1<<17, // Handles cup-based progression + GTR_LIVES = 1<<18, // Lives system, players are forced to spectate during Game Over. + GTR_SPECIALBOTS = 1<<19, // Bot difficulty gets stronger between rounds, and the rival system is enabled. // free: to and including 1<<31 }; diff --git a/src/g_game.c b/src/g_game.c index 4378b014e..793ec8dbb 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2793,7 +2793,7 @@ UINT32 gametypedefaultrules[NUMGAMETYPES] = // Race GTR_CIRCUIT|GTR_BOTS, // Battle - GTR_SPHERES|GTR_BUMPERS|GTR_WANTED|GTR_KARMA|GTR_ITEMARROWS|GTR_CAPSULES|GTR_BATTLESTARTS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_OVERTIME + GTR_SPHERES|GTR_BUMPERS|GTR_PAPERITEMS|GTR_WANTED|GTR_KARMA|GTR_ITEMARROWS|GTR_CAPSULES|GTR_BATTLESTARTS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_OVERTIME }; // diff --git a/src/info.c b/src/info.c index 8bd117731..90da90918 100644 --- a/src/info.c +++ b/src/info.c @@ -28680,6 +28680,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_PAPERITEMSPOT + -1, // doomednum + S_INVISIBLE, // 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_NOCLIPTHING|MF_NOGRAVITY|MF_DONTENCOREMAP, // flags + S_NULL // raisestate + }, + // ============================================================================================================================// #ifdef SEENAMES diff --git a/src/info.h b/src/info.h index b56f436b2..e7d21744e 100644 --- a/src/info.h +++ b/src/info.h @@ -6312,6 +6312,8 @@ typedef enum mobj_type MT_WATERTRAIL, MT_WATERTRAILUNDERLAY, + MT_PAPERITEMSPOT, + #ifdef SEENAMES MT_NAMECHECK, #endif diff --git a/src/k_battle.c b/src/k_battle.c index 518ae260f..b3939dad8 100644 --- a/src/k_battle.c +++ b/src/k_battle.c @@ -277,6 +277,127 @@ void K_CheckBumpers(void) P_DoPlayerExit(&players[i]); } +void K_RunPaperItemSpawners(void) +{ + const boolean overtime = (battleovertime.enabled >= 10*TICRATE); + tic_t interval = 8*TICRATE; + + if (leveltime <= starttime) + { + return; + } + + if ((battleovertime.enabled > 0) && (battleovertime.radius < 256*mapobjectscale)) + { + return; + } + + if (overtime == true) + { + interval /= 2; + } + + if (((leveltime - starttime - (interval / 2)) % interval) != 0) + { + return; + } + + if (overtime == true) + { + SINT8 flip = 1; + + K_CreatePaperItem( + battleovertime.x, battleovertime.y, battleovertime.z + (128 * mapobjectscale * flip), + FixedAngle(P_RandomRange(0, 359) * FRACUNIT), flip, + 0, 0 + ); + } + else + { + UINT8 pcount = 0; + UINT8 i; + + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i] || players[i].spectator + || players[i].exiting > 0 + || players[i].eliminated) + { + continue; + } + + if ((gametyperules & GTR_BUMPERS) && players[i].bumpers <= 0) + { + continue; + } + + pcount++; + } + + if (pcount > 0) + { +#define MAXITEM 64 + UINT16 item = 0; + mobj_t *spotList[MAXITEM]; + boolean spotUsed[MAXITEM]; + + thinker_t *th; + mobj_t *mo; + + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) + { + if (item >= MAXITEM) + break; + + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + + mo = (mobj_t *)th; + + if (mo->type == MT_PAPERITEMSPOT) + { + spotList[item] = mo; + item++; + } + } + + if (item <= 0) + { + return; + } + + for (i = 0; i < min(item, pcount); i++) + { + UINT8 r = P_RandomRange(0, item-1); + UINT8 recursion = 0; + mobj_t *drop = NULL; + SINT8 flip = 1; + + while (spotUsed[r] == true) + { + r = P_RandomRange(0, item-1); + + if ((recursion++) > 32) + { + break; + } + } + + flip = P_MobjFlip(spotList[r]); + + drop = K_CreatePaperItem( + spotList[r]->x, spotList[r]->y, spotList[r]->z + (128 * mapobjectscale * flip), + FixedAngle(P_RandomRange(0, 359) * FRACUNIT), flip, + 0, 0 + ); + + K_FlipFromObject(drop, spotList[r]); + spotUsed[r] = true; + } + } + } +} + static void K_SpawnOvertimeLaser(fixed_t x, fixed_t y, fixed_t scale) { UINT8 i, j; @@ -359,8 +480,6 @@ static void K_SpawnOvertimeLaser(fixed_t x, fixed_t y, fixed_t scale) } } -#undef MAXPLANESPERSECTOR - void K_RunBattleOvertime(void) { if (battleovertime.enabled < 10*TICRATE) diff --git a/src/k_battle.h b/src/k_battle.h index 3f63e25f2..90ee20df7 100644 --- a/src/k_battle.h +++ b/src/k_battle.h @@ -20,6 +20,7 @@ boolean K_IsPlayerWanted(player_t *player); void K_CalculateBattleWanted(void); void K_SpawnBattlePoints(player_t *source, player_t *victim, UINT8 amount); void K_CheckBumpers(void); +void K_RunPaperItemSpawners(void); void K_RunBattleOvertime(void); void K_SetupMovingCapsule(mapthing_t *mt, mobj_t *mobj); void K_SpawnBattleCapsules(void); diff --git a/src/k_kart.c b/src/k_kart.c index cc9824722..273903ff0 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -4342,6 +4342,118 @@ void K_DropHnextList(player_t *player, boolean keepshields) } } +mobj_t *K_CreatePaperItem(fixed_t x, fixed_t y, fixed_t z, angle_t angle, SINT8 flip, UINT8 type, UINT8 amount) +{ + mobj_t *drop = P_SpawnMobj(x, y, z, MT_FLOATINGITEM); + P_SetScale(drop, drop->scale>>4); + drop->destscale = (3*drop->destscale)/2; + + drop->angle = angle; + P_Thrust(drop, + FixedAngle(P_RandomFixed() * 180) + angle, + 16*mapobjectscale); + + drop->momz = flip * 3 * mapobjectscale; + if (drop->eflags & MFE_UNDERWATER) + drop->momz = (117 * drop->momz) / 200; + + if (type == 0) + { + UINT8 useodds = 0; + INT32 spawnchance[NUMKARTRESULTS]; + INT32 totalspawnchance = 0; + INT32 i; + + memset(spawnchance, 0, sizeof (spawnchance)); + + useodds = amount; + + for (i = 1; i < NUMKARTRESULTS; i++) + spawnchance[i] = (totalspawnchance += K_KartGetItemOdds(useodds, i, 0, false, false, false)); + + if (totalspawnchance > 0) + { + UINT8 newType; + UINT8 newAmount; + + totalspawnchance = P_RandomKey(totalspawnchance); + for (i = 0; i < NUMKARTRESULTS && spawnchance[i] <= totalspawnchance; i++); + + // TODO: this is bad! + // K_KartGetItemResult requires a player + // but item roulette will need rewritten to change this + + switch (i) + { + // Special roulettes first, then the generic ones are handled by default + case KRITEM_DUALSNEAKER: // Sneaker x2 + newType = KITEM_SNEAKER; + newAmount = 2; + break; + case KRITEM_TRIPLESNEAKER: // Sneaker x3 + newType = KITEM_SNEAKER; + newAmount = 3; + break; + case KRITEM_TRIPLEBANANA: // Banana x3 + newType = KITEM_BANANA; + newAmount = 3; + break; + case KRITEM_TENFOLDBANANA: // Banana x10 + newType = KITEM_BANANA; + newAmount = 10; + break; + case KRITEM_TRIPLEORBINAUT: // Orbinaut x3 + newType = KITEM_ORBINAUT; + newAmount = 3; + break; + case KRITEM_QUADORBINAUT: // Orbinaut x4 + newType = KITEM_ORBINAUT; + newAmount = 4; + break; + case KRITEM_DUALJAWZ: // Jawz x2 + newType = KITEM_JAWZ; + newAmount = 2; + break; + default: + newType = i; + newAmount = 1; + break; + } + + if (newAmount > 1) + { + UINT8 j; + + for (j = 0; j < newAmount-1; j++) + { + K_CreatePaperItem( + x, y, z, + angle, flip, + newType, 1 + ); + } + } + + drop->threshold = newType; + drop->movecount = 1; + } + else + { + drop->threshold = 1; + drop->movecount = 1; + } + } + else + { + drop->threshold = type; + drop->movecount = amount; + } + + drop->flags |= MF_NOCLIPTHING; + + return drop; +} + // For getting EXTRA hit! void K_DropItems(player_t *player) { @@ -4349,24 +4461,13 @@ void K_DropItems(player_t *player) if (player->mo && !P_MobjWasRemoved(player->mo) && player->kartstuff[k_itemamount] > 0) { - mobj_t *drop = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z + player->mo->height/2, MT_FLOATINGITEM); - P_SetScale(drop, drop->scale>>4); - drop->destscale = (3*drop->destscale)/2; - - drop->angle = player->mo->angle + ANGLE_90; - P_Thrust(drop, - FixedAngle(P_RandomFixed()*180) + player->mo->angle + ANGLE_90, - 16*mapobjectscale); - drop->momz = P_MobjFlip(player->mo)*3*mapobjectscale; - if (drop->eflags & MFE_UNDERWATER) - drop->momz = (117 * drop->momz) / 200; - - drop->threshold = player->kartstuff[k_itemtype]; - drop->movecount = player->kartstuff[k_itemamount]; + mobj_t *drop = K_CreatePaperItem( + player->mo->x, player->mo->y, player->mo->z + player->mo->height/2, + player->mo->angle + ANGLE_90, P_MobjFlip(player->mo), + player->kartstuff[k_itemtype], player->kartstuff[k_itemamount] + ); K_FlipFromObject(drop, player->mo); - - drop->flags |= MF_NOCLIPTHING; } K_StripItems(player); diff --git a/src/k_kart.h b/src/k_kart.h index 0a4765b32..115b7f47c 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -70,6 +70,7 @@ INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue); INT32 K_GetKartDriftSparkValue(player_t *player); void K_SpawnDriftBoostExplosion(player_t *player, int stage); void K_KartUpdatePosition(player_t *player); +mobj_t *K_CreatePaperItem(fixed_t x, fixed_t y, fixed_t z, angle_t angle, SINT8 flip, UINT8 type, UINT8 amount); void K_DropItems(player_t *player); void K_DropRocketSneaker(player_t *player); void K_DropKitchenSink(player_t *player); diff --git a/src/p_mobj.c b/src/p_mobj.c index b1b415114..7d5d04bdc 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -10512,6 +10512,9 @@ static mobjtype_t P_GetMobjtypeSubstitute(mapthing_t *mthing, mobjtype_t i) if ((gametyperules & GTR_SPHERES) && (i == MT_RING)) return MT_BLUESPHERE; + if ((gametyperules & GTR_PAPERITEMS) && (i == MT_RANDOMITEM)) + return MT_PAPERITEMSPOT; + return i; } diff --git a/src/p_tick.c b/src/p_tick.c index 79e71c655..5a9acefa1 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -595,6 +595,9 @@ void P_Ticker(boolean run) if ((gametyperules & GTR_BUMPERS) && battleovertime.enabled) K_RunBattleOvertime(); + if (gametyperules & GTR_PAPERITEMS) + K_RunPaperItemSpawners(); + ps_lua_thinkframe_time = I_GetTimeMicros(); LUAh_ThinkFrame(); ps_lua_thinkframe_time = I_GetTimeMicros() - ps_lua_thinkframe_time; @@ -755,6 +758,9 @@ void P_PreTicker(INT32 frames) if ((gametyperules & GTR_BUMPERS) && battleovertime.enabled) K_RunBattleOvertime(); + if (gametyperules & GTR_PAPERITEMS) + K_RunPaperItemSpawners(); + LUAh_ThinkFrame(); // Run shield positioning From 16e08d43889e2080de2a033d308c47dbd567e6bb Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 26 Oct 2020 22:33:14 -0400 Subject: [PATCH 040/143] Don't run P_RespawnBattleBoxes --- src/p_mobj.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index e40885875..e13e9f428 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9948,8 +9948,8 @@ void P_RespawnSpecials(void) INT32 time = 30*TICRATE; // Respawn things in empty dedicated servers mapthing_t *mthing = NULL; - if (!(gametyperules & GTR_CIRCUIT) && numgotboxes >= (4*nummapboxes/5)) // Battle Mode respawns all boxes in a different way - P_RespawnBattleBoxes(); + //if (!(gametyperules & GTR_CIRCUIT) && numgotboxes >= (4*nummapboxes/5)) // Battle Mode respawns all boxes in a different way + //P_RespawnBattleBoxes(); // wait time depends on player count for (p = 0; p < MAXPLAYERS; p++) From ddee6257e7e5cbac6acd90f1995c7cbd64dffd04 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 26 Oct 2020 23:46:56 -0400 Subject: [PATCH 041/143] Move to P_RunThinkers --- src/p_tick.c | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/src/p_tick.c b/src/p_tick.c index 5a9acefa1..eed42f049 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -332,6 +332,11 @@ static inline void P_RunThinkers(void) ps_thlist_times[i] = I_GetTimeMicros() - ps_thlist_times[i]; } + if (gametyperules & GTR_PAPERITEMS) + K_RunPaperItemSpawners(); + + if ((gametyperules & GTR_BUMPERS) && battleovertime.enabled) + K_RunBattleOvertime(); } // @@ -592,12 +597,6 @@ void P_Ticker(boolean run) if (playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo)) P_PlayerAfterThink(&players[i]); - if ((gametyperules & GTR_BUMPERS) && battleovertime.enabled) - K_RunBattleOvertime(); - - if (gametyperules & GTR_PAPERITEMS) - K_RunPaperItemSpawners(); - ps_lua_thinkframe_time = I_GetTimeMicros(); LUAh_ThinkFrame(); ps_lua_thinkframe_time = I_GetTimeMicros() - ps_lua_thinkframe_time; @@ -755,12 +754,6 @@ void P_PreTicker(INT32 frames) if (playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo)) P_PlayerAfterThink(&players[i]); - if ((gametyperules & GTR_BUMPERS) && battleovertime.enabled) - K_RunBattleOvertime(); - - if (gametyperules & GTR_PAPERITEMS) - K_RunPaperItemSpawners(); - LUAh_ThinkFrame(); // Run shield positioning From a2a947db62148cf687dd6580d230c5f86bb5a9c9 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 27 Oct 2020 00:19:11 -0400 Subject: [PATCH 042/143] bruh thanks jart --- src/k_battle.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/k_battle.c b/src/k_battle.c index 461799f74..cfc389b88 100644 --- a/src/k_battle.c +++ b/src/k_battle.c @@ -344,6 +344,8 @@ void K_RunPaperItemSpawners(void) thinker_t *th; mobj_t *mo; + memset(spotUsed, false, sizeof(spotUsed)); + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { if (item >= MAXITEM) From f8e52ae6a0c34a0677c61d91429c6858176d8b37 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 27 Oct 2020 00:22:33 -0400 Subject: [PATCH 043/143] Increase radius of floating items --- src/info.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/info.c b/src/info.c index 90da90918..7aa323150 100644 --- a/src/info.c +++ b/src/info.c @@ -22940,7 +22940,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_itpick, // deathsound 0, // speed - 32*FRACUNIT, // radius + 48*FRACUNIT, // radius 32*FRACUNIT, // height 0, // display offset 100, // mass From 63c84567c51ee5d250e208dd3f299bf30b2dc0f5 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 27 Oct 2020 00:23:46 -0400 Subject: [PATCH 044/143] Spawn an item right at 0:00.00, instead of at 0:04.00 --- src/k_battle.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/k_battle.c b/src/k_battle.c index cfc389b88..4c13cd9cf 100644 --- a/src/k_battle.c +++ b/src/k_battle.c @@ -282,7 +282,7 @@ void K_RunPaperItemSpawners(void) const boolean overtime = (battleovertime.enabled >= 10*TICRATE); tic_t interval = 8*TICRATE; - if (leveltime <= starttime) + if (leveltime < starttime) { return; } @@ -297,7 +297,7 @@ void K_RunPaperItemSpawners(void) interval /= 2; } - if (((leveltime - starttime - (interval / 2)) % interval) != 0) + if (((leveltime - starttime) % interval) != 0) { return; } From 714f04c93095dd8fbc7f9ea32ae081fd4bd820f5 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 27 Oct 2020 01:09:51 -0400 Subject: [PATCH 045/143] Eliminate karma players at overtime --- src/k_kart.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/k_kart.c b/src/k_kart.c index bbdc62e82..bee2e88d9 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -2451,6 +2451,11 @@ void K_RemoveBumper(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 a 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]); + + if (battleovertime.enabled > 0) + { + player->eliminated = true; + } } player->bumpers -= amount; @@ -5740,6 +5745,11 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) } else if (player->karmadelay > 0 && !P_PlayerInPain(player)) { + if (battleovertime.enabled > 0) + { + player->eliminated = true; + } + player->karmadelay--; if (P_IsDisplayPlayer(player) && player->bumpers <= 0 && player->karmadelay <= 0) comebackshowninfo = true; // client has already seen the message From 32008425190b20a3afa601789d9e3375deb9317d Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 27 Oct 2020 01:27:51 -0400 Subject: [PATCH 046/143] this is stupid --- 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 bee2e88d9..f652778a0 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -5745,7 +5745,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) } else if (player->karmadelay > 0 && !P_PlayerInPain(player)) { - if (battleovertime.enabled > 0) + if ((battleovertime.enabled > 0) && (player->bumpers <= 0)) { player->eliminated = true; } From 9dd43d4e4e342940e0b5819c48fd3ab0d2fe69e6 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Wed, 28 Oct 2020 18:36:26 -0400 Subject: [PATCH 047/143] Remove modeltilt, use roll & pitch instead Broken currently, about half of the slopes you can go into have the wrong tilt --- src/hardware/hw_defs.h | 7 +----- src/hardware/hw_md2.c | 20 +++++++--------- src/hardware/r_opengl/r_opengl.c | 2 -- src/k_kart.c | 12 ++++------ src/p_local.h | 1 + src/p_map.c | 8 ++----- src/p_mobj.c | 40 ++++++++++++++++++++++---------- src/p_mobj.h | 3 --- src/p_saveg.c | 5 ---- src/p_slopes.c | 9 +++---- src/p_user.c | 6 ++--- 11 files changed, 51 insertions(+), 62 deletions(-) diff --git a/src/hardware/hw_defs.h b/src/hardware/hw_defs.h index f9e6f0c11..67a996466 100644 --- a/src/hardware/hw_defs.h +++ b/src/hardware/hw_defs.h @@ -102,8 +102,7 @@ typedef struct //BP: transform order : scale(rotation_x(rotation_y(translation(v)))) // Kart features -//#define USE_FTRANSFORM_ANGLEZ -//#define USE_FTRANSFORM_MIRROR +#define USE_FTRANSFORM_MIRROR // Vanilla features #define USE_MODEL_NEXTFRAME @@ -111,11 +110,7 @@ typedef struct typedef struct { FLOAT x,y,z; // position -#ifdef USE_FTRANSFORM_ANGLEZ FLOAT anglex,angley,anglez; // aimingangle / viewangle -#else - FLOAT anglex,angley; // aimingangle / viewangle -#endif FLOAT scalex,scaley,scalez; FLOAT fovxangle, fovyangle; UINT8 splitscreen; diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 9896eb458..cbf84e212 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1605,22 +1605,18 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) p.rollflip *= -1; } + p.anglez = 0.0f; p.anglex = 0.0f; -#ifdef USE_FTRANSFORM_ANGLEZ - // Slope rotation from Kart - p.anglez = 0.0f; - if (spr->mobj->standingslope) + if (spr->mobj->pitch) { - fixed_t tempz = spr->mobj->standingslope->normal.z; - fixed_t tempy = spr->mobj->standingslope->normal.y; - fixed_t tempx = spr->mobj->standingslope->normal.x; - fixed_t tempangle = AngleFixed(R_PointToAngle2(0, 0, FixedSqrt(FixedMul(tempy, tempy) + FixedMul(tempz, tempz)), tempx)); - p.anglez = FIXED_TO_FLOAT(tempangle); - tempangle = -AngleFixed(R_PointToAngle2(0, 0, tempz, tempy)); - p.anglex = FIXED_TO_FLOAT(tempangle); + p.anglez = FIXED_TO_FLOAT(-AngleFixed(spr->mobj->pitch)); + } + + if (spr->mobj->roll) + { + p.anglex = FIXED_TO_FLOAT(AngleFixed(spr->mobj->roll)); } -#endif // SRB2CBTODO: MD2 scaling support finalscale *= FIXED_TO_FLOAT(spr->mobj->scale); diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 942d3d3de..fe07fc808 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -2643,9 +2643,7 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 if (hflipped) scalez = -scalez; -#ifdef USE_FTRANSFORM_ANGLEZ pglRotatef(pos->anglez, 0.0f, 0.0f, -1.0f); // rotate by slope from Kart -#endif pglRotatef(pos->angley, 0.0f, -1.0f, 0.0f); pglRotatef(pos->anglex, 1.0f, 0.0f, 0.0f); diff --git a/src/k_kart.c b/src/k_kart.c index 8a3597f1f..5196ad751 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -4576,10 +4576,7 @@ static void K_CalculateBananaSlope(mobj_t *mobj, fixed_t x, fixed_t y, fixed_t z } //mobj->standingslope = slope; - -#ifdef HWRENDER - mobj->modeltilt = slope; -#endif + P_SetPitchRollFromSlope(mobj, slope); } // Move the hnext chain! @@ -4872,9 +4869,10 @@ static void K_MoveHeldObjects(player_t *player) P_TeleportMove(cur, targx, targy, targz); K_FlipFromObject(cur, player->mo); // Update graviflip in real time thanks. -#ifdef HWRENDER - cur->modeltilt = player->mo->modeltilt; -#endif + + cur->roll = player->mo->roll; + cur->pitch = player->mo->pitch; + num = (num+1) % 2; cur = cur->hnext; } diff --git a/src/p_local.h b/src/p_local.h index bdc28075a..34ba47807 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -517,5 +517,6 @@ boolean P_CheckMissileSpawn(mobj_t *th); void P_Thrust(mobj_t *mo, angle_t angle, fixed_t move); void P_ExplodeMissile(mobj_t *mo); void P_CheckGravity(mobj_t *mo, boolean affect); +void P_SetPitchRollFromSlope(mobj_t *mo, pslope_t *slope); #endif // __P_LOCAL__ diff --git a/src/p_map.c b/src/p_map.c index b8d9820dd..8c4acdfbf 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -2633,9 +2633,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) if (thing->momz <= 0) { thing->standingslope = tmfloorslope; -#ifdef HWRENDER - thing->modeltilt = thing->standingslope; -#endif + P_SetPitchRollFromSlope(thing, thing->standingslope); if (thing->momz == 0 && thing->player && !startingonground) P_PlayerHitFloor(thing->player, true); @@ -2648,9 +2646,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) if (thing->momz >= 0) { thing->standingslope = tmceilingslope; -#ifdef HWRENDER - thing->modeltilt = thing->standingslope; -#endif + P_SetPitchRollFromSlope(thing, thing->standingslope); if (thing->momz == 0 && thing->player && !startingonground) P_PlayerHitFloor(thing->player, true); diff --git a/src/p_mobj.c b/src/p_mobj.c index be907321e..59f8af921 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1216,6 +1216,26 @@ void P_CheckGravity(mobj_t *mo, boolean affect) } } +// +// P_SetPitchRollFromSlope +// +void P_SetPitchRollFromSlope(mobj_t *mo, pslope_t *slope) +{ + if (slope) + { + fixed_t tempz = slope->normal.z; + fixed_t tempy = slope->normal.y; + fixed_t tempx = slope->normal.x; + + mo->pitch = -R_PointToAngle2(0, 0, FixedSqrt(FixedMul(tempy, tempy) + FixedMul(tempz, tempz)), tempx); + mo->roll = -R_PointToAngle2(0, 0, tempz, tempy); + } + else + { + mo->pitch = mo->roll = 0; + } +} + #define STOPSPEED (FRACUNIT) // @@ -1708,9 +1728,7 @@ void P_XYMovement(mobj_t *mo) // Now compare the Zs of the different quantizations if (oldangle-newangle > ANG30 && oldangle-newangle < ANGLE_180) { // Allow for a bit of sticking - this value can be adjusted later mo->standingslope = oldslope; -#ifdef HWRENDER - mo->modeltilt = mo->standingslope; -#endif + P_SetPitchRollFromSlope(mo, mo->standingslope); P_SlopeLaunch(mo); //CONS_Printf("launched off of slope - "); @@ -2228,9 +2246,7 @@ boolean P_ZMovement(mobj_t *mo) if (((mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope) && (mo->type != MT_STEAM)) { mo->standingslope = (mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope; -#ifdef HWRENDER - mo->modeltilt = mo->standingslope; -#endif + P_SetPitchRollFromSlope(mo, mo->standingslope); P_ReverseQuantizeMomentumToSlope(&mom, mo->standingslope); } @@ -6426,9 +6442,9 @@ static boolean P_MobjRegularThink(mobj_t *mobj) mobj->target->z); } P_SetScale(mobj, mobj->target->scale); -#ifdef HWRENDER - mobj->modeltilt = mobj->target->modeltilt; -#endif + + mobj->roll = mobj->target->roll; + mobj->pitch = mobj->target->pitch; if (mobj->fuse <= 16) { @@ -6490,9 +6506,9 @@ static boolean P_MobjRegularThink(mobj_t *mobj) P_TeleportMove(mobj, mobj->target->x + P_ReturnThrustX(mobj, mobj->angle+ANGLE_180, mobj->target->radius), mobj->target->y + P_ReturnThrustY(mobj, mobj->angle+ANGLE_180, mobj->target->radius), mobj->target->z); P_SetScale(mobj, mobj->target->scale); -#ifdef HWRENDER - mobj->modeltilt = mobj->target->modeltilt; -#endif + + mobj->roll = mobj->target->roll; + mobj->pitch = mobj->target->pitch; { player_t *p = NULL; diff --git a/src/p_mobj.h b/src/p_mobj.h index 6ffa393aa..60fd7d07c 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -408,9 +408,6 @@ typedef struct mobj_s INT32 cvmem; struct pslope_s *standingslope; // The slope that the object is standing on (shouldn't need synced in savegames, right?) -#ifdef HWRENDER - struct pslope_s *modeltilt; // Slope used for model tilting. Also is not synched, this is totally visual. -#endif boolean colorized; // Whether the mobj uses the rainbow colormap boolean mirrored; // The object's rotations will be mirrored left to right, e.g., see frame AL from the right and AR from the left diff --git a/src/p_saveg.c b/src/p_saveg.c index 0b083e42c..eb88e0c50 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -2795,12 +2795,7 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker) if (diff2 & MD2_ITNEXT) mobj->itnext = (mobj_t *)(size_t)READUINT32(save_p); if (diff2 & MD2_SLOPE) - { mobj->standingslope = P_SlopeById(READUINT16(save_p)); -#ifdef HWRENDER - mobj->modeltilt = mobj->standingslope; -#endif - } if (diff2 & MD2_COLORIZED) mobj->colorized = READUINT8(save_p); if (diff2 & MD2_MIRRORED) diff --git a/src/p_slopes.c b/src/p_slopes.c index d903afb71..f3e1e2930 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -897,9 +897,8 @@ void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope) if (P_MobjFlip(thing)*(thing->momz) < 0) // falling, land on slope { thing->standingslope = slope; -#ifdef HWRENDER - thing->modeltilt = thing->standingslope; -#endif + P_SetPitchRollFromSlope(thing, slope); + if (!thing->player || !(thing->player->pflags & PF_BOUNCING)) thing->momz = -P_MobjFlip(thing); } @@ -916,9 +915,7 @@ void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope) thing->momx = mom.x; thing->momy = mom.y; thing->standingslope = slope; -#ifdef HWRENDER - thing->modeltilt = thing->standingslope; -#endif + P_SetPitchRollFromSlope(thing, slope); if (!thing->player || !(thing->player->pflags & PF_BOUNCING)) thing->momz = -P_MobjFlip(thing); } diff --git a/src/p_user.c b/src/p_user.c index cdaa24123..5a8e5612c 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1290,6 +1290,8 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj) ghost->colorized = mobj->colorized; // Kart: they should also be colorized if their origin is ghost->angle = (mobj->player ? mobj->player->drawangle : mobj->angle); + ghost->roll = mobj->roll; + ghost->pitch = mobj->pitch; ghost->sprite = mobj->sprite; ghost->sprite2 = mobj->sprite2; ghost->frame = mobj->frame; @@ -1298,13 +1300,11 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj) ghost->fuse = ghost->info->damage; ghost->skin = mobj->skin; ghost->standingslope = mobj->standingslope; -#ifdef HWRENDER - ghost->modeltilt = mobj->modeltilt; -#endif ghost->sprxoff = mobj->sprxoff; ghost->spryoff = mobj->spryoff; ghost->sprzoff = mobj->sprzoff; + ghost->rollangle = mobj->rollangle; if (mobj->flags2 & MF2_OBJECTFLIP) ghost->flags |= MF2_OBJECTFLIP; From 64c321fbedc5013dd8bc6a8451d9b3b640297fef Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Wed, 28 Oct 2020 21:05:58 -0400 Subject: [PATCH 048/143] Fix incorrect tilts --- src/hardware/hw_md2.c | 14 ++------------ src/hardware/r_opengl/r_opengl.c | 4 ++-- src/p_mobj.c | 4 ++-- 3 files changed, 6 insertions(+), 16 deletions(-) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index cbf84e212..e8f28d8f5 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1605,18 +1605,8 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) p.rollflip *= -1; } - p.anglez = 0.0f; - p.anglex = 0.0f; - - if (spr->mobj->pitch) - { - p.anglez = FIXED_TO_FLOAT(-AngleFixed(spr->mobj->pitch)); - } - - if (spr->mobj->roll) - { - p.anglex = FIXED_TO_FLOAT(AngleFixed(spr->mobj->roll)); - } + p.anglez = FIXED_TO_FLOAT(AngleFixed(spr->mobj->pitch)); + p.anglex = FIXED_TO_FLOAT(AngleFixed(spr->mobj->roll)); // SRB2CBTODO: MD2 scaling support finalscale *= FIXED_TO_FLOAT(spr->mobj->scale); diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index fe07fc808..3e97bc807 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -2643,9 +2643,9 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 if (hflipped) scalez = -scalez; - pglRotatef(pos->anglez, 0.0f, 0.0f, -1.0f); // rotate by slope from Kart - pglRotatef(pos->angley, 0.0f, -1.0f, 0.0f); + pglRotatef(pos->anglez, 0.0f, 0.0f, -1.0f); pglRotatef(pos->anglex, 1.0f, 0.0f, 0.0f); + pglRotatef(pos->angley, 0.0f, -1.0f, 0.0f); if (pos->roll) { diff --git a/src/p_mobj.c b/src/p_mobj.c index 59f8af921..910f9ee20 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1227,8 +1227,8 @@ void P_SetPitchRollFromSlope(mobj_t *mo, pslope_t *slope) fixed_t tempy = slope->normal.y; fixed_t tempx = slope->normal.x; - mo->pitch = -R_PointToAngle2(0, 0, FixedSqrt(FixedMul(tempy, tempy) + FixedMul(tempz, tempz)), tempx); - mo->roll = -R_PointToAngle2(0, 0, tempz, tempy); + mo->pitch = R_PointToAngle2(0, 0, FixedSqrt(FixedMul(tempy, tempy) + FixedMul(tempz, tempz)), tempx); + mo->roll = R_PointToAngle2(0, 0, tempz, tempy); } else { From 918b4a203989e57b282f9dd61b644ea04acb6c48 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 28 Oct 2020 23:30:34 -0700 Subject: [PATCH 049/143] Revert "this is stupid" This reverts commit 32008425190b20a3afa601789d9e3375deb9317d. --- 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 f652778a0..bee2e88d9 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -5745,7 +5745,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) } else if (player->karmadelay > 0 && !P_PlayerInPain(player)) { - if ((battleovertime.enabled > 0) && (player->bumpers <= 0)) + if (battleovertime.enabled > 0) { player->eliminated = true; } From 4d8447dc1c2bb8735d4cb0da9857cdf4069b1d72 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 28 Oct 2020 23:30:37 -0700 Subject: [PATCH 050/143] Revert "Eliminate karma players at overtime" This reverts commit 714f04c93095dd8fbc7f9ea32ae081fd4bd820f5. --- src/k_kart.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index bee2e88d9..bbdc62e82 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -2451,11 +2451,6 @@ void K_RemoveBumper(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 a 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]); - - if (battleovertime.enabled > 0) - { - player->eliminated = true; - } } player->bumpers -= amount; @@ -5745,11 +5740,6 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) } else if (player->karmadelay > 0 && !P_PlayerInPain(player)) { - if (battleovertime.enabled > 0) - { - player->eliminated = true; - } - player->karmadelay--; if (P_IsDisplayPlayer(player) && player->bumpers <= 0 && player->karmadelay <= 0) comebackshowninfo = true; // client has already seen the message From cb941050e228f8014ca6e7936f2b2c4c45505220 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 28 Oct 2020 23:48:16 -0700 Subject: [PATCH 051/143] Paper item hitbox extends just as far below --- src/k_collide.c | 29 +++++++++++++++++++++++++++++ src/k_collide.h | 1 + src/p_inter.c | 21 --------------------- src/p_map.c | 21 +++++++++++++++++++++ 4 files changed, 51 insertions(+), 21 deletions(-) diff --git a/src/k_collide.c b/src/k_collide.c index 963ec4e64..48b20c8a1 100644 --- a/src/k_collide.c +++ b/src/k_collide.c @@ -404,3 +404,32 @@ boolean K_SMKIceBlockCollide(mobj_t *t1, mobj_t *t2) K_KartBouncing(t2, t1, false, true); return false; } + +boolean K_FloatingItemCollide(mobj_t *t1, mobj_t *t2) +{ + player_t * player = t2->player; + + if (! player) + return true; + + if (!P_CanPickupItem(player, 3) || (player->kartstuff[k_itemamount] && player->kartstuff[k_itemtype] != t1->threshold)) + return true; + + if ((gametyperules & GTR_BUMPERS) && player->bumpers <= 0) + return true; + + player->kartstuff[k_itemtype] = t2->threshold; + player->kartstuff[k_itemamount] += t2->movecount; + if (player->kartstuff[k_itemamount] > 255) + player->kartstuff[k_itemamount] = 255; + + S_StartSound(t1, t1->info->deathsound); + + P_SetTarget(&t1->tracer, t2); + t1->flags2 |= MF2_NIGHTSPULL; + t1->destscale = mapobjectscale>>4; + t1->scalespeed <<= 1; + + t1->flags &= ~MF_SPECIAL; + return false; +} diff --git a/src/k_collide.h b/src/k_collide.h index 86f643b3f..fed8969d6 100644 --- a/src/k_collide.h +++ b/src/k_collide.h @@ -12,5 +12,6 @@ boolean K_MineExplosionCollide(mobj_t *t1, mobj_t *t2); boolean K_KitchenSinkCollide(mobj_t *t1, mobj_t *t2); boolean K_FallingRockCollide(mobj_t *t1, mobj_t *t2); boolean K_SMKIceBlockCollide(mobj_t *t1, mobj_t *t2); +boolean K_FloatingItemCollide(mobj_t *t1, mobj_t *t2); #endif diff --git a/src/p_inter.c b/src/p_inter.c index e190e1274..08bd29fdf 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -231,27 +231,6 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) P_SetObjectMomZ(player->mo, 12<mo, player->mo->angle, 20<kartstuff[k_itemamount] && player->kartstuff[k_itemtype] != special->threshold)) - return; - - if ((gametyperules & GTR_BUMPERS) && player->bumpers <= 0) - return; - - player->kartstuff[k_itemtype] = special->threshold; - player->kartstuff[k_itemamount] += special->movecount; - if (player->kartstuff[k_itemamount] > 255) - player->kartstuff[k_itemamount] = 255; - - S_StartSound(special, special->info->deathsound); - - P_SetTarget(&special->tracer, toucher); - special->flags2 |= MF2_NIGHTSPULL; - special->destscale = mapobjectscale>>4; - special->scalespeed <<= 1; - - special->flags &= ~MF_SPECIAL; - return; case MT_RANDOMITEM: // SRB2kart if (!P_CanPickupItem(player, 1)) return; diff --git a/src/p_map.c b/src/p_map.c index 7a0958f7f..bea4849dd 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -970,6 +970,27 @@ static boolean PIT_CheckThing(mobj_t *thing) return K_FallingRockCollide(thing, tmthing); } + if (tmthing->type == MT_FLOATINGITEM) + { + // see if it went over / under + if (tmthing->z > thing->z + thing->height) + return true; // overhead + if (tmthing->z + tmthing->height < thing->z - thing->height) // extended hitbox + return true; // underneath + + return K_FloatingItemCollide(tmthing, thing); + } + else if (thing->type == MT_FLOATINGITEM) + { + // see if it went over / under + if (tmthing->z > thing->z + thing->height) + return true; // overhead + if (tmthing->z + tmthing->height < thing->z - thing->height) // extended hitbox + return true; // underneath + + return K_FloatingItemCollide(thing, tmthing); + } + //} if ((thing->type == MT_SPRINGSHELL || thing->type == MT_YELLOWSHELL) && thing->health > 0 From 875493d77842a7b62fbf1fb78d494da6cbfff57c Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Fri, 30 Oct 2020 02:15:49 -0400 Subject: [PATCH 052/143] Remove the need for setting rotation axis in spriteinfo for models Now it just does it like Software --- src/dehacked.c | 7 ------- src/hardware/hw_defs.h | 8 +------- src/hardware/hw_main.c | 6 ++++++ src/hardware/hw_md2.c | 33 +++++++++----------------------- src/hardware/r_opengl/r_opengl.c | 26 ++----------------------- src/lua_infolib.c | 6 ------ 6 files changed, 18 insertions(+), 68 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index a467543e9..fa361169b 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -1271,8 +1271,6 @@ static void readspriteframe(MYFILE *f, spriteinfo_t *sprinfo, UINT8 frame) sprinfo->pivot[frame].x = value; else if (fastcmp(word, "YPIVOT")) sprinfo->pivot[frame].y = value; - else if (fastcmp(word, "ROTAXIS")) - sprinfo->pivot[frame].rotaxis = value; else { f->curpos = lastline; @@ -11480,11 +11478,6 @@ struct { {"DI_SOUTHEAST",DI_SOUTHEAST}, {"NUMDIRS",NUMDIRS}, - // Sprite rotation axis (rotaxis_t) - {"ROTAXIS_X",ROTAXIS_X}, - {"ROTAXIS_Y",ROTAXIS_Y}, - {"ROTAXIS_Z",ROTAXIS_Z}, - // Buttons (ticcmd_t) // SRB2kart {"BT_ACCELERATE",BT_ACCELERATE}, {"BT_DRIFT",BT_DRIFT}, diff --git a/src/hardware/hw_defs.h b/src/hardware/hw_defs.h index 67a996466..9cb48620e 100644 --- a/src/hardware/hw_defs.h +++ b/src/hardware/hw_defs.h @@ -101,9 +101,6 @@ typedef struct //Hurdler: Transform (coords + angles) //BP: transform order : scale(rotation_x(rotation_y(translation(v)))) -// Kart features -#define USE_FTRANSFORM_MIRROR - // Vanilla features #define USE_MODEL_NEXTFRAME @@ -118,13 +115,10 @@ typedef struct boolean shearing; // 14042019 angle_t viewaiming; // 17052019 boolean roll; - SINT8 rollflip; FLOAT rollangle; // done to not override USE_FTRANSFORM_ANGLEZ - UINT8 rotaxis; FLOAT centerx, centery; -#ifdef USE_FTRANSFORM_MIRROR + FLOAT rollx, rollz; boolean mirror; // SRB2Kart: Encore Mode -#endif } FTransform; // Transformed vector, as passed to HWR API diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index bc7a673b7..b00ea6440 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5508,6 +5508,8 @@ static void HWR_DrawSkyBackground(player_t *player) fixed_t rol = AngleFixed(player->viewrollangle); dometransform.rollangle = FIXED_TO_FLOAT(rol); dometransform.roll = true; + dometransform.rollx = 1.0f; + dometransform.rollz = 0.0f; } dometransform.splitscreen = r_splitscreen; @@ -5786,6 +5788,8 @@ void HWR_RenderSkyboxView(player_t *player) fixed_t rol = AngleFixed(player->viewrollangle); atransform.rollangle = FIXED_TO_FLOAT(rol); atransform.roll = true; + atransform.rollx = 1.0f; + atransform.rollz = 0.0f; } atransform.splitscreen = r_splitscreen; @@ -5987,6 +5991,8 @@ void HWR_RenderPlayerView(void) fixed_t rol = AngleFixed(player->viewrollangle); atransform.rollangle = FIXED_TO_FLOAT(rol); atransform.roll = true; + atransform.rollx = 1.0f; + atransform.rollz = 0.0f; } atransform.splitscreen = r_splitscreen; diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index e8f28d8f5..2ac4e8a9f 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1353,8 +1353,6 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) const UINT8 hflip = (UINT8)(!(spr->mobj->mirrored) != !(spr->mobj->frame & FF_HORIZONTALFLIP)); spritedef_t *sprdef; spriteframe_t *sprframe; - spriteinfo_t *sprinfo; - angle_t ang; INT32 mod; float finalscale; @@ -1378,12 +1376,10 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) { md2 = &md2_playermodels[(skin_t*)spr->mobj->skin-skins]; md2->skin = (skin_t*)spr->mobj->skin-skins; - sprinfo = &((skin_t *)spr->mobj->skin)->sprinfo[spr->mobj->sprite2]; } else { md2 = &md2_models[spr->mobj->sprite]; - sprinfo = &spriteinfo[spr->mobj->sprite]; } // texture loading before model init, so it knows if sprite graphics are used, which @@ -1578,31 +1574,22 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) } p.rollangle = 0.0f; - p.rollflip = 1; - p.rotaxis = 0; + if (spr->mobj->rollangle) { + fixed_t camAngleDiff = AngleFixed(viewangle) - FLOAT_TO_FIXED(p.angley); // dumb reconversion back, I know fixed_t anglef = AngleFixed(spr->mobj->rollangle); + p.rollangle = FIXED_TO_FLOAT(anglef); p.roll = true; // rotation pivot - p.centerx = FIXED_TO_FLOAT(spr->mobj->radius/2); - p.centery = FIXED_TO_FLOAT(spr->mobj->height/(flip ? -2 : 2)); + p.centerx = FIXED_TO_FLOAT(spr->mobj->radius / 2); + p.centery = FIXED_TO_FLOAT(spr->mobj->height / 2); - // rotation axis - if (sprinfo->available) - p.rotaxis = (UINT8)(sprinfo->pivot[(spr->mobj->frame & FF_FRAMEMASK)].rotaxis); - - // for NiGHTS specifically but should work everywhere else - ang = R_PointToAngle (spr->mobj->x, spr->mobj->y) - (spr->mobj->player ? spr->mobj->player->drawangle : spr->mobj->angle); - if ((sprframe->rotate & SRF_RIGHT) && (ang < ANGLE_180)) // See from right - p.rollflip = 1; - else if ((sprframe->rotate & SRF_LEFT) && (ang >= ANGLE_180)) // See from left - p.rollflip = -1; - - if (flip) - p.rollflip *= -1; + // rotation axes relative to camera + p.rollx = FIXED_TO_FLOAT(FINECOSINE(FixedAngle(camAngleDiff) >> ANGLETOFINESHIFT)); + p.rollz = FIXED_TO_FLOAT(FINESINE(FixedAngle(camAngleDiff) >> ANGLETOFINESHIFT)); } p.anglez = FIXED_TO_FLOAT(AngleFixed(spr->mobj->pitch)); @@ -1612,9 +1599,7 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) finalscale *= FIXED_TO_FLOAT(spr->mobj->scale); p.flip = atransform.flip; -#ifdef USE_FTRANSFORM_MIRROR - p.mirror = atransform.mirror; // from Kart -#endif + p.mirror = atransform.mirror; HWD.pfnSetShader(SHADER_MODEL); // model shader HWD.pfnDrawModel(md2->model, frame, durs, tics, nextFrame, &p, finalscale, flip, hflip, &Surf); diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 3e97bc807..783466ff8 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -2610,7 +2610,6 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 pglEnable(GL_CULL_FACE); pglEnable(GL_NORMALIZE); -#ifdef USE_FTRANSFORM_MIRROR // flipped is if the object is vertically flipped // hflipped is if the object is horizontally flipped // pos->flip is if the screen is flipped vertically @@ -2623,17 +2622,6 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 else pglCullFace(GL_BACK); } -#else - // pos->flip is if the screen is flipped too - if (flipped ^ hflipped ^ pos->flip) // If one or three of these are active, but not two, invert the model's culling - { - pglCullFace(GL_FRONT); - } - else - { - pglCullFace(GL_BACK); - } -#endif pglPushMatrix(); // should be the same as glLoadIdentity //Hurdler: now it seems to work @@ -2649,14 +2637,8 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 if (pos->roll) { - float roll = (1.0f * pos->rollflip); pglTranslatef(pos->centerx, pos->centery, 0); - if (pos->rotaxis == 2) // Z - pglRotatef(pos->rollangle, 0.0f, 0.0f, roll); - else if (pos->rotaxis == 1) // Y - pglRotatef(pos->rollangle, 0.0f, roll, 0.0f); - else // X - pglRotatef(pos->rollangle, roll, 0.0f, 0.0f); + pglRotatef(pos->rollangle, pos->rollx, 0.0f, pos->rollz); pglTranslatef(-pos->centerx, -pos->centery, 0); } @@ -2829,13 +2811,9 @@ EXPORT void HWRAPI(SetTransform) (FTransform *stransform) if (stransform) { used_fov = stransform->fovxangle; -#ifdef USE_FTRANSFORM_MIRROR - // mirroring from Kart if (stransform->mirror) pglScalef(-stransform->scalex, stransform->scaley, -stransform->scalez); - else -#endif - if (stransform->flip) + else if (stransform->flip) pglScalef(stransform->scalex, -stransform->scaley, -stransform->scalez); else pglScalef(stransform->scalex, stransform->scaley, -stransform->scalez); diff --git a/src/lua_infolib.c b/src/lua_infolib.c index 5e5a1dbc4..7e2445b0c 100644 --- a/src/lua_infolib.c +++ b/src/lua_infolib.c @@ -313,8 +313,6 @@ static int PopPivotSubTable(spriteframepivot_t *pivot, lua_State *L, int stk, in pivot[idx].x = (INT32)value; else if (ikey == 2 || (key && fastcmp(key, "y"))) pivot[idx].y = (INT32)value; - else if (ikey == 3 || (key && fastcmp(key, "rotaxis"))) - pivot[idx].rotaxis = (UINT8)value; else if (ikey == -1 && (key != NULL)) FIELDERROR("pivot key", va("invalid option %s", key)); okcool = 1; @@ -579,8 +577,6 @@ static int framepivot_get(lua_State *L) lua_pushinteger(L, framepivot->x); else if (fastcmp("y", field)) lua_pushinteger(L, framepivot->y); - else if (fastcmp("rotaxis", field)) - lua_pushinteger(L, (UINT8)framepivot->rotaxis); else return luaL_error(L, va("Field %s does not exist in spriteframepivot_t", field)); @@ -605,8 +601,6 @@ static int framepivot_set(lua_State *L) framepivot->x = luaL_checkinteger(L, 3); else if (fastcmp("y", field)) framepivot->y = luaL_checkinteger(L, 3); - else if (fastcmp("rotaxis", field)) - framepivot->rotaxis = luaL_checkinteger(L, 3); else return luaL_error(L, va("Field %s does not exist in spriteframepivot_t", field)); From fed0ed98deb9554df47bef15ae703b71ce449b0d Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Fri, 30 Oct 2020 15:54:58 -0400 Subject: [PATCH 053/143] Add R_SpriteRotationAngle function Gets the rotation angle for the mobj's sprite. Meant for pitch & roll later, but that part is if'd out currently and just returns mobj->rollangle --- src/hardware/hw_main.c | 7 +++++-- src/r_picformats.c | 22 ++++++++++++++++++++++ src/r_picformats.h | 1 + src/r_things.c | 7 +++++-- 4 files changed, 33 insertions(+), 4 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index b00ea6440..0be2e2c86 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -4902,6 +4902,7 @@ static void HWR_ProjectSprite(mobj_t *thing) #ifdef ROTSPRITE patch_t *rotsprite = NULL; INT32 rollangle = 0; + angle_t spriterotangle = 0; #endif if (!thing) @@ -5025,9 +5026,11 @@ static void HWR_ProjectSprite(mobj_t *thing) spr_topoffset = spritecachedinfo[lumpoff].topoffset; #ifdef ROTSPRITE - if (thing->rollangle) + spriterotangle = R_SpriteRotationAngle(thing); + + if (spriterotangle != 0) { - rollangle = R_GetRollAngle(thing->rollangle); + rollangle = R_GetRollAngle(spriterotangle); if (!(sprframe->rotsprite.cached & (1<sprite, (thing->frame & FF_FRAMEMASK), sprinfo, sprframe, rot, flip); rotsprite = sprframe->rotsprite.patch[rot][rollangle]; diff --git a/src/r_picformats.c b/src/r_picformats.c index 95fe23aeb..19079d3b7 100644 --- a/src/r_picformats.c +++ b/src/r_picformats.c @@ -23,6 +23,7 @@ #include "v_video.h" #include "z_zone.h" #include "w_wad.h" +#include "r_main.h" // R_PointToAngle #ifdef HWRENDER #include "hardware/hw_glob.h" @@ -1605,6 +1606,27 @@ void R_LoadSpriteInfoLumps(UINT16 wadnum, UINT16 numlumps) } #ifdef ROTSPRITE +// +// R_SpriteRotationAngle +// +// Gets the rollangle for the input object. +// +angle_t R_SpriteRotationAngle(mobj_t *mobj) +{ +#if 0 + angle_t viewingAngle = R_PointToAngle(mobj->x, mobj->y); + + fixed_t pitchMul = -FINESINE(viewingAngle >> ANGLETOFINESHIFT); + fixed_t rollMul = FINECOSINE(viewingAngle >> ANGLETOFINESHIFT); + + angle_t rollOrPitch = FixedMul(mobj->pitch, pitchMul) + FixedMul(mobj->roll, rollMul); + + return (rollOrPitch + mobj->rollangle); +#else + return mobj->rollangle; +#endif +} + // // R_GetRollAngle // diff --git a/src/r_picformats.h b/src/r_picformats.h index 3ee76a92f..d677e783b 100644 --- a/src/r_picformats.h +++ b/src/r_picformats.h @@ -122,6 +122,7 @@ void R_ParseSPRTINFOLump(UINT16 wadNum, UINT16 lumpNum); // Sprite rotation #ifdef ROTSPRITE +angle_t R_SpriteRotationAngle(mobj_t *mobj); INT32 R_GetRollAngle(angle_t rollangle); void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, spriteframe_t *sprframe, INT32 rot, UINT8 flip); void R_FreeSingleRotSprite(spritedef_t *spritedef); diff --git a/src/r_things.c b/src/r_things.c index fd200cf87..3110d86bc 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1446,6 +1446,7 @@ static void R_ProjectSprite(mobj_t *thing) #ifdef ROTSPRITE patch_t *rotsprite = NULL; INT32 rollangle = 0; + angle_t spriterotangle = 0; #endif // transform the origin point @@ -1571,9 +1572,11 @@ static void R_ProjectSprite(mobj_t *thing) spr_topoffset = spritecachedinfo[lump].topoffset; #ifdef ROTSPRITE - if (thing->rollangle) + spriterotangle = R_SpriteRotationAngle(thing); + + if (spriterotangle != 0) { - rollangle = R_GetRollAngle(thing->rollangle); + rollangle = R_GetRollAngle(spriterotangle); if (!(sprframe->rotsprite.cached & (1<sprite, frame, sprinfo, sprframe, rot, flip); rotsprite = sprframe->rotsprite.patch[rot][rollangle]; From 6864705b674cdbd77b28f5ab03fdf0b26cc1dbd4 Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 30 Oct 2020 19:00:37 -0700 Subject: [PATCH 054/143] Fix fuckup --- src/info.c | 2 +- src/k_collide.c | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/info.c b/src/info.c index d8b814841..4782fb0b5 100644 --- a/src/info.c +++ b/src/info.c @@ -22946,7 +22946,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 100, // mass 0, // damage sfx_None, // activesound - MF_SLIDEME|MF_SPECIAL|MF_DONTENCOREMAP, // flags + MF_SLIDEME|MF_DONTENCOREMAP, // flags S_NULL // raisestate }, diff --git a/src/k_collide.c b/src/k_collide.c index 48b20c8a1..79abdfa94 100644 --- a/src/k_collide.c +++ b/src/k_collide.c @@ -409,6 +409,9 @@ boolean K_FloatingItemCollide(mobj_t *t1, mobj_t *t2) { player_t * player = t2->player; + if (t1->health < 1) + return true; + if (! player) return true; @@ -418,8 +421,8 @@ boolean K_FloatingItemCollide(mobj_t *t1, mobj_t *t2) if ((gametyperules & GTR_BUMPERS) && player->bumpers <= 0) return true; - player->kartstuff[k_itemtype] = t2->threshold; - player->kartstuff[k_itemamount] += t2->movecount; + player->kartstuff[k_itemtype] = t1->threshold; + player->kartstuff[k_itemamount] += t1->movecount; if (player->kartstuff[k_itemamount] > 255) player->kartstuff[k_itemamount] = 255; @@ -430,6 +433,7 @@ boolean K_FloatingItemCollide(mobj_t *t1, mobj_t *t2) t1->destscale = mapobjectscale>>4; t1->scalespeed <<= 1; - t1->flags &= ~MF_SPECIAL; + t1->health--; + return false; } From 619402666a92bcb4d5e6496c4a91df67466fa8b5 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Fri, 30 Oct 2020 22:57:42 -0400 Subject: [PATCH 055/143] Better Jawz - More friction in Battle - Throwables take your momz (has been bothering me for an eternity) --- src/k_kart.c | 2 ++ src/p_enemy.c | 2 +- src/p_mobj.c | 7 +++---- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index bbdc62e82..67859e077 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -2889,8 +2889,10 @@ static mobj_t *K_SpawnKartMissile(mobj_t *source, mobjtype_t type, angle_t an, I } th->angle = an; + th->momx = FixedMul(finalspeed, FINECOSINE(an>>ANGLETOFINESHIFT)); th->momy = FixedMul(finalspeed, FINESINE(an>>ANGLETOFINESHIFT)); + th->momz = source->momz; switch (type) { diff --git a/src/p_enemy.c b/src/p_enemy.c index 630e3b29e..790144caa 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -8676,7 +8676,7 @@ void A_JawzChase(mobj_t *actor) angle_t angledelta = actor->angle - targetangle; boolean turnclockwise = true; - if ((gametyperules & GTR_CIRCUIT)) + if (gametyperules & GTR_CIRCUIT) { const fixed_t distbarrier = FixedMul(512*mapobjectscale, FRACUNIT + ((gamespeed-1) * (FRACUNIT/4))); const fixed_t distaway = P_AproxDistance(actor->tracer->x - actor->x, actor->tracer->y - actor->y); diff --git a/src/p_mobj.c b/src/p_mobj.c index e13e9f428..1b53f8072 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1166,10 +1166,6 @@ fixed_t P_GetMobjGravity(mobj_t *mo) case MT_SINK: if (mo->extravalue2 > 0) gravityadd *= mo->extravalue2; - /* FALLTHRU */ - case MT_ORBINAUT: - case MT_JAWZ: - case MT_JAWZ_DUD: gravityadd = (5*gravityadd)/2; break; case MT_KARMAFIREWORK: @@ -6184,6 +6180,9 @@ static boolean P_MobjRegularThink(mobj_t *mobj) if (P_MobjTouchingSectorSpecial(mobj, 3, 1, true)) K_DoPogoSpring(mobj, 0, 1); + if (!(gametyperules & GTR_CIRCUIT)) + mobj->friction = max(0, 3 * mobj->friction / 4); + break; } case MT_JAWZ_DUD: From 84f027d24425495ec3c56c20b0c9b704d4ba6294 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Fri, 30 Oct 2020 23:09:29 -0400 Subject: [PATCH 056/143] Item table changes - Mine: 4 -> 6 - Thunder Shield: 0 -> 4 - Bubble Shield: 0 -> 1 - Sneaker x3: 0 -> 1 - Banana x10: 0 -> 1 2 of the 3 shields added, included some items that normally only appeared for Karma items, and makes Mines much more common --- src/k_kart.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 67859e077..06c963db1 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -316,22 +316,22 @@ static INT32 K_KartItemOddsBattle[NUMKARTRESULTS][2] = /*Eggman Monitor*/ { 1, 0 }, // Eggman Monitor /*Orbinaut*/ { 8, 0 }, // Orbinaut /*Jawz*/ { 8, 1 }, // Jawz - /*Mine*/ { 4, 1 }, // Mine + /*Mine*/ { 6, 1 }, // Mine /*Ballhog*/ { 2, 1 }, // Ballhog /*Self-Propelled Bomb*/ { 0, 0 }, // Self-Propelled Bomb /*Grow*/ { 2, 1 }, // Grow /*Shrink*/ { 0, 0 }, // Shrink - /*Thunder Shield*/ { 0, 0 }, // Thunder Shield - /*Bubble Shield*/ { 0, 0 }, // Bubble Shield + /*Thunder Shield*/ { 4, 0 }, // Thunder Shield + /*Bubble Shield*/ { 1, 0 }, // Bubble Shield /*Flame Shield*/ { 0, 0 }, // Flame Shield /*Hyudoro*/ { 2, 0 }, // Hyudoro /*Pogo Spring*/ { 2, 0 }, // Pogo Spring /*Super Ring*/ { 0, 0 }, // Super Ring /*Kitchen Sink*/ { 0, 0 }, // Kitchen Sink /*Sneaker x2*/ { 0, 0 }, // Sneaker x2 - /*Sneaker x3*/ { 0, 1 }, // Sneaker x3 + /*Sneaker x3*/ { 1, 1 }, // Sneaker x3 /*Banana x3*/ { 1, 0 }, // Banana x3 - /*Banana x10*/ { 0, 1 }, // Banana x10 + /*Banana x10*/ { 1, 1 }, // Banana x10 /*Orbinaut x3*/ { 2, 0 }, // Orbinaut x3 /*Orbinaut x4*/ { 1, 1 }, // Orbinaut x4 /*Jawz x2*/ { 2, 1 } // Jawz x2 From 4bdd3c809fb99b682986e9114033959752e31923 Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 30 Oct 2020 20:54:21 -0700 Subject: [PATCH 057/143] Major brother moment --- src/p_map.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index bea4849dd..0b8c7f577 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -973,9 +973,9 @@ static boolean PIT_CheckThing(mobj_t *thing) if (tmthing->type == MT_FLOATINGITEM) { // see if it went over / under - if (tmthing->z > thing->z + thing->height) + if (tmthing->z - tmthing->height > thing->z + thing->height) return true; // overhead - if (tmthing->z + tmthing->height < thing->z - thing->height) // extended hitbox + if (tmthing->z + tmthing->height < thing->z) // extended hitbox return true; // underneath return K_FloatingItemCollide(tmthing, thing); From 46b1b6db1c28bb084e93765bf993c41172c9ac7d Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 30 Oct 2020 21:09:36 -0700 Subject: [PATCH 058/143] Double paper item height --- src/info.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/info.c b/src/info.c index 4782fb0b5..1b62c7501 100644 --- a/src/info.c +++ b/src/info.c @@ -22941,7 +22941,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_itpick, // deathsound 0, // speed 48*FRACUNIT, // radius - 32*FRACUNIT, // height + 64*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage From 76e0102b3f7b531952e5255046ca9bc386ccb936 Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 30 Oct 2020 21:13:36 -0700 Subject: [PATCH 059/143] Fix paper items not being removed after shrunk --- src/k_collide.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/k_collide.c b/src/k_collide.c index 79abdfa94..282fa0072 100644 --- a/src/k_collide.c +++ b/src/k_collide.c @@ -409,7 +409,7 @@ boolean K_FloatingItemCollide(mobj_t *t1, mobj_t *t2) { player_t * player = t2->player; - if (t1->health < 1) + if (t1->flags2 & MF2_NIGHTSPULL) return true; if (! player) @@ -433,7 +433,5 @@ boolean K_FloatingItemCollide(mobj_t *t1, mobj_t *t2) t1->destscale = mapobjectscale>>4; t1->scalespeed <<= 1; - t1->health--; - return false; } From 91ed67bece1e8dfd7123bf28d775a1bf42111f71 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sun, 1 Nov 2020 23:44:54 -0500 Subject: [PATCH 060/143] Start on Chaos Emeralds Functional! However, you don't drop them yet. --- src/dehacked.c | 47 ++++----- src/doomstat.h | 35 +++++-- src/f_finale.c | 4 +- src/info.c | 241 ++++++---------------------------------------- src/info.h | 31 +++--- src/k_battle.c | 123 ++++++++++++++++++++--- src/k_battle.h | 1 + src/lua_mathlib.c | 4 +- src/m_cheat.c | 8 +- src/m_menu.c | 2 +- src/p_inter.c | 37 ++++++- src/p_mobj.c | 9 +- src/p_mobj.h | 1 - src/p_spec.c | 2 +- 14 files changed, 260 insertions(+), 285 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 73fb81f6c..cbff0adce 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -6269,13 +6269,13 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_EMBLEM26", // Chaos Emeralds - "S_CEMG1", - "S_CEMG2", - "S_CEMG3", - "S_CEMG4", - "S_CEMG5", - "S_CEMG6", - "S_CEMG7", + "S_EMERALD_CHAOS1", + "S_EMERALD_CHAOS2", + "S_EMERALD_CHAOS3", + "S_EMERALD_CHAOS4", + "S_EMERALD_CHAOS5", + "S_EMERALD_CHAOS6", + "S_EMERALD_CHAOS7", // Emerald hunt shards "S_SHRD1", @@ -9499,16 +9499,9 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_REDFLAG", // Red CTF Flag "MT_BLUEFLAG", // Blue CTF Flag "MT_EMBLEM", - "MT_EMERALD1", - "MT_EMERALD2", - "MT_EMERALD3", - "MT_EMERALD4", - "MT_EMERALD5", - "MT_EMERALD6", - "MT_EMERALD7", + "MT_EMERALD", "MT_EMERHUNT", // Emerald Hunt "MT_EMERALDSPAWN", // Emerald spawner w/ delay - "MT_FLINGEMERALD", // Lost emerald // Springs and others "MT_FAN", @@ -11204,13 +11197,23 @@ struct { {"LF2_VISITNEEDED",LF2_VISITNEEDED}, // Emeralds - {"EMERALD1",EMERALD1}, - {"EMERALD2",EMERALD2}, - {"EMERALD3",EMERALD3}, - {"EMERALD4",EMERALD4}, - {"EMERALD5",EMERALD5}, - {"EMERALD6",EMERALD6}, - {"EMERALD7",EMERALD7}, + {"EMERALD_CHAOS1",EMERALD_CHAOS1}, + {"EMERALD_CHAOS2",EMERALD_CHAOS2}, + {"EMERALD_CHAOS3",EMERALD_CHAOS3}, + {"EMERALD_CHAOS4",EMERALD_CHAOS4}, + {"EMERALD_CHAOS5",EMERALD_CHAOS5}, + {"EMERALD_CHAOS6",EMERALD_CHAOS6}, + {"EMERALD_CHAOS7",EMERALD_CHAOS7}, + {"EMERALD_ALLCHAOS",EMERALD_ALLCHAOS}, + {"EMERALD_SUPER1",EMERALD_SUPER1}, + {"EMERALD_SUPER2",EMERALD_SUPER2}, + {"EMERALD_SUPER3",EMERALD_SUPER3}, + {"EMERALD_SUPER4",EMERALD_SUPER4}, + {"EMERALD_SUPER5",EMERALD_SUPER5}, + {"EMERALD_SUPER6",EMERALD_SUPER6}, + {"EMERALD_SUPER7",EMERALD_SUPER7}, + {"EMERALD_ALLSUPER",EMERALD_ALLSUPER}, + {"EMERALD_ALL",EMERALD_ALL}, // SKINCOLOR_ doesn't include these..! {"MAXSKINCOLORS",MAXSKINCOLORS}, diff --git a/src/doomstat.h b/src/doomstat.h index 57738aaa2..2df6caeb5 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -522,15 +522,34 @@ extern UINT32 matchesplayed; extern UINT8 stagefailed; // Emeralds stored as bits to throw savegame hackers off. +typedef enum +{ + EMERALD_CHAOS1 = 1, + EMERALD_CHAOS2 = 1<<1, + EMERALD_CHAOS3 = 1<<2, + EMERALD_CHAOS4 = 1<<3, + EMERALD_CHAOS5 = 1<<4, + EMERALD_CHAOS6 = 1<<5, + EMERALD_CHAOS7 = 1<<6, + EMERALD_ALLCHAOS = EMERALD_CHAOS1|EMERALD_CHAOS2|EMERALD_CHAOS3|EMERALD_CHAOS4|EMERALD_CHAOS5|EMERALD_CHAOS6|EMERALD_CHAOS7, + + EMERALD_SUPER1 = 1<<7, + EMERALD_SUPER2 = 1<<8, + EMERALD_SUPER3 = 1<<9, + EMERALD_SUPER4 = 1<<10, + EMERALD_SUPER5 = 1<<11, + EMERALD_SUPER6 = 1<<12, + EMERALD_SUPER7 = 1<<13, + EMERALD_ALLSUPER = EMERALD_SUPER1|EMERALD_SUPER2|EMERALD_SUPER3|EMERALD_SUPER4|EMERALD_SUPER5|EMERALD_SUPER6|EMERALD_SUPER7, + + EMERALD_ALL = EMERALD_ALLCHAOS|EMERALD_ALLSUPER +} emeraldflags_t; + extern UINT16 emeralds; -#define EMERALD1 1 -#define EMERALD2 2 -#define EMERALD3 4 -#define EMERALD4 8 -#define EMERALD5 16 -#define EMERALD6 32 -#define EMERALD7 64 -#define ALL7EMERALDS(v) ((v & (EMERALD1|EMERALD2|EMERALD3|EMERALD4|EMERALD5|EMERALD6|EMERALD7)) == (EMERALD1|EMERALD2|EMERALD3|EMERALD4|EMERALD5|EMERALD6|EMERALD7)) + +#define ALLCHAOSEMERALDS(v) ((v & EMERALD_ALLCHAOS) == EMERALD_ALLCHAOS) +#define ALLSUPEREMERALDS(v) ((v & EMERALD_ALLSUPER) == EMERALD_ALLSUPER) +#define ALLEMERALDS(v) ((v & EMERALD_ALL) == EMERALD_ALL) #define NUM_LUABANKS 16 // please only make this number go up between versions, never down. you'll break saves otherwise. also, must fit in UINT8 extern INT32 luabanks[NUM_LUABANKS]; diff --git a/src/f_finale.c b/src/f_finale.c index 4355cf231..0d290330c 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -889,7 +889,7 @@ void F_StartGameEvaluation(void) // Just in case they're open ... somehow M_ClearMenus(true); - goodending = (ALL7EMERALDS(emeralds)); + goodending = (ALLCHAOSEMERALDS(emeralds)); gameaction = ga_nothing; paused = false; @@ -1154,7 +1154,7 @@ static void F_CacheEnding(void) endescp[4] = W_CachePatchName("ENDESCP4", PU_PATCH); // so we only need to check once - if ((goodending = ALL7EMERALDS(emeralds))) + if ((goodending = ALLCHAOSEMERALDS(emeralds))) { endfwrk[0] = W_CachePatchName("ENDFWRK3", PU_PATCH); endfwrk[1] = W_CachePatchName("ENDFWRK4", PU_PATCH); diff --git a/src/info.c b/src/info.c index 1b62c7501..6cf3335b2 100644 --- a/src/info.c +++ b/src/info.c @@ -139,7 +139,13 @@ char sprnames[NUMSPRITES + 1][5] = "NCHP", // NiGHTS chip "NSTR", // NiGHTS star "EMBM", // Emblem - "CEMG", // Chaos Emeralds + "EMC1", // Chaos Emeralds + "EMC2", + "EMC3", + "EMC4", + "EMC5", + "EMC6", + "EMC7", "SHRD", // Emerald Hunt // Interactive Objects @@ -1896,13 +1902,13 @@ state_t states[NUMSTATES] = {SPR_EMBM, 25, -1, {NULL}, 0, 0, S_NULL}, // S_EMBLEM26 // Chaos Emeralds - {SPR_CEMG, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_CEMG1 - {SPR_CEMG, FF_FULLBRIGHT|1, -1, {NULL}, 0, 0, S_NULL}, // S_CEMG2 - {SPR_CEMG, FF_FULLBRIGHT|2, -1, {NULL}, 0, 0, S_NULL}, // S_CEMG3 - {SPR_CEMG, FF_FULLBRIGHT|3, -1, {NULL}, 0, 0, S_NULL}, // S_CEMG4 - {SPR_CEMG, FF_FULLBRIGHT|4, -1, {NULL}, 0, 0, S_NULL}, // S_CEMG5 - {SPR_CEMG, FF_FULLBRIGHT|5, -1, {NULL}, 0, 0, S_NULL}, // S_CEMG6 - {SPR_CEMG, FF_FULLBRIGHT|6, -1, {NULL}, 0, 0, S_NULL}, // S_CEMG7 + {SPR_EMC1, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_EMERALD_CHAOS1 + {SPR_EMC2, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_EMERALD_CHAOS2 + {SPR_EMC3, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_EMERALD_CHAOS3 + {SPR_EMC4, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_EMERALD_CHAOS4 + {SPR_EMC5, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_EMERALD_CHAOS5 + {SPR_EMC6, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_EMERALD_CHAOS6 + {SPR_EMC7, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_EMERALD_CHAOS7 // Emerald hunt shards {SPR_SHRD, 0, -1, {NULL}, 0, 0, S_NULL}, // S_SHRD1 @@ -3746,14 +3752,14 @@ state_t states[NUMSTATES] = {SPR_CAPS, 0, -1, {NULL}, 0, 0, S_NULL}, // S_EGGCAPSULE // Orbiting Chaos Emeralds/Ideya for NiGHTS - {SPR_CEMG, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM1}, // S_ORBITEM1 - {SPR_CEMG, FF_FULLBRIGHT|1, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM2}, // S_ORBITEM2 - {SPR_CEMG, FF_FULLBRIGHT|2, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM3}, // S_ORBITEM3 - {SPR_CEMG, FF_FULLBRIGHT|3, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM4}, // S_ORBITEM4 - {SPR_CEMG, FF_FULLBRIGHT|4, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM5}, // S_ORBITEM5 - {SPR_CEMG, FF_FULLBRIGHT|5, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM6}, // S_ORBITEM6 - {SPR_CEMG, FF_FULLBRIGHT|6, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM7}, // S_ORBITEM7 - {SPR_CEMG, FF_FULLBRIGHT|7, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM8}, // S_ORBITEM8 + {SPR_EMC1, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM1}, // S_ORBITEM1 + {SPR_EMC2, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM2}, // S_ORBITEM2 + {SPR_EMC3, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM3}, // S_ORBITEM3 + {SPR_EMC4, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM4}, // S_ORBITEM4 + {SPR_EMC5, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM5}, // S_ORBITEM5 + {SPR_EMC6, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM6}, // S_ORBITEM6 + {SPR_EMC7, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM7}, // S_ORBITEM7 + {SPR_EMC1, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM8}, // S_ORBITEM8 {SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBIDYA1}, // S_ORBIDYA1 {SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT|1, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBIDYA2}, // S_ORBIDYA2 {SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT|2, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBIDYA3}, // S_ORBIDYA3 @@ -8197,9 +8203,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_EMERALD1 - 313, // doomednum - S_CEMG1, // spawnstate + { // MT_EMERALD + -1, // doomednum + S_EMERALD_CHAOS1, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -8210,173 +8216,17 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_SPRK1, // deathstate + S_NULL, // deathstate S_NULL, // xdeathstate - sfx_cgot, // deathsound - EMERALD1, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + sfx_s3k2b, // deathsound + 0, // speed + 72*FRACUNIT, // radius + 72*FRACUNIT, // height 0, // display offset 16, // mass 0, // damage sfx_None, // activesound - MF_NOGRAVITY|MF_SPECIAL, // flags - S_NULL // raisestate - }, - { // MT_EMERALD2 - 314, // doomednum - S_CEMG2, // 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_SPRK1, // deathstate - S_NULL, // xdeathstate - sfx_cgot, // deathsound - EMERALD2, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height - 0, // display offset - 16, // mass - 0, // damage - sfx_None, // activesound - MF_NOGRAVITY|MF_SPECIAL, // flags - S_NULL // raisestate - }, - { // MT_EMERALD3 - 315, // doomednum - S_CEMG3, // 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_SPRK1, // deathstate - S_NULL, // xdeathstate - sfx_cgot, // deathsound - EMERALD3, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height - 0, // display offset - 16, // mass - 0, // damage - sfx_None, // activesound - MF_NOGRAVITY|MF_SPECIAL, // flags - S_NULL // raisestate - }, - { // MT_EMERALD4 - 316, // doomednum - S_CEMG4, // 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_SPRK1, // deathstate - S_NULL, // xdeathstate - sfx_cgot, // deathsound - EMERALD4, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height - 0, // display offset - 16, // mass - 0, // damage - sfx_None, // activesound - MF_NOGRAVITY|MF_SPECIAL, // flags - S_NULL // raisestate - }, - { // MT_EMERALD5 - 317, // doomednum - S_CEMG5, // 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_SPRK1, // deathstate - S_NULL, // xdeathstate - sfx_cgot, // deathsound - EMERALD5, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height - 0, // display offset - 16, // mass - 0, // damage - sfx_None, // activesound - MF_NOGRAVITY|MF_SPECIAL, // flags - S_NULL // raisestate - }, - { // MT_EMERALD6 - 318, // doomednum - S_CEMG6, // 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_SPRK1, // deathstate - S_NULL, // xdeathstate - sfx_cgot, // deathsound - EMERALD6, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height - 0, // display offset - 16, // mass - 0, // damage - sfx_None, // activesound - MF_NOGRAVITY|MF_SPECIAL, // flags - S_NULL // raisestate - }, - { // MT_EMERALD7 - 319, // doomednum - S_CEMG7, // 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_SPRK1, // deathstate - S_NULL, // xdeathstate - sfx_cgot, // deathsound - EMERALD7, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height - 0, // display offset - 16, // mass - 0, // damage - sfx_None, // activesound - MF_NOGRAVITY|MF_SPECIAL, // flags + MF_SPECIAL, // flags S_NULL // raisestate }, @@ -8434,33 +8284,6 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_FLINGEMERALD - -1, // doomednum - S_CEMG1, // spawnstate - 1000, // spawnhealth - S_NULL, // seestate - sfx_None, // seesound - 0, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate - 0, // painchance - sfx_None, // painsound - S_NULL, // meleestate - S_NULL, // missilestate - S_SPRK1, // deathstate - S_NULL, // xdeathstate - sfx_cgot, // deathsound - 60*FRACUNIT, // speed - 16*FRACUNIT, // radius - 48*FRACUNIT, // height - 0, // display offset - 100, // mass - 0, // damage - sfx_None, // activesound - MF_SLIDEME|MF_SPECIAL, // flags - S_NULL // raisestate - }, - { // MT_FAN 540, // doomednum S_FAN, // spawnstate @@ -19105,7 +18928,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = { // MT_GOTEMERALD -1, // doomednum - S_CEMG1, // spawnstate + S_EMERALD_CHAOS1, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound diff --git a/src/info.h b/src/info.h index e7d21744e..bb8e067be 100644 --- a/src/info.h +++ b/src/info.h @@ -410,7 +410,13 @@ typedef enum sprite SPR_NCHP, // NiGHTS chip SPR_NSTR, // NiGHTS star SPR_EMBM, // Emblem - SPR_CEMG, // Chaos Emeralds + SPR_EMC1, // Chaos Emeralds + SPR_EMC2, + SPR_EMC3, + SPR_EMC4, + SPR_EMC5, + SPR_EMC6, + SPR_EMC7, SPR_SHRD, // Emerald Hunt // Interactive Objects @@ -2111,13 +2117,13 @@ typedef enum state S_EMBLEM26, // Chaos Emeralds - S_CEMG1, - S_CEMG2, - S_CEMG3, - S_CEMG4, - S_CEMG5, - S_CEMG6, - S_CEMG7, + S_EMERALD_CHAOS1, + S_EMERALD_CHAOS2, + S_EMERALD_CHAOS3, + S_EMERALD_CHAOS4, + S_EMERALD_CHAOS5, + S_EMERALD_CHAOS6, + S_EMERALD_CHAOS7, // Emerald hunt shards S_SHRD1, @@ -5381,16 +5387,9 @@ typedef enum mobj_type MT_REDFLAG, // Red CTF Flag MT_BLUEFLAG, // Blue CTF Flag MT_EMBLEM, - MT_EMERALD1, - MT_EMERALD2, - MT_EMERALD3, - MT_EMERALD4, - MT_EMERALD5, - MT_EMERALD6, - MT_EMERALD7, + MT_EMERALD, MT_EMERHUNT, // Emerald Hunt MT_EMERALDSPAWN, // Emerald spawner w/ delay - MT_FLINGEMERALD, // Lost emerald // Springs and others MT_FAN, diff --git a/src/k_battle.c b/src/k_battle.c index 4c13cd9cf..6d73df2eb 100644 --- a/src/k_battle.c +++ b/src/k_battle.c @@ -277,24 +277,85 @@ void K_CheckBumpers(void) P_DoPlayerExit(&players[i]); } +mobj_t *K_SpawnChaosEmerald(mobj_t *parent, angle_t angle, SINT8 flip, UINT32 emeraldType) +{ + boolean validEmerald = true; + mobj_t *emerald = P_SpawnMobjFromMobj(parent, 0, 0, 0, MT_EMERALD); + + emerald->angle = angle; + + P_Thrust(emerald, + FixedAngle(P_RandomFixed() * 180) + angle, + 16*mapobjectscale); + + emerald->momz = flip * 3 * mapobjectscale; + if (emerald->eflags & MFE_UNDERWATER) + emerald->momz = (117 * emerald->momz) / 200; + + emerald->threshold = 10; + + switch (emeraldType) + { + case EMERALD_CHAOS1: + P_SetMobjState(emerald, S_EMERALD_CHAOS1); + break; + case EMERALD_CHAOS2: + P_SetMobjState(emerald, S_EMERALD_CHAOS2); + break; + case EMERALD_CHAOS3: + P_SetMobjState(emerald, S_EMERALD_CHAOS3); + break; + case EMERALD_CHAOS4: + P_SetMobjState(emerald, S_EMERALD_CHAOS4); + break; + case EMERALD_CHAOS5: + P_SetMobjState(emerald, S_EMERALD_CHAOS5); + break; + case EMERALD_CHAOS6: + P_SetMobjState(emerald, S_EMERALD_CHAOS6); + break; + case EMERALD_CHAOS7: + P_SetMobjState(emerald, S_EMERALD_CHAOS7); + break; + default: + CONS_Printf("Invalid emerald type %d\n", emeraldType); + validEmerald = false; + break; + } + + if (validEmerald == true) + { + emerald->extravalue1 = emeraldType; + } + + return emerald; +} + void K_RunPaperItemSpawners(void) { const boolean overtime = (battleovertime.enabled >= 10*TICRATE); tic_t interval = 8*TICRATE; + UINT32 emeraldsSpawned = 0; if (leveltime < starttime) { + // Round hasn't started yet! return; } if ((battleovertime.enabled > 0) && (battleovertime.radius < 256*mapobjectscale)) { + // Barrier has closed in too much return; } if (overtime == true) { + // Double frequency of items interval /= 2; + + // Even if this isn't true, we pretend it is, because it's too late to do anything about it :p + emeraldsSpawned = EMERALD_ALLCHAOS; } if (((leveltime - starttime) % interval) != 0) @@ -315,18 +376,19 @@ void K_RunPaperItemSpawners(void) else { UINT8 pcount = 0; - UINT8 i; + INT16 i; for (i = 0; i < MAXPLAYERS; i++) { - if (!playeringame[i] || players[i].spectator - || players[i].exiting > 0 - || players[i].eliminated) + if (!playeringame[i] || players[i].spectator) { continue; } - if ((gametyperules & GTR_BUMPERS) && players[i].bumpers <= 0) + emeraldsSpawned |= players[i].powers[pw_emeralds]; + + if ((players[i].exiting > 0 || players[i].eliminated) + || ((gametyperules & GTR_BUMPERS) && players[i].bumpers <= 0)) { continue; } @@ -337,10 +399,13 @@ void K_RunPaperItemSpawners(void) if (pcount > 0) { #define MAXITEM 64 - UINT16 item = 0; + UINT8 item = 0; mobj_t *spotList[MAXITEM]; boolean spotUsed[MAXITEM]; + UINT32 firstUnspawnedEmerald = 0; + INT16 starti = 0; + thinker_t *th; mobj_t *mo; @@ -348,9 +413,6 @@ void K_RunPaperItemSpawners(void) for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (item >= MAXITEM) - break; - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) continue; @@ -358,9 +420,16 @@ void K_RunPaperItemSpawners(void) if (mo->type == MT_PAPERITEMSPOT) { + if (item >= MAXITEM) + continue; + spotList[item] = mo; item++; } + else if (mo->type == MT_EMERALD) + { + emeraldsSpawned |= mo->extravalue1; + } } if (item <= 0) @@ -368,7 +437,19 @@ void K_RunPaperItemSpawners(void) return; } - for (i = 0; i < min(item, pcount); i++) + for (i = 0; i < 7; i++) + { + UINT32 emeraldFlag = (1 << i); + + if (!(emeraldsSpawned & emeraldFlag)) + { + firstUnspawnedEmerald = emeraldFlag; + starti = -1; + break; + } + } + + for (i = starti; i < min(item, pcount); i++) { UINT8 r = P_RandomRange(0, item-1); UINT8 recursion = 0; @@ -387,11 +468,23 @@ void K_RunPaperItemSpawners(void) flip = P_MobjFlip(spotList[r]); - drop = K_CreatePaperItem( - spotList[r]->x, spotList[r]->y, spotList[r]->z + (128 * mapobjectscale * flip), - FixedAngle(P_RandomRange(0, 359) * FRACUNIT), flip, - 0, 0 - ); + // When -1, we're spawning a Chaos Emerald. + if (i == -1) + { + drop = K_SpawnChaosEmerald( + spotList[r], + FixedAngle(P_RandomRange(0, 359) * FRACUNIT), flip, + firstUnspawnedEmerald + ); + } + else + { + drop = K_CreatePaperItem( + spotList[r]->x, spotList[r]->y, spotList[r]->z + (128 * mapobjectscale * flip), + FixedAngle(P_RandomRange(0, 359) * FRACUNIT), flip, + 0, 0 + ); + } K_FlipFromObject(drop, spotList[r]); spotUsed[r] = true; diff --git a/src/k_battle.h b/src/k_battle.h index 90ee20df7..346e57c48 100644 --- a/src/k_battle.h +++ b/src/k_battle.h @@ -20,6 +20,7 @@ boolean K_IsPlayerWanted(player_t *player); void K_CalculateBattleWanted(void); void K_SpawnBattlePoints(player_t *source, player_t *victim, UINT8 amount); void K_CheckBumpers(void); +mobj_t *K_SpawnChaosEmerald(mobj_t *parent, angle_t angle, SINT8 flip, UINT32 emeraldType); void K_RunPaperItemSpawners(void); void K_RunBattleOvertime(void); void K_SetupMovingCapsule(mapthing_t *mt, mobj_t *mobj); diff --git a/src/lua_mathlib.c b/src/lua_mathlib.c index c6c07fc7e..621f421ea 100644 --- a/src/lua_mathlib.c +++ b/src/lua_mathlib.c @@ -14,7 +14,7 @@ //#include "fastcmp.h" #include "tables.h" #include "p_local.h" -#include "doomstat.h" // for ALL7EMERALDS +#include "doomstat.h" // for ALLCHAOSEMERALDS #include "lua_script.h" #include "lua_libs.h" @@ -162,7 +162,7 @@ static int lib_getsecspecial(lua_State *L) static int lib_all7emeralds(lua_State *L) { - lua_pushboolean(L, ALL7EMERALDS(luaL_checkinteger(L, 1))); + lua_pushboolean(L, ALLCHAOSEMERALDS(luaL_checkinteger(L, 1))); return 1; } diff --git a/src/m_cheat.c b/src/m_cheat.c index ff5f86968..0f39bb643 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -771,12 +771,13 @@ void Command_Savecheckpoint_f(void) } // Like M_GetAllEmeralds() but for console devmode junkies. -/*void Command_Getallemeralds_f(void) +/* +void Command_Getallemeralds_f(void) { REQUIRE_SINGLEPLAYER; REQUIRE_PANDORA; - emeralds = ((EMERALD7)*2)-1; + emeralds = EMERALD_ALL; CONS_Printf(M_GetText("You now have all 7 emeralds.\n")); } @@ -788,7 +789,8 @@ void Command_Resetemeralds_f(void) emeralds = 0; CONS_Printf(M_GetText("Emeralds reset to zero.\n")); -}*/ +} +*/ void Command_Devmode_f(void) { diff --git a/src/m_menu.c b/src/m_menu.c index 7f6f542c6..dcd46b238 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -6374,7 +6374,7 @@ static void M_GetAllEmeralds(INT32 choice) { (void)choice; - emeralds = ((EMERALD7)*2)-1; + emeralds = EMERALD_ALL; M_StartMessage(M_GetText("You now have all 7 emeralds.\nUse them wisely.\nWith great power comes great ring drain.\n"),NULL,MM_NOTHING); G_SetGameModified(multiplayer, true); diff --git a/src/p_inter.c b/src/p_inter.c index 08bd29fdf..2b91278df 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -231,7 +231,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) P_SetObjectMomZ(player->mo, 12<mo, player->mo->angle, 20<mo, special, special->target, 1, DMG_NORMAL); } return; - /*case MT_EERIEFOG: + case MT_EMERALD: + if (!P_CanPickupItem(player, 0)) + return; + + if (special->threshold > 0) + return; + + player->powers[pw_emeralds] |= special->extravalue1; + + if (ALLCHAOSEMERALDS(player->powers[pw_emeralds])) + { + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i] || players[i].spectator) + { + continue; + } + + if (&players[i] == player) + { + continue; + } + + players[i].bumpers = 0; + } + + K_CheckBumpers(); + } + break; + /* + case MT_EERIEFOG: special->frame &= ~FF_TRANS80; special->frame |= FF_TRANS90; - return;*/ + return; + */ case MT_SMK_MOLE: if (special->target && !P_MobjWasRemoved(special->target)) return; diff --git a/src/p_mobj.c b/src/p_mobj.c index 1b53f8072..cc3bc3a9b 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1130,7 +1130,6 @@ fixed_t P_GetMobjGravity(mobj_t *mo) case MT_FLINGCOIN: case MT_FLINGBLUESPHERE: case MT_FLINGNIGHTSCHIP: - case MT_FLINGEMERALD: case MT_BOUNCERING: case MT_RAILRING: case MT_INFINITYRING: @@ -2082,6 +2081,7 @@ boolean P_ZMovement(mobj_t *mo) case MT_BALLHOG: case MT_SSMINE: case MT_BUBBLESHIELDTRAP: + case MT_EMERALD: // Remove stuff from death pits. if (P_CheckDeathPitCollide(mo)) { @@ -6384,6 +6384,10 @@ static boolean P_MobjRegularThink(mobj_t *mobj) S_StartSound(mobj, sfx_s3k4e); mobj->health--; break; + case MT_EMERALD: + if (mobj->threshold > 0) + mobj->threshold--; + break; case MT_DRIFTEXPLODE: if (!mobj->target || !mobj->target->health) { @@ -8566,7 +8570,7 @@ void P_MobjThinker(mobj_t *mobj) || mobj->type == MT_FLINGCOIN || mobj->type == MT_FLINGBLUESPHERE || mobj->type == MT_FLINGNIGHTSCHIP - || mobj->type == MT_FLINGEMERALD + || mobj->type == MT_EMERALD || mobj->type == MT_BIGTUMBLEWEED || mobj->type == MT_LITTLETUMBLEWEED || mobj->type == MT_CANNONBALLDECOR @@ -8873,6 +8877,7 @@ static void P_DefaultMobjShadowScale(mobj_t *thing) case MT_SINK: case MT_ROCKETSNEAKER: case MT_SPB: + case MT_EMERALD: thing->shadowscale = 3*FRACUNIT/2; break; case MT_BANANA_SHIELD: diff --git a/src/p_mobj.h b/src/p_mobj.h index 6ffa393aa..9cafcefa7 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -530,7 +530,6 @@ boolean P_ZMovement(mobj_t *mo); void P_RingZMovement(mobj_t *mo); boolean P_SceneryZMovement(mobj_t *mo); void P_PlayerZMovement(mobj_t *mo); -void P_EmeraldManager(void); extern INT32 modulothing; diff --git a/src/p_spec.c b/src/p_spec.c index a86c54c07..f95bbd39d 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -1612,7 +1612,7 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller { if (GETSECSPECIAL(caller->special, 2) == 6) { - if (!(ALL7EMERALDS(emeralds))) + if (!(ALLCHAOSEMERALDS(emeralds))) return false; } From a011278dd40f66d862178edb790b826fd947ade4 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sun, 1 Nov 2020 23:46:26 -0500 Subject: [PATCH 061/143] Slight tweaks to item spawn location --- src/k_battle.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/k_battle.c b/src/k_battle.c index 6d73df2eb..d77ab0432 100644 --- a/src/k_battle.c +++ b/src/k_battle.c @@ -449,19 +449,20 @@ void K_RunPaperItemSpawners(void) } } - for (i = starti; i < min(item, pcount); i++) + for (i = starti; i < min(item + starti, pcount); i++) { - UINT8 r = P_RandomRange(0, item-1); + UINT8 r = P_RandomKey(item); UINT8 recursion = 0; mobj_t *drop = NULL; SINT8 flip = 1; while (spotUsed[r] == true) { - r = P_RandomRange(0, item-1); + r = P_RandomKey(item); - if ((recursion++) > 32) + if ((recursion++) > MAXITEM) { + // roll with it anyway I guess break; } } From 961ff69241c32b22d2fc73ea556baf4b48d2f735 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 2 Nov 2020 00:41:41 -0500 Subject: [PATCH 062/143] You can drop Chaos Emeralds --- src/k_battle.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++---- src/k_battle.h | 2 ++ src/p_inter.c | 37 ++++++++++++++++------------------ src/p_mobj.c | 19 ++++++++++++++++-- 4 files changed, 86 insertions(+), 26 deletions(-) diff --git a/src/k_battle.c b/src/k_battle.c index d77ab0432..42343002e 100644 --- a/src/k_battle.c +++ b/src/k_battle.c @@ -277,18 +277,45 @@ void K_CheckBumpers(void) P_DoPlayerExit(&players[i]); } +void K_CheckEmeralds(player_t *player) +{ + UINT8 i; + + if (!ALLCHAOSEMERALDS(player->powers[pw_emeralds])) + { + return; + } + + player->marescore++; // lol + + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i] || players[i].spectator) + { + continue; + } + + if (&players[i] == player) + { + continue; + } + + players[i].bumpers = 0; + } + + K_CheckBumpers(); +} + mobj_t *K_SpawnChaosEmerald(mobj_t *parent, angle_t angle, SINT8 flip, UINT32 emeraldType) { boolean validEmerald = true; mobj_t *emerald = P_SpawnMobjFromMobj(parent, 0, 0, 0, MT_EMERALD); - emerald->angle = angle; - P_Thrust(emerald, FixedAngle(P_RandomFixed() * 180) + angle, - 16*mapobjectscale); + 32 * mapobjectscale); - emerald->momz = flip * 3 * mapobjectscale; + emerald->momz = flip * 24 * mapobjectscale; if (emerald->eflags & MFE_UNDERWATER) emerald->momz = (117 * emerald->momz) / 200; @@ -331,6 +358,25 @@ mobj_t *K_SpawnChaosEmerald(mobj_t *parent, angle_t angle, SINT8 flip, UINT32 em return emerald; } +void K_DropEmeraldsFromPlayer(player_t *player, UINT32 emeraldType) +{ + UINT8 i; + SINT8 flip = P_MobjFlip(player->mo); + + for (i = 0; i < 14; i++) + { + UINT32 emeraldFlag = (1 << i); + + if ((player->powers[pw_emeralds] & emeraldFlag) && (emeraldFlag & emeraldType)) + { + mobj_t *emerald = K_SpawnChaosEmerald(player->mo, player->mo->angle, flip, emeraldFlag); + P_SetTarget(&emerald->target, player->mo); + + player->powers[pw_emeralds] &= ~emeraldFlag; + } + } +} + void K_RunPaperItemSpawners(void) { const boolean overtime = (battleovertime.enabled >= 10*TICRATE); diff --git a/src/k_battle.h b/src/k_battle.h index 346e57c48..c83cd7e04 100644 --- a/src/k_battle.h +++ b/src/k_battle.h @@ -20,7 +20,9 @@ boolean K_IsPlayerWanted(player_t *player); void K_CalculateBattleWanted(void); void K_SpawnBattlePoints(player_t *source, player_t *victim, UINT8 amount); void K_CheckBumpers(void); +void K_CheckEmeralds(player_t *player); mobj_t *K_SpawnChaosEmerald(mobj_t *parent, angle_t angle, SINT8 flip, UINT32 emeraldType); +void K_DropEmeraldsFromPlayer(player_t *player, UINT32 emeraldType); void K_RunPaperItemSpawners(void); void K_RunBattleOvertime(void); void K_SetupMovingCapsule(mapthing_t *mt, mobj_t *mobj); diff --git a/src/p_inter.c b/src/p_inter.c index 2b91278df..e8157543f 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -421,26 +421,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) return; player->powers[pw_emeralds] |= special->extravalue1; - - if (ALLCHAOSEMERALDS(player->powers[pw_emeralds])) - { - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i] || players[i].spectator) - { - continue; - } - - if (&players[i] == player) - { - continue; - } - - players[i].bumpers = 0; - } - - K_CheckBumpers(); - } + K_CheckEmeralds(player); break; /* case MT_EERIEFOG: @@ -1680,6 +1661,8 @@ static boolean P_KillPlayer(player_t *player, UINT8 type) break; } + K_DropEmeraldsFromPlayer(player, player->powers[pw_emeralds]); + player->pflags &= ~PF_SLIDING; player->powers[pw_carry] = CR_NONE; @@ -1909,9 +1892,23 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da { K_PlayHitEmSound(source); K_StealBumper(source->player, player, bumpadd); + + if (damagetype & DMG_STEAL) + { + // Give them ALL of your emeralds :) + source->player->powers[pw_emeralds] |= player->powers[pw_emeralds]; + player->powers[pw_emeralds] = 0; + K_CheckEmeralds(source->player); + } } K_RemoveBumper(player, inflictor, source, bumpadd, false); + + if (!(damagetype & DMG_STEAL)) + { + // Drop all of your emeralds + K_DropEmeraldsFromPlayer(player, player->powers[pw_emeralds]); + } } player->kartstuff[k_sneakertimer] = player->kartstuff[k_numsneakers] = 0; diff --git a/src/p_mobj.c b/src/p_mobj.c index cc3bc3a9b..dd8aef239 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1163,6 +1163,7 @@ fixed_t P_GetMobjGravity(mobj_t *mo) case MT_EGGMANITEM: case MT_SSMINE: case MT_SINK: + case MT_EMERALD: if (mo->extravalue2 > 0) gravityadd *= mo->extravalue2; gravityadd = (5*gravityadd)/2; @@ -2081,7 +2082,6 @@ boolean P_ZMovement(mobj_t *mo) case MT_BALLHOG: case MT_SSMINE: case MT_BUBBLESHIELDTRAP: - case MT_EMERALD: // Remove stuff from death pits. if (P_CheckDeathPitCollide(mo)) { @@ -2089,6 +2089,7 @@ boolean P_ZMovement(mobj_t *mo) return false; } break; + case MT_REDFLAG: case MT_BLUEFLAG: // Remove from death pits. DON'T FUCKING DESPAWN IT DAMMIT @@ -2099,6 +2100,20 @@ boolean P_ZMovement(mobj_t *mo) } break; + case MT_EMERALD: + if (P_CheckDeathPitCollide(mo)) + { + P_RemoveMobj(mo); + return false; + } + + if (mo->z <= mo->floorz || mo->z + mo->height >= mo->ceilingz) + { + // Stop when hitting the floor + mo->momx = mo->momy = 0; + } + break; + case MT_RING: // Ignore still rings case MT_BLUESPHERE: case MT_FLINGRING: @@ -8877,7 +8892,6 @@ static void P_DefaultMobjShadowScale(mobj_t *thing) case MT_SINK: case MT_ROCKETSNEAKER: case MT_SPB: - case MT_EMERALD: thing->shadowscale = 3*FRACUNIT/2; break; case MT_BANANA_SHIELD: @@ -8904,6 +8918,7 @@ static void P_DefaultMobjShadowScale(mobj_t *thing) case MT_RING: case MT_FLOATINGITEM: case MT_BLUESPHERE: + case MT_EMERALD: thing->shadowscale = FRACUNIT/2; break; case MT_DRIFTCLIP: From ea14d6bb1c30a68e376f42297f4168025c1f719e Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 2 Nov 2020 00:51:47 -0500 Subject: [PATCH 063/143] Use Super Emerald collect sound instead for now --- src/info.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/info.c b/src/info.c index 6cf3335b2..8640268b6 100644 --- a/src/info.c +++ b/src/info.c @@ -8218,7 +8218,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate - sfx_s3k2b, // deathsound + sfx_s3k9c, // deathsound 0, // speed 72*FRACUNIT, // radius 72*FRACUNIT, // height From 7bff7931ede317f79e2ef63770219bbff813cf20 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 2 Nov 2020 01:09:14 -0500 Subject: [PATCH 064/143] Sort wanted players by bumpers & emeralds first --- src/k_battle.c | 68 +++++++++++++++++++++++++++++--------------------- src/k_battle.h | 1 + 2 files changed, 40 insertions(+), 29 deletions(-) diff --git a/src/k_battle.c b/src/k_battle.c index 42343002e..29b9333c7 100644 --- a/src/k_battle.c +++ b/src/k_battle.c @@ -58,24 +58,19 @@ boolean K_IsPlayerWanted(player_t *player) void K_CalculateBattleWanted(void) { - UINT8 numingame = 0, numplaying = 0, numwanted = 0; - SINT8 bestbumperplayer = -1, bestbumper = -1; + UINT8 numingame = 0, numwanted = 0; SINT8 camppos[MAXPLAYERS]; // who is the biggest camper UINT8 ties = 0, nextcamppos = 0; - boolean setbumper = false; UINT8 i, j; if (!(gametyperules & GTR_WANTED)) { - for (i = 0; i < 4; i++) - battlewanted[i] = -1; + memset(battlewanted, -1, sizeof (battlewanted)); return; } wantedcalcdelay = wantedfrequency; - - for (i = 0; i < MAXPLAYERS; i++) - camppos[i] = -1; // initialize + memset(camppos, -1, sizeof (camppos)); // initialize for (i = 0; i < MAXPLAYERS; i++) { @@ -87,33 +82,38 @@ void K_CalculateBattleWanted(void) if (players[i].exiting) // We're done, don't calculate. return; - numplaying++; - if (players[i].bumpers <= 0) // Not alive, so don't do anything else continue; numingame++; - if (bestbumper == -1 || players[i].bumpers > bestbumper) - { - bestbumper = players[i].bumpers; - bestbumperplayer = i; - } - else if (players[i].bumpers == bestbumper) - bestbumperplayer = -1; // Tie, no one has best bumper. - for (j = 0; j < MAXPLAYERS; j++) { if (!playeringame[j] || players[j].spectator) continue; + if (players[j].bumpers <= 0) continue; + if (j == i) continue; - if (players[j].kartstuff[k_wanted] == players[i].kartstuff[k_wanted] && players[j].marescore > players[i].marescore) + + if (K_NumEmeralds(&players[j]) > K_NumEmeralds(&players[i])) + { position++; + } + else if (players[j].bumpers > players[i].bumpers) + { + position++; + } + else if (players[j].marescore > players[i].marescore) + { + position++; + } else if (players[j].kartstuff[k_wanted] > players[i].kartstuff[k_wanted]) + { position++; + } } position--; // Make zero based @@ -124,7 +124,7 @@ void K_CalculateBattleWanted(void) camppos[position] = i; } - if (numplaying <= 2 || (numingame <= 2 && bestbumper == 1)) // In 1v1s then there's no need for WANTED. In bigger netgames, don't show anyone as WANTED when they're equally matched. + if (numingame <= 2) // In 1v1s then there's no need for WANTED. numwanted = 0; else numwanted = min(4, 1 + ((numingame-2) / 4)); @@ -132,19 +132,11 @@ void K_CalculateBattleWanted(void) for (i = 0; i < 4; i++) { if (i+1 > numwanted) // Not enough players for this slot to be wanted! - battlewanted[i] = -1; - else if (bestbumperplayer != -1 && !setbumper) // If there's a player who has an untied bumper lead over everyone else, they are the first to be wanted. { - battlewanted[i] = bestbumperplayer; - setbumper = true; // Don't set twice + battlewanted[i] = -1; } else { - // Don't accidentally set the same player, if the bestbumperplayer is also a huge camper. - while (bestbumperplayer != -1 && camppos[nextcamppos] != -1 - && bestbumperplayer == camppos[nextcamppos]) - nextcamppos++; - // Do not add *any* more people if there's too many times that are tied with others. // This could theoretically happen very easily if people don't hit each other for a while after the start of a match. // (I will be sincerely impressed if more than 2 people tie after people start hitting each other though) @@ -377,6 +369,24 @@ void K_DropEmeraldsFromPlayer(player_t *player, UINT32 emeraldType) } } +UINT8 K_NumEmeralds(player_t *player) +{ + UINT8 i; + UINT8 num = 0; + + for (i = 0; i < 14; i++) + { + UINT32 emeraldFlag = (1 << i); + + if (player->powers[pw_emeralds] & emeraldFlag) + { + num++; + } + } + + return num; +} + void K_RunPaperItemSpawners(void) { const boolean overtime = (battleovertime.enabled >= 10*TICRATE); diff --git a/src/k_battle.h b/src/k_battle.h index c83cd7e04..ddd8a5437 100644 --- a/src/k_battle.h +++ b/src/k_battle.h @@ -23,6 +23,7 @@ void K_CheckBumpers(void); void K_CheckEmeralds(player_t *player); mobj_t *K_SpawnChaosEmerald(mobj_t *parent, angle_t angle, SINT8 flip, UINT32 emeraldType); void K_DropEmeraldsFromPlayer(player_t *player, UINT32 emeraldType); +UINT8 K_NumEmeralds(player_t *player); void K_RunPaperItemSpawners(void); void K_RunBattleOvertime(void); void K_SetupMovingCapsule(mapthing_t *mt, mobj_t *mobj); From 56dc08ed88223e06042f92690941ce172fd4b126 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 2 Nov 2020 01:09:38 -0500 Subject: [PATCH 065/143] Shitty temp emeralds hud --- src/k_hud.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/k_hud.c b/src/k_hud.c index ff689f7f2..f6f6cbb47 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -4115,4 +4115,9 @@ void K_drawKartHUD(void) } K_DrawWaypointDebugger(); + + if (gametype == GT_BATTLE) + { + V_DrawString(8, 8, V_SPLITSCREEN|V_SNAPTOTOP|V_SNAPTOLEFT, va("Emeralds: %d / 7", K_NumEmeralds(stplyr))); + } } From 2745ea2938303eaca5c15c5561729ef1531b6cc4 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 2 Nov 2020 01:22:41 -0500 Subject: [PATCH 066/143] Drop emeralds in front of the hurt player, instead of to their left --- src/k_battle.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/k_battle.c b/src/k_battle.c index 29b9333c7..cc12851d4 100644 --- a/src/k_battle.c +++ b/src/k_battle.c @@ -361,7 +361,7 @@ void K_DropEmeraldsFromPlayer(player_t *player, UINT32 emeraldType) if ((player->powers[pw_emeralds] & emeraldFlag) && (emeraldFlag & emeraldType)) { - mobj_t *emerald = K_SpawnChaosEmerald(player->mo, player->mo->angle, flip, emeraldFlag); + mobj_t *emerald = K_SpawnChaosEmerald(player->mo, player->mo->angle - ANGLE_90, flip, emeraldFlag); P_SetTarget(&emerald->target, player->mo); player->powers[pw_emeralds] &= ~emeraldFlag; From 896b29f002fd07099371ff2ec067a0cc4d96e371 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 1 Nov 2020 22:33:42 -0800 Subject: [PATCH 067/143] Replace special handling for picking up items from below with MF_PICKUPFROMBELOW --- src/info.c | 2 +- src/k_collide.c | 31 ------------------------------- src/k_collide.h | 1 - src/p_inter.c | 38 ++++++++++++++++++++++++++++++++++---- src/p_map.c | 21 --------------------- src/p_mobj.h | 2 ++ 6 files changed, 37 insertions(+), 58 deletions(-) diff --git a/src/info.c b/src/info.c index 8640268b6..b7124449b 100644 --- a/src/info.c +++ b/src/info.c @@ -22769,7 +22769,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 100, // mass 0, // damage sfx_None, // activesound - MF_SLIDEME|MF_DONTENCOREMAP, // flags + MF_SLIDEME|MF_SPECIAL|MF_PICKUPFROMBELOW|MF_DONTENCOREMAP, // flags S_NULL // raisestate }, diff --git a/src/k_collide.c b/src/k_collide.c index 282fa0072..963ec4e64 100644 --- a/src/k_collide.c +++ b/src/k_collide.c @@ -404,34 +404,3 @@ boolean K_SMKIceBlockCollide(mobj_t *t1, mobj_t *t2) K_KartBouncing(t2, t1, false, true); return false; } - -boolean K_FloatingItemCollide(mobj_t *t1, mobj_t *t2) -{ - player_t * player = t2->player; - - if (t1->flags2 & MF2_NIGHTSPULL) - return true; - - if (! player) - return true; - - if (!P_CanPickupItem(player, 3) || (player->kartstuff[k_itemamount] && player->kartstuff[k_itemtype] != t1->threshold)) - return true; - - if ((gametyperules & GTR_BUMPERS) && player->bumpers <= 0) - return true; - - player->kartstuff[k_itemtype] = t1->threshold; - player->kartstuff[k_itemamount] += t1->movecount; - if (player->kartstuff[k_itemamount] > 255) - player->kartstuff[k_itemamount] = 255; - - S_StartSound(t1, t1->info->deathsound); - - P_SetTarget(&t1->tracer, t2); - t1->flags2 |= MF2_NIGHTSPULL; - t1->destscale = mapobjectscale>>4; - t1->scalespeed <<= 1; - - return false; -} diff --git a/src/k_collide.h b/src/k_collide.h index fed8969d6..86f643b3f 100644 --- a/src/k_collide.h +++ b/src/k_collide.h @@ -12,6 +12,5 @@ boolean K_MineExplosionCollide(mobj_t *t1, mobj_t *t2); boolean K_KitchenSinkCollide(mobj_t *t1, mobj_t *t2); boolean K_FallingRockCollide(mobj_t *t1, mobj_t *t2); boolean K_SMKIceBlockCollide(mobj_t *t1, mobj_t *t2); -boolean K_FloatingItemCollide(mobj_t *t1, mobj_t *t2); #endif diff --git a/src/p_inter.c b/src/p_inter.c index e8157543f..d990a0bb3 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -182,15 +182,24 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (heightcheck) { + fixed_t toucher_bottom = toucher->z; + fixed_t special_bottom = special->z; + + if (toucher->flags & MF_PICKUPFROMBELOW) + toucher_bottom -= toucher->height; + + if (special->flags & MF_PICKUPFROMBELOW) + special_bottom -= special->height; + if (toucher->momz < 0) { - if (toucher->z + toucher->momz > special->z + special->height) + if (toucher_bottom + toucher->momz > special->z + special->height) return; - } else if (toucher->z > special->z + special->height) + } else if (toucher_bottom > special->z + special->height) return; if (toucher->momz > 0) { - if (toucher->z + toucher->height + toucher->momz < special->z) + if (toucher->z + toucher->height + toucher->momz < special_bottom) return; - } else if (toucher->z + toucher->height < special->z) + } else if (toucher->z + toucher->height < special_bottom) return; } @@ -231,6 +240,27 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) P_SetObjectMomZ(player->mo, 12<mo, player->mo->angle, 20<kartstuff[k_itemamount] && player->kartstuff[k_itemtype] != special->threshold)) + return; + + if ((gametyperules & GTR_BUMPERS) && player->bumpers <= 0) + return; + + player->kartstuff[k_itemtype] = special->threshold; + player->kartstuff[k_itemamount] += special->movecount; + if (player->kartstuff[k_itemamount] > 255) + player->kartstuff[k_itemamount] = 255; + + S_StartSound(special, special->info->deathsound); + + P_SetTarget(&special->tracer, toucher); + special->flags2 |= MF2_NIGHTSPULL; + special->destscale = mapobjectscale>>4; + special->scalespeed <<= 1; + + special->flags &= ~MF_SPECIAL; + return; case MT_RANDOMITEM: if (!P_CanPickupItem(player, 1)) return; diff --git a/src/p_map.c b/src/p_map.c index 0b8c7f577..7a0958f7f 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -970,27 +970,6 @@ static boolean PIT_CheckThing(mobj_t *thing) return K_FallingRockCollide(thing, tmthing); } - if (tmthing->type == MT_FLOATINGITEM) - { - // see if it went over / under - if (tmthing->z - tmthing->height > thing->z + thing->height) - return true; // overhead - if (tmthing->z + tmthing->height < thing->z) // extended hitbox - return true; // underneath - - return K_FloatingItemCollide(tmthing, thing); - } - else if (thing->type == MT_FLOATINGITEM) - { - // see if it went over / under - if (tmthing->z > thing->z + thing->height) - return true; // overhead - if (tmthing->z + tmthing->height < thing->z - thing->height) // extended hitbox - return true; // underneath - - return K_FloatingItemCollide(thing, tmthing); - } - //} if ((thing->type == MT_SPRINGSHELL || thing->type == MT_YELLOWSHELL) && thing->health > 0 diff --git a/src/p_mobj.h b/src/p_mobj.h index 9cafcefa7..5c205a758 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -157,6 +157,8 @@ typedef enum MF_RUNSPAWNFUNC = 1<<27, // Don't remap in Encore mode. (Not a drawflag so that it's settable by mobjinfo.) MF_DONTENCOREMAP = 1<<28, + // Hitbox extends just as far below as above. + MF_PICKUPFROMBELOW = 1<<29, // free: to and including 1<<31 } mobjflag_t; From 6370919e0594a37ceea8b1bf954c8e5d9f61b769 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 1 Nov 2020 22:34:14 -0800 Subject: [PATCH 068/143] Pick up emeralds from below --- src/info.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/info.c b/src/info.c index b7124449b..1b9f58220 100644 --- a/src/info.c +++ b/src/info.c @@ -8226,7 +8226,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 16, // mass 0, // damage sfx_None, // activesound - MF_SPECIAL, // flags + MF_SPECIAL|MF_PICKUPFROMBELOW, // flags S_NULL // raisestate }, From 7304dff3e5dc6605c91234c199ae8f8e3674cdd8 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 2 Nov 2020 02:03:50 -0500 Subject: [PATCH 069/143] Don't let karma players pick anything up --- src/p_inter.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index e8157543f..7ce08cb82 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -108,11 +108,13 @@ void P_RampConstant(const BasicFF_t *FFInfo, INT32 Start, INT32 End) // boolean P_CanPickupItem(player_t *player, UINT8 weapon) { - if (player->exiting || mapreset) + if (player->exiting || mapreset || player->eliminated) return false; - /*if ((gametyperules & GTR_BUMPERS) && player->bumpers <= 0) // No bumpers in Match - return false;*/ +#ifndef OTHERKARMAMODES + if ((gametyperules & GTR_BUMPERS) && player->bumpers <= 0) // No bumpers in Match + return false; +#endif if (weapon) { From 4a9a438270b5138c5ebc4cb43869ec808ae0fc62 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 2 Nov 2020 03:51:16 -0500 Subject: [PATCH 070/143] Dummy out wanted system - Remove WANTED hud item - Person in 1st place is the bonus points giver - Sort players by Emeralds > Bumpers > Points --- src/d_clisrv.c | 4 +--- src/d_netcmd.c | 3 +-- src/k_battle.c | 6 ++++++ src/k_collide.c | 3 +-- src/k_hud.c | 5 ++++- src/k_kart.c | 29 ++++++++++++++++++++--------- 6 files changed, 33 insertions(+), 17 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 0e1d58098..d7f4af80c 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -2992,9 +2992,7 @@ void CL_RemovePlayer(INT32 playernum, kickreason_t reason) } } - if (K_IsPlayerWanted(&players[playernum])) - K_CalculateBattleWanted(); - + K_CalculateBattleWanted(); LUAh_PlayerQuit(&players[playernum], reason); // Lua hook for player quitting // don't look through someone's view who isn't there diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 223430e44..d31e9537e 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -3469,8 +3469,7 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum) if (gametyperules & GTR_BUMPERS) // SRB2kart { players[playernum].marescore = 0; - if (K_IsPlayerWanted(&players[playernum])) - K_CalculateBattleWanted(); + K_CalculateBattleWanted(); } K_PlayerForfeit(playernum, true); diff --git a/src/k_battle.c b/src/k_battle.c index cc12851d4..a9924b1de 100644 --- a/src/k_battle.c +++ b/src/k_battle.c @@ -41,6 +41,9 @@ INT32 K_StartingBumperCount(void) boolean K_IsPlayerWanted(player_t *player) { +#if 1 + return (player->kartstuff[k_position] == 1); +#else UINT8 i; if (!(gametyperules & GTR_WANTED)) @@ -54,6 +57,7 @@ boolean K_IsPlayerWanted(player_t *player) return true; } return false; +#endif } void K_CalculateBattleWanted(void) @@ -63,7 +67,9 @@ void K_CalculateBattleWanted(void) UINT8 ties = 0, nextcamppos = 0; UINT8 i, j; +#if 0 if (!(gametyperules & GTR_WANTED)) +#endif { memset(battlewanted, -1, sizeof (battlewanted)); return; diff --git a/src/k_collide.c b/src/k_collide.c index 963ec4e64..34c0e2b59 100644 --- a/src/k_collide.c +++ b/src/k_collide.c @@ -30,8 +30,7 @@ boolean K_OrbinautJawzCollide(mobj_t *t1, mobj_t *t2) if (t2->player) { - if (t2->player->powers[pw_flashing] - && !(t1->type == MT_ORBINAUT || t1->type == MT_JAWZ || t1->type == MT_JAWZ_DUD)) + if (t2->player->powers[pw_flashing] && (t1->type == MT_ORBINAUT_SHIELD || t1->type == MT_JAWZ_SHIELD)) return true; if (t2->player->kartstuff[k_hyudorotimer]) diff --git a/src/k_hud.c b/src/k_hud.c index f6f6cbb47..63f6b1af5 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -2143,6 +2143,9 @@ static void K_drawKartWanted(void) UINT8 *colormap = NULL; INT32 basex = 0, basey = 0; + if (!splitscreen) + return; + if (stplyr != &players[displayplayers[0]]) return; @@ -4118,6 +4121,6 @@ void K_drawKartHUD(void) if (gametype == GT_BATTLE) { - V_DrawString(8, 8, V_SPLITSCREEN|V_SNAPTOTOP|V_SNAPTOLEFT, va("Emeralds: %d / 7", K_NumEmeralds(stplyr))); + V_DrawRightAlignedString(BASEVIDWIDTH - 10, BASEVIDHEIGHT - 18, V_SPLITSCREEN|V_SNAPTOBOTTOM|V_SNAPTORIGHT, va("Emeralds: %d / 7", K_NumEmeralds(stplyr))); } } diff --git a/src/k_kart.c b/src/k_kart.c index 06c963db1..8bf94a65c 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -2454,9 +2454,7 @@ void K_RemoveBumper(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 a } player->bumpers -= amount; - - if (K_IsPlayerWanted(player)) - K_CalculateBattleWanted(); + K_CalculateBattleWanted(); } if (player->bumpers <= 0) @@ -6793,7 +6791,7 @@ void K_KartUpdatePosition(player_t *player) if (!playeringame[i] || players[i].spectator || !players[i].mo) continue; - if (gametype == GT_RACE) + if (gametyperules & GTR_CIRCUIT) { if (player->exiting) // End of match standings { @@ -6812,7 +6810,7 @@ void K_KartUpdatePosition(player_t *player) } } } - else if (gametype == GT_BATTLE) + else { if (player->exiting) // End of match standings { @@ -6822,11 +6820,24 @@ void K_KartUpdatePosition(player_t *player) } else { - // I have less points than but the same bumpers as this player OR - // I have less bumpers than this player - if ((players[i].bumpers == player->bumpers && players[i].marescore > player->marescore) - || (players[i].bumpers > player->bumpers)) + if (K_NumEmeralds(&players[i]) > K_NumEmeralds(player)) + { position++; + } + else if (players[i].bumpers > player->bumpers) + { + position++; + } + else if (players[i].marescore > player->marescore) + { + position++; + } + /* + else if (players[i].kartstuff[k_wanted] > player->kartstuff[k_wanted]) + { + position++; + } + */ } } } From e478d542a0c3600b9f2a06cf89db61a189e064ab Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 2 Nov 2020 04:23:31 -0500 Subject: [PATCH 071/143] Emeralds are on ranking --- src/k_hud.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/src/k_hud.c b/src/k_hud.c index 63f6b1af5..9b4bf88f7 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -88,6 +88,7 @@ static patch_t *kp_rankbumper; static patch_t *kp_tinybumper[2]; static patch_t *kp_ranknobumpers; static patch_t *kp_rankcapsule; +static patch_t *kp_rankemeralds[7]; static patch_t *kp_battlewin; static patch_t *kp_battlecool; @@ -351,6 +352,13 @@ void K_LoadKartHUDGraphics(void) kp_ranknobumpers = W_CachePatchName("K_NOBLNS", PU_HUDGFX); kp_rankcapsule = W_CachePatchName("K_CAPICO", PU_HUDGFX); + sprintf(buffer, "K_EMERCx"); + for (i = 0; i < 7; i++) + { + buffer[7] = '0'+(i+1); + kp_rankemeralds[i] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX); + } + // Battle graphics kp_battlewin = W_CachePatchName("K_BWIN", PU_HUDGFX); kp_battlecool = W_CachePatchName("K_BCOOL", PU_HUDGFX); @@ -1515,7 +1523,7 @@ static boolean K_drawKartPositionFaces(void) INT32 i, j, ranklines, strank = -1; boolean completed[MAXPLAYERS]; INT32 rankplayer[MAXPLAYERS]; - INT32 bumperx, numplayersingame = 0; + INT32 bumperx, emeraldx, numplayersingame = 0; UINT8 *colormap; ranklines = 0; @@ -1596,6 +1604,7 @@ static boolean K_drawKartPositionFaces(void) if (!players[rankplayer[i]].mo) continue; bumperx = FACE_X+19; + emeraldx = FACE_X+16; if (players[rankplayer[i]].mo->color) { @@ -1609,7 +1618,7 @@ static boolean K_drawKartPositionFaces(void) if (LUA_HudEnabled(hud_battlebumpers)) { - if (gametype == GT_BATTLE && players[rankplayer[i]].bumpers > 0) + if ((gametyperules & GTR_BUMPERS) && players[rankplayer[i]].bumpers > 0) { V_DrawMappedPatch(bumperx-2, Y, V_HUDTRANS|V_SLIDEIN|V_SNAPTOLEFT, kp_tinybumper[0], colormap); for (j = 1; j < players[rankplayer[i]].bumpers; j++) @@ -1618,7 +1627,18 @@ static boolean K_drawKartPositionFaces(void) V_DrawMappedPatch(bumperx, Y, V_HUDTRANS|V_SLIDEIN|V_SNAPTOLEFT, kp_tinybumper[1], colormap); } } - } // A new level of stupidity: checking if lua is enabled to close a bracket. :Fascinating: + } + } + + for (j = 0; j < 7; j++) + { + UINT32 emeraldFlag = (1 << j); + + if (players[rankplayer[i]].powers[pw_emeralds] & emeraldFlag) + { + V_DrawScaledPatch(emeraldx, Y+7, V_HUDTRANS|V_SLIDEIN|V_SNAPTOLEFT, kp_rankemeralds[j]); + emeraldx += 7; + } } if (i == strank) From a19ce98350aa1e12bdc6c44f2d99ffc5750ec4fb Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 2 Nov 2020 05:15:45 -0500 Subject: [PATCH 072/143] Fix positions tying at 2nd place --- src/k_kart.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 8bf94a65c..29dfe1d67 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -6820,24 +6820,30 @@ void K_KartUpdatePosition(player_t *player) } else { - if (K_NumEmeralds(&players[i]) > K_NumEmeralds(player)) + UINT8 myEmeralds = K_NumEmeralds(player); + UINT8 yourEmeralds = K_NumEmeralds(&players[i]); + + if (yourEmeralds > myEmeralds) { + // Emeralds matter above all position++; } - else if (players[i].bumpers > player->bumpers) + else if (yourEmeralds == myEmeralds) { - position++; + // Bumpers are a tie breaker + if (players[i].bumpers > player->bumpers) + { + position++; + } + else if (players[i].bumpers == player->bumpers) + { + // Score is the second tier tie breaker + if (players[i].marescore > player->marescore) + { + position++; + } + } } - else if (players[i].marescore > player->marescore) - { - position++; - } - /* - else if (players[i].kartstuff[k_wanted] > player->kartstuff[k_wanted]) - { - position++; - } - */ } } } From d970747c85979ff3480dfff28271f7b8b4be4736 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 2 Nov 2020 05:19:45 -0500 Subject: [PATCH 073/143] Remove FIN KartZ holdover that Oni never wanted apparently :V --- src/k_hud.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/k_hud.c b/src/k_hud.c index 9b4bf88f7..330bfb8fe 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -1925,11 +1925,7 @@ static void K_drawKartLapsAndRings(void) { // Laps V_DrawScaledPatch(LAPS_X, LAPS_Y, V_HUDTRANS|V_SLIDEIN|splitflags, kp_lapsticker); - - if (stplyr->exiting) - V_DrawKartString(LAPS_X+33, LAPS_Y+3, V_HUDTRANS|V_SLIDEIN|splitflags, "FIN"); - else - V_DrawKartString(LAPS_X+33, LAPS_Y+3, V_HUDTRANS|V_SLIDEIN|splitflags, va("%d/%d", stplyr->laps, cv_numlaps.value)); + V_DrawKartString(LAPS_X+33, LAPS_Y+3, V_HUDTRANS|V_SLIDEIN|splitflags, va("%d/%d", stplyr->laps, cv_numlaps.value)); // Rings if (!uselives) From 3d7a2b8c959fdf03dc4f97b7cd98f96b13f839a2 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 2 Nov 2020 18:10:59 -0500 Subject: [PATCH 074/143] Set cl_packetmissed = true when dropping a packet due to gentlemens This might be dumb enough to work? :) --- src/d_clisrv.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 062cfd535..d857aaa43 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -5487,7 +5487,10 @@ static void CL_SendClientCmd(void) boolean mis = false; if (lowest_lag && ( gametic % lowest_lag )) + { + cl_packetmissed = true; return; + } netbuffer->packettype = PT_CLIENTCMD; From 5d22277aed1575e844173fee083718d78b337271 Mon Sep 17 00:00:00 2001 From: JugadorXEI Date: Tue, 3 Nov 2020 16:41:00 +0100 Subject: [PATCH 075/143] Polyobject and SPB 'lastlook' interaction fix --- src/p_polyobj.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/p_polyobj.c b/src/p_polyobj.c index 60c653b16..cdcf37d9f 100644 --- a/src/p_polyobj.c +++ b/src/p_polyobj.c @@ -1042,6 +1042,10 @@ static void Polyobj_carryThings(polyobj_t *po, fixed_t dx, fixed_t dy) for (; mo; mo = mo->bnext) { + // lastlook is used by the SPB to determine targets, do not let it affect it + if (mo->type == MT_SPB) + continue; + if (mo->lastlook == pomovecount) continue; @@ -1286,6 +1290,10 @@ static void Polyobj_rotateThings(polyobj_t *po, vertex_t origin, angle_t delta, for (; mo; mo = mo->bnext) { + // lastlook is used by the SPB to determine targets, do not let it affect it + if (mo->type == MT_SPB) + continue; + if (mo->lastlook == pomovecount) continue; From 648f1f0958e119978ddaf3d83e57efbdff1d0601 Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 5 Nov 2020 00:20:14 -0800 Subject: [PATCH 076/143] Revert "Do not sort sprite in front of plane if plane should render in front of sprite's plane" This reverts commit 0d6f329b1d9ecf3ba754a5affe80c669c56afc07. --- src/r_things.c | 37 ++----------------------------------- src/r_things.h | 1 - 2 files changed, 2 insertions(+), 36 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index df1946ba6..9702c7d3f 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1230,32 +1230,6 @@ fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope) return groundz; } -static void R_SetSpritePlaneHeights(vissprite_t *vis) -{ - ffloor_t *rover; - - fixed_t top; - fixed_t bot; - - vis->pt = vis->sector->floorheight; - vis->pb = vis->sector->ceilingheight; - - for (rover = vis->sector->ffloors; rover; rover = rover->next) - { - if (rover->flags & FF_EXISTS) - { - top = P_GetFFloorTopZAt (rover, vis->gx, vis->gy); - bot = P_GetFFloorBottomZAt (rover, vis->gx, vis->gy); - - if (top <= vis->gzt && top > vis->pt) - vis->pt = top; - - if (bot >= vis->gz && bot < vis->pb) - vis->pb = bot; - } - } -} - static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale, fixed_t tx, fixed_t tz) { vissprite_t *shadow; @@ -1344,8 +1318,6 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale, shadow->xscale = FixedMul(xscale, shadowxscale); //SoM: 4/17/2000 shadow->scale = FixedMul(yscale, shadowyscale); shadow->sector = vis->sector; - shadow->pt = vis->pt; - shadow->pb = vis->pb; shadow->szt = (INT16)((centeryfrac - FixedMul(shadow->gzt - viewz, yscale))>>FRACBITS); shadow->sz = (INT16)((centeryfrac - FixedMul(shadow->gz - viewz, yscale))>>FRACBITS); shadow->cut = SC_ISSCALED|SC_SHADOW; //check this @@ -1845,9 +1817,6 @@ static void R_ProjectSprite(mobj_t *thing) vis->sector = thing->subsector->sector; vis->szt = (INT16)((centeryfrac - FixedMul(vis->gzt - viewz, sortscale))>>FRACBITS); vis->sz = (INT16)((centeryfrac - FixedMul(vis->gz - viewz, sortscale))>>FRACBITS); - - R_SetSpritePlaneHeights(vis); - vis->cut = cut; if (thing->subsector->sector->numlights) vis->extra_colormap = *thing->subsector->sector->lightlist[light].extra_colormap; @@ -2062,8 +2031,6 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing) vis->szt = (INT16)((centeryfrac - FixedMul(vis->gzt - viewz, yscale))>>FRACBITS); vis->sz = (INT16)((centeryfrac - FixedMul(vis->gz - viewz, yscale))>>FRACBITS); - R_SetSpritePlaneHeights(vis); - iscale = FixedDiv(FRACUNIT, xscale); vis->startfrac = 0; @@ -2443,12 +2410,12 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps // bird: if any part of the sprite peeks in front the plane if (planecameraz < viewz) { - if (rover->pt >= planeobjectz && rover->gzt >= planeobjectz) + if (rover->gzt >= planeobjectz) continue; } else if (planecameraz > viewz) { - if (rover->pb <= planeobjectz && rover->gz <= planeobjectz) + if (rover->gz <= planeobjectz) continue; } diff --git a/src/r_things.h b/src/r_things.h index f95cd5c9e..400a63bcb 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -171,7 +171,6 @@ typedef struct vissprite_s // Precalculated top and bottom screen coords for the sprite. sector_t *sector; // The sector containing the thing. - fixed_t pt, pb; // plane heights, also for sorting against 3D floors INT16 sz, szt; spritecut_e cut; From 131d592bbfa896f131210e79ce458f0efa670d13 Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 5 Nov 2020 04:55:01 -0800 Subject: [PATCH 077/143] Do not factor height into sprite thickseg sorting --- src/r_things.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/r_things.c b/src/r_things.c index 9702c7d3f..50eb222ae 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -2448,7 +2448,7 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps } else if (r2->thickseg) { - fixed_t topplaneobjectz, topplanecameraz, botplaneobjectz, botplanecameraz; + //fixed_t topplaneobjectz, topplanecameraz, botplaneobjectz, botplanecameraz; if (rover->x1 > r2->thickseg->x2 || rover->x2 < r2->thickseg->x1) continue; @@ -2459,6 +2459,11 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps if (scale <= rover->sortscale) continue; + // bird: Always sort sprites behind segs. This helps the plane + // sorting above too. Basically if the sprite gets sorted behind + // the seg here, it will be behind the plane too, since planes + // are added after segs in the list. +#if 0 topplaneobjectz = P_GetFFloorTopZAt (r2->ffloor, rover->gx, rover->gy); topplanecameraz = P_GetFFloorTopZAt (r2->ffloor, viewx, viewy); botplaneobjectz = P_GetFFloorBottomZAt(r2->ffloor, rover->gx, rover->gy); @@ -2467,6 +2472,7 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps if ((topplanecameraz > viewz && botplanecameraz < viewz) || (topplanecameraz < viewz && rover->gzt < topplaneobjectz) || (botplanecameraz > viewz && rover->gz > botplaneobjectz)) +#endif { entry = R_CreateDrawNode(NULL); (entry->prev = r2->prev)->next = entry; From 745b293c477a2b7f7108f90131d153efbe4aa43a Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 5 Nov 2020 20:00:21 -0800 Subject: [PATCH 078/143] Always allow access to the serverplayer --- src/dehacked.c | 7 +++---- src/lua_playerlib.c | 16 +++++++++++++++- src/lua_script.c | 8 ++++++++ src/lua_script.h | 1 + 4 files changed, 27 insertions(+), 5 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 00f4fa96d..101507511 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -9704,11 +9704,10 @@ static inline int lib_getenum(lua_State *L) lua_pushinteger(L, mapmusposition); return 1; } else if (fastcmp(word,"server")) { - if ((!multiplayer || !(netgame || demo.playback)) && !playeringame[serverplayer]) - return 0; - LUA_PushUserdata(L, &players[serverplayer], META_PLAYER); - return 1; + return LUA_PushServerPlayer(L); } else if (fastcmp(word,"consoleplayer")) { // Player controlling the console, basically our local player + if (consoleplayer == serverplayer) + return LUA_PushServerPlayer(L); if (consoleplayer < 0 || !playeringame[consoleplayer]) return 0; LUA_PushUserdata(L, &players[consoleplayer], META_PLAYER); diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index 3aeeed734..c4c996e5e 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -27,17 +27,28 @@ static int lib_iteratePlayers(lua_State *L) { INT32 i = -1; + if (lua_gettop(L) < 2) { //return luaL_error(L, "Don't call players.iterate() directly, use it as 'for player in players.iterate do end'."); lua_pushcfunction(L, lib_iteratePlayers); return 1; } + lua_settop(L, 2); lua_remove(L, 1); // state is unused. + if (!lua_isnil(L, 1)) i = (INT32)(*((player_t **)luaL_checkudata(L, 1, META_PLAYER)) - players); - for (i++; i < MAXPLAYERS; i++) + + i++; + + if (i == serverplayer) + { + return LUA_PushServerPlayer(L); + } + + for (; i < MAXPLAYERS; i++) { if (!playeringame[i]) continue; @@ -46,6 +57,7 @@ static int lib_iteratePlayers(lua_State *L) LUA_PushUserdata(L, &players[i], META_PLAYER); return 1; } + return 0; } @@ -58,6 +70,8 @@ static int lib_getPlayer(lua_State *L) lua_Integer i = luaL_checkinteger(L, 2); if (i < 0 || i >= MAXPLAYERS) return luaL_error(L, "players[] index %d out of range (0 - %d)", i, MAXPLAYERS-1); + if (i == serverplayer) + return LUA_PushServerPlayer(L); if (!playeringame[i]) return 0; if (!players[i].mo) diff --git a/src/lua_script.c b/src/lua_script.c index 7c951efb3..ee49efcc1 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -367,6 +367,14 @@ void LUA_PushUserdata(lua_State *L, void *data, const char *meta) lua_remove(L, -2); // remove LREG_VALID } +int LUA_PushServerPlayer(lua_State *L) +{ + if ((!multiplayer || !(netgame || demo.playback)) && !playeringame[serverplayer]) + return 0; + LUA_PushUserdata(L, &players[serverplayer], META_PLAYER); + return 1; +} + // When userdata is freed, use this function to remove it from Lua. void LUA_InvalidateUserdata(void *data) { diff --git a/src/lua_script.h b/src/lua_script.h index b3ca16bc0..5e2e171f5 100644 --- a/src/lua_script.h +++ b/src/lua_script.h @@ -46,6 +46,7 @@ void LUA_DumpFile(const char *filename); #endif fixed_t LUA_EvalMath(const char *word); void LUA_PushUserdata(lua_State *L, void *data, const char *meta); +int LUA_PushServerPlayer(lua_State *L); void LUA_InvalidateUserdata(void *data); void LUA_InvalidateLevel(void); void LUA_InvalidateMapthings(void); From 3386ff6b902cab5a8c88fc2c4d7cf8ca1651befc Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 5 Nov 2020 20:02:40 -0800 Subject: [PATCH 079/143] Allow accessing a player even if there is no mobj The worst part is you could've just saved the player userdata and accessed it later anyway while player.mo is nil. --- src/lua_playerlib.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index c4c996e5e..24bc6c480 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -52,8 +52,6 @@ static int lib_iteratePlayers(lua_State *L) { if (!playeringame[i]) continue; - if (!players[i].mo) - continue; LUA_PushUserdata(L, &players[i], META_PLAYER); return 1; } @@ -74,8 +72,6 @@ static int lib_getPlayer(lua_State *L) return LUA_PushServerPlayer(L); if (!playeringame[i]) return 0; - if (!players[i].mo) - return 0; LUA_PushUserdata(L, &players[i], META_PLAYER); return 1; } @@ -136,8 +132,6 @@ static int lib_iterateDisplayplayers(lua_State *L) if (i > splitscreen || !playeringame[displayplayers[i]]) return 0; // Stop! There are no more players for us to go through. There will never be a player gap in displayplayers. - if (!players[displayplayers[i]].mo) - continue; LUA_PushUserdata(L, &players[displayplayers[i]], META_PLAYER); lua_pushinteger(L, i); // push this to recall what number we were on for the next function call. I suppose this also means you can retrieve the splitscreen player number with 'for p, n in displayplayers.iterate'! return 2; @@ -158,8 +152,6 @@ static int lib_getDisplayplayers(lua_State *L) return 0; if (!playeringame[displayplayers[i]]) return 0; - if (!players[displayplayers[i]].mo) - return 0; LUA_PushUserdata(L, &players[displayplayers[i]], META_PLAYER); return 1; } From 1cedb32e51735519e9a66a3119019e2ffa6b9484 Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 5 Nov 2020 20:05:04 -0800 Subject: [PATCH 080/143] Let access spectator mobj --- src/lua_playerlib.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index 24bc6c480..5f034c29d 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -190,12 +190,7 @@ static int player_get(lua_State *L) else if (fastcmp(field,"name")) lua_pushstring(L, player_names[plr-players]); else if (fastcmp(field,"mo")) - { - if (plr->spectator) - lua_pushnil(L); - else - LUA_PushUserdata(L, plr->mo, META_MOBJ); - } + LUA_PushUserdata(L, plr->mo, META_MOBJ); else if (fastcmp(field,"cmd")) LUA_PushUserdata(L, &plr->cmd, META_TICCMD); else if (fastcmp(field,"playerstate")) From d996a6a3b96ce46eecc20c34ce255827c3231ec9 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 29 Dec 2019 20:59:48 -0800 Subject: [PATCH 081/143] Fuck magic numbers; COM_ flags for Lua commands! --- src/command.h | 7 +++++++ src/dehacked.c | 4 ++++ src/lua_consolelib.c | 15 +++++++++++---- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/command.h b/src/command.h index 0880065b2..3a4260ec3 100644 --- a/src/command.h +++ b/src/command.h @@ -20,6 +20,13 @@ // Command buffer & command execution //=================================== +/* Lua command registration flags. */ +enum +{ + COM_ADMIN = 1, + COM_SPLITSCREEN = 2, +}; + typedef void (*com_func_t)(void); void COM_AddCommand(const char *name, com_func_t func); diff --git a/src/dehacked.c b/src/dehacked.c index 00f4fa96d..ccda71625 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -8685,6 +8685,10 @@ struct { {"BT_CUSTOM2",BT_CUSTOM2}, // Lua customizable {"BT_CUSTOM3",BT_CUSTOM3}, // Lua customizable + // Lua command registration flags + {"COM_ADMIN",COM_ADMIN}, + {"COM_SPLITSCREEN",COM_SPLITSCREEN}, + // cvflags_t {"CV_SAVE",CV_SAVE}, {"CV_CALL",CV_CALL}, diff --git a/src/lua_consolelib.c b/src/lua_consolelib.c index 0c73459cb..081a5fab7 100644 --- a/src/lua_consolelib.c +++ b/src/lua_consolelib.c @@ -113,12 +113,12 @@ void COM_Lua_f(void) lua_rawgeti(gL, -1, 2); // push flags from command info table if (lua_isboolean(gL, -1)) - flags = (lua_toboolean(gL, -1) ? 1 : 0); + flags = (lua_toboolean(gL, -1) ? COM_ADMIN : 0); else flags = (UINT8)lua_tointeger(gL, -1); lua_pop(gL, 1); // pop flags - if (flags & 2) // flag 2: splitscreen player command. TODO: support 4P + if (flags & COM_SPLITSCREEN) // flag 2: splitscreen player command. TODO: support 4P { if (!splitscreen) { @@ -133,7 +133,7 @@ void COM_Lua_f(void) UINT8 argc; lua_pop(gL, 1); // pop command info table - if (flags & 1 && !server && !IsPlayerAdmin(playernum)) // flag 1: only server/admin can use this command. + if (flags & COM_ADMIN && !server && !IsPlayerAdmin(playernum)) // flag 1: only server/admin can use this command. { CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n")); return; @@ -187,7 +187,14 @@ static int lib_comAddCommand(lua_State *L) if (lua_gettop(L) >= 3) { // For the third argument, only take a boolean or a number. lua_settop(L, 3); - if (lua_type(L, 3) != LUA_TBOOLEAN) + if (lua_type(L, 3) == LUA_TBOOLEAN) + { + CONS_Alert(CONS_WARNING, + "Using a boolean is deprecated and will be removed.\n" + "Use \"COM_\" flags instead.\n" + ); + } + else luaL_checktype(L, 3, LUA_TNUMBER); } else From 7e9922febfec1023d1648fa793ab02da76bb06df Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 29 Dec 2019 21:07:28 -0800 Subject: [PATCH 082/143] COM_LOCAL makes your commands NetXCmd free, FUCK NetXCmd --- src/command.h | 1 + src/dehacked.c | 1 + src/lua_consolelib.c | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/command.h b/src/command.h index 3a4260ec3..ae573a16c 100644 --- a/src/command.h +++ b/src/command.h @@ -25,6 +25,7 @@ enum { COM_ADMIN = 1, COM_SPLITSCREEN = 2, + COM_LOCAL = 4, }; typedef void (*com_func_t)(void); diff --git a/src/dehacked.c b/src/dehacked.c index ccda71625..af576554f 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -8688,6 +8688,7 @@ struct { // Lua command registration flags {"COM_ADMIN",COM_ADMIN}, {"COM_SPLITSCREEN",COM_SPLITSCREEN}, + {"COM_LOCAL",COM_LOCAL}, // cvflags_t {"CV_SAVE",CV_SAVE}, diff --git a/src/lua_consolelib.c b/src/lua_consolelib.c index 081a5fab7..5d45da533 100644 --- a/src/lua_consolelib.c +++ b/src/lua_consolelib.c @@ -128,7 +128,7 @@ void COM_Lua_f(void) playernum = displayplayers[1]; } - if (netgame) + if (netgame && !( flags & COM_LOCAL ))/* don't send local commands */ { // Send the command through the network UINT8 argc; lua_pop(gL, 1); // pop command info table From 2ba99dac90599ef0c5f59f6ecc8bac9fdc35117c Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 29 Dec 2019 21:09:07 -0800 Subject: [PATCH 083/143] Improve COM_AddCommand boolean deprecated warning --- src/lua_consolelib.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/lua_consolelib.c b/src/lua_consolelib.c index 5d45da533..49ef6752b 100644 --- a/src/lua_consolelib.c +++ b/src/lua_consolelib.c @@ -190,8 +190,9 @@ static int lib_comAddCommand(lua_State *L) if (lua_type(L, 3) == LUA_TBOOLEAN) { CONS_Alert(CONS_WARNING, - "Using a boolean is deprecated and will be removed.\n" - "Use \"COM_\" flags instead.\n" + "Using a boolean for admin commands is " + "deprecated and will be removed.\n" + "Use \"COM_ADMIN\" instead.\n" ); } else From 3d62b6f2ade8609aac6f1aa40f7b26b1914f930a Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Sat, 27 Jun 2020 15:30:23 +0200 Subject: [PATCH 084/143] Expose "server" and "dedicated" to Lua scripts Careful! Both are local variables and are always false for clients, and therefore should obviously not be used in anything gamelogic-related. --- src/dehacked.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index af576554f..2fae84160 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -9718,12 +9718,12 @@ static inline int lib_getenum(lua_State *L) return 0; LUA_PushUserdata(L, &players[consoleplayer], META_PLAYER); return 1; - /*} else if (fastcmp(word,"admin")) { - LUA_Deprecated(L, "admin", "IsPlayerAdmin(player)"); - if (!playeringame[adminplayers[0]] || IsPlayerAdmin(serverplayer)) - return 0; - LUA_PushUserdata(L, &players[adminplayers[0]], META_PLAYER); - return 1;*/ + } else if (fastcmp(word,"isserver")) { + lua_pushboolean(L, server); + return 1; + } else if (fastcmp(word, "isdedicatedserver")) { + lua_pushboolean(L, dedicated); + return 1; } else if (fastcmp(word,"gravity")) { lua_pushinteger(L, gravity); return 1; From 758a43385d8080d2db69d36393e23915615b4d2a Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 20 Oct 2020 16:08:34 -0700 Subject: [PATCH 085/143] Add CV_Set, CV_SetValue, CV_StealthSet, CV_StealthSetValue and CV_AddValue to Lua CV_SetValue merged with CV_Set (same with CV_StealthSetValue and CV_StealthSet). --- src/lua_consolelib.c | 44 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/src/lua_consolelib.c b/src/lua_consolelib.c index 49ef6752b..3869fdc72 100644 --- a/src/lua_consolelib.c +++ b/src/lua_consolelib.c @@ -444,6 +444,45 @@ static int lib_cvFindVar(lua_State *L) return 0; } +static int CVarSetFunction +( + lua_State *L, + void (*Set)(consvar_t *, const char *), + void (*SetValue)(consvar_t *, INT32) +){ + consvar_t *cvar = (consvar_t *)luaL_checkudata(L, 1, META_CVAR); + + switch (lua_type(L, 2)) + { + case LUA_TSTRING: + (*Set)(cvar, lua_tostring(L, 2)); + break; + case LUA_TNUMBER: + (*SetValue)(cvar, (INT32)lua_tonumber(L, 2)); + break; + default: + return luaL_typerror(L, 1, "string or number"); + } + + return 0; +} + +static int lib_cvSet(lua_State *L) +{ + return CVarSetFunction(L, CV_Set, CV_SetValue); +} + +static int lib_cvStealthSet(lua_State *L) +{ + return CVarSetFunction(L, CV_StealthSet, CV_StealthSetValue); +} + +static int lib_cvAddValue(lua_State *L) +{ + consvar_t *cvar = (consvar_t *)luaL_checkudata(L, 1, META_CVAR); + CV_AddValue(cvar, (INT32)luaL_checknumber(L, 2)); + return 0; +} // CONS_Printf for a single player // Use 'print' in baselib for a global message. @@ -483,8 +522,11 @@ static luaL_Reg lib[] = { {"COM_BufAddText", lib_comBufAddText}, {"COM_BufInsertText", lib_comBufInsertText}, {"CV_RegisterVar", lib_cvRegisterVar}, - {"CONS_Printf", lib_consPrintf}, {"CV_FindVar", lib_cvFindVar}, + {"CV_Set", lib_cvSet}, + {"CV_StealthSet", lib_cvStealthSet}, + {"CV_AddValue", lib_cvAddValue}, + {"CONS_Printf", lib_consPrintf}, {NULL, NULL} }; From cacca05ed3376c46eddd526cb20a438407672f34 Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 5 Nov 2020 21:04:25 -0800 Subject: [PATCH 086/143] PreThinkFrame and PostThinkFrame hooks Changes from e4d1b9491c1137530e2b4b9d34e5f94d2bad10ac, 4456ff50abfb3207dadd9a033e6f3e1e3ee73c92, 20494c4c427f111add919437b87cf833a6196504, ee0e68d8dca67e34d81d7e2b2ee8cac05725e911. --- src/lua_hook.h | 4 ++++ src/lua_hooklib.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++ src/p_tick.c | 16 ++++++++++++++++ 3 files changed, 68 insertions(+) diff --git a/src/lua_hook.h b/src/lua_hook.h index 6af3941f1..bd2afebb4 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -20,7 +20,9 @@ enum hook { hook_MapChange, hook_MapLoad, hook_PlayerJoin, + hook_PreThinkFrame, hook_ThinkFrame, + hook_PostThinkFrame, hook_MobjSpawn, hook_MobjCollide, hook_MobjMoveCollide, @@ -64,7 +66,9 @@ extern boolean hook_cmd_running; // This is used by PlayerCmd and lua_playerlib void LUAh_MapChange(INT16 mapnumber); // Hook for map change (before load) void LUAh_MapLoad(void); // Hook for map load void LUAh_PlayerJoin(int playernum); // Hook for Got_AddPlayer +void LUAh_PreThinkFrame(void); // Hook for frame (before mobj and player thinkers) void LUAh_ThinkFrame(void); // Hook for frame (after mobj and player thinkers) +void LUAh_PostThinkFrame(void); // Hook for frame (at end of tick, ie after overlays, precipitation, specials) boolean LUAh_MobjHook(mobj_t *mo, enum hook which); boolean LUAh_PlayerHook(player_t *plr, enum hook which); #define LUAh_MobjSpawn(mo) LUAh_MobjHook(mo, hook_MobjSpawn) // Hook for P_SpawnMobj by mobj type diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 41a436e01..90a13c6fa 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -31,7 +31,9 @@ const char *const hookNames[hook_MAX+1] = { "MapChange", "MapLoad", "PlayerJoin", + "PreThinkFrame", "ThinkFrame", + "PostThinkFrame", "MobjSpawn", "MobjCollide", "MobjMoveCollide", @@ -402,6 +404,29 @@ void LUAh_PlayerJoin(int playernum) lua_settop(gL, 0); } +// Hook for frame (before mobj and player thinkers) +void LUAh_PreThinkFrame(void) +{ + hook_p hookp; + if (!gL || !(hooksAvailable[hook_PreThinkFrame/8] & (1<<(hook_PreThinkFrame%8)))) + return; + + for (hookp = roothook; hookp; hookp = hookp->next) + { + if (hookp->type != hook_PreThinkFrame) + continue; + + lua_pushfstring(gL, FMT_HOOKID, hookp->id); + lua_gettable(gL, LUA_REGISTRYINDEX); + if (lua_pcall(gL, 0, 0, 0)) { + if (!hookp->error || cv_debug & DBG_LUA) + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); + hookp->error = true; + } + } +} + // Hook for frame (after mobj and player thinkers) void LUAh_ThinkFrame(void) { @@ -423,6 +448,29 @@ void LUAh_ThinkFrame(void) } } +// Hook for frame (at end of tick, ie after overlays, precipitation, specials) +void LUAh_PostThinkFrame(void) +{ + hook_p hookp; + if (!gL || !(hooksAvailable[hook_PostThinkFrame/8] & (1<<(hook_PostThinkFrame%8)))) + return; + + for (hookp = roothook; hookp; hookp = hookp->next) + { + if (hookp->type != hook_PostThinkFrame) + continue; + + lua_pushfstring(gL, FMT_HOOKID, hookp->id); + lua_gettable(gL, LUA_REGISTRYINDEX); + if (lua_pcall(gL, 0, 0, 0)) { + if (!hookp->error || cv_debug & DBG_LUA) + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); + hookp->error = true; + } + } +} + // Hook for Y_Ticker void LUAh_IntermissionThinker(void) { diff --git a/src/p_tick.c b/src/p_tick.c index 4cc6c9ba4..bf0344477 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -648,6 +648,10 @@ void P_Ticker(boolean run) #endif } +#ifdef HAVE_BLUA + LUAh_PreThinkFrame(); +#endif + for (i = 0; i < MAXPLAYERS; i++) if (playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo)) P_PlayerThink(&players[i]); @@ -779,6 +783,10 @@ void P_Ticker(boolean run) && --mapreset <= 1 && server) // Remember: server uses it for mapchange, but EVERYONE ticks down for the animation D_MapChange(gamemap, gametype, encoremode, true, 0, false, false); + +#ifdef HAVE_BLUA + LUAh_PostThinkFrame(); +#endif } // Always move the camera. @@ -809,6 +817,10 @@ void P_PreTicker(INT32 frames) { P_MapStart(); +#ifdef HAVE_BLUA + LUAh_PreThinkFrame(); +#endif + for (i = 0; i < MAXPLAYERS; i++) if (playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo)) { @@ -843,6 +855,10 @@ void P_PreTicker(INT32 frames) P_UpdateSpecials(); P_RespawnSpecials(); +#ifdef HAVE_BLUA + LUAh_PostThinkFrame(); +#endif + P_MapEnd(); } } From 7efb33a38edc0f472c4cc8f212f9240b9f9e78c2 Mon Sep 17 00:00:00 2001 From: Zachary McAlpin Date: Sat, 14 Dec 2019 15:28:24 -0600 Subject: [PATCH 087/143] Added PlayerThink hook --- src/lua_hook.h | 2 ++ src/lua_hooklib.c | 2 ++ src/p_user.c | 20 +++++++++++++++++++- 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/lua_hook.h b/src/lua_hook.h index bd2afebb4..3f2dfd7a5 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -46,6 +46,7 @@ enum hook { hook_HurtMsg, hook_PlayerSpawn, hook_PlayerQuit, + hook_PlayerThink, hook_MusicChange, hook_ShouldSpin, //SRB2KART hook_ShouldExplode, //SRB2KART @@ -110,5 +111,6 @@ boolean LUAh_PlayerCmd(player_t *player, ticcmd_t *cmd); // Allows to write to p void LUAh_IntermissionThinker(void); // Hook for Y_Ticker void LUAh_VoteThinker(void); // Hook for Y_VoteTicker +#define LUAh_PlayerThink(player) LUAh_PlayerHook(player, hook_PlayerThink) // Hook for P_PlayerThink #endif diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 90a13c6fa..e9a4d0b40 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -57,6 +57,7 @@ const char *const hookNames[hook_MAX+1] = { "HurtMsg", "PlayerSpawn", "PlayerQuit", + "PlayerThink", "MusicChange", "ShouldSpin", "ShouldExplode", @@ -208,6 +209,7 @@ static int lib_addHook(lua_State *L) case hook_SpinSpecial: case hook_JumpSpinSpecial: case hook_PlayerSpawn: + case hook_PlayerThink: lastp = &playerhooks; break; case hook_LinedefExecute: diff --git a/src/p_user.c b/src/p_user.c index cb6b7bd62..dc22bd940 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -8244,7 +8244,12 @@ void P_PlayerThink(player_t *player) player->playerstate = PST_REBORN; } if (player->playerstate == PST_REBORN) + { +#ifdef HAVE_BLUA + LUAh_PlayerThink(player); +#endif return; + } } #ifdef SEENAMES @@ -8368,7 +8373,12 @@ void P_PlayerThink(player_t *player) P_DoTimeOver(player); if (player->playerstate == PST_DEAD) + { +#ifdef HAVE_BLUA + LUAh_PlayerThink(player); +#endif return; + } } } @@ -8432,7 +8442,9 @@ void P_PlayerThink(player_t *player) else player->mo->flags2 &= ~MF2_SHADOW; P_DeathThink(player); - +#ifdef HAVE_BLUA + LUAh_PlayerThink(player); +#endif return; } @@ -8566,6 +8578,12 @@ void P_PlayerThink(player_t *player) } else P_MovePlayer(player); + } + +#ifdef HAVE_BLUA + LUAh_PlayerThink(player); +#endif + if (!player->mo) return; // P_MovePlayer removed player->mo. From 2764c283d2a27dcafe784086863cc7e5923ff79f Mon Sep 17 00:00:00 2001 From: Zachary McAlpin Date: Sat, 28 Dec 2019 17:40:47 -0600 Subject: [PATCH 088/143] Execute LUAh_PlayerThink(player) at the end if the player has a valid mobj_t object --- src/p_user.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index dc22bd940..6f00e410f 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -8580,13 +8580,13 @@ void P_PlayerThink(player_t *player) P_MovePlayer(player); } -#ifdef HAVE_BLUA - LUAh_PlayerThink(player); -#endif - - if (!player->mo) + { +#ifdef HAVE_BLUA + LUAh_PlayerThink(player); +#endif return; // P_MovePlayer removed player->mo. + } // Unset statis flags after moving. // In other words, if you manually set stasis via code, @@ -8782,6 +8782,10 @@ void P_PlayerThink(player_t *player) K_KartPlayerThink(player, cmd); // SRB2kart +#ifdef HAVE_BLUA + LUAh_PlayerThink(player); +#endif + /* // Colormap verification { From e2df4cf027c05d8e0bc466863bc3fa8fb1b809a9 Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 5 Nov 2020 22:18:41 -0800 Subject: [PATCH 089/143] :V --- src/p_user.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index 6f00e410f..8d5536338 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -8578,7 +8578,6 @@ void P_PlayerThink(player_t *player) } else P_MovePlayer(player); - } if (!player->mo) { From c902f9addb995dd65852264122f8035d9e450621 Mon Sep 17 00:00:00 2001 From: Hannu Hanhi Date: Sat, 7 Nov 2020 20:32:44 +0200 Subject: [PATCH 090/143] R_FindPlane optimization from SRB2 --- src/r_plane.c | 61 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 24 deletions(-) diff --git a/src/r_plane.c b/src/r_plane.c index d00274262..9b0691da8 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -46,7 +46,10 @@ //#define SHITPLANESPARENCY //SoM: 3/23/2000: Use Boom visplane hashing. -#define MAXVISPLANES 512 +#define VISPLANEHASHBITS 9 +#define VISPLANEHASHMASK ((1<next) + if (!pfloor) { - if (check->polyobj && pfloor) - continue; - if (polyobj != check->polyobj) - continue; - if (height == check->height && picnum == check->picnum - && lightlevel == check->lightlevel - && xoff == check->xoffs && yoff == check->yoffs - && planecolormap == check->extra_colormap - && !pfloor && !check->ffloor - && check->viewx == viewx && check->viewy == viewy && check->viewz == viewz - && check->viewangle == viewangle - && check->plangle == plangle - && check->slope == slope - && check->noencore == noencore) + hash = visplane_hash(picnum, lightlevel, height); + for (check = visplanes[hash]; check; check = check->next) { - return check; + if (polyobj != check->polyobj) + continue; + if (height == check->height && picnum == check->picnum + && lightlevel == check->lightlevel + && xoff == check->xoffs && yoff == check->yoffs + && planecolormap == check->extra_colormap + && check->viewx == viewx && check->viewy == viewy && check->viewz == viewz + && check->viewangle == viewangle + && check->plangle == plangle + && check->slope == slope + && check->noencore == noencore) + { + return check; + } } } + else + { + hash = MAXVISPLANES - 1; + } check = new_visplane(hash); @@ -559,9 +564,17 @@ visplane_t *R_CheckPlane(visplane_t *pl, INT32 start, INT32 stop) } else /* Cannot use existing plane; create a new one */ { - unsigned hash = - visplane_hash(pl->picnum, pl->lightlevel, pl->height); - visplane_t *new_pl = new_visplane(hash); + visplane_t *new_pl; + if (pl->ffloor) + { + new_pl = new_visplane(MAXVISPLANES - 1); + } + else + { + unsigned hash = + visplane_hash(pl->picnum, pl->lightlevel, pl->height); + new_pl = new_visplane(hash); + } new_pl->height = pl->height; new_pl->picnum = pl->picnum; From f27a2b904b0cd6e99af3229da44e0cfe0a6a7cba Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sat, 7 Nov 2020 19:47:50 -0500 Subject: [PATCH 091/143] Use FixedHypot over P_AproxDistance Not convinced that the small speed benefit from P_AproxDistance is worth the "aproximate"[sic] results it gives. Let's instead try a define to replace it with FixedHypot. In Lua, the function gives a deprecated warning. Inspired by the hyperwall fix for vanilla, except for everything. From little testing, actively improves waypoint checks, bumping, speed checks, wall collisions, Jawz targetting, Lightning Shield attacks, so on. The only way I see this as a potential downgrade is A_Look (and related functions) getting slower, which are barely used in Kart. --- src/lua_baselib.c | 3 ++- src/p_maputl.c | 13 ------------- src/p_maputl.h | 2 +- 3 files changed, 3 insertions(+), 15 deletions(-) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 56b1a5a54..c50f53dfc 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -238,7 +238,8 @@ static int lib_pAproxDistance(lua_State *L) fixed_t dx = luaL_checkfixed(L, 1); fixed_t dy = luaL_checkfixed(L, 2); //HUDSAFE - lua_pushfixed(L, P_AproxDistance(dx, dy)); + LUA_Deprecated(L, "P_AproxDistance", "FixedHypot"); + lua_pushfixed(L, FixedHypot(dx, dy)); return 1; } diff --git a/src/p_maputl.c b/src/p_maputl.c index 260eb3ec6..760e45c4f 100644 --- a/src/p_maputl.c +++ b/src/p_maputl.c @@ -23,19 +23,6 @@ #include "p_slopes.h" #include "z_zone.h" -// -// P_AproxDistance -// Gives an estimation of distance (not exact) -// -fixed_t P_AproxDistance(fixed_t dx, fixed_t dy) -{ - dx = abs(dx); - dy = abs(dy); - if (dx < dy) - return dx + dy - (dx>>1); - return dx + dy - (dy>>1); -} - // // P_ClosestPointOnLine // Finds the closest point on a given line to the supplied point diff --git a/src/p_maputl.h b/src/p_maputl.h index be69e0265..ec4a4aa33 100644 --- a/src/p_maputl.h +++ b/src/p_maputl.h @@ -41,7 +41,7 @@ typedef boolean (*traverser_t)(intercept_t *in); boolean P_PathTraverse(fixed_t px1, fixed_t py1, fixed_t px2, fixed_t py2, INT32 pflags, traverser_t ptrav); -FUNCMATH fixed_t P_AproxDistance(fixed_t dx, fixed_t dy); +#define P_AproxDistance(dx, dy) FixedHypot(dx, dy) void P_ClosestPointOnLine(fixed_t x, fixed_t y, line_t *line, vertex_t *result); void P_ClosestPointOnLine3D(fixed_t x, fixed_t y, fixed_t z, line_t *line, vertex_t *result); INT32 P_PointOnLineSide(fixed_t x, fixed_t y, line_t *line); From def9b7112a6253512bdc7023115c63266cc2d468 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sat, 7 Nov 2020 23:56:46 -0500 Subject: [PATCH 092/143] Use R_PointToDist2 instead Apparently overflows less often --- src/lua_baselib.c | 4 ++-- src/p_maputl.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index c50f53dfc..73295a139 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -238,8 +238,8 @@ static int lib_pAproxDistance(lua_State *L) fixed_t dx = luaL_checkfixed(L, 1); fixed_t dy = luaL_checkfixed(L, 2); //HUDSAFE - LUA_Deprecated(L, "P_AproxDistance", "FixedHypot"); - lua_pushfixed(L, FixedHypot(dx, dy)); + LUA_Deprecated(L, "P_AproxDistance", "R_PointToDist2"); + lua_pushfixed(L, R_PointToDist2(0, 0, dx, dy)); return 1; } diff --git a/src/p_maputl.h b/src/p_maputl.h index ec4a4aa33..5be618d8f 100644 --- a/src/p_maputl.h +++ b/src/p_maputl.h @@ -41,7 +41,7 @@ typedef boolean (*traverser_t)(intercept_t *in); boolean P_PathTraverse(fixed_t px1, fixed_t py1, fixed_t px2, fixed_t py2, INT32 pflags, traverser_t ptrav); -#define P_AproxDistance(dx, dy) FixedHypot(dx, dy) +#define P_AproxDistance(dx, dy) R_PointToDist2(0, 0, dx, dy) void P_ClosestPointOnLine(fixed_t x, fixed_t y, line_t *line, vertex_t *result); void P_ClosestPointOnLine3D(fixed_t x, fixed_t y, fixed_t z, line_t *line, vertex_t *result); INT32 P_PointOnLineSide(fixed_t x, fixed_t y, line_t *line); From b3f4483ac225fab05d2617590680a099136f3647 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sun, 8 Nov 2020 00:45:16 -0500 Subject: [PATCH 093/143] Actually, lets just fix FixedHypot instead. Now FixedHypot uses the code from R_PointToDist2, and R_PointToDist2 just calls FixedHypot. Ultimately, this branch was intended to get rid of a redundant way to retrieve distance and replace it with the one that was actually good at its job. So consolidating FixedHypot and R_PointToDist2 together is just an extension of that. --- src/lua_baselib.c | 4 ++-- src/m_fixed.c | 40 ++++++++++++++++++++++++++++------------ src/p_maputl.h | 2 +- src/r_main.c | 24 +----------------------- 4 files changed, 32 insertions(+), 38 deletions(-) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 73295a139..c50f53dfc 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -238,8 +238,8 @@ static int lib_pAproxDistance(lua_State *L) fixed_t dx = luaL_checkfixed(L, 1); fixed_t dy = luaL_checkfixed(L, 2); //HUDSAFE - LUA_Deprecated(L, "P_AproxDistance", "R_PointToDist2"); - lua_pushfixed(L, R_PointToDist2(0, 0, dx, dy)); + LUA_Deprecated(L, "P_AproxDistance", "FixedHypot"); + lua_pushfixed(L, FixedHypot(dx, dy)); return 1; } diff --git a/src/m_fixed.c b/src/m_fixed.c index 7241be9c0..3724144f7 100644 --- a/src/m_fixed.c +++ b/src/m_fixed.c @@ -18,8 +18,10 @@ #define HAVE_SQRTF #endif #endif + #include "doomdef.h" #include "m_fixed.h" +#include "tables.h" // ANGLETOFINESHIFT #ifdef __USE_C_FIXEDMUL__ @@ -105,20 +107,34 @@ fixed_t FixedSqrt(fixed_t x) fixed_t FixedHypot(fixed_t x, fixed_t y) { - fixed_t ax, yx, yx2, yx1; - if (abs(y) > abs(x)) // |y|>|x| + // Moved the code from R_PointToDist2 to here, + // since R_PointToDist2 did the same thing, + // except less prone to overflowing. + + angle_t angle; + fixed_t dist; + + x = abs(x); + y = abs(y); + + if (y > x) { - ax = abs(y); // |y| => ax - yx = FixedDiv(x, y); // (x/y) + fixed_t temp; + + temp = x; + x = y; + y = temp; } - else // |x|>|y| - { - ax = abs(x); // |x| => ax - yx = FixedDiv(y, x); // (x/y) - } - yx2 = FixedMul(yx, yx); // (x/y)^2 - yx1 = FixedSqrt(1 * FRACUNIT + yx2); // (1 + (x/y)^2)^1/2 - return FixedMul(ax, yx1); // |x|*((1 + (x/y)^2)^1/2) + + if (!y) + return x; + + angle = (tantoangle[FixedDiv(y, x)>>DBITS] + ANGLE_90) >> ANGLETOFINESHIFT; + + // use as cosine + dist = FixedDiv(x, FINESINE(angle)); + + return dist; } vector2_t *FV2_Load(vector2_t *vec, fixed_t x, fixed_t y) diff --git a/src/p_maputl.h b/src/p_maputl.h index 5be618d8f..ec4a4aa33 100644 --- a/src/p_maputl.h +++ b/src/p_maputl.h @@ -41,7 +41,7 @@ typedef boolean (*traverser_t)(intercept_t *in); boolean P_PathTraverse(fixed_t px1, fixed_t py1, fixed_t px2, fixed_t py2, INT32 pflags, traverser_t ptrav); -#define P_AproxDistance(dx, dy) R_PointToDist2(0, 0, dx, dy) +#define P_AproxDistance(dx, dy) FixedHypot(dx, dy) void P_ClosestPointOnLine(fixed_t x, fixed_t y, line_t *line, vertex_t *result); void P_ClosestPointOnLine3D(fixed_t x, fixed_t y, fixed_t z, line_t *line, vertex_t *result); INT32 P_PointOnLineSide(fixed_t x, fixed_t y, line_t *line); diff --git a/src/r_main.c b/src/r_main.c index 5f3639ded..a78cd57eb 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -393,29 +393,7 @@ angle_t R_PointToAngle2(fixed_t pviewx, fixed_t pviewy, fixed_t x, fixed_t y) fixed_t R_PointToDist2(fixed_t px2, fixed_t py2, fixed_t px1, fixed_t py1) { - angle_t angle; - fixed_t dx, dy, dist; - - dx = abs(px1 - px2); - dy = abs(py1 - py2); - - if (dy > dx) - { - fixed_t temp; - - temp = dx; - dx = dy; - dy = temp; - } - if (!dy) - return dx; - - angle = (tantoangle[FixedDiv(dy, dx)>>DBITS] + ANGLE_90) >> ANGLETOFINESHIFT; - - // use as cosine - dist = FixedDiv(dx, FINESINE(angle)); - - return dist; + return FixedHypot(px1 - px2, py1 - py2); } // Little extra utility. Works in the same way as R_PointToAngle2 From 9434dd3ae3c1abd1a2911145203f4ef6048556f1 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sun, 8 Nov 2020 02:10:53 -0500 Subject: [PATCH 094/143] Make the stuff that lost it use K_MomentumAngle again --- src/k_kart.c | 4 ++-- src/p_mobj.c | 24 ++++++++++-------------- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 6ecdc7223..68f8c70c6 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -3262,7 +3262,7 @@ void K_SpawnBoostTrail(player_t *player) if (player->kartstuff[k_drift] != 0) travelangle = player->mo->angle; else - travelangle = R_PointToAngle2(0, 0, player->rmomx, player->rmomy); + travelangle = K_MomentumAngle(player->mo); for (i = 0; i < 2; i++) { @@ -3354,7 +3354,7 @@ void K_SpawnWipeoutTrail(mobj_t *mo, boolean translucent) mo->z, MT_WIPEOUTTRAIL); P_SetTarget(&dust->target, mo); - dust->angle = R_PointToAngle2(0,0,mo->momx,mo->momy); + dust->angle = K_MomentumAngle(mo); dust->destscale = mo->scale; P_SetScale(dust, mo->scale); K_FlipFromObject(dust, mo); diff --git a/src/p_mobj.c b/src/p_mobj.c index bd56665ae..3e595dec8 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1620,8 +1620,10 @@ void P_XYMovement(mobj_t *mo) relation = transferslope->xydirection - R_PointToAngle2(0, 0, mo->momx, mo->momy); else // Give it for free, I guess. relation = ANGLE_90; + transfermomz = FixedMul(transfermomz, abs(FINESINE((relation >> ANGLETOFINESHIFT) & FINEMASK))); + if (P_MobjFlip(mo)*(transfermomz - mo->momz) > 2*FRACUNIT) // Do the actual launch! { mo->momz = transfermomz; @@ -1696,7 +1698,7 @@ void P_XYMovement(mobj_t *mo) if (oldslope != mo->standingslope) { // First, compare different slopes angle_t oldangle, newangle; - angle_t moveangle = R_PointToAngle2(0, 0, mo->momx, mo->momy); + angle_t moveangle = K_MomentumAngle(mo); oldangle = FixedMul((signed)oldslope->zangle, FINECOSINE((moveangle - oldslope->xydirection) >> ANGLETOFINESHIFT)); @@ -1728,7 +1730,7 @@ void P_XYMovement(mobj_t *mo) P_SlopeLaunch(mo); } } else if (moved && mo->standingslope && predictedz) { - angle_t moveangle = R_PointToAngle2(0, 0, mo->momx, mo->momy); + angle_t moveangle = K_MomentumAngle(mo); angle_t newangle = FixedMul((signed)mo->standingslope->zangle, FINECOSINE((moveangle - mo->standingslope->xydirection) >> ANGLETOFINESHIFT)); /*CONS_Printf("flat to angle %f - predicted z of %f\n", @@ -6137,7 +6139,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) frictionsafety = FRACUNIT; } - mobj->angle = R_PointToAngle2(0, 0, mobj->momx, mobj->momy); + mobj->angle = K_MomentumAngle(mobj); if (mobj->health <= 5) { INT32 i; @@ -6239,7 +6241,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) thrustamount = beatfriction + FixedDiv(mobj->movefactor - currentspeed, frictionsafety); } - mobj->angle = R_PointToAngle2(0, 0, mobj->momx, mobj->momy); + mobj->angle = K_MomentumAngle(mobj); P_Thrust(mobj, mobj->angle, thrustamount); if (P_MobjTouchingSectorSpecial(mobj, 3, 1, true)) @@ -6402,7 +6404,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) //mobj->angle = mobj->target->angle; { - angle_t angle = R_PointToAngle2(0, 0, mobj->target->momx, mobj->target->momy); + angle_t angle = K_MomentumAngle(mobj->target); fixed_t nudge; mobj->angle = angle; @@ -6670,7 +6672,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) { const angle_t off = FixedAngle(40*FRACUNIT); - angle_t ang = mobj->target->angle; + angle_t ang = K_MomentumAngle(mobj->target); fixed_t z; UINT8 trans = (mobj->target->player->kartstuff[k_tiregrease] * (NUMTRANSMAPS+1)) / greasetics; @@ -6683,9 +6685,6 @@ static boolean P_MobjRegularThink(mobj_t *mobj) if (mobj->eflags & MFE_VERTICALFLIP) z += mobj->target->height; - if (mobj->target->momx || mobj->target->momy) - ang = R_PointToAngle2(0, 0, mobj->target->momx, mobj->target->momy); - if (mobj->extravalue1) ang = (signed)(ang - off); else @@ -6980,10 +6979,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) } P_TeleportMove(mobj, destx, desty, mobj->target->z); - if (mobj->target->momx || mobj->target->momy) - mobj->angle = R_PointToAngle2(0, 0, mobj->target->momx, mobj->target->momy); - else - mobj->angle = mobj->target->angle; + mobj->angle = K_MomentumAngle(mobj->target); if (underlayst != S_NULL) { @@ -7860,7 +7856,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) mobj->momx = (23*mobj->momx)/24; mobj->momy = (23*mobj->momy)/24; - mobj->angle = R_PointToAngle2(0,0,mobj->momx,mobj->momy); + mobj->angle = K_MomentumAngle(mobj); if ((mobj->z - mobj->floorz) < (24*mobj->scale) && (leveltime % 3 != 0)) { From bffc367c36505f96d81652706b3e4262513d45f7 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sun, 8 Nov 2020 14:14:13 -0500 Subject: [PATCH 095/143] Second-half spindash dust effect --- src/dehacked.c | 4 ++++ src/info.c | 31 ++++++++++++++++++++++++++ src/info.h | 6 +++++ src/k_kart.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++---- src/k_kart.h | 2 +- 5 files changed, 97 insertions(+), 5 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index a467543e9..8f4bd5083 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -9317,6 +9317,8 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_WATERTRAILUNDERLAY7", "S_WATERTRAILUNDERLAY8", + "S_SPINDASHDUST", + #ifdef SEENAMES "S_NAMECHECK", #endif @@ -10397,6 +10399,8 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_WATERTRAIL", "MT_WATERTRAILUNDERLAY", + "MT_SPINDASHDUST", + #ifdef SEENAMES "MT_NAMECHECK", #endif diff --git a/src/info.c b/src/info.c index 5677e4270..91cb1cb59 100644 --- a/src/info.c +++ b/src/info.c @@ -730,6 +730,8 @@ char sprnames[NUMSPRITES + 1][5] = "DBCL", // Drift boost clip "DBNC", // Drift boost clip's sparks "DBST", // Drift boost plume + + "SDDS", // Spindash dust }; char spr2names[NUMPLAYERSPRITES][5] = @@ -5026,6 +5028,8 @@ state_t states[NUMSTATES] = {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 + {SPR_SDDS, FF_ANIMATE, 9, {NULL}, 9, 1, S_NULL}, // S_SPINDASHDUST + #ifdef SEENAMES {SPR_NULL, 0, 1, {NULL}, 0, 0, S_NULL}, // S_NAMECHECK #endif @@ -28675,6 +28679,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_SPINDASHDUST + -1, // doomednum + S_SPINDASHDUST, // 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 + 12*FRACUNIT, // radius + 24*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY|MF_DONTENCOREMAP, // flags + S_NULL // raisestate + }, + // ============================================================================================================================// #ifdef SEENAMES diff --git a/src/info.h b/src/info.h index e7d53cb5b..b8e2908e2 100644 --- a/src/info.h +++ b/src/info.h @@ -1002,6 +1002,8 @@ typedef enum sprite SPR_DBNC, // Drift boost clip's sparks SPR_DBST, // Drift boost plume + SPR_SDDS, // Spindash dust + SPR_FIRSTFREESLOT, SPR_LASTFREESLOT = SPR_FIRSTFREESLOT + NUMSPRITEFREESLOTS - 1, NUMSPRITES @@ -5177,6 +5179,8 @@ typedef enum state S_WATERTRAILUNDERLAY7, S_WATERTRAILUNDERLAY8, + S_SPINDASHDUST, + #ifdef SEENAMES S_NAMECHECK, #endif @@ -6277,6 +6281,8 @@ typedef enum mobj_type MT_WATERTRAIL, MT_WATERTRAILUNDERLAY, + MT_SPINDASHDUST, + #ifdef SEENAMES MT_NAMECHECK, #endif diff --git a/src/k_kart.c b/src/k_kart.c index 8a3597f1f..1197706ae 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -2044,7 +2044,7 @@ static fixed_t K_FlameShieldDashVar(INT32 val) return (3*FRACUNIT/4) + (((val * FRACUNIT) / TICRATE) / 2); } -tic_t K_GetSpindashChargeTime(player_t *player) +INT16 K_GetSpindashChargeTime(player_t *player) { // more charge time for higher speed // Tails = 2s, Mighty = 3s, Fang = 4s, Metal = 4s @@ -6788,9 +6788,43 @@ boolean K_PlayerEBrake(player_t *player) && player->powers[pw_nocontrol] == 0; } +static void K_KartSpindashDust(mobj_t *parent) +{ + fixed_t rad = FixedHypot(parent->radius, parent->radius); + INT32 i; + + for (i = 0; i < 2; i++) + { + + fixed_t hmomentum = P_RandomRange(6, 12) * parent->scale; + fixed_t vmomentum = P_RandomRange(2, 6) * parent->scale; + + angle_t ang = parent->player->drawangle + ANGLE_180; + SINT8 flip = 1; + + mobj_t *dust; + + if (i & 1) + ang -= ANGLE_45; + else + ang += ANGLE_45; + + dust = P_SpawnMobjFromMobj(parent, + FixedMul(rad, FINECOSINE(ang >> ANGLETOFINESHIFT)), + FixedMul(rad, FINESINE(ang >> ANGLETOFINESHIFT)), + 0, MT_SPINDASHDUST + ); + flip = P_MobjFlip(dust); + + dust->momx = FixedMul(hmomentum, FINECOSINE(ang >> ANGLETOFINESHIFT)); + dust->momy = FixedMul(hmomentum, FINESINE(ang >> ANGLETOFINESHIFT)); + dust->momz = vmomentum * flip; + } +} + static void K_KartSpindash(player_t *player) { - const tic_t MAXCHARGETIME = K_GetSpindashChargeTime(player); + const INT16 MAXCHARGETIME = K_GetSpindashChargeTime(player); ticcmd_t *cmd = &player->cmd; if (player->kartstuff[k_spindash] > 0 && (cmd->buttons & (BT_DRIFT|BT_BRAKE)) != (BT_DRIFT|BT_BRAKE)) @@ -6817,6 +6851,11 @@ static void K_KartSpindash(player_t *player) S_StartSound(player->mo, sfx_s23c); } + if (player->kartstuff[k_spindashboost] > (TICRATE/2)) + { + K_KartSpindashDust(player->mo); + } + if (K_PlayerEBrake(player) == false) { player->kartstuff[k_spindash] = 0; @@ -6831,24 +6870,36 @@ static void K_KartSpindash(player_t *player) if ((cmd->buttons & (BT_DRIFT|BT_BRAKE)) == (BT_DRIFT|BT_BRAKE)) { INT16 chargetime = MAXCHARGETIME - ++player->kartstuff[k_spindash]; + boolean spawnOldEffect = true; + + if (chargetime <= (MAXCHARGETIME / 2)) + { + K_KartSpindashDust(player->mo); + spawnOldEffect = false; + } + if (chargetime > 0) { UINT16 soundcharge = 0; UINT8 add = 0; + while ((soundcharge += ++add) < chargetime); + if (soundcharge == chargetime) { - K_SpawnDashDustRelease(player); + if (spawnOldEffect == true) + K_SpawnDashDustRelease(player); S_StartSound(player->mo, sfx_s3kab); } } else if (chargetime < -TICRATE) + { P_DamageMobj(player->mo, NULL, NULL, 1, DMG_NORMAL); + } else { if (player->kartstuff[k_spindash] % 4 == 0) { - K_SpawnDashDustRelease(player); K_FlameDashLeftoverSmoke(player->mo); } } diff --git a/src/k_kart.h b/src/k_kart.h index 2c1236368..6fcf7690d 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -77,7 +77,7 @@ void K_StripItems(player_t *player); void K_StripOther(player_t *player); void K_MomentumToFacing(player_t *player); boolean K_ApplyOffroad(player_t *player); -tic_t K_GetSpindashChargeTime(player_t *player); +INT16 K_GetSpindashChargeTime(player_t *player); fixed_t K_GetSpindashChargeSpeed(player_t *player); fixed_t K_GetKartSpeedFromStat(UINT8 kartspeed); fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower); From 39acb46903f65fb640e74d3ebf2c28743d119a57 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sun, 8 Nov 2020 15:32:30 -0500 Subject: [PATCH 096/143] Last 3/4s: Spindash wind --- src/dehacked.c | 2 ++ src/info.c | 29 +++++++++++++++++++++++++++++ src/info.h | 3 +++ src/k_kart.c | 45 ++++++++++++++++++++++++++++++++++++--------- src/p_mobj.c | 3 +++ 5 files changed, 73 insertions(+), 9 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 8f4bd5083..7f6be7e6d 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -9318,6 +9318,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_WATERTRAILUNDERLAY8", "S_SPINDASHDUST", + "S_SPINDASHWIND", #ifdef SEENAMES "S_NAMECHECK", @@ -10400,6 +10401,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_WATERTRAILUNDERLAY", "MT_SPINDASHDUST", + "MT_SPINDASHWIND", #ifdef SEENAMES "MT_NAMECHECK", diff --git a/src/info.c b/src/info.c index 91cb1cb59..ab581d5a4 100644 --- a/src/info.c +++ b/src/info.c @@ -732,6 +732,7 @@ char sprnames[NUMSPRITES + 1][5] = "DBST", // Drift boost plume "SDDS", // Spindash dust + "SDWN", // Spindash wind }; char spr2names[NUMPLAYERSPRITES][5] = @@ -5029,6 +5030,7 @@ state_t states[NUMSTATES] = {SPR_WTRL, FF_TRANS50|FF_PAPERSPRITE|15, 2, {NULL}, 0, 0, S_NULL}, // S_WATERTRAILUNDERLAY8 {SPR_SDDS, FF_ANIMATE, 9, {NULL}, 9, 1, S_NULL}, // S_SPINDASHDUST + {SPR_SDWN, FF_ANIMATE|FF_PAPERSPRITE, 18, {NULL}, 9, 2, S_NULL}, // S_SPINDASHWIND #ifdef SEENAMES {SPR_NULL, 0, 1, {NULL}, 0, 0, S_NULL}, // S_NAMECHECK @@ -28706,6 +28708,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_SPINDASHWIND + -1, // doomednum + S_SPINDASHWIND, // 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 + 12*FRACUNIT, // radius + 24*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY|MF_DONTENCOREMAP, // flags + S_NULL // raisestate + }, + // ============================================================================================================================// #ifdef SEENAMES diff --git a/src/info.h b/src/info.h index b8e2908e2..8e8a05ca3 100644 --- a/src/info.h +++ b/src/info.h @@ -1003,6 +1003,7 @@ typedef enum sprite SPR_DBST, // Drift boost plume SPR_SDDS, // Spindash dust + SPR_SDWN, // Spindash wind SPR_FIRSTFREESLOT, SPR_LASTFREESLOT = SPR_FIRSTFREESLOT + NUMSPRITEFREESLOTS - 1, @@ -5180,6 +5181,7 @@ typedef enum state S_WATERTRAILUNDERLAY8, S_SPINDASHDUST, + S_SPINDASHWIND, #ifdef SEENAMES S_NAMECHECK, @@ -6282,6 +6284,7 @@ typedef enum mobj_type MT_WATERTRAILUNDERLAY, MT_SPINDASHDUST, + MT_SPINDASHWIND, #ifdef SEENAMES MT_NAMECHECK, diff --git a/src/k_kart.c b/src/k_kart.c index 1197706ae..ddbab8fe1 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -6790,12 +6790,11 @@ boolean K_PlayerEBrake(player_t *player) static void K_KartSpindashDust(mobj_t *parent) { - fixed_t rad = FixedHypot(parent->radius, parent->radius); + fixed_t rad = FixedDiv(FixedHypot(parent->radius, parent->radius), parent->scale); INT32 i; for (i = 0; i < 2; i++) { - fixed_t hmomentum = P_RandomRange(6, 12) * parent->scale; fixed_t vmomentum = P_RandomRange(2, 6) * parent->scale; @@ -6822,10 +6821,34 @@ static void K_KartSpindashDust(mobj_t *parent) } } +static void K_KartSpindashWind(mobj_t *parent) +{ + mobj_t *wind = P_SpawnMobjFromMobj(parent, + P_RandomRange(-36,36) * FRACUNIT, + P_RandomRange(-36,36) * FRACUNIT, + FixedDiv(parent->height / 2, parent->scale) + (P_RandomRange(-20,20) * FRACUNIT), + MT_SPINDASHWIND + ); + + P_SetTarget(&wind->target, parent); + + if (parent->momx || parent->momy) + wind->angle = R_PointToAngle2(0, 0, parent->momx, parent->momy); + else + wind->angle = parent->player->drawangle; + + wind->momx = 3 * parent->momx / 4; + wind->momy = 3 * parent->momy / 4; + wind->momz = 3 * parent->momz / 4; + + K_MatchGenericExtraFlags(wind, parent); +} + static void K_KartSpindash(player_t *player) { const INT16 MAXCHARGETIME = K_GetSpindashChargeTime(player); ticcmd_t *cmd = &player->cmd; + boolean spawnWind = (leveltime % 2 == 0); if (player->kartstuff[k_spindash] > 0 && (cmd->buttons & (BT_DRIFT|BT_BRAKE)) != (BT_DRIFT|BT_BRAKE)) { @@ -6851,6 +6874,12 @@ static void K_KartSpindash(player_t *player) S_StartSound(player->mo, sfx_s23c); } + + if ((player->kartstuff[k_spindashboost] > 0) && (spawnWind == true)) + { + K_KartSpindashWind(player->mo); + } + if (player->kartstuff[k_spindashboost] > (TICRATE/2)) { K_KartSpindashDust(player->mo); @@ -6878,6 +6907,11 @@ static void K_KartSpindash(player_t *player) spawnOldEffect = false; } + if (chargetime <= (MAXCHARGETIME / 4) && spawnWind == true) + { + K_KartSpindashWind(player->mo); + } + if (chargetime > 0) { UINT16 soundcharge = 0; @@ -6896,13 +6930,6 @@ static void K_KartSpindash(player_t *player) { P_DamageMobj(player->mo, NULL, NULL, 1, DMG_NORMAL); } - else - { - if (player->kartstuff[k_spindash] % 4 == 0) - { - K_FlameDashLeftoverSmoke(player->mo); - } - } } } else diff --git a/src/p_mobj.c b/src/p_mobj.c index be907321e..1f3648ac1 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -5623,6 +5623,9 @@ static void P_MobjSceneryThink(mobj_t *mobj) if (mobj->tics > 0) mobj->drawflags ^= MFD_DONTDRAW; break; + case MT_SPINDASHWIND: + mobj->drawflags ^= MFD_DONTDRAW; + break; case MT_VWREF: case MT_VWREB: { From ee8fb39974e7f778124715d1f970c9cfeb30a5cd Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 8 Nov 2020 20:14:18 -0800 Subject: [PATCH 097/143] Make all springs MF_NOGRAVITY by default --- src/info.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/info.c b/src/info.c index 5677e4270..5979d2f46 100644 --- a/src/info.c +++ b/src/info.c @@ -8560,7 +8560,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 25*FRACUNIT, // mass 0, // damage sfx_None, // activesound - MF_SOLID|MF_SPRING|MF_DONTENCOREMAP, // flags + MF_SOLID|MF_SPRING|MF_NOGRAVITY|MF_DONTENCOREMAP, // flags S_YELLOWSPRING2 // raisestate }, @@ -8587,7 +8587,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 40*FRACUNIT, // mass 0, // damage sfx_None, // activesound - MF_SOLID|MF_SPRING|MF_DONTENCOREMAP, // flags + MF_SOLID|MF_SPRING|MF_NOGRAVITY|MF_DONTENCOREMAP, // flags S_REDSPRING2 // raisestate }, @@ -8614,7 +8614,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 64*FRACUNIT, // mass 0, // damage sfx_None, // activesound - MF_SOLID|MF_SPRING|MF_DONTENCOREMAP, // flags + MF_SOLID|MF_SPRING|MF_NOGRAVITY|MF_DONTENCOREMAP, // flags S_BLUESPRING2 // raisestate }, @@ -8641,7 +8641,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 15*FRACUNIT, // mass 0, // damage sfx_None, // activesound - MF_SOLID|MF_SPRING|MF_DONTENCOREMAP, // flags + MF_SOLID|MF_SPRING|MF_NOGRAVITY|MF_DONTENCOREMAP, // flags S_GREYSPRING2 // raisestate }, @@ -8668,7 +8668,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 25*FRACUNIT, // mass 25*FRACUNIT, // damage sfx_None, // activesound - MF_SOLID|MF_SPRING|MF_DONTENCOREMAP, // flags + MF_SOLID|MF_SPRING|MF_NOGRAVITY|MF_DONTENCOREMAP, // flags S_YDIAG2 // raisestate }, @@ -8695,7 +8695,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 40*FRACUNIT, // mass 40*FRACUNIT, // damage sfx_None, // activesound - MF_SOLID|MF_SPRING|MF_DONTENCOREMAP, // flags + MF_SOLID|MF_SPRING|MF_NOGRAVITY|MF_DONTENCOREMAP, // flags S_RDIAG2 // raisestate }, @@ -8722,7 +8722,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 64*FRACUNIT, // mass 64*FRACUNIT, // damage sfx_None, // activesound - MF_SOLID|MF_SPRING|MF_DONTENCOREMAP, // flags + MF_SOLID|MF_SPRING|MF_NOGRAVITY|MF_DONTENCOREMAP, // flags S_BDIAG2 // raisestate }, @@ -8749,7 +8749,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 15*FRACUNIT, // mass 15*FRACUNIT, // damage sfx_None, // activesound - MF_SOLID|MF_SPRING|MF_DONTENCOREMAP, // flags + MF_SOLID|MF_SPRING|MF_NOGRAVITY|MF_DONTENCOREMAP, // flags S_GDIAG2 // raisestate }, From d7a0c8ae0a34fbdf554ad73b49083005b843a7af Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 8 Nov 2020 20:15:17 -0800 Subject: [PATCH 098/143] Setting the ambush flag on any MF_SPRING thing toggles MF_NOGRAVITY --- src/p_mobj.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index be907321e..f4c7c3b29 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11594,8 +11594,11 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean static void P_SetAmbush(mobj_t *mobj) { - if (mobj->type == MT_YELLOWDIAG || mobj->type == MT_REDDIAG || mobj->type == MT_BLUEDIAG) - mobj->angle += ANGLE_22h; + if (mobj->flags & MF_SPRING) + { + // gravity toggle + mobj->flags ^= MF_NOGRAVITY; + } if (mobj->flags & MF_NIGHTSITEM) { @@ -11624,9 +11627,6 @@ static void P_SetAmbush(mobj_t *mobj) static void P_SetObjectSpecial(mobj_t *mobj) { - if (mobj->type == MT_YELLOWDIAG || mobj->type == MT_REDDIAG || mobj->type == MT_BLUEDIAG) - mobj->flags |= MF_NOGRAVITY; - if ((mobj->flags & MF_MONITOR) && mobj->info->speed != 0) { // flag for strong/weak random boxes From 8b5a78114ea989d0cf2d84da1a564c9b0bd616f6 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 9 Nov 2020 21:35:08 -0500 Subject: [PATCH 099/143] Hitlag occurs on registered damage instead of being before damage calls --- src/k_collide.c | 32 -------------------------------- src/k_kart.c | 24 ++---------------------- src/p_inter.c | 33 +++++++++++++++++++++++++-------- src/p_map.c | 6 ------ 4 files changed, 27 insertions(+), 68 deletions(-) diff --git a/src/k_collide.c b/src/k_collide.c index f5e9f96b5..00bd9c6b3 100644 --- a/src/k_collide.c +++ b/src/k_collide.c @@ -45,7 +45,6 @@ boolean K_OrbinautJawzCollide(mobj_t *t1, mobj_t *t2) else { // Player Damage - K_SetHitLagForObjects(t1, t2, 10, false); P_DamageMobj(t2, t1, t1->target, 1, DMG_WIPEOUT); K_KartBouncing(t2, t1, false, false); S_StartSound(t2, sfx_s3k7b); @@ -59,7 +58,6 @@ boolean K_OrbinautJawzCollide(mobj_t *t1, mobj_t *t2) || t2->type == MT_BALLHOG) { // Other Item Damage - K_SetHitLagForObjects(t1, t2, 10, false); S_StartSound(t2, t2->info->deathsound); P_KillMobj(t2, t1, t1, DMG_NORMAL); @@ -72,7 +70,6 @@ boolean K_OrbinautJawzCollide(mobj_t *t1, mobj_t *t2) } else if (t2->type == MT_SSMINE_SHIELD || t2->type == MT_SSMINE) { - K_SetHitLagForObjects(t1, t2, 10, false); damageitem = true; // Bomb death P_KillMobj(t2, t1, t1, DMG_NORMAL); @@ -84,7 +81,6 @@ boolean K_OrbinautJawzCollide(mobj_t *t1, mobj_t *t2) } else if (t2->flags & MF_SHOOTABLE) { - K_SetHitLagForObjects(t1, t2, 10, false); // Shootable damage P_DamageMobj(t2, t1, t1->target, 1, DMG_NORMAL); damageitem = true; @@ -141,18 +137,6 @@ boolean K_BananaBallhogCollide(mobj_t *t1, mobj_t *t2) } else { - // Player Damage - if (t1->type == MT_BALLHOG || (t1->type == MT_BANANA && t1->health > 1)) - { - // Long hitlag - K_SetHitLagForObjects(t1, t2, 10, false); - } - else - { - // Short hitlag - K_SetHitLagForObjects(t1, t2, 2, true); - } - P_DamageMobj(t2, t1, t1->target, 1, DMG_NORMAL); } @@ -164,8 +148,6 @@ boolean K_BananaBallhogCollide(mobj_t *t1, mobj_t *t2) || t2->type == MT_BALLHOG) { // Other Item Damage - K_SetHitLagForObjects(t1, t2, 10, false); - S_StartSound(t2, t2->info->deathsound); P_KillMobj(t2, t1, t1, DMG_NORMAL); @@ -179,7 +161,6 @@ boolean K_BananaBallhogCollide(mobj_t *t1, mobj_t *t2) else if (t2->flags & MF_SHOOTABLE) { // Shootable damage - K_SetHitLagForObjects(t1, t2, 10, false); P_DamageMobj(t2, t1, t1->target, 1, DMG_NORMAL); damageitem = true; } @@ -187,8 +168,6 @@ boolean K_BananaBallhogCollide(mobj_t *t1, mobj_t *t2) if (damageitem) { // This Item Damage - K_SetHitLagForObjects(t1, t2, 10, false); - S_StartSound(t1, t1->info->deathsound); P_KillMobj(t1, t2, t2, DMG_NORMAL); @@ -290,7 +269,6 @@ boolean K_MineCollide(mobj_t *t1, mobj_t *t2) if ((t1->state >= &states[S_SSMINE1] && t1->state <= &states[S_SSMINE4]) || (t1->state >= &states[S_SSMINE_DEPLOY8] && t1->state <= &states[S_SSMINE_DEPLOY13])) { - K_SetHitLagForObjects(t1, t2, 10, false); P_KillMobj(t1, t2, t2, DMG_NORMAL); } else @@ -302,8 +280,6 @@ boolean K_MineCollide(mobj_t *t1, mobj_t *t2) else if (t2->type == MT_ORBINAUT || t2->type == MT_JAWZ || t2->type == MT_JAWZ_DUD || t2->type == MT_ORBINAUT_SHIELD || t2->type == MT_JAWZ_SHIELD) { - K_SetHitLagForObjects(t1, t2, 10, false); - // Bomb death P_KillMobj(t1, t2, t2, DMG_NORMAL); @@ -316,7 +292,6 @@ boolean K_MineCollide(mobj_t *t1, mobj_t *t2) } else if (t2->flags & MF_SHOOTABLE) { - K_SetHitLagForObjects(t1, t2, 10, false); // Bomb death P_KillMobj(t1, t2, t2, DMG_NORMAL); // Shootable damage @@ -335,19 +310,16 @@ boolean K_MineExplosionCollide(mobj_t *t1, mobj_t *t2) if (t1->state == &states[S_MINEEXPLOSION1]) { - K_SetHitLagForObjects(t1, t2, 10, false); P_DamageMobj(t2, t1, t1->target, 1, DMG_EXPLODE); } else { - K_SetHitLagForObjects(t1, t2, 2, true); P_DamageMobj(t2, t1, t1->target, 1, DMG_NORMAL); } } else if (t2->flags & MF_SHOOTABLE) { // Shootable damage - K_SetHitLagForObjects(t1, t2, 10, false); P_DamageMobj(t2, t1, t1->target, 1, DMG_NORMAL); } @@ -364,8 +336,6 @@ boolean K_KitchenSinkCollide(mobj_t *t1, mobj_t *t2) if (t2->player->powers[pw_flashing] > 0 && t2->hitlag == 0) return true; - K_SetHitLagForObjects(t1, t2, 10, false); - S_StartSound(NULL, sfx_bsnipe); // let all players hear it. HU_SetCEchoFlags(0); @@ -378,8 +348,6 @@ boolean K_KitchenSinkCollide(mobj_t *t1, mobj_t *t2) } else if (t2->flags & MF_SHOOTABLE) { - K_SetHitLagForObjects(t1, t2, 10, false); - // Shootable damage P_KillMobj(t2, t2, t1->target, DMG_NORMAL); // This item damage diff --git a/src/k_kart.c b/src/k_kart.c index 68f8c70c6..2cdb731cd 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -2384,8 +2384,8 @@ void K_SetHitLagForObjects(mobj_t *mo1, mobj_t *mo2, INT32 tics, boolean fixed) const fixed_t ticaddfactor = mapobjectscale * 8; const INT32 mintics = tics; - const fixed_t mo1speed = P_AproxDistance(P_AproxDistance(mo1->momx, mo1->momy), mo1->momz); - const fixed_t mo2speed = P_AproxDistance(P_AproxDistance(mo2->momx, mo2->momy), mo2->momz); + const fixed_t mo1speed = FixedHypot(FixedHypot(mo1->momx, mo1->momy), mo1->momz); + const fixed_t mo2speed = FixedHypot(FixedHypot(mo2->momx, mo2->momy), mo2->momz); const fixed_t speeddiff = mo2speed - mo1speed; const fixed_t scalediff = mo2->scale - mo1->scale; @@ -2423,26 +2423,6 @@ void K_SetHitLagForObjects(mobj_t *mo1, mobj_t *mo2, INT32 tics, boolean fixed) } } - if (mo1->player && !mo2->player) - { - if (mo1->player->powers[pw_flashing] > 0 - || mo1->player->kartstuff[k_invincibilitytimer] > 0 - || mo1->player->kartstuff[k_growshrinktimer] > 0) - { - tics1 = 0; - } - } - - if (mo2->player && !mo1->player) - { - if (mo2->player->powers[pw_flashing] > 0 - || mo2->player->kartstuff[k_invincibilitytimer] > 0 - || mo2->player->kartstuff[k_growshrinktimer] > 0) - { - tics2 = 0; - } - } - //CONS_Printf("tics1: %d, tics2: %d\n", tics1, tics2); mo1->hitlag += tics1; diff --git a/src/p_inter.c b/src/p_inter.c index b0dd45156..cc6bb89e7 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1075,6 +1075,8 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget if (LUAh_MobjDeath(target, inflictor, source, damagetype) || P_MobjWasRemoved(target)) return; + //K_SetHitLagForObjects(target, inflictor, 15, false); + // SRB2kart // I wish I knew a better way to do this if (target->target && target->target->player && target->target->player->mo) @@ -1646,8 +1648,10 @@ static boolean P_PlayerHitsPlayer(mobj_t *target, mobj_t *inflictor, mobj_t *sou return true; } -static boolean P_KillPlayer(player_t *player, UINT8 type) +static boolean P_KillPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 type) { + (void)source; + if (player->exiting) { player->mo->destscale = 1; @@ -1668,6 +1672,8 @@ static boolean P_KillPlayer(player_t *player, UINT8 type) break; } + K_SetHitLagForObjects(player->mo, inflictor, 15, false); + player->pflags &= ~PF_SLIDING; player->powers[pw_carry] = CR_NONE; @@ -1753,6 +1759,9 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da player_t *player; boolean force = false; + INT32 laglength = 2; + boolean lagfixed = true; + if (objectplacing) return false; @@ -1760,13 +1769,16 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da return false; // Spectator handling - if (multiplayer) - { - if (damagetype != DMG_SPECTATOR && target->player && target->player->spectator) - return false; + if (damagetype != DMG_SPECTATOR && target->player && target->player->spectator) + return false; - if (source && source->player && source->player->spectator) - return false; + if (source && source->player && source->player->spectator) + return false; + + if ((damagetype & DMG_TYPEMASK) != DMG_NORMAL && (damagetype & DMG_TYPEMASK) != DMG_STING) + { + laglength = 10; + lagfixed = false; } // Everything above here can't be forced. @@ -1830,7 +1842,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da // Instant-Death if ((damagetype & DMG_DEATHMASK)) { - if (!P_KillPlayer(player, damagetype)) + if (!P_KillPlayer(player, inflictor, source, damagetype)) return false; } else if (LUAh_MobjDamage(target, inflictor, source, damage, damagetype)) @@ -1941,6 +1953,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da } player->kartstuff[k_instashield] = 15; + K_SetHitLagForObjects(target, inflictor, laglength, lagfixed); return true; } } @@ -1962,12 +1975,16 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da if (source && source->player && target) G_GhostAddHit((INT32) (source->player - players), target); + K_SetHitLagForObjects(target, inflictor, laglength, lagfixed); + if (target->health <= 0) { P_KillMobj(target, inflictor, source, damagetype); return true; } + //K_SetHitLagForObjects(target, inflictor, laglength, lagfixed); + if (player) P_ResetPlayer(target->player); else diff --git a/src/p_map.c b/src/p_map.c index 376d70f20..48e274ebb 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1218,34 +1218,28 @@ static boolean PIT_CheckThing(mobj_t *thing) { if (tmthing->scale > thing->scale + (mapobjectscale/8)) // SRB2kart - Handle squishes first! { - K_SetHitLagForObjects(tmthing, thing, 10, false); P_DamageMobj(thing, tmthing, tmthing, 1, DMG_SQUISH); } else if (thing->scale > tmthing->scale + (mapobjectscale/8)) { - K_SetHitLagForObjects(thing, tmthing, 10, false); P_DamageMobj(tmthing, thing, thing, 1, DMG_SQUISH); } else if (tmthing->player->kartstuff[k_invincibilitytimer] && !thing->player->kartstuff[k_invincibilitytimer]) // SRB2kart - Then invincibility! { - K_SetHitLagForObjects(tmthing, thing, 10, false); P_DamageMobj(thing, tmthing, tmthing, 1, DMG_WIPEOUT); } else if (thing->player->kartstuff[k_invincibilitytimer] && !tmthing->player->kartstuff[k_invincibilitytimer]) { - K_SetHitLagForObjects(thing, tmthing, 10, false); P_DamageMobj(tmthing, thing, thing, 1, DMG_WIPEOUT); } else if ((tmthing->player->kartstuff[k_flamedash] && tmthing->player->kartstuff[k_itemtype] == KITEM_FLAMESHIELD) && !(thing->player->kartstuff[k_flamedash] && thing->player->kartstuff[k_itemtype] == KITEM_FLAMESHIELD)) // SRB2kart - Then flame shield! { - K_SetHitLagForObjects(tmthing, thing, 10, false); P_DamageMobj(thing, tmthing, tmthing, 1, DMG_WIPEOUT); } else if ((thing->player->kartstuff[k_flamedash] && thing->player->kartstuff[k_itemtype] == KITEM_FLAMESHIELD) && !(tmthing->player->kartstuff[k_flamedash] && tmthing->player->kartstuff[k_itemtype] == KITEM_FLAMESHIELD)) { - K_SetHitLagForObjects(thing, tmthing, 10, false); P_DamageMobj(tmthing, thing, thing, 1, DMG_WIPEOUT); } } From 1f1607cc6d2367d1fb6e41a033d5a020dda78943 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 10 Nov 2020 19:49:21 -0500 Subject: [PATCH 100/143] This was lost --- src/m_swap.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/m_swap.h b/src/m_swap.h index c1e5e39b7..faa54e0b2 100644 --- a/src/m_swap.h +++ b/src/m_swap.h @@ -44,4 +44,13 @@ #define MSBF_LONG SWAP_LONG #endif +// Big to little endian +#ifdef SRB2_LITTLE_ENDIAN + #define BIGENDIAN_LONG(x) ((INT32)(((x)>>24)&0xff)|(((x)<<8)&0xff0000)|(((x)>>8)&0xff00)|(((x)<<24)&0xff000000)) + #define BIGENDIAN_SHORT(x) ((INT16)(((x)>>8)|((x)<<8))) +#else + #define BIGENDIAN_LONG(x) ((INT32)(x)) + #define BIGENDIAN_SHORT(x) ((INT16)(x)) +#endif + #endif From 454fc41b713951fc15a659981cb71dc37e28a9c8 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 10 Nov 2020 20:31:50 -0500 Subject: [PATCH 101/143] Increase BACKUPTICS --- src/d_clisrv.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d_clisrv.h b/src/d_clisrv.h index c6d83fa1a..013990325 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -37,7 +37,7 @@ applications may follow different packet versions. // be transmitted. // Networking and tick handling related. -#define BACKUPTICS 32 +#define BACKUPTICS 1024 #define TICQUEUE 512 // more than enough for most timeouts.... #define MAXTEXTCMD 256 // From 5f12dd156c479e7be0161393d50d88f58c37c608 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 10 Nov 2020 21:49:11 -0500 Subject: [PATCH 102/143] Fix hitlag crashing for level damage --- src/k_kart.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index bc275e19c..0df4cacd2 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -2376,10 +2376,13 @@ angle_t K_MomentumAngle(mobj_t *mo) void K_SetHitLagForObjects(mobj_t *mo1, mobj_t *mo2, INT32 tics, boolean fixed) { + boolean mo1valid = (mo1 && !P_MobjWasRemoved(mo1)); + boolean mo2valid = (mo2 && !P_MobjWasRemoved(mo2)); + INT32 tics1 = tics; INT32 tics2 = tics; - if (fixed == false) + if (mo1valid == true && mo2valid == true && fixed == false) { const fixed_t ticaddfactor = mapobjectscale * 8; const INT32 mintics = tics; @@ -2425,8 +2428,15 @@ void K_SetHitLagForObjects(mobj_t *mo1, mobj_t *mo2, INT32 tics, boolean fixed) //CONS_Printf("tics1: %d, tics2: %d\n", tics1, tics2); - mo1->hitlag += tics1; - mo2->hitlag += tics2; + if (mo1valid == true) + { + mo1->hitlag += tics1; + } + + if (mo2valid == true) + { + mo2->hitlag += tics2; + } } void K_DoInstashield(player_t *player) From c86d496fefb012653ec35c7b76172eda5cee0f0f Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 10 Nov 2020 23:02:58 -0500 Subject: [PATCH 103/143] Removed fixed length hit lag --- src/k_collide.c | 2 +- src/k_kart.c | 4 ++-- src/k_kart.h | 2 +- src/p_inter.c | 14 ++++++-------- 4 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/k_collide.c b/src/k_collide.c index 00bd9c6b3..13b17e981 100644 --- a/src/k_collide.c +++ b/src/k_collide.c @@ -273,7 +273,7 @@ boolean K_MineCollide(mobj_t *t1, mobj_t *t2) } else { - K_SetHitLagForObjects(t1, t2, 2, true); + K_SetHitLagForObjects(t1, t2, 2); K_PuntMine(t1, t2); } } diff --git a/src/k_kart.c b/src/k_kart.c index 0df4cacd2..8512649b3 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -2374,7 +2374,7 @@ angle_t K_MomentumAngle(mobj_t *mo) } } -void K_SetHitLagForObjects(mobj_t *mo1, mobj_t *mo2, INT32 tics, boolean fixed) +void K_SetHitLagForObjects(mobj_t *mo1, mobj_t *mo2, INT32 tics) { boolean mo1valid = (mo1 && !P_MobjWasRemoved(mo1)); boolean mo2valid = (mo2 && !P_MobjWasRemoved(mo2)); @@ -2382,7 +2382,7 @@ void K_SetHitLagForObjects(mobj_t *mo1, mobj_t *mo2, INT32 tics, boolean fixed) INT32 tics1 = tics; INT32 tics2 = tics; - if (mo1valid == true && mo2valid == true && fixed == false) + if (mo1valid == true && mo2valid == true) { const fixed_t ticaddfactor = mapobjectscale * 8; const INT32 mintics = tics; diff --git a/src/k_kart.h b/src/k_kart.h index dd390f362..408ed3303 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -40,7 +40,7 @@ void K_KartPlayerHUDUpdate(player_t *player); void K_KartPlayerThink(player_t *player, ticcmd_t *cmd); void K_KartPlayerAfterThink(player_t *player); angle_t K_MomentumAngle(mobj_t *mo); -void K_SetHitLagForObjects(mobj_t *mo1, mobj_t *mo2, INT32 tics, boolean fixed); +void K_SetHitLagForObjects(mobj_t *mo1, mobj_t *mo2, INT32 tics); void K_DoInstashield(player_t *player); void K_BattleHitPlayer(player_t *player, player_t *victim, UINT8 points, boolean reducewanted); void K_RemoveBumper(player_t *player, mobj_t *inflictor, mobj_t *source); diff --git a/src/p_inter.c b/src/p_inter.c index cc6bb89e7..499ba5713 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1075,7 +1075,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget if (LUAh_MobjDeath(target, inflictor, source, damagetype) || P_MobjWasRemoved(target)) return; - //K_SetHitLagForObjects(target, inflictor, 15, false); + //K_SetHitLagForObjects(target, inflictor, 15); // SRB2kart // I wish I knew a better way to do this @@ -1672,7 +1672,7 @@ static boolean P_KillPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, break; } - K_SetHitLagForObjects(player->mo, inflictor, 15, false); + K_SetHitLagForObjects(player->mo, inflictor, 15); player->pflags &= ~PF_SLIDING; player->powers[pw_carry] = CR_NONE; @@ -1759,8 +1759,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da player_t *player; boolean force = false; - INT32 laglength = 2; - boolean lagfixed = true; + INT32 laglength = 3; if (objectplacing) return false; @@ -1778,7 +1777,6 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da if ((damagetype & DMG_TYPEMASK) != DMG_NORMAL && (damagetype & DMG_TYPEMASK) != DMG_STING) { laglength = 10; - lagfixed = false; } // Everything above here can't be forced. @@ -1953,7 +1951,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da } player->kartstuff[k_instashield] = 15; - K_SetHitLagForObjects(target, inflictor, laglength, lagfixed); + K_SetHitLagForObjects(target, inflictor, laglength); return true; } } @@ -1975,7 +1973,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da if (source && source->player && target) G_GhostAddHit((INT32) (source->player - players), target); - K_SetHitLagForObjects(target, inflictor, laglength, lagfixed); + K_SetHitLagForObjects(target, inflictor, laglength); if (target->health <= 0) { @@ -1983,7 +1981,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da return true; } - //K_SetHitLagForObjects(target, inflictor, laglength, lagfixed); + //K_SetHitLagForObjects(target, inflictor, laglength); if (player) P_ResetPlayer(target->player); From da59009ba196cdbb642814ec9e24d849d6230459 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 10 Nov 2020 23:12:17 -0500 Subject: [PATCH 104/143] More extreme hitlag vibration --- src/hardware/hw_main.c | 4 ++-- src/hardware/hw_md2.c | 2 +- src/r_things.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index c8905c689..5f1d3e74f 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -3640,7 +3640,7 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale) // hitlag vibrating if (thing->hitlag > 0) { - fixed_t mul = thing->hitlag * (FRACUNIT / 20); + fixed_t mul = thing->hitlag * (FRACUNIT / 10); if (leveltime & 1) { @@ -4925,7 +4925,7 @@ static void HWR_ProjectSprite(mobj_t *thing) // hitlag vibrating if (thing->hitlag > 0) { - fixed_t mul = thing->hitlag * (FRACUNIT / 20); + fixed_t mul = thing->hitlag * (FRACUNIT / 10); if (leveltime & 1) { diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 0a39092f4..f68771a1b 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1361,7 +1361,7 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) // hitlag vibrating if (spr->mobj->hitlag > 0) { - fixed_t mul = spr->mobj->hitlag * (FRACUNIT / 20); + fixed_t mul = spr->mobj->hitlag * (FRACUNIT / 10); if (leveltime & 1) { diff --git a/src/r_things.c b/src/r_things.c index d337bd219..9788d916b 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1467,7 +1467,7 @@ static void R_ProjectSprite(mobj_t *thing) // hitlag vibrating if (thing->hitlag > 0) { - fixed_t mul = thing->hitlag * (FRACUNIT / 20); + fixed_t mul = thing->hitlag * (FRACUNIT / 10); if (leveltime & 1) { From bd495c7f55130ad9380f94707564bb57636984a7 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 10 Nov 2020 23:13:32 -0500 Subject: [PATCH 105/143] Increase hitlag for bananas from 2 to 5, use 10 for normal damage by default instead Ballhogs & Lightning Shield get intense hitlag again --- src/p_inter.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index 499ba5713..acd8f0433 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1759,7 +1759,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da player_t *player; boolean force = false; - INT32 laglength = 3; + INT32 laglength = 10; if (objectplacing) return false; @@ -1774,9 +1774,10 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da if (source && source->player && source->player->spectator) return false; - if ((damagetype & DMG_TYPEMASK) != DMG_NORMAL && (damagetype & DMG_TYPEMASK) != DMG_STING) + if (((damagetype & DMG_TYPEMASK) == DMG_STING) + || (inflictor->type == MT_BANANA && inflictor->health <= 1)) { - laglength = 10; + laglength = 5; } // Everything above here can't be forced. From 4abb14a158fc80518822668ec52febec59de633c Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 10 Nov 2020 23:22:05 -0500 Subject: [PATCH 106/143] Check for null --- src/p_inter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_inter.c b/src/p_inter.c index acd8f0433..efa3d3eaa 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1775,7 +1775,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da return false; if (((damagetype & DMG_TYPEMASK) == DMG_STING) - || (inflictor->type == MT_BANANA && inflictor->health <= 1)) + || ((inflictor && !P_MobjWasRemoved(inflictor)) && inflictor->type == MT_BANANA && inflictor->health <= 1)) { laglength = 5; } From 87e3dd518b12c5ebcb8f1306cc4238313e520089 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 10 Nov 2020 23:42:30 -0500 Subject: [PATCH 107/143] Don't set hitlag for punted mines multiple times --- src/k_collide.c | 1 - src/k_kart.c | 5 +++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/k_collide.c b/src/k_collide.c index 13b17e981..7fbe17603 100644 --- a/src/k_collide.c +++ b/src/k_collide.c @@ -273,7 +273,6 @@ boolean K_MineCollide(mobj_t *t1, mobj_t *t2) } else { - K_SetHitLagForObjects(t1, t2, 2); K_PuntMine(t1, t2); } } diff --git a/src/k_kart.c b/src/k_kart.c index 8512649b3..117136fb9 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -3816,6 +3816,9 @@ void K_PuntMine(mobj_t *thismine, mobj_t *punter) if (!mine || P_MobjWasRemoved(mine)) return; + if (mine->threshold > 0 || mine->hitlag > 0) + return; + spd = (82 + ((gamespeed-1) * 14))*mapobjectscale; // Avg Speed is 41 in Normal mine->flags |= MF_NOCLIPTHING; @@ -3825,6 +3828,8 @@ void K_PuntMine(mobj_t *thismine, mobj_t *punter) mine->extravalue1 = 0; mine->reactiontime = mine->info->reactiontime; + K_SetHitLagForObjects(punter, mine, 5); + mine->momx = punter->momx + FixedMul(FINECOSINE(fa), spd); mine->momy = punter->momy + FixedMul(FINESINE(fa), spd); mine->momz = P_MobjFlip(mine) * z; From 94eca0f92843a0fea0fd87d1ee88e6b4ce431a60 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 10 Nov 2020 23:50:59 -0500 Subject: [PATCH 108/143] Don't explode mines multiple times while they're in hitlag --- src/k_kart.c | 2 +- src/p_enemy.c | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/k_kart.c b/src/k_kart.c index 117136fb9..e35b9ff56 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -2815,7 +2815,7 @@ void K_SpawnMineExplosion(mobj_t *source, UINT8 color) if (!bombflashtimer && P_CheckSight(p->mo, source)) { bombflashtimer = TICRATE*2; - P_FlashPal(p, 1, 1); + P_FlashPal(p, PAL_WHITE, 1); } break; // we can break right now because quakes are global to all split players somehow. } diff --git a/src/p_enemy.c b/src/p_enemy.c index 78d6f0668..bc925d4aa 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -4457,6 +4457,9 @@ void A_GrenadeRing(mobj_t *actor) if (actor->flags2 & MF2_DEBRIS) return; + if (actor->hitlag > 0) + return; + if (actor->state == &states[S_SSMINE_DEPLOY8]) explodedist = (3*explodedist)/2; @@ -4524,6 +4527,9 @@ void A_SSMineExplode(mobj_t *actor) if (actor->flags2 & MF2_DEBRIS) return; + if (actor->hitlag > 0) + return; + type = (mobjtype_t)locvar1; // Use blockmap to check for nearby shootables From c8d4ef64f986bea422717695b9cbd0086bf77c3d Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 12 Nov 2020 17:07:19 -0800 Subject: [PATCH 109/143] Hole punching --- src/d_clisrv.c | 25 +++++++++ src/d_net.c | 5 ++ src/i_net.h | 17 +++++++ src/i_tcp.c | 134 ++++++++++++++++++++++++++++++++++++++++--------- src/mserv.c | 2 + src/mserv.h | 1 + 6 files changed, 161 insertions(+), 23 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index a3f7b2522..16b850a4b 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1990,6 +1990,8 @@ static void SendAskInfo(INT32 node) // now allowed traffic from the host to us in, so once the MS relays // our address to the host, it'll be able to speak to us. HSendPacket(node, false, 0, sizeof (askinfo_pak)); + + I_NetRequestHolePunch(); } serverelem_t serverlist[MAXSERVERLIST]; @@ -6092,6 +6094,19 @@ static void UpdatePingTable(void) } } +static void RenewHolePunch(void) +{ + static time_t past; + + const time_t now = time(NULL); + + if ((now - past) > 20) + { + I_NetRegisterHolePunch(); + past = now; + } +} + // Handle timeouts to prevent definitive freezes from happenning static void HandleNodeTimeouts(void) { @@ -6130,6 +6145,11 @@ void NetKeepAlive(void) MasterClient_Ticker(); #endif + if (serverrunning) + { + RenewHolePunch(); + } + if (client) { // send keep alive @@ -6189,6 +6209,11 @@ void NetUpdate(void) MasterClient_Ticker(); // Acking the Master Server #endif + if (serverrunning) + { + RenewHolePunch(); + } + if (client) { if (!resynch_local_inprogress) diff --git a/src/d_net.c b/src/d_net.c index d4e1f4d03..8af1889bc 100644 --- a/src/d_net.c +++ b/src/d_net.c @@ -49,6 +49,8 @@ tic_t connectiontimeout = (10*TICRATE); doomcom_t *doomcom = NULL; /// \brief network packet data, points inside doomcom doomdata_t *netbuffer = NULL; +/// \brief hole punching packet, also points inside doomcom +holepunch_t *holepunchpacket = NULL; #ifdef DEBUGFILE FILE *debugfile = NULL; // put some net info in a file during the game @@ -72,6 +74,8 @@ boolean (*I_NetCanGet)(void) = NULL; void (*I_NetCloseSocket)(void) = NULL; void (*I_NetFreeNodenum)(INT32 nodenum) = NULL; SINT8 (*I_NetMakeNodewPort)(const char *address, const char* port) = NULL; +void (*I_NetRequestHolePunch)(void) = NULL; +void (*I_NetRegisterHolePunch)(void) = NULL; boolean (*I_NetOpenSocket)(void) = NULL; boolean (*I_Ban) (INT32 node) = NULL; void (*I_ClearBans)(void) = NULL; @@ -1347,6 +1351,7 @@ boolean D_CheckNetGame(void) I_Error("Too many nodes (%d), max:%d", doomcom->numnodes, MAXNETNODES); netbuffer = (doomdata_t *)(void *)&doomcom->data; + holepunchpacket = (holepunch_t *)(void *)&doomcom->data; #ifdef DEBUGFILE if (M_CheckParm("-debugfile")) diff --git a/src/i_net.h b/src/i_net.h index 5d93f191e..8caa0edcc 100644 --- a/src/i_net.h +++ b/src/i_net.h @@ -77,11 +77,19 @@ typedef struct char data[MAXPACKETLENGTH]; } ATTRPACK doomcom_t; +typedef struct +{ + INT32 magic; + INT32 addr; + INT16 port; +} ATTRPACK holepunch_t; + #if defined(_MSC_VER) #pragma pack() #endif extern doomcom_t *doomcom; +extern holepunch_t *holepunchpacket; /** \brief return packet in doomcom struct */ @@ -140,6 +148,15 @@ extern boolean (*I_NetOpenSocket)(void); extern void (*I_NetCloseSocket)(void); +/** \brief send a hole punching request +*/ +extern void (*I_NetRequestHolePunch)(void); + +/** \brief register this machine on the hole punching server +*/ +extern void (*I_NetRegisterHolePunch)(void); + + extern boolean (*I_Ban) (INT32 node); extern void (*I_ClearBans)(void); extern const char *(*I_GetNodeAddress) (INT32 node); diff --git a/src/i_tcp.c b/src/i_tcp.c index a9ffe5f3b..e99672d14 100644 --- a/src/i_tcp.c +++ b/src/i_tcp.c @@ -204,6 +204,7 @@ static size_t broadcastaddresses = 0; static boolean nodeconnected[MAXNETNODES+1]; static mysockaddr_t banned[MAXBANS]; static UINT8 bannedmask[MAXBANS]; +static const INT32 hole_punch_magic = MSBF_LONG (0x52eb11); #endif static size_t numbans = 0; @@ -560,6 +561,27 @@ void Command_Numnodes(void) #endif #ifndef NONET +static boolean hole_punch(ssize_t c) +{ + if (c == 10 && holepunchpacket->magic == hole_punch_magic) + { + mysockaddr_t addr; + addr.ip4.sin_family = AF_INET; + addr.ip4.sin_addr.s_addr = holepunchpacket->addr; + addr.ip4.sin_port = holepunchpacket->port; + sendto(mysockets[0], NULL, 0, 0, &addr.any, sizeof addr.ip4); + + CONS_Debug(DBG_NETPLAY, + "hole punching request from %s\n", SOCK_AddrToStr(&addr)); + + return true; + } + else + { + return false; + } +} + // Returns true if a packet was received from a new node, false in all other cases static boolean SOCK_Get(void) { @@ -583,6 +605,11 @@ static boolean SOCK_Get(void) } #endif + if (hole_punch(c)) + { + return false; + } + // find remote node number for (j = 1; j <= MAXNETNODES; j++) //include LAN { @@ -1265,17 +1292,14 @@ void I_ShutdownTcpDriver(void) } #ifndef NONET -static SINT8 SOCK_NetMakeNodewPort(const char *address, const char *port) +static boolean SOCK_GetAddr(struct sockaddr_in *sin, const char *address, const char *port, boolean test) { - SINT8 newnode = -1; struct my_addrinfo *ai = NULL, *runp, hints; int gaie; - if (!port || !port[0]) + if (!port || !port[0]) port = DEFAULTPORT; - DEBFILE(va("Creating new node: %s@%s\n", address, port)); - memset (&hints, 0x00, sizeof (hints)); hints.ai_flags = 0; hints.ai_family = AF_UNSPEC; @@ -1283,30 +1307,91 @@ static SINT8 SOCK_NetMakeNodewPort(const char *address, const char *port) hints.ai_protocol = IPPROTO_UDP; gaie = I_getaddrinfo(address, port, &hints, &ai); - if (gaie == 0) - { - newnode = getfreenode(); - } - if (newnode == -1) + + if (gaie != 0) { I_freeaddrinfo(ai); - return -1; + return false; + } + + runp = ai; + + if (test) + { + while (runp != NULL) + { + if (sendto(mysockets[0], NULL, 0, 0, runp->ai_addr, runp->ai_addrlen) == 0) + break; + + runp = runp->ai_next; + } + } + + if (runp != NULL) + memcpy(sin, runp->ai_addr, runp->ai_addrlen); + + I_freeaddrinfo(ai); + + return (runp != NULL); +} + +static SINT8 SOCK_NetMakeNodewPort(const char *address, const char *port) +{ + SINT8 newnode = getfreenode(); + + DEBFILE(va("Creating new node: %s@%s\n", address, port)); + + if (newnode != -1) + { + if (!SOCK_GetAddr(&clientaddress[newnode].ip4, address, port, true)) + { + nodeconnected[newnode] = false; + return -1; + } + } + + return newnode; +} + +static void rendezvous(int size) +{ + char *addrs = strdup(cv_rendezvousserver.string); + + char *host = strtok(addrs, ":"); + char *port = strtok(NULL, ":"); + + mysockaddr_t rzv; + + if (SOCK_GetAddr(&rzv.ip4, host, (port ? port : "7777"), false)) + { + holepunchpacket->magic = hole_punch_magic; + sendto(mysockets[0], doomcom->data, size, 0, &rzv.any, sizeof rzv.ip4); } else - runp = ai; - - while (runp != NULL) { - // find ip of the server - if (sendto(mysockets[0], NULL, 0, 0, runp->ai_addr, runp->ai_addrlen) == 0) - { - memcpy(&clientaddress[newnode], runp->ai_addr, runp->ai_addrlen); - break; - } - runp = runp->ai_next; + CONS_Alert(CONS_ERROR, "Failed to contact rendezvous server (%s).\n", + cv_rendezvousserver.string); } - I_freeaddrinfo(ai); - return newnode; + + free(addrs); +} + +static void SOCK_RequestHolePunch(void) +{ + mysockaddr_t * addr = &clientaddress[doomcom->remotenode]; + + holepunchpacket->addr = addr->ip4.sin_addr.s_addr; + holepunchpacket->port = addr->ip4.sin_port; + + CONS_Debug(DBG_NETPLAY, + "requesting hole punch to node %s\n", SOCK_AddrToStr(addr)); + + rendezvous(10); +} + +static void SOCK_RegisterHolePunch(void) +{ + rendezvous(4); } #endif @@ -1333,6 +1418,9 @@ static boolean SOCK_OpenSocket(void) I_NetCanGet = SOCK_CanGet; #endif + I_NetRequestHolePunch = SOCK_RequestHolePunch; + I_NetRegisterHolePunch = SOCK_RegisterHolePunch; + // build the socket but close it first SOCK_CloseSocket(); return UDP_Socket(); diff --git a/src/mserv.c b/src/mserv.c index 88cede440..c91c59167 100644 --- a/src/mserv.c +++ b/src/mserv.c @@ -68,6 +68,7 @@ static CV_PossibleValue_t masterserver_update_rate_cons_t[] = { }; consvar_t cv_masterserver = CVAR_INIT ("masterserver", "https://ms.kartkrew.org/ms/api", CV_SAVE|CV_CALL, NULL, MasterServer_OnChange); +consvar_t cv_rendezvousserver = CVAR_INIT ("rendezvousserver", "jart-dev.jameds.org", CV_SAVE, NULL, NULL); consvar_t cv_servername = CVAR_INIT ("servername", "SRB2Kart server", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Update_parameters); consvar_t cv_server_contact = CVAR_INIT ("server_contact", "", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Update_parameters); @@ -99,6 +100,7 @@ void AddMServCommands(void) CV_RegisterVar(&cv_masterserver_debug); CV_RegisterVar(&cv_masterserver_token); CV_RegisterVar(&cv_advertise); + CV_RegisterVar(&cv_rendezvousserver); CV_RegisterVar(&cv_servername); CV_RegisterVar(&cv_server_contact); #ifdef MASTERSERVER diff --git a/src/mserv.h b/src/mserv.h index 2a0afd1b3..eb1152876 100644 --- a/src/mserv.h +++ b/src/mserv.h @@ -58,6 +58,7 @@ extern consvar_t cv_masterserver_update_rate; extern consvar_t cv_masterserver_timeout; extern consvar_t cv_masterserver_debug; extern consvar_t cv_masterserver_token; +extern consvar_t cv_rendezvousserver; extern consvar_t cv_advertise; From b4e6bc6e67c679cadef07a905781fbf0e1d603c2 Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 12 Nov 2020 17:07:34 -0800 Subject: [PATCH 110/143] Ignore zero length packets --- src/i_tcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i_tcp.c b/src/i_tcp.c index e99672d14..483062793 100644 --- a/src/i_tcp.c +++ b/src/i_tcp.c @@ -596,7 +596,7 @@ static boolean SOCK_Get(void) fromlen = (socklen_t)sizeof(fromaddress); c = recvfrom(mysockets[n], (char *)&doomcom->data, MAXPACKETLENGTH, 0, (void *)&fromaddress, &fromlen); - if (c != ERRSOCKET) + if (c > 0) { #ifdef USE_STUN if (STUN_got_response(doomcom->data, c)) From ed96a8b43234b19c1e13010bb2e87515c77b0292 Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 12 Nov 2020 17:31:16 -0800 Subject: [PATCH 111/143] Don't request hole punch to self, and don't register local server for hole punching --- src/d_clisrv.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 16b850a4b..e4e19d259 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1991,7 +1991,8 @@ static void SendAskInfo(INT32 node) // our address to the host, it'll be able to speak to us. HSendPacket(node, false, 0, sizeof (askinfo_pak)); - I_NetRequestHolePunch(); + if (node != 0 && node != BROADCASTADDR) + I_NetRequestHolePunch(); } serverelem_t serverlist[MAXSERVERLIST]; @@ -6145,7 +6146,7 @@ void NetKeepAlive(void) MasterClient_Ticker(); #endif - if (serverrunning) + if (netgame && serverrunning) { RenewHolePunch(); } @@ -6209,7 +6210,7 @@ void NetUpdate(void) MasterClient_Ticker(); // Acking the Master Server #endif - if (serverrunning) + if (netgame && serverrunning) { RenewHolePunch(); } From 3a57e8eca5ff1b1f9e290c801f80282cb1e6b264 Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 13 Nov 2020 00:51:13 -0800 Subject: [PATCH 112/143] Don't use drawflags for drawing precipitation in opengl drawflags does not exist in precipmobj_t --- src/hardware/hw_main.c | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 5f1d3e74f..fd131fa26 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -4278,20 +4278,10 @@ static inline void HWR_DrawPrecipitationSprite(gl_vissprite_t *spr) UINT8 brightmode = 0; extracolormap_t *colormap = sector->extra_colormap; - if (spr->mobj->drawflags & MFD_BRIGHTMASK) - { - if (spr->mobj->drawflags & MFD_FULLBRIGHT) - brightmode = 1; - else if (spr->mobj->drawflags & MFD_SEMIBRIGHT) - brightmode = 2; - } - else - { - if (spr->mobj->frame & FF_FULLBRIGHT) - brightmode = 1; - else if (spr->mobj->frame & FF_SEMIBRIGHT) - brightmode = 2; - } + if (spr->mobj->frame & FF_FULLBRIGHT) + brightmode = 1; + else if (spr->mobj->frame & FF_SEMIBRIGHT) + brightmode = 2; if (sector->numlights) { @@ -4320,9 +4310,7 @@ static inline void HWR_DrawPrecipitationSprite(gl_vissprite_t *spr) HWR_Lighting(&Surf, lightlevel, colormap); } - if (spr->mobj->drawflags & MFD_TRANSMASK) - blend = HWR_TranstableToAlpha((spr->mobj->drawflags & MFD_TRANSMASK)>>MFD_TRANSSHIFT, &Surf); - else if (spr->mobj->frame & FF_TRANSMASK) + if (spr->mobj->frame & FF_TRANSMASK) blend = HWR_TranstableToAlpha((spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT, &Surf); else { From 827a1b5fcabf1d16b5ad424b85f5a28854dacdb0 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sun, 15 Nov 2020 06:25:38 -0500 Subject: [PATCH 113/143] Refactor stealing & destroying bumpers - Prevents being able to farm extra bumpers off of karma players - Paves the way for bumper destroy animation later --- src/d_clisrv.c | 4 +- src/d_clisrv.h | 2 +- src/d_player.h | 2 +- src/dehacked.c | 1 + src/k_kart.c | 260 +++++++++++++++++++++++++++------------------- src/k_kart.h | 7 +- src/lua_baselib.c | 6 +- src/p_inter.c | 49 ++++++--- src/p_local.h | 1 + src/p_mobj.c | 42 +++++--- src/p_saveg.c | 4 +- 11 files changed, 229 insertions(+), 149 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 43bb54538..11d603cae 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -617,7 +617,7 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i) rsp->airtime = (tic_t)LONG(players[i].airtime); - rsp->bumpers = SHORT(players[i].bumpers); + rsp->bumpers = players[i].bumpers; rsp->karmadelay = SHORT(players[i].karmadelay); rsp->eliminated = players[i].eliminated; @@ -765,7 +765,7 @@ static void resynch_read_player(resynch_pak *rsp) players[i].airtime = (tic_t)LONG(rsp->airtime); - players[i].bumpers = SHORT(rsp->bumpers); + players[i].bumpers = rsp->bumpers; players[i].karmadelay = SHORT(rsp->karmadelay); players[i].eliminated = rsp->eliminated; diff --git a/src/d_clisrv.h b/src/d_clisrv.h index c5f69d9df..ab08f0bdb 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -281,7 +281,7 @@ typedef struct // SRB2kart INT32 kartstuff[NUMKARTSTUFF]; tic_t airtime; - INT16 bumpers; + UINT8 bumpers; INT16 karmadelay; boolean eliminated; diff --git a/src/d_player.h b/src/d_player.h index a9330ffc8..f9159e8b7 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -524,7 +524,7 @@ typedef struct player_s waypoint_t *nextwaypoint; respawnvars_t respawn; // Respawn info tic_t airtime; // Keep track of how long you've been in the air - INT16 bumpers; + UINT8 bumpers; INT16 karmadelay; boolean eliminated; diff --git a/src/dehacked.c b/src/dehacked.c index 49b34e8bc..ae9ab561a 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -11313,6 +11313,7 @@ struct { {"DMG_EXPLODE",DMG_EXPLODE}, {"DMG_SQUISH",DMG_SQUISH}, {"DMG_STING",DMG_STING}, + {"DMG_KARMA",DMG_KARMA}, //// Death types {"DMG_INSTAKILL",DMG_INSTAKILL}, {"DMG_DEATHPIT",DMG_DEATHPIT}, diff --git a/src/k_kart.c b/src/k_kart.c index ecdb32f5d..cf45256ac 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -2461,93 +2461,51 @@ void K_DoInstashield(player_t *player) P_SetTarget(&layerb->target, player->mo); } -void K_BattleHitPlayer(player_t *player, player_t *victim, UINT8 points, boolean reducewanted) +void K_BattleAwardHit(player_t *player, player_t *victim, mobj_t *inflictor, UINT8 bumpersRemoved) { - if (reducewanted == false) - points = 1; // Force to 1 + UINT8 points = 1; + boolean trapItem = false; + + if (player == NULL || victim == NULL) + { + // Invalid player or victim + return; + } + + if (player == victim) + { + // You cannot give yourself points + return; + } + + if ((inflictor && !P_MobjWasRemoved(inflictor)) && (inflictor->type == MT_BANANA && inflictor->health > 1)) + { + trapItem = true; + } + + // Only apply score bonuses to non-bananas + if (trapItem == false) + { + if (K_IsPlayerWanted(victim)) + { + // +3 points for hitting a wanted player + points = 3; + } + else if (gametyperules & GTR_BUMPERS) + { + if ((victim->bumpers > 0) && (victim->bumpers <= bumpersRemoved)) + { + // +2 points for finishing off a player + points = 2; + } + } + } if (gametyperules & GTR_POINTLIMIT) { P_AddPlayerScore(player, points); K_SpawnBattlePoints(player, victim, points); } - - if ((gametyperules & GTR_WANTED) && (reducewanted == true)) - { - // Seems a little backwards, but the WANTED system is meant to prevent camping. - // If you don't want people to go after you, then be proactive! - player->kartstuff[k_wanted] -= wantedreduce; - victim->kartstuff[k_wanted] -= (wantedreduce/2); - } -} - -void K_RemoveBumper(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 amount, boolean force) -{ - UINT8 score = 1; - boolean trapitem = false; - - if (amount <= 0) - return; - - if (!(gametyperules & GTR_BUMPERS)) - return; - - if (force == false) - { - if (player->powers[pw_flashing] || P_PlayerInPain(player)) - return; - } - - if (inflictor && !P_MobjWasRemoved(inflictor)) - { - if (inflictor->type == MT_BANANA && inflictor->health <= 1) - { - trapitem = true; - } - } - - if (gametyperules & GTR_POINTLIMIT) - { - if (K_IsPlayerWanted(player)) - score = 3; - else if ((gametyperules & GTR_BUMPERS) && (player->bumpers <= amount)) - score = 2; - } - - if (source && source->player && player != source->player) - { - K_BattleHitPlayer(source->player, player, score, trapitem); - } - - if (player->bumpers > 0) - { - if (player->bumpers <= amount) - { - 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->bumpers -= amount; - K_CalculateBattleWanted(); - } - - if (player->bumpers <= 0) - { - player->bumpers = 0; - player->karmadelay = 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(); } void K_SpinPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 type) @@ -2660,30 +2618,110 @@ void K_DebtStingPlayer(player_t *player, mobj_t *source) P_SetPlayerMobjState(player->mo, S_KART_SPINOUT); } -void K_StealBumper(player_t *player, player_t *victim, UINT8 amount) +void K_HandleBumperChanges(player_t *player, UINT8 prevBumpers) { - INT32 intendedamount = player->bumpers + amount; - INT32 newbumper; - angle_t newangle, diff; - fixed_t newx, newy; - mobj_t *newmo; - - if (amount <= 0) + if (!(gametyperules & GTR_BUMPERS)) + { + // Bumpers aren't being used return; + } + + // TODO: replace all console text print-outs with a real visual + + if (player->bumpers > 0 && prevBumpers == 0) + { + 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; + + if (netgame) + { + CONS_Printf(M_GetText("%s is back in the game!\n"), player_names[player-players]); + } + } + else if (player->bumpers == 0 && prevBumpers > 0) + { + mobj_t *karmahitbox = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_KARMAHITBOX); + P_SetTarget(&karmahitbox->target, player->mo); + + karmahitbox->destscale = player->mo->destscale; + P_SetScale(karmahitbox, player->mo->scale); + + if (netgame) + { + CONS_Printf(M_GetText("%s lost all of their bumpers!\n"), player_names[player-players]); + } + } + + player->karmadelay = comebacktime; + K_CalculateBattleWanted(); + K_CheckBumpers(); +} + +void K_DestroyBumpers(player_t *player, UINT8 amount) +{ + UINT8 oldBumpers = player->bumpers; if (!(gametyperules & GTR_BUMPERS)) - return; - - if (netgame && player->bumpers <= 0) - CONS_Printf(M_GetText("%s is back in the game!\n"), player_names[player-players]); - - while (player->bumpers < intendedamount) { - newbumper = player->bumpers; + return; + } + + amount = min(amount, player->bumpers); + + if (amount == 0) + { + return; + } + + player->bumpers -= amount; + + // TODO: Store a bumperlist on the player mobj, + // that way we can do a bumper destruction animation + + K_HandleBumperChanges(player, oldBumpers); +} + +void K_TakeBumpersFromPlayer(player_t *player, player_t *victim, UINT8 amount) +{ + UINT8 oldPlayerBumpers = player->bumpers; + UINT8 oldVictimBumpers = victim->bumpers; + + UINT8 tookBumpers = 0; + + if (!(gametyperules & GTR_BUMPERS)) + { + return; + } + + amount = min(amount, victim->bumpers); + + if (amount == 0) + { + return; + } + + while ((tookBumpers < amount) && (victim->bumpers > 0)) + { + UINT8 newbumper = player->bumpers; + + angle_t newangle, diff; + fixed_t newx, newy; + + mobj_t *newmo; + if (newbumper <= 1) + { diff = 0; + } else + { diff = FixedAngle(360*FRACUNIT/newbumper); + } newangle = player->mo->angle; newx = player->mo->x + P_ReturnThrustX(player->mo, newangle + ANGLE_180, 64*FRACUNIT); @@ -2691,36 +2729,42 @@ void K_StealBumper(player_t *player, player_t *victim, UINT8 amount) newmo = P_SpawnMobj(newx, newy, player->mo->z, MT_BATTLEBUMPER); newmo->threshold = newbumper; + P_SetTarget(&newmo->tracer, victim->mo); P_SetTarget(&newmo->target, player->mo); + newmo->angle = (diff * (newbumper-1)); newmo->color = victim->skincolor; if (newbumper+1 < 2) + { P_SetMobjState(newmo, S_BATTLEBUMPER3); + } else if (newbumper+1 < 3) + { P_SetMobjState(newmo, S_BATTLEBUMPER2); + } else + { P_SetMobjState(newmo, S_BATTLEBUMPER1); + } player->bumpers++; + victim->bumpers--; + tookBumpers++; } + if (tookBumpers == 0) + { + // No change occured. + return; + } + + // Play steal sound S_StartSound(player->mo, sfx_3db06); - player->powers[pw_flashing] = K_GetKartFlashing(player); - player->karmadelay = comebacktime; - - /* - victim->powers[pw_flashing] = K_GetKartFlashing(victim); - victim->karmadelay = comebacktime; - */ - - victim->kartstuff[k_instashield] = 15; - if (cv_kartdebughuddrop.value && !modeattacking) - K_DropItems(victim); - else - K_DropHnextList(victim, false); + K_HandleBumperChanges(player, oldPlayerBumpers); + K_HandleBumperChanges(victim, oldVictimBumpers); } // source is the mobj that originally threw the bomb that exploded etc. diff --git a/src/k_kart.h b/src/k_kart.h index ce3300b52..cadb8b772 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -42,13 +42,14 @@ void K_KartPlayerAfterThink(player_t *player); angle_t K_MomentumAngle(mobj_t *mo); void K_SetHitLagForObjects(mobj_t *mo1, mobj_t *mo2, INT32 tics); void K_DoInstashield(player_t *player); -void K_BattleHitPlayer(player_t *player, player_t *victim, UINT8 points, boolean reducewanted); -void K_RemoveBumper(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 amount, boolean force); +void K_BattleAwardHit(player_t *player, player_t *victim, mobj_t *inflictor, UINT8 bumpersRemoved); void K_SpinPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 type); void K_SquishPlayer(player_t *player, mobj_t *inflictor, mobj_t *source); void K_ExplodePlayer(player_t *player, mobj_t *inflictor, mobj_t *source); void K_DebtStingPlayer(player_t *player, mobj_t *source); -void K_StealBumper(player_t *player, player_t *victim, UINT8 amount); +void K_HandleBumperChanges(player_t *player, UINT8 prevBumpers); +void K_DestroyBumpers(player_t *player, UINT8 amount); +void K_TakeBumpersFromPlayer(player_t *player, player_t *victim, UINT8 amount); void K_SpawnKartExplosion(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32 number, mobjtype_t type, angle_t rotangle, boolean spawncenter, boolean ghostit, mobj_t *source); void K_SpawnMineExplosion(mobj_t *source, UINT8 color); UINT16 K_DriftSparkColor(player_t *player, INT32 charge); diff --git a/src/lua_baselib.c b/src/lua_baselib.c index a9d09dd58..d689dc848 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -3432,7 +3432,7 @@ static int lib_kExplodePlayer(lua_State *L) return 0; } -static int lib_kStealBumper(lua_State *L) +static int lib_kTakeBumpersFromPlayer(lua_State *L) { player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); player_t *victim = *((player_t **)luaL_checkudata(L, 2, META_PLAYER)); @@ -3442,7 +3442,7 @@ static int lib_kStealBumper(lua_State *L) return LUA_ErrInvalid(L, "player_t"); if (!victim) return LUA_ErrInvalid(L, "player_t"); - K_StealBumper(player, victim, amount); + K_TakeBumpersFromPlayer(player, victim, amount); return 0; } @@ -3919,7 +3919,7 @@ static luaL_Reg lib[] = { {"K_SpinPlayer",lib_kSpinPlayer}, {"K_SquishPlayer",lib_kSquishPlayer}, {"K_ExplodePlayer",lib_kExplodePlayer}, - {"K_StealBumper",lib_kStealBumper}, + {"K_TakeBumpersFromPlayer",lib_kTakeBumpersFromPlayer}, {"K_SpawnKartExplosion",lib_kSpawnKartExplosion}, {"K_SpawnMineExplosion",lib_kSpawnMineExplosion}, {"K_SpawnBoostTrail",lib_kSpawnBoostTrail}, diff --git a/src/p_inter.c b/src/p_inter.c index 9b71eac0d..39dfe7404 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -305,7 +305,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) { mobj_t *boom; - if (P_DamageMobj(toucher, special, special->target, 1, DMG_EXPLODE) == false) + if (P_DamageMobj(toucher, special, special->target, 1, DMG_KARMA) == false) { return; } @@ -323,9 +323,6 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) S_StartSound(boom, special->info->attacksound); - K_StealBumper(special->target->player, player, max(1, player->bumpers-1)); // bumpers-1 to slowly remove bumpers from the economy - K_RemoveBumper(player, special->target, special->target, player->bumpers, true); - special->target->player->karthud[khud_yougotem] = 2*TICRATE; special->target->player->karmadelay = comebacktime; } @@ -1692,7 +1689,7 @@ static boolean P_KillPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, { case DMG_DEATHPIT: // Respawn kill types - K_RemoveBumper(player, NULL, NULL, 1, true); + K_DestroyBumpers(player, 1); K_DoIngameRespawn(player); return false; default: @@ -1733,7 +1730,7 @@ static boolean P_KillPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, P_SetTarget(&boom->target, player->mo); } - K_RemoveBumper(player, NULL, NULL, player->bumpers, true); + K_DestroyBumpers(player, player->bumpers); player->eliminated = true; } @@ -1923,31 +1920,54 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da } } - // We successfully hit 'em! + // We successfully damaged them! Give 'em some bumpers! if (type != DMG_STING) { - UINT8 bumpadd = 1; + UINT8 takeBumpers = 1; if (damagetype & DMG_STEAL) { - bumpadd = 2; + takeBumpers = 2; + + if (type == DMG_KARMA) + { + takeBumpers = player->bumpers; + } + } + else + { + if (type == DMG_KARMA) + { + // Take half of their bumpers for karma comeback damage + takeBumpers = max(1, player->bumpers / 2); + } } if (source && source != player->mo && source->player) { K_PlayHitEmSound(source); - K_StealBumper(source->player, player, bumpadd); + + K_BattleAwardHit(source->player, player, inflictor, takeBumpers); + K_TakeBumpersFromPlayer(source->player, player, takeBumpers); + + if (type == DMG_KARMA) + { + // Destroy any remainder bumpers from the player for karma comeback damage + K_DestroyBumpers(player, player->bumpers); + } if (damagetype & DMG_STEAL) { - // Give them ALL of your emeralds :) + // Give them ALL of your emeralds instantly :) source->player->powers[pw_emeralds] |= player->powers[pw_emeralds]; player->powers[pw_emeralds] = 0; K_CheckEmeralds(source->player); } } - - K_RemoveBumper(player, inflictor, source, bumpadd, false); + else + { + K_DestroyBumpers(player, takeBumpers); + } if (!(damagetype & DMG_STEAL)) { @@ -1968,6 +1988,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da ringburst = 0; break; case DMG_EXPLODE: + case DMG_KARMA: K_ExplodePlayer(player, inflictor, source); break; case DMG_WIPEOUT: @@ -1997,7 +2018,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da K_PlayPainSound(player->mo); - if ((type == DMG_EXPLODE) || (cv_kartdebughuddrop.value && !modeattacking)) + if ((type == DMG_EXPLODE || type == DMG_KARMA) || (cv_kartdebughuddrop.value && !modeattacking)) { K_DropItems(player); } diff --git a/src/p_local.h b/src/p_local.h index bdc28075a..b577f3cef 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -467,6 +467,7 @@ typedef struct BasicFF_s #define DMG_EXPLODE 0x02 #define DMG_SQUISH 0x03 #define DMG_STING 0x04 +#define DMG_KARMA 0x05 // Karma Bomb explosion -- works like DMG_EXPLODE, but steals half of their bumpers & deletes the rest //// Death types - cannot be combined with damage types #define DMG_INSTAKILL 0x80 #define DMG_DEATHPIT 0x81 diff --git a/src/p_mobj.c b/src/p_mobj.c index 42bbecb1e..090977559 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -5278,15 +5278,23 @@ static void P_MobjSceneryThink(mobj_t *mobj) } break; case MT_BATTLEBUMPER: - if (mobj->health > 0 && mobj->target && mobj->target->player - && mobj->target->health > 0 && !mobj->target->player->spectator) + if (mobj->health <= 0) { + // DO EXPLODE ANIMATION HERE + //CONS_Printf("bumper explosion\n"); + P_RemoveMobj(mobj); + return; + } + else if (mobj->target && mobj->target->player && mobj->target->health > 0 && !mobj->target->player->spectator) + { + // Following a player + fixed_t rad = 32*mobj->target->scale; fixed_t offz; angle_t ang, diff; if (!((mobj->target->player-players) & 1)) - ang = (FixedAngle(mobj->info->speed) * -1); + ang = -FixedAngle(mobj->info->speed); else ang = FixedAngle(mobj->info->speed); @@ -5341,21 +5349,20 @@ static void P_MobjSceneryThink(mobj_t *mobj) P_SetThingPosition(mobj); } - // Was this so hard? if (mobj->target->player->bumpers <= mobj->threshold) { + // Sliently remove P_RemoveMobj(mobj); return; } } - else if ((mobj->health > 0 - && (!mobj->target || !mobj->target->player || !mobj->target->player->mo || mobj->target->health <= 0 || mobj->target->player->spectator)) - || (mobj->health <= 0 && P_IsObjectOnGround(mobj)) - || P_CheckDeathPitCollide(mobj)) // When in death state + else { + // Sliently remove P_RemoveMobj(mobj); return; } + break; case MT_PLAYERARROW: if (mobj->target && mobj->target->health @@ -10167,20 +10174,25 @@ void P_SpawnPlayer(INT32 playernum) P_SetScale(mobj, mobj->destscale); P_FlashPal(p, 0, 0); // Resets - if ((gametyperules & GTR_BUMPERS)) // SRB2kart + if (gametyperules & GTR_BUMPERS) { mobj_t *overheadarrow = P_SpawnMobj(mobj->x, mobj->y, mobj->z + mobj->height + 16*FRACUNIT, MT_PLAYERARROW); P_SetTarget(&overheadarrow->target, mobj); overheadarrow->drawflags |= MFD_DONTDRAW; P_SetScale(overheadarrow, mobj->destscale); - if (p->spectator && pcount > 1) // HEY! No being cheap... - p->bumpers = 0; - else if (p->bumpers > 0 || leveltime < 1 - || (p->jointime <= 1 && pcount <= 1)) + if (p->spectator) { - if (leveltime < 1 || (p->jointime <= 1 && pcount <= 1)) // Start of the map? - p->bumpers = K_StartingBumperCount(); // Reset those bumpers! + // HEY! No being cheap... + p->bumpers = 0; + } + else if ((p->bumpers > 0) || (leveltime < starttime) || (pcount <= 1)) + { + if ((leveltime < starttime) || (pcount <= 1)) // Start of the map? + { + // Reset those bumpers! + p->bumpers = K_StartingBumperCount(); + } if (p->bumpers) { diff --git a/src/p_saveg.c b/src/p_saveg.c index 1b02f39a7..afc08ffdb 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -257,7 +257,7 @@ static void P_NetArchivePlayers(void) WRITEUINT32(save_p, K_GetWaypointHeapIndex(players[i].nextwaypoint)); WRITEUINT32(save_p, players[i].airtime); - WRITEINT16(save_p, players[i].bumpers); + WRITEUINT8(save_p, players[i].bumpers); WRITEINT16(save_p, players[i].karmadelay); WRITEUINT8(save_p, players[i].eliminated); @@ -447,7 +447,7 @@ static void P_NetUnArchivePlayers(void) players[i].nextwaypoint = (waypoint_t *)(size_t)READUINT32(save_p); players[i].airtime = READUINT32(save_p); - players[i].bumpers = READINT16(save_p); + players[i].bumpers = READUINT8(save_p); players[i].karmadelay = READINT16(save_p); players[i].eliminated = (boolean)READUINT8(save_p); From 42f411399aa42abcb6efb73d730a350e3b43175d Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sun, 15 Nov 2020 12:56:03 -0500 Subject: [PATCH 114/143] Add bumper explosion effect --- src/dehacked.c | 24 +++++++++++++++ src/info.c | 34 ++++++++++++++++++--- src/info.h | 26 ++++++++++++++++ src/k_kart.c | 4 --- src/p_inter.c | 53 ++++++++++++++++++++++++++------ src/p_mobj.c | 82 ++++++++++++++++++++++++++++++++++++++++---------- 6 files changed, 190 insertions(+), 33 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index ae9ab561a..e361bbc8e 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -8720,6 +8720,30 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_BATTLEBUMPER2", "S_BATTLEBUMPER3", + "S_BATTLEBUMPER_EXCRYSTALA1", + "S_BATTLEBUMPER_EXCRYSTALA2", + "S_BATTLEBUMPER_EXCRYSTALA3", + "S_BATTLEBUMPER_EXCRYSTALA4", + + "S_BATTLEBUMPER_EXCRYSTALB1", + "S_BATTLEBUMPER_EXCRYSTALB2", + "S_BATTLEBUMPER_EXCRYSTALB3", + "S_BATTLEBUMPER_EXCRYSTALB4", + + "S_BATTLEBUMPER_EXCRYSTALC1", + "S_BATTLEBUMPER_EXCRYSTALC2", + "S_BATTLEBUMPER_EXCRYSTALC3", + "S_BATTLEBUMPER_EXCRYSTALC4", + + "S_BATTLEBUMPER_EXSHELLA1", + "S_BATTLEBUMPER_EXSHELLA2", + + "S_BATTLEBUMPER_EXSHELLB1", + "S_BATTLEBUMPER_EXSHELLB2", + + "S_BATTLEBUMPER_EXSHELLC1", + "S_BATTLEBUMPER_EXSHELLC2", + // DEZ respawn laser "S_DEZLASER", "S_DEZLASER_TRAIL1", diff --git a/src/info.c b/src/info.c index 5409bf41a..bedf6e69e 100644 --- a/src/info.c +++ b/src/info.c @@ -563,6 +563,8 @@ char sprnames[NUMSPRITES + 1][5] = "SINK", // Kitchen Sink "SITR", // Kitchen Sink Trail "KBLN", // Battle Mode Bumper + "BEXC", // Battle Bumper Explosion: Crystal + "BEXS", // Battle Bumper Explosion: Shell "DEZL", // DEZ Laser respawn @@ -4402,9 +4404,33 @@ state_t states[NUMSTATES] = {SPR_SITR, 1, 5, {NULL}, 0, 0, S_SINKTRAIL3}, // S_SINKTRAIL2 {SPR_SITR, 2, 3, {NULL}, 0, 0, S_NULL}, // S_SINKTRAIL3 - {SPR_KBLN, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_BATTLEBUMPER1}, // S_BATTLEBUMPER1 - {SPR_KBLN, FF_FULLBRIGHT|1, -1, {NULL}, 0, 0, S_BATTLEBUMPER2}, // S_BATTLEBUMPER2 - {SPR_KBLN, FF_FULLBRIGHT|2, -1, {NULL}, 0, 0, S_BATTLEBUMPER3}, // S_BATTLEBUMPER3 + {SPR_KBLN, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_BATTLEBUMPER1 + {SPR_KBLN, FF_FULLBRIGHT|1, -1, {NULL}, 0, 0, S_NULL}, // S_BATTLEBUMPER2 + {SPR_KBLN, FF_FULLBRIGHT|2, -1, {NULL}, 0, 0, S_NULL}, // S_BATTLEBUMPER3 + + {SPR_BEXC, FF_SEMIBRIGHT, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXCRYSTALA2}, // S_BATTLEBUMPER_EXCRYSTALA1 + {SPR_BEXC, FF_FULLBRIGHT|1, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXCRYSTALA3}, // S_BATTLEBUMPER_EXCRYSTALA2 + {SPR_BEXC, FF_SEMIBRIGHT, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXCRYSTALA4}, // S_BATTLEBUMPER_EXCRYSTALA3 + {SPR_BEXC, FF_FULLBRIGHT|2, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXCRYSTALA1}, // S_BATTLEBUMPER_EXCRYSTALA4 + + {SPR_BEXC, FF_SEMIBRIGHT|3, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXCRYSTALB2}, // S_BATTLEBUMPER_EXCRYSTALB1 + {SPR_BEXC, FF_FULLBRIGHT|4, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXCRYSTALB3}, // S_BATTLEBUMPER_EXCRYSTALB2 + {SPR_BEXC, FF_SEMIBRIGHT|3, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXCRYSTALB4}, // S_BATTLEBUMPER_EXCRYSTALB3 + {SPR_BEXC, FF_FULLBRIGHT|5, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXCRYSTALB1}, // S_BATTLEBUMPER_EXCRYSTALB4 + + {SPR_BEXC, FF_SEMIBRIGHT|6, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXCRYSTALC2}, // S_BATTLEBUMPER_EXCRYSTALC1 + {SPR_BEXC, FF_FULLBRIGHT|7, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXCRYSTALC3}, // S_BATTLEBUMPER_EXCRYSTALC2 + {SPR_BEXC, FF_SEMIBRIGHT|6, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXCRYSTALC4}, // S_BATTLEBUMPER_EXCRYSTALC3 + {SPR_BEXC, FF_FULLBRIGHT|8, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXCRYSTALC1}, // S_BATTLEBUMPER_EXCRYSTALC4 + + {SPR_BEXS, FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXSHELLA2}, // S_BATTLEBUMPER_EXSHELLA1 + {SPR_BEXS, FF_FULLBRIGHT|1, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXSHELLA1}, // S_BATTLEBUMPER_EXSHELLA2 + + {SPR_BEXS, FF_FULLBRIGHT|2, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXSHELLB2}, // S_BATTLEBUMPER_EXSHELLB1 + {SPR_BEXS, FF_FULLBRIGHT|3, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXSHELLB1}, // S_BATTLEBUMPER_EXSHELLB2 + + {SPR_BEXS, FF_FULLBRIGHT|4, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXSHELLC2}, // S_BATTLEBUMPER_EXSHELLC1 + {SPR_BEXS, FF_FULLBRIGHT|5, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXSHELLC1}, // S_BATTLEBUMPER_EXSHELLC2 {SPR_DEZL, FF_FULLBRIGHT|FF_PAPERSPRITE, 8, {NULL}, 0, 0, S_NULL}, // S_DEZLASER {SPR_DEZL, FF_FULLBRIGHT|1, 2, {NULL}, 0, 0, S_DEZLASER_TRAIL2}, // S_DEZLASER_TRAIL1 @@ -24061,7 +24087,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_NULL, // deathstate + S_BATTLEBUMPER_EXCRYSTALA1, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 4*FRACUNIT, // speed diff --git a/src/info.h b/src/info.h index 483706c90..84ea30757 100644 --- a/src/info.h +++ b/src/info.h @@ -834,6 +834,8 @@ typedef enum sprite SPR_SINK, // Kitchen Sink SPR_SITR, // Kitchen Sink Trail SPR_KBLN, // Battle Mode Bumper + SPR_BEXC, // Battle Bumper Explosion: Crystal + SPR_BEXS, // Battle Bumper Explosion: Shell SPR_DEZL, // DEZ Laser respawn @@ -4571,6 +4573,30 @@ typedef enum state S_BATTLEBUMPER2, S_BATTLEBUMPER3, + S_BATTLEBUMPER_EXCRYSTALA1, + S_BATTLEBUMPER_EXCRYSTALA2, + S_BATTLEBUMPER_EXCRYSTALA3, + S_BATTLEBUMPER_EXCRYSTALA4, + + S_BATTLEBUMPER_EXCRYSTALB1, + S_BATTLEBUMPER_EXCRYSTALB2, + S_BATTLEBUMPER_EXCRYSTALB3, + S_BATTLEBUMPER_EXCRYSTALB4, + + S_BATTLEBUMPER_EXCRYSTALC1, + S_BATTLEBUMPER_EXCRYSTALC2, + S_BATTLEBUMPER_EXCRYSTALC3, + S_BATTLEBUMPER_EXCRYSTALC4, + + S_BATTLEBUMPER_EXSHELLA1, + S_BATTLEBUMPER_EXSHELLA2, + + S_BATTLEBUMPER_EXSHELLB1, + S_BATTLEBUMPER_EXSHELLB2, + + S_BATTLEBUMPER_EXSHELLC1, + S_BATTLEBUMPER_EXSHELLC2, + // DEZ Laser respawn S_DEZLASER, S_DEZLASER_TRAIL1, diff --git a/src/k_kart.c b/src/k_kart.c index cf45256ac..e36845ef7 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -2679,10 +2679,6 @@ void K_DestroyBumpers(player_t *player, UINT8 amount) } player->bumpers -= amount; - - // TODO: Store a bumperlist on the player mobj, - // that way we can do a bumper destruction animation - K_HandleBumperChanges(player, oldBumpers); } diff --git a/src/p_inter.c b/src/p_inter.c index 39dfe7404..29c4cb887 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1065,12 +1065,6 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget { mobj_t *mo; - //if (inflictor && (inflictor->type == MT_SHELL || inflictor->type == MT_FIREBALL)) - // P_SetTarget(&target->tracer, inflictor); - - if (G_IsSpecialStage(gamemap) && target->player && target->player->nightstime > 6) - target->player->nightstime = 6; // Just let P_Ticker take care of the rest. - if (target->flags & (MF_ENEMY|MF_BOSS)) target->momx = target->momy = target->momz = 0; @@ -1096,7 +1090,11 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget target->flags &= ~(MF_SHOOTABLE|MF_FLOAT|MF_SPECIAL); target->flags2 &= ~(MF2_SKULLFLY|MF2_NIGHTSPULL); target->health = 0; // This makes it easy to check if something's dead elsewhere. - target->shadowscale = 0; + + if (target->type != MT_BATTLEBUMPER) + { + target->shadowscale = 0; + } if (LUAh_MobjDeath(target, inflictor, source, damagetype) || P_MobjWasRemoved(target)) return; @@ -1219,7 +1217,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget } } - if ((gametyperules & GTR_BUMPERS)) + if (gametyperules & GTR_BUMPERS) K_CheckBumpers(); target->player->kartstuff[k_pogospring] = 0; @@ -1449,6 +1447,42 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget } break; + case MT_BATTLEBUMPER: + { + mobj_t *owner = target->target; + mobj_t *overlay; + + target->flags &= ~MF_NOGRAVITY; + + target->destscale = (3 * target->destscale) / 2; + target->scalespeed = FRACUNIT/100; + + if (owner && !P_MobjWasRemoved(owner)) + { + /* + target->momx = owner->momx / 2; + target->momy = owner->momy / 2; + target->momz = owner->momz / 2; + */ + + P_Thrust(target, R_PointToAngle2(owner->x, owner->y, target->x, target->y), 4 * target->scale); + } + + target->momz += (24 * target->scale) * P_MobjFlip(target); + + target->shadowscale *= 3; + target->fuse = 16; + + overlay = P_SpawnMobjFromMobj(target, 0, 0, 0, MT_OVERLAY); + + P_SetTarget(&target->tracer, overlay); + P_SetTarget(&overlay->target, target); + + overlay->color = target->color; + P_SetMobjState(overlay, S_BATTLEBUMPER_EXSHELLA1); + } + break; + default: break; } @@ -1685,11 +1719,12 @@ static boolean P_KillPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, return false; } + K_DestroyBumpers(player, 1); + switch (type) { case DMG_DEATHPIT: // Respawn kill types - K_DestroyBumpers(player, 1); K_DoIngameRespawn(player); return false; default: diff --git a/src/p_mobj.c b/src/p_mobj.c index 090977559..3c0df40fe 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1157,6 +1157,7 @@ fixed_t P_GetMobjGravity(mobj_t *mo) break; case MT_WATERDROP: case MT_CYBRAKDEMON: + case MT_BATTLEBUMPER: gravityadd /= 2; break; case MT_BANANA: @@ -1165,7 +1166,10 @@ fixed_t P_GetMobjGravity(mobj_t *mo) case MT_SINK: case MT_EMERALD: if (mo->extravalue2 > 0) + { gravityadd *= mo->extravalue2; + } + gravityadd = (5*gravityadd)/2; break; case MT_KARMAFIREWORK: @@ -5280,15 +5284,52 @@ static void P_MobjSceneryThink(mobj_t *mobj) case MT_BATTLEBUMPER: if (mobj->health <= 0) { - // DO EXPLODE ANIMATION HERE - //CONS_Printf("bumper explosion\n"); - P_RemoveMobj(mobj); - return; - } - else if (mobj->target && mobj->target->player && mobj->target->health > 0 && !mobj->target->player->spectator) - { - // Following a player + mobj->fuse--; + if (mobj->fuse <= 0) + { + statenum_t curState = (mobj->state - states); + + if (curState >= S_BATTLEBUMPER_EXCRYSTALA1 && curState <= S_BATTLEBUMPER_EXCRYSTALA4) + { + P_SetMobjState(mobj, S_BATTLEBUMPER_EXCRYSTALB1); + + if (mobj->tracer && !P_MobjWasRemoved(mobj->tracer)) + { + P_SetMobjState(mobj->tracer, S_BATTLEBUMPER_EXSHELLB1); + } + + mobj->shadowscale *= 3; + mobj->fuse = 24; + break; + } + else if (curState >= S_BATTLEBUMPER_EXCRYSTALB1 && curState <= S_BATTLEBUMPER_EXCRYSTALB4) + { + P_SetMobjState(mobj, S_BATTLEBUMPER_EXCRYSTALC1); + + if (mobj->tracer && !P_MobjWasRemoved(mobj->tracer)) + { + P_SetMobjState(mobj->tracer, S_BATTLEBUMPER_EXSHELLC1); + } + + mobj->shadowscale *= 3; + mobj->fuse = 32; + break; + } + else + { + // TODO: confetti goes here + P_RemoveMobj(mobj); + return; + } + } + + break; + } + + if (mobj->target && !P_MobjWasRemoved(mobj->target) && mobj->target->player + && mobj->target->health > 0 && !mobj->target->player->spectator) + { fixed_t rad = 32*mobj->target->scale; fixed_t offz; angle_t ang, diff; @@ -5320,15 +5361,23 @@ static void P_MobjSceneryThink(mobj_t *mobj) mobj->drawflags = (mobj->target->drawflags & MFD_DONTDRAW); if (mobj->target->eflags & MFE_VERTICALFLIP) + { offz += 4*FRACUNIT; + } else + { offz -= 4*FRACUNIT; + } - if (mobj->tracer && mobj->tracer->player && mobj->tracer->player->mo + if (mobj->tracer && !P_MobjWasRemoved(mobj->tracer) && mobj->tracer->player && mobj->tracer->health > 0 && !mobj->tracer->player->spectator) // STOLEN - mobj->color = mobj->tracer->player->skincolor; // don't do star flashing for stolen bumpers + { + mobj->color = mobj->tracer->color; + } else - mobj->color = mobj->target->color; // but do so if it belongs to you :B + { + mobj->color = mobj->target->color; + } if (mobj->target->player->bumpers < 2) P_SetMobjState(mobj, S_BATTLEBUMPER3); @@ -5338,11 +5387,11 @@ static void P_MobjSceneryThink(mobj_t *mobj) P_SetMobjState(mobj, S_BATTLEBUMPER1); // Shrink your items if the player shrunk too. - mobj->scale = mobj->target->scale; + P_SetScale(mobj, mobj->target->scale); P_UnsetThingPosition(mobj); { - const angle_t fa = ang>>ANGLETOFINESHIFT; + const angle_t fa = ang >> ANGLETOFINESHIFT; mobj->x = mobj->target->x + FixedMul(FINECOSINE(fa), rad); mobj->y = mobj->target->y + FixedMul(FINESINE(fa), rad); mobj->z = mobj->target->z + offz; @@ -5351,9 +5400,9 @@ static void P_MobjSceneryThink(mobj_t *mobj) if (mobj->target->player->bumpers <= mobj->threshold) { - // Sliently remove - P_RemoveMobj(mobj); - return; + // Do bumper destruction + P_KillMobj(mobj, NULL, NULL, DMG_NORMAL); + break; } } else @@ -8366,6 +8415,7 @@ static boolean P_FuseThink(mobj_t *mobj) if (mobj->threshold == 70) newmobj->threshold = 70; } + P_RemoveMobj(mobj); // make sure they disappear return false; case MT_SMK_ICEBLOCK: From 0882fe2b014fd389a2ad6231c1f287fcd14efb65 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sun, 15 Nov 2020 12:59:05 -0500 Subject: [PATCH 115/143] Change overtime center hitbox --- src/info.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/info.c b/src/info.c index bedf6e69e..d32980537 100644 --- a/src/info.c +++ b/src/info.c @@ -28333,8 +28333,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 48< Date: Sun, 15 Nov 2020 15:11:13 -0500 Subject: [PATCH 116/143] More finalized Chaos Emerald visuals --- src/dehacked.c | 116 ++++++++++++++++++++++++------------------------- src/doomdef.h | 8 ++++ src/info.c | 48 ++++++++++---------- src/info.h | 18 ++------ src/k_battle.c | 20 ++++++--- src/k_hud.c | 51 +++++++++++++++++----- 6 files changed, 145 insertions(+), 116 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index e361bbc8e..142a14efc 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -6269,13 +6269,9 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_EMBLEM26", // Chaos Emeralds - "S_EMERALD_CHAOS1", - "S_EMERALD_CHAOS2", - "S_EMERALD_CHAOS3", - "S_EMERALD_CHAOS4", - "S_EMERALD_CHAOS5", - "S_EMERALD_CHAOS6", - "S_EMERALD_CHAOS7", + "S_CHAOSEMERALD1", + "S_CHAOSEMERALD2", + "S_CHAOSEMERALD_UNDER", // Emerald hunt shards "S_SHRD1", @@ -10775,67 +10771,67 @@ static const char *COLOR_ENUMS[] = { // Rejigged for Kart. // Special super colors // Super Sonic Yellow - "SUPER1", // SKINCOLOR_SUPER1 - "SUPER2", // SKINCOLOR_SUPER2, - "SUPER3", // SKINCOLOR_SUPER3, - "SUPER4", // SKINCOLOR_SUPER4, - "SUPER5", // SKINCOLOR_SUPER5, + "SUPERSILVER1", + "SUPERSILVER2", + "SUPERSILVER3", + "SUPERSILVER4", + "SUPERSILVER5", - // Super Tails Orange - "TSUPER1", // SKINCOLOR_TSUPER1, - "TSUPER2", // SKINCOLOR_TSUPER2, - "TSUPER3", // SKINCOLOR_TSUPER3, - "TSUPER4", // SKINCOLOR_TSUPER4, - "TSUPER5", // SKINCOLOR_TSUPER5, + "SUPERRED1", + "SUPERRED2", + "SUPERRED3", + "SUPERRED4", + "SUPERRED5", - // Super Knuckles Red - "KSUPER1", // SKINCOLOR_KSUPER1, - "KSUPER2", // SKINCOLOR_KSUPER2, - "KSUPER3", // SKINCOLOR_KSUPER3, - "KSUPER4", // SKINCOLOR_KSUPER4, - "KSUPER5", // SKINCOLOR_KSUPER5, + "SUPERORANGE1", + "SUPERORANGE2", + "SUPERORANGE3", + "SUPERORANGE4", + "SUPERORANGE5", - // Hyper Sonic Pink - "PSUPER1", // SKINCOLOR_PSUPER1, - "PSUPER2", // SKINCOLOR_PSUPER2, - "PSUPER3", // SKINCOLOR_PSUPER3, - "PSUPER4", // SKINCOLOR_PSUPER4, - "PSUPER5", // SKINCOLOR_PSUPER5, + "SUPERGOLD1", + "SUPERGOLD2", + "SUPERGOLD3", + "SUPERGOLD4", + "SUPERGOLD5", - // Hyper Sonic Blue - "BSUPER1", // SKINCOLOR_BSUPER1, - "BSUPER2", // SKINCOLOR_BSUPER2, - "BSUPER3", // SKINCOLOR_BSUPER3, - "BSUPER4", // SKINCOLOR_BSUPER4, - "BSUPER5", // SKINCOLOR_BSUPER5, + "SUPERPERIDOT1", + "SUPERPERIDOT2", + "SUPERPERIDOT3", + "SUPERPERIDOT4", + "SUPERPERIDOT5", - // Aqua Super - "ASUPER1", // SKINCOLOR_ASUPER1, - "ASUPER2", // SKINCOLOR_ASUPER2, - "ASUPER3", // SKINCOLOR_ASUPER3, - "ASUPER4", // SKINCOLOR_ASUPER4, - "ASUPER5", // SKINCOLOR_ASUPER5, + "SUPERSKY1", + "SUPERSKY2", + "SUPERSKY3", + "SUPERSKY4", + "SUPERSKY5", - // Hyper Sonic Green - "GSUPER1", // SKINCOLOR_GSUPER1, - "GSUPER2", // SKINCOLOR_GSUPER2, - "GSUPER3", // SKINCOLOR_GSUPER3, - "GSUPER4", // SKINCOLOR_GSUPER4, - "GSUPER5", // SKINCOLOR_GSUPER5, + "SUPERPURPLE1", + "SUPERPURPLE2", + "SUPERPURPLE3", + "SUPERPURPLE4", + "SUPERPURPLE5", - // Hyper Sonic White - "WSUPER1", // SKINCOLOR_WSUPER1, - "WSUPER2", // SKINCOLOR_WSUPER2, - "WSUPER3", // SKINCOLOR_WSUPER3, - "WSUPER4", // SKINCOLOR_WSUPER4, - "WSUPER5", // SKINCOLOR_WSUPER5, + "SUPERRUST1", + "SUPERRUST2", + "SUPERRUST3", + "SUPERRUST4", + "SUPERRUST5", - // Creamy Super (Shadow?) - "CSUPER1", // SKINCOLOR_CSUPER1, - "CSUPER2", // SKINCOLOR_CSUPER2, - "CSUPER3", // SKINCOLOR_CSUPER3, - "CSUPER4", // SKINCOLOR_CSUPER4, - "CSUPER5" // SKINCOLOR_CSUPER5, + "SUPERTAN1", + "SUPERTAN2", + "SUPERTAN3", + "SUPERTAN4", + "SUPERTAN5", + + "CHAOSEMERALD1", + "CHAOSEMERALD2", + "CHAOSEMERALD3", + "CHAOSEMERALD4", + "CHAOSEMERALD5", + "CHAOSEMERALD6", + "CHAOSEMERALD7" }; static const char *const POWERS_LIST[] = { diff --git a/src/doomdef.h b/src/doomdef.h index c301640ad..c51cf4a5f 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -386,6 +386,14 @@ typedef enum SKINCOLOR_SUPERTAN4, SKINCOLOR_SUPERTAN5, + SKINCOLOR_CHAOSEMERALD1, + SKINCOLOR_CHAOSEMERALD2, + SKINCOLOR_CHAOSEMERALD3, + SKINCOLOR_CHAOSEMERALD4, + SKINCOLOR_CHAOSEMERALD5, + SKINCOLOR_CHAOSEMERALD6, + SKINCOLOR_CHAOSEMERALD7, + SKINCOLOR_FIRSTFREESLOT, SKINCOLOR_LASTFREESLOT = SKINCOLOR_FIRSTFREESLOT + NUMCOLORFREESLOTS - 1, diff --git a/src/info.c b/src/info.c index d32980537..2f9b1faf1 100644 --- a/src/info.c +++ b/src/info.c @@ -139,13 +139,7 @@ char sprnames[NUMSPRITES + 1][5] = "NCHP", // NiGHTS chip "NSTR", // NiGHTS star "EMBM", // Emblem - "EMC1", // Chaos Emeralds - "EMC2", - "EMC3", - "EMC4", - "EMC5", - "EMC6", - "EMC7", + "EMRC", // Chaos Emeralds "SHRD", // Emerald Hunt // Interactive Objects @@ -1907,13 +1901,9 @@ state_t states[NUMSTATES] = {SPR_EMBM, 25, -1, {NULL}, 0, 0, S_NULL}, // S_EMBLEM26 // Chaos Emeralds - {SPR_EMC1, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_EMERALD_CHAOS1 - {SPR_EMC2, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_EMERALD_CHAOS2 - {SPR_EMC3, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_EMERALD_CHAOS3 - {SPR_EMC4, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_EMERALD_CHAOS4 - {SPR_EMC5, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_EMERALD_CHAOS5 - {SPR_EMC6, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_EMERALD_CHAOS6 - {SPR_EMC7, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_EMERALD_CHAOS7 + {SPR_EMRC, FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_CHAOSEMERALD2}, // S_CHAOSEMERALD1 + {SPR_EMRC, FF_FULLBRIGHT|FF_TRANSADD, 1, {NULL}, 0, 0, S_CHAOSEMERALD1}, // S_CHAOSEMERALD2 + {SPR_EMRC, FF_FULLBRIGHT|1, -1, {NULL}, 1, 0, S_NULL}, // S_CHAOSEMERALD_UNDER // Emerald hunt shards {SPR_SHRD, 0, -1, {NULL}, 0, 0, S_NULL}, // S_SHRD1 @@ -3757,14 +3747,14 @@ state_t states[NUMSTATES] = {SPR_CAPS, 0, -1, {NULL}, 0, 0, S_NULL}, // S_EGGCAPSULE // Orbiting Chaos Emeralds/Ideya for NiGHTS - {SPR_EMC1, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM1}, // S_ORBITEM1 - {SPR_EMC2, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM2}, // S_ORBITEM2 - {SPR_EMC3, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM3}, // S_ORBITEM3 - {SPR_EMC4, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM4}, // S_ORBITEM4 - {SPR_EMC5, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM5}, // S_ORBITEM5 - {SPR_EMC6, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM6}, // S_ORBITEM6 - {SPR_EMC7, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM7}, // S_ORBITEM7 - {SPR_EMC1, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM8}, // S_ORBITEM8 + {SPR_EMRC, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM1}, // S_ORBITEM1 + {SPR_EMRC, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM2}, // S_ORBITEM2 + {SPR_EMRC, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM3}, // S_ORBITEM3 + {SPR_EMRC, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM4}, // S_ORBITEM4 + {SPR_EMRC, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM5}, // S_ORBITEM5 + {SPR_EMRC, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM6}, // S_ORBITEM6 + {SPR_EMRC, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM7}, // S_ORBITEM7 + {SPR_EMRC, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM8}, // S_ORBITEM8 {SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBIDYA1}, // S_ORBIDYA1 {SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT|1, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBIDYA2}, // S_ORBIDYA2 {SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT|2, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBIDYA3}, // S_ORBIDYA3 @@ -8237,7 +8227,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = { // MT_EMERALD -1, // doomednum - S_EMERALD_CHAOS1, // spawnstate + S_CHAOSEMERALD1, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -18960,7 +18950,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = { // MT_GOTEMERALD -1, // doomednum - S_EMERALD_CHAOS1, // spawnstate + S_CHAOSEMERALD1, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -28805,7 +28795,15 @@ skincolor_t skincolors[MAXSKINCOLORS] = { {"Super Tan 2", {0x00, 0x50, 0x50, 0x51, 0x51, 0x52, 0x52, 0x52, 0x54, 0x54, 0x54, 0x54, 0x55, 0x56, 0x57, 0xf5}, SKINCOLOR_BROWN, 13, V_BROWNMAP, false}, // SKINCOLOR_SUPERTAN2 {"Super Tan 3", {0x50, 0x51, 0x51, 0x52, 0x52, 0x52, 0x54, 0x54, 0x54, 0x54, 0x55, 0x56, 0x57, 0xf5, 0xf7, 0xf9}, SKINCOLOR_BROWN, 12, V_BROWNMAP, false}, // SKINCOLOR_SUPERTAN3 {"Super Tan 4", {0x51, 0x52, 0x52, 0x52, 0x52, 0x54, 0x54, 0x54, 0x55, 0x56, 0x57, 0xf5, 0xf7, 0xf9, 0xfb, 0xed}, SKINCOLOR_BROWN, 11, V_BROWNMAP, false}, // SKINCOLOR_SUPERTAN4 - {"Super Tan 5", {0x52, 0x52, 0x54, 0x54, 0x54, 0x55, 0x56, 0x57, 0xf5, 0xf7, 0xf9, 0xfb, 0xed, 0xee, 0xef, 0xef}, SKINCOLOR_BROWN, 10, V_BROWNMAP, false} // SKINCOLOR_SUPERTAN5 + {"Super Tan 5", {0x52, 0x52, 0x54, 0x54, 0x54, 0x55, 0x56, 0x57, 0xf5, 0xf7, 0xf9, 0xfb, 0xed, 0xee, 0xef, 0xef}, SKINCOLOR_BROWN, 10, V_BROWNMAP, false}, // SKINCOLOR_SUPERTAN5 + + {"Chaos Emerald 1", { 0, 88, 188, 98, 114, 116, 117, 119, 0, 0, 0, 0, 0, 0, 0, 0}, SKINCOLOR_NONE, 0, 0, false}, // SKINCOLOR_CHAOSEMERALD1 + {"Chaos Emerald 2", { 0, 80, 82, 74, 65, 52, 56, 60, 0, 0, 0, 0, 0, 0, 0, 0}, SKINCOLOR_NONE, 0, 0, false}, // SKINCOLOR_CHAOSEMERALD2 + {"Chaos Emerald 3", { 0, 252, 201, 179, 182, 183, 185, 187, 0, 0, 0, 0, 0, 0, 0, 0}, SKINCOLOR_NONE, 0, 0, false}, // SKINCOLOR_CHAOSEMERALD3 + {"Chaos Emerald 4", { 0, 144, 146, 147, 149, 165, 167, 169, 0, 0, 0, 0, 0, 0, 0, 0}, SKINCOLOR_NONE, 0, 0, false}, // SKINCOLOR_CHAOSEMERALD4 + {"Chaos Emerald 5", { 0, 1, 144, 4, 9, 170, 14, 21, 0, 0, 0, 0, 0, 0, 0, 0}, SKINCOLOR_NONE, 0, 0, false}, // SKINCOLOR_CHAOSEMERALD5 + {"Chaos Emerald 6", { 0, 208, 50, 32, 34, 37, 40, 44, 0, 0, 0, 0, 0, 0, 0, 0}, SKINCOLOR_NONE, 0, 0, false}, // SKINCOLOR_CHAOSEMERALD6 + {"Chaos Emerald 7", { 0, 120, 121, 140, 133, 135, 149, 156, 0, 0, 0, 0, 0, 0, 0, 0}, SKINCOLOR_NONE, 0, 0, false} // SKINCOLOR_CHAOSEMERALD7 }; /** Patches the mobjinfo, state, and skincolor tables. diff --git a/src/info.h b/src/info.h index 84ea30757..1bcd03b56 100644 --- a/src/info.h +++ b/src/info.h @@ -410,13 +410,7 @@ typedef enum sprite SPR_NCHP, // NiGHTS chip SPR_NSTR, // NiGHTS star SPR_EMBM, // Emblem - SPR_EMC1, // Chaos Emeralds - SPR_EMC2, - SPR_EMC3, - SPR_EMC4, - SPR_EMC5, - SPR_EMC6, - SPR_EMC7, + SPR_EMRC, // Chaos Emeralds SPR_SHRD, // Emerald Hunt // Interactive Objects @@ -2122,13 +2116,9 @@ typedef enum state S_EMBLEM26, // Chaos Emeralds - S_EMERALD_CHAOS1, - S_EMERALD_CHAOS2, - S_EMERALD_CHAOS3, - S_EMERALD_CHAOS4, - S_EMERALD_CHAOS5, - S_EMERALD_CHAOS6, - S_EMERALD_CHAOS7, + S_CHAOSEMERALD1, + S_CHAOSEMERALD2, + S_CHAOSEMERALD_UNDER, // Emerald hunt shards S_SHRD1, diff --git a/src/k_battle.c b/src/k_battle.c index a9924b1de..1f0db486c 100644 --- a/src/k_battle.c +++ b/src/k_battle.c @@ -308,6 +308,7 @@ mobj_t *K_SpawnChaosEmerald(mobj_t *parent, angle_t angle, SINT8 flip, UINT32 em { boolean validEmerald = true; mobj_t *emerald = P_SpawnMobjFromMobj(parent, 0, 0, 0, MT_EMERALD); + mobj_t *overlay; P_Thrust(emerald, FixedAngle(P_RandomFixed() * 180) + angle, @@ -322,25 +323,25 @@ mobj_t *K_SpawnChaosEmerald(mobj_t *parent, angle_t angle, SINT8 flip, UINT32 em switch (emeraldType) { case EMERALD_CHAOS1: - P_SetMobjState(emerald, S_EMERALD_CHAOS1); + emerald->color = SKINCOLOR_CHAOSEMERALD1; break; case EMERALD_CHAOS2: - P_SetMobjState(emerald, S_EMERALD_CHAOS2); + emerald->color = SKINCOLOR_CHAOSEMERALD2; break; case EMERALD_CHAOS3: - P_SetMobjState(emerald, S_EMERALD_CHAOS3); + emerald->color = SKINCOLOR_CHAOSEMERALD3; break; case EMERALD_CHAOS4: - P_SetMobjState(emerald, S_EMERALD_CHAOS4); + emerald->color = SKINCOLOR_CHAOSEMERALD4; break; case EMERALD_CHAOS5: - P_SetMobjState(emerald, S_EMERALD_CHAOS5); + emerald->color = SKINCOLOR_CHAOSEMERALD5; break; case EMERALD_CHAOS6: - P_SetMobjState(emerald, S_EMERALD_CHAOS6); + emerald->color = SKINCOLOR_CHAOSEMERALD6; break; case EMERALD_CHAOS7: - P_SetMobjState(emerald, S_EMERALD_CHAOS7); + emerald->color = SKINCOLOR_CHAOSEMERALD7; break; default: CONS_Printf("Invalid emerald type %d\n", emeraldType); @@ -353,6 +354,11 @@ mobj_t *K_SpawnChaosEmerald(mobj_t *parent, angle_t angle, SINT8 flip, UINT32 em emerald->extravalue1 = emeraldType; } + overlay = P_SpawnMobjFromMobj(emerald, 0, 0, 0, MT_OVERLAY); + P_SetTarget(&overlay->target, emerald); + P_SetMobjState(overlay, S_CHAOSEMERALD_UNDER); + overlay->color = emerald->color; + return emerald; } diff --git a/src/k_hud.c b/src/k_hud.c index 330bfb8fe..dac19ffa6 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -88,7 +88,7 @@ static patch_t *kp_rankbumper; static patch_t *kp_tinybumper[2]; static patch_t *kp_ranknobumpers; static patch_t *kp_rankcapsule; -static patch_t *kp_rankemeralds[7]; +static patch_t *kp_rankemerald; static patch_t *kp_battlewin; static patch_t *kp_battlecool; @@ -351,13 +351,7 @@ void K_LoadKartHUDGraphics(void) kp_tinybumper[1] = W_CachePatchName("K_BLNB", PU_HUDGFX); kp_ranknobumpers = W_CachePatchName("K_NOBLNS", PU_HUDGFX); kp_rankcapsule = W_CachePatchName("K_CAPICO", PU_HUDGFX); - - sprintf(buffer, "K_EMERCx"); - for (i = 0; i < 7; i++) - { - buffer[7] = '0'+(i+1); - kp_rankemeralds[i] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX); - } + kp_rankemerald = W_CachePatchName("K_EMERC", PU_HUDGFX); // Battle graphics kp_battlewin = W_CachePatchName("K_BWIN", PU_HUDGFX); @@ -1633,10 +1627,12 @@ static boolean K_drawKartPositionFaces(void) for (j = 0; j < 7; j++) { UINT32 emeraldFlag = (1 << j); + UINT16 emeraldColor = SKINCOLOR_CHAOSEMERALD1 + j; if (players[rankplayer[i]].powers[pw_emeralds] & emeraldFlag) { - V_DrawScaledPatch(emeraldx, Y+7, V_HUDTRANS|V_SLIDEIN|V_SNAPTOLEFT, kp_rankemeralds[j]); + colormap = R_GetTranslationColormap(TC_DEFAULT, emeraldColor, GTC_CACHE); + V_DrawMappedPatch(emeraldx, Y+7, V_HUDTRANS|V_SLIDEIN|V_SNAPTOLEFT, kp_rankemerald, colormap); emeraldx += 7; } } @@ -1661,6 +1657,41 @@ static boolean K_drawKartPositionFaces(void) return false; } +static void K_drawKartEmeralds(void) +{ + static const INT32 emeraldOffsets[7][2] = { + {27, 0}, + {18, 15}, + {36, 15}, + {9, 0}, + {45, 0}, + {0, 15}, + {54, 15} + }; + + const INT32 startx = BASEVIDWIDTH - 88; + const INT32 starty = BASEVIDHEIGHT - 32; + + UINT8 *colormap; + INT32 i; + + for (i = 0; i < 7; i++) + { + UINT32 emeraldFlag = (1 << i); + UINT16 emeraldColor = SKINCOLOR_CHAOSEMERALD1 + i; + + if (stplyr->powers[pw_emeralds] & emeraldFlag) + { + colormap = R_GetTranslationColormap(TC_DEFAULT, emeraldColor, GTC_CACHE); + V_DrawMappedPatch( + startx + emeraldOffsets[i][0], starty + emeraldOffsets[i][1], + V_HUDTRANS|V_SLIDEIN|V_SNAPTOBOTTOM|V_SNAPTORIGHT, + kp_rankemerald, colormap + ); + } + } +} + // // HU_DrawTabRankings -- moved here to take advantage of kart stuff! // @@ -4137,6 +4168,6 @@ void K_drawKartHUD(void) if (gametype == GT_BATTLE) { - V_DrawRightAlignedString(BASEVIDWIDTH - 10, BASEVIDHEIGHT - 18, V_SPLITSCREEN|V_SNAPTOBOTTOM|V_SNAPTORIGHT, va("Emeralds: %d / 7", K_NumEmeralds(stplyr))); + K_drawKartEmeralds(); } } From 0db31e0fcd3d616e3758535a4fba80e51e3e3879 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 16 Nov 2020 00:17:40 -0500 Subject: [PATCH 117/143] HUD polish - Emeralds have background & white flashing - Blue sphere meter has shading - V_SLIDEIN works off of lt_exitticker instead of introtime --- src/k_hud.c | 55 ++++++++++++++++++++++++++++++++++++-------------- src/st_stuff.c | 6 ++---- 2 files changed, 42 insertions(+), 19 deletions(-) diff --git a/src/k_hud.c b/src/k_hud.c index dac19ffa6..43c3718a1 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -89,6 +89,8 @@ static patch_t *kp_tinybumper[2]; static patch_t *kp_ranknobumpers; static patch_t *kp_rankcapsule; static patch_t *kp_rankemerald; +static patch_t *kp_rankemeraldflash; +static patch_t *kp_rankemeraldback; static patch_t *kp_battlewin; static patch_t *kp_battlecool; @@ -352,6 +354,8 @@ void K_LoadKartHUDGraphics(void) kp_ranknobumpers = W_CachePatchName("K_NOBLNS", PU_HUDGFX); kp_rankcapsule = W_CachePatchName("K_CAPICO", PU_HUDGFX); kp_rankemerald = W_CachePatchName("K_EMERC", PU_HUDGFX); + kp_rankemeraldflash = W_CachePatchName("K_EMERW", PU_HUDGFX); + kp_rankemeraldback = W_CachePatchName("K_EMERBK", PU_HUDGFX); // Battle graphics kp_battlewin = W_CachePatchName("K_BWIN", PU_HUDGFX); @@ -733,11 +737,12 @@ void K_AdjustXYWithSnap(INT32 *x, INT32 *y, UINT32 options, INT32 dupx, INT32 du if (options & V_SLIDEIN) { - tic_t length = TICRATE/2; + const tic_t length = TICRATE/2; + const tic_t end = (lt_endtime + length); - if (leveltime < introtime + length) + if (lt_ticker < end) { - INT32 offset = screenwidth - (((leveltime - introtime) * screenwidth) / length); + INT32 offset = screenwidth - ((lt_exitticker * screenwidth) / length); boolean slidefromright = false; if (r_splitscreen > 1) @@ -1660,21 +1665,22 @@ static boolean K_drawKartPositionFaces(void) static void K_drawKartEmeralds(void) { static const INT32 emeraldOffsets[7][2] = { - {27, 0}, - {18, 15}, - {36, 15}, - {9, 0}, - {45, 0}, - {0, 15}, - {54, 15} + {34, 0}, + {25, 8}, + {43, 8}, + {16, 0}, + {52, 0}, + {7, 8}, + {61, 8} }; - const INT32 startx = BASEVIDWIDTH - 88; - const INT32 starty = BASEVIDHEIGHT - 32; + const INT32 startx = BASEVIDWIDTH - 77 - 8; + const INT32 starty = BASEVIDHEIGHT - 29 - 8; - UINT8 *colormap; INT32 i; + V_DrawScaledPatch(startx, starty, V_HUDTRANS|V_SLIDEIN|V_SNAPTOBOTTOM|V_SNAPTORIGHT, kp_rankemeraldback); + for (i = 0; i < 7; i++) { UINT32 emeraldFlag = (1 << i); @@ -1682,12 +1688,29 @@ static void K_drawKartEmeralds(void) if (stplyr->powers[pw_emeralds] & emeraldFlag) { + boolean whiteFlash = (leveltime & 1); + UINT8 *colormap; + + if (i & 1) + { + whiteFlash = !whiteFlash; + } + colormap = R_GetTranslationColormap(TC_DEFAULT, emeraldColor, GTC_CACHE); V_DrawMappedPatch( startx + emeraldOffsets[i][0], starty + emeraldOffsets[i][1], V_HUDTRANS|V_SLIDEIN|V_SNAPTOBOTTOM|V_SNAPTORIGHT, kp_rankemerald, colormap ); + + if (whiteFlash == true) + { + V_DrawScaledPatch( + startx + emeraldOffsets[i][0], starty + emeraldOffsets[i][1], + V_HUDTRANSHALF|V_SLIDEIN|V_SNAPTOBOTTOM|V_SNAPTORIGHT, + kp_rankemeraldflash + ); + } } } } @@ -2051,7 +2074,7 @@ static void K_drawBlueSphereMeter(void) const UINT8 sphere = max(min(stplyr->spheres, 40), 0); UINT8 numBars = min((sphere / 10), maxBars); - UINT8 color = segColors[(sphere * sizeof(segColors)) / (40 + 1)]; + UINT8 colorIndex = (sphere * sizeof(segColors)) / (40 + 1); INT32 x = LAPS_X + 25; UINT8 i; @@ -2066,7 +2089,9 @@ static void K_drawBlueSphereMeter(void) segLen = (sphere % 10); } - V_DrawFill(x, LAPS_Y - 16, segLen, 6, color | V_HUDTRANS|V_SLIDEIN|V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_SPLITSCREEN); + V_DrawFill(x, LAPS_Y - 16, segLen, 3, segColors[max(colorIndex-1, 0)] | V_HUDTRANS|V_SLIDEIN|V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_SPLITSCREEN); + V_DrawFill(x, LAPS_Y - 15, segLen, 1, segColors[max(colorIndex-2, 0)] | V_HUDTRANS|V_SLIDEIN|V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_SPLITSCREEN); + V_DrawFill(x, LAPS_Y - 13, segLen, 3, segColors[colorIndex] | V_HUDTRANS|V_SLIDEIN|V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_SPLITSCREEN); x += 15; } diff --git a/src/st_stuff.c b/src/st_stuff.c index a8e7d2434..d6f80a9f5 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -673,10 +673,8 @@ void ST_preDrawTitleCard(void) if (lt_ticker >= (lt_endtime + TICRATE)) return; - if (!lt_exitticker) - st_translucency = 0; - else - st_translucency = max(0, min((INT32)lt_exitticker-4, cv_translucenthud.value)); + // Kart: nothing + st_translucency = cv_translucenthud.value; } // From ae5d5abe245a7e6d7edcc74c8e46e095cb11f9d5 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 16 Nov 2020 00:51:00 -0500 Subject: [PATCH 118/143] Chaos Emeralds now sparkle --- src/dehacked.c | 9 +++++++++ src/info.c | 40 ++++++++++++++++++++++++++++++++++++++-- src/info.h | 10 ++++++++++ src/p_mobj.c | 16 ++++++++++++++++ 4 files changed, 73 insertions(+), 2 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 142a14efc..23359b705 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -6273,6 +6273,14 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_CHAOSEMERALD2", "S_CHAOSEMERALD_UNDER", + "S_EMERALDSPARK1", + "S_EMERALDSPARK2", + "S_EMERALDSPARK3", + "S_EMERALDSPARK4", + "S_EMERALDSPARK5", + "S_EMERALDSPARK6", + "S_EMERALDSPARK7", + // Emerald hunt shards "S_SHRD1", "S_SHRD2", @@ -9523,6 +9531,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_BLUEFLAG", // Blue CTF Flag "MT_EMBLEM", "MT_EMERALD", + "MT_EMERALDSPARK", "MT_EMERHUNT", // Emerald Hunt "MT_EMERALDSPAWN", // Emerald spawner w/ delay diff --git a/src/info.c b/src/info.c index 2f9b1faf1..4331e66b0 100644 --- a/src/info.c +++ b/src/info.c @@ -140,6 +140,7 @@ char sprnames[NUMSPRITES + 1][5] = "NSTR", // NiGHTS star "EMBM", // Emblem "EMRC", // Chaos Emeralds + "ESPK", "SHRD", // Emerald Hunt // Interactive Objects @@ -1901,10 +1902,18 @@ state_t states[NUMSTATES] = {SPR_EMBM, 25, -1, {NULL}, 0, 0, S_NULL}, // S_EMBLEM26 // Chaos Emeralds - {SPR_EMRC, FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_CHAOSEMERALD2}, // S_CHAOSEMERALD1 + {SPR_EMRC, FF_SEMIBRIGHT, 1, {NULL}, 0, 0, S_CHAOSEMERALD2}, // S_CHAOSEMERALD1 {SPR_EMRC, FF_FULLBRIGHT|FF_TRANSADD, 1, {NULL}, 0, 0, S_CHAOSEMERALD1}, // S_CHAOSEMERALD2 {SPR_EMRC, FF_FULLBRIGHT|1, -1, {NULL}, 1, 0, S_NULL}, // S_CHAOSEMERALD_UNDER + {SPR_ESPK, FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_EMERALDSPARK2}, // S_EMERALDSPARK1 + {SPR_ESPK, FF_FULLBRIGHT|1, 3, {NULL}, 0, 0, S_EMERALDSPARK3}, // S_EMERALDSPARK2 + {SPR_ESPK, FF_FULLBRIGHT|2, 3, {NULL}, 0, 0, S_EMERALDSPARK4}, // S_EMERALDSPARK3 + {SPR_ESPK, FF_FULLBRIGHT|3, 3, {NULL}, 0, 0, S_EMERALDSPARK5}, // S_EMERALDSPARK4 + {SPR_ESPK, FF_FULLBRIGHT|4, 3, {NULL}, 0, 0, S_EMERALDSPARK6}, // S_EMERALDSPARK5 + {SPR_ESPK, FF_FULLBRIGHT|5, 3, {NULL}, 0, 0, S_EMERALDSPARK7}, // S_EMERALDSPARK6 + {SPR_ESPK, FF_FULLBRIGHT|6, 3, {NULL}, 0, 0, S_NULL}, // S_EMERALDSPARK7 + // Emerald hunt shards {SPR_SHRD, 0, -1, {NULL}, 0, 0, S_NULL}, // S_SHRD1 {SPR_SHRD, 1, -1, {NULL}, 0, 0, S_NULL}, // S_SHRD2 @@ -8248,7 +8257,34 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 16, // mass 0, // damage sfx_None, // activesound - MF_SPECIAL|MF_PICKUPFROMBELOW, // flags + MF_SPECIAL|MF_PICKUPFROMBELOW|MF_DONTENCOREMAP, // flags + S_NULL // raisestate + }, + + { // MT_EMERALDSPARK + -1, // doomednum + S_EMERALDSPARK1,// 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 + 8*FRACUNIT, // radius + 8*FRACUNIT, // height + 0, // display offset + 16, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_DONTENCOREMAP, // flags S_NULL // raisestate }, diff --git a/src/info.h b/src/info.h index 1bcd03b56..d5946e8e6 100644 --- a/src/info.h +++ b/src/info.h @@ -411,6 +411,7 @@ typedef enum sprite SPR_NSTR, // NiGHTS star SPR_EMBM, // Emblem SPR_EMRC, // Chaos Emeralds + SPR_ESPK, SPR_SHRD, // Emerald Hunt // Interactive Objects @@ -2120,6 +2121,14 @@ typedef enum state S_CHAOSEMERALD2, S_CHAOSEMERALD_UNDER, + S_EMERALDSPARK1, + S_EMERALDSPARK2, + S_EMERALDSPARK3, + S_EMERALDSPARK4, + S_EMERALDSPARK5, + S_EMERALDSPARK6, + S_EMERALDSPARK7, + // Emerald hunt shards S_SHRD1, S_SHRD2, @@ -5410,6 +5419,7 @@ typedef enum mobj_type MT_BLUEFLAG, // Blue CTF Flag MT_EMBLEM, MT_EMERALD, + MT_EMERALDSPARK, MT_EMERHUNT, // Emerald Hunt MT_EMERALDSPAWN, // Emerald spawner w/ delay diff --git a/src/p_mobj.c b/src/p_mobj.c index 3c0df40fe..0b0661a60 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6460,7 +6460,23 @@ static boolean P_MobjRegularThink(mobj_t *mobj) break; case MT_EMERALD: if (mobj->threshold > 0) + { mobj->threshold--; + } + + if (leveltime % 3 == 0) + { + mobj_t *sparkle = P_SpawnMobjFromMobj( + mobj, + P_RandomRange(-48, 48) * FRACUNIT, + P_RandomRange(-48, 48) * FRACUNIT, + P_RandomRange(0, 64) * FRACUNIT, + MT_EMERALDSPARK + ); + + sparkle->color = mobj->color; + sparkle->momz += 8 * mobj->scale * P_MobjFlip(mobj); + } break; case MT_DRIFTEXPLODE: if (!mobj->target || !mobj->target->health) From 8c5abf41ea700abef567cca862b6cae0fb23dadd Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 16 Nov 2020 01:20:55 -0500 Subject: [PATCH 119/143] Bumper destruction starts with the normal bumper sprite before transitioning into the giant bumper --- src/info.c | 2 +- src/p_inter.c | 6 ++---- src/p_mobj.c | 18 +++++++++++++++--- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/info.c b/src/info.c index 4331e66b0..e9376c607 100644 --- a/src/info.c +++ b/src/info.c @@ -24113,7 +24113,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_BATTLEBUMPER_EXCRYSTALA1, // deathstate + S_BATTLEBUMPER1, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 4*FRACUNIT, // speed diff --git a/src/p_inter.c b/src/p_inter.c index 29c4cb887..3a97433a1 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1469,9 +1469,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget } target->momz += (24 * target->scale) * P_MobjFlip(target); - - target->shadowscale *= 3; - target->fuse = 16; + target->fuse = 8; overlay = P_SpawnMobjFromMobj(target, 0, 0, 0, MT_OVERLAY); @@ -1479,7 +1477,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget P_SetTarget(&overlay->target, target); overlay->color = target->color; - P_SetMobjState(overlay, S_BATTLEBUMPER_EXSHELLA1); + P_SetMobjState(overlay, S_INVISIBLE); } break; diff --git a/src/p_mobj.c b/src/p_mobj.c index 0b0661a60..348059be3 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -5290,7 +5290,19 @@ static void P_MobjSceneryThink(mobj_t *mobj) { statenum_t curState = (mobj->state - states); - if (curState >= S_BATTLEBUMPER_EXCRYSTALA1 && curState <= S_BATTLEBUMPER_EXCRYSTALA4) + if (curState == S_BATTLEBUMPER1) + { + P_SetMobjState(mobj, S_BATTLEBUMPER_EXCRYSTALA1); + + if (mobj->tracer && !P_MobjWasRemoved(mobj->tracer)) + { + P_SetMobjState(mobj->tracer, S_BATTLEBUMPER_EXSHELLA1); + } + + mobj->shadowscale *= 2; + mobj->fuse = 12; + } + else if (curState >= S_BATTLEBUMPER_EXCRYSTALA1 && curState <= S_BATTLEBUMPER_EXCRYSTALA4) { P_SetMobjState(mobj, S_BATTLEBUMPER_EXCRYSTALB1); @@ -5299,7 +5311,7 @@ static void P_MobjSceneryThink(mobj_t *mobj) P_SetMobjState(mobj->tracer, S_BATTLEBUMPER_EXSHELLB1); } - mobj->shadowscale *= 3; + mobj->shadowscale *= 2; mobj->fuse = 24; break; } @@ -5312,7 +5324,7 @@ static void P_MobjSceneryThink(mobj_t *mobj) P_SetMobjState(mobj->tracer, S_BATTLEBUMPER_EXSHELLC1); } - mobj->shadowscale *= 3; + mobj->shadowscale *= 2; mobj->fuse = 32; break; } From 0dc567973c1f2dd5946889ec59e8cb927a1fcc6e Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 16 Nov 2020 01:29:09 -0500 Subject: [PATCH 120/143] Overtime: Chaos Emeralds get deleted by the barrier, and respawn in the middle --- src/k_battle.c | 120 +++++++++++++++++++++++++++++++------------------ src/k_battle.h | 2 +- src/p_mobj.c | 39 ++++++++++------ 3 files changed, 103 insertions(+), 58 deletions(-) diff --git a/src/k_battle.c b/src/k_battle.c index 1f0db486c..84ac61b62 100644 --- a/src/k_battle.c +++ b/src/k_battle.c @@ -304,10 +304,10 @@ void K_CheckEmeralds(player_t *player) K_CheckBumpers(); } -mobj_t *K_SpawnChaosEmerald(mobj_t *parent, angle_t angle, SINT8 flip, UINT32 emeraldType) +mobj_t *K_SpawnChaosEmerald(fixed_t x, fixed_t y, fixed_t z, angle_t angle, SINT8 flip, UINT32 emeraldType) { boolean validEmerald = true; - mobj_t *emerald = P_SpawnMobjFromMobj(parent, 0, 0, 0, MT_EMERALD); + mobj_t *emerald = P_SpawnMobj(x, y, z, MT_EMERALD); mobj_t *overlay; P_Thrust(emerald, @@ -373,7 +373,7 @@ void K_DropEmeraldsFromPlayer(player_t *player, UINT32 emeraldType) if ((player->powers[pw_emeralds] & emeraldFlag) && (emeraldFlag & emeraldType)) { - mobj_t *emerald = K_SpawnChaosEmerald(player->mo, player->mo->angle - ANGLE_90, flip, emeraldFlag); + mobj_t *emerald = K_SpawnChaosEmerald(player->mo->x, player->mo->y, player->mo->z, player->mo->angle - ANGLE_90, flip, emeraldFlag); P_SetTarget(&emerald->target, player->mo); player->powers[pw_emeralds] &= ~emeraldFlag; @@ -403,7 +403,15 @@ void K_RunPaperItemSpawners(void) { const boolean overtime = (battleovertime.enabled >= 10*TICRATE); tic_t interval = 8*TICRATE; + UINT32 emeraldsSpawned = 0; + UINT32 firstUnspawnedEmerald = 0; + + thinker_t *th; + mobj_t *mo; + + UINT8 pcount = 0; + INT16 i; if (leveltime < starttime) { @@ -411,19 +419,16 @@ void K_RunPaperItemSpawners(void) return; } - if ((battleovertime.enabled > 0) && (battleovertime.radius < 256*mapobjectscale)) - { - // Barrier has closed in too much - return; - } - if (overtime == true) { + if (battleovertime.radius < 512*mapobjectscale) + { + // Barrier has closed in too much + return; + } + // Double frequency of items interval /= 2; - - // Even if this isn't true, we pretend it is, because it's too late to do anything about it :p - emeraldsSpawned = EMERALD_ALLCHAOS; } if (((leveltime - starttime) % interval) != 0) @@ -431,39 +436,72 @@ void K_RunPaperItemSpawners(void) return; } + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i] || players[i].spectator) + { + continue; + } + + emeraldsSpawned |= players[i].powers[pw_emeralds]; + + if ((players[i].exiting > 0 || players[i].eliminated) + || ((gametyperules & GTR_BUMPERS) && players[i].bumpers <= 0)) + { + continue; + } + + pcount++; + } + if (overtime == true) { SINT8 flip = 1; - K_CreatePaperItem( - battleovertime.x, battleovertime.y, battleovertime.z + (128 * mapobjectscale * flip), - FixedAngle(P_RandomRange(0, 359) * FRACUNIT), flip, - 0, 0 - ); + // Just find emeralds, no paper spots + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) + { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + + mo = (mobj_t *)th; + + if (mo->type == MT_EMERALD) + { + emeraldsSpawned |= mo->extravalue1; + } + } + + for (i = 0; i < 7; i++) + { + UINT32 emeraldFlag = (1 << i); + + if (!(emeraldsSpawned & emeraldFlag)) + { + firstUnspawnedEmerald = emeraldFlag; + break; + } + } + + if (firstUnspawnedEmerald != 0) + { + K_SpawnChaosEmerald( + battleovertime.x, battleovertime.y, battleovertime.z + (128 * mapobjectscale * flip), + FixedAngle(P_RandomRange(0, 359) * FRACUNIT), flip, + firstUnspawnedEmerald + ); + } + else + { + K_CreatePaperItem( + battleovertime.x, battleovertime.y, battleovertime.z + (128 * mapobjectscale * flip), + FixedAngle(P_RandomRange(0, 359) * FRACUNIT), flip, + 0, 0 + ); + } } else { - UINT8 pcount = 0; - INT16 i; - - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i] || players[i].spectator) - { - continue; - } - - emeraldsSpawned |= players[i].powers[pw_emeralds]; - - if ((players[i].exiting > 0 || players[i].eliminated) - || ((gametyperules & GTR_BUMPERS) && players[i].bumpers <= 0)) - { - continue; - } - - pcount++; - } - if (pcount > 0) { #define MAXITEM 64 @@ -471,12 +509,8 @@ void K_RunPaperItemSpawners(void) mobj_t *spotList[MAXITEM]; boolean spotUsed[MAXITEM]; - UINT32 firstUnspawnedEmerald = 0; INT16 starti = 0; - thinker_t *th; - mobj_t *mo; - memset(spotUsed, false, sizeof(spotUsed)); for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) @@ -541,7 +575,7 @@ void K_RunPaperItemSpawners(void) if (i == -1) { drop = K_SpawnChaosEmerald( - spotList[r], + spotList[r]->x, spotList[r]->y, spotList[r]->z + (128 * mapobjectscale * flip), FixedAngle(P_RandomRange(0, 359) * FRACUNIT), flip, firstUnspawnedEmerald ); diff --git a/src/k_battle.h b/src/k_battle.h index ddd8a5437..4b1508cbf 100644 --- a/src/k_battle.h +++ b/src/k_battle.h @@ -21,7 +21,7 @@ void K_CalculateBattleWanted(void); void K_SpawnBattlePoints(player_t *source, player_t *victim, UINT8 amount); void K_CheckBumpers(void); void K_CheckEmeralds(player_t *player); -mobj_t *K_SpawnChaosEmerald(mobj_t *parent, angle_t angle, SINT8 flip, UINT32 emeraldType); +mobj_t *K_SpawnChaosEmerald(fixed_t x, fixed_t y, fixed_t z, angle_t angle, SINT8 flip, UINT32 emeraldType); void K_DropEmeraldsFromPlayer(player_t *player, UINT32 emeraldType); UINT8 K_NumEmeralds(player_t *player); void K_RunPaperItemSpawners(void); diff --git a/src/p_mobj.c b/src/p_mobj.c index 348059be3..dd69a9036 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6471,23 +6471,34 @@ static boolean P_MobjRegularThink(mobj_t *mobj) mobj->health--; break; case MT_EMERALD: - if (mobj->threshold > 0) { - mobj->threshold--; - } + if (battleovertime.enabled >= 10*TICRATE) + { + fixed_t distance = R_PointToDist2(mobj->x, mobj->y, battleovertime.x, battleovertime.y); - if (leveltime % 3 == 0) - { - mobj_t *sparkle = P_SpawnMobjFromMobj( - mobj, - P_RandomRange(-48, 48) * FRACUNIT, - P_RandomRange(-48, 48) * FRACUNIT, - P_RandomRange(0, 64) * FRACUNIT, - MT_EMERALDSPARK - ); + if (distance > battleovertime.radius) + { + // Delete emeralds to let them reappear + P_KillMobj(mobj, NULL, NULL, DMG_NORMAL); + } + } - sparkle->color = mobj->color; - sparkle->momz += 8 * mobj->scale * P_MobjFlip(mobj); + if (leveltime % 3 == 0) + { + mobj_t *sparkle = P_SpawnMobjFromMobj( + mobj, + P_RandomRange(-48, 48) * FRACUNIT, + P_RandomRange(-48, 48) * FRACUNIT, + P_RandomRange(0, 64) * FRACUNIT, + MT_EMERALDSPARK + ); + + sparkle->color = mobj->color; + sparkle->momz += 8 * mobj->scale * P_MobjFlip(mobj); + } + + if (mobj->threshold > 0) + mobj->threshold--; } break; case MT_DRIFTEXPLODE: From ef0da6ce9cca3ad1b4682c7e1f120a81245a5e31 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 16 Nov 2020 02:38:13 -0500 Subject: [PATCH 121/143] Finished bumper destruction --- src/dehacked.c | 16 ++++++++++++ src/info.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/info.h | 18 +++++++++++++ src/p_mobj.c | 57 +++++++++++++++++++++++++++++++++++++++- 4 files changed, 160 insertions(+), 1 deletion(-) diff --git a/src/dehacked.c b/src/dehacked.c index 23359b705..b04ccd92f 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -8748,6 +8748,20 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_BATTLEBUMPER_EXSHELLC1", "S_BATTLEBUMPER_EXSHELLC2", + "S_BATTLEBUMPER_EXDEBRIS1", + "S_BATTLEBUMPER_EXDEBRIS2", + + "S_BATTLEBUMPER_EXBLAST1", + "S_BATTLEBUMPER_EXBLAST2", + "S_BATTLEBUMPER_EXBLAST3", + "S_BATTLEBUMPER_EXBLAST4", + "S_BATTLEBUMPER_EXBLAST5", + "S_BATTLEBUMPER_EXBLAST6", + "S_BATTLEBUMPER_EXBLAST7", + "S_BATTLEBUMPER_EXBLAST8", + "S_BATTLEBUMPER_EXBLAST9", + "S_BATTLEBUMPER_EXBLAST10", + // DEZ respawn laser "S_DEZLASER", "S_DEZLASER_TRAIL1", @@ -10228,6 +10242,8 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_SINKTRAIL", "MT_BATTLEBUMPER", // Battle Mode bumper + "MT_BATTLEBUMPER_DEBRIS", + "MT_BATTLEBUMPER_BLAST", "MT_DEZLASER", diff --git a/src/info.c b/src/info.c index e9376c607..ae7e58b8e 100644 --- a/src/info.c +++ b/src/info.c @@ -560,6 +560,8 @@ char sprnames[NUMSPRITES + 1][5] = "KBLN", // Battle Mode Bumper "BEXC", // Battle Bumper Explosion: Crystal "BEXS", // Battle Bumper Explosion: Shell + "BDEB", // Battle Bumper Explosion: Debris + "BEXB", // Battle Bumper Explosion: Blast "DEZL", // DEZ Laser respawn @@ -4431,6 +4433,20 @@ state_t states[NUMSTATES] = {SPR_BEXS, FF_FULLBRIGHT|4, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXSHELLC2}, // S_BATTLEBUMPER_EXSHELLC1 {SPR_BEXS, FF_FULLBRIGHT|5, 1, {NULL}, 0, 0, S_BATTLEBUMPER_EXSHELLC1}, // S_BATTLEBUMPER_EXSHELLC2 + {SPR_BDEB, FF_FULLBRIGHT|FF_ANIMATE, 84, {NULL}, 13, 6, S_BATTLEBUMPER_EXDEBRIS2}, // S_BATTLEBUMPER_EXDEBRIS1 + {SPR_BDEB, FF_FULLBRIGHT|13, 20, {NULL}, 0, 0, S_NULL}, // S_BATTLEBUMPER_EXDEBRIS2 + + {SPR_BEXB, FF_FULLBRIGHT|FF_PAPERSPRITE, 2, {NULL}, 0, 0, S_BATTLEBUMPER_EXBLAST2}, // S_BATTLEBUMPER_EXBLAST1 + {SPR_BEXB, FF_FULLBRIGHT|FF_PAPERSPRITE|FF_TRANS10, 2, {NULL}, 0, 0, S_BATTLEBUMPER_EXBLAST3}, // S_BATTLEBUMPER_EXBLAST2 + {SPR_BEXB, FF_FULLBRIGHT|FF_PAPERSPRITE|FF_TRANS20, 2, {NULL}, 0, 0, S_BATTLEBUMPER_EXBLAST4}, // S_BATTLEBUMPER_EXBLAST3 + {SPR_BEXB, FF_FULLBRIGHT|FF_PAPERSPRITE|FF_TRANS30, 2, {NULL}, 0, 0, S_BATTLEBUMPER_EXBLAST5}, // S_BATTLEBUMPER_EXBLAST4 + {SPR_BEXB, FF_FULLBRIGHT|FF_PAPERSPRITE|FF_TRANS40, 2, {NULL}, 0, 0, S_BATTLEBUMPER_EXBLAST6}, // S_BATTLEBUMPER_EXBLAST5 + {SPR_BEXB, FF_FULLBRIGHT|FF_PAPERSPRITE|FF_TRANS50, 2, {NULL}, 0, 0, S_BATTLEBUMPER_EXBLAST7}, // S_BATTLEBUMPER_EXBLAST6 + {SPR_BEXB, FF_FULLBRIGHT|FF_PAPERSPRITE|FF_TRANS60, 2, {NULL}, 0, 0, S_BATTLEBUMPER_EXBLAST8}, // S_BATTLEBUMPER_EXBLAST7 + {SPR_BEXB, FF_FULLBRIGHT|FF_PAPERSPRITE|FF_TRANS70, 2, {NULL}, 0, 0, S_BATTLEBUMPER_EXBLAST9}, // S_BATTLEBUMPER_EXBLAST8 + {SPR_BEXB, FF_FULLBRIGHT|FF_PAPERSPRITE|FF_TRANS80, 2, {NULL}, 0, 0, S_BATTLEBUMPER_EXBLAST10}, // S_BATTLEBUMPER_EXBLAST9 + {SPR_BEXB, FF_FULLBRIGHT|FF_PAPERSPRITE|FF_TRANS90, 2, {NULL}, 0, 0, S_NULL}, // S_BATTLEBUMPER_EXBLAST10 + {SPR_DEZL, FF_FULLBRIGHT|FF_PAPERSPRITE, 8, {NULL}, 0, 0, S_NULL}, // S_DEZLASER {SPR_DEZL, FF_FULLBRIGHT|1, 2, {NULL}, 0, 0, S_DEZLASER_TRAIL2}, // S_DEZLASER_TRAIL1 {SPR_DEZL, FF_FULLBRIGHT|2, 2, {NULL}, 0, 0, S_DEZLASER_TRAIL3}, // S_DEZLASER_TRAIL2 @@ -24127,6 +24143,60 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_BATTLEBUMPER_DEBRIS + -1, // doomednum + S_BATTLEBUMPER_EXDEBRIS1,// 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 + 8*FRACUNIT, // radius + 16*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_NOCLIPTHING|MF_SCENERY|MF_DONTENCOREMAP, // flags + S_NULL // raisestate + }, + + { // MT_BATTLEBUMPER_BLAST + -1, // doomednum + S_BATTLEBUMPER_EXBLAST1, // 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 + 8*FRACUNIT, // radius + 16*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_NOCLIPTHING|MF_SCENERY|MF_DONTENCOREMAP, // flags + S_NULL // raisestate + }, + { // MT_DEZLASER -1, // doomednum S_DEZLASER, // spawnstate diff --git a/src/info.h b/src/info.h index d5946e8e6..d51267587 100644 --- a/src/info.h +++ b/src/info.h @@ -831,6 +831,8 @@ typedef enum sprite SPR_KBLN, // Battle Mode Bumper SPR_BEXC, // Battle Bumper Explosion: Crystal SPR_BEXS, // Battle Bumper Explosion: Shell + SPR_BDEB, // Battle Bumper Explosion: Debris + SPR_BEXB, // Battle Bumper Explosion: Blast SPR_DEZL, // DEZ Laser respawn @@ -4596,6 +4598,20 @@ typedef enum state S_BATTLEBUMPER_EXSHELLC1, S_BATTLEBUMPER_EXSHELLC2, + S_BATTLEBUMPER_EXDEBRIS1, + S_BATTLEBUMPER_EXDEBRIS2, + + S_BATTLEBUMPER_EXBLAST1, + S_BATTLEBUMPER_EXBLAST2, + S_BATTLEBUMPER_EXBLAST3, + S_BATTLEBUMPER_EXBLAST4, + S_BATTLEBUMPER_EXBLAST5, + S_BATTLEBUMPER_EXBLAST6, + S_BATTLEBUMPER_EXBLAST7, + S_BATTLEBUMPER_EXBLAST8, + S_BATTLEBUMPER_EXBLAST9, + S_BATTLEBUMPER_EXBLAST10, + // DEZ Laser respawn S_DEZLASER, S_DEZLASER_TRAIL1, @@ -6116,6 +6132,8 @@ typedef enum mobj_type MT_SINKTRAIL, MT_BATTLEBUMPER, // Battle Mode bumpers + MT_BATTLEBUMPER_DEBRIS, + MT_BATTLEBUMPER_BLAST, MT_DEZLASER, diff --git a/src/p_mobj.c b/src/p_mobj.c index dd69a9036..b74380517 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -5330,7 +5330,54 @@ static void P_MobjSceneryThink(mobj_t *mobj) } else { - // TODO: confetti goes here + const INT16 spacing = 64; + UINT8 i; + + for (i = 0; i < 10; i++) + { + mobj_t *debris = P_SpawnMobjFromMobj( + mobj, + P_RandomRange(-spacing, spacing) * FRACUNIT, + P_RandomRange(-spacing, spacing) * FRACUNIT, + P_RandomRange(-spacing, spacing) * FRACUNIT, + MT_BATTLEBUMPER_DEBRIS + ); + + P_SetScale(debris, (debris->destscale *= 2)); + debris->color = mobj->color; + + debris->momz = -debris->scale * P_MobjFlip(debris); + } + + for (i = 0; i < 2; i++) + { + mobj_t *blast = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_BATTLEBUMPER_BLAST); + + blast->angle = R_PointToAngle2(0, 0, mobj->momx, mobj->momy) + ANGLE_45; + blast->destscale *= 4; + + if (i & 1) + { + blast->angle += ANGLE_90; + } + } + + for (i = 0; i < 10; i++) + { + mobj_t *puff = P_SpawnMobjFromMobj( + mobj, + P_RandomRange(-spacing, spacing) * FRACUNIT, + P_RandomRange(-spacing, spacing) * FRACUNIT, + P_RandomRange(-spacing, spacing) * FRACUNIT, + MT_SPINDASHDUST + ); + + P_SetScale(puff, (puff->destscale *= 5)); + puff->momz = puff->scale * P_MobjFlip(puff); + + P_Thrust(puff, R_PointToAngle2(mobj->x, mobj->y, puff->x, puff->y), puff->scale); + } + P_RemoveMobj(mobj); return; } @@ -5425,6 +5472,14 @@ static void P_MobjSceneryThink(mobj_t *mobj) } break; + + case MT_BATTLEBUMPER_DEBRIS: + if (mobj->state == states + S_BATTLEBUMPER_EXDEBRIS2) + { + mobj->drawflags ^= MFD_DONTDRAW; + } + break; + case MT_PLAYERARROW: if (mobj->target && mobj->target->health && mobj->target->player && !mobj->target->player->spectator From c31efd8631fc02585e7d04617e3c4fe819c3e899 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 16 Nov 2020 02:59:41 -0500 Subject: [PATCH 122/143] Give bumper destruction some sound effects --- src/p_inter.c | 7 +------ src/p_mobj.c | 6 ++++++ src/sounds.c | 6 +++--- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index 3a97433a1..a16705741 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1452,6 +1452,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget mobj_t *owner = target->target; mobj_t *overlay; + S_StartSound(target, sfx_kc52); target->flags &= ~MF_NOGRAVITY; target->destscale = (3 * target->destscale) / 2; @@ -1459,12 +1460,6 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget if (owner && !P_MobjWasRemoved(owner)) { - /* - target->momx = owner->momx / 2; - target->momy = owner->momy / 2; - target->momz = owner->momz / 2; - */ - P_Thrust(target, R_PointToAngle2(owner->x, owner->y, target->x, target->y), 4 * target->scale); } diff --git a/src/p_mobj.c b/src/p_mobj.c index b74380517..e04c90fea 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -5286,6 +5286,11 @@ static void P_MobjSceneryThink(mobj_t *mobj) { mobj->fuse--; + if (!S_SoundPlaying(mobj, sfx_cdfm71)) + { + S_StartSound(mobj, sfx_cdfm71); + } + if (mobj->fuse <= 0) { statenum_t curState = (mobj->state - states); @@ -5359,6 +5364,7 @@ static void P_MobjSceneryThink(mobj_t *mobj) if (i & 1) { blast->angle += ANGLE_90; + S_StartSound(blast, sfx_cdfm64); } } diff --git a/src/sounds.c b/src/sounds.c index d06e521d0..dc777a088 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -740,14 +740,14 @@ sfxinfo_t S_sfx[NUMSFX] = {"cdfm61", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"cdfm62", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Speed boost"}, {"cdfm63", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, - {"cdfm64", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"cdfm64", false, 64, 8, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"cdfm65", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"cdfm66", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"cdfm67", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"cdfm68", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"cdfm69", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"cdfm70", false, 96, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, - {"cdfm71", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"cdfm71", false, 64, 8, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"cdfm72", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"cdfm73", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"cdfm74", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, @@ -808,7 +808,7 @@ sfxinfo_t S_sfx[NUMSFX] = {"kc4f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"kc50", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"kc51", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, ""}, - {"kc52", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"kc52", false, 64, 8, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"kc53", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"kc54", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"kc55", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, From 34450fa028e1d394070cdc6a3c686400baa9dc4c Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 16 Nov 2020 05:16:34 -0800 Subject: [PATCH 123/143] Don't add translucency to THOK Various visuals use THOKS, maybe there should be another barebones type with no extra handling. But this is good enough for now. --- src/p_mobj.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index ae09c87e1..42e61a918 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8437,7 +8437,7 @@ void P_MobjThinker(mobj_t *mobj) if (mobj->scale != mobj->destscale) P_MobjScaleThink(mobj); // Slowly scale up/down to reach your destscale. - if ((mobj->type == MT_GHOST || mobj->type == MT_THOK) && mobj->fuse > 0) // Not guaranteed to be MF_SCENERY or not MF_SCENERY! + if (mobj->type == MT_GHOST && mobj->fuse > 0) // Not guaranteed to be MF_SCENERY or not MF_SCENERY! { if (mobj->flags2 & MF2_BOSSNOTRAP) // "fast" flag { From 082d253553fdd0b6670d12455f40a747b83371e1 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 16 Nov 2020 17:00:21 -0500 Subject: [PATCH 124/143] Remove bot friction Not convinced this fixes anything anymore --- src/k_bot.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/k_bot.c b/src/k_bot.c index a32a554e1..899a70eb1 100644 --- a/src/k_bot.c +++ b/src/k_bot.c @@ -473,6 +473,10 @@ fixed_t K_BotTopSpeedRubberband(player_t *player) --------------------------------------------------*/ fixed_t K_BotFrictionRubberband(player_t *player, fixed_t frict) { +#if 1 + (void)player; + return frict; +#else fixed_t rubberband = K_BotRubberband(player) - FRACUNIT; fixed_t newfrict; @@ -490,6 +494,7 @@ fixed_t K_BotFrictionRubberband(player_t *player, fixed_t frict) newfrict = FRACUNIT; return newfrict; +#endif } /*-------------------------------------------------- From 6a4eb721bd5798d3150a31e2699efa711a3604bf Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 16 Nov 2020 18:35:07 -0500 Subject: [PATCH 125/143] The real problem --- src/k_bot.c | 5 ----- src/p_user.c | 5 ----- 2 files changed, 10 deletions(-) diff --git a/src/k_bot.c b/src/k_bot.c index 899a70eb1..a32a554e1 100644 --- a/src/k_bot.c +++ b/src/k_bot.c @@ -473,10 +473,6 @@ fixed_t K_BotTopSpeedRubberband(player_t *player) --------------------------------------------------*/ fixed_t K_BotFrictionRubberband(player_t *player, fixed_t frict) { -#if 1 - (void)player; - return frict; -#else fixed_t rubberband = K_BotRubberband(player) - FRACUNIT; fixed_t newfrict; @@ -494,7 +490,6 @@ fixed_t K_BotFrictionRubberband(player_t *player, fixed_t frict) newfrict = FRACUNIT; return newfrict; -#endif } /*-------------------------------------------------- diff --git a/src/p_user.c b/src/p_user.c index 6c6c0578a..8065ae13b 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1941,11 +1941,6 @@ static void P_3dMovement(player_t *player) totalthrust.x += P_ReturnThrustX(player->mo, movepushangle, movepushforward); totalthrust.y += P_ReturnThrustY(player->mo, movepushangle, movepushforward); - - if (K_PlayerUsesBotMovement(player) == true) - { - K_MomentumToFacing(player); - } } if ((totalthrust.x || totalthrust.y) From f4e763ed722dd1481029b5f3271bf1ccbeba84ff Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 17 Nov 2020 18:49:14 -0500 Subject: [PATCH 126/143] Use additive/subtractive on models --- src/hardware/hw_drv.h | 2 +- src/hardware/hw_md2.c | 12 +++++++++--- src/hardware/r_opengl/r_opengl.c | 8 ++++---- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/hardware/hw_drv.h b/src/hardware/hw_drv.h index 1480ee839..613005421 100644 --- a/src/hardware/hw_drv.h +++ b/src/hardware/hw_drv.h @@ -50,7 +50,7 @@ EXPORT void HWRAPI(ClearMipMapCache) (void); EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value); //Hurdler: added for new development -EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface); +EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface, FBITFIELD blendmode); EXPORT void HWRAPI(CreateModelVBOs) (model_t *model); EXPORT void HWRAPI(SetTransform) (FTransform *stransform); EXPORT INT32 HWRAPI(GetTextureUsed) (void); diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index f68771a1b..25c0589c6 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1357,6 +1357,7 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) angle_t ang; INT32 mod; float finalscale; + FBITFIELD blendmode = PF_Masked; // hitlag vibrating if (spr->mobj->hitlag > 0) @@ -1378,12 +1379,17 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) //durs = tics; if (spr->mobj->drawflags & MFD_TRANSMASK) - HWR_TranstableToAlpha((spr->mobj->drawflags & MFD_TRANSMASK)>>MFD_TRANSSHIFT, &Surf); + blendmode = HWR_TranstableToAlpha((spr->mobj->drawflags & MFD_TRANSMASK)>>MFD_TRANSSHIFT, &Surf); else if (spr->mobj->frame & FF_TRANSMASK) - HWR_TranstableToAlpha((spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT, &Surf); + blendmode = HWR_TranstableToAlpha((spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT, &Surf); else Surf.PolyColor.s.alpha = 0xFF; + if (blendmode == PF_Masked) + { + blendmode |= PF_Occlude; + } + // dont forget to enabled the depth test because we can't do this like // before: polygons models are not sorted @@ -1646,7 +1652,7 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) #endif HWD.pfnSetShader(SHADER_MODEL); // model shader - HWD.pfnDrawModel(md2->model, frame, durs, tics, nextFrame, &p, finalscale, flip, hflip, &Surf); + HWD.pfnDrawModel(md2->model, frame, durs, tics, nextFrame, &p, finalscale, flip, hflip, &Surf, blendmode); } return true; diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 942d3d3de..1f1fcdbd5 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -2513,7 +2513,7 @@ EXPORT void HWRAPI(CreateModelVBOs) (model_t *model) #define BUFFER_OFFSET(i) ((void*)(i)) -static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface) +static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface, FBITFIELD blendmode) { static GLRGBAFloat poly = {0,0,0,0}; static GLRGBAFloat tint = {0,0,0,0}; @@ -2593,7 +2593,7 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 else pglColor4ubv((GLubyte*)&Surface->PolyColor.s); - SetBlend((poly.alpha < 1 ? PF_Translucent : (PF_Masked|PF_Occlude))|PF_Modulated); + SetBlend(blendmode|PF_Modulated); tint.red = byte2float[Surface->TintColor.s.red]; tint.green = byte2float[Surface->TintColor.s.green]; @@ -2812,9 +2812,9 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 // -----------------+ // HWRAPI DrawModel : Draw a model // -----------------+ -EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface) +EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface, FBITFIELD blendmode) { - DrawModelEx(model, frameIndex, duration, tics, nextFrameIndex, pos, scale, flipped, hflipped, Surface); + DrawModelEx(model, frameIndex, duration, tics, nextFrameIndex, pos, scale, flipped, hflipped, Surface, blendmode); } // -----------------+ From a4cd61d226985ee48fd911b128692c262d305d36 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Wed, 18 Nov 2020 17:08:54 -0500 Subject: [PATCH 127/143] Make i consistent with orbs variable --- src/k_battle.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/k_battle.c b/src/k_battle.c index 84ac61b62..7a3d43967 100644 --- a/src/k_battle.c +++ b/src/k_battle.c @@ -709,7 +709,7 @@ void K_RunBattleOvertime(void) fixed_t size = FixedMul(mobjinfo[MT_OVERTIME_PARTICLE].radius, scale); fixed_t posOffset = max(battleovertime.radius - size, 0); - UINT32 i; + INT32 i; for (i = 0; i < orbs; i++) { From 931bcb3c2a3b908abbe7e648c5e1210ccd9e3af7 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Wed, 18 Nov 2020 17:10:48 -0500 Subject: [PATCH 128/143] Fix laps counter after finishing --- src/d_netcmd.c | 6 +++--- src/k_hud.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 6ce0b6df9..373f4f4f2 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -461,9 +461,9 @@ static CV_PossibleValue_t pointlimit_cons_t[] = {{1, "MIN"}, {MAXSCORE, "MAX"}, consvar_t cv_pointlimit = CVAR_INIT ("pointlimit", "None", CV_SAVE|CV_NETVAR|CV_CALL|CV_NOINIT, pointlimit_cons_t, PointLimit_OnChange); static CV_PossibleValue_t timelimit_cons_t[] = {{1, "MIN"}, {30, "MAX"}, {0, "None"}, {0, NULL}}; consvar_t cv_timelimit = CVAR_INIT ("timelimit", "None", CV_SAVE|CV_NETVAR|CV_CALL|CV_NOINIT, timelimit_cons_t, TimeLimit_OnChange); -static CV_PossibleValue_t numlaps_cons_t[] = {{1, "MIN"}, {50, "MAX"}, {0, NULL}}; -consvar_t cv_numlaps = CVAR_INIT ("numlaps", "4", CV_NETVAR|CV_CALL|CV_NOINIT, numlaps_cons_t, NumLaps_OnChange); -static CV_PossibleValue_t basenumlaps_cons_t[] = {{1, "MIN"}, {50, "MAX"}, {0, "Map default"}, {0, NULL}}; +static CV_PossibleValue_t numlaps_cons_t[] = {{1, "MIN"}, {99, "MAX"}, {0, NULL}}; +consvar_t cv_numlaps = CVAR_INIT ("numlaps", "3", CV_NETVAR|CV_CALL|CV_NOINIT, numlaps_cons_t, NumLaps_OnChange); +static CV_PossibleValue_t basenumlaps_cons_t[] = {{1, "MIN"}, {99, "MAX"}, {0, "Map default"}, {0, NULL}}; consvar_t cv_basenumlaps = CVAR_INIT ("basenumlaps", "Map default", CV_SAVE|CV_NETVAR|CV_CALL|CV_CHEAT, basenumlaps_cons_t, BaseNumLaps_OnChange); // Point and time limits for every gametype diff --git a/src/k_hud.c b/src/k_hud.c index 43c3718a1..36577ced5 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -1979,7 +1979,7 @@ static void K_drawKartLapsAndRings(void) { // Laps V_DrawScaledPatch(LAPS_X, LAPS_Y, V_HUDTRANS|V_SLIDEIN|splitflags, kp_lapsticker); - V_DrawKartString(LAPS_X+33, LAPS_Y+3, V_HUDTRANS|V_SLIDEIN|splitflags, va("%d/%d", stplyr->laps, cv_numlaps.value)); + V_DrawKartString(LAPS_X+33, LAPS_Y+3, V_HUDTRANS|V_SLIDEIN|splitflags, va("%d/%d", min(stplyr->laps, cv_numlaps.value), cv_numlaps.value)); // Rings if (!uselives) From 350a8bd5c44103beb3b77f37ea0a8bf43e8625ef Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Wed, 18 Nov 2020 17:24:03 -0500 Subject: [PATCH 129/143] We can bring this back now --- src/d_clisrv.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 3374bbae0..30ab8e7ab 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -6240,12 +6240,12 @@ void NetUpdate(void) firstticstosend = gametic; for (i = 0; i < MAXNETNODES; i++) if (nodeingame[i] && nettics[i] < firstticstosend) - //{ + { firstticstosend = nettics[i]; - //if (maketic + 1 >= nettics[i] + BACKUPTICS) - //Net_ConnectionTimeout(i); - //} + if (maketic + 1 >= nettics[i] + BACKUPTICS) + Net_ConnectionTimeout(i); + } // Don't erase tics not acknowledged counts = realtics; From 6f6e87f9df7d74ef7c0abc26576ae7e52f51fd42 Mon Sep 17 00:00:00 2001 From: toaster Date: Fri, 27 Nov 2020 17:32:04 +0000 Subject: [PATCH 130/143] Fix replays not being accessible via menus. --- src/m_menu.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 7f6f542c6..56c5585b4 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -8139,11 +8139,11 @@ static void M_ReplayTimeAttack(INT32 choice) break; case 3: // guest // srb2/replay/main/map01-guest.lmp - G_DoPlayDemo(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value))); + G_DoPlayDemo(va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value))); return; } // srb2/replay/main/map01-sonic-time-best.lmp - G_DoPlayDemo(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), cv_chooseskin.string, which)); + G_DoPlayDemo(va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), cv_chooseskin.string, which)); } /*else if (currentMenu == &SP_NightsReplayDef) { @@ -8165,13 +8165,13 @@ static void M_ReplayTimeAttack(INT32 choice) break; } // srb2/replay/main/map01-score-best.lmp - G_DoPlayDemo(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), which)); + G_DoPlayDemo(va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), which)); }*/ } static void M_EraseGuest(INT32 choice) { - const char *rguest = va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value)); + const char *rguest = va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value)); (void)choice; if (FIL_FileExists(rguest)) remove(rguest); @@ -8186,10 +8186,10 @@ static void M_EraseGuest(INT32 choice) static void M_OverwriteGuest(const char *which) { - char *rguest = Z_StrDup(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value))); + char *rguest = Z_StrDup(va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value))); UINT8 *buf; size_t len; - len = FIL_ReadFile(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), cv_chooseskin.string, which), &buf); + len = FIL_ReadFile(va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), cv_chooseskin.string, which), &buf); if (!len) { return; } @@ -8258,7 +8258,7 @@ static void M_SetGuestReplay(INT32 choice) M_StartMessage(M_GetText("Are you sure you want to\ndelete the guest replay data?\n\n(Press 'Y' to confirm)\n"),M_EraseGuest,MM_YESNO); return; } - if (FIL_FileExists(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value)))) + if (FIL_FileExists(va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value)))) M_StartMessage(M_GetText("Are you sure you want to\noverwrite the guest replay data?\n\n(Press 'Y' to confirm)\n"),which,MM_YESNO); else which(0); From 9c0edb097f728c87ed214bebbd32671e753ea6dc Mon Sep 17 00:00:00 2001 From: toaster Date: Fri, 27 Nov 2020 17:59:57 +0000 Subject: [PATCH 131/143] Fix demos doing incomprehensibly nasty bullshit; now they only desync for a handful of easier-to-hammer-down cases. --- src/g_demo.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/src/g_demo.c b/src/g_demo.c index 7c2f9f25c..9b5687750 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -1205,9 +1205,6 @@ void G_GhostTicker(void) g->p += 12; // kartitem, kartamount, kartbumpers } - if (READUINT8(g->p) != 0xFF) // Make sure there isn't other ghost data here. - I_Error("Ghost is not a record attack ghost"); //@TODO lmao don't blow up like this - skippedghosttic: // Tick ghost colors (Super and Mario Invincibility flashing) switch(g->color) @@ -1294,6 +1291,7 @@ skippedghosttic: P_RemoveMobj(follow); P_SetTarget(&follow, NULL); } + // Demo ends after ghost data. if (*g->p == DEMOMARKER) { @@ -1314,6 +1312,10 @@ skippedghosttic: Z_Free(g); continue; } + + if (READUINT8(g->p) != 0xFF) // Make sure there isn't other ghost data here. + I_Error("Ghost is not a record attack ghost"); //@TODO lmao don't blow up like this + p = g; #undef follow } @@ -1899,7 +1901,8 @@ void G_BeginRecording(void) if (encoremode) demoflags |= DF_ENCORE; - demoflags |= DF_LUAVARS; + if (multiplayer) + demoflags |= DF_LUAVARS; // Setup header. M_Memcpy(demo_p, DEMOHEADER, 12); demo_p += 12; @@ -2033,9 +2036,8 @@ void G_BeginRecording(void) WRITEUINT8(demo_p, 0xFF); // Denote the end of the player listing // player lua vars, always saved even if empty - LUA_Archive(&demo_p); - - WRITEUINT32(demo_p,P_GetInitSeed()); + if (demoflags & DF_LUAVARS) + LUA_Archive(&demo_p); memset(&oldcmd,0,sizeof(oldcmd)); memset(&oldghost,0,sizeof(oldghost)); @@ -3145,6 +3147,14 @@ void G_AddGhost(char *defdemoname) return; } + if (flags & DF_LUAVARS) // can't be arsed to add support for grinding away ported lua material + { + CONS_Alert(CONS_NOTICE, M_GetText("Ghost %s: Replay data contains luavars, cannot continue.\n"), pdemoname); + Z_Free(pdemoname); + Z_Free(buffer); + return; + } + p++; // gametype G_SkipDemoExtraFiles(&p); // Don't wanna modify the file list for ghosts. From f72108c4faa6ec5abb06b1f788f78d646202b764 Mon Sep 17 00:00:00 2001 From: toaster Date: Fri, 27 Nov 2020 20:30:28 +0000 Subject: [PATCH 132/143] A whole bunch of cleanup to get most record attack/replay stuff reasonably functional. * Fix the screen being stuck black at the very start of start record attack. * Bump up the demoversion to 7, because I want all previous v2 demos to be guaranteed kaput (it was previously 4, but 7 is a nice number). * Fix a ton MORE shitcausing misalignments in the replay system, this time specifically focused on getting ghosts functional. * Plug a few holes in the "best lap" record implementation that allowed for stupidly easy records due to the way v2's finish lines work. * Make a few follower-related things sane, to prevent spurious console prints that were getting in the way of my test prints. --- src/d_netcmd.c | 15 ++---- src/g_demo.c | 127 +++++++++++++++++++++++++------------------------ src/p_spec.c | 17 +++---- src/p_tick.c | 4 +- src/p_user.c | 4 +- src/r_skins.c | 5 ++ 6 files changed, 85 insertions(+), 87 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index a87d04cb5..46ecc1b97 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -289,10 +289,10 @@ consvar_t cv_skin[MAXSPLITSCREENPLAYERS] = { // player's followers. Also saved. consvar_t cv_follower[MAXSPLITSCREENPLAYERS] = { - CVAR_INIT ("follower", "-1", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Follower_OnChange), - CVAR_INIT ("follower2", "-1", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Follower2_OnChange), - CVAR_INIT ("follower3", "-1", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Follower3_OnChange), - CVAR_INIT ("follower4", "-1", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Follower4_OnChange) + CVAR_INIT ("follower", "None", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Follower_OnChange), + CVAR_INIT ("follower2", "None", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Follower2_OnChange), + CVAR_INIT ("follower3", "None", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Follower3_OnChange), + CVAR_INIT ("follower4", "None", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Follower4_OnChange) }; // player's follower colors... Also saved... @@ -2858,13 +2858,6 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum) memset(&luabanks, 0, sizeof(luabanks)); } - if (modeattacking) - { - SetPlayerSkinByNum(0, cv_chooseskin.value-1); - players[0].skincolor = skins[players[0].skin].prefcolor; - CV_StealthSetValue(&cv_playercolor[0], players[0].skincolor); - } - mapnumber = M_MapNumber(mapname[3], mapname[4]); LUAh_MapChange(mapnumber); diff --git a/src/g_demo.c b/src/g_demo.c index 9b5687750..69c8fb760 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -104,7 +104,7 @@ demoghost *ghosts = NULL; // DEMO RECORDING // -#define DEMOVERSION 0x0004 +#define DEMOVERSION 0x0007 #define DEMOHEADER "\xF0" "KartReplay" "\x0F" #define DF_GHOST 0x01 // This demo contains ghost data too! @@ -112,7 +112,7 @@ demoghost *ghosts = NULL; #define DF_BREAKTHECAPSULES 0x04 // This demo is from Break the Capsules and contains its final completion time! #define DF_ATTACKMASK 0x06 // This demo is from ??? attack and contains ??? -#define DF_LUAVARS 0x20 // this demo contains extra lua vars; this is mostly used for backwards compability +#define DF_LUAVARS 0x20 // this demo contains extra lua vars #define DF_ATTACKSHIFT 1 #define DF_ENCORE 0x40 @@ -419,7 +419,10 @@ void G_WriteDemoExtraData(void) { // write follower memset(name, 0, 16); - strncpy(name, followers[players[i].followerskin].skinname, 16); + if (players[i].followerskin == -1) + strncpy(name, "None", 16); + else + strncpy(name, followers[players[i].followerskin].skinname, 16); M_Memcpy(demo_p, name, 16); demo_p += 16; @@ -619,13 +622,21 @@ void G_WriteAllGhostTics(void) counter++; - if (counter % cv_netdemosyncquality.value != 0) // Only write 1 in this many ghost datas per tic to cut down on multiplayer replay size. + if (multiplayer && (counter % cv_netdemosyncquality.value != 0)) // Only write 1 in this many ghost datas per tic to cut down on multiplayer replay size. continue; WRITEUINT8(demo_p, i); G_WriteGhostTic(players[i].mo, i); } WRITEUINT8(demo_p, 0xFF); + + // attention here for the ticcmd size! + // latest demos with mouse aiming byte in ticcmd + if (demo_p >= demoend - (13 + 9 + 9)) + { + G_CheckDemoStatus(); // no more space + return; + } } void G_WriteGhostTic(mobj_t *ghost, INT32 playernum) @@ -722,26 +733,22 @@ void G_WriteGhostTic(mobj_t *ghost, INT32 playernum) ghostext[playernum].flags |= EZT_SPRITE; } + if (ghost->player && ( + ghostext[playernum].kartitem != ghost->player->kartstuff[k_itemtype] || + ghostext[playernum].kartamount != ghost->player->kartstuff[k_itemamount] || + ghostext[playernum].kartbumpers != ghost->player->kartstuff[k_bumper] + )) + { + ghostext[playernum].flags |= EZT_KART; + ghostext[playernum].kartitem = ghost->player->kartstuff[k_itemtype]; + ghostext[playernum].kartamount = ghost->player->kartstuff[k_itemamount]; + ghostext[playernum].kartbumpers = ghost->player->kartstuff[k_bumper]; + } + if (ghostext[playernum].flags) { ziptic |= GZT_EXTRA; - if (ghost->player) - { - if ( - ghostext[playernum].kartitem != ghost->player->kartstuff[k_itemtype] || - ghostext[playernum].kartamount != ghost->player->kartstuff[k_itemamount] || - ghostext[playernum].kartbumpers != ghost->player->kartstuff[k_bumper] - ) - { - ghostext[playernum].flags |= EZT_KART; - ghostext[playernum].kartitem = ghost->player->kartstuff[k_itemtype]; - ghostext[playernum].kartamount = ghost->player->kartstuff[k_itemamount]; - ghostext[playernum].kartbumpers = ghost->player->kartstuff[k_bumper]; - - } - } - if (ghostext[playernum].color == ghostext[playernum].lastcolor) ghostext[playernum].flags &= ~EZT_COLOR; if (ghostext[playernum].scale == ghostext[playernum].lastscale) @@ -836,14 +843,6 @@ void G_WriteGhostTic(mobj_t *ghost, INT32 playernum) oldghost[playernum].flags2 &= ~MF2_AMBUSH; *ziptic_p = ziptic; - - // attention here for the ticcmd size! - // latest demos with mouse aiming byte in ticcmd - if (demo_p >= demoend - (13 + 9 + 9)) - { - G_CheckDemoStatus(); // no more space - return; - } } void G_ConsAllGhostTics(void) @@ -1067,16 +1066,18 @@ void G_GhostTicker(void) if (ziptic & DXD_FOLLOWER) g->p += 32; // ok (32 because there's both the skin and the colour) if (ziptic & DXD_PLAYSTATE && READUINT8(g->p) != DXD_PST_PLAYING) - I_Error("Ghost is not a record attack ghost"); //@TODO lmao don't blow up like this + I_Error("Ghost is not a record attack ghost PLAYSTATE"); //@TODO lmao don't blow up like this } else if (ziptic == DW_RNG) g->p += 4; // RNG seed else - I_Error("Ghost is not a record attack ghost"); //@TODO lmao don't blow up like this + I_Error("Ghost is not a record attack ghost DXD"); //@TODO lmao don't blow up like this ziptic = READUINT8(g->p); } + ziptic = READUINT8(g->p); + if (ziptic & ZT_FWD) g->p++; if (ziptic & ZT_TURNING) @@ -1086,9 +1087,9 @@ void G_GhostTicker(void) if (ziptic & ZT_AIMING) g->p += 2; if (ziptic & ZT_LATENCY) - g->p += 1; + g->p++; if (ziptic & ZT_FLAGS) - g->p += 1; + g->p++; // Grab ghost data. ziptic = READUINT8(g->p); @@ -1096,7 +1097,7 @@ void G_GhostTicker(void) if (ziptic == 0xFF) goto skippedghosttic; // Didn't write ghost info this frame else if (ziptic != 0) - I_Error("Ghost is not a record attack ghost"); //@TODO lmao don't blow up like this + I_Error("Ghost is not a record attack ghost ZIPTIC"); //@TODO lmao don't blow up like this ziptic = READUINT8(g->p); if (ziptic & GZT_XYZ) @@ -1109,17 +1110,17 @@ void G_GhostTicker(void) { if (ziptic & GZT_MOMXY) { - g->oldmo.momx = (g->version < 0x000e) ? READINT16(g->p)<<8 : READFIXED(g->p); - g->oldmo.momy = (g->version < 0x000e) ? READINT16(g->p)<<8 : READFIXED(g->p); + g->oldmo.momx = READFIXED(g->p); + g->oldmo.momy = READFIXED(g->p); } if (ziptic & GZT_MOMZ) - g->oldmo.momz = (g->version < 0x000e) ? READINT16(g->p)<<8 : READFIXED(g->p); + g->oldmo.momz = READFIXED(g->p); g->oldmo.x += g->oldmo.momx; g->oldmo.y += g->oldmo.momy; g->oldmo.z += g->oldmo.momz; } if (ziptic & GZT_ANGLE) - g->mo->angle = READUINT8(g->p)<<24; + g->oldmo.angle = READUINT8(g->p)<<24; if (ziptic & GZT_FRAME) g->oldmo.frame = READUINT8(g->p); if (ziptic & GZT_SPR2) @@ -1205,27 +1206,6 @@ void G_GhostTicker(void) g->p += 12; // kartitem, kartamount, kartbumpers } -skippedghosttic: - // Tick ghost colors (Super and Mario Invincibility flashing) - switch(g->color) - { - case GHC_SUPER: // Super (P_DoSuperStuff) - if (g->mo->skin) - { - skin_t *skin = (skin_t *)g->mo->skin; - g->mo->color = skin->supercolor; - } - else - g->mo->color = SKINCOLOR_SUPERGOLD1; - g->mo->color += abs( ( (signed)( (unsigned)leveltime >> 1 ) % 9) - 4); - break; - case GHC_INVINCIBLE: // Mario invincibility (P_CheckInvincibilityTimer) - g->mo->color = (UINT16)(SKINCOLOR_RUBY + (leveltime % (FIRSTSUPERCOLOR - SKINCOLOR_RUBY))); // Passes through all saturated colours - break; - default: - break; - } - #define follow g->mo->tracer if (ziptic & GZT_FOLLOW) { // Even more... @@ -1292,6 +1272,30 @@ skippedghosttic: P_SetTarget(&follow, NULL); } +skippedghosttic: + // Tick ghost colors (Super and Mario Invincibility flashing) + switch(g->color) + { + case GHC_SUPER: // Super (P_DoSuperStuff) + if (g->mo->skin) + { + skin_t *skin = (skin_t *)g->mo->skin; + g->mo->color = skin->supercolor; + } + else + g->mo->color = SKINCOLOR_SUPERGOLD1; + g->mo->color += abs( ( (signed)( (unsigned)leveltime >> 1 ) % 9) - 4); + break; + case GHC_INVINCIBLE: // Mario invincibility (P_CheckInvincibilityTimer) + g->mo->color = (UINT16)(SKINCOLOR_RUBY + (leveltime % (FIRSTSUPERCOLOR - SKINCOLOR_RUBY))); // Passes through all saturated colours + break; + default: + break; + } + + if (READUINT8(g->p) != 0xFF) // Make sure there isn't other ghost data here. + I_Error("Ghost is not a record attack ghost GHOSTEND"); //@TODO lmao don't blow up like this + // Demo ends after ghost data. if (*g->p == DEMOMARKER) { @@ -1313,9 +1317,6 @@ skippedghosttic: continue; } - if (READUINT8(g->p) != 0xFF) // Make sure there isn't other ghost data here. - I_Error("Ghost is not a record attack ghost"); //@TODO lmao don't blow up like this - p = g; #undef follow } @@ -2714,7 +2715,6 @@ void G_DoPlayDemo(char *defdemoname) demo.version = READUINT16(demo_p); switch(demo.version) { - case 0x000d: case DEMOVERSION: // latest always supported break; // too old, cannot support. @@ -3103,7 +3103,6 @@ void G_AddGhost(char *defdemoname) ghostversion = READUINT16(p); switch(ghostversion) { - case 0x000d: case DEMOVERSION: // latest always supported break; // too old, cannot support. @@ -3221,6 +3220,8 @@ void G_AddGhost(char *defdemoname) kartspeed = READUINT8(p); kartweight = READUINT8(p); + p += 4; // followitem (maybe change later) + if (READUINT8(p) != 0xFF) { CONS_Alert(CONS_NOTICE, M_GetText("Failed to add ghost %s: Invalid player slot.\n"), pdemoname); diff --git a/src/p_spec.c b/src/p_spec.c index 3d0eddd2e..519f21cd4 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -2028,6 +2028,14 @@ static void K_HandleLapIncrement(player_t *player) player->karthud[khud_laphand] = 0; // No hands in FREE PLAY player->karthud[khud_lapanimation] = 80; + + // save best lap for record attack + if (player == &players[consoleplayer]) + { + if (curlap < bestlap || bestlap == 0) + bestlap = curlap; + curlap = 0; + } } if (rainbowstartavailable == true) @@ -2041,14 +2049,6 @@ static void K_HandleLapIncrement(player_t *player) if (netgame && player->laps >= (UINT8)cv_numlaps.value) CON_LogMessage(va(M_GetText("%s has finished the race.\n"), player_names[player-players])); - // SRB2Kart: save best lap for record attack - if (player == &players[consoleplayer]) - { - if (curlap < bestlap || bestlap == 0) - bestlap = curlap; - curlap = 0; - } - player->starpostnum = 0; if (P_IsDisplayPlayer(player)) @@ -2133,6 +2133,7 @@ static void K_HandleLapDecrement(player_t *player) { player->starpostnum = numstarposts; player->laps--; + curlap = UINT32_MAX; } } } diff --git a/src/p_tick.c b/src/p_tick.c index 79e71c655..9d7a6ac5c 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -613,9 +613,7 @@ void P_Ticker(boolean run) if (run) leveltime++; - // as this is mostly used for HUD stuff, add the record attack specific hack to it as well! - if (!(modeattacking && !demo.playback) || leveltime >= starttime - TICRATE*4) - timeinmap++; + timeinmap++; if (G_GametypeHasTeams()) P_DoTeamStuff(); diff --git a/src/p_user.c b/src/p_user.c index f03c63464..10b2c9a97 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2644,7 +2644,7 @@ static void P_DeathThink(player_t *player) { if (player->spectator || !circuitmap) curlap = 0; - else + else if (curlap != UINT32_MAX) curlap++; // This is too complicated to sync to realtime, just sorta hope for the best :V } } @@ -4385,7 +4385,7 @@ void P_PlayerThink(player_t *player) { if (player->spectator || !circuitmap) curlap = 0; - else + else if (curlap != UINT32_MAX) curlap++; // This is too complicated to sync to realtime, just sorta hope for the best :V } } diff --git a/src/r_skins.c b/src/r_skins.c index 951eeaad6..135221ea6 100644 --- a/src/r_skins.c +++ b/src/r_skins.c @@ -876,6 +876,11 @@ boolean SetPlayerFollower(INT32 playernum, const char *skinname) INT32 i; player_t *player = &players[playernum]; + if (stricmp("None", skinname) == 0) + { + SetFollower(playernum, -1); // reminder that -1 is nothing + return true; + } for (i = 0; i < numfollowers; i++) { // search in the skin list From c2447154ecec27e0a6e9e1ab7acf5ee077f99004 Mon Sep 17 00:00:00 2001 From: toaster Date: Sat, 28 Nov 2020 11:32:29 +0000 Subject: [PATCH 133/143] Bracketing fix for Sryder. --- src/g_demo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/g_demo.c b/src/g_demo.c index 69c8fb760..773c0119e 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -622,7 +622,7 @@ void G_WriteAllGhostTics(void) counter++; - if (multiplayer && (counter % cv_netdemosyncquality.value != 0)) // Only write 1 in this many ghost datas per tic to cut down on multiplayer replay size. + if (multiplayer && ((counter % cv_netdemosyncquality.value) != 0)) // Only write 1 in this many ghost datas per tic to cut down on multiplayer replay size. continue; WRITEUINT8(demo_p, i); From 495e4896dcef5a4e9f0d911cdac5cfcc751e575e Mon Sep 17 00:00:00 2001 From: toaster Date: Sat, 28 Nov 2020 11:45:25 +0000 Subject: [PATCH 134/143] Fixed Chengi's sprite2 bug, and started on (but haven't nailed down) the rewind crash. --- src/g_demo.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/g_demo.c b/src/g_demo.c index 773c0119e..aebc447f2 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -1439,8 +1439,11 @@ void G_PreviewRewind(tic_t previewtime) players[i].drawangle = info->playerinfo[i].player.drawangle + FixedMul((INT32) (next_info->playerinfo[i].player.drawangle - info->playerinfo[i].player.drawangle), tweenvalue); players[i].mo->sprite = info->playerinfo[i].mobj.sprite; + players[i].mo->sprite2 = info->playerinfo[i].mobj.sprite2; players[i].mo->frame = info->playerinfo[i].mobj.frame; + players[i].mo->hitlag = info->playerinfo[i].mobj.hitlag; + players[i].realtime = info->playerinfo[i].player.realtime; for (j = 0; j < NUMKARTSTUFF; j++) players[i].kartstuff[j] = info->playerinfo[i].player.kartstuff[j]; From 762dfd3063f50854399a46865fe9b34379f18b08 Mon Sep 17 00:00:00 2001 From: toaster Date: Sat, 28 Nov 2020 12:31:16 +0000 Subject: [PATCH 135/143] When resuming from a rewind, don't: * run wipes again * run titlecards again * stop the music --- src/g_demo.c | 2 +- src/g_game.c | 2 +- src/p_setup.c | 60 +++++++++++++++++++++++++-------------------------- src/p_tick.c | 2 ++ 4 files changed, 34 insertions(+), 32 deletions(-) diff --git a/src/g_demo.c b/src/g_demo.c index aebc447f2..693a4f095 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -1468,7 +1468,7 @@ void G_ConfirmRewind(tic_t rewindtime) if (rewindtime <= starttime) { - demo.rewinding = false; + demo.rewinding = true; // this doesn't APPEAR to cause any misery, and it allows us to prevent running all the wipes again G_DoPlayDemo(NULL); // Restart the current demo } else diff --git a/src/g_game.c b/src/g_game.c index 0151783e9..1f17fc181 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1252,7 +1252,7 @@ void G_StartTitleCard(void) { // The title card has been disabled for this map. // Oh well. - if (!G_IsTitleCardAvailable()) + if (!G_IsTitleCardAvailable() || demo.rewinding) { WipeStageTitle = false; return; diff --git a/src/p_setup.c b/src/p_setup.c index 50f39c5fa..15e6767a5 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3924,40 +3924,40 @@ boolean P_LoadLevel(boolean fromnetsave) } */ - // Make sure all sounds are stopped before Z_FreeTags. - S_StopSounds(); - S_ClearSfx(); - - // Fade out music here. Deduct 2 tics so the fade volume actually reaches 0. - // But don't halt the music! S_Start will take care of that. This dodges a MIDI crash bug. - if (!titlemapinaction) - S_FadeMusic(0, FixedMul( - FixedDiv((F_GetWipeLength(wipedefs[wipe_level_toblack])-2)*NEWTICRATERATIO, NEWTICRATE), MUSICRATE)); - - // Reset the palette now all fades have been done - if (rendermode != render_none) - V_SetPaletteLump(GetPalette()); // Set the level palette - - if (!titlemapinaction) - { - if (ranspecialwipe == 2) - { - pausedelay = -3; // preticker plus one - S_StartSound(NULL, sfx_s3k73); - } - - // As oddly named as this is, this handles music only. - // We should be fine starting it here. - // Don't do this during titlemap, because the menu code handles music by itself. - S_Start(); - } - - levelfadecol = (encoremode ? 0 : 31); - // Let's fade to white here // But only if we didn't do the encore startup wipe if (!demo.rewinding) { + // Make sure all sounds are stopped before Z_FreeTags. + S_StopSounds(); + S_ClearSfx(); + + // Fade out music here. Deduct 2 tics so the fade volume actually reaches 0. + // But don't halt the music! S_Start will take care of that. This dodges a MIDI crash bug. + if (!titlemapinaction) + S_FadeMusic(0, FixedMul( + FixedDiv((F_GetWipeLength(wipedefs[wipe_level_toblack])-2)*NEWTICRATERATIO, NEWTICRATE), MUSICRATE)); + + // Reset the palette now all fades have been done + if (rendermode != render_none) + V_SetPaletteLump(GetPalette()); // Set the level palette + + if (!titlemapinaction) + { + if (ranspecialwipe == 2) + { + pausedelay = -3; // preticker plus one + S_StartSound(NULL, sfx_s3k73); + } + + // As oddly named as this is, this handles music only. + // We should be fine starting it here. + // Don't do this during titlemap, because the menu code handles music by itself. + S_Start(); + } + + levelfadecol = (encoremode ? 0 : 31); + if (rendermode != render_none) { F_WipeStartScreen(); diff --git a/src/p_tick.c b/src/p_tick.c index 9d7a6ac5c..cef59ea8d 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -516,6 +516,8 @@ void P_Ticker(boolean run) if (demo.rewinding && leveltime > 0) { leveltime = (leveltime-1) & ~3; + if (timeinmap > 0) + timeinmap = (timeinmap-1) & ~3; G_PreviewRewind(leveltime); } else if (demo.freecam && democam.cam) // special case: allow freecam to MOVE during pause! From 891f14dd26848fa4b4abbbdf3a395f18d7e20974 Mon Sep 17 00:00:00 2001 From: toaster Date: Sat, 28 Nov 2020 17:29:28 +0000 Subject: [PATCH 136/143] Don't show post-race bot inputs on input display UI. --- src/k_hud.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/k_hud.c b/src/k_hud.c index 42c7fd7c2..056beb408 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -3523,7 +3523,7 @@ static void K_drawInput(void) #define BUTTH 11 #define drawbutt(xoffs, butt, symb)\ - if (stplyr->cmd.buttons & butt)\ + if (!stplyr->exiting && (cmd->buttons & butt))\ {\ offs = 2;\ col = accent1;\ @@ -3549,7 +3549,7 @@ static void K_drawInput(void) y -= 1; - if (!cmd->turning) // no turn + if (stplyr->exiting || !cmd->turning) // no turn target = 0; else // turning of multiple strengths! { From a7621f4e96f7b3c450ddf710dfc87b7c5a2d56fe Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 29 Nov 2020 16:41:48 -0800 Subject: [PATCH 137/143] Fix compiler warning --- src/k_hud.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/k_hud.c b/src/k_hud.c index fa4c86f9a..ec80a8f96 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -2166,8 +2166,8 @@ static void K_drawKartBumpersOrKarma(void) if (stplyr->bumpers > 9 || maxbumper > 9) { UINT8 ln[2]; - ln[0] = ((abs(stplyr->bumpers) / 10) % 10); - ln[1] = (abs(stplyr->bumpers) % 10); + ln[0] = (stplyr->bumpers / 10 % 10); + ln[1] = (stplyr->bumpers % 10); V_DrawScaledPatch(fx+13, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font[ln[0]]); V_DrawScaledPatch(fx+17, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font[ln[1]]); From 90507126e47cdd5d4ecf8273f5f6b74e0ea82ffa Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 4 Jan 2021 17:34:10 -0800 Subject: [PATCH 138/143] Move block line checks to a single function --- src/p_map.c | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index d3e9aaa80..b60d243e2 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1624,6 +1624,22 @@ static boolean PIT_CheckCameraLine(line_t *ld) return true; } +static boolean P_IsLineBlocking(const line_t *ld, const mobj_t *thing) +{ + // missiles can cross uncrossable lines + if ((thing->flags & MF_MISSILE)) + return false; + else + { + return + ( + (ld->flags & ML_IMPASSABLE) || // block objects from moving through this linedef. + (thing->player && !thing->player->spectator && + ld->flags & ML_BLOCKPLAYERS) // SRB2Kart: Only block players, not items + ); + } +} + // // PIT_CheckLine // Adjusts tmfloorz and tmceilingz as lines are contacted @@ -1699,14 +1715,8 @@ static boolean PIT_CheckLine(line_t *ld) return false; } - // missiles can cross uncrossable lines - if (!(tmthing->flags & MF_MISSILE)) - { - if (ld->flags & ML_IMPASSABLE) // block objects from moving through this linedef. - return false; - if (tmthing->player && !tmthing->player->spectator && ld->flags & ML_BLOCKPLAYERS) - return false; // SRB2Kart: Only block players, not items - } + if (P_IsLineBlocking(ld, tmthing)) + return false; // set openrange, opentop, openbottom P_LineOpening(ld, tmthing); @@ -3172,14 +3182,8 @@ static boolean PTR_LineIsBlocking(line_t *li) if (!li->backsector) return !P_PointOnLineSide(slidemo->x, slidemo->y, li); - if (!(slidemo->flags & MF_MISSILE)) - { - if (li->flags & ML_IMPASSABLE) - return true; - - if (slidemo->player && !slidemo->player->spectator && li->flags & ML_BLOCKPLAYERS) - return true; - } + if (P_IsLineBlocking(li, slidemo)) + return true; // set openrange, opentop, openbottom P_LineOpening(li, slidemo); From 6070d14fa5772398a8977be1f8346f60b5c0d0c4 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 4 Jan 2021 17:40:06 -0800 Subject: [PATCH 139/143] Line special 11: block monsters for this line --- src/p_map.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/p_map.c b/src/p_map.c index b60d243e2..d6a3044cb 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1635,7 +1635,8 @@ static boolean P_IsLineBlocking(const line_t *ld, const mobj_t *thing) ( (ld->flags & ML_IMPASSABLE) || // block objects from moving through this linedef. (thing->player && !thing->player->spectator && - ld->flags & ML_BLOCKPLAYERS) // SRB2Kart: Only block players, not items + ld->flags & ML_BLOCKPLAYERS) || // SRB2Kart: Only block players, not items + ((thing->flags & (MF_ENEMY|MF_BOSS)) && ld->special == 11) // case 11: block monsters only ); } } From c76ae9a4fd878826312202697b38ac2210fd14d2 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 4 Jan 2021 18:55:33 -0800 Subject: [PATCH 140/143] Actually put it on line type 81 --- src/p_map.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_map.c b/src/p_map.c index d6a3044cb..898ee0a49 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1636,7 +1636,7 @@ static boolean P_IsLineBlocking(const line_t *ld, const mobj_t *thing) (ld->flags & ML_IMPASSABLE) || // block objects from moving through this linedef. (thing->player && !thing->player->spectator && ld->flags & ML_BLOCKPLAYERS) || // SRB2Kart: Only block players, not items - ((thing->flags & (MF_ENEMY|MF_BOSS)) && ld->special == 11) // case 11: block monsters only + ((thing->flags & (MF_ENEMY|MF_BOSS)) && ld->special == 81) // case 81: block monsters only ); } } From fe4d9ce8895da6242d02b148778c76efc84d82a5 Mon Sep 17 00:00:00 2001 From: Latapostrophe Date: Wed, 6 Jan 2021 21:20:28 +0100 Subject: [PATCH 141/143] New trick panel shit (but only the gameplay part) --- src/d_clisrv.c | 20 +++++--- src/d_clisrv.h | 5 +- src/d_player.h | 14 ++++-- src/k_kart.c | 116 ++++++++++++++++++++++++++++++++------------ src/lua_playerlib.c | 12 +++++ src/p_inter.c | 2 +- src/p_map.c | 4 +- src/p_mobj.c | 6 +-- src/p_saveg.c | 14 ++++-- src/p_spec.c | 2 +- 10 files changed, 142 insertions(+), 53 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 610152d90..3c4c087df 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -617,7 +617,10 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i) rsp->airtime = (tic_t)LONG(players[i].airtime); rsp->trickpanel = (UINT8)players[i].trickpanel; - rsp->trickdelay = (tic_t)LONG(players[i].trickdelay); + rsp->trickdelay = (boolean)players[i].trickdelay; + rsp->trickmomx = (fixed_t)LONG(players[i].trickmomx); + rsp->trickmomy = (fixed_t)LONG(players[i].trickmomy); + rsp->trickmomz = (fixed_t)LONG(players[i].trickmomz); rsp->bumpers = players[i].bumpers; rsp->karmadelay = SHORT(players[i].karmadelay); @@ -767,7 +770,10 @@ static void resynch_read_player(resynch_pak *rsp) players[i].airtime = (tic_t)LONG(rsp->airtime); players[i].trickpanel = (UINT8)rsp->trickpanel; - players[i].trickdelay = (tic_t)LONG(rsp->trickdelay); + players[i].trickdelay = (boolean)rsp->trickdelay; + players[i].trickmomx = (fixed_t)LONG(rsp->trickmomx); + players[i].trickmomy = (fixed_t)LONG(rsp->trickmomy); + players[i].trickmomz = (fixed_t)LONG(rsp->trickmomz); players[i].bumpers = rsp->bumpers; players[i].karmadelay = SHORT(rsp->karmadelay); @@ -1260,7 +1266,7 @@ static inline void CL_DrawConnectionStatus(void) cltext = M_GetText("Server full, waiting for a slot..."); else cltext = M_GetText("Requesting to join..."); - + break; #ifdef HAVE_CURL case CL_PREPAREHTTPFILES: @@ -2129,7 +2135,7 @@ void CL_UpdateServerList (void) static void M_ConfirmConnect(event_t *ev) { -#ifndef NONET +#ifndef NONET if (ev->type == ev_keydown) { if (ev->data1 == ' ' || ev->data1 == 'y' || ev->data1 == KEY_ENTER || ev->data1 == gamecontrol[0][gc_accelerate][0] || ev->data1 == gamecontrol[0][gc_accelerate][1]) @@ -2152,7 +2158,7 @@ static void M_ConfirmConnect(event_t *ev) } else cl_mode = CL_LOADFILES; - + M_ClearMenus(true); } else if (ev->data1 == 'n' || ev->data1 == KEY_ESCAPE|| ev->data1 == gamecontrol[0][gc_brake][0] || ev->data1 == gamecontrol[0][gc_brake][1]) @@ -2400,7 +2406,7 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic { boolean waitmore; INT32 i; - + #ifdef NONET (void)tmpsave; #endif @@ -2437,7 +2443,7 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic { curl_transfers++; } - + cl_mode = CL_DOWNLOADHTTPFILES; } break; diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 365059c3d..ae9e59e7a 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -282,7 +282,10 @@ typedef struct INT32 kartstuff[NUMKARTSTUFF]; tic_t airtime; UINT8 trickpanel; - tic_t trickdelay; + boolean trickdelay; + fixed_t trickmomx; + fixed_t trickmomy; + fixed_t trickmomz; UINT8 bumpers; INT16 karmadelay; diff --git a/src/d_player.h b/src/d_player.h index 07eecc54d..89679e9f1 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -449,6 +449,10 @@ typedef enum // QUICKLY GET RING TOTAL, INCLUDING RINGS CURRENTLY IN THE PICKUP ANIMATION #define RINGTOTAL(p) (p->rings + p->kartstuff[k_pickuprings]) +// CONSTANTS FOR TRICK PANELS +#define TRICKMOMZRAMP (30) +#define TRICKLAG (9) + //} // player_t struct for all respawn variables @@ -523,9 +527,13 @@ typedef struct player_s UINT32 distancetofinish; waypoint_t *nextwaypoint; respawnvars_t respawn; // Respawn info - tic_t airtime; // Keep track of how long you've been in the air - UINT8 trickpanel; // Trick panel state - tic_t trickdelay; + tic_t airtime; // Keep track of how long you've been in the air + + UINT8 trickpanel; // Trick panel state + boolean trickdelay; // Prevent tricks until control stick is neutral + fixed_t trickmomx; + fixed_t trickmomy; + fixed_t trickmomz; // Instead of stupid auxiliary variables let's... just make some ourselves. UINT8 bumpers; INT16 karmadelay; diff --git a/src/k_kart.c b/src/k_kart.c index a94dce177..6a05c50d5 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -2052,7 +2052,7 @@ INT16 K_GetSpindashChargeTime(player_t *player) { // more charge time for higher speed // Tails = 2s, Mighty = 3s, Fang = 4s, Metal = 4s - return (player->kartspeed + 4) * (TICRATE/3); + return (player->kartspeed + 4) * (TICRATE/3); } fixed_t K_GetSpindashChargeSpeed(player_t *player) @@ -4209,6 +4209,8 @@ void K_DoPogoSpring(mobj_t *mo, fixed_t vertispeed, UINT8 sound) { thrust = FixedMul(thrust, 9*FRACUNIT/8); } + + mo->player->trickmomx = mo->player->trickmomy = mo->player->trickmomz = 0; // Reset post-hitlag momentums. } mo->momz = FixedMul(thrust, vscale); @@ -7830,7 +7832,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) K_PlayBoostTaunt(player->mo); K_DoPogoSpring(player->mo, 32<trickpanel = 1; - player->trickdelay = TICRATE/2; + player->trickdelay = 1; player->kartstuff[k_itemamount]--; } break; @@ -7944,49 +7946,101 @@ void K_MoveKartPlayer(player_t *player, boolean onground) player->mo->drawflags &= ~(MFD_TRANSMASK|MFD_BRIGHTMASK); } - if (player->trickpanel == 1 && player->trickdelay <= 0) + if (player->trickpanel == 1) { const angle_t lr = ANGLE_45; - fixed_t speed = P_AproxDistance(player->mo->momx, player->mo->momy); + fixed_t momz = FixedDiv(player->mo->momz, mapobjectscale); // bring momz back to scale... + fixed_t speedmult = max(0, FRACUNIT - abs(momz)/TRICKMOMZRAMP); // TRICKMOMZRAMP momz is minimum speed (Should be 20) + fixed_t basespeed = P_AproxDistance(player->mo->momx, player->mo->momy); // at WORSE, keep your normal speed when tricking. + fixed_t speed = FixedMul(speedmult, P_AproxDistance(player->mo->momx, player->mo->momy)); - if (cmd->turning > 0) + // debug shit + //CONS_Printf("%d\n", player->mo->momz / mapobjectscale); + + if (player->trickdelay <= 0) { - P_InstaThrust(player->mo, player->mo->angle + lr, speed*2); - player->trickpanel = 2; - } - else if (cmd->turning < 0) - { - P_InstaThrust(player->mo, player->mo->angle - lr, speed*2); - player->trickpanel = 3; - } - else if (player->kartstuff[k_throwdir] == 1) - { - if (player->mo->momz * P_MobjFlip(player->mo) > 0) + + if (cmd->turning > 0) { + P_InstaThrust(player->mo, player->mo->angle + lr, max(basespeed, speed*2)); + + player->trickmomx = player->mo->momx; + player->trickmomy = player->mo->momy; + player->trickmomz = player->mo->momz; + P_InstaThrust(player->mo, 0, 0); // Sike, you have no speed :) player->mo->momz = 0; + + player->trickpanel = 2; + player->mo->hitlag = TRICKLAG; } - - P_InstaThrust(player->mo, player->mo->angle, speed*3); - player->trickpanel = 2; - } - else if (player->kartstuff[k_throwdir] == -1) - { - boolean relative = true; - - player->mo->momx /= 3; - player->mo->momy /= 3; - - if (player->mo->momz * P_MobjFlip(player->mo) <= 0) + else if (cmd->turning < 0) { - relative = false; + P_InstaThrust(player->mo, player->mo->angle - lr, max(basespeed, speed*2)); + + player->trickmomx = player->mo->momx; + player->trickmomy = player->mo->momy; + player->trickmomz = player->mo->momz; + P_InstaThrust(player->mo, 0, 0); // Sike, you have no speed :) + player->mo->momz = 0; + + player->trickpanel = 3; + player->mo->hitlag = TRICKLAG; } + else if (player->kartstuff[k_throwdir] == 1) + { + if (player->mo->momz * P_MobjFlip(player->mo) > 0) + { + player->mo->momz = 0; + } - P_SetObjectMomZ(player->mo, 48*FRACUNIT, relative); + P_InstaThrust(player->mo, player->mo->angle, max(basespeed, speed*3)); - player->trickpanel = 3; + player->trickmomx = player->mo->momx; + player->trickmomy = player->mo->momy; + player->trickmomz = player->mo->momz; + P_InstaThrust(player->mo, 0, 0); // Sike, you have no speed :) + player->mo->momz = 0; + + player->trickpanel = 2; + player->mo->hitlag = TRICKLAG; + } + else if (player->kartstuff[k_throwdir] == -1) + { + boolean relative = true; + + player->mo->momx /= 3; + player->mo->momy /= 3; + + if (player->mo->momz * P_MobjFlip(player->mo) <= 0) + { + relative = false; + } + + P_SetObjectMomZ(player->mo, 48*FRACUNIT, relative); + + player->trickmomx = player->mo->momx; + player->trickmomy = player->mo->momy; + player->trickmomz = player->mo->momz; + P_InstaThrust(player->mo, 0, 0); // Sike, you have no speed :) + player->mo->momz = 0; + + player->trickpanel = 3; + player->mo->hitlag = TRICKLAG; + } } } + // After hitlag, we will get here and will be able to apply the desired momentums! + else if (player->trickmomx || player->trickmomy || player->trickmomz) + { + player->mo->momx = player->trickmomx; + player->mo->momy = player->trickmomy; + player->mo->momz = player->trickmomz; + player->trickmomx = player->trickmomy = player->trickmomz = 0; + + } + + // Wait until we let go off the control stick to remove the delay if (player->trickdelay > 0) { player->trickdelay--; diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index f28987700..daf1666c8 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -218,6 +218,12 @@ static int player_get(lua_State *L) lua_pushinteger(L, plr->trickpanel); else if (fastcmp(field,"trickdelay")) lua_pushinteger(L, plr->trickdelay); + else if (fastcmp(field,"trickmomx")) + lua_pushfixed(L, plr->trickmomx); + else if (fastcmp(field,"trickmomy")) + lua_pushfixed(L, plr->trickmomy); + else if (fastcmp(field,"trickmomz")) + lua_pushfixed(L, plr->trickmomz); else if (fastcmp(field,"pflags")) lua_pushinteger(L, plr->pflags); else if (fastcmp(field,"panim")) @@ -511,6 +517,12 @@ static int player_set(lua_State *L) plr->trickpanel = luaL_checkinteger(L, 3); else if (fastcmp(field,"trickdelay")) plr->trickdelay = (tic_t)luaL_checkinteger(L, 3); + else if (fastcmp(field,"trickmomx")) + plr->trickmomx = (fixed_t)luaL_checkfixed(L, 3); + else if (fastcmp(field,"trickmomy")) + plr->trickmomy = (fixed_t)luaL_checkfixed(L, 3); + else if (fastcmp(field,"trickmomz")) + plr->trickmomz = (fixed_t)luaL_checkfixed(L, 3); else if (fastcmp(field,"kartspeed")) plr->kartspeed = (UINT8)luaL_checkinteger(L, 3); else if (fastcmp(field,"kartweight")) diff --git a/src/p_inter.c b/src/p_inter.c index 7aa25c25d..4a798d4d0 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -30,7 +30,7 @@ #include "f_finale.h" // SRB2kart -#include "k_kart.h" +#include "k_kart.h" #include "k_battle.h" #include "k_pwrlv.h" #include "k_grandprix.h" diff --git a/src/p_map.c b/src/p_map.c index 2309ac260..31df0e09b 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -449,7 +449,7 @@ static void P_DoFanAndGasJet(mobj_t *spring, mobj_t *object) if (object->player) { object->player->trickpanel = 1; - object->player->trickdelay = TICRATE/2; + object->player->trickdelay = 1; } K_DoPogoSpring(object, 32<color = K_RainbowColor( (SKINCOLOR_PURPLE - SKINCOLOR_PINK) // Smoothly transition into the other state + ((mobj->fuse - 32) * 2) // Make the color flashing slow down while it runs out - ); + ); switch (mobj->extravalue1) { @@ -10243,7 +10243,7 @@ void P_SpawnPlayer(INT32 playernum) /* if (bonusgame || specialstage) { - // Bots should avoid + // Bots should avoid p->spectator = true; } */ @@ -10357,7 +10357,7 @@ void P_SpawnPlayer(INT32 playernum) if ((leveltime < starttime) || (pcount <= 1)) // Start of the map? { // Reset those bumpers! - p->bumpers = K_StartingBumperCount(); + p->bumpers = K_StartingBumperCount(); } if (p->bumpers) diff --git a/src/p_saveg.c b/src/p_saveg.c index e32b69735..4e6e31d88 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -235,7 +235,7 @@ static void P_NetArchivePlayers(void) if (flags & FOLLOWITEM) WRITEUINT32(save_p, players[i].followmobj->mobjnum); - + WRITEUINT32(save_p, (UINT32)players[i].followitem); WRITEUINT32(save_p, players[i].charflags); @@ -257,7 +257,10 @@ static void P_NetArchivePlayers(void) WRITEUINT32(save_p, K_GetWaypointHeapIndex(players[i].nextwaypoint)); WRITEUINT32(save_p, players[i].airtime); WRITEUINT8(save_p, players[i].trickpanel); - WRITEUINT32(save_p, players[i].trickdelay); + WRITEUINT8(save_p, players[i].trickdelay); + WRITEUINT32(save_p, players[i].trickmomx); + WRITEUINT32(save_p, players[i].trickmomy); + WRITEUINT32(save_p, players[i].trickmomz); WRITEUINT8(save_p, players[i].bumpers); WRITEINT16(save_p, players[i].karmadelay); @@ -426,7 +429,7 @@ static void P_NetUnArchivePlayers(void) if (flags & FOLLOWITEM) players[i].followmobj = (mobj_t *)(size_t)READUINT32(save_p); - + players[i].followitem = (mobjtype_t)READUINT32(save_p); //SetPlayerSkinByNum(i, players[i].skin); @@ -449,7 +452,10 @@ static void P_NetUnArchivePlayers(void) players[i].nextwaypoint = (waypoint_t *)(size_t)READUINT32(save_p); players[i].airtime = READUINT32(save_p); players[i].trickpanel = READUINT8(save_p); - players[i].trickdelay = READUINT32(save_p); + players[i].trickdelay = READUINT8(save_p); + players[i].trickmomx = READUINT32(save_p); + players[i].trickmomy = READUINT32(save_p); + players[i].trickmomz = READUINT32(save_p); players[i].bumpers = READUINT8(save_p); players[i].karmadelay = READINT16(save_p); diff --git a/src/p_spec.c b/src/p_spec.c index ce7ffd841..62dffaf67 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -4618,7 +4618,7 @@ DoneSection2: } player->trickpanel = 1; - player->trickdelay = TICRATE/2; + player->trickdelay = 1; K_DoPogoSpring(player->mo, upwards, 1); // Reduce speed From 9d7e880d66f3617129aeb5e265a7f1ef45298f9a Mon Sep 17 00:00:00 2001 From: Latapostrophe Date: Wed, 6 Jan 2021 21:52:33 +0100 Subject: [PATCH 142/143] Buff side tricks slightly --- src/k_kart.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 6a05c50d5..bc91e6ea9 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -7962,7 +7962,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) if (cmd->turning > 0) { - P_InstaThrust(player->mo, player->mo->angle + lr, max(basespeed, speed*2)); + P_InstaThrust(player->mo, player->mo->angle + lr, max(basespeed, speed*5/2)); player->trickmomx = player->mo->momx; player->trickmomy = player->mo->momy; @@ -7975,7 +7975,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) } else if (cmd->turning < 0) { - P_InstaThrust(player->mo, player->mo->angle - lr, max(basespeed, speed*2)); + P_InstaThrust(player->mo, player->mo->angle - lr, max(basespeed, speed*5/2)); player->trickmomx = player->mo->momx; player->trickmomy = player->mo->momy; From 834bd78eb56df3e0ff61c035c1c56d7583137739 Mon Sep 17 00:00:00 2001 From: Latapostrophe Date: Wed, 6 Jan 2021 22:10:23 +0100 Subject: [PATCH 143/143] Consider stuff unlocked if DEVELOP flag set --- src/m_cond.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/m_cond.c b/src/m_cond.c index 8ffe3c378..bfd463a7c 100644 --- a/src/m_cond.c +++ b/src/m_cond.c @@ -341,6 +341,12 @@ UINT8 M_CompletionEmblems(void) // Bah! Duplication sucks, but it's for a separa UINT8 M_AnySecretUnlocked(void) { INT32 i; + +#ifdef DEVELOP + if (1) + return true; +#endif + for (i = 0; i < MAXUNLOCKABLES; ++i) { if (!unlockables[i].nocecho && unlockables[i].unlocked) @@ -376,6 +382,12 @@ UINT8 M_SecretUnlocked(INT32 type) UINT8 M_MapLocked(INT32 mapnum) { + +#ifdef DEVELOP + if (1) + return false; +#endif + if (!mapheaderinfo[mapnum-1] || mapheaderinfo[mapnum-1]->unlockrequired < 0) return false; if (!unlockables[mapheaderinfo[mapnum-1]->unlockrequired].unlocked)