IW4-Dump-Files/maps/arcadia_stryker.gsc

430 lines
13 KiB
Plaintext

#include common_scripts\utility;
#include maps\_utility;
#include maps\_anim;
#include maps\_vehicle;
#include maps\arcadia;
#include maps\arcadia_code;
STRYKER_TARGET_OFFSET_VEHICLE = 30;
STRYKER_TARGET_OFFSET_HELICOPTER = -80;
STRYKER_MANUAL_AI_DURATION = 20;
setup_stryker_modes()
{
level.stryker_settings[ "ai" ] = spawnStruct();
level.stryker_settings[ "ai" ].target_engage_duration = 3.0; // number of seconds the stryker will shoot at a target
level.stryker_settings[ "ai" ].target_engage_break_time = 3.0; // number of seconds the stryker will wait before searching for a new target when no target is found
level.stryker_settings[ "ai" ].target_min_range = 300; // min distance the stryker will search for targets
level.stryker_settings[ "ai" ].target_max_range = 3500; // max distance the stryker will search for targets
level.stryker_settings[ "ai" ].target_min_range_veh = 0; // min distance the stryker will search for targets
level.stryker_settings[ "ai" ].target_max_range_veh = 300; // max distance the stryker will search for targets
level.stryker_settings[ "ai" ].burst_count_min = 3; // min number of bullets per burst
level.stryker_settings[ "ai" ].burst_count_max = 10; // max number of bullets per burst
level.stryker_settings[ "ai" ].burst_delay_min = 8.0; // min wait time between bursts
level.stryker_settings[ "ai" ].burst_delay_max = 15.0; // max wait time between bursts
level.stryker_settings[ "ai" ].fire_time = 0.1; // time between bullets
level.stryker_settings[ "ai" ].getVehicles = false; // should we seek out vehicle targets?
level.stryker_settings[ "manual" ] = spawnStruct();
level.stryker_settings[ "manual" ].target_engage_duration = 4.0; // number of seconds the stryker will shoot at a target
level.stryker_settings[ "manual" ].target_engage_break_time = 0.2; // number of seconds the stryker will wait before searching for a new target when no target is found
level.stryker_settings[ "manual" ].target_min_range = 0; // min distance the stryker will search for targets
level.stryker_settings[ "manual" ].target_max_range = 4500; // max distance the stryker will search for targets
level.stryker_settings[ "manual" ].target_min_range_veh = 0; // min distance the stryker will search for targets
level.stryker_settings[ "manual" ].target_max_range_veh = 200; // max distance the stryker will search for targets
level.stryker_settings[ "manual" ].burst_count_min = 15; // min number of bullets per burst
level.stryker_settings[ "manual" ].burst_count_max = 25; // max number of bullets per burst
level.stryker_settings[ "manual" ].burst_delay_min = 0.1; // min wait time between bursts
level.stryker_settings[ "manual" ].burst_delay_max = 0.4; // max wait time between bursts
level.stryker_settings[ "manual" ].fire_time = 0.1; // time between bullets
level.stryker_settings[ "manual" ].getVehicles = true; // should we seek out vehicle targets?
}
stryker_setmode_ai()
{
self.turretMode = "ai";
self.targetSearchOrigin = undefined;
/#
if ( getdvar( "arcadia_debug_stryker" ) == "1" )
iprintln( "^2stryker - " + self.turretMode + " mode" );
#/
self thread stryker_turret_think();
}
stryker_setmode_manual( origin )
{
self endon( "death" );
assert( isdefined( origin ) );
self notify( "stryker_setmode_manual" );
self endon( "stryker_setmode_manual" );
self.turretMode = "manual";
self.targetSearchOrigin = origin;
self thread stryker_turret_think();
/#
if ( getdvar( "arcadia_debug_stryker" ) == "1" )
iprintln( "^2stryker - " + self.turretMode + " mode" );
#/
wait STRYKER_MANUAL_AI_DURATION;
thread stryker_suppression_complete_dialog();
thread stryker_laser_reminder_dialog();
thread stryker_setmode_ai();
}
stryker_turret_think()
{
/#
assert( isdefined( self.turretMode ) );
assert( isdefined( level.stryker_settings[ self.turretMode ] ) );
#/
self notify( "stryker_turret_think" );
self endon( "stryker_turret_think" );
self endon( "death" );
self thread stryker_scan_stop();
for(;;)
{
target = self stryker_get_target();
if ( !isdefined( target ) )
{
self thread stryker_scan_start();
wait level.stryker_settings[ self.turretMode ].target_engage_break_time;
self stryker_scan_stop();
continue;
}
self stryker_shoot_target( target );
wait level.stryker_settings[ self.turretMode ].target_engage_break_time;
}
}
stryker_scan_start()
{
self endon( "death" );
self endon( "stop_scanning" );
assert( !isdefined( self.scanning ) );
self.scanning = true;
/#
if ( getdvar( "arcadia_debug_stryker" ) == "1" )
iprintln( "^2stryker - scan start" );
#/
alternate = 0;
for(;;)
{
// get random point in front of stryker
forward = anglesToForward( self.angles ) * 1000;
if ( alternate == 0 )
{
alternate = 1;
sideOffset = randomintrange( -1500, -200 );
}
else
{
alternate = 0;
sideOffset = randomintrange( 200, 1500 );
}
right = anglesToRight( self.angles ) * sideOffset;
aimPoint = self.origin + forward + right;
aimPoint = ( aimPoint[ 0 ], aimPoint[ 1 ], self.origin[ 2 ] );
self SetTurretTargetVec( aimPoint );
wait randomfloatrange( 2.0, 5.0 );
}
}
stryker_scan_stop()
{
/#
if ( getdvar( "arcadia_debug_stryker" ) == "1" )
iprintln( "^2stryker - scan stop" );
#/
self clearTurretTarget();
self.scanning = undefined;
self notify( "stop_scanning" );
}
stryker_get_target()
{
SEARCH_ORIGIN = self.origin;
if ( isdefined( self.targetSearchOrigin ) )
SEARCH_ORIGIN = self.targetSearchOrigin;
SEARCH_RADIUS_MIN = level.stryker_settings[ self.turretMode ].target_min_range;
SEARCH_RADIUS_MAX = level.stryker_settings[ self.turretMode ].target_max_range;
SEARCH_RADIUS_MIN_VEH = level.stryker_settings[ self.turretMode ].target_min_range_veh;
SEARCH_RADIUS_MAX_VEH = level.stryker_settings[ self.turretMode ].target_max_range_veh;
GET_VEHICLES = level.stryker_settings[ self.turretMode ].getVehicles;
eTargets = [];
enemyTeam = common_scripts\utility::get_enemy_team( self.script_team );
possibleTargets = [];
vehicleTargets = [];
destructibleTargets = [];
sentientTargets = [];
prof_begin( "stryker_ai" );
// ADD VEHICLE AND DESTRUCTIBLE VEHICLE TARGETS
if ( GET_VEHICLES )
{
assert( isdefined( level.vehicles[ enemyTeam ] ) );
vehicleTargets = level.vehicles[ enemyTeam ];
vehicleTargets = get_array_of_closest( SEARCH_ORIGIN, vehicleTargets, undefined, undefined, SEARCH_RADIUS_MAX_VEH, SEARCH_RADIUS_MIN_VEH );
ents = getentarray( "destructible_vehicle", "targetname" );
foreach( ent in ents )
{
if ( isdefined( ent.exploded ) )
continue;
destructibleTargets[ destructibleTargets.size ] = ent;
}
ents = undefined;
destructibleTargets = get_array_of_closest( SEARCH_ORIGIN, destructibleTargets, undefined, undefined, SEARCH_RADIUS_MAX_VEH, SEARCH_RADIUS_MIN_VEH );
}
// ADD AI TARGETS
sentientTargets = getaiarray( enemyTeam );
sentientTargets = get_array_of_closest( SEARCH_ORIGIN, sentientTargets, undefined, undefined, SEARCH_RADIUS_MAX, SEARCH_RADIUS_MIN );
// BUILD FULL ARRAY OF ALL POSSIBLE TARGETS
possibleTargets = array_combine( possibleTargets, vehicleTargets );
possibleTargets = array_combine( possibleTargets, destructibleTargets );
possibleTargets = array_combine( possibleTargets, sentientTargets );
// clear unused arrays
vehicleTargets = undefined;
destructibleTargets = undefined;
sentientTargets = undefined;
foreach( target in possibleTargets )
{
// threatbias - if this is an ignored group then dont consider this target
if ( isdefined( self.threatBiasGroup ) && IsSentient( target ) )
{
bias = getThreatBias( target getThreatBiasGroup(), self.threatBiasGroup );
if ( bias <= -1000000 )
continue;
}
// don't shoot at targets that are supposed to be ignored
if ( isdefined( target.ignoreme ) && target.ignoreme == true )
continue;
if ( isAI( target ) )
{
if ( !sightTracePassed( self getTagOrigin( "tag_flash" ), target getEye(), false, self ) )
continue;
}
prof_end( "stryker_ai" );
return target;
}
prof_end( "stryker_ai" );
return undefined;
}
stryker_get_target_offset( target )
{
if ( isAi( target ) )
{
eye = target getEye();
zOffset = eye[ 2 ] - target.origin[ 2 ];
return ( 0, 0, zOffset );
}
if ( isdefined( target.vehicletype ) )
{
if ( target isHelicopter() )
return ( 0, 0, STRYKER_TARGET_OFFSET_HELICOPTER );
return ( 0, 0, STRYKER_TARGET_OFFSET_VEHICLE );
}
if( isdefined( target.destuctableinfo ) )
return ( 0, 0, STRYKER_TARGET_OFFSET_VEHICLE );
return ( 0, 0, 0 );
}
stryker_shoot_target( target )
{
self notify( "stryker_shoot_target" );
self endon( "stryker_shoot_target" );
if ( !isdefined( target ) )
return;
// aim the gun at the target and wait for it to be lined up or timeout
targetOffset = stryker_get_target_offset( target );
/#
if ( getdvar( "arcadia_debug_stryker" ) == "1" )
{
iprintln( "^2stryker - shooting a target" );
if ( self.turretMode == "ai" )
thread draw_line_for_time( self.origin + ( 0, 0, 100 ), target.origin + targetOffset, 1, 1, 0, 2.0 );
else
thread draw_line_for_time( self.origin + ( 0, 0, 100 ), target.origin + targetOffset, 1, 0, 0, 2.0 );
}
#/
self setTurretTargetEnt( target, targetOffset );
if ( self.lastTarget != target )
self waittill_notify_or_timeout( "turret_rotate_stopped", 1.0 );
self.lastTarget = target;
startTime = getTime();
while( isdefined( target ) )
{
// thread ends after level.stryker_settings[ self.turretMode ].target_engage_duration time elapses
timeElapsed = getTime() - startTime;
if ( timeElapsed >= level.stryker_settings[ self.turretMode ].target_engage_duration * 1000 )
return;
self stryker_fire_shots( target, targetOffset );
wait randomfloatrange( level.stryker_settings[ self.turretMode ].burst_delay_min, level.stryker_settings[ self.turretMode ].burst_delay_max );
}
}
stryker_fire_shots( target, targetOffset )
{
self notify( "stryker_fire_shots" );
self endon( "stryker_fire_shots" );
shots = randomintrange( level.stryker_settings[ self.turretMode ].burst_count_min, level.stryker_settings[ self.turretMode ].burst_count_max );
for( i = 0 ; i < shots ; i++ )
{
if ( isdefined( target ) && isdefined( targetOffset ) )
self fireWeapon( "tag_flash", target, targetOffset, 0.0 );
else
self fireWeapon( "tag_flash", undefined, ( 0, 0, 0 ), 0.0 );
wait level.stryker_settings[ self.turretMode ].fire_time;
}
}
/*
ai_becomes_suppressed()
{
self endon( "death" );
self notify( "ai_becomes_suppressed" );
self endon( "ai_becomes_suppressed" );
/#
if ( getdvar( "arcadia_debug_stryker" ) == "1" )
thread draw_line_to_ent_for_time( ( 0, 0, 10000 ), self, 1, 0, 0, STRYKER_AI_SUPPRESSION_TIME );
#/
self.forceSuppression = true;
wait STRYKER_AI_SUPPRESSION_TIME;
self.forceSuppression = undefined;
}
*/
stryker_suppression_complete_dialog()
{
dialog = [];
dialog[ dialog.size ] = "arcadia_str_targdestroyed"; // Badger One to Hunter Two, target destroyed.
dialog[ dialog.size ] = "arcadia_str_areasuppressed"; // Badger One to Hunter Two, area suppressed.
dialog[ dialog.size ] = "arcadia_str_tasuppressed"; // Badger One to Hunter Two, target area suppressed.
if ( flag( "disable_stryker_dialog" ) )
return;
thread radio_dialogue( dialog[ randomint( dialog.size ) ] );
}
stryker_laser_reminder_dialog()
{
level endon( "golf_course_mansion" );
level endon( "laser_coordinates_received" );
level.stryker notify( "stryker_laser_reminder_dialog" );
level.stryker endon( "stryker_laser_reminder_dialog" );
level.stryker endon( "death" );
for(;;)
{
wait randomintrange( 30, 60 );
if ( !isalive( level.stryker ) )
return;
if ( flag( "disable_stryker_dialog" ) )
continue;
if ( flag_exist( "no_living_enemies" ) && flag( "no_living_enemies" ) )
{
continue;
}
thread laser_hint_print();
rand = randomint( 5 );
switch( rand )
{
case 0:
// Use your designator! Lase targets for the Stryker!
level.foley thread anim_single_queue( level.foley, "arcadia_fly_usedesignator" );
break;
case 1:
// Squad, use your laser designators! Paint targets for the Stryker!
level.foley thread anim_single_queue( level.foley, "arcadia_fly_painttargets" );
break;
case 2:
// All Hunter units, this is Badger One. Lase the target, over.
thread radio_dialogue( "arcadia_str_lasetarget" );
break;
case 3:
// All Hunter units, this is Badger One. Standing by to engage your targets, over.
thread radio_dialogue( "arcadia_str_standingby" );
break;
case 4:
// All Hunter teams, this is Badger One. Paint the target, over.
thread radio_dialogue( "arcadia_str_painttarget" );
break;
}
}
}
stryker_death_wait()
{
level endon( "golf_course_mansion" );
self waittill( "death" );
wait 1.5;
// All Hunter units, be advised, we just lost Badger One. Stryker support is unavailable, I repeat, Stryker support is unavailable. Make do with what you got. Out.
level.foley thread anim_single_queue( level.foley, "arcadia_fly_lostbadgerone" );
}