1 #using scripts\shared\ai\systems\animation_state_machine_utility;
2 #using scripts\shared\ai\systems\animation_state_machine_notetracks;
3 #using scripts\shared\ai\archetype_utility;
4 #using scripts\shared\ai\systems\behavior_tree_utility;
5 #using scripts\shared\ai\systems\blackboard;
6 #using scripts\shared\ai\systems\ai_interface;
7 #using scripts\shared\ai\zombie;
8 #using scripts\shared\spawner_shared;
9 #using scripts\shared\ai\archetype_mocomps_utility;
10 #using scripts\shared\ai\archetype_zombie_dog_interface;
11 #using scripts\shared\ai_shared;
12 #using scripts\shared\math_shared;
14 #insert scripts\shared\ai\systems\animation_state_machine.gsh;
15 #insert scripts\shared\ai\systems\behavior.gsh;
16 #insert scripts\shared\ai\systems\behavior_tree.gsh;
17 #insert scripts\shared\ai\systems\blackboard.gsh;
18 #insert scripts\shared\ai\utility.gsh;
19 #insert scripts\shared\ai\zombie.gsh;
21 #insert scripts\shared\archetype_shared\archetype_shared.gsh;
22 #insert scripts\shared\shared.gsh;
24 #namespace ZombieDogBehavior;
70 self.kill_on_wine_coccon =
true;
76 entity.__blackboard = undefined;
100 if ( !isdefined(
self.shouldHowl ) )
103 self.shouldHowl = RandomFloat( 1 ) <= chance;
105 if (
self.shouldHowl )
120 angles = VectorToAngles(org-
self.origin);
127 assert( IsDefined(
self.enemy) );
129 yaw =
self.angles[1] -
GetYaw(
self.enemy.origin);
130 yaw = AngleClamp180( yaw );
147 if (
self.health <
self.maxhealth )
153 if ( !IsDefined(
self.enemy ) || !IsAlive(
self.enemy ) )
158 if ( !
self CanSee(
self.enemy ) )
163 dist = DistanceSquared(
self.origin,
self.enemy.origin );
164 if ( dist > run_dist_squared )
169 height =
self.origin[2] -
self.enemy.origin[2];
170 if ( abs( height ) > run_height )
181 pitch = AngleClamp180( VectorToAngles(
self.origin -
self.enemy.origin )[0] );
182 if ( abs( pitch ) > run_pitch )
192 if( !IsDefined( target ) )
197 if( !IsAlive( target ) )
201 if (!(dog.team ==
"allies"))
203 if( !IsPlayer( target ) && SessionModeIsZombiesGame())
208 if( IsDefined(target.is_zombie) && target.is_zombie ==
true )
214 if( IsPlayer( target ) && target.sessionstate ==
"spectator" )
219 if( IsPlayer( target ) && target.sessionstate ==
"intermission" )
234 if( target IsNoTarget() )
239 if( dog.team == target.team )
245 if( IsPlayer( target ) && IsDefined( level.is_player_valid_override ) )
247 return [[ level.is_player_valid_override ]]( target );
256 if ( SessionModeIsZombiesGame() )
258 if (
self.team ==
"allies")
260 dog_targets = GetAITeamArray( level.zombie_team );
264 dog_targets = getplayers();
269 dog_targets = ArrayCombine( getplayers(), GetAIArray(),
false,
false );
271 least_hunted = dog_targets[0];
272 closest_target_dist_squared = undefined;
273 for( i = 0; i < dog_targets.size; i++ )
275 if ( !isdefined( dog_targets[i].hunted_by ) )
277 dog_targets[i].hunted_by = 0;
287 least_hunted = dog_targets[i];
290 dist_squared = DistanceSquared( dog.origin, dog_targets[i].origin );
291 if( dog_targets[i].hunted_by <= least_hunted.hunted_by && ( !IsDefined( closest_target_dist_squared ) || dist_squared < closest_target_dist_squared ) )
293 least_hunted = dog_targets[i];
294 closest_target_dist_squared = dist_squared;
304 least_hunted.hunted_by += 1;
313 if ( IsPlayer(
self ) )
314 return self.last_valid_position;
334 to_enemy = behaviorTreeEntity.favoriteenemy.origin - behaviorTreeEntity.origin;
335 perp = VectorNormalize( ( -to_enemy[1], to_enemy[0], 0 ) );
338 offset = perp * spacing_horz_dist * spacing_value;
341 spacing_dist =
math::clamp( Length( to_enemy ), spacing_near_dist, spacing_far_dist );
342 lerp_amount =
math::clamp( ( spacing_dist - spacing_near_dist ) / ( spacing_far_dist - spacing_near_dist ), 0.0, 1.0 );
346 desired_point = GetClosestPointOnNavMesh( desired_point, spacing_horz_dist * 1.2, 16 );
347 if ( IsDefined( desired_point ) )
352 locomotion_target = desired_point;
356 return locomotion_target;
363 if (
IS_TRUE( level.intermission ) )
365 behaviorTreeEntity ClearPath();
371 if (
IS_TRUE( behaviortreeentity.isPuppet ) )
378 if ( behaviorTreeEntity.ignoreall || behaviorTreeEntity.pacifist || ( isdefined( behaviorTreeEntity.favoriteenemy ) && !
is_target_valid( behaviorTreeEntity, behaviorTreeEntity.favoriteenemy ) ) )
380 if ( isdefined( behaviorTreeEntity.favoriteenemy ) && isdefined( behaviorTreeEntity.favoriteenemy.hunted_by ) && behaviorTreeEntity.favoriteenemy.hunted_by > 0 )
383 behaviorTreeEntity.favoriteenemy.hunted_by--;
385 behaviorTreeEntity.favoriteenemy = undefined;
386 behaviorTreeEntity.hasSeenFavoriteEnemy =
false;
389 if ( !behaviorTreeEntity.ignoreall )
391 behaviorTreeEntity SetGoal( behaviorTreeEntity.origin );
398 if (
IS_TRUE( behaviorTreeEntity.ignoreme ) )
404 if( (!SessionModeIsZombiesGame() || behaviorTreeEntity.team ==
"allies") && !
is_target_valid(behaviorTreeEntity, behaviorTreeEntity.favoriteenemy) )
410 if ( !
IS_TRUE( behaviorTreeEntity.hasSeenFavoriteEnemy ) )
412 if ( IsDefined( behaviorTreeEntity.favoriteenemy ) && behaviorTreeEntity
need_to_run() )
414 behaviorTreeEntity.hasSeenFavoriteEnemy =
true;
419 if ( IsDefined( behaviorTreeEntity.favoriteenemy ) )
421 if ( IsDefined( level.enemy_location_override_func ) )
423 goalPos = [[ level.enemy_location_override_func ]]( behaviorTreeEntity, behaviorTreeEntity.favoriteenemy );
425 if ( IsDefined( goalPos ) )
427 behaviorTreeEntity SetGoal( goalPos );
433 if ( IsDefined( locomotion_target ) )
436 if ( !IsDefined( behaviorTreeEntity.lastTargetPosition ) || DistanceSquared( behaviorTreeEntity.lastTargetPosition, locomotion_target ) >
SQR( repathDist ) || !behaviorTreeEntity HasPath() )
438 behaviorTreeEntity UsePosition( locomotion_target );
439 behaviorTreeEntity.lastTargetPosition = locomotion_target;
449 if ( behaviorTreeEntity.ignoreall || !
is_target_valid( behaviorTreeEntity, behaviorTreeEntity.favoriteenemy ) )
454 if ( !
IS_TRUE( level.intermission ) )
457 if ( DistanceSquared( behaviorTreeEntity.origin, behaviorTreeEntity.favoriteenemy.origin ) <
SQR( meleeDist ) && behaviorTreeEntity CanSee( behaviorTreeEntity.favoriteenemy ) )
459 dog_eye = behaviorTreeEntity.origin + ( 0, 0, 40 );
460 enemy_eye = behaviorTreeEntity.favoriteenemy GetEye();
463 trace = PhysicsTrace( dog_eye, enemy_eye, (0, 0, 0), (0, 0, 0),
self, clip_mask );
464 can_melee = (
trace[
"fraction" ] == 1.0 || ( IsDefined(
trace[
"entity" ] ) &&
trace[
"entity" ] == behaviorTreeEntity.favoriteenemy ) );
490 if ( !IsDefined(
self.enemy ) || !IsPlayer(
self.enemy ) )
493 height_diff =
self.enemy.origin[2] -
self.origin[2];
497 if ( height_diff < low_enough &&
self.enemy GetStance() ==
"prone" )
503 melee_origin = (
self.origin[0],
self.origin[1],
self.origin[2] + 65 );
504 enemy_origin = (
self.enemy.origin[0],
self.enemy.origin[1],
self.enemy.origin[2] + 32 );
506 if ( !BulletTracePassed( melee_origin, enemy_origin,
false,
self ) )
516 behaviorTreeEntity ClearPath();