From 21bab775b139530884b34900eb1ed0b311c784a6 Mon Sep 17 00:00:00 2001 From: Sally Cochenour Date: Sun, 19 Apr 2020 09:07:29 -0400 Subject: [PATCH] Add difficulty settings --- src/d_clisrv.c | 4 ++ src/d_player.h | 19 ++++++-- src/dehacked.c | 6 +-- src/g_game.c | 3 ++ src/k_bot.c | 121 +++++++++++++++++++++++++++---------------------- src/k_bot.h | 5 +- src/k_kart.c | 30 +++++++++--- 7 files changed, 117 insertions(+), 71 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 0ca8eb2b8..818eeb659 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -3616,6 +3616,7 @@ static void Got_AddBot(UINT8 **p, INT32 playernum) { INT16 newplayernum; UINT8 skinnum = 0; + UINT8 difficulty = MAXBOTDIFFICULTY; if (playernum != serverplayer && !IsPlayerAdmin(playernum)) { @@ -3634,6 +3635,7 @@ static void Got_AddBot(UINT8 **p, INT32 playernum) newplayernum = (UINT8)READUINT8(*p); skinnum = (UINT8)READUINT8(*p); + difficulty = (UINT8)READUINT8(*p); CONS_Debug(DBG_NETPLAY, "addbot: %d\n", newplayernum); @@ -3647,6 +3649,8 @@ static void Got_AddBot(UINT8 **p, INT32 playernum) players[newplayernum].splitscreenindex = 0; players[newplayernum].bot = true; + players[newplayernum].botvars.difficulty = difficulty; + CONS_Printf("%d == %d\n", difficulty, players[newplayernum].botvars.difficulty); players[newplayernum].skincolor = skins[skinnum].prefcolor; sprintf(player_names[newplayernum], "%s", skins[skinnum].realname); diff --git a/src/d_player.h b/src/d_player.h index 278361cfa..f43c90f60 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -347,10 +347,6 @@ typedef enum k_killfield, // How long have you been in the kill field, stay in too long and lose a bumper k_wrongway, // Display WRONG WAY on screen - k_botitemdelay, - k_botitemconfirm, - k_botlastturn, - NUMKARTSTUFF } kartstufftype_t; @@ -414,6 +410,17 @@ typedef enum RW_RAIL = 32 } ringweapons_t; +// player_t struct for all bot variables +typedef struct botvars_s +{ + UINT8 difficulty; + + tic_t itemdelay; + tic_t itemconfirm; + + INT16 lastturn; +} botvars_t; + // ======================================================================== // PLAYER STRUCTURE // ======================================================================== @@ -587,7 +594,9 @@ typedef struct player_s angle_t awayviewaiming; // Used for cut-away view boolean spectator; - UINT8 bot; + + boolean bot; + botvars_t botvars; tic_t jointime; // Timer when player joins game to change skin/color diff --git a/src/dehacked.c b/src/dehacked.c index d55869434..60d61903a 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -8605,11 +8605,7 @@ static const char *const KARTSTUFF_LIST[] = { "SPRINGSTARS", "SPRINGCOLOR", "KILLFIELD", - "WRONGWAY", - - "BOTITEMDELAY", - "BOTITEMCONFIRM", - "BOTLASTTURN" + "WRONGWAY" }; #endif diff --git a/src/g_game.c b/src/g_game.c index fa4ae8b00..ac20c3c25 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2572,6 +2572,7 @@ void G_PlayerReborn(INT32 player) UINT8 splitscreenindex; boolean spectator; boolean bot; + UINT8 botdifficulty; SINT8 pity; // SRB2kart @@ -2624,6 +2625,7 @@ void G_PlayerReborn(INT32 player) mare = players[player].mare; bot = players[player].bot; + botdifficulty = players[player].botvars.difficulty; pity = players[player].pity; // SRB2kart @@ -2703,6 +2705,7 @@ void G_PlayerReborn(INT32 player) p->mare = mare; p->bot = bot; + p->botvars.difficulty = botdifficulty; p->pity = pity; // SRB2kart diff --git a/src/k_bot.c b/src/k_bot.c index f6014f152..093c43976 100644 --- a/src/k_bot.c +++ b/src/k_bot.c @@ -27,13 +27,14 @@ void K_AddBots(SINT8 numbots) { UINT8 newplayernum = 0; + UINT8 difficulty = MAXBOTDIFFICULTY; if (dedicated) newplayernum = 1; while (numbots > 0) { - UINT8 buf[2]; + UINT8 buf[3]; UINT8 *buf_p = buf; numbots--; @@ -73,8 +74,15 @@ void K_AddBots(SINT8 numbots) else WRITEUINT8(buf_p, 10); + WRITEUINT8(buf_p, difficulty); + SendNetXCmd(XD_ADDBOT, buf, buf_p - buf); + if (difficulty > 0) + { + difficulty--; + } + DEBFILE(va("Server added bot %d\n", newplayernum)); // use the next free slot (we can't put playeringame[newplayernum] = true here) newplayernum++; @@ -103,7 +111,7 @@ boolean K_BotCanTakeCut(player_t *player) fixed_t K_BotRubberband(player_t *player) { fixed_t rubberband = FRACUNIT; - player_t *besthumanplayer = NULL; + player_t *firstplace = NULL; UINT8 i; for (i = 0; i < MAXPLAYERS; i++) @@ -113,25 +121,32 @@ fixed_t K_BotRubberband(player_t *player) continue; } - if (&players[i] == player || players[i].bot) + /*if (players[i].bot) { continue; - } + }*/ - if (besthumanplayer == NULL || players[i].distancetofinish < besthumanplayer->distancetofinish) + if (firstplace == NULL || players[i].distancetofinish < firstplace->distancetofinish) { - besthumanplayer = &players[i]; + firstplace = &players[i]; } } - if (besthumanplayer != NULL) + if (firstplace != NULL) { - UINT32 wanteddist = besthumanplayer->distancetofinish; // TODO: Add difficulty here + const UINT32 spacing = 1024; + UINT32 easiness = (MAXBOTDIFFICULTY - player->botvars.difficulty); + UINT32 wanteddist = firstplace->distancetofinish + (spacing * easiness); if (wanteddist < player->distancetofinish) { // Catch up to 1st! - rubberband = FRACUNIT + (8 * (player->distancetofinish - wanteddist)); + rubberband = FRACUNIT + (player->botvars.difficulty * (player->distancetofinish - wanteddist)); + } + + if (P_IsDisplayPlayer(player)) + { + CONS_Printf("difficulty: %d, easiness: %d, wanted: %d, rubberband: %d\n", player->botvars.difficulty, easiness, wanteddist, rubberband); } } @@ -904,10 +919,10 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd) } else { - if (player->kartstuff[k_botitemdelay]) + if (player->botvars.itemdelay) { - player->kartstuff[k_botitemdelay]--; - player->kartstuff[k_botitemconfirm] = 0; + player->botvars.itemdelay--; + player->botvars.itemconfirm = 0; } else if (player->kartstuff[k_stealingtimer] == 0 && player->kartstuff[k_stolentimer] == 0) { @@ -917,17 +932,17 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd) } else if (player->kartstuff[k_rocketsneakertimer] > 0) { - if (player->kartstuff[k_botitemconfirm] > TICRATE) + if (player->botvars.itemconfirm > TICRATE) { if (!player->kartstuff[k_sneakertimer] && !(player->pflags & PF_ATTACKDOWN)) { cmd->buttons |= BT_ATTACK; - player->kartstuff[k_botitemconfirm] = 0; + player->botvars.itemconfirm = 0; } } else { - player->kartstuff[k_botitemconfirm]++; + player->botvars.itemconfirm++; } } else @@ -941,38 +956,38 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd) case KITEM_HYUDORO: case KITEM_SUPERRING: cmd->buttons |= BT_ATTACK; - player->kartstuff[k_botitemconfirm] = 0; + player->botvars.itemconfirm = 0; break; case KITEM_SNEAKER: if ((player->kartstuff[k_offroad] && K_ApplyOffroad(player)) // Stuck in offroad, use it NOW || K_GetWaypointIsShortcut(player->nextwaypoint) == true // Going toward a shortcut! || player->speed < K_GetKartSpeed(player, false)/2 // Being slowed down too much || player->kartstuff[k_speedboost] > (FRACUNIT/8) // Have another type of boost (tethering) - || player->kartstuff[k_botitemconfirm] > 4*TICRATE) // Held onto it for too long + || player->botvars.itemconfirm > 4*TICRATE) // Held onto it for too long { if (!player->kartstuff[k_sneakertimer] && !(player->pflags & PF_ATTACKDOWN)) { cmd->buttons |= BT_ATTACK; - player->kartstuff[k_botitemconfirm] = 2*TICRATE; + player->botvars.itemconfirm = 2*TICRATE; } } else { - player->kartstuff[k_botitemconfirm]++; + player->botvars.itemconfirm++; } break; case KITEM_ROCKETSNEAKER: if (player->kartstuff[k_rocketsneakertimer] <= 0) { cmd->buttons |= BT_ATTACK; - player->kartstuff[k_botitemconfirm] = 0; + player->botvars.itemconfirm = 0; } break; case KITEM_BANANA: if (!player->kartstuff[k_itemheld]) { cmd->buttons |= BT_ATTACK; - player->kartstuff[k_botitemconfirm] = 0; + player->botvars.itemconfirm = 0; } else { @@ -981,7 +996,7 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd) if (abs(turnamt) >= KART_FULLTURN/2) { - player->kartstuff[k_botitemconfirm]++; + player->botvars.itemconfirm++; } else { @@ -992,7 +1007,7 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd) if (K_PlayerNearSpot(player, estx, esty, player->mo->radius * 16)) { - player->kartstuff[k_botitemconfirm] += 4; + player->botvars.itemconfirm += 4; throwdir = 1; } } @@ -1042,13 +1057,13 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd) if (ad >= 180-cone) { - player->kartstuff[k_botitemconfirm] += 2; + player->botvars.itemconfirm += 2; throwdir = -1; } } } - if ((player->kartstuff[k_botitemconfirm] > 2*TICRATE) + if ((player->botvars.itemconfirm > 2*TICRATE) || (player->kartstuff[k_bananadrag] >= TICRATE)) { if (throwdir == 1) @@ -1061,7 +1076,7 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd) } cmd->buttons |= BT_ATTACK; - player->kartstuff[k_botitemconfirm] = 0; + player->botvars.itemconfirm = 0; } } break; @@ -1069,7 +1084,7 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd) if (!player->kartstuff[k_itemheld]) { cmd->buttons |= BT_ATTACK; - player->kartstuff[k_botitemconfirm] = 0; + player->botvars.itemconfirm = 0; } else if (player->kartstuff[k_position] != 1) // Hold onto orbiting items when in 1st :) /* FALL-THRU */ @@ -1130,17 +1145,17 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd) if (ad <= cone) { - player->kartstuff[k_botitemconfirm] += 4; + player->botvars.itemconfirm += 4; throwdir = 1; } else if (ad >= 180-cone) { - player->kartstuff[k_botitemconfirm] += 2; + player->botvars.itemconfirm += 2; } } } - if (player->kartstuff[k_botitemconfirm] > 5*TICRATE) + if (player->botvars.itemconfirm > 5*TICRATE) { if (throwdir == 1) { @@ -1152,7 +1167,7 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd) } cmd->buttons |= BT_ATTACK; - player->kartstuff[k_botitemconfirm] = 0; + player->botvars.itemconfirm = 0; } } break; @@ -1160,14 +1175,14 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd) if (!player->kartstuff[k_itemheld]) { cmd->buttons |= BT_ATTACK; - player->kartstuff[k_botitemconfirm] = 0; + player->botvars.itemconfirm = 0; } else if (player->kartstuff[k_position] != 1) // Hold onto orbiting items when in 1st :) { SINT8 throwdir = 1; UINT8 i; - player->kartstuff[k_botitemconfirm]++; + player->botvars.itemconfirm++; for (i = 0; i < MAXPLAYERS; i++) { @@ -1214,7 +1229,7 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd) if (ad >= 180-cone) { - player->kartstuff[k_botitemconfirm] += 2; + player->botvars.itemconfirm += 2; throwdir = -1; } } @@ -1222,11 +1237,11 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd) if (player->kartstuff[k_lastjawztarget] != -1) { - player->kartstuff[k_botitemconfirm] += 4; + player->botvars.itemconfirm += 4; throwdir = 1; } - if (player->kartstuff[k_botitemconfirm] > 5*TICRATE) + if (player->botvars.itemconfirm > 5*TICRATE) { if (throwdir == 1) { @@ -1238,7 +1253,7 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd) } cmd->buttons |= BT_ATTACK; - player->kartstuff[k_botitemconfirm] = 0; + player->botvars.itemconfirm = 0; } } break; @@ -1246,7 +1261,7 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd) if (!player->kartstuff[k_itemheld]) { cmd->buttons |= BT_ATTACK; - player->kartstuff[k_botitemconfirm] = 0; + player->botvars.itemconfirm = 0; } else { @@ -1298,7 +1313,7 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd) if (ad >= 180-cone) { - player->kartstuff[k_botitemconfirm] += 2; + player->botvars.itemconfirm += 2; throwdir = -1; } } @@ -1306,7 +1321,7 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd) if (abs(turnamt) >= KART_FULLTURN/2) { - player->kartstuff[k_botitemconfirm]++; + player->botvars.itemconfirm++; } else { @@ -1317,7 +1332,7 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd) if (K_PlayerNearSpot(player, estx, esty, player->mo->radius * 16)) { - player->kartstuff[k_botitemconfirm] += 4; + player->botvars.itemconfirm += 4; throwdir = 0; } @@ -1328,12 +1343,12 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd) if (K_PlayerNearSpot(player, estx, esty, player->mo->radius * 16)) { - player->kartstuff[k_botitemconfirm] += 4; + player->botvars.itemconfirm += 4; throwdir = 1; } } - if ((player->kartstuff[k_botitemconfirm] > 2*TICRATE) + if ((player->botvars.itemconfirm > 2*TICRATE) || (player->kartstuff[k_bananadrag] >= TICRATE)) { if (throwdir == 1) @@ -1346,26 +1361,26 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd) } cmd->buttons |= BT_ATTACK; - player->kartstuff[k_botitemconfirm] = 0; + player->botvars.itemconfirm = 0; } } break; case KITEM_THUNDERSHIELD: if (!K_BotUseItemNearPlayer(player, cmd, 192*player->mo->scale)) { - if (player->kartstuff[k_botitemconfirm] > 10*TICRATE) + if (player->botvars.itemconfirm > 10*TICRATE) { cmd->buttons |= BT_ATTACK; - player->kartstuff[k_botitemconfirm] = 0; + player->botvars.itemconfirm = 0; } else { - player->kartstuff[k_botitemconfirm]++; + player->botvars.itemconfirm++; } } break; default: - player->kartstuff[k_botitemconfirm] = 0; + player->botvars.itemconfirm = 0; break; } } @@ -1383,16 +1398,16 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd) turnamt = -KART_FULLTURN; } - if ((turnamt > 0 && player->kartstuff[k_botlastturn] >= 0) - || (turnamt < 0 && player->kartstuff[k_botlastturn] <= 0)) + if ((turnamt > 0 && player->botvars.lastturn >= 0) + || (turnamt < 0 && player->botvars.lastturn <= 0)) { if (turnamt > 0) { - player->kartstuff[k_botlastturn] = 1; + player->botvars.lastturn = 1; } else if (turnamt < 0) { - player->kartstuff[k_botlastturn] = -1; + player->botvars.lastturn = -1; } cmd->driftturn = turnamt; @@ -1400,7 +1415,7 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd) } else { - player->kartstuff[k_botlastturn] = 0; + player->botvars.lastturn = 0; } } diff --git a/src/k_bot.h b/src/k_bot.h index 38e3af27b..4a5af7122 100644 --- a/src/k_bot.h +++ b/src/k_bot.h @@ -7,10 +7,13 @@ // terms of the GNU General Public License, version 2. // See the 'LICENSE' file for more details. //----------------------------------------------------------------------------- -/// \file b_bot.h +/// \file k_bot.h /// \brief Basic bot handling #include "k_waypoint.h" +#include "d_player.h" + +#define MAXBOTDIFFICULTY 9 // Path that bot will attempt to take typedef struct botprediction_s { diff --git a/src/k_kart.c b/src/k_kart.c index 91f25e042..e36627ae3 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -801,8 +801,8 @@ static void K_KartGetItemResult(player_t *player, SINT8 getitem) if (getitem == KITEM_HYUDORO) // Hyudoro cooldown hyubgone = 5*TICRATE; - player->kartstuff[k_botitemdelay] = TICRATE; - player->kartstuff[k_botitemconfirm] = 0; + player->botvars.itemdelay = TICRATE; + player->botvars.itemconfirm = 0; switch (getitem) { @@ -2704,19 +2704,35 @@ fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower) if (K_PlayerUsesBotMovement(player)) { - fixed_t speedmul = FRACUNIT + ((K_BotRubberband(player) - FRACUNIT) / 2); - // Give top speed a buff for bots, since it's a fairly weak stat without drifting - speedmul += ((kartspeed-1) * FRACUNIT / 8) / 10; // +10% for speed 9 - - finalspeed = FixedMul(finalspeed, speedmul); + fixed_t speedmul = ((kartspeed-1) * FRACUNIT / 8) / 10; // +10% for speed 9 + finalspeed = FixedMul(finalspeed, FRACUNIT + speedmul); } if (player->mo && !P_MobjWasRemoved(player->mo)) finalspeed = FixedMul(finalspeed, player->mo->scale); if (doboostpower) + { + if (K_PlayerUsesBotMovement(player)) + { + fixed_t rubberband = K_BotRubberband(player); + + if (rubberband > 3*FRACUNIT/2) + { + rubberband = 3*FRACUNIT/2; + } + else if (rubberband < FRACUNIT) + { + rubberband = FRACUNIT; + } + + finalspeed = FixedMul(finalspeed, rubberband); + } + return FixedMul(finalspeed, player->kartstuff[k_boostpower]+player->kartstuff[k_speedboost]); + } + return finalspeed; }