etqw-sdk/base/script/deployables/ssm.script

409 lines
8.8 KiB
Plaintext
Raw Permalink Normal View History

2008-05-29 00:00:00 +00:00
object deployable_ssm : deployable_base {
void init();
void preinit();
void syncFields();
void destroy();
void Idle();
void Ready();
void Launch();
void Reloading();
void CheckReload();
void CheckLaunch();
boolean vTargetPlayerEligible( entity p );
boolean vTargetGetValid( vector pos );
void vTargetSetTarget( vector targetPos, entity targetEnt );
void vDoneDeploy();
void vOnDeploy();
boolean CalcFiringVelocity( vector targetPos, vector launchPos );
void PlayRaiseAnim();
void PlayLowerAnim();
void MissileCheck();
void OnMissileChanged();
void OnKilled( entity inflictor, entity attacker, float damage, vector direction, float location );
void ClearFiringDecal();
void CreateFiringDecal();
target_marker vCreateTargetMarker();
float vGetFireSupportMode();
float projectileIndex;
float launchJoint;
float sync_reloadTime;
float reloadTime;
boolean hasTarget;
vector target;
entity targetEntity;
void vStartMagogDrop();
void StartBarrelUpdateThread();
void BarrelUpdateThread();
void OnBarrelChanged();
entity barrelEntity;
boolean barrelThreadActive;
boolean dropping;
float targetHeight;
vector firingVelocity;
entity missile;
boolean missileActive;
generic_target_marker firingDecal;
entity firingMarker;
}
void deployable_ssm::syncFields() {
syncBroadcast( "sync_reloadTime" );
syncBroadcast( "hasTarget" );
syncBroadcast( "target" );
syncBroadcast( "missile" );
syncBroadcast( "barrelEntity" );
syncCallback( "missile", "OnMissileChanged" );
syncCallback( "barrelEntity", "OnBarrelChanged" );
}
float deployable_ssm::vGetFireSupportMode() {
return TARGET_SSM;
}
void deployable_ssm::preinit() {
float entityDeclIndex;
reloadTime = getFloatKey( "reload_time" );
sync_reloadTime = 0;
hasTarget = false;
launchJoint = getJointHandle( getKey( "joint_launch" ) );
targetHeight = getFloatKey( "target_height" );
entityDeclIndex = sys.getDeclType( "entityDef" );
projectileIndex = sys.getDeclIndex( entityDeclIndex, getKey( "def_projectile" ) );
fsStatus = new fireSupportStatus;
if ( !sys.isClient() ) {
thread MissileCheck();
}
}
void deployable_ssm::init() {
if ( !sys.isClient() ) {
// HACK: barrel clip
barrelEntity = sys.spawn( getKey( "def_barrel_clip" ) );
OnBarrelChanged();
}
setState( "Idle" );
}
void deployable_ssm::OnBarrelChanged() {
float barrelJoint = getJointHandle( "barrel_base" );
if ( barrelJoint != INVALID_JOINT ) {
vector org = getJointPos( barrelJoint );
vector ang = getJointAngle( barrelJoint );
barrelEntity.setContents( CONTENTS_PLAYERCLIP | CONTENTS_VEHICLECLIP | CONTENTS_FLYERHIVECLIP );
barrelEntity.unbind();
barrelEntity.setOrigin( org );
barrelEntity.setAngles( ang );
barrelEntity.bindToJoint( self, "barrel_base", 1 );
}
}
void deployable_ssm::StartBarrelUpdateThread() {
if ( barrelThreadActive ) {
return;
}
barrelThreadActive = true;
thread BarrelUpdateThread();
}
void deployable_ssm::BarrelUpdateThread() {
float damageIndex = GetDamage( getKey( "dmg_crush" ) );
vector mins = barrelEntity.getMins();
vector maxs = barrelEntity.getMaxs();
while ( isAnimating() || dropping ) {
barrelEntity.forceRunPhysics();
if ( !sys.isClient() ) {
LocalBoundsDamage( mins, maxs, barrelEntity, self, damageIndex );
}
sys.waitFrame();
}
barrelThreadActive = false;
}
void deployable_ssm::vStartMagogDrop() {
dropping = true;
StartBarrelUpdateThread();
}
void deployable_ssm::vOnDeploy() {
dropping = false;
thread DoDeploy();
}
void deployable_ssm::destroy() {
delete fsStatus;
if ( !sys.isClient() && barrelEntity != $null_entity ) {
barrelEntity.remove();
}
ClearFiringDecal();
}
void deployable_ssm::OnKilled( entity inflictor, entity attacker, float damage, vector direction, float location ) {
if ( !sys.isClient() && barrelEntity != $null_entity ) {
barrelEntity.remove();
}
DeployableBase_OnKilled( attacker, inflictor );
}
void deployable_ssm::Idle() {
}
void deployable_ssm::OnMissileChanged() {
if ( missile != $null_entity ) {
CreateFiringDecal();
} else {
ClearFiringDecal();
}
}
void deployable_ssm::vDoneDeploy() {
PlayRaiseAnim();
SetDeployingFinished();
setState( "Ready" );
}
void deployable_ssm::Ready() {
hasTarget = false;
fireSupportState = MPS_READY;
while( 1 ) {
CheckLaunch();
CheckReload();
sys.waitFrame();
}
}
void deployable_ssm::MissileCheck() {
while ( true ) {
if ( missile != $null_entity ) {
missileActive = true;
} else {
if ( missileActive ) {
missileActive = false;
ClearFiringDecal();
}
}
sys.waitFrame();
}
}
void deployable_ssm::CheckLaunch() {
if( hasTarget ) {
setState( "Launch" );
}
}
void deployable_ssm::CheckReload() {
if ( sys.getTime() < sync_reloadTime ) {
setState( "Reloading" );
}
}
boolean deployable_ssm::CalcFiringVelocity( vector targetPos, vector launchPos ) {
vector targetDiff = targetPos - launchPos;
firingVelocity_x = 0;
firingVelocity_y = 0;
firingVelocity_z = sys.sqrt( 2 * 400 * targetHeight );
float upTime = firingVelocity_z / 400;
float downTime = ( 2 * ( targetDiff_z - targetHeight ) ) / -400;
if ( downTime < 0.f ) {
return false;
}
downTime = sys.sqrt( downTime );
float t1 = upTime + downTime;
vector temp = targetDiff;
temp_z = 0.f;
targetDiff = sys.vecNormalize( temp );
float diffX = sys.vecLength( temp );
firingVelocity = firingVelocity + ( ( diffX / t1 ) * targetDiff );
return true;
}
void deployable_ssm::Launch() {
CreateFiringDecal();
vector missilePos;
string anim;
float channel;
fireSupportState = MPS_FIRING;
missilePos = getJointPos( launchJoint );
if ( CalcFiringVelocity( target, missilePos ) ) {
if( !sys.isClient() ) {
missile = launchMissileSimple( owner, self, $null_entity, projectileIndex, -1, 0.f, missilePos, firingVelocity );
missile.vSetNewTarget( targetEntity );
}
} else {
ClearFiringDecal();
}
anim = getKey( "missile_anim" );
if ( anim != "" ) {
channel = getIntKey( "missile_channel" );
playAnim( channel, anim );
StartBarrelUpdateThread();
}
objManager.CPrintEvent( sys.localizeString( "game/hammer_fired" ), $null );
if ( !sys.isClient() ) {
sync_reloadTime = sys.getTime() + reloadTime;
}
sys.wait( 3 );
setState( "Reloading" );
}
void deployable_ssm::Reloading() {
boolean playAnims = currentState == DS_NORMAL;
if ( playAnims ) {
PlayLowerAnim();
}
fireSupportState = MPS_RELOADING;
while ( 1 ) {
if ( sys.getTime() > sync_reloadTime ) {
break;
}
sys.waitFrame();
}
float waitTime = getFloatKey( "stay_lowered_time" );
if( waitTime <= 0 ) {
waitTime = 15;
}
sys.wait( waitTime );
if ( playAnims && currentState == DS_NORMAL ) {
PlayRaiseAnim();
}
setState( "Ready" );
}
boolean deployable_ssm::vTargetPlayerEligible( entity p ) {
if ( disabledState || !finishedDeploying ) {
return 0.f;
}
return 1.f;
}
boolean deployable_ssm::vTargetGetValid( vector pos ) {
return true;
}
void deployable_ssm::vTargetSetTarget( vector targetPos, entity targetEnt ) {
hasTarget = true;
target = targetPos;
targetEntity = targetEnt;
Base_TargetSetTarget( targetPos, targetEnt );
}
void deployable_ssm::PlayLowerAnim() {
startSound( "snd_lower", SND_ANY );
playAnim( ANIMCHANNEL_ALL, "lowering" );
StartBarrelUpdateThread();
waitUntil( !isAnimating() );
}
void deployable_ssm::PlayRaiseAnim() {
startSound( "snd_raise", SND_ANY );
playAnim( ANIMCHANNEL_ALL, "raising" );
StartBarrelUpdateThread();
waitUntil( !isAnimating() );
}
target_marker deployable_ssm::vCreateTargetMarker() {
string entityDef = getKey( "def_marker" );
if ( entityDef == "" ) {
return $null;
}
generic_target_marker marker = new generic_target_marker;
marker.Init( self, entityDef, getKey( "mtr_marker_cm" ), getFloatKey( "cm_marker_sort" ) );
return marker;
}
void deployable_ssm::ClearFiringDecal() {
if ( firingDecal != $null_entity ) {
delete firingDecal;
}
if ( !sys.isClient() ) {
if ( firingMarker != $null_entity ) {
thread G_DelayRemoveEntity( firingMarker, 5.f );
firingMarker = $null_entity;
}
}
}
void deployable_ssm::CreateFiringDecal() {
if ( !sys.isClient() ) {
firingMarker = G_CreateFiringMarker( self, firingMarker, target );
}
entity p = sys.getLocalPlayer();
if ( p == $null_entity ) {
return;
}
if ( getEntityAllegiance( p ) != TA_FRIEND ) {
return;
}
if ( firingDecal == $null ) {
firingDecal = vCreateTargetMarker();
}
firingDecal.SetTargetPosition( target );
}