iw6-scripts/animscripts/dog/dog_combat.gsc
2024-02-13 13:20:49 +01:00

1708 lines
48 KiB
Plaintext

// IW6 GSC SOURCE
// Generated by https://github.com/xensik/gsc-tool
main()
{
if ( isdefined( level.shark_functions ) )
{
if ( issubstr( self.model, "shark" ) )
{
self [[ level.shark_functions["combat"] ]]();
return;
}
}
self endon( "killanimscript" );
if ( !isalive( self.enemy ) )
combatidle();
else
{
if ( isplayer( self.enemy ) )
{
meleebiteattackplayer();
return;
}
meleestrugglevsai();
}
}
end_script()
{
self setpitchorient();
self.doglastknowngoodpos = undefined;
}
killplayer()
{
self endon( "pvd_melee_interrupted" );
if ( !isdefined( self.meleeingplayer.player_view ) )
return;
var_0 = self.meleeingplayer.player_view;
if ( isdefined( var_0.player_killed ) )
return;
var_0.player_killed = 1;
if ( maps\_utility::killing_will_down( self.meleeingplayer ) )
{
knock_down_player_coop( self.meleeingplayer, self );
return;
}
self.meleeingplayer.specialdeath = 1;
self.meleeingplayer setcandamage( 1 );
playfxontag( level._effect["dog_bite_blood"], var_0, "tag_torso" );
wait 1;
if ( !isdefined( self ) || !isdefined( self.meleeingplayer ) )
return;
var_1 = is_hyena();
self.meleeingplayer enablehealthshield( 0 );
if ( !isalive( self.meleeingplayer ) )
return;
self.meleeingplayer dog_player_kill( self );
self.meleeingplayer shellshock( "default", 5 );
waittillframeend;
setdvar( "ui_deadquote", "" );
thread dog_death_hud( self.meleeingplayer, var_1 );
}
#using_animtree("dog");
knock_down_player_coop( var_0, var_1 )
{
var_0.dog_downed_player = 1;
var_2 = dog_vs_player_anim_rate();
self setflaggedanimknobrestart( "meleeanim", %german_shepherd_player_getoff, 1, 0.1, var_2 );
var_0.player_view notify( "pvd_melee_interrupted" );
var_0.player_view notify( "pvd_melee_done" );
var_0.player_view playerview_endsequence( var_0 );
if ( !maps\_utility::killing_will_down( var_0 ) )
var_0 dog_player_kill( var_1 );
}
dog_player_kill( var_0 )
{
if ( maps\_utility::laststand_enabled() )
self enabledeathshield( 0 );
self disableinvulnerability();
if ( isalive( var_0 ) )
self kill( self.origin, var_0 );
else
self kill( self.origin );
}
dog_death_hud( var_0, var_1 )
{
if ( maps\_utility::is_specialop() )
return;
wait 1.5;
thread dog_deathquote( var_0 );
var_2 = newclienthudelem( var_0 );
var_2.x = 0;
var_2.y = 50;
if ( var_1 )
var_2 setshader( "hud_hyena_melee", 96, 96 );
else
var_2 setshader( "hud_dog_melee", 96, 96 );
var_2.alignx = "center";
var_2.aligny = "middle";
var_2.horzalign = "center";
var_2.vertalign = "middle";
var_2.foreground = 1;
var_2.alpha = 0;
var_2 fadeovertime( 1 );
var_2.alpha = 1;
}
dog_deathquote( var_0 )
{
var_1 = var_0 maps\_hud_util::createclientfontstring( "default", 1.75 );
var_1.color = ( 1, 1, 1 );
var_1 settext( level.dog_death_quote );
var_1.x = 0;
var_1.y = -30;
var_1.alignx = "center";
var_1.aligny = "middle";
var_1.horzalign = "center";
var_1.vertalign = "middle";
var_1.foreground = 1;
var_1.alpha = 0;
var_1 fadeovertime( 1 );
var_1.alpha = 1;
}
attackmiss()
{
self clearanim( %body, 0.1 );
var_0 = %german_shepherd_attack_player_miss_b;
if ( isdefined( self.enemy ) )
{
var_1 = anglestoforward( ( 0, self.desiredangle, 0 ) );
var_2 = vectornormalize( self.enemy.origin - self.origin );
var_3 = self.enemy.origin - ( self.origin + var_1 * 40 );
if ( vectordot( var_2, var_1 ) > 0.707 || vectordot( var_3, var_1 ) > 0 )
thread animscripts\dog\dog_stop::lookattarget( "normal" );
else
{
self.skipstartmove = 1;
thread attackmisstracktargetthread();
if ( var_2[0] * var_1[1] - var_2[1] * var_1[0] > 0 )
var_0 = %german_shepherd_attack_player_miss_turnr;
else
var_0 = %german_shepherd_attack_player_miss_turnl;
}
}
self setflaggedanimrestart( "miss_anim", var_0, 1, 0, 1 );
var_4 = getanimlength( var_0 );
animscripts\notetracks::donotetracksfortime( var_4 - 0.1, "miss_anim" );
self notify( "stop tracking" );
}
attackmisstracktargetthread()
{
self endon( "killanimscript" );
wait 0.6;
self orientmode( "face enemy" );
}
knockoutofads( var_0 )
{
var_0 endon( "death" );
var_0 allowads( 0 );
wait 0.75;
var_0 allowads( 1 );
}
dogmelee()
{
if ( isdefined( self.meleeingplayer ) )
{
if ( isdefined( self.meleeingplayer.using_uav ) && self.meleeingplayer.using_uav )
self.meleeingplayer notify( "force_out_of_uav" );
if ( self.meleeingplayer islinked() )
return undefined;
if ( self.meleeingplayer ismantling() )
return undefined;
if ( self.meleeingplayer.laststand && self.meleeingplayer.ignoreme )
return undefined;
}
if ( isdefined( self.enemy ) )
{
if ( distance2d( self.origin, self.enemy.origin ) < 32 )
return self melee();
}
return self melee( anglestoforward( self.angles ) );
}
handlemeleebiteattacknotetracks( var_0 )
{
switch ( var_0 )
{
case "dog_melee":
var_1 = dogmelee();
if ( isdefined( var_1 ) )
{
if ( isplayer( var_1 ) )
{
var_1 shellshock( "dog_bite", 1 );
thread knockoutofads( var_1 );
}
}
else
{
attackmiss();
return 1;
}
break;
case "stop_tracking":
self orientmode( "face current" );
break;
}
}
addsafetyhealth()
{
var_0 = self.meleeingplayer getnormalhealth();
if ( var_0 == 0 )
return 0;
if ( var_0 < 0.25 )
{
self.meleeingplayer setnormalhealth( var_0 + 0.25 );
return 1;
}
return 0;
}
removesafetyhealth()
{
var_0 = self.meleeingplayer getnormalhealth();
if ( var_0 > 0.25 )
self.meleeingplayer setnormalhealth( var_0 - 0.25 );
else
self.meleeingplayer setnormalhealth( 0.01 );
}
handlemeleefinishattacknotetracks( var_0 )
{
switch ( var_0 )
{
case "dog_melee":
var_1 = addsafetyhealth();
var_2 = dogmelee();
if ( isdefined( var_2 ) && isplayer( var_2 ) && isalive( self.meleeingplayer ) )
{
if ( var_1 )
removesafetyhealth();
self.skipstartmove = undefined;
self.meleeingplayer.player_view = playerview_spawn( self );
if ( self.meleeingplayer.player_view playerview_startsequence( self ) )
self setcandamage( 0 );
}
else
{
if ( var_1 )
removesafetyhealth();
attackmiss();
return 1;
}
break;
case "dog_early":
self notify( "dog_early_notetrack" );
var_3 = 0.45 + 0.8 * level.dog_melee_timing_array[level.dog_melee_index];
var_3 = var_3 * dog_vs_player_anim_rate();
level.dog_melee_index++;
if ( level.dog_melee_index >= level.dog_melee_timing_array.size )
{
level.dog_melee_index = 0;
level.dog_melee_timing_array = common_scripts\utility::array_randomize( level.dog_melee_timing_array );
}
self setflaggedanimlimited( "meleeanim", %german_shepherd_attack_player, 1, 0.2, var_3 );
self setflaggedanimlimited( "meleeanim", %german_shepherd_attack_player_late, 1, 0.2, var_3 );
self.meleeingplayer.player_view playerview_playknockdownanimlimited( var_3 );
break;
case "dog_lunge":
thread set_melee_timer();
var_3 = dog_vs_player_anim_rate();
self setflaggedanim( "meleeanim", %german_shepherd_attack_player, 1, 0.2, var_3 );
self.meleeingplayer.player_view playerview_playknockdownanim( var_3 );
break;
case "dogbite_damage":
thread killplayer();
break;
case "stop_tracking":
self orientmode( "face current" );
break;
}
}
handle_dogbite_notetrack( var_0 )
{
switch ( var_0 )
{
case "dogbite_damage":
thread killplayer();
break;
}
}
set_melee_timer()
{
wait 0.1;
thread dog_hint();
wait 0.05;
self.melee_able_timer = gettime();
}
playerdoginit()
{
self.lastdogmeleeplayertime = 0;
self.dogmeleeplayercounter = 0;
}
meleebiteattackplayer()
{
self.meleeingplayer = self.enemy;
if ( !isdefined( self.meleeingplayer.doginited ) )
self.meleeingplayer playerdoginit();
var_0 = 30;
var_1 = self.meleeattackdist + var_0;
for (;;)
{
if ( !isalive( self.enemy ) )
break;
if ( !isplayer( self.enemy ) )
break;
if ( maps\_utility::is_player_down( self.enemy ) )
{
combatidle();
continue;
}
if ( isdefined( self.meleeingplayer.syncedmeleetarget ) && self.meleeingplayer.syncedmeleetarget != self || isdefined( self.meleeingplayer.player_view ) && isdefined( self.meleeingplayer.player_view.inseq ) )
{
if ( checkendcombat( var_1 ) )
break;
else
{
combatidle();
continue;
}
}
if ( shouldwaitincombatidle() )
{
combatidle();
continue;
}
self orientmode( "face enemy" );
self animmode( "zonly_physics" );
self.safetochangescript = 0;
prepareattackplayer();
self clearanim( %body, 0.1 );
self clearpitchorient();
self.meleeingplayer setnextdogattackallowtime( 500 );
if ( dog_cant_kill_in_one_hit() )
{
self.meleeingplayer.lastdogmeleeplayertime = gettime();
self.meleeingplayer.dogmeleeplayercounter++;
self setflaggedanimrestart( "meleeanim", %german_shepherd_run_attack_b, 1, 0.2, 1 );
animscripts\shared::donotetracks( "meleeanim", ::handlemeleebiteattacknotetracks );
}
else
{
thread dog_melee_death();
self.meleeingplayer.attacked_by_dog = 1;
self.meleeingplayer.laststand = 0;
self.meleeingplayer.achieve_downed_kills = undefined;
thread clear_player_attacked_by_dog_on_death();
self setflaggedanimrestart( "meleeanim", %german_shepherd_attack_player, 1, 0.2, 1 );
self setflaggedanimrestart( "meleeanim", %german_shepherd_attack_player_late, 1, 0, 1 );
self setanimlimited( %attack_player, 1, 0, 1 );
self setanimlimited( %attack_player_late, 0.01, 0, 1 );
animscripts\shared::donotetracks( "meleeanim", ::handlemeleefinishattacknotetracks );
self notify( "dog_no_longer_melee_able" );
self setcandamage( 1 );
self unlink();
}
self.safetochangescript = 1;
wait 0.05;
if ( checkendcombat( var_1 ) )
break;
}
self.safetochangescript = 1;
self animmode( "none" );
}
clear_player_attacked_by_dog_on_death()
{
self waittill( "death" );
self.meleeingplayer.attacked_by_dog = undefined;
}
dog_cant_kill_in_one_hit()
{
if ( isdefined( self.meleeingplayer.dogs_dont_instant_kill ) )
return 1;
if ( maps\_utility::is_player_down( self.meleeingplayer ) )
return 1;
if ( isdefined( self.meleeingplayer.slidemodel ) )
return 1;
if ( gettime() - self.meleeingplayer.lastdogmeleeplayertime > 8000 )
self.meleeingplayer.dogmeleeplayercounter = 0;
return self.meleeingplayer.dogmeleeplayercounter < self.meleeingplayer.gs.dog_hits_before_kill && self.meleeingplayer.health > 25;
}
shouldwaitincombatidle()
{
return isdefined( self.enemy.dogattackallowtime ) && gettime() < self.enemy.dogattackallowtime;
}
setnextdogattackallowtime( var_0 )
{
self.dogattackallowtime = gettime() + var_0;
}
isdoingtraversal()
{
return self isinscriptedstate() && self.script != "scripted" && self.script != "<custom>";
}
meleestrugglevsai()
{
if ( !isalive( self.enemy ) )
return;
if ( isdefined( self.enemy.melee ) )
{
if ( !isdefined( self.enemy.melee.target ) || self.enemy.melee.target != self )
{
combatidle();
return;
}
}
if ( isdefined( self.enemy.syncedmeleetarget ) || shouldwaitincombatidle() || !isai( self.enemy ) )
combatidle();
else
{
self.in_melee = 1;
self.enemy setnextdogattackallowtime( 500 );
self.enemy.dog_attacking_me = self;
var_0 = animscripts\battlechatter::getdirectionfacingclock( self.enemy.angles, self.enemy.origin, self.origin );
var_1 = "F";
switch ( var_0 )
{
case "4":
case "3":
case "2":
var_1 = "R";
break;
case "10":
case "9":
case "8":
var_1 = "L";
break;
case "7":
case "6":
case "5":
var_1 = "B";
break;
}
self.enemy.dog_attack_dir = var_1;
level notify( "dog_attacks_ai", self, self.enemy, var_1 );
self.enemy notify( "dog_attacks_ai", self, var_1 );
if ( isdefined( level.dog_alt_melee_func ) )
{
if ( [[ level.dog_alt_melee_func ]]( var_1 ) )
return 1;
}
self.safetochangescript = 0;
self animmode( "zonly_physics" );
self.pushable = 0;
self clearpitchorient();
self.meleekilltarget = !isdefined( self.enemy.magic_bullet_shield ) && ( isdefined( self.enemy.a.doinglongdeath ) || isdefined( self.meleealwayswin ) || randomint( 100 ) > 50 );
self.originaltarget = self.enemy;
self.enemy.battlechatter = 0;
self.enemy.ignoreall = 1;
self.enemy clearenemy();
self.enemy.diequietly = 1;
var_2 = 0;
if ( isdefined( self.enemy.use_old_dog_attack ) )
var_2 = 1;
if ( meleestruggle_istraverse() )
return meleestrugglevsai_traverse( var_1 );
var_3 = vectortoangles( self.origin - self.enemy.origin );
var_3 = ( 0, var_3[1], 0 );
var_4 = [];
var_4[0] = %body;
if ( var_2 )
{
self.enemy.use_old_dog_attack = 1;
var_4[1] = %iw6_dog_kill_front_quick_1;
var_5 = 1;
if ( isdefined( self.controlling_dog ) && self.controlling_dog )
thread maps\_utility::play_sound_on_entity( "scn_nml_dog_attack_short" );
else
thread maps\_utility::play_sound_on_entity( "scn_nml_dog_attack_short_npc" );
}
else if ( isdefined( self.enemy.a.doinglongdeath ) || self.enemy.a.pose == "prone" || self.enemy isdoingtraversal() )
{
thread maps\_utility::play_sound_on_entity( "scn_nml_dog_attack_short_npc" );
return domeleevsai_simple();
}
else
{
var_4[1] = %iw6_dog_kill_front_long_1;
var_5 = 1;
switch ( var_1 )
{
case "R":
var_4[1] = %iw6_dog_kill_right_quick_1;
var_5 = 1;
var_3 = var_3 + ( 0, 90, 0 );
if ( isdefined( self.controlling_dog ) && self.controlling_dog )
thread maps\_utility::play_sound_on_entity( "scn_nml_dog_attack_short" );
else
thread maps\_utility::play_sound_on_entity( "scn_nml_dog_attack_short_npc" );
break;
case "L":
var_4[1] = %iw6_dog_kill_left_quick_1;
var_5 = 1;
var_3 = var_3 + ( 0, -90, 0 );
if ( isdefined( self.controlling_dog ) && self.controlling_dog )
thread maps\_utility::play_sound_on_entity( "scn_nml_dog_attack_short" );
else
thread maps\_utility::play_sound_on_entity( "scn_nml_dog_attack_short_npc" );
break;
case "B":
var_4[1] = %iw6_dog_kill_back_quick_1;
var_5 = 1;
var_3 = var_3 - ( 0, 180, 0 );
if ( isdefined( self.controlling_dog ) && self.controlling_dog )
thread maps\_utility::play_sound_on_entity( "scn_nml_dog_attack_quick_back_plr" );
else
thread maps\_utility::play_sound_on_entity( "scn_nml_dog_attack_quick_back_npc" );
break;
default:
if ( isdefined( self.controlling_dog ) && self.controlling_dog )
thread maps\_utility::play_sound_on_entity( "scn_nml_dog_attack_front_plr" );
else
thread maps\_utility::play_sound_on_entity( "scn_nml_dog_attack_front_npc" );
break;
}
}
}
}
domeleevsai_simple()
{
self animcustom( ::domeleevsai_simple_animcustom, ::domeleevsai_simple_animcustom_cleanup );
return 1;
}
domeleevsai_simple_animcustom()
{
self notify( "stop_pant" );
self.flashbangimmunity = 1;
self.enemy meleestrugglevsdog_justdie();
var_0 = self.enemy.origin - self.origin;
var_1 = vectortoangles( var_0 );
self clearanim( %body, 0.1 );
self animmode( "zonly_physics" );
self orientmode( "face angle", var_1[1] );
self setflaggedanim( "meleeanim", %iw6_dog_kill_low_front_1 );
animscripts\shared::donotetracks( "meleeanim" );
}
domeleevsai_simple_animcustom_cleanup()
{
self.pushable = 1;
self.safetochangescript = 1;
self.flashbangimmunity = 0;
self.in_melee = 0;
}
domeleevsai( var_0, var_1, var_2, var_3 )
{
self notify( "stop_pant" );
self setcandamage( 0 );
self.enemy.fndogmeleevictim = var_3;
self endon( "melee_dog_interrupted" );
thread meleestrugglevsai_interruptedcheck( self.enemy );
self clearanim( var_0[0], 0.1 );
self animrelative( "meleeanim", self.enemy.origin, var_2, var_0[1] );
if ( !animhasnotetrack( var_0[1], "ai_attack_start" ) )
handlestartaipart( "ai_attack_start" );
animscripts\shared::donotetracks( "meleeanim", ::handlestartaipart );
self notify( "end_dog_interrupted_check" );
self setcandamage( 1 );
self animmode( "zonly_physics" );
for ( var_4 = 1; var_4 < var_1; var_4++ )
{
if ( isdefined( level._effect["dog_bite"] ) && isdefined( level._effect["dog_bite"][var_4] ) && isdefined( self.enemy ) )
playfxontag( level._effect["dog_bite"][var_4], self.enemy, "TAG_EYE" );
self clearanim( var_0[var_4], 0 );
if ( !insyncmeleewithtarget() )
break;
if ( !self.meleekilltarget && var_4 + 1 == var_1 )
self.health = 1;
self setflaggedanimrestart( "meleeanim", var_0[var_4 + 1], 1, 0, 1 );
animscripts\shared::donotetracks( "meleeanim" );
}
melee_dogcleanup();
return 1;
}
melee_dogcleanup()
{
self unlink();
if ( !self.meleekilltarget )
{
if ( !isdefined( self.magic_bullet_shield ) )
self kill();
}
else
{
self.pushable = 1;
self.safetochangescript = 1;
self.flashbangimmunity = 0;
}
thread ragdoll_corpses();
self.in_melee = 0;
if ( isdefined( self.doglastknowngoodpos ) )
{
var_0 = self aiphysicstrace( self.origin, self.origin + ( 0, 0, 2 ), undefined, undefined, 1, 0, 1 );
if ( distancesquared( var_0, self.origin ) < 0.001 )
self forceteleport( self.doglastknowngoodpos, self.angles, 60 );
self.doglastknowngoodpos = undefined;
}
self animmode( "none" );
}
meleestruggle_istraverse()
{
var_0 = self getdogattackbeginnode();
return isdefined( var_0 );
}
meleestrugglevsai_traverse( var_0 )
{
self.safetochangescript = 0;
self animmode( "zonly_physics" );
self.pushable = 0;
self clearpitchorient();
self.meleekilltarget = !isdefined( self.enemy.magic_bullet_shield ) && ( isdefined( self.enemy.a.doinglongdeath ) || isdefined( self.meleealwayswin ) || randomint( 100 ) > 50 );
self.originaltarget = self.enemy;
self.enemy.battlechatter = 0;
var_1 = vectortoangles( self.origin - self.enemy.origin );
var_1 = ( 0, var_1[1], 0 );
var_2 = [];
var_2[0] = %body;
var_2[1] = %iw6_dog_kill_wall_over_front_1;
var_3 = 1;
if ( self.enemy isdoingtraversal() )
thread maps\_utility::play_sound_on_entity( "scn_nml_dog_attack_short_npc" );
else if ( isdefined( self.controlling_dog ) && self.controlling_dog )
thread maps\_utility::play_sound_on_entity( "scn_nml_dog_attack_front_plr" );
else
thread maps\_utility::play_sound_on_entity( "scn_nml_dog_attack_front_npc" );
self.doglastknowngoodpos = self.origin;
return domeleevsai( var_2, var_3, var_1, ::meleestrugglevsdog_traverse );
}
meleestrugglevsai_interrupted_animcustom()
{
self animmode( "gravity" );
self clearanim( %body, 0.2 );
self setflaggedanim( "meleeanim", %iw6_dog_kill_breach_end_nml );
animscripts\shared::donotetracks( "meleeanim" );
}
meleestrugglevsai_interrupted_animcustom_cleanup()
{
if ( isdefined( self.doglastknowngoodposcustom ) )
self.doglastknowngoodpos = self.doglastknowngoodposcustom;
self.doglastknowngoodposcustom = undefined;
self animmode( "zonly_physics" );
melee_dogcleanup();
meleestrugglevsdog_end();
}
meleestrugglevsai_interruptedcheck( var_0 )
{
self endon( "killanimscript" );
self endon( "death" );
self endon( "end_melee_all" );
self endon( "end_dog_interrupted_check" );
var_0 waittill( "death" );
self notify( "melee_dog_interrupted" );
self unlink();
self setcandamage( 1 );
self.doglastknowngoodposcustom = self.doglastknowngoodpos;
self animcustom( ::meleestrugglevsai_interrupted_animcustom, ::meleestrugglevsai_interrupted_animcustom_cleanup );
}
combatidle()
{
self orientmode( "face enemy" );
self clearanim( %body, 0.1 );
self animmode( "zonly_physics" );
var_0 = [];
var_0[0] = %iw6_dog_attackidle;
var_0[1] = %iw6_dog_attackidle_bark;
var_1 = common_scripts\utility::random( var_0 );
thread combatidlepreventoverlappingplayer();
self setflaggedanimrestart( "combat_idle", var_1, 1, 0.2, 1 );
animscripts\shared::donotetracks( "combat_idle" );
self notify( "combatIdleEnd" );
}
combatidlepreventoverlappingplayer()
{
self endon( "killanimscript" );
self endon( "combatIdleEnd" );
for (;;)
{
wait 0.1;
var_0 = getentarray( "player", "classname" );
for ( var_1 = 0; var_1 < var_0.size; var_1++ )
{
var_2 = var_0[var_1];
if ( !isdefined( var_2.syncedmeleetarget ) || var_2.syncedmeleetarget == self )
continue;
var_3 = var_2.origin - self.origin;
if ( var_3[2] * var_3[2] > 6400 )
continue;
var_3 = ( var_3[0], var_3[1], 0 );
var_4 = length( var_3 );
if ( var_4 < 1 )
var_3 = anglestoforward( self.angles );
if ( var_4 < 30 )
{
var_3 = var_3 * ( 3 / var_4 );
self safeteleport( self.origin - var_3, ( 0, 30, 0 ) );
}
}
}
}
insyncmeleewithtarget()
{
return isdefined( self.enemy ) && isdefined( self.enemy.syncedmeleetarget ) && self.enemy.syncedmeleetarget == self;
}
handlestartaipart( var_0 )
{
if ( var_0 != "ai_attack_start" )
{
handlevxnotetrack( var_0 );
return undefined;
}
if ( !isdefined( self.enemy ) )
return 1;
if ( self.enemy != self.originaltarget )
return 1;
if ( isdefined( self.enemy.syncedmeleetarget ) )
return 1;
self.flashbangimmunity = 1;
self.enemy.syncedmeleetarget = self;
if ( self.enemy isdoingtraversal() )
self.enemy meleestrugglevsdog_justdie();
else if ( isdefined( self.enemy.fndogmeleevictim ) )
self.enemy animcustom( self.enemy.fndogmeleevictim );
else
self.enemy animcustom( ::meleestrugglevsdog );
}
checkendcombat( var_0 )
{
if ( !isdefined( self.enemy ) )
return 0;
var_1 = distancesquared( self.origin, self.enemy.origin );
return var_1 > var_0 * var_0;
}
prepareattackplayer()
{
if ( is_hyena() )
{
level.dog_death_quote = &"NEW_HYENA_DEATH_DO_NOTHING_ALT";
level.so_dog_death_quote = "@NEW_HYENA_DEATH_DO_NOTHING_ALT";
}
else
{
level.dog_death_quote = &"NEW_DOG_DEATH_DO_NOTHING_ALT";
level.so_dog_death_quote = "@NEW_DOG_DEATH_DO_NOTHING_ALT";
}
level.dog_death_type = "nothing";
var_0 = distance( self.origin, self.enemy.origin );
if ( var_0 > self.meleeattackdist )
{
var_1 = self.enemy.origin - self.origin;
var_2 = ( var_0 - self.meleeattackdist ) / var_0;
var_1 = ( var_1[0] * var_2, var_1[1] * var_2, var_1[2] * var_2 );
thread attackteleportthread( var_1 );
}
}
attackteleportthread( var_0 )
{
self endon( "death" );
self endon( "killanimscript" );
var_1 = 5;
var_2 = ( var_0[0] / var_1, var_0[1] / var_1, var_0[2] / var_1 );
for ( var_3 = 0; var_3 < var_1; var_3++ )
{
self teleport( self.origin + var_2 );
wait 0.05;
}
}
player_attacked()
{
return isalive( self.meleeingplayer ) && self.meleeingplayer meleebuttonpressed();
}
dog_hint()
{
var_0 = self.meleeingplayer.gs.dog_presstime / 1000 / dog_vs_player_anim_rate();
level endon( "clearing_dog_hint" );
if ( isdefined( self.meleeingplayer.doghintelem ) )
self.meleeingplayer.doghintelem maps\_hud_util::destroyelem();
self.meleeingplayer.doghintelem = self.meleeingplayer maps\_hud_util::createclientfontstring( "default", 3 );
self.meleeingplayer.doghintelem.color = ( 1, 1, 1 );
self.meleeingplayer.doghintelem settext( &"SCRIPT_PLATFORM_DOG_HINT" );
self.meleeingplayer.doghintelem.x = 0;
self.meleeingplayer.doghintelem.y = 20;
self.meleeingplayer.doghintelem.alignx = "center";
self.meleeingplayer.doghintelem.aligny = "middle";
self.meleeingplayer.doghintelem.horzalign = "center";
self.meleeingplayer.doghintelem.vertalign = "middle";
self.meleeingplayer.doghintelem.foreground = 1;
self.meleeingplayer.doghintelem.alpha = 1;
self.meleeingplayer.doghintelem.hidewhendead = 1;
self.meleeingplayer.doghintelem.sort = -1;
self.meleeingplayer.doghintelem endon( "death" );
wait( var_0 );
thread dog_hint_fade();
}
dog_hint_fade()
{
level notify( "clearing_dog_hint" );
if ( isdefined( self ) && isdefined( self.meleeingplayer.doghintelem ) )
{
var_0 = self.meleeingplayer.doghintelem;
if ( isdefined( self.meleeingplayer.player_view.necksnapped ) && self.meleeingplayer.player_view.necksnapped )
{
var_1 = 0.5;
var_0 changefontscaleovertime( var_1 );
var_0.fontscale = var_0.fontscale * 1.5;
var_0.glowcolor = ( 0.3, 0.6, 0.3 );
var_0.glowalpha = 1;
var_0 fadeovertime( var_1 );
var_0.color = ( 0, 0, 0 );
var_0.alpha = 0;
wait( var_1 );
var_0 maps\_hud_util::destroyelem();
}
else
var_0 maps\_hud_util::destroyelem();
}
}
dog_delayed_unlink()
{
wait 0.7;
if ( isdefined( self ) )
self unlink();
}
dog_delayed_allow_damage()
{
self endon( "death" );
wait 1.5;
if ( isdefined( self ) )
self setcandamage( 1 );
}
dog_melee_death()
{
self endon( "killanimscript" );
self endon( "dog_no_longer_melee_able" );
var_0 = 0;
var_1 = self.meleeingplayer.gs.dog_presstime / dog_vs_player_anim_rate();
self waittill( "dog_early_notetrack" );
while ( player_attacked() )
wait 0.05;
var_2 = 0;
for (;;)
{
if ( !var_0 )
{
if ( player_attacked() )
{
var_0 = 1;
if ( isdefined( self.melee_able_timer ) && isalive( self.meleeingplayer ) )
{
if ( gettime() - self.melee_able_timer <= var_1 )
{
self.meleeingplayer set_melee_early( var_2 );
self.meleeingplayer.player_view.necksnapped = 1;
self notify( "melee_stop" );
self setflaggedanimknobrestart( "dog_death_anim", %german_shepherd_player_neck_snap, 1, 0.2, 1 );
thread dog_delayed_allow_damage();
self setcandamage( 0 );
self waittillmatch( "dog_death_anim", "dog_death" );
thread common_scripts\utility::play_sound_in_space( "dog_neckbreak", self geteye() );
self setcandamage( 1 );
self.a.nodeath = 1;
self.dog_neck_snapped = 1;
var_3 = self.meleeingplayer.origin - self.origin;
var_3 = ( var_3[0], var_3[1], 0 );
thread dog_delayed_unlink();
self kill( self geteye() - var_3, self.meleeingplayer );
self notify( "killanimscript" );
}
else
{
self.meleeingplayer set_melee_early( var_2 );
self.meleeingplayer.player_view playerview_knockdownlate();
self setanimlimited( %attack_player, 0.01, 0.2, 1 );
self setanimlimited( %attack_player_late, 1, 0.2, 1 );
if ( is_hyena() )
{
level.dog_death_quote = &"NEW_HYENA_DEATH_TOO_LATE_ALT";
level.so_dog_death_quote = "@NEW_HYENA_DEATH_TOO_LATE_ALT";
}
else
{
level.dog_death_quote = &"NEW_DOG_DEATH_TOO_LATE_ALT";
level.so_dog_death_quote = "@NEW_DOG_DEATH_TOO_LATE_ALT";
}
level.dog_death_type = "late";
}
return;
}
var_2 = 1;
if ( self.meleeingplayer can_early_melee() )
{
if ( is_hyena() )
{
level.dog_death_quote = &"NEW_HYENA_DEATH_TOO_SOON_ALT";
level.so_dog_death_quote = "@NEW_HYENA_DEATH_TOO_SOON_ALT";
}
else
{
level.dog_death_quote = &"NEW_DOG_DEATH_TOO_SOON_ALT";
level.so_dog_death_quote = "@NEW_DOG_DEATH_TOO_SOON_ALT";
}
level.dog_death_type = "soon";
var_4 = dog_vs_player_anim_rate();
self setflaggedanimknobrestart( "meleeanim", %german_shepherd_player_neck_miss, 1, 0.2, var_4 );
self.meleeingplayer.player_view playerview_playmissanim( var_4 );
return;
}
}
}
else if ( !player_attacked() )
var_0 = 0;
wait 0.05;
}
}
can_early_melee()
{
if ( self.gameskill == 3 )
return 1;
if ( isdefined( self.dogmeleeearly ) && self.dogmeleeearly )
return 1;
return 0;
}
set_melee_early( var_0 )
{
if ( !var_0 )
return;
if ( level.gameskill > 1 && !isdefined( self.dogmeleeearly ) )
self.dogmeleeearly = 1;
}
#using_animtree("generic_human");
meleestrugglevsdog()
{
self endon( "killanimscript" );
self endon( "death" );
self endon( "end_melee_all" );
if ( !isdefined( self.syncedmeleetarget ) )
return;
self stopsounds();
var_0 = vectortoangles( self.syncedmeleetarget.origin - self.origin );
var_1 = var_0[1];
if ( isdefined( self.use_old_dog_attack ) && self.use_old_dog_attack )
{
var_2 = [];
var_2[0] = %body;
var_2[1] = %iw6_dog_kill_front_quick_guy_1;
var_3 = 1;
maps\_utility::gun_remove();
}
else
{
var_2 = [];
var_2[0] = %body;
switch ( self.dog_attack_dir )
{
case "F":
var_2[1] = %iw6_dog_kill_front_long_guy_1;
var_3 = 1;
playsound_victim( "dogdeathlong" );
break;
case "R":
var_2[1] = %iw6_dog_kill_right_quick_guy_1;
var_3 = 1;
var_1 = var_0[1] + 90;
playsound_victim( "dogdeathshort" );
break;
case "L":
var_2[1] = %iw6_dog_kill_left_quick_guy_1;
var_3 = 1;
var_1 = var_0[1] - 90;
playsound_victim( "dogdeathshort" );
break;
case "B":
var_2[1] = %iw6_dog_kill_back_quick_guy_1;
var_3 = 1;
var_1 = var_0[1] - 180;
playsound_victim( "dogdeathshort" );
break;
default:
break;
}
}
domeleevsdog( var_2, var_1 );
}
playsound_victim( var_0 )
{
if ( isdefined( self.syncedmeleetarget.controlling_dog ) )
var_0 = var_0 + "plr";
thread animscripts\face::saygenericdialogue( var_0 );
}
meleestrugglevsdog_interruptedcheck()
{
self endon( "killanimscript" );
self endon( "death" );
self endon( "end_melee_all" );
var_0 = [];
var_0[1] = %ai_attacked_german_shepherd_02_getup_a;
var_0[2] = %ai_attacked_german_shepherd_02_getup_a;
if ( self.syncedmeleetarget.meleekilltarget )
var_0[4] = %ai_attacked_german_shepherd_04_getup_a;
for (;;)
{
if ( !isdefined( self.syncedmeleetarget ) || !isalive( self.syncedmeleetarget ) )
break;
wait 0.1;
}
self.ragdoll_immediate = undefined;
if ( self.meleeseq > 0 )
{
if ( !isdefined( var_0[self.meleeseq] ) )
return;
self clearanim( %melee_dog, 0.1 );
self setflaggedanimrestart( "getupanim", var_0[self.meleeseq], 1, 0.1, 1 );
animscripts\shared::donotetracks( "getupanim" );
}
meleestrugglevsdog_end();
}
meleestrugglevsdog_end()
{
self orientmode( "face default" );
self.syncedmeleetarget = undefined;
self.meleeseq = undefined;
self.allowpain = 1;
self.battlechatter = 1;
self.use_old_dog_attack = undefined;
self.dog_attacking_me = undefined;
setnextdogattackallowtime( 1000 );
if ( isdefined( self.olddontattackme ) )
{
self.dontattackme = self.olddontattackme;
self.olddontattackme = undefined;
}
self notify( "end_melee_all" );
}
meleestrugglevsdog_collision( var_0 )
{
self endon( "killanimscript" );
self endon( "death" );
self endon( "end_melee_all" );
var_1 = self.syncedmeleetarget;
var_1 endon( "death" );
var_1 endon( "killanimscript" );
if ( isdefined( var_0 ) && var_0 > 0 )
wait( var_0 );
var_1.doglastknowngoodpos = var_1.origin;
for (;;)
{
var_2 = var_1 aiphysicstrace( self.origin, var_1.origin, undefined, undefined, 1, 1, 1 );
if ( var_2["fraction"] >= 1 )
{
var_1.doglastknowngoodpos = var_1.origin;
wait 0.05;
continue;
}
if ( var_2["normal"][2] > 0 )
{
var_3 = var_2["position"] - var_1.origin;
var_4 = vectordot( var_3, var_2["normal"] );
if ( var_4 > 0 )
{
var_5 = self.origin + ( var_4 + 1 ) * var_2["normal"];
var_6 = var_5 + ( 0, 0, 9 );
var_7 = var_5 + ( 0, 0, -9 );
var_8 = self aiphysicstrace( var_6, var_7 );
if ( var_8[2] > var_5[2] )
var_5 = var_8;
self forceteleport( var_5, self.angles, 60 );
}
}
wait 0.05;
}
}
meleestrugglevsdog_justdie()
{
thread animscripts\face::saygenericdialogue( "dogdeathlong" );
self.ragdoll_immediate = 1;
if ( !isdefined( self.magic_bullet_shield ) )
{
self.forceragdollimmediate = 1;
animscripts\shared::dropallaiweapons();
self kill( self.dog_attacking_me.origin, self.dog_attacking_me );
}
thread ragdoll_corpses();
setnextdogattackallowtime( 1000 );
}
meleestrugglevsdog_traverse()
{
if ( !isdefined( self.syncedmeleetarget ) )
return;
var_0 = vectortoangles( self.syncedmeleetarget.origin - self.origin );
var_1 = var_0[1];
var_2 = [];
var_2[0] = %body;
var_2[1] = %iw6_dog_kill_wall_over_front_guy_1;
playsound_victim( "dogdeathlong" );
domeleevsdog( var_2, var_1, 0.15 );
}
domeleevsdog( var_0, var_1, var_2 )
{
self endon( "killanimscript" );
self endon( "death" );
self endon( "end_melee_all" );
if ( !isdefined( self.syncedmeleetarget ) )
return;
self orientmode( "face angle", var_1 );
self animmode( "gravity" );
self.olddontattackme = self.dontattackme;
self.dontattackme = 1;
self.health = 1;
self.battlechatter = 0;
self.a.pose = "stand";
self.a.special = "none";
if ( animscripts\utility::usingsidearm() )
animscripts\shared::placeweaponon( self.primaryweapon, "right" );
self.ragdoll_immediate = 1;
self.meleeseq = 0;
thread meleestrugglevsdog_interruptedcheck();
self clearanim( var_0[0], 0.1 );
self setflaggedanimrestart( "aianim", var_0[1], 1, 0.1, 1 );
thread animscripts\shared::donotetracks( "aianim" );
wait 0.15;
self.syncedmeleetarget linkto( self, "tag_sync", ( 0, 0, 0 ), ( 0, 0, 0 ) );
thread meleestrugglevsdog_collision( var_2 );
self waittillmatch( "aianim", "end" );
self.syncedmeleetarget notify( "end_dog_interrupted_check" );
if ( !isdefined( self.magic_bullet_shield ) )
{
self.forceragdollimmediate = 1;
self.a.nodeath = 1;
animscripts\shared::dropallaiweapons();
self kill( self.dog_attacking_me.origin, self.dog_attacking_me );
}
meleestrugglevsdog_end();
}
#using_animtree("player_3rd_person");
playerdrone_create( var_0 )
{
var_1 = spawn( "script_model", var_0.origin );
var_1 [[ var_0.last_modelfunc ]]();
var_1 useanimtree( #animtree );
return var_1;
}
playerdrone_anim_knockdown( var_0 )
{
self endon( "death" );
var_1 = getanimlength( %player_3rd_dog_knockdown );
self setanim( %player_3rd_dog_knockdown, 1, 0, var_0 );
}
playerdone_anim_neck_snap()
{
self setanimknobrestart( %player_3rd_dog_knockdown_neck_snap, 1, 0, 1 );
}
playerdone_anim_saved()
{
self setanimknobrestart( %player_3rd_dog_knockdown_saved, 1, 0, 1 );
}
playerdone_anim_laststand()
{
self setanimknobrestart( %player_3rd_dog_knockdown_laststand, 1, 0, 1 );
}
#using_animtree("player");
playerview_spawn( var_0 )
{
var_1 = spawn( "script_model", var_0.meleeingplayer.origin );
var_1.angles = var_0.meleeingplayer.angles;
var_1 setmodel( level.player_viewhand_model );
var_1 useanimtree( #animtree );
var_1 hide();
return var_1;
}
handleplayerknockdownnotetracks( var_0 )
{
switch ( var_0 )
{
case "allow_player_save":
if ( isdefined( self.dog ) )
{
wait 1;
self.dog setcandamage( 1 );
}
break;
case "blood_pool":
if ( !isdefined( self.dog.meleeingplayer ) )
break;
if ( maps\_utility::killing_will_down( self.dog.meleeingplayer ) )
break;
var_1 = self gettagorigin( "tag_torso" );
var_2 = self gettagangles( "tag_torso" );
var_3 = anglestoforward( var_2 );
var_4 = anglestoup( var_2 );
var_5 = anglestoright( var_2 );
var_1 = var_1 + var_3 * -8.5 + var_4 * 5 + var_5 * 0;
playfx( level._effect["deathfx_bloodpool"], var_1, var_3, var_4 );
break;
}
}
playerview_knockdownanim( var_0 )
{
self endon( "pvd_melee_interrupted" );
var_1 = var_0.meleeingplayer;
self.dog = var_0;
thread playerview_checkinterrupted( var_1 );
self setflaggedanimrestart( "viewanim", %player_view_dog_knockdown );
self setflaggedanimrestart( "viewanim", %player_view_dog_knockdown_late );
self setanimlimited( %knockdown, 1, 0, 1 );
self setanimlimited( %knockdown_late, 0.01, 0, 1 );
animscripts\shared::donotetracks( "viewanim", ::handleplayerknockdownnotetracks );
self dontinterpolate();
self.dog = undefined;
playerview_endsequence( var_1 );
self notify( "pvd_melee_done" );
}
playerview_checkinterrupted( var_0 )
{
self endon( "pvd_melee_done" );
self.dog common_scripts\utility::waittill_any( "death", "pain", "melee_stop" );
if ( !isdefined( var_0.specialdeath ) && isalive( var_0 ) )
{
self notify( "pvd_melee_interrupted" );
self.dog notify( "pvd_melee_interrupted" );
playerview_endsequence( var_0 );
}
}
playerview_startsequence( var_0 )
{
if ( isdefined( self.inseq ) )
return 0;
var_1 = var_0.meleeingplayer;
if ( isdefined( var_1 ) && isdefined( var_1.placingsentry ) )
var_1 notify( "sentry_placement_canceled" );
var_1 notify( "dog_attacks_player" );
self.inseq = 1;
if ( isalive( var_1 ) )
var_1 hidehud();
var_1 setstance( "stand" );
var_1.syncedmeleetarget = var_0;
var_1.player_view playerview_show( var_1 );
var_2 = var_0.origin - var_1.origin;
self.angles = vectortoangles( var_2 );
self.angles = ( 0, self.angles[1], 0 );
self.startangles = self.angles;
var_3 = var_1.origin;
var_4 = var_1 getdroptofloorposition( var_1.origin );
if ( isdefined( var_4 ) )
self.origin = var_4;
else
self.origin = var_1.origin;
thread playerview_knockdownanim( var_0 );
self dontinterpolate();
var_1 playerlinktoabsolute( self, "tag_player" );
var_0 linkto( self, "tag_sync", ( 0, 0, 0 ), ( 0, 0, 0 ) );
var_5 = self gettagangles( "tag_sync" );
var_0 orientmode( "face angle", var_5[1] );
var_0 orientmode( "face default" );
var_1 allowstand( 1 );
var_1 allowlean( 0 );
var_1 allowcrouch( 0 );
var_1 allowprone( 0 );
var_1 freezecontrols( 1 );
var_1 setcandamage( 0 );
return 1;
}
savednotify( var_0 )
{
wait 0.5;
var_0 playsound( "saved_from_dog" );
}
player_gets_weapons_back()
{
self endon( "death" );
self showviewmodel();
self enableweapons();
}
playerview_endsequence( var_0 )
{
var_0 showhud();
if ( isalive( var_0 ) )
{
self clearanim( %player_view_dog_knockdown, 0.1 );
if ( isdefined( self.necksnapped ) )
{
self setflaggedanimrestart( "viewanim", %player_view_dog_knockdown_neck_snap, 1, 0.2, 1 );
if ( isdefined( self.playerdrone ) )
self.playerdrone playerdone_anim_neck_snap();
}
else if ( isdefined( var_0.dog_downed_player ) )
{
self setflaggedanimknobrestart( "viewanim", %player_view_dog_knockdown_laststand, 1, 0.1, 1 );
if ( isdefined( self.playerdrone ) )
self.playerdrone playerdone_anim_laststand();
}
else
{
thread savednotify( var_0 );
self setflaggedanimrestart( "viewanim", %player_view_dog_knockdown_saved );
if ( isdefined( self.playerdrone ) )
self.playerdrone playerdone_anim_saved();
}
if ( !isdefined( var_0.dog_downed_player ) )
{
var_0 maps\_utility::delaythread( 2.5, ::player_gets_weapons_back );
animscripts\shared::donotetracks( "viewanim" );
var_0 notify( "player_saved_from_dog" );
}
else
{
animscripts\shared::donotetracks( "viewanim" );
var_0 notify( "deathshield", 1000000, self.dog );
var_0 showviewmodel();
}
playerview_unlinkplayeranddelete( var_0 );
}
else
setsaveddvar( "compass", 0 );
var_0.syncedmeleetarget = undefined;
var_0.dog_downed_player = undefined;
restoreplayercontrols( var_0 );
}
playerview_unlinkplayeranddelete( var_0 )
{
var_0 show();
var_0 unlink();
var_0 setorigin( self.origin );
var_0 setplayerangles( self.startangles );
var_0 setcandamage( 1 );
var_1 = var_0.player_view;
if ( isdefined( var_1 ) )
{
if ( isdefined( var_1.playerdrone ) )
var_1.playerdrone delete();
var_1 delete();
var_0.player_view = undefined;
}
}
restoreplayercontrols( var_0 )
{
var_0 allowlean( 1 );
var_0 allowcrouch( 1 );
var_0 allowprone( 1 );
var_0 freezecontrols( 0 );
var_0.attacked_by_dog = undefined;
}
playerview_show( var_0 )
{
self showonclient( var_0 );
if ( maps\_utility::is_coop() )
{
var_1 = playerdrone_create( var_0 );
var_1 linkto( self, "tag_origin", ( 0, 0, 0 ), ( 0, 0, 0 ) );
var_1 thread playerdrone_anim_knockdown( 1 );
self.playerdrone = var_1;
if ( level.player == var_0 && isdefined( level.player2 ) )
{
var_0 hideonclient( level.player2 );
var_1 hideonclient( level.player );
}
else
{
var_0 hideonclient( level.player );
var_1 hideonclient( level.player2 );
}
}
var_0 hideviewmodel();
var_0 disableweapons();
}
playerview_playknockdownanimlimited( var_0 )
{
self setflaggedanimlimited( "viewanim", %player_view_dog_knockdown, 1, 0.2, var_0 );
self setflaggedanimlimited( "viewanim", %player_view_dog_knockdown_late, 1, 0.2, var_0 );
if ( isdefined( self.playerdrone ) )
self.playerdrone playerdrone_anim_knockdown( var_0 );
}
playerview_playknockdownanim( var_0 )
{
self setflaggedanimlimited( "viewanim", %player_view_dog_knockdown, 1, 0.2, var_0 );
self setflaggedanimlimited( "viewanim", %player_view_dog_knockdown_late, 1, 0.2, var_0 );
if ( isdefined( self.playerdrone ) )
self.playerdrone playerdrone_anim_knockdown( var_0 );
}
playerview_playmissanim( var_0 )
{
self setflaggedanimknobrestart( "viewanim", %player_view_dog_knockdown_neck_miss, 1, 0.2, var_0 );
}
playerview_knockdownlate()
{
self setanimlimited( %knockdown, 0.01, 0.2, 1 );
self setanimlimited( %knockdown_late, 1, 0.2, 1 );
}
dog_vs_player_anim_rate()
{
return 1;
}
is_hyena()
{
if ( issubstr( self.classname, "hyena" ) )
return 1;
return 0;
}
ragdoll_corpses()
{
wait 0.1;
var_0 = getcorpsearray();
foreach ( var_2 in var_0 )
{
if ( var_2 isragdoll() == 0 )
var_2 startragdoll();
}
}
handlevxnotetrack( var_0 )
{
if ( common_scripts\utility::string_starts_with( var_0, "vfx" ) )
{
if ( isdefined( level._effect[var_0] ) )
playfxontag( common_scripts\utility::getfx( var_0 ), self, "TAG_MOUTH_FX" );
}
else if ( common_scripts\utility::string_starts_with( var_0, "screen_blood" ) )
{
if ( isdefined( self.controlling_dog ) )
{
var_1 = "bottom";
if ( issubstr( var_0, "right" ) )
var_1 = "right";
else if ( issubstr( var_0, "left" ) )
var_1 = "left";
self notify( "screen_blood", var_1 );
}
}
}