Slightly smarter sneaker usage

- Use sneaker if held for too long without a proper use
- Use sneaker if losing too much speed
- Use sneaker if you have another boost (tether, boosters)
- Add triple sneaker & rocket sneaker support
- Don't go towards shortcut waypoints without a shortcut item
- Bots get naturally better handling
This commit is contained in:
Sally Cochenour 2020-03-30 17:17:20 -04:00
parent 9e2c119b56
commit fb550f2868
6 changed files with 96 additions and 11 deletions

View file

@ -348,6 +348,7 @@ typedef enum
k_wrongway, // Display WRONG WAY on screen
k_botitemdelay,
k_botitemconfirm,
NUMKARTSTUFF
} kartstufftype_t;

View file

@ -8607,7 +8607,8 @@ static const char *const KARTSTUFF_LIST[] = {
"KILLFIELD",
"WRONGWAY",
"BOTITEMDELAY"
"BOTITEMDELAY",
"BOTITEMCONFIRM"
};
#endif

View file

@ -68,7 +68,7 @@ void K_AddBots(SINT8 numbots)
else if (numbots == 2)
WRITEUINT8(buf_p, 5);
else if (numbots == 1)
WRITEUINT8(buf_p, 7);
WRITEUINT8(buf_p, 9);
else
WRITEUINT8(buf_p, 10);
@ -88,6 +88,17 @@ boolean K_PlayerUsesBotMovement(player_t *player)
return false;
}
boolean K_BotCanTakeCut(player_t *player)
{
if (!K_ApplyOffroad(player)
|| player->kartstuff[k_itemtype] == KITEM_SNEAKER
|| player->kartstuff[k_itemtype] == KITEM_INVINCIBILITY
|| player->kartstuff[k_itemtype] == KITEM_HYUDORO)
return true;
return false;
}
static fixed_t K_DistanceOfLineFromPoint(fixed_t v1x, fixed_t v1y, fixed_t v2x, fixed_t v2y, fixed_t cx, fixed_t cy)
{
fixed_t v1toc[2] = {cx - v1x, cy - v1y};
@ -105,7 +116,7 @@ static fixed_t K_DistanceOfLineFromPoint(fixed_t v1x, fixed_t v1y, fixed_t v2x,
static botprediction_t *K_CreateBotPrediction(player_t *player)
{
const INT32 distance = ((256 * player->mo->scale) + (player->speed * 16)) / FRACUNIT;
const INT32 distance = (player->speed / FRACUNIT) * TICRATE;
INT32 distanceleft = distance;
botprediction_t *predictcoords = Z_Calloc(sizeof(botprediction_t), PU_LEVEL, NULL);
waypoint_t *wp = player->nextwaypoint;
@ -113,6 +124,14 @@ static botprediction_t *K_CreateBotPrediction(player_t *player)
size_t i;
INT32 lp = 0;
if (distance <= 0)
{
predictcoords->x = wp->mobj->x;
predictcoords->y = wp->mobj->y;
predictcoords->radius = wp->mobj->radius;
return predictcoords;
}
while (distanceleft > 0)
{
lp++;
@ -132,6 +151,11 @@ static botprediction_t *K_CreateBotPrediction(player_t *player)
for (i = 0; i < wp->numnextwaypoints; i++)
{
if (K_GetWaypointIsShortcut(wp->nextwaypoints[i]) && !K_BotCanTakeCut(player))
{
continue;
}
dist = P_AproxDistance(
player->mo->x - wp->nextwaypoints[i]->mobj->x,
player->mo->y - wp->nextwaypoints[i]->mobj->y
@ -246,7 +270,7 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
if (dirdist <= rad)
{
if (dirdist < rad/2)
if (dirdist < 2*rad/3)
{
// Don't need to turn!
turnamt = 0;
@ -257,12 +281,12 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
turnamt /= 4;
}
}
/*else
else if (anglediff > 45)
{
// Actually, don't go too fast...
cmd->forwardmove /= 2;
cmd->buttons |= BT_BRAKE;
}*/
}
}
if (turnamt != 0)
@ -282,13 +306,51 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
else
{
if (player->kartstuff[k_botitemdelay])
{
player->kartstuff[k_botitemdelay]--;
player->kartstuff[k_botitemconfirm] = 0;
return;
}
switch (player->kartstuff[k_itemtype])
{
case KITEM_SNEAKER:
if (player->kartstuff[k_offroad] || K_GetWaypointIsShortcut(player->nextwaypoint) == true)
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] > 0 // Have another type of boost (tethering)
|| player->kartstuff[k_botitemconfirm] > 4*TICRATE) // Held onto it for too long
{
cmd->buttons |= BT_ATTACK;
player->kartstuff[k_botitemconfirm] -= 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;
}
else
{
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] > 0 // Have another type of boost (tethering)
|| player->kartstuff[k_botitemconfirm] > TICRATE) // Held onto it for too long
{
cmd->buttons |= BT_ATTACK;
player->kartstuff[k_botitemconfirm] -= TICRATE/2;
}
else
{
player->kartstuff[k_botitemconfirm]++;
}
}
break;
case KITEM_INVINCIBILITY:
case KITEM_SPB:
@ -297,8 +359,10 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
case KITEM_HYUDORO:
case KITEM_SUPERRING:
cmd->buttons |= BT_ATTACK;
player->kartstuff[k_botitemconfirm] = 0;
break;
default:
player->kartstuff[k_botitemconfirm] = 0;
break;
}
}

