111 lines
2.8 KiB
Text
111 lines
2.8 KiB
Text
|
/***********************************************************************
|
||
|
|
||
|
projectile_homingmissile.script
|
||
|
|
||
|
***********************************************************************/
|
||
|
|
||
|
object projectile_homingmissile : projectile_missile {
|
||
|
void preinit();
|
||
|
void init();
|
||
|
void Idle();
|
||
|
void destroy();
|
||
|
void OnSetEnemy( entity oldEnemy, entity newEnemy );
|
||
|
void UpdateFocusedTargeting();
|
||
|
void vSetNewTarget( entity newTarget );
|
||
|
entity vGetCurrentTarget();
|
||
|
|
||
|
void OnUpdateTargeting();
|
||
|
void OnThrustStarted();
|
||
|
|
||
|
void syncFields();
|
||
|
|
||
|
float spawnTime;
|
||
|
};
|
||
|
|
||
|
void projectile_homingmissile::OnThrustStarted() {
|
||
|
playEffect( "fx_trail", "", 1 );
|
||
|
startSound( "snd_fly", SND_WEAPON_FIRE );
|
||
|
}
|
||
|
|
||
|
void projectile_homingmissile::preinit() {
|
||
|
if ( !sys.isClient() ) {
|
||
|
spawnTime = sys.getTime();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void projectile_homingmissile::syncFields() {
|
||
|
syncBroadcast( "spawnTime" );
|
||
|
}
|
||
|
|
||
|
void projectile_homingmissile::init() {
|
||
|
SetupContents();
|
||
|
|
||
|
setState( "Idle" );
|
||
|
}
|
||
|
|
||
|
void projectile_homingmissile::destroy() {
|
||
|
setEnemy( $null_entity );
|
||
|
}
|
||
|
|
||
|
void projectile_homingmissile::Idle() {
|
||
|
startSound( "snd_release", SND_WEAPON_BRASS );
|
||
|
}
|
||
|
|
||
|
void projectile_homingmissile::OnSetEnemy( entity oldEnemy, entity newEnemy ) {
|
||
|
if ( oldEnemy != $null_entity ) {
|
||
|
oldEnemy.vStopTargetLockAlarm( self );
|
||
|
}
|
||
|
|
||
|
if ( newEnemy != $null_entity ) {
|
||
|
newEnemy.vTargetLockAlarm( self );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void projectile_homingmissile::UpdateFocusedTargeting() {
|
||
|
}
|
||
|
|
||
|
void projectile_homingmissile::OnUpdateTargeting() {
|
||
|
entity enemy = getEnemy();
|
||
|
|
||
|
vector enemyOrg;
|
||
|
vector dir;
|
||
|
|
||
|
if ( enemy == $null_entity ) {
|
||
|
UpdateFocusedTargeting();
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
vector absMins = enemy.getVectorKeyWithDefault( "selection_mins", enemy.getMins() );
|
||
|
vector absMaxs = enemy.getVectorKeyWithDefault( "selection_maxs", enemy.getMaxs() );
|
||
|
absMins = sys.toWorldSpace( absMins, enemy );
|
||
|
absMaxs = sys.toWorldSpace( absMaxs, enemy );
|
||
|
enemyOrg = ( absMins + absMaxs ) * 0.5f ;
|
||
|
|
||
|
// lead ahead of the enemy a bit - calculate the time it'll take to get there and adjust
|
||
|
vector myCurrentVel = getLinearVelocity();
|
||
|
float myCurrentSpeed = sys.vecLength( myCurrentVel );
|
||
|
vector delta = enemyOrg - getWorldOrigin(); // adjust for own origin
|
||
|
float distance = sys.vecLength( delta );
|
||
|
float approxClosingTime = 1;
|
||
|
if ( myCurrentSpeed > 0.0001f ) {
|
||
|
approxClosingTime = distance / myCurrentSpeed;
|
||
|
}
|
||
|
|
||
|
// estimate where the enemy will be at that time
|
||
|
vector enemyCurrentVel = enemy.getLinearVelocity();
|
||
|
enemyOrg += enemyCurrentVel * approxClosingTime;
|
||
|
|
||
|
delta = enemyOrg - getWorldOrigin();
|
||
|
dir = sys.vecNormalize( delta );
|
||
|
|
||
|
turnTowards( dir, 180.f );
|
||
|
}
|
||
|
|
||
|
void projectile_homingmissile::vSetNewTarget( entity newTarget ) {
|
||
|
setEnemy( newTarget );
|
||
|
}
|
||
|
|
||
|
entity projectile_homingmissile::vGetCurrentTarget() {
|
||
|
return getEnemy();
|
||
|
}
|