diff --git a/src/cvars.cpp b/src/cvars.cpp index 2b439d89e..6fefb14f8 100644 --- a/src/cvars.cpp +++ b/src/cvars.cpp @@ -814,6 +814,8 @@ consvar_t cv_kartdebugbots = OnlineCheat("debugbots", "Off").on_off().descriptio consvar_t cv_kartdebugdistribution = OnlineCheat("debugitemodds", "Off").on_off().description("Show items that the roulette can roll"); consvar_t cv_kartdebughuddrop = OnlineCheat("debugitemdrop", "Off").on_off().description("Players drop paper items when damaged in any way"); +consvar_t cv_kartdebugbotwhip = OnlineCheat("debugbotwhip", "Off").on_off().description("Disable bot ring and item pickups"); + extern CV_PossibleValue_t kartdebugitem_cons_t[]; consvar_t cv_kartdebugitem = OnlineCheat("debugitem", "None").values(kartdebugitem_cons_t).description("Force item boxes to only roll one kind of item"); diff --git a/src/d_netcmd.h b/src/d_netcmd.h index d1d0fa643..00c7c3322 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -94,6 +94,7 @@ extern consvar_t cv_kartdebugitem, cv_kartdebugamount, cv_kartdebugdistribution, extern consvar_t cv_kartdebugnodes, cv_kartdebugcolorize, cv_kartdebugdirector; extern consvar_t cv_spbtest, cv_reducevfx, cv_screenshake; extern consvar_t cv_kartdebugwaypoints, cv_kartdebugbots; +extern consvar_t cv_kartdebugbotwhip; extern consvar_t cv_kartdebugstart; extern consvar_t cv_debugrank; extern consvar_t cv_battletest; diff --git a/src/k_botitem.cpp b/src/k_botitem.cpp index 84baaab6b..db9cd35f7 100644 --- a/src/k_botitem.cpp +++ b/src/k_botitem.cpp @@ -1479,13 +1479,19 @@ static void K_BotItemInstashield(const player_t *player, ticcmd_t *cmd) const fixed_t radius = FixedMul(mobjinfo[MT_INSTAWHIP].radius, player->mo->scale); size_t i = SIZE_MAX; - if (K_ItemButtonWasDown(player) == true) - { - // Release the button, dude. - return; - } + boolean nearbyThreat = false; // Someone's near enough to worry about, start charging. + boolean attackOpportunity = false; // Someone's close enough to hit! + boolean coastIsClear = true; // Nobody is nearby, let any pending charge go. - if (player->instaWhipCharge || leveltime < starttime || player->spindash) + UINT8 stupidRating = MAXBOTDIFFICULTY - player->botvars.difficulty; + // Weak bots take a second to react on offense. + UINT8 reactiontime = stupidRating; + // Weak bots misjudge their attack range. Purely accurate at Lv.MAX, 250% overestimate at Lv.1 + fixed_t radiusWithError = radius + 3*(radius * stupidRating / MAXBOTDIFFICULTY)/2; + + // Future work: Expand threat range versus fast pursuers. + + if (leveltime < starttime || player->spindash || player->defenseLockout) { // Instashield is on cooldown. return; @@ -1517,18 +1523,41 @@ static void K_BotItemInstashield(const player_t *player, ticcmd_t *cmd) (player->mo->z - target->mo->z) / 4 ); - if (dist <= radius) + if (dist <= 8 * radius) { - K_ItemConfirmForTarget(player, cmd, target, player->botvars.difficulty * 2); + coastIsClear = false; + } + + if (dist <= 5 * radius) + { + nearbyThreat = true; + } + + if (dist <= (radiusWithError + target->mo->radius)) + { + attackOpportunity = true; + K_ItemConfirmForTarget(player, cmd, target, 1); } } - if (player->botvars.itemconfirm > 10*TICRATE) + if (player->instaWhipCharge) // Already charging, do we stay committed? { - // Use it!! - cmd->buttons |= BT_ATTACK; - //player->botvars.itemconfirm = 0; + cmd->buttons |= BT_ATTACK; // Keep holding, unless... + + // ...there are no attackers that are even distantly threatening... + if (coastIsClear) + cmd->buttons &= ~BT_ATTACK; + + // ...or we're ready to rock. + if (attackOpportunity && player->instaWhipCharge >= (INSTAWHIP_CHARGETIME + reactiontime) && player->botvars.itemconfirm >= reactiontime) + cmd->buttons &= ~BT_ATTACK; } + else // When should we get spooked and start a charge? + { + if (nearbyThreat) + cmd->buttons |= BT_ATTACK; + } + } /*-------------------------------------------------- @@ -1800,7 +1829,7 @@ static void K_UpdateBotGameplayVarsItemUsageMash(player_t *player) --------------------------------------------------*/ void K_UpdateBotGameplayVarsItemUsage(player_t *player) { - if (player->itemflags & IF_USERINGS) + if (player->itemflags & IF_USERINGS && !player->instaWhipCharge) { return; } diff --git a/src/k_kart.c b/src/k_kart.c index 0444d3c11..15bdf2629 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -8497,6 +8497,17 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) else if (player->rings < -20) player->rings = -20; + if (cv_kartdebugbotwhip.value) + { + if (player->bot) + { + player->rings = 0; + player->itemtype = 0; + player->itemamount = 0; + player->itemRoulette.active = false; + } + } + if (player->spheres > 40) player->spheres = 40; // where's the < 0 check? see below the following block! @@ -11914,6 +11925,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) { S_StartSound(player->mo, sfx_kc50); player->instaWhipCharge = 0; + player->botvars.itemconfirm = 0; } else {