mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-01-01 20:52:47 +00:00
Merge branch 'bot-finally' into 'master'
Fix bot memory leak See merge request KartKrew/Kart!1474
This commit is contained in:
commit
86ff4f720b
6 changed files with 299 additions and 286 deletions
|
|
@ -125,7 +125,7 @@ add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32
|
|||
k_waypoint.cpp
|
||||
k_pathfind.c
|
||||
k_bheap.c
|
||||
k_bot.c
|
||||
k_bot.cpp
|
||||
k_botitem.c
|
||||
k_botsearch.c
|
||||
k_grandprix.c
|
||||
|
|
|
|||
|
|
@ -4060,10 +4060,10 @@ static void Got_AddBot(UINT8 **p, INT32 playernum)
|
|||
}
|
||||
|
||||
static boolean SV_AddWaitingPlayers(SINT8 node, UINT8 *availabilities,
|
||||
const char *name, uint8_t *key, UINT16 *pwr,
|
||||
const char *name2, uint8_t *key2, UINT16 *pwr2,
|
||||
const char *name3, uint8_t *key3, UINT16 *pwr3,
|
||||
const char *name4, uint8_t *key4, UINT16 *pwr4)
|
||||
const char *name, uint8_t *key, UINT16 *pwr,
|
||||
const char *name2, uint8_t *key2, UINT16 *pwr2,
|
||||
const char *name3, uint8_t *key3, UINT16 *pwr3,
|
||||
const char *name4, uint8_t *key4, UINT16 *pwr4)
|
||||
{
|
||||
INT32 n, newplayernum, i;
|
||||
UINT8 buf[4 + MAXPLAYERNAME + PUBKEYLENGTH + MAXAVAILABILITY + sizeof(((serverplayer_t *)0)->powerlevels)];
|
||||
|
|
@ -4172,6 +4172,85 @@ const char *name4, uint8_t *key4, UINT16 *pwr4)
|
|||
return newplayer;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
boolean K_AddBotFromServer(UINT8 skin, UINT8 difficulty, botStyle_e style, UINT8 *p)
|
||||
|
||||
See header file for description.
|
||||
--------------------------------------------------*/
|
||||
boolean K_AddBotFromServer(UINT8 skin, UINT8 difficulty, botStyle_e style, UINT8 *p)
|
||||
{
|
||||
UINT8 newplayernum = *p;
|
||||
|
||||
// search for a free playernum
|
||||
// we can't use playeringame since it is not updated here
|
||||
for (; newplayernum < MAXPLAYERS; newplayernum++)
|
||||
{
|
||||
UINT8 n;
|
||||
|
||||
for (n = 0; n < MAXNETNODES; n++)
|
||||
{
|
||||
if (nodetoplayer[n] == newplayernum
|
||||
|| nodetoplayer2[n] == newplayernum
|
||||
|| nodetoplayer3[n] == newplayernum
|
||||
|| nodetoplayer4[n] == newplayernum)
|
||||
break;
|
||||
}
|
||||
|
||||
if (n == MAXNETNODES)
|
||||
break;
|
||||
}
|
||||
|
||||
for (; newplayernum < MAXPLAYERS; newplayernum++)
|
||||
{
|
||||
if (playeringame[newplayernum] == false)
|
||||
{
|
||||
// free player slot
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (newplayernum >= MAXPLAYERS)
|
||||
{
|
||||
// nothing is free
|
||||
*p = MAXPLAYERS;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (server)
|
||||
{
|
||||
UINT8 buf[4];
|
||||
UINT8 *buf_p = buf;
|
||||
|
||||
WRITEUINT8(buf_p, newplayernum);
|
||||
|
||||
if (skin > numskins)
|
||||
{
|
||||
skin = numskins;
|
||||
}
|
||||
|
||||
WRITEUINT8(buf_p, skin);
|
||||
|
||||
if (difficulty < 1)
|
||||
{
|
||||
difficulty = 1;
|
||||
}
|
||||
else if (difficulty > MAXBOTDIFFICULTY)
|
||||
{
|
||||
difficulty = MAXBOTDIFFICULTY;
|
||||
}
|
||||
|
||||
WRITEUINT8(buf_p, difficulty);
|
||||
WRITEUINT8(buf_p, style);
|
||||
|
||||
SendNetXCmd(XD_ADDBOT, buf, buf_p - buf);
|
||||
DEBFILE(va("Server added bot %d\n", newplayernum));
|
||||
}
|
||||
|
||||
// use the next free slot (we can't put playeringame[newplayernum] = true here)
|
||||
*p = newplayernum+1;
|
||||
return true;
|
||||
}
|
||||
|
||||
void CL_AddSplitscreenPlayer(void)
|
||||
{
|
||||
if (cl_mode == CL_CONNECTED)
|
||||
|
|
|
|||
|
|
@ -588,6 +588,27 @@ void SV_StartSinglePlayerServer(INT32 dogametype, boolean donetgame);
|
|||
boolean SV_SpawnServer(void);
|
||||
void SV_StopServer(void);
|
||||
void SV_ResetServer(void);
|
||||
|
||||
/*--------------------------------------------------
|
||||
boolean K_AddBotFromServer(UINT8 skin, UINT8 difficulty, botStyle_e style, UINT8 *newplayernum);
|
||||
|
||||
Adds a new bot, using a server-sided packet sent to all clients.
|
||||
Using regular K_AddBot wherever possible is better, but this is kept
|
||||
as a back-up measure if this is the only option.
|
||||
|
||||
Input Arguments:-
|
||||
skin - Skin number that the bot will use.
|
||||
difficulty - Difficulty level this bot will use.
|
||||
style - Bot style to spawn this bot with, see botStyle_e.
|
||||
newplayernum - Pointer to the last valid player slot number.
|
||||
Is a pointer so that this function can be called multiple times to add more than one bot.
|
||||
|
||||
Return:-
|
||||
true if a bot can be added via a packet later, otherwise false.
|
||||
--------------------------------------------------*/
|
||||
|
||||
boolean K_AddBotFromServer(UINT8 skin, UINT8 difficulty, botStyle_e style, UINT8 *p);
|
||||
|
||||
void CL_AddSplitscreenPlayer(void);
|
||||
void CL_RemoveSplitscreenPlayer(UINT8 p);
|
||||
void CL_Reset(void);
|
||||
|
|
|
|||
|
|
@ -1,15 +1,19 @@
|
|||
// SONIC ROBO BLAST 2 KART
|
||||
// DR. ROBOTNIK'S RING RACERS
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2018-2020 by Sally "TehRealSalt" Cochenour
|
||||
// Copyright (C) 2018-2020 by Kart Krew
|
||||
// Copyright (C) by Sally "TehRealSalt" Cochenour
|
||||
// Copyright (C) by Kart Krew
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file k_bot.c
|
||||
/// \file k_bot.cpp
|
||||
/// \brief Bot logic & ticcmd generation code
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "cxxutil.hpp"
|
||||
|
||||
#include "doomdef.h"
|
||||
#include "d_player.h"
|
||||
#include "g_game.h"
|
||||
|
|
@ -116,85 +120,6 @@ boolean K_AddBot(UINT8 skin, UINT8 difficulty, botStyle_e style, UINT8 *p)
|
|||
return true;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
boolean K_AddBotFromServer(UINT8 skin, UINT8 difficulty, botStyle_e style, UINT8 *p)
|
||||
|
||||
See header file for description.
|
||||
--------------------------------------------------*/
|
||||
boolean K_AddBotFromServer(UINT8 skin, UINT8 difficulty, botStyle_e style, UINT8 *p)
|
||||
{
|
||||
UINT8 newplayernum = *p;
|
||||
|
||||
// search for a free playernum
|
||||
// we can't use playeringame since it is not updated here
|
||||
for (; newplayernum < MAXPLAYERS; newplayernum++)
|
||||
{
|
||||
UINT8 n;
|
||||
|
||||
for (n = 0; n < MAXNETNODES; n++)
|
||||
{
|
||||
if (nodetoplayer[n] == newplayernum
|
||||
|| nodetoplayer2[n] == newplayernum
|
||||
|| nodetoplayer3[n] == newplayernum
|
||||
|| nodetoplayer4[n] == newplayernum)
|
||||
break;
|
||||
}
|
||||
|
||||
if (n == MAXNETNODES)
|
||||
break;
|
||||
}
|
||||
|
||||
for (; newplayernum < MAXPLAYERS; newplayernum++)
|
||||
{
|
||||
if (playeringame[newplayernum] == false)
|
||||
{
|
||||
// free player slot
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (newplayernum >= MAXPLAYERS)
|
||||
{
|
||||
// nothing is free
|
||||
*p = MAXPLAYERS;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (server)
|
||||
{
|
||||
UINT8 buf[4];
|
||||
UINT8 *buf_p = buf;
|
||||
|
||||
WRITEUINT8(buf_p, newplayernum);
|
||||
|
||||
if (skin > numskins)
|
||||
{
|
||||
skin = numskins;
|
||||
}
|
||||
|
||||
WRITEUINT8(buf_p, skin);
|
||||
|
||||
if (difficulty < 1)
|
||||
{
|
||||
difficulty = 1;
|
||||
}
|
||||
else if (difficulty > MAXBOTDIFFICULTY)
|
||||
{
|
||||
difficulty = MAXBOTDIFFICULTY;
|
||||
}
|
||||
|
||||
WRITEUINT8(buf_p, difficulty);
|
||||
WRITEUINT8(buf_p, style);
|
||||
|
||||
SendNetXCmd(XD_ADDBOT, buf, buf_p - buf);
|
||||
DEBFILE(va("Server added bot %d\n", newplayernum));
|
||||
}
|
||||
|
||||
// use the next free slot (we can't put playeringame[newplayernum] = true here)
|
||||
*p = newplayernum+1;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
void K_UpdateMatchRaceBots(void)
|
||||
|
||||
|
|
@ -204,7 +129,7 @@ void K_UpdateMatchRaceBots(void)
|
|||
{
|
||||
const UINT8 defaultbotskin = R_BotDefaultSkin();
|
||||
const UINT8 difficulty = cv_kartbot.value;
|
||||
UINT8 pmax = min((dedicated ? MAXPLAYERS-1 : MAXPLAYERS), cv_maxconnections.value);
|
||||
UINT8 pmax = std::min<UINT8>((dedicated ? MAXPLAYERS-1 : MAXPLAYERS), static_cast<UINT8>(cv_maxconnections.value));
|
||||
UINT8 numplayers = 0;
|
||||
UINT8 numbots = 0;
|
||||
UINT8 numwaiting = 0;
|
||||
|
|
@ -222,7 +147,7 @@ void K_UpdateMatchRaceBots(void)
|
|||
|
||||
if (cv_maxplayers.value > 0)
|
||||
{
|
||||
pmax = min(pmax, cv_maxplayers.value);
|
||||
pmax = std::min<UINT8>(pmax, static_cast<UINT8>(cv_maxplayers.value));
|
||||
}
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
|
|
@ -429,7 +354,7 @@ static fixed_t K_BotSpeedScaled(player_t *player, fixed_t speed)
|
|||
result = FixedMul(result, moveFactor);
|
||||
}
|
||||
|
||||
if (player->mo->standingslope != NULL)
|
||||
if (player->mo->standingslope != nullptr)
|
||||
{
|
||||
const pslope_t *slope = player->mo->standingslope;
|
||||
|
||||
|
|
@ -462,7 +387,7 @@ static fixed_t K_BotSpeedScaled(player_t *player, fixed_t speed)
|
|||
mo - The bot player's mobj.
|
||||
|
||||
Return:-
|
||||
Linedef of the bot controller. NULL if it doesn't exist.
|
||||
Linedef of the bot controller. nullptr if it doesn't exist.
|
||||
--------------------------------------------------*/
|
||||
static line_t *K_FindBotController(mobj_t *mo)
|
||||
{
|
||||
|
|
@ -471,7 +396,7 @@ static line_t *K_FindBotController(mobj_t *mo)
|
|||
INT16 lineNum = -1;
|
||||
mtag_t tag;
|
||||
|
||||
I_Assert(mo != NULL);
|
||||
I_Assert(mo != nullptr);
|
||||
I_Assert(!P_MobjWasRemoved(mo));
|
||||
|
||||
for (node = mo->touching_sectorlist; node; node = node->m_sectorlist_next)
|
||||
|
|
@ -491,7 +416,7 @@ static line_t *K_FindBotController(mobj_t *mo)
|
|||
|
||||
for (rover = node->m_sector->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
sector_t *rs = NULL;
|
||||
sector_t *rs = nullptr;
|
||||
|
||||
if (!(rover->fofflags & FOF_EXISTS))
|
||||
{
|
||||
|
|
@ -520,7 +445,7 @@ static line_t *K_FindBotController(mobj_t *mo)
|
|||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -595,7 +520,7 @@ fixed_t K_BotRubberband(player_t *player)
|
|||
const fixed_t rubbermax = Easing_Linear(difficultyEase, FRACUNIT, FRACUNIT * 165 / 100);
|
||||
|
||||
fixed_t rubberband = FRACUNIT >> 1;
|
||||
player_t *firstplace = NULL;
|
||||
player_t *firstplace = nullptr;
|
||||
size_t i = SIZE_MAX;
|
||||
|
||||
if (player->exiting)
|
||||
|
|
@ -608,7 +533,7 @@ fixed_t K_BotRubberband(player_t *player)
|
|||
{
|
||||
const line_t *botController = &lines[player->botvars.controller];
|
||||
|
||||
if (botController != NULL)
|
||||
if (botController != nullptr)
|
||||
{
|
||||
// Disable rubberbanding
|
||||
if (botController->args[1] & TMBOT_NORUBBERBAND)
|
||||
|
|
@ -633,18 +558,18 @@ fixed_t K_BotRubberband(player_t *player)
|
|||
}
|
||||
#endif
|
||||
|
||||
if (firstplace == NULL || players[i].distancetofinish < firstplace->distancetofinish)
|
||||
if (firstplace == nullptr || players[i].distancetofinish < firstplace->distancetofinish)
|
||||
{
|
||||
firstplace = &players[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (firstplace != NULL)
|
||||
if (firstplace != nullptr)
|
||||
{
|
||||
// Lv. 1: 5120 units
|
||||
// Lv. 9: 320 units
|
||||
const fixed_t spacing = FixedDiv(
|
||||
max(
|
||||
std::max<fixed_t>(
|
||||
80 * mapobjectscale,
|
||||
Easing_Linear(difficultyEase, 5120 * mapobjectscale, 320 * mapobjectscale)
|
||||
),
|
||||
|
|
@ -759,7 +684,7 @@ static void K_GetBotWaypointRadius(waypoint_t *const waypoint, fixed_t *smallest
|
|||
waypoint->mobj->x, waypoint->mobj->y
|
||||
);
|
||||
|
||||
delta = max(delta, AngleDelta(nextAngle, prevAngle));
|
||||
delta = std::max<angle_t>(delta, AngleDelta(nextAngle, prevAngle));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -771,13 +696,13 @@ static void K_GetBotWaypointRadius(waypoint_t *const waypoint, fixed_t *smallest
|
|||
reduce = FixedDiv(delta, maxDelta);
|
||||
reduce = FRACUNIT + FixedMul(reduce, maxReduce - FRACUNIT);
|
||||
|
||||
*smallestRadius = min(*smallestRadius, radius);
|
||||
*smallestScaled = min(*smallestScaled, FixedMul(radius, reduce));
|
||||
*smallestRadius = std::min<fixed_t>(*smallestRadius, radius);
|
||||
*smallestScaled = std::min<fixed_t>(*smallestScaled, FixedMul(radius, reduce));
|
||||
}
|
||||
|
||||
static fixed_t K_ScaleWPDistWithSlope(fixed_t disttonext, angle_t angletonext, const pslope_t *slope, SINT8 flip)
|
||||
{
|
||||
if (slope == NULL)
|
||||
if (slope == nullptr)
|
||||
{
|
||||
return disttonext;
|
||||
}
|
||||
|
|
@ -824,12 +749,12 @@ static botprediction_t *K_CreateBotPrediction(player_t *player)
|
|||
|
||||
const INT16 handling = K_GetKartTurnValue(player, KART_FULLTURN) / jankDiv; // Reduce prediction based on how fast you can turn
|
||||
|
||||
const tic_t futuresight = (TICRATE * KART_FULLTURN) / max(1, handling); // How far ahead into the future to try and predict
|
||||
const tic_t futuresight = (TICRATE * KART_FULLTURN) / std::max<INT16>(1, handling); // How far ahead into the future to try and predict
|
||||
const fixed_t speed = K_BotSpeedScaled(player, P_AproxDistance(player->mo->momx, player->mo->momy));
|
||||
|
||||
const INT32 startDist = 0; //(DEFAULT_WAYPOINT_RADIUS * mapobjectscale) / FRACUNIT;
|
||||
const INT32 maxDist = (DEFAULT_WAYPOINT_RADIUS * 3 * mapobjectscale) / FRACUNIT; // This function gets very laggy when it goes far distances, and going too far isn't very helpful anyway.
|
||||
const INT32 distance = min(((speed / FRACUNIT) * (INT32)futuresight) + startDist, maxDist);
|
||||
const INT32 distance = std::min<INT32>(((speed / FRACUNIT) * static_cast<INT32>(futuresight)) + startDist, maxDist);
|
||||
|
||||
// Halves radius when encountering a wall on your way to your destination.
|
||||
fixed_t radReduce = FRACUNIT;
|
||||
|
|
@ -851,16 +776,16 @@ static botprediction_t *K_CreateBotPrediction(player_t *player)
|
|||
boolean pathfindsuccess = false;
|
||||
path_t pathtofinish = {0};
|
||||
|
||||
botprediction_t *predict = NULL;
|
||||
botprediction_t *predict = nullptr;
|
||||
size_t i;
|
||||
|
||||
if (wp == NULL || P_MobjWasRemoved(wp->mobj) == true)
|
||||
if (wp == nullptr || P_MobjWasRemoved(wp->mobj) == true)
|
||||
{
|
||||
// Can't do any of this if we don't have a waypoint.
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
predict = Z_Calloc(sizeof(botprediction_t), PU_STATIC, NULL);
|
||||
predict = static_cast<botprediction_t *>(Z_Calloc(sizeof(botprediction_t), PU_LEVEL, nullptr));
|
||||
|
||||
// Init defaults in case of pathfind failure
|
||||
angletonext = R_PointToAngle2(prevwpmobj->x, prevwpmobj->y, wp->mobj->x, wp->mobj->y);
|
||||
|
|
@ -927,8 +852,8 @@ static botprediction_t *K_CreateBotPrediction(player_t *player)
|
|||
if (distanceleft > 0)
|
||||
{
|
||||
// Scaled with the leftover anglemul!
|
||||
predict->x += P_ReturnThrustX(NULL, angletonext, min(disttonext, distanceleft) * FRACUNIT);
|
||||
predict->y += P_ReturnThrustY(NULL, angletonext, min(disttonext, distanceleft) * FRACUNIT);
|
||||
predict->x += P_ReturnThrustX(nullptr, angletonext, std::min<fixed_t>(disttonext, distanceleft) * FRACUNIT);
|
||||
predict->y += P_ReturnThrustY(nullptr, angletonext, std::min<fixed_t>(disttonext, distanceleft) * FRACUNIT);
|
||||
}
|
||||
|
||||
ps_bots[player - players].prediction += I_GetPreciseTime() - time;
|
||||
|
|
@ -976,7 +901,7 @@ static UINT8 K_TrySpindash(player_t *player)
|
|||
{
|
||||
INT32 boosthold = starttime - K_GetSpindashChargeTime(player);
|
||||
|
||||
boosthold -= (DIFFICULTBOT - min(DIFFICULTBOT, player->botvars.difficulty)) * difficultyModifier;
|
||||
boosthold -= (DIFFICULTBOT - std::min<UINT8>(DIFFICULTBOT, player->botvars.difficulty)) * difficultyModifier;
|
||||
|
||||
if (leveltime >= (unsigned)boosthold)
|
||||
{
|
||||
|
|
@ -996,7 +921,7 @@ static UINT8 K_TrySpindash(player_t *player)
|
|||
|
||||
// Release quicker the higher the difficulty is.
|
||||
// Sounds counter-productive, but that's actually the best strategy after the race has started.
|
||||
chargingPoint -= min(DIFFICULTBOT, player->botvars.difficulty) * difficultyModifier;
|
||||
chargingPoint -= std::min<UINT8>(DIFFICULTBOT, player->botvars.difficulty) * difficultyModifier;
|
||||
|
||||
if (player->spindash > chargingPoint)
|
||||
{
|
||||
|
|
@ -1022,7 +947,7 @@ static UINT8 K_TrySpindash(player_t *player)
|
|||
} \
|
||||
}
|
||||
|
||||
if (K_SlopeResistance(player) == false && player->mo->standingslope != NULL)
|
||||
if (K_SlopeResistance(player) == false && player->mo->standingslope != nullptr)
|
||||
{
|
||||
const pslope_t *slope = player->mo->standingslope;
|
||||
|
||||
|
|
@ -1120,13 +1045,13 @@ static boolean K_TryRingShooter(player_t *player)
|
|||
--------------------------------------------------*/
|
||||
static void K_DrawPredictionDebug(botprediction_t *predict, player_t *player)
|
||||
{
|
||||
mobj_t *debugMobj = NULL;
|
||||
mobj_t *debugMobj = nullptr;
|
||||
angle_t sideAngle = ANGLE_MAX;
|
||||
UINT8 i = UINT8_MAX;
|
||||
|
||||
I_Assert(predict != NULL);
|
||||
I_Assert(player != NULL);
|
||||
I_Assert(player->mo != NULL && P_MobjWasRemoved(player->mo) == false);
|
||||
I_Assert(predict != nullptr);
|
||||
I_Assert(player != nullptr);
|
||||
I_Assert(player->mo != nullptr && P_MobjWasRemoved(player->mo) == false);
|
||||
|
||||
sideAngle = player->mo->angle + ANGLE_90;
|
||||
|
||||
|
|
@ -1143,7 +1068,7 @@ static void K_DrawPredictionDebug(botprediction_t *predict, player_t *player)
|
|||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
mobj_t *radiusMobj = NULL;
|
||||
mobj_t *radiusMobj = nullptr;
|
||||
fixed_t radiusX = predict->x, radiusY = predict->y;
|
||||
|
||||
if (i & 1)
|
||||
|
|
@ -1186,7 +1111,7 @@ static void K_DrawPredictionDebug(botprediction_t *predict, player_t *player)
|
|||
static void K_BotTrick(player_t *player, ticcmd_t *cmd, const line_t *botController)
|
||||
{
|
||||
// Trick panel state -- do nothing until a controller line is found, in which case do a trick.
|
||||
if (botController == NULL)
|
||||
if (botController == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -1232,7 +1157,7 @@ static angle_t K_BotSmoothLanding(player_t *player, angle_t destangle)
|
|||
angle_t newAngle = destangle;
|
||||
boolean air = !P_IsObjectOnGround(player->mo);
|
||||
angle_t steepVal = air ? STUMBLE_STEEP_VAL_AIR : STUMBLE_STEEP_VAL;
|
||||
angle_t slopeSteep = max(AngleDelta(player->mo->pitch, 0), AngleDelta(player->mo->roll, 0));
|
||||
angle_t slopeSteep = std::max<angle_t>(AngleDelta(player->mo->pitch, 0), AngleDelta(player->mo->roll, 0));
|
||||
|
||||
if (slopeSteep > steepVal)
|
||||
{
|
||||
|
|
@ -1284,7 +1209,7 @@ static INT32 K_HandleBotTrack(player_t *player, ticcmd_t *cmd, botprediction_t *
|
|||
angle_t moveangle;
|
||||
INT32 anglediff;
|
||||
|
||||
I_Assert(predict != NULL);
|
||||
I_Assert(predict != nullptr);
|
||||
|
||||
destangle = K_BotSmoothLanding(player, destangle);
|
||||
|
||||
|
|
@ -1329,7 +1254,7 @@ static INT32 K_HandleBotTrack(player_t *player, ticcmd_t *cmd, botprediction_t *
|
|||
// This makes predictions into turns a little nicer
|
||||
// Facing 90 degrees away from the predicted point gives you 0 radius
|
||||
rad = FixedMul(rad,
|
||||
FixedDiv(max(0, ANGLE_90 - anglediff), ANGLE_90)
|
||||
FixedDiv(std::max<angle_t>(0, ANGLE_90 - anglediff), ANGLE_90)
|
||||
);
|
||||
|
||||
// Become more precise the slower you're moving
|
||||
|
|
@ -1384,21 +1309,21 @@ static INT32 K_HandleBotReverse(player_t *player, ticcmd_t *cmd, botprediction_t
|
|||
angle_t moveangle, angle;
|
||||
INT16 anglediff, momdiff;
|
||||
|
||||
if (predict != NULL)
|
||||
if (predict != nullptr)
|
||||
{
|
||||
// TODO: Should we reverse through bot controllers?
|
||||
return K_HandleBotTrack(player, cmd, predict, destangle);
|
||||
}
|
||||
|
||||
if (player->nextwaypoint == NULL
|
||||
|| player->nextwaypoint->mobj == NULL
|
||||
if (player->nextwaypoint == nullptr
|
||||
|| player->nextwaypoint->mobj == nullptr
|
||||
|| P_MobjWasRemoved(player->nextwaypoint->mobj))
|
||||
{
|
||||
// No data available...
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((player->nextwaypoint->prevwaypoints != NULL)
|
||||
if ((player->nextwaypoint->prevwaypoints != nullptr)
|
||||
&& (player->nextwaypoint->numprevwaypoints > 0U))
|
||||
{
|
||||
size_t i;
|
||||
|
|
@ -1470,7 +1395,7 @@ static INT32 K_HandleBotReverse(player_t *player, ticcmd_t *cmd, botprediction_t
|
|||
{
|
||||
fixed_t slopeMul = FRACUNIT;
|
||||
|
||||
if (player->mo->standingslope != NULL)
|
||||
if (player->mo->standingslope != nullptr)
|
||||
{
|
||||
const pslope_t *slope = player->mo->standingslope;
|
||||
|
||||
|
|
@ -1543,7 +1468,7 @@ static void K_BotPodiumTurning(player_t *player, ticcmd_t *cmd)
|
|||
--------------------------------------------------*/
|
||||
static void K_BuildBotPodiumTiccmd(player_t *player, ticcmd_t *cmd)
|
||||
{
|
||||
if (player->currentwaypoint == NULL)
|
||||
if (player->currentwaypoint == nullptr)
|
||||
{
|
||||
// We've reached the end of our path.
|
||||
// Simply stop moving.
|
||||
|
|
@ -1573,12 +1498,15 @@ static void K_BuildBotPodiumTiccmd(player_t *player, ticcmd_t *cmd)
|
|||
static void K_BuildBotTiccmdNormal(player_t *player, ticcmd_t *cmd)
|
||||
{
|
||||
precise_t t = 0;
|
||||
botprediction_t *predict = NULL;
|
||||
|
||||
botprediction_t *predict = nullptr;
|
||||
auto predict_finally = srb2::finally([&predict]() { Z_Free(predict); });
|
||||
|
||||
boolean trySpindash = true;
|
||||
angle_t destangle = 0;
|
||||
UINT8 spindash = 0;
|
||||
INT32 turnamt = 0;
|
||||
const line_t *botController = player->botvars.controller != UINT16_MAX ? &lines[player->botvars.controller] : NULL;
|
||||
const line_t *botController = player->botvars.controller != UINT16_MAX ? &lines[player->botvars.controller] : nullptr;
|
||||
|
||||
if (!(gametyperules & GTR_BOTS) // No bot behaviors
|
||||
|| K_GetNumWaypoints() == 0 // No waypoints
|
||||
|
|
@ -1618,7 +1546,7 @@ static void K_BuildBotTiccmdNormal(player_t *player, ticcmd_t *cmd)
|
|||
return;
|
||||
}
|
||||
|
||||
if (botController != NULL && (botController->args[1] & TMBOT_NOCONTROL))
|
||||
if (botController != nullptr && (botController->args[1] & TMBOT_NOCONTROL))
|
||||
{
|
||||
// Disable bot controls entirely.
|
||||
return;
|
||||
|
|
@ -1626,7 +1554,7 @@ static void K_BuildBotTiccmdNormal(player_t *player, ticcmd_t *cmd)
|
|||
|
||||
destangle = player->mo->angle;
|
||||
|
||||
if (botController != NULL && (botController->args[1] & TMBOT_FORCEDIR))
|
||||
if (botController != nullptr && (botController->args[1] & TMBOT_FORCEDIR))
|
||||
{
|
||||
const fixed_t dist = DEFAULT_WAYPOINT_RADIUS * player->mo->scale;
|
||||
|
||||
|
|
@ -1634,14 +1562,14 @@ static void K_BuildBotTiccmdNormal(player_t *player, ticcmd_t *cmd)
|
|||
destangle = FixedAngle(botController->args[2] * FRACUNIT);
|
||||
|
||||
// Overwritten prediction
|
||||
predict = Z_Calloc(sizeof(botprediction_t), PU_STATIC, NULL);
|
||||
predict = static_cast<botprediction_t *>(Z_Calloc(sizeof(botprediction_t), PU_STATIC, nullptr));
|
||||
|
||||
predict->x = player->mo->x + FixedMul(dist, FINECOSINE(destangle >> ANGLETOFINESHIFT));
|
||||
predict->y = player->mo->y + FixedMul(dist, FINESINE(destangle >> ANGLETOFINESHIFT));
|
||||
predict->radius = (DEFAULT_WAYPOINT_RADIUS / 4) * mapobjectscale;
|
||||
}
|
||||
|
||||
if (leveltime <= starttime && finishBeamLine != NULL)
|
||||
if (leveltime <= starttime && finishBeamLine != nullptr)
|
||||
{
|
||||
// Handle POSITION!!
|
||||
const fixed_t distBase = 480*mapobjectscale;
|
||||
|
|
@ -1684,13 +1612,13 @@ static void K_BuildBotTiccmdNormal(player_t *player, ticcmd_t *cmd)
|
|||
if (bullyTurn == INT32_MAX)
|
||||
{
|
||||
// No one to bully, just go for a spindash as anyone.
|
||||
if (predict == NULL)
|
||||
if (predict == nullptr)
|
||||
{
|
||||
// Create a prediction.
|
||||
predict = K_CreateBotPrediction(player);
|
||||
}
|
||||
|
||||
if (predict != NULL)
|
||||
if (predict != nullptr)
|
||||
{
|
||||
K_NudgePredictionTowardsObjects(predict, player);
|
||||
destangle = R_PointToAngle2(player->mo->x, player->mo->y, predict->x, predict->y);
|
||||
|
|
@ -1716,13 +1644,13 @@ static void K_BuildBotTiccmdNormal(player_t *player, ticcmd_t *cmd)
|
|||
else
|
||||
{
|
||||
// Too far away, we need to just drive up.
|
||||
if (predict == NULL)
|
||||
if (predict == nullptr)
|
||||
{
|
||||
// Create a prediction.
|
||||
predict = K_CreateBotPrediction(player);
|
||||
}
|
||||
|
||||
if (predict != NULL)
|
||||
if (predict != nullptr)
|
||||
{
|
||||
K_NudgePredictionTowardsObjects(predict, player);
|
||||
destangle = R_PointToAngle2(player->mo->x, player->mo->y, predict->x, predict->y);
|
||||
|
|
@ -1733,13 +1661,13 @@ static void K_BuildBotTiccmdNormal(player_t *player, ticcmd_t *cmd)
|
|||
else
|
||||
{
|
||||
// Handle steering towards waypoints!
|
||||
if (predict == NULL)
|
||||
if (predict == nullptr)
|
||||
{
|
||||
// Create a prediction.
|
||||
predict = K_CreateBotPrediction(player);
|
||||
}
|
||||
|
||||
if (predict != NULL)
|
||||
if (predict != nullptr)
|
||||
{
|
||||
K_NudgePredictionTowardsObjects(predict, player);
|
||||
destangle = R_PointToAngle2(player->mo->x, player->mo->y, predict->x, predict->y);
|
||||
|
|
@ -1821,14 +1749,12 @@ static void K_BuildBotTiccmdNormal(player_t *player, ticcmd_t *cmd)
|
|||
}
|
||||
|
||||
// Free the prediction we made earlier
|
||||
if (predict != NULL)
|
||||
if (predict != nullptr)
|
||||
{
|
||||
if (cv_kartdebugbots.value != 0 && player - players == displayplayers[0])
|
||||
{
|
||||
K_DrawPredictionDebug(predict, player);
|
||||
}
|
||||
|
||||
Z_Free(predict);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1842,7 +1768,7 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
|
|||
// Remove any existing controls
|
||||
memset(cmd, 0, sizeof(ticcmd_t));
|
||||
|
||||
if (player->mo == NULL
|
||||
if (player->mo == nullptr
|
||||
|| player->spectator == true
|
||||
|| G_GamestateUsesLevel() == false)
|
||||
{
|
||||
30
src/k_bot.h
30
src/k_bot.h
|
|
@ -1,7 +1,7 @@
|
|||
// SONIC ROBO BLAST 2 KART
|
||||
// DR. ROBOTNIK'S RING RACERS
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2018-2020 by Sally "TehRealSalt" Cochenour
|
||||
// Copyright (C) 2018-2020 by Kart Krew
|
||||
// Copyright (C) by Sally "TehRealSalt" Cochenour
|
||||
// Copyright (C) by Kart Krew
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
|
@ -45,7 +45,8 @@ extern "C" {
|
|||
#define BOT_ITEM_DECISION_TIME (2*TICRATE)
|
||||
|
||||
// Point for bots to aim for
|
||||
struct botprediction_t {
|
||||
struct botprediction_t
|
||||
{
|
||||
fixed_t x, y;
|
||||
fixed_t radius, baseRadius;
|
||||
};
|
||||
|
|
@ -180,27 +181,6 @@ boolean K_AddBot(UINT8 skin, UINT8 difficulty, botStyle_e style, UINT8 *p);
|
|||
void K_SetBot(UINT8 newplayernum, UINT8 skinnum, UINT8 difficulty, botStyle_e style);
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
boolean K_AddBotFromServer(UINT8 skin, UINT8 difficulty, botStyle_e style, UINT8 *newplayernum);
|
||||
|
||||
Adds a new bot, using a server-sided packet sent to all clients.
|
||||
Using regular K_AddBot wherever possible is better, but this is kept
|
||||
as a back-up measure if this is the only option.
|
||||
|
||||
Input Arguments:-
|
||||
skin - Skin number that the bot will use.
|
||||
difficulty - Difficulty level this bot will use.
|
||||
style - Bot style to spawn this bot with, see botStyle_e.
|
||||
newplayernum - Pointer to the last valid player slot number.
|
||||
Is a pointer so that this function can be called multiple times to add more than one bot.
|
||||
|
||||
Return:-
|
||||
true if a bot can be added via a packet later, otherwise false.
|
||||
--------------------------------------------------*/
|
||||
|
||||
boolean K_AddBotFromServer(UINT8 skin, UINT8 difficulty, botStyle_e style, UINT8 *p);
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
void K_UpdateMatchRaceBots(void);
|
||||
|
||||
|
|
|
|||
|
|
@ -29,28 +29,6 @@
|
|||
#include "p_slopes.h" // P_GetZAt
|
||||
#include "m_perfstats.h"
|
||||
|
||||
struct globalsmuggle
|
||||
{
|
||||
mobj_t *botmo;
|
||||
botprediction_t *predict;
|
||||
fixed_t distancetocheck;
|
||||
|
||||
INT64 gotoAvgX[2], gotoAvgY[2];
|
||||
UINT32 gotoObjs[2];
|
||||
|
||||
INT64 avoidAvgX[2], avoidAvgY[2];
|
||||
UINT32 avoidObjs[2];
|
||||
|
||||
fixed_t annoyscore;
|
||||
mobj_t *annoymo;
|
||||
|
||||
fixed_t closestlinedist;
|
||||
|
||||
fixed_t eggboxx, eggboxy;
|
||||
UINT8 randomitems;
|
||||
UINT8 eggboxes;
|
||||
} globalsmuggle;
|
||||
|
||||
/*--------------------------------------------------
|
||||
static BlockItReturn_t K_FindEggboxes(mobj_t *thing)
|
||||
|
||||
|
|
@ -63,6 +41,14 @@ struct globalsmuggle
|
|||
Return:-
|
||||
BlockItReturn_t enum, see its definition for more information.
|
||||
--------------------------------------------------*/
|
||||
static struct eggboxSearch_s
|
||||
{
|
||||
fixed_t distancetocheck;
|
||||
fixed_t eggboxx, eggboxy;
|
||||
UINT8 randomitems;
|
||||
UINT8 eggboxes;
|
||||
} g_eggboxSearch;
|
||||
|
||||
static BlockItReturn_t K_FindEggboxes(mobj_t *thing)
|
||||
{
|
||||
fixed_t dist;
|
||||
|
|
@ -77,20 +63,20 @@ static BlockItReturn_t K_FindEggboxes(mobj_t *thing)
|
|||
return BMIT_CONTINUE;
|
||||
}
|
||||
|
||||
dist = P_AproxDistance(thing->x - globalsmuggle.eggboxx, thing->y - globalsmuggle.eggboxy);
|
||||
dist = P_AproxDistance(thing->x - g_eggboxSearch.eggboxx, thing->y - g_eggboxSearch.eggboxy);
|
||||
|
||||
if (dist > globalsmuggle.distancetocheck)
|
||||
if (dist > g_eggboxSearch.distancetocheck)
|
||||
{
|
||||
return BMIT_CONTINUE;
|
||||
}
|
||||
|
||||
if (thing->type == MT_RANDOMITEM)
|
||||
{
|
||||
globalsmuggle.randomitems++;
|
||||
g_eggboxSearch.randomitems++;
|
||||
}
|
||||
else
|
||||
{
|
||||
globalsmuggle.eggboxes++;
|
||||
g_eggboxSearch.eggboxes++;
|
||||
}
|
||||
|
||||
return BMIT_CONTINUE;
|
||||
|
|
@ -105,16 +91,16 @@ UINT8 K_EggboxStealth(fixed_t x, fixed_t y)
|
|||
{
|
||||
INT32 xl, xh, yl, yh, bx, by;
|
||||
|
||||
globalsmuggle.eggboxx = x;
|
||||
globalsmuggle.eggboxy = y;
|
||||
globalsmuggle.distancetocheck = (mapobjectscale * 256);
|
||||
globalsmuggle.randomitems = 0;
|
||||
globalsmuggle.eggboxes = 0;
|
||||
g_eggboxSearch.eggboxx = x;
|
||||
g_eggboxSearch.eggboxy = y;
|
||||
g_eggboxSearch.distancetocheck = (mapobjectscale * 256);
|
||||
g_eggboxSearch.randomitems = 0;
|
||||
g_eggboxSearch.eggboxes = 0;
|
||||
|
||||
xl = (unsigned)(globalsmuggle.eggboxx - globalsmuggle.distancetocheck - bmaporgx)>>MAPBLOCKSHIFT;
|
||||
xh = (unsigned)(globalsmuggle.eggboxx + globalsmuggle.distancetocheck - bmaporgx)>>MAPBLOCKSHIFT;
|
||||
yl = (unsigned)(globalsmuggle.eggboxy - globalsmuggle.distancetocheck - bmaporgy)>>MAPBLOCKSHIFT;
|
||||
yh = (unsigned)(globalsmuggle.eggboxy + globalsmuggle.distancetocheck - bmaporgy)>>MAPBLOCKSHIFT;
|
||||
xl = (unsigned)(g_eggboxSearch.eggboxx - g_eggboxSearch.distancetocheck - bmaporgx)>>MAPBLOCKSHIFT;
|
||||
xh = (unsigned)(g_eggboxSearch.eggboxx + g_eggboxSearch.distancetocheck - bmaporgx)>>MAPBLOCKSHIFT;
|
||||
yl = (unsigned)(g_eggboxSearch.eggboxy - g_eggboxSearch.distancetocheck - bmaporgy)>>MAPBLOCKSHIFT;
|
||||
yh = (unsigned)(g_eggboxSearch.eggboxy + g_eggboxSearch.distancetocheck - bmaporgy)>>MAPBLOCKSHIFT;
|
||||
|
||||
BMBOUNDFIX(xl, xh, yl, yh);
|
||||
|
||||
|
|
@ -126,7 +112,7 @@ UINT8 K_EggboxStealth(fixed_t x, fixed_t y)
|
|||
}
|
||||
}
|
||||
|
||||
return (globalsmuggle.randomitems * (globalsmuggle.eggboxes + 1));
|
||||
return (g_eggboxSearch.randomitems * (g_eggboxSearch.eggboxes + 1));
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
|
|
@ -269,6 +255,19 @@ boolean K_BotHatesThisSector(player_t *player, sector_t *sec, fixed_t x, fixed_t
|
|||
Return:-
|
||||
None
|
||||
--------------------------------------------------*/
|
||||
static struct nudgeSearch_s
|
||||
{
|
||||
mobj_t *botmo;
|
||||
angle_t angle;
|
||||
fixed_t distancetocheck;
|
||||
|
||||
INT64 gotoAvgX[2], gotoAvgY[2];
|
||||
UINT32 gotoObjs[2];
|
||||
|
||||
INT64 avoidAvgX[2], avoidAvgY[2];
|
||||
UINT32 avoidObjs[2];
|
||||
} g_nudgeSearch;
|
||||
|
||||
static void K_AddAttackObject(mobj_t *thing, UINT8 side, UINT8 weight)
|
||||
{
|
||||
fixed_t x, y;
|
||||
|
|
@ -284,7 +283,7 @@ static void K_AddAttackObject(mobj_t *thing, UINT8 side, UINT8 weight)
|
|||
|
||||
x = thing->x;
|
||||
y = thing->y;
|
||||
a = R_PointToAngle2(globalsmuggle.botmo->x, globalsmuggle.botmo->y, x, y);
|
||||
a = R_PointToAngle2(g_nudgeSearch.botmo->x, g_nudgeSearch.botmo->y, x, y);
|
||||
|
||||
dir = a + (side ? -ANGLE_90 : ANGLE_90);
|
||||
x += FixedMul(thing->radius, FINECOSINE(dir >> ANGLETOFINESHIFT));
|
||||
|
|
@ -295,9 +294,9 @@ static void K_AddAttackObject(mobj_t *thing, UINT8 side, UINT8 weight)
|
|||
|
||||
for (i = 0; i < weight; i++)
|
||||
{
|
||||
globalsmuggle.gotoAvgX[side] += x;
|
||||
globalsmuggle.gotoAvgY[side] += y;
|
||||
globalsmuggle.gotoObjs[side]++;
|
||||
g_nudgeSearch.gotoAvgX[side] += x;
|
||||
g_nudgeSearch.gotoAvgY[side] += y;
|
||||
g_nudgeSearch.gotoObjs[side]++;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -329,7 +328,7 @@ static void K_AddDodgeObject(mobj_t *thing, UINT8 side, UINT8 weight)
|
|||
|
||||
x = thing->x;
|
||||
y = thing->y;
|
||||
a = R_PointToAngle2(globalsmuggle.botmo->x, globalsmuggle.botmo->y, x, y);
|
||||
a = R_PointToAngle2(g_nudgeSearch.botmo->x, g_nudgeSearch.botmo->y, x, y);
|
||||
|
||||
dir = a + (side ? -ANGLE_90 : ANGLE_90);
|
||||
x += FixedMul(thing->radius, FINECOSINE(dir >> ANGLETOFINESHIFT));
|
||||
|
|
@ -340,9 +339,9 @@ static void K_AddDodgeObject(mobj_t *thing, UINT8 side, UINT8 weight)
|
|||
|
||||
for (i = 0; i < weight; i++)
|
||||
{
|
||||
globalsmuggle.avoidAvgX[side] += x;
|
||||
globalsmuggle.avoidAvgY[side] += y;
|
||||
globalsmuggle.avoidObjs[side]++;
|
||||
g_nudgeSearch.avoidAvgX[side] += x;
|
||||
g_nudgeSearch.avoidAvgY[side] += y;
|
||||
g_nudgeSearch.avoidObjs[side]++;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -394,10 +393,10 @@ static BlockItReturn_t K_FindObjectsForNudging(mobj_t *thing)
|
|||
{
|
||||
INT16 angledelta, anglediff;
|
||||
fixed_t fulldist;
|
||||
angle_t destangle, angle, predictangle;
|
||||
angle_t destangle, angle;
|
||||
UINT8 side = 0;
|
||||
|
||||
if (!globalsmuggle.botmo || P_MobjWasRemoved(globalsmuggle.botmo) || !globalsmuggle.botmo->player)
|
||||
if (!g_nudgeSearch.botmo || P_MobjWasRemoved(g_nudgeSearch.botmo) || !g_nudgeSearch.botmo->player)
|
||||
{
|
||||
return BMIT_ABORT;
|
||||
}
|
||||
|
|
@ -407,26 +406,25 @@ static BlockItReturn_t K_FindObjectsForNudging(mobj_t *thing)
|
|||
return BMIT_CONTINUE;
|
||||
}
|
||||
|
||||
if (globalsmuggle.botmo == thing)
|
||||
if (g_nudgeSearch.botmo == thing)
|
||||
{
|
||||
return BMIT_CONTINUE;
|
||||
}
|
||||
|
||||
fulldist = R_PointToDist2(globalsmuggle.botmo->x, globalsmuggle.botmo->y, thing->x, thing->y) - thing->radius;
|
||||
fulldist = R_PointToDist2(g_nudgeSearch.botmo->x, g_nudgeSearch.botmo->y, thing->x, thing->y) - thing->radius;
|
||||
|
||||
if (fulldist > globalsmuggle.distancetocheck)
|
||||
if (fulldist > g_nudgeSearch.distancetocheck)
|
||||
{
|
||||
return BMIT_CONTINUE;
|
||||
}
|
||||
|
||||
if (P_CheckSight(globalsmuggle.botmo, thing) == false)
|
||||
if (P_CheckSight(g_nudgeSearch.botmo, thing) == false)
|
||||
{
|
||||
return BMIT_CONTINUE;
|
||||
}
|
||||
|
||||
predictangle = R_PointToAngle2(globalsmuggle.botmo->x, globalsmuggle.botmo->y, globalsmuggle.predict->x, globalsmuggle.predict->y);
|
||||
destangle = R_PointToAngle2(globalsmuggle.botmo->x, globalsmuggle.botmo->y, thing->x, thing->y);
|
||||
angle = (predictangle - destangle);
|
||||
destangle = R_PointToAngle2(g_nudgeSearch.botmo->x, g_nudgeSearch.botmo->y, thing->x, thing->y);
|
||||
angle = (g_nudgeSearch.angle - destangle);
|
||||
|
||||
if (angle < ANGLE_180)
|
||||
{
|
||||
|
|
@ -462,7 +460,7 @@ static BlockItReturn_t K_FindObjectsForNudging(mobj_t *thing)
|
|||
K_AddDodgeObject(thing, side, 20);
|
||||
break;
|
||||
case MT_SHRINK_GUN:
|
||||
if (thing->target == globalsmuggle.botmo)
|
||||
if (thing->target == g_nudgeSearch.botmo)
|
||||
{
|
||||
K_AddAttackObject(thing, side, 20);
|
||||
}
|
||||
|
|
@ -477,7 +475,7 @@ static BlockItReturn_t K_FindObjectsForNudging(mobj_t *thing)
|
|||
break;
|
||||
}
|
||||
|
||||
if (P_CanPickupItem(globalsmuggle.botmo->player, 1))
|
||||
if (P_CanPickupItem(g_nudgeSearch.botmo->player, 1))
|
||||
{
|
||||
K_AddAttackObject(thing, side, 10);
|
||||
}
|
||||
|
|
@ -488,10 +486,10 @@ static BlockItReturn_t K_FindObjectsForNudging(mobj_t *thing)
|
|||
break;
|
||||
}
|
||||
|
||||
if (P_CanPickupItem(globalsmuggle.botmo->player, 1)) // Can pick up an actual item
|
||||
if (P_CanPickupItem(g_nudgeSearch.botmo->player, 1)) // Can pick up an actual item
|
||||
{
|
||||
const UINT8 stealth = K_EggboxStealth(thing->x, thing->y);
|
||||
const UINT8 requiredstealth = (globalsmuggle.botmo->player->botvars.difficulty * globalsmuggle.botmo->player->botvars.difficulty);
|
||||
const UINT8 requiredstealth = (g_nudgeSearch.botmo->player->botvars.difficulty * g_nudgeSearch.botmo->player->botvars.difficulty);
|
||||
|
||||
if (stealth >= requiredstealth)
|
||||
{
|
||||
|
|
@ -509,7 +507,7 @@ static BlockItReturn_t K_FindObjectsForNudging(mobj_t *thing)
|
|||
break;
|
||||
}
|
||||
|
||||
if (P_CanPickupItem(globalsmuggle.botmo->player, 3))
|
||||
if (P_CanPickupItem(g_nudgeSearch.botmo->player, 3))
|
||||
{
|
||||
K_AddAttackObject(thing, side, 20);
|
||||
}
|
||||
|
|
@ -521,31 +519,31 @@ static BlockItReturn_t K_FindObjectsForNudging(mobj_t *thing)
|
|||
break;
|
||||
}
|
||||
|
||||
if ((RINGTOTAL(globalsmuggle.botmo->player) < 20 && !(globalsmuggle.botmo->player->pflags & PF_RINGLOCK)
|
||||
&& P_CanPickupItem(globalsmuggle.botmo->player, 0))
|
||||
if ((RINGTOTAL(g_nudgeSearch.botmo->player) < 20 && !(g_nudgeSearch.botmo->player->pflags & PF_RINGLOCK)
|
||||
&& P_CanPickupItem(g_nudgeSearch.botmo->player, 0))
|
||||
&& !thing->extravalue1
|
||||
&& (globalsmuggle.botmo->player->itemtype != KITEM_LIGHTNINGSHIELD))
|
||||
&& (g_nudgeSearch.botmo->player->itemtype != KITEM_LIGHTNINGSHIELD))
|
||||
{
|
||||
K_AddAttackObject(thing, side, (RINGTOTAL(globalsmuggle.botmo->player) < 3) ? 5 : 1);
|
||||
K_AddAttackObject(thing, side, (RINGTOTAL(g_nudgeSearch.botmo->player) < 3) ? 5 : 1);
|
||||
}
|
||||
break;
|
||||
case MT_PLAYER:
|
||||
if (thing->player
|
||||
&& !thing->player->hyudorotimer
|
||||
&& !globalsmuggle.botmo->player->hyudorotimer)
|
||||
&& !g_nudgeSearch.botmo->player->hyudorotimer)
|
||||
{
|
||||
// There REALLY ought to be a better way to handle this logic, right?!
|
||||
// Squishing
|
||||
if (K_PlayerAttackSteer(thing, side, 20,
|
||||
K_IsBigger(globalsmuggle.botmo, thing),
|
||||
K_IsBigger(thing, globalsmuggle.botmo)
|
||||
K_IsBigger(g_nudgeSearch.botmo, thing),
|
||||
K_IsBigger(thing, g_nudgeSearch.botmo)
|
||||
))
|
||||
{
|
||||
break;
|
||||
}
|
||||
// Invincibility
|
||||
else if (K_PlayerAttackSteer(thing, side, 20,
|
||||
globalsmuggle.botmo->player->invincibilitytimer,
|
||||
g_nudgeSearch.botmo->player->invincibilitytimer,
|
||||
thing->player->invincibilitytimer
|
||||
))
|
||||
{
|
||||
|
|
@ -553,7 +551,7 @@ static BlockItReturn_t K_FindObjectsForNudging(mobj_t *thing)
|
|||
}
|
||||
// Lightning Shield
|
||||
else if (K_PlayerAttackSteer(thing, side, 20,
|
||||
globalsmuggle.botmo->player->itemtype == KITEM_LIGHTNINGSHIELD,
|
||||
g_nudgeSearch.botmo->player->itemtype == KITEM_LIGHTNINGSHIELD,
|
||||
thing->player->itemtype == KITEM_LIGHTNINGSHIELD
|
||||
))
|
||||
{
|
||||
|
|
@ -561,7 +559,7 @@ static BlockItReturn_t K_FindObjectsForNudging(mobj_t *thing)
|
|||
}
|
||||
// Bubble Shield
|
||||
else if (K_PlayerAttackSteer(thing, side, 20,
|
||||
globalsmuggle.botmo->player->itemtype == KITEM_BUBBLESHIELD,
|
||||
g_nudgeSearch.botmo->player->itemtype == KITEM_BUBBLESHIELD,
|
||||
thing->player->itemtype == KITEM_BUBBLESHIELD
|
||||
))
|
||||
{
|
||||
|
|
@ -569,7 +567,7 @@ static BlockItReturn_t K_FindObjectsForNudging(mobj_t *thing)
|
|||
}
|
||||
// Flame Shield
|
||||
else if (K_PlayerAttackSteer(thing, side, 20,
|
||||
globalsmuggle.botmo->player->itemtype == KITEM_FLAMESHIELD,
|
||||
g_nudgeSearch.botmo->player->itemtype == KITEM_FLAMESHIELD,
|
||||
thing->player->itemtype == KITEM_FLAMESHIELD
|
||||
))
|
||||
{
|
||||
|
|
@ -578,7 +576,7 @@ static BlockItReturn_t K_FindObjectsForNudging(mobj_t *thing)
|
|||
// Has held item shield
|
||||
else if (K_PlayerAttackSteer(thing, side, 20,
|
||||
(thing->player->pflags & (PF_ITEMOUT|PF_EGGMANOUT)),
|
||||
(globalsmuggle.botmo->player->pflags & (PF_ITEMOUT|PF_EGGMANOUT))
|
||||
(g_nudgeSearch.botmo->player->pflags & (PF_ITEMOUT|PF_EGGMANOUT))
|
||||
))
|
||||
{
|
||||
break;
|
||||
|
|
@ -586,7 +584,7 @@ static BlockItReturn_t K_FindObjectsForNudging(mobj_t *thing)
|
|||
// Ring Sting
|
||||
else if (K_PlayerAttackSteer(thing, side, 20,
|
||||
thing->player->rings <= 0,
|
||||
globalsmuggle.botmo->player->rings <= 0
|
||||
g_nudgeSearch.botmo->player->rings <= 0
|
||||
))
|
||||
{
|
||||
break;
|
||||
|
|
@ -594,8 +592,8 @@ static BlockItReturn_t K_FindObjectsForNudging(mobj_t *thing)
|
|||
else
|
||||
{
|
||||
// After ALL of that, we can do standard bumping
|
||||
fixed_t ourweight = K_GetMobjWeight(globalsmuggle.botmo, thing);
|
||||
fixed_t theirweight = K_GetMobjWeight(thing, globalsmuggle.botmo);
|
||||
fixed_t ourweight = K_GetMobjWeight(g_nudgeSearch.botmo, thing);
|
||||
fixed_t theirweight = K_GetMobjWeight(thing, g_nudgeSearch.botmo);
|
||||
fixed_t weightdiff = 0;
|
||||
|
||||
if (anglediff >= 90)
|
||||
|
|
@ -699,25 +697,25 @@ void K_NudgePredictionTowardsObjects(botprediction_t *predict, player_t *player)
|
|||
radToPredict = distToPredict >> 1;
|
||||
angleToPredict = R_PointToAngle2(player->mo->x, player->mo->y, predict->x, predict->y);
|
||||
|
||||
globalsmuggle.distancetocheck = distToPredict;
|
||||
g_nudgeSearch.distancetocheck = distToPredict;
|
||||
|
||||
baseNudge = predict->baseRadius >> 3;
|
||||
maxNudge = predict->baseRadius - baseNudge;
|
||||
|
||||
globalsmuggle.botmo = player->mo;
|
||||
globalsmuggle.predict = predict;
|
||||
g_nudgeSearch.botmo = player->mo;
|
||||
g_nudgeSearch.angle = angleToPredict;
|
||||
|
||||
// silly variable reuse
|
||||
avgX = globalsmuggle.botmo->x + FixedMul(radToPredict, FINECOSINE(angleToPredict >> ANGLETOFINESHIFT));
|
||||
avgY = globalsmuggle.botmo->y + FixedMul(radToPredict, FINESINE(angleToPredict >> ANGLETOFINESHIFT));
|
||||
avgX = g_nudgeSearch.botmo->x + FixedMul(radToPredict, FINECOSINE(angleToPredict >> ANGLETOFINESHIFT));
|
||||
avgY = g_nudgeSearch.botmo->y + FixedMul(radToPredict, FINESINE(angleToPredict >> ANGLETOFINESHIFT));
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
globalsmuggle.gotoAvgX[i] = globalsmuggle.gotoAvgY[i] = 0;
|
||||
globalsmuggle.gotoObjs[i] = 0;
|
||||
g_nudgeSearch.gotoAvgX[i] = g_nudgeSearch.gotoAvgY[i] = 0;
|
||||
g_nudgeSearch.gotoObjs[i] = 0;
|
||||
|
||||
globalsmuggle.avoidAvgX[i] = globalsmuggle.avoidAvgY[i] = 0;
|
||||
globalsmuggle.avoidObjs[i] = 0;
|
||||
g_nudgeSearch.avoidAvgX[i] = g_nudgeSearch.avoidAvgY[i] = 0;
|
||||
g_nudgeSearch.avoidObjs[i] = 0;
|
||||
}
|
||||
|
||||
xl = (unsigned)(avgX - (distToPredict + MAXRADIUS) - bmaporgx)>>MAPBLOCKSHIFT;
|
||||
|
|
@ -736,9 +734,9 @@ void K_NudgePredictionTowardsObjects(botprediction_t *predict, player_t *player)
|
|||
}
|
||||
|
||||
// Handle dodge characters
|
||||
if (globalsmuggle.avoidObjs[1] > 0 || globalsmuggle.avoidObjs[0] > 0)
|
||||
if (g_nudgeSearch.avoidObjs[1] > 0 || g_nudgeSearch.avoidObjs[0] > 0)
|
||||
{
|
||||
if (globalsmuggle.avoidObjs[1] > globalsmuggle.avoidObjs[0])
|
||||
if (g_nudgeSearch.avoidObjs[1] > g_nudgeSearch.avoidObjs[0])
|
||||
{
|
||||
gotoSide = 1;
|
||||
}
|
||||
|
|
@ -747,8 +745,8 @@ void K_NudgePredictionTowardsObjects(botprediction_t *predict, player_t *player)
|
|||
gotoSide = 0;
|
||||
}
|
||||
|
||||
avgX = (globalsmuggle.avoidAvgX[gotoSide] / globalsmuggle.avoidObjs[gotoSide]) * mapobjectscale;
|
||||
avgY = (globalsmuggle.avoidAvgY[gotoSide] / globalsmuggle.avoidObjs[gotoSide]) * mapobjectscale;
|
||||
avgX = (g_nudgeSearch.avoidAvgX[gotoSide] / g_nudgeSearch.avoidObjs[gotoSide]) * mapobjectscale;
|
||||
avgY = (g_nudgeSearch.avoidAvgY[gotoSide] / g_nudgeSearch.avoidObjs[gotoSide]) * mapobjectscale;
|
||||
|
||||
avgDist = R_PointToDist2(
|
||||
avgX, avgY,
|
||||
|
|
@ -756,7 +754,7 @@ void K_NudgePredictionTowardsObjects(botprediction_t *predict, player_t *player)
|
|||
);
|
||||
|
||||
// High handling characters dodge better
|
||||
nudgeDist = ((9 - globalsmuggle.botmo->player->kartweight) + 1) * baseNudge;
|
||||
nudgeDist = ((9 - g_nudgeSearch.botmo->player->kartweight) + 1) * baseNudge;
|
||||
if (nudgeDist > maxNudge)
|
||||
{
|
||||
nudgeDist = maxNudge;
|
||||
|
|
@ -791,7 +789,7 @@ void K_NudgePredictionTowardsObjects(botprediction_t *predict, player_t *player)
|
|||
// We don't want to pick contradictory sides, so keep the old side otherwise,
|
||||
// even if there's more to grab on the other side.
|
||||
|
||||
if (globalsmuggle.gotoObjs[1] > globalsmuggle.gotoObjs[0])
|
||||
if (g_nudgeSearch.gotoObjs[1] > g_nudgeSearch.gotoObjs[0])
|
||||
{
|
||||
gotoSide = 1;
|
||||
}
|
||||
|
|
@ -802,7 +800,7 @@ void K_NudgePredictionTowardsObjects(botprediction_t *predict, player_t *player)
|
|||
}
|
||||
|
||||
// Check if our side is invalid, if so, don't do the code below.
|
||||
if (gotoSide != -1 && globalsmuggle.gotoObjs[gotoSide] == 0)
|
||||
if (gotoSide != -1 && g_nudgeSearch.gotoObjs[gotoSide] == 0)
|
||||
{
|
||||
// Do not use a side
|
||||
gotoSide = -1;
|
||||
|
|
@ -810,8 +808,8 @@ void K_NudgePredictionTowardsObjects(botprediction_t *predict, player_t *player)
|
|||
|
||||
if (gotoSide != -1)
|
||||
{
|
||||
avgX = (globalsmuggle.gotoAvgX[gotoSide] / globalsmuggle.gotoObjs[gotoSide]) * mapobjectscale;
|
||||
avgY = (globalsmuggle.gotoAvgY[gotoSide] / globalsmuggle.gotoObjs[gotoSide]) * mapobjectscale;
|
||||
avgX = (g_nudgeSearch.gotoAvgX[gotoSide] / g_nudgeSearch.gotoObjs[gotoSide]) * mapobjectscale;
|
||||
avgY = (g_nudgeSearch.gotoAvgY[gotoSide] / g_nudgeSearch.gotoObjs[gotoSide]) * mapobjectscale;
|
||||
|
||||
avgDist = R_PointToDist2(
|
||||
predict->x, predict->y,
|
||||
|
|
@ -819,7 +817,7 @@ void K_NudgePredictionTowardsObjects(botprediction_t *predict, player_t *player)
|
|||
);
|
||||
|
||||
// Acceleration characters are more aggressive
|
||||
nudgeDist = ((9 - globalsmuggle.botmo->player->kartspeed) + 1) * baseNudge;
|
||||
nudgeDist = ((9 - g_nudgeSearch.botmo->player->kartspeed) + 1) * baseNudge;
|
||||
if (nudgeDist > maxNudge)
|
||||
{
|
||||
nudgeDist = maxNudge;
|
||||
|
|
@ -862,6 +860,15 @@ void K_NudgePredictionTowardsObjects(botprediction_t *predict, player_t *player)
|
|||
Return:-
|
||||
BlockItReturn_t enum, see its definition for more information.
|
||||
--------------------------------------------------*/
|
||||
static struct bullySearch_s
|
||||
{
|
||||
mobj_t *botmo;
|
||||
fixed_t distancetocheck;
|
||||
|
||||
fixed_t annoyscore;
|
||||
mobj_t *annoymo;
|
||||
} g_bullySearch;
|
||||
|
||||
static BlockItReturn_t K_FindPlayersToBully(mobj_t *thing)
|
||||
{
|
||||
INT16 anglediff;
|
||||
|
|
@ -869,7 +876,7 @@ static BlockItReturn_t K_FindPlayersToBully(mobj_t *thing)
|
|||
fixed_t ourweight, theirweight, weightdiff;
|
||||
angle_t ourangle, destangle, angle;
|
||||
|
||||
if (!globalsmuggle.botmo || P_MobjWasRemoved(globalsmuggle.botmo) || !globalsmuggle.botmo->player)
|
||||
if (!g_bullySearch.botmo || P_MobjWasRemoved(g_bullySearch.botmo) || !g_bullySearch.botmo->player)
|
||||
{
|
||||
return BMIT_ABORT;
|
||||
}
|
||||
|
|
@ -884,25 +891,25 @@ static BlockItReturn_t K_FindPlayersToBully(mobj_t *thing)
|
|||
return BMIT_CONTINUE;
|
||||
}
|
||||
|
||||
if (globalsmuggle.botmo == thing)
|
||||
if (g_bullySearch.botmo == thing)
|
||||
{
|
||||
return BMIT_CONTINUE;
|
||||
}
|
||||
|
||||
fulldist = R_PointToDist2(globalsmuggle.botmo->x, globalsmuggle.botmo->y, thing->x, thing->y) - thing->radius;
|
||||
fulldist = R_PointToDist2(g_bullySearch.botmo->x, g_bullySearch.botmo->y, thing->x, thing->y) - thing->radius;
|
||||
|
||||
if (fulldist > globalsmuggle.distancetocheck)
|
||||
if (fulldist > g_bullySearch.distancetocheck)
|
||||
{
|
||||
return BMIT_CONTINUE;
|
||||
}
|
||||
|
||||
if (P_CheckSight(globalsmuggle.botmo, thing) == false)
|
||||
if (P_CheckSight(g_bullySearch.botmo, thing) == false)
|
||||
{
|
||||
return BMIT_CONTINUE;
|
||||
}
|
||||
|
||||
ourangle = globalsmuggle.botmo->angle;
|
||||
destangle = R_PointToAngle2(globalsmuggle.botmo->x, globalsmuggle.botmo->y, thing->x, thing->y);
|
||||
ourangle = g_bullySearch.botmo->angle;
|
||||
destangle = R_PointToAngle2(g_bullySearch.botmo->x, g_bullySearch.botmo->y, thing->x, thing->y);
|
||||
angle = (ourangle - destangle);
|
||||
|
||||
if (angle < ANGLE_180)
|
||||
|
|
@ -916,8 +923,8 @@ static BlockItReturn_t K_FindPlayersToBully(mobj_t *thing)
|
|||
|
||||
anglediff = abs(anglediff);
|
||||
|
||||
ourweight = K_GetMobjWeight(globalsmuggle.botmo, thing);
|
||||
theirweight = K_GetMobjWeight(thing, globalsmuggle.botmo);
|
||||
ourweight = K_GetMobjWeight(g_bullySearch.botmo, thing);
|
||||
theirweight = K_GetMobjWeight(thing, g_bullySearch.botmo);
|
||||
weightdiff = 0;
|
||||
|
||||
if (anglediff >= 90)
|
||||
|
|
@ -929,10 +936,10 @@ static BlockItReturn_t K_FindPlayersToBully(mobj_t *thing)
|
|||
weightdiff = ourweight - theirweight;
|
||||
}
|
||||
|
||||
if (weightdiff > mapobjectscale && weightdiff > globalsmuggle.annoyscore)
|
||||
if (weightdiff > mapobjectscale && weightdiff > g_bullySearch.annoyscore)
|
||||
{
|
||||
globalsmuggle.annoyscore = weightdiff;
|
||||
globalsmuggle.annoymo = thing;
|
||||
g_bullySearch.annoyscore = weightdiff;
|
||||
g_bullySearch.annoymo = thing;
|
||||
}
|
||||
|
||||
return BMIT_CONTINUE;
|
||||
|
|
@ -950,16 +957,16 @@ INT32 K_PositionBully(player_t *player)
|
|||
angle_t ourangle, destangle, angle;
|
||||
INT16 anglediff;
|
||||
|
||||
globalsmuggle.botmo = player->mo;
|
||||
globalsmuggle.distancetocheck = 1024*player->mo->scale;
|
||||
g_bullySearch.botmo = player->mo;
|
||||
g_bullySearch.distancetocheck = 1024*player->mo->scale;
|
||||
|
||||
globalsmuggle.annoymo = NULL;
|
||||
globalsmuggle.annoyscore = 0;
|
||||
g_bullySearch.annoymo = NULL;
|
||||
g_bullySearch.annoyscore = 0;
|
||||
|
||||
xl = (unsigned)(globalsmuggle.botmo->x - globalsmuggle.distancetocheck - bmaporgx)>>MAPBLOCKSHIFT;
|
||||
xh = (unsigned)(globalsmuggle.botmo->x + globalsmuggle.distancetocheck - bmaporgx)>>MAPBLOCKSHIFT;
|
||||
yl = (unsigned)(globalsmuggle.botmo->y - globalsmuggle.distancetocheck - bmaporgy)>>MAPBLOCKSHIFT;
|
||||
yh = (unsigned)(globalsmuggle.botmo->y + globalsmuggle.distancetocheck - bmaporgy)>>MAPBLOCKSHIFT;
|
||||
xl = (unsigned)(g_bullySearch.botmo->x - g_bullySearch.distancetocheck - bmaporgx)>>MAPBLOCKSHIFT;
|
||||
xh = (unsigned)(g_bullySearch.botmo->x + g_bullySearch.distancetocheck - bmaporgx)>>MAPBLOCKSHIFT;
|
||||
yl = (unsigned)(g_bullySearch.botmo->y - g_bullySearch.distancetocheck - bmaporgy)>>MAPBLOCKSHIFT;
|
||||
yh = (unsigned)(g_bullySearch.botmo->y + g_bullySearch.distancetocheck - bmaporgy)>>MAPBLOCKSHIFT;
|
||||
|
||||
BMBOUNDFIX(xl, xh, yl, yh);
|
||||
|
||||
|
|
@ -971,13 +978,13 @@ INT32 K_PositionBully(player_t *player)
|
|||
}
|
||||
}
|
||||
|
||||
if (globalsmuggle.annoymo == NULL)
|
||||
if (g_bullySearch.annoymo == NULL)
|
||||
{
|
||||
return INT32_MAX;
|
||||
}
|
||||
|
||||
ourangle = globalsmuggle.botmo->angle;
|
||||
destangle = R_PointToAngle2(globalsmuggle.botmo->x, globalsmuggle.botmo->y, globalsmuggle.annoymo->x, globalsmuggle.annoymo->y);
|
||||
ourangle = g_bullySearch.botmo->angle;
|
||||
destangle = R_PointToAngle2(g_bullySearch.botmo->x, g_bullySearch.botmo->y, g_bullySearch.annoymo->x, g_bullySearch.annoymo->y);
|
||||
angle = (ourangle - destangle);
|
||||
|
||||
if (angle < ANGLE_180)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue