1 #using scripts\codescripts\struct;
3 #using scripts\shared\array_shared;
4 #using scripts\shared\callbacks_shared;
5 #using scripts\shared\clientfield_shared;
6 #using scripts\shared\killstreaks_shared;
7 #using scripts\shared\math_shared;
8 #using scripts\shared\statemachine_shared;
9 #using scripts\shared\system_shared;
10 #using scripts\shared\turret_shared;
11 #using scripts\shared\util_shared;
12 #using scripts\shared\vehicle_ai_shared;
13 #using scripts\shared\vehicle_death_shared;
14 #using scripts\shared\vehicle_shared;
16 #using scripts\mp\_util;
17 #using scripts\mp\gametypes\_shellshock;
18 #using scripts\mp\killstreaks\_killstreakrules;
19 #using scripts\mp\killstreaks\_airsupport;
20 #using scripts\mp\killstreaks\_killstreaks;
21 #using scripts\mp\killstreaks\_remote_weapons;
22 #using scripts\mp\teams\_teams;
23 #using scripts\shared\weapons\_heatseekingmissile;
25 #insert scripts\mp\_hacker_tool.gsh;
26 #insert scripts\mp\killstreaks\_killstreaks.gsh;
27 #insert scripts\shared\clientfields.gsh;
28 #insert scripts\shared\shared.gsh;
29 #insert scripts\shared\statemachine.gsh;
30 #insert scripts\shared\version.gsh;
31 #insert scripts\shared\archetype_shared\archetype_shared.gsh;
33 #precache( "fx", "explosions/fx_vexp_wasp_gibb_death" );
35 #namespace flak_drone;
37 #define FLAK_DRONE_NAME "flak_drone"
38 #define FLAK_DRONE_MISSILE_TOO_CLOSE_TO_PARENT_DISTANCE 1000
49 self.health =
self.healthdefault;
51 self EnableAimAssist();
54 self SetVehicleAvoidance(
true );
56 self.fovcosinebusy = 0;
57 self.vehAirCraftCollisionEnabled =
true;
58 self.goalRadius = 999999;
59 self.goalHeight = 999999;
60 self SetGoal(
self.origin,
false,
self.goalRadius,
self.goalHeight );
81 self endon(
"change_state" );
82 self endon(
"death" );
84 while( !isdefined(
self.parent ) )
89 self.parent endon(
"death" );
100 self ClearLookAtEnt();
102 self.current_pathto_pos = undefined;
105 queryResult = PositionQuery_Source_Navigation( queryOrigin,
112 if( isdefined( queryResult ) )
114 PositionQuery_Filter_DistanceToGoal( queryResult,
self );
117 best_point = undefined;
118 best_score = -999999;
120 foreach ( point
in queryResult.data )
122 randomScore = randomFloatRange( 0, 100 );
123 distToOriginScore = point.distToOrigin2D * 0.2;
125 point.score += randomScore + distToOriginScore;
126 ADD_POINT_SCORE( point,
"distToOrigin", distToOriginScore );
128 if ( point.score > best_score )
130 best_score = point.score;
137 if( isdefined( best_point ) )
139 self.current_pathto_pos = best_point.origin;
143 if( IsDefined(
self.current_pathto_pos ) )
146 if(
self SetVehGoalPos(
self.current_pathto_pos,
true,
false ) )
148 self playsound (
"veh_wasp_vox");
153 self.current_pathto_pos =
self GetClosestPointOnNavVolume(
self.origin, 999999 );
154 self SetVehGoalPos(
self.current_pathto_pos,
true,
false );
159 if( isDefined(
self.parent.heliGoalPos ) )
161 self.current_pathto_pos =
self.parent.heliGoalPos;
165 self.current_pathto_pos = queryOrigin;
168 self SetVehGoalPos(
self.current_pathto_pos,
true,
false );
179 if ( isdefined(
self.parent ) )
181 parentSpeed =
self.parent GetSpeed();
182 desiredSpeed = parentSpeed * 0.9;
183 if ( Distance2DSquared(
self.parent.origin,
self.origin ) >
SQR( 36 ) )
185 if ( isdefined(
self.current_pathto_pos ) )
187 flakDroneDistanceToGoalSquared = Distance2DSquared(
self.origin,
self.current_pathto_pos );
188 parentDistanceToGoalSquared = Distance2DSquared(
self.parent.origin,
self.current_pathto_pos );
189 if ( flakDroneDistanceToGoalSquared > parentDistanceToGoalSquared )
191 desiredSpeed = parentSpeed * 1.3;
195 desiredSpeed = parentSpeed * 0.8;
201 self SetSpeed( max( desiredSpeed, 10 ) );
211 drone endon(
"change_state" );
212 drone endon(
"death" );
214 drone thread
SpawnFlakRocket( drone.incoming_missile, drone.origin, drone.parent );
222 missile endon(
"death");
223 missile Missile_SetTarget( parent );
225 rocket = MagicBullet( GetWeapon(
"flak_drone_rocket" ), spawnPos, missile.origin, parent, missile );
226 rocket.team = parent.team;
227 rocket setTeam( parent.team );
229 rocket Missile_SetTarget( missile );
232 curDist = Distance( missile.origin, rocket.origin );
234 tooCloseToPredictedParent =
false;
237 debug_draw = GetDvarInt(
"scr_flak_drone_debug_trails", 0 );
238 debug_duration = GetDvarInt(
"scr_flak_drone_debug_trails_duration", 20 * 20 );
247 if ( isdefined( rocket ) )
249 curDist = Distance( missile.origin, rocket.origin );
251 distDelta = prevDist - curDist;
253 predictedDist = curDist - distDelta;
257 if ( debug_draw && isdefined( missile ) )
260 if ( debug_draw && isdefined( rocket ) )
264 if ( isdefined( parent ) )
266 parentVelocity = parent GetVelocity();
267 parentPredictedLocation = parent.origin + ( parentVelocity * 0.05 );
268 missileVelocity = missile GetVelocity();
269 missilePredictedLocation = missile.origin + ( missileVelocity * 0.05 );
273 tooCloseToPredictedParent =
true;
277 if( ( predictedDist < 0 ) || ( curDist > prevDist ) || tooCloseToPredictedParent || !isdefined( rocket ) )
280 if ( debug_draw && isdefined( parent ) )
282 if ( tooCloseToPredictedParent && ! ( ( predictedDist < 0 ) || ( curDist > prevDist ) ) )
293 if ( isdefined( rocket ) )
306 missile waittill(
"death" );
310 if ( isdefined( rocket ) )
315 if ( isdefined( flak_drone ) )
323 self endon(
"death" );
324 doGibbedDeath =
false;
326 if( isdefined(
self.death_info ) )
328 if( isdefined(
self.death_info.weapon ) )
330 if(
self.death_info.weapon.dogibbing ||
self.death_info.weapon.doannihilate )
332 doGibbedDeath =
true;
335 if( isdefined(
self.death_info.meansOfDeath ) )
337 meansOfDeath =
self.death_info.meansOfDeath;
338 if( meansOfDeath ==
"MOD_EXPLOSIVE" || meansOfDeath ==
"MOD_GRENADE_SPLASH" || meansOfDeath ==
"MOD_PROJECTILE_SPLASH" || meansOfDeath ==
"MOD_PROJECTILE" )
340 doGibbedDeath =
true;
347 self playsound (
"veh_wasp_gibbed");
348 PlayFxOnTag(
"explosions/fx_vexp_wasp_gibb_death",
self,
"tag_origin" );
353 if( isdefined(
self ) )
366 self endon(
"death" );
368 self.painStartTime = GetTime();
374 while ( GetTime() <
self.painStartTime + time * 1000 )
376 self SetVehVelocity(
self.velocity * stablizeParam );
377 self SetAngularVelocity(
self GetAngularVelocity() * stablizeParam );
381 if ( isdefined( restoreLookPoint ) )
383 restoreLookEnt =
Spawn(
"script_model", restoreLookPoint );
384 restoreLookEnt SetModel(
"tag_origin" );
386 self ClearLookAtEnt();
387 self SetLookAtEnt( restoreLookEnt );
388 self setTurretTargetEnt( restoreLookEnt );
391 self ClearLookAtEnt();
392 self ClearTurretTarget();
393 restoreLookEnt
delete();
400 function drone_pain( eAttacker, damageType, hitPoint, hitDirection, hitLocationInfo, partName )
406 ang_vel =
self GetAngularVelocity();
407 ang_vel += ( RandomFloatRange( -120, -100 ), yaw_vel, RandomFloatRange( -200, 200 ) );
408 self SetAngularVelocity( ang_vel );
414 function FlakDroneDamageOverride( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, vDamageOrigin, psOffsetTime, damageFromUnderneath, modelIndex, partName, vSurfaceNormal )
416 if( sMeansOfDeath ==
"MOD_TRIGGER_HURT" )
419 if( isdefined( eAttacker ) && isdefined( eAttacker.team ) && eAttacker.team !=
self.team )
421 drone_pain( eAttacker, sMeansOfDeath, vPoint, vDir, sHitLoc, partName );
427 function Spawn( parent, onDeathCallback )
429 if( !IsNavVolumeLoaded() )
431 /# IPrintLnBold(
"Error: NavVolume Not Loaded" ); #/
438 drone.death_callback = onDeathCallback;
450 drone.team = parent.team;
451 drone SetTeam( parent.team );
460 drone.parent = parent;
467 drone endon(
"death" );
469 drone.parent.owner
util::waittill_any(
"game_ended",
"emp_jammed",
"disconnect",
"joined_team" );
476 drone.parent endon(
"death" );
478 drone waittill(
"death" );
485 drone endon(
"death" );
487 drone.parent waittill(
"death" );
494 drone endon(
"death" );
495 drone.parent endon(
"death" );
497 drone.parent waittill(
"stinger_fired_at_me", missile, weapon, attacker );
499 drone.incoming_missile = missile;
500 drone.incoming_missile.target_weapon = weapon;
501 drone.incoming_missile.target_attacker = attacker;
514 if( isdefined( drone.death_callback ) )
516 drone.parent thread [[ drone.death_callback ]]();
519 if( isdefined( drone ) && !isdefined( drone.parent ) )
524 if( isdefined( drone ) )
528 if( isdefined( drone ) )
532 drone DoDamage( drone.health + 1000, drone.origin, drone, drone,
"none",
"MOD_EXPLOSIVE" );