boiii-scripts/shared/vehicles/_driving_fx.csc
2023-04-13 17:30:38 +02:00

670 lines
20 KiB
Plaintext

#using scripts\shared\audio_shared;
#namespace driving_fx;
class GroundFx
{
var id ;
var handle;
constructor()
{
id = undefined;
handle = -1;
}
destructor()
{
}
function play( localClientNum, vehicle, fx_id, fx_tag )
{
if ( !isdefined(fx_id ) )
{
//stop( localClientNum );
if ( handle > 0 )
{
StopFx( localClientNum, handle );
}
id = undefined;
handle = -1;
return;
}
if ( !isdefined( id ) )
{
id = fx_id;
handle = PlayFxOnTag( localClientNum, id, vehicle, fx_tag );
}
else
{
if ( !isdefined( id ) || id != fx_id )
{
if ( handle > 0 )
{
StopFx( localClientNum, handle );
}
id = fx_id;
handle = PlayFxOnTag( localClientNum, id, vehicle, fx_tag );
}
}
}
function stop( localClientNum )
{
if ( handle > 0 )
{
StopFx( localClientNum, handle );
}
id = undefined;
handle = -1;
}
}
class VehicleWheelFx
{
var name;
var tag_name;
var ground_fx;
constructor()
{
name = "";
tag_name = "";
}
destructor()
{
}
function init( _name, _tag_name )
{
name = _name;
tag_name = _tag_name;
ground_fx = [];
ground_fx[ "skid" ] = new GroundFx();
ground_fx[ "tread" ] = new GroundFx();
ground_fx[ "tread" ].id = "";
ground_fx[ "tread" ].handle = -1;
}
function update( localClientNum, vehicle, speed_fraction )
{
if ( vehicle.vehicleclass === "boat" )
{
peelingout = false;
sliding = false;
trace = bullettrace( vehicle.origin + ( 0, 0, 60 ), vehicle.origin - ( 0, 0, 200 ), false, vehicle );
if( trace["fraction"] < 1.0 )
{
surface = trace["surfacetype"];
}
else
{
[[ ground_fx[ "skid" ] ]]->stop( localClientNum );
[[ ground_fx[ "tread" ] ]]->stop( localClientNum );
return;
}
}
else
{
// If we are not colliding stop all fx
if ( !vehicle IsWheelColliding( name ) )
{
[[ ground_fx[ "skid" ] ]]->stop( localClientNum );
[[ ground_fx[ "tread" ] ]]->stop( localClientNum );
return;
}
peelingout = vehicle IsWheelPeelingOut( name );
sliding = vehicle IsWheelSliding( name );
surface = vehicle GetWheelSurface( name );
}
origin = vehicle GetTagOrigin( tag_name ) + ( 0, 0, 1 );
angles = vehicle GetTagAngles( tag_name );
fwd = AnglesToForward( angles );
right = AnglesToRight( angles );
rumble = false;
if ( peelingout )
{
peel_fx = vehicle driving_fx::get_wheel_fx( "peel", surface );
if ( isdefined( peel_fx ) )
{
PlayFx( localClientNum, peel_fx, origin, fwd * -1 );
rumble = true;
}
}
if ( sliding )
{
skid_fx = vehicle driving_fx::get_wheel_fx( "skid", surface );
[[ ground_fx[ "skid" ] ]]->play( localClientNum, vehicle, skid_fx, tag_name );
vehicle.skidding = true;
rumble = true;
}
else
{
[[ ground_fx[ "skid" ] ]]->stop( localClientNum );
}
if ( speed_fraction > 0.1 )
{
tread_fx = vehicle driving_fx::get_wheel_fx( "tread", surface );
[[ ground_fx[ "tread" ] ]]->play( localClientNum, vehicle, tread_fx, tag_name );
}
else
{
[[ ground_fx[ "tread" ] ]]->stop( localClientNum );
}
if ( rumble )
{
if ( vehicle IsLocalClientDriver( localClientNum ) )
{
player = GetLocalPlayer( localClientNum );
player PlayRumbleOnEntity( localClientNum, "reload_small" );
}
}
}
}
class vehicle_camera_fx
{
var quake_time_min;
var quake_time_max;
var quake_strength_min;
var quake_strength_max;
var rumble_name;
constructor()
{
quake_time_min = 0.5;
quake_time_max = 1.0;
quake_strength_min = 0.1;
quake_strength_max = 0.115;
rumble_name = "";
}
destructor()
{
}
function init( t_min, t_max, s_min, s_max, rumble = "" )
{
quake_time_min = t_min;
quake_time_max = t_max;
quake_strength_min = s_min;
quake_strength_max = s_max;
rumble_name = ( rumble != "" ? rumble : rumble_name );
}
function update( localClientNum, vehicle, speed_fraction )
{
if ( vehicle IsLocalClientDriver( localClientNum ) )
{
player = getlocalplayer( localClientNum );
if ( speed_fraction > 0 )
{
strength = RandomFloatRange( quake_strength_min, quake_strength_max ) * speed_fraction;
time = RandomFloatRange( quake_time_min, quake_time_max );
player Earthquake( strength, time, player.origin, 500 );
if ( rumble_name != "" && speed_fraction > 0.5 )
{
if ( RandomInt( 100 ) < 10 )
{
player PlayRumbleOnEntity( localClientNum, rumble_name );
}
}
}
}
}
}
/* DEAD CODE REMOVAL
function play_driving_fx_thirdperson( localClientNum, speed, speed_fraction )
{
// SP uses _treadfx.csc
}
*/
function vehicle_enter( localClientNum )
{
self endon( "entityshutdown" );
while ( 1 )
{
self waittill( "enter_vehicle", user );
if ( isdefined( user ) && user isplayer() )
{
self thread driving_fx::collision_thread( localClientNum );
self thread driving_fx::jump_landing_thread( localClientNum );
// self thread driving_fx::speed_fx( localClientNum );
}
}
}
function speed_fx( localClientNum )
{
self endon( "entityshutdown" );
self endon( "exit_vehicle" );
while ( 1 )
{
curspeed = self GetSpeed();
curspeed = 0.0005 * curspeed;
curspeed = Abs(curspeed);
if (curspeed>0.001)
{
SetSavedDvar("r_speedBlurFX_enable","1");
SetSavedDvar("r_speedBlurAmount",curspeed);
}
else
{
SetSavedDvar("r_speedBlurFX_enable","0");
}
wait 0.05;
}
}
function play_driving_fx( localClientNum )
{
self endon( "entityshutdown" );
self thread vehicle_enter( localClientNum );
if ( self.surfacefxdeftype == "" )
return;
if ( !isdefined( self.wheel_fx ) )
{
wheel_names = array( "front_left", "front_right", "back_left", "back_right" );
wheel_tag_names = array( "tag_wheel_front_left", "tag_wheel_front_right", "tag_wheel_back_left", "tag_wheel_back_right" );
// temp hack for RAPS vehicle
if( isdefined( self.scriptvehicletype ) && self.scriptvehicletype == "raps" )
{
wheel_names = array( "front_left" );
wheel_tag_names = array( "tag_origin" );
}
else if( self.vehicleclass == "boat" )
{
wheel_names = array( "tag_origin" );
wheel_tag_names = array( "tag_origin" );
}
self.wheel_fx = [];
for ( i = 0; i < wheel_names.size; i++ )
{
self.wheel_fx[i] = new VehicleWheelFx();
[[ self.wheel_fx[i] ]]->init( wheel_names[i], wheel_tag_names[i] );
}
self.camera_fx = [];
self.camera_fx[ "speed" ] = new vehicle_camera_fx();
[[ self.camera_fx[ "speed" ] ]]->init( 0.5, 1.0, 0.1, 0.115, "reload_small" );
self.camera_fx[ "skid" ] = new vehicle_camera_fx();
[[ self.camera_fx[ "skid" ] ]]->init( 0.25, 0.35, 0.1, 0.115 );
}
self.last_screen_dirt = 0;
self.screen_dirt_delay = 0;
speed_fraction = 0;
while ( 1 )
{
speed = Length( self GetVelocity() );
max_speed = ( speed < 0 ? self GetMaxReverseSpeed() : self GetMaxSpeed() );
speed_fraction = ( max_speed > 0 ? Abs(speed) / max_speed : 0 );
self.skidding = false;
for ( i = 0; i < self.wheel_fx.size; i++ )
{
[[ self.wheel_fx[i] ]]->update( localClientNum, self, speed_fraction );
}
// [[ self.camera_fx[ "speed" ] ]]->update( localClientNum, self, speed_fraction );
//
// if ( self.skidding )
// {
// [[ self.camera_fx[ "skid" ] ]]->update( localClientNum, self, ( speed_fraction < 0.25 ? 0.25 : 1 ) );
// }
wait( 0.1 );
}
}
function get_wheel_fx( type, surface )
{
fxarray = undefined;
if ( type == "tread" )
{
fxarray = self.treadfxnamearray;
}
else if ( type == "peel" )
{
fxarray = self.peelfxnamearray;
}
else if ( type == "skid" )
{
fxarray = self.skidfxnamearray;
}
if( isdefined( fxarray ) )
{
return fxarray[ surface ];
}
return undefined;
}
function play_driving_fx_firstperson( localClientNum, speed, speed_fraction )
{
const normal_speed_fraction = 0.25;
// in yo face!
if ( speed > 0 && speed_fraction >= normal_speed_fraction )
{
viewangles = getlocalclientangles( localClientNum );
pitch = angleclamp180( viewangles[0] );
const max_additional_time = 1000;
const no_effects_pitch = -10.0; // 10 degress up, no dirt
const full_effects_pitch = 10.0; // 10 down, full dirt
if ( pitch > no_effects_pitch )
{
current_additional_time = 0;
if ( pitch < full_effects_pitch )
{
current_additional_time = max_additional_time * ( ( (pitch - full_effects_pitch) / ( no_effects_pitch - full_effects_pitch ) ) );
}
if ( self.last_screen_dirt + self.screen_dirt_delay + current_additional_time < getrealtime() )
{
screen_fx_type = self correct_surface_type_for_screen_fx();
if ( screen_fx_type == "dirt" )
{
play_screen_fx_dirt( localClientNum );
}
else
{
play_screen_fx_dust( localClientNum );
}
self.last_screen_dirt = getrealtime();
self.screen_dirt_delay = RandomIntRange( 250, 500 );
}
}
}
}
function collision_thread( localClientNum )
{
self endon( "entityshutdown" );
self endon( "exit_vehicle" );
while( 1 )
{
self waittill( "veh_collision", hip, hitn, hit_intensity );
if ( self IsLocalClientDriver( localClientNum ) )
{
//println( "veh_collision " + hit_intensity );
player = getlocalplayer( localClientNum );
if ( isdefined( self.driving_fx_collision_override ) )
{
self [[ self.driving_fx_collision_override ]]( localClientNum, player, hip, hitn, hit_intensity );
}
else
{
if( isdefined( player ) && isdefined( hit_intensity ) )
{
if( hit_intensity > self.heavyCollisionSpeed )
{
volume = get_impact_vol_from_speed();
if (isdefined (self.sounddef))
{
alias = self.sounddef + "_suspension_lg_hd";
}
else
{
alias = "veh_default_suspension_lg_hd";
}
id = PlaySound( 0, alias, self.origin, volume);
if( isdefined( self.heavyCollisionRumble ) )
{
player PlayRumbleOnEntity( localClientNum, self.heavyCollisionRumble );
}
}
else if( hit_intensity > self.lightCollisionSpeed )
{
volume = get_impact_vol_from_speed();
if (isdefined (self.sounddef))
{
alias = self.sounddef + "_suspension_lg_lt";
}
else
{
alias = "veh_default_suspension_lg_lt";
}
id = PlaySound( 0, alias, self.origin, volume );
if( isdefined( self.lightCollisionRumble ) )
{
player PlayRumbleOnEntity( localClientNum, self.lightCollisionRumble );
}
}
}
}
}
}
}
function jump_landing_thread( localClientNum )
{
self endon( "entityshutdown" );
self endon( "exit_vehicle" );
while( 1 )
{
self waittill( "veh_landed" );
if ( self IsLocalClientDriver( localClientNum ) )
{
player = getlocalplayer( localClientNum );
if( isdefined( player ) )
{
if ( isdefined( self.driving_fx_jump_landing_override ) )
{
self [[ self.driving_fx_jump_landing_override ]]( localClientNum, player );
}
else
{
volume = get_impact_vol_from_speed();
if (isdefined (self.sounddef))
{
alias = self.sounddef + "_suspension_lg_hd";
}
else
{
alias = "veh_default_suspension_lg_hd";
}
id = PlaySound( 0, alias, self.origin, volume);
if( isdefined( self.jumpLandingRumble ) )
{
player PlayRumbleOnEntity( localClientNum, self.jumpLandingRumble );
}
}
}
}
}
}
function suspension_thread( localClientNum )
{
self endon( "entityshutdown" );
self endon( "exit_vehicle" );
while( 1 )
{
self waittill( "veh_suspension_limit_activated" );
if ( self IsLocalClientDriver( localClientNum ) )
{
player = getlocalplayer( localClientNum );
if( isdefined( player ) )
{
volume = get_impact_vol_from_speed();
if (isdefined (self.sounddef))
{
alias = self.sounddef + "_suspension_lg_lt";
}
else
{
alias = "veh_default_suspension_lg_lt";
}
id = PlaySound( 0, alias, self.origin, volume);
player PlayRumbleOnEntity( localClientNum, "damage_light" );
}
}
}
}
function get_impact_vol_from_speed( )
{
// values to map to a linear scale
curspeed = self GetSpeed();
maxSpeed = self GetMaxSpeed();
volume = audio::scale_speed( 0, maxSpeed, 0, 1, curspeed );
volume = volume * volume * volume;
return volume;
}
function any_wheel_colliding()
{
return ( self iswheelcolliding( "front_left" ) || self iswheelcolliding( "front_right" ) ||
self iswheelcolliding( "back_left" ) || self iswheelcolliding( "back_right" ) );
}
function dirt_surface_type( surface_type )
{
switch( surface_type )
{
case "dirt":
case "mud":
case "gravel":
case "grass":
case "foliage":
case "sand":
case "snow":
case "water":
return true;
}
return false;
}
function correct_surface_type_for_screen_fx()
{
right_rear = self GetWheelSurface("back_right");
left_rear = self GetWheelSurface("back_left");
// PrintLn("surfacetypes: " + left_rear + " " + right_rear );
if ( dirt_surface_type( right_rear ) )
return "dirt";
if ( dirt_surface_type( left_rear ) )
return "dirt";
return "dust";
}
function play_screen_fx_dirt(localClientNum)
{
// support for this has been removed with the .menu system
/*
pick_one = RandomIntRange(0,4);
if ( pick_one == 0 )
{
AnimateUI( localClientNum, "fullscreen_dirt", "dirt", "in", 0 );
}
else if ( pick_one == 1 )
{
AnimateUI( localClientNum, "fullscreen_dirt", "dirt_right_splash", "in", 0 );
}
else if ( pick_one == 2 )
{
AnimateUI( localClientNum, "fullscreen_dirt", "dirt_left_splash", "in", 0 );
}
else
{
AnimateUI( localClientNum, "fullscreen_dirt", "blurred_dirt_random", "in", 0 );
}
*/
}
function play_screen_fx_dust(localClientNum)
{
// support for this has been removed with the .menu system
/*
pick_one = RandomIntRange(0,4);
if ( pick_one == 0 )
{
AnimateUI( localClientNum, "fullscreen_dust", "dust", "in", 0 );
}
else if ( pick_one == 1 )
{
AnimateUI( localClientNum, "fullscreen_dust", "dust_right_splash", "in", 0 );
}
else if ( pick_one == 2 )
{
AnimateUI( localClientNum, "fullscreen_dust", "dust_left_splash", "in", 0 );
}
else
{
AnimateUI( localClientNum, "fullscreen_dust", "blurred_dust_random", "in", 0 );
}
*/
}