1 #using scripts\codescripts\struct;
3 #using scripts\shared\array_shared;
4 #using scripts\shared\system_shared;
5 #using scripts\shared\tweakables_shared;
6 #using scripts\shared\scoreevents_shared;
7 #using scripts\shared\util_shared;
8 #using scripts\shared\weapons\_weapons;
9 #using scripts\shared\weapons\_weapon_utils;
11 #insert scripts\shared\shared.gsh;
13 #using scripts\mp\gametypes\_battlechatter;
14 #using scripts\mp\gametypes\_dev;
15 #using scripts\mp\gametypes\_spawning;
16 #using scripts\mp\gametypes\_spawnlogic;
18 #using scripts\mp\_util;
19 #using scripts\mp\killstreaks\_killstreakrules;
20 #using scripts\mp\killstreaks\_killstreaks;
21 #using scripts\mp\killstreaks\_supplydrop;
23 #define DOG_MODEL_FRIENDLY "german_shepherd_vest"
24 #define DOG_MODEL_ENEMY "german_shepherd_vest_black"
25 #define DOG_SPAWN_TIME_DELAY_MIN 2
26 #define DOG_SPAWN_TIME_DELAY_MAX 5
27 #define DOG_MAX_DOG_ATTACKERS 2
28 #define DOG_HEALTH_REGEN_TIME 5
31 #define DOG_HEALTH 100
33 #define DOG_COUNT_MAX_AT_ONCE 5
35 #precache( "string", "KILLSTREAK_EARNED_DOGS" );
36 #precache( "string", "KILLSTREAK_DOGS_NOT_AVAILABLE" );
37 #precache( "string", "KILLSTREAK_DOGS_INBOUND" );
38 #precache( "string", "KILLSTREAK_DOGS_HACKED" );
39 #precache( "eventstring", "mpl_killstreak_dogs" );
46 level.dog_targets = [];
47 level.dog_targets[ level.dog_targets.size ] =
"trigger_radius";
48 level.dog_targets[ level.dog_targets.size ] =
"trigger_multiple";
49 level.dog_targets[ level.dog_targets.size ] =
"trigger_use_touch";
51 level.dog_spawns = [];
58 spawns = GetNodeArray(
"spawn",
"script_noteworthy" );
60 if ( !IsDefined( spawns ) || !spawns.size )
62 /# println(
"No dog spawn nodes found in map" ); #/
66 dog_spawner = GetEnt(
"dog_spawner",
"targetname" );
68 if ( !IsDefined( dog_spawner ) )
70 /# println(
"No dog_spawner entity found in map" ); #/
75 dog = dog_spawner SpawnFromSpawner();
77 foreach(
spawn in spawns )
79 valid = ArraySort( valid,
spawn.origin,
false );
81 for( i = 0; i < 5; i++ )
83 if ( dog FindPath(
spawn.origin, valid[i].origin,
true,
false ) )
85 level.dog_spawns[ level.dog_spawns.size ] =
spawn;
92 if ( !level.dog_spawns.size )
94 println(
"No dog spawns connect to MP spawn nodes" );
117 if ( killstreak_id == -1 )
120 if ( level.teambased )
122 foreach( team
in level.teams )
124 if ( team ==
self.team )
130 self AddWeaponStat( GetWeapon(
"dogs" ),
"used", 1 );
132 ownerDeathCount =
self.deathCount;
135 level notify(
"called_in_the_dogs" );
141 self endon(
"disconnect" );
142 self.dogsActive =
true;
143 self.dogsActiveKillstreak = 0;
146 self.dogsActiveKillstreak = 0;
147 self.dogsActive = undefined;
152 dog_spawner = GetEnt(
"dog_spawner",
"targetname" );
154 if( !isdefined( dog_spawner ) )
156 /# println(
"No dog spawners found in map" ); #/
160 spawns = GetNodeArray(
"spawn",
"script_noteworthy" );
162 if ( level.dog_spawns.size <= 0 )
164 /# println(
"No dog spawn nodes found in map" ); #/
168 exits = GetNodeArray(
"exit",
"script_noteworthy" );
170 if ( exits.size <= 0 )
172 /# println(
"No dog exit nodes found in map" ); #/
187 assert( IsAi(
self ) );
189 self.targetname =
"attack_dog";
191 self.animTree =
"dog.atr";
196 self.secondaryweapon =
"";
198 self.grenadeAmmo = 0;
199 self.goalradius = 128;
200 self.noDodgeMove =
true;
201 self.ignoreSuppression =
true;
202 self.suppressionThreshold = 1;
203 self.disableArrivals =
false;
204 self.pathEnemyFightDist = 512;
205 self.soundMod =
"dog";
213 assert( level.dog_spawns.size > 0 );
214 return array::random( level.dog_spawns );
219 players = GetPlayers();
222 foreach( player
in players )
224 if ( !isdefined( player ) )
229 if ( !IsAlive( player ) )
234 if ( player.sessionstate !=
"playing" )
239 if ( DistanceSquared( player.origin, origin ) > 2048 * 2048 )
244 if ( player.team == team )
259 self SetEntityOwner( owner );
262 self.requiredDeathCount = requiredDeathCount;
272 dog_spawner = GetEnt(
"dog_spawner",
"targetname" );
274 dog = dog_spawner SpawnFromSpawner();
275 dog ForceTeleport( spawn_node.origin, spawn_node.angles );
299 self waittill(
"damage",
damage, attacker, direction_vec, point, type, modelName, tagName, partName, weapon, iDFlags );
303 damage_area =
spawn(
"trigger_radius",
self.origin, 0, 128, 128 );
306 damage_area
delete();
314 requiredDeathCount = deathCount;
317 level.dog_abort =
false;
323 if ( level.dog_abort )
340 level waittill(
"dog_died" );
347 if ( dogs.size <= 0 )
350 if ( isdefined( owner ) )
352 owner notify(
"dogs_complete" );
357 level waittill(
"dog_died" );
363 level.dog_abort =
true;
367 foreach( dog
in dogs )
369 dog notify(
"abort" );
372 level notify(
"dog_abort" );
377 level endon(
"dog_abort" );
384 level endon(
"dog_abort" );
386 level waittill(
"game_ended" );
392 self waittill(
"death" );
393 level notify(
"dog_died" );
399 self clearentitytarget();
400 self.ignoreall =
true;
401 self.goalradius = 30;
410 self endon(
"death" );
414 if ( level.dog_abort )
420 if ( isdefined(
self.enemy ) )
422 wait( RandomIntRange( 3, 5 ) );
430 for ( i = 0; i < objectives.size; i++ )
432 objective = array::random( objectives );
434 nodes = GetNodesInRadius( objective.origin, 256, 64, 512,
"Path", 16 );
446 if ( isdefined( player ) )
448 nodes = GetNodesInRadius( player.origin, 1024, 0, 128,
"Path", 8 );
452 if ( !nodes.size && isdefined(
self.script_owner ) )
454 if ( IsAlive(
self.script_owner ) &&
self.script_owner.sessionstate ==
"playing" )
456 nodes = GetNodesInRadius(
self.script_owner.origin, 512, 256, 512,
"Path", 16 );
462 nodes = GetNodesInRadius(
self.origin, 1024, 512, 512,
"Path" );
467 nodes = array::randomize( nodes );
469 foreach( node
in nodes )
471 if ( isdefined( node.script_noteworthy ) )
476 if ( isdefined( node.dog_claimed ) && IsAlive( node.dog_claimed ) )
481 self SetGoal( node );
482 node.dog_claimed =
self;
487 if ( event ==
"goal" )
492 node.dog_claimed = undefined;
503 if ( !isdefined( level.dog_objectives ) )
505 level.dog_objectives = [];
506 level.dog_objective_next_update = 0;
509 if ( level.gameType ==
"tdm" || level.gameType ==
"dm" )
511 return level.dog_objectives;
514 if ( GetTime() >= level.dog_objective_next_update )
516 level.dog_objectives = [];
518 foreach( target
in level.dog_targets )
520 ents = GetEntArray( target,
"classname" );
522 foreach( ent
in ents )
524 if ( level.gameType ==
"koth" )
526 if ( isdefined( ent.targetname ) && ent.targetname ==
"radiotrigger" )
528 level.dog_objectives[ level.dog_objectives.size ] = ent;
534 if ( level.gameType ==
"sd" )
536 if ( isdefined( ent.targetname ) && ent.targetname ==
"bombzone" )
538 level.dog_objectives[ level.dog_objectives.size ] = ent;
544 if ( !isdefined( ent.script_gameobjectname ) )
549 if ( !IsSubStr( ent.script_gameobjectname, level.gameType ) )
554 level.dog_objectives[ level.dog_objectives.size ] = ent;
558 level.dog_objective_next_update = GetTime() + RandomIntRange( 5000, 10000 );
561 return level.dog_objectives;
566 players = GetPlayers();
571 foreach( player
in players )
573 if ( !isdefined( player ) )
578 if ( !IsAlive( player ) )
583 if ( player.sessionstate !=
"playing" )
588 if ( isdefined(
self.script_owner ) && player ==
self.script_owner )
593 if ( level.teambased )
595 if ( player.team ==
self.team )
601 if ( GetTime() - player.lastFireTime > 3000 )
606 if ( !isdefined( closest ) )
609 distSq = DistanceSquared(
self.origin, player.origin );
613 d = DistanceSquared(
self.origin, player.origin );
627 dogs = GetEntArray(
"attack_dog",
"targetname" );
633 if ( !isdefined(
self.script_owner ) )
636 self endon(
"clear_owner");
638 self.script_owner endon(
"disconnect");
642 self waittill(
"killed", player);
643 self.script_owner notify(
"dog_handler" );
649 self endon(
"death" );
657 self waittill(
"damage",
damage, attacker, direction, point, type, tagName, modelName, partname, weapon, iDFlags );
666 if ( !isdefined( attacker ) || !isPlayer( attacker ) || !isdefined(
self.script_owner ) )
671 if ( ( level.teambased && attacker.team ==
self.script_owner.team ) || attacker ==
self )
676 if ( !isdefined(
self.attackerData ) || !isdefined(
self.attackers ) )
678 self.attackerData = [];
681 if ( !isdefined(
self.attackerData[attacker.clientid] ) )
683 self.attackerClientID[attacker.clientid] = spawnstruct();
684 self.attackers[
self.attackers.size ] = attacker;
690 self.attackerData = [];
696 self endon(
"death" );
697 self endon(
"damage" );
708 self.health += regen_interval;
718 self waittill (
"death", attacker);
720 if ( isdefined( attacker ) && isPlayer( attacker ) )
722 if (isdefined (
self.script_owner ) &&
self.script_owner == attacker)
724 if ( level.teambased && isdefined (
self.script_owner ) &&
self.script_owner.team == attacker.team )
727 if ( isdefined(
self.attackers ) )
729 foreach ( player
in self.attackers )
731 if ( player != attacker )
737 attacker notify (
"selfdefense_dog");
744 exits = GetNodeArray(
"exit",
"script_noteworthy" );
745 return ArrayGetClosest(
self.origin, exits );
750 self endon(
"disconnect");
754 foreach( dog
in dogs )
759 if ( dog istouching(area) )
762 if ( isPlayer(
self ) )
764 if ( level.teamBased && (dog.team ==
self.team) )
768 else if ( !level.teambased && isdefined(dog.script_owner) &&
self == dog.script_owner )
774 if ( isdefined( dog.lastFlashed ) && dog.lastFlashed + 1500 > gettime() )
781 dog setFlashBanged(
true, 500 );
782 dog.lastFlashed = gettime();