| 1435 | #define HOMING_FIND_LOC_INTERVAL 0.20f |
| 1436 | |
| 1437 | object *HomingAquireTarget(object *obj) { |
| 1438 | object *track_goal = ObjGet(obj->ctype.laser_info.track_handle); |
| 1439 | object *weapon_parent = ObjGet(obj->parent_handle); |
| 1440 | |
| 1441 | // Forces its parent to itself if there is no parent |
| 1442 | if (weapon_parent == NULL) { |
| 1443 | weapon_parent = obj; |
| 1444 | } |
| 1445 | |
| 1446 | // Determine if the current track_goal is valid |
| 1447 | if (track_goal) { |
| 1448 | bool f_locked = false; |
| 1449 | |
| 1450 | vector to_target = track_goal->pos - obj->pos; |
| 1451 | float dist_to_target = vm_NormalizeVector(&to_target) - track_goal->size - obj->size; |
| 1452 | |
| 1453 | if (obj->type == OBJ_GHOST || obj->type == OBJ_DUMMY || |
| 1454 | (obj->type == OBJ_PLAYER && (Players[obj->id].flags & PLAYER_FLAGS_DEAD))) { |
| 1455 | f_locked = false; |
| 1456 | } else if (obj->effect_info && (obj->effect_info->type_flags & EF_CLOAKED)) { |
| 1457 | f_locked = false; |
| 1458 | } else if (to_target * obj->orient.fvec > Weapons[obj->id].homing_fov) { |
| 1459 | if (track_goal == Player_object && Player_object->type == OBJ_PLAYER) { |
| 1460 | float sound_delta; |
| 1461 | float volume; |
| 1462 | |
| 1463 | if (dist_to_target > MAX_HOMING_SOUND_TIME_DIST) { |
| 1464 | sound_delta = MAX_HOMING_SOUND_TIME; |
| 1465 | volume = MAX_GAME_VOLUME / 2.0f; |
| 1466 | } else { |
| 1467 | float percent_near = dist_to_target / (float)MAX_HOMING_SOUND_TIME_DIST; |
| 1468 | |
| 1469 | sound_delta = MAX_HOMING_SOUND_TIME * percent_near; |
| 1470 | volume = MAX_GAME_VOLUME / 2.0f + MAX_GAME_VOLUME / 2.0 * (1.0f - percent_near); |
| 1471 | |
| 1472 | if (sound_delta < MIN_HOMING_SOUND_TIME) { |
| 1473 | sound_delta = MIN_HOMING_SOUND_TIME; |
| 1474 | volume = MAX_GAME_VOLUME; |
| 1475 | } |
| 1476 | } |
| 1477 | |
| 1478 | if (!(obj->type == OBJ_WEAPON && Weapons[obj->id].flags & WF_SILENT_HOMING) && |
| 1479 | !(obj->mtype.phys_info.flags & PF_GUIDED) && |
| 1480 | Players[Player_object->id].last_homing_warning_sound_time + sound_delta < Gametime) { |
| 1481 | fvi_query fq; |
| 1482 | fvi_info hit_info; |
| 1483 | |
| 1484 | fq.p0 = &obj->pos; |
| 1485 | fq.startroom = obj->roomnum; |
| 1486 | fq.p1 = &track_goal->pos; |
| 1487 | fq.rad = 0.0f; |
| 1488 | fq.thisobjnum = OBJNUM(obj); |
| 1489 | fq.ignore_obj_list = NULL; |
| 1490 | fq.flags = /*FQ_TRANSPOINT | */ FQ_CHECK_OBJS | FQ_ONLY_DOOR_OBJ | FQ_NO_RELINK; |
| 1491 | |
| 1492 | fvi_FindIntersection(&fq, &hit_info); |
| 1493 | |
| 1494 | // Only plays sound if there is a LOS between the player and the homing weapon |
no test coverage detected