mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Better steering
- If they're already turning in one direction, they are more likely to steer in that direction for objects - Bots have to want to turn in 1 direction for a few frames in a row before it'll let them Prevents twitching & makes them less indecisive in general
This commit is contained in:
parent
ca7154f521
commit
edfc14c506
6 changed files with 95 additions and 41 deletions
|
|
@ -650,7 +650,7 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i)
|
||||||
rsp->bot_difficulty = players[i].botvars.difficulty;
|
rsp->bot_difficulty = players[i].botvars.difficulty;
|
||||||
rsp->bot_itemdelay = players[i].botvars.itemdelay;
|
rsp->bot_itemdelay = players[i].botvars.itemdelay;
|
||||||
rsp->bot_itemconfirm = players[i].botvars.itemconfirm;
|
rsp->bot_itemconfirm = players[i].botvars.itemconfirm;
|
||||||
rsp->bot_lastturn = players[i].botvars.lastturn;
|
rsp->bot_turnconfirm = players[i].botvars.turnconfirm;
|
||||||
|
|
||||||
rsp->hasmo = false;
|
rsp->hasmo = false;
|
||||||
//Transfer important mo information if the player has a body.
|
//Transfer important mo information if the player has a body.
|
||||||
|
|
@ -779,7 +779,7 @@ static void resynch_read_player(resynch_pak *rsp)
|
||||||
players[i].botvars.difficulty = rsp->bot_difficulty;
|
players[i].botvars.difficulty = rsp->bot_difficulty;
|
||||||
players[i].botvars.itemdelay = rsp->bot_itemdelay;
|
players[i].botvars.itemdelay = rsp->bot_itemdelay;
|
||||||
players[i].botvars.itemconfirm = rsp->bot_itemconfirm;
|
players[i].botvars.itemconfirm = rsp->bot_itemconfirm;
|
||||||
players[i].botvars.lastturn = rsp->bot_lastturn;
|
players[i].botvars.turnconfirm = rsp->bot_turnconfirm;
|
||||||
|
|
||||||
//We get a packet for each player in game.
|
//We get a packet for each player in game.
|
||||||
if (!playeringame[i])
|
if (!playeringame[i])
|
||||||
|
|
|
||||||
|
|
@ -289,7 +289,7 @@ typedef struct
|
||||||
UINT8 bot_difficulty;
|
UINT8 bot_difficulty;
|
||||||
tic_t bot_itemdelay;
|
tic_t bot_itemdelay;
|
||||||
tic_t bot_itemconfirm;
|
tic_t bot_itemconfirm;
|
||||||
INT16 bot_lastturn;
|
SINT8 bot_turnconfirm;
|
||||||
|
|
||||||
//player->mo stuff
|
//player->mo stuff
|
||||||
UINT8 hasmo; // Boolean
|
UINT8 hasmo; // Boolean
|
||||||
|
|
|
||||||
|
|
@ -428,7 +428,7 @@ typedef struct botvars_s
|
||||||
tic_t itemdelay;
|
tic_t itemdelay;
|
||||||
tic_t itemconfirm;
|
tic_t itemconfirm;
|
||||||
|
|
||||||
INT16 lastturn;
|
SINT8 turnconfirm;
|
||||||
} botvars_t;
|
} botvars_t;
|
||||||
|
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
|
|
|
||||||
123
src/k_bot.c
123
src/k_bot.c
|
|
@ -410,6 +410,7 @@ fixed_t distancetocheck = 0;
|
||||||
|
|
||||||
fixed_t closestlinedist = INT32_MAX;
|
fixed_t closestlinedist = INT32_MAX;
|
||||||
|
|
||||||
|
INT16 curturn = 0;
|
||||||
INT16 badsteerglobal = 0;
|
INT16 badsteerglobal = 0;
|
||||||
|
|
||||||
fixed_t eggboxx, eggboxy;
|
fixed_t eggboxx, eggboxy;
|
||||||
|
|
@ -761,30 +762,60 @@ static void K_SteerFromObject(mobj_t *bot, mobj_t *thing, fixed_t fulldist, fixe
|
||||||
{
|
{
|
||||||
angle_t destangle = R_PointToAngle2(bot->x, bot->y, thing->x, thing->y);
|
angle_t destangle = R_PointToAngle2(bot->x, bot->y, thing->x, thing->y);
|
||||||
angle_t angle;
|
angle_t angle;
|
||||||
|
SINT8 flip = 1;
|
||||||
|
|
||||||
amount = (amount * FixedDiv(distancetocheck - fulldist, distancetocheck)) / FRACUNIT;
|
amount = (amount * FixedDiv(distancetocheck - fulldist, distancetocheck)) / FRACUNIT;
|
||||||
|
|
||||||
if (towards)
|
if (amount == 0)
|
||||||
{
|
{
|
||||||
if (xdist < (bot->radius + thing->radius))
|
// Shouldn't happen
|
||||||
{
|
|
||||||
// Don't need to turn any harder!
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
amount = -amount;
|
if (towards)
|
||||||
}
|
|
||||||
|
|
||||||
angle = (bot->angle - destangle);
|
|
||||||
|
|
||||||
if (angle < ANGLE_180)
|
|
||||||
{
|
{
|
||||||
badsteerglobal -= amount;
|
if (xdist < FixedHypot(bot->radius, thing->radius))
|
||||||
|
{
|
||||||
|
// Don't need to turn any harder!
|
||||||
|
|
||||||
|
if (abs(badsteerglobal) <= amount)
|
||||||
|
{
|
||||||
|
badsteerglobal = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
if (badsteerglobal > 0)
|
||||||
|
{
|
||||||
|
badsteerglobal -= amount;
|
||||||
|
}
|
||||||
|
else if (badsteerglobal < 0)
|
||||||
{
|
{
|
||||||
badsteerglobal += amount;
|
badsteerglobal += amount;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Still turning towards it, flip.
|
||||||
|
flip = -flip;
|
||||||
|
}
|
||||||
|
|
||||||
|
angle = (bot->angle - destangle);
|
||||||
|
if (angle < ANGLE_180)
|
||||||
|
{
|
||||||
|
flip = -flip;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If going in the opposite direction of where you wanted to turn,
|
||||||
|
// then reduce the amount that you can turn in that direction.
|
||||||
|
if ((flip == 1 && curturn < 0)
|
||||||
|
|| (flip == -1 && curturn > 0))
|
||||||
|
{
|
||||||
|
amount /= 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
badsteerglobal += amount * flip;
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean K_BotSteerObjects(mobj_t *thing)
|
static boolean K_BotSteerObjects(mobj_t *thing)
|
||||||
|
|
@ -876,7 +907,7 @@ static boolean K_BotSteerObjects(mobj_t *thing)
|
||||||
K_SteerFromObject(botmo, thing, fulldist, xdist, false, 2 * (KART_FULLTURN + dodge));
|
K_SteerFromObject(botmo, thing, fulldist, xdist, false, 2 * (KART_FULLTURN + dodge));
|
||||||
break;
|
break;
|
||||||
case MT_RANDOMITEM:
|
case MT_RANDOMITEM:
|
||||||
if (anglediff > 90)
|
if (anglediff >= 60)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -887,7 +918,7 @@ static boolean K_BotSteerObjects(mobj_t *thing)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MT_EGGMANITEM:
|
case MT_EGGMANITEM:
|
||||||
if (anglediff > 90)
|
if (anglediff >= 60)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -908,7 +939,7 @@ static boolean K_BotSteerObjects(mobj_t *thing)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MT_FLOATINGITEM:
|
case MT_FLOATINGITEM:
|
||||||
if (anglediff > 90)
|
if (anglediff >= 60)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -920,7 +951,7 @@ static boolean K_BotSteerObjects(mobj_t *thing)
|
||||||
break;
|
break;
|
||||||
case MT_RING:
|
case MT_RING:
|
||||||
case MT_FLINGRING:
|
case MT_FLINGRING:
|
||||||
if (anglediff > 90)
|
if (anglediff >= 60)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -932,8 +963,8 @@ static boolean K_BotSteerObjects(mobj_t *thing)
|
||||||
{
|
{
|
||||||
K_SteerFromObject(botmo, thing, fulldist, xdist, true,
|
K_SteerFromObject(botmo, thing, fulldist, xdist, true,
|
||||||
(RINGTOTAL(botmo->player) < 3
|
(RINGTOTAL(botmo->player) < 3
|
||||||
? (2 * (KART_FULLTURN + attack))
|
? (4 * (KART_FULLTURN + attack))
|
||||||
: ((KART_FULLTURN + attack) / 2))
|
: (KART_FULLTURN + attack))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -985,7 +1016,7 @@ static boolean K_BotSteerObjects(mobj_t *thing)
|
||||||
fixed_t theirweight = K_GetMobjWeight(thing, botmo);
|
fixed_t theirweight = K_GetMobjWeight(thing, botmo);
|
||||||
fixed_t weightdiff = 0;
|
fixed_t weightdiff = 0;
|
||||||
|
|
||||||
if (anglediff > 90)
|
if (anglediff >= 90)
|
||||||
{
|
{
|
||||||
weightdiff = theirweight - ourweight;
|
weightdiff = theirweight - ourweight;
|
||||||
}
|
}
|
||||||
|
|
@ -1006,6 +1037,11 @@ static boolean K_BotSteerObjects(mobj_t *thing)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MT_BOTHINT:
|
case MT_BOTHINT:
|
||||||
|
if (anglediff >= 60)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (thing->extravalue1 == 0)
|
if (thing->extravalue1 == 0)
|
||||||
{
|
{
|
||||||
K_SteerFromObject(botmo, thing, fulldist, xdist, false, thing->extravalue2 * (KART_FULLTURN + dodge));
|
K_SteerFromObject(botmo, thing, fulldist, xdist, false, thing->extravalue2 * (KART_FULLTURN + dodge));
|
||||||
|
|
@ -1025,14 +1061,15 @@ static boolean K_BotSteerObjects(mobj_t *thing)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static INT16 K_BotFindObjects(player_t *player)
|
static INT16 K_BotFindObjects(player_t *player, INT16 turn)
|
||||||
{
|
{
|
||||||
INT32 xl, xh, yl, yh, bx, by;
|
INT32 xl, xh, yl, yh, bx, by;
|
||||||
|
|
||||||
badsteerglobal = 0;
|
badsteerglobal = 0;
|
||||||
|
|
||||||
botmo = player->mo;
|
botmo = player->mo;
|
||||||
distancetocheck = (player->mo->radius * 32) + (player->speed * 4);
|
curturn = turn;
|
||||||
|
distancetocheck = 2048*mapobjectscale;
|
||||||
|
|
||||||
xl = (unsigned)(botmo->x - distancetocheck - bmaporgx)>>MAPBLOCKSHIFT;
|
xl = (unsigned)(botmo->x - distancetocheck - bmaporgx)>>MAPBLOCKSHIFT;
|
||||||
xh = (unsigned)(botmo->x + distancetocheck - bmaporgx)>>MAPBLOCKSHIFT;
|
xh = (unsigned)(botmo->x + distancetocheck - bmaporgx)>>MAPBLOCKSHIFT;
|
||||||
|
|
@ -1409,11 +1446,6 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
|
||||||
cmd->forwardmove /= 2;
|
cmd->forwardmove /= 2;
|
||||||
cmd->buttons |= BT_BRAKE;
|
cmd->buttons |= BT_BRAKE;
|
||||||
}
|
}
|
||||||
else if (dirdist <= realrad)
|
|
||||||
{
|
|
||||||
// Steer towards/away from objects!
|
|
||||||
turnamt += K_BotFindObjects(player);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dirdist <= rad)
|
if (dirdist <= rad)
|
||||||
{
|
{
|
||||||
|
|
@ -1446,6 +1478,12 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
|
||||||
turnamt /= 4;
|
turnamt /= 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (anglediff < 60)
|
||||||
|
{
|
||||||
|
// Steer towards/away from objects!
|
||||||
|
turnamt += K_BotFindObjects(player, turnamt);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2169,8 +2207,6 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
|
||||||
|
|
||||||
if (turnamt != 0)
|
if (turnamt != 0)
|
||||||
{
|
{
|
||||||
const INT16 minturn = KART_FULLTURN/2;
|
|
||||||
|
|
||||||
if (turnamt > KART_FULLTURN)
|
if (turnamt > KART_FULLTURN)
|
||||||
{
|
{
|
||||||
turnamt = KART_FULLTURN;
|
turnamt = KART_FULLTURN;
|
||||||
|
|
@ -2180,26 +2216,39 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
|
||||||
turnamt = -KART_FULLTURN;
|
turnamt = -KART_FULLTURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((turnamt > minturn && player->botvars.lastturn >= 0)
|
|
||||||
|| (turnamt < -minturn && player->botvars.lastturn <= 0))
|
|
||||||
{
|
|
||||||
if (turnamt > 0)
|
if (turnamt > 0)
|
||||||
{
|
{
|
||||||
player->botvars.lastturn = 1;
|
if (player->botvars.turnconfirm < 0)
|
||||||
|
{
|
||||||
|
// Reset turn confirm
|
||||||
|
player->botvars.turnconfirm = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (player->botvars.turnconfirm < BOTTURNCONFIRM)
|
||||||
|
{
|
||||||
|
player->botvars.turnconfirm++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (turnamt < 0)
|
else if (turnamt < 0)
|
||||||
{
|
{
|
||||||
player->botvars.lastturn = -1;
|
if (player->botvars.turnconfirm > 0)
|
||||||
|
{
|
||||||
|
// Reset turn confirm
|
||||||
|
player->botvars.turnconfirm = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (player->botvars.turnconfirm > -BOTTURNCONFIRM)
|
||||||
|
{
|
||||||
|
player->botvars.turnconfirm--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (abs(player->botvars.turnconfirm) >= BOTTURNCONFIRM)
|
||||||
|
{
|
||||||
|
// You're probably commiting to your turn, here you go.
|
||||||
cmd->driftturn = turnamt;
|
cmd->driftturn = turnamt;
|
||||||
cmd->angleturn += K_GetKartTurnValue(player, turnamt);
|
cmd->angleturn += K_GetKartTurnValue(player, turnamt);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
// Can reset turn dir
|
|
||||||
player->botvars.lastturn = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (predict != NULL)
|
if (predict != NULL)
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,13 @@
|
||||||
#include "k_waypoint.h"
|
#include "k_waypoint.h"
|
||||||
#include "d_player.h"
|
#include "d_player.h"
|
||||||
|
|
||||||
|
// Maximum value of botvars.difficulty
|
||||||
#define MAXBOTDIFFICULTY 9
|
#define MAXBOTDIFFICULTY 9
|
||||||
|
|
||||||
|
// How many tics in a row do you need to turn in this direction before we'll let you turn.
|
||||||
|
// Made it as small as possible without making it look like the bots are twitching constantly.
|
||||||
|
#define BOTTURNCONFIRM 7
|
||||||
|
|
||||||
// Path that bot will attempt to take
|
// Path that bot will attempt to take
|
||||||
typedef struct botprediction_s {
|
typedef struct botprediction_s {
|
||||||
fixed_t x, y;
|
fixed_t x, y;
|
||||||
|
|
|
||||||
|
|
@ -272,7 +272,7 @@ static void P_NetArchivePlayers(void)
|
||||||
WRITEUINT8(save_p, players[i].botvars.difficulty);
|
WRITEUINT8(save_p, players[i].botvars.difficulty);
|
||||||
WRITEUINT32(save_p, players[i].botvars.itemdelay);
|
WRITEUINT32(save_p, players[i].botvars.itemdelay);
|
||||||
WRITEUINT32(save_p, players[i].botvars.itemconfirm);
|
WRITEUINT32(save_p, players[i].botvars.itemconfirm);
|
||||||
WRITEINT16(save_p, players[i].botvars.lastturn);
|
WRITESINT8(save_p, players[i].botvars.turnconfirm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -448,7 +448,7 @@ static void P_NetUnArchivePlayers(void)
|
||||||
players[i].botvars.difficulty = READUINT8(save_p);
|
players[i].botvars.difficulty = READUINT8(save_p);
|
||||||
players[i].botvars.itemdelay = READUINT32(save_p);
|
players[i].botvars.itemdelay = READUINT32(save_p);
|
||||||
players[i].botvars.itemconfirm = READUINT32(save_p);
|
players[i].botvars.itemconfirm = READUINT32(save_p);
|
||||||
players[i].botvars.lastturn = READINT16(save_p);
|
players[i].botvars.turnconfirm = READSINT8(save_p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue