etqw-sdk/base/script/vehicles/strogg_drop.script
2008-05-29 00:00:00 +00:00

288 lines
No EOL
6.5 KiB
Text

#define STROGG_DROP_ACCELERATION -1066
#define STROGG_DROP_SPEED_INITIAL -200
#define STROGG_DROP_SOUND_TIME 4
object strogg_drop {
void preinit();
void init();
void destroy();
void syncFields();
void Idle();
void OnItemChanged();
void OnTargetPosChanged();
void OnSetDeploymentParms( float deploymentItemIndex, float playerIndex, vector target, float rotation );
void vSetDeploymentParms( float deploymentItemIndex, float playerIndex, vector target, float rotation ) {
OnSetDeploymentParms( deploymentItemIndex, playerIndex, target, rotation );
}
boolean ContinueDrop();
void ClearRequest();
void SetupItem();
void SetupTrajectory();
entity item;
vector itemTargetPos;
float itemRotation;
float deployPlayerIndex;
float launchTime;
vector startPos;
boolean alwaysDrop;
boolean cancelled;
entity vGetItem() {
return item;
}
}
void strogg_drop::preinit() {
deployPlayerIndex = -1;
launchTime = -1;
cancelled = false;
}
void strogg_drop::init() {
setState( "Idle" );
}
void strogg_drop::destroy() {
ClearRequest();
}
void strogg_drop::syncFields() {
syncBroadcast( "item" );
syncBroadcast( "itemTargetPos" );
syncBroadcast( "itemRotation" );
syncBroadcast( "launchTime" );
syncCallback( "item", "OnItemChanged" );
syncCallback( "itemTargetPos", "OnTargetPosChanged" );
}
#define STROGG_DROP_PARABOLE_TIME 5
void strogg_drop::Idle() {
float height;
float flightTime;
float endTime;
float soundTime;
vector currentPos;
// FeaRog: wait for the server to synchronise the launch info through to avoid weirdness
while( launchTime < 0 ) {
sys.waitFrame();
}
playEffect( "fx_trail", "", 1 );
//
// Part 1 parabolic reentry
//
flightTime = sys.getTime() - launchTime;
while ( flightTime < STROGG_DROP_PARABOLE_TIME ) {
sys.waitFrame();
flightTime = sys.getTime() - launchTime;
if ( STROGG_DROP_PARABOLE_TIME < flightTime ) {
break;
}
currentPos_x = startPos_x;
currentPos_y = startPos_y + (STROGG_DROP_PARABOLE_TIME - flightTime) * 1000;
currentPos_z = startPos_z + sys.sqrt( (STROGG_DROP_PARABOLE_TIME - flightTime) * 1000 ) * 100;
setOrigin( currentPos );
item.setOrigin( currentPos );
}
playEffect( "fx_booster", "", false );
startSound( "snd_landfall", SND_VEHICLE_IDLE );
startSound( "snd_landfall_far", SND_VEHICLE );
soundTime = sys.getTime();
// Solve the quadratic equation for 0 (assuming height 0 is good enough an estimate for the ground height)
{
float roots = sys.solveRoots( STROGG_DROP_ACCELERATION / 2.0, STROGG_DROP_SPEED_INITIAL, startPos_z );
float time_zero;
if ( roots > 0 ) {
time_zero = sys.getRoot( 0 );
}
soundTime += time_zero - STROGG_DROP_SOUND_TIME;
}
//
// Part 2 just a linear fall
//
while ( true ) {
sys.waitFrame();
if( !ContinueDrop() ) {
// player switched teams before we've deployed
stopEffect( "fx_trail" );
stopEffect( "fx_booster" );
if ( !sys.isClient() ) {
player p = sys.getClient( deployPlayerIndex );
objManager.PlaySoundForPlayer( getKey( "snd_cancel_deploy" ), p );
}
ClearRequest();
if( !sys.isClient() ) {
item.remove();
remove();
}
return;
}
flightTime = sys.getTime() - launchTime - STROGG_DROP_PARABOLE_TIME;
height = startPos_z + ( ( STROGG_DROP_SPEED_INITIAL + ( STROGG_DROP_ACCELERATION * ( flightTime ) / 2 ) ) * flightTime );
if ( height < itemTargetPos_z ) {
setOrigin( itemTargetPos );
item.setOrigin( itemTargetPos );
break;
}
if ( sys.getTime() > soundTime ) {
// sys.print( "playsound: current(" + sys.getTime() + ")\n" );
soundTime += 10000;/// so it only plays it once
}
currentPos = startPos;
currentPos_z = height;
setOrigin( currentPos );
item.setOrigin( currentPos );
}
stopEffect( "fx_trail" );
stopEffect( "fx_booster" );
playEffect( "fx_hitground", "", false );
startSound( "snd_impact", SND_VEHICLE_IDLE );
ClearRequest();
if ( item != $null_entity ) {
sys.waitFrame();
item.setOrigin( itemTargetPos );
item.setAngles( getAngles() );
item.vOnDeploy();
}
sys.wait( 5.f );
if ( !sys.isClient() ) {
remove();
}
}
void strogg_drop::OnItemChanged() {
SetupItem();
}
void strogg_drop::OnTargetPosChanged() {
SetupTrajectory();
}
void strogg_drop::ClearRequest() {
if ( sys.isClient() ) {
return;
}
if ( deployPlayerIndex != -1 ) {
sys.clearDeployRequest( deployPlayerIndex );
deployPlayerIndex = -1;
}
}
void strogg_drop::OnSetDeploymentParms( float deploymentItemIndex, float playerIndex, vector target, float rotation ) {
deployPlayerIndex = playerIndex;
itemTargetPos = target;
itemRotation = rotation;
player p = sys.getClient( playerIndex );
item = sys.spawnType( deploymentItemIndex );
item.vSetDeployableOwner( p );
deployable_base deployable = item;
if ( deployable != $null_entity ) {
p.SetTargetingItem( item );
}
string statName = item.getKey( "stat_name" );
if ( statName != "" ) {
sys.increaseStatInt( sys.allocStatInt( statName + "_deployed" ), deployPlayerIndex, 1 );
}
launchTime = sys.getTime();
SetupTrajectory();
vector currentPos;
currentPos_x = startPos_x;
currentPos_y = startPos_y + STROGG_DROP_PARABOLE_TIME * 1000;
currentPos_z = startPos_z + sys.sqrt( STROGG_DROP_PARABOLE_TIME * 1000 ) * 100;
setOrigin( currentPos );
item.setOrigin( currentPos );
SetupItem();
}
void strogg_drop::SetupItem() {
if ( item == $null_entity ) {
return;
}
alwaysDrop = item.getIntKey( "always_drop" );
item.setOrigin( getWorldOrigin() );
item.setAngles( getAngles() );
item.setGameTeam( getGameTeam() );
item.vSetManualDeploy();
}
void strogg_drop::SetupTrajectory() {
vector worldMaxs = sys.getWorldMaxs();
startPos = itemTargetPos;
startPos_z = worldMaxs_z;
vector angles;
angles_y = itemRotation;
setAngles( angles );
}
boolean strogg_drop::ContinueDrop() {
// special cases
if ( deployPlayerIndex == -1 || alwaysDrop ) {
return true;
}
player p = sys.getClient( deployPlayerIndex );
if( getEntityAllegiance( p ) != TA_FRIEND ) {
return false;
}
if( sys.getTerritoryForPoint( itemTargetPos, getGameTeam(), 1.f, 0.f ) == $null_entity ) {
return false;
}
return !cancelled;
}
void strogg_drop::vCancelDeployForPlayer( float playerIndex ) {
if ( deployPlayerIndex == playerIndex ) {
cancelled = true;
}
}