init
This commit is contained in:
603
maps/mp/killstreaks/_dronehive.gsc
Normal file
603
maps/mp/killstreaks/_dronehive.gsc
Normal file
@ -0,0 +1,603 @@
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\gametypes\_hud_util;
|
||||
#include common_scripts\utility;
|
||||
|
||||
|
||||
//============================================
|
||||
// constants
|
||||
//============================================
|
||||
CONST_DRONE_HIVE_DEBUG = false;
|
||||
CONST_MISSILE_COUNT = 2;
|
||||
CONST_WEAPON_MAIN = "drone_hive_projectile_mp";
|
||||
CONST_WEAPON_CHILD = "switch_blade_child_mp";
|
||||
|
||||
|
||||
//============================================
|
||||
// init
|
||||
//============================================
|
||||
init()
|
||||
{
|
||||
level.killstreakFuncs["drone_hive"] = ::tryUseDroneHive;
|
||||
|
||||
level.droneMissileSpawnArray = GetEntArray( "remoteMissileSpawn", "targetname" );
|
||||
|
||||
foreach( missileSpawn in level.droneMissileSpawnArray )
|
||||
{
|
||||
missileSpawn.targetEnt = GetEnt( missileSpawn.target, "targetname" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//============================================
|
||||
// tryUseDroneHive
|
||||
//============================================
|
||||
tryUseDroneHive( lifeId, streakName )
|
||||
{
|
||||
/#
|
||||
if( (!IsDefined(level.droneMissileSpawnArray) || !level.droneMissileSpawnArray.size) )
|
||||
{
|
||||
AssertMsg( "map needs remoteMissileSpawn entities" );
|
||||
}
|
||||
#/
|
||||
|
||||
return useDroneHive( self, lifeId );
|
||||
}
|
||||
|
||||
|
||||
//============================================
|
||||
// useDroneHive
|
||||
//============================================
|
||||
useDroneHive( player, lifeId )
|
||||
{
|
||||
if ( IsDefined( self.underWater ) && self.underWater )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
player setUsingRemote( "remotemissile" );
|
||||
player freezeControlsWrapper( true );
|
||||
player _disableWeaponSwitch();
|
||||
// JC-10/01/13-Because the init ride of the killstreak has waits
|
||||
// the killstreak disowned notify could get missed causing the
|
||||
// usingRemote variable to never get cleared on the player. Start
|
||||
// these clean up threads off before to prevent this.
|
||||
level thread monitorDisownKillstreaks( player );
|
||||
level thread monitorGameEnd( player );
|
||||
level thread monitorObjectiveCamera(player);
|
||||
|
||||
result = player maps\mp\killstreaks\_killstreaks::initRideKillstreak( "drone_hive" );
|
||||
|
||||
if ( result == "success" )
|
||||
{
|
||||
player freezeControlsWrapper( false );
|
||||
level thread runDroneHive( player, lifeId);
|
||||
}
|
||||
else
|
||||
{
|
||||
player notify( "end_kill_streak" ); // stop the monitor threads
|
||||
player clearUsingRemote();
|
||||
player _enableWeaponSwitch();
|
||||
}
|
||||
|
||||
return result == "success";
|
||||
}
|
||||
|
||||
//============================================
|
||||
// watchHostMigrationStartedInit
|
||||
//============================================
|
||||
watchHostMigrationStartedInit( player )
|
||||
{
|
||||
player endon( "killstreak_disowned" );
|
||||
player endon ( "disconnect" );
|
||||
level endon( "game_ended" );
|
||||
self endon ( "death" );
|
||||
|
||||
for (;;)
|
||||
{
|
||||
level waittill( "host_migration_begin" );
|
||||
|
||||
if ( isDefined( self ) )
|
||||
{
|
||||
player VisionSetMissilecamForPlayer( game["thermal_vision"], 0 );
|
||||
player set_visionset_for_watching_players( "default", 0, undefined, true );
|
||||
player ThermalVisionFOFOverlayOn();
|
||||
}
|
||||
else
|
||||
{
|
||||
player SetClientOmnvar( "ui_predator_missile", 2 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//============================================
|
||||
// watchHostMigrationFinishedInit
|
||||
//============================================
|
||||
watchHostMigrationFinishedInit( player )
|
||||
{
|
||||
player endon( "killstreak_disowned" );
|
||||
player endon ( "disconnect" );
|
||||
level endon( "game_ended" );
|
||||
self endon ( "death" );
|
||||
|
||||
for (;;)
|
||||
{
|
||||
level waittill( "host_migration_end" );
|
||||
|
||||
|
||||
if ( isDefined( self ) )
|
||||
{
|
||||
player SetClientOmnvar( "ui_predator_missile", 1 );
|
||||
player SetClientOmnvar( "ui_predator_missiles_left", self.missilesLeft );
|
||||
}
|
||||
else
|
||||
{
|
||||
player SetClientOmnvar( "ui_predator_missile", 2 );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//============================================
|
||||
// useDroneHive
|
||||
//============================================
|
||||
runDroneHive( player, lifeId )
|
||||
{
|
||||
player endon( "killstreak_disowned" );
|
||||
level endon( "game_ended" );
|
||||
|
||||
player notifyOnPlayerCommand( "missileTargetSet", "+attack" );
|
||||
player notifyOnPlayerCommand( "missileTargetSet", "+attack_akimbo_accessible" );
|
||||
|
||||
remoteMissileSpawn = getBestMissileSpawnPoint( player, level.droneMissileSpawnArray );
|
||||
|
||||
startPos = remoteMissileSpawn.origin;
|
||||
targetPos = remoteMissileSpawn.targetEnt.origin;
|
||||
vector = VectorNormalize( startPos - targetPos );
|
||||
startPos = ( vector * 14000 ) + targetPos;
|
||||
|
||||
/#
|
||||
if( CONST_DRONE_HIVE_DEBUG )
|
||||
{
|
||||
level thread drawLine( startPos, targetPos, 15, (1,0,0) );
|
||||
}
|
||||
#/
|
||||
|
||||
rocket = MagicBullet( CONST_WEAPON_MAIN, startpos, targetPos, player );
|
||||
rocket SetCanDamage( true );
|
||||
rocket DisableMissileBoosting();
|
||||
rocket SetMissileMinimapVisible( true );
|
||||
|
||||
rocket.team = player.team;
|
||||
rocket.lifeId = lifeId;
|
||||
rocket.type = "remote";
|
||||
rocket.owner = player;
|
||||
rocket.entityNumber = rocket GetEntityNumber();
|
||||
|
||||
level.rockets[ rocket.entityNumber ] = rocket;
|
||||
level.remoteMissileInProgress = true;
|
||||
|
||||
level thread monitorDeath( rocket, true );
|
||||
level thread monitorBoost( rocket );
|
||||
|
||||
// this is used for challenge tracking
|
||||
if ( IsDefined( player.killsThisLifePerWeapon ) )
|
||||
{
|
||||
player.killsThisLifePerWeapon[ CONST_WEAPON_MAIN ] = 0;
|
||||
player.killsThisLifePerWeapon[ CONST_WEAPON_CHILD ] = 0;
|
||||
}
|
||||
|
||||
missileEyes( player, rocket );
|
||||
|
||||
player SetClientOmnvar( "ui_predator_missile", 1 );
|
||||
|
||||
rocket thread watchHostMigrationStartedInit( player );
|
||||
rocket thread watchHostMigrationFinishedInit( player );
|
||||
|
||||
missileCount = 0;
|
||||
rocket.missilesLeft = CONST_MISSILE_COUNT;
|
||||
|
||||
player setClientOmnVar( "ui_predator_missiles_left", CONST_MISSILE_COUNT );
|
||||
|
||||
while( true )
|
||||
{
|
||||
result = rocket waittill_any_return( "death", "missileTargetSet" );
|
||||
maps\mp\gametypes\_hostmigration::waitTillHostMigrationDone();
|
||||
|
||||
if( result == "death" )
|
||||
break;
|
||||
|
||||
//rocket trigger could be hit pre migration then rocket dies during migration
|
||||
//causing this case
|
||||
if ( !isDefined( rocket ) )
|
||||
break;
|
||||
|
||||
if( missileCount < CONST_MISSILE_COUNT )
|
||||
{
|
||||
level thread spawnSwitchBlade( rocket, missileCount );
|
||||
missileCount++;
|
||||
|
||||
rocket.missilesLeft = CONST_MISSILE_COUNT - missileCount;
|
||||
player setClientOmnVar( "ui_predator_missiles_left", rocket.missilesLeft );
|
||||
|
||||
if( missileCount == CONST_MISSILE_COUNT )
|
||||
rocket EnableMissileBoosting();
|
||||
}
|
||||
}
|
||||
|
||||
thread returnPlayer( player );
|
||||
}
|
||||
|
||||
|
||||
//============================================
|
||||
// monitorLockedTarget NOT IN USE WorldPointInReticle_Circle doesnt function here
|
||||
//============================================
|
||||
monitorLockedTarget()
|
||||
{
|
||||
level endon( "game_ended" );
|
||||
self endon ( "death" );
|
||||
|
||||
enemyTargets = [];
|
||||
sortedTargets = [];
|
||||
|
||||
for(;;)
|
||||
{
|
||||
targetsInsideReticle = [];
|
||||
enemyTargets = getEnemyTargets();
|
||||
|
||||
foreach( targ in enemyTargets )
|
||||
{
|
||||
targInReticle = self.owner WorldPointInReticle_Circle( targ.origin, 65, 90 );
|
||||
|
||||
if ( targInReticle )
|
||||
{
|
||||
self.owner thread drawLine( self.origin, targ.origin, 10, (0,0,1) );
|
||||
targetsInsideReticle[targetsInsideReticle.size] = targ;
|
||||
}
|
||||
}
|
||||
|
||||
if( targetsInsideReticle.size )
|
||||
{
|
||||
sortedTargets = SortByDistance( targetsInsideReticle, self.origin );
|
||||
self.lastTargetLocked = sortedTargets[0];
|
||||
maps\mp\gametypes\_hostmigration::waitLongDurationWithHostMigrationPause( 0.25 );
|
||||
}
|
||||
|
||||
wait ( 0.05 );
|
||||
maps\mp\gametypes\_hostmigration::waitTillHostMigrationDone();
|
||||
}
|
||||
}
|
||||
|
||||
//============================================
|
||||
// getEnemyTargets
|
||||
//============================================
|
||||
getEnemyTargets( owner )
|
||||
{
|
||||
enemyTargets = [];
|
||||
|
||||
foreach ( player in level.participants )
|
||||
{
|
||||
if ( owner isEnemy( player )
|
||||
&& !(player _hasPerk( "specialty_blindeye" ))
|
||||
)
|
||||
{
|
||||
enemyTargets[ enemyTargets.size ] = player;
|
||||
}
|
||||
}
|
||||
|
||||
enemyVehicleTargets = maps\mp\gametypes\_weapons::lockOnLaunchers_getTargetArray();
|
||||
|
||||
if ( enemyTargets.size && enemyVehicleTargets.size )
|
||||
{
|
||||
finalTargets = array_combine( enemyTargets, enemyVehicleTargets );
|
||||
return finalTargets;
|
||||
}
|
||||
else if ( enemyTargets.size )
|
||||
{
|
||||
return enemyTargets;
|
||||
}
|
||||
else
|
||||
{
|
||||
return enemyVehicleTargets;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//============================================
|
||||
// spawnSwitchBlade
|
||||
//============================================
|
||||
spawnSwitchBlade( rocket, spawnOnLeft )
|
||||
{
|
||||
rocket.owner playLocalSound( "ammo_crate_use" );
|
||||
|
||||
playerViewAngles = rocket GetTagAngles( "tag_camera" );
|
||||
forwardDir = AnglesToForward( playerViewAngles );
|
||||
rightDir = AnglesToRight( playerViewAngles );
|
||||
spawnOffset = (35,35,35);
|
||||
targetOffset = (15000,15000,15000);
|
||||
|
||||
if(spawnOnLeft)
|
||||
spawnOffset = spawnOffset * -1;
|
||||
|
||||
result = BulletTrace( rocket.origin, rocket.origin + (forwardDir * targetOffset), false, rocket );
|
||||
|
||||
targetOffset = targetOffset * result["fraction"];
|
||||
startPosition = rocket.origin + (rightDir * spawnOffset );
|
||||
targetLocation = rocket.origin + (forwardDir * targetOffset );
|
||||
|
||||
targets = rocket.owner getEnemyTargets( rocket.owner );
|
||||
missile = MagicBullet( CONST_WEAPON_CHILD, startPosition, targetLocation, rocket.owner );
|
||||
|
||||
foreach ( targ in targets )
|
||||
{
|
||||
if ( Distance2dsquared( targ.origin, targetLocation ) < (512*512) )
|
||||
{
|
||||
missile Missile_SetTargetEnt( targ );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//missile.targEffect = SpawnFx( level.lasedStrikeGlow, targetLocation );
|
||||
//self thread DrawLine(startPosition, targetLocation, 20, (1,0,0) );
|
||||
|
||||
missile SetCanDamage( true );
|
||||
missile SetMissileMinimapVisible( true );
|
||||
|
||||
missile.team = rocket.team;
|
||||
missile.lifeId = rocket.lifeId;
|
||||
missile.type = rocket.type;
|
||||
missile.owner = rocket.owner;
|
||||
missile.entityNumber = missile GetEntityNumber();
|
||||
|
||||
level.rockets[ missile.entityNumber ] = missile;
|
||||
level thread monitorDeath( missile, false );
|
||||
}
|
||||
|
||||
|
||||
//============================================
|
||||
// loop effect for targ
|
||||
//============================================
|
||||
loopTriggeredEffect( effect, missile )
|
||||
{
|
||||
missile endon( "death" );
|
||||
level endon( "game_ended" );
|
||||
self endon ( "death" );
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
TriggerFX( effect );
|
||||
wait ( 0.25 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//============================================
|
||||
// getNextMissileSpawnIndex
|
||||
//============================================
|
||||
getNextMissileSpawnIndex( oldIndex )
|
||||
{
|
||||
index = oldIndex + 1;
|
||||
|
||||
if( index == level.droneMissileSpawnArray.size )
|
||||
{
|
||||
index = 0;
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
|
||||
//============================================
|
||||
// monitorBoost
|
||||
//============================================
|
||||
monitorBoost( rocket )
|
||||
{
|
||||
rocket endon( "death" );
|
||||
|
||||
while( true )
|
||||
{
|
||||
rocket.owner waittill( "missileTargetSet" );
|
||||
rocket notify( "missileTargetSet" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//============================================
|
||||
// getBestMissileSpawnPoint
|
||||
//============================================
|
||||
getBestMissileSpawnPoint( owner, remoteMissileSpawnPoints )
|
||||
{
|
||||
validEnemies = [];
|
||||
|
||||
foreach( player in level.players )
|
||||
{
|
||||
if( !isReallyAlive( player ) )
|
||||
continue;
|
||||
|
||||
if( player.team == owner.team )
|
||||
continue;
|
||||
|
||||
if( player.team == "spectator" )
|
||||
continue;
|
||||
|
||||
validEnemies[validEnemies.size] = player;
|
||||
}
|
||||
|
||||
if( !validEnemies.size )
|
||||
{
|
||||
return remoteMissileSpawnPoints[ RandomInt(remoteMissileSpawnPoints.size)];
|
||||
}
|
||||
|
||||
remoteMissileSpawnPointsRandomized = array_randomize(remoteMissileSpawnPoints);
|
||||
bestMissileSpawn = remoteMissileSpawnPointsRandomized[0];
|
||||
|
||||
// select a missile spawn that can see the most enemies
|
||||
foreach( missileSpawn in remoteMissileSpawnPointsRandomized )
|
||||
{
|
||||
missileSpawn.sightedEnemies = 0;
|
||||
|
||||
for ( i = 0; i < validEnemies.size; i++ )
|
||||
{
|
||||
enemy = validEnemies[i];
|
||||
if( !isReallyAlive( enemy ) )
|
||||
{
|
||||
validEnemies[i] = validEnemies[validEnemies.size-1];
|
||||
validEnemies[validEnemies.size-1] = undefined;
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
|
||||
//IW6 JH made this way cheaper if it sees an enemy it returns it.
|
||||
if( BulletTracePassed( enemy.origin + (0,0,32), missileSpawn.origin, false, enemy ) )
|
||||
{
|
||||
missileSpawn.sightedEnemies += 1;
|
||||
return missileSpawn;
|
||||
}
|
||||
|
||||
wait(0.05); // This loop is O(n^2), and it does a trace each time, so make sure to only do one per frame
|
||||
maps\mp\gametypes\_hostmigration::waitTillHostMigrationDone();
|
||||
}
|
||||
|
||||
if ( missileSpawn.sightedEnemies == validEnemies.size )
|
||||
{
|
||||
// Optimization - if this missileSpawn can see all enemies, then we're not going to find a better one, so just return it immediately
|
||||
return missileSpawn;
|
||||
}
|
||||
|
||||
if( missileSpawn.sightedEnemies > bestMissileSpawn.sightedEnemies )
|
||||
{
|
||||
bestMissileSpawn = missileSpawn;
|
||||
}
|
||||
}
|
||||
|
||||
return bestMissileSpawn;
|
||||
}
|
||||
|
||||
|
||||
//============================================
|
||||
// missileEyes
|
||||
//============================================
|
||||
missileEyes( player, rocket )
|
||||
{
|
||||
delayTime = 1.0;
|
||||
|
||||
player freezeControlsWrapper( true );
|
||||
player CameraLinkTo( rocket, "tag_origin" );
|
||||
player ControlsLinkTo( rocket );
|
||||
player VisionSetMissilecamForPlayer( "default", delayTime );
|
||||
player thread set_visionset_for_watching_players( "default", delayTime, undefined, true );
|
||||
|
||||
player VisionSetMissilecamForPlayer( game["thermal_vision"], 1.0 );
|
||||
player thread delayedFOFOverlay();
|
||||
|
||||
level thread unfreezeControls( player, delayTime );
|
||||
}
|
||||
|
||||
|
||||
delayedFOFOverlay()
|
||||
{
|
||||
self endon ( "death" );
|
||||
self endon ( "disconnect" );
|
||||
level endon ( "game_ended" );
|
||||
|
||||
maps\mp\gametypes\_hostmigration::waitLongDurationWithHostMigrationPause( 0.25 );
|
||||
|
||||
self ThermalVisionFOFOverlayOn();
|
||||
}
|
||||
|
||||
//============================================
|
||||
// unfreezeControls
|
||||
//============================================
|
||||
unfreezeControls( player, delayTime, i )
|
||||
{
|
||||
player endon( "disconnect" );
|
||||
|
||||
maps\mp\gametypes\_hostmigration::waitLongDurationWithHostMigrationPause( delayTime - 0.35 );
|
||||
|
||||
player freezeControlsWrapper( false );
|
||||
}
|
||||
|
||||
|
||||
//============================================
|
||||
// monitorDisownKillstreaks
|
||||
//============================================
|
||||
monitorDisownKillstreaks( player )
|
||||
{
|
||||
player endon( "disconnect" );
|
||||
player endon( "end_kill_streak" );
|
||||
|
||||
player waittill( "killstreak_disowned" );
|
||||
|
||||
level thread returnPlayer( player );
|
||||
}
|
||||
|
||||
|
||||
//============================================
|
||||
// monitorGameEnd
|
||||
//============================================
|
||||
monitorGameEnd( player )
|
||||
{
|
||||
player endon( "disconnect" );
|
||||
player endon( "end_kill_streak" );
|
||||
|
||||
level waittill( "game_ended" );
|
||||
|
||||
level thread returnPlayer( player );
|
||||
}
|
||||
|
||||
|
||||
//============================================
|
||||
// monitorObjectiveCamera
|
||||
//============================================
|
||||
monitorObjectiveCamera( player )
|
||||
{
|
||||
player endon( "end_kill_streak" );
|
||||
player endon( "disconnect" );
|
||||
|
||||
level waittill( "objective_cam" );
|
||||
|
||||
level thread returnPlayer( player, true );
|
||||
}
|
||||
|
||||
|
||||
//============================================
|
||||
// monitorDeath
|
||||
//============================================
|
||||
monitorDeath( killStreakEnt, mainMissile )
|
||||
{
|
||||
killStreakEnt waittill( "death" );
|
||||
maps\mp\gametypes\_hostmigration::waitTillHostMigrationDone();
|
||||
|
||||
if ( isDefined( killStreakEnt.targEffect ) )
|
||||
killStreakEnt.targEffect Delete();
|
||||
|
||||
if ( isDefined ( killStreakEnt.entityNumber ) )
|
||||
level.rockets[ killStreakEnt.entityNumber ] = undefined;
|
||||
|
||||
if ( mainMissile )
|
||||
level.remoteMissileInProgress = undefined;
|
||||
}
|
||||
|
||||
|
||||
//============================================
|
||||
// returnPlayer
|
||||
//============================================
|
||||
returnPlayer( player, instant )
|
||||
{
|
||||
if( !IsDefined(player) )
|
||||
return;
|
||||
|
||||
player SetClientOmnvar( "ui_predator_missile", 2 );
|
||||
player notify( "end_kill_streak" );
|
||||
|
||||
player freezeControlsWrapper( true );
|
||||
player ThermalVisionFOFOverlayOff();
|
||||
player ControlsUnlink();
|
||||
|
||||
if ( !isDefined( instant ) )
|
||||
maps\mp\gametypes\_hostmigration::waitLongDurationWithHostMigrationPause( 0.95 );
|
||||
|
||||
player CameraUnlink();
|
||||
player SetClientOmnvar( "ui_predator_missile", 0 );
|
||||
player clearUsingRemote();
|
||||
player _enableWeaponSwitch();
|
||||
}
|
Reference in New Issue
Block a user