From 5129250e48ad8dadde328292ac3318b51cf059e1 Mon Sep 17 00:00:00 2001 From: Antonio Martinez Date: Tue, 13 May 2025 12:39:16 -0400 Subject: [PATCH 1/5] WIP: no early items --- src/d_player.h | 2 ++ src/g_game.c | 6 ++++++ src/k_kart.c | 1 + src/lua_playerlib.c | 4 ++++ src/objects/random-item.c | 9 +++++++++ src/p_inter.c | 3 +++ src/p_saveg.cpp | 4 ++++ 7 files changed, 29 insertions(+) diff --git a/src/d_player.h b/src/d_player.h index 64547b348..ca4e4f38e 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -727,6 +727,8 @@ struct player_t UINT8 justDI; // Turn-lockout timer to briefly prevent unintended turning after DI, resets when actionable or no input boolean flipDI; // Bananas flip the DI direction. Was a bug, but it made bananas much more interesting. + boolean cangrabitems; + SINT8 drift; // (-5 to 5) - Drifting Left or Right, plus a bigger counter = sharper turn fixed_t driftcharge; // Charge your drift so you can release a burst of speed UINT16 driftboost; // (0 to 125 baseline) - Boost you get from drifting diff --git a/src/g_game.c b/src/g_game.c index 392d6f72b..e0bc76b25 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2241,6 +2241,8 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) UINT8 botdiffincrease; boolean botrival; + boolean cangrabitems; + SINT8 xtralife; uint8_t public_key[PUBKEYLENGTH]; @@ -2342,6 +2344,8 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) bot = players[player].bot; botdifficulty = players[player].botvars.difficulty; + cangrabitems = players[player].cangrabitems; + botdiffincrease = players[player].botvars.diffincrease; botrival = players[player].botvars.rival; @@ -2567,6 +2571,8 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) p->charflags = charflags; p->lastfakeskin = lastfakeskin; + p->cangrabitems = cangrabitems; + memcpy(players[player].availabilities, availabilities, sizeof(availabilities)); p->followitem = followitem; diff --git a/src/k_kart.c b/src/k_kart.c index 5173fa3eb..48e20206b 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -4235,6 +4235,7 @@ void K_CheckpointCrossAward(player_t *player) return; player->exp += K_GetExpAdjustment(player); + player->cangrabitems = true; K_AwardPlayerRings(player, (player->bot ? 20 : 10), true); } diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index 62eca4611..0da01f714 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -264,6 +264,8 @@ static int player_get(lua_State *L) lua_pushinteger(L, plr->justDI); else if (fastcmp(field,"flipdi")) lua_pushboolean(L, plr->flipDI); + else if (fastcmp(field,"cangrabitems")) + lua_pushboolean(L, plr->cangrabitems); else if (fastcmp(field,"analoginput")) lua_pushboolean(L, plr->analoginput); else if (fastcmp(field,"transfer")) @@ -876,6 +878,8 @@ static int player_set(lua_State *L) plr->justDI = luaL_checkinteger(L, 3); else if (fastcmp(field,"flipdi")) plr->flipDI = luaL_checkboolean(L, 3); + else if (fastcmp(field,"cangrabitems")) + plr->cangrabitems = luaL_checkboolean(L, 3); else if (fastcmp(field,"incontrol")) plr->incontrol = luaL_checkinteger(L, 3); else if (fastcmp(field,"progressivethrust")) diff --git a/src/objects/random-item.c b/src/objects/random-item.c index 0e0a2a788..fa5419084 100644 --- a/src/objects/random-item.c +++ b/src/objects/random-item.c @@ -112,6 +112,15 @@ void Obj_RandomItemVisuals(mobj_t *mobj) ItemBoxScaling(mobj); item_vfxtimer(mobj)++; + for (UINT8 i = 0; i <= r_splitscreen; i++) + { + UINT32 flag = K_GetPlayerDontDrawFlag(&players[displayplayers[i]]); + if (!players[displayplayers[i]].cangrabitems) + mobj->renderflags |= flag; + else + mobj->renderflags &= ~(flag); + } + if (mobj->type != MT_RANDOMITEM) return; diff --git a/src/p_inter.c b/src/p_inter.c index b3d178254..76997b541 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -128,6 +128,9 @@ boolean P_CanPickupItem(player_t *player, UINT8 weapon) if (weapon != 2 && player->instaWhipCharge) return false; + if (weapon == 1 && !player->cangrabitems) + return false; + if (weapon) { // Item slot already taken up diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index 9f11fbb70..4abeb51fb 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -459,6 +459,8 @@ static void P_NetArchivePlayers(savebuffer_t *save) WRITEUINT8(save->p, players[i].justDI); WRITEUINT8(save->p, players[i].flipDI); + WRITEUINT8(save->p, players[i].cangrabitems); + WRITESINT8(save->p, players[i].drift); WRITEFIXED(save->p, players[i].driftcharge); WRITEUINT16(save->p, players[i].driftboost); @@ -1097,6 +1099,8 @@ static void P_NetUnArchivePlayers(savebuffer_t *save) players[i].justDI = READUINT8(save->p); players[i].flipDI = (boolean)READUINT8(save->p); + players[i].cangrabitems = (boolean)READUINT8(save->p); + players[i].drift = READSINT8(save->p); players[i].driftcharge = READFIXED(save->p); players[i].driftboost = READUINT16(save->p); From 4b1417fe9784a9e795d5dd18ffe209f22b103302 Mon Sep 17 00:00:00 2001 From: Antonio Martinez Date: Tue, 13 May 2025 13:52:15 -0400 Subject: [PATCH 2/5] Reset grabitems between maps --- src/g_game.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/g_game.c b/src/g_game.c index e0bc76b25..f129c13f9 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2429,6 +2429,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) bigwaypointgap = 0; tallyactive = false; + cangrabitems = false; } else { From 25de15672e3589d0036135ea7090a4cda4c1c3fc Mon Sep 17 00:00:00 2001 From: Antonio Martinez Date: Tue, 13 May 2025 16:00:37 -0400 Subject: [PATCH 3/5] Fix item flicker --- src/objects/random-item.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/objects/random-item.c b/src/objects/random-item.c index fa5419084..f1409ceb2 100644 --- a/src/objects/random-item.c +++ b/src/objects/random-item.c @@ -112,18 +112,22 @@ void Obj_RandomItemVisuals(mobj_t *mobj) ItemBoxScaling(mobj); item_vfxtimer(mobj)++; - for (UINT8 i = 0; i <= r_splitscreen; i++) - { - UINT32 flag = K_GetPlayerDontDrawFlag(&players[displayplayers[i]]); - if (!players[displayplayers[i]].cangrabitems) - mobj->renderflags |= flag; - else - mobj->renderflags &= ~(flag); - } - if (mobj->type != MT_RANDOMITEM) return; + if (!((mobj->flags & MF_NOCLIPTHING) || mobj->fuse)) + { + for (UINT8 i = 0; i <= r_splitscreen; i++) + { + UINT32 flag = K_GetPlayerDontDrawFlag(&players[displayplayers[i]]); + if (!players[displayplayers[i]].cangrabitems) + mobj->renderflags |= flag; + else + mobj->renderflags &= ~(flag); + } + } + + // Respawn flow, documented by a dumb asshole: // P_TouchSpecialThing -> P_ItemPop sets fuse, NOCLIPTHING and DONTDRAW. // P_FuseThink does visual flicker, and when fuse is 0, unsets NOCLIPTHING/DONTDRAW/etc... From 77167d1e32519a24851ca1c354abb91ba22b2853 Mon Sep 17 00:00:00 2001 From: Antonio Martinez Date: Tue, 13 May 2025 16:49:32 -0400 Subject: [PATCH 4/5] Early item fade, fix gametypes / edge cases --- src/d_player.h | 2 +- src/g_game.c | 8 +++++++- src/k_kart.c | 4 +++- src/k_kart.h | 2 ++ src/lua_playerlib.c | 4 ++-- src/objects/random-item.c | 29 ++++++++++++++++++++++++----- src/p_saveg.cpp | 2 +- 7 files changed, 40 insertions(+), 11 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index ca4e4f38e..75db7c887 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -727,7 +727,7 @@ struct player_t UINT8 justDI; // Turn-lockout timer to briefly prevent unintended turning after DI, resets when actionable or no input boolean flipDI; // Bananas flip the DI direction. Was a bug, but it made bananas much more interesting. - boolean cangrabitems; + UINT8 cangrabitems; SINT8 drift; // (-5 to 5) - Drifting Left or Right, plus a bigger counter = sharper turn fixed_t driftcharge; // Charge your drift so you can release a burst of speed diff --git a/src/g_game.c b/src/g_game.c index f129c13f9..0b305c3d1 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2429,7 +2429,13 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) bigwaypointgap = 0; tallyactive = false; - cangrabitems = false; + + cangrabitems = 0; + if (gametyperules & GTR_SPHERES + || gametyperules & GTR_CATCHER + || G_TimeAttackStart() + || gametype == GT_TUTORIAL) + cangrabitems = EARLY_ITEM_FLICKER; } else { diff --git a/src/k_kart.c b/src/k_kart.c index 48e20206b..66e47e269 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -4235,7 +4235,7 @@ void K_CheckpointCrossAward(player_t *player) return; player->exp += K_GetExpAdjustment(player); - player->cangrabitems = true; + player->cangrabitems = 1; K_AwardPlayerRings(player, (player->bot ? 20 : 10), true); } @@ -9579,6 +9579,8 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) player->invincibilitytimer--; } + if (player->cangrabitems && player->cangrabitems <= EARLY_ITEM_FLICKER) + player->cangrabitems++; if (!player->invincibilitytimer) player->invincibilityextensions = 0; diff --git a/src/k_kart.h b/src/k_kart.h index 00b0e44c3..b634b96eb 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -60,6 +60,8 @@ Make sure this matches the actual number of states #define SCAMDIST (2000) +#define EARLY_ITEM_FLICKER (NUMTRANSMAPS) + // 2023-08-26 +ang20 to Sal's OG values to make them friendlier - Tyron #define STUMBLE_STEEP_VAL (ANG60 + ANG20) #define STUMBLE_STEEP_VAL_AIR (ANG30 + ANG10 + ANG20) diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index 0da01f714..42904bb21 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -265,7 +265,7 @@ static int player_get(lua_State *L) else if (fastcmp(field,"flipdi")) lua_pushboolean(L, plr->flipDI); else if (fastcmp(field,"cangrabitems")) - lua_pushboolean(L, plr->cangrabitems); + lua_pushinteger(L, plr->cangrabitems); else if (fastcmp(field,"analoginput")) lua_pushboolean(L, plr->analoginput); else if (fastcmp(field,"transfer")) @@ -879,7 +879,7 @@ static int player_set(lua_State *L) else if (fastcmp(field,"flipdi")) plr->flipDI = luaL_checkboolean(L, 3); else if (fastcmp(field,"cangrabitems")) - plr->cangrabitems = luaL_checkboolean(L, 3); + plr->cangrabitems = luaL_checkinteger(L, 3); else if (fastcmp(field,"incontrol")) plr->incontrol = luaL_checkinteger(L, 3); else if (fastcmp(field,"progressivethrust")) diff --git a/src/objects/random-item.c b/src/objects/random-item.c index f1409ceb2..3ef9d1f9b 100644 --- a/src/objects/random-item.c +++ b/src/objects/random-item.c @@ -115,15 +115,34 @@ void Obj_RandomItemVisuals(mobj_t *mobj) if (mobj->type != MT_RANDOMITEM) return; + // Fade items in as we cross the first checkpoint, but don't touch their visibility otherwise! if (!((mobj->flags & MF_NOCLIPTHING) || mobj->fuse)) { + UINT8 maxgrab = 0; + for (UINT8 i = 0; i <= r_splitscreen; i++) { - UINT32 flag = K_GetPlayerDontDrawFlag(&players[displayplayers[i]]); - if (!players[displayplayers[i]].cangrabitems) - mobj->renderflags |= flag; - else - mobj->renderflags &= ~(flag); + maxgrab = max(maxgrab, players[displayplayers[i]].cangrabitems); + } + + if (maxgrab == 0) + mobj->renderflags |= RF_DONTDRAW; + else + mobj->renderflags &= ~RF_DONTDRAW; + + if (maxgrab > 0 && maxgrab <= EARLY_ITEM_FLICKER) + { + UINT8 maxtranslevel = NUMTRANSMAPS; + + UINT8 trans = maxgrab; + if (trans > maxtranslevel) + trans = maxtranslevel; + trans = NUMTRANSMAPS - trans; + + mobj->renderflags &= ~(RF_TRANSMASK); + + if (trans != 0) + mobj->renderflags |= (trans << RF_TRANSSHIFT); } } diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index 4abeb51fb..827ab32cb 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -1099,7 +1099,7 @@ static void P_NetUnArchivePlayers(savebuffer_t *save) players[i].justDI = READUINT8(save->p); players[i].flipDI = (boolean)READUINT8(save->p); - players[i].cangrabitems = (boolean)READUINT8(save->p); + players[i].cangrabitems = READUINT8(save->p); players[i].drift = READSINT8(save->p); players[i].driftcharge = READFIXED(save->p); From b9d02184d243b07bbb4edc55b9d381fa7e3eacda Mon Sep 17 00:00:00 2001 From: Antonio Martinez Date: Tue, 13 May 2025 20:04:34 -0400 Subject: [PATCH 5/5] Never retrigger item fade --- src/k_kart.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/k_kart.c b/src/k_kart.c index 66e47e269..daced7c9e 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -4235,7 +4235,8 @@ void K_CheckpointCrossAward(player_t *player) return; player->exp += K_GetExpAdjustment(player); - player->cangrabitems = 1; + if (!player->cangrabitems) + player->cangrabitems = 1; K_AwardPlayerRings(player, (player->bot ? 20 : 10), true); }