From aa48a92174788c41e007f82c56affabe7b4ef311 Mon Sep 17 00:00:00 2001 From: NepDisk Date: Tue, 28 Oct 2025 22:22:02 -0400 Subject: [PATCH] Make the director force switch to a sink user Lets catch rare high moments:tm: in action. --- src/k_director.c | 36 +++++++++++++++++------------------- src/k_director.h | 13 +++++++++++++ src/k_kart.c | 6 ++++++ 3 files changed, 36 insertions(+), 19 deletions(-) diff --git a/src/k_director.c b/src/k_director.c index aa08edba5..852d553ae 100644 --- a/src/k_director.c +++ b/src/k_director.c @@ -23,13 +23,6 @@ #include "r_fps.h" -#define SWITCHTIME TICRATE * 5 // cooldown between unforced switches -#define BOREDOMTIME 3 * TICRATE / 2 // how long until players considered far apart? -#define TRANSFERTIME TICRATE // how long to delay reaction shots? -#define BREAKAWAYDIST 2000 // how *far* until players considered far apart? -#define WALKBACKDIST 400 // how close should a trailing player be before we switch? -#define PINCHDIST 20000 // how close should the leader be to be considered "end of race"? - struct directorinfo { player_t* viewplayer; @@ -125,7 +118,7 @@ void K_InitDirector(void) { INT32 playernum; - directorinfo.cooldown = SWITCHTIME; + directorinfo.cooldown = DIRECTORSWITCHTIME; directorinfo.freeze = 0; directorinfo.attacker = 0; directorinfo.maxdist = 0; @@ -197,9 +190,9 @@ static void K_UpdateDirectorPositions(void) directorinfo.gap[position] = ScaleFromMap(K_GetFinishGap(directorinfo.sortedplayers[position], directorinfo.sortedplayers[position + 1]), FRACUNIT); - if (directorinfo.gap[position] >= BREAKAWAYDIST) + if (directorinfo.gap[position] >= DIRECTORBREAKAWAYDIST) { - directorinfo.boredom[position] = (INT32)(min(BOREDOMTIME * 2, directorinfo.boredom[position] + 1)); + directorinfo.boredom[position] = (INT32)(min(DIRECTORBOREDOMTIME * 2, directorinfo.boredom[position] + 1)); } else if (directorinfo.boredom[position] > 0) { @@ -226,7 +219,7 @@ static boolean K_CanSwitchDirector(void) return true; } -static void K_DirectorSwitch(INT32 player, boolean force) +void K_DirectorSwitch(INT32 player, boolean force) { if (!K_DirectorIsEnabled()) { @@ -244,12 +237,17 @@ static void K_DirectorSwitch(INT32 player, boolean force) } G_ResetView(1, player, true); - directorinfo.cooldown = SWITCHTIME; + directorinfo.cooldown = DIRECTORSWITCHTIME; directorinfo.chaosleep = 0; } -static void K_DirectorForceSwitch(INT32 player, INT32 time) +void K_DirectorForceSwitch(INT32 player, INT32 time) { + if (!K_DirectorIsEnabled()) + { + return; + } + if (players[player].exiting) { return; @@ -293,11 +291,11 @@ void K_DirectorFollowAttack(player_t *player, mobj_t *inflictor, mobj_t *source) if (inflictor && inflictor->player) { - K_DirectorForceSwitch(inflictor->player - players, TRANSFERTIME); + K_DirectorForceSwitch(inflictor->player - players, DIRECTORTRANSFERTIME); } else if (source && source->player) { - K_DirectorForceSwitch(source->player - players, TRANSFERTIME); + K_DirectorForceSwitch(source->player - players, DIRECTORTRANSFERTIME); } } @@ -340,7 +338,7 @@ void K_DrawDirectorDebugger(void) V_DrawThinString(80, ytxt, V_70TRANS, va("%d", directorinfo.gap[position])); - if (directorinfo.boredom[position] >= BOREDOMTIME) + if (directorinfo.boredom[position] >= DIRECTORBOREDOMTIME) { V_DrawThinString(120, ytxt, V_70TRANS, va("BORED")); } @@ -424,7 +422,7 @@ void K_UpdateDirector(void) } // pair too far apart? try the next one - if (directorinfo.boredom[targetposition - 1] >= BOREDOMTIME) + if (directorinfo.boredom[targetposition - 1] >= DIRECTORBOREDOMTIME) { continue; } @@ -436,12 +434,12 @@ void K_UpdateDirector(void) } // don't risk switching away from forward pairs at race end, might miss something! - if (directorinfo.maxdist > PINCHDIST) + if (directorinfo.maxdist > DIRECTORPINCHDIST) { // if the "next" player is close enough, they should be able to see everyone fine! // walk back through the standings to find a vantage that gets everyone in frame. // (also creates a pretty cool effect w/ overtakes at speed) - while (targetposition < MAXPLAYERS && directorinfo.gap[targetposition] < WALKBACKDIST) + while (targetposition < MAXPLAYERS && directorinfo.gap[targetposition] < DIRECTORWALKBACKDIST) { targetposition++; } diff --git a/src/k_director.h b/src/k_director.h index d61f9fcd2..ac104a833 100644 --- a/src/k_director.h +++ b/src/k_director.h @@ -17,12 +17,25 @@ extern "C" { #endif +#include "doomtype.h" +#include "doomdef.h" + +#define DIRECTORSWITCHTIME TICRATE * 5 // cooldown between unforced switches +#define DIRECTORBOREDOMTIME 3 * TICRATE / 2 // how long until players considered far apart? +#define DIRECTORTRANSFERTIME TICRATE // how long to delay reaction shots? +#define DIRECTORBREAKAWAYDIST 2000 // how *far* until players considered far apart? +#define DIRECTORWALKBACKDIST 400 // how close should a trailing player be before we switch? +#define DIRECTORPINCHDIST 20000 // how close should the leader be to be considered "end of race"? + boolean K_DirectorIsAvailable(void); void K_InitDirector(void); void K_UpdateDirector(void); void K_DrawDirectorDebugger(void); void K_DirectorFollowAttack(player_t *player, mobj_t *inflictor, mobj_t *source); void K_ToggleDirector(void); +void K_DirectorSwitch(INT32 player, boolean force); +void K_DirectorForceSwitch(INT32 player, INT32 time); + #ifdef __cplusplus } // extern "C" diff --git a/src/k_kart.c b/src/k_kart.c index 7d1ff4ad0..4828e0fb8 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -4709,6 +4709,9 @@ static void K_DoHyudoroSteal(player_t *player) player->itemtype = KITEM_KITCHENSINK; player->itemamount = 1; K_UnsetItemOut(player); + + // Woah this could be big, lets get the inside scoop... + K_DirectorForceSwitch(player - players, 1); return; } else if ((gametype == GT_RACE && player->position == 1) || numplayers == 0) // No-one can be stolen from? Oh well... @@ -10977,6 +10980,9 @@ void K_MoveKartPlayer(player_t *player, boolean onground) P_SetTarget(&player->mo->hnext, mo); } K_BotResetItemConfirm(player, false); + + // Woah this could be big, lets get the inside scoop... + K_DirectorForceSwitch(player - players, 1); } else if (ATTACK_IS_DOWN && HOLDING_ITEM && (player->itemflags & IF_ITEMOUT)) // Sink thrown {