View file

@ -20,4 +20,5 @@ typedef struct botprediction_s {
void K_AddBots(SINT8 numbots);
boolean K_PlayerUsesBotMovement(player_t *player);
boolean K_BotCanTakeCut(player_t *player);
void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd);

View file

@ -763,6 +763,7 @@ static void K_KartGetItemResult(player_t *player, SINT8 getitem)
hyubgone = 5*TICRATE;
player->kartstuff[k_botitemdelay] = TICRATE;
player->kartstuff[k_botitemconfirm] = 0;
switch (getitem)
{
@ -907,12 +908,14 @@ static INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed, boolean sp
switch (item)
{
case KITEM_SNEAKER:
case KITEM_ROCKETSNEAKER:
case KITEM_INVINCIBILITY:
case KITEM_SPB:
case KITEM_GROW:
case KITEM_SHRINK:
case KITEM_HYUDORO:
case KITEM_SUPERRING:
case KRITEM_TRIPLESNEAKER:
break;
default:
return 0;
@ -2536,7 +2539,7 @@ void K_MomentumToFacing(player_t *player)
player->mo->momy = FixedMul(player->mo->momy - player->cmomy, player->mo->friction) + player->cmomy;
}
static boolean K_ApplyOffroad(player_t *player)
boolean K_ApplyOffroad(player_t *player)
{
if (player->kartstuff[k_invincibilitytimer] || player->kartstuff[k_hyudorotimer] || EITHERSNEAKER(player))
return false;
@ -6023,9 +6026,6 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
player->powers[pw_flashing]--;
}
if (player->kartstuff[k_botitemdelay])
player->kartstuff[k_botitemdelay]--;
if (player->kartstuff[k_spinouttimer])
{
if ((P_IsObjectOnGround(player->mo)
@ -6411,6 +6411,13 @@ static waypoint_t *K_GetPlayerNextWaypoint(player_t *player)
{
for (i = 0U; i < waypoint->numnextwaypoints; i++)
{
if (K_GetWaypointIsShortcut(waypoint->nextwaypoints[i])
&& K_PlayerUsesBotMovement(player)
&& !K_BotCanTakeCut(player))
{
continue;
}
angletowaypoint = R_PointToAngle2(
player->mo->x, player->mo->y,
waypoint->nextwaypoints[i]->mobj->x, waypoint->nextwaypoints[i]->mobj->y);
@ -6451,6 +6458,13 @@ static waypoint_t *K_GetPlayerNextWaypoint(player_t *player)
{
for (i = 0U; i < waypoint->numprevwaypoints; i++)
{
if (K_GetWaypointIsShortcut(waypoint->prevwaypoints[i])
&& K_PlayerUsesBotMovement(player)
&& !K_BotCanTakeCut(player))
{
continue;
}
angletowaypoint = R_PointToAngle2(
player->mo->x, player->mo->y,
waypoint->prevwaypoints[i]->mobj->x, waypoint->prevwaypoints[i]->mobj->y);
@ -6746,6 +6760,9 @@ INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue)
if (EITHERSNEAKER(player) || player->kartstuff[k_invincibilitytimer] || player->kartstuff[k_growshrinktimer] > 0)
turnvalue = FixedMul(turnvalue, (5*FRACUNIT)/4);
if (K_PlayerUsesBotMovement(player))
turnvalue = FixedMul(turnvalue, (5*FRACUNIT)/4);
return turnvalue;
}

View file

@ -66,6 +66,7 @@ void K_DropItems(player_t *player);
void K_StripItems(player_t *player);
void K_StripOther(player_t *player);
void K_MomentumToFacing(player_t *player);
boolean K_ApplyOffroad(player_t *player);
fixed_t K_GetKartSpeedFromStat(UINT8 kartspeed);
fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower);
fixed_t K_GetKartAccel(player_t *player);