832 lines
22 KiB
Plaintext
832 lines
22 KiB
Plaintext
#include maps\_utility;
|
|
#include common_scripts\utility;
|
|
#include maps\_anim;
|
|
#include maps\_vehicle;
|
|
|
|
UPDATE_TIME = 0.05; // Time between player input checks.
|
|
BLEND_TIME = 0.5; // Blend time for lean animations.
|
|
CONST_MPHCONVERSION = 17.6;
|
|
|
|
SHOOT_BLEND_TIME = 0.1;
|
|
SHOOT_ARM_UP_DELAY = 1.0;
|
|
SHOOT_FIRE_TIME = 0.05;
|
|
SHOOT_AMMO_COUNT = 32;
|
|
|
|
SLEEVE_FLAP_SPEED = 65.0;
|
|
SLEEVE_FLAP_MAX_RATE = 1.5;
|
|
SLEEVE_FLAP_MIN_RATE = 0.75;
|
|
SLEEVE_FLAP_MAX_WEIGHT = 1.0;
|
|
SLEEVE_FLAP_MIN_WEIGHT = 0.1;
|
|
|
|
STEERING_BLEND_TIME = 0.08;
|
|
|
|
CLOSE_GUY_DIST = 62500;
|
|
|
|
zodiac_preLoad( playerHandModel )
|
|
{
|
|
flag_init( "player_can_die_on_zodiac" );
|
|
flag_init( "player_shot_on_zodiac" );
|
|
flag_set( "player_can_die_on_zodiac" );
|
|
|
|
// set player hand model
|
|
if ( !isdefined( playerHandModel ) )
|
|
level.zodiac_playerHandModel = "viewhands_player_udt";
|
|
else
|
|
level.zodiac_playerHandModel = playerHandModel;
|
|
|
|
level.zodiac_playerZodiacModel = "vehicle_zodiac_viewmodel";
|
|
|
|
// set gun
|
|
level.zodiac_gunModel = "viewmodel_miniUZI";
|
|
|
|
level.zodiac_gun = "uzi";
|
|
|
|
// precahe models and itmes
|
|
PreCacheModel( level.zodiac_playerHandModel );
|
|
PreCacheModel( level.zodiac_playerZodiacModel );
|
|
PreCacheModel( level.zodiac_gunModel );
|
|
PreCacheItem( level.zodiac_gun );
|
|
|
|
// load gun effects
|
|
level.zodiac_gunFlashFx = LoadFX( "muzzleflashes/uzi_flash_view" );
|
|
level.zodiac_gunShellFx = LoadFX( "shellejects/pistol_view" );
|
|
|
|
level.zodiac_sound_overrides = [];
|
|
level.zodiac_sound_overrides[ "weap_glock_fire_snowmobile" ] = "weap_miniuzi_fire_plr";
|
|
|
|
zodiac_anims();
|
|
|
|
// Hold ^3[{+speed_throw}]^7 to shoot.
|
|
add_hint_string( "zodiac_attack", &"SCRIPT_PLATFORM_SNOWMOBILE_ATTACK", ::should_stop_zodiac_attack_hint );
|
|
// Hold ^3[{+attack}]^7 to drive.
|
|
add_hint_string( "zodiac_drive", &"SCRIPT_PLATFORM_SNOWMOBILE_DRIVE", ::should_stop_zodiac_drive_hint );
|
|
|
|
add_hint_string( "zodiac_reverse" , &"SCRIPT_PLATFORM_SNOWMOBILE_REVERSE", ::should_stop_zodiac_reverse_hint );
|
|
|
|
}
|
|
|
|
drive_vehicle()
|
|
{
|
|
Assert( self.code_classname == "script_vehicle" );
|
|
vehicle = self;
|
|
vehicle MakeUsable();
|
|
|
|
self waittill( "vehicle_mount", player );
|
|
Assert( IsDefined( player ) );
|
|
Assert( player.classname == "player" );
|
|
|
|
if ( !getdvarint( "scr_zodiac_test" ) && is_default_start() )
|
|
{
|
|
delayThread( 20, ::display_hint, "zodiac_attack" );
|
|
delayThread( 3, ::display_hint, "zodiac_drive" );
|
|
}
|
|
|
|
player.vehicle = vehicle;
|
|
|
|
vehicle.zodiac_3rdPersonModel = vehicle.model;
|
|
vehicle.zodiacAmmoCount = SHOOT_AMMO_COUNT;
|
|
|
|
vehicle.animname = "zodiac_player";
|
|
vehicle assign_animtree();
|
|
|
|
vehicle MakeUnusable();
|
|
vehicle DontCastShadows();
|
|
|
|
|
|
player thread reverse_hint( vehicle );
|
|
player thread drive_target_enemy( vehicle );
|
|
player thread drive_crash_detection( vehicle );
|
|
player thread drive_camera( vehicle );
|
|
|
|
player thread drive_notetrack_sounds( vehicle, "pullout_anim" );
|
|
player thread drive_notetrack_sounds( vehicle, "fire_anim" );
|
|
player thread drive_notetrack_sounds( vehicle, "reload_anim" );
|
|
player thread drive_notetrack_sounds( vehicle, "putaway_anim" );
|
|
|
|
player drive_switch_to_1st_person( vehicle );
|
|
vehicle waittill_either( "vehicle_dismount", "death" );
|
|
// player drive_switch_to_3rd_person( vehicle );
|
|
|
|
player.vehicle = undefined;
|
|
}
|
|
|
|
|
|
|
|
get_ai_for_player()
|
|
{
|
|
return GetAIArray( "bad_guys" );
|
|
}
|
|
|
|
get_ai_for_price()
|
|
{
|
|
return GetAIArray( "bad_guys" );
|
|
}
|
|
|
|
|
|
drive_target_enemy( vehicle )
|
|
{
|
|
vehicle endon( "vehicle_dismount" );
|
|
vehicle endon( "death" );
|
|
vehicle endon( "stop_targetting" );
|
|
|
|
check_dist_for_hargroves_boat[ "player" ] = 700*700;
|
|
check_dist_for_enemy_boat[ "player" ] = 1300*1300;
|
|
check_dist_for_stationary_guys[ "player" ] = 1300*1300;
|
|
|
|
check_dist_for_hargroves_boat[ "price" ] = 1000*1000;
|
|
check_dist_for_enemy_boat[ "price" ] = 3800*3800;
|
|
check_dist_for_stationary_guys[ "price" ] = 4300*4300;
|
|
|
|
ai_get_func[ "player" ] = ::get_ai_for_player;
|
|
ai_get_func[ "price" ] = ::get_ai_for_price;
|
|
|
|
baseYawSettings[ "price" ][ "right" ] = spawnstruct();
|
|
baseYawSettings[ "price" ][ "right" ].min = -80;
|
|
baseYawSettings[ "price" ][ "right" ].max = 5;
|
|
baseYawSettings[ "price" ][ "right" ].ideal = -25;
|
|
baseYawSettings[ "price" ][ "right" ].retainEnemyMin = -55;
|
|
baseYawSettings[ "price" ][ "right" ].retainEnemyMax = 5;
|
|
baseYawSettings[ "price" ][ "left" ] = spawnstruct();
|
|
baseYawSettings[ "price" ][ "left" ].min = -5;
|
|
baseYawSettings[ "price" ][ "left" ].max = 80;
|
|
baseYawSettings[ "price" ][ "left" ].ideal = 25;
|
|
baseYawSettings[ "price" ][ "left" ].retainEnemyMin = -5;
|
|
baseYawSettings[ "price" ][ "left" ].retainEnemyMax = 55;
|
|
|
|
baseYawSettings[ "player" ] = spawnstruct();
|
|
baseYawSettings[ "player" ].min = -20;
|
|
baseYawSettings[ "player" ].max = 20;
|
|
baseYawSettings[ "player" ].ideal = 0;
|
|
|
|
checking = "player";
|
|
|
|
for ( ;; )
|
|
{
|
|
check_dist = check_dist_for_hargroves_boat[ checking ];
|
|
ai = [[ ai_get_func[ checking ] ]]();
|
|
bestAngle = 180.1;
|
|
enemy = undefined;
|
|
|
|
currentguy = self;
|
|
if ( checking == "price" )
|
|
currentguy = level.price;
|
|
|
|
my_org = currentguy.origin;
|
|
|
|
yawSettings = baseYawSettings[ "player" ];
|
|
if ( checking == "price" )
|
|
{
|
|
if ( !isdefined( currentguy.a.boat_pose ) )
|
|
{
|
|
// Price hasn't started his boat AI anim script yet
|
|
checking = "player";
|
|
wait .05;
|
|
continue;
|
|
}
|
|
yawSettings = baseYawSettings[ "price" ][ currentguy.a.boat_pose ];
|
|
}
|
|
|
|
foreach ( guy in ai )
|
|
{
|
|
his_org = guy.origin;
|
|
|
|
if ( IsDefined( guy.ridingvehicle ) )
|
|
{
|
|
if ( guy.ridingvehicle == level.enemy_boat )
|
|
check_dist = check_dist_for_hargroves_boat[ checking ];
|
|
check_dist = check_dist_for_enemy_boat[ checking ];
|
|
}
|
|
else
|
|
check_dist = check_dist_for_stationary_guys[ checking ];// helps make death animations more visible for those guys that are stationary.
|
|
|
|
dist = distancesquared( his_org, my_org );
|
|
if ( dist > check_dist )
|
|
continue;
|
|
|
|
anglesToGuy = vectorToAngles( his_org - my_org );
|
|
pitch = AngleClamp180( anglesToGuy[0] );
|
|
if ( abs( pitch ) > 15 )
|
|
continue;
|
|
|
|
yaw = AngleClamp180( anglesToGuy[1] - currentguy.angles[1] );
|
|
|
|
if ( yaw < yawSettings.min || yaw > yawSettings.max )
|
|
continue;
|
|
|
|
if ( checking == "price" )
|
|
{
|
|
// price should always shoot the guys in close proximity (if he can aim at them)
|
|
if ( dist < CLOSE_GUY_DIST )
|
|
{
|
|
enemy = guy;
|
|
break;
|
|
}
|
|
// don't change price's enemy if the old one is still good
|
|
if ( isDefined( currentguy.zodiac_enemy ) && guy == currentguy.zodiac_enemy && yaw >= yawSettings.retainEnemyMin && yaw <= yawSettings.retainEnemyMax )
|
|
{
|
|
enemy = guy;
|
|
break;
|
|
}
|
|
}
|
|
|
|
yaw = abs( AngleClamp180( yaw - yawSettings.ideal ) );
|
|
if ( yaw < bestAngle )
|
|
{
|
|
bestAngle = yaw;
|
|
enemy = guy;
|
|
}
|
|
}
|
|
|
|
currentguy.zodiac_enemy = enemy;
|
|
|
|
//if( checking == "price" && IsDefined( currentguy.zodiac_enemy ) )
|
|
// thread draw_line_from_ent_to_ent_for_time( currentguy.zodiac_enemy, currentguy, 1 , 1 , 1 , .2 );
|
|
wait( 0.1 );
|
|
|
|
if ( checking == "price" )
|
|
checking = "player";
|
|
else
|
|
checking = "price";
|
|
}
|
|
}
|
|
|
|
drive_crash_detection( vehicle )
|
|
{
|
|
vehicle endon( "vehicle_dismount" );
|
|
vehicle endon( "death" );
|
|
level endon( "avalanche_begins" );
|
|
|
|
vehicle waittill_vehicle_crashes();
|
|
|
|
yaw_velocity = vehicle Vehicle_GetSpeed();
|
|
yaw_velocity *= CONST_MPHCONVERSION;
|
|
velocity = ( 0, yaw_velocity, 64 );
|
|
|
|
self thread drive_crash_slide( vehicle, velocity );
|
|
self player_dismount_vehicle();
|
|
}
|
|
|
|
waittill_vehicle_crashes()
|
|
{
|
|
level endon( "player_crashes" );// from triggers in the map
|
|
self waittill( "veh_collision" );
|
|
}
|
|
|
|
|
|
drive_crash_slide( vehicle, velocity )
|
|
{
|
|
vehicle waittill( "vehicle_dismount" );
|
|
|
|
self BeginSliding( velocity );
|
|
|
|
if ( flag( "player_can_die_on_zodiac" ) )
|
|
self kill_wrapper();
|
|
|
|
wait( 1.0 );
|
|
|
|
//self EndSliding();
|
|
}
|
|
|
|
|
|
drive_camera( vehicle )
|
|
{
|
|
vehicle endon( "vehicle_dismount" );
|
|
vehicle endon( "death" );
|
|
|
|
for ( ;; )
|
|
{
|
|
vehicle waittill( "third_person" );
|
|
self drive_switch_to_3rd_person( vehicle );
|
|
|
|
vehicle waittill( "first_person" );
|
|
self drive_switch_to_1st_person( vehicle );
|
|
}
|
|
}
|
|
|
|
|
|
drive_notetrack_sounds( vehicle, animflag )
|
|
{
|
|
vehicle endon( "vehicle_dismount" );
|
|
vehicle endon( "death" );
|
|
|
|
for ( ;; )
|
|
{
|
|
vehicle waittill( animflag, notetrack );
|
|
|
|
prefix = GetSubStr( notetrack, 0, 3 );
|
|
|
|
if ( prefix == "ps_" )
|
|
{
|
|
alias = GetSubStr( notetrack, 3 );
|
|
|
|
if ( IsDefined( level.zodiac_sound_overrides[ alias ] ) )
|
|
alias = level.zodiac_sound_overrides[ alias ];
|
|
|
|
vehicle PlaySound( alias );
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
drive_switch_to_1st_person( vehicle )
|
|
{
|
|
if ( IsDefined( vehicle.firstPerson ) )
|
|
return;
|
|
|
|
vehicle SetModel( level.zodiac_playerZodiacModel );
|
|
vehicle Attach( level.zodiac_playerHandModel, "tag_player" );
|
|
vehicle ClearAnim( vehicle getanim( "root" ), 0 );
|
|
|
|
vehicle.firstPerson = true;
|
|
|
|
self thread drive_firstperson_anims( vehicle );
|
|
}
|
|
|
|
|
|
drive_switch_to_3rd_person( vehicle )
|
|
{
|
|
if ( !isDefined( vehicle.firstPerson ) )
|
|
return;
|
|
|
|
if ( IsDefined( vehicle.gun_attached ) )
|
|
{
|
|
vehicle Detach( level.zodiac_gunModel, "tag_weapon_left" );
|
|
vehicle.gun_attached = undefined;
|
|
}
|
|
|
|
vehicle Detach( level.zodiac_playerHandModel, "tag_player" );
|
|
vehicle SetModel( vehicle.zodiac_3rdPersonModel );
|
|
vehicle ClearAnim( vehicle getanim( "root" ), 0 );
|
|
|
|
vehicle.firstPerson = undefined;
|
|
|
|
vehicle notify( "kill_anims" );
|
|
}
|
|
|
|
|
|
drive_firstperson_anims( vehicle )
|
|
{
|
|
vehicle endon( "vehicle_dismount" );
|
|
vehicle endon( "death" );
|
|
vehicle endon( "kill_anims" );
|
|
vehicle endon( "cleanup" );
|
|
|
|
self childthread drive_shooting_anims( vehicle );
|
|
}
|
|
|
|
shootable_stuff_assist_damage( obj )
|
|
{
|
|
// don't assist destruction of these objects.
|
|
dont_assist_destructible_destruction_here = getstructarray( "dont_assist_destructible_destruction_here", "targetname" );
|
|
foreach ( spot in dont_assist_destructible_destruction_here )
|
|
{
|
|
Assert( IsDefined( spot.radius ) );
|
|
if ( Distance( spot.origin, obj.origin ) < spot.radius )
|
|
return;
|
|
}
|
|
|
|
self notify( "new_shootable_stuff_assist" );
|
|
self endon( "new_shootable_stuff_assist" );
|
|
|
|
obj waittill( "damage", ammount, attacker, dvec, p, type );
|
|
for ( i = 0; i < 10; i++ )
|
|
{
|
|
wait .05;
|
|
obj notify( "damage", ammount, level.player, dvec, p, type );
|
|
}
|
|
}
|
|
|
|
|
|
|
|
SHOOTABLE_STUFF_COS = 0.965925;// Cos( 15 )
|
|
drive_magic_bullet_get_end( vehicle, start, noshot )
|
|
{
|
|
end = SpawnStruct();
|
|
|
|
if ( IsAlive( self.zodiac_enemy ) )
|
|
{
|
|
end.obj = self.zodiac_enemy;
|
|
end.origin = self.zodiac_enemy GetShootAtPos() + randomvectorrange( -10, 10 ) + (0,0,-1*randomfloat(40 ) );
|
|
return end;
|
|
}
|
|
|
|
shootable_stuff = array_combine( GetEntArray( "destructible_toy", "targetname" ), GetEntArray( "explodable_barrel", "targetname" ) );
|
|
|
|
//try to shoot stuff ahead when there aren't any snowmbobile_enemy's..
|
|
foreach ( obj in shootable_stuff )
|
|
{
|
|
if ( Distance( level.player.origin, obj.origin ) > 2300 )
|
|
continue;
|
|
|
|
if ( ! within_fov_2d( level.player.origin, level.player.angles, obj.origin, SHOOTABLE_STUFF_COS ) )
|
|
continue;
|
|
|
|
if ( ! level.player SightConeTrace( obj GetShootAtPos(), obj ) )
|
|
continue;
|
|
|
|
end.obj = obj;
|
|
end.origin = obj.origin;
|
|
|
|
thread shootable_stuff_assist_damage( obj );
|
|
return end;
|
|
}
|
|
|
|
//target the last remaining boat drivers
|
|
shootable_boat_drivers = get_shootable_boatdrivers();
|
|
|
|
foreach ( obj in shootable_boat_drivers )
|
|
{
|
|
if ( Distance( level.player.origin, obj.origin ) > 1300 )
|
|
continue;
|
|
|
|
if ( ! within_fov_2d( level.player.origin, level.player.angles, obj.origin, Cos( 15 ) ) )
|
|
continue;
|
|
|
|
if ( ! level.player SightConeTrace( obj.origin + ( 0, 0, 16 ), obj ) )
|
|
continue;
|
|
|
|
end.obj = obj;
|
|
end.origin = obj.origin;
|
|
end.shootable_driver = true;
|
|
return end;
|
|
}
|
|
|
|
if ( IsDefined( noshot ) )
|
|
return end;
|
|
|
|
angles = vehicle GetTagAngles( "tag_flash" );
|
|
forward = AnglesToForward( angles );
|
|
end.origin = start + forward * 1500;
|
|
|
|
return end;
|
|
|
|
}
|
|
|
|
get_shootable_boatdrivers()
|
|
{
|
|
boats = GetEntArray( "script_vehicle_zodiac_physics", "classname" );
|
|
|
|
boatdrivers = [];
|
|
foreach ( boat in boats )
|
|
{
|
|
if ( boat == level.players_boat )
|
|
continue;
|
|
if ( boat == level.enemy_boat )
|
|
continue;
|
|
|
|
|
|
if ( IsSpawner( boat ) )
|
|
continue;
|
|
|
|
if ( boat.riders.size > 1 )
|
|
continue;
|
|
|
|
if ( !boat.riders.size )
|
|
continue;
|
|
|
|
if ( IsDefined( boat.script_noteworthy ) && boat.script_noteworthy == "bobbing_boat" )
|
|
continue;
|
|
|
|
boat thread wipeout_when_not_in_fov();
|
|
|
|
Assert( boat.riders[ 0 ].vehicle_position == 0 );
|
|
Assert( IsDefined( boat.riders[ 0 ].ridingvehicle ) );
|
|
boatdrivers[ boatdrivers.size ] = boat.riders[ 0 ];
|
|
}
|
|
return boatdrivers;
|
|
|
|
}
|
|
|
|
FOV_FOR_WIPEOUT = 0.5;// Cos( 60 );
|
|
|
|
wipeout_when_not_in_fov()
|
|
{
|
|
self notify( "wipeout_when_not_in_fov" );
|
|
self endon( "wipeout_when_not_in_fov" );
|
|
self endon( "death" );
|
|
|
|
while ( within_fov_of_players( self.origin, FOV_FOR_WIPEOUT ) )
|
|
wait .05;
|
|
|
|
self.wipeout = true;
|
|
}
|
|
|
|
drive_magic_bullet_trace( obj, start, end )
|
|
{
|
|
trace = BulletTrace( start, end, false, self );
|
|
if ( !isdefined( trace[ "entity" ] ) )
|
|
return false;
|
|
if ( trace[ "entity" ] != obj )
|
|
return false;
|
|
return true;
|
|
}
|
|
|
|
|
|
|
|
drive_magic_bullet( vehicle )
|
|
{
|
|
start = vehicle GetTagOrigin( "tag_flash" );
|
|
|
|
end = drive_magic_bullet_get_end( vehicle, start );
|
|
|
|
if( flag( "player_in_sight_of_boarding" ) )
|
|
MagicBullet( level.zodiac_gun, start, start + ( 0, 0, 255 ), self );
|
|
else
|
|
MagicBullet( level.zodiac_gun, start, end.origin, self );
|
|
|
|
PlayFXOnTag( level.zodiac_gunFlashFx, vehicle, "tag_flash" );
|
|
PlayFXOnTag( level.zodiac_gunShellFx, vehicle, "tag_brass" );
|
|
|
|
level.player PlayRumbleOnEntity( "smg_fire" );
|
|
|
|
|
|
|
|
if ( !isdefined( end.obj ) )
|
|
return;
|
|
|
|
if ( !isai( end.obj ) )
|
|
end.obj notify( "damage", 50, level.player, self.origin, end.obj.origin, "MOD_PISTOL_BULLET", "", "" );
|
|
|
|
if ( IsDefined( end.shootable_driver ) )
|
|
{
|
|
driver_death( end.obj );
|
|
return;
|
|
}
|
|
// end.obj common_scripts\_destructible::force_explosion();
|
|
}
|
|
|
|
driver_death( guy )
|
|
{
|
|
guy notify( "newanim" );
|
|
Assert( !IsAI( guy ) );
|
|
guy StartRagdoll();
|
|
guy.ridingvehicle.wipeout = true;
|
|
}
|
|
|
|
drive_blend_anims_with_steering( vehicle, animflag, endNotify, leftAnim, centerAnim, rightAnim )
|
|
{
|
|
vehicle endon( endNotify );
|
|
|
|
vehicle SetFlaggedAnimRestart( animflag, vehicle getanim( leftAnim ), 0.001, STEERING_BLEND_TIME, 1.0 );
|
|
vehicle SetFlaggedAnimRestart( animflag, vehicle getanim( centerAnim ), 0.001, STEERING_BLEND_TIME, 1.0 );
|
|
vehicle SetFlaggedAnimRestart( animflag, vehicle getanim( rightAnim ), 0.001, STEERING_BLEND_TIME, 1.0 );
|
|
|
|
for ( ;; )
|
|
{
|
|
steerValue = vehicle Vehicle_GetSteering() * -1.0;
|
|
|
|
// never set a weight to zero so that all the anims continue to play
|
|
if ( steerValue >= 0.0 )
|
|
{
|
|
leftWeight = 0.001;
|
|
centerWeight = -0.999 * steerValue + 1.0;
|
|
rightWeight = 0.999 * steerValue + 0.001;
|
|
}
|
|
else
|
|
{
|
|
leftWeight = -0.999 * steerValue + 0.001;
|
|
centerWeight = 0.999 * steerValue + 1.0;
|
|
rightWeight = 0.001;
|
|
}
|
|
|
|
vehicle SetFlaggedAnim( animflag, vehicle getanim( leftAnim ), leftWeight, STEERING_BLEND_TIME, 1.0 );
|
|
vehicle SetFlaggedAnim( animflag, vehicle getanim( centerAnim ), centerWeight, STEERING_BLEND_TIME, 1.0 );
|
|
vehicle SetFlaggedAnim( animflag, vehicle getanim( rightAnim ), rightWeight, STEERING_BLEND_TIME, 1.0 );
|
|
|
|
wait UPDATE_TIME;
|
|
}
|
|
}
|
|
|
|
|
|
drive_shooting_update_anims( vehicle )
|
|
{
|
|
// start pull out anim
|
|
vehicle SetAnimKnobLimited( vehicle getanim( "gun_pullout_root" ), 1.0, 0.0, 1.0 );
|
|
self childthread drive_blend_anims_with_steering( vehicle, "pullout_anim", "pullout_done", "gun_pullout_L", "gun_pullout", "gun_pullout_R" );
|
|
|
|
// attach the gun
|
|
vehicle waittillmatch( "pullout_anim", "attach_gun" );
|
|
vehicle Attach( level.zodiac_gunModel, "tag_weapon_left" );
|
|
|
|
//"viewmodel_miniUZI"
|
|
vehicle HidePart( "TAG_ACOG_2", level.zodiac_gunModel );
|
|
vehicle HidePart( "TAG_RAIL", level.zodiac_gunModel );
|
|
vehicle HidePart( "TAG_RED_DOT", level.zodiac_gunModel );
|
|
vehicle HidePart( "TAG_EOTECH", level.zodiac_gunModel );
|
|
vehicle HidePart( "TAG_SILENCER", level.zodiac_gunModel );
|
|
vehicle HidePart( "TAG_THERMAL_SCOPE", level.zodiac_gunModel );
|
|
vehicle HidePart( "TAG_RETICLE_RED_DOT", level.zodiac_gunModel );
|
|
vehicle HidePart( "TAG_EOTECH_RETICLE", level.zodiac_gunModel );
|
|
vehicle HidePart( "TAG_RETICLE_ACOG", level.zodiac_gunModel );
|
|
vehicle HidePart( "TAG_RETICLE_THERMAL_SCOPE", level.zodiac_gunModel );
|
|
|
|
|
|
vehicle.gun_attached = true;
|
|
|
|
vehicle waittillmatch( "pullout_anim", "end" );
|
|
vehicle notify( "pullout_done" );
|
|
|
|
// start gun anim
|
|
vehicle SetAnim( vehicle getanim( "uzi" ), 1.0, 0.0, 1.0 );
|
|
|
|
// start idle
|
|
vehicle SetAnimKnobLimited( vehicle getanim( "gun_idle" ), 1.0, 0.0, 1.0 );
|
|
|
|
vehicle.zodiacShootTimer = SHOOT_ARM_UP_DELAY;
|
|
|
|
for ( ;; )
|
|
{
|
|
if ( vehicle.zodiacShootTimer <= 0.0 )
|
|
break;
|
|
|
|
shootButtonPressed = is_shoot_button_pressed();
|
|
|
|
if ( shootButtonPressed && ( vehicle.zodiacAmmoCount > 0 ) )
|
|
{
|
|
flag_set( "player_shot_on_zodiac" );
|
|
// play gun fire anims
|
|
vehicle SetFlaggedAnimKnobLimitedRestart( "fire_anim", vehicle getanim( "gun_fire" ), 1.0, 0.0, 1.0 );
|
|
|
|
if ( vehicle.zodiacAmmoCount == 1 )
|
|
vehicle SetAnimKnobLimitedRestart( vehicle getanim( "uzi_last_fire" ), 1.0, 0.0, 1.0 );
|
|
else
|
|
vehicle SetAnimKnobLimitedRestart( vehicle getanim( "uzi_fire" ), 1.0, 0.0, 1.0 );
|
|
|
|
// fire bullet
|
|
self drive_magic_bullet( vehicle );
|
|
|
|
wait( SHOOT_FIRE_TIME );
|
|
|
|
vehicle.zodiacAmmoCount -= 1;
|
|
vehicle.zodiacShootTimer = SHOOT_ARM_UP_DELAY;
|
|
}
|
|
else if ( vehicle.zodiacAmmoCount <= 0 )
|
|
{
|
|
// play reload anims
|
|
vehicle SetFlaggedAnimKnobLimitedRestart( "reload_anim", vehicle getanim( "gun_reload" ), 1.0, 0.0, 1.0 );
|
|
vehicle SetAnimKnobLimitedRestart( vehicle getanim( "uzi_reload" ), 1.0, 0.0, 1.0 );
|
|
|
|
vehicle waittillmatch( "reload_anim", "end" );
|
|
|
|
vehicle.zodiacAmmoCount = SHOOT_AMMO_COUNT;
|
|
vehicle.zodiacShootTimer = SHOOT_ARM_UP_DELAY;
|
|
}
|
|
else
|
|
{
|
|
// play idle
|
|
vehicle SetAnimKnobLimited( vehicle getanim( "gun_idle" ), 1.0, 0.0, 1.0 );
|
|
vehicle.zodiacShootTimer -= UPDATE_TIME;
|
|
}
|
|
|
|
wait UPDATE_TIME;
|
|
}
|
|
|
|
// start put away anim
|
|
vehicle SetAnimKnobLimited( vehicle getanim( "gun_putaway_root" ), 1.0, 0.0, 1.0 );
|
|
self childthread drive_blend_anims_with_steering( vehicle, "putaway_anim", "putaway_done", "gun_putaway_L", "gun_putaway", "gun_putaway_R" );
|
|
|
|
// detach the gun
|
|
vehicle waittillmatch( "putaway_anim", "detach_gun" );
|
|
if ( IsDefined( vehicle.gun_attached ) )
|
|
{
|
|
vehicle Detach( level.zodiac_gunModel, "tag_weapon_left" );
|
|
vehicle.gun_attached = undefined;
|
|
}
|
|
|
|
vehicle waittillmatch( "putaway_anim", "end" );
|
|
vehicle notify( "putaway_done" );
|
|
vehicle notify( "drive_shooting_done" );
|
|
}
|
|
|
|
|
|
drive_shooting_anims( vehicle )
|
|
{
|
|
vehicle SetAnim( vehicle getanim( "drive_left_arm" ), 1.0, SHOOT_BLEND_TIME, 1.0 );
|
|
vehicle SetAnim( vehicle getanim( "shoot_left_arm" ), 0.0, SHOOT_BLEND_TIME, 1.0 );
|
|
|
|
for ( ;; )
|
|
{
|
|
shootButtonPressed = is_shoot_button_pressed();
|
|
|
|
if ( shootButtonPressed )
|
|
{
|
|
vehicle SetAnim( vehicle getanim( "drive_left_arm" ), 0.001, SHOOT_BLEND_TIME, 1.0 );
|
|
vehicle SetAnim( vehicle getanim( "shoot_left_arm" ), 1.0, SHOOT_BLEND_TIME, 1.0 );
|
|
|
|
self childthread drive_shooting_update_anims( vehicle );
|
|
|
|
vehicle waittill( "drive_shooting_done" );
|
|
}
|
|
|
|
vehicle SetAnim( vehicle getanim( "drive_left_arm" ), 1.0, SHOOT_BLEND_TIME, 1.0 );
|
|
vehicle SetAnim( vehicle getanim( "shoot_left_arm" ), 0.0, SHOOT_BLEND_TIME, 1.0 );
|
|
|
|
wait UPDATE_TIME;
|
|
}
|
|
}
|
|
|
|
is_shoot_button_pressed()
|
|
{
|
|
// pc
|
|
return self AttackButtonPressed();
|
|
}
|
|
|
|
|
|
|
|
#using_animtree( "vehicles" );
|
|
zodiac_anims()
|
|
{
|
|
level.scr_animtree[ "zodiac_player" ] = #animtree;
|
|
level.scr_model[ "zodiac_player" ] = level.zodiac_playerHandModel;
|
|
level.scr_anim[ "zodiac_player" ][ "root" ] = %root;
|
|
level.scr_anim[ "zodiac_player" ][ "left_arm" ] = %player_snowmobile_left_arm;
|
|
level.scr_anim[ "zodiac_player" ][ "drive_left_arm" ] = %player_snowmobile_drive_left_arm;
|
|
level.scr_anim[ "zodiac_player" ][ "shoot_left_arm" ] = %player_snowmobile_shoot_left_arm;
|
|
level.scr_anim[ "zodiac_player" ][ "gun_fire" ] = %player_snowmobile_gun_fire;
|
|
level.scr_anim[ "zodiac_player" ][ "gun_idle" ] = %player_snowmobile_gun_idle;
|
|
level.scr_anim[ "zodiac_player" ][ "gun_pullout_root" ] = %player_snowmobile_gun_pullout_root;
|
|
level.scr_anim[ "zodiac_player" ][ "gun_pullout_L" ] = %player_snowmobile_gun_pullout_L;
|
|
level.scr_anim[ "zodiac_player" ][ "gun_pullout" ] = %player_snowmobile_gun_pullout;
|
|
level.scr_anim[ "zodiac_player" ][ "gun_pullout_R" ] = %player_snowmobile_gun_pullout_R;
|
|
level.scr_anim[ "zodiac_player" ][ "gun_putaway_root" ] = %player_snowmobile_gun_putaway_root;
|
|
level.scr_anim[ "zodiac_player" ][ "gun_putaway_L" ] = %player_snowmobile_gun_putaway_L;
|
|
level.scr_anim[ "zodiac_player" ][ "gun_putaway" ] = %player_snowmobile_gun_putaway;
|
|
level.scr_anim[ "zodiac_player" ][ "gun_putaway_R" ] = %player_snowmobile_gun_putaway_R;
|
|
level.scr_anim[ "zodiac_player" ][ "gun_reload" ] = %player_snowmobile_gun_reload;
|
|
|
|
level.scr_anim[ "zodiac_player" ][ "right_arm" ] = %player_snowmobile_right_arm;
|
|
|
|
level.scr_anim[ "zodiac_player" ][ "uzi" ] = %snowmobile_glock;
|
|
level.scr_anim[ "zodiac_player" ][ "uzi_fire" ] = %snowmobile_glock_fire;
|
|
level.scr_anim[ "zodiac_player" ][ "uzi_last_fire" ] = %snowmobile_glock_last_fire;
|
|
level.scr_anim[ "zodiac_player" ][ "uzi_reload" ] = %snowmobile_glock_reload;
|
|
|
|
level.scr_anim[ "zodiac_player" ][ "sleeve_pose" ] = %player_sleeve_pose;
|
|
level.scr_anim[ "zodiac_player" ][ "sleeve_flapping" ] = %player_sleeve_flapping;
|
|
}
|
|
|
|
should_stop_zodiac_attack_hint()
|
|
{
|
|
if ( !isdefined( level.player.vehicle ) )
|
|
return true;
|
|
|
|
return flag( "player_shot_on_zodiac" );
|
|
}
|
|
|
|
|
|
should_stop_zodiac_drive_hint()
|
|
{
|
|
if ( !isdefined( level.player.vehicle ) )
|
|
return true;
|
|
|
|
return level.player.vehicle.veh_speed > 10;
|
|
}
|
|
|
|
|
|
reverse_hint( vehicle )
|
|
{
|
|
self endon( "death" );
|
|
vehicle endon( "vehicle_dismount" );
|
|
vehicle endon( "death" );
|
|
|
|
level endon ( "no_more_reverse_hints" );
|
|
|
|
vehicle wait_for_vehicle_to_move();
|
|
|
|
vehicle.hint_brake_count = 0;
|
|
for ( ;; )
|
|
{
|
|
if ( abs( vehicle.veh_speed ) < 5 )
|
|
{
|
|
vehicle.hint_brake_count++;
|
|
if ( vehicle.hint_brake_count >= 3 )
|
|
{
|
|
vehicle display_hint( "zodiac_reverse" );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
vehicle.hint_brake_count = 0;
|
|
}
|
|
wait( 1 );
|
|
}
|
|
}
|
|
|
|
wait_for_vehicle_to_move()
|
|
{
|
|
for ( ;; )
|
|
{
|
|
if ( self.veh_speed > 40 )
|
|
return;
|
|
wait( 1 );
|
|
}
|
|
}
|
|
|
|
should_stop_zodiac_reverse_hint()
|
|
{
|
|
if ( !isdefined( self.vehicle ) )
|
|
return true;
|
|
return self.vehicle.hint_brake_count < 3;
|
|
}
|