mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
All around polishing
- Make ring usage smarter - Ring usage threshold varies between characters (Tails will be more willing to dump rings, Metal will hold onto them) - Decrease ring use threshold when they have a speed boost (tethering) - Decrease ring use threshold when slowed down more than usual - Properly implement Triple Sneaker & Rocket Sneaker usage - Use smallest radius of all waypoints being predicted, to improve precision - Bots never use prev waypoints
This commit is contained in:
parent
29613dba90
commit
4380caf7dd
5 changed files with 118 additions and 65 deletions
154
src/k_bot.c
154
src/k_bot.c
|
|
@ -116,10 +116,12 @@ 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 = (player->speed / FRACUNIT) * TICRATE;
|
||||
const INT32 futuresight = (3*TICRATE/4); // How far ahead into the future to try and predict
|
||||
const INT32 distance = (player->speed / FRACUNIT) * futuresight;
|
||||
INT32 distanceleft = distance;
|
||||
botprediction_t *predictcoords = Z_Calloc(sizeof(botprediction_t), PU_LEVEL, NULL);
|
||||
waypoint_t *wp = player->nextwaypoint;
|
||||
fixed_t smallestradius = wp->mobj->radius;
|
||||
size_t nwp;
|
||||
size_t i;
|
||||
INT32 lp = 0;
|
||||
|
|
@ -128,7 +130,7 @@ static botprediction_t *K_CreateBotPrediction(player_t *player)
|
|||
{
|
||||
predictcoords->x = wp->mobj->x;
|
||||
predictcoords->y = wp->mobj->y;
|
||||
predictcoords->radius = wp->mobj->radius;
|
||||
predictcoords->radius = smallestradius;
|
||||
return predictcoords;
|
||||
}
|
||||
|
||||
|
|
@ -174,13 +176,19 @@ static botprediction_t *K_CreateBotPrediction(player_t *player)
|
|||
break;
|
||||
}
|
||||
|
||||
wp = wp->nextwaypoints[nwp];
|
||||
distanceleft -= wp->nextwaypointdistances[nwp];
|
||||
|
||||
if (wp->nextwaypoints[nwp]->mobj->radius < smallestradius)
|
||||
{
|
||||
smallestradius = wp->nextwaypoints[nwp]->mobj->radius;
|
||||
}
|
||||
|
||||
wp = wp->nextwaypoints[nwp];
|
||||
}
|
||||
|
||||
predictcoords->x = wp->mobj->x;
|
||||
predictcoords->y = wp->mobj->y;
|
||||
predictcoords->radius = wp->mobj->radius;
|
||||
predictcoords->radius = smallestradius;
|
||||
|
||||
if (distanceleft > 0)
|
||||
{
|
||||
|
|
@ -195,6 +203,9 @@ static botprediction_t *K_CreateBotPrediction(player_t *player)
|
|||
|
||||
void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
|
||||
{
|
||||
boolean ontrack = false;
|
||||
INT16 turnamt = KART_FULLTURN;
|
||||
|
||||
// Can't build a ticcmd if we aren't spawned...
|
||||
if (!player->mo)
|
||||
return;
|
||||
|
|
@ -225,7 +236,6 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
|
|||
if (player->nextwaypoint != NULL && player->nextwaypoint->mobj != NULL && !P_MobjWasRemoved(player->nextwaypoint->mobj))
|
||||
{
|
||||
botprediction_t *predict = K_CreateBotPrediction(player);
|
||||
INT16 turnamt = KART_FULLTURN;
|
||||
SINT8 turnsign = 0;
|
||||
angle_t destangle, moveangle, angle;
|
||||
INT16 anglediff;
|
||||
|
|
@ -256,13 +266,18 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
|
|||
}
|
||||
else
|
||||
{
|
||||
fixed_t rad = predict->radius - (player->mo->radius*2);
|
||||
fixed_t rad = predict->radius - (player->mo->radius*4);
|
||||
fixed_t dirdist = K_DistanceOfLineFromPoint(
|
||||
player->mo->x, player->mo->y,
|
||||
player->mo->x + FINECOSINE(moveangle >> ANGLETOFINESHIFT), player->mo->y + FINESINE(moveangle >> ANGLETOFINESHIFT),
|
||||
predict->x, predict->y
|
||||
);
|
||||
|
||||
if (rad < 0)
|
||||
{
|
||||
rad = 0;
|
||||
}
|
||||
|
||||
cmd->buttons |= BT_ACCELERATE;
|
||||
|
||||
// Full speed ahead!
|
||||
|
|
@ -270,7 +285,22 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
|
|||
|
||||
if (dirdist <= rad)
|
||||
{
|
||||
if (dirdist < 2*rad/3)
|
||||
fixed_t speedmul = FixedMul(player->speed, K_GetKartSpeed(player, false));
|
||||
fixed_t speedrad = rad/4;
|
||||
|
||||
ontrack = true;
|
||||
|
||||
if (speedmul > FRACUNIT)
|
||||
{
|
||||
speedmul = FRACUNIT;
|
||||
}
|
||||
|
||||
// Increase radius with speed
|
||||
// At low speed, the CPU will try to be more accurate
|
||||
// At high speed, they're more likely to lawnmower
|
||||
speedrad += FixedMul(speedmul, rad/2);
|
||||
|
||||
if (dirdist < speedrad)
|
||||
{
|
||||
// Don't need to turn!
|
||||
turnamt = 0;
|
||||
|
|
@ -291,17 +321,36 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
|
|||
|
||||
if (turnamt != 0)
|
||||
{
|
||||
cmd->driftturn = KART_FULLTURN * turnsign;
|
||||
cmd->angleturn += KART_FULLTURN * turnsign;
|
||||
cmd->driftturn = turnamt * turnsign;
|
||||
cmd->angleturn += turnamt * turnsign;
|
||||
}
|
||||
|
||||
Z_Free(predict);
|
||||
}
|
||||
|
||||
if (player->kartstuff[k_userings] == 1 && !player->exiting)
|
||||
else
|
||||
{
|
||||
if (player->kartstuff[k_rings] > 10)
|
||||
cmd->buttons |= BT_ATTACK;
|
||||
turnamt = 0;
|
||||
}
|
||||
|
||||
(void)ontrack;
|
||||
|
||||
if (player->kartstuff[k_userings] == 1)
|
||||
{
|
||||
if (!player->exiting)
|
||||
{
|
||||
INT32 saferingsval = 8 + K_GetKartRingPower(player);
|
||||
|
||||
if (player->speed < K_GetKartSpeed(player, false)/2 // Being slowed down too much
|
||||
|| player->kartstuff[k_speedboost] > 0) // Have another type of boost (tethering)
|
||||
{
|
||||
saferingsval -= 5;
|
||||
}
|
||||
|
||||
if (player->kartstuff[k_rings] > saferingsval)
|
||||
{
|
||||
cmd->buttons |= BT_ATTACK;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -312,58 +361,63 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
|
|||
return;
|
||||
}
|
||||
|
||||
switch (player->kartstuff[k_itemtype])
|
||||
if (player->kartstuff[k_rocketsneakertimer] > 0)
|
||||
{
|
||||
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] > 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)
|
||||
if (player->kartstuff[k_botitemconfirm] > TICRATE)
|
||||
{
|
||||
if (player->kartstuff[k_sneakertimer] <= (TICRATE/3) && !(player->pflags & PF_ATTACKDOWN))
|
||||
{
|
||||
cmd->buttons |= BT_ATTACK;
|
||||
player->kartstuff[k_botitemconfirm] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
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] > 0 // Have another type of boost (tethering)
|
||||
|| player->kartstuff[k_botitemconfirm] > TICRATE) // Held onto it for too long
|
||||
|| player->kartstuff[k_botitemconfirm] > 4*TICRATE) // Held onto it for too long
|
||||
{
|
||||
cmd->buttons |= BT_ATTACK;
|
||||
player->kartstuff[k_botitemconfirm] -= TICRATE/2;
|
||||
if (player->kartstuff[k_sneakertimer] <= (TICRATE/3) && !(player->pflags & PF_ATTACKDOWN))
|
||||
{
|
||||
cmd->buttons |= BT_ATTACK;
|
||||
player->kartstuff[k_botitemconfirm] -= 2*TICRATE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
player->kartstuff[k_botitemconfirm]++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
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;
|
||||
default:
|
||||
player->kartstuff[k_botitemconfirm] = 0;
|
||||
break;
|
||||
break;
|
||||
case KITEM_ROCKETSNEAKER:
|
||||
if (player->kartstuff[k_rocketsneakertimer] <= 0)
|
||||
{
|
||||
cmd->buttons |= BT_ATTACK;
|
||||
player->kartstuff[k_botitemconfirm] = 0;
|
||||
}
|
||||
break;
|
||||
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;
|
||||
default:
|
||||
player->kartstuff[k_botitemconfirm] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
typedef struct botprediction_s {
|
||||
fixed_t x, y;
|
||||
fixed_t radius;
|
||||
angle_t dir;
|
||||
} botprediction_t;
|
||||
|
||||
void K_AddBots(SINT8 numbots);
|
||||
|
|
|
|||
21
src/k_kart.c
21
src/k_kart.c
|
|
@ -6455,9 +6455,9 @@ 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))
|
||||
if (K_PlayerUsesBotMovement(player)
|
||||
&& K_GetWaypointIsShortcut(waypoint->nextwaypoints[i])
|
||||
&& !K_BotCanTakeCut(player))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
|
@ -6498,17 +6498,11 @@ static waypoint_t *K_GetPlayerNextWaypoint(player_t *player)
|
|||
}
|
||||
}
|
||||
|
||||
if ((waypoint->prevwaypoints != NULL) && (waypoint->numprevwaypoints > 0U))
|
||||
if ((waypoint->prevwaypoints != NULL) && (waypoint->numprevwaypoints > 0U)
|
||||
&& !(K_PlayerUsesBotMovement(player))) // Bots do not need prev waypoints
|
||||
{
|
||||
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);
|
||||
|
|
@ -6729,6 +6723,11 @@ static void K_UpdateDistanceFromFinishLine(player_t *const player)
|
|||
}
|
||||
}
|
||||
|
||||
INT32 K_GetKartRingPower(player_t *player)
|
||||
{
|
||||
return (((9 - player->kartspeed) + (9 - player->kartweight)) / 2);
|
||||
}
|
||||
|
||||
// Returns false if this player being placed here causes them to collide with any other player
|
||||
// Used in g_game.c for match etc. respawning
|
||||
// This does not check along the z because the z is not correctly set for the spawnee at this point
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ void K_UpdateHnextList(player_t *player, boolean clean);
|
|||
void K_DropHnextList(player_t *player);
|
||||
void K_RepairOrbitChain(mobj_t *orbit);
|
||||
player_t *K_FindJawzTarget(mobj_t *actor, player_t *source);
|
||||
INT32 K_GetKartRingPower(player_t *player);
|
||||
boolean K_CheckPlayersRespawnColliding(INT32 playernum, fixed_t x, fixed_t y);
|
||||
INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue);
|
||||
INT32 K_GetKartDriftSparkValue(player_t *player);
|
||||
|
|
|
|||
|
|
@ -3570,7 +3570,6 @@ void A_AttractChase(mobj_t *actor)
|
|||
|
||||
if (actor->extravalue1) // SRB2Kart
|
||||
{
|
||||
#define RINGBOOSTPWR (((9 - actor->target->player->kartspeed) + (9 - actor->target->player->kartweight)) / 2)
|
||||
if (!actor->target || P_MobjWasRemoved(actor->target) || !actor->target->player)
|
||||
{
|
||||
P_RemoveMobj(actor);
|
||||
|
|
@ -3588,7 +3587,7 @@ void A_AttractChase(mobj_t *actor)
|
|||
angle_t offset = FixedAngle(18<<FRACBITS);
|
||||
|
||||
// Base add is 3 tics for 9,9, adds 1 tic for each point closer to the 1,1 end
|
||||
actor->target->player->kartstuff[k_ringboost] += RINGBOOSTPWR+3;
|
||||
actor->target->player->kartstuff[k_ringboost] += K_GetKartRingPower(actor->target->player)+3;
|
||||
S_StartSound(actor->target, sfx_s1b5);
|
||||
|
||||
sparkle = P_SpawnMobj(actor->target->x, actor->target->y, actor->target->z, MT_RINGSPARKS);
|
||||
|
|
@ -3616,7 +3615,7 @@ void A_AttractChase(mobj_t *actor)
|
|||
if (actor->extravalue1 >= 16)
|
||||
{
|
||||
if (actor->target->player->kartstuff[k_rings] >= 20)
|
||||
actor->target->player->kartstuff[k_ringboost] += RINGBOOSTPWR+3;
|
||||
actor->target->player->kartstuff[k_ringboost] += K_GetKartRingPower(actor->target->player)+3;
|
||||
else
|
||||
P_GivePlayerRings(actor->target->player, 1);
|
||||
|
||||
|
|
@ -3645,7 +3644,6 @@ void A_AttractChase(mobj_t *actor)
|
|||
actor->extravalue1++;
|
||||
}
|
||||
}
|
||||
#undef RINGBOOSTPWR
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue