481 lines
9.4 KiB
Text
481 lines
9.4 KiB
Text
|
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();
|
||
|
}
|
||
|
}
|
||
|
|