mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-04-27 20:41:46 +00:00
Yet more misc polish since I can't focus on orbis
- Massive improvements to object steering -- they do it more often and more strongly - Steering towards hurtable players is now weighted on acceleration, and steering away from painful players is weighted on handling - Bots now can get & use Thunder Shield - Bots now know how to detontate Eggman Item explosions early - Top speed gets a buff to make up for them losing lots of speed without drifting, weighted more heavily towards low acceleration characters
This commit is contained in:
parent
ccc7ac8cad
commit
b983031587
4 changed files with 267 additions and 111 deletions
|
|
@ -349,6 +349,7 @@ typedef enum
|
||||||
|
|
||||||
k_botitemdelay,
|
k_botitemdelay,
|
||||||
k_botitemconfirm,
|
k_botitemconfirm,
|
||||||
|
k_botlastturn,
|
||||||
|
|
||||||
NUMKARTSTUFF
|
NUMKARTSTUFF
|
||||||
} kartstufftype_t;
|
} kartstufftype_t;
|
||||||
|
|
|
||||||
|
|
@ -8608,7 +8608,8 @@ static const char *const KARTSTUFF_LIST[] = {
|
||||||
"WRONGWAY",
|
"WRONGWAY",
|
||||||
|
|
||||||
"BOTITEMDELAY",
|
"BOTITEMDELAY",
|
||||||
"BOTITEMCONFIRM"
|
"BOTITEMCONFIRM",
|
||||||
|
"BOTLASTTURN"
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
361
src/k_bot.c
361
src/k_bot.c
|
|
@ -351,9 +351,8 @@ static INT16 K_BotSteerFromWalls(player_t *player, botprediction_t *predict)
|
||||||
return badsteerglobal;
|
return badsteerglobal;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void K_SteerFromObject(mobj_t *bot, mobj_t *thing, boolean towards, fixed_t turnmul)
|
static void K_SteerFromObject(mobj_t *bot, mobj_t *thing, boolean towards, INT16 amount)
|
||||||
{
|
{
|
||||||
INT16 amount = 3*KART_FULLTURN;
|
|
||||||
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;
|
||||||
|
|
||||||
|
|
@ -374,11 +373,6 @@ static void K_SteerFromObject(mobj_t *bot, mobj_t *thing, boolean towards, fixed
|
||||||
amount = -amount;
|
amount = -amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (turnmul != FRACUNIT)
|
|
||||||
{
|
|
||||||
amount = FixedMul(amount * FRACUNIT, turnmul) / FRACUNIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
angle = (bot->angle - destangle);
|
angle = (bot->angle - destangle);
|
||||||
|
|
||||||
if (angle < ANGLE_180)
|
if (angle < ANGLE_180)
|
||||||
|
|
@ -394,6 +388,7 @@ static void K_SteerFromObject(mobj_t *bot, mobj_t *thing, boolean towards, fixed
|
||||||
static inline boolean K_BotSteerObjects(mobj_t *thing)
|
static inline boolean K_BotSteerObjects(mobj_t *thing)
|
||||||
{
|
{
|
||||||
INT16 anglediff;
|
INT16 anglediff;
|
||||||
|
fixed_t dist;
|
||||||
angle_t destangle, angle;
|
angle_t destangle, angle;
|
||||||
|
|
||||||
if (!botmo || P_MobjWasRemoved(botmo) || !botmo->player)
|
if (!botmo || P_MobjWasRemoved(botmo) || !botmo->player)
|
||||||
|
|
@ -406,7 +401,23 @@ static inline boolean K_BotSteerObjects(mobj_t *thing)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (P_AproxDistance(botmo->x - thing->x, botmo->y - thing->y) > distancetocheck)
|
if (botmo == thing)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
dist = P_AproxDistance(P_AproxDistance(
|
||||||
|
botmo->x - thing->x,
|
||||||
|
botmo->y - thing->y),
|
||||||
|
(botmo->z - thing->z) / 4
|
||||||
|
);
|
||||||
|
|
||||||
|
if (dist > distancetocheck)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!P_CheckSight(botmo, thing))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -440,33 +451,34 @@ static inline boolean K_BotSteerObjects(mobj_t *thing)
|
||||||
case MT_SSMINE_SHIELD:
|
case MT_SSMINE_SHIELD:
|
||||||
case MT_BALLHOG:
|
case MT_BALLHOG:
|
||||||
case MT_SPB:
|
case MT_SPB:
|
||||||
K_SteerFromObject(botmo, thing, false, FRACUNIT);
|
case MT_BUBBLESHIELDTRAP:
|
||||||
|
K_SteerFromObject(botmo, thing, false, 2*KART_FULLTURN);
|
||||||
break;
|
break;
|
||||||
case MT_RANDOMITEM:
|
case MT_RANDOMITEM:
|
||||||
if (anglediff > 25)
|
if (anglediff > 90)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (P_CanPickupItem(botmo->player, 1))
|
if (P_CanPickupItem(botmo->player, 1))
|
||||||
{
|
{
|
||||||
K_SteerFromObject(botmo, thing, true, FRACUNIT);
|
K_SteerFromObject(botmo, thing, true, 2*KART_FULLTURN);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MT_FLOATINGITEM:
|
case MT_FLOATINGITEM:
|
||||||
if (anglediff > 25)
|
if (anglediff > 90)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (P_CanPickupItem(botmo->player, 3))
|
if (P_CanPickupItem(botmo->player, 3))
|
||||||
{
|
{
|
||||||
K_SteerFromObject(botmo, thing, true, FRACUNIT);
|
K_SteerFromObject(botmo, thing, true, 2*KART_FULLTURN);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MT_RING:
|
case MT_RING:
|
||||||
case MT_FLINGRING:
|
case MT_FLINGRING:
|
||||||
if (anglediff > 25)
|
if (anglediff > 90)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -475,7 +487,7 @@ static inline boolean K_BotSteerObjects(mobj_t *thing)
|
||||||
&& P_CanPickupItem(botmo->player, 0))
|
&& P_CanPickupItem(botmo->player, 0))
|
||||||
&& (!thing->extravalue1))
|
&& (!thing->extravalue1))
|
||||||
{
|
{
|
||||||
K_SteerFromObject(botmo, thing, true, FRACUNIT/3);
|
K_SteerFromObject(botmo, thing, true, (RINGTOTAL(botmo->player) <= 0 ? 2*KART_FULLTURN : KART_FULLTURN));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MT_PLAYER:
|
case MT_PLAYER:
|
||||||
|
|
@ -483,68 +495,104 @@ static inline boolean K_BotSteerObjects(mobj_t *thing)
|
||||||
&& !thing->player->kartstuff[k_hyudorotimer]
|
&& !thing->player->kartstuff[k_hyudorotimer]
|
||||||
&& !botmo->player->kartstuff[k_hyudorotimer])
|
&& !botmo->player->kartstuff[k_hyudorotimer])
|
||||||
{
|
{
|
||||||
|
INT16 attack = ((9 - botmo->player->kartspeed) * KART_FULLTURN) / 8; // Acceleration chars are more aggressive
|
||||||
|
INT16 dodge = ((9 - botmo->player->kartweight) * KART_FULLTURN) / 8; // Handling chars dodge better
|
||||||
|
|
||||||
// Squish
|
// Squish
|
||||||
if (botmo->scale > thing->scale + (mapobjectscale/8))
|
if (botmo->scale > thing->scale + (mapobjectscale/8))
|
||||||
{
|
{
|
||||||
K_SteerFromObject(botmo, thing, true, FRACUNIT);
|
K_SteerFromObject(botmo, thing, true, KART_FULLTURN + attack);
|
||||||
}
|
}
|
||||||
else if (thing->scale > botmo->scale + (mapobjectscale/8))
|
else if (thing->scale > botmo->scale + (mapobjectscale/8))
|
||||||
{
|
{
|
||||||
K_SteerFromObject(botmo, thing, false, FRACUNIT);
|
K_SteerFromObject(botmo, thing, false, KART_FULLTURN + dodge);
|
||||||
}
|
}
|
||||||
// Invincibility
|
// Invincibility
|
||||||
else if (botmo->player->kartstuff[k_invincibilitytimer] && !thing->player->kartstuff[k_invincibilitytimer])
|
else if (botmo->player->kartstuff[k_invincibilitytimer] && !thing->player->kartstuff[k_invincibilitytimer])
|
||||||
{
|
{
|
||||||
K_SteerFromObject(botmo, thing, true, FRACUNIT);
|
K_SteerFromObject(botmo, thing, true, KART_FULLTURN + attack);
|
||||||
}
|
}
|
||||||
else if (thing->player->kartstuff[k_invincibilitytimer] && !botmo->player->kartstuff[k_invincibilitytimer])
|
else if (thing->player->kartstuff[k_invincibilitytimer] && !botmo->player->kartstuff[k_invincibilitytimer])
|
||||||
{
|
{
|
||||||
K_SteerFromObject(botmo, thing, false, FRACUNIT);
|
K_SteerFromObject(botmo, thing, false, KART_FULLTURN + dodge);
|
||||||
|
}
|
||||||
|
// Thunder Shield
|
||||||
|
else if (botmo->player->kartstuff[k_itemtype] == KITEM_THUNDERSHIELD
|
||||||
|
&& thing->player->kartstuff[k_itemtype] != KITEM_THUNDERSHIELD)
|
||||||
|
{
|
||||||
|
K_SteerFromObject(botmo, thing, true, KART_FULLTURN + attack);
|
||||||
|
}
|
||||||
|
else if (thing->player->kartstuff[k_itemtype] == KITEM_THUNDERSHIELD
|
||||||
|
&& botmo->player->kartstuff[k_itemtype] != KITEM_THUNDERSHIELD)
|
||||||
|
{
|
||||||
|
K_SteerFromObject(botmo, thing, false, KART_FULLTURN + dodge);
|
||||||
|
}
|
||||||
|
// Bubble Shield
|
||||||
|
else if (botmo->player->kartstuff[k_itemtype] == KITEM_BUBBLESHIELD
|
||||||
|
&& thing->player->kartstuff[k_itemtype] != KITEM_BUBBLESHIELD)
|
||||||
|
{
|
||||||
|
K_SteerFromObject(botmo, thing, true, KART_FULLTURN + attack);
|
||||||
|
}
|
||||||
|
else if (thing->player->kartstuff[k_itemtype] == KITEM_BUBBLESHIELD
|
||||||
|
&& botmo->player->kartstuff[k_itemtype] != KITEM_BUBBLESHIELD)
|
||||||
|
{
|
||||||
|
K_SteerFromObject(botmo, thing, false, KART_FULLTURN + dodge);
|
||||||
}
|
}
|
||||||
// Flame Shield
|
// Flame Shield
|
||||||
// Not a check for Flame Shield && flame dash, because they could potentially flame dash at any time!
|
// Not a check for Flame Shield && flame dash, because they could potentially flame dash at any time!
|
||||||
else if (botmo->player->kartstuff[k_itemtype] == KITEM_FLAMESHIELD
|
else if (botmo->player->kartstuff[k_itemtype] == KITEM_FLAMESHIELD
|
||||||
&& thing->player->kartstuff[k_itemtype] != KITEM_FLAMESHIELD)
|
&& thing->player->kartstuff[k_itemtype] != KITEM_FLAMESHIELD)
|
||||||
{
|
{
|
||||||
K_SteerFromObject(botmo, thing, true, FRACUNIT);
|
K_SteerFromObject(botmo, thing, true, KART_FULLTURN + attack);
|
||||||
}
|
}
|
||||||
else if (thing->player->kartstuff[k_itemtype] == KITEM_FLAMESHIELD
|
else if (thing->player->kartstuff[k_itemtype] == KITEM_FLAMESHIELD
|
||||||
&& botmo->player->kartstuff[k_itemtype] != KITEM_FLAMESHIELD)
|
&& botmo->player->kartstuff[k_itemtype] != KITEM_FLAMESHIELD)
|
||||||
{
|
{
|
||||||
K_SteerFromObject(botmo, thing, false, FRACUNIT);
|
K_SteerFromObject(botmo, thing, false, KART_FULLTURN + dodge);
|
||||||
}
|
}
|
||||||
// Has shield item
|
// Has shield item
|
||||||
else if (botmo->player->kartstuff[k_itemheld] && !thing->player->kartstuff[k_itemheld])
|
else if (botmo->player->kartstuff[k_itemheld] && !thing->player->kartstuff[k_itemheld])
|
||||||
{
|
{
|
||||||
K_SteerFromObject(botmo, thing, true, FRACUNIT);
|
K_SteerFromObject(botmo, thing, true, KART_FULLTURN + attack);
|
||||||
}
|
}
|
||||||
else if (thing->player->kartstuff[k_itemheld] && !botmo->player->kartstuff[k_itemheld])
|
else if (thing->player->kartstuff[k_itemheld] && !botmo->player->kartstuff[k_itemheld])
|
||||||
{
|
{
|
||||||
K_SteerFromObject(botmo, thing, false, FRACUNIT);
|
K_SteerFromObject(botmo, thing, false, KART_FULLTURN + dodge);
|
||||||
}
|
}
|
||||||
// Ring Sting
|
// Ring Sting
|
||||||
else if ((thing->player->kartstuff[k_rings] <= 0)
|
else if ((thing->player->kartstuff[k_rings] <= 0)
|
||||||
&& !(botmo->player->kartstuff[k_rings] <= 0))
|
&& !(botmo->player->kartstuff[k_rings] <= 0))
|
||||||
{
|
{
|
||||||
K_SteerFromObject(botmo, thing, true, FRACUNIT);
|
K_SteerFromObject(botmo, thing, true, KART_FULLTURN + attack);
|
||||||
}
|
}
|
||||||
else if ((botmo->player->kartstuff[k_rings] <= 0)
|
else if ((botmo->player->kartstuff[k_rings] <= 0)
|
||||||
&& !(thing->player->kartstuff[k_rings] <= 0))
|
&& !(thing->player->kartstuff[k_rings] <= 0))
|
||||||
{
|
{
|
||||||
K_SteerFromObject(botmo, thing, false, FRACUNIT);
|
K_SteerFromObject(botmo, thing, false, KART_FULLTURN + dodge);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// After ALL of that, we can do standard bumping
|
// After ALL of that, we can do standard bumping
|
||||||
fixed_t weightdiff = K_GetMobjWeight(botmo, thing) - K_GetMobjWeight(thing, botmo);
|
const fixed_t ourweight = K_GetMobjWeight(botmo, thing);
|
||||||
|
const fixed_t theirweight = K_GetMobjWeight(thing, botmo);
|
||||||
|
fixed_t weightdiff = 0;
|
||||||
|
|
||||||
if (weightdiff > mapobjectscale)
|
if (anglediff > 90)
|
||||||
{
|
{
|
||||||
K_SteerFromObject(botmo, thing, true, FRACUNIT);
|
weightdiff = theirweight - ourweight;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
K_SteerFromObject(botmo, thing, false, FRACUNIT);
|
weightdiff = ourweight - theirweight;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (weightdiff > mapobjectscale)
|
||||||
|
{
|
||||||
|
K_SteerFromObject(botmo, thing, true, (KART_FULLTURN + attack) / 2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
K_SteerFromObject(botmo, thing, false, (KART_FULLTURN + dodge) * 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -552,7 +600,7 @@ static inline boolean K_BotSteerObjects(mobj_t *thing)
|
||||||
default:
|
default:
|
||||||
if (thing->flags & (MF_SOLID|MF_ENEMY|MF_BOSS|MF_PAIN|MF_MISSILE|MF_FIRE))
|
if (thing->flags & (MF_SOLID|MF_ENEMY|MF_BOSS|MF_PAIN|MF_MISSILE|MF_FIRE))
|
||||||
{
|
{
|
||||||
K_SteerFromObject(botmo, thing, false, FRACUNIT);
|
K_SteerFromObject(botmo, thing, false, 2*KART_FULLTURN);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -567,7 +615,7 @@ static INT16 K_BotFindObjects(player_t *player)
|
||||||
badsteerglobal = 0;
|
badsteerglobal = 0;
|
||||||
|
|
||||||
botmo = player->mo;
|
botmo = player->mo;
|
||||||
distancetocheck = (player->mo->radius * 8) + (player->speed * 2);
|
distancetocheck = (player->mo->radius * 16) + (player->speed * 4);
|
||||||
|
|
||||||
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;
|
||||||
|
|
@ -587,6 +635,50 @@ static INT16 K_BotFindObjects(player_t *player)
|
||||||
return badsteerglobal;
|
return badsteerglobal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static boolean K_BotUseItemNearPlayer(player_t *player, ticcmd_t *cmd, fixed_t radius)
|
||||||
|
{
|
||||||
|
UINT8 i;
|
||||||
|
|
||||||
|
if (player->pflags & PF_ATTACKDOWN)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
|
{
|
||||||
|
player_t *target = NULL;
|
||||||
|
fixed_t dist = INT32_MAX;
|
||||||
|
|
||||||
|
if (!playeringame[i])
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
target = &players[i];
|
||||||
|
|
||||||
|
if (target->mo == NULL || P_MobjWasRemoved(target->mo)
|
||||||
|
|| player == target || target->spectator
|
||||||
|
|| target->powers[pw_flashing])
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
dist = P_AproxDistance(P_AproxDistance(
|
||||||
|
player->mo->x - target->mo->x,
|
||||||
|
player->mo->y - target->mo->y),
|
||||||
|
player->mo->z - target->mo->z
|
||||||
|
);
|
||||||
|
|
||||||
|
if (dist <= radius)
|
||||||
|
{
|
||||||
|
cmd->buttons |= BT_ATTACK;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
|
void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
|
||||||
{
|
{
|
||||||
botprediction_t *predict = NULL;
|
botprediction_t *predict = NULL;
|
||||||
|
|
@ -615,7 +707,7 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
|
||||||
// Start boost handler
|
// Start boost handler
|
||||||
if (leveltime <= starttime)
|
if (leveltime <= starttime)
|
||||||
{
|
{
|
||||||
if (leveltime >= starttime-40)
|
if (leveltime >= starttime-35)
|
||||||
cmd->buttons |= BT_ACCELERATE;
|
cmd->buttons |= BT_ACCELERATE;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -656,6 +748,7 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
INT16 wallsteer = K_BotSteerFromWalls(player, predict);
|
INT16 wallsteer = K_BotSteerFromWalls(player, predict);
|
||||||
|
INT16 objectsteer = 0;
|
||||||
fixed_t rad = predict->radius - (player->mo->radius*4);
|
fixed_t rad = predict->radius - (player->mo->radius*4);
|
||||||
fixed_t dirdist = K_DistanceOfLineFromPoint(
|
fixed_t dirdist = K_DistanceOfLineFromPoint(
|
||||||
player->mo->x, player->mo->y,
|
player->mo->x, player->mo->y,
|
||||||
|
|
@ -681,11 +774,18 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
|
||||||
// Full speed ahead!
|
// Full speed ahead!
|
||||||
cmd->forwardmove = 50;
|
cmd->forwardmove = 50;
|
||||||
|
|
||||||
if (wallsteer != 0)
|
if (anglediff > 60)
|
||||||
{
|
{
|
||||||
turnamt = wallsteer;
|
// Actually, don't go too fast...
|
||||||
|
cmd->forwardmove /= 2;
|
||||||
|
cmd->buttons |= BT_BRAKE;
|
||||||
}
|
}
|
||||||
else if (dirdist <= rad)
|
else if (anglediff <= 15 || dirdist <= rad)
|
||||||
|
{
|
||||||
|
objectsteer = K_BotFindObjects(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dirdist <= rad)
|
||||||
{
|
{
|
||||||
fixed_t speedmul = FixedMul(player->speed, K_GetKartSpeed(player, false));
|
fixed_t speedmul = FixedMul(player->speed, K_GetKartSpeed(player, false));
|
||||||
fixed_t speedrad = rad/4;
|
fixed_t speedrad = rad/4;
|
||||||
|
|
@ -698,11 +798,16 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
|
||||||
// Increase radius with speed
|
// Increase radius with speed
|
||||||
// At low speed, the CPU will try to be more accurate
|
// At low speed, the CPU will try to be more accurate
|
||||||
// At high speed, they're more likely to lawnmower
|
// At high speed, they're more likely to lawnmower
|
||||||
speedrad += FixedMul(speedmul, rad/2);
|
speedrad += FixedMul(speedmul, (3*rad/4) - speedrad);
|
||||||
|
|
||||||
|
if (speedrad < 2*player->mo->radius)
|
||||||
|
{
|
||||||
|
speedrad = 2*player->mo->radius;
|
||||||
|
}
|
||||||
|
|
||||||
if (dirdist <= speedrad)
|
if (dirdist <= speedrad)
|
||||||
{
|
{
|
||||||
// Don't need to turn!
|
// Don't turn at all
|
||||||
turnamt = 0;
|
turnamt = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -710,35 +815,20 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
|
||||||
// Make minor adjustments
|
// Make minor adjustments
|
||||||
turnamt /= 4;
|
turnamt /= 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Steer towards or away from nearby objects!
|
|
||||||
turnamt += K_BotFindObjects(player);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (anglediff > 60)
|
if (wallsteer != 0)
|
||||||
{
|
{
|
||||||
// Actually, don't go too fast...
|
turnamt += wallsteer;
|
||||||
cmd->forwardmove /= 2;
|
}
|
||||||
cmd->buttons |= BT_BRAKE;
|
|
||||||
|
if (objectsteer != 0)
|
||||||
|
{
|
||||||
|
turnamt += objectsteer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (turnamt != 0)
|
|
||||||
{
|
|
||||||
if (turnamt > KART_FULLTURN)
|
|
||||||
{
|
|
||||||
turnamt = KART_FULLTURN;
|
|
||||||
}
|
|
||||||
else if (turnamt < -KART_FULLTURN)
|
|
||||||
{
|
|
||||||
turnamt = -KART_FULLTURN;
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd->driftturn = turnamt;
|
|
||||||
cmd->angleturn += turnamt;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (player->kartstuff[k_userings] == 1)
|
if (player->kartstuff[k_userings] == 1)
|
||||||
{
|
{
|
||||||
if (!player->exiting)
|
if (!player->exiting)
|
||||||
|
|
@ -763,66 +853,117 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
|
||||||
{
|
{
|
||||||
player->kartstuff[k_botitemdelay]--;
|
player->kartstuff[k_botitemdelay]--;
|
||||||
player->kartstuff[k_botitemconfirm] = 0;
|
player->kartstuff[k_botitemconfirm] = 0;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
else if (player->kartstuff[k_stealingtimer] == 0 && player->kartstuff[k_stolentimer] == 0)
|
||||||
if (player->kartstuff[k_rocketsneakertimer] > 0)
|
|
||||||
{
|
{
|
||||||
if (player->kartstuff[k_botitemconfirm] > TICRATE)
|
if (player->kartstuff[k_eggmanexplode])
|
||||||
{
|
{
|
||||||
if (!player->kartstuff[k_sneakertimer] && !(player->pflags & PF_ATTACKDOWN))
|
K_BotUseItemNearPlayer(player, cmd, 128*player->mo->scale);
|
||||||
|
}
|
||||||
|
else if (player->kartstuff[k_rocketsneakertimer] > 0)
|
||||||
|
{
|
||||||
|
if (player->kartstuff[k_botitemconfirm] > TICRATE)
|
||||||
{
|
{
|
||||||
cmd->buttons |= BT_ATTACK;
|
if (!player->kartstuff[k_sneakertimer] && !(player->pflags & PF_ATTACKDOWN))
|
||||||
player->kartstuff[k_botitemconfirm] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
player->kartstuff[k_botitemconfirm]++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
switch (player->kartstuff[k_itemtype])
|
|
||||||
{
|
|
||||||
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
|
|
||||||
{
|
|
||||||
if (!player->kartstuff[k_sneakertimer] && !(player->pflags & PF_ATTACKDOWN))
|
|
||||||
{
|
|
||||||
cmd->buttons |= BT_ATTACK;
|
|
||||||
player->kartstuff[k_botitemconfirm] = 2*TICRATE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
player->kartstuff[k_botitemconfirm]++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case KITEM_ROCKETSNEAKER:
|
|
||||||
if (player->kartstuff[k_rocketsneakertimer] <= 0)
|
|
||||||
{
|
{
|
||||||
cmd->buttons |= BT_ATTACK;
|
cmd->buttons |= BT_ATTACK;
|
||||||
player->kartstuff[k_botitemconfirm] = 0;
|
player->kartstuff[k_botitemconfirm] = 0;
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
case KITEM_INVINCIBILITY:
|
else
|
||||||
case KITEM_SPB:
|
{
|
||||||
case KITEM_GROW:
|
player->kartstuff[k_botitemconfirm]++;
|
||||||
case KITEM_SHRINK:
|
}
|
||||||
case KITEM_HYUDORO:
|
|
||||||
case KITEM_SUPERRING:
|
|
||||||
cmd->buttons |= BT_ATTACK;
|
|
||||||
player->kartstuff[k_botitemconfirm] = 0;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
player->kartstuff[k_botitemconfirm] = 0;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (player->kartstuff[k_itemtype])
|
||||||
|
{
|
||||||
|
case KITEM_INVINCIBILITY:
|
||||||
|
case KITEM_SPB:
|
||||||
|
case KITEM_GROW:
|
||||||
|
case KITEM_SHRINK:
|
||||||
|
case KITEM_HYUDORO:
|
||||||
|
case KITEM_SUPERRING:
|
||||||
|
cmd->buttons |= BT_ATTACK;
|
||||||
|
player->kartstuff[k_botitemconfirm] = 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
|
||||||
|
{
|
||||||
|
if (!player->kartstuff[k_sneakertimer] && !(player->pflags & PF_ATTACKDOWN))
|
||||||
|
{
|
||||||
|
cmd->buttons |= BT_ATTACK;
|
||||||
|
player->kartstuff[k_botitemconfirm] = 2*TICRATE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
player->kartstuff[k_botitemconfirm]++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case KITEM_ROCKETSNEAKER:
|
||||||
|
if (player->kartstuff[k_rocketsneakertimer] <= 0)
|
||||||
|
{
|
||||||
|
cmd->buttons |= BT_ATTACK;
|
||||||
|
player->kartstuff[k_botitemconfirm] = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case KITEM_THUNDERSHIELD:
|
||||||
|
if (!K_BotUseItemNearPlayer(player, cmd, 192*player->mo->scale))
|
||||||
|
{
|
||||||
|
if (player->kartstuff[k_botitemconfirm] > 10*TICRATE)
|
||||||
|
{
|
||||||
|
cmd->buttons |= BT_ATTACK;
|
||||||
|
player->kartstuff[k_botitemconfirm] = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
player->kartstuff[k_botitemconfirm]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
player->kartstuff[k_botitemconfirm] = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (turnamt != 0)
|
||||||
|
{
|
||||||
|
if (turnamt > KART_FULLTURN)
|
||||||
|
{
|
||||||
|
turnamt = KART_FULLTURN;
|
||||||
|
}
|
||||||
|
else if (turnamt < -KART_FULLTURN)
|
||||||
|
{
|
||||||
|
turnamt = -KART_FULLTURN;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((turnamt > 0 && player->kartstuff[k_botlastturn] >= 0)
|
||||||
|
|| (turnamt < 0 && player->kartstuff[k_botlastturn] <= 0))
|
||||||
|
{
|
||||||
|
if (turnamt > 0)
|
||||||
|
{
|
||||||
|
player->kartstuff[k_botlastturn] = 1;
|
||||||
|
}
|
||||||
|
else if (turnamt < 0)
|
||||||
|
{
|
||||||
|
player->kartstuff[k_botlastturn] = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd->driftturn = turnamt;
|
||||||
|
cmd->angleturn += turnamt;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
player->kartstuff[k_botlastturn] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
13
src/k_kart.c
13
src/k_kart.c
|
|
@ -953,6 +953,7 @@ static INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed, boolean sp
|
||||||
case KITEM_SHRINK:
|
case KITEM_SHRINK:
|
||||||
case KITEM_HYUDORO:
|
case KITEM_HYUDORO:
|
||||||
case KITEM_SUPERRING:
|
case KITEM_SUPERRING:
|
||||||
|
case KITEM_THUNDERSHIELD:
|
||||||
case KRITEM_TRIPLESNEAKER:
|
case KRITEM_TRIPLESNEAKER:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
@ -2680,6 +2681,18 @@ fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower)
|
||||||
|
|
||||||
finalspeed = K_GetKartSpeedFromStat(kartspeed);
|
finalspeed = K_GetKartSpeedFromStat(kartspeed);
|
||||||
|
|
||||||
|
if (K_PlayerUsesBotMovement(player))
|
||||||
|
{
|
||||||
|
fixed_t speedmul = FRACUNIT;
|
||||||
|
|
||||||
|
// 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
|
||||||
|
|
||||||
|
// TODO: Rubberbanding goes here. Do it for accel too!
|
||||||
|
|
||||||
|
finalspeed = FixedMul(finalspeed, speedmul);
|
||||||
|
}
|
||||||
|
|
||||||
if (player->mo && !P_MobjWasRemoved(player->mo))
|
if (player->mo && !P_MobjWasRemoved(player->mo))
|
||||||
finalspeed = FixedMul(finalspeed, player->mo->scale);
|
finalspeed = FixedMul(finalspeed, player->mo->scale);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue