Fix SHIP_FLYING attribute applied too generously; close #96

This commit is contained in:
Dominic Szablewski 2024-05-13 10:54:18 +02:00
parent 0dae020303
commit a342af737e
5 changed files with 18 additions and 8 deletions

View file

@ -42,7 +42,7 @@ void camera_update(camera_t *camera, ship_t *ship, droid_t *droid) {
void camera_update_race_external(camera_t *camera, ship_t *ship, droid_t *droid) {
vec3_t pos = vec3_sub(ship->position, vec3_mulf(ship->dir_forward, 1024));
pos.y -= 200;
camera->section = track_nearest_section(pos, camera->section, NULL);
camera->section = track_nearest_section(pos, vec3(1,1,1), camera->section, NULL);
section_t *next = camera->section->next;
vec3_t target = vec3_project_to_ray(pos, next->center, camera->section->center);
@ -78,7 +78,7 @@ void camera_update_race_intro(camera_t *camera, ship_t *ship, droid_t *droid) {
camera->has_initial_section = true;
}
else {
camera->section = track_nearest_section(pos, camera->section, NULL);
camera->section = track_nearest_section(pos, vec3(1,1,1), camera->section, NULL);
}
camera->position = pos;

View file

@ -467,8 +467,15 @@ void ship_update(ship_t *self) {
self->dir_up.z = (sy * sz) + (cy * sx * cz);
self->prev_section = self->section;
// To find the nearest section to the ship, the original source de-emphasizes
// the .y component when calculating the distance to each section by a
// >> 2 shift. I.e. it tries to find the section that is more closely to the
// horizontal x,z plane (directly underneath the ship), instead of finding
// the section with the "real" closest distance. Hence the bias of
// vec3(1, 0.25, 1) here.
float distance;
self->section = track_nearest_section(self->position, self->section, &distance);
self->section = track_nearest_section(self->position, vec3(1, 0.25, 1), self->section, &distance);
if (distance > 3700) {
flags_add(self->flags, SHIP_FLYING);
}

View file

@ -323,7 +323,7 @@ track_face_t *track_section_get_base_face(section_t *section) {
return face;
}
section_t *track_nearest_section(vec3_t pos, section_t *section, float *distance) {
section_t *track_nearest_section(vec3_t pos, vec3_t bias, section_t *section, float *distance) {
// Start search several sections before current section
for (int i = 0; i < TRACK_SEARCH_LOOK_BACK; i++) {
@ -340,7 +340,10 @@ section_t *track_nearest_section(vec3_t pos, section_t *section, float *distance
junction = section->junction;
}
float d = vec3_len(vec3_sub(pos, section->center));
// Some callers of this function want to de-emphazise the .y component
// of the difference, hence the multiplication with the bias vector.
// For the real, exact difference bias should be vec3(1,1,1)
float d = vec3_len(vec3_mul(vec3_sub(pos, section->center), bias));
if (d < shortest_distance) {
shortest_distance = d;
nearest_section = section;
@ -352,7 +355,7 @@ section_t *track_nearest_section(vec3_t pos, section_t *section, float *distance
if (junction) {
section = junction;
for (int i = 0; i < TRACK_SEARCH_LOOK_AHEAD; i++) {
float d = vec3_len(vec3_sub(pos, section->center));
float d = vec3_len(vec3_mul(vec3_sub(pos, section->center), bias));
if (d < shortest_distance) {
shortest_distance = d;
nearest_section = section;

View file

@ -86,7 +86,7 @@ void track_load_sections(char *file);
bool track_collect_pickups(track_face_t *face);
void track_face_set_color(track_face_t *face, rgba_t color);
track_face_t *track_section_get_base_face(section_t *section);
section_t *track_nearest_section(vec3_t pos, section_t *section, float *distance);
section_t *track_nearest_section(vec3_t pos, vec3_t bias, section_t *section, float *distance);
struct camera_t;
void track_draw(struct camera_t *camera);

View file

@ -195,7 +195,7 @@ void weapons_update(void) {
}
// Track collision
weapon->section = track_nearest_section(weapon->position, weapon->section, NULL);
weapon->section = track_nearest_section(weapon->position, vec3(1,1,1), weapon->section, NULL);
if (weapon_collides_with_track(weapon)) {
for (int p = 0; p < 32; p++) {
vec3_t velocity = vec3(rand_float(-512, 512), rand_float(-512, 512), rand_float(-512, 512));