288 lines
6.3 KiB
Text
288 lines
6.3 KiB
Text
|
|
object deployable_antiarmour : deployable_turret {
|
|
boolean TargetIsValid( entity targetEnt );
|
|
|
|
entity OnAcquireTarget();
|
|
|
|
void OnSetTarget( entity oldTarget, entity newTarget );
|
|
|
|
void preinit();
|
|
void syncFields();
|
|
|
|
void OnPostDamage( entity attacker, float oldHealth, float newHealth );
|
|
void CheckRetribution( entity attacker );
|
|
|
|
void OnFullChargeTimeChanged();
|
|
|
|
boolean CanFire();
|
|
void Fired();
|
|
|
|
void FireMissile();
|
|
|
|
void UpdateCharge();
|
|
|
|
boolean TraceCheck( entity other );
|
|
|
|
float fullChargeTime;
|
|
float chargeTime;
|
|
float chargePerShot;
|
|
|
|
float projectileIndexDumb;
|
|
|
|
float numMuzzleJoints;
|
|
|
|
boolean updateChargeThreadActive;
|
|
}
|
|
|
|
void deployable_antiarmour::preinit() {
|
|
fullChargeTime = -1;
|
|
chargeTime = getFloatKeyWithDefault( "charge_time", 10 );
|
|
chargePerShot = getFloatKeyWithDefault( "charge_per_shot", 0.7 );
|
|
|
|
projectileIndexDumb = GetEntityDef( getKey( "def_projectile_dumb" ) );
|
|
|
|
numMuzzleJoints = getFloatKey( "num_muzzlejoints" );
|
|
}
|
|
|
|
void deployable_antiarmour::syncFields() {
|
|
syncBroadcast( "fullChargeTime" );
|
|
syncCallback( "fullChargeTime", "OnFullChargeTimeChanged" );
|
|
}
|
|
|
|
void deployable_antiarmour::OnFullChargeTimeChanged() {
|
|
if ( !updateChargeThreadActive ) {
|
|
if ( myUser.isLocalPlayer() ) {
|
|
thread UpdateCharge();
|
|
}
|
|
}
|
|
}
|
|
|
|
void deployable_antiarmour::CheckRetribution( entity attacker ) {
|
|
player testPlayer = attacker;
|
|
if ( testPlayer == $null_entity ) {
|
|
return;
|
|
}
|
|
|
|
entity vehicle = testPlayer.getVehicle();
|
|
if ( vehicle == $null_entity ) {
|
|
return;
|
|
}
|
|
|
|
if ( !TargetIsValid( vehicle ) ) {
|
|
return;
|
|
}
|
|
|
|
if ( !InRange( attacker.getWorldOrigin() ) ) {
|
|
return;
|
|
}
|
|
|
|
setTurretEnemy( vehicle, retributionDelay );
|
|
}
|
|
|
|
void deployable_antiarmour::OnPostDamage( entity attacker, float oldHealth, float newHealth ) {
|
|
boolean oldDisabled = disabledState;
|
|
UpdateState( newHealth );
|
|
|
|
if ( !isDisabled() ) {
|
|
if ( getEnemy() == $null_entity && newHealth < oldHealth ) {
|
|
CheckRetribution( attacker );
|
|
}
|
|
}
|
|
|
|
UpdateDisabledStats( attacker, oldDisabled );
|
|
}
|
|
|
|
boolean deployable_antiarmour::TargetIsValid( entity targetEnt ) {
|
|
if ( targetEnt.vTargetLockDisabled() ) {
|
|
return false;
|
|
}
|
|
|
|
if ( targetEnt.getHealth() <= 0 ) {
|
|
return false;
|
|
}
|
|
|
|
if ( getEntityAllegiance( targetEnt ) != TA_ENEMY ) {
|
|
return false;
|
|
}
|
|
|
|
if ( !TraceCheck( targetEnt ) ) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
boolean deployable_antiarmour::TraceCheck( entity other ) {
|
|
vector targetPos = getTargetPosition( other );
|
|
|
|
sys.tracePoint( getWorldOrigin() + traceCheckOffset, targetPos, checkMask, self );
|
|
if ( sys.getTraceFraction() == 1.f ) {
|
|
return true;
|
|
}
|
|
|
|
entity traceEnt = sys.getTraceEntity();
|
|
|
|
player traceEntPlayer = traceEnt;
|
|
if ( traceEntPlayer != $null_entity ) {
|
|
traceEnt = traceEntPlayer.getProxyEntity();
|
|
}
|
|
|
|
if ( traceEnt != other ) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
entity deployable_antiarmour::OnAcquireTarget() {
|
|
if ( !finishedDeploying ) {
|
|
return $null_entity;
|
|
}
|
|
|
|
float i;
|
|
float count;
|
|
entity ent;
|
|
entity targetingRangeEnt;
|
|
vector targetDir;
|
|
vector selfDir;
|
|
|
|
entitiesOfCollection( "antivehicle" );
|
|
filterEntitiesByAllegiance( TA_FLAG_ENEMY, 1 );
|
|
filterEntitiesByRadius( getWorldOrigin(), maxRange, 1 );
|
|
|
|
selfDir = getWorldAxis( 0 );
|
|
selfDir_z = 0;
|
|
|
|
count = getBoundsCacheCount();
|
|
for ( i = 0; i < count; i++ ) {
|
|
ent = getBoundsCacheEntity( i );
|
|
|
|
targetDir = sys.vecNormalize( ent.getWorldOrigin() - getWorldOrigin() );
|
|
targetDir_z = 0;
|
|
|
|
if ( targetDir * selfDir < angleRange ) {
|
|
continue;
|
|
}
|
|
|
|
if ( !TargetIsValid( ent ) ) {
|
|
continue;
|
|
}
|
|
|
|
if ( !InRange( ent.getWorldOrigin() ) ) {
|
|
continue;
|
|
}
|
|
if ( InFiringRange( ent.getWorldOrigin() ) ) {
|
|
return ent;
|
|
}
|
|
|
|
if ( targetingRangeEnt == $null_entity ) {
|
|
targetingRangeEnt = ent;
|
|
}
|
|
}
|
|
|
|
return targetingRangeEnt;
|
|
}
|
|
|
|
void deployable_antiarmour::OnSetTarget( entity oldTarget, entity newTarget ) {
|
|
if ( oldTarget != $null_entity ) {
|
|
oldTarget.vStopTargetLockAlarm( self );
|
|
}
|
|
|
|
if ( newTarget != $null_entity ) {
|
|
newTarget.vTargetLockAlarm( self );
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void deployable_antiarmour::UpdateCharge() {
|
|
sys.assert( false );
|
|
|
|
updateChargeThreadActive = true;
|
|
|
|
while ( true ) {
|
|
if ( !myUser.isLocalPlayer() ) {
|
|
break;
|
|
}
|
|
|
|
float chargeAmount = ( chargeTime - ( fullChargeTime - sys.getTime() ) ) / chargeTime;
|
|
if ( chargeAmount > 1 ) {
|
|
chargeAmount = 1;
|
|
}
|
|
|
|
sys.setGUIFloat( GUI_GLOBALS_HANDLE, "weapons.energyBarCharge", chargeAmount );
|
|
sys.setGUIFloat( GUI_GLOBALS_HANDLE, "weapons.energyAvailable", CanFire() );
|
|
|
|
if ( chargeAmount == 1.f ) {
|
|
break;
|
|
}
|
|
|
|
sys.waitFrame();
|
|
}
|
|
|
|
updateChargeThreadActive = false;
|
|
}
|
|
|
|
boolean deployable_antiarmour::CanFire() {
|
|
if ( myUser == $null_entity ) {
|
|
return true;
|
|
}
|
|
|
|
float chargeAmount = ( chargeTime - ( fullChargeTime - sys.getTime() ) ) / chargeTime;
|
|
if ( chargeAmount >= chargePerShot ) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void deployable_antiarmour::Fired() {
|
|
if ( myUser == $null_entity ) {
|
|
return;
|
|
}
|
|
|
|
if ( !sys.isClient() ) {
|
|
if ( fullChargeTime < sys.getTime() ) {
|
|
fullChargeTime = sys.getTime();
|
|
}
|
|
fullChargeTime = fullChargeTime + ( chargeTime * chargePerShot );
|
|
}
|
|
|
|
if ( !updateChargeThreadActive ) {
|
|
if ( myUser.isLocalPlayer() ) {
|
|
thread UpdateCharge();
|
|
}
|
|
}
|
|
}
|
|
|
|
void deployable_antiarmour::FireMissile() {
|
|
entity target;
|
|
entity controller = myUser;
|
|
if ( controller != $null_entity ) {
|
|
target = controller.getEnemy();
|
|
} else {
|
|
if ( owner != $null_entity ) {
|
|
controller = owner;
|
|
} else {
|
|
controller = self;
|
|
}
|
|
target = getEnemy();
|
|
}
|
|
|
|
float pIndex;
|
|
if ( target == $null_entity && projectileIndexDumb != -1 ) {
|
|
pIndex = projectileIndexDumb;
|
|
} else {
|
|
pIndex = projectileIndex;
|
|
}
|
|
|
|
float muzzleJointIndex = int( sys.random( numMuzzleJoints ) ) + 1;
|
|
float muzzleJoint = getJointHandle( getKey( "joint_muzzle" + muzzleJointIndex ) );
|
|
|
|
launchMissileSimple( controller, self, target, pIndex, -1, spread, getJointPos( muzzleJoint ), getJointAxis( muzzleJoint, 0 ) * projectileSpeed );
|
|
playJointEffect( "fx_fire", muzzleJoint, 0 );
|
|
playAnim( ANIMCHANNEL_ALL, "fire" );
|
|
|
|
Fired();
|
|
}
|