1 #using scripts\shared\util_shared;
2 #using scripts\shared\ai_shared;
3 #using scripts\shared\array_shared;
4 #using scripts\shared\spawner_shared;
5 #using scripts\shared\system_shared;
6 #using scripts\codescripts\struct;
7 #using scripts\shared\ai\systems\blackboard;
9 #insert scripts\shared\shared.gsh;
10 #insert scripts\shared\ai\systems\blackboard.gsh;
35 if ( !isDefined( targetName ) )
36 targetName =
"ai_sniper_node_scan";
56 pointList = GetEntArray( targetName,
"targetname" );
57 foreach (
struct in structList )
58 pointList[pointlist.size] =
struct;
60 foreach ( point
in pointList )
62 if ( isDefined( point.target ) )
64 node = getnode( point.target,
"targetname" );
65 if ( isDefined( node ) )
67 if ( !isDefined( node.lase_points ) )
68 node.lase_points = [];
69 node.lase_points[node.lase_points.size] = point;
75 nodeList = GetNodeArray( targetName,
"script_noteworthy" );
76 foreach ( node
in nodeList )
78 if ( isDefined( node.script_linkto ) )
80 node.lase_path =
struct::get( node.script_linkto,
"script_linkname" );
81 if ( !isDefined( node.lase_path ) )
82 node.lase_path = GetEnt( node.script_linkto,
"script_linkname" );
105 if ( !isDefined( node ) )
108 if ( !isDefined( node.lase_points ) && !isDefined( node.lase_path ) )
111 self notify(
"goal_wait_notify_lase");
112 self endon(
"goal_wait_notify_lase");
114 self endon(
"lase_points");
120 goalPos = node.origin;
121 if ( isDefined(
self.pathGoalPos ) )
122 goalPos =
self.pathGoalPos;
123 if( IsDefined(
self.arrivalFinalPos ) )
124 goalPos =
self.arrivalFinalPos;
125 while ( DistanceSquared(
self.origin, goalPos ) > (16 * 16) )
128 self notify(
"lase_goal", node );
133 self notify(
"goal_watcher_patrol");
134 self endon(
"goal_watcher_patrol");
139 self waittill (
"patrol_goal", node );
147 self notify(
"goal_watcher_target");
148 self endon(
"goal_watcher_target");
151 if ( isDefined(
self.target ) && !
IS_TRUE(
self.patroller ) )
153 node = GetNode(
self.target,
"targetname" );
155 if ( isDefined( node ) )
157 self waittill(
"goal" );
166 self notify(
"patrol_lase_goal_waiter");
167 self endon(
"patrol_lase_goal_waiter");
174 self waittill (
"lase_goal", node );
176 if ( isDefined( node.lase_path ) )
188 if ( isDefined(
self.currentgoal ) && isDefined(
self.currentgoal.target ) &&
self.currentgoal.target !=
"" )
191 self SetGoal( node,
true );
192 self waittill(
"lase_points_loop" );
195 self notify(
"lase_points");
197 self.holdfire =
false;
200 if ( isDefined(
self.ai_sniper_prev_goal_radius ) )
202 self.goalradius =
self.ai_sniper_prev_goal_radius;
203 self.ai_sniper_prev_goal_radius = undefined;
206 if ( isDefined(
self.currentgoal ) )
232 self notify(
"lase_points");
233 self endon(
"lase_points");
237 self.holdfire =
true;
240 self.blindaim =
true;
243 if ( !isDefined(
self.ai_sniper_prev_goal_radius ) )
244 self.ai_sniper_prev_goal_radius =
self.goalradius;
248 if ( IsDefined(
self.__blackboard ) && isDefined(
self.script_parameters ) &&
self.script_parameters ==
"steady" )
251 if ( !isDefined( entity_or_point_array ) && isDefined(
self.target ) )
252 entity_or_point_array =
struct::get(
self.target,
"targetname" );
254 if ( !isDefined( entity_or_point_array ) || ( isArray( entity_or_point_array ) && entity_or_point_array.size == 0 ) )
256 /# IPrintLnBold(
"actor_lase_points_behavior - invalid entity_or_point_array" ); #/
260 firstPoint = undefined;
261 if ( isArray( entity_or_point_array ) )
262 firstPoint = entity_or_point_array[0];
264 firstPoint = entity_or_point_array;
266 if ( !isDefined(
self.lase_ent ) )
269 self.lase_ent SetModel(
"tag_origin");
270 self.lase_ent.velocity = (100, 0, 0);
275 if (
self.lase_ent.health <= 0 )
276 self.lase_ent.health = 1;
297 if ( !isDefined(
self.lase_ent ) )
300 self notify(
"lase_points");
302 self.holdfire =
false;
304 self.blindaim =
false;
306 self.lase_ent
delete();
307 self.lase_ent = undefined;
309 self clearentitytarget();
311 if ( isDefined(
self.ai_sniper_prev_goal_radius ) )
313 self.goalradius =
self.ai_sniper_prev_goal_radius;
314 self.ai_sniper_prev_goal_radius = undefined;
319 if ( IsDefined(
self.__blackboard ) )
326 self endon(
"lase_points");
328 lastTransition = GetTime();
333 if (
self asmIsTransDecRunning() )
336 lastTransition = GetTime();
339 else if ( GetTime() - lastTransition > 350 )
350 self endon(
"lase_points");
352 self waittill(
"death");
354 if ( isDefined(
self ) )
360 if ( !isDefined( entity_or_point ) )
365 if ( !isVec( entity_or_point ) && isDefined( entity_or_point.origin ) )
367 result = entity_or_point.origin;
369 if ( isPlayer( entity_or_point ) || isActor( entity_or_point ) )
370 result = entity_or_point GetEye();
387 self notify(
"actor_lase_points_player_track");
388 self endon(
"actor_lase_points_player_track");
392 if ( !isDefined( level.target_lase_allyList ) )
393 level.target_lase_allyList = [];
394 if ( !isDefined( level.target_lase_nextAllyListUpdate ) )
395 level.target_lase_nextAllyListUpdate = 0;
399 dirLaser = VectorNormalize(
self.origin - v_eye );
401 if ( GetTime() > level.target_lase_nextAllyListUpdate )
403 level.target_lase_allyList = GetPlayers();
405 actorList = GetAITeamArray(
"allies" );
406 foreach ( actor
in actorList )
411 if ( isAlive( actor ) )
412 level.target_lase_allyList[level.target_lase_allyList.size] = actor;
415 level.target_lase_nextAllyListUpdate = GetTime() + 1000;
418 for ( i = 0; i < level.target_lase_allyList.size; i++ )
420 ally = level.target_lase_allyList[i];
422 if ( !isAlive( ally ) )
425 if ( ally IsNoTarget() ||
IS_TRUE( ally.ignoreme ) )
431 dirAlly = VectorNormalize( allyEye - v_eye );
432 if ( VectorDot( dirLaser, dirAlly ) < 0.7 )
436 nearestPointAlongLaser = PointOnSegmentNearestToPoint( v_eye,
self.origin, allyEye );
437 if ( DistanceSquared( allyEye, nearestPointAlongLaser ) < 200 * 200 )
439 if ( SightTracePassed( v_eye, allyEye,
false, undefined ) )
441 if ( isDefined( a_owner ) )
442 a_owner notify(
"alert",
"combat", allyEye, ally );
457 if ( IsDefined(
self.a_owner) && IsDefined(
self.a_owner.laser_sight_timeout) )
458 sight_timeout =
self.a_owner.laser_sight_timeout;
460 self target_lase_override( v_eye, entity_or_point, sight_timeout, a_owner,
true, allow_interrupts );
476 self notify(
"lase_points");
477 self endon(
"lase_points");
481 pauseTime = RandomFloatRange( 2.0, 4.0 );
483 if ( isArray( entity_or_point_array ) && entity_or_point_array.size <= 0 )
487 start = entity_or_point_array;
491 while ( isDefined(
self.lase_override ) )
497 if ( isArray( entity_or_point_array ) )
500 if ( !isVec( entity_or_point_array[index] ) && isDefined( entity_or_point_array[index].
script_wait ) )
501 wait entity_or_point_array[index].script_wait;
507 if ( !isVec( entity_or_point_array ) && isDefined( entity_or_point_array.script_wait ) )
508 wait entity_or_point_array.script_wait;
512 if ( isArray( entity_or_point_array ) )
515 if ( index >= entity_or_point_array.size )
521 else if ( entity_or_point_array == start )
528 self notify(
"lase_points_loop");
529 if ( isDefined( e_owner ) )
530 e_owner notify(
"lase_points_loop");
537 self notify(
"velocity_approach");
538 self endon(
"velocity_approach");
539 self endon(
"death" );
541 startPosition =
self.origin;
542 startVelocity =
self.velocity;
543 startVelocityDir = VectorNormalize(
self.velocity );
545 decelerateTime = totalTime * 4.0;
546 phase = Length(
self.velocity ) / (decelerateTime * 2);
548 totalTimeMs = totalTime * 1000;
549 timeEarlyOut = totalTimeMs * 0.75;
553 if ( !isDefined( b_early_out ) || b_early_out )
556 self endon(
"velocity_approach_early_out" );
559 while ( (GetTime() -
startTime) < totalTimeMs )
562 if ( !notified && (GetTime() -
startTime) > timeEarlyOut )
564 self notify(
"velocity_approach_early_out" );
568 deltaTime = float(GetTime() -
startTime) / 1000.0;
571 decelDeltaTime = min( deltaTime, decelerateTime );
572 posWithoutBraking = startPosition + (startVelocity * decelDeltaTime);
573 posWithBraking = posWithoutBraking + (startVelocityDir * phase * -0.5 * decelDeltaTime * decelDeltaTime);
576 coef = deltaTime / totalTime;
577 coef = 1.0 - (0.5 + Cos( coef * 180 ) * 0.5);
578 actualEndPosition = endPosition;
580 assert( IsDefined( actualEndPosition ) );
582 newOrigin = VectorLerp( posWithBraking, actualEndPosition, coef );
585 if ( newOrigin[0] > -MAX_MAP && newOrigin[0] < MAX_MAP && newOrigin[1] > -MAX_MAP && newOrigin[1] < MAX_MAP && newOrigin[2] > -MAX_MAP && newOrigin[2] < MAX_MAP )
586 self.origin = newOrigin;
605 if ( !isDefined( node ) )
614 if ( isDefined( node.target ) && isDefined( node.script_linkto ) )
617 nextB =
struct::get( node.script_linkto,
"script_linkname" );
619 else if ( isDefined( node.target ) )
623 else if ( isDefined( node.script_linkto ) )
625 nextA =
struct::get( node.script_linkto,
"script_linkname" );
628 if ( isDefined( nextA ) && isDefined( nextB ) )
630 if ( RandomFloatRange( 0.0, 1.0 ) < 0.5 )
652 self notify(
"target_lase_transition");
653 self endon(
"target_lase_transition");
656 if ( isEntity( entity_or_point ) )
659 entity_or_point endon(
"death");
665 delta = point -
self.origin;
667 self.origin += delta;
677 time = Distance( point,
self.origin ) / speed;
680 if ( IsDefined(owner) && IsDefined(owner.max_laser_transition_time) )
683 time = Min(time, owner.max_laser_transition_time);
689 self waittill(
"velocity_approach_early_out" );
709 if ( (IsDefined(
self.lase_override) && ( !allow_interrupts ||
self.lase_override == entity_or_point) ))
712 self notify(
"target_lase_override");
713 self endon(
"target_lase_override");
716 self.lase_override = entity_or_point;
720 outOfSightTime = 0.0;
723 delayBeforeFiring = 0.0;
725 if ( IsDefined(a_owner.lase_fire_delay) )
727 delayBeforeFiring = a_owner.lase_fire_delay;
735 if ( reTargetTime >= delayBeforeFiring )
737 if ( isActor( a_owner ) )
742 a_owner.sniper_last_fire = GetTime();
746 if ( !isDefined( entity_or_point ) || outOfSightTime >= sight_timeout )
748 self notify(
"target_lase_transition");
752 if ( !SightTracePassed( v_eye,
lase_point( entity_or_point ),
false, undefined ) )
755 outOfSightTime = 0.0;
763 if ( isActor( a_owner ) )
764 a_owner.holdfire =
true;
766 self.lase_override = undefined;
781 if ( !isDefined( a_owner ) )
784 if ( !isDefined( a_owner.sniper_last_fire ) )
787 return ( GetTime() - a_owner.sniper_last_fire ) < 3000;