179 lines
4.1 KiB
Plaintext
179 lines
4.1 KiB
Plaintext
|
#include maps\_utility;
|
||
|
#include common_scripts\utility;
|
||
|
|
||
|
#using_animtree( "generic_human" );
|
||
|
|
||
|
JUGGERNAUT_MUSIC_DISTANCE = 2500;
|
||
|
|
||
|
// must be called before maps::\_load::main()
|
||
|
main()
|
||
|
{
|
||
|
if ( isdefined( level.juggernaut_initialized ) )
|
||
|
return;
|
||
|
|
||
|
level.juggernaut_initialized = true;
|
||
|
|
||
|
if ( !isdefined( level.subclass_spawn_functions ) )
|
||
|
level.subclass_spawn_functions = [];
|
||
|
|
||
|
level.subclass_spawn_functions[ "juggernaut" ] = ::subclass_juggernaut;
|
||
|
level.juggernaut_next_alert_time = 0;
|
||
|
}
|
||
|
|
||
|
subclass_juggernaut()
|
||
|
{
|
||
|
self.juggernaut = true;
|
||
|
|
||
|
//self.health = 1800;//moved to ai type
|
||
|
self.minPainDamage = 200;
|
||
|
|
||
|
self.grenadeAmmo = 0;
|
||
|
self.doorFlashChance = .05;
|
||
|
self.aggressivemode = true;
|
||
|
self.ignoresuppression = true;
|
||
|
self.no_pistol_switch = true;
|
||
|
self.noRunNGun = true;
|
||
|
self.dontMelee = true;
|
||
|
self.disableExits = true;
|
||
|
self.disableArrivals = true;
|
||
|
self.disableBulletWhizbyReaction = true;
|
||
|
self.combatMode = "no_cover";
|
||
|
self.neverSprintForVariation = true;
|
||
|
self.a.disableLongDeath = true;
|
||
|
|
||
|
self disable_turnAnims();
|
||
|
self disable_surprise();
|
||
|
|
||
|
init_juggernaut_animsets();
|
||
|
|
||
|
self add_damage_function( animscripts\pain::additive_pain );
|
||
|
self add_damage_function( maps\_spawner::pain_resistance );
|
||
|
|
||
|
if( !self isBadGuy() )
|
||
|
return;
|
||
|
|
||
|
self.bullet_resistance = 40;
|
||
|
self add_damage_function( maps\_spawner::bullet_resistance );
|
||
|
self thread juggernaut_hunt_immediately_behavior();
|
||
|
self thread juggernaut_sound_when_player_close();
|
||
|
|
||
|
|
||
|
self.pathEnemyFightDist = 128;
|
||
|
self.pathenemylookahead = 128;
|
||
|
level notify( "juggernaut_spawned" );
|
||
|
|
||
|
self waittill( "death", attacker, type, weapon );
|
||
|
|
||
|
if ( isdefined( self ) && isdefined( self.noDrop ) )
|
||
|
{
|
||
|
positions = [];
|
||
|
positions[ positions.size ] = "left";
|
||
|
positions[ positions.size ] = "right";
|
||
|
positions[ positions.size ] = "chest";
|
||
|
positions[ positions.size ] = "back";
|
||
|
|
||
|
self animscripts\shared::detachAllWeaponModels();
|
||
|
|
||
|
foreach ( position in positions )
|
||
|
{
|
||
|
weapon = self.a.weaponPos[ position ];
|
||
|
|
||
|
if ( weapon == "none" )
|
||
|
continue;
|
||
|
|
||
|
self.weaponInfo[ weapon ].position = "none";
|
||
|
self.a.weaponPos[ position ] = "none";
|
||
|
}
|
||
|
|
||
|
self.weapon = "none";
|
||
|
self animscripts\shared::updateAttachedWeaponModels();
|
||
|
}
|
||
|
|
||
|
level notify( "juggernaut_died" );
|
||
|
|
||
|
if ( ! isdefined( self ) )
|
||
|
return;// deleted
|
||
|
if ( ! isdefined( attacker ) )
|
||
|
return;
|
||
|
if ( ! isplayer( attacker ) )
|
||
|
return;
|
||
|
|
||
|
attacker player_giveachievement_wrapper( "IM_THE_JUGGERNAUT" );
|
||
|
}
|
||
|
|
||
|
juggernaut_hunt_immediately_behavior()
|
||
|
{
|
||
|
self endon( "death" );
|
||
|
self.useChokePoints = false;
|
||
|
|
||
|
|
||
|
//small goal at the player so they can close in aggressively
|
||
|
while ( 1 )
|
||
|
{
|
||
|
wait .5;
|
||
|
if ( isdefined( self.enemy ) )
|
||
|
{
|
||
|
self setgoalpos( self.enemy.origin );
|
||
|
self.goalradius = 128;
|
||
|
self.goalheight = 81;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
juggernaut_sound_when_player_close()
|
||
|
{
|
||
|
self endon( "death" );
|
||
|
level endon( "special_op_terminated" );
|
||
|
|
||
|
music_distance = JUGGERNAUT_MUSIC_DISTANCE;
|
||
|
if ( level.script == "ending" )
|
||
|
{
|
||
|
flag_wait( "panic_button" );
|
||
|
music_distance = 750;
|
||
|
}
|
||
|
|
||
|
while ( 1 )
|
||
|
{
|
||
|
wait 0.05;
|
||
|
|
||
|
if ( gettime() < level.juggernaut_next_alert_time )
|
||
|
continue;
|
||
|
|
||
|
player = get_closest_player( self.origin );
|
||
|
|
||
|
if ( !isalive( player ) )
|
||
|
continue;
|
||
|
|
||
|
if ( distance( player.origin, self.origin ) > music_distance )
|
||
|
continue;
|
||
|
|
||
|
if ( level.pmc_alljuggernauts )
|
||
|
{
|
||
|
if ( !BulletTracePassed( self getEye(), player geteye(), false, undefined ) )
|
||
|
{
|
||
|
wait 0.25; // reduce the amount of traces to the rate it used to use
|
||
|
continue;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
level.juggernaut_next_alert_time = gettime() + 15000;
|
||
|
level notify( "juggernaut_attacking" );
|
||
|
//iprintlnbold( "juggernaut" );
|
||
|
array_thread( level.players, ::playLocalSoundWrapper, "_juggernaut_attack" );
|
||
|
}
|
||
|
|
||
|
|
||
|
init_juggernaut_animsets()
|
||
|
{
|
||
|
self.walkDist = 500;
|
||
|
self.walkDistFacingMotion = 500;
|
||
|
|
||
|
self set_move_animset( "run", %Juggernaut_runF, %Juggernaut_sprint );
|
||
|
self set_move_animset( "walk", %Juggernaut_walkF );
|
||
|
self set_move_animset( "cqb", %Juggernaut_walkF );
|
||
|
self set_combat_stand_animset( %Juggernaut_stand_fire_burst, %Juggernaut_aim5, %Juggernaut_stand_idle, %Juggernaut_stand_reload );
|
||
|
}
|