1 #using scripts\shared\ai_shared;
2 #using scripts\shared\array_shared;
3 #using scripts\shared\clientfield_shared;
4 #using scripts\shared\flag_shared;
5 #using scripts\shared\flagsys_shared;
6 #using scripts\shared\system_shared;
7 #using scripts\shared\util_shared;
8 #using scripts\shared\vehicleriders_shared;
10 #insert scripts\shared\shared.gsh;
11 #insert scripts\shared\version.gsh;
211 #define MAX_OCCUPY_NO_TARGET_TIME 3600
217 level._turrets = SpawnStruct();
231 w_weapon =
self SeatGetWeapon( n_index );
251 self notify(
"laser_death_thread_stop" );
252 self endon(
"laser_death_thread_stop" );
253 self waittill(
"death" );
272 self notify(
"laser_death_thread_stop" );
278 self endon(
"watch_for_flash_and_stun" );
279 self endon(
"death" );
283 self waittill(
"flashbang", pct_dist, pct_angle, attacker, team );
284 self notify(
"damage", 1, attacker, undefined, undefined, undefined, undefined, undefined, undefined,
"flash_grenade" );
290 self notify(
"watch_for_flash_and_stun_end" );
291 self endon(
"watch_for_flash_and_stun" );
292 self endon(
"death" );
298 self waittill(
"damage",
damage, attacker, direction, point, type, tagName, modelName, partname, weapon );
302 if ( isdefined(
self.stunned ) )
309 stop( n_index,
true );
311 wait RandomFloatRange( 5, 7 );
313 self.stunned = undefined;
320 self notify(
"emp_thread_stop" );
321 self endon(
"emp_thread_stop" );
322 self endon(
"death" );
326 self waittill(
"damage",
damage, attacker, direction, point, type, tagName, modelName, partname, weapon );
330 if ( isdefined(
self.
emped ) )
342 stop( n_index,
true );
344 wait RandomFloatRange( 5, 7 );
346 self.emped = undefined;
362 self.takedamage =
true;
367 self notify(
"emp_thread_stop" );
376 self.team = str_team;
381 str_team = undefined;
385 str_team =
self.team;
387 if ( !isdefined( s_turret.str_team ) )
389 s_turret.str_team = str_team;
449 return (
self GetSeatOccupant( n_index ) );
458 s_turret.b_needs_user =
true;
463 self notify(
"watch_for_flash_and_stun_end" );
464 s_turret.b_needs_user =
false;
483 s_turret.priority_target_array =
a_ents;
501 if ( !IsArray( ent_or_ent_array ) )
504 a_new_targets[ 0 ] = ent_or_ent_array;
508 a_new_targets = ent_or_ent_array;
512 if ( isdefined( s_turret.priority_target_array ) )
514 a_new_targets = ArrayCombine( s_turret.priority_target_array, a_new_targets,
true,
false );
517 s_turret.priority_target_array = a_new_targets;
533 s_turret.priority_target_array = undefined;
551 s_turret.a_ignore_target_array =
a_ents;
567 s_turret.a_ignore_target_array = undefined;
572 self endon(
"death" );
574 while ( IsAlive(
get_user( n_index ) ) )
593 return ( IsAlive( ai_current_user ) && ( ai_user == ai_current_user ) );
612 s_turret.n_burst_fire_min = n_fire_min;
613 s_turret.n_burst_fire_max = n_fire_max;
614 s_turret.n_burst_wait_min = n_wait_min;
615 s_turret.n_burst_wait_max = n_wait_max;
622 s_turret.n_torso_targetting_offset = n_torso_targetting_offset;
629 s_turret.n_target_leading_factor = n_target_leading_factor;
647 if ( !isdefined( n_angle ) )
649 if ( s_turret.str_guidance_type !=
"none" )
661 self SetOnTargetAngle( n_angle, n_index - 1 );
665 self SetOnTargetAngle( n_angle );
684 if ( !isdefined( v_offset ) )
689 if ( !isdefined( n_index ) || n_index == 0 )
691 self SetTargetEntity(
e_target, v_offset );
695 self SetTargetEntity(
e_target, v_offset, n_index - 1 );
700 s_turret.v_offset = v_offset;
706 if ( s_turret.str_weapon_type ==
"bullet" )
710 if ( IsSentient(
self ) && IsSentient(
e_target ) )
712 z_offset = ( IsVehicle(
e_target ) ? 0 :
VAL( s_turret.n_torso_targetting_offset, 0 ) );
716 z_offset = RandomIntRange( 40, 50 );
720 z_offset = RandomIntRange( 20, 60 );
724 z_offset = RandomIntRange( 40, 60 );
727 if ( isdefined(
e_target.z_target_offset_override) )
729 if( !isdefined(z_offset) )
733 z_offset +=
e_target.z_target_offset_override;
739 v_offset = ( 0, 0, z_offset );
742 if (
VAL( s_turret.n_target_leading_factor, 0 ) != 0 && isdefined(
e_target ) && IsSentient(
self ) && IsSentient(
e_target ) && !IsVehicle(
e_target ) )
745 v_offset += velocity * s_turret.n_target_leading_factor;
773 if ( isdefined( e_current_target ) )
775 return ( e_current_target ==
e_target );
796 s_turret.e_next_target = undefined;
797 s_turret.e_target = undefined;
799 if ( !isdefined( n_index ) || ( n_index == 0 ) )
801 self ClearTurretTarget();
805 self ClearGunnerTarget( n_index - 1 );
822 s_turret.n_target_flags = n_flags;
828 return ( ( n_current_flags & n_flags ) == n_flags);
845 s_turret.n_max_target_distance_squared = n_distance * n_distance;
861 s_turret.n_min_target_distance_squared = n_distance * n_distance;
877 s_turret.n_min_target_distance_squared = n_distance_squared;
893 assert( isdefined( n_index ) && ( n_index >= 0 ),
"Invalid index specified to fire vehicle turret." );
897 self FireWeapon( 0, s_turret.e_target );
902 if(isdefined(ai_current_user) &&
IS_TRUE(ai_current_user.is_disabled))
905 if ( isdefined( s_turret.e_target ) )
907 self SetGunnerTargetEnt( s_turret.e_target, s_turret.v_offset, n_index - 1 );
910 self FireWeapon( n_index, s_turret.e_target, s_turret.v_offset, s_turret.e_parent );
913 s_turret.n_last_fire_time = GetTime();
926 function stop( n_index, b_clear_target =
false )
930 s_turret.e_next_target = undefined;
931 s_turret.e_target = undefined;
935 if ( b_clear_target )
940 self notify(
"_stop_turret" +
_index( n_index ) );
955 Assert( isdefined( n_time ),
"n_time is a required parameter for _turet::fire_for_time." );
957 self endon(
"death" );
958 self endon(
"drone_death" );
960 self endon(
"_stop_turret" +
_index( n_index ) );
962 self endon(
"turret_disabled" +
_index( n_index ) );
966 self notify(
"_fire_turret_for_time" +
_index( n_index ) );
967 self endon(
"_fire_turret_for_time" +
_index( n_index ) );
969 b_fire_forever =
false;
972 b_fire_forever =
true;
978 assert( n_time >= w_weapon.fireTime,
"Fire time (" + n_time +
") must be greater than the weapon's fire time. weapon fire time = " + w_weapon.fireTime );
982 while ( ( n_time > 0 ) || b_fire_forever )
988 if ( !b_fire_forever )
990 n_time -= n_burst_time;
1012 Assert( isdefined(
e_target ),
"Undefined target passed to shoot_at_target()." );
1014 self endon(
"drone_death" );
1015 self endon(
"death" );
1028 self endon(
"drone_death" );
1029 self endon(
"death" );
1030 self endon(
"_stop_turret" +
_index( n_index ) );
1031 self endon(
"turret_disabled" +
_index( n_index ) );
1034 self notify(
"_shoot_turret_at_target" +
_index( n_index ) );
1035 self endon(
"_shoot_turret_at_target" +
_index( n_index ) );
1042 if ( !isdefined( b_just_once ) )
1044 b_just_once =
false;
1049 if ( !isdefined(
self.aim_only_no_shooting ) )
1068 wait
VAL(
self.waittill_turret_on_target_delay, 0.5 );
1069 if ( !isdefined( n_index ) || ( n_index == 0 ) )
1071 self waittill(
"turret_on_target" );
1075 self waittill(
"gunner_turret_on_target" );
1108 function enable( n_index, b_user_required, v_offset )
1114 self notify(
"turret_enabled" +
_index( n_index ) );
1116 if ( isdefined( b_user_required ) && ( !b_user_required ) )
1139 self.script_auto_use = b_enable;
1178 self notify(
"turret_disabled" +
_index( n_index ) );
1204 if ( isdefined( s_turret.pause ) )
1206 s_turret.pause_time = s_turret.pause_time + time;
1211 s_turret.pause_time = time;
1228 s_turret.pause = undefined;
1231 #define TURRET_LOSE_SIGHT_TIME 3000
1236 TURRET_THINK_TIME = Max( 1.5,
get_weapon( n_index ).fireTime );
1238 no_target_start_time = 0;
1240 self endon(
"death" );
1241 self endon(
"turret_disabled" +
_index( n_index ) );
1245 self notify(
"_turret_think" +
_index( n_index ) );
1246 self endon(
"_turret_think" +
_index( n_index ) );
1256 if ( isdefined( s_turret.has_laser ) )
1265 n_time_now = GetTime();
1270 wait TURRET_THINK_TIME;
1276 if ( !isdefined( s_turret.e_target )
1277 || ( s_turret.e_target.health < 0 )
1278 || !IsInArray( a_potential_targets, s_turret.e_target )
1284 e_original_next_target = s_turret.e_next_target;
1290 if ( isdefined( s_turret.e_next_target ) )
1292 s_turret.b_target_out_of_range = undefined;
1293 s_turret.n_time_lose_sight = undefined;
1294 no_target_start_time = 0;
1300 if ( s_turret.e_next_target !== e_original_next_target )
1302 self notify(
"has_new_target", s_turret.e_next_target );
1308 if ( !isdefined(
self.do_not_clear_targets_during_think ) || !
self.do_not_clear_targets_during_think )
1313 if ( no_target_start_time == 0 )
1315 no_target_start_time = n_time_now;
1319 target_wait_time = ( n_time_now - no_target_start_time );
1322 if ( isdefined(s_turret.occupy_no_target_time) )
1324 occupy_time = s_turret.occupy_no_target_time;
1332 if(!
IS_TRUE(s_turret.disable_ai_getoff))
1334 bWasPlayerTarget = isdefined( s_turret.e_last_target ) && ( s_turret.e_last_target.health > 0 ) && IsPlayer(s_turret.e_last_target);
1336 if(bWasPlayerTarget)
1337 occupy_time = occupy_time / 4;
1341 bWasPlayerTarget =
false;
1344 if ( target_wait_time >= occupy_time )
1350 if ( !
IS_TRUE(s_turret.disable_ai_getoff) &&
1356 wait TURRET_THINK_TIME;
1360 #define NEARBY_DISTANCE_SQ SQR( 300 )
1361 #define NEARBY_DISTANCE_Z 60
1362 #define NEARBY_ENEMY_TIME 1000
1365 has_nearby_enemy =
false;
1370 if ( !IsDefined( ai_user ) )
1372 return has_nearby_enemy;
1375 if ( !IsDefined( turret.next_nearby_enemy_time ) )
1377 turret.next_nearby_enemy_time = time;
1380 if ( time >= turret.next_nearby_enemy_time )
1382 players = GetPlayers();
1384 foreach ( player
in players )
1386 if ( turret.team == player.team )
1394 has_nearby_enemy =
true;
1402 return has_nearby_enemy;
1408 if (
IS_TRUE(
self.b_target_out_of_range ) )
1412 else if ( isdefined(
self.n_time_lose_sight ) )
1422 self endon(
"death" );
1423 self endon(
"turret_disabled" +
_index( n_index ) );
1424 self endon(
"_turret_think" +
_index( n_index ) );
1428 ai_user =
self GetSeatOccupant( n_index );
1430 if ( IsActor( ai_user ) )
1440 stop( n_index,
true );
1444 ai_user =
self GetSeatOccupant( n_index );
1446 if ( IsActor( ai_user ) )
1456 self endon(
"death" );
1457 ai_user endon(
"death" );
1458 self endon(
"turret_disabled" +
_index( n_index ) );
1459 self endon(
"_turret_think" +
_index( n_index ) );
1460 self endon(
"exit_vehicle" );
1464 ai_user waittill(
"damage", n_amount, e_attacker, v_org, v_dir, str_mod );
1468 if(isdefined(s_turret))
1470 if(!isdefined(s_turret.e_next_target) && !isdefined(s_turret.e_target))
1472 s_turret.e_last_target = e_attacker;
1480 ai_user =
self GetSeatOccupant( n_index );
1482 if ( IsAlive( ai_user ) )
1484 if ( IsActor( ai_user ) )
1486 ai_user endon(
"death" );
1488 else if ( IsPlayer( ai_user ) )
1490 self notify(
"turret_disabled" +
_index( n_index ) );
1502 s_turret.pause_start_time = GetTime();
1504 while ( isdefined( s_turret.pause ) )
1506 if ( s_turret.pause_time > 0 )
1509 paused_time = time - s_turret.pause_start_time;
1510 if( paused_time > s_turret.pause_time )
1512 s_turret.pause = undefined;
1528 if ( IsAlive( ai_user ) && (
IS_TRUE( ai_user.turret_auto_use ) || (isdefined(bExitIfAutomatedOnly) && !bExitIfAutomatedOnly)) )
1536 const NEW_USER_THINK_TIME = 3;
1538 self endon(
"death" );
1539 self endon(
"_turret_think" +
_index( n_index ) );
1540 self endon(
"turret_disabled" +
_index( n_index ) );
1546 str_gunner_pos =
"driver";
1550 str_gunner_pos =
"gunner" + n_index;
1556 wait NEW_USER_THINK_TIME;
1561 a_users = GetAIArchetypeArray(
"human" , str_team );
1562 a_ai_by_vehicle = ArraySortClosest( GetAIArray(),
self.origin, 99999, 0, 300 );
1564 if ( a_users.size > 0 )
1566 a_potential_users = [];
1567 if ( isdefined(
self.script_auto_use_radius ) )
1569 a_potential_users = ArraySort( a_users,
self.origin,
true, a_potential_users.size,
self.script_auto_use_radius );
1573 a_potential_users = ArraySort( a_users,
self.origin,
true );
1576 ai_user = undefined;
1577 foreach ( ai
in a_potential_users )
1579 b_enemy_close =
false;
1580 foreach ( ai_enemy
in a_ai_by_vehicle )
1582 if ( ai_enemy.team != ai.team )
1584 b_enemy_close =
true;
1589 if ( b_enemy_close )
1608 if ( IsAlive( ai_user ) )
1610 ai_user.turret_auto_use =
true;
1642 self endon(
"death" );
1643 self endon(
"_turret_think" +
_index( n_index ) );
1644 self endon(
"turret_disabled" +
_index( n_index ) );
1647 v_color = ( 0, 0, 1 );
1651 if ( !GetDvarint(
"g_debugTurrets") )
1662 v_color = ( 1, 1, 0 );
1666 v_color = ( 0, 1, 0 );
1670 if ( !isdefined( str_team ) )
1672 str_team =
"no team";
1675 str_target =
"target > ";
1686 str_target +=
"player";
1690 str_target +=
"vehicle";
1694 str_target +=
"drone";
1696 else if ( isdefined(
e_target.classname ) )
1703 str_target +=
"none";
1706 str_debug =
self GetEntNum() +
":" + str_team +
":" + str_target;
1707 Record3DText( str_debug,
self.origin, v_color,
"Script",
self );
1727 s_turret = undefined;
1729 if ( IsVehicle(
self ) )
1731 if ( isdefined(
self.a_turrets ) && isdefined(
self.a_turrets[ n_index ] ) )
1733 s_turret =
self.a_turrets[ n_index ];
1738 s_turret =
self._turret;
1741 if ( !isdefined( s_turret ) )
1758 if ( isdefined(
self.a_turrets ) && isdefined(
self.a_turrets[ n_index ] ) )
1775 self endon(
"death" );
1779 if ( w_weapon == level.weaponNone )
1781 AssertMsg(
"Cannot initialize turret. No weapon info." );
1787 if ( IsVehicle(
self ) )
1793 AssertMsg(
"Misc turrets are no longer supported, please use a supported script_vehicle turret" );
1796 s_turret.w_weapon = w_weapon;
1799 s_turret.is_enabled =
false;
1800 s_turret.e_parent =
self;
1801 s_turret.e_target = undefined;
1802 s_turret.b_ignore_line_of_sight =
false;
1803 s_turret.v_offset = (0, 0, 0);
1804 s_turret.n_burst_fire_time = 0;
1805 s_turret.n_max_target_distance_squared = undefined;
1806 s_turret.n_min_target_distance_squared = undefined;
1809 s_turret.str_weapon_type =
"bullet";
1810 s_turret.str_guidance_type =
"none";
1812 s_turret.str_weapon_type = w_weapon.type;
1813 s_turret.str_guidance_type = w_weapon.guidedMissileType;
1829 s_turret.rightarc = s_turret.w_weapon.rightArc;
1830 s_turret.leftarc = s_turret.w_weapon.leftArc;
1831 s_turret.toparc = s_turret.w_weapon.topArc;
1832 s_turret.bottomarc = s_turret.w_weapon.bottomArc;
1856 AssertMsg(
"unsupported turret weapon type." );
1884 Assert( isdefined( n_index ) && ( n_index >= 0 ),
"Invalid index specified to initialize vehicle turret." );
1886 s_turret = SpawnStruct();
1888 v_angles =
self GetSeatFiringAngles( n_index );
1889 if ( isdefined( v_angles ) )
1891 s_turret.n_rest_angle_pitch = 0;
1892 s_turret.n_rest_angle_yaw = 0;
1898 s_turret.str_tag_flash =
"tag_flash";
1899 s_turret.str_tag_pivot =
"tag_barrel";
1903 s_turret.str_tag_flash =
"tag_gunner_flash1";
1904 s_turret.str_tag_pivot =
"tag_gunner_barrel1";
1908 s_turret.str_tag_flash =
"tag_gunner_flash2";
1909 s_turret.str_tag_pivot =
"tag_gunner_barrel2";
1913 s_turret.str_tag_flash =
"tag_gunner_flash3";
1914 s_turret.str_tag_pivot =
"tag_gunner_barrel3";
1918 s_turret.str_tag_flash =
"tag_gunner_flash4";
1919 s_turret.str_tag_pivot =
"tag_gunner_barrel4";
1927 s_turret.e_trace_ignore =
self;
1930 if ( !isdefined(
self.a_turrets ) )
1932 self.a_turrets = [];
1935 self.a_turrets[n_index] = s_turret;
1941 if ( isdefined( tag_origin ) )
1960 self endon(
"terminate_all_turrets_firing" );
1962 if ( n_max_time < 0 )
1972 if ( !isdefined( n_burst_time ) || ( n_burst_time > n_max_time ) )
1974 n_burst_time = n_max_time;
1977 if ( s_turret.n_burst_fire_time >= n_burst_time )
1979 s_turret.n_burst_fire_time = 0;
1981 n_time_since_last_shot = ( GetTime() - s_turret.n_last_fire_time ) / 1000;
1982 if ( n_time_since_last_shot < n_burst_wait )
1984 wait ( n_burst_wait - n_time_since_last_shot );
1989 n_burst_time = n_burst_time - s_turret.n_burst_fire_time;
1993 n_fire_time = w_weapon.fireTime;
1996 while ( n_total_time < n_burst_time )
2000 n_total_time += n_fire_time;
2001 s_turret.n_burst_fire_time += n_fire_time;
2006 if ( n_burst_wait > 0 )
2011 return n_burst_time + n_burst_wait;
2026 if ( isdefined( s_turret.n_burst_fire_min ) && isdefined( s_turret.n_burst_fire_max ) )
2028 if ( s_turret.n_burst_fire_min == s_turret.n_burst_fire_max )
2030 n_time = s_turret.n_burst_fire_min;
2034 n_time = RandomFloatRange( s_turret.n_burst_fire_min, s_turret.n_burst_fire_max );
2037 else if ( isdefined( s_turret.n_burst_fire_max ) )
2039 n_time = RandomFloatRange( 0, s_turret.n_burst_fire_max );
2057 if ( isdefined( s_turret.n_burst_wait_min ) && isdefined( s_turret.n_burst_wait_max ) )
2059 if ( s_turret.n_burst_wait_min == s_turret.n_burst_wait_max )
2061 n_time = s_turret.n_burst_wait_min;
2065 n_time = RandomFloatRange( s_turret.n_burst_wait_min, s_turret.n_burst_wait_max );
2068 else if ( isdefined( s_turret.n_burst_wait_max ) )
2070 n_time = RandomFloatRange( 0, s_turret.n_burst_wait_max );
2085 return STR( n_index );
2103 if ( isdefined( a_priority_targets ) && ( a_priority_targets.size > 0 ) )
2106 return( a_priority_targets );
2113 a_potential_targets = [];
2116 if (
self.use_non_teambased_enemy_selection ===
true && !level.teambased )
2124 a_ai_targets = GetAIArray();
2125 a_all_targets = ArrayCombine( a_all_targets, a_ai_targets,
true,
false );
2130 a_all_targets = ArrayCombine( a_all_targets, level.players,
true,
false );
2135 a_all_targets = ArrayCombine( a_all_targets, level.vehicles_list,
true,
false );
2139 for ( i = 0; i < a_all_targets.size; i++ )
2155 a_potential_targets[ a_potential_targets.size ] =
e_target;
2158 else if ( isdefined( str_team ) )
2160 str_opposite_team =
"allies";
2161 if ( str_team ==
"allies" )
2163 str_opposite_team =
"axis";
2168 a_ai_targets = GetAITeamArray( str_opposite_team );
2169 if(
IS_TRUE( level.team_free_targeting ) )
2171 a_ai_targets = ArrayCombine( GetAITeamArray(
"free" ), a_ai_targets,
true,
false );
2173 a_potential_targets = ArrayCombine( a_potential_targets, a_ai_targets,
true,
false );
2178 a_potential_targets = ArrayCombine( a_potential_targets, level.aliveplayers[ str_opposite_team ],
true,
false );
2189 a_vehicle_targets = GetVehicleTeamArray( str_opposite_team );
2190 a_potential_targets = ArrayCombine( a_potential_targets, a_vehicle_targets,
true,
false );
2194 if ( isdefined( s_turret.e_target ) && !IsInArray( a_potential_targets, s_turret.e_target ) )
2196 a_potential_targets[ a_potential_targets.size ] = s_turret.e_target;
2203 if ( isdefined( str_team ) )
2205 a_valid_targets = [];
2207 for ( i = 0; i < a_potential_targets.size; i++ )
2210 ignore_target =
false;
2212 assert( isdefined(
e_target ),
"Undefined potential turret target." );
2217 ignore_target =
true;
2221 ignore_target =
true;
2225 ignore_target =
true;
2227 else if ( isplayer(
e_target ) &&
e_target hasPerk(
"specialty_nottargetedbysentry" ) )
2229 ignore_target =
true;
2232 if ( !ignore_target )
2234 a_valid_targets[ a_valid_targets.size ] =
e_target;
2239 a_potential_targets = a_valid_targets;
2242 a_targets = a_potential_targets;
2244 if ( isdefined( s_turret ) && isdefined( s_turret.a_ignore_target_array ) )
2248 found_bad_target = 0;
2249 a_targets = a_potential_targets;
2251 for ( i = 0; i < a_targets.size; i++ )
2254 found_bad_target = 0;
2256 for ( j = 0; j < s_turret.a_ignore_target_array.size; j++ )
2258 if (
e_target == s_turret.a_ignore_target_array[ j ] )
2260 ArrayRemoveValue( a_potential_targets,
e_target );
2261 found_bad_target = 1;
2267 if ( !found_bad_target )
2274 return a_potential_targets;
2280 if ( isdefined( s_turret.n_max_target_distance_squared ) || isdefined( s_turret.n_min_target_distance_squared ) )
2285 n_dist_squared = DistanceSquared(
e_target.origin,
self.origin );
2287 if ( n_dist_squared >
VAL( s_turret.n_max_target_distance_squared, 811711611 ) )
2290 if ( n_dist_squared <
VAL( s_turret.n_min_target_distance_squared, 0 ) )
2299 a_targets = undefined;
2304 if ( isdefined( s_turret.priority_target_array ) )
2308 found_bad_target = 0;
2309 a_targets = s_turret.priority_target_array;
2312 for ( i = 0; i < a_targets.size; i++ )
2315 bad_index = undefined;
2335 if ( isdefined( bad_index ) )
2337 s_turret.priority_target_array = a_targets;
2338 ArrayRemoveValue( s_turret.priority_target_array,
e_target );
2339 found_bad_target = 1;
2345 if ( !found_bad_target )
2347 return ( s_turret.priority_target_array );
2352 if ( s_turret.priority_target_array.size <= 0 )
2354 s_turret.priority_target_array = undefined;
2355 self notify(
"target_array_destroyed" );
2362 return( a_targets );
2368 return [[ s_turret.func_get_best_target ]]( a_potential_targets, n_index );
2373 e_best_target = undefined;
2375 while ( !isdefined( e_best_target ) && ( a_potential_targets.size > 0 ) )
2377 e_closest_target = ArrayGetClosest(
self.origin, a_potential_targets );
2379 if ( !isdefined( e_closest_target ) )
2385 e_best_target = e_closest_target;
2389 ArrayRemoveValue( a_potential_targets, e_closest_target );
2393 return e_best_target;
2436 b_trace_passed =
true;
2438 if ( b_target_in_view )
2440 if ( !s_turret.b_ignore_line_of_sight )
2445 if ( b_current_target && !b_trace_passed && !isdefined( s_turret.n_time_lose_sight ) )
2447 s_turret.n_time_lose_sight = GetTime();
2450 else if ( b_current_target )
2452 s_turret.b_target_out_of_range =
true;
2455 return ( b_target_in_view && b_trace_passed );
2477 v_pivot_pos =
self GetTagOrigin( s_turret.str_tag_pivot );
2478 v_angles_to_target = VectorToAngles( v_target - v_pivot_pos );
2480 n_rest_angle_pitch = s_turret.n_rest_angle_pitch +
self.angles[0];
2481 n_rest_angle_yaw = s_turret.n_rest_angle_yaw +
self.angles[1];
2483 n_ang_pitch = AngleClamp180( v_angles_to_target[0] - n_rest_angle_pitch );
2484 n_ang_yaw = AngleClamp180( v_angles_to_target[1] - n_rest_angle_yaw );
2486 b_out_of_range =
false;
2488 if ( n_ang_pitch > 0 )
2490 if ( n_ang_pitch > s_turret.bottomarc )
2492 b_out_of_range =
true;
2497 if ( Abs( n_ang_pitch ) > s_turret.toparc )
2499 b_out_of_range =
true;
2503 if ( n_ang_yaw > 0 )
2505 if ( n_ang_yaw > s_turret.leftarc )
2507 b_out_of_range =
true;
2512 if ( Abs( n_ang_yaw ) > s_turret.rightarc )
2514 b_out_of_range =
true;
2518 return !b_out_of_range;
2533 #define TURRET_TRACE_OFFSET 50
2541 if ( isdefined(
self.good_old_style_turret_tracing ) )
2545 v_start_org =
self GetTagOrigin( s_turret.str_tag_pivot );
2546 if (
e_target SightConeTrace( v_start_org,
self ) > .2 )
2551 a_trace = BulletTrace( v_start_org, v_target,
true, s_turret.e_trace_ignore,
true,
true );
2552 if ( a_trace[
"fraction"] > .6 )
2569 v_start_org =
self GetTagOrigin( s_turret.str_tag_pivot );
2572 if ( SessionModeIsMultiplayerGame() && IsPlayer(
e_target ) )
2575 if ( DistanceSquared( v_start_org, v_target ) < 100*100 )
2578 v_dir_to_target = VectorNormalize( v_target - v_start_org );
2581 v_target -= v_dir_to_target * 75;
2583 if ( SightTracePassed( v_start_org, v_target,
false,
self ) )
2616 s_turret.b_ignore_line_of_sight = b_ignore;
2633 s_turret.occupy_no_target_time = time;
2644 self endon(
"death" );
2645 self notify(
"disable_lens_flare" );
2646 self endon(
"disable_lens_flare" );
2653 if ( IsDefined(
self GetTagOrigin(
"TAG_LASER" ) ) )
2681 case 1:
return "tag_gunner1";
2682 case 2:
return "tag_gunner2";
2683 case 3:
return "tag_gunner3";
2684 case 4:
return "tag_gunner4";
2685 default: AssertMsg(
"unsupported turret index for getting gunner tag." );
2693 case "tag_gunner1":
return 1;
2694 case "tag_gunner2":
return 2;
2695 case "tag_gunner3":
return 3;
2696 case "tag_gunner4":
return 4;