Traverses the straight-line shot path and gathers object data
| 449 | |
| 450 | // Traverses the straight-line shot path and gathers object data |
| 451 | float TraverseShotPath(tShotData *shot_data) { |
| 452 | float next_scan_dist, scan_radius; |
| 453 | float current_path_dist, dist; |
| 454 | vector start_pos, end_pos, target_pos; |
| 455 | vector shot_dir; |
| 456 | int start_room, end_room; |
| 457 | int flags, fate; |
| 458 | ray_info ray; |
| 459 | bool done, max_distance_reached; |
| 460 | |
| 461 | // Clear out any existing shot scan positions |
| 462 | num_shot_path_positions = 0; |
| 463 | |
| 464 | // Setup the shot's starting data |
| 465 | start_pos = shot_data->start_point; |
| 466 | start_room = shot_data->start_room; |
| 467 | shot_dir = shot_data->dir; |
| 468 | next_scan_dist = shot_data->danger_radius; |
| 469 | scan_radius = shot_data->danger_radius; |
| 470 | |
| 471 | // Start scanning |
| 472 | current_path_dist = 0.0f; |
| 473 | max_distance_reached = false; |
| 474 | done = false; |
| 475 | |
| 476 | while (!done) { |
| 477 | // Check the max shot distance |
| 478 | if ((current_path_dist + next_scan_dist) >= shot_data->max_dist) { |
| 479 | next_scan_dist = shot_data->max_dist - current_path_dist; |
| 480 | max_distance_reached = true; |
| 481 | } |
| 482 | |
| 483 | // Calculate shot's target position |
| 484 | target_pos = start_pos + (shot_dir * next_scan_dist); |
| 485 | |
| 486 | // Cast a ray to see if a wall or any clutter objects lie in the target path |
| 487 | flags = FQ_CHECK_OBJS | FQ_IGNORE_POWERUPS | FQ_IGNORE_WEAPONS | FQ_IGNORE_MOVING_OBJECTS | |
| 488 | FQ_IGNORE_NON_LIGHTMAP_OBJECTS; |
| 489 | fate = |
| 490 | FVI_RayCast(shot_data->object_handle, &start_pos, &target_pos, start_room, shot_data->shot_radius, flags, &ray); |
| 491 | |
| 492 | // Store the ray hit point and room |
| 493 | end_pos = ray.hit_point; |
| 494 | end_room = ray.hit_room; |
| 495 | |
| 496 | // If necessary, calculate the distance from start point to the hit point |
| 497 | if (fate == HIT_NONE) { |
| 498 | dist = next_scan_dist; |
| 499 | } else { |
| 500 | dist = vm_VectorDistance(&start_pos, &end_pos); |
| 501 | } |
| 502 | |
| 503 | // Add the new distance to our total shot path distance |
| 504 | current_path_dist += dist; |
| 505 | |
| 506 | // If it hit a wall, change the direction (perfect reflection) |
| 507 | if (fate == HIT_WALL) { |
| 508 | // Calculate the bounce dir from the current dir and face normal |
no test coverage detected