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

514 lines
No EOL
12 KiB
Text

#define DROP_DIST '0 0 32768'
void G_Jotun_DropItem( float requestId, entity item, vector targetPos ) {
if ( sys.isClient() ) {
return;
}
sys.waitFrame();
vector dropOrigin = item.getWorldOrigin();
dropOrigin_x = targetPos_x;
dropOrigin_y = targetPos_y;
entity parachute;
vector down = dropOrigin - DROP_DIST;
float frac;
if ( item.vDropItemTrace( dropOrigin, down, item, targetPos ) ) {
if ( !item.vAllowDrop() ) {
if ( requestId != -1 ) {
sys.clearDeployRequest( requestId );
requestId = -1;
}
item.remove();
return;
}
frac = sys.getTraceFraction();
} else {
frac = sys.tracePoint( dropOrigin, down, CONTENTS_SOLID | CONTENTS_MOVEABLECLIP, item );
}
if ( frac == 1.f ) {
sys.warning( "G_Jotun_DropItem did not find the ground" );
}
vector finalDestinationII = sys.getTraceEndPos();
item.setComeToRest( false );
item.setGroundPosition( finalDestinationII );
item.disableKnockback();
entity traceEnt = sys.getTraceEntity();
if ( traceEnt != $null_entity && traceEnt != sys.getEntity( "worldspawn" ) ) {
item.vBindToEntity( traceEnt );
}
float parachuteDelay = item.getFloatKeyWithDefault( "parachute_deploy_delay", 3.f );
float parachuteTime = sys.getTime() + parachuteDelay;
float parachuteZ = finalDestinationII_z + 4196;
while( 1 ) {
sys.waitFrame();
if ( item == $null_entity ) { // Gordon: map restart may have happened, or something else that removes the entity, don't want to spin forever
return;
}
vector origin = item.getWorldOrigin();
vector velocity = item.getLinearVelocity();
vector delta = origin - finalDestinationII;
if ( parachuteTime != -1 && sys.getTime() > parachuteTime && origin_z < parachuteZ ) {
// spawn a parachute on the dropped vehicle
string paraDef = item.getKeyWithDefault( "def_parachute", "round_parachute" );
if ( paraDef != "" ) {
parachute = sys.spawn( paraDef );
if ( parachute != $null_entity ) {
parachute.vSetOwner( item );
parachute.vForceStayOpen( true );
}
}
parachuteTime = -1;
if ( item.vSkipDeployDrop() ) {
break;
}
}
float count = item.entitiesInBounds( item.getAbsMins(), item.getAbsMaxs(), -1, 0 );
float index;
for ( index = 0; index < count; index++ ) {
entity other = item.getBoundsCacheEntity( index );
other.applyDamage( $null_entity, item, down, GetDamage( "damage_magog_npc_collide" ), 1.f, $null_entity ); // FIXME: Get damage decl
}
if ( delta_z <= 1 ) {
break;
}
if ( velocity_z != 0.f ) {
// drift the item towards its destination to account for error in launch origin
float estTimeToHit = sys.fabs( delta_z / velocity_z );
vector newVelocity = delta * ( velocity_z / delta_z );
newVelocity_z = velocity_z;
item.setLinearVelocity( newVelocity );
}
}
item.enableKnockback();
if ( parachute != $null_entity ) {
parachute.vForceStayOpen( false );
}
if ( requestId != -1 ) {
sys.clearDeployRequest( requestId );
requestId = -1;
}
if ( item != $null_entity ) {
item.vOnDeploy();
item = $null_entity;
}
}
object vehicle_jotun {
void preinit();
void init();
void destroy();
void syncFields();
// states
void Deliver();
void Drop();
void Return();
// callbacks
void OnSetDeploymentParms( float deploymentItemIndex, float playerIndex, vector target, float rotation );
void OnKilled( entity inflictor, entity attacker, float damage, vector direction, float location );
void ClearRequest();
void OnItemChanged();
void OnStartTimeChanged();
// utility
void DoSound();
void SetupCommandMap();
boolean PerformDrop();
// virtuals
boolean vIgnoreMagogCollsion();
// threads
void KillAllInBoundingBox();
// deployment stuff
float deployIndex;
float deployPlayerIndex;
float itemIndex;
entity item;
vector targetPos;
float itemRotation;
float startTime;
float dropTime;
float returnTime;
vector gdfCorner;
float deliveryPathLength;
float returnPathLength;
// local data
float maxHealth;
float damageIndex;
boolean cancelDrop;
boolean dropped;
boolean playedFlyBySound;
boolean playingFlySound;
float flyOverSoundRange;
};
void vehicle_jotun::SetupCommandMap() {
}
void vehicle_jotun::syncFields() {
syncBroadcast( "item" );
syncBroadcast( "dropTime" );
syncBroadcast( "returnTime" );
syncBroadcast( "targetPos" );
syncBroadcast( "itemRotation" );
syncBroadcast( "gdfCorner" );
syncBroadcast( "startTime" );
syncCallback( "item", "OnItemChanged" );
syncCallback( "startTime", "OnStartTimeChanged" );
}
void vehicle_jotun::OnItemChanged() {
}
void vehicle_jotun::OnStartTimeChanged() {
if ( startTime != -1 ) {
setState( "Deliver" );
}
}
void vehicle_jotun::preinit() {
deployPlayerIndex = -1;
startTime = -1;
dropTime = -1;
returnTime = -1;
maxHealth = getFloatKey( "health" );
SetupCommandMap();
float damageDeclIndex = sys.getDeclType( "damageDef" );
damageIndex = sys.getDeclIndex( damageDeclIndex, getKey( "dmg_drop_damage" ) );
gdfCorner = '0 0 0';
cancelDrop = false;
dropped = false;
playedFlyBySound = false;
playingFlySound = false;
flyOverSoundRange = getFloatKey( "flyover_sndrange" );
flyOverSoundRange = flyOverSoundRange * flyOverSoundRange;
setCoverage( 0.f );
disableKnockback();
hide();
}
void vehicle_jotun::init() {
thread KillAllInBoundingBox();
}
void vehicle_jotun::ClearRequest() {
if ( sys.isClient() ) {
return;
}
if ( deployPlayerIndex != -1 ) {
sys.clearDeployRequest( deployPlayerIndex );
deployPlayerIndex = -1;
}
}
void vehicle_jotun::destroy() {
sys.killThread( "KillAllInBoundingBox_" + getName() );
ClearRequest();
}
#define JOTUN_FLY_HEIGHT 4096
void vehicle_jotun::Deliver() {
show();
if ( !sys.isClient() ) {
startTime = sys.getTime();
gdfCorner = objManager.GetGDFBasePosition();
}
float pathSpeed = getFloatKeyWithDefault( "path_speed", 1024 );
string pathType = getKey( "path_type" );
// find the delivery path & level it out
pathFind( pathType, targetPos, startTime, 1.0f, gdfCorner_x, gdfCorner_y, 256.0f, false );
pathLevel( 13, -1, -1 );
float numPoints = pathGetNumPoints();
if ( numPoints < 2 ) {
return;
}
deliveryPathLength = pathGetLength();
// get the return path & level that out
pathFind( pathType, targetPos, startTime + deliveryPathLength / pathSpeed, -1.0f, gdfCorner_x, gdfCorner_y, 1024.0f, true );
float newNumPoints = pathGetNumPoints();
pathLevel( 13, numPoints - 1, newNumPoints - 1 );
returnPathLength = pathGetLength() - deliveryPathLength;
float pathLength = deliveryPathLength;
float leadTime = 2.0f;
vector flyOffset = '0 0 0';
flyOffset_z = JOTUN_FLY_HEIGHT;
// setup the start
vector startPoint = pathGetPoint( 0 ) + flyOffset;
vector endPoint = pathGetPoint( numPoints - 1 ) + flyOffset;
vector startDir = sys.vecNormalize( endPoint - startPoint );
vector startAngles = sys.vecToAngles( startDir );
setWorldOrigin( startPoint );
setAngles( startAngles );
startJotunDelivery( startTime, pathSpeed, leadTime );
float minDistance = 9999999999.0f;
float coverage = 0.f;
while ( true ) {
float time = sys.getTime() - startTime;
float frameTime = sys.getFrameTime();
setCoverage( coverage );
coverage = coverage + frameTime;
//sys.debugCircle( '1 0 0', startPoint, '0 0 1', 256.0f, 16, 0 );
//sys.debugCircle( '1 0 0', endPoint, '0 0 1', 128.0f, 16, 0 );
float aheadPosition = ( time + leadTime )* pathSpeed;
DoSound();
if ( !sys.isClient() ) {
vector origin = getWorldOrigin();
vector delta = origin - endPoint;
delta_z = 0.0f;
float distance = sys.vecLength( delta );
if ( distance < minDistance ) {
minDistance = distance;
} else if ( aheadPosition > pathLength ) {
Drop();
}
} else if ( returnTime != -1 ) {
setState( "Return" );
}
if ( cancelDrop ) {
ClearRequest();
setState( "Return" );
}
sys.waitFrame();
}
}
void vehicle_jotun::Drop() {
player p = sys.getClient( deployPlayerIndex );
item = sys.spawnType( itemIndex );
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 );
}
if( PerformDrop() ) {
vector temp = getWorldOrigin();
vector angles;
angles_y = itemRotation;
item.setOrigin( temp - ( g_vectorDown * 256 ) );
item.setAngles( angles );
item.setGameTeam( getGameTeam() );
item.vSetManualDeploy();
thread G_Jotun_DropItem( deployPlayerIndex, item, targetPos );
} else {
item.remove();
ClearRequest();
}
deployPlayerIndex = -1;
dropped = true;
setState( "Return" );
}
void vehicle_jotun::Return() {
if ( !sys.isClient() ) {
returnTime = sys.getTime();
} else {
while ( returnTime == -1 ) {
sys.waitFrame();
}
}
float numPoints = pathGetNumPoints();
if ( numPoints < 2 ) {
return;
}
float pathSpeed = getFloatKeyWithDefault( "path_speed", 1024 );
float pathLength = returnPathLength;
float leadTime = 2.0f;
vector flyOffset = '0 0 0';
flyOffset_z = JOTUN_FLY_HEIGHT;
vector endPoint = pathGetPoint( numPoints - 1 ) + flyOffset;
startJotunReturn( returnTime, pathSpeed, leadTime );
while ( true ) {
DoSound();
float time = sys.getTime() - returnTime;
float position = time * pathSpeed;
setCoverage( ( pathLength - 1 - position ) / pathSpeed );
if ( !sys.isClient() ) {
if ( position > pathLength ) {
remove();
}
}
sys.waitFrame();
}
}
void vehicle_jotun::DoSound() {
if( !playingFlySound ) {
playingFlySound = true;
fadeSound( SND_VEHICLE_IDLE, -60.f, 0.f );
startSound( "snd_flyby_far", SND_VEHICLE_IDLE );
fadeSound( SND_VEHICLE_IDLE, 0.f, 2.f );
}
// check distance to local player
if( !playedFlyBySound ) {
entity p = sys.getLocalPlayer();
if( p != $null_entity ) {
vector playerOrigin = p.getWorldOrigin();
playerOrigin -= getWorldOrigin();
playerOrigin_z = 0.f;
if( sys.vecLengthSquared( playerOrigin ) < flyOverSoundRange ) {
sys.startSoundDirect( getKey( "snd_flyby" ), SND_VEHICLE_IDLE );
playedFlyBySound = true;
}
}
}
}
void vehicle_jotun::OnSetDeploymentParms( float deploymentItemIndex, float playerIndex, vector target, float rotation ) {
deployPlayerIndex = playerIndex;
targetPos = target;
itemRotation = sys.angleNormalize180( rotation );
itemIndex = deploymentItemIndex;
if( !PerformDrop() ) {
// player has switched sides since calling in the deployable
ClearRequest();
remove();
return;
}
player p = sys.getClient( playerIndex );
setState( "Deliver" );
}
void vehicle_jotun::OnKilled( entity inflictor, entity attacker, float damage, vector direction, float location ) {
}
void vehicle_jotun::KillAllInBoundingBox() {
sys.threadName( "KillAllInBoundingBox_" + getName() );
sys.wait( 3 );
eachFrame {
vector mins = getAbsMins();
vector maxs = getAbsMaxs();
// sys.debugBounds( '1 1 1', mins, maxs, 0.f );
float count = entitiesInBounds( mins, maxs, MASK_ALL, 1 );
count = filterEntitiesByClass( "sdTransport", 1 );
float i;
for( i = 0; i < count; i++ ) {
entity ent = getBoundsCacheEntity( i );
if( ent == self || ent == item || ent == $null_entity ) {
continue;
}
if( !ent.vIgnoreMagogCollsion() ) {
ent.applyDamage( $null_entity, self, '0 1 0', GetDamage( "damage_magog_npc_collide" ), 60000.f, $null_entity );
}
}
}
}
boolean vehicle_jotun::vIgnoreMagogCollsion() {
return true;
}
boolean vehicle_jotun::PerformDrop() {
return true;
}
void vehicle_jotun::vCancelDeployForPlayer( float playerIndex ) {
if ( playerIndex != deployPlayerIndex ) {
return;
}
// deployables already gone
if ( dropped ) {
return;
}
player p = sys.getClient( deployPlayerIndex );
objManager.PlaySoundForPlayer( getKey( "snd_cancel_deploy" ), p );
ClearRequest();
setState( "Return" );
}