nx1-gsc-dump/maps/_chute.gsc

1307 lines
45 KiB
Plaintext

//****************************************************************************
// **
// Confidential - (C) Activision Publishing, Inc. 2010 **
// **
//****************************************************************************
// **
// Module: _chute.gsc -> Contains all the routines related with the **
// first-person parachuting experience **
// **
// Use: chute_start() starts the parachute sequence **
// chute_end() ends the parachute sequence **
// **
// Created: 10/20/2010 **
// **
//****************************************************************************
#include maps\_utility;
#include common_scripts\utility;
#include maps\_anim;
#include maps\_vehicle;
#include maps\_hud_util;
//*******************************************************************
// *
// *
//*******************************************************************
main()
{
// Internal Initialization
init_chute_variables();
chute_flag_inits();
PreCacheShellShock( "parachute_buffeting" );
// Anims
player_animations();
legs_animations();
head_animations();
//parachute bg sound
level._ambient_track [ "nx_chute_amb" ] = "ambient_parachute";
}
//*******************************************************************
// *
// SETUP *
// *
//*******************************************************************
// Setup global variables
init_chute_variables()
{
// const, don't change
level._TIMESTEP = 0.05;
// Angular properties:
level._ang_acceleration = 160.0; // deg/s^2
level._max_ang_velocity = 150.0; // deg/s
level._damping_coefficient = 2.0;
// Linear descent props:
level._descent_acceleration = 0.0; // in/s^2
level._max_descent_velocity = 1200.0; // in/s
level._min_descent_velocity = 77.0; // in/s
// Linear forward props:
level._forward_acceleration = 200.0; // in/s^2
level._max_forward_velocity = 890.0; // in/s
level._min_forward_velocity = 400.0; // in/s
level._forward_velocity = level._max_forward_velocity;
level._forward_brake_deceleration = -200.0; // in/s^2
// External forces:
level._explosion_force = 500;
level._external_acceleration = ( 0, 0, 0 );
level._external_velocity = ( 0, 0, 0 );
// Pendular props:
level._pend_speed_factor = 8.0;
level._pend_length = 480.0; // 40 ft == 480 in
level._pend_G = 1200; // 30 m/s^2 ~= 1200 in/s^2
level._pend_accel_factor = ( level._pend_G / level._max_ang_velocity ); // accel = kw, this is k
level._pend_damping = 0.15;
level._pend_brake_accel_factor = ( level._pend_G / ( level._forward_acceleration * level._TIMESTEP * level._pend_speed_factor ) );
// These should only be set to 0 for debugging purposes
level._USE_ANIMS = 1;
level._MOVE_PLAYER = 1;
// Rate for "lerping" the anims, i.e the percentage of weight change per frame.
// Valid Range: 0.05 - 1.0
level._anim_rate_in = 0.15;
level._anim_rate_out = 0.1;
level._anim_state = "idle"; // <-- valid: idle, turn, stop, falling, landing
level._idle_view_clamp = 50;
level._turn_view_clamp = 40;
level._stop_view_clamp = 40;
level._falling_view_clamp = 40;
level._landing_view_clamp = 2;
level._view_lerp_time = 0.5;
level._enable_chute_controls = 1;
level._landing_sequence = 0;
level._landing_interrupt = 0;
level._fail_sequence = 0;
level._allow_collision_death = 1;
level._collision_forgiveness_angle = 30.0;
// HUD
level._hud_chute_alpha_fade_time_ms = 1000; // ms to fade in
level._INCHES_PER_METER = 39.3700787;
level._hud_chute_altimeter_max = ( 100 * level._INCHES_PER_METER ); // 100 m in inches
// Sound variables, for turning on/off appropriate sounds
level._audio_turn_lt = 0;
level._audio_turn_rt = 0;
level._audio_braking = 0;
}
//*******************************************************************
// *
// *
//*******************************************************************
// All flag_init() calls
chute_flag_inits()
{
// These flags will be set when associated keys are pressed during gameplay (good for tutorials)
flag_init( "_chute.gsc_flag_LT_pressed" );
flag_init( "_chute.gsc_flag_RT_pressed" );
flag_init( "_chute.gsc_flag_parachute_active" );
}
//*******************************************************************
// *
// *
//*******************************************************************
#using_animtree( "player" );
player_animations()
{
level._scr_animtree[ "player_rig" ] = #animtree;
level._scr_model[ "player_rig" ] = "nx_fp_viewmodel_parachute";
level._scr_anim[ "player_rig" ][ "idle" ] = %nx_fp_viewmodel_parachute_idle;
level._scr_anim[ "player_rig" ][ "parachute_turn_r_idle" ] = %nx_fp_viewmodel_parachute_turn_r_idle;
level._scr_anim[ "player_rig" ][ "parachute_turn_l_idle" ] = %nx_fp_viewmodel_parachute_turn_l_idle;
level._scr_anim[ "player_rig" ][ "parachute_stop_idle" ] = %nx_fp_viewmodel_parachute_stop_idle;
level._scr_anim[ "player_rig" ][ "parachute_falling" ] = %nx_fp_viewmodel_parachute_falling;
level._scr_anim[ "player_rig" ][ "parachute_landing" ] = %nx_fp_viewmodel_parachute_landing;
level._scr_anim[ "player_rig" ][ "parachute_buffeting" ] = %nx_fp_viewmodel_parachute_buffeting;
level._scr_anim[ "player_rig" ][ "parachute_buffeting_2" ] = %nx_fp_viewmodel_parachute_buffeting_2;
level._scr_anim[ "player_rig" ][ "parachute_bump" ] = %nx_fp_viewmodel_parachute_bump;
}
//*******************************************************************
// *
// *
//*******************************************************************
#using_animtree( "player" );
legs_animations()
{
level._scr_animtree[ "legs" ] = #animtree;
level._scr_model[ "legs" ] = "nx_us_specops_body_assault_a";
level._scr_anim[ "legs" ][ "idle" ] = %nx_tp_parachute_idle;
level._scr_anim[ "legs" ][ "parachute_turn_r_idle" ] = %nx_tp_parachute_turn_r_idle;
level._scr_anim[ "legs" ][ "parachute_turn_l_idle" ] = %nx_tp_parachute_turn_l_idle;
level._scr_anim[ "legs" ][ "parachute_stop_idle" ] = %nx_tp_parachute_stop_idle;
level._scr_anim[ "legs" ][ "parachute_falling" ] = %nx_tp_parachute_falling;
level._scr_anim[ "legs" ][ "parachute_landing" ] = %nx_tp_parachute_landing;
level._scr_anim[ "legs" ][ "parachute_buffeting" ] = %nx_tp_parachute_buffeting;
level._scr_anim[ "legs" ][ "parachute_buffeting_2" ] = %nx_tp_parachute_buffeting_2;
}
//*******************************************************************
// *
// *
//*******************************************************************
#using_animtree( "player" );
head_animations()
{
level._scr_animtree[ "head" ] = #animtree;
level._scr_model[ "head" ] = "nx_head_us_army_a";
}
//*******************************************************************
// *
// MAIN FUNCTIONALITY SCRIPTS *
// *
//*******************************************************************
chute_start()
{
flag_set( "_chute.gsc_flag_parachute_active" );
parachute_player_constraints();
parachute_player_setup();
thread parachute_input_and_motion();
}
//*******************************************************************
// *
// *
//*******************************************************************
parachute_hud_bootup( skip_wait, chute_light )
{
if ( !IsDefined( skip_wait ))
{
// wait the amount of time that was taken up by the bootup movie
wait 6.0;
}
SetSavedDvar( "hud_chute_alpha_fade_time_ms", level._hud_chute_alpha_fade_time_ms );
// Calculate the altimeter maximum with various levels of resolution depending on starting altitude
player_y_in_meters = ( level._player.origin[2] / level._INCHES_PER_METER );
resolution = 25.0;
if ( player_y_in_meters < 500.0 && player_y_in_meters > 250.0 )
{
resolution = 50.0;
}
else if ( player_y_in_meters > 500.0 )
{
resolution = 100.0;
}
max_alt_meters = floor( ( player_y_in_meters + resolution ) / resolution ) * resolution;
level._hud_chute_altimeter_max = ( max_alt_meters * level._INCHES_PER_METER ); // in inches
SetSavedDvar( "hud_chute_altimeter_max", level._hud_chute_altimeter_max );
if ( !IsDefined( chute_light ))
{
SetSavedDvar( "hud_chute_active", 1 );
}
else
{
SetSavedDvar( "hud_chute_altimeter_active", 1 );
SetSavedDvar( "hud_chute_compass_active", 1 );
}
}
//*******************************************************************
// *
// *
//*******************************************************************
parachute_player_constraints()
{
level._player.disableReload = true;
level._player DisableWeapons();
level._player DisableOffhandWeapons();
level._player DisableWeaponSwitch();
level._player AllowCrouch( false );
level._player AllowJump( false );
//level._player AllowLean( false );
level._player AllowMelee( false );
level._player AllowProne( false );
level._player AllowSprint( false );
}
//*******************************************************************
// *
// *
//*******************************************************************
parachute_player_setup()
{
// Player Rig ---
player_rig = spawn_anim_model( "player_rig", level._player.origin );
level.player_rig = player_rig;
player_rig.angles = level._player.angles;
//player_rig hide();
// Play sounds
//thread maps\_utility::set_ambient( "nx_chute_amb" );
//level._player PlaySound( "parachute_deploy" );
//give player a node to play loop sounds on
level._chute_sfx = Spawn( "script_origin", level._player.origin );
level._chute_sfx LinkTo( level._player );
// Cannot animate & move via script the player rig at the same time, so spawn a tag_origin
player_mover = spawn_tag_origin();
level.player_mover = player_mover;
player_mover.origin = level._player.origin;
player_mover.angles = level._player.angles;
player_rig LinkTo( player_mover );
// This call constrains camera movement as well as linking
level._player PlayerLinkToDelta( player_rig, "tag_player", 1, level._idle_view_clamp, level._idle_view_clamp, level._idle_view_clamp, level._idle_view_clamp, true, true );
level._player SetRelinkPlayerFlag( 1 );
thread wait_and_reset_relink_player_flag();
//player_rig show();
// Legs ---
legs = spawn_anim_model( "legs", level._player.origin );
level.legs = legs;
//legs hide();
legs.angles = level._player.angles;
legs LinkTo( player_rig, "tag_origin", ( -5, 0, -5 ), ( 0, 0, 0 ) );
//legs show();
// Head ---
head = spawn_anim_model( "head", level._player GetEye() );
level.head = head;
//head hide();
head.angles = level._player.angles;
head LinkTo( player_rig, "tag_torso", ( -4, 0, -14 ), ( -90, 0, -90 ) );
//head show();
/*
player_anim_node = GetEnt( "playerstart_parachute_jump", "targetname" );
player_anim_node anim_single_solo( player_rig, "parachute_jump" );
//player_rig ClearAnim( %root, 0 );
player_rig SetAnim( level._scr_anim[ "player_rig" ][ "parachute_jump" ], 1, level._TIMESTEP, 1 );
//level._player notify( "notify_player_jump_anim_complete" );
player_rig DumpAnims();
*/
if ( level._USE_ANIMS == 1 )
{
// Begin with idle anims
level.player_rig SetAnimKnob( level._scr_anim[ "player_rig" ][ "idle" ], 1, 0, 1 );
level.legs SetAnimKnob( level._scr_anim[ "legs" ][ "idle" ], 1, 0, 1 );
// Init anim lerp vars
level.player_rig.idle_weight_curr = 1;
level.player_rig.turn_l_idle_weight_curr = 0;
level.player_rig.turn_r_idle_weight_curr = 0;
level.player_rig.stop_idle_weight_curr = 0;
level.player_rig.buffeting_weight_curr = 0;
level.player_rig.buffeting_2_weight_curr = 0;
}
}
//*******************************************************************
// *
// *
//*******************************************************************
wait_and_reset_relink_player_flag()
{
// wait a frame
wait 0.05;
// reset
level._player SetRelinkPlayerFlag( 0 );
level notify( "player_relink_complete" );
}
//*******************************************************************
// *
// *
//*******************************************************************
parachute_input_and_motion()
{
level.player_rig endon( "death" );
// Physics variables
absolute_pos = level.player_rig.origin;
absolute_angles = level.player_rig.angles;
angular_accel = 0.0;
angular_velocity = 0.0;
descent_velocity = level._min_descent_velocity;
forward_accel = level._forward_acceleration;
pendular_accel = 0.0;
pendular_omega = 0.0;
pendular_theta = 0.0;
pendular_brake_accel = 0.0;
pendular_brake_omega = 0.0;
pendular_brake_theta = 0.0;
delta_forward_velocity = 0;
external_accel = level._external_acceleration;
delta_external_velocity = ( 0, 0, 0 );
// Player input (LT/RT) will affect not only yaw, but descent speed as well
while ( 1 )
{
flag_clear( "_chute.gsc_flag_LT_pressed" );
flag_clear( "_chute.gsc_flag_RT_pressed" );
forward_accel = level._forward_acceleration;
external_accel = level._external_acceleration;
turning_left = 0;
turning_right = 0;
// Detect player button presses
if ( level._enable_chute_controls )
{
if( level._ps3 || level._xenon )
{
if ( level._player AdsButtonPressed() )
{
turning_left = 1;
}
if ( level._player AttackButtonPressed() )
{
turning_right = 1;
}
}
else // PC
{
if ( level._player ButtonPressed( "MOUSE1" ) )
{
turning_left = 1;
}
if ( level._player ButtonPressed( "MOUSE2" ) )
{
turning_right = 1;
}
}
}
if ( turning_left )
{
flag_set( "_chute.gsc_flag_LT_pressed" );
if ( turning_right )
{
flag_set( "_chute.gsc_flag_RT_pressed" );
angular_accel = 0.0;
if ( level._landing_sequence == 0 )
{
forward_accel = level._forward_brake_deceleration;
}
thread parachute_stop_anims();
if ( level._anim_state != "stop" && level._anim_state != "falling" && level._anim_state != "landing" )
{
// lerp
level._player LerpViewAngleClamp( level._view_lerp_time, level._view_lerp_time, 0, level._stop_view_clamp, level._stop_view_clamp, level._stop_view_clamp, level._stop_view_clamp );
level._anim_state = "stop";
}
if ( level._audio_turn_lt == 1 )
{
level._chute_sfx StopLoopSound( "parachute_turn_loop" );
level._audio_turn_lt = 0;
}
if ( level._audio_turn_rt == 1 )
{
level._chute_sfx StopLoopSound( "parachute_turn_loop" );
level._audio_turn_rt = 0;
}
if ( level._audio_braking == 0 )
{
level._player PlaySound( "parachute_brake" );
level._chute_sfx PlayLoopSound( "parachute_brake_loop" );
level._audio_braking = 1;
}
}
else
{
angular_accel = level._ang_acceleration;
thread parachute_L_anims();
if ( level._anim_state != "turn" && level._anim_state != "falling" && level._anim_state != "landing" )
{
// lerp
level._player LerpViewAngleClamp( level._view_lerp_time, level._view_lerp_time, 0, level._turn_view_clamp, level._turn_view_clamp, level._turn_view_clamp, level._turn_view_clamp );
level._anim_state = "turn";
}
if ( level._audio_turn_lt == 0 )
{
level._player PlaySound( "parachute_turn_lt" );
level._chute_sfx PlayLoopSound( "parachute_turn_loop" );
level._audio_turn_lt = 1;
}
if ( level._audio_braking == 1 )
{
level._chute_sfx StopLoopSound( "parachute_brake_loop" );
level._audio_braking = 0;
}
}
}
else if ( turning_right )
{
flag_set( "_chute.gsc_flag_RT_pressed" );
angular_accel = ( -1 * level._ang_acceleration );
thread parachute_R_anims();
if ( level._anim_state != "turn" && level._anim_state != "falling" && level._anim_state != "landing" )
{
// lerp
level._player LerpViewAngleClamp( level._view_lerp_time, level._view_lerp_time, 0, level._turn_view_clamp, level._turn_view_clamp, level._turn_view_clamp, level._turn_view_clamp );
level._anim_state = "turn";
}
if ( level._audio_turn_rt == 0 )
{
level._player PlaySound( "parachute_turn_rt" );
level._chute_sfx PlayLoopSound( "parachute_turn_loop" );
level._audio_turn_rt = 1;
}
if ( level._audio_braking == 1 )
{
level._chute_sfx StopLoopSound( "parachute_brake_loop" );
level._audio_braking = 0;
}
}
else // Nothing pressed, blend back to idle
{
angular_accel = 0.0;
thread parachute_idle_anims();
if ( level._anim_state != "idle" && level._anim_state != "falling" && level._anim_state != "landing" )
{
// lerp
level._player LerpViewAngleClamp( level._view_lerp_time, level._view_lerp_time, 0, level._idle_view_clamp, level._idle_view_clamp, level._idle_view_clamp, level._idle_view_clamp );
level._anim_state = "idle";
}
if ( level._audio_turn_lt == 1 )
{
level._chute_sfx StopLoopSound( "parachute_turn_loop" );
level._audio_turn_lt = 0;
}
if ( level._audio_turn_rt == 1 )
{
level._chute_sfx StopLoopSound( "parachute_turn_loop" );
level._audio_turn_rt = 0;
}
if ( level._audio_braking == 1 )
{
level._chute_sfx StopLoopSound( "parachute_brake_loop" );
level._audio_braking = 0;
}
}
// Rotational aspects ---
// w = w0 + at
angular_velocity += angular_accel * level._TIMESTEP;
// clamp angular velocity
if ( angular_velocity > level._max_ang_velocity )
{
angular_velocity = level._max_ang_velocity;
}
else if ( angular_velocity < ( -1 * level._max_ang_velocity ) )
{
angular_velocity = ( -1 * level._max_ang_velocity );
}
// air resistance (damping)
// dv = -kvdt
angular_velocity += ( ( -1 * level._damping_coefficient ) * angular_velocity * level._TIMESTEP );
// apply
absolute_angles = ( absolute_angles + ( ( 0, 1, 0 ) * angular_velocity * level._TIMESTEP ) );
// End Rotational aspects ---
// Pendular ---
// acceleration is comprised of 2 tangential components: one from linear acceleration, one from gravity
cos_theta = Cos( pendular_theta );
sin_theta = Sin( pendular_theta );
lin_accel_tan = ( ( level._pend_accel_factor * angular_velocity ) * cos_theta );
grav_tan = ( level._pend_G * sin_theta );
pendular_accel = ( ( lin_accel_tan - grav_tan ) / level._pend_length );
pendular_omega += pendular_accel * level._TIMESTEP * level._pend_speed_factor;
// damping
pendular_omega += ( ( -1 * level._pend_damping ) * pendular_omega * level._TIMESTEP * level._pend_speed_factor );
pendular_theta += pendular_omega * level._TIMESTEP * level._pend_speed_factor;
pend_offset_x = ( AnglesToRight( level.player_mover.angles ) * ( level._pend_length * ( sin_theta ) ) );
pend_offset_y = ( ( 0, 0, 1 ) * ( level._pend_length * ( 1 - cos_theta ) ) );
// pendular motion for braking
cos_brake_theta = Cos( pendular_brake_theta );
sin_brake_theta = Sin( pendular_brake_theta );
lin_brake_accel_tan = ( ( level._pend_brake_accel_factor * delta_forward_velocity ) * cos_brake_theta );
grav_brake_tan = ( level._pend_G * sin_brake_theta );
pendular_brake_accel = ( ( lin_brake_accel_tan - grav_brake_tan ) / level._pend_length );
pendular_brake_omega += pendular_brake_accel * level._TIMESTEP * level._pend_speed_factor;
// damping
pendular_brake_omega += ( ( -1 * level._pend_damping ) * pendular_brake_omega * level._TIMESTEP * level._pend_speed_factor );
pendular_brake_theta += pendular_brake_omega * level._TIMESTEP * level._pend_speed_factor;
pend_brake_offset_x = ( -1 * AnglesToForward( level.player_mover.angles ) * ( level._pend_length * ( sin_brake_theta ) ) );
pend_brake_offset_y = ( ( 0, 0, 1 ) * ( level._pend_length * ( 1 - cos_brake_theta ) ) );
// End Pendular ---
// Descent ---
// v = v0 + at
descent_velocity += level._descent_acceleration * level._TIMESTEP;
// clamp descent velocity
if ( descent_velocity > level._max_descent_velocity )
{
descent_velocity = level._max_descent_velocity;
}
else if ( descent_velocity < level._min_descent_velocity )
{
descent_velocity = level._min_descent_velocity;
}
descent_offset = ( descent_velocity * level._TIMESTEP * ( 0, 0, -1 ) );
// End Descent ---
// Forward ---
// v = v0 + at
delta_forward_velocity = forward_accel * level._TIMESTEP;
level._forward_velocity += delta_forward_velocity;
// clamp forward velocity
if ( level._forward_velocity > level._max_forward_velocity )
{
level._forward_velocity = level._max_forward_velocity;
delta_forward_velocity = 0;
}
else if ( !level._landing_sequence && level._forward_velocity < level._min_forward_velocity )
{
level._forward_velocity = level._min_forward_velocity;
delta_forward_velocity = 0;
}
else if ( level._landing_sequence && level._forward_velocity < 0 )
{
level._forward_velocity = 0.0;
delta_forward_velocity = 0;
}
forward_offset = ( AnglesToForward( absolute_angles ) * level._TIMESTEP * level._forward_velocity );
// End Forward ---
// External Forces ---
delta_external_velocity = external_accel * level._TIMESTEP;
level._external_velocity += delta_external_velocity;
external_offset = ( level._external_velocity * level._TIMESTEP );
// End External Forces ---
// Now apply movement
if ( level._MOVE_PLAYER )
{
old_pos = level.player_mover.origin;
absolute_pos += ( descent_offset + forward_offset + external_offset );
level.player_mover.angles = ( absolute_angles + ( ( 0, 0, -1 ) * pendular_theta ) + ( ( 1, 0, 0 ) * pendular_brake_theta ) );
new_pos = absolute_pos + pend_offset_x + pend_offset_y + pend_brake_offset_x + pend_brake_offset_y;
// Need to check for colliding with things (fail condition)
coll_info = PlayerPhysicsTraceExtraInfo( old_pos, new_pos );
collide_pos = coll_info["position"];
if ( !f3D_vectors_equal( collide_pos, new_pos ) )
{
//pos_delta = collide_pos - new_pos;
//absolute_pos += pos_delta;
//level.player_mover.origin = collide_pos;
//thread parachute_fail_sequence2();
//return;
// This gives collision info (normal, surface type, etc.)
//coll_info = BulletTrace( old_pos, new_pos, false, level.player_mover );
// We only want to collide with surfaces
if ( coll_info["surfacetype"] != "none" )
{
death = 0;
// Calculate the offset to not allow interpenetration
dot_result = VectorDot( collide_pos - new_pos, coll_info["normal"] );
if ( dot_result > level._collision_forgiveness_angle )
{
death = 1;
}
ip_offset = dot_result * coll_info["normal"];
resolved_pos = new_pos + ip_offset + coll_info["normal"];
// Iterate a 2nd time
coll_info_2 = PlayerPhysicsTraceExtraInfo( collide_pos, resolved_pos );
collide_pos_2 = coll_info_2["position"];
if ( !f3D_vectors_equal( collide_pos_2, resolved_pos ) )
{
// Apply offsets
//absolute_pos += ( collide_pos_2 - new_pos );
//level.player_mover.origin = collide_pos_2;
//coll_info_2 = BulletTrace( collide_pos, resolved_pos, false, level.player_mover );
if ( coll_info_2["surfacetype"] != "none" )
{
dot_result_2 = VectorDot( collide_pos_2 - resolved_pos, coll_info_2["normal"] );
ip_offset_2 = dot_result_2 * coll_info_2["normal"];
resolved_pos_2 = resolved_pos + ip_offset_2 + coll_info_2["normal"];
// Iterate a 3rd time
collide_pos_3 = PlayerPhysicsTrace( collide_pos_2, resolved_pos_2 );
if ( !f3D_vectors_equal( collide_pos_3, resolved_pos_2 ) )
{
// Apply offsets
absolute_pos += ( collide_pos_3 - new_pos );
level.player_mover.origin = collide_pos_3;
}
else
{
// Apply offsets
absolute_pos += ip_offset_2;
level.player_mover.origin = resolved_pos_2;
}
}
else
{
// Apply offsets
absolute_pos += ip_offset;
level.player_mover.origin = resolved_pos;
}
}
else
{
// Apply offsets
absolute_pos += ip_offset;
level.player_mover.origin = resolved_pos;
}
// Kick in gravity & start fail sequence
if ( !level._landing_sequence && level._allow_collision_death && death )
{
level._descent_acceleration = level._pend_G;
thread parachute_fail_sequence();
}
else if ( level._landing_sequence && death && !level._landing_interrupt )
{
thread parachute_landing_bump();
}
}
else
{
level.player_mover.origin = new_pos;
}
}
else
{
level.player_mover.origin = new_pos;
}
}
thread parachute_lerp_anims();
wait( level._TIMESTEP );
}
}
//*******************************************************************
// *
// *
//*******************************************************************
/*parachute_fail_sequence2()
{
if ( level._fail_sequence )
{
return;
}
level._fail_sequence = 1;
level._anim_state = "falling";
// Remove player control
//level._enable_chute_controls = 0;
// Death anims
//level._player shellshock( "default", 3 );
//level._USE_ANIMS = 0;
//thread parachute_falling_anims();
//level.player_rig Unlink();
//level.player_mover Delete();
level._player Unlink();
//chute_destroy_assets();
level._player SetViewmodel( "nx_fp_viewmodel_parachute" );
level._player ShowViewModel();
//thread parachute_link_to_player();
//level.player_rig.origin = level._player.origin;
//level.player_rig LinkTo( level._player );
//level._player Attach( "nx_fp_viewmodel_parachute" );
//level.player_rig thread manual_linkto( level._player );
//wait 1.5;
// Now Fail
//level._player PlaySound( "parachute_impact" );
//SetDvar( "ui_deadquote", "(PLACEHOLDER) It's Bad to Run Into Things!" );
//level notify( "notify_parachute_failure" );
//maps\_utility::missionFailedWrapper();
}
parachute_link_to_player()
{
level._player endon( "death" );
while ( 1 )
{
//thread parachute_idle_anims();
//thread parachute_lerp_anims();
wait 0.05;
}
}*/
//*******************************************************************
// *
// *
//*******************************************************************
parachute_fail_sequence( fail_message )
{
if ( level._fail_sequence )
{
return;
}
level._fail_sequence = 1;
SetSavedDvar( "hud_chute_active", 0 );
// lerp
level._player LerpViewAngleClamp( level._view_lerp_time, level._view_lerp_time, 0, level._falling_view_clamp, level._falling_view_clamp, level._falling_view_clamp, level._falling_view_clamp );
level._anim_state = "falling";
// Remove player control
level._enable_chute_controls = 0;
// Death anims
level._player shellshock( "default", 3 );
level._USE_ANIMS = 0;
thread parachute_falling_anims();
thread parachute_check_for_ground_damage();
wait 1.5;
// Now Fail
level._player PlaySound( "parachute_impact" );
if( isdefined( fail_message))
{
SetDvar( "ui_deadquote", fail_message );
}
else
{
SetDvar( "ui_deadquote", &"_CHUTE_FAIL_COLLISION" );
}
level notify( "notify_parachute_failure" );
maps\_utility::missionFailedWrapper();
}
//*******************************************************************
// *
// *
//*******************************************************************
parachute_check_for_ground_damage()
{
GROUND_CHECK_OFFSET = 4;
while ( 1 )
{
ground_pos = GetGroundPosition( level.player_mover.origin, 0, 1000.0, 64.0, true );
if ( IsDefined( ground_pos ) )
{
if ( abs( ground_pos[2] - level.player_mover.origin[2] ) < GROUND_CHECK_OFFSET )
//if ( level._player IsOnGround() ) <-- This doesn't work with player linked to object it seems
{
RadiusDamage( level._player.origin, 500, 500, 500 );
chute_destroy_assets();
return;
}
}
wait 0.05;
}
}
//*******************************************************************
// *
// *
//*******************************************************************
parachute_buffeting( explosion_origin, anim_name )
{
level._player shellshock( "parachute_buffeting", 1 );
level._USE_ANIMS = 0;
parachute_buffeting_anims( anim_name );
thread parachute_buffeting_anim_cleanup( anim_name );
// Disable all the forward physics
/*temp_forward_acceleration = level._forward_acceleration;
temp_max_forward_velocity = level._max_forward_velocity;
temp_min_forward_velocity = level._min_forward_velocity;
temp_forward_velocity = level._forward_velocity;
level._forward_acceleration = 0.0;
level._max_forward_velocity = 0.0;
level._min_forward_velocity = 0.0;
level._forward_velocity = 0.0;*/
// Disable collision death
level._allow_collision_death = 0;
// Apply push velocity
explosion_vector = ( level._player.origin - explosion_origin );
dist = Length( explosion_vector );
explosion_vector_norm = VectorNormalize( explosion_vector );
// The magic numbers here are just to get a "normalized" application force with the inverse of the distance
level._external_velocity = explosion_vector_norm * ( 1000.0 / dist ) * level._explosion_force;
// Apply damping force in opposite direction to push
level._external_acceleration = ( level._external_velocity * -0.5 );
// Wait until the push velocity is zero
EPSILON = 0.01;
while ( LengthSquared( level._external_velocity ) > EPSILON )
{
//println( Length( level._external_velocity ) );
wait 0.05;
}
// Reset external forces
level._external_velocity = ( 0, 0, 0 );
level._external_acceleration = ( 0, 0, 0 );
// Reset forward physics
/*level._forward_acceleration = temp_forward_acceleration;
level._max_forward_velocity = temp_max_forward_velocity;
level._min_forward_velocity = temp_min_forward_velocity;
//level._forward_velocity = temp_forward_velocity;*/
// Reenable collision death
level._allow_collision_death = 1;
}
//*******************************************************************
// *
// *
//*******************************************************************
parachute_buffeting_anim_cleanup( anim_name )
{
level.player_rig endon( "death" );
anim_time = 0.0;
// We need to let it play through until a certain point before turning all other anims on
if ( !IsDefined( anim_name ) || anim_name == "parachute_buffeting" )
{
anim_time = level.player_rig GetAnimTime( %nx_fp_viewmodel_parachute_buffeting );
}
else
{
anim_time = level.player_rig GetAnimTime( %nx_fp_viewmodel_parachute_buffeting_2 );
}
while ( anim_time < 0.66 )
{
if ( !IsDefined( anim_name ) || anim_name == "parachute_buffeting" )
{
anim_time = level.player_rig GetAnimTime( %nx_fp_viewmodel_parachute_buffeting );
}
else
{
anim_time = level.player_rig GetAnimTime( %nx_fp_viewmodel_parachute_buffeting_2 );
}
wait 0.05;
}
level.player_rig.idle_weight_curr = 0;
level.player_rig.turn_l_idle_weight_curr = 0;
level.player_rig.turn_r_idle_weight_curr = 0;
level.player_rig.stop_idle_weight_curr = 0;
level._USE_ANIMS = 1;
}
//*******************************************************************
// *
// *
//*******************************************************************
parachute_landing_bump()
{
level notify( "chute_land_interrupt" );
level._landing_interrupt = 1;
level._forward_acceleration = 0.0;
level._forward_velocity = 0.0;
blend_time = 0.3; // 4 frames (0.05 per frame)
level._player shellshock("parachute_buffeting", 1.25);
quakeobj = spawn( "script_origin", level._player.origin );
quakeobj PlayRumbleOnEntity( "artillery_rumble" );
level.player_rig SetAnimKnob( level._scr_anim[ "player_rig" ][ "parachute_bump" ], 1, blend_time, 1 );
while ( 1 )
{
// Finish the chute_end as soon as the anim is complete
curr_time = level.player_rig GetAnimTime( level._scr_anim[ "player_rig" ][ "parachute_bump" ] );
if ( curr_time >= 0.98 )
{
level._player notify( "landing_anim_complete" );
break;
}
wait( 0.05 );
}
}
//*******************************************************************
// *
// *
//*******************************************************************
parachute_lerp_anims()
{
if ( level._USE_ANIMS == 0 )
{
return;
}
level.player_rig SetAnim( level._scr_anim[ "player_rig" ][ "idle" ], level.player_rig.idle_weight_curr, level._TIMESTEP, 1 );
level.legs SetAnim( level._scr_anim[ "legs" ][ "idle" ], level.player_rig.idle_weight_curr, level._TIMESTEP, 1 );
level.player_rig SetAnim( level._scr_anim[ "player_rig" ][ "parachute_turn_l_idle" ], level.player_rig.turn_l_idle_weight_curr, level._TIMESTEP, 1 );
level.legs SetAnim( level._scr_anim[ "legs" ][ "parachute_turn_l_idle" ], level.player_rig.turn_l_idle_weight_curr, level._TIMESTEP, 1 );
level.player_rig SetAnim( level._scr_anim[ "player_rig" ][ "parachute_turn_r_idle" ], level.player_rig.turn_r_idle_weight_curr, level._TIMESTEP, 1 );
level.legs SetAnim( level._scr_anim[ "legs" ][ "parachute_turn_r_idle" ], level.player_rig.turn_r_idle_weight_curr, level._TIMESTEP, 1 );
level.player_rig SetAnim( level._scr_anim[ "player_rig" ][ "parachute_stop_idle" ], level.player_rig.stop_idle_weight_curr, level._TIMESTEP, 1 );
level.legs SetAnim( level._scr_anim[ "legs" ][ "parachute_stop_idle" ], level.player_rig.stop_idle_weight_curr, level._TIMESTEP, 1 );
level.player_rig SetAnim( level._scr_anim[ "player_rig" ][ "parachute_buffeting" ], level.player_rig.buffeting_weight_curr, level._TIMESTEP, 1 );
level.legs SetAnim( level._scr_anim[ "legs" ][ "parachute_buffeting" ], level.player_rig.buffeting_weight_curr, level._TIMESTEP, 1 );
level.player_rig SetAnim( level._scr_anim[ "player_rig" ][ "parachute_buffeting_2" ], level.player_rig.buffeting_2_weight_curr, level._TIMESTEP, 1 );
level.legs SetAnim( level._scr_anim[ "legs" ][ "parachute_buffeting_2" ], level.player_rig.buffeting_2_weight_curr, level._TIMESTEP, 1 );
}
//*******************************************************************
// *
// *
//*******************************************************************
parachute_idle_anims( time )
{
if ( level._USE_ANIMS == 0 )
{
return;
}
// curr = curr + ( target - curr ) * rate
level.player_rig.idle_weight_curr += ( 1.0 - level.player_rig.idle_weight_curr ) * level._anim_rate_in;
level.player_rig.turn_l_idle_weight_curr += ( 0.0 - level.player_rig.turn_l_idle_weight_curr ) * level._anim_rate_in;
level.player_rig.turn_r_idle_weight_curr += ( 0.0 - level.player_rig.turn_r_idle_weight_curr ) * level._anim_rate_in;
level.player_rig.stop_idle_weight_curr += ( 0.0 - level.player_rig.stop_idle_weight_curr ) * level._anim_rate_in;
level.player_rig.buffeting_weight_curr += ( 0.0 - level.player_rig.buffeting_weight_curr ) * level._anim_rate_in;
level.player_rig.buffeting_2_weight_curr += ( 0.0 - level.player_rig.buffeting_2_weight_curr ) * level._anim_rate_in;
}
//*******************************************************************
// *
// *
//*******************************************************************
parachute_L_anims()
{
if ( level._USE_ANIMS == 0 )
{
return;
}
// curr = curr + ( target - curr ) * rate
level.player_rig.turn_l_idle_weight_curr += ( 1.0 - level.player_rig.turn_l_idle_weight_curr ) * level._anim_rate_out;
level.player_rig.idle_weight_curr += ( 0.0 - level.player_rig.idle_weight_curr ) * level._anim_rate_out;
level.player_rig.turn_r_idle_weight_curr += ( 0.0 - level.player_rig.turn_r_idle_weight_curr ) * level._anim_rate_out;
level.player_rig.stop_idle_weight_curr += ( 0.0 - level.player_rig.stop_idle_weight_curr ) * level._anim_rate_out;
level.player_rig.buffeting_weight_curr += ( 0.0 - level.player_rig.buffeting_weight_curr ) * level._anim_rate_out;
level.player_rig.buffeting_2_weight_curr += ( 0.0 - level.player_rig.buffeting_2_weight_curr ) * level._anim_rate_out;
}
//*******************************************************************
// *
// *
//*******************************************************************
parachute_R_anims()
{
if ( level._USE_ANIMS == 0 )
{
return;
}
// curr = curr + ( target - curr ) * rate
level.player_rig.turn_r_idle_weight_curr += ( 1.0 - level.player_rig.turn_r_idle_weight_curr ) * level._anim_rate_out;
level.player_rig.idle_weight_curr += ( 0.0 - level.player_rig.idle_weight_curr ) * level._anim_rate_out;
level.player_rig.turn_l_idle_weight_curr += ( 0.0 - level.player_rig.turn_l_idle_weight_curr ) * level._anim_rate_out;
level.player_rig.stop_idle_weight_curr += ( 0.0 - level.player_rig.stop_idle_weight_curr ) * level._anim_rate_out;
level.player_rig.buffeting_weight_curr += ( 0.0 - level.player_rig.buffeting_weight_curr ) * level._anim_rate_out;
level.player_rig.buffeting_2_weight_curr += ( 0.0 - level.player_rig.buffeting_2_weight_curr ) * level._anim_rate_out;
}
//*******************************************************************
// *
// *
//*******************************************************************
parachute_falling_anims()
{
level.player_rig SetAnimKnob( level._scr_anim[ "player_rig" ][ "parachute_falling" ], 1, 0.5, 1 );
level.legs SetAnimKnob( level._scr_anim[ "legs" ][ "parachute_falling" ], 1, 0.5, 1 );
}
//*******************************************************************
// *
// *
//*******************************************************************
parachute_landing_anims()
{
level.player_rig SetAnimKnob( level._scr_anim[ "player_rig" ][ "parachute_landing" ], 1, 0.5, 1 );
level.legs SetAnimKnob( level._scr_anim[ "legs" ][ "parachute_landing" ], 1, 0.5, 1 );
}
//*******************************************************************
// *
// *
//*******************************************************************
parachute_buffeting_anims( anim_name )
{
if ( !IsDefined( anim_name ) || anim_name == "parachute_buffeting" )
{
level.player_rig SetAnimKnob( level._scr_anim[ "player_rig" ][ "parachute_buffeting" ], 1, 0.5, 1 );
level.legs SetAnimKnob( level._scr_anim[ "legs" ][ "parachute_buffeting" ], 1, 0.5, 1 );
level.player_rig.buffeting_weight_curr = 1.0;
}
else
{
level.player_rig SetAnimKnob( level._scr_anim[ "player_rig" ][ "parachute_buffeting_2" ], 1, 0.5, 1 );
level.legs SetAnimKnob( level._scr_anim[ "legs" ][ "parachute_buffeting_2" ], 1, 0.5, 1 );
level.player_rig.buffeting_2_weight_curr = 1.0;
}
}
//*******************************************************************
// *
// *
//*******************************************************************
parachute_stop_anims()
{
if ( level._USE_ANIMS == 0 )
{
return;
}
// curr = curr + ( target - curr ) * rate
level.player_rig.stop_idle_weight_curr += ( 1.0 - level.player_rig.stop_idle_weight_curr ) * level._anim_rate_out;
level.player_rig.turn_r_idle_weight_curr += ( 0.0 - level.player_rig.turn_r_idle_weight_curr ) * level._anim_rate_out;
level.player_rig.idle_weight_curr += ( 0.0 - level.player_rig.idle_weight_curr ) * level._anim_rate_out;
level.player_rig.turn_l_idle_weight_curr += ( 0.0 - level.player_rig.turn_l_idle_weight_curr ) * level._anim_rate_out;
level.player_rig.buffeting_weight_curr += ( 0.0 - level.player_rig.buffeting_weight_curr ) * level._anim_rate_out;
level.player_rig.buffeting_2_weight_curr += ( 0.0 - level.player_rig.buffeting_2_weight_curr ) * level._anim_rate_out;
}
//*******************************************************************
// *
// *
//*******************************************************************
chute_end()
{
// If we're already failing...don't land
if ( level._fail_sequence == 1 )
{
return;
}
level._enable_chute_controls = 0;
level._landing_sequence = 1;
level._USE_ANIMS = 0;
// lerp
level._player LerpViewAngleClamp( level._view_lerp_time, level._view_lerp_time, 0, level._landing_view_clamp, level._landing_view_clamp, level._landing_view_clamp, level._landing_view_clamp );
level._anim_state = "landing";
// Need to apply a deceleration for the landing
anim_length = GetAnimLength( level._scr_anim[ "player_rig" ][ "parachute_landing" ] );
level._forward_acceleration = ( -1.0 * ( level._forward_velocity / anim_length ) );
parachute_landing_anims();
thread chute_wait_for_landing_complete();
level._player waittill( "landing_anim_complete" );
level._player.disableReload = false;
level._player EnableWeapons();
level._player EnableOffhandWeapons();
level._player EnableWeaponSwitch();
level._player AllowCrouch( true );
level._player AllowJump( true );
//level._player AllowLean( true );
level._player AllowMelee( true );
level._player AllowProne( true );
level._player AllowSprint( true );
//kill sounds
level._chute_sfx StopSounds();
level._chute_sfx Delete();
chute_destroy_assets();
level notify( "maps\_chute::chute_end() complete" );
// Need to snap the player to the ground
level._player SetOrigin( drop_to_ground( level._player.origin, 100, -100 ) );
flag_clear( "_chute.gsc_flag_parachute_active" );
SetSavedDvar( "hud_chute_active", 0 );
}
//*******************************************************************
// *
// *
//*******************************************************************
chute_destroy_assets()
{
level._player Unlink();
level.player_mover Delete();
level.legs Delete();
level.head Delete();
level.player_rig Delete();
}
//*******************************************************************
// *
// *
//*******************************************************************
chute_wait_for_landing_complete()
{
level endon( "chute_land_interrupt" );
while ( 1 )
{
// Finish the chute_end as soon as the anim is complete
curr_time = level.player_rig GetAnimTime( level._scr_anim[ "player_rig" ][ "parachute_landing" ] );
if ( curr_time >= 0.98 )
{
level._player notify( "landing_anim_complete" );
break;
}
wait( 0.05 );
}
}