‪Black Ops 3 Source Code Explorer  0.1
‪An script explorer for Black Ops 3 by ZeRoY
zm_giant_cleanup_mgr.gsc
Go to the documentation of this file.
1 #insert scripts\shared\shared.gsh;
2 
3 #using scripts\codescripts\struct;
4 
5 #using scripts\shared\array_shared;
6 #using scripts\shared\flag_shared;
7 #using scripts\shared\system_shared;
8 #using scripts\shared\util_shared;
9 
10 #using scripts\shared\ai\zombie_utility;
11 
12 #using scripts\zm\_zm_utility;
13 #using scripts\zm\_zm_zonemgr;
14 
15 
16 #namespace giant_cleanup;
17 
18 #define TRACKING_INNER_DIST 2000
19 #define TRACKING_OUTER_DIST 2200
20 #define TOO_HIGH_DIST 800
21 
22 #define N_CLEANUP_INTERVAL_MIN 3000 // Minimum time in msec for cleanup checks
23 #define N_CLEANUP_AGE_MIN 5000 // You must be this old (in msec) before considering for cleanup
24 #define N_CLEANUP_AGE_TIMEOUT 45000 // If you are at least this old (in msec) then allow cleanup no matter what
25 #define N_CLEANUP_EVALS_PER_FRAME_MAX 1 // Maximum number of AI to process per frame
26 #define N_CLEANUP_FOV_COS 0.766 // cos(40) == 80 degree FOV
27 #define N_CLEANUP_DIST_SQ_MIN_AGGRESSIVE 189225 // Minimum distance squared. 435^2
28 #define N_CLEANUP_DIST_SQ_MIN 250000 // Minimum distance squared. 500^2
29 #define N_CLEANUP_DIST_SQ_ROUND_END 2250000 // Minimum distance squared. 1500^2
30 
31 ‪REGISTER_SYSTEM_EX( "giant_cleanup", &‪__init__, &‪__main__, undefined )
32 
33 
34 #define N_MSEC 1000
35 
36 
37 function ‪__init__()
38 {
39  level.n_cleanups_processed_this_frame = 0;
40 }
41 
42 function ‪__main__()
43 {
44  level thread ‪cleanup_main();
45 }
46 
48 {
49  level notify( "pump_distance_check" );
50 }
51 
52 // Periodically loop through the AI to see if they need cleanup
53 function private ‪cleanup_main()
54 {
55  n_next_eval = 0;
56 
57  while ( true )
58  {
60 
61  n_time = GetTime();
62  if ( n_time < n_next_eval )
63  {
64  continue;
65  }
66 
67  // Has the cleanup manager been delayed?
68  if( isdefined(level.n_cleanup_manager_restart_time) )
69  {
70  n_current_time = gettime() / ‪N_MSEC;
71  n_delta_time = n_current_time - level.n_cleanup_manager_restart_time;
72  if( n_delta_time < 0 )
73  {
74  continue;
75  }
76  level.n_cleanup_manager_restart_time = undefined;
77  }
78 
79  // Don't do cleanup early in the round, attempt to stop lulls between rounds
80  n_round_time = ( n_time - level.round_start_time ) / ‪N_MSEC;
81  if( (level.round_number <= 5) && (n_round_time < 30) )
82  {
83  continue;
84  }
85  else if( (level.round_number > 5) && (n_round_time < 20) )
86  {
87  continue;
88  }
89 
90  // If there are no zombies left to spawn in the round AND there are less then 3 zombies alive, then use a much bigger cleanup distance check
91  // This will stop the last zombie constantly despawning and respawning if the players are running around looking for him
92  n_override_cleanup_dist_sq = undefined;
93  if( ( level.zombie_total == 0 ) && ( ‪zombie_utility::get_current_zombie_count() < 3 ) )
94  {
95  n_override_cleanup_dist_sq = ‪N_CLEANUP_DIST_SQ_ROUND_END;
96  }
97 
98  n_next_eval += ‪N_CLEANUP_INTERVAL_MIN;
99 
100  // Process all enemies alive at this point in time
101  a_ai_enemies = GetAITeamArray( "axis" );
102  foreach( ai_enemy in a_ai_enemies )
103  {
104  if ( level.n_cleanups_processed_this_frame >= ‪N_CLEANUP_EVALS_PER_FRAME_MAX )
105  {
106  level.n_cleanups_processed_this_frame = 0;
108  }
109 
110  ai_enemy ‪do_cleanup_check( n_override_cleanup_dist_sq );
111  }
112  }
113 }
114 
115 
116 // Check to see if we need to be cleaned up
117 // self is an ai
118 function ‪do_cleanup_check( n_override_cleanup_dist )
119 {
120  if ( !IsAlive( self ) )
121  {
122  return;
123  }
124 
125  if ( self.b_ignore_cleanup === true )
126  {
127  return;
128  }
129 
130  n_time_alive = GetTime() - self.spawn_time;
131  if ( n_time_alive < ‪N_CLEANUP_AGE_MIN )
132  {
133  return;
134  }
135 
136 
137  // Try not to clean up guys who are just trying to break through boards before they get through.
138  // But we still have to do something in case they get stuck...
139  //if( IS_EQUAL( self.archetype, ARCHETYPE_ZOMBIE ) )
140  {
141  if ( n_time_alive < ‪N_CLEANUP_AGE_TIMEOUT &&
142  self.script_string !== "find_flesh" &&
143  self.completed_emerging_into_playable_area !== true )
144  {
145  return;
146  }
147  }
148 
149  // If we're not in an Active zone, we are a candidate to be cleaned up.
150  b_in_active_zone = self ‪zm_zonemgr::entity_in_active_zone();
151  level.n_cleanups_processed_this_frame++;
152 
153  if ( !b_in_active_zone )
154  {
155  // Minimum distance check. Don't delete if you're too close to players
156  n_dist_sq_min = 10000000; // lowest distance squared value, init to a very large value
157  e_closest_player = level.activeplayers[0];
158  foreach( player in level.activeplayers )
159  {
160  n_dist_sq = DistanceSquared( self.origin, player.origin );
161  if ( n_dist_sq < n_dist_sq_min )
162  {
163  n_dist_sq_min = n_dist_sq;
164  e_closest_player = player;
165  }
166  }
167 
168  // Get the required distance check
169  if( isdefined(n_override_cleanup_dist) )
170  {
171  n_cleanup_dist_sq = n_override_cleanup_dist;
172  }
173  // If the player is ahead of me, use an aggressive closer distance check
174  else if( isdefined(e_closest_player) && ‪player_ahead_of_me( e_closest_player ) )
175  {
176  n_cleanup_dist_sq = ‪N_CLEANUP_DIST_SQ_MIN_AGGRESSIVE;
177  }
178  else
179  {
180  n_cleanup_dist_sq = ‪N_CLEANUP_DIST_SQ_MIN;
181  }
182 
183  // Distance check
184  if ( n_dist_sq_min >= n_cleanup_dist_sq )
185  {
186  // process for cleanup
187  self thread ‪delete_zombie_noone_looking();
188  }
189  }
190 }
191 
192 
193 //-------------------------------------------------------------------------------
194 // Deletes the zombie and adds him back into the queue if unseen & out of range.
195 //
196 // self = zombie
197 //-------------------------------------------------------------------------------
199 {
200  // exclude rising zombies that haven't finished rising.
201  if( ‪IS_TRUE( self.in_the_ground ) )
202  {
203  return;
204  }
205 
206  foreach ( player in level.players )
207  {
208  // pass through players in spectator mode.
209  if( player.sessionstate == "spectator" )
210  {
211  continue;
212  }
213 
214  if( self ‪player_can_see_me( player ) )
215  {
216  return;
217  }
218  }
219 
220  // put him back into the list to be respawned.
221  if ( !‪IS_TRUE( self.exclude_cleanup_adding_to_total ) )
222  {
223  level.zombie_total++;
224  level.zombie_respawns++; // Increment total of zombies needing to be respawned
225 
226  if(self.health < self.maxhealth)
227  {
228  if ( !isdefined( level.a_zombie_respawn_health[ self.archetype ] ) )
229  {
230  level.a_zombie_respawn_health[ self.archetype ] = [];
231  }
232  ‪ARRAY_ADD( level.a_zombie_respawn_health[ self.archetype ], self.health);
233  }
234  }
235 
237  self Kill();
238  wait( 0.05 ); // allow death to process
239 
240  if ( isdefined( self ) )
241  {
242 
243 
244  self Delete();
245  }
246 }
247 
248 
249 //-------------------------------------------------------------------------------
250 // Utility for checking if the player can see the zombie (ai).
251 // Just does a simple FOV check.
252 // self is the entity to check against
253 //-------------------------------------------------------------------------------
254 function private ‪player_can_see_me( player )
255 {
256  v_player_angles = player GetPlayerAngles();
257  v_player_forward = AnglesToForward( v_player_angles );
258 
259  v_player_to_self = self.origin - player GetOrigin();
260  v_player_to_self = VectorNormalize( v_player_to_self );
261 
262  n_dot = VectorDot( v_player_forward, v_player_to_self );
263  if ( n_dot < ‪N_CLEANUP_FOV_COS )
264  {
265  return false;
266  }
267 
268  return true;
269 }
270 
271 //-------------------------------------------------------------------------------
272 // self is the entity to check against
273 //-------------------------------------------------------------------------------
274 function private ‪player_ahead_of_me( player )
275 {
276  v_player_angles = player GetPlayerAngles();
277  v_player_forward = AnglesToForward( v_player_angles );
278 
279  v_dir = player GetOrigin() - self.origin;
280 
281  n_dot = VectorDot( v_player_forward, v_dir );
282  if ( n_dot < 0 )
283  {
284  return false;
285  }
286 
287  return true;
288 }
289 
290 
291 //-------------------------------------------------------------------------------
292 // Cleanup for when zombies have bad pathing.
293 //-------------------------------------------------------------------------------
294 
295 function ‪get_escape_position() // self = AI
296 {
297  self endon( "death" );
298 
299  // get zombie's current zone
300  str_zone = self.zone_name;
301 
302  //if not in a zone use the zone they were spawned from
303  if( !IsDefined( str_zone ) )
304  {
305  str_zone = self.zone_name;
306  }
307 
308  // get adjacent zones to current zone
309  if ( IsDefined( str_zone ) )
310  {
311  a_zones = ‪get_adjacencies_to_zone( str_zone );
312 
313  // get all dog locations in all zones + adjacencies
314  a_wait_locations = ‪get_wait_locations_in_zones( a_zones );
315 
316  // find farthest point away
317  s_farthest = self ‪get_farthest_wait_location( a_wait_locations );
318  }
319 
320  // return farthest
321  return s_farthest;
322 }
323 
324 
325 function ‪get_adjacencies_to_zone( str_zone )
326 {
327  a_adjacencies = [];
328  a_adjacencies[ 0 ] = str_zone; // the return value of this array will be referenced directly, so make sure initial zone is included
329 
330  a_adjacent_zones = GetArrayKeys( level.zones[ str_zone ].adjacent_zones );
331  for ( i = 0; i < a_adjacent_zones.size; i++ )
332  {
333  if ( level.zones[ str_zone ].adjacent_zones[ a_adjacent_zones[ i ] ].is_connected )
334  {
335  ‪ARRAY_ADD( a_adjacencies, a_adjacent_zones[ i ] );
336  }
337  }
338 
339  return a_adjacencies;
340 }
341 
342 
343 function private ‪get_wait_locations_in_zones( a_zones )
344 {
345  a_wait_locations = [];
346 
347  foreach ( zone in a_zones )
348  {
349  a_wait_locations = ArrayCombine( a_wait_locations, level.zones[ zone ].a_loc_types[ "dog_location" ], false, false );
350  }
351 
352  return a_wait_locations;
353 }
354 
355 
356 // self == AI
357 function private ‪get_farthest_wait_location( a_wait_locations )
358 {
359  if ( !isdefined( a_wait_locations ) || a_wait_locations.size == 0 )
360  {
361  return undefined;
362  }
363 
364  n_farthest_index = 0; // initialization
365  n_distance_farthest = 0;
366  for ( i = 0; i < a_wait_locations.size; i++ )
367  {
368 
369  n_distance_sq = DistanceSquared( self.origin, a_wait_locations[ i ].origin );
370 
371  if ( n_distance_sq > n_distance_farthest )
372  {
373  n_distance_farthest = n_distance_sq;
374  n_farthest_index = i;
375  }
376  }
377 
378  return a_wait_locations[ n_farthest_index ];
379 }
380 
381 
382 function private ‪get_wait_locations_in_zone( zone )
383 {
384  if( isdefined(level.zones[ zone ].a_loc_types[ "dog_location" ]) )
385  {
386  a_wait_locations = [];
387  a_wait_locations = ArrayCombine( a_wait_locations, level.zones[ zone ].a_loc_types[ "dog_location" ], false, false );
388  return a_wait_locations;
389  }
390  return( undefined );
391 }
392 
393 
394 // self = AI
396 {
397  self endon( "death" );
398 
399  // get zombie's current zone
400  str_zone = self.zone_name;
401 
402  //if not in a zone use the zone they were spawned from
403  if( !IsDefined( str_zone ) )
404  {
405  str_zone = self.zone_name;
406  }
407 
408  if ( IsDefined( str_zone ) )
409  {
410  // get all wait locations in this zone
411  a_wait_locations = ‪get_wait_locations_in_zone( str_zone );
412 
413  // find farthest point away
414  if( isdefined(a_wait_locations) )
415  {
416  s_farthest = self ‪get_farthest_wait_location( a_wait_locations );
417  }
418  }
419 
420  return s_farthest;
421 }
‪force_check_now
‪function force_check_now()
Definition: zm_giant_cleanup_mgr.gsc:47
‪entity_in_active_zone
‪function entity_in_active_zone(ignore_enabled_check=false)
Definition: _zm_zonemgr.gsc:243
‪cleanup_main
‪function private cleanup_main()
Definition: zm_giant_cleanup_mgr.gsc:53
‪delete_zombie_noone_looking
‪function private delete_zombie_noone_looking()
Definition: zm_giant_cleanup_mgr.gsc:198
‪N_CLEANUP_DIST_SQ_MIN
‪#define N_CLEANUP_DIST_SQ_MIN
Definition: zm_giant_cleanup_mgr.gsc:28
‪N_MSEC
‪#define N_MSEC
Definition: zm_giant_cleanup_mgr.gsc:34
‪N_CLEANUP_AGE_TIMEOUT
‪#define N_CLEANUP_AGE_TIMEOUT
Definition: zm_giant_cleanup_mgr.gsc:24
‪N_CLEANUP_AGE_MIN
‪#define N_CLEANUP_AGE_MIN
Definition: zm_giant_cleanup_mgr.gsc:23
‪IS_TRUE
‪#define IS_TRUE(__a)
Definition: shared.gsh:251
‪do_cleanup_check
‪function do_cleanup_check(n_override_cleanup_dist)
Definition: zm_giant_cleanup_mgr.gsc:118
‪reset_attack_spot
‪function reset_attack_spot()
Definition: zombie_utility.gsc:1671
‪get_wait_locations_in_zones
‪function private get_wait_locations_in_zones(a_zones)
Definition: zm_giant_cleanup_mgr.gsc:343
‪N_CLEANUP_INTERVAL_MIN
‪#define N_CLEANUP_INTERVAL_MIN
Definition: zm_giant_cleanup_mgr.gsc:22
‪N_CLEANUP_DIST_SQ_MIN_AGGRESSIVE
‪#define N_CLEANUP_DIST_SQ_MIN_AGGRESSIVE
Definition: zm_giant_cleanup_mgr.gsc:27
‪wait_network_frame
‪function wait_network_frame(n_count=1)
Definition: util_shared.gsc:64
‪player_ahead_of_me
‪function private player_ahead_of_me(player)
Definition: zm_giant_cleanup_mgr.gsc:274
‪REGISTER_SYSTEM_EX
‪#define REGISTER_SYSTEM_EX(__sys, __func_init_preload, __func_init_postload, __reqs)
Definition: shared.gsh:209
‪get_escape_position
‪function get_escape_position()
Definition: zm_giant_cleanup_mgr.gsc:295
‪N_CLEANUP_FOV_COS
‪#define N_CLEANUP_FOV_COS
Definition: zm_giant_cleanup_mgr.gsc:26
‪N_CLEANUP_EVALS_PER_FRAME_MAX
‪#define N_CLEANUP_EVALS_PER_FRAME_MAX
Definition: zm_giant_cleanup_mgr.gsc:25
‪ARRAY_ADD
‪#define ARRAY_ADD(__array, __item)
Definition: shared.gsh:304
‪get_escape_position_in_current_zone
‪function get_escape_position_in_current_zone()
Definition: zm_giant_cleanup_mgr.gsc:395
‪get_wait_locations_in_zone
‪function private get_wait_locations_in_zone(zone)
Definition: zm_giant_cleanup_mgr.gsc:382
‪N_CLEANUP_DIST_SQ_ROUND_END
‪#define N_CLEANUP_DIST_SQ_ROUND_END
Definition: zm_giant_cleanup_mgr.gsc:29
‪__init__
‪function __init__()
Definition: zm_giant_cleanup_mgr.gsc:37
‪get_adjacencies_to_zone
‪function get_adjacencies_to_zone(str_zone)
Definition: zm_giant_cleanup_mgr.gsc:325
‪get_current_zombie_count
‪function get_current_zombie_count()
Definition: zombie_utility.gsc:2018
‪__main__
‪function __main__()
Definition: zm_giant_cleanup_mgr.gsc:42
‪get_farthest_wait_location
‪function private get_farthest_wait_location(a_wait_locations)
Definition: zm_giant_cleanup_mgr.gsc:357
‪player_can_see_me
‪function private player_can_see_me(player)
Definition: zm_giant_cleanup_mgr.gsc:254