‪Black Ops 3 Source Code Explorer  0.1
‪An script explorer for Black Ops 3 by ZeRoY
colors_shared.gsc
Go to the documentation of this file.
1 #using scripts\codescripts\struct;
2 
3 #using scripts\shared\ai_shared;
4 #using scripts\shared\array_shared;
5 #using scripts\shared\flag_shared;
6 #using scripts\shared\system_shared;
7 #using scripts\shared\trigger_shared;
8 #using scripts\shared\spawner_shared;
9 #using scripts\shared\util_shared;
10 
11 #insert scripts\shared\shared.gsh;
12 
13 #define COLOR_NODE_BIG_RADIUS 1024
14 #define COLOR_FIXED_NODE_RADIUS 64
15 
16 #namespace colors;
17 
18 /*
19  Color coded AI travel system
20  A colorCode is a color( red, blue, yellow, cyan, green, purple or orange ) and a #.
21  When a trigger and AI and node are color grouped in Radiant, they get a unique color and #.
22  When when a color coded trigger is hit, that colorCode is "fired" and any AI that are in colorCoded mode get their goalnode set.
23 
24  AI can be forced to a color generically. For example if an AI is forced to the color "red" and a trigger fires off "red15", the AI
25  will go to that node even if the AI doesn't have script_color_allies( or axis ) "red15". This is mainly for friendlies.
26 
27  AI can also have their script_careful variable set, which prevents them from advancing to a node or a volume if an enemy is occupying it.
28  They will move up if the zone is cleared.
29 
30  Volumes can also be tagged with a code and a number like r6. So if an enemy is present in this volume, no AI will run to any node tagged r6.
31 */
32 
33 ‪REGISTER_SYSTEM_EX( "colors", &‪__init__, &‪__main__, undefined )
34 
35 function ‪__init__()
36 {
37  nodes = GetAllNodes();
38 
39  // friendly spawner global stuff
40  level ‪flag::init( "player_looks_away_from_spawner" );
41  level ‪flag::init( "friendly_spawner_locked" );
42 
43  // can be turned on and off to control friendly_respawn_trigger
44  level ‪flag::init( "respawn_friendlies" );
45 
46  level.arrays_of_colorCoded_nodes = [];
47  level.arrays_of_colorCoded_nodes[ "axis" ] = [];
48  level.arrays_of_colorCoded_nodes[ "allies" ] = [];
49 
50  level.colorCoded_volumes = [];
51  level.colorCoded_volumes[ "axis" ] = [];
52  level.colorCoded_volumes[ "allies" ] = [];
53 
54  volumes = GetEntArray( "info_volume", "classname" );
55 
56  // go through all the nodes and if they have color codes then add them too
57  for( i=0;i<nodes.size;i++ )
58  {
59  if( IsDefined( nodes[ i ].script_color_allies ) )
60  {
61  nodes[ i ] ‪add_node_to_global_arrays( nodes[ i ].script_color_allies, "allies" );
62  }
63 
64  if( IsDefined( nodes[ i ].script_color_axis ) )
65  {
66  nodes[ i ] ‪add_node_to_global_arrays( nodes[ i ].script_color_axis, "axis" );
67  }
68  }
69 
70  // volumes that have color codes wait for trigger and then fire their colorcode to control fixednodesafe volumes
71  for( i=0;i<volumes.size;i++ )
72  {
73  if( IsDefined( volumes[ i ].script_color_allies ) )
74  {
75  volumes[ i ] ‪add_volume_to_global_arrays( volumes[ i ].script_color_allies, "allies" );
76  }
77 
78  if( IsDefined( volumes[ i ].script_color_axis ) )
79  {
80  volumes[ i ] ‪add_volume_to_global_arrays( volumes[ i ].script_color_axis, "axis" );
81  }
82  }
83 
84  level.color_node_type_function = [];
85 
86  ‪add_cover_node( "BAD NODE" );
87  ‪add_cover_node( "Cover Stand" );
88  ‪add_cover_node( "Cover Crouch" );
89  ‪add_cover_node( "Cover Prone" );
90  ‪add_cover_node( "Cover Crouch Window" );
91  ‪add_cover_node( "Cover Right" );
92  ‪add_cover_node( "Cover Left" );
93  ‪add_cover_node( "Cover Wide Left" );
94  ‪add_cover_node( "Cover Wide Right" );
95  ‪add_cover_node( "Cover Pillar" );
96  ‪add_cover_node( "Conceal Stand" );
97  ‪add_cover_node( "Conceal Crouch" );
98  ‪add_cover_node( "Conceal Prone" );
99  ‪add_cover_node( "Reacquire" );
100  ‪add_cover_node( "Balcony" );
101  ‪add_cover_node( "Scripted" );
102  ‪add_cover_node( "Begin" );
103  ‪add_cover_node( "End" );
104  ‪add_cover_node( "Turret" );
105  ‪add_path_node( "Guard" );
106  ‪add_path_node( "Exposed" );
107  ‪add_path_node( "Path" );
108 
109  level.colorList = [];
110  level.colorList[ level.colorList.size ] = "r";
111  level.colorList[ level.colorList.size ] = "b";
112  level.colorList[ level.colorList.size ] = "y";
113  level.colorList[ level.colorList.size ] = "c";
114  level.colorList[ level.colorList.size ] = "g";
115  level.colorList[ level.colorList.size ] = "p";
116  level.colorList[ level.colorList.size ] = "o";
117 
118  level.colorCheckList[ "red" ] = "r";
119  level.colorCheckList[ "r" ] = "r";
120  level.colorCheckList[ "blue" ] = "b";
121  level.colorCheckList[ "b" ] = "b";
122  level.colorCheckList[ "yellow" ]= "y";
123  level.colorCheckList[ "y" ] = "y";
124  level.colorCheckList[ "cyan" ] = "c";
125  level.colorCheckList[ "c" ] = "c";
126  level.colorCheckList[ "green" ] = "g";
127  level.colorCheckList[ "g" ] = "g";
128  level.colorCheckList[ "purple" ]= "p";
129  level.colorCheckList[ "p" ] = "p";
130  level.colorCheckList[ "orange" ]= "o";
131  level.colorCheckList[ "o" ] = "o";
132 
133  level.currentColorForced = [];
134  level.currentColorForced[ "allies" ] = [];
135  level.currentColorForced[ "axis" ] = [];
136 
137  level.lastColorForced = [];
138  level.lastColorForced[ "allies" ] = [];
139  level.lastColorForced[ "axis" ] = [];
140 
141  for( i = 0; i < level.colorList.size; i++ )
142  {
143  level.arrays_of_colorForced_ai[ "allies" ][ level.colorList[ i ] ] = [];
144  level.arrays_of_colorForced_ai[ "axis" ][ level.colorList[ i ] ] = [];
145  level.currentColorForced[ "allies" ][ level.colorList[ i ] ] = undefined;
146  level.currentColorForced[ "axis" ][ level.colorList[ i ] ] = undefined;
147  }
148 }
149 
150 function ‪__main__()
151 {
152  foreach ( trig in ‪trigger::get_all() )
153  {
154  if ( isdefined( trig.script_color_allies ) )
155  {
156  trig thread ‪trigger_issues_orders( trig.script_color_allies, "allies" );
157  }
158 
159  if ( isdefined( trig.script_color_axis ) )
160  {
161  trig thread ‪trigger_issues_orders( trig.script_color_axis, "axis" );
162  }
163  }
164 }
165 
169 
171 {
172  thread ‪player_color_node();
173 }
174 
176 {
177  // shorten the forcecolors string to a single letter
178  self.script_forceColor = level.colorCheckList[ self.script_forceColor ];
179 }
180 
182 {
183  if( !IsDefined( self.currentColorCode ) )
184  {
185  return;
186  }
187 
188  nodes = level.arrays_of_colorCoded_nodes[ self.team ][ self.currentColorCode ];
189  ‪ARRAY_ADD( nodes, level.colorCoded_volumes[ self.team ][ self.currentColorCode ] );
190 
191  self ‪left_color_node();
192  // can be deleted/killed during left_color_node
193  if( !isalive( self ) )
194  {
195  return;
196  }
197 
198  // can lose color during left_color_node
199  if( !‪has_color() )
200  {
201  return;
202  }
203 
204 
205  for( i=0; i <nodes.size; i++ )
206  {
207  node = nodes[ i ];
208  if ( isalive( node.color_user ) && !IsPlayer(node.color_user) )
209  {
210  continue;
211  }
212 
213  self thread ‪ai_sets_goal_with_delay( node );
214 
215  thread ‪decrementColorUsers( node );
216  return;
217  }
218 
219  /#println( "AI with export " + self.export + " was told to go to color node but had no node to go to." );#/
220 }
221 
222 
224 {
225  colorList = [];
226  // returns an array of the acceptable color letters
227  colorList[ colorList.size ] = "r";
228  colorList[ colorList.size ] = "b";
229  colorList[ colorList.size ] = "y";
230  colorList[ colorList.size ] = "c";
231  colorList[ colorList.size ] = "g";
232  colorList[ colorList.size ] = "p";
233  colorList[ colorList.size ] = "o";
234 
235  return colorList;
236 }
237 
238 function ‪get_colorcodes_from_trigger( color_team, team )
239 {
240  colorCodes = strtok( color_team, " " );
241  colors = [];
242  colorCodesByColorIndex = [];
243  usable_colorCodes = [];
244 
245  colorList = ‪get_color_list();
246 
247  for( i = 0; i < colorCodes.size; i++ )
248  {
249  color = undefined;
250  for( p = 0; p < colorList.size; p++ )
251  {
252  if( issubstr( colorCodes[ i ], colorList[ p ] ) )
253  {
254  color = colorList[ p ];
255  break;
256  }
257  }
258 
259  // does this order actually tie to existing nodes?
260  if( !IsDefined( level.arrays_of_colorCoded_nodes[ team ][ colorCodes[ i ] ] )
261  && !IsDefined( level.colorCoded_volumes[ team ][ colorCodes[ i ] ] )
262  )
263  {
264  continue;
265  }
266 
267 
268 
269  assert( IsDefined( color ), "Trigger at origin " + self getorigin() + " had strange color index " + colorCodes[ i ] );
270 
271  colorCodesByColorIndex[ color ] = colorCodes[ i ];
272  colors[ colors.size ] = color;
273  usable_colorCodes[ usable_colorCodes.size ] = colorCodes[ i ];
274  }
275 
276  // color codes that don't tie to existing nodes have been culled
277  colorCodes = usable_colorCodes;
278 
279  ‪array = [];
280  ‪array[ "colorCodes" ] = colorCodes;
281  ‪array[ "colorCodesByColorIndex" ] = colorCodesByColorIndex;
282  ‪array[ "colors" ] = colors;
283  return ‪array;
284 }
285 
286 function ‪trigger_issues_orders( color_team, team )
287 {
288  self endon( "death" );
289 
290  ‪array = ‪get_colorcodes_from_trigger( color_team, team );
291  colorCodes = ‪array[ "colorCodes" ];
292  colorCodesByColorIndex = ‪array[ "colorCodesByColorIndex" ];
293  colors = ‪array[ "colors" ];
294 
295  if ( isdefined( self.target ) )
296  {
297  a_s_targets = ‪struct::get_array( self.target, "targetname" );
298  foreach( s_target in a_s_targets )
299  {
300  if ( ‪IS_EQUAL( s_target.script_string, "hero_catch_up" ) )
301  {
302  ‪DEFAULT( self.a_s_hero_catch_up, [] );
303  ‪ARRAY_ADD( self.a_s_hero_catch_up, s_target );
304  if( isdefined( s_target.script_num ) )//Check struct for distance override
305  {
306  self.num_hero_catch_up_dist = s_target.script_num;
307  }
308  }
309  }
310  }
311 
312  for( ;; )
313  {
314  self waittill( "trigger" );
315 
316  if( IsDefined( self.activated_color_trigger ) )
317  {
318  // activated by an _utility::activate_trigger() call, so don't bother running activate_color_trigger() again.
319  self.activated_color_trigger = undefined;
320  continue;
321  }
322 
323  if( !IsDefined( self.color_enabled ) || ( IsDefined( self.color_enabled ) && self.color_enabled ) )
324  {
325  ‪activate_color_trigger_internal( colorCodes, colors, team, colorCodesByColorIndex );
326  }
327 
329  }
330 }
331 
333 {
334  if( !IsDefined( self.script_color_stay_on ) )
335  {
336  self.script_color_stay_on = false;
337  }
338 
339  if( !IsDefined( self.color_enabled ) )
340  {
341  if( ‪IS_TRUE( self.script_color_stay_on ) )
342  {
343  self.color_enabled = true;
344  }
345  else
346  {
347  self.color_enabled = false;
348  }
349  }
350 }
351 
353 {
354  if ( team == "allies" )
355  {
356  self thread ‪get_colorcodes_and_activate_trigger( self.script_color_allies, team );
357  }
358  else
359  {
360  self thread ‪get_colorcodes_and_activate_trigger( self.script_color_axis, team );
361  }
362 }
363 
364 function ‪get_colorcodes_and_activate_trigger( color_team, team )
365 {
366  ‪array = ‪get_colorcodes_from_trigger( color_team, team );
367  colorCodes = ‪array[ "colorCodes" ];
368  colorCodesByColorIndex = ‪array[ "colorCodesByColorIndex" ];
369  colors = ‪array[ "colors" ];
370 
371  ‪activate_color_trigger_internal( colorCodes, colors, team, colorCodesByColorIndex );
372 }
373 
374 function private ‪is_target_visible( target )
375 {
376  n_player_fov = GetDvarFloat( "cg_fov" );
377  n_dot_check = cos( n_player_fov );
378 
379  v_pos = target;
380  if ( !IsVec( target ) )
381  {
382  v_pos = target.origin;
383  }
384 
385  foreach ( player in level.players )
386  {
387  v_eye = player GetEye();
388  v_facing = AnglesToForward( player GetPlayerAngles() );
389  v_to_ent = VectorNormalize( v_pos - v_eye );
390  n_dot = VectorDot( v_facing, v_to_ent );
391 
392  if ( n_dot > n_dot_check )
393  {
394  return true;
395  }
396  else if ( IsVec( target ) )
397  {
398  a_trace = BulletTrace( v_eye, target, false, player );
399  if ( a_trace["fraction"] == 1 )
400  {
401  return true;
402  }
403  }
404  else if ( target SightConeTrace( v_eye, player ) != 0 )
405  {
406  return true;
407  }
408  }
409 
410  return false;
411 }
412 
413 // Teleports a hero once it's safe to do so (no telefragging, no player visibility)."
414 //
415 // Will bail if one of the teleport points is further from the goal than the hero.
416 //
417 function ‪hero_catch_up_teleport( s_teleport, n_min_dist_from_player = 400.0, b_disable_colors = false, func_callback )
418 {
419  self notify( "_hero_catch_up_teleport_" );
420  self endon( "_hero_catch_up_teleport_" );
421  self endon( "stop_hero_catch_up_teleport" );
422 
423  const n_telefrag_radius = 16.0;
424  const n_teleport_cooldown_ms = 2000;
425 
426  n_min_player_dist_sq = n_min_dist_from_player * n_min_dist_from_player;
427 
428  self endon( "death" );
429 
430  a_teleport = s_teleport;
431  ‪MAKE_ARRAY( a_teleport );
432  a_teleport = array::randomize( a_teleport );
433 
434  while ( true )
435  {
436  b_player_nearby = false;
437  foreach( player in level.players )
438  {
439  if ( DistanceSquared( player.origin, self.origin ) < n_min_player_dist_sq )
440  {
441  b_player_nearby = true;
442  break;
443  }
444  }
445 
446  if ( !b_player_nearby )
447  {
448  n_ai_dist = -1.0;
449  if ( isdefined( self.goal ) )
450  {
451  n_ai_dist = self CalcPathLength( self.node );
452  }
453 
454  foreach( s in a_teleport )
455  {
456  if ( PositionWouldTelefrag( s.origin ) )
457  {
458  continue;
459  }
460 
461  if ( isdefined( s.teleport_cooldown ) )
462  {
463  if ( GetTime() < s.teleport_cooldown )
464  {
465  continue;
466  }
467  }
468 
469  // Don't teleport on top of heroes.
470  //
471  if ( self.team == "allies" && isdefined( level.heroes ) )
472  {
473  hit_hero = ArrayGetClosest( s.origin, level.heroes, n_telefrag_radius );
474  if ( isdefined( hit_hero ) )
475  {
476  continue;
477  }
478  }
479 
480  // Distance from teleport location to the goal node.
481  if ( isdefined( self.node ) && n_ai_dist >= 0.0 )
482  {
483  // If the teleport position would put us further from our goal, we're close enough.
484  n_teleport_distance = PathDistance( s.origin, self.node.origin );
485  if ( n_teleport_distance > n_ai_dist )
486  {
487  return;
488  }
489  }
490 
491  // Don't teleport if someone's looking at them.
492  //
493  if ( ‪is_target_visible( self ) )
494  {
495  continue;
496  }
497 
498  // Don't teleport if someone's looking at the destination.
499  //
500  if ( ‪is_target_visible( s.origin ) )
501  {
502  continue;
503  }
504 
505  if ( isdefined( self.script_forceColor ) || b_disable_colors )
506  {
507  if ( self ForceTeleport( s.origin, s.angles, true, true ) )
508  {
509  self PathMode( "move allowed" );
510 
511  s.teleport_cooldown = GetTime() + n_teleport_cooldown_ms;
512 
513  self notify( "hero_catch_up_teleport" );
514 
515  if ( b_disable_colors )
516  {
517  ‪disable();
518  }
519  else
520  {
521  self ‪colors::set_force_color( self.script_forceColor );
522  }
523 
524  if ( isdefined( func_callback ) )
525  {
526  self [[ func_callback ]]();
527  }
528 
529  return;
530  }
531  }
532  }
533  }
534  else
535  {
536  return;//A player is close, no need to keep checking
537  }
538 
539  // Try again soon.
540  wait 0.5;
541  }
542 }
543 
544 
545 function ‪activate_color_trigger_internal( colorCodes, colors, team, colorCodesByColorIndex )
546 {
547  // remove all the dead from any colors this trigger effects
548  // a trigger should never effect the same color twice
549  for( i = 0; i < colorCodes.size; i++ )
550  {
551  if( !IsDefined( level.arrays_of_colorCoded_spawners[ team ][ colorCodes[ i ] ] ) )
552  {
553  continue;
554  }
555 
556  // remove deleted spawners
557  ArrayRemoveValue( level.arrays_of_colorCoded_spawners[ team ][ colorCodes[ i ] ], undefined );
558 
559  // set the .currentColorCode on each appropriate spawner
560  for( p = 0; p < level.arrays_of_colorCoded_spawners[ team ][ colorCodes[ i ] ].size; p++ )
561  {
562  level.arrays_of_colorCoded_spawners[ team ][ colorCodes[ i ] ][ p ].currentColorCode = colorCodes[ i ];
563  }
564  }
565 
566  for( i = 0; i < colors.size; i++ )
567  {
568  // remove the dead from the color forced ai
569  level.arrays_of_colorForced_ai[ team ][ colors[ i ] ] = array::remove_dead( level.arrays_of_colorForced_ai[ team ][ colors[ i ] ] );
570 
571  // set the last color forced so we can compare it with current when we tell guys to go to nodes,
572  // so they can prefer new nodes over old ones, so they move up
573  level.lastColorForced[ team ][ colors[ i ] ] = level.currentColorForced[ team ][ colors[ i ] ];
574 
575  // set the destination of the color forced spawners
576  level.currentColorForced[ team ][ colors[ i ] ] = colorCodesByColorIndex[ colors[ i ] ];
577 
578  /#
579  assert( IsDefined( level.arrays_of_colorCoded_nodes[ team ][ level.currentColorForced[ team ][ colors[ i ] ] ] )
580  || IsDefined( level.colorCoded_volumes[ team ][ level.currentColorForced[ team ][ colors[ i ] ] ] ),
581  "Trigger tried to set colorCode " + colors[ i ] + " but there are no nodes for " + team + " that use that color combo." );
582  #/
583  }
584 
585  ai_array = [];
586 
587  for ( i = 0; i < colorCodes.size; i++ )
588  {
589  // no need to run this again if it's still the current forced color
590  if ( ‪same_color_code_as_last_time( team, colors[ i ] ) )
591  {
592  continue;
593  }
594 
595  colorCode = colorCodes[ i ];
596 
597  if ( !IsDefined( level.arrays_of_colorCoded_ai[ team ][ colorCode ] ) )
598  {
599  continue;
600  }
601 
602  ai_array[ colorCode ] = ‪issue_leave_node_order_to_ai_and_get_ai( colorCode, colors[ i ], team );
603 
604  if ( isdefined( self.a_s_hero_catch_up ) && ai_array.size > 0 )
605  {
606  if( isdefined( ai_array[ colorCode ] ) )
607  {
608  for ( j = 0; j < ai_array[ colorCode ].size; j++ )
609  {
610  ai = ai_array[ colorCode ][ j ];
611  if ( ‪IS_TRUE( ai.is_hero ) && IsDefined( ai.script_forceColor ) )
612  {
613  ai thread ‪hero_catch_up_teleport( self.a_s_hero_catch_up );
614  }
615  }
616  }
617  }
618  }
619 
620  for( i = 0; i < colorCodes.size; i++ )
621  {
622  colorCode = colorCodes[ i ];
623  if ( !IsDefined( ai_array[ colorCode ] ) )
624  {
625  continue;
626  }
627 
628  // no need to run this again if it's still the current forced color
629  if( ‪same_color_code_as_last_time( team, colors[ i ] ) )
630  {
631  continue;
632  }
633 
634  if ( !IsDefined( level.arrays_of_colorCoded_ai[ team ][ colorCode ] ) )
635  {
636  continue;
637  }
638 
639  ‪issue_color_order_to_ai( colorCode, colors[ i ], team, ai_array[ colorCode ] );
640  }
641 }
642 
643 function ‪same_color_code_as_last_time( team, color )
644 {
645  if( !IsDefined( level.lastColorForced[ team ][ color ] ) )
646  {
647  return false;
648  }
649 
650  return level.lastColorForced[ team ][ color ] == level.currentColorForced[ team ][ color ];
651 }
652 
653 
655 {
656  // nodes that were in the last color order go at the end
657  if( issubstr( node.script_color_allies, lastColor ) )
658  {
659  self.cover_nodes_last[ self.cover_nodes_last.size ] = node;
660  }
661  else
662  {
663  self.cover_nodes_first[ self.cover_nodes_first.size ] = node;
664  }
665 }
666 
668 {
669  // nodes that were in the last color order go at the end
670  if( issubstr( node.script_color_axis, lastColor ) )
671  {
672  self.cover_nodes_last[ self.cover_nodes_last.size ] = node;
673  }
674  else
675  {
676  self.cover_nodes_first[ self.cover_nodes_first.size ] = node;
677  }
678 }
679 
680 function ‪process_cover_node( node, null )
681 {
682  self.cover_nodes_first[ self.cover_nodes_first.size ] = node;
683 }
684 
685 function ‪process_path_node( node, null )
686 {
687  self.path_nodes[ self.path_nodes.size ] = node;
688 }
689 
690 function ‪prioritize_colorCoded_nodes( team, colorCode, color )
691 {
692  nodes = level.arrays_of_colorCoded_nodes[ team ][ colorCode ];
693 
694  // need a place to store the nodes externally so we can put the pathnodes in the back
695  ent = spawnstruct();
696  ent.path_nodes = [];
697  ent.cover_nodes_first = [];
698  ent.cover_nodes_last = [];
699 
700  lastColorForced_exists = IsDefined( level.lastColorForced[ team ][ color ] );
701 
702  // fills ent.path_nodes or .cover_nodes depending on node type
703  for( i=0 ; i < nodes.size; i++ )
704  {
705  node = nodes[ i ];
706  ent [ [ level.color_node_type_function[ node.type ][ lastColorForced_exists ][ team ] ] ]( node, level.lastColorForced[ team ][ color ] );
707  }
708 
709  ent.cover_nodes_first = array::randomize( ent.cover_nodes_first );
710  nodes = ent.cover_nodes_first;
711 
712  // put the path nodes at the end of the array so they're less favored
713  for( i=0; i < ent.cover_nodes_last.size; i++ )
714  {
715  nodes[ nodes.size ] = ent.cover_nodes_last[ i ];
716  }
717 
718  for( i=0; i < ent.path_nodes.size; i++ )
719  {
720  nodes[ nodes.size ] = ent.path_nodes[ i ];
721  }
722 
723  level.arrays_of_colorCoded_nodes[ team ][ colorCode ] = nodes;
724 }
725 
726 function ‪get_prioritized_colorCoded_nodes( team, colorCode, color )
727 {
728  if ( IsDefined( level.arrays_of_colorCoded_nodes[ team ][ colorCode ] ) )
729  return level.arrays_of_colorCoded_nodes[ team ][ colorCode ];
730 
731  if ( IsDefined( level.colorCoded_volumes[ team ][ colorCode ] ) )
732  return level.colorCoded_volumes[ team ][ colorCode ];
733 }
734 
735 function ‪issue_leave_node_order_to_ai_and_get_ai( colorCode, color, team )
736 {
737  // remove dead from this specific colorCode
738  level.arrays_of_colorCoded_ai[ team ][ colorCode ] = array::remove_dead( level.arrays_of_colorCoded_ai[ team ][ colorCode ] );
739  ai = level.arrays_of_colorCoded_ai[ team ][ colorCode ];
740  ai = ArrayCombine( ai, level.arrays_of_colorForced_ai[ team ][ color ], true, false );
741  newArray = [];
742  for( i=0;i<ai.size;i++ )
743  {
744  // ignore AI that are already going to this colorCode
745  if( IsDefined( ai[ i ].currentColorCode ) && ai[ i ].currentColorCode == colorCode )
746  {
747  continue;
748  }
749  newArray[ newArray.size ] = ai[ i ];
750  }
751 
752  ai = newArray;
753  if( !ai.size )
754  {
755  return;
756  }
757 
758  for( i=0; i < ai.size; i++ )
759  {
760  ai[ i ] ‪left_color_node();
761  }
762 
763  return ai;
764 }
765 
766 function ‪issue_color_order_to_ai( colorCode, color, team, ai )
767 {
768  original_ai_array = ai;
769 
770  ‪prioritize_colorCoded_nodes( team, colorCode, color );
771  nodes = ‪get_prioritized_colorCoded_nodes( team, colorCode, color );
772 
773  /#
774  if( nodes.size < ai.size )
775  {
776  println( "^3Warning, ColorNumber system tried to make " + ai.size + " AI go to " + nodes.size + " nodes." );
777  }
778  #/
779 
780  counter = 0;
781  ai_count = ai.size;
782  for( i=0; i < nodes.size; i++ )
783  {
784  node = nodes[ i ];
785  // add guys to the nodes with the fewest AI on them
786  if( isalive( node.color_user ) )
787  {
788  continue;
789  }
790 
791  closestAI = ArraySort( ai, node.origin, true, 1 )[0];
792  assert( isalive( closestAI ) );
793  ArrayRemoveValue( ai, closestAI );
794 
795  closestAI ‪take_color_node( node, colorCode, self, counter );
796  counter++;
797 
798  if( !ai.size )
799  {
800  return;
801  }
802  }
803 }
804 
805 function ‪take_color_node( node, colorCode, trigger, counter )
806 {
807  self notify( "stop_color_move" );
808  self.script_careful = true;
809  self.currentColorCode = colorCode;
810  self thread ‪process_color_order_to_ai( node, trigger, counter );
811 }
812 
814 {
815  // detect if the player gets a node and set its .color_user
816  for( ;; )
817  {
818  playerNode = undefined;
819  if( !IsDefined( self.node ) )
820  {
822  continue;
823  }
824 
825  olduser = self.node.color_user;
826 
827  playerNode = self.node;
828  playerNode.color_user = self;
829 
830  for( ;; )
831  {
832  if( !IsDefined( self.node ) )
833  {
834  break;
835  }
836  if( self.node != playerNode )
837  {
838  break;
839  }
841  }
842 
843  playerNode.color_user = undefined;
844 
845  playerNode ‪color_node_finds_a_user();
846  }
847 }
848 
850 {
851  if ( IsDefined( self.script_color_allies ) )
852  {
853  ‪color_node_finds_user_from_colorcodes( self.script_color_allies, "allies" );
854  }
855 
856  if ( IsDefined( self.script_color_axis ) )
857  {
858  ‪color_node_finds_user_from_colorcodes( self.script_color_axis, "axis" );
859  }
860 }
861 
862 function ‪color_node_finds_user_from_colorcodes( colorCodeString, team )
863 {
864  if ( IsDefined( self.color_user ) )
865  {
866  // If we successfully found a guy for this node then we shouldnt go find another
867  return;
868  }
869 
870  colorCodes = strtok( colorCodeString, " " );
871  array::thread_all_ents( colorCodes,&‪color_node_finds_user_for_colorCode, team );
872 }
873 
874 function ‪color_node_finds_user_for_colorCode( colorCode, team )
875 {
876  color = colorCode[ 0 ];
877  assert( ‪colorIsLegit( color ), "Color " + color + " is not legit" );
878 
879  if ( !IsDefined( level.currentColorForced[ team ][ color ] ) )
880  {
881  // AI of this color are not assigned to a colornode currently
882  return;
883  }
884 
885  if ( level.currentColorForced[ team ][ color ] != colorCode )
886  {
887  // AI of this color are not currently assigned to our colorCode
888  return;
889  }
890 
891  ai = ‪get_force_color_guys( team, color );
892  if ( !ai.size )
893  {
894  return;
895  }
896 
897  for ( i = 0; i < ai.size; i++ )
898  {
899  guy = ai[ i ];
900  if ( guy ‪occupies_colorCode( colorCode ) )
901  {
902  continue;
903  }
904 
905  // found a guy that should use this node, so assign and get out
906  guy ‪take_color_node( self, colorCode );
907  return;
908  }
909 }
910 
911 function ‪occupies_colorCode( colorCode )
912 {
913  if ( !IsDefined( self.currentColorCode ) )
914  {
915  return false;
916  }
917 
918  return self.currentColorCode == colorCode;
919 }
920 
922 {
923  self endon( "death" );
925  if ( ‪delay )
926  {
927  wait( ‪delay );
928  }
929  ‪ai_sets_goal( node );
930 }
931 
932 function ‪ai_sets_goal( node )
933 {
934  // makes AI stop trying to run to their chain of nodes in _spawner go_to_node
935  self notify( "stop_going_to_node" );
936 
937  ‪set_goal_and_volume( node );
938  volume = level.colorCoded_volumes[ self.team ][ self.currentColorCode ];
939 
940  // SUMEET TODO - Do we need support for careful logic anymore?
941  //if ( IS_TRUE( self.script_careful ) )
942  //{
943  // thread careful_logic( node, volume );
944  //}
945 }
946 
947 function ‪set_goal_and_volume( node )
948 {
949  if ( IsDefined( self._colors_go_line ) )
950  {
951  self notify( "colors_go_line_done" );
952  self._colors_go_line = undefined;
953  }
954 
955  if( ‪IS_TRUE( node.radius ) )
956  {
957  self.goalradius = node.radius;
958  }
959 
960  if ( ‪IS_TRUE( node.script_forcegoal ) )
961  {
962  self thread ‪color_force_goal(node);
963  }
964  else
965  {
966  self SetGoal( node );
967  }
968 
969  volume = level.colorCoded_volumes[ self.team ][ self.currentColorCode ];
970  if ( IsDefined( volume ) )
971  {
972  self SetGoal( volume );
973  }
974  else
975  {
976  self ClearFixedNodeSafeVolume();
977  }
978 
979  if( IsDefined( node.fixedNodeSafeRadius ) )
980  {
981  self.fixedNodeSafeRadius = node.fixedNodeSafeRadius;
982  }
983  else
984  {
985  self.fixedNodeSafeRadius = ‪COLOR_FIXED_NODE_RADIUS;
986  }
987 }
988 
989 function ‪color_force_goal(node)
990 {
991  self endon("death");
992  self thread ‪ai::force_goal( node, undefined, true, "stop_color_forcegoal", true );
993  self ‪util::waittill_either( "goal", "stop_color_move" );
994  self notify( "stop_color_forcegoal" );
995 }
996 
997 function ‪careful_logic( node, volume )
998 {
999  self endon( "death" );
1000  self endon( "stop_being_careful" );
1001  self endon( "stop_going_to_node" );
1002  thread ‪recover_from_careful_disable( node );
1003 
1004  for ( ;; )
1005  {
1007  ‪use_big_goal_until_goal_is_safe( node, volume );
1008 
1009  ‪set_goal_and_volume( node );
1010  }
1011 }
1012 
1014 {
1015  self endon( "death" );
1016  self endon( "stop_going_to_node" );
1017  self waittill( "stop_being_careful" );
1018 
1019  ‪set_goal_and_volume( node );
1020 }
1021 
1022 function ‪use_big_goal_until_goal_is_safe( node, volume )
1023 {
1024  self.goalradius = ‪COLOR_NODE_BIG_RADIUS;
1025  self SetGoal( self.origin );
1026 
1027  if ( IsDefined( volume ) )
1028  {
1029  for ( ;; )
1030  {
1031  wait( 1 );
1032 
1033  if ( self isKnownEnemyInRadius( node.origin, self.fixedNodeSafeRadius ) )
1034  {
1035  continue;
1036  }
1037  if ( self isKnownEnemyInVolume( volume ) )
1038  {
1039  continue;
1040  }
1041 
1042  return;
1043  }
1044  }
1045  else
1046  {
1047  for ( ;; )
1048  {
1049  if ( !( self isKnownEnemyInRadius( node.origin, self.fixedNodeSafeRadius ) ) )
1050  {
1051  return;
1052  }
1053 
1054  wait( 1 );
1055  }
1056  }
1057 }
1058 
1060 {
1061  if ( IsDefined( volume ) )
1062  {
1063  for ( ;; )
1064  {
1065  if ( self IsKnownEnemyInRadius( node.origin, self.fixedNodeSafeRadius ) )
1066  {
1067  return;
1068  }
1069 
1070  if ( self IsKnownEnemyInVolume( volume ) )
1071  {
1072  return;
1073  }
1074 
1075  wait( 1 );
1076  }
1077  }
1078  else
1079  {
1080  for ( ;; )
1081  {
1082  if ( self IsKnownEnemyInRadius( node.origin, self.fixedNodeSafeRadius ) )
1083  {
1084  return;
1085  }
1086 
1087  wait( 1 );
1088  }
1089  }
1090 }
1091 
1093 {
1094  if ( !IsDefined( self.node ) )
1095  {
1096  return false;
1097  }
1098 
1099  return self.node ‪util::script_delay();
1100 }
1101 
1102 function ‪process_color_order_to_ai( node, trigger, counter )
1103 {
1104  thread ‪decrementColorUsers( node );
1105 
1106  self endon( "stop_color_move" );
1107  self endon( "death" );
1108 
1109  if ( IsDefined( trigger ) )
1110  {
1111  trigger ‪util::script_delay();
1112  }
1113 
1114  // wait if need to wait on a flag
1115  if( IsDefined( trigger ) )
1116  {
1117  if( IsDefined( trigger.script_flag_wait ) )
1118  level ‪flag::wait_till( trigger.script_flag_wait );
1119  }
1120 
1121  if ( !‪my_current_node_delays() )
1122  {
1123  if ( IsDefined( counter ) )
1124  {
1125  wait( counter * RandomFloatRange( 0.2, 0.35 ) );
1126  }
1127  }
1128 
1129  self ‪ai_sets_goal( node );
1130 
1131  // record the node so the guy can find out who has his node, and get that guys
1132  self.color_ordered_node_assignment = node;
1133 
1134  for( ;; )
1135  {
1136  self waittill( "node_taken", taker );
1137  if( taker == self )
1138  {
1139  // give time for the player to claim the node
1141  }
1142 
1143  // lost our node so try to get a new one
1145  if( IsDefined( node ) )
1146  {
1147  assert( !isalive( node.color_user ), "Node already had color user!" );
1148  if( isalive( self.color_node.color_user ) && self.color_node.color_user == self )
1149  {
1150  self.color_node.color_user = undefined;
1151  }
1152  self.color_node = node;
1153  node.color_user = self;
1154  self ‪ai_sets_goal( node );
1155  }
1156  }
1157 }
1158 
1159 
1160 
1162 {
1163  assert( self.team != "neutral" );
1164  assert( IsDefined( self.script_forceColor ), "AI with export " + self.export + " lost his script_forcecolor.. somehow." );
1165  colorCode = level.currentColorForced[ self.team ][ self.script_forceColor ];
1166 
1167  nodes = ‪get_prioritized_colorCoded_nodes( self.team, colorCode, self.script_forcecolor );
1168 
1169  assert( nodes.size > 0, "Tried to make guy with export " + self.export + " go to forcecolor " + self.script_forceColor + " but there are no nodes of that color enabled" );
1170  for( i=0; i < nodes.size; i++ )
1171  {
1172  if( !isalive( nodes[ i ].color_user ) )
1173  {
1174  return nodes[ i ];
1175  }
1176  }
1177 }
1178 
1180 {
1181  assert( self.team != "neutral" );
1182  assert( IsDefined( self.script_forceColor ), "AI with export " + self.export + " lost his script_forcecolor.. somehow." );
1183  colorCode = level.currentColorForced[ self.team ][ self.script_forceColor ];
1184  nodes = ‪get_prioritized_colorCoded_nodes( self.team, colorCode, self.script_forcecolor );
1185 
1186  assert( nodes.size > 0, "Tried to make guy with export " + self.export + " go to forcecolor " + self.script_forceColor + " but there are no nodes of that color enabled" );
1187 
1188  nodes = ArraySort( nodes, self.origin );
1189 
1190  for( i=0; i < nodes.size; i++ )
1191  {
1192  if( !isalive( nodes[ i ].color_user ) )
1193  {
1194  return nodes[ i ];
1195  }
1196  }
1197 }
1198 
1200 {
1201  self endon( "stopScript" );
1202  self endon( "death" );
1203 
1204  if( IsDefined( self.node ) )
1205  {
1206  return;
1207  }
1208 
1209  // first check to see if we're right near it
1210  if( distancesquared( node.origin, self.origin ) < 32*32 )
1211  {
1213  return;
1214  }
1215 
1216  // if we're far away, maybe somebody cut us off then took our node, now we're stuck in limbo
1217  // so wait one second, if we're still in stop script( ie no killanimscripts ) then push the guy
1218  // off the node
1219  currentTime = gettime();
1221  newTime = gettime();
1222 
1223  // did we break out of stop fast enough to indicate we continued moving? If not, then reclaim the node
1224  if( newTime - currentTime >= 1000 )
1225  {
1227  }
1228 }
1229 
1231 {
1232  self endon( "killanimscript" );
1233  wait( ‪timer );
1234 }
1235 
1236 
1238 {
1239 
1240 
1241  ai = GetAIArray();
1242  for( i=0;i<ai.size;i++ )
1243  {
1244  if( !IsDefined( ai[ i ].node ) )
1245  {
1246  continue;
1247  }
1248 
1249  if( ai[ i ].node != node )
1250  {
1251  continue;
1252  }
1253 
1254  ai[ i ] notify( "eject_from_my_node" );
1255  wait( 1 );
1256  self notify( "eject_from_my_node" );
1257  return true;
1258  }
1259  return false;
1260 }
1261 
1262 
1263 function ‪decrementColorUsers( node )
1264 {
1265  node.color_user = self;
1266  self.color_node = node;
1267 
1268  self endon( "stop_color_move" );
1269  self waittill( "death" );
1270  self.color_node.color_user = undefined;
1271 }
1272 
1273 function ‪colorIsLegit( color )
1274 {
1275  for( i = 0; i < level.colorList.size; i++ )
1276  {
1277  if( color == level.colorList[ i ] )
1278  {
1279  return true;
1280  }
1281  }
1282  return false;
1283 }
1284 
1285 function ‪add_volume_to_global_arrays( colorCode, team )
1286 {
1287  colors = strtok( colorCode, " " );
1288 
1289  for( p = 0; p < colors.size; p++ )
1290  {
1291  assert( !IsDefined( level.colorCoded_volumes[ team ][ colors[ p ] ] ), "Multiple info_volumes exist with color code " + colors[ p ] );
1292 
1293  level.colorCoded_volumes[ team ][ colors[ p ] ] = self;
1294  }
1295 }
1296 
1297 function ‪add_node_to_global_arrays( colorCode, team )
1298 {
1299  self.color_user = undefined;
1300  colors = strtok( colorCode, " " );
1301 
1302  for( p = 0; p < colors.size; p++ )
1303  {
1304  if( IsDefined( level.arrays_of_colorCoded_nodes[ team ] ) && IsDefined( level.arrays_of_colorCoded_nodes[ team ][ colors[ p ] ] ) )
1305  {
1306  // array already exists so add this color coded node to that color code array.
1307  ‪ARRAY_ADD( level.arrays_of_colorCoded_nodes[ team ][ colors[ p ] ], self );
1308  continue;
1309  }
1310 
1311  // array doesn't exist so we have to initialize all the variables related to this color coding.
1312  level.arrays_of_colorCoded_nodes[ team ][ colors[ p ] ][ 0 ] = self;
1313  level.arrays_of_colorCoded_ai[ team ][ colors[ p ] ] = [];
1314  level.arrays_of_colorCoded_spawners[ team ][ colors[ p ] ] = [];
1315  }
1316 }
1317 
1319 {
1320  if( !IsDefined( self.color_node ) )
1321  {
1322  return;
1323  }
1324 
1325  if( IsDefined( self.color_node.color_user ) && self.color_node.color_user == self )
1326  {
1327  self.color_node.color_user = undefined;
1328  }
1329 
1330  self.color_node = undefined;
1331  self notify( "stop_color_move" );
1332 }
1333 
1334 
1336 {
1337  ‪array = [];
1338  if( issubstr( self.classname, "axis" ) || issubstr( self.classname, "enemy" ) )
1339  {
1340  ‪array[ "team" ] = "axis";
1341  ‪array[ "colorTeam" ] = self.script_color_axis;
1342  }
1343 
1344  if(( issubstr( self.classname, "ally" ) ) ||( issubstr( self.classname, "civilian" ) ) )
1345  {
1346  ‪array[ "team" ] = "allies";
1347  ‪array[ "colorTeam" ] = self.script_color_allies;
1348  }
1349 
1350  if( !IsDefined( ‪array[ "colorTeam" ] ) )
1351  {
1352  ‪array = undefined;
1353  }
1354 
1355  return ‪array;
1356 }
1357 
1359 {
1360  colorNumberArray = ‪GetColorNumberArray();
1361  if( !IsDefined( colorNumberArray ) )
1362  {
1363  return;
1364  }
1365 
1366  team = colorNumberArray[ "team" ];
1367  colorTeam = colorNumberArray[ "colorTeam" ];
1368 
1369  // remove this spawner from any array it was in
1370  colors = strtok( colorTeam, " " );
1371  for( i=0;i<colors.size;i++ )
1372  {
1373  ArrayRemoveValue( level.arrays_of_colorCoded_spawners[ team ][ colors[ i ] ], self );
1374  }
1375 }
1376 
1377 function ‪add_cover_node( type )
1378 {
1379  level.color_node_type_function[ type ][ true ][ "allies" ] =&‪process_cover_node_with_last_in_mind_allies;
1380  level.color_node_type_function[ type ][ true ][ "axis" ] =&‪process_cover_node_with_last_in_mind_axis;
1381  level.color_node_type_function[ type ][ false ][ "allies" ] =&‪process_cover_node;
1382  level.color_node_type_function[ type ][ false ][ "axis" ] =&‪process_cover_node;
1383 }
1384 
1385 function ‪add_path_node( type )
1386 {
1387  level.color_node_type_function[ type ][ true ][ "allies" ] =&‪process_path_node;
1388  level.color_node_type_function[ type ][ false ][ "allies" ] =&‪process_path_node;
1389  level.color_node_type_function[ type ][ true ][ "axis" ] =&‪process_path_node;
1390  level.color_node_type_function[ type ][ false ][ "axis" ] =&‪process_path_node;
1391 }
1392 
1393 
1394 // ColorNode respawn system
1395 function ‪colorNode_spawn_reinforcement( classname, fromColor )
1396 {
1397  level endon( "kill_color_replacements" );
1398 
1399  friendly_spawners_type = ‪getClassColorHash(classname, fromColor);
1400 
1401  while(level.friendly_spawners_types[friendly_spawners_type] > 0)
1402  {
1403  ‪spawn = undefined;
1404 
1405  for( ;; )
1406  {
1407  if( !level ‪flag::get( "respawn_friendlies" ) )
1408  {
1409  if( !IsDefined( level.friendly_respawn_vision_checker_thread ) )
1411 
1412  // have to break if respawn_friendlies gets enabled because that disables the
1413  // fov check that toggles player_looks_away_from_spawner.
1414  for ( ;; )
1415  {
1416  level ‪flag::wait_till_any( ‪array( "player_looks_away_from_spawner", "respawn_friendlies" ) );
1417  level ‪flag::wait_till_clear( "friendly_spawner_locked" );
1418  if ( level ‪flag::get( "player_looks_away_from_spawner" ) || level ‪flag::get( "respawn_friendlies" ) )
1419  {
1420  break;
1421  }
1422  }
1423  level ‪flag::set( "friendly_spawner_locked" );
1424  }
1425 
1426  spawner = ‪get_color_spawner( classname, fromColor );
1427  spawner.count = 1;
1428 
1429  level.friendly_spawners_types[friendly_spawners_type] = level.friendly_spawners_types[friendly_spawners_type] - 1;
1430 
1431  spawner ‪util::script_wait();
1432 
1433  ‪spawn = spawner ‪spawner::spawn();
1435  {
1436  thread ‪lock_spawner_for_awhile();
1437  wait( 1 );
1438  continue;
1439  }
1440 
1441  level notify( "reinforcement_spawned", ‪spawn );
1442  break;
1443  }
1444 
1445  // figure out which color the spawned guy should be
1446  for( ;; )
1447  {
1448  if( !IsDefined( fromColor ) )
1449  {
1450  break;
1451  }
1452 
1453  if( ‪get_color_from_order( fromColor, level.current_color_order ) == "none" )
1454  {
1455  break;
1456  }
1457  fromColor = level.current_color_order[ fromColor ];
1458  }
1459  if( IsDefined( fromColor ) )
1460  {
1461  ‪spawn ‪set_force_color( fromColor );
1462  }
1463 
1464  thread ‪lock_spawner_for_awhile();
1465 
1466  if( IsDefined( level.friendly_startup_thread ) )
1467  {
1468  ‪spawn thread [ [ level.friendly_startup_thread ] ]();
1469  }
1470 
1472  }
1473 }
1474 
1476 {
1477  level endon( "kill_color_replacements" );
1478 
1479  assert( isalive( self ), "Tried to do replace on death on something that was not alive" );
1480  self endon( "_disable_reinforcement" );
1481 
1482 
1483  if( self.team == "axis" )
1484  {
1485  return;
1486  }
1487 
1488  if ( IsDefined( self.‪replace_on_death ) )
1489  {
1490  return;
1491  }
1492 
1493  self.replace_on_death = true;
1494  assert( !IsDefined( self.respawn_on_death ), "Guy with export " + self.export + " tried to run respawn on death twice." );
1495 
1496  // when a red or green guy dies, an orange guy becomes a red guy
1497  // when an orange guy dies, a yellow guy becomes an orange guy
1498  classname = self.classname;
1499  color = self.script_forceColor;
1500 
1501  // if we spawn a new guy with spawn_reinforcement, he needs to get his color assignment before he checks his forcecolor
1502  waittillframeend;
1503 
1504  if( isalive( self ) )
1505  {
1506  // could've died in waittillframeend
1507  self waittill( "death" );
1508  }
1509 
1510  color_order = level.current_color_order;
1511 
1512  if( !IsDefined( self.script_forceColor ) )
1513  {
1514  return;
1515  }
1516 
1517  //Create only 1 respawn thread per class/color
1518  friendly_spawners_type = ‪getClassColorHash(classname, self.script_forceColor);
1519 
1520  if(!isdefined(level.friendly_spawners_types) || !isdefined(level.friendly_spawners_types[friendly_spawners_type])
1521  || level.friendly_spawners_types[friendly_spawners_type] <= 0)
1522  {
1523  level.friendly_spawners_types[friendly_spawners_type] = 1;
1524 
1525  // spawn a replacement yellow guy
1526  thread ‪colorNode_spawn_reinforcement( classname, self.script_forceColor );
1527  }
1528  else
1529  {
1530  level.friendly_spawners_types[friendly_spawners_type] = level.friendly_spawners_types[friendly_spawners_type] + 1;
1531  }
1532 
1533 
1534  if( IsDefined( self ) && IsDefined( self.script_forceColor ) )
1535  {
1536  color = self.script_forceColor;
1537  }
1538 
1539  if( IsDefined( self ) && IsDefined( self.origin ) )
1540  {
1541  origin = self.origin;
1542  }
1543 
1544 
1545  // a replacement has been spawned, so now promote somebody to our color
1546  for( ;; )
1547  {
1548  if( ‪get_color_from_order( color, color_order ) == "none" )
1549  {
1550  return;
1551  }
1552 
1553  correct_colored_friendlies = ‪get_force_color_guys( "allies", color_order[ color ] );
1554 
1555  //correct_colored_friendlies = remove_heroes( correct_colored_friendlies );//TODO T7 - bring over hero system if we need it
1556 
1557  correct_colored_friendlies = array::filter_classname( correct_colored_friendlies, true, classname );
1558 
1559 
1560  if( !correct_colored_friendlies.size )
1561  {
1562  // nobody of the correct color existed, so give them more time to spawn
1563  wait( 2 );
1564  continue;
1565  }
1566 
1567  players = GetPlayers();
1568  //correct_colored_guy = _utility::getClosest( players[0].origin, correct_colored_friendlies );
1569  correct_colored_guy = ArraySort( correct_colored_friendlies, players[0].origin, 1 )[0];
1570  assert( correct_colored_guy.script_forceColor != color, "Tried to replace a " + color + " guy with a guy of the same color!" );
1571 
1572  // have to wait until the end of the frame because the guy may have just spawned and been given his forcecolor,
1573  // and you cant give a guy forcecolor twice in one frame currently.
1574  waittillframeend;
1575  if( !isalive( correct_colored_guy ) )
1576  {
1577  // if he died during the frame then try again!
1578  continue;
1579  }
1580 
1581  correct_colored_guy ‪set_force_color( color );
1582 
1583  // should something special happen when a guy is promoted? Like a change in threatbias group?
1584  if( IsDefined( level.friendly_promotion_thread ) )
1585  {
1586  correct_colored_guy [ [ level.friendly_promotion_thread ] ]( color );
1587  }
1588 
1589  color = color_order[ color ];
1590  }
1591 }
1592 
1593 function ‪get_color_from_order( color, color_order )
1594 {
1595  if( !IsDefined( color ) )
1596  {
1597  return "none";
1598  }
1599 
1600  if( !IsDefined( color_order ) )
1601  {
1602  return "none";
1603  }
1604 
1605  if( !IsDefined( color_order[ color ] ) )
1606  {
1607  return "none";
1608  }
1609 
1610  return color_order[ color ];
1611 }
1612 
1614 {
1615  level.friendly_respawn_vision_checker_thread = true;
1616  // checks to see if the player is looking at the friendly spawner
1617 
1618  successes = 0;
1619  for( ;; )
1620  {
1621  level ‪flag::wait_till_clear( "respawn_friendlies" );
1622  wait( 1 );
1623  // friendly_respawn is disabled but if the player is far enough away and looking away
1624  // from the spawner then we can still spawn from it.
1625  if( !IsDefined( level.respawn_spawner ) )
1626  {
1627  continue;
1628  }
1629 
1630  spawner = level.respawn_spawner;
1631 
1632  players = GetPlayers();
1633 
1634  ‪player_sees_spawner = false;
1635  for( q = 0; q < players.size; q++ )
1636  {
1637  difference_vec = players[q].origin - spawner.origin;
1638  if( length( difference_vec ) < 200 )
1639  {
1641  ‪player_sees_spawner = true;
1642  break;
1643  }
1644 
1645  forward = anglesToForward(( 0, players[q] getplayerangles()[ 1 ], 0 ) );
1646  difference = vectornormalize( difference_vec );
1647  dot = vectordot( forward, difference );
1648  if( dot < 0.2 )
1649  {
1651  ‪player_sees_spawner = true;
1652  break;
1653  }
1654 
1655  successes++;
1656  if( successes < 3 )
1657  {
1658  continue;
1659  }
1660  }
1661 
1663  {
1664  continue;
1665  }
1666 
1667  // player has been looking away for 3 seconds
1668  level ‪flag::set( "player_looks_away_from_spawner" );
1669  }
1670 }
1671 
1672 function ‪get_color_spawner( classname, fromColor )
1673 {
1674  // make sure we don't assume that this array is defined!
1675  specificFromColor = false;
1676 
1677  if( IsDefined( level.respawn_spawners_specific ) && IsDefined( level.respawn_spawners_specific[fromColor] ) )
1678  {
1679  specificFromColor = true;
1680  }
1681 
1682  if( !IsDefined( level.respawn_spawner ) )
1683  {
1684  // make sure we're not using color-specific respawners instead
1685  if( !IsDefined( fromColor ) || !specificFromColor )
1686  {
1687  ASSERTMSG( "Tried to spawn a guy but neither level.respawn_spawner or level.respawn_spawners_specific is defined. Either set it to a spawner or use targetname trigger_friendly_respawn triggers. HINT: has the player hit a friendly_respawn_trigger for ALL allied color groups in the map by the time the player has reached this point?" );
1688  }
1689  }
1690 
1691  // if the classname is not set, just use the global respawn spawner
1692  if( !IsDefined( classname ) )
1693  {
1694  if( IsDefined( fromColor ) && specificFromColor )
1695  {
1696  return level.respawn_spawners_specific[fromColor];
1697  }
1698  else
1699  {
1700  return level.respawn_spawner;
1701  }
1702  }
1703 
1704  spawners = GetEntArray( "color_spawner", "targetname" );
1705  class_spawners = [];
1706  for( i=0; i < spawners.size; i++ )
1707  {
1708  class_spawners[ spawners[ i ].classname ] = spawners[ i ];
1709  }
1710 
1711  // find the spawner that has the supplied classname as a substr
1712  spawner = undefined;
1713  keys = getarraykeys( class_spawners );
1714  for( i=0; i < keys.size; i++ )
1715  {
1716  if( !issubstr( class_spawners[ keys[ i ] ].classname, classname ) )
1717  {
1718  continue;
1719  }
1720  spawner = class_spawners[ keys[ i ] ];
1721  break;
1722  }
1723 // spawner = class_spawners[ classname ];
1724 
1725  if( !IsDefined( spawner ) )
1726  {
1727  if( IsDefined( fromColor ) && specificFromColor )
1728  {
1729  return level.respawn_spawners_specific[fromColor];
1730  }
1731  else
1732  {
1733  return level.respawn_spawner;
1734  }
1735  }
1736 
1737  if( IsDefined( fromColor ) && specificFromColor )
1738  {
1739  spawner.origin = level.respawn_spawners_specific[fromColor].origin;
1740  }
1741  else
1742  {
1743  spawner.origin = level.respawn_spawner.origin;
1744  }
1745 
1746  return spawner;
1747 }
1748 
1749 function ‪getClassColorHash(classname, fromcolor )
1750 {
1751  //Create only 1 respawn thread per class/color
1752  classColorHash = classname;
1753 
1754  if(isdefined(fromcolor))
1755  {
1756  classColorHash += "##" + fromcolor;
1757  }
1758 
1759  return classColorHash;
1760 }
1761 
1763 {
1764  level ‪flag::set( "friendly_spawner_locked" );
1765  wait( 2 );
1766  level ‪flag::clear( "friendly_spawner_locked" );
1767 }
1768 
1770 {
1771  level ‪flag::clear( "player_looks_away_from_spawner" );
1772 }
1773 
1774 
1776 {
1777  // kills ALL color respawning
1778  level ‪flag::clear( "friendly_spawner_locked" );
1779  level notify( "kill_color_replacements" );
1780  level.friendly_spawners_types = undefined;
1781 
1782  ai = GetAIArray();
1783  array::thread_all( ai,&‪remove_replace_on_death );
1784 }
1785 
1787 {
1788  self.replace_on_death = undefined;
1789 }
1790 
1800 function ‪set_force_color( _color )
1801 {
1802  // shorten and lowercase the ai's forcecolor to a single letter
1803  color = ‪shortenColor( _color );
1804 
1805  assert( ‪colorIsLegit( color ), "Tried to set force color on an undefined color: " + color );
1806 
1807  if( !IsActor( self ) )
1808  {
1809  ‪set_force_color_spawner( color );
1810  return;
1811  }
1812 
1813  assert( isalive( self ), "Tried to set force color on a dead / undefined entity." );
1814 
1815  self.fixedNodeSafeRadius = ‪COLOR_FIXED_NODE_RADIUS;
1816 
1817  self.script_color_axis = undefined;
1818  self.script_color_allies = undefined;
1819  self.old_forcecolor = undefined;
1820 
1821  if( IsDefined( self.script_forcecolor ) )
1822  {
1823  // first remove the guy from the force color array he used to belong to
1824  ArrayRemoveValue( level.arrays_of_colorForced_ai[ self.team ][ self.script_forcecolor ], self );
1825  }
1826 
1827  self.script_forceColor = color;
1828 
1829  // get added to the new array of AI that are forced to this color
1830  ‪ARRAY_ADD( level.arrays_of_colorForced_ai[ self.team ][ self.script_forceColor ], self );
1831  level thread ‪remove_colorForced_ai_when_dead( self );
1832 
1833 
1834  // set it here so that he continues in script as the correct color
1835  self thread ‪new_color_being_set( color );
1836 }
1837 
1839 {
1840  script_forceColor = ai.script_forceColor;
1841  team = ai.team;
1842 
1843  ai waittill( "death" );
1844 
1845  level.arrays_of_colorForced_ai[ team ][ script_forceColor ] = ‪array::remove_undefined( level.arrays_of_colorForced_ai[ team ][ script_forceColor ] );
1846 }
1847 
1848 function ‪shortenColor( color )
1849 {
1850  Assert( IsDefined( level.colorCheckList[ ToLower( color ) ] ), "Tried to set force color on an undefined color: " + color );
1851  return level.colorCheckList[ ToLower( color ) ];
1852 }
1853 
1855 {
1856  self.script_forceColor = color;
1857  self.old_forceColor = undefined;
1858 }
1859 
1860 function ‪new_color_being_set( color )
1861 {
1862  self notify( "new_color_being_set" );
1863  self.new_force_color_being_set = true;
1865 
1866  self endon( "new_color_being_set" );
1867  self endon( "death" );
1868 
1869  // insure we're only getting one color change, multiple in one frame will get overwritten.
1870  waittillframeend;
1871  waittillframeend;
1872 
1873  if ( IsDefined( self.script_forceColor ) )
1874  {
1875  // grab the current colorCode that AI of this color are forced to, if there is one
1876  self.currentColorCode = level.currentColorForced[ self.team ][ self.script_forceColor ];
1877  self thread ‪goto_current_ColorIndex();
1878  }
1879 
1880  self.new_force_color_being_set = undefined;
1881  self notify( "done_setting_new_color" );
1882 }
1883 
1885 {
1886  self notify( "debug_color_update" );
1887  self endon( "debug_color_update" );
1888  self waittill( "death" );
1889 
1890  // updates the debug color friendlies info
1891  level notify( "updated_color_friendlies" );
1892 }
1893 
1894 
1896 {
1898 
1899  if ( isdefined( self.script_forceColor ) )
1900  {
1901  level.debug_color_friendlies[ self GetEntityNumber() ] = self.script_forceColor;
1902  }
1903  else
1904  {
1905  level.debug_color_friendlies[ self GetEntityNumber() ] = undefined;
1906  }
1907 
1908  // updates the debug color friendlies info
1909  level notify( "updated_color_friendlies" );
1910 }
1911 
1912 function ‪has_color()
1913 {
1914  // can lose color during the waittillframeend in left_color_node
1915  if ( self.team == "axis" )
1916  {
1917  return IsDefined( self.script_color_axis ) || IsDefined( self.script_forceColor );
1918  }
1919 
1920  return IsDefined( self.script_color_allies ) || IsDefined( self.script_forceColor );
1921 }
1922 
1933 {
1934  color = self.script_forceColor;
1935  return color;
1936 }
1937 
1949 function ‪get_force_color_guys( team, color )
1950 {
1951  ai = GetAITeamArray( team );
1952  guys = [];
1953  for( i = 0; i < ai.size; i++ )
1954  {
1955  guy = ai[ i ];
1956  if( !IsDefined( guy.script_forceColor ) )
1957  {
1958  continue;
1959  }
1960 
1961  if( guy.script_forceColor != color )
1962  {
1963  continue;
1964  }
1965  guys[ guys.size ] = guy;
1966  }
1967 
1968  return guys;
1969 }
1970 
1972 {
1973  ai = GetAITeamArray( "allies" );
1974  guys = [];
1975  for( i = 0; i < ai.size; i++ )
1976  {
1977  guy = ai[ i ];
1978  if( !IsDefined( guy.script_forceColor ) )
1979  {
1980  continue;
1981  }
1982  guys[ guys.size ] = guy;
1983  }
1984 
1985  return guys;
1986 }
1987 
1997 function ‪disable( stop_being_careful )
1998 {
1999  if( IsDefined( self.new_force_color_being_set ) )
2000  {
2001  self endon( "death" );
2002  // setting force color happens after waittillframeend so we need to wait until it finishes
2003  // setting before we disable it, so a set followed by a disable will send the guy to a node.
2004  self waittill( "done_setting_new_color" );
2005  }
2006 
2007  // SUMEET_TODO - AI should stop going to node/running careful right when color is disabled.
2008  // Added this late on Black Ops2 ( 08/10/2012 ) hence not making it global. Might introduce issues
2009  // on other maps.
2010  if( ‪IS_TRUE( stop_being_careful ) )
2011  {
2012  self notify( "stop_going_to_node" );
2013  self notify( "stop_being_careful" );
2014  }
2015 
2016  self clearFixedNodeSafeVolume();
2017  // any color on this guy?
2018  if( !IsDefined( self.script_forceColor ) )
2019  {
2020  return;
2021  }
2022 
2023  assert( !IsDefined( self.old_forcecolor ), "Tried to disable forcecolor on a guy that somehow had a old_forcecolor already. Investigate!!!" );
2024 
2025  self.old_forceColor = self.script_forceColor;
2026 
2027 
2028  // first remove the guy from the force color array he used to belong to
2029  ArrayRemoveValue( level.arrays_of_colorForced_ai[ self.team ][ self.script_forcecolor ], self );
2030  // self _colors::removeAIFromColorNumberArray();
2031 
2033  self.script_forceColor = undefined;
2034  self.currentColorCode = undefined;
2035 }
2036 
2046 function ‪enable()
2047 {
2048  if ( IsDefined( self.script_forceColor ) )
2049  {
2050  return;
2051  }
2052 
2053  if ( !IsDefined( self.old_forceColor ) )
2054  {
2055  return;
2056  }
2057 
2058  ‪set_force_color( self.old_forcecolor );
2059  self.old_forceColor = undefined;
2060 }
2061 
2062 function ‪is_color_ai()
2063 {
2064  return ( isdefined( self.script_forcecolor ) || isdefined( self.old_forcecolor ) );
2065 }
2066 
2067 
‪replace_on_death
‪function replace_on_death()
Definition: spawner_shared.gsc:2963
‪issue_color_order_to_ai
‪function issue_color_order_to_ai(colorCode, color, team, ai)
Definition: colors_shared.gsc:766
‪script_delay
‪function script_delay()
Definition: util_shared.gsc:970
‪add_node_to_global_arrays
‪function add_node_to_global_arrays(colorCode, team)
Definition: colors_shared.gsc:1297
‪player_sees_spawner
‪function player_sees_spawner()
Definition: colors_shared.gsc:1769
‪shortenColor
‪function shortenColor(color)
Definition: colors_shared.gsc:1848
‪take_color_node
‪function take_color_node(node, colorCode, trigger, counter)
Definition: colors_shared.gsc:805
‪hero_catch_up_teleport
‪function hero_catch_up_teleport(s_teleport, n_min_dist_from_player=400.0, b_disable_colors=false, func_callback)
Definition: colors_shared.gsc:417
‪reached_node_but_could_not_claim_it
‪function reached_node_but_could_not_claim_it(node)
Definition: colors_shared.gsc:1237
‪force_goal
‪function force_goal(goto, n_radius, b_shoot=true, str_end_on, b_keep_colors=false, b_should_sprint=false)
Definition: ai_shared.gsc:570
‪is_color_ai
‪function is_color_ai()
Definition: colors_shared.gsc:2062
‪GetColorNumberArray
‪function GetColorNumberArray()
Definition: colors_shared.gsc:1335
‪__main__
‪function __main__()
Definition: colors_shared.gsc:150
‪same_color_code_as_last_time
‪function same_color_code_as_last_time(team, color)
Definition: colors_shared.gsc:643
‪occupies_colorCode
‪function occupies_colorCode(colorCode)
Definition: colors_shared.gsc:911
‪remove_replace_on_death
‪function remove_replace_on_death()
Definition: colors_shared.gsc:1786
‪player_color_node
‪function player_color_node()
Definition: colors_shared.gsc:813
‪timer
‪function timer(n_time, str_endon, x, y, height)
Definition: lui_shared.gsc:163
‪colorNode_replace_on_death
‪function colorNode_replace_on_death()
Definition: colors_shared.gsc:1475
‪wait_for_killanimscript_or_time
‪function wait_for_killanimscript_or_time(timer)
Definition: colors_shared.gsc:1230
‪careful_logic
‪function careful_logic(node, volume)
Definition: colors_shared.gsc:997
‪kill_color_replacements
‪function kill_color_replacements()
Definition: colors_shared.gsc:1775
‪clear
‪function clear(str_flag)
Definition: flag_shared.csc:130
‪color_node_finds_a_user
‪function color_node_finds_a_user()
Definition: colors_shared.gsc:849
‪wait_till_any
‪function wait_till_any(a_flags)
Definition: flag_shared.csc:227
‪process_stop_short_of_node
‪function process_stop_short_of_node(node)
Definition: colors_shared.gsc:1199
‪waittill_either
‪function waittill_either(msg1, msg2)
Definition: util_shared.gsc:303
‪get_prioritized_colorCoded_nodes
‪function get_prioritized_colorCoded_nodes(team, colorCode, color)
Definition: colors_shared.gsc:726
‪get_array
‪function get_array(kvp_value, kvp_key="targetname")
Definition: struct.csc:34
‪__init__
‪function __init__()
Definition: colors_shared.gsc:35
‪process_cover_node_with_last_in_mind_axis
‪function process_cover_node_with_last_in_mind_axis(node, lastColor)
Definition: colors_shared.gsc:667
‪get_colorcodes_from_trigger
‪function get_colorcodes_from_trigger(color_team, team)
Definition: colors_shared.gsc:238
‪recover_from_careful_disable
‪function recover_from_careful_disable(node)
Definition: colors_shared.gsc:1013
‪spawn
‪function spawn(v_origin=(0, 0, 0), v_angles=(0, 0, 0))
Definition: struct.csc:23
‪IS_TRUE
‪#define IS_TRUE(__a)
Definition: shared.gsh:251
‪decrementColorUsers
‪function decrementColorUsers(node)
Definition: colors_shared.gsc:1263
‪get
‪function get(kvp_value, kvp_key="targetname")
Definition: struct.csc:13
‪trigger_auto_disable
‪function trigger_auto_disable()
Definition: colors_shared.gsc:332
‪delay
‪function delay(time_or_notify, str_endon, func, arg1, arg2, arg3, arg4, arg5, arg6)
Definition: util_shared.csc:784
‪player_init_color_grouping
‪function player_init_color_grouping()
Definition: colors_shared.gsc:170
‪get_color_list
‪function get_color_list()
Definition: colors_shared.gsc:223
‪set_goal_and_volume
‪function set_goal_and_volume(node)
Definition: colors_shared.gsc:947
‪get_best_available_colored_node
‪function get_best_available_colored_node()
Definition: colors_shared.gsc:1161
‪friendly_spawner_vision_checker
‪function friendly_spawner_vision_checker()
Definition: colors_shared.gsc:1613
‪trigger_issues_orders
‪function trigger_issues_orders(color_team, team)
Definition: colors_shared.gsc:286
‪issue_leave_node_order_to_ai_and_get_ai
‪function issue_leave_node_order_to_ai_and_get_ai(colorCode, color, team)
Definition: colors_shared.gsc:735
‪disable
‪function disable(stop_being_careful)
Definition: colors_shared.gsc:1997
‪add_cover_node
‪function add_cover_node(type)
Definition: colors_shared.gsc:1377
‪color_node_finds_user_for_colorCode
‪function color_node_finds_user_for_colorCode(colorCode, team)
Definition: colors_shared.gsc:874
‪DEFAULT
‪#define DEFAULT(__var, __default)
Definition: shared.gsh:270
‪process_cover_node_with_last_in_mind_allies
‪function process_cover_node_with_last_in_mind_allies(node, lastColor)
Definition: colors_shared.gsc:654
‪process_color_order_to_ai
‪function process_color_order_to_ai(node, trigger, counter)
Definition: colors_shared.gsc:1102
‪colorIsLegit
‪function colorIsLegit(color)
Definition: colors_shared.gsc:1273
‪is_target_visible
‪function private is_target_visible(target)
Definition: colors_shared.gsc:374
‪prioritize_colorCoded_nodes
‪function prioritize_colorCoded_nodes(team, colorCode, color)
Definition: colors_shared.gsc:690
‪set_force_color_spawner
‪function set_force_color_spawner(color)
Definition: colors_shared.gsc:1854
‪convert_color_to_short_string
‪function convert_color_to_short_string()
Definition: colors_shared.gsc:175
‪get_color_spawner
‪function get_color_spawner(classname, fromColor)
Definition: colors_shared.gsc:1672
‪update_debug_friendlycolor
‪function update_debug_friendlycolor()
Definition: colors_shared.gsc:1895
‪REGISTER_SYSTEM_EX
‪#define REGISTER_SYSTEM_EX(__sys, __func_init_preload, __func_init_postload, __reqs)
Definition: shared.gsh:209
‪spawn_failed
‪function spawn_failed(spawn)
Definition: spawner_shared.gsc:2902
‪use_big_goal_until_goal_is_safe
‪function use_big_goal_until_goal_is_safe(node, volume)
Definition: colors_shared.gsc:1022
‪enable
‪function enable()
Definition: colors_shared.gsc:2046
‪activate_color_trigger
‪function activate_color_trigger(team)
Definition: colors_shared.gsc:352
‪ARRAY_ADD
‪#define ARRAY_ADD(__array, __item)
Definition: shared.gsh:304
‪get_colorcodes_and_activate_trigger
‪function get_colorcodes_and_activate_trigger(color_team, team)
Definition: colors_shared.gsc:364
‪remove_undefined
‪function remove_undefined(array, b_keep_keys)
Definition: array_shared.csc:56
‪color_force_goal
‪function color_force_goal(node)
Definition: colors_shared.gsc:989
‪left_color_node
‪function left_color_node()
Definition: colors_shared.gsc:1318
‪set_force_color
‪function set_force_color(_color)
Definition: colors_shared.gsc:1800
‪script_wait
‪function script_wait(called_from_spawner=false)
Definition: util_shared.gsc:1930
‪wait_till
‪function wait_till(str_flag)
Definition: flag_shared.csc:189
‪getClassColorHash
‪function getClassColorHash(classname, fromcolor)
Definition: colors_shared.gsc:1749
‪colorNode_spawn_reinforcement
‪function colorNode_spawn_reinforcement(classname, fromColor)
Definition: colors_shared.gsc:1395
‪array
‪function filter array
Definition: array_shared.csc:16
‪color_node_finds_user_from_colorcodes
‪function color_node_finds_user_from_colorcodes(colorCodeString, team)
Definition: colors_shared.gsc:862
‪goto_current_ColorIndex
‪function goto_current_ColorIndex()
Definition: colors_shared.gsc:181
‪removeSpawnerFromColorNumberArray
‪function removeSpawnerFromColorNumberArray()
Definition: colors_shared.gsc:1358
‪new_color_being_set
‪function new_color_being_set(color)
Definition: colors_shared.gsc:1860
‪activate_color_trigger_internal
‪function activate_color_trigger_internal(colorCodes, colors, team, colorCodesByColorIndex)
Definition: colors_shared.gsc:545
‪MAKE_ARRAY
‪#define MAKE_ARRAY(__array)
Definition: shared.gsh:303
‪get_all
‪function get_all(type1, type2, type3, type4, type5, type6, type7, type8, type9)
Definition: trigger_shared.gsc:802
‪add_volume_to_global_arrays
‪function add_volume_to_global_arrays(colorCode, team)
Definition: colors_shared.gsc:1285
‪init
‪function init()
Definition: struct.csc:1
‪remove_colorForced_ai_when_dead
‪function remove_colorForced_ai_when_dead(ai)
Definition: colors_shared.gsc:1838
‪my_current_node_delays
‪function my_current_node_delays()
Definition: colors_shared.gsc:1092
‪process_path_node
‪function process_path_node(node, null)
Definition: colors_shared.gsc:685
‪set
‪function set(str_field_name, n_value)
Definition: clientfield_shared.gsc:34
‪IS_EQUAL
‪#define IS_EQUAL(__a, __b)
Definition: shared.gsh:250
‪add_path_node
‪function add_path_node(type)
Definition: colors_shared.gsc:1385
‪COLOR_NODE_BIG_RADIUS
‪#define COLOR_NODE_BIG_RADIUS
Definition: colors_shared.gsc:13
‪wait_until_an_enemy_is_in_safe_area
‪function wait_until_an_enemy_is_in_safe_area(node, volume)
Definition: colors_shared.gsc:1059
‪get_best_available_new_colored_node
‪function get_best_available_new_colored_node()
Definition: colors_shared.gsc:1179
‪lock_spawner_for_awhile
‪function lock_spawner_for_awhile()
Definition: colors_shared.gsc:1762
‪has_color
‪function has_color()
Definition: colors_shared.gsc:1912
‪COLOR_FIXED_NODE_RADIUS
‪#define COLOR_FIXED_NODE_RADIUS
Definition: colors_shared.gsc:14
‪update_debug_friendlycolor_on_death
‪function update_debug_friendlycolor_on_death()
Definition: colors_shared.gsc:1884
‪process_cover_node
‪function process_cover_node(node, null)
Definition: colors_shared.gsc:680
‪wait_till_clear
‪function wait_till_clear(str_flag)
Definition: flag_shared.csc:248
‪ai_sets_goal
‪function ai_sets_goal(node)
Definition: colors_shared.gsc:932
‪get_color_from_order
‪function get_color_from_order(color, color_order)
Definition: colors_shared.gsc:1593
‪get_force_color_guys
‪function get_force_color_guys(team, color)
Definition: colors_shared.gsc:1949
‪ai_sets_goal_with_delay
‪function ai_sets_goal_with_delay(node)
Definition: colors_shared.gsc:921
‪get_force_color
‪function get_force_color()
Definition: colors_shared.gsc:1932
‪WAIT_SERVER_FRAME
‪#define WAIT_SERVER_FRAME
Definition: shared.gsh:265
‪get_all_force_color_friendlies
‪function get_all_force_color_friendlies()
Definition: colors_shared.gsc:1971