This commit is contained in:
Future committed 2023-04-13 17:30:38 +02:00
commit 013c6f3b4d
921 files changed
+337975

No files matched your search

File diff suppressed because it is too large. Load diff
+27
View File
@@ -0,0 +1,27 @@
#using scripts\codescripts\struct;
#using scripts\shared\math_shared;
#using scripts\shared\statemachine_shared;
#using scripts\shared\system_shared;
#using scripts\shared\util_shared;
#using scripts\shared\vehicle_shared;
#using scripts\shared\vehicle_death_shared;
#using scripts\shared\vehicle_ai_shared;
Line truncated
#namespace attack_drone;
function autoexec __init__sytem__() { system::register("attack_drone",&__init__,undefined,undefined); }
function __init__()
{
}
+495
View File
@@ -0,0 +1,495 @@
#using scripts\codescripts\struct;
#using scripts\shared\array_shared;
#using scripts\shared\clientfield_shared;
#using scripts\shared\flag_shared;
#using scripts\shared\fx_shared;
#using scripts\shared\math_shared;
#using scripts\shared\statemachine_shared;
#using scripts\shared\system_shared;
#using scripts\shared\turret_shared;
#using scripts\shared\util_shared;
#using scripts\shared\vehicle_death_shared;
#using scripts\shared\vehicle_shared;
#using scripts\shared\vehicle_ai_shared;
Line truncated
#namespace auto_turret;
function autoexec __init__sytem__() { system::register("auto_turret",&__init__,undefined,undefined); }
function __init__()
{
vehicle::add_main_callback( "auto_turret", &turret_initialze );
}
function turret_initialze()
{
self.health = self.healthdefault;
if ( isdefined( self.scriptbundlesettings ) )
{
self.settings = struct::get_script_bundle( "vehiclecustomsettings", self.scriptbundlesettings );
}
else
{
self.settings = struct::get_script_bundle( "vehiclecustomsettings", "artillerysettings" );
}
sightfov = self.settings.sightfov;
if ( !isdefined( sightfov ) )
{
sightfov = 0;
}
self.fovcosine = Cos( sightfov - 0.1 );
self.fovcosinebusy = Cos( sightfov - 0.1 );
if ( self.settings.disconnectpaths === true )
{
self DisconnectPaths();
}
if ( self.settings.ignoreme === true )
{
self.ignoreme = true;
}
if ( self.settings.laseron === true )
{
self laserOn();
}
// only auto aim if it can fire. if more specific situation comes we can separate aim assist into a separate GDT field
if ( self.settings.disablefiring !== true )
{
self EnableAimAssist();
}
else
{
self.noCybercom = true;
}
self thread turret::track_lens_flare();
self.overrideVehicleDamage =&turretCallback_VehicleDamage;
self.allowFriendlyFireDamageOverride = &turretAllowFriendlyFireDamage;
//disable some cybercom abilities
if( IsDefined( level.vehicle_initializer_cb ) )
{
[[level.vehicle_initializer_cb]]( self );
}
self.ignoreFireFly = true;
self.ignoreDecoy = true;
self vehicle_ai::InitThreatBias();
defaultRole();
}
function defaultRole()
{
self vehicle_ai::init_state_machine_for_role( "default" );
self vehicle_ai::get_state_callbacks( "death" ).update_func = &state_death_update;
self vehicle_ai::get_state_callbacks( "combat" ).update_func = &state_combat_update;
self vehicle_ai::get_state_callbacks( "combat" ).exit_func = &state_combat_exit;
self vehicle_ai::get_state_callbacks( "off" ).enter_func = &state_off_enter;
self vehicle_ai::get_state_callbacks( "off" ).exit_func = &state_off_exit;
self vehicle_ai::get_state_callbacks( "emped" ).enter_func = &state_emped_enter;
self vehicle_ai::get_state_callbacks( "emped" ).update_func = &state_emped_update;
self vehicle_ai::get_state_callbacks( "emped" ).exit_func = &state_emped_exit;
self vehicle_ai::add_state( "unaware",
undefined,
&state_unaware_update,
undefined );
vehicle_ai::add_interrupt_connection( "unaware", "scripted", "enter_scripted" );
vehicle_ai::add_interrupt_connection( "unaware", "emped", "emped" );
vehicle_ai::add_interrupt_connection( "unaware", "off", "shut_off" );
vehicle_ai::add_interrupt_connection( "unaware", "driving", "enter_vehicle" );
vehicle_ai::add_interrupt_connection( "unaware", "pain", "pain" );
vehicle_ai::add_utility_connection( "unaware", "combat", &should_switch_to_combat );
vehicle_ai::add_utility_connection( "combat", "unaware", &should_switch_to_unaware );
vehicle_ai::StartInitialState( "unaware" );
}
// ----------------------------------------------
// State: death
// ----------------------------------------------
function state_death_update( params )
{
self endon( "death" );
owner = self GetVehicleOwner();
if ( isdefined( owner ) )
{
self waittill( "exit_vehicle" );
}
self SetTurretSpinning( false );
self turret::toggle_lensflare( false );
params.death_type = "default"; // only do default death for now
self thread turret_idle_sound_stop();
self playsound("veh_sentry_turret_dmg_hit");
self.turretRotScale = 2;
self rest_turret( params.resting_pitch );
self vehicle_ai::defaultstate_death_update( params );
}
// death-----------------------------------------
// ----------------------------------------------
// State: unaware
// ----------------------------------------------
function should_switch_to_unaware( current_state, to_state, connection )
{
if ( !isdefined( self.enemy ) || !self VehSeenRecently( self.enemy, 1.5 ) )
{
return 100;
}
return 0;
}
function state_unaware_update( params )
{
self endon( "death" );
self endon( "change_state" );
turret_left = true;
relativeAngle = 0;
self thread turret_idle_sound();
self playsound ("mpl_turret_startup");
self ClearTargetEntity();
while( true )
{
rotScale = self.settings.scanning_speedscale;
if ( !isdefined( rotScale ) )
{
rotScale = 0.01;
}
self.turretRotScale = rotScale;
scanning_arc = self.settings.scanning_arc;
if ( !isdefined( scanning_arc ) )
{
scanning_arc = 0;
}
limits = self GetTurretLimitsYaw();
scanning_arc = min( scanning_arc, limits[0] - 0.1 );
scanning_arc = min( scanning_arc, limits[1] - 0.1 );
if ( scanning_arc > 179 )
{
if ( self.turretontarget )
{
relativeAngle += 90;
if ( relativeAngle > 180 )
{
relativeAngle -= 360;
}
}
scanning_arc = relativeAngle;
}
else
{
if ( self.turretontarget )
{
turret_left = !turret_left;
}
if ( !turret_left )
{
scanning_arc *= -1;
}
}
scanning_pitch = self.settings.scanning_pitch;
if ( !isdefined( scanning_pitch ) )
{
scanning_pitch = 0;
}
self SetTurretTargetRelativeAngles( ( scanning_pitch, scanning_arc, 0 ) );
self vehicle_ai::evaluate_connections();
wait 0.5;
}
}
// unaware---------------------------------------
// ----------------------------------------------
// State: combat
// ----------------------------------------------
function should_switch_to_combat( current_state, to_state, connection )
{
if ( isdefined( self.enemy ) && isAlive( self.enemy ) && self VehCanSee( self.enemy ) )
{
return 100;
}
return 0;
}
function state_combat_update( params )
{
self endon( "death" );
self endon( "change_state" );
if( isdefined( self.enemy ) )
{
sentry_turret_alert_sound();
wait 0.5;
}
while( 1 )
{
if( isdefined( self.enemy ) && self VehCanSee( self.enemy ) )
{
self.turretRotScale = 1;
if ( isdefined( self.enemy ) && self HasPart( "tag_minigun_spin" ) )
{
self SetTurretTargetEnt( self.enemy );
self SetTurretSpinning( true );
wait 0.5;
}
for( i = 0; i < 3; i++ )
{
if( isdefined( self.enemy ) && IsAlive( self.enemy ) && self VehCanSee( self.enemy ) )
{
self SetTurretTargetEnt( self.enemy );
wait 0.1;
waitTime = RandomFloatRange( 0.4, 1.5 );
if ( self.settings.disablefiring !== true )
{
self sentry_turret_fire_for_time( waitTime, self.enemy );
}
else
{
wait waitTime;
}
}
if( isdefined( self.enemy ) && IsPlayer( self.enemy ) )
wait RandomFloatRange( 0.3, 0.6 );
else
wait RandomFloatRange( 0.3, 0.6 ) * 2;
}
self SetTurretSpinning( false );
if( isdefined( self.enemy ) && IsAlive( self.enemy ) && self VehCanSee( self.enemy ) )
{
if( IsPlayer( self.enemy ) )
wait RandomFloatRange( 0.5, 1.3 );
else
wait RandomFloatRange( 0.5, 1.3 ) * 2;
}
}
self vehicle_ai::evaluate_connections();
wait 0.5;
}
}
function state_combat_exit( params )
{
self SetTurretSpinning( false );
}
function sentry_turret_fire_for_time( totalFireTime, enemy )
{
self endon( "death" );
self endon( "change_state" );
sentry_turret_alert_sound();
wait .1;//giving time for the alert to play
weapon = self SeatGetWeapon( 0 );
fireTime = weapon.fireTime;
time = 0;
is_minigun = false;
if ( IsSubStr( weapon.name, "minigun" ) )
{
is_minigun = true;
self SetTurretSpinning( true );
wait 0.5;
}
while( time < totalFireTime )
{
self FireWeapon(0, enemy);
wait fireTime;
time += fireTime;
}
if( is_minigun )
{
self SetTurretSpinning( false );
}
}
// combat----------------------------------------
// ----------------------------------------------
// State: off
// ----------------------------------------------
function state_off_enter( params )
{
self vehicle_ai::defaultstate_off_enter( params );
self.turretRotScale = 0.5;
self rest_turret( params.resting_pitch );
}
function state_off_exit( params )
{
self vehicle_ai::defaultstate_off_exit( params );
self.turretRotScale = 1.0;
self playsound ("mpl_turret_startup");
}
function rest_turret( resting_pitch )
{
if ( !isdefined( resting_pitch ) )
{
resting_pitch = self.settings.resting_pitch;
}
if ( !isdefined( resting_pitch ) )
{
resting_pitch = 0;
}
angles = self GetTagAngles( "tag_turret" ) - self.angles;
self SetTurretTargetRelativeAngles( ( resting_pitch, angles[1], 0 ) );
}
// off-------------------------------------------
// ----------------------------------------------
// State: emped
// ----------------------------------------------
function state_emped_enter( params )
{
self vehicle_ai::defaultstate_emped_enter( params );
PlaySoundAtPosition( "veh_sentry_turret_emp_down", self.origin );
self.turretRotScale = 0.5;
self rest_turret( params.resting_pitch );
params.laserOn = IsLaserOn( self );
self LaserOff();
self vehicle::lights_off();
if ( !isdefined( self.abnormal_status ) )
{
self.abnormal_status = spawnStruct();
}
self.abnormal_status.emped = true;
self.abnormal_status.attacker = params.notify_param[1];
self.abnormal_status.inflictor = params.notify_param[2];
self vehicle::toggle_emp_fx( true );
}
function state_emped_update( params )
{
self endon ("death");
self endon ("change_state");
time = params.notify_param[0];
assert( isdefined( time ) );
vehicle_ai::Cooldown( "emped_timer", time );
while( !vehicle_ai::IsCooldownReady( "emped_timer" ) )
{
timeLeft = max( vehicle_ai::GetCooldownLeft( "emped_timer" ), 0.5 );
wait timeLeft;
}
self.abnormal_status.emped = false;
self vehicle::toggle_emp_fx( false );
self vehicle_ai::emp_startup_fx();
self rest_turret( 0 );
wait 1;
self vehicle_ai::evaluate_connections();
}
function state_emped_exit( params )
{
self vehicle_ai::defaultstate_emped_exit( params );
self.turretRotScale = 1.0;
self playsound ("mpl_turret_startup");
}
// emped-----------------------------------------
// ----------------------------------------------
// State: scripted
// ----------------------------------------------
function state_scripted_update( params )
{
self.turretRotScale = 1;
}
// scripted--------------------------------------
function turretAllowFriendlyFireDamage( eInflictor, eAttacker, sMeansOfDeath, weapon )
{
if ( isdefined( eAttacker ) && isdefined( sMeansOfDeath ) && sMeansOfDeath == "MOD_EXPLOSIVE" )
{
return true;
}
return false;
}
function turretCallback_VehicleDamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, vDamageOrigin, psOffsetTime, damageFromUnderneath, modelIndex, partName, vSurfaceNormal )
{
iDamage = vehicle_ai::shared_callback_damage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, vDamageOrigin, psOffsetTime, damageFromUnderneath, modelIndex, partName, vSurfaceNormal );
//self HidePart( "tag_shield" );
return iDamage;
}
function sentry_turret_alert_sound()
{
self playsound ("veh_turret_alert");
}
function turret_idle_sound()
{
if ( !isdefined( self.sndloop_ent ) )
{
self.sndloop_ent = Spawn("script_origin", self.origin);
self.sndloop_ent linkto (self);
self.sndloop_ent PlayLoopSound ("veh_turret_idle");
}
}
function turret_idle_sound_stop()
{
self endon( "death" );
if ( isdefined( self.sndloop_ent ) )
{
self.sndloop_ent stoploopsound( .5 );
wait( 2 );
self.sndloop_ent delete();
}
}
+20
View File
@@ -0,0 +1,20 @@
#using scripts\codescripts\struct;
#using scripts\shared\callbacks_shared;
#using scripts\shared\clientfield_shared;
#using scripts\shared\filter_shared;
#using scripts\shared\system_shared;
#using scripts\shared\util_shared;
#using scripts\shared\vehicle_shared;
#using scripts\shared\archetype_shared\archetype_shared;
Line truncated
#namespace counteruav;
function autoexec __init__sytem__() { system::register("counteruav",&__init__,undefined,undefined); }
function __init__()
{
}
+75
View File
@@ -0,0 +1,75 @@
#using scripts\codescripts\struct;
#using scripts\shared\math_shared;
#using scripts\shared\statemachine_shared;
#using scripts\shared\system_shared;
#using scripts\shared\array_shared;
#using scripts\shared\util_shared;
#using scripts\shared\vehicle_shared;
#using scripts\shared\vehicle_ai_shared;
#using scripts\shared\vehicle_death_shared;
#using scripts\shared\clientfield_shared;
Line truncated
#using_animtree( "generic" );
#namespace counteruav;
function autoexec __init__sytem__() { system::register("counteruav",&__init__,undefined,undefined); }
function __init__()
{
vehicle::add_main_callback( "counteruav", &counteruav_initialize );
}
function counteruav_initialize()
{
self UseAnimTree( #animtree );
Target_Set( self, ( 0, 0, 0 ) );
self.health = self.healthdefault;
self vehicle::friendly_fire_shield();
//self EnableAimAssist();
//self SetNearGoalNotifyDist( 40 );
self SetVehicleAvoidance( true ); // this is ORCA avoidance
self SetHoverParams( 50.0, 100.0, 100.0 );
self.vehAirCraftCollisionEnabled = true;
assert( isdefined( self.scriptbundlesettings ) );
self.settings = struct::get_script_bundle( "vehiclecustomsettings", self.scriptbundlesettings );
self.goalRadius = 999999;
self.goalHeight = 999999;
self SetGoal( self.origin, false, self.goalRadius, self.goalHeight );
self.overrideVehicleDamage = &drone_callback_damage;
// self thread vehicle_ai::nudge_collision(); // do we need this?
//disable some cybercom abilities
if( IsDefined( level.vehicle_initializer_cb ) )
{
[[level.vehicle_initializer_cb]]( self );
}
}
function drone_callback_damage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, vDamageOrigin, psOffsetTime, damageFromUnderneath, modelIndex, partName, vSurfaceNormal )
{
iDamage = vehicle_ai::shared_callback_damage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, vDamageOrigin, psOffsetTime, damageFromUnderneath, modelIndex, partName, vSurfaceNormal );
return iDamage;
}
+669
View File
@@ -0,0 +1,669 @@
Line truncated
#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 );
}
*/
}
File diff suppressed because it is too large. Load diff
+82
View File
@@ -0,0 +1,82 @@
#using scripts\codescripts\struct;
#using scripts\shared\callbacks_shared;
#using scripts\shared\clientfield_shared;
#using scripts\shared\duplicaterender_mgr;
#using scripts\shared\filter_shared;
#using scripts\shared\postfx_shared;
#using scripts\shared\system_shared;
#using scripts\shared\util_shared;
#using scripts\shared\vehicle_shared;
Line truncated
#namespace parasite;
function autoexec main()
{
clientfield::register( "vehicle", "parasite_tell_fx", 1, 1, "int", &parasiteTellFxHandler, !true, !true );
clientfield::register( "toplayer", "parasite_damage", 1, 1, "counter", &parasite_damage, !true, !true );
clientfield::register( "vehicle", "parasite_secondary_deathfx", 1, 1, "int", &parasiteSecondaryDeathFxHandler, !true, !true );
vehicle::add_vehicletype_callback( "parasite", &_setup_ );
}
function private parasiteTellFxHandler( localClientNum, oldValue, newValue, bNewEnt, bInitialSnap, fieldName, wasDemoJump )
{
if ( IsDefined( self.tellFxHandle ) )
{
StopFX( localClientNum, self.tellFxHandle );
self.tellFxHandle = undefined;
self MapShaderConstant( localClientNum, 0, "scriptVector2", 0.1 );
}
settings = struct::get_script_bundle( "vehiclecustomsettings", "parasitesettings" );
if( IsDefined( settings ) )
{
if( newValue )
{
self.tellFxHandle = PlayFXOnTag( localClientNum, settings.weakspotfx, self, "tag_flash" );
self MapShaderConstant( localClientNum, 0, "scriptVector2", 1.0 );
}
}
}
function private parasite_damage( localClientNum, oldValue, newValue, bNewEnt, bInitialSnap, fieldName, wasDemoJump )
{
if ( newValue )
{
self postfx::PlayPostfxBundle( "pstfx_parasite_dmg" );
}
}
function private parasiteSecondaryDeathFxHandler( localClientNum, oldValue, newValue, bNewEnt, bInitialSnap, fieldName, wasDemoJump )
{
settings = struct::get_script_bundle( "vehiclecustomsettings", "parasitesettings" );
if( IsDefined( settings ) )
{
if( newValue )
{
handle = PlayFX( localClientNum, settings.secondary_death_fx_1, self GetTagOrigin( settings.secondary_death_tag_1 ) );
SetFXIgnorePause( localClientNum, handle, true );
}
}
}
function private _setup_( localClientNum )
{
self MapShaderConstant( localClientNum, 0, "scriptVector2", 0.1 );
if( ( isdefined( level.debug_keyline_zombies ) && level.debug_keyline_zombies ) )
{
self duplicate_render::set_dr_flag( "keyline_active", 1 );
self duplicate_render::update_dr_filters(localClientNum);
}
}
+768
View File
@@ -0,0 +1,768 @@
#using scripts\codescripts\struct;
#using scripts\shared\math_shared;
#using scripts\shared\statemachine_shared;
#using scripts\shared\callbacks_shared;
#using scripts\shared\clientfield_shared;
#using scripts\shared\system_shared;
#using scripts\shared\array_shared;
#using scripts\shared\util_shared;
#using scripts\shared\ai_shared;
#using scripts\shared\vehicle_shared;
#using scripts\shared\vehicle_death_shared;
#using scripts\shared\vehicle_ai_shared;
#using scripts\shared\ai\systems\blackboard;
#using scripts\shared\ai\blackboard_vehicle;
#using scripts\shared\ai\systems\ai_interface;
Line truncated
#using scripts\shared\ai\zombie_utility;
//reduce these defines to have the parasite make more movements close together
#namespace parasite;
function autoexec __init__sytem__() { system::register("parasite",&__init__,undefined,undefined); }
#using_animtree( "generic" );
function __init__()
{
vehicle::add_main_callback( "parasite", &parasite_initialize );
clientfield::register( "vehicle", "parasite_tell_fx", 1, 1, "int" );
clientfield::register( "vehicle", "parasite_secondary_deathfx", 1, 1, "int" );
clientfield::register( "toplayer", "parasite_damage", 1, 1, "counter" );
callback::on_spawned( &parasite_damage );
ai::RegisterMatchedInterface(
"parasite",
"firing_rate",
"slow",
array( "slow", "medium", "fast" ) );
}
function parasite_damage()
{
self notify( "parasite_damage_thread" );
self endon( "parasite_damage_thread" );
self endon( "death" );
while ( true )
{
self waittill( "damage", n_ammount, e_attacker );
if ( IsDefined( e_attacker ) && ( isdefined( e_attacker.is_parasite ) && e_attacker.is_parasite ) && !( isdefined( e_attacker.squelch_damage_overlay ) && e_attacker.squelch_damage_overlay ) )
{
self clientfield::increment_to_player( "parasite_damage" );
}
}
}
function private is_target_valid( target )
{
if( !IsDefined( target ) )
{
return false;
}
if( !IsAlive( target ) )
{
return false;
}
if( IsPlayer( target ) && target.sessionstate == "spectator" )
{
return false;
}
if( IsPlayer( target ) && target.sessionstate == "intermission" )
{
return false;
}
if( ( isdefined( target.ignoreme ) && target.ignoreme ) )
{
return false;
}
if( target IsNoTarget() )
{
return false;
}
if( IsDefined( self.is_target_valid_cb ) )
{
return self [[ self.is_target_valid_cb ]]( target );
}
return true;
}
function get_parasite_enemy()
{
parasite_targets = GetPlayers();
least_hunted = parasite_targets[0];
for( i = 0; i < parasite_targets.size; i++ )
{
if ( !isdefined( parasite_targets[i].hunted_by ) )
{
parasite_targets[i].hunted_by = 0;
}
if( !is_target_valid( parasite_targets[i] ) )
{
continue;
}
if( !is_target_valid( least_hunted ) )
{
least_hunted = parasite_targets[i];
}
if( parasite_targets[i].hunted_by < least_hunted.hunted_by )
{
least_hunted = parasite_targets[i];
}
}
// do not return the default first player if he is invalid
if( !is_target_valid( least_hunted ) )
{
return undefined;
}
else
{
return least_hunted;
}
}
function set_parasite_enemy( enemy )
{
if( !is_target_valid( enemy ) )
{
return;
}
if( IsDefined( self.parasiteEnemy ) )
{
if( !IsDefined( self.parasiteEnemy.hunted_by ) )
{
self.parasiteEnemy.hunted_by = 0;
}
if( self.parasiteEnemy.hunted_by > 0 )
{
self.parasiteEnemy.hunted_by--;
}
}
self.parasiteEnemy = enemy;
if( !IsDefined( self.parasiteEnemy.hunted_by ) )
{
self.parasiteEnemy.hunted_by = 0;
}
self.parasiteEnemy.hunted_by++;
self SetLookAtEnt( self.parasiteEnemy );
self SetTurretTargetEnt( self.parasiteEnemy );
}
function private parasite_target_selection()
{
self endon( "change_state" );
self endon( "death" );
for( ;; )
{
if ( ( isdefined( self.ignoreall ) && self.ignoreall ) )
{
wait 0.5;
continue;
}
if( is_target_valid( self.parasiteEnemy ) )
{
wait 0.5;
continue;
}
//decide who the enemy should be
target = get_parasite_enemy();
if( !isDefined( target ) )
{
self.parasiteEnemy = undefined;
}
else
{
self.parasiteEnemy = target;
//update hunted_by
self.parasiteEnemy.hunted_by += 1;
self SetLookAtEnt( self.parasiteEnemy );
self SetTurretTargetEnt( self.parasiteEnemy );
}
wait 0.5;
}
}
function parasite_initialize()
{
self useanimtree( #animtree );
// AI SPECIFIC INITIALIZATION
blackboard::CreateBlackBoardForEntity( self );
self Blackboard::RegisterVehicleBlackBoardAttributes();
ai::CreateInterfaceForEntity( self );
Blackboard::RegisterBlackBoardAttribute(self,"_parasite_firing_rate","slow",&getParasiteFiringRate); if( IsActor(self) ) { /#self TrackBlackBoardAttribute("_parasite_firing_rate");#/ };
self.health = self.healthdefault;
self vehicle::friendly_fire_shield();
self EnableAimAssist();
self SetNearGoalNotifyDist( 25 );
self SetDrawInfrared( true );
self.fovcosine = 0;
self.fovcosinebusy = 0;
self.vehAirCraftCollisionEnabled = true;
assert( isdefined( self.scriptbundlesettings ) );
self.settings = struct::get_script_bundle( "vehiclecustomsettings", self.scriptbundlesettings );
self.goalRadius = 999999;
self.goalHeight = 4000;
self SetGoal( self.origin, false, self.goalRadius, self.goalHeight );
self.is_parasite = true;
self thread vehicle_ai::nudge_collision();
if( IsDefined( level.vehicle_initializer_cb ) )
{
[[level.vehicle_initializer_cb]]( self );
}
defaultRole();
}
function defaultRole()
{
self vehicle_ai::init_state_machine_for_role( "default" );
self vehicle_ai::get_state_callbacks( "combat" ).enter_func = &state_combat_enter;
self vehicle_ai::get_state_callbacks( "combat" ).update_func = &state_combat_update;
self vehicle_ai::get_state_callbacks( "death" ).update_func = &state_death_update;
self vehicle_ai::call_custom_add_state_callbacks();
vehicle_ai::StartInitialState( "combat" );
}
// ----------------------------------------------
//BB getter functions
// ----------------------------------------------
function getParasiteFiringRate()
{
return self ai::get_behavior_attribute( "firing_rate" );
}
// ----------------------------------------------
// State: death
// ----------------------------------------------
function state_death_update( params )
{
self endon( "death" );
self ASMRequestSubstate( "death@stationary" );
if( IsDefined( self.parasiteEnemy ) && IsDefined( self.parasiteEnemy.hunted_by ) )
{
self.parasiteEnemy.hunted_by--;
}
self SetPhysAcceleration( ( 0, 0, -300 ) );
self.vehcheckforpredictedcrash = true;
self thread vehicle_death::death_fx();
self playsound( "zmb_parasite_explo" );
self util::waittill_notify_or_timeout( "veh_predictedcollision", 4.0 );
self clientfield::set( "parasite_secondary_deathfx", 1 );
//make sure the client gets a chance to play the second fx before deleting
wait 0.2;
self Delete();
}
// ----------------------------------------------
// State: combat
// ----------------------------------------------
function state_combat_enter( params )
{
if ( IsDefined( self.owner ) && IsDefined( self.owner.enemy ) )
{
self.parasiteEnemy = self.owner.enemy;
}
self thread parasite_target_selection();
}
function state_combat_update( params )
{
self endon( "change_state" );
self endon( "death" );
lastTimeChangePosition = 0;
self.shouldGotoNewPosition = false;
self.lastTimeTargetInSight = 0;
self.lastTimeJuked = false;
//request movement animations
self ASMRequestSubstate( "locomotion@movement" );
for( ;; )
{
if( IsDefined( self._override_parasite_combat_speed ) )
{
self SetSpeed( self._override_parasite_combat_speed );
}
else
{
self SetSpeed( self.settings.defaultMoveSpeed );
}
if ( ( isdefined( self.inpain ) && self.inpain ) )
{
wait 0.1;
}
else if ( !IsDefined( self.parasiteEnemy ) )
{
//no enemy, do nothing
wait( 0.25 );
}
else
{
if( self.goalforced )
{
returnData = [];
returnData[ "origin" ] = self GetClosestPointOnNavVolume( self.goalpos, 100 );
returnData[ "centerOnNav" ] = IsPointInNavVolume( self.origin, "navvolume_small" );
}
//prevent two consecutive forward jukes, and force juke if path was interrupted ( possibly due to collision )
else if( ( RandomInt( 100 ) < self.settings.jukeprobability && !( isdefined( self.lastTimeJuked ) && self.lastTimeJuked ) ) || ( isdefined( self._override_juke ) && self._override_juke ) )
{
returnData = GetNextMovePosition_forwardjuke();
self.lastTimeJuked = true;
self._override_juke = undefined;
}
else
{
returnData = GetNextMovePosition_tactical();
self.lastTimeJuked = false;
}
self.current_pathto_pos = returnData[ "origin" ];
if ( IsDefined( self.current_pathto_pos ) )
{
if( IsDefined( self.stuckTime ) )
{
self.stuckTime = undefined;
}
if ( self SetVehGoalPos( self.current_pathto_pos, true, returnData[ "centerOnNav" ] ) )
{
self thread path_update_interrupt();
//AUDIO: Was on JUST the juke, but I've moved it for any movement to make it more interesting
self playsound( "zmb_vocals_parasite_juke" );
self vehicle_ai::waittill_pathing_done( 5 );
}
else
{
//failsafe, cannot pathfind
wait( 0.1 );
}
}
else
{
if( !( isdefined( returnData[ "centerOnNav" ] ) && returnData[ "centerOnNav" ] ) )
{
//not on navmesh, no valid goto points, kill parasite as failsafe
if( !IsDefined( self.stuckTime ) )
{
self.stuckTime = GetTime();
}
if( GetTime() - self.stuckTime > 10000 )
{
self DoDamage( self.health + 100, self.origin );
}
}
}
if( ( isdefined( self.lastTimeJuked ) && self.lastTimeJuked ) )
{
if( RandomInt( 100 ) < 50 && IsDefined( self.parasiteEnemy ) && Distance2DSquared( self.origin, self.parasiteEnemy.origin ) < ( (64) * (64) ) )
{
//parasite melee bite
self.parasiteEnemy DoDamage( self.settings.meleedamage, self.parasiteEnemy.origin, self );
}
else
{
self fire_pod_logic( self.lastTimeJuked );
}
}
else
{
if( RandomInt( 100 ) < 30 )
{
self fire_pod_logic( self.lastTimeJuked );
}
}
}
}
}
function fire_pod_logic( choseToJuke )
{
if( IsDefined( self.parasiteEnemy ) && self VehCanSee( self.parasiteEnemy ) && Distance2DSquared( self.parasiteEnemy.origin, self.origin ) < ( (0.5 * ( self.settings.engagementDistMin + self.settings.engagementDistMax ) * 3) * (0.5 * ( self.settings.engagementDistMin + self.settings.engagementDistMax ) * 3) ) )
{
//switch to fire animation
self ASMRequestSubstate( "fire@stationary" );
//do the tell
self PlaySound( "zmb_vocals_parasite_preattack" );
self clientfield::set( "parasite_tell_fx", 1 );
//reached the point in the animation to adjust the turret
self waittill( "pre_fire" );
if( IsDefined( self.parasiteEnemy ) && self VehCanSee( self.parasiteEnemy ) && Distance2DSquared( self.parasiteEnemy.origin, self.origin ) < ( (0.5 * ( self.settings.engagementDistMin + self.settings.engagementDistMax ) * 3) * (0.5 * ( self.settings.engagementDistMin + self.settings.engagementDistMax ) * 3) ) )
{
//fire the projectile at the predicted player position
self SetTurretTargetEnt( self.parasiteEnemy, self.parasiteEnemy GetVelocity() * 0.3 );
}
self vehicle_ai::waittill_asm_complete( "fire@stationary", 5 );
//switch back to locomotion
self ASMRequestSubstate( "locomotion@movement" );
//cleanup the fx
self clientfield::set( "parasite_tell_fx", 0 );
if( !choseToJuke )
{
wait RandomFloatRange( 0.25, 0.5 );
}
}
else
{
wait RandomFloatRange( 1, 2 );
}
}
function GetNextMovePosition_tactical() // has self.parasiteEnemy
{
self endon( "change_state" );
self endon( "death" );
// distance based multipliers
selfDistToTarget = Distance2D( self.origin, self.parasiteEnemy.origin );
goodDist = 0.5 * ( self.settings.engagementDistMin + self.settings.engagementDistMax );
closeDist = 1.2 * goodDist;
farDist = 3 * goodDist;
queryMultiplier = MapFloat( closeDist, farDist, 1, 3, selfDistToTarget );
//the preferred height range should be half the max possible difference to not exceed valid heights for points near the goalheight
preferedHeightRange = 0.5 * ( self.settings.engagementHeightMax - self.settings.engagementHeightMin );
randomness = 30;
// query
queryResult = PositionQuery_Source_Navigation( self.origin, 75, 225 * queryMultiplier, 75, 20 * queryMultiplier, self, 20 * queryMultiplier );
//turn off collision, we are not on the navvolume
if( !( isdefined( queryResult.centerOnNav ) && queryResult.centerOnNav ) )
{
self.vehAirCraftCollisionEnabled = false;
}
else
{
self.vehAirCraftCollisionEnabled = true;
}
// filter
PositionQuery_Filter_DistanceToGoal( queryResult, self );
vehicle_ai::PositionQuery_Filter_OutOfGoalAnchor( queryResult );
self vehicle_ai::PositionQuery_Filter_EngagementDist( queryResult, self.parasiteEnemy, self.settings.engagementDistMin, self.settings.engagementDistMax );
goalHeight = self.parasiteEnemy.origin[2] + 0.5 * ( self.settings.engagementHeightMin + self.settings.engagementHeightMax );
// score points
best_point = undefined;
best_score = -999999;
trace_count = 0;
foreach ( point in queryResult.data )
{
if( !( isdefined( queryResult.centerOnNav ) && queryResult.centerOnNav ) )
{
if( SightTracePassed( self.origin, point.origin, false, undefined ) )
{
trace_count++;
if( trace_count > 3 )
{
{wait(.05);};
trace_count = 0;
}
if( !BulletTracePassed( self.origin, point.origin, false, self ) )
{
continue;
}
}
else
{
continue;
}
}
/# if ( !isdefined( point._scoreDebug ) ) { point._scoreDebug = []; } point._scoreDebug[ "random" ] = randomFloatRange( 0, randomness ); #/ point.score += randomFloatRange( 0, randomness );;
/# if ( !isdefined( point._scoreDebug ) ) { point._scoreDebug = []; } point._scoreDebug[ "engagementDist" ] = -point.distAwayFromEngagementArea; #/ point.score += -point.distAwayFromEngagementArea;;
// height
distFromPreferredHeight = abs( point.origin[2] - goalHeight );
if ( distFromPreferredHeight > preferedHeightRange )
{
heightScore = MapFloat( 0, 500, 0, 2000, distFromPreferredHeight );
/# if ( !isdefined( point._scoreDebug ) ) { point._scoreDebug = []; } point._scoreDebug[ "height" ] = -heightScore; #/ point.score += -heightScore;;
}
if ( point.score > best_score )
{
best_score = point.score;
best_point = point;
}
}
self vehicle_ai::PositionQuery_DebugScores( queryResult );
/#
if ( ( isdefined( GetDvarInt("hkai_debugPositionQuery") ) && GetDvarInt("hkai_debugPositionQuery") ) )
{
recordLine( self.origin, best_point.origin, (0.3,1,0) );
recordLine( self.origin, self.parasiteEnemy.origin, (1,0,0.4) );
}
#/
returnData = [];
returnData[ "origin" ] = ( ( IsDefined( best_point ) ) ? best_point.origin : undefined );
returnData[ "centerOnNav" ] = queryResult.centerOnNav;
return returnData;
}
function GetNextMovePosition_forwardjuke() // has self.parasiteEnemy
{
self endon( "change_state" );
self endon( "death" );
// distance based multipliers
selfDistToTarget = Distance2D( self.origin, self.parasiteEnemy.origin );
goodDist = 0.5 * ( self.settings.forwardJukeEngagementDistMin + self.settings.forwardJukeEngagementDistMax );
closeDist = 1.2 * goodDist;
farDist = 3 * goodDist;
queryMultiplier = MapFloat( closeDist, farDist, 1, 3, selfDistToTarget );
preferedHeightRange = 0.5 * ( self.settings.forwardJukeEngagementHeightMax - self.settings.forwardJukeEngagementHeightMin );
randomness = 30;
// query
queryResult = PositionQuery_Source_Navigation( self.origin, 75, 300 * queryMultiplier, 75, 20 * queryMultiplier, self, 20 * queryMultiplier );
if( !( isdefined( queryResult.centerOnNav ) && queryResult.centerOnNav ) )
{
self.vehAirCraftCollisionEnabled = false;
}
else
{
self.vehAirCraftCollisionEnabled = true;
}
// filter
PositionQuery_Filter_DistanceToGoal( queryResult, self );
vehicle_ai::PositionQuery_Filter_OutOfGoalAnchor( queryResult );
self vehicle_ai::PositionQuery_Filter_EngagementDist( queryResult, self.parasiteEnemy, self.settings.forwardJukeEngagementDistMin, self.settings.forwardJukeEngagementDistMax );
goalHeight = self.parasiteEnemy.origin[2] + 0.5 * ( self.settings.forwardJukeEngagementHeightMin + self.settings.forwardJukeEngagementHeightMax );
// score points
best_point = undefined;
best_score = -999999;
trace_count = 0;
foreach ( point in queryResult.data )
{
if( !( isdefined( queryResult.centerOnNav ) && queryResult.centerOnNav ) )
{
if( SightTracePassed( self.origin, point.origin, false, undefined ) )
{
trace_count++;
if( trace_count > 3 )
{
{wait(.05);};
trace_count = 0;
}
if( !BulletTracePassed( self.origin, point.origin, false, self ) )
{
continue;
}
}
else
{
continue;
}
}
/# if ( !isdefined( point._scoreDebug ) ) { point._scoreDebug = []; } point._scoreDebug[ "random" ] = randomFloatRange( 0, randomness ); #/ point.score += randomFloatRange( 0, randomness );;
/# if ( !isdefined( point._scoreDebug ) ) { point._scoreDebug = []; } point._scoreDebug[ "engagementDist" ] = -point.distAwayFromEngagementArea; #/ point.score += -point.distAwayFromEngagementArea;;
// height
distFromPreferredHeight = abs( point.origin[2] - goalHeight );
if ( distFromPreferredHeight > preferedHeightRange )
{
heightScore = MapFloat( 0, 500, 0, 2000, distFromPreferredHeight );
/# if ( !isdefined( point._scoreDebug ) ) { point._scoreDebug = []; } point._scoreDebug[ "height" ] = -heightScore; #/ point.score += -heightScore;;
}
if ( point.score > best_score )
{
best_score = point.score;
best_point = point;
}
}
self vehicle_ai::PositionQuery_DebugScores( queryResult );
/#
if ( ( isdefined( GetDvarInt("hkai_debugPositionQuery") ) && GetDvarInt("hkai_debugPositionQuery") ) )
{
recordLine( self.origin, best_point.origin, (0.3,1,0) );
recordLine( self.origin, self.parasiteEnemy.origin, (1,0,0.4) );
}
#/
returnData = [];
returnData[ "origin" ] = ( ( IsDefined( best_point ) ) ? best_point.origin : undefined );
returnData[ "centerOnNav" ] = queryResult.centerOnNav;
return returnData;
}
function path_update_interrupt()
{
self endon( "death" );
self endon( "change_state" );
self endon( "near_goal" );
self endon( "reached_end_node" );
wait 1;
while( 1 )
{
if( isdefined( self.current_pathto_pos ) )
{
if( distance2dSquared( self.current_pathto_pos, self.goalpos ) > ( (self.goalradius) * (self.goalradius) ) )
{
wait 0.2;
self._override_juke = true;
self notify( "near_goal" );
}
}
wait 0.2;
}
}
// ----------------------------------------------
// pain/hit reaction
// ----------------------------------------------
function drone_pain_for_time( time, stablizeParam, restoreLookPoint )
{
self endon( "death" );
self.painStartTime = GetTime();
if ( !( isdefined( self.inpain ) && self.inpain ) )
{
self.inpain = true;
self PlaySound( "zmb_vocals_parasite_pain" );
while ( GetTime() < self.painStartTime + time * 1000 )
{
self SetVehVelocity( self.velocity * stablizeParam );
self SetAngularVelocity( self GetAngularVelocity() * stablizeParam );
wait 0.1;
}
if ( isdefined( restoreLookPoint ) )
{
restoreLookEnt = Spawn( "script_model", restoreLookPoint );
restoreLookEnt SetModel( "tag_origin" );
self ClearLookAtEnt();
self SetLookAtEnt( restoreLookEnt );
self setTurretTargetEnt( restoreLookEnt );
wait 1.5;
self ClearLookAtEnt();
self ClearTurretTarget();
restoreLookEnt delete();
}
self.inpain = false;
}
}
function drone_pain( eAttacker, damageType, hitPoint, hitDirection, hitLocationInfo, partName )
{
if ( !( isdefined( self.inpain ) && self.inpain ) )
{
yaw_vel = math::randomSign() * RandomFloatRange( 280, 320 );
ang_vel = self GetAngularVelocity();
ang_vel += ( RandomFloatRange( -120, -100 ), yaw_vel, RandomFloatRange( -200, 200 ) );
self SetAngularVelocity( ang_vel );
self thread drone_pain_for_time( 0.8, 0.7 );
}
}
+199
View File
@@ -0,0 +1,199 @@
#using scripts\codescripts\struct;
#using scripts\shared\callbacks_shared;
#using scripts\shared\clientfield_shared;
#using scripts\shared\filter_shared;
#using scripts\shared\system_shared;
#using scripts\shared\util_shared;
#using scripts\shared\vehicle_shared;
Line truncated
#namespace quadtank;
function autoexec __init__sytem__() { system::register("quadtank",&__init__,undefined,undefined); }
function __init__()
{
vehicle::add_vehicletype_callback( "quadtank", &_setup_ );
clientfield::register( "toplayer", "player_shock_fx", 1, 1, "int", &player_shock_fx_handler, !true, !true );
clientfield::register( "vehicle", "quadtank_trophy_state", 1, 1, "int", &update_trophy_system_state, !true, !true );
}
function _setup_( localClientNum )
{
player = GetLocalPlayer( localClientNum );
if( isdefined( player ) )
{
filter::init_filter_ev_interference( player );
}
//set code field to get notifies to play impact effects
self.notifyOnBulletImpact = true;
self thread wait_for_bullet_impact( localClientNum );
//trophy state
self.trophy_on = false;
}
function player_shock_fx_handler( localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump )
{
if ( isdefined( self ) )
{
self thread player_shock_fx_fade_off( localClientNum, 1.0, 1.0 );
}
}
function player_shock_fx_fade_off( localClientNum, amount, fadeoutTime )
{
// not ending on death or shutdown, cause we have to clean ourselves up
self endon( "disconnect" );
self notify( "player_shock_fx_fade_off_end" ); // kill previous threads
self endon( "player_shock_fx_fade_off_end" );
if ( !isAlive( self ) )
{
return;
}
startTime = GetTime();
filter::set_filter_ev_interference_amount( self, 4, amount );
filter::enable_filter_ev_interference( self, 4 );
while ( GetTime() <= startTime + fadeoutTime * 1000 && isAlive( self ) )
{
ratio = ( GetTime() - startTime ) / ( fadeoutTime * 1000 );
currentValue = LerpFloat( amount, 0, ratio );
setfilterpassconstant( localClientNum, 4, 0, 0, currentValue ); // use code function instead of script wrapper cause player can be undefined
wait .016;
}
setfilterpassenabled( localClientNum, 4, 0, false );
}
function update_trophy_system_state( localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump )
{
self thread set_trophy_state( localClientNum, newval === 1 );
}
function set_trophy_state( localClientNum, isOn )
{
self endon( "entityshutdown" );
self notify( "stop_set_trophy_state" );
self endon( "stop_set_trophy_state" );
if ( isdefined( self.trophydestroy_fx_handle ) )
{
StopFX( localClientNum, self.trophydestroy_fx_handle );
}
if ( isdefined( self.trophylight_fx_handle ) )
{
StopFX( localClientNum, self.trophylight_fx_handle );
}
vehicle::wait_for_DObj( localClientNum );
if( isdefined( self.scriptbundlesettings ) )
{
settings = struct::get_script_bundle( "vehiclecustomsettings", self.scriptbundlesettings );
}
if ( !isdefined( settings ) )
{
return;
}
if ( isOn === 1 )
{
warmuptime = (isdefined(settings.trophywarmup)?settings.trophywarmup:0.1);
start = GetTime();
interval = 0.3;
while ( GetTime() <= start + warmuptime * 1000 )
{
if ( isdefined( settings.trophylight_fx_1 ) && isdefined( settings.trophylight_tag_1 ) )
{
self.trophylight_fx_handle = PlayFXOnTag( localClientNum, settings.trophylight_fx_1, self, settings.trophylight_tag_1 );
}
wait 0.05;
if ( isdefined( self.trophylight_fx_handle ) )
{
StopFX( localClientNum, self.trophylight_fx_handle );
}
wait max( interval, 0.05 );
interval *= 0.8;
}
if ( isdefined( settings.trophylight_fx_1 ) && isdefined( settings.trophylight_tag_1 ) )
{
self.trophylight_fx_handle = PlayFXOnTag( localClientNum, settings.trophylight_fx_1, self, settings.trophylight_tag_1 );
}
self.trophy_on = true;
self PlayLoopSound ( "wpn_trophy_spin_loop");
rate = 0.0;
while ( isdefined( settings.trophyanim ) && rate < 1 )
{
rate += 0.02;
self SetAnim( settings.trophyanim, 1.0, 0.1, rate );
{wait(.016);};
}
self SetAnim( settings.trophyanim, 1.0, 0.1, 1.0 );
}
else
{
self.trophy_on = false;
self StopAllLoopSounds();
if ( isdefined( settings.trophyanim ) )
{
self SetAnim( settings.trophyanim, 0.0, 0.2, 1.0 );
}
if ( isdefined( settings.trophydestroyfx ) )
{
self.trophydestroy_fx_handle = PlayFXOnTag( localClientNum, settings.trophydestroyfx, self, "tag_target_lower" );
}
}
}
function wait_for_bullet_impact( localClientNum )
{
self endon( "entityshutdown" );
if( isdefined( self.scriptbundlesettings ) )
{
settings = struct::get_script_bundle( "vehiclecustomsettings", self.scriptbundlesettings );
}
else
{
return;
}
while( 1 )
{
self waittill( "damage", attacker, impactPos, effectDir, partname );
if( partName == "tag_target_lower" || partName == "tag_target_upper" || partName == "tag_defense_active" || partName == "tag_body_animate" )
{
if( self.trophy_on )
{
if( IsDefined( attacker ) && attacker IsPlayer() && attacker.team != self.team )
{
PlayFx( localClientNum, settings.weakspotfx, impactPos, effectDir );
self playsound( 0, "veh_quadtank_panel_hit" );
}
}
}
}
}
File diff suppressed because it is too large. Load diff
+89
View File
@@ -0,0 +1,89 @@
Line truncated
#using scripts\codescripts\struct;
#using scripts\shared\clientfield_shared;
#using scripts\shared\system_shared;
#using scripts\shared\vehicle_shared;
#namespace raps;
function autoexec main()
{
// clientfield setup
clientfield::register( "vehicle", "raps_side_deathfx", 1, 1, "int", &do_side_death_fx, !true, !true );
}
function adjust_side_death_dir_if_trace_fail( origin, side_dir, fxlength, up_dir )
{
end = origin + side_dir * fxlength;
trace = BulletTrace( origin, end, false, self, true );
if ( trace["fraction"] < 1.0 )
{
new_side_dir = VectorNormalize( side_dir + up_dir );
end = origin + new_side_dir * fxlength;
new_trace = BulletTrace( origin, end, false, self, true );
if ( new_trace["fraction"] > trace["fraction"] )
{
side_dir = new_side_dir;
}
}
return side_dir;
}
function do_side_death_fx(localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump)
{
self endon( "entityshutdown" );
vehicle::wait_for_DObj( localClientNum );
radius = 1;
fxlength = 40;
fxtag = "tag_body";
if( newVal && !bInitialSnap )
{
if(!isdefined(self.settings))
{
self.settings = struct::get_script_bundle( "vehiclecustomsettings", self.scriptbundlesettings );
}
forward_direction = AnglesToForward( self.angles );
up_direction = AnglesToUp( self.angles );
origin = self GetTagOrigin( fxtag );
if ( !isdefined( origin ) )
{
origin = self.origin + (0,0,15);
}
right_direction = VectorCross(forward_direction, up_direction);
right_direction = VectorNormalize(right_direction);
right_start = origin + right_direction * radius;
right_direction = adjust_side_death_dir_if_trace_fail( right_start, right_direction, fxlength, up_direction );
left_direction = -right_direction;
left_start = origin + left_direction * radius;
left_direction = adjust_side_death_dir_if_trace_fail( left_start, left_direction, fxlength, up_direction );
if( isdefined( self.settings.sideExplosionFx ) )
{
playfx(localClientNum, self.settings.sideExplosionFx, right_start, right_direction );
playfx(localClientNum, self.settings.sideExplosionFx, left_start, left_direction );
}
if( isdefined( self.settings.killedexplosionfx ) )
{
playfx(localClientNum, self.settings.killedexplosionfx, origin, (0,0,1) );
}
self PlaySound( localClientNum, self.deathfxsound );
if ( isdefined( self.deathquakescale ) && self.deathquakescale > 0 )
{
self Earthquake( self.deathquakescale, self.deathquakeduration, origin, self.deathquakeradius );
}
}
}
File diff suppressed because it is too large. Load diff
+30
View File
@@ -0,0 +1,30 @@
Line truncated
#using scripts\codescripts\struct;
#using scripts\shared\clientfield_shared;
#using scripts\shared\system_shared;
#using scripts\shared\vehicle_shared;
#using scripts\shared\callbacks_shared;
#using scripts\shared\weapons\spike_charge_siegebot;
#namespace siegebot;
function autoexec main()
{
vehicle::add_vehicletype_callback( "siegebot", &_setup_ );
}
function _setup_( localClientNum )
{
if( isdefined( self.scriptbundlesettings ) )
{
settings = struct::get_script_bundle( "vehiclecustomsettings", self.scriptbundlesettings );
}
if ( !isdefined( settings ) )
{
return;
}
}
File diff suppressed because it is too large. Load diff
+45
View File
@@ -0,0 +1,45 @@
#using scripts\codescripts\struct;
#using scripts\shared\callbacks_shared;
#using scripts\shared\clientfield_shared;
#using scripts\shared\filter_shared;
#using scripts\shared\system_shared;
#using scripts\shared\util_shared;
#using scripts\shared\vehicle_shared;
#using scripts\shared\archetype_shared\archetype_shared;
Line truncated
#namespace wasp;
function autoexec __init__sytem__() { system::register("wasp",&__init__,undefined,undefined); }
function __init__()
{
// clientfield setup
clientfield::register( "vehicle", "rocket_wasp_hijacked", 1, 1, "int", &handle_lod_display_for_driver, !true, !true );
level.sentinelBundle = struct::get_script_bundle( "killstreak", "killstreak_sentinel" );
if( isdefined( level.sentinelBundle ) )
vehicle::add_vehicletype_callback( level.sentinelBundle.ksVehicle, &spawned );
}
function spawned( localClientNum )
{
self.killstreakBundle = level.sentinelBundle;
}
function handle_lod_display_for_driver(localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump)
{
self endon( "entityshutdown" );
if( isDefined( self ) )
{
if( self IsLocalClientDriver( localClientNum ))
{
self SetHighDetail( true );
wait 0.05;
self vehicle::lights_off( localClientNum );
}
}
}
File diff suppressed because it is too large. Load diff