etqw-sdk/base/script/misc/parachute.script

481 lines
9.4 KiB
Plaintext

object parachute : parachute_base {
void preinit();
void init();
void destroy();
void syncFields();
void Idle();
void FindWeapon();
void RestoreWeapon();
void SetDeployStart( float t );
void OnOwnerChanged();
void OnDeployStartChanged();
entity owner;
void vSetOwner( entity o ) { owner = o; OnOwnerChanged(); }
entity vGetOwner() { return owner; }
void vCancel();
void Cancel();
float openDelay;
void vSetDelay( float time ) { openDelay = time; }
boolean forceStayOpen;
void vForceStayOpen( boolean force ) { forceStayOpen = force; }
float deployStart;
boolean collapsing;
string previousWeapon;
boolean weaponRestored;
}
void parachute::preinit() {
deployStart = -1;
hide();
}
void parachute::syncFields() {
syncBroadcast( "owner" );
syncBroadcast( "collapsing" );
syncBroadcast( "deployStart" );
syncCallback( "owner", "OnOwnerChanged" );
syncCallback( "deployStart", "OnDeployStartChanged" );
}
void parachute::OnOwnerChanged() {
setOwner( owner );
player playerOwner = owner;
if ( playerOwner != $null_entity ) {
playerOwner.binAdd( self );
}
}
void parachute::OnDeployStartChanged() {
setDeployStart( deployStart );
}
void parachute::init() {
setContents( 0 );
setClipmask( 0 );
while( owner == $null_entity ) {
sys.waitFrame();
}
setState( "Idle" );
}
void parachute::destroy() {
player playerOwner = owner;
if ( playerOwner != $null_entity ) {
playerOwner.binRemove( self );
}
RestoreWeapon();
}
void parachute::SetDeployStart( float t ) {
deployStart = t;
setDeployStart( t );
}
void parachute::FindWeapon() {
if ( !sys.isClient() ) {
previousWeapon = owner.getCurrentWeapon();
}
}
void parachute::RestoreWeapon() {
if ( weaponRestored ) {
return;
}
weaponRestored = true;
if ( !sys.isClient() ) {
player playerOwner = owner;
if ( playerOwner != $null_entity ) {
if ( previousWeapon != "" && previousWeapon != "inventory/tools/gdf_parachute" ) {
playerOwner.setWeapon( previousWeapon, 0 );
} else {
playerOwner.selectBestWeapon( false );
}
}
}
}
void parachute::Idle() {
player playerOwner = owner;
if ( playerOwner != $null_entity ) {
// change the owner's weapon
if ( openDelay > 0.0f ) {
playerOwner.setWeapon( "inventory/tools/gdf_parachute", 1 );
} else {
// find out what weapon the player has
FindWeapon();
playerOwner.setWeapon( "inventory/tools/gdf_parachute", 0 );
}
}
sys.wait( openDelay );
playAnim( ANIMCHANNEL_ALL, "deploy" );
startSound( "snd_start", SND_VEHICLE_IDLE );
entity p = owner;
vector origin;
vector angles = g_vectorZero;
if ( playerOwner != $null_entity ) {
origin = playerOwner.getWorldOrigin() + '0 0 80';
angles = owner.getViewAngles();
angles_x = 0;
angles_z = 0;
} else {
origin = sys.toWorldSpace( p.getCenterOfMass(), p );
angles = owner.getAngles();
}
setAngles( angles );
vector offset = owner.getVectorKey( "parachute_offset" );
offset = sys.rotateVecByAngles( offset, angles );
origin += offset;
setOrigin( origin );
bind( p );
show();
if ( !sys.isClient() ) {
SetDeployStart( sys.getTime() );
}
while ( 1 ) {
// HACK - force change to parachute
if ( playerOwner != $null_entity ) {
string weapon = playerOwner.getCurrentWeapon();
if ( weapon != "inventory/tools/gdf_parachute" ) {
// change the owner's weapon
if ( openDelay > 0.0f ) {
playerOwner.setWeapon( "inventory/tools/gdf_parachute", 1 );
} else {
playerOwner.setWeapon( "inventory/tools/gdf_parachute", 0 );
}
}
if ( playerOwner.getGameTeam() == $null_entity ) {
break;
}
}
if ( !isAnimating() ) {
playCycle( ANIMCHANNEL_ALL, "idle_open" );
}
if ( !sys.isClient() ) {
if ( owner == $null_entity ) {
break;
}
if ( playerOwner != $null_entity ) {
if ( playerOwner.getProxyEntity() != $null_entity ) {
break;
}
}
if ( owner.getHealth() <= 0 ) {
break;
}
if ( !forceStayOpen ) {
if ( playerOwner == $null_entity ) {
if ( isMovingTooSlow() ) {
break;
}
} else {
if ( playerOwner.AI_ONLADDER || playerOwner.AI_INWATER || playerOwner.AI_ONGROUND ) {
break;
}
}
}
}
if ( collapsing ) {
break;
}
if ( playerOwner == sys.getLocalViewPlayer() ) {
hideInLocalView();
} else {
showInLocalView();
}
sys.waitFrame();
}
vCancel();
}
void parachute::vCancel() {
player playerOwner = owner;
if ( playerOwner != $null_entity ) {
playerOwner.binRemove( self );
}
if ( !sys.isClient() ) {
SetDeployStart( -1 );
}
// collapse into a crumpled heap
collapsing = true;
startSound( "snd_stop", SND_VEHICLE_IDLE );
playAnim( ANIMCHANNEL_ALL, "compact" );
RestoreWeapon();
setState( "Cancel" );
}
void parachute::Cancel() {
waitUntil( !isAnimating() );
if ( !sys.isClient() ) {
remove();
}
}
/*
===============================================================================
Parachute cockpit
===============================================================================
*/
object tool_parachute : weapon_base {
void init();
void Idle();
};
void tool_parachute::init() {
weaponState( "Raise", 0 );
}
void tool_parachute::Idle() {
weaponReady();
enableClamp( '0 0 0' );
playCycle( ANIMCHANNEL_ALL, "idle" );
sys.wait( 0.2f );
while ( true ) {
if ( WEAPON_LOWERWEAPON ) {
weaponState( "Lower", 4 );
}
sys.waitFrame();
}
}
/*
===============================================================================
Strogg "Parachute"
===============================================================================
*/
object strogg_parachute : parachute_base {
void preinit();
void init();
void destroy();
void syncFields();
void Idle();
void CleanUp();
void OnOwnerChanged();
entity owner;
void vSetOwner( entity o ) { owner = o; OnOwnerChanged(); }
void vCancel();
void Cancel();
float openDelay;
void vSetDelay( float time ) { openDelay = time; }
boolean collapsing;
boolean cleanupApplied;
}
void strogg_parachute::preinit() {
collapsing = false;
openDelay = 0;
}
void strogg_parachute::syncFields() {
syncBroadcast( "owner" );
syncCallback( "owner", "OnOwnerChanged" );
syncBroadcast( "collapsing" );
}
void strogg_parachute::init() {
while( owner == $null_entity ) {
sys.waitFrame();
}
setState( "Idle" );
}
void strogg_parachute::destroy() {
CleanUp();
}
void strogg_parachute::CleanUp() {
if ( cleanupApplied ) {
return;
}
player playerOwner = owner;
if ( playerOwner != $null_entity ) {
playerOwner.binRemove( self );
playerOwner.disableFallingDamage( false );
}
cleanupApplied = true;
}
void strogg_parachute::OnOwnerChanged() {
player playerOwner = owner;
if ( playerOwner != $null_entity ) {
playerOwner.binAdd( self );
playerOwner.disableFallingDamage( true );
}
}
void strogg_parachute::Idle() {
player playerOwner = owner;
if ( openDelay > 0.f ) {
if ( playerOwner != $null_entity ) {
playerOwner.selectBestWeapon( true );
}
sys.wait( openDelay );
}
setContents( 0 );
if ( owner != sys.getLocalViewPlayer() || pm_thirdperson.getBoolValue() ) {
playEffect( "fx_fly", "", 1 );
}
startSound( "snd_start", SND_VEHICLE_IDLE );
float deployTime = 1.0f;
// Doesn't really need to do this I guess, but if they use a model it will work
entity p = owner;
vector origin;
vector angles = g_vectorZero;
if ( owner != $null_entity ) {
origin = playerOwner.getWorldOrigin() + '0 0 80';
angles = owner.getViewAngles();
angles_x = 0;
angles_z = 0;
} else {
origin = sys.toWorldSpace( p.getCenterOfMass(), p );
angles = owner.getAngles();
}
setAngles( angles );
vector offset = owner.getVectorKey( "parachute_offset" );
offset = sys.rotateVecByAngles( offset, angles );
origin += offset;
setOrigin( origin );
bind( p );
float maxSpeed = getFloatKey( "min_speed" );
float tooSlowTime = 0;
float deployStart = sys.getTime();
while ( 1 ) {
if ( !sys.isClient() ) {
if ( owner == $null_entity ) {
break;
}
if ( playerOwner != $null_entity ) {
if ( playerOwner.getProxyEntity() != $null_entity ) {
break;
}
}
if ( owner.getHealth() <= 0 ) {
break;
}
}
if ( collapsing ) {
break;
}
if ( owner == sys.getLocalViewPlayer() && !pm_thirdperson.getBoolValue() ) {
hide();
} else {
show();
}
// convert velocity to metric
vector velocity = InchesToMetres( p.getLinearVelocity() );
float speedSquared = sys.vecLengthSquared( velocity );
if ( velocity_z > -maxSpeed ) {
if ( !sys.isClient() ) {
if ( !tooSlowTime ) {
tooSlowTime = sys.getTime();
} else {
if ( sys.getTime() - tooSlowTime > 0.1f ) {
break;
}
}
}
}
sys.waitFrame();
}
vCancel();
}
void strogg_parachute::vCancel() {
CleanUp();
// collapse into a crumpled heap
collapsing = true;
startSound( "snd_stop", SND_VEHICLE_IDLE );
stopEffect( "fx_fly" );
setState( "Cancel" );
}
void strogg_parachute::Cancel() {
sys.wait( 1.0f );
if ( !sys.isClient() ) {
remove();
}
}