From d55c9038cc1b0834078b9adb114c664fb3cd3329 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sun, 14 May 2023 19:32:51 -0400 Subject: [PATCH] Bots: Can now use Ring Shooter Reuses most of the anti-grief code, but with a very low timer (5sec) and they simply hold Y when reaching it until they eventually respawn from the ring shooter. --- src/d_player.h | 1 + src/k_bot.c | 40 +++++++++++++++++++++++++++++++++++ src/k_bot.h | 5 ++++- src/k_respawn.c | 3 ++- src/p_local.h | 1 + src/p_saveg.c | 2 ++ src/p_user.c | 55 +++++++++++++++++++++++++++---------------------- 7 files changed, 80 insertions(+), 27 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index e9f166399..1cb70aeaa 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -332,6 +332,7 @@ struct botvars_t SINT8 turnconfirm; // Confirm turn direction tic_t spindashconfirm; // When high enough, they will try spindashing + UINT32 respawnconfirm; // When high enough, they will use Ring Shooter }; // player_t struct for round-specific condition tracking diff --git a/src/k_bot.c b/src/k_bot.c index b03b0d1b7..dd777b0bb 100644 --- a/src/k_bot.c +++ b/src/k_bot.c @@ -29,6 +29,7 @@ #include "k_race.h" // finishBeamLine #include "m_perfstats.h" #include "k_podium.h" +#include "k_respawn.h" /*-------------------------------------------------- boolean K_AddBot(UINT8 skin, UINT8 difficulty, UINT8 *p) @@ -971,6 +972,38 @@ static UINT8 K_TrySpindash(player_t *player) return 0; } +/*-------------------------------------------------- + static boolean K_TryRingShooter(player_t *player) + + Determines conditions where the bot should attempt to respawn. + + Input Arguments:- + player - Bot player to check. + + Return:- + true if we want to hold the respawn button, otherwise false. +--------------------------------------------------*/ +static boolean K_TryRingShooter(player_t *player) +{ + if (player->respawn.state != RESPAWNST_NONE) + { + // We're already respawning! + return false; + } + + if ((gametyperules & GTR_CIRCUIT) == 0 || (leveltime <= starttime)) + { + // Only do this during a Race that has started. + return false; + } + + // Our anti-grief system is already a perfect system + // for determining if we're not making progress, so + // lets reuse it for bot respawning! + P_IncrementGriefValue(player, &player->botvars.respawnconfirm, BOTRESPAWNCONFIRM); + return (player->botvars.respawnconfirm >= BOTRESPAWNCONFIRM); +} + /*-------------------------------------------------- static void K_DrawPredictionDebug(botprediction_t *predict, player_t *player) @@ -1484,6 +1517,13 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd) return; } + if (K_TryRingShooter(player) == true) + { + // We want to respawn. Simply hold Y and stop here! + cmd->buttons |= (BT_RESPAWN | BT_EBRAKEMASK); + return; + } + if (player->trickpanel != 0) { K_BotTrick(player, cmd, botController); diff --git a/src/k_bot.h b/src/k_bot.h index 630d1fbb0..274b57858 100644 --- a/src/k_bot.h +++ b/src/k_bot.h @@ -31,9 +31,12 @@ extern "C" { // Made it as small as possible without making it look like the bots are twitching constantly. #define BOTTURNCONFIRM 4 -// How many tics without being able to accelerate before we'll let you spindash. +// How many tics with only one spindash-viable condition before we'll let you spindash. #define BOTSPINDASHCONFIRM (3*TICRATE) +// How many tics without being able to make progress before we'll let you respawn. +#define BOTRESPAWNCONFIRM (5*TICRATE) + // Point for bots to aim for struct botprediction_t { fixed_t x, y; diff --git a/src/k_respawn.c b/src/k_respawn.c index 8f0c756f1..46851a02f 100644 --- a/src/k_respawn.c +++ b/src/k_respawn.c @@ -147,7 +147,6 @@ void K_DoIngameRespawn(player_t *player) K_DoFault(player); } - player->ringboost = 0; player->driftboost = player->strongdriftboost = 0; player->gateBoost = 0; @@ -292,6 +291,8 @@ void K_DoIngameRespawn(player_t *player) player->respawn.airtimer = player->airtime; player->respawn.truedeath = !!(player->pflags & PF_FAULT); + player->botvars.respawnconfirm = 0; + player->mo->flags |= MF_NOCLIPTHING; } diff --git a/src/p_local.h b/src/p_local.h index 59e9c0315..738faffd3 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -209,6 +209,7 @@ void P_PlayerAfterThink(player_t *player); void P_DoPlayerExit(player_t *player, pflags_t flags); void P_DoAllPlayersExit(pflags_t flags, boolean givelife); void P_DoTimeOver(player_t *player); +void P_IncrementGriefValue(player_t *player, UINT32 *grief, const UINT32 griefMax); void P_CheckRaceGriefing(player_t *player, boolean dopunishment); void P_ResetPlayerCheats(void); diff --git a/src/p_saveg.c b/src/p_saveg.c index 027174dad..9acb3d980 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -443,6 +443,7 @@ static void P_NetArchivePlayers(savebuffer_t *save) WRITEUINT32(save->p, players[i].botvars.itemconfirm); WRITESINT8(save->p, players[i].botvars.turnconfirm); WRITEUINT32(save->p, players[i].botvars.spindashconfirm); + WRITEUINT32(save->p, players[i].botvars.respawnconfirm); // itemroulette_t WRITEUINT8(save->p, players[i].itemRoulette.active); @@ -825,6 +826,7 @@ static void P_NetUnArchivePlayers(savebuffer_t *save) players[i].botvars.itemconfirm = READUINT32(save->p); players[i].botvars.turnconfirm = READSINT8(save->p); players[i].botvars.spindashconfirm = READUINT32(save->p); + players[i].botvars.respawnconfirm = READUINT32(save->p); // itemroulette_t players[i].itemRoulette.active = (boolean)READUINT8(save->p); diff --git a/src/p_user.c b/src/p_user.c index a3ac135a6..3afb5b7bf 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -4640,11 +4640,8 @@ void P_PlayerAfterThink(player_t *player) player->mo->pmomz = 0; } -void P_CheckRaceGriefing(player_t *player, boolean dopunishment) +void P_IncrementGriefValue(player_t *player, UINT32 *grief, const UINT32 griefMax) { - const UINT32 griefMax = cv_antigrief.value * TICRATE; - const UINT8 n = player - players; - const fixed_t requireDist = (12*player->mo->scale) / FRACUNIT; INT32 progress = player->distancetofinishprev - player->distancetofinish; boolean exceptions = ( @@ -4654,6 +4651,34 @@ void P_CheckRaceGriefing(player_t *player, boolean dopunishment) || (player->justbumped > 0 && player->justbumped < bumptime-1) ); + if (!exceptions && (progress < requireDist)) + { + // If antigrief is disabled, we don't want the + // player getting into a hole so deep no amount + // of good behaviour could ever make up for it. + if (*grief < griefMax) + { + // Making no progress, start counting against you. + *grief = *grief + 1; + if (progress < -requireDist && *grief < griefMax) + { + // Making NEGATIVE progress? Start counting even harder. + *grief = *grief + 1; + } + } + } + else if (*grief > 0) + { + // Playing normally. + *grief = *grief - 1; + } +} + +void P_CheckRaceGriefing(player_t *player, boolean dopunishment) +{ + const UINT32 griefMax = cv_antigrief.value * TICRATE; + const UINT8 n = player - players; + // Don't punish if the cvar is turned off, // otherwise NOBODY would be able to play! if (griefMax == 0) @@ -4661,27 +4686,7 @@ void P_CheckRaceGriefing(player_t *player, boolean dopunishment) dopunishment = false; } - if (!exceptions && (progress < requireDist)) - { - // If antigrief is disabled, we don't want the - // player getting into a hole so deep no amount - // of good behaviour could ever make up for it. - if (player->griefValue < griefMax) - { - // Making no progress, start counting against you. - player->griefValue++; - if (progress < -requireDist && player->griefValue < griefMax) - { - // Making NEGATIVE progress? Start counting even harder. - player->griefValue++; - } - } - } - else if (player->griefValue > 0) - { - // Playing normally. - player->griefValue--; - } + P_IncrementGriefValue(player, &player->griefValue, griefMax); if (dopunishment && player->griefValue >= griefMax) {