1 #using scripts\codescripts\struct;
3 #using scripts\shared\audio_shared;
4 #using scripts\shared\callbacks_shared;
5 #using scripts\shared\challenges_shared;
6 #using scripts\shared\clientfield_shared;
7 #using scripts\shared\killstreaks_shared;
8 #using scripts\shared\scoreevents_shared;
9 #using scripts\shared\util_shared;
10 #using scripts\shared\_oob;
11 #using scripts\shared\popups_shared;
12 #using scripts\shared\vehicle_shared;
13 #using scripts\shared\weapons\_heatseekingmissile;
14 #using scripts\shared\weapons\_weaponobjects;
15 #using scripts\shared\weapons\_hacker_tool;
16 #using scripts\shared\visionset_mgr_shared;
18 #using scripts\mp\_util;
19 #using scripts\mp\gametypes\_globallogic;
20 #using scripts\mp\gametypes\_globallogic_audio;
21 #using scripts\mp\gametypes\_spawning;
22 #using scripts\mp\killstreaks\_airsupport;
23 #using scripts\mp\killstreaks\_helicopter;
24 #using scripts\mp\killstreaks\_killstreak_bundles;
25 #using scripts\mp\killstreaks\_killstreak_detect;
26 #using scripts\mp\killstreaks\_killstreak_hacking;
27 #using scripts\mp\killstreaks\_killstreakrules;
28 #using scripts\mp\killstreaks\_killstreaks;
29 #using scripts\mp\teams\_teams;
30 #using scripts\mp\killstreaks\_remote_weapons;
32 #insert scripts\mp\_hacker_tool.gsh;
33 #insert scripts\mp\killstreaks\_killstreaks.gsh;
34 #insert scripts\shared\clientfields.gsh;
35 #insert scripts\shared\shared.gsh;
36 #insert scripts\shared\version.gsh;
38 #precache( "string", "KILLSTREAK_EARNED_HELICOPTER_GUNNER" );
39 #precache( "string", "KILLSTREAK_HELICOPTER_GUNNER_NOT_AVAILABLE" );
40 #precache( "string", "KILLSTREAK_HELICOPTER_GUNNER_INBOUND" );
41 #precache( "string", "KILLSTREAK_HELICOPTER_GUNNER_HACKED" );
42 #precache( "string", "KILLSTREAK_DESTROYED_HELICOPTER_GUNNER" );
43 #precache( "string", "KILLSTREAK_HELICOPTER_GUNNER_DAMAGED" );
44 #precache( "eventstring", "mpl_killstreak_osprey_strt" );
46 #namespace helicopter_gunner;
47 #define HELICOPTER_GUNNER_NAME "helicopter_gunner"
48 #define HELICOPTER_GUNNER_WEAPON_NAME "helicopter_player_gunner"
49 #define HELICOPTER_GUNNER_ASSISTANT_NAME "helicopter_gunner_assistant"
50 #define INVENTORY_HELICOPTER_GUNNER_ASSISTANT_NAME "inventory_helicopter_gunner_assistant"
52 #define INVALID_ASSISTANT_SEAT_INDEX -1
53 #define HELICOPTER_LEAVE_DELAY 2.0
55 #define REALLY_LONG_TIME_MS 9009009
61 killstreaks::register_dialog(
HELICOPTER_GUNNER_NAME,
"mpl_killstreak_osprey_strt",
"helicopterGunnerDialogBundle",
"helicopterGunnerPilotDialogBundle",
"friendlyHelicopterGunner",
"enemyHelicopterGunner",
"enemyHelicopterGunnerMultiple",
"friendlyHelicopterGunnerHacked",
"enemyHelecopterGunnerHacked",
"requestHelicopterGunner",
"threatHelicopterGunner" );
70 killstreaks::register_dialog(
HELICOPTER_GUNNER_ASSISTANT_NAME,
"mpl_killstreak_osprey_strt",
"helicopterGunnerDialogBundle",
"helicopterGunnerPilotDialogBundle",
"friendlyHelicopterGunner",
"enemyHelicopterGunner",
"enemyHelicopterGunnerMultiple",
"friendlyHelicopterGunnerHacked",
"enemyHelecopterGunnerHacked",
"requestHelicopterGunner",
"threatHelicopterGunner" );
93 level.vtol = undefined;
98 if( !isdefined(
self.entNum ) )
100 self.entNum =
self getEntityNumber();
112 foreach( player
in level.players )
114 if( isdefined( player.sessionstate ) && player.sessionstate ==
"playing" )
121 if( !isdefined( player ) )
124 heli_team = undefined;
126 heli_team = level.vtol.owner.team;
128 if( isdefined( heli_team ) && ( player.team == heli_team ) )
146 while( isdefined( level.vtol ) && level.vtol.shuttingdown )
158 if( level.gameEnded )
171 if( isdefined( level.vtol ) && level.vtol.shuttingdown )
174 if( isdefined( level.vtol.usage[player.entNum] ) )
188 if( isdefined( level.vtol ) && ( !level.vtol.shuttingDown ) && ( level.vtol.team == player.team ) && ( level.vtol.owner != player ) )
192 if( !isdefined( level.vtol.assistants[i].occupant ) && !level.vtol.assistants[i].destroyed )
204 level.vtol.assistants[index] = SpawnStruct();
205 assistant = level.vtol.assistants[index];
207 assistant.occupant = undefined;
208 assistant.destroyed =
false;
209 assistant.rocketHits = 0;
210 assistant.targetTag = destroyTag;
212 assistant.targetEnt =
spawn(
"script_model", ( 0, 0, 0 ) );
213 assistant.targetEnt.useVTOLTime =
true;
214 assistant.targetEnt SetModel(
"p7_dogtags_enemy" );
215 assistant.targetEnt LinkTo( level.vtol, assistant.targetTag, ( 0, 0, 0 ), ( 0, 0, 0 ) );
216 assistant.targetEnt.team = level.vtol.team;
217 Target_Set( assistant.targetEnt, ( 0, 0, 0 ) );
218 Target_SetAllowHighSteering( assistant.targetEnt,
true );
219 assistant.targetEnt.parent = level.vtol;
227 heliGunner.owner unlink();
230 heliGunner.owner SetModelLodBias( 0 );
233 heliGunner.owner notify(
"gunner_left" );
239 foreach( assistant
in heliGunner.assistants )
241 if( isdefined( assistant.occupant ) )
242 assistant.occupant iPrintLnBold( &
"KILLSTREAK_HELICOPTER_GUNNER_DAMAGED" );
246 heliGunner MakeVehicleUnusable();
253 heliGunner MakeVehicleUsable();
254 heliGunner UseVehicle( hacker, 0 );
263 hacker SetModelLodBias(
VAL( level.mothership_lod_bias, 8 ) );
264 heliGunner.owner GiveDedicatedShadow( level.vtol );
270 if ( heliGunner.killstreak_timer_started )
274 heliGunner.killstreakEndTime = int( heliGunner.killstreak_end_time );
278 heliGunner.killstreak_timer_start_using_hacked_time =
true;
285 player endon(
"disconnect" );
286 level endon(
"game_ended" );
288 if( !isdefined( level.heli_paths ) || !level.heli_paths.size )
291 if( !isdefined( level.Heli_primary_path ) || !level.heli_primary_path.size )
301 startNode = level.heli_primary_path[0];
306 level.vtol.killstreak_id = killstreak_id;
314 level.vtol.killstreak_timer_started =
false;
315 level.vtol.allowdeath =
false;
317 level.vtol.playerMovedRecently =
false;
318 level.vtol.soundmod =
"default_loud";
321 level.vtol.assistants = [];
322 level.vtol.usage = [];
331 level.vtol.shuttingDown =
false;
340 if ( isdefined( tableHealth ) )
342 level.vtol.maxhealth = tableHealth;
344 level.vtol.original_health = level.vtol.maxhealth;
345 level.vtol.health = level.vtol.maxhealth;
347 level.vtol SetCanDamage(
true );
351 attack_nodes = GetEntArray(
"heli_attack_area",
"targetname" );
352 if( attack_nodes.size )
362 level.vtol.totalRocketHits = 0;
363 level.vtol.turretRocketHits = 0;
364 level.vtol.targetEnt = undefined;
386 if ( helicopter.shuttingDown ==
true )
408 assert( isdefined( hackedHealth ) );
409 if ( helicopter.health > hackedhealth )
411 helicopter.health = hackedhealth;
418 level waittill(
"game_ended" );
419 if( isdefined( level.vtol ) && isdefined( level.vtol.owner ))
426 helicopter waittill(
"vtol_shutdown", attacker );
428 if( isdefined( attacker ) )
430 LUINotifyEvent( &
"player_callout", 2, &
"KILLSTREAK_DESTROYED_HELICOPTER_GUNNER", attacker.entnum );
433 if( isdefined( helicopter.targetEnt ) )
435 Target_Remove( helicopter.targetEnt );
436 helicopter.targetEnt Delete();
437 helicopter.targetEnt = undefined;
442 assistant = level.vtol.assistants[seatIndex];
443 if( isdefined( assistant.targetEnt ) )
445 Target_Remove( assistant.targetEnt );
446 assistant.targetEnt Delete();
447 assistant.targetEnt = undefined;
455 level.vtol = undefined;
463 helicopter notify(
"vtol_shutdown", undefined );
470 if( isdefined(level.vtol.assistants[i].occupant ) )
481 helicopter notify(
"mothership_team_change" );
482 helicopter endon (
"mothership_team_change" );
484 assert( IsPlayer(
self ) );
487 player endon(
"gunner_left" );
491 ownerLeft = helicopter.ownerEntNum == player.entNum;
496 helicopter notify(
"vtol_shutdown", undefined );
501 player notify(
"WatchPlayerExitRequestThread_singleton" );
502 player endon (
"WatchPlayerExitRequestThread_singleton" );
503 assert( IsPlayer( player ) );
506 level endon(
"game_ended" );
507 player endon(
"disconnect" );
508 player endon(
"gunner_left" );
510 owner = mothership.ownerEntNum == player.entNum;
515 while( player UseButtonPressed() )
518 if( timeUsed > 0.25 )
532 assert( IsPlayer(
self ) );
543 level.vtol.assistants[ seatIndex ].occupant = player;
546 level.vtol.occupied =
true;
549 player.ignoreEMPJammed =
true;
551 player.ignoreEMPJammed =
false;
560 level.vtol.assistants[ seatIndex ].occupant = undefined;
564 level.vtol.failed2enter =
true;
565 level.vtol notify(
"vtol_shutdown" );
573 level.vtol UseVehicle( player, 0 );
578 if( level.vtol.shuttingdown )
589 killcament =
spawn(
"script_model", ( 0, 0, 0 ) );
590 killcament SetModel(
"tag_origin" );
591 killcament.angles = ( 0, 0, 0 );
592 killcament SetWeapon( GetWeapon(
"helicopter_gunner_turret_primary" ) );
593 killcament linkto( level.vtol,
"tag_barrel", ( 370, 0, 25 ), ( 0, 0, 0 ) );
594 level.vtol.killcament = killcament;
596 level.vtol.usage[player.entNum] = 1;
603 if ( level.vtol.killstreak_timer_started )
621 player SetModelLodBias(
VAL( level.mothership_lod_bias, 8 ) );
622 player GiveDedicatedShadow( level.vtol );
635 self endon(
"death" );
636 self endon(
"disconnect" );
645 helicopter.owner iPrintLnBold( &
"KILLSTREAK_HELICOPTER_GUNNER_DAMAGED" );
647 if ( isdefined(helicopter.targetEnt))
649 Target_Remove( helicopter.targetEnt );
650 helicopter.targetEnt Delete();
651 helicopter.targetEnt = undefined;
653 helicopter.shuttingDown =
true;
656 eAttacker =
self [[ level.figure_out_attacker ]]( eAttacker );
657 if( !isdefined( helicopter.destroyScoreEventGiven ) && isdefined( eAttacker ) && ( !isdefined( helicopter.owner ) || helicopter.owner
util::IsEnemyPlayer( eAttacker ) ) )
659 LUINotifyEvent( &
"player_callout", 2, &
"KILLSTREAK_HELICOPTER_GUNNER_DAMAGED", eAttacker.entnum );
664 helicopter.destroyScoreEventGiven = 1;
672 self endon(
"vtol_shutdown" );
676 self waittill(
"bda_dialog", dialogKey );
680 if( isdefined( level.vtol.assistants[i].occupant ) )
690 assistant = helicopter.assistants[seatIndex];
691 if( !assistant.destroyed )
693 Target_Remove( assistant.targetEnt );
696 assistant.targetEnt Delete();
697 assistant.targetEnt = undefined;
698 assistant.destroyed =
true;
700 if ( isdefined( helicopter.owner ) && isdefined( helicopter.hardpointType ) )
705 if( isdefined( assistant.occupant ) )
716 if ( seatIndex == 0 )
721 else if ( seatIndex == 1 )
734 foreach( assistant
in vtol.assistants )
742 if ( isdefined( player ) )
752 helicopter endon (
"delete" );
753 helicopter endon (
"vtol_shutdown" );
756 notifies[0] =
"turret1_destroyed";
757 notifies[1] =
"turret2_destroyed";
761 if( brokenNotify == notifies[seatIndex] )
768 if( brokenNotify ==
"turret_destroyed" )
782 if( helicopter.assistants[0].destroyed && helicopter.assistants[1].destroyed )
784 if( !isdefined( helicopter.targetEnt ) )
786 helicopter.targetEnt =
spawn(
"script_model", ( 0, 0, 0 ) );
787 helicopter.targetEnt SetModel(
"p7_dogtags_enemy" );
788 helicopter.targetEnt LinkTo( level.vtol,
"tag_barrel", ( 0, 0, 0 ), ( 0, 0, 0 ) );
789 helicopter.targetEnt.parent = level.vtol;
790 helicopter.targetEnt.team = level.vtol.team;
791 Target_Set( helicopter.targetEnt, ( 0, 0, 0 ) );
792 helicopter.targetEnt.useVTOLTime =
true;
793 Target_SetAllowHighSteering( helicopter.targetEnt,
true );
802 if( !isdefined( level.vtol ) || level.vtol.completely_shutdown ===
true )
805 if( isdefined( player ) )
811 if( isdefined( player ) && isdefined( level.vtol ) && isdefined( level.vtol.owner ) )
813 if( isdefined( player.usingvehicle ) && player.usingvehicle )
827 level.vtol.shuttingDown =
true;
828 foreach( assistant
in level.vtol.assistants )
830 if( isdefined( assistant.occupant ) )
832 assistant.occupant iPrintLnBold( &
"KILLSTREAK_HELICOPTER_GUNNER_DAMAGED" );
837 level.vtol.occupied =
false;
844 if( isdefined( player ) )
848 foreach( assistant
in level.vtol.assistants )
850 if( isdefined( assistant.occupant ) && assistant.occupant == player )
852 assistant.occupant = undefined;
859 if( isdefined( player ) )
863 player SetModelLodBias( 0 );
864 player GiveDedicatedShadow( player );
869 player notify(
"gunner_left" );
873 if( level.gameEnded )
880 level.vtol.completely_shutdown =
true;
885 if( isdefined( level.vtol ) && isdefined( level.vtol.owner ) )
887 org = level.vtol GetTagOrigin(
"tag_barrel" );
893 Earthquake( magnitude, duration, org, 500 );
898 function HelicopterGunnerDamageOverride( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, vDamageOrigin, psOffsetTime, damageFromUnderneath, modelIndex, partName, vSurfaceNormal )
902 if( sMeansOfDeath ==
"MOD_TRIGGER_HURT" )
905 if( helicopter.shuttingDown )
908 iDamage =
self killstreaks::OnDamagePerWeapon(
HELICOPTER_GUNNER_NAME, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, level.vtol.maxhealth, undefined, level.vtol.maxhealth*0.4, undefined, 0, undefined,
true, 1.0 );
913 handleAsRocketDamage = ( ( sMeansOfDeath ==
"MOD_PROJECTILE" ) || ( sMeansOfDeath ==
"MOD_EXPLOSIVE" ) );
914 if ( weapon.statIndex == level.weaponShotgunEnergy.statIndex || weapon.statIndex == level.weaponPistolEnergy.statIndex || weapon.statIndex == level.weaponSmgNailGun.statIndex )
915 handleAsRocketDamage =
false;
917 if( handleAsRocketDamage )
921 missileTarget = eInflictor missile_gettarget();
926 if ( weapon.statIndex == level.weaponLauncherMulti.statIndex )
929 helicopter.totalRocketHits += rocketHit;
931 if( isdefined( missileTarget ) )
936 assistant = helicopter.assistants[seatIndex];
938 if( !assistant.destroyed && ( assistant.targetEnt == missileTarget ) )
940 assistant.rocketHits += rocketHit;
942 if ( assistant.rocketHits >= 2 )
944 helicopter DoDamage( iDamage, assistant.targetEnt.origin, eAttacker, eInflictor, sHitLoc,
"MOD_UNKNOWN", 0, weapon, seatIndex + 8 );
952 if( isdefined( helicopter.targetEnt ) && ( helicopter.targetEnt == missileTarget ) )
954 helicopter.turretRocketHits += rocketHit;
957 if( helicopter.turretRocketHits >= 2 )
959 Target_Remove( helicopter.targetEnt );
960 helicopter.targetEnt Delete();
961 helicopter.targetEnt = undefined;
967 if( helicopter.assistants[0].destroyed && helicopter.assistants[1].destroyed && ( !isdefined( helicopter.targetEnt ) ) )
969 helicopter.targetEnt =
spawn(
"script_model", ( 0, 0, 0 ) );
970 helicopter.targetEnt SetModel(
"p7_dogtags_enemy" );
971 helicopter.targetEnt LinkTo( level.vtol,
"tag_barrel", ( 0, 0, 0 ), ( 0, 0, 0 ) );
972 helicopter.targetEnt.parent = level.vtol;
973 helicopter.targetEnt.team = level.vtol.team;
974 Target_Set( helicopter.targetEnt, ( 0, 0, 0 ) );
975 helicopter.targetEnt.useVTOLTime =
true;
976 Target_SetAllowHighSteering( helicopter.targetEnt,
true );
985 if ( updateInventory )
989 if( iDamage >= level.vtol.health && !helicopter.shuttingDown )
991 helicopter.shuttingDown =
true;
994 if ( !isdefined( helicopter.destroyScoreEventGiven ) && isdefined( eAttacker ) && ( !isdefined( helicopter.owner ) || helicopter.owner
util::IsEnemyPlayer( eAttacker ) ) )
996 eAttacker =
self [[ level.figure_out_attacker ]]( eAttacker );
997 LUINotifyEvent( &
"player_callout", 2, &
"KILLSTREAK_HELICOPTER_GUNNER_DAMAGED", eAttacker.entnum );
1000 helicopter.destroyScoreEventGiven = 1;
1006 if( helicopter.shuttingDown )
1008 if( iDamage >= helicopter.health )
1009 iDamage = helicopter.health - 1;
1019 helicopter endon(
"death" );
1021 if (
self.leave_by_damage_initiated ===
true )
1024 self.leave_by_damage_initiated =
true;
1027 failsafe_timeout = 5.0;
1041 targetEnt endon(
"delete" );
1042 targetEnt endon(
"death" );
1052 player = helicopter.owner;
1054 player endon(
"disconnect" );
1055 player endon(
"gunner_left" );
1057 heliMissile = GetWeapon(
"helicopter_gunner_turret_rockets" );
1061 player waittill(
"missile_fire", missile );
1063 trace_origin = level.vtol GetTagOrigin(
"tag_flash" );
1064 trace_direction = level.vtol GetTagAngles(
"tag_barrel" );
1065 trace_direction = AnglesToForward( trace_direction ) * 8000;
1066 trace = BulletTrace( trace_origin, trace_origin + trace_direction,
false, level.vtol );
1067 end_origin =
trace[
"position"];
1069 missiles = getentarray(
"rocket",
"classname" );
1075 foreach( missile
in missiles )
1077 if( missile.item == heliMissile )
1079 targetEnt =
Spawn(
"script_model", end_origin );
1080 missile Missile_SetTarget( targetEnt );
1086 weapon_wait_duration_ms = Int( heliMissile.fireTime * 1000 );
1087 player SetVehicleWeaponWaitDuration( weapon_wait_duration_ms );
1088 player SetVehicleWeaponWaitEndTime( GetTime() + weapon_wait_duration_ms );
1094 assert( IsPlayer(
self ) );
1097 player endon(
"disconnect" );
1098 player endon(
"gunner_left" );
1105 if( player JumpButtonPressed() )
1110 player PlaySoundToPlayer(
"mpl_cgunner_flir_off", player );
1115 player PlaySoundToPlayer(
"mpl_cgunner_flir_on", player );
1118 inverted = !inverted;
1120 while( player JumpButtonPressed() )
1130 player endon(
"disconnect" );
1131 player endon(
"gunner_left" );
1133 heli endon(
"death" );
1134 heli endon (
"crashing" );
1135 heli endon (
"leaving" );
1137 heli.lockSounds =
spawn(
"script_model", heli.origin );
1139 heli.lockSounds LinkTo( heli,
"tag_player" );
1143 heli waittill(
"locking on" );
1149 heli.lockSounds PlaySoundToPlayer(
"uin_alert_lockon", player );
1155 heli.lockSounds PlaySoundToPlayer(
"uin_alert_lockon", player );
1161 heli.lockSounds StopSounds();
1170 return ( isdefined( heli.locking_on ) && heli.locking_on );
1175 return ( isdefined( heli.locked_on ) && heli.locked_on );
1180 self notify(
"flying");
1181 self endon(
"flying" );
1183 self endon (
"death" );
1184 self endon (
"crashing" );
1185 self endon (
"leaving" );
1187 nextnode = getent( startNode.target,
"targetname" );
1188 assert( isdefined( nextnode ),
"Next node in path is undefined, but has targetname" );
1189 self SetSpeed( 150, 80 );
1191 self waittill(
"near_goal" );
1196 if( !
self.playerMovedRecently )
1199 level.vtol.currentNode = node;
1200 targetNode = getEnt( node.target,
"targetname" );
1204 if( isdefined( targetNode.script_airspeed ) && isdefined( targetNode.script_accel ) )
1206 heli_speed = targetNode.script_airspeed;
1207 heli_accel = targetNode.script_accel;
1211 heli_speed = 150+randomInt(20);
1212 heli_accel = 40+randomInt(10);
1215 self SetSpeed( heli_speed, heli_accel );
1222 self waittill(
"near_goal" );
1225 else if( !isdefined( targetNode.script_delay ) )
1227 self waittill(
"near_goal" );
1228 waitTime = 10 + randomInt( 5 );
1232 self waittillmatch(
"goal" );
1233 waitTime = targetNode.script_delay;
1239 self.killstreak_end_time = GetTime() +
self.killstreak_duration;
1240 self.killstreakEndTime = int(
self.killstreak_end_time );
1242 self.killstreak_timer_started =
true;
1254 if ( isdefined(
self.owner ) )
1261 if( isdefined(
self.assistants[i].occupant ) && !
self.assistants[i].destroyed )
1272 player endon(
"disconnect" );
1273 player endon(
"gunner_left" );
1275 helicopter = level.vtol;
1277 helicopter endon (
"delete" );
1278 helicopter endon (
"vtol_shutdown" );
1281 helicopter waittill (
"near_goal" );
1282 helicopter waittill (
"goal" );
1286 if(
self SecondaryOffhandButtonPressed() )
1291 helicopter.currentNode = node;
1292 targetNode = getEnt( node.target,
"targetname" );
1294 player playlocalsound (
"mpl_cgunner_nav" );
1297 if( isdefined( targetNode.script_airspeed ) && isdefined( targetNode.script_accel ) )
1299 heli_speed = targetNode.script_airspeed;
1300 heli_accel = targetNode.script_accel;
1304 heli_speed = 80+randomInt(20);
1305 heli_accel = 40+randomInt(10);
1308 helicopter SetSpeed( heli_speed, heli_accel );
1312 helicopter waittill(
"goal" );
1315 while (
self SecondaryOffhandButtonPressed() )
1329 player endon(
"disconnect" );
1330 player endon(
"gunner_left" );
1332 helicopter = level.vtol;
1334 helicopter endon (
"delete" );
1335 helicopter endon (
"vtol_shutdown" );
1337 myMove =
self.moves;
1338 level.vtol.playerMovedRecently =
true;
1342 if( myMove ==
self.moves && isdefined( level.vtol ) )
1344 level.vtol.playerMovedRecently =
false;
1352 foreach( node
in areaNodes )
1354 node.validPlayers = [];
1358 foreach( player
in level.players )
1360 if( !isAlive( player ) )
1365 if( player.team ==
self.team )
1370 foreach( node
in areaNodes )
1372 if( distanceSquared( player.origin, node.origin ) > 1048576 )
1377 node.validPlayers[node.validPlayers.size] = player;
1381 bestNode = undefined;
1382 foreach ( node
in areaNodes )
1384 if( isdefined( level.vtol.currentNode ) && ( node == level.vtol.currentNode ) )
1389 heliNode = getEnt( node.target,
"targetname" );
1390 foreach( player
in node.validPlayers )
1392 node.nodeScore += 1;
1394 if( bulletTracePassed( player.origin + (0,0,32), heliNode.origin,
false, player ) )
1396 node.nodeScore += 3;
1400 if( forceMove && ( distance( level.vtol.origin, heliNode.origin ) < 200 ) )
1402 node.nodeScore = -1;
1405 if( !isdefined( bestNode ) || ( node.nodeScore > bestNode.nodeScore ) )
1418 if( originOffets[
"start"] !=
self.origin )
1420 if( isdefined( goalNode.script_airspeed ) && isdefined( goalNode.script_accel ) )
1422 heli_speed = goalNode.script_airspeed;
1423 heli_accel = goalNode.script_accel;
1427 heli_speed = 30 + randomInt(20);
1428 heli_accel = 15 + randomInt(15);
1431 self SetSpeed( heli_speed, heli_accel );
1432 self setvehgoalpos( originOffets[
"start"] + (0,0,30), 0 );
1435 self waittill (
"goal" );
1438 if( originOffets[
"end"] != goalNode.origin )
1440 if( isdefined( goalNode.script_airspeed ) && isdefined( goalNode.script_accel ) )
1442 heli_speed = goalNode.script_airspeed;
1443 heli_accel = goalNode.script_accel;
1447 heli_speed = 30+randomInt(20);
1448 heli_accel = 15+randomInt(15);
1451 self SetSpeed( heli_speed, heli_accel );
1452 self setvehgoalpos( originOffets[
"end"] + (0,0,30), 0 );
1455 self waittill (
"goal" );
1461 startOrigin =
self.origin;
1462 endOrigin = goalNode.origin;
1467 traceOffset = (0,0,-196);
1469 traceOrigin = BulletTrace( startOrigin+traceOffset, endOrigin+traceOffset,
false,
self );
1471 while( DistanceSquared( traceOrigin[
"position" ], endOrigin+traceOffset ) > 10 && numTraces < maxTraces )
1473 /#println(
"trace failed: " + DistanceSquared( traceOrigin[
"position" ], endOrigin+traceOffset ) );#/
1475 if( startOrigin[2] < endOrigin[2] )
1477 startOrigin += (0,0,128);
1479 else if( startOrigin[2] > endOrigin[2] )
1481 endOrigin += (0,0,128);
1485 startOrigin += (0,0,128);
1486 endOrigin += (0,0,128);
1490 traceOrigin = BulletTrace( startOrigin+traceOffset, endOrigin+traceOffset,
false,
self );
1494 offsets[
"start"] = startOrigin;
1495 offsets[
"end"] = endOrigin;