mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Merge branch 'more-bot-crudules' into 'master'
More bot crudules See merge request KartKrew/Kart!788
This commit is contained in:
commit
bc2d4a2d83
9 changed files with 255 additions and 30 deletions
27
src/k_bot.c
27
src/k_bot.c
|
|
@ -710,7 +710,7 @@ static botprediction_t *K_CreateBotPrediction(player_t *player)
|
||||||
if (P_TraceBotTraversal(player->mo, wp->mobj) == false)
|
if (P_TraceBotTraversal(player->mo, wp->mobj) == false)
|
||||||
{
|
{
|
||||||
// If we can't get a direct path to this waypoint, predict less.
|
// If we can't get a direct path to this waypoint, predict less.
|
||||||
distanceleft -= disttonext;
|
distanceleft /= 2;
|
||||||
radreduce = FRACUNIT >> 1;
|
radreduce = FRACUNIT >> 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -745,6 +745,25 @@ static botprediction_t *K_CreateBotPrediction(player_t *player)
|
||||||
predict->y += P_ReturnThrustY(NULL, angletonext, min(disttonext, distanceleft) * FRACUNIT);
|
predict->y += P_ReturnThrustY(NULL, angletonext, min(disttonext, distanceleft) * FRACUNIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (player->mo->standingslope != NULL)
|
||||||
|
{
|
||||||
|
const pslope_t *slope = player->mo->standingslope;
|
||||||
|
|
||||||
|
if (!(slope->flags & SL_NOPHYSICS) && abs(slope->zdelta) >= FRACUNIT/21)
|
||||||
|
{
|
||||||
|
// Displace the prediction to go against the slope physics.
|
||||||
|
angle_t angle = slope->xydirection;
|
||||||
|
|
||||||
|
if (P_MobjFlip(player->mo) * slope->zdelta < 0)
|
||||||
|
{
|
||||||
|
angle ^= ANGLE_180;
|
||||||
|
}
|
||||||
|
|
||||||
|
predict->x -= P_ReturnThrustX(NULL, angle, startDist * abs(slope->zdelta));
|
||||||
|
predict->y -= P_ReturnThrustY(NULL, angle, startDist * abs(slope->zdelta));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ps_bots[player - players].prediction += I_GetPreciseTime() - time;
|
ps_bots[player - players].prediction += I_GetPreciseTime() - time;
|
||||||
return predict;
|
return predict;
|
||||||
}
|
}
|
||||||
|
|
@ -875,7 +894,7 @@ static void K_DrawPredictionDebug(botprediction_t *predict, player_t *player)
|
||||||
debugMobj->frame |= FF_TRANS20|FF_FULLBRIGHT;
|
debugMobj->frame |= FF_TRANS20|FF_FULLBRIGHT;
|
||||||
|
|
||||||
debugMobj->color = SKINCOLOR_ORANGE;
|
debugMobj->color = SKINCOLOR_ORANGE;
|
||||||
debugMobj->scale *= 2;
|
P_SetScale(debugMobj, debugMobj->destscale * 2);
|
||||||
|
|
||||||
debugMobj->tics = 2;
|
debugMobj->tics = 2;
|
||||||
|
|
||||||
|
|
@ -902,7 +921,7 @@ static void K_DrawPredictionDebug(botprediction_t *predict, player_t *player)
|
||||||
radiusMobj->frame |= FF_TRANS20|FF_FULLBRIGHT;
|
radiusMobj->frame |= FF_TRANS20|FF_FULLBRIGHT;
|
||||||
|
|
||||||
radiusMobj->color = SKINCOLOR_YELLOW;
|
radiusMobj->color = SKINCOLOR_YELLOW;
|
||||||
radiusMobj->scale /= 2;
|
P_SetScale(debugMobj, debugMobj->destscale / 2);
|
||||||
|
|
||||||
radiusMobj->tics = 2;
|
radiusMobj->tics = 2;
|
||||||
}
|
}
|
||||||
|
|
@ -1452,7 +1471,7 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (spindash == 0)
|
if (spindash == 0 && player->exiting == 0)
|
||||||
{
|
{
|
||||||
// Don't pointlessly try to use rings/sneakers while charging a spindash.
|
// Don't pointlessly try to use rings/sneakers while charging a spindash.
|
||||||
// TODO: Allowing projectile items like orbinaut while e-braking would be nice, maybe just pass in the spindash variable?
|
// TODO: Allowing projectile items like orbinaut while e-braking would be nice, maybe just pass in the spindash variable?
|
||||||
|
|
|
||||||
220
src/k_botitem.c
220
src/k_botitem.c
|
|
@ -486,6 +486,12 @@ static void K_BotItemGenericOrbitShield(player_t *player, ticcmd_t *cmd)
|
||||||
--------------------------------------------------*/
|
--------------------------------------------------*/
|
||||||
static void K_BotItemSneaker(player_t *player, ticcmd_t *cmd)
|
static void K_BotItemSneaker(player_t *player, ticcmd_t *cmd)
|
||||||
{
|
{
|
||||||
|
if (P_IsObjectOnGround(player->mo) == false)
|
||||||
|
{
|
||||||
|
// Don't use while mid-air.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if ((player->offroad && K_ApplyOffroad(player)) // Stuck in offroad, use it NOW
|
if ((player->offroad && K_ApplyOffroad(player)) // Stuck in offroad, use it NOW
|
||||||
|| K_GetWaypointIsShortcut(player->nextwaypoint) == true // Going toward a shortcut!
|
|| K_GetWaypointIsShortcut(player->nextwaypoint) == true // Going toward a shortcut!
|
||||||
|| player->speed < K_GetKartSpeed(player, false, true) / 2 // Being slowed down too much
|
|| player->speed < K_GetKartSpeed(player, false, true) / 2 // Being slowed down too much
|
||||||
|
|
@ -518,6 +524,12 @@ static void K_BotItemSneaker(player_t *player, ticcmd_t *cmd)
|
||||||
--------------------------------------------------*/
|
--------------------------------------------------*/
|
||||||
static void K_BotItemRocketSneaker(player_t *player, ticcmd_t *cmd)
|
static void K_BotItemRocketSneaker(player_t *player, ticcmd_t *cmd)
|
||||||
{
|
{
|
||||||
|
if (P_IsObjectOnGround(player->mo) == false)
|
||||||
|
{
|
||||||
|
// Don't use while mid-air.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (player->botvars.itemconfirm > TICRATE)
|
if (player->botvars.itemconfirm > TICRATE)
|
||||||
{
|
{
|
||||||
if (player->sneakertimer == 0 && K_ItemButtonWasDown(player) == false)
|
if (player->sneakertimer == 0 && K_ItemButtonWasDown(player) == false)
|
||||||
|
|
@ -892,9 +904,9 @@ static void K_BotItemOrbinaut(player_t *player, ticcmd_t *cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*--------------------------------------------------
|
/*--------------------------------------------------
|
||||||
static void K_BotItemDropTarget(player_t *player, ticcmd_t *cmd)
|
static void K_BotItemBallhog(player_t *player, ticcmd_t *cmd)
|
||||||
|
|
||||||
Item usage for Drop Target throwing.
|
Item usage for Ballhog throwing.
|
||||||
|
|
||||||
Input Arguments:-
|
Input Arguments:-
|
||||||
player - Bot to do this for.
|
player - Bot to do this for.
|
||||||
|
|
@ -903,14 +915,15 @@ static void K_BotItemOrbinaut(player_t *player, ticcmd_t *cmd)
|
||||||
Return:-
|
Return:-
|
||||||
None
|
None
|
||||||
--------------------------------------------------*/
|
--------------------------------------------------*/
|
||||||
static void K_BotItemDropTarget(player_t *player, ticcmd_t *cmd)
|
static void K_BotItemBallhog(player_t *player, ticcmd_t *cmd)
|
||||||
{
|
{
|
||||||
const fixed_t topspeed = K_GetKartSpeed(player, false, true);
|
const fixed_t topspeed = K_GetKartSpeed(player, false, true);
|
||||||
fixed_t radius = FixedMul(1280 * mapobjectscale, K_GetKartGameSpeedScalar(gamespeed));
|
fixed_t radius = FixedMul(2560 * mapobjectscale, K_GetKartGameSpeedScalar(gamespeed));
|
||||||
SINT8 throwdir = -1;
|
SINT8 throwdir = -1;
|
||||||
boolean tryLookback = false;
|
boolean tryLookback = false;
|
||||||
UINT8 snipeMul = 2;
|
UINT8 snipeMul = 2;
|
||||||
player_t *target = NULL;
|
player_t *target = NULL;
|
||||||
|
boolean hold = false;
|
||||||
|
|
||||||
if (player->speed > topspeed)
|
if (player->speed > topspeed)
|
||||||
{
|
{
|
||||||
|
|
@ -918,8 +931,6 @@ static void K_BotItemDropTarget(player_t *player, ticcmd_t *cmd)
|
||||||
snipeMul = 3; // Confirm faster when you'll throw it with a bunch of extra speed!!
|
snipeMul = 3; // Confirm faster when you'll throw it with a bunch of extra speed!!
|
||||||
}
|
}
|
||||||
|
|
||||||
player->botvars.itemconfirm++;
|
|
||||||
|
|
||||||
target = K_PlayerInCone(player, radius, 15, false);
|
target = K_PlayerInCone(player, radius, 15, false);
|
||||||
if (target != NULL)
|
if (target != NULL)
|
||||||
{
|
{
|
||||||
|
|
@ -943,7 +954,89 @@ static void K_BotItemDropTarget(player_t *player, ticcmd_t *cmd)
|
||||||
cmd->buttons |= BT_LOOKBACK;
|
cmd->buttons |= BT_LOOKBACK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (player->botvars.itemconfirm > 25*TICRATE)
|
if (target != NULL)
|
||||||
|
{
|
||||||
|
// Charge up!
|
||||||
|
hold = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If we lose sight of the target, then we'll just
|
||||||
|
// let go and it'll do a partial-blast.
|
||||||
|
|
||||||
|
// If we've been waiting for too long though, then
|
||||||
|
// we'll go for the full charge :)
|
||||||
|
player->botvars.itemconfirm++;
|
||||||
|
hold = (player->botvars.itemconfirm > 10*TICRATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hold == true)
|
||||||
|
{
|
||||||
|
cmd->throwdir = KART_FULLTURN * throwdir;
|
||||||
|
cmd->buttons |= BT_ATTACK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------
|
||||||
|
static void K_BotItemDropTarget(player_t *player, ticcmd_t *cmd, INT16 turnamt)
|
||||||
|
|
||||||
|
Item usage for Drop Target throwing.
|
||||||
|
|
||||||
|
Input Arguments:-
|
||||||
|
player - Bot to do this for.
|
||||||
|
cmd - Bot's ticcmd to edit.
|
||||||
|
turnamt - How hard they currently are turning.
|
||||||
|
|
||||||
|
Return:-
|
||||||
|
None
|
||||||
|
--------------------------------------------------*/
|
||||||
|
static void K_BotItemDropTarget(player_t *player, ticcmd_t *cmd, INT16 turnamt)
|
||||||
|
{
|
||||||
|
const fixed_t topspeed = K_GetKartSpeed(player, false, true);
|
||||||
|
fixed_t radius = FixedMul(1280 * mapobjectscale, K_GetKartGameSpeedScalar(gamespeed));
|
||||||
|
SINT8 throwdir = -1;
|
||||||
|
boolean tryLookback = false;
|
||||||
|
UINT8 snipeMul = 2;
|
||||||
|
player_t *target = NULL;
|
||||||
|
|
||||||
|
if (player->speed > topspeed)
|
||||||
|
{
|
||||||
|
radius = FixedMul(radius, FixedDiv(player->speed, topspeed));
|
||||||
|
snipeMul = 3; // Confirm faster when you'll throw it with a bunch of extra speed!!
|
||||||
|
}
|
||||||
|
|
||||||
|
player->botvars.itemconfirm++;
|
||||||
|
|
||||||
|
if (abs(turnamt) >= KART_FULLTURN/2)
|
||||||
|
{
|
||||||
|
player->botvars.itemconfirm += player->botvars.difficulty / 2;
|
||||||
|
throwdir = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
target = K_PlayerInCone(player, radius, 15, false);
|
||||||
|
if (target != NULL)
|
||||||
|
{
|
||||||
|
K_ItemConfirmForTarget(player, target, player->botvars.difficulty * snipeMul);
|
||||||
|
throwdir = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
target = K_PlayerInCone(player, radius, 15, true);
|
||||||
|
|
||||||
|
if (target != NULL)
|
||||||
|
{
|
||||||
|
K_ItemConfirmForTarget(player, target, player->botvars.difficulty);
|
||||||
|
throwdir = -1;
|
||||||
|
tryLookback = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tryLookback == true && throwdir == -1)
|
||||||
|
{
|
||||||
|
cmd->buttons |= BT_LOOKBACK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (player->botvars.itemconfirm > 10*TICRATE || player->bananadrag >= TICRATE)
|
||||||
{
|
{
|
||||||
K_BotGenericPressItem(player, cmd, throwdir);
|
K_BotGenericPressItem(player, cmd, throwdir);
|
||||||
}
|
}
|
||||||
|
|
@ -1166,6 +1259,92 @@ static void K_BotItemFlame(player_t *player, ticcmd_t *cmd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------
|
||||||
|
static void K_BotItemGardenTopDeploy(player_t *player, ticcmd_t *cmd)
|
||||||
|
|
||||||
|
Item usage for deploying the Garden Top.
|
||||||
|
|
||||||
|
Input Arguments:-
|
||||||
|
player - Bot to do this for.
|
||||||
|
cmd - Bot's ticcmd to edit.
|
||||||
|
|
||||||
|
Return:-
|
||||||
|
None
|
||||||
|
--------------------------------------------------*/
|
||||||
|
static void K_BotItemGardenTopDeploy(player_t *player, ticcmd_t *cmd)
|
||||||
|
{
|
||||||
|
//if (player->curshield != KSHIELD_TOP)
|
||||||
|
if (player->botvars.itemconfirm++ > 2*TICRATE)
|
||||||
|
{
|
||||||
|
K_BotGenericPressItem(player, cmd, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------
|
||||||
|
static void K_BotItemGardenTop(player_t *player, ticcmd_t *cmd, INT16 turnamt)
|
||||||
|
|
||||||
|
Item usage for Garden Top movement.
|
||||||
|
|
||||||
|
Input Arguments:-
|
||||||
|
player - Bot to do this for.
|
||||||
|
cmd - Bot's ticcmd to edit.
|
||||||
|
turnamt - How hard they currently are turning.
|
||||||
|
|
||||||
|
Return:-
|
||||||
|
None
|
||||||
|
--------------------------------------------------*/
|
||||||
|
static void K_BotItemGardenTop(player_t *player, ticcmd_t *cmd, INT16 turnamt)
|
||||||
|
{
|
||||||
|
const fixed_t topspeed = K_GetKartSpeed(player, false, true);
|
||||||
|
fixed_t radius = FixedMul(2560 * mapobjectscale, K_GetKartGameSpeedScalar(gamespeed));
|
||||||
|
SINT8 throwdir = -1;
|
||||||
|
UINT8 snipeMul = 1;
|
||||||
|
player_t *target = NULL;
|
||||||
|
|
||||||
|
if (player->speed > topspeed)
|
||||||
|
{
|
||||||
|
radius = FixedMul(radius, FixedDiv(player->speed, topspeed));
|
||||||
|
snipeMul = 2; // Confirm faster when you'll throw it with a bunch of extra speed!!
|
||||||
|
}
|
||||||
|
|
||||||
|
player->botvars.itemconfirm++;
|
||||||
|
|
||||||
|
target = K_PlayerInCone(player, radius, 15, false);
|
||||||
|
if (target != NULL)
|
||||||
|
{
|
||||||
|
K_ItemConfirmForTarget(player, target, player->botvars.difficulty * snipeMul);
|
||||||
|
throwdir = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (player->topdriftheld > 0)
|
||||||
|
{
|
||||||
|
// Grinding in place.
|
||||||
|
// Wait until we're mostly done turning.
|
||||||
|
// Cancel early if we hit max thrust speed.
|
||||||
|
if ((abs(turnamt) >= KART_FULLTURN/8)
|
||||||
|
&& (player->topdriftheld <= GARDENTOP_MAXGRINDTIME))
|
||||||
|
{
|
||||||
|
cmd->buttons |= BT_DRIFT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const angle_t maxDelta = ANGLE_11hh;
|
||||||
|
angle_t delta = AngleDelta(player->mo->angle, K_MomentumAngle(player->mo));
|
||||||
|
|
||||||
|
if (delta > maxDelta)
|
||||||
|
{
|
||||||
|
// Do we need to turn? Start grinding!
|
||||||
|
cmd->buttons |= BT_DRIFT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (player->botvars.itemconfirm > 25*TICRATE)
|
||||||
|
{
|
||||||
|
K_BotGenericPressItem(player, cmd, throwdir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*--------------------------------------------------
|
/*--------------------------------------------------
|
||||||
static void K_BotItemRings(player_t *player, ticcmd_t *cmd)
|
static void K_BotItemRings(player_t *player, ticcmd_t *cmd)
|
||||||
|
|
||||||
|
|
@ -1182,6 +1361,12 @@ static void K_BotItemRings(player_t *player, ticcmd_t *cmd)
|
||||||
{
|
{
|
||||||
INT32 saferingsval = 16 - K_GetKartRingPower(player, false);
|
INT32 saferingsval = 16 - K_GetKartRingPower(player, false);
|
||||||
|
|
||||||
|
if (P_IsObjectOnGround(player->mo) == false)
|
||||||
|
{
|
||||||
|
// Don't use while mid-air.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (player->speed < K_GetKartSpeed(player, false, true) / 2 // Being slowed down too much
|
if (player->speed < K_GetKartSpeed(player, false, true) / 2 // Being slowed down too much
|
||||||
|| player->speedboost > (FRACUNIT/5)) // Have another type of boost (tethering)
|
|| player->speedboost > (FRACUNIT/5)) // Have another type of boost (tethering)
|
||||||
{
|
{
|
||||||
|
|
@ -1242,7 +1427,7 @@ void K_BotItemUsage(player_t *player, ticcmd_t *cmd, INT16 turnamt)
|
||||||
{
|
{
|
||||||
// Use rings!
|
// Use rings!
|
||||||
|
|
||||||
if (leveltime > starttime && !player->exiting)
|
if (leveltime > starttime)
|
||||||
{
|
{
|
||||||
K_BotItemRings(player, cmd);
|
K_BotItemRings(player, cmd);
|
||||||
}
|
}
|
||||||
|
|
@ -1293,7 +1478,6 @@ void K_BotItemUsage(player_t *player, ticcmd_t *cmd, INT16 turnamt)
|
||||||
case KITEM_SPB:
|
case KITEM_SPB:
|
||||||
case KITEM_GROW:
|
case KITEM_GROW:
|
||||||
case KITEM_SHRINK:
|
case KITEM_SHRINK:
|
||||||
case KITEM_HYUDORO:
|
|
||||||
case KITEM_SUPERRING:
|
case KITEM_SUPERRING:
|
||||||
K_BotItemGenericTap(player, cmd);
|
K_BotItemGenericTap(player, cmd);
|
||||||
break;
|
break;
|
||||||
|
|
@ -1325,8 +1509,6 @@ void K_BotItemUsage(player_t *player, ticcmd_t *cmd, INT16 turnamt)
|
||||||
K_BotItemGenericOrbitShield(player, cmd);
|
K_BotItemGenericOrbitShield(player, cmd);
|
||||||
}
|
}
|
||||||
else if (player->position != 1) // Hold onto orbiting items when in 1st :)
|
else if (player->position != 1) // Hold onto orbiting items when in 1st :)
|
||||||
/* FALLTHRU */
|
|
||||||
case KITEM_BALLHOG:
|
|
||||||
{
|
{
|
||||||
K_BotItemOrbinaut(player, cmd);
|
K_BotItemOrbinaut(player, cmd);
|
||||||
}
|
}
|
||||||
|
|
@ -1352,8 +1534,12 @@ void K_BotItemUsage(player_t *player, ticcmd_t *cmd, INT16 turnamt)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case KITEM_LANDMINE:
|
case KITEM_LANDMINE:
|
||||||
|
case KITEM_HYUDORO: // Function re-use, as they have about the same usage.
|
||||||
K_BotItemLandmine(player, cmd, turnamt);
|
K_BotItemLandmine(player, cmd, turnamt);
|
||||||
break;
|
break;
|
||||||
|
case KITEM_BALLHOG:
|
||||||
|
K_BotItemBallhog(player, cmd);
|
||||||
|
break;
|
||||||
case KITEM_DROPTARGET:
|
case KITEM_DROPTARGET:
|
||||||
if (!(player->pflags & PF_ITEMOUT))
|
if (!(player->pflags & PF_ITEMOUT))
|
||||||
{
|
{
|
||||||
|
|
@ -1361,7 +1547,17 @@ void K_BotItemUsage(player_t *player, ticcmd_t *cmd, INT16 turnamt)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
K_BotItemDropTarget(player, cmd);
|
K_BotItemDropTarget(player, cmd, turnamt);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case KITEM_GARDENTOP:
|
||||||
|
if (player->curshield != KSHIELD_TOP)
|
||||||
|
{
|
||||||
|
K_BotItemGardenTopDeploy(player, cmd);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
K_BotItemGardenTop(player, cmd, turnamt);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case KITEM_LIGHTNINGSHIELD:
|
case KITEM_LIGHTNINGSHIELD:
|
||||||
|
|
|
||||||
|
|
@ -149,7 +149,7 @@ static boolean K_BotHatesThisSectorsSpecial(player_t *player, sector_t *sec)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sec->offroad > FRACUNIT) // Only care about strong offroad.
|
if (sec->offroad > 0)
|
||||||
{
|
{
|
||||||
return !K_BotCanTakeCut(player);
|
return !K_BotCanTakeCut(player);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9067,6 +9067,11 @@ static waypoint_t *K_GetPlayerNextWaypoint(player_t *player)
|
||||||
|
|
||||||
if (angledelta < nextbestdelta && momdelta < nextbestmomdelta)
|
if (angledelta < nextbestdelta && momdelta < nextbestmomdelta)
|
||||||
{
|
{
|
||||||
|
if (waypoint->prevwaypoints[i] == finishline) // NEVER allow finish line.
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (P_TraceWaypointTraversal(player->mo, waypoint->prevwaypoints[i]->mobj) == false)
|
if (P_TraceWaypointTraversal(player->mo, waypoint->prevwaypoints[i]->mobj) == false)
|
||||||
{
|
{
|
||||||
// Save sight checks when all of the other checks pass, so we only do it if we have to
|
// Save sight checks when all of the other checks pass, so we only do it if we have to
|
||||||
|
|
|
||||||
|
|
@ -361,7 +361,7 @@ waypoint_t *K_GetBestWaypointForMobj(mobj_t *const mobj)
|
||||||
// remember: huge radius
|
// remember: huge radius
|
||||||
if (closestdist <= rad && checkdist <= rad && finishline != NULL)
|
if (closestdist <= rad && checkdist <= rad && finishline != NULL)
|
||||||
{
|
{
|
||||||
if (!P_TraceBlockingLines(mobj, checkwaypoint->mobj)) // Intentionally not P_TraceWaypointTraversal
|
if (!P_TraceWaypointTraversal(mobj, checkwaypoint->mobj))
|
||||||
{
|
{
|
||||||
// Save sight checks when all of the other checks pass, so we only do it if we have to
|
// Save sight checks when all of the other checks pass, so we only do it if we have to
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -379,7 +379,7 @@ waypoint_t *K_GetBestWaypointForMobj(mobj_t *const mobj)
|
||||||
}
|
}
|
||||||
else if (checkdist < closestdist && bestfindist == INT32_MAX)
|
else if (checkdist < closestdist && bestfindist == INT32_MAX)
|
||||||
{
|
{
|
||||||
if (!P_TraceBlockingLines(mobj, checkwaypoint->mobj)) // Intentionally not P_TraceWaypointTraversal
|
if (!P_TraceWaypointTraversal(mobj, checkwaypoint->mobj))
|
||||||
{
|
{
|
||||||
// Save sight checks when all of the other checks pass, so we only do it if we have to
|
// Save sight checks when all of the other checks pass, so we only do it if we have to
|
||||||
continue;
|
continue;
|
||||||
|
|
|
||||||
|
|
@ -750,9 +750,6 @@ boolean P_LookForPlayers(mobj_t *actor, boolean allaround, boolean tracer, fixed
|
||||||
if (player->mo->health <= 0)
|
if (player->mo->health <= 0)
|
||||||
continue; // dead
|
continue; // dead
|
||||||
|
|
||||||
if (player->bot)
|
|
||||||
continue; // ignore bots
|
|
||||||
|
|
||||||
if (dist > 0
|
if (dist > 0
|
||||||
&& P_AproxDistance(P_AproxDistance(player->mo->x - actor->x, player->mo->y - actor->y), player->mo->z - actor->z) > dist)
|
&& P_AproxDistance(P_AproxDistance(player->mo->x - actor->x, player->mo->y - actor->y), player->mo->z - actor->z) > dist)
|
||||||
continue; // Too far away
|
continue; // Too far away
|
||||||
|
|
|
||||||
|
|
@ -4538,7 +4538,7 @@ boolean P_SupermanLook4Players(mobj_t *actor)
|
||||||
{
|
{
|
||||||
if (playeringame[c] && !players[c].spectator)
|
if (playeringame[c] && !players[c].spectator)
|
||||||
{
|
{
|
||||||
if (!players[c].mo || players[c].bot)
|
if (!players[c].mo)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (players[c].mo->health <= 0)
|
if (players[c].mo->health <= 0)
|
||||||
|
|
|
||||||
|
|
@ -334,6 +334,12 @@ static boolean P_CanTraceBlockingLine(seg_t *seg, divline_t *divl, register los_
|
||||||
|
|
||||||
(void)divl;
|
(void)divl;
|
||||||
|
|
||||||
|
if (!(line->flags & ML_TWOSIDED))
|
||||||
|
{
|
||||||
|
// stop because it is not two sided anyway
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (P_IsLineBlocking(line, los->compareThing) == true)
|
if (P_IsLineBlocking(line, los->compareThing) == true)
|
||||||
{
|
{
|
||||||
// This line will always block us
|
// This line will always block us
|
||||||
|
|
@ -380,11 +386,16 @@ static boolean P_CanBotTraverse(seg_t *seg, divline_t *divl, register los_t *los
|
||||||
if (los->compareThing->player != NULL && los->alreadyHates == false)
|
if (los->compareThing->player != NULL && los->alreadyHates == false)
|
||||||
{
|
{
|
||||||
// Treat damage sectors like walls, if you're not already in a bad sector.
|
// Treat damage sectors like walls, if you're not already in a bad sector.
|
||||||
|
sector_t *front, *back;
|
||||||
vertex_t pos;
|
vertex_t pos;
|
||||||
|
|
||||||
P_ClosestPointOnLine(los->compareThing->x, los->compareThing->y, line, &pos);
|
P_ClosestPointOnLine(los->compareThing->x, los->compareThing->y, line, &pos);
|
||||||
|
|
||||||
if (K_BotHatesThisSector(los->compareThing->player, line->frontsector, pos.x, pos.y)
|
front = seg->frontsector;
|
||||||
|| K_BotHatesThisSector(los->compareThing->player, line->backsector, pos.x, pos.y))
|
back = seg->backsector;
|
||||||
|
|
||||||
|
if (K_BotHatesThisSector(los->compareThing->player, front, pos.x, pos.y)
|
||||||
|
|| K_BotHatesThisSector(los->compareThing->player, back, pos.x, pos.y))
|
||||||
{
|
{
|
||||||
// This line does not block us, but we don't want to be in it.
|
// This line does not block us, but we don't want to be in it.
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -4282,7 +4282,7 @@ boolean P_IsPlayerValid(size_t playernum)
|
||||||
|
|
||||||
boolean P_CanPlayerTrigger(size_t playernum)
|
boolean P_CanPlayerTrigger(size_t playernum)
|
||||||
{
|
{
|
||||||
return P_IsPlayerValid(playernum) && !players[playernum].bot;
|
return P_IsPlayerValid(playernum);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \todo check continues for proper splitscreen support?
|
/// \todo check continues for proper splitscreen support?
|
||||||
|
|
@ -4310,7 +4310,7 @@ static void P_ProcessEggCapsule(player_t *player, sector_t *sector)
|
||||||
mobj_t *mo2;
|
mobj_t *mo2;
|
||||||
INT32 i;
|
INT32 i;
|
||||||
|
|
||||||
if (player->bot || sector->ceilingdata || sector->floordata)
|
if (sector->ceilingdata || sector->floordata)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Find the center of the Eggtrap and release all the pretty animals!
|
// Find the center of the Eggtrap and release all the pretty animals!
|
||||||
|
|
@ -4517,9 +4517,6 @@ static void P_EvaluateDamageType(player_t *player, sector_t *sector, boolean isT
|
||||||
|
|
||||||
static void P_EvaluateLinedefExecutorTrigger(player_t *player, sector_t *sector, boolean isTouching)
|
static void P_EvaluateLinedefExecutorTrigger(player_t *player, sector_t *sector, boolean isTouching)
|
||||||
{
|
{
|
||||||
if (player->bot)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!sector->triggertag)
|
if (!sector->triggertag)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue