diff --git a/src/d_player.h b/src/d_player.h index f19dec65d..5870da947 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -407,6 +407,7 @@ struct botvars_t // All entries above persist between rounds and must be recorded in demos fixed_t rubberband; // Bot rubberband value + UINT8 bumpslow; tic_t itemdelay; // Delay before using item at all tic_t itemconfirm; // When high enough, they will use their item diff --git a/src/k_bot.cpp b/src/k_bot.cpp index c55766189..041a0be38 100644 --- a/src/k_bot.cpp +++ b/src/k_bot.cpp @@ -803,8 +803,13 @@ fixed_t K_UpdateRubberband(player_t *player) fixed_t dest = K_BotRubberband(player); fixed_t ret = player->botvars.rubberband; + UINT8 ease_soften = 8; + + if (player->botvars.bumpslow && dest > ret) + ease_soften *= 10; + // Ease into the new value. - ret += (dest - player->botvars.rubberband) / 8; + ret += (dest - player->botvars.rubberband) / ease_soften; return ret; } diff --git a/src/k_kart.c b/src/k_kart.c index c87111217..b2e7c6d7e 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -9494,6 +9494,9 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) if (player->trickboost) player->trickboost--; + if (K_PlayerUsesBotMovement(players) && player->botvars.bumpslow && player->incontrol) + player->botvars.bumpslow--; + if (player->flamedash) { player->flamedash--; @@ -15514,6 +15517,15 @@ UINT32 K_GetNumGradingPoints(void) return numlaps * (1 + Obj_GetCheckpointCount()); } +void K_BotHitPenalty(player_t *player) +{ + if (K_PlayerUsesBotMovement(player)) + { + player->botvars.rubberband = max(player->botvars.rubberband/2, FRACUNIT/2); + player->botvars.bumpslow = TICRATE*2; + } +} + static boolean K_PickUp(player_t *player, mobj_t *picked) { SINT8 type = -1; diff --git a/src/k_kart.h b/src/k_kart.h index 5c3cc88db..b88bcd684 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -314,6 +314,8 @@ UINT16 K_GetDisplayEXP(player_t *player); UINT32 K_GetNumGradingPoints(void); +void K_BotHitPenalty(player_t *player); + boolean K_TryPickMeUp(mobj_t *m1, mobj_t *m2); #ifdef __cplusplus diff --git a/src/p_inter.c b/src/p_inter.c index fd30df42a..09ac618c7 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -3204,6 +3204,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da if (source && source != player->mo && source->player) { K_SpawnAmps(source->player, K_PvPAmpReward((type == DMG_WHUMBLE) ? 30 : 20, source->player, player), target); + K_BotHitPenalty(player); // Extend the invincibility if the hit was a direct hit. if (inflictor == source && source->player->invincibilitytimer && diff --git a/src/p_map.c b/src/p_map.c index 1289dc71f..68c487acf 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -4118,6 +4118,8 @@ static void P_BouncePlayerMove(mobj_t *mo, TryMoveResult_t *result) if (mo->player) mo->player->bumpUnstuck += 5; + K_BotHitPenalty(mo->player); + // Combo avoidance! if (mo->player && P_PlayerInPain(mo->player) && gametyperules & GTR_BUMPERS && mo->health == 1) { diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index 591613d6f..a4f5b269b 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -737,6 +737,7 @@ static void P_NetArchivePlayers(savebuffer_t *save) WRITEUINT8(save->p, players[i].botvars.diffincrease); WRITEUINT8(save->p, players[i].botvars.rival); WRITEFIXED(save->p, players[i].botvars.rubberband); + WRITEUINT8(save->p, players[i].botvars.bumpslow); WRITEUINT32(save->p, players[i].botvars.itemdelay); WRITEUINT32(save->p, players[i].botvars.itemconfirm); WRITESINT8(save->p, players[i].botvars.turnconfirm); @@ -1380,6 +1381,7 @@ static void P_NetUnArchivePlayers(savebuffer_t *save) players[i].botvars.diffincrease = READUINT8(save->p); players[i].botvars.rival = (boolean)READUINT8(save->p); players[i].botvars.rubberband = READFIXED(save->p); + players[i].botvars.bumpslow = READUINT8(save->p); players[i].botvars.itemdelay = READUINT32(save->p); players[i].botvars.itemconfirm = READUINT32(save->p); players[i].botvars.turnconfirm = READSINT8(save->p);