4 #using scripts\codescripts\struct;
6 #using scripts\shared\_oob;
7 #using scripts\shared\callbacks_shared;
8 #using scripts\shared\clientfield_shared;
9 #using scripts\shared\gameskill_shared;
10 #using scripts\shared\math_shared;
11 #using scripts\shared\scoreevents_shared;
12 #using scripts\shared\statemachine_shared;
13 #using scripts\shared\system_shared;
14 #using scripts\shared\array_shared;
15 #using scripts\shared\util_shared;
17 #using scripts\shared\vehicle_shared;
18 #using scripts\shared\vehicle_death_shared;
19 #using scripts\shared\vehicle_ai_shared;
21 #using scripts\shared\ai\systems\blackboard;
22 #using scripts\shared\ai\blackboard_vehicle;
24 #using scripts\shared\turret_shared;
25 #using scripts\shared\weapons\_spike_charge_siegebot;
27 #insert scripts\mp\_hacker_tool.gsh;
28 #insert scripts\shared\shared.gsh;
29 #insert scripts\shared\statemachine.gsh;
30 #insert scripts\shared\archetype_shared\archetype_shared.gsh;
32 #using scripts\mp\killstreaks\_killstreaks;
33 #using scripts\mp\killstreaks\_killstreak_bundles;
34 #using scripts\mp\gametypes\_loadout;
36 #insert scripts\shared\ai\utility.gsh;
37 #insert scripts\shared\version.gsh;
39 #define JUMP_COOLDOWN 7
40 #define DEBUG_ON false
42 #define SIEGEBOT_BUNDLE "siegebot"
43 #define SIEGEBOT_MISSILE_TURRET_INDEX 2 // number similiarly to Gunner1, Gunner2, etc.
44 #define SIEGEBOT_MISSILE_COUNT_AFTER_RELOAD 3
46 #define SIEGEBOT_RIGHT_ARM_TRACE_TAG "tag_turret"
47 #define SIEGEBOT_RIGHT_ARM_TRACE_OFFSET 60 // relative to right axis
48 #define SIEGEBOT_RIGHT_ARM_TRACE_START 40 // relative to forward
49 #define SIEGEBOT_RIGHT_ARM_TRACE_END -30 // relative to forward
51 #define SIEGEBOT_LEFT_ARM_TRACE_TAG "tag_turret"
52 #define SIEGEBOT_LEFT_ARM_TRACE_OFFSET -60
53 #define SIEGEBOT_LEFT_ARM_TRACE_START 40 // relative to forward
54 #define SIEGEBOT_LEFT_ARM_TRACE_END -30 // relative to forward
56 #define SIEGEBOT_ARM_TRACE_CLIP_MASK PHYSICS_TRACE_MASK_PHYSICS | PHYSICS_TRACE_MASK_CLIP
58 #define SIEGEBOT_ROCKET_WALL_TRACE_TAG "tag_gunner_flash2b"
59 #define SIEGEBOT_ROCKET_WALL_TRACE_START 12 // relative to forward
60 #define SIEGEBOT_ROCKET_WALL_TRACE_END -12 // relative to forward
61 #define SIEGEBOT_ROCKET_WALL_RELATIVE_TAG "tag_turret"
63 #define SIEGEBOT_ROCKET_WALL_TAG "tag_turret" // to re-aim when rocket will shoot through a wall
64 #define SIEGEBOT_ROCKET_WALL_FORWARD_OFFSET 100
65 #define SIEGEBOT_ROCKET_WALL_RIGHT_OFFSET 40
66 #define SIEGEBOT_ROCKET_WALL_Z_OFFSET 500
67 #define SIEGEBOT_ROCKET_WALL_BLOCKED_FRAMES 10 // how many frames not check wall block after becoming blocked
74 #using_animtree( "generic" );
88 self useanimtree( #animtree );
93 self.health =
self.healthdefault;
94 self.spawnTime = GetTime();
95 self.is_oob_kill_target =
true;
96 self.isStunned =
false;
97 self.missiles_disabled =
false;
103 self.targetOffset = ( 0, 0, 84 );
106 self EnableAimAssist();
107 self SetNearGoalNotifyDist( 40 );
109 self.fovcosine = 0.5;
110 self.fovcosinebusy = 0.5;
111 self.maxsightdistsqrd =
SQR( 10000 );
113 assert( isdefined(
self.scriptbundlesettings ) );
117 self.goalRadius = 9999999;
118 self.goalHeight = 5000;
119 self SetGoal(
self.origin,
false,
self.goalRadius,
self.goalHeight );
125 self SetGunnerTurretOnTargetRange( 0,
self.settings.gunner_turret_on_target_range );
127 self ASMRequestSubstate(
"locomotion@movement" );
129 if(
self.vehicletype ===
"spawner_enemy_boss_siegebot_zombietron" )
131 self ASMSetAnimationRate( 0.5 );
132 self HidePart(
"tag_turret_canopy_animate" );
133 self HidePart(
"tag_turret_panel_01_d0" );
134 self HidePart(
"tag_turret_panel_02_d0" );
135 self HidePart(
"tag_turret_panel_03_d0" );
136 self HidePart(
"tag_turret_panel_04_d0" );
137 self HidePart(
"tag_turret_panel_05_d0" );
139 else if(
self.vehicletype ==
"zombietron_veh_siegebot" )
141 self ASMSetAnimationRate( 1.429 );
147 if( IsDefined( level.vehicle_initializer_cb ) )
149 [[level.vehicle_initializer_cb]]( self );
152 self.ignoreFireFly =
true;
153 self.ignoreDecoy =
true;
158 self.ignoreme =
true;
163 self.heatlh =
self.maxhealth;
179 scale_up = mapfloat( 0, 9, 0.8, 2.0, value );
180 scale_down = mapfloat( 0, 9, 1.0, 0.5, value );
182 self.difficulty_scale_up = scale_up;
183 self.difficulty_scale_down = scale_down;
226 self endon(
"death" );
227 self endon(
"nodeath_thread" );
230 StreamerModelHint(
self.deathmodel, 6 );
233 if ( !isdefined( death_type ) )
235 params.death_type =
"gibbed";
236 death_type = params.death_type;
241 self SetTurretSpinning(
false );
245 self playsound(
"veh_quadtank_sparks");
247 if (
self.vehicletype ===
"spawner_enemy_boss_siegebot_zombietron" )
249 self ASMSetAnimationRate( 1.0 );
252 self.turretRotScale = 3;
253 self SetTurretTargetRelativeAngles( (0,0,0), 0 );
254 self SetTurretTargetRelativeAngles( (0,0,0), 1 );
255 self SetTurretTargetRelativeAngles( (0,0,0), 2 );
257 self ASMRequestSubstate(
"death@stationary" );
259 self waittill(
"model_swap" );
264 self waittill(
"bodyfall large" );
267 self RadiusDamage(
self.origin + (0,0,10),
self.radius * 0.8, 150, 60,
self,
"MOD_CRUSH" );
285 self ClearTargetEntity();
287 self ClearVehGoalPos();
292 self endon(
"death" );
293 self endon(
"exit_vehicle" );
299 selfup = AnglesToUp(
self.angles );
300 worldup = ( 0, 0, 1 );
302 if ( VectorDot( selfup, worldup ) < 0.64 )
311 if ( tileCount > 20 )
313 driver =
self GetSeatOccupant( 0 );
314 self Kill(
self.origin );
323 self endon(
"death" );
324 self endon(
"exit_vehicle" );
327 driver =
self GetSeatOccupant( 0 );
329 if ( !isdefined( driver ) )
334 while( isdefined( driver ) )
336 if( driver FragButtonPressed() && !
self.missiles_disabled )
339 wait weapon.fireTime;
350 self endon(
"death" );
351 self endon(
"exit_vehicle" );
353 rocket_wall_blocked_count = 0;
354 use_old_trace =
true;
361 use_old_trace =
true;
364 if ( rocket_wall_blocked_count > 0 )
368 forward = AnglesToForward( ref_angles );
369 right = AnglesToRight( ref_angles );
375 rocket_wall_blocked_count--;
380 use_old_trace =
false;
393 if ( !isdefined(
self.abnormal_status ) )
395 self.abnormal_status = spawnStruct();
398 self.abnormal_status.emped =
true;
399 self.abnormal_status.attacker = params.notify_param[1];
400 self.abnormal_status.inflictor = params.notify_param[2];
407 self endon(
"death" );
408 self endon(
"change_state" );
412 if (
self.vehicletype ===
"spawner_enemy_boss_siegebot_zombietron" )
414 self ASMSetAnimationRate( 1.0 );
417 asmState =
"damage_2@pain";
418 self ASMRequestSubstate( asmState );
441 self._enablePain = enabled;
446 self endon(
"death" );
447 self endon(
"change_state" );
451 if (
self.vehicletype ===
"spawner_enemy_boss_siegebot_zombietron" )
453 self ASMSetAnimationRate( 1.0 );
456 if (
self.newDamageLevel == 3 )
458 asmState =
"damage_2@pain";
462 asmState =
"damage_1@pain";
465 self ASMRequestSubstate( asmState );
479 self endon(
"death" );
480 self endon(
"change_state" );
482 self SetTurretTargetRelativeAngles( (0,90,0), 1 );
483 self SetTurretTargetRelativeAngles( (0,90,0), 2 );
496 self endon(
"death" );
497 self endon(
"change_state" );
498 self notify(
"end_movement_thread" );
499 self endon(
"end_movement_thread" );
505 foundpath =
self SetVehGoalPos(
self.current_pathto_pos,
false,
true );
512 self notify(
"near_goal" );
514 self ClearVehGoalPos();
529 if(
self.goalforced )
534 minSearchRadius = 500;
535 maxSearchRadius = 1500;
539 queryResult = PositionQuery_Source_Navigation(
self.origin, minSearchRadius, maxSearchRadius, halfHeight, spacing,
self, spacing );
540 PositionQuery_Filter_DistanceToGoal( queryResult,
self );
543 forward = AnglesToForward(
self.angles );
544 foreach ( point
in queryResult.data )
546 ADD_POINT_SCORE( point,
"random", randomFloatRange( 0, 30 ) );
548 pointDirection = VectorNormalize( point.origin -
self.origin );
549 factor = VectorDot( pointDirection, forward );
552 ADD_POINT_SCORE( point,
"directionDiff", 600 );
554 else if ( factor > 0 )
556 ADD_POINT_SCORE( point,
"directionDiff", 0 );
558 else if ( factor > -0.5 )
560 ADD_POINT_SCORE( point,
"directionDiff", -600 );
564 ADD_POINT_SCORE( point,
"directionDiff", -1200 );
571 if( queryResult.data.size == 0 )
574 return queryResult.data[0].origin;
582 if ( isdefined(
self.jump ) && isDefined(
self.jump.linkEnt) )
584 self.jump.linkEnt Delete();
590 entToWatch waittill(
"death");
597 if ( isdefined(
self.jump ) )
600 self.jump.linkEnt Delete();
604 self.jump = spawnstruct();
605 self.jump.linkEnt =
Spawn(
"script_origin",
self.origin );
607 self.jump.in_air =
false;
620 return (
self.vehicletype ===
"spawner_enemy_boss_siegebot_zombietron" );
625 goal = params.jumpgoal;
627 trace = PhysicsTrace( goal + ( 0, 0, 500 ), goal - ( 0, 0, 10000 ), ( -10, -10, -10 ), ( 10, 10, 10 ),
self,
PHYSICS_TRACE_MASK_VEHICLE );
630 /#debugstar( goal, 60000, (0,1,0) ); #/
631 /#debugstar(
trace[
"position" ], 60000, (0,1,0) ); #/
632 /#line(goal,
trace[
"position" ], (0,1,0), 1,
false, 60000 ); #/
634 if (
trace[
"fraction" ] < 1 )
636 goal =
trace[
"position" ];
639 self.jump.goal = goal;
641 params.scaleForward = 40;
642 params.gravityForce = (0, 0, -6);
643 params.upByHeight = 50;
644 params.landingState =
"land@jump";
653 self endon(
"change_state" );
654 self endon(
"death" );
656 goal =
self.jump.goal;
660 self.jump.linkEnt.origin =
self.origin;
661 self.jump.linkEnt.angles =
self.angles;
665 self LinkTo(
self.jump.linkEnt );
667 self.jump.in_air =
true;
671 /#debugstar( goal, 60000, (0,1,0) ); #/
672 /#debugstar( goal + (0,0,100), 60000, (0,1,0) ); #/
673 /#line(goal, goal + (0,0,100), (0,1,0), 1,
false, 60000 ); #/
677 totalDistance = Distance2D(goal,
self.jump.linkEnt.origin);
678 forward =
FLAT_ORIGIN( ((goal -
self.jump.linkEnt.origin) / totalDistance) );
679 upByDistance = MapFloat( 500, 2000, 46, 52, totalDistance );
680 antiGravityByDistance = 0;
682 initVelocityUp = (0,0,1) * ( upByDistance + params.upByHeight );
683 initVelocityForward = forward * params.scaleForward * MapFloat( 500, 2000, 0.8, 1, totalDistance );
684 velocity = initVelocityUp + initVelocityForward;
687 if (
self.vehicletype ===
"spawner_enemy_boss_siegebot_zombietron" )
689 self ASMSetAnimationRate( 1.0 );
692 self ASMRequestSubstate(
"inair@jump" );
693 self waittill(
"engine_startup" );
695 self waittill(
"leave_ground" );
700 distanceToGoal = Distance2D(
self.jump.linkEnt.origin, goal);
702 antiGravityScaleUp = 1.0;
703 antiGravityScale = 1.0;
704 antiGravity = (0,0,0);
705 if (
DEBUG_ON ) /#line(
self.jump.linkEnt.origin,
self.jump.linkEnt.origin + antiGravity, (0,1,0), 1,
false, 60000 ); #/
707 velocityForwardScale = MapFloat( (
self.radius * 1), (
self.radius * 4), 0.2, 1, distanceToGoal );
708 velocityForward = initVelocityForward * velocityForwardScale;
709 if (
DEBUG_ON ) /#line(
self.jump.linkEnt.origin,
self.jump.linkEnt.origin + velocityForward, (0,1,0), 1,
false, 60000 ); #/
711 oldVerticleSpeed = velocity[2];
712 velocity = (0,0, velocity[2]);
713 velocity += velocityForward + params.gravityForce + antiGravity;
715 if ( oldVerticleSpeed > 0 && velocity[2] < 0 )
717 self ASMRequestSubstate(
"fall@jump" );
720 if ( velocity[2] < 0 &&
self.jump.linkEnt.origin[2] + velocity[2] < goal[2] )
725 heightThreshold = goal[2] + 110;
726 oldHeight =
self.jump.linkEnt.origin[2];
727 self.jump.linkEnt.origin += velocity;
729 if (
self.jump.linkEnt.origin[2] < heightThreshold && ( oldHeight > heightThreshold || ( oldVerticleSpeed > 0 && velocity[2] < 0 ) ) )
731 self notify(
"start_landing" );
732 self ASMRequestSubstate( params.landingState );
735 if (
DEBUG_ON ) /#debugstar(
self.jump.linkEnt.origin, 60000, (1,0,0) ); #/
740 self.jump.linkEnt.origin =
FLAT_ORIGIN(
self.jump.linkEnt.origin ) + ( 0, 0, goal[2] );
741 self notify(
"land_crush" );
744 foreach( player
in level.players )
746 player._takedamage_old = player.takedamage;
747 player.takedamage =
false;
749 self RadiusDamage(
self.origin + ( 0,0,15 ),
self.radiusdamageradius,
self.radiusdamagemax,
self.radiusdamagemin,
self,
"MOD_EXPLOSIVE" );
751 foreach( player
in level.players )
753 player.takedamage = player._takedamage_old;
754 player._takedamage_old = undefined;
756 if ( Distance2DSquared(
self.origin, player.origin ) <
SQR( 200 ) )
758 direction =
FLAT_ORIGIN( ( player.origin -
self.origin ) );
759 if ( Abs( direction[0] ) < 0.01 && Abs( direction[1] ) < 0.01 )
761 direction = ( RandomFloatRange( 1, 2 ), RandomFloatRange( 1, 2 ), 0 );
763 direction = VectorNormalize( direction );
765 player SetVelocity( player GetVelocity() + direction * strength );
767 if ( player.health > 80 )
769 player DoDamage( player.health - 70,
self.origin,
self );
786 self.jump.in_air =
false;
788 self notify (
"jump_finished" );
806 self endon(
"death" );
807 self endon(
"change_state" );
816 self ClearTurretTarget();
817 self SetTurretSpinning(
false );
822 if(
self.vehicletype ===
"spawner_enemy_boss_siegebot_zombietron" )
824 self ASMSetAnimationRate( 0.5 );
827 self ASMRequestSubstate(
"locomotion@movement" );
832 if(
self.goalforced )
837 maxSearchRadius = 800;
842 queryResult = PositionQuery_Source_Navigation(
self.origin, 0, maxSearchRadius, halfHeight, innerSpacing,
self, outerSpacing );
843 PositionQuery_Filter_DistanceToGoal( queryResult,
self );
846 if( isdefined(
self.enemy ) )
848 PositionQuery_Filter_Sight( queryResult,
self.enemy.origin,
self GetEye() -
self.origin,
self, 0,
self.enemy );
852 foreach ( point
in queryResult.data )
854 ADD_POINT_SCORE( point,
"random", randomFloatRange( 0, 30 ) );
856 if( point.disttoorigin2d < 120 )
858 ADD_POINT_SCORE( point,
"tooCloseToSelf", (120 - point.disttoorigin2d) * -1.5 );
861 if( isdefined(
self.enemy ) )
863 ADD_POINT_SCORE( point,
"engagementDist", -point.distAwayFromEngagementArea );
865 if ( !point.visibility )
867 ADD_POINT_SCORE( point,
"visibility", -600 );
875 if( queryResult.data.size == 0 )
878 return queryResult.data[0].origin;
883 self endon(
"death" );
884 self endon(
"change_state" );
885 self endon(
"near_goal" );
886 self endon(
"reached_end_node" );
888 canSeeEnemyCount = 0;
890 old_enemy =
self.enemy;
892 startPath = GetTime();
893 old_origin =
self.origin;
900 self SetMaxSpeedScale( 1 );
901 self SetMaxAccelerationScale( 1 );
902 self SetSpeed(
self.settings.defaultMoveSpeed );
904 if ( isdefined(
self.enemy ) )
906 selfDistToTarget = Distance2D(
self.origin,
self.enemy.origin );
908 farEngagementDist =
self.settings.engagementDistMax + 150;
909 closeEngagementDist =
self.settings.engagementDistMin - 150;
911 if(
self VehCanSee(
self.enemy ) )
913 self SetLookAtEnt(
self.enemy );
914 self SetTurretTargetEnt(
self.enemy );
917 if( selfDistToTarget < farEngagementDist && selfDistToTarget > closeEngagementDist )
922 if( canSeeEnemyCount > 3 && (
vehicle_ai::TimeSince( startPath ) > 5 || Distance2DSquared( old_origin,
self.origin ) >
SQR( move_dist ) ) )
924 self notify(
"near_goal" );
930 self SetMaxSpeedScale( 2.5 );
931 self SetMaxAccelerationScale( 3 );
932 self SetSpeed(
self.settings.defaultMoveSpeed * 2 );
935 else if( (!
self VehSeenRecently(
self.enemy, 1.5 ) &&
self VehSeenRecently(
self.enemy, 15 )) || selfDistToTarget > farEngagementDist )
937 self SetMaxSpeedScale( 1.8 );
938 self SetMaxAccelerationScale( 2 );
939 self SetSpeed(
self.settings.defaultMoveSpeed * 1.5 );
944 canSeeEnemyCount = 0;
947 if ( isdefined(
self.enemy ) )
949 if( !isdefined( old_enemy ) )
951 self notify(
"near_goal" );
953 else if(
self.enemy != old_enemy )
955 self notify(
"near_goal" );
958 if(
self VehCanSee(
self.enemy ) && distance2dSquared(
self.origin,
self.enemy.origin ) <
SQR( 150 ) && Distance2DSquared( old_origin,
self.enemy.origin ) >
SQR( 151 ) )
960 self notify(
"near_goal" );
970 self endon(
"death" );
971 self notify(
"weapon_doors_state" );
972 self endon(
"weapon_doors_state" );
974 if ( isdefined( waittime ) && waittime > 0 )
984 self endon(
"death" );
985 self endon(
"change_state" );
986 self notify(
"end_movement_thread" );
987 self endon(
"end_movement_thread" );
993 if(
self.vehicletype ===
"spawner_enemy_boss_siegebot_zombietron" )
997 params = SpawnStruct();
998 params.jumpgoal =
self.current_pathto_pos;
1006 foundpath =
self SetVehGoalPos(
self.current_pathto_pos,
false,
true );
1010 if ( isdefined(
self.enemy ) &&
self VehSeenRecently(
self.enemy, 1 ) )
1012 self SetLookAtEnt(
self.enemy );
1013 self SetTurretTargetEnt(
self.enemy );
1018 self notify(
"near_goal" );
1019 self CancelAIMove();
1020 self ClearVehGoalPos();
1021 if ( isdefined(
self.enemy ) &&
self VehSeenRecently(
self.enemy, 2 ) )
1029 startAdditionalWaiting = GetTime();
1030 while ( isdefined(
self.enemy ) &&
self VehCanSee(
self.enemy ) &&
vehicle_ai::TimeSince( startAdditionalWaiting ) < 1.5 )
1039 self notify(
"end_movement_thread" );
1040 self notify(
"near_goal" );
1041 self CancelAIMove();
1042 self ClearVehGoalPos();
1043 self ClearTurretTarget();
1044 self ClearLookAtEnt();
1050 if ( !isdefined( targetAngleDiff ) )
1052 targetAngleDiff = 30;
1056 v_to_enemy = VectorNormalize( v_to_enemy );
1057 goalAngles = VectortoAngles( v_to_enemy );
1059 angleDiff = AbsAngleClamp180(
self.angles[1] - goalAngles[1] );
1060 if ( angleDiff <= targetAngleDiff )
1065 self SetLookAtOrigin( position );
1066 self SetTurretTargetVec( position );
1069 angleAdjustingStart = GetTime();
1072 angleDiff = AbsAngleClamp180(
self.angles[1] - goalAngles[1] );
1076 self ClearVehGoalPos();
1077 self ClearLookAtEnt();
1078 self ClearTurretTarget();
1079 self CancelAIMove();
1084 angles =
self GetTagAngles(
"tag_barrel" );
1085 angles = (0,angles[1],0);
1093 forward = AnglesToForward( angles );
1095 aimpos =
self.origin + forward * 1000;
1096 self SetTurretTargetVec( aimpos );
1100 if( isdefined(
self.enemy ) &&
self VehCanSee(
self.enemy ) )
1102 self SetTurretTargetEnt(
self.enemy );
1103 self SetLookAtEnt(
self.enemy );
1110 forward = AnglesToForward(
self.angles );
1112 aimpos =
self.origin + forward * 1000;
1113 self SetTurretTargetVec( aimpos );
1115 self ClearTurretTarget();
1120 self endon(
"death" );
1121 self endon(
"change_state" );
1122 self endon(
"end_attack_thread" );
1123 self notify(
"end_machinegun_attack_thread" );
1124 self endon(
"end_machinegun_attack_thread" );
1126 self.turretrotscale = 1 *
self.difficulty_scale_up;
1132 if( isdefined(
self.enemy ) &&
self VehCanSee(
self.enemy ) )
1134 self SetLookAtEnt(
self.enemy );
1135 self SetTurretTargetEnt(
self.enemy );
1140 self SetTurretSpinning(
true );
1145 self SetGunnerTargetEnt(
self.enemy, (0,0,0), 0 );
1146 self SetGunnerTargetEnt(
self.enemy, (0,0,0), 1 );
1150 if( isdefined(
self.enemy ) && IsAI(
self.enemy ) )
1152 wait( RandomFloatRange( 0.1, 0.2 ) );
1156 wait( RandomFloatRange( 0.2, 0.3 ) ) *
self.difficulty_scale_down;
1162 self SetTurretSpinning(
false );
1163 self ClearGunnerTarget( 0 );
1164 self ClearGunnerTarget( 1 );
1172 if ( isdefined( target ) )
1174 self SetTurretTargetEnt( target );
1175 self SetGunnerTargetEnt( target, (0,0,-10), 2 );
1177 self FireWeapon( 2, target, (0,0,-10) );
1178 self ClearGunnerTarget( 1 );
1184 self endon(
"death" );
1185 self endon(
"change_state" );
1186 self endon(
"end_attack_thread" );
1187 self notify(
"end_rocket_attack_thread" );
1188 self endon(
"end_rocket_attack_thread" );
1196 self SetGunnerTargetEnt(
self.enemy, (0,0,0), 0 );
1197 self SetGunnerTargetEnt(
self.enemy, (0,0,-10), 2 );
1201 if ( isdefined(
self.enemy ) &&
self VehSeenRecently(
self.enemy, 1 ) )
1206 if ( isdefined(
self.enemy ) )
1219 self ClearGunnerTarget( 0 );
1220 self ClearGunnerTarget( 1 );
1228 self endon(
"death" );
1236 self waittill(
"enter_vehicle", player );
1239 self waittill(
"exit_vehicle", player );
1251 self.ignoreme =
false;
1258 if ( IsPlayer( player ) )
1260 player.using_map_vehicle =
true;
1261 player.current_map_vehicle =
self;
1262 player.ignoreme =
true;
1263 self.current_driver = player;
1264 player SetClientUIVisibilityFlag(
"weapon_hud_visible", 0 );
1266 player DisableWeaponCycling();
1269 player.siegebot_kills = undefined;
1278 self.ignoreme =
true;
1282 if ( IsPlayer( player ) )
1284 player.using_map_vehicle = undefined;
1285 player.current_map_vehicle = undefined;
1286 player.ignoreme =
false;
1287 player SetClientUIVisibilityFlag(
"weapon_hud_visible", 1 );
1288 player EnableWeaponCycling();
1293 self.current_driver = undefined;
1301 function siegebot_callback_damage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, vDamageOrigin, psOffsetTime, damageFromUnderneath, modelIndex, partName, vSurfaceNormal )
1303 time_alive = GetTime() -
self.spawnTime;
1305 if ( time_alive < 500 && sMeansOfDeath ==
"MOD_TRIGGER_HURT" )
1309 iDamage =
self killstreaks::OnDamagePerWeapon(
SIEGEBOT_BUNDLE, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon,
self.maxhealth, undefined,
self.maxhealth * 0.4, undefined, 0, undefined,
true, 1.0 );
1313 if(
IS_TRUE( fmj ) && ( !isdefined( weapon.isHeroWeapon ) || !weapon.isHeroWeapon ) )
1315 iDamage = iDamage / 2;
1320 minEmpDownTime = 0.8 *
self.settings.empdowntime;
1321 maxEmpDownTime = 1.2 *
self.settings.empdowntime;
1322 self notify (
"emped", RandomFloatRange( minEmpDownTime, maxEmpDownTime ), eAttacker, eInflictor );
1327 if ( newDamageLevel >
self.damageLevel )
1329 self.damageLevel = newDamageLevel;
1333 driver =
self GetSeatOccupant( 0 );
1334 if ( isPlayer( driver ) )
1338 if ( iDamage >
self.health )
1349 self endon(
"death" );
1353 self waittill(
"emped", down_time, attacker, inflictor );
1355 self thread
emped( down_time );
1361 self notify(
"emped_singleton" );
1362 self endon(
"death" );
1363 self endon(
"emped_singleton" );
1384 if ( IsPlayer( driver ) )
1389 driver SetEMPJammed( value );
1395 self endon(
"death" );
1397 level waittill(
"game_ended");
1405 self DoDamage(
self.health + 1,
self.origin + (0, 0, 60), undefined, undefined,
"none",
"MOD_EXPLOSIVE", 0 );
1413 if ( isdefined(
self ) )
1421 self notify(
"siegebot_watch_death" );
1422 self endon(
"siegebot_watch_death" );
1424 self waittill(
"death" );
1429 if ( IsPlayer(
self.current_driver ) )
1435 StreamerModelHint(
self.deathmodel, 6 );
1447 if ( !isdefined(
self ) )
1450 if (
self.team ==
"neutral" )
1453 if ( !IsPlayer( driver ) )
1456 if ( IsPlayer(
self.attacker ) )
1458 if ( driver ==
self.attacker )
1464 if ( isdefined(
self.attackers ) )
1466 foreach( kill_assist
in self.attackers )
1468 if ( IsPlayer( kill_assist ) )
1470 if (
self.attacker === kill_assist )
1473 if ( !isdefined(
self.attacker ) || kill_assist.team ==
self.attacker.team )
1488 weapon_wait_duration_ms = Int( bundle.ksWeaponReloadTime * 1000 );
1489 player SetVehicleWeaponWaitDuration( weapon_wait_duration_ms );
1490 player SetVehicleWeaponWaitEndTime( GetTime() + weapon_wait_duration_ms );
1492 wait ( bundle.ksWeaponReloadTime );
1504 self.numberRockets = rocket_count;
1510 self.missiles_disabled =
false;
1516 self.missiles_disabled =
true;
1522 self endon(
"death" );
1523 self endon(
"exit_vehicle" );
1525 if (
self.numberRockets <= 0 )
1539 player waittill(
"missile_fire", missile );
1541 missile.ignore_team_kills =
self.ignore_team_kills;
1547 if (
self.numberRockets <= 0 )
1554 if ( !driver_only_update )
1559 if ( IsPlayer(
self.current_driver ) )
1568 self notify(
"arm_test" );
1569 self endon(
"arm_test" );
1571 level endon(
"game_ended" );
1590 DEFAULT(
self.left_arm_retracted,
false );
1591 if (
self.left_arm_retracted )
1594 self.left_arm_retracted =
true;
1596 self UseAnimTree( #animtree );
1598 self ClearAnim( %ai_siegebot_base_mp_left_arm_extend, 0.2 );
1599 self SetAnim( %ai_siegebot_base_mp_left_arm_retract, 1.0 );
1604 DEFAULT(
self.left_arm_retracted,
false );
1605 if ( !
self.left_arm_retracted )
1608 self.left_arm_retracted =
false;
1610 self UseAnimTree( #animtree );
1613 self ClearAnim( %ai_siegebot_base_mp_left_arm_retract, 0.2 );
1614 self SetAnim( %ai_siegebot_base_mp_left_arm_extend, 1.0, 0.0 );
1618 if (
self.left_arm_retracted ==
false )
1619 self ClearAnim( %ai_siegebot_base_mp_left_arm_extend, 0.1 );
1624 DEFAULT(
self.right_arm_retracted,
false );
1625 if (
self.right_arm_retracted )
1628 self.right_arm_retracted =
true;
1630 self UseAnimTree( #animtree );
1632 self ClearAnim( %ai_siegebot_base_mp_right_arm_extend, 0.2 );
1633 self SetAnim( %ai_siegebot_base_mp_right_arm_retract, 1.0 );
1638 DEFAULT(
self.right_arm_retracted,
false );
1639 if ( !
self.right_arm_retracted )
1642 self.right_arm_retracted =
false;
1644 self UseAnimTree( #animtree );
1646 self ClearAnim( %ai_siegebot_base_mp_right_arm_retract, 0.2 );
1647 self SetAnim( %ai_siegebot_base_mp_right_arm_extend, 1.0 );
1651 if (
self.right_arm_retracted ==
false )
1652 self ClearAnim( %ai_siegebot_base_mp_right_arm_extend, 0.1 );
1657 self endon(
"death" );
1658 self endon(
"exit_vehicle" );
1660 wait RandomFloatRange( 0.05, 0.3 );
1667 forward = AnglesToForward( ref_angles );
1668 right = AnglesToRight( ref_angles );
1680 if (
trace[
"fraction"] < 1.0 )
1691 self endon(
"death" );
1692 self endon(
"exit_vehicle" );
1694 wait RandomFloatRange( 0.05, 0.3 );
1701 forward = AnglesToForward( ref_angles );
1702 right = AnglesToRight( ref_angles );
1714 if (
trace[
"fraction"] < 1.0 )
1725 if ( use_old_trace && isdefined(
self.rocket_wall_origin_offset ) )
1728 base_forward = AnglesToForward( base_tag_angles );
1729 base_right = AnglesToRight( base_tag_angles );
1730 base_up = AnglesToUp( base_tag_angles );
1732 offset =
self.rocket_wall_origin_offset;
1733 ref_origin =
self.origin + ( offset[0] * base_forward ) + ( offset[1] * base_right ) + ( offset[2] * base_up );
1734 ref_angles = base_tag_angles +
self.rocket_wall_angles_offset;
1742 forward = AnglesToForward( ref_angles );
1752 shoot_through_wall = (
trace[
"fraction"] < 1.0 );
1754 if ( shoot_through_wall )
1756 if ( !isdefined( base_tag_angles ) )
1759 base_forward = AnglesToForward( base_tag_angles );
1760 base_right = AnglesToRight( base_tag_angles );
1761 base_up = AnglesToUp( base_tag_angles );
1764 ref_offset = ref_origin -
self.origin;;
1766 self.rocket_wall_origin_offset = ( VectorDot( ref_offset, base_forward), VectorDot( ref_offset, base_right ), VectorDot( ref_offset, base_up ) ) ;
1767 self.rocket_wall_angles_offset = ref_angles - base_tag_angles;
1770 return shoot_through_wall;
1777 if ( isdefined( player ) && isdefined( player.current_map_vehicle ) )
1779 player.current_map_vehicle notify(
"exit_vehicle", player );