1763 lines
43 KiB
Plaintext
1763 lines
43 KiB
Plaintext
// IW6 GSC SOURCE
|
|
// Generated by https://github.com/xensik/gsc-tool
|
|
|
|
init_mgturretsettings()
|
|
{
|
|
level.mgturretsettings["easy"]["convergenceTime"] = 2.5;
|
|
level.mgturretsettings["easy"]["suppressionTime"] = 3.0;
|
|
level.mgturretsettings["easy"]["accuracy"] = 0.38;
|
|
level.mgturretsettings["easy"]["aiSpread"] = 2;
|
|
level.mgturretsettings["easy"]["playerSpread"] = 0.5;
|
|
level.mgturretsettings["medium"]["convergenceTime"] = 1.5;
|
|
level.mgturretsettings["medium"]["suppressionTime"] = 3.0;
|
|
level.mgturretsettings["medium"]["accuracy"] = 0.38;
|
|
level.mgturretsettings["medium"]["aiSpread"] = 2;
|
|
level.mgturretsettings["medium"]["playerSpread"] = 0.5;
|
|
level.mgturretsettings["hard"]["convergenceTime"] = 0.8;
|
|
level.mgturretsettings["hard"]["suppressionTime"] = 3.0;
|
|
level.mgturretsettings["hard"]["accuracy"] = 0.38;
|
|
level.mgturretsettings["hard"]["aiSpread"] = 2;
|
|
level.mgturretsettings["hard"]["playerSpread"] = 0.5;
|
|
level.mgturretsettings["fu"]["convergenceTime"] = 0.4;
|
|
level.mgturretsettings["fu"]["suppressionTime"] = 3.0;
|
|
level.mgturretsettings["fu"]["accuracy"] = 0.38;
|
|
level.mgturretsettings["fu"]["aiSpread"] = 2;
|
|
level.mgturretsettings["fu"]["playerSpread"] = 0.5;
|
|
}
|
|
|
|
main()
|
|
{
|
|
if ( getdvar( "mg42" ) == "" )
|
|
setdvar( "mgTurret", "off" );
|
|
|
|
level.magic_distance = 24;
|
|
var_0 = getentarray( "turretInfo", "targetname" );
|
|
|
|
for ( var_1 = 0; var_1 < var_0.size; var_1++ )
|
|
var_0[var_1] delete();
|
|
}
|
|
|
|
portable_mg_behavior()
|
|
{
|
|
self detach( "weapon_mg42_carry", "tag_origin" );
|
|
self endon( "death" );
|
|
self.goalradius = level.default_goalradius;
|
|
|
|
if ( isdefined( self.target ) )
|
|
{
|
|
var_0 = getnode( self.target, "targetname" );
|
|
|
|
if ( isdefined( var_0 ) )
|
|
{
|
|
if ( isdefined( var_0.radius ) )
|
|
self.goalradius = var_0.radius;
|
|
|
|
self setgoalnode( var_0 );
|
|
}
|
|
}
|
|
|
|
while ( !isdefined( self.node ) )
|
|
wait 0.05;
|
|
|
|
var_1 = undefined;
|
|
|
|
if ( isdefined( self.target ) )
|
|
{
|
|
var_0 = getnode( self.target, "targetname" );
|
|
var_1 = var_0;
|
|
}
|
|
|
|
if ( !isdefined( var_1 ) )
|
|
var_1 = self.node;
|
|
|
|
if ( !isdefined( var_1 ) )
|
|
return;
|
|
|
|
if ( var_1.type != "Turret" )
|
|
return;
|
|
|
|
var_2 = gettakennodes();
|
|
var_2[self.node.origin + ""] = undefined;
|
|
|
|
if ( isdefined( var_2[var_1.origin + ""] ) )
|
|
return;
|
|
|
|
var_3 = var_1.turret;
|
|
|
|
if ( isdefined( var_3.reserved ) )
|
|
return;
|
|
|
|
reserve_turret( var_3 );
|
|
|
|
if ( var_3.issetup )
|
|
leave_gun_and_run_to_new_spot( var_3 );
|
|
else
|
|
run_to_new_spot_and_setup_gun( var_3 );
|
|
|
|
maps\_mg_penetration::gunner_think( var_1.turret );
|
|
}
|
|
|
|
mg42_trigger()
|
|
{
|
|
self waittill( "trigger" );
|
|
level notify( self.targetname );
|
|
level.mg42_trigger[self.targetname] = 1;
|
|
self delete();
|
|
}
|
|
|
|
mgturret_auto( var_0 )
|
|
{
|
|
var_0 waittill( "trigger" );
|
|
var_1 = getaiarray( "bad_guys" );
|
|
|
|
for ( var_2 = 0; var_2 < var_1.size; var_2++ )
|
|
{
|
|
if ( isdefined( var_1[var_2].script_mg42auto ) && var_0.script_mg42auto == var_1[var_2].script_mg42auto )
|
|
var_1[var_2] notify( "auto_ai" );
|
|
}
|
|
|
|
var_3 = getspawnerarray();
|
|
|
|
for ( var_2 = 0; var_2 < var_3.size; var_2++ )
|
|
{
|
|
if ( isdefined( var_3[var_2].script_mg42auto ) && var_0.script_mg42auto == var_3[var_2].script_mg42auto )
|
|
var_3[var_2].ai_mode = "auto_ai";
|
|
}
|
|
|
|
maps\_spawner::kill_trigger( var_0 );
|
|
}
|
|
|
|
mg42_suppressionfire( var_0 )
|
|
{
|
|
self endon( "death" );
|
|
self endon( "stop_suppressionFire" );
|
|
|
|
if ( !isdefined( self.suppresionfire ) )
|
|
self.suppresionfire = 1;
|
|
|
|
for (;;)
|
|
{
|
|
while ( self.suppresionfire )
|
|
{
|
|
self settargetentity( var_0[randomint( var_0.size )] );
|
|
wait( 2 + randomfloat( 2 ) );
|
|
}
|
|
|
|
self cleartargetentity();
|
|
|
|
while ( !self.suppresionfire )
|
|
wait 1;
|
|
}
|
|
}
|
|
|
|
manual_think( var_0 )
|
|
{
|
|
var_1 = self.origin;
|
|
self waittill( "auto_ai" );
|
|
var_0 notify( "stopfiring" );
|
|
var_0 setmode( "auto_ai" );
|
|
var_0 settargetentity( level.player );
|
|
}
|
|
|
|
burst_fire_settings( var_0 )
|
|
{
|
|
if ( var_0 == "delay" )
|
|
return 0.2;
|
|
else if ( var_0 == "delay_range" )
|
|
return 0.5;
|
|
else if ( var_0 == "burst" )
|
|
return 0.5;
|
|
else
|
|
return 1.5;
|
|
}
|
|
|
|
burst_fire_unmanned()
|
|
{
|
|
self endon( "death" );
|
|
self endon( "stop_burst_fire_unmanned" );
|
|
|
|
if ( isdefined( self.script_delay_min ) )
|
|
var_0 = self.script_delay_min;
|
|
else
|
|
var_0 = burst_fire_settings( "delay" );
|
|
|
|
if ( isdefined( self.script_delay_max ) )
|
|
var_1 = self.script_delay_max - var_0;
|
|
else
|
|
var_1 = burst_fire_settings( "delay_range" );
|
|
|
|
if ( isdefined( self.script_burst_min ) )
|
|
var_2 = self.script_burst_min;
|
|
else
|
|
var_2 = burst_fire_settings( "burst" );
|
|
|
|
if ( isdefined( self.script_burst_max ) )
|
|
var_3 = self.script_burst_max - var_2;
|
|
else
|
|
var_3 = burst_fire_settings( "burst_range" );
|
|
|
|
var_4 = gettime();
|
|
var_5 = "start";
|
|
|
|
if ( isdefined( self.shell_fx ) )
|
|
thread turret_shell_fx();
|
|
|
|
for (;;)
|
|
{
|
|
var_6 = ( var_4 - gettime() ) * 0.001;
|
|
|
|
if ( self isfiringturret() && var_6 <= 0 )
|
|
{
|
|
if ( var_5 != "fire" )
|
|
{
|
|
var_5 = "fire";
|
|
thread doshoot();
|
|
}
|
|
|
|
var_6 = var_2 + randomfloat( var_3 );
|
|
thread turrettimer( var_6 );
|
|
self waittill( "turretstatechange" );
|
|
var_6 = var_0 + randomfloat( var_1 );
|
|
var_4 = gettime() + int( var_6 * 1000 );
|
|
continue;
|
|
}
|
|
|
|
if ( var_5 != "aim" )
|
|
var_5 = "aim";
|
|
|
|
thread turrettimer( var_6 );
|
|
self waittill( "turretstatechange" );
|
|
}
|
|
}
|
|
|
|
doshoot()
|
|
{
|
|
self endon( "death" );
|
|
self endon( "turretstatechange" );
|
|
|
|
for (;;)
|
|
{
|
|
self shootturret();
|
|
wait 0.1;
|
|
}
|
|
}
|
|
|
|
turret_shell_fx()
|
|
{
|
|
self endon( "death" );
|
|
self endon( "stop_burst_fire_unmanned" );
|
|
|
|
if ( isdefined( self.shell_sound ) )
|
|
self.shell_sound_enabled = 1;
|
|
|
|
for (;;)
|
|
{
|
|
self waittill( "turret_fire" );
|
|
playfxontag( self.shell_fx, self, "tag_origin" );
|
|
|
|
if ( isdefined( self.shell_sound_enabled ) && self.shell_sound_enabled )
|
|
thread turret_shell_sound();
|
|
}
|
|
}
|
|
|
|
turret_shell_sound()
|
|
{
|
|
self endon( "death" );
|
|
self.shell_sound_enabled = 0;
|
|
var_0 = self gettagorigin( "tag_origin" );
|
|
var_1 = common_scripts\utility::drop_to_ground( var_0, -30 );
|
|
var_2 = var_0[2] - var_1[2];
|
|
var_3 = var_2 / 300;
|
|
wait( var_3 );
|
|
level thread common_scripts\utility::play_sound_in_space( self.shell_sound, var_1 );
|
|
wait 1;
|
|
self.shell_sound_enabled = 1;
|
|
}
|
|
|
|
turrettimer( var_0 )
|
|
{
|
|
if ( var_0 <= 0 )
|
|
return;
|
|
|
|
self endon( "turretstatechange" );
|
|
wait( var_0 );
|
|
|
|
if ( isdefined( self ) )
|
|
self notify( "turretstatechange" );
|
|
}
|
|
|
|
random_spread( var_0 )
|
|
{
|
|
self endon( "death" );
|
|
self notify( "stop random_spread" );
|
|
self endon( "stop random_spread" );
|
|
self endon( "stopfiring" );
|
|
self settargetentity( var_0 );
|
|
|
|
for (;;)
|
|
{
|
|
if ( isplayer( var_0 ) )
|
|
var_0.origin = self.manual_target getorigin();
|
|
else
|
|
var_0.origin = self.manual_target.origin;
|
|
|
|
var_0.origin = var_0.origin + ( 20 - randomfloat( 40 ), 20 - randomfloat( 40 ), 20 - randomfloat( 60 ) );
|
|
wait 0.2;
|
|
}
|
|
}
|
|
|
|
mg42_firing( var_0 )
|
|
{
|
|
self notify( "stop_using_built_in_burst_fire" );
|
|
self endon( "stop_using_built_in_burst_fire" );
|
|
var_0 stopfiring();
|
|
|
|
for (;;)
|
|
{
|
|
var_0 waittill( "startfiring" );
|
|
thread burst_fire( var_0 );
|
|
var_0 startfiring();
|
|
var_0 waittill( "stopfiring" );
|
|
var_0 stopfiring();
|
|
}
|
|
}
|
|
|
|
burst_fire( var_0, var_1 )
|
|
{
|
|
var_0 endon( "stopfiring" );
|
|
self endon( "stop_using_built_in_burst_fire" );
|
|
|
|
if ( isdefined( var_0.script_delay_min ) )
|
|
var_2 = var_0.script_delay_min;
|
|
else
|
|
var_2 = burst_fire_settings( "delay" );
|
|
|
|
if ( isdefined( var_0.script_delay_max ) )
|
|
var_3 = var_0.script_delay_max - var_2;
|
|
else
|
|
var_3 = burst_fire_settings( "delay_range" );
|
|
|
|
if ( isdefined( var_0.script_burst_min ) )
|
|
var_4 = var_0.script_burst_min;
|
|
else
|
|
var_4 = burst_fire_settings( "burst" );
|
|
|
|
if ( isdefined( var_0.script_burst_max ) )
|
|
var_5 = var_0.script_burst_max - var_4;
|
|
else
|
|
var_5 = burst_fire_settings( "burst_range" );
|
|
|
|
for (;;)
|
|
{
|
|
var_0 startfiring();
|
|
|
|
if ( isdefined( var_1 ) )
|
|
var_0 thread random_spread( var_1 );
|
|
|
|
wait( var_4 + randomfloat( var_5 ) );
|
|
var_0 stopfiring();
|
|
wait( var_2 + randomfloat( var_3 ) );
|
|
}
|
|
}
|
|
|
|
_spawner_mg42_think()
|
|
{
|
|
if ( !isdefined( self.flagged_for_use ) )
|
|
self.flagged_for_use = 0;
|
|
|
|
if ( !isdefined( self.targetname ) )
|
|
return;
|
|
|
|
var_0 = getnode( self.targetname, "target" );
|
|
|
|
if ( !isdefined( var_0 ) )
|
|
return;
|
|
|
|
if ( !isdefined( var_0.script_mg42 ) )
|
|
return;
|
|
|
|
if ( !isdefined( var_0.mg42_enabled ) )
|
|
var_0.mg42_enabled = 1;
|
|
|
|
self.script_mg42 = var_0.script_mg42;
|
|
var_1 = 1;
|
|
|
|
for (;;)
|
|
{
|
|
if ( var_1 )
|
|
{
|
|
var_1 = 0;
|
|
|
|
if ( isdefined( var_0.targetname ) || self.flagged_for_use )
|
|
self waittill( "get new user" );
|
|
}
|
|
|
|
if ( !var_0.mg42_enabled )
|
|
{
|
|
var_0 waittill( "enable mg42" );
|
|
var_0.mg42_enabled = 1;
|
|
}
|
|
|
|
var_2 = [];
|
|
var_3 = getaiarray();
|
|
|
|
for ( var_4 = 0; var_4 < var_3.size; var_4++ )
|
|
{
|
|
var_5 = 1;
|
|
|
|
if ( isdefined( var_3[var_4].script_mg42 ) && var_3[var_4].script_mg42 == self.script_mg42 )
|
|
var_5 = 0;
|
|
|
|
if ( isdefined( var_3[var_4].used_an_mg42 ) )
|
|
var_5 = 1;
|
|
|
|
if ( var_5 )
|
|
var_2[var_2.size] = var_3[var_4];
|
|
}
|
|
|
|
if ( var_2.size )
|
|
var_3 = maps\_utility::get_closest_ai_exclude( var_0.origin, undefined, var_2 );
|
|
else
|
|
var_3 = maps\_utility::get_closest_ai( var_0.origin, undefined );
|
|
|
|
var_2 = undefined;
|
|
|
|
if ( isdefined( var_3 ) )
|
|
{
|
|
var_3 notify( "stop_going_to_node" );
|
|
var_3 thread maps\_spawner::go_to_node( var_0 );
|
|
var_3 waittill( "death" );
|
|
continue;
|
|
}
|
|
|
|
self waittill( "get new user" );
|
|
}
|
|
}
|
|
|
|
mg42_think()
|
|
{
|
|
if ( !isdefined( self.ai_mode ) )
|
|
self.ai_mode = "manual_ai";
|
|
|
|
var_0 = getnode( self.target, "targetname" );
|
|
|
|
if ( !isdefined( var_0 ) )
|
|
return;
|
|
|
|
var_1 = getent( var_0.target, "targetname" );
|
|
var_1.org = var_0.origin;
|
|
|
|
if ( isdefined( var_1.target ) )
|
|
{
|
|
if ( !isdefined( level.mg42_trigger ) || !isdefined( level.mg42_trigger[var_1.target] ) )
|
|
{
|
|
level.mg42_trigger[var_1.target] = 0;
|
|
getent( var_1.target, "targetname" ) thread mg42_trigger();
|
|
}
|
|
|
|
var_2 = 1;
|
|
}
|
|
else
|
|
var_2 = 0;
|
|
|
|
for (;;)
|
|
{
|
|
if ( self.count == 0 )
|
|
return;
|
|
|
|
var_3 = undefined;
|
|
|
|
while ( !isdefined( var_3 ) )
|
|
{
|
|
var_3 = self dospawn();
|
|
wait 1;
|
|
}
|
|
|
|
var_3 thread mg42_gunner_think( var_1, var_2, self.ai_mode );
|
|
var_3 thread mg42_firing( var_1 );
|
|
var_3 waittill( "death" );
|
|
|
|
if ( isdefined( self.script_delay ) )
|
|
{
|
|
wait( self.script_delay );
|
|
continue;
|
|
}
|
|
|
|
if ( isdefined( self.script_delay_min ) && isdefined( self.script_delay_max ) )
|
|
{
|
|
wait( self.script_delay_min + randomfloat( self.script_delay_max - self.script_delay_min ) );
|
|
continue;
|
|
}
|
|
|
|
wait 1;
|
|
}
|
|
}
|
|
|
|
kill_objects( var_0, var_1, var_2, var_3 )
|
|
{
|
|
var_0 waittill( var_1 );
|
|
|
|
if ( isdefined( var_2 ) )
|
|
var_2 delete();
|
|
|
|
if ( isdefined( var_3 ) )
|
|
var_3 delete();
|
|
}
|
|
|
|
mg42_gunner_think( var_0, var_1, var_2 )
|
|
{
|
|
self endon( "death" );
|
|
|
|
if ( var_2 == "manual_ai" )
|
|
{
|
|
for (;;)
|
|
{
|
|
thread mg42_gunner_manual_think( var_0, var_1 );
|
|
self waittill( "auto_ai" );
|
|
move_use_turret( var_0, "auto_ai" );
|
|
self waittill( "manual_ai" );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (;;)
|
|
{
|
|
move_use_turret( var_0, "auto_ai", level.player );
|
|
self waittill( "manual_ai" );
|
|
thread mg42_gunner_manual_think( var_0, var_1 );
|
|
self waittill( "auto_ai" );
|
|
}
|
|
}
|
|
}
|
|
|
|
player_safe()
|
|
{
|
|
if ( !isdefined( level.player_covertrigger ) )
|
|
return 0;
|
|
|
|
if ( level.player getstance() == "prone" )
|
|
return 1;
|
|
|
|
if ( level.player_covertype == "cow" && level.player getstance() == "crouch" )
|
|
return 1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
stance_num()
|
|
{
|
|
if ( level.player getstance() == "prone" )
|
|
return ( 0, 0, 5 );
|
|
else if ( level.player getstance() == "crouch" )
|
|
return ( 0, 0, 25 );
|
|
|
|
return ( 0, 0, 50 );
|
|
}
|
|
|
|
mg42_gunner_manual_think( var_0, var_1 )
|
|
{
|
|
self endon( "death" );
|
|
self endon( "auto_ai" );
|
|
self.pacifist = 1;
|
|
self setgoalpos( var_0.org );
|
|
self.goalradius = level.magic_distance;
|
|
self waittill( "goal" );
|
|
|
|
if ( var_1 )
|
|
{
|
|
if ( !level.mg42_trigger[var_0.target] )
|
|
level waittill( var_0.target );
|
|
}
|
|
|
|
self.pacifist = 0;
|
|
var_0 setmode( "auto_ai" );
|
|
var_0 cleartargetentity();
|
|
var_2 = spawn( "script_origin", ( 0, 0, 0 ) );
|
|
var_3 = spawn( "script_model", ( 0, 0, 0 ) );
|
|
var_3.scale = 3;
|
|
|
|
if ( getdvar( "mg42" ) != "off" )
|
|
var_3 setmodel( "temp" );
|
|
|
|
var_3 thread temp_think( var_0, var_2 );
|
|
level thread kill_objects( self, "death", var_2, var_3 );
|
|
level thread kill_objects( self, "auto_ai", var_2, var_3 );
|
|
var_0.player_target = 0;
|
|
var_4 = 0;
|
|
var_5 = getentarray( "mg42_target", "targetname" );
|
|
|
|
if ( var_5.size > 0 )
|
|
{
|
|
var_6 = 1;
|
|
var_7 = var_5[randomint( var_5.size )].origin;
|
|
thread shoot_mg42_script_targets( var_5 );
|
|
move_use_turret( var_0 );
|
|
self.target_entity = var_2;
|
|
var_0 setmode( "manual_ai" );
|
|
var_0 settargetentity( var_2 );
|
|
var_0 notify( "startfiring" );
|
|
var_8 = 15;
|
|
var_9 = 0.08;
|
|
var_10 = 0.05;
|
|
var_2.origin = var_5[randomint( var_5.size )].origin;
|
|
var_11 = 0;
|
|
|
|
while ( !isdefined( level.player_covertrigger ) )
|
|
{
|
|
var_7 = var_2.origin;
|
|
|
|
if ( distance( var_7, var_5[self.gun_targ].origin ) > var_8 )
|
|
{
|
|
var_12 = vectornormalize( var_5[self.gun_targ].origin - var_7 );
|
|
var_12 = var_12 * var_8;
|
|
var_7 = var_7 + var_12;
|
|
}
|
|
else
|
|
self notify( "next_target" );
|
|
|
|
var_2.origin = var_7;
|
|
wait 0.1;
|
|
}
|
|
|
|
for (;;)
|
|
{
|
|
for ( var_13 = 0; var_13 < 1; var_13 = var_13 + var_10 )
|
|
{
|
|
var_2.origin = var_7 * ( 1.0 - var_13 ) + ( level.player getorigin() + stance_num() ) * var_13;
|
|
|
|
if ( player_safe() )
|
|
var_13 = 2;
|
|
|
|
wait( var_9 );
|
|
}
|
|
|
|
var_14 = level.player getorigin();
|
|
|
|
while ( !player_safe() )
|
|
{
|
|
var_2.origin = level.player getorigin();
|
|
var_15 = var_2.origin - var_14;
|
|
var_2.origin = var_2.origin + var_15 + stance_num();
|
|
var_14 = level.player getorigin();
|
|
wait 0.1;
|
|
}
|
|
|
|
if ( player_safe() )
|
|
{
|
|
var_11 = gettime() + 1500 + randomfloat( 4000 );
|
|
|
|
while ( player_safe() && isdefined( level.player_covertrigger.target ) && gettime() < var_11 )
|
|
{
|
|
var_16 = getentarray( level.player_covertrigger.target, "targetname" );
|
|
var_16 = var_16[randomint( var_16.size )];
|
|
var_2.origin = var_16.origin + ( randomfloat( 30 ) - 15, randomfloat( 30 ) - 15, randomfloat( 40 ) - 60 );
|
|
wait 0.1;
|
|
}
|
|
}
|
|
|
|
self notify( "next_target" );
|
|
|
|
while ( player_safe() )
|
|
{
|
|
var_7 = var_2.origin;
|
|
|
|
if ( distance( var_7, var_5[self.gun_targ].origin ) > var_8 )
|
|
{
|
|
var_12 = vectornormalize( var_5[self.gun_targ].origin - var_7 );
|
|
var_12 = var_12 * var_8;
|
|
var_7 = var_7 + var_12;
|
|
}
|
|
else
|
|
self notify( "next_target" );
|
|
|
|
var_2.origin = var_7;
|
|
wait 0.1;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (;;)
|
|
{
|
|
move_use_turret( var_0 );
|
|
|
|
while ( !isdefined( level.player_covertrigger ) )
|
|
{
|
|
if ( !var_0.player_target )
|
|
{
|
|
var_0 settargetentity( level.player );
|
|
var_0.player_target = 1;
|
|
var_3.targent = level.player;
|
|
}
|
|
|
|
wait 0.2;
|
|
}
|
|
|
|
var_0 setmode( "manual_ai" );
|
|
move_use_turret( var_0 );
|
|
var_0 notify( "startfiring" );
|
|
var_11 = gettime() + 1500 + randomfloat( 4000 );
|
|
|
|
while ( var_11 > gettime() )
|
|
{
|
|
if ( isdefined( level.player_covertrigger ) )
|
|
{
|
|
var_16 = getentarray( level.player_covertrigger.target, "targetname" );
|
|
var_16 = var_16[randomint( var_16.size )];
|
|
var_2.origin = var_16.origin + ( randomfloat( 30 ) - 15, randomfloat( 30 ) - 15, randomfloat( 40 ) - 60 );
|
|
var_0 settargetentity( var_2 );
|
|
var_3.targent = var_2;
|
|
wait( randomfloat( 1 ) );
|
|
continue;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
var_0 notify( "stopfiring" );
|
|
move_use_turret( var_0 );
|
|
|
|
if ( var_0.player_target )
|
|
{
|
|
var_0 setmode( "auto_ai" );
|
|
var_0 cleartargetentity();
|
|
var_0.player_target = 0;
|
|
var_3.targent = var_3;
|
|
var_3.origin = ( 0, 0, 0 );
|
|
}
|
|
|
|
while ( isdefined( level.player_covertrigger ) )
|
|
wait 0.2;
|
|
|
|
wait( 0.75 + randomfloat( 0.2 ) );
|
|
}
|
|
}
|
|
}
|
|
|
|
shoot_mg42_script_targets( var_0 )
|
|
{
|
|
self endon( "death" );
|
|
|
|
for (;;)
|
|
{
|
|
var_1 = [];
|
|
|
|
for ( var_2 = 0; var_2 < var_0.size; var_2++ )
|
|
var_1[var_2] = 0;
|
|
|
|
for ( var_2 = 0; var_2 < var_0.size; var_2++ )
|
|
{
|
|
self.gun_targ = randomint( var_0.size );
|
|
self waittill( "next_target" );
|
|
|
|
while ( var_1[self.gun_targ] )
|
|
{
|
|
self.gun_targ++;
|
|
|
|
if ( self.gun_targ >= var_0.size )
|
|
self.gun_targ = 0;
|
|
}
|
|
|
|
var_1[self.gun_targ] = 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
move_use_turret( var_0, var_1, var_2 )
|
|
{
|
|
self setgoalpos( var_0.org );
|
|
self.goalradius = level.magic_distance;
|
|
self waittill( "goal" );
|
|
|
|
if ( isdefined( var_1 ) && var_1 == "auto_ai" )
|
|
{
|
|
var_0 setmode( "auto_ai" );
|
|
|
|
if ( isdefined( var_2 ) )
|
|
var_0 settargetentity( var_2 );
|
|
else
|
|
var_0 cleartargetentity();
|
|
}
|
|
|
|
self useturret( var_0 );
|
|
}
|
|
|
|
temp_think( var_0, var_1 )
|
|
{
|
|
if ( getdvar( "mg42" ) == "off" )
|
|
return;
|
|
|
|
self.targent = self;
|
|
|
|
for (;;)
|
|
{
|
|
self.origin = var_1.origin;
|
|
wait 0.1;
|
|
}
|
|
}
|
|
|
|
turret_think( var_0 )
|
|
{
|
|
var_1 = getent( var_0.auto_mg42_target, "targetname" );
|
|
var_2 = 0.5;
|
|
|
|
if ( isdefined( var_1.script_turret_reuse_min ) )
|
|
var_2 = var_1.script_turret_reuse_min;
|
|
|
|
var_3 = 2;
|
|
|
|
if ( isdefined( var_1.script_turret_reuse_max ) )
|
|
var_2 = var_1.script_turret_reuse_max;
|
|
|
|
for (;;)
|
|
{
|
|
var_1 waittill( "turret_deactivate" );
|
|
wait( var_2 + randomfloat( var_3 - var_2 ) );
|
|
|
|
while ( !isturretactive( var_1 ) )
|
|
{
|
|
turret_find_user( var_0, var_1 );
|
|
wait 1.0;
|
|
}
|
|
}
|
|
}
|
|
|
|
turret_find_user( var_0, var_1 )
|
|
{
|
|
var_2 = getaiarray();
|
|
|
|
for ( var_3 = 0; var_3 < var_2.size; var_3++ )
|
|
{
|
|
if ( var_2[var_3] isingoal( var_0.origin ) && var_2[var_3] canuseturret( var_1 ) )
|
|
{
|
|
var_4 = var_2[var_3].keepclaimednodeifvalid;
|
|
var_2[var_3].keepclaimednodeifvalid = 0;
|
|
|
|
if ( !var_2[var_3] usecovernode( var_0 ) )
|
|
var_2[var_3].keepclaimednodeifvalid = var_4;
|
|
}
|
|
}
|
|
}
|
|
|
|
setdifficulty()
|
|
{
|
|
init_mgturretsettings();
|
|
var_0 = getentarray( "misc_turret", "code_classname" );
|
|
var_1 = maps\_utility::getdifficulty();
|
|
|
|
for ( var_2 = 0; var_2 < var_0.size; var_2++ )
|
|
{
|
|
if ( isdefined( var_0[var_2].script_skilloverride ) )
|
|
{
|
|
switch ( var_0[var_2].script_skilloverride )
|
|
{
|
|
case "easy":
|
|
var_1 = "easy";
|
|
break;
|
|
case "medium":
|
|
var_1 = "medium";
|
|
break;
|
|
case "hard":
|
|
var_1 = "hard";
|
|
break;
|
|
case "fu":
|
|
var_1 = "fu";
|
|
break;
|
|
default:
|
|
continue;
|
|
}
|
|
}
|
|
|
|
mg42_setdifficulty( var_0[var_2], var_1 );
|
|
}
|
|
}
|
|
|
|
mg42_setdifficulty( var_0, var_1 )
|
|
{
|
|
var_0.convergencetime = level.mgturretsettings[var_1]["convergenceTime"];
|
|
var_0.suppressiontime = level.mgturretsettings[var_1]["suppressionTime"];
|
|
var_0.accuracy = level.mgturretsettings[var_1]["accuracy"];
|
|
var_0.aispread = level.mgturretsettings[var_1]["aiSpread"];
|
|
var_0.playerspread = level.mgturretsettings[var_1]["playerSpread"];
|
|
}
|
|
|
|
mg42_target_drones( var_0, var_1, var_2 )
|
|
{
|
|
if ( !isdefined( var_2 ) )
|
|
var_2 = 0.88;
|
|
|
|
self endon( "death" );
|
|
self notify( "stop_mg42_target_drones" );
|
|
self endon( "stop_mg42_target_drones" );
|
|
self.dronefailed = 0;
|
|
|
|
if ( !isdefined( self.script_fireondrones ) )
|
|
self.script_fireondrones = 0;
|
|
|
|
if ( !isdefined( var_0 ) )
|
|
var_0 = 0;
|
|
|
|
self setmode( "manual_ai" );
|
|
var_3 = maps\_utility::getdifficulty();
|
|
|
|
if ( !isdefined( level.drones ) )
|
|
var_4 = 1;
|
|
else
|
|
var_4 = 0;
|
|
|
|
for (;;)
|
|
{
|
|
if ( var_4 )
|
|
{
|
|
if ( isdefined( self.drones_targets_sets_to_default ) )
|
|
self setmode( self.defaultonmode );
|
|
else if ( var_0 )
|
|
self setmode( "auto_nonai" );
|
|
else
|
|
self setmode( "auto_ai" );
|
|
|
|
level waittill( "new_drone" );
|
|
}
|
|
|
|
if ( !isdefined( self.oldconvergencetime ) )
|
|
self.oldconvergencetime = self.convergencetime;
|
|
|
|
self.convergencetime = 2;
|
|
|
|
if ( !var_0 )
|
|
{
|
|
var_5 = self getturretowner();
|
|
|
|
if ( !isalive( var_5 ) || isplayer( var_5 ) )
|
|
{
|
|
wait 0.05;
|
|
continue;
|
|
}
|
|
else
|
|
var_1 = var_5.team;
|
|
}
|
|
else
|
|
var_5 = undefined;
|
|
|
|
if ( var_1 == "allies" )
|
|
var_6 = "axis";
|
|
else
|
|
var_6 = "allies";
|
|
|
|
while ( level.drones[var_6].lastindex )
|
|
{
|
|
common_scripts\utility::lock( "mg42_drones" );
|
|
|
|
if ( !level.drones[var_6].lastindex )
|
|
{
|
|
common_scripts\utility::unlock( "mg42_drones" );
|
|
break;
|
|
}
|
|
|
|
var_7 = get_bestdrone( var_6, var_2 );
|
|
common_scripts\utility::unlock( "mg42_drones" );
|
|
|
|
if ( !isdefined( self.script_fireondrones ) || !self.script_fireondrones )
|
|
{
|
|
wait 0.05;
|
|
break;
|
|
}
|
|
|
|
if ( !isdefined( var_7 ) )
|
|
{
|
|
wait 0.05;
|
|
break;
|
|
}
|
|
|
|
if ( isdefined( self.anim_wait_func ) )
|
|
[[ self.anim_wait_func ]]();
|
|
|
|
if ( var_0 )
|
|
self setmode( "manual" );
|
|
else
|
|
self setmode( "manual_ai" );
|
|
|
|
self settargetentity( var_7, ( 0, 0, 32 ) );
|
|
drone_target( var_7, 1, var_2 );
|
|
self cleartargetentity();
|
|
self stopfiring();
|
|
|
|
if ( !var_0 && !( isdefined( self getturretowner() ) && self getturretowner() == var_5 ) )
|
|
break;
|
|
}
|
|
|
|
self.convergencetime = self.oldconvergencetime;
|
|
self.oldconvergencetime = undefined;
|
|
self cleartargetentity();
|
|
self stopfiring();
|
|
|
|
if ( level.drones[var_6].lastindex )
|
|
{
|
|
var_4 = 0;
|
|
continue;
|
|
}
|
|
|
|
var_4 = 1;
|
|
}
|
|
}
|
|
|
|
drone_target( var_0, var_1, var_2 )
|
|
{
|
|
self endon( "death" );
|
|
var_0 endon( "death" );
|
|
var_3 = gettime() + var_1 * 1000;
|
|
var_4 = 0;
|
|
|
|
while ( var_3 > gettime() || var_4 )
|
|
{
|
|
common_scripts\utility::lock( "mg42_drones_target_trace" );
|
|
var_5 = self getturrettarget( 1 );
|
|
|
|
if ( !bullettracepassed( self gettagorigin( "tag_flash" ), var_0.origin + ( 0, 0, 40 ), 0, var_0 ) )
|
|
{
|
|
common_scripts\utility::unlock( "mg42_drones_target_trace" );
|
|
break;
|
|
}
|
|
else if ( isdefined( var_5 ) && distance( var_5.origin, self.origin ) < distance( self.origin, var_0.origin ) )
|
|
{
|
|
common_scripts\utility::unlock( "mg42_drones_target_trace" );
|
|
break;
|
|
}
|
|
|
|
if ( !var_4 )
|
|
{
|
|
self startfiring();
|
|
var_4 = 1;
|
|
}
|
|
|
|
common_scripts\utility::unlock_wait( "mg42_drones_target_trace" );
|
|
}
|
|
|
|
self stopfiring();
|
|
maps\_utility::structarray_shuffle( level.drones[var_0.team], 1 );
|
|
}
|
|
|
|
get_bestdrone( var_0, var_1 )
|
|
{
|
|
if ( level.drones[var_0].lastindex < 1 )
|
|
return;
|
|
|
|
var_2 = undefined;
|
|
var_3 = anglestoforward( self.angles );
|
|
|
|
for ( var_4 = 0; var_4 < level.drones[var_0].lastindex; var_4++ )
|
|
{
|
|
if ( !isdefined( level.drones[var_0].array[var_4] ) )
|
|
continue;
|
|
|
|
var_5 = vectortoangles( level.drones[var_0].array[var_4].origin - self.origin );
|
|
var_6 = anglestoforward( var_5 );
|
|
|
|
if ( vectordot( var_3, var_6 ) < var_1 )
|
|
continue;
|
|
|
|
var_2 = level.drones[var_0].array[var_4];
|
|
|
|
if ( !bullettracepassed( self gettagorigin( "tag_flash" ), var_2 getcentroid(), 0, var_2 ) )
|
|
{
|
|
var_2 = undefined;
|
|
continue;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
var_7 = self getturrettarget( 1 );
|
|
|
|
if ( !isdefined( self.prefers_drones ) )
|
|
{
|
|
if ( isdefined( var_2 ) && isdefined( var_7 ) && distancesquared( self.origin, var_7.origin ) < distancesquared( self.origin, var_2.origin ) )
|
|
var_2 = undefined;
|
|
}
|
|
|
|
return var_2;
|
|
}
|
|
|
|
saw_mgturretlink( var_0 )
|
|
{
|
|
var_1 = getentarray( "misc_turret", "code_classname" );
|
|
var_2 = [];
|
|
|
|
for ( var_3 = 0; var_3 < var_1.size; var_3++ )
|
|
{
|
|
if ( isdefined( var_1[var_3].targetname ) )
|
|
continue;
|
|
|
|
if ( isdefined( var_1[var_3].isvehicleattached ) )
|
|
continue;
|
|
|
|
var_2[var_1[var_3].origin + ""] = var_1[var_3];
|
|
}
|
|
|
|
if ( !var_2.size )
|
|
return;
|
|
|
|
for ( var_4 = 0; var_4 < var_0.size; var_4++ )
|
|
{
|
|
var_5 = var_0[var_4];
|
|
|
|
if ( var_5.type == "Path" )
|
|
continue;
|
|
|
|
if ( var_5.type == "Begin" )
|
|
continue;
|
|
|
|
if ( var_5.type == "End" )
|
|
continue;
|
|
|
|
var_6 = anglestoforward( ( 0, var_5.angles[1], 0 ) );
|
|
|
|
foreach ( var_11, var_8 in var_2 )
|
|
{
|
|
if ( distance( var_5.origin, var_8.origin ) > 50 )
|
|
continue;
|
|
|
|
var_9 = anglestoforward( ( 0, var_8.angles[1], 0 ) );
|
|
var_10 = vectordot( var_6, var_9 );
|
|
|
|
if ( var_10 < 0.9 )
|
|
continue;
|
|
|
|
var_5.turretinfo = spawn( "script_origin", var_8.origin );
|
|
var_5.turretinfo.angles = var_8.angles;
|
|
var_5.turretinfo.node = var_5;
|
|
var_5.turretinfo.leftarc = 45;
|
|
var_5.turretinfo.rightarc = 45;
|
|
var_5.turretinfo.toparc = 15;
|
|
var_5.turretinfo.bottomarc = 15;
|
|
|
|
if ( isdefined( var_8.leftarc ) )
|
|
var_5.turretinfo.leftarc = min( var_8.leftarc, 45 );
|
|
|
|
if ( isdefined( var_8.rightarc ) )
|
|
var_5.turretinfo.rightarc = min( var_8.rightarc, 45 );
|
|
|
|
if ( isdefined( var_8.toparc ) )
|
|
var_5.turretinfo.toparc = min( var_8.toparc, 15 );
|
|
|
|
if ( isdefined( var_8.bottomarc ) )
|
|
var_5.turretinfo.bottomarc = min( var_8.bottomarc, 15 );
|
|
|
|
var_2[var_11] = undefined;
|
|
var_8 delete();
|
|
}
|
|
}
|
|
}
|
|
|
|
auto_mgturretlink( var_0 )
|
|
{
|
|
var_1 = getentarray( "misc_turret", "code_classname" );
|
|
var_2 = [];
|
|
|
|
for ( var_3 = 0; var_3 < var_1.size; var_3++ )
|
|
{
|
|
if ( !isdefined( var_1[var_3].targetname ) || tolower( var_1[var_3].targetname ) != "auto_mgturret" )
|
|
continue;
|
|
|
|
if ( !isdefined( var_1[var_3].export ) )
|
|
continue;
|
|
|
|
if ( !isdefined( var_1[var_3].script_dont_link_turret ) )
|
|
var_2[var_1[var_3].origin + ""] = var_1[var_3];
|
|
}
|
|
|
|
if ( !var_2.size )
|
|
return;
|
|
|
|
for ( var_4 = 0; var_4 < var_0.size; var_4++ )
|
|
{
|
|
var_5 = var_0[var_4];
|
|
|
|
if ( var_5.type == "Path" )
|
|
continue;
|
|
|
|
if ( var_5.type == "Begin" )
|
|
continue;
|
|
|
|
if ( var_5.type == "End" )
|
|
continue;
|
|
|
|
var_6 = anglestoforward( ( 0, var_5.angles[1], 0 ) );
|
|
var_7 = getarraykeys( var_2 );
|
|
|
|
for ( var_3 = 0; var_3 < var_7.size; var_3++ )
|
|
{
|
|
var_8 = var_2[var_7[var_3]];
|
|
|
|
if ( distance( var_5.origin, var_8.origin ) > 70 )
|
|
continue;
|
|
|
|
var_9 = anglestoforward( ( 0, var_8.angles[1], 0 ) );
|
|
var_10 = vectordot( var_6, var_9 );
|
|
|
|
if ( var_10 < 0.9 )
|
|
continue;
|
|
|
|
var_5.turret = var_8;
|
|
var_8.node = var_5;
|
|
var_8.issetup = 1;
|
|
var_2[var_7[var_3]] = undefined;
|
|
}
|
|
}
|
|
|
|
var_0 = undefined;
|
|
}
|
|
|
|
save_turret_sharing_info()
|
|
{
|
|
self.shared_turrets = [];
|
|
self.shared_turrets["connected"] = [];
|
|
self.shared_turrets["ambush"] = [];
|
|
|
|
if ( !isdefined( self.export ) )
|
|
return;
|
|
|
|
level.shared_portable_turrets[self.export] = self;
|
|
|
|
if ( isdefined( self.script_turret_share ) )
|
|
{
|
|
var_0 = strtok( self.script_turret_share, " " );
|
|
|
|
for ( var_1 = 0; var_1 < var_0.size; var_1++ )
|
|
self.shared_turrets["connected"][var_0[var_1]] = 1;
|
|
}
|
|
|
|
if ( isdefined( self.script_turret_ambush ) )
|
|
{
|
|
var_0 = strtok( self.script_turret_ambush, " " );
|
|
|
|
for ( var_1 = 0; var_1 < var_0.size; var_1++ )
|
|
self.shared_turrets["ambush"][var_0[var_1]] = 1;
|
|
}
|
|
}
|
|
|
|
restoredefaultpitch()
|
|
{
|
|
self notify( "gun_placed_again" );
|
|
self endon( "gun_placed_again" );
|
|
self waittill( "restore_default_drop_pitch" );
|
|
wait 1;
|
|
self restoredefaultdroppitch();
|
|
}
|
|
|
|
dropturret()
|
|
{
|
|
thread dropturretproc();
|
|
}
|
|
|
|
dropturretproc()
|
|
{
|
|
var_0 = spawn( "script_model", ( 0, 0, 0 ) );
|
|
var_0.origin = self gettagorigin( level.portable_mg_gun_tag );
|
|
var_0.angles = self gettagangles( level.portable_mg_gun_tag );
|
|
var_0 setmodel( self.turretmodel );
|
|
var_1 = anglestoforward( self.angles );
|
|
var_1 = var_1 * 100;
|
|
var_0 movegravity( var_1, 0.5 );
|
|
self detach( self.turretmodel, level.portable_mg_gun_tag );
|
|
self.turretmodel = undefined;
|
|
wait 0.7;
|
|
var_0 delete();
|
|
}
|
|
|
|
turretdeathdetacher()
|
|
{
|
|
self endon( "kill_turret_detach_thread" );
|
|
self endon( "dropped_gun" );
|
|
self waittill( "death" );
|
|
|
|
if ( !isdefined( self ) )
|
|
return;
|
|
|
|
dropturret();
|
|
}
|
|
|
|
turretdetacher()
|
|
{
|
|
self endon( "death" );
|
|
self endon( "kill_turret_detach_thread" );
|
|
self waittill( "dropped_gun" );
|
|
self detach( self.turretmodel, level.portable_mg_gun_tag );
|
|
}
|
|
|
|
restoredefaults()
|
|
{
|
|
self.run_overrideanim = undefined;
|
|
common_scripts\utility::set_all_exceptions( animscripts\init::empty );
|
|
}
|
|
|
|
restorepitch()
|
|
{
|
|
self waittill( "turret_deactivate" );
|
|
self restoredefaultdroppitch();
|
|
}
|
|
|
|
update_enemy_target_pos_while_running( var_0 )
|
|
{
|
|
self endon( "death" );
|
|
self endon( "end_mg_behavior" );
|
|
self endon( "stop_updating_enemy_target_pos" );
|
|
|
|
for (;;)
|
|
{
|
|
self waittill( "saw_enemy" );
|
|
var_0.origin = self.last_enemy_sighting_position;
|
|
}
|
|
}
|
|
|
|
move_target_pos_to_new_turrets_visibility( var_0, var_1 )
|
|
{
|
|
self endon( "death" );
|
|
self endon( "end_mg_behavior" );
|
|
self endon( "stop_updating_enemy_target_pos" );
|
|
var_2 = self.turret.origin + ( 0, 0, 16 );
|
|
var_3 = var_1.origin + ( 0, 0, 16 );
|
|
|
|
for (;;)
|
|
{
|
|
wait 0.05;
|
|
|
|
if ( sighttracepassed( var_0.origin, var_3, 0, undefined ) )
|
|
continue;
|
|
|
|
var_4 = vectortoangles( var_2 - var_0.origin );
|
|
var_5 = anglestoforward( var_4 );
|
|
var_5 = var_5 * 8;
|
|
var_0.origin = var_0.origin + var_5;
|
|
}
|
|
}
|
|
|
|
record_bread_crumbs_for_ambush( var_0 )
|
|
{
|
|
self endon( "death" );
|
|
self endon( "end_mg_behavior" );
|
|
self endon( "stop_updating_enemy_target_pos" );
|
|
var_0.bread_crumbs = [];
|
|
|
|
for (;;)
|
|
{
|
|
var_0.bread_crumbs[var_0.bread_crumbs.size] = self.origin + ( 0, 0, 50 );
|
|
wait 0.35;
|
|
}
|
|
}
|
|
|
|
aim_turret_at_ambush_point_or_visible_enemy( var_0, var_1 )
|
|
{
|
|
if ( !isalive( self.current_enemy ) && self cansee( self.current_enemy ) )
|
|
{
|
|
var_1.origin = self.last_enemy_sighting_position;
|
|
return;
|
|
}
|
|
|
|
var_2 = anglestoforward( var_0.angles );
|
|
|
|
for ( var_3 = var_1.bread_crumbs.size - 3; var_3 >= 0; var_3-- )
|
|
{
|
|
var_4 = var_1.bread_crumbs[var_3];
|
|
var_5 = vectornormalize( var_4 - var_0.origin );
|
|
var_6 = vectordot( var_2, var_5 );
|
|
|
|
if ( var_6 < 0.75 )
|
|
continue;
|
|
|
|
var_1.origin = var_4;
|
|
|
|
if ( sighttracepassed( var_0.origin, var_4, 0, undefined ) )
|
|
continue;
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
find_a_new_turret_spot( var_0 )
|
|
{
|
|
var_1 = get_portable_mg_spot( var_0 );
|
|
var_2 = var_1["spot"];
|
|
var_3 = var_1["type"];
|
|
|
|
if ( !isdefined( var_2 ) )
|
|
return;
|
|
|
|
reserve_turret( var_2 );
|
|
thread update_enemy_target_pos_while_running( var_0 );
|
|
thread move_target_pos_to_new_turrets_visibility( var_0, var_2 );
|
|
|
|
if ( var_3 == "ambush" )
|
|
thread record_bread_crumbs_for_ambush( var_0 );
|
|
|
|
if ( var_2.issetup )
|
|
leave_gun_and_run_to_new_spot( var_2 );
|
|
else
|
|
{
|
|
pickup_gun( var_2 );
|
|
run_to_new_spot_and_setup_gun( var_2 );
|
|
}
|
|
|
|
self notify( "stop_updating_enemy_target_pos" );
|
|
|
|
if ( var_3 == "ambush" )
|
|
aim_turret_at_ambush_point_or_visible_enemy( var_2, var_0 );
|
|
|
|
var_2 settargetentity( var_0 );
|
|
}
|
|
|
|
snap_lock_turret_onto_target( var_0 )
|
|
{
|
|
var_0 setmode( "manual" );
|
|
wait 0.5;
|
|
var_0 setmode( "manual_ai" );
|
|
}
|
|
|
|
leave_gun_and_run_to_new_spot( var_0 )
|
|
{
|
|
self stopuseturret();
|
|
animscripts\shared::placeweaponon( self.primaryweapon, "none" );
|
|
var_1 = get_turret_setup_anim( var_0 );
|
|
var_2 = getstartorigin( var_0.origin, var_0.angles, var_1 );
|
|
self setruntopos( var_2 );
|
|
self waittill( "runto_arrived" );
|
|
use_the_turret( var_0 );
|
|
}
|
|
|
|
pickup_gun( var_0 )
|
|
{
|
|
self stopuseturret();
|
|
self.turret hide_turret();
|
|
}
|
|
|
|
get_turret_setup_anim( var_0 )
|
|
{
|
|
var_1 = [];
|
|
var_1["saw_bipod_stand"] = level.mg_animmg["bipod_stand_setup"];
|
|
var_1["saw_bipod_crouch"] = level.mg_animmg["bipod_crouch_setup"];
|
|
var_1["saw_bipod_prone"] = level.mg_animmg["bipod_prone_setup"];
|
|
return var_1[var_0.weaponinfo];
|
|
}
|
|
|
|
#using_animtree("generic_human");
|
|
|
|
run_to_new_spot_and_setup_gun( var_0 )
|
|
{
|
|
var_1 = self.health;
|
|
var_0 endon( "turret_deactivate" );
|
|
self.mg42 = var_0;
|
|
self endon( "death" );
|
|
self endon( "dropped_gun" );
|
|
var_2 = get_turret_setup_anim( var_0 );
|
|
self.turretmodel = "weapon_mg42_carry";
|
|
self notify( "kill_get_gun_back_on_killanimscript_thread" );
|
|
animscripts\shared::placeweaponon( self.weapon, "none" );
|
|
|
|
if ( self isbadguy() )
|
|
self.health = 1;
|
|
|
|
self.run_overrideanim = %saw_gunner_run_fast;
|
|
self.crouchrun_combatanim = %saw_gunner_run_fast;
|
|
self attach( self.turretmodel, level.portable_mg_gun_tag );
|
|
thread turretdeathdetacher();
|
|
var_3 = getstartorigin( var_0.origin, var_0.angles, var_2 );
|
|
self setruntopos( var_3 );
|
|
wait 0.05;
|
|
common_scripts\utility::set_all_exceptions( animscripts\combat::exception_exposed_mg42_portable );
|
|
common_scripts\utility::clear_exception( "move" );
|
|
common_scripts\utility::set_exception( "cover_crouch", ::hold_indefintely );
|
|
|
|
while ( distance( self.origin, var_3 ) > 16 )
|
|
{
|
|
self setruntopos( var_3 );
|
|
wait 0.05;
|
|
}
|
|
|
|
self notify( "kill_turret_detach_thread" );
|
|
|
|
if ( self isbadguy() )
|
|
self.health = var_1;
|
|
|
|
if ( soundexists( "weapon_setup" ) )
|
|
thread common_scripts\utility::play_sound_in_space( "weapon_setup" );
|
|
|
|
self animscripted( "setup_done", var_0.origin, var_0.angles, var_2 );
|
|
restoredefaults();
|
|
self waittillmatch( "setup_done", "end" );
|
|
var_0 notify( "restore_default_drop_pitch" );
|
|
var_0 show_turret();
|
|
animscripts\shared::placeweaponon( self.primaryweapon, "right" );
|
|
use_the_turret( var_0 );
|
|
self detach( self.turretmodel, level.portable_mg_gun_tag );
|
|
common_scripts\utility::set_all_exceptions( animscripts\init::empty );
|
|
self notify( "bcs_portable_turret_setup" );
|
|
}
|
|
|
|
move_to_run_pos()
|
|
{
|
|
self setruntopos( self.runpos );
|
|
}
|
|
|
|
hold_indefintely()
|
|
{
|
|
self endon( "killanimscript" );
|
|
self waittill( "death" );
|
|
}
|
|
|
|
using_a_turret()
|
|
{
|
|
if ( !isdefined( self.turret ) )
|
|
return 0;
|
|
|
|
return self.turret.owner == self;
|
|
}
|
|
|
|
turret_user_moves()
|
|
{
|
|
if ( !using_a_turret() )
|
|
{
|
|
common_scripts\utility::clear_exception( "move" );
|
|
return;
|
|
}
|
|
|
|
var_0 = find_connected_turrets( "connected" );
|
|
var_1 = var_0["spots"];
|
|
|
|
if ( !var_1.size )
|
|
{
|
|
common_scripts\utility::clear_exception( "move" );
|
|
return;
|
|
}
|
|
|
|
var_2 = self.node;
|
|
|
|
if ( !isdefined( var_2 ) || !maps\_utility::is_in_array( var_1, var_2 ) )
|
|
{
|
|
var_3 = gettakennodes();
|
|
|
|
for ( var_4 = 0; var_4 < var_1.size; var_4++ )
|
|
{
|
|
var_2 = common_scripts\utility::random( var_1 );
|
|
|
|
if ( isdefined( var_3[var_2.origin + ""] ) )
|
|
return;
|
|
}
|
|
}
|
|
|
|
var_5 = var_2.turret;
|
|
|
|
if ( isdefined( var_5.reserved ) )
|
|
return;
|
|
|
|
reserve_turret( var_5 );
|
|
|
|
if ( var_5.issetup )
|
|
leave_gun_and_run_to_new_spot( var_5 );
|
|
else
|
|
run_to_new_spot_and_setup_gun( var_5 );
|
|
|
|
maps\_mg_penetration::gunner_think( var_2.turret );
|
|
}
|
|
|
|
use_the_turret( var_0 )
|
|
{
|
|
var_1 = self useturret( var_0 );
|
|
|
|
if ( var_1 )
|
|
{
|
|
common_scripts\utility::set_exception( "move", ::turret_user_moves );
|
|
self.turret = var_0;
|
|
thread mg42_firing( var_0 );
|
|
var_0 setmode( "manual_ai" );
|
|
var_0 thread restorepitch();
|
|
self.turret = var_0;
|
|
var_0.owner = self;
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
var_0 restoredefaultdroppitch();
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
get_portable_mg_spot( var_0 )
|
|
{
|
|
var_1 = [];
|
|
var_1[var_1.size] = ::find_different_way_to_attack_last_seen_position;
|
|
var_1[var_1.size] = ::find_good_ambush_spot;
|
|
var_1 = common_scripts\utility::array_randomize( var_1 );
|
|
|
|
for ( var_2 = 0; var_2 < var_1.size; var_2++ )
|
|
{
|
|
var_3 = [[ var_1[var_2] ]]( var_0 );
|
|
|
|
if ( !isdefined( var_3["spots"] ) )
|
|
continue;
|
|
|
|
var_3["spot"] = common_scripts\utility::random( var_3["spots"] );
|
|
return var_3;
|
|
}
|
|
}
|
|
|
|
gettakennodes()
|
|
{
|
|
var_0 = [];
|
|
var_1 = getaiarray();
|
|
|
|
for ( var_2 = 0; var_2 < var_1.size; var_2++ )
|
|
{
|
|
if ( !isdefined( var_1[var_2].node ) )
|
|
continue;
|
|
|
|
var_0[var_1[var_2].node.origin + ""] = 1;
|
|
}
|
|
|
|
return var_0;
|
|
}
|
|
|
|
find_connected_turrets( var_0 )
|
|
{
|
|
var_1 = level.shared_portable_turrets;
|
|
var_2 = [];
|
|
var_3 = getarraykeys( var_1 );
|
|
var_4 = gettakennodes();
|
|
var_4[self.node.origin + ""] = undefined;
|
|
|
|
for ( var_5 = 0; var_5 < var_3.size; var_5++ )
|
|
{
|
|
var_6 = var_3[var_5];
|
|
|
|
if ( var_1[var_6] == self.turret )
|
|
continue;
|
|
|
|
var_7 = getarraykeys( self.turret.shared_turrets[var_0] );
|
|
|
|
for ( var_8 = 0; var_8 < var_7.size; var_8++ )
|
|
{
|
|
if ( var_1[var_6].export + "" != var_7[var_8] )
|
|
continue;
|
|
|
|
if ( isdefined( var_1[var_6].reserved ) )
|
|
continue;
|
|
|
|
if ( isdefined( var_4[var_1[var_6].node.origin + ""] ) )
|
|
continue;
|
|
|
|
if ( distance( self.goalpos, var_1[var_6].origin ) > self.goalradius )
|
|
continue;
|
|
|
|
var_2[var_2.size] = var_1[var_6];
|
|
}
|
|
}
|
|
|
|
var_9 = [];
|
|
var_9["type"] = var_0;
|
|
var_9["spots"] = var_2;
|
|
return var_9;
|
|
}
|
|
|
|
find_good_ambush_spot( var_0 )
|
|
{
|
|
return find_connected_turrets( "ambush" );
|
|
}
|
|
|
|
find_different_way_to_attack_last_seen_position( var_0 )
|
|
{
|
|
var_1 = find_connected_turrets( "connected" );
|
|
var_2 = var_1["spots"];
|
|
|
|
if ( !var_2.size )
|
|
return;
|
|
|
|
var_3 = [];
|
|
|
|
for ( var_4 = 0; var_4 < var_2.size; var_4++ )
|
|
{
|
|
if ( !common_scripts\utility::within_fov( var_2[var_4].origin, var_2[var_4].angles, var_0.origin, 0.75 ) )
|
|
continue;
|
|
|
|
if ( !sighttracepassed( var_0.origin, var_2[var_4].origin + ( 0, 0, 16 ), 0, undefined ) )
|
|
continue;
|
|
|
|
var_3[var_3.size] = var_2[var_4];
|
|
}
|
|
|
|
var_1["spots"] = var_3;
|
|
return var_1;
|
|
}
|
|
|
|
portable_mg_spot()
|
|
{
|
|
save_turret_sharing_info();
|
|
var_0 = 1;
|
|
self.issetup = 1;
|
|
self.reserved = undefined;
|
|
|
|
if ( isdefined( self.isvehicleattached ) )
|
|
return;
|
|
|
|
if ( self.spawnflags & var_0 )
|
|
return;
|
|
|
|
hide_turret();
|
|
}
|
|
|
|
hide_turret()
|
|
{
|
|
self notify( "stop_checking_for_flanking" );
|
|
self.issetup = 0;
|
|
self hide();
|
|
self.solid = 0;
|
|
self makeunusable();
|
|
self setdefaultdroppitch( 0 );
|
|
thread restoredefaultpitch();
|
|
}
|
|
|
|
show_turret()
|
|
{
|
|
self show();
|
|
self.solid = 1;
|
|
self makeusable();
|
|
self.issetup = 1;
|
|
thread stop_mg_behavior_if_flanked();
|
|
}
|
|
|
|
stop_mg_behavior_if_flanked()
|
|
{
|
|
self endon( "stop_checking_for_flanking" );
|
|
self waittill( "turret_deactivate" );
|
|
|
|
if ( isalive( self.owner ) )
|
|
self.owner notify( "end_mg_behavior" );
|
|
}
|
|
|
|
turret_is_mine( var_0 )
|
|
{
|
|
var_1 = var_0 getturretowner();
|
|
|
|
if ( !isdefined( var_1 ) )
|
|
return 0;
|
|
|
|
return var_1 == self;
|
|
}
|
|
|
|
end_turret_reservation( var_0 )
|
|
{
|
|
waittill_turret_is_released( var_0 );
|
|
var_0.reserved = undefined;
|
|
}
|
|
|
|
waittill_turret_is_released( var_0 )
|
|
{
|
|
var_0 endon( "turret_deactivate" );
|
|
self endon( "death" );
|
|
self waittill( "end_mg_behavior" );
|
|
}
|
|
|
|
reserve_turret( var_0 )
|
|
{
|
|
var_0.reserved = self;
|
|
thread end_turret_reservation( var_0 );
|
|
}
|