1 #using scripts\codescripts\struct;
3 #using scripts\shared\ai_shared;
4 #using scripts\shared\array_shared;
5 #using scripts\shared\callbacks_shared;
6 #using scripts\shared\colors_shared;
7 #using scripts\shared\flag_shared;
8 #using scripts\shared\gameskill_shared;
9 #using scripts\shared\serverfaceanim_shared;
10 #using scripts\shared\system_shared;
11 #using scripts\shared\trigger_shared;
12 #using scripts\shared\turret_shared;
13 #using scripts\shared\util_shared;
15 #insert scripts\shared\shared.gsh;
20 #define XP_DISPLAY_TOTAL_TIME 40
21 #define XP_DISPLAY_MAX_HEIGHT_OFFSET 45
22 #define XP_DISPLAY_DELAY_BEFORE_FADE 20
23 #define DEBUG_DAMAGE_DISPLAY_COLOR (0.96, 0.12, 0.12)
24 #define DEBUG_XP_DISPLAY_COLOR (0.83, 0.18, 0.76)
43 if( GetDvarString(
"noai" ) ==
"" )
45 SetDvar(
"noai",
"off" );
53 level._nextcoverprint = 0;
57 level.missionfailed =
false;
58 level.gather_delay = [];
59 level.smoke_thrown = [];
60 level.deathflags = [];
61 level.spawner_number = 0;
62 level.go_to_node_arrays = [];
64 level.next_health_drop_time = 0;
65 level.guys_to_die_before_next_health_drop = RandomIntRange( 1, 4 );
66 level.portable_mg_gun_tag =
"J_Shoulder_RI";
67 level.mg42_hide_distance = 1024;
69 level.global_spawn_timer = 0;
70 level.global_spawn_count = 0;
72 if( !isdefined( level.maxFriendlies ) )
74 level.maxFriendlies = 11;
77 level.ai_classname_in_level = [];
79 spawners = GetSpawnerArray();
80 for( i = 0; i < spawners.size; i++ )
107 ai = GetAISpeciesArray(
"all" );
110 foreach( ai_guy
in ai )
112 if ( IsAlive( ai_guy ) )
124 level.valid_navmesh_positions = [];
126 a_nav_triggers = GetEntArray(
"trigger_navmesh",
"classname" );
128 if ( !a_nav_triggers.size )
135 level.navmesh_zones = [];
136 foreach ( trig
in a_nav_triggers )
138 level.navmesh_zones[ trig.targetname ] =
false;
191 self waittill(
"death" );
193 if ( isdefined(
self ) )
196 if( IsDefined( level.ai ) && IsDefined( level.ai[
self.team ] ) && IsInArray( level.ai[
self.team ],
self ) )
198 ArrayRemoveValue( level.ai[
self.team ],
self );
203 foreach( aiArray
in level.ai )
205 if( IsInArray( aiArray,
self ) )
207 ArrayRemoveValue( aiArray,
self );
215 foreach ( team,
array in level.ai )
217 for ( i =
array.size - 1; i >= 0; i-- )
219 if ( !isdefined(
array[ i ] ) )
221 ArrayRemoveIndex(
array, i );
234 level.global_spawn_count = 0;
240 if ( !
IS_TRUE( level.first_frame ) )
242 while ( level.global_spawn_count >= n_count_per_network_frame )
247 level.global_spawn_count++;
258 volumes = GetEntArray(
"info_volume",
"classname" );
259 level.deathchain_goalVolume = [];
260 level.goalVolumes = [];
262 for ( i = 0; i < volumes.size; i++ )
264 volume = volumes[ i ];
265 if ( isdefined( volume.script_deathChain ) )
267 level.deathchain_goalVolume[ volume.script_deathChain ] = volume;
269 if ( isdefined( volume.script_goalvolume ) )
271 level.goalVolumes[ volume.script_goalVolume ] = volume;
278 level.ai_classname_in_level_keys = getarraykeys( level.ai_classname_in_level );
279 for ( i = 0 ; i < level.ai_classname_in_level_keys.size ; i++ )
281 if( weapon_names.size <= 0 )
286 for( j = 0 ; j < weapon_names.size ; j++ )
288 weaponName = weapon_names[j];
290 if ( !issubstr( tolower( level.ai_classname_in_level_keys[ i ] ), weaponName ) )
295 ArrayRemoveValue( weapon_names, weaponName );
299 level.ai_classname_in_level_keys = undefined;
304 keys = getarraykeys( level.deathflags );
305 level.deathflags = [];
306 for ( i=0; i < keys.size; i++ )
308 deathflag = keys[ i ];
309 level.deathflags[ deathflag ] = [];
310 level.deathflags[ deathflag ][
"ai" ] = [];
312 if ( !isdefined( level.flag[ deathflag ] ) )
322 self endon(
"death" );
323 self waittill(
"count_gone" );
328 assert( isdefined( spawners ) && spawners.size,
"Script tried to flood spawn without any spawners" );
336 spawner endon(
"death" );
338 self waittill(
"death" );
339 if( !isdefined(
self ) )
347 if( !isdefined( trigger ) )
352 if( ( isdefined( trigger.targetname ) ) &&( trigger.targetname !=
"flood_spawner" ) )
362 self endon(
"death" );
363 self waittill(
"pain_death" );
371 if( !isdefined(
self ) )
376 if(
self.grenadeAmmo <= 0 )
381 if( isdefined(
self.dropweapon ) && !
self.dropweapon )
386 if (!IsDefined( level.nextGrenadeDrop ))
388 level.nextGrenadeDrop = RandomInt(3);
391 level.nextGrenadeDrop--;
392 if( level.nextGrenadeDrop > 0 )
397 level.nextGrenadeDrop = 2 + RandomInt( 2 );
400 spawn_grenade_bag(
self.origin +( RandomInt( max )-min, RandomInt( max )-min, 2 ) +( 0, 0, 42 ), ( 0, RandomInt( 360 ), 0 ),
self.team );
425 if( !isdefined( level.grenade_cache ) || !isdefined( level.grenade_cache[team] ) )
427 level.grenade_cache_index[team] = 0;
428 level.grenade_cache[team] = [];
431 index = level.grenade_cache_index[team];
432 grenade = level.grenade_cache[team][index];
433 if( isdefined( grenade ) )
438 count =
self.grenadeammo;
439 grenade =
sys::Spawn(
"weapon_" +
self.grenadeWeapon.name + level.game_mode_suffix, origin );
440 level.grenade_cache[team][index] = grenade;
441 level.grenade_cache_index[team] = ( index + 1 ) % 16;
443 grenade.angles = angles;
444 grenade.count = count;
451 assert(
self != level );
453 level.ai_classname_in_level[
self.classname ] =
true;
456 if (GetDvarString (
"noai") !=
"off")
467 if( isdefined(
self.script_aigroup ) )
472 if( isdefined(
self.script_delete ) )
475 if( isdefined( level._ai_delete ) )
477 if( isdefined( level._ai_delete[
self.script_delete] ) )
479 array_size = level._ai_delete[
self.script_delete].size;
483 level._ai_delete[
self.script_delete][array_size] =
self;
486 if ( isdefined(
self.target ) )
494 level notify(
"update_nav_triggers" );
496 while ( IsAlive(
self ) )
499 level notify(
"update_nav_triggers" );
506 self endon(
"death" );
510 if ( IsDefined(
self.spawn_think_thread_active ) )
513 self.spawn_think_thread_active =
true;
515 self.spawner = spawner;
517 assert( IsActor(
self ) || IsVehicle(
self ), __FUNCTION__ +
" only supports actors and vehicles." );
519 if ( !IsVehicle(
self ) )
521 if ( !IsAlive(
self ) )
526 self.maxhealth =
self.health;
531 self.script_animname = undefined;
533 if ( isdefined(
self.script_aigroup ) )
535 level
flag::set(
self.script_aigroup +
"_spawning" );
536 self thread
aigroup_think( level._ai_group[
self.script_aigroup ] );
539 if ( isdefined( spawner ) && isdefined( spawner.script_dropAmmo ) )
541 self.disableAmmoDrop = !spawner.script_dropAmmo;
544 if ( isdefined( spawner ) && isdefined( spawner.spawn_funcs ) )
546 self.spawn_funcs = spawner.spawn_funcs;
553 assert( IsAlive(
self ) );
554 assert( isdefined(
self.team ) );
559 self.finished_spawning =
true;
560 self notify(
"finished spawning" );
565 self endon(
"death" );
567 if ( !isdefined( level.spawn_funcs ) )
572 if ( isdefined(
self.archetype ) && isdefined( level.spawn_funcs[
self.archetype ] ) )
574 for (i = 0; i < level.spawn_funcs[
self.archetype ].size; i++)
576 func = level.spawn_funcs[
self.archetype ][ i ];
577 util::single_thread(
self, func[
"function" ], func[
"param1" ], func[
"param2" ], func[
"param3" ], func[
"param4" ], func[
"param5" ] );
585 if ( IsDefined( level.spawn_funcs[
self.team ] ) )
587 for (i = 0; i < level.spawn_funcs[
self.team ].size; i++)
589 func = level.spawn_funcs[
self.team ][ i ];
590 util::single_thread(
self, func[
"function" ], func[
"param1" ], func[
"param2" ], func[
"param3" ], func[
"param4" ], func[
"param5" ] );
594 if ( isdefined(
self.spawn_funcs ) )
596 for ( i = 0; i <
self.spawn_funcs.size; i++ )
598 func =
self.spawn_funcs[ i ];
599 util::single_thread(
self, func[
"function" ], func[
"param1" ], func[
"param2" ], func[
"param3" ], func[
"param4" ], func[
"param5" ] );
607 self.spawn_funcs = undefined;
613 if ( isdefined(
self.script_deathflag ) )
616 level.deathflags[
self.script_deathflag ] =
true;
619 if ( isdefined(
self.target ) )
629 if ( isdefined(
array ) )
631 targets =
array[
"node" ];
632 get_func =
array[
"get_target_func" ];
633 for ( i = 0; i < targets.size; i++ )
643 self.spawner_number = undefined;
651 if (
IS_TRUE( level._use_faceanim ) )
658 if ( isdefined( spawner ) )
660 if ( isdefined( spawner.targetname ) && !isdefined(
self.targetname ) )
662 self.targetname = spawner.targetname +
"_ai";
666 if ( isdefined( spawner ) && isdefined( spawner.script_animname ) )
668 self.animname = spawner.script_animname;
670 else if ( isdefined(
self.script_animname ) )
672 self.animname =
self.script_animname;
682 if ( isdefined(
self.script_forceColor ) )
688 if ( ( !isdefined(
self.script_no_respawn ) ||
self.script_no_respawn < 1 ) && !isdefined( level.no_color_respawners_sm ) )
694 if ( ( isdefined(
self.script_moveoverride ) ) &&(
self.script_moveoverride == 1 ) )
724 self.heavy_machine_gunner = IsSubStr(
self.classname,
"mgportable" );
728 if( isdefined(
self.script_ignoreme ) )
730 assert(
self.script_ignoreme ==
true,
"Tried to set self.script_ignoreme to false, not allowed. Just set it to undefined." );
731 self.ignoreme =
true;
740 if( isdefined(
self.script_hero ) )
742 assert(
self.script_hero == 1,
"Tried to set script_hero to something other than 1" );
747 if ( isdefined(
self.script_ignoreall ) )
749 assert(
self.script_ignoreall ==
true,
"Tried to set self.script_ignoreme to false, not allowed. Just set it to undefined." );
750 self.ignoreall =
true;
772 if ( isdefined(
self.script_sightrange ) )
774 self.maxSightDistSqrd =
self.script_sightrange;
776 else if (
IS_EQUAL(
self.weaponclass,
"gas" ) )
778 self.maxSightDistSqrd = 1024 * 1024;
781 if (
self.team !=
"axis" )
784 if ( isdefined(
self.script_followmin ) )
786 self.followmin =
self.script_followmin;
790 if ( isdefined(
self.script_followmax ) )
792 self.followmax =
self.script_followmax;
796 if (
self.team ==
"axis" )
798 if ( IsDefined(
self.type ) &&
self.type ==
"human" )
805 if ( isdefined(
self.script_fightdist ) )
807 self.pathenemyfightdist =
self.script_fightdist;
810 if ( isdefined(
self.script_maxdist ) )
812 self.pathenemylookahead =
self.script_maxdist;
816 if ( isdefined(
self.script_longdeath ) )
818 assert( !
self.script_longdeath,
"Long death is enabled by default so don't set script_longdeath to true, check ai with export " +
self.export );
819 self.a.disableLongDeath =
true;
820 assert(
self.team !=
"allies",
"Allies can't do long death, so why disable it on guy with export " +
self.export );
824 if ( isdefined(
self.script_grenades ) )
826 self.grenadeAmmo =
self.script_grenades;
830 if ( isdefined(
self.script_pacifist ) )
832 self.pacifist =
true;
836 if ( isdefined(
self.script_startinghealth ) )
838 self.health =
self.script_startinghealth;
842 if ( isdefined(
self.script_allowdeath ) )
844 self.allowdeath =
self.script_allowdeath;
848 if ( isdefined(
self.script_forcegib ) )
861 if ( isdefined(
self.script_lights_on ) )
867 if ( isdefined(
self.script_stealth ) )
873 if ( isdefined(
self.script_patroller ) )
879 if (
IS_TRUE(
self.script_rusher ) )
909 if ( isdefined(
self.used_an_mg42 ) )
917 self SetGoal(
self.origin );
923 if (
IS_TRUE( level.using_awareness ) )
933 if ( isdefined(
self.target ) )
935 e_goal = GetEnt(
self.target,
"targetname" );
936 if ( isdefined( e_goal ) )
938 self SetGoal( e_goal );
949 if ( isdefined(
self.script_spawner_targets ) )
957 if ( isdefined(
self.script_goalvolume ) )
963 if ( isdefined(
self.script_turnrate ) )
965 self.turnrate =
self.script_turnrate;
973 self endon(
"death" );
978 volume = level.goalVolumes[
self.script_goalvolume ];
979 if ( !isdefined( volume ) )
982 if ( isdefined( volume.target ) )
984 node = GetNode( volume.target,
"targetname" );
985 ent = GetEnt( volume.target,
"targetname" );
989 if ( isdefined( node ) )
994 else if ( isdefined( ent ) )
997 self SetGoal( pos.origin );
999 else if ( isdefined(
struct ) )
1002 self SetGoal( pos.origin );
1005 if ( isdefined( pos.radius ) && pos.radius != 0 )
1007 self.goalradius = pos.radius;
1010 if ( isdefined( pos.goalheight ) && pos.goalheight != 0 )
1012 self.goalheight = pos.goalheight;
1016 if ( isdefined(
self.target ) )
1018 self SetGoal( volume );
1020 else if ( isdefined(
self.script_spawner_targets ) )
1022 self waittill(
"spawner_target_set" );
1023 self SetGoal( volume );
1027 self SetGoal( volume );
1033 return GetEntArray( target,
"targetname" );
1038 return getnodearray( target,
"targetname" );
1048 return isdefined( node.radius ) && node.radius != 0;
1053 self go_to_node( node,
"origin", optional_arrived_at_node_func );
1058 self go_to_node( node,
"struct", optional_arrived_at_node_func );
1061 function go_to_node( node, goal_type, optional_arrived_at_node_func )
1063 self endon(
"death");
1065 if ( isdefined(
self.used_an_mg42 ) )
1071 if ( !isdefined(
array ) )
1073 self notify(
"reached_path_end" );
1078 if ( !isdefined( optional_arrived_at_node_func ) )
1097 allnodes = GetAllNodes();
1098 level.script_spawner_targets_nodes = [];
1099 for( i = 0; i < allnodes.size; i++)
1101 if(isdefined(allnodes[i].script_spawner_targets))
1103 level.script_spawner_targets_nodes[level.script_spawner_targets_nodes.size] = allnodes[i];
1110 self endon(
"death" );
1112 self notify(
"go_to_spawner_target" );
1113 self endon(
"go_to_spawner_target" );
1116 a_nodes_unavailable = [];
1117 nodesPresent =
false;
1119 for ( i = 0; i < target_names.size; i++ )
1122 if ( target_nodes.size > 0 )
1124 nodesPresent =
true;
1127 foreach ( node
in target_nodes )
1129 if ( IsNodeOccupied( node ) ||
IS_TRUE( node.node_claimed ) )
1145 if ( nodes.size == 0 )
1147 while ( nodes.size == 0 )
1149 foreach ( node
in a_nodes_unavailable )
1151 if ( !IsNodeOccupied( node )
1164 Assert( nodesPresent,
"No spawner target nodes for AI." );
1167 if ( nodes.size > 0 )
1169 goal = array::random( nodes );
1172 if ( isdefined( goal ) )
1175 if ( isdefined(
self.script_radius ) )
1177 self.goalradius =
self.script_radius;
1181 self.goalradius = 400;
1184 goal.node_claimed =
true;
1185 self SetGoal( goal );
1187 self notify(
"spawner_target_set" );
1191 self waittill(
"goal" );
1200 node.node_claimed = undefined;
1213 for ( i = 0; i < level.script_spawner_targets_nodes.size; i++)
1215 groups = strtok( level.script_spawner_targets_nodes[i].script_spawner_targets,
" ");
1217 for ( j = 0; j < groups.size; j++)
1219 if ( groups[j] == group )
1221 nodes[nodes.size] = level.script_spawner_targets_nodes[i];
1235 assert(
array.size > 0,
"Somehow array had zero entrees" );
1241 targetname =
array[ 0 ].targetname;
1242 if ( !isdefined( level.go_to_node_arrays[ targetname ] ) )
1244 level.go_to_node_arrays[ targetname ] =
array;
1247 array = level.go_to_node_arrays[ targetname ];
1252 for ( i = 0; i <
array.size - 1; i++ )
1254 newarray[ i ] =
array[ i + 1 ];
1257 level.go_to_node_arrays[ targetname ] = newarray;
1263 function go_to_node_using_funcs( node, get_target_func, set_goal_func_quits, optional_arrived_at_node_func, require_player_dist )
1266 self endon(
"stop_going_to_node" );
1267 self endon(
"death" );
1274 player_wait_dist = require_player_dist;
1275 if( isdefined( node.script_requires_player ) )
1277 if( node.script_requires_player > 1 )
1278 player_wait_dist = node.script_requires_player;
1280 player_wait_dist = 256;
1282 node.script_requires_player =
false;
1287 if ( isdefined( node.height ) )
1289 self.goalheight = node.height;
1292 [[ set_goal_func_quits ]]( node );
1293 self waittill(
"goal" );
1295 [[ optional_arrived_at_node_func ]]( node );
1297 if ( isdefined( node.script_flag_set ) )
1302 if ( isdefined( node.script_flag_clear ) )
1307 if ( isdefined( node.script_ent_flag_set ) )
1310 AssertMsg(
"Tried to set a ent flag "+ node.script_ent_flag_set +
" on a node, but it doesnt exist." );
1315 if ( isdefined( node.script_ent_flag_clear ) )
1318 AssertMsg(
"Tried to clear a ent flag "+ node.script_ent_flag_clear +
" on a node, but it doesnt exist." );
1323 if ( isdefined( node.script_flag_wait ) )
1328 while ( isdefined( node.script_requires_player ) )
1330 node.script_requires_player =
false;
1333 node.script_requires_player =
true;
1334 node notify(
"script_requires_player" );
1341 if( isdefined( node.script_aigroup ) )
1348 if ( !isdefined( node.target ) )
1354 if ( !nextNode_array.size )
1359 node = nextNode_array;
1363 if( isdefined(
self.arrived_at_end_node_func ) )
1364 [[
self.arrived_at_end_node_func ]]( node );
1366 self notify(
"reached_path_end" );
1368 if( isdefined(
self.delete_on_path_end ) )
1378 players = GetPlayers();
1380 for( i=0; i< players.size; i++ )
1382 player = players[i];
1384 if ( distancesquared( player.origin, node.origin ) < distancesquared(
self.origin, node.origin ) )
1389 vec = anglestoforward(
self.angles );
1390 if ( isdefined( node.target ) )
1392 temp = [[ get_target_func ]]( node.target );
1395 if ( temp.size == 1 )
1396 vec = vectornormalize( temp[ 0 ].origin - node.origin );
1398 else if ( isdefined( node.angles ) )
1399 vec = anglestoforward( node.angles );
1402 else if ( isdefined( node.angles ) )
1403 vec = anglestoforward( node.angles );
1407 for( i=0; i< players.size; i++ )
1409 player = players[i];
1411 vec2[ vec2.size ] = vectornormalize( ( player.origin -
self.origin ) );
1416 for( i=0; i< vec2.size; i++ )
1420 if ( vectordot( vec, value ) > 0 )
1427 dist2rd = dist * dist;
1428 for( i=0; i< players.size; i++ )
1430 player = players[i];
1432 if ( distancesquared( player.origin,
self.origin ) < dist2rd )
1443 self SetGoal( ent.origin );
1448 self SetGoal( node );
1454 if ( isdefined( ent ) )
1456 ent.crawled = undefined;
1466 if ( !isdefined( ent.crawled ) )
1471 if ( isdefined( ent.script_flag_set ) )
1473 if ( !isdefined( level.flag[ ent.script_flag_set ] ) )
1479 if ( isdefined( ent.script_flag_wait ) )
1481 if ( !isdefined( level.flag[ ent.script_flag_wait ] ) )
1487 if ( isdefined( ent.target ) )
1489 new_targets = [[ get_func ]]( ent.target );
1495 if ( index >= targets.size )
1500 ent = targets[ index ];
1518 if ( !isdefined( goal_type ) )
1524 if ( isdefined( node ) )
1526 array[
"node" ][ 0 ] = node;
1531 node = GetEntArray(
self.target,
"targetname" );
1533 if ( node.size > 0 )
1535 goal_type =
"origin";
1538 if ( goal_type ==
"node" )
1540 node = getnodearray(
self.target,
"targetname" );
1549 goal_type =
"struct";
1556 array[
"get_target_func" ] = get_target_func[ goal_type ];
1557 array[
"set_goal_func_quits" ] = set_goal_func_quits[ goal_type ];
1565 a_nd_target = GetNodeArray( str_target,
"targetname" );
1566 if( a_nd_target.size )
1573 if( a_s_target.size )
1579 a_e_target = GetEntArray( str_target,
"targetname" );
1580 if( a_e_target.size )
1589 self endon(
"death" );
1591 if( isdefined(
self.script_radius ) )
1594 self.goalradius =
self.script_radius;
1598 self.goalradius = node.radius;
1601 if(
IS_TRUE(
self.script_forcegoal ) )
1603 n_radius = (
self.script_forcegoal > 1 ?
self.script_forcegoal : undefined );
1610 a_goals = GetNodeArray( str_goal, str_key );
1611 if ( !a_goals.size )
1613 a_goals = GetEntArray( str_goal, str_key );
1616 return array::random( a_goals );
1621 self endon(
"death" );
1623 level.max_fallbackers[num]+=
self.count;
1625 while(
self.count > 0 )
1627 self waittill(
"spawned",
spawn );
1631 if( GetDvarString(
"fallback" ) ==
"1" )
1633 println(
"^a First spawned: ", num );
1636 level notify( (
"fallback_firstspawn" + num ) );
1643 level notify( (
"fallbacker_died" + num ) );
1644 level.max_fallbackers[num]--;
1656 ai waittill(
"death" );
1657 level.current_fallbackers[num]--;
1659 level notify( (
"fallbacker_died" + num ) );
1664 if( ( !isdefined(
self.fallback ) ) ||( !isdefined(
self.fallback[num] ) ) )
1666 self.fallback[num] =
true;
1673 self.script_fallback = num;
1674 if( !isdefined( spawner ) )
1676 level.current_fallbackers[num]++;
1679 if( ( isdefined( node_array ) ) &&( level.fallback_initiated[num] ) )
1681 self thread
fallback_ai( num, node_array, ignoreWhileFallingBack );
1689 ai waittill(
"death" );
1691 if (isdefined(ai.fallback_node))
1693 ai.fallback_node.fallback_occupied =
false;
1696 level notify( (
"fallback_reached_goal" + num ) );
1703 self waittill(
"goal" );
1704 self.ignoresuppression =
false;
1706 if( isdefined( ignoreWhileFallingBack ) && ignoreWhileFallingBack )
1708 self.ignoreall =
false;
1711 self notify(
"fallback_notify" );
1712 self notify(
"stop_coverprint" );
1717 self notify(
"stop_fallback_interrupt" );
1718 self endon(
"stop_fallback_interrupt" );
1720 self endon(
"stop_going_to_node" );
1721 self endon (
"goto next fallback");
1722 self endon (
"fallback_notify");
1723 self endon(
"death" );
1727 origin =
self.origin;
1729 if (
self.origin == origin )
1731 self.ignoreall =
false;
1740 self notify(
"stop_going_to_node" );
1741 self endon(
"stop_going_to_node" );
1742 self endon (
"goto next fallback");
1743 self endon(
"death" );
1749 assert((node_array.size >= level.current_fallbackers[num]),
"Number of fallbackers exceeds number of fallback nodes for fallback # " + num +
". Add more fallback nodes or reduce possible fallbackers.");
1751 node = node_array[RandomInt( node_array.size )];
1752 if (!isdefined(node.fallback_occupied) || !node.fallback_occupied)
1755 node.fallback_occupied =
true;
1756 self.fallback_node = node;
1765 self.ignoresuppression =
true;
1767 if(
self.ignoreall ==
false && isdefined( ignoreWhileFallingBack ) && ignoreWhileFallingBack )
1769 self.ignoreall =
true;
1773 self SetGoal( node );
1774 if( node.radius != 0 )
1776 self.goalradius = node.radius;
1779 self endon(
"death" );
1783 if( GetDvarString(
"fallback" ) ==
"1" )
1788 self waittill(
"fallback_notify" );
1789 level notify( (
"fallback_reached_goal" + num ) );
1795 self endon(
"fallback_notify" );
1796 self endon(
"stop_coverprint" );
1797 self endon (
"death");
1800 line(
self.origin +( 0, 0, 35 ), org, ( 0.2, 0.5, 0.8 ), 0.5 );
1801 print3d( (
self.origin +( 0, 0, 70 ) ),
"Falling Back", ( 0.98, 0.4, 0.26 ), 0.85 );
1811 fallback_nodes = undefined;
1812 nodes = GetAllNodes();
1813 for( i = 0; i < nodes.size; i++ )
1815 if( ( isdefined( nodes[i].script_fallback ) ) &&( nodes[i].script_fallback == num ) )
1821 if( isdefined( fallback_nodes ) )
1832 level.current_fallbackers[num] = 0;
1833 level.max_fallbackers[num] = 0;
1834 level.spawner_fallbackers[num] = 0;
1835 level.fallback_initiated[num] =
false;
1838 spawners = GetSpawnerArray();
1839 for( i = 0; i < spawners.size; i++ )
1841 if( ( isdefined( spawners[i].script_fallback ) ) &&( spawners[i].script_fallback == num ) )
1843 if( spawners[i].count > 0 )
1846 level.spawner_fallbackers[num]++;
1851 assert( level.spawner_fallbackers[num] <= fallback_nodes.size,
"There are more fallback spawners than fallback nodes. Add more node or remove spawners from script_fallback: "+ num );
1854 for( i = 0; i < ai.size; i++ )
1856 if( ( isdefined( ai[i].script_fallback ) ) &&( ai[i].script_fallback == num ) )
1858 ai[i] thread
fallback_ai_think( num, undefined, undefined, ignoreWhileFallingBack );
1862 if( ( !level.current_fallbackers[num] ) &&( !level.spawner_fallbackers[num] ) )
1867 spawners = undefined;
1870 thread
fallback_wait( num, group, ignoreWhileFallingBack, percent );
1871 level waittill( (
"fallbacker_trigger" + num ) );
1876 if( GetDvarString(
"fallback" ) ==
"1" )
1878 println(
"^a fallback trigger hit: ", num );
1882 level.fallback_initiated[num] =
true;
1886 for( i = 0; i < ai.size; i++ )
1888 if( ( ( isdefined( ai[i].script_fallback ) ) &&( ai[i].script_fallback == num ) ) || ( ( isdefined( ai[i].script_fallback_group ) ) &&( isdefined( group ) ) &&( ai[i].script_fallback_group == group ) ) )
1900 if( !isdefined( percent ) )
1906 first_half = Int( first_half );
1908 level notify(
"fallback initiated " + num );
1913 for( i = 0; i < first_half; i++ )
1920 for( i = 0; i < first_half; i++ )
1922 level waittill( (
"fallback_reached_goal" + num ) );
1933 set_fallback =
true;
1934 for (p = 0; p < first_half_ai.size; p++)
1936 if ( isalive(first_half_ai[p]))
1940 set_fallback =
false;
1957 if( GetTime() <= level._nextcoverprint )
1962 for( i = start; i <
end; i++ )
1964 if( !IsAlive( fallbackers[i] ) )
1969 level._nextcoverprint = GetTime() + 2500 + RandomInt( 2000 );
1978 level endon( (
"fallbacker_trigger" + num ) );
1980 if( GetDvarString(
"fallback" ) ==
"1" )
1982 println(
"^a Fallback wait: ", num );
1985 for( i = 0; i < level.spawner_fallbackers[num]; i++ )
1988 if( GetDvarString(
"fallback" ) ==
"1" )
1990 println(
"^a Waiting for spawners to be hit: ", num,
" i: ", i );
1993 level waittill( (
"fallback_firstspawn" + num ) );
1996 if( GetDvarString(
"fallback" ) ==
"1" )
1998 println(
"^a Waiting for AI to die, fall backers for group ", num,
" is ", level.current_fallbackers[num] );
2003 for( i = 0; i < ai.size; i++ )
2005 if( ( ( isdefined( ai[i].script_fallback ) ) &&( ai[i].script_fallback == num ) ) || ( ( isdefined( ai[i].script_fallback_group ) ) &&( isdefined( group ) ) &&( ai[i].script_fallback_group == group ) ) )
2007 ai[i] thread
fallback_ai_think( num, undefined, undefined, ignoreWhileFallingBack );
2012 deadfallbackers = 0;
2014 while( deadfallbackers < level.max_fallbackers[num] * percent )
2017 if( GetDvarString(
"fallback" ) ==
"1" )
2019 println(
"^cwaiting for " + deadfallbackers +
" to be more than " +( level.max_fallbackers[num] * 0.5 ) );
2022 level waittill( (
"fallbacker_died" + num ) );
2026 /#println( deadfallbackers ,
" fallbackers have died, time to retreat" );#/
2027 level notify( (
"fallbacker_trigger" + num ) );
2036 ignoreWhileFallingBack =
false;
2037 if( isdefined( trigger.script_ignoreall ) && trigger.script_ignoreall )
2039 ignoreWhileFallingBack =
true;
2042 if( ( !isdefined( level.fallback ) ) ||( !isdefined( level.fallback[trigger.script_fallback] ) ) )
2047 if( isdefined( trigger.script_percent ) )
2049 percent = trigger.script_percent / 100;
2052 level thread
fallback_overmind( trigger.script_fallback, trigger.script_fallback_group, ignoreWhileFallingBack, percent );
2055 trigger waittill(
"trigger" );
2057 level notify( (
"fallbacker_trigger" + trigger.script_fallback ) );
2068 if (!isdefined (level.current_fallbackers[num - 1]))
2074 for (i = 0; i < level.current_fallbackers[num - 1]; i++)
2076 level.max_fallbackers[num]++;
2080 for (i = 0; i < level.current_fallbackers[num - 1]; i++)
2082 level.current_fallbackers[num]++;
2086 for( i = 0; i < ai.size; i++ )
2088 if( ( ( isdefined( ai[i].script_fallback ) ) && ( ai[i].script_fallback == (num - 1) ) ) )
2091 ai[i].script_fallback++;
2093 if (isdefined (ai[i].fallback_node))
2095 ai[i].fallback_node.fallback_occupied =
false;
2096 ai[i].fallback_node = undefined;
2369 if ( !isdefined( level._ai_group[aigroup] ) )
2371 level._ai_group[aigroup] = SpawnStruct();
2372 level._ai_group[aigroup].aigroup = aigroup;
2373 level._ai_group[aigroup].aicount = 0;
2374 level._ai_group[aigroup].killed_count = 0;
2375 level._ai_group[aigroup].ai = [];
2376 level._ai_group[aigroup].spawners = [];
2377 level._ai_group[aigroup].cleared_count = 0;
2379 if ( !isdefined( level.flag[aigroup +
"_cleared"] ) )
2384 if ( !isdefined( level.flag[aigroup +
"_spawning"] ) )
2392 if ( isdefined( spawner ) )
2394 ARRAY_ADD( level._ai_group[aigroup].spawners, spawner );
2402 tracker notify(
"update_aigroup" );
2408 tracker.ai[tracker.ai.size] =
self;
2409 tracker notify(
"update_aigroup" );
2411 if ( isdefined(
self.script_deathflag_longdeath ) )
2417 self waittill(
"death" );
2421 tracker.killed_count++;
2422 tracker notify(
"update_aigroup" );
2435 tracker waittill(
"update_aigroup" );
2438 level
flag::set( tracker.aigroup +
"_cleared" );
2445 assert( isdefined( trigger.target ),
"flood_spawner at " + trigger.origin +
" without target" );
2447 floodSpawners = GetEntArray( trigger.target,
"targetname" );
2448 assert( floodSpawners.size,
"flood_spawner at with target " + trigger.target +
" without any targets" );
2450 for(i = 0; i < floodSpawners.size; i++)
2452 floodSpawners[i].script_trigger = trigger;
2470 trigger waittill(
"trigger" );
2472 floodSpawners = GetEntArray( trigger.target,
"targetname" );
2491 if( !isdefined( trigger ) )
2496 return isdefined( trigger.script_requires_player );
2501 self endon(
"death" );
2502 self notify(
"stop current floodspawner" );
2503 self endon(
"stop current floodspawner" );
2509 while(
self.count > 0 )
2514 if( requires_player )
2532 soldier waittill(
"death", attacker );
2539 if( !isdefined( soldier ) )
2546 players = GetPlayers();
2548 if (players.size == 1)
2550 wait( RandomFloatrange( 5, 9 ) );
2552 else if (players.size == 2)
2554 wait( RandomFloatrange( 3, 6 ) );
2556 else if (players.size == 3)
2558 wait( RandomFloatrange( 1, 4 ) );
2560 else if (players.size == 4)
2562 wait( RandomFloatrange( 0.5, 1.5 ) );
2570 if ( isdefined(
self.script_force_count ) )
2572 if (
self.script_force_count )
2578 if ( !isdefined( guy ) )
2583 if ( IsAlive( attacker ) )
2585 if ( IsPlayer( attacker ) )
2590 players = GetPlayers();
2592 for( q = 0; q < players.size; q++ )
2594 if ( DistanceSquared( attacker.origin, players[q].origin ) < 200 * 200 )
2603 if ( isdefined( attacker ) )
2605 if ( attacker.classname ==
"worldspawn" )
2611 if ( isdefined( player ) && distancesquared( attacker.origin, player.origin ) < 200*200 )
2621 if ( isdefined( closest_player ) && distancesquared( guy.origin, closest_player.origin ) < 200*200 )
2628 return bulletTracePassed( closest_player geteye(), guy geteye(),
false, undefined );
2637 self endon(
"death" );
2638 last_bad_path_time = -5000;
2642 self waittill(
"bad_path", badPathPos );
2644 if ( !isdefined(level.debug_badpath) || !level.debug_badpath )
2649 if ( gettime() - last_bad_path_time > 5000 )
2658 last_bad_path_time = gettime();
2660 if ( bad_path_count < 10 )
2665 for ( p = 0; p < 10 * 20; p++ )
2667 line(
self.origin, badPathPos, ( 1, 0.4, 0.1 ), 0, 10 * 20 );
2692 function spawn( b_force =
false, str_targetname, v_origin, v_angles, bIgnoreSpawningLimit )
2694 if( IsDefined( level.overrideGlobalSpawnFunc ) &&
self.team ==
"axis" )
2696 return [[level.overrideGlobalSpawnFunc]]( b_force, str_targetname, v_origin, v_angles );
2699 e_spawned = undefined;
2700 force_spawn =
false;
2702 infinitespawn =
false;
2703 deleteonzerocount =
false;
2706 if ( GetDvarString(
"noai" ) !=
"off" )
2719 if ( !
IS_TRUE( bIgnoreSpawningLimit ) && !
IS_TRUE(
self.ignorespawninglimit ) )
2730 if ( isdefined(
self.lastSpawnTime ) &&
self.lastSpawnTime >= GetTime() )
2739 if ( IsActorSpawner(
self ) )
2746 else if ( IsVehicleSpawner(
self ) )
2762 infinitespawn =
true;
2765 if ( !IsDefined( e_spawned ) )
2767 female_override = undefined;
2768 use_female = RandomInt( 100 ) < level.female_percent;
2769 if( level.dont_use_female_replacements ===
true )
2774 if ( use_female && IsDefined(
self.aitypevariant ) )
2776 e_spawned =
self SpawnFromSpawner( str_targetname, force_spawn, makeroom, infinitespawn,
"actor_" +
self.aitypevariant );
2780 override_aitype = undefined;
2782 if( isDefined( level.override_spawned_aitype_func ))
2784 override_aitype = [[ level.override_spawned_aitype_func ]]( self );
2787 if( IsDefined( override_aitype ) )
2789 e_spawned =
self SpawnFromSpawner( str_targetname, force_spawn, makeroom, infinitespawn, override_aitype );
2793 e_spawned =
self SpawnFromSpawner( str_targetname, force_spawn, makeroom, infinitespawn );
2800 if ( IsDefined( e_spawned ) )
2802 if( isdefined( level.run_custom_function_on_ai ) )
2804 e_spawned thread [[level.run_custom_function_on_ai]](
self, str_targetname, force_spawn );
2807 if ( isdefined( v_origin ) || isdefined( v_angles ) )
2812 self.lastSpawnTime = GetTime();
2815 if ( ( deleteonzerocount ||
IS_TRUE(
self.script_delete_on_zero ) ) && isdefined(
self.count ) && (
self.count <= 0 ) )
2820 if ( IsSentient( e_spawned ) )
2838 if ( IsActor(
self ) )
2840 self ForceTeleport( v_origin, v_angles,
true, b_reset_entity );
2844 self.origin = v_origin;
2845 self.angles = v_angles;
2851 if ( isdefined( level.players ) && level.players.size > 0 )
2853 n_player_count = level.players.size;
2857 n_player_count = GetNumExpectedPlayers();
2860 if ( isdefined(
self.script_minplayers ) )
2862 if ( n_player_count <
self.script_minplayers )
2870 if ( isdefined(
self.script_numplayers ) )
2872 if ( n_player_count <
self.script_numplayers )
2880 if ( isdefined(
self.script_maxplayers ) )
2882 if ( n_player_count >
self.script_maxplayers )
2906 if ( !isdefined(
spawn.finished_spawning ) )
2908 spawn waittill(
"finished spawning");
2933 foreach ( sp
in GetSpawnerArray(
"" + number,
"script_killspawner" ) )
2950 self.replace_on_death = undefined;
2951 self notify(
"_disable_reinforcement" );
2981 level._ai_group[aigroup].cleared_count = count;
2995 assert(isdefined(level._ai_group[aigroup]),
"The aigroup "+aigroup+
" does not exist");
3012 level._ai_group[ aigroup ] waittill(
"update_aigroup" );
3027 while( level._ai_group[ aigroup ].aicount > count )
3029 level._ai_group[ aigroup ] waittill(
"update_aigroup" );
3046 level._ai_group[ aigroup ] waittill(
"update_aigroup" );
3061 while ( level._ai_group[ aigroup ].killed_count < amount_killed )
3063 level._ai_group[ aigroup ] waittill(
"update_aigroup" );
3092 return( level._ai_group[ aigroup ].aicount );
3098 foreach ( sp
in level._ai_group[ aigroup ].spawners )
3100 if ( isdefined( sp ) )
3102 n_count += sp.count;
3120 for( index = 0; index < level._ai_group[ aigroup ].ai.size; index ++ )
3122 if( !isAlive( level._ai_group[ aigroup ].ai[ index ] ) )
3127 aiSet[ aiSet.size ] = level._ai_group[ aigroup ].ai[ index ];
3151 if ( !isdefined( level.spawn_funcs ) )
3153 level.spawn_funcs = [];
3156 if ( !isdefined( level.spawn_funcs[team] ) )
3158 level.spawn_funcs[team] = [];
3162 func[
"function" ] =spawn_func;
3163 func[
"param1" ] = param1;
3164 func[
"param2" ] = param2;
3165 func[
"param3" ] = param3;
3166 func[
"param4" ] = param4;
3167 func[
"param5" ] = param5;
3169 ARRAY_ADD( level.spawn_funcs[ team ], func );
3190 if ( !isdefined( level.spawn_funcs ) )
3192 level.spawn_funcs = [];
3195 if ( !isdefined( level.spawn_funcs[archetype] ) )
3197 level.spawn_funcs[archetype] = [];
3201 func[
"function" ] = spawn_func;
3202 func[
"param1" ] = param1;
3203 func[
"param2" ] = param2;
3204 func[
"param3" ] = param3;
3205 func[
"param4" ] = param4;
3206 func[
"param5" ] = param5;
3208 ARRAY_ADD( level.spawn_funcs[ archetype ], func );
3224 if ( isdefined( level.spawn_funcs ) && isdefined( level.spawn_funcs[team] ) )
3227 for( i = 0; i < level.spawn_funcs[ team ].size; i++ )
3229 if( level.spawn_funcs[ team ][ i ][
"function" ] !=func )
3231 array[
array.size ] = level.spawn_funcs[ team ][ i ];
3235 level.spawn_funcs[ team ] =
array;
3254 assert( !isdefined( level._loadStarted ) || !IsAlive(
self ),
"Tried to add_spawn_function to a living guy." );
3257 func[
"function" ] =spawn_func;
3258 func[
"param1" ] = param1;
3259 func[
"param2" ] = param2;
3260 func[
"param3" ] = param3;
3261 func[
"param4" ] = param4;
3262 func[
"param5" ] = param5;
3264 if (!isdefined(
self.spawn_funcs))
3266 self.spawn_funcs = [];
3269 self.spawn_funcs[
self.spawn_funcs.size ] = func;
3282 assert( !isdefined( level._loadStarted ) || !IsAlive(
self ),
"Tried to remove_spawn_function to a living guy." );
3284 if ( isdefined(
self.spawn_funcs ) )
3287 for ( i = 0; i <
self.spawn_funcs.size; i++ )
3289 if (
self.spawn_funcs[ i ][
"function" ] != func )
3295 assert(
self.spawn_funcs.size !=
array.size,
"Tried to remove a function from level.spawn_funcs, but that function didn't exist!" );
3296 self.spawn_funcs =
array;
3320 Assert( isdefined( str_value ),
"str_value is a required parameter for add_spawn_function_group" );
3321 Assert( isdefined( func_spawn ),
"func_spawn is a required parameter for add_spawn_function_group" );
3323 a_spawners = GetSpawnerArray( str_value, str_key );
3324 array::run_all( a_spawners, &
add_spawn_function, func_spawn, param_1, param_2, param_3, param_4, param_5 );
3345 assert( isdefined( str_aigroup ),
"str_aigroup is a required parameter for add_spawn_function_ai_group" );
3346 assert( isdefined( func_spawn ),
"func_spawn is a required parameter for add_spawn_function_ai_group" );
3348 a_spawners = GetSpawnerArray( str_aigroup,
"script_aigroup" );
3349 array::run_all( a_spawners, &
add_spawn_function, func_spawn, param_1, param_2, param_3, param_4, param_5 );
3365 assert( isdefined( str_aigroup ),
"str_aigroup is a required parameter for remove_spawn_function_ai_group" );
3366 assert( isdefined( func_spawn ),
"func_spawn is a required parameter for remove_spawn_function_ai_group" );
3368 a_spawners = GetSpawnerArray( str_aigroup,
"script_aigroup" );
3385 spawners = getEntArray(
name,
"targetname" );
3386 assert( spawners.size,
"no spawners with targetname " +
name +
" found!" );
3389 if( isdefined( spawn_func ) )
3391 for( i = 0; i < spawners.size; i++ )
3397 if( isdefined( spawn_func_2 ) )
3399 for( i = 0; i < spawners.size; i++ )
3405 for( i = 0; i < spawners.size; i++ )
3435 function simple_spawn( name_or_spawners, spawn_func, param1, param2, param3, param4, param5, bForce )
3439 if ( IsString( name_or_spawners ) )
3441 spawners = GetEntArray( name_or_spawners,
"targetname" );
3442 assert( spawners.size,
"no spawners with targetname " + name_or_spawners +
" found!" );
3447 spawners = name_or_spawners;
3452 foreach ( sp
in spawners )
3456 if ( isdefined( e_spawned ) )
3458 if ( isdefined( spawn_func ) )
3488 ai =
simple_spawn( name_or_spawner, spawn_func, param1, param2, param3, param4, param5, bforce );
3489 assert( ai.size <= 1,
"simple_spawn called from simple_spawn_single somehow spawned more than one guy!" );
3514 level.female_percent = 0;
3528 level.female_percent = percent;