// 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 != ""; } 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 ); } } }