mirror of
https://github.com/Cesarus85/ringfall-mjolnir-vr.git
synced 2026-10-17 14:00:25 +02:00
Bot drivers see walls and rocks ahead, back off when stuck, go round teammates
Driving a jeep or a scout, a bot looks ahead (farther the faster) along the way it turns: a wall or a rock there (not ground it can drive up) is passed on the most open side nearest its way, slower, and boxed in it backs off. Stuck is now making no way along its heading for a second and a half, which spinning wheels no longer hide. A teammate in the way is gone round slowly on the other side instead of waited for. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
9e7fd75f57
commit
867855d388
1 file changed
+93
-12
+93
-12
@@ -1475,12 +1475,13 @@ static boolean bot_riders_coming(
|
||||
}
|
||||
|
||||
/* whether a teammate on foot stands in the way the vehicle goes (ahead of
|
||||
it, or behind it backing), near */
|
||||
it, or behind it backing), near; and on which side of the way (+1 left) */
|
||||
static boolean bot_teammate_in_the_way(
|
||||
struct player_datum const *player,
|
||||
real_point3d const *position,
|
||||
real heading,
|
||||
boolean backing)
|
||||
boolean backing,
|
||||
real *side)
|
||||
{
|
||||
short index;
|
||||
|
||||
@@ -1500,10 +1501,14 @@ static boolean bot_teammate_in_the_way(
|
||||
if (unit_index == NONE || object_get(unit_index)->object.parent_object_index != NONE)
|
||||
continue;
|
||||
object_get_origin(unit_index, &origin);
|
||||
if (distance3d(position, &origin) < 8.0f &&
|
||||
fabsf(bot_angle_difference((real)atan2(origin.y - position->y, origin.x - position->x), heading)) < 0.7f)
|
||||
{
|
||||
return TRUE;
|
||||
real off = bot_angle_difference((real)atan2(origin.y - position->y, origin.x - position->x), heading);
|
||||
|
||||
if (distance3d(position, &origin) < 8.0f && fabsf(off) < 0.7f)
|
||||
{
|
||||
*side = off >= 0.0f ? 1.0f : -1.0f;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
@@ -1748,6 +1753,31 @@ static void bot_far_point(
|
||||
}
|
||||
}
|
||||
|
||||
/* how far a vehicle runs along a yaw before the level stops it (world
|
||||
units, up to length): a ray at about its bumper's height */
|
||||
static real bot_drive_clearance(
|
||||
long vehicle_index,
|
||||
real_point3d const *position,
|
||||
real yaw,
|
||||
real length)
|
||||
{
|
||||
struct collision_result collision;
|
||||
real_point3d start = *position;
|
||||
real_vector3d vector;
|
||||
|
||||
start.z += 0.5f;
|
||||
vector.i = (real)cos(yaw) * length;
|
||||
vector.j = (real)sin(yaw) * length;
|
||||
vector.k = 0.0f;
|
||||
/* (ground rising ahead, not too steep to drive up, is no wall) */
|
||||
if (!collision_test_vector(FLAG(_collision_test_structure_bit) | FLAG(_collision_test_front_facing_surfaces_bit),
|
||||
&start, &vector, vehicle_index, &collision) || collision.plane.n.k > 0.6f)
|
||||
{
|
||||
return length;
|
||||
}
|
||||
return distance3d(&start, &collision.point);
|
||||
}
|
||||
|
||||
/* the yaw from one point to another */
|
||||
static real bot_yaw_to(
|
||||
real_point3d const *from,
|
||||
@@ -1906,6 +1936,7 @@ static void bot_ride(
|
||||
boolean race = bots_game_type() == game_engine_race;
|
||||
real_point3d point;
|
||||
real moved = distance3d(&position, &bot->drive_last);
|
||||
real mate_side = 0.0f;
|
||||
|
||||
bot->drive_last = position;
|
||||
bot->step_radius = BOT_DRIVE_STEP_RADIUS;
|
||||
@@ -1965,12 +1996,48 @@ static void bot_ride(
|
||||
|
||||
if (drive == _vehicle_bot_drive_facing)
|
||||
{
|
||||
real speed = magnitude3d(&vehicle->object.translational_velocity);
|
||||
real ahead = 4.0f + speed * 20.0f;
|
||||
real way = heading + PIN(off, -0.6f, 0.6f);
|
||||
|
||||
/* turned by facing off its heading, as a stick turns it */
|
||||
turn_freely = TRUE;
|
||||
wanted_yaw = heading + PIN(off, -1.0f, 1.0f);
|
||||
action->throttle.i = fabsf(off) > 1.6f ? 0.4f : fabsf(off) > 0.8f ? 0.6f : fabsf(off) > 0.4f ? 0.8f : 1.0f;
|
||||
if (distance < 6.0f && !race)
|
||||
action->throttle.i *= 0.5f;
|
||||
/* (a wall or a rock ahead, the way it turns: round it, by the
|
||||
side most open nearest the way it wants, slower; boxed in, back
|
||||
off) */
|
||||
if (bot->reverse_ticks == 0 && bot_drive_clearance(vehicle_index, &position, way, ahead) < ahead)
|
||||
{
|
||||
static real const turns[] = { 0.4f, -0.4f, 0.8f, -0.8f, 1.2f, -1.2f };
|
||||
real best_clear = 0.0f;
|
||||
real best_turn = 0.0f;
|
||||
short index;
|
||||
|
||||
for (index = 0; index < (short)NUMBEROF(turns); index++)
|
||||
{
|
||||
real turn = (off < 0.0f ? -1.0f : 1.0f) * turns[index];
|
||||
real clear = bot_drive_clearance(vehicle_index, &position, heading + turn, ahead);
|
||||
|
||||
if (clear > best_clear + 0.5f)
|
||||
{
|
||||
best_clear = clear;
|
||||
best_turn = turn;
|
||||
}
|
||||
}
|
||||
if (best_clear < 3.0f)
|
||||
{
|
||||
bot->reverse_ticks = 35;
|
||||
bots.stucks++;
|
||||
}
|
||||
else
|
||||
{
|
||||
wanted_yaw = heading + PIN(best_turn * 1.5f, -1.0f, 1.0f);
|
||||
action->throttle.i = MIN(action->throttle.i, best_clear < ahead * 0.5f ? 0.5f : 0.75f);
|
||||
}
|
||||
}
|
||||
/* (a Ghost's guns at an enemy ahead of it) */
|
||||
if (bot->target_unit_index != NONE && TEST_FLAG(seat->flags, _unit_seat_gunner_bit))
|
||||
{
|
||||
@@ -2009,14 +2076,21 @@ static void bot_ride(
|
||||
bot->drive_stuck_ticks = 0;
|
||||
bot->reverse_ticks = 0;
|
||||
}
|
||||
/* (a teammate in the way: braked, not run down) */
|
||||
/* (a teammate in the way: braked, not run down, and round them
|
||||
slowly, turned off their side) */
|
||||
else if (bot_teammate_in_the_way(player, &position, heading,
|
||||
bot->reverse_ticks > 0 || action->throttle.i < 0.0f))
|
||||
bot->reverse_ticks > 0 || action->throttle.i < 0.0f, &mate_side))
|
||||
{
|
||||
action->throttle.i = moved > 0.08f ? (action->throttle.i > 0.0f ? -1.0f : 1.0f) : 0.0f;
|
||||
boolean backing = bot->reverse_ticks > 0 || action->throttle.i < 0.0f;
|
||||
|
||||
if (moved > 0.08f)
|
||||
action->throttle.i = backing ? 1.0f : -1.0f;
|
||||
else
|
||||
action->throttle.i = backing ? -0.3f : 0.3f;
|
||||
action->throttle.j = 0.0f;
|
||||
if (drive == _vehicle_bot_drive_facing)
|
||||
wanted_yaw = heading - mate_side * (backing ? -0.9f : 0.9f);
|
||||
bot->drive_stuck_ticks = 0;
|
||||
bot->reverse_ticks = 0;
|
||||
}
|
||||
/* (an enemy close by, and the vehicle all but still: out to fight it
|
||||
on foot) */
|
||||
@@ -2047,13 +2121,20 @@ static void bot_ride(
|
||||
}
|
||||
else if (fabsf(action->throttle.i) > 0.3f || fabsf(action->throttle.j) > 0.3f)
|
||||
{
|
||||
if (moved < 0.03f)
|
||||
/* (making no way where it pushes: a jeep's way along its heading,
|
||||
however its wheels spin) */
|
||||
real forward_speed = drive == _vehicle_bot_drive_facing ?
|
||||
(action->throttle.i > 0.0f ? 1.0f : -1.0f) *
|
||||
dot_product3d(&vehicle->object.translational_velocity, &forward) :
|
||||
moved;
|
||||
|
||||
if (forward_speed < 0.02f)
|
||||
{
|
||||
bot->drive_moving_ticks = 0;
|
||||
if (++bot->drive_stuck_ticks >= 40)
|
||||
if (++bot->drive_stuck_ticks >= 45)
|
||||
{
|
||||
bot->drive_stuck_ticks = 0;
|
||||
bot->reverse_ticks = 30;
|
||||
bot->reverse_ticks = 40;
|
||||
bot->path_time = game_time_get() - PATH_REFRESH_TICKS;
|
||||
bots.stucks++;
|
||||
if (++bot->drive_stucks >= 4)
|
||||
|
||||
Reference in new issue
Block a user