‪Black Ops 3 Source Code Explorer  0.1
‪An script explorer for Black Ops 3 by ZeRoY
ai_squads.gsc
Go to the documentation of this file.
1 #using scripts\shared\ai_shared;
2 #using scripts\shared\array_shared;
3 #using scripts\shared\flag_shared;
4 #using scripts\shared\system_shared;
5 #using scripts\shared\trigger_shared;
6 #using scripts\shared\spawner_shared;
7 #using scripts\shared\util_shared;
8 
9 #insert scripts\shared\archetype_shared\archetype_shared.gsh;
10 #insert scripts\shared\shared.gsh;
11 
12 #define NULL 0
13 #define IS_NULL(variable) (IsInt(variable) && variable == 0)
14 
15 #define SQUAD_RADIUS_MIN 200
16 #define SQUAD_RADIUS_MAX 300
17 
18 #define SQUAD_BREADCRUMB_DISTSQ 96 * 96
19 #define SQUAD_SPRINT_OFFSET_DISTSQ 150 * 150
20 
21 #namespace AiSquads;
22 
23 ‪REGISTER_SYSTEM( "ai_squads", &‪__init__, undefined )
24 
25 function ‪__init__()
26 {
27  level._squads = [];
28 
29  actorSpawnerArray = GetActorSpawnerTeamArray( "axis" );
30  array::run_all( actorSpawnerArray, &‪spawner::add_spawn_function, &‪SquadMemberThink );
31 }
32 
33 // ------- AI SQUAD -----------//
34 class ‪Squad
35 {
39 
41  {
43  ‪squadMembers = [];
44  ‪squadBreadCrumb = [];
45  }
46 
47  function ‪addSquadBreadCrumbs( ai )
48  {
49  assert( ‪squadLeader == ai );
50 
51  if( Distance2DSquared( ‪squadBreadCrumb, ai.origin ) >= ‪SQUAD_BREADCRUMB_DISTSQ )
52  {
53  /# RecordCircle( ai.origin, 4, ‪BLUE, "Animscript", ai ); #/
54  ‪squadBreadCrumb = ai.origin;
55  }
56  }
57 
59  {
60  return ‪squadBreadCrumb;
61  }
62 
63  function ‪GetLeader()
64  {
65  return ‪squadLeader;
66  }
67 
68  function ‪GetMembers()
69  {
70  return ‪squadMembers;
71  }
72 
73  function ‪AddAIToSquad( ai )
74  {
75  if( !IsInArray( ‪squadMembers, ai ) )
76  {
77  // TEMP : Turn off other behaviors of the robot, to make sure that he will respect and follow the squad
78  if( ai.archetype == ‪ARCHETYPE_ROBOT )
79  {
80  ai ‪ai::set_behavior_attribute( "move_mode", "squadmember" );
81  }
82 
84  }
85  }
86 
87  function ‪RemoveAIFromSqaud( ai )
88  {
89  if( IsInArray( ‪squadMembers, ai ) )
90  {
91  ArrayRemoveValue( ‪squadMembers, ai, false );
92 
93  if( ‪squadLeader === ai )
94  {
95  ‪squadLeader = undefined;
96  }
97  }
98  }
99 
100  function ‪Think()
101  {
102  // update squad leader - pick the first one in the squadMembers list
103  // remove the squad if no one is left
104  if( ‪IS_NULL( ‪squadLeader ) || !IsDefined( ‪squadLeader ) )
105  {
106  if( ‪squadMembers.size > 0 )
107  {
110  }
111  else
112  {
113  return false;
114  }
115  }
116 
117  return true;
118  }
119 }
120 
121 function private ‪CreateSquad( squadName )
122 {
123  level._squads[squadName] = new ‪Squad();
124  return level._squads[squadName];
125 }
126 
127 function private ‪RemoveSquad( squadName )
128 {
129  if( IsDefined( level._squads ) && IsDefined( level._squads[squadName] ) )
130  {
131  level._squads[squadName] = undefined;
132  }
133 }
134 
135 function private ‪GetSquad( squadName )
136 {
137  return level._squads[squadName];
138 }
139 
140 function private ‪ThinkSquad( squadName )
141 {
142  while(1)
143  {
144  if( [[ level._squads[squadName] ]]->Think() )
145  {
146  wait 0.5;
147  }
148  else
149  {
150  ‪RemoveSquad( squadName );
151  break;
152  }
153  }
154 }
155 
156 function private ‪SquadMemberDeath()
157 {
158  self waittill( "death" );
159 
160  if( IsDefined( self.squadName ) && IsDefined( level._squads[self.squadName] ) )
161  {
162  [[ level._squads[self.squadName] ]]->RemoveAIFromSqaud( self );
163  }
164 }
165 
166 function private ‪SquadMemberThink()
167 {
168  self endon("death");
169 
170  if( !IsDefined( self.script_aisquadname ) )
171  return;
172 
173  // wait for other ai systems to initialize
174  wait 0.5;
175 
176  // Assign the squad name
177  self.squadName = self.script_aisquadname;
178 
179  if( IsDefined( self.squadName ) )
180  {
181  // Create squad if it does not exist, then create it
182  if( !IsDefined( level._squads[self.squadName] ) )
183  {
184  squad = ‪CreateSquad( self.squadName );
185  newSquadCreated = true;
186  }
187  else
188  {
189  squad = ‪GetSquad( self.squadName );
190  }
191 
192  // Add this AI as a member of the squad
193  [[squad]]->AddAIToSquad( self );
194 
195  // Handle the death of the sqaudMember and remove him from squad
196  self thread ‪SquadMemberDeath();
197 
198  // start ticking this squad
199  if( ‪IS_TRUE( newSquadCreated ) )
200  {
201  level thread ‪ThinkSquad( self.squadName );
202  }
203 
204  // Keep updating and following the leader of the squad
205  while(1)
206  {
207  ‪squadLeader = [[ level._squads[self.squadName] ]]->GetLeader();
208 
209  if( IsDefined( ‪squadLeader ) && !‪IS_NULL( ‪squadLeader ) )
210  {
211  if( ‪squadLeader == self )
212  {
213  /# RecordEntText( self.squadName + ": LEADER", self, ‪GREEN, "Animscript" ); #/
214  /# RecordEntText( self.squadName + ": LEADER", self, ‪GREEN, "Animscript" ); #/
215  /# RecordCircle( self.origin, ‪SQUAD_RADIUS_MAX, ‪ORANGE, "Animscript", self ); #/
216 
217  if( IsDefined( self.enemy ) )
218  {
219  self SetGoal( self.enemy );
220  }
221 
222  [[squad]]->addSquadBreadCrumbs( self );
223  }
224  else
225  {
226  /# RecordLine( self.origin, ‪squadLeader.origin, ‪GREEN, "Animscript", self ); #/
227  /# RecordEntText( self.squadName+ ": FOLLOWER", self, ‪GREEN, "Animscript" ); #/
228 
229  followPosition = [[squad]]->getSquadBreadCrumb();
230  followDistSq = Distance2DSquared( self.goalPos, followPosition );
231 
232  if( IsDefined( ‪squadLeader.enemy ) )
233  {
234  if( !IsDefined( self.enemy ) || ( IsDefined( self.enemy ) && self.enemy != ‪squadLeader.enemy ) )
235  self SetEntityTarget( ‪squadLeader.enemy, 1 );
236  }
237 
238  if( IsDefined( self.goalPos ) && followDistSq >= 16 * 16 )
239  {
240  if( followDistSq >= ‪SQUAD_SPRINT_OFFSET_DISTSQ )
241  {
242  self ‪ai::set_behavior_attribute( "sprint", true );
243  }
244  else
245  {
246  self ‪ai::set_behavior_attribute( "sprint", false );
247  }
248 
249  self SetGoal( followPosition, true );
250  }
251  }
252  }
253 
254  wait 1;
255  }
256  }
257 }
258 
259 // ------- UTILITY -----------//
261 {
262  if( ai ‪ai::get_behavior_attribute( "move_mode" ) != "squadmember" )
263  {
264  return false;
265  }
266 
267  squadMember = ‪isSquadMember( ai );
268  currentSquadLeader = ‪getSquadLeader( ai ) ;
269  isAISquadLeader = IsDefined( currentSquadLeader ) && currentSquadLeader == ai;
270 
271  if( squadMember && !isAISquadLeader )
272  {
273  return true;
274  }
275 
276  return false;
277 }
278 
279 function ‪isSquadMember( ai )
280 {
281  if( IsDefined( ai.squadName ) )
282  {
283  squad = ‪GetSquad( ai.squadName );
284 
285  if( IsDefined( squad ) )
286  {
287  return IsInArray( [[squad]]->‪GetMembers(), ai );
288  }
289  }
290 
291  return false;
292 }
293 
294 function ‪isSquadLeader( ai )
295 {
296  if( IsDefined( ai.squadName ) )
297  {
298  squad = ‪GetSquad( ai.squadName );
299 
300  if( IsDefined( squad ) )
301  {
302  ‪squadLeader = [[squad]]->GetLeader();
303 
304  return IsDefined( ‪squadLeader ) && ‪squadLeader == ai;
305  }
306  }
307 
308  return false;
309 }
310 
311 function ‪getSquadLeader( ai )
312 {
313  if( IsDefined( ai.squadName ) )
314  {
315  squad = ‪GetSquad( ai.squadName );
316 
317  if( IsDefined( squad ) )
318  {
319  return [[squad]]->GetLeader();
320  }
321  }
322 
323  return undefined;
324 }
‪CreateSquad
‪class Squad CreateSquad(squadName)
Definition: ai_squads.gsc:121
‪ThinkSquad
‪function private ThinkSquad(squadName)
Definition: ai_squads.gsc:140
‪Squad::constructor
‪constructor()
Definition: ai_squads.gsc:40
‪squadLeader
‪var squadLeader
Definition: ai_squads.gsc:26
‪Squad::AddAIToSquad
‪function AddAIToSquad(ai)
Definition: ai_squads.gsc:73
‪GetSquad
‪function private GetSquad(squadName)
Definition: ai_squads.gsc:135
‪Squad::addSquadBreadCrumbs
‪function addSquadBreadCrumbs(ai)
Definition: ai_squads.gsc:47
‪isSquadMember
‪function isSquadMember(ai)
Definition: ai_squads.gsc:279
‪IS_TRUE
‪#define IS_TRUE(__a)
Definition: shared.gsh:251
‪GREEN
‪#define GREEN
Definition: shared.gsh:176
‪SquadMemberDeath
‪function private SquadMemberDeath()
Definition: ai_squads.gsc:156
‪getSquadLeader
‪function getSquadLeader(ai)
Definition: ai_squads.gsc:311
‪SquadMemberThink
‪function private SquadMemberThink()
Definition: ai_squads.gsc:166
‪SQUAD_RADIUS_MAX
‪#define SQUAD_RADIUS_MAX
Definition: ai_squads.gsc:16
‪GetMembers
‪function GetMembers()
Definition: ai_squads.gsc:58
‪isSquadLeader
‪function isSquadLeader(ai)
Definition: ai_squads.gsc:294
‪Squad::getSquadBreadCrumb
‪function getSquadBreadCrumb()
Definition: ai_squads.gsc:58
‪SQUAD_BREADCRUMB_DISTSQ
‪#define SQUAD_BREADCRUMB_DISTSQ
Definition: ai_squads.gsc:18
‪SQUAD_SPRINT_OFFSET_DISTSQ
‪#define SQUAD_SPRINT_OFFSET_DISTSQ
Definition: ai_squads.gsc:19
‪Squad::GetMembers
‪function GetMembers()
Definition: ai_squads.gsc:68
‪Squad::squadBreadCrumb
‪var squadBreadCrumb
Definition: ai_squads.gsc:38
‪Squad::squadLeader
‪var squadLeader
Definition: ai_squads.gsc:36
‪REGISTER_SYSTEM
‪#define REGISTER_SYSTEM(__sys, __func_init_preload, __reqs)
Definition: shared.gsh:204
‪BLUE
‪#define BLUE
Definition: shared.gsh:177
‪Squad::squadMembers
‪var squadMembers
Definition: ai_squads.gsc:37
‪Squad::Think
‪function Think()
Definition: ai_squads.gsc:100
‪NULL
‪#define NULL
Definition: ai_squads.gsc:12
‪__init__
‪function __init__()
Definition: ai_squads.gsc:25
‪Squad::GetLeader
‪function GetLeader()
Definition: ai_squads.gsc:63
‪set_behavior_attribute
‪function set_behavior_attribute(attribute, value)
Definition: ai_shared.gsc:159
‪IS_NULL
‪#define IS_NULL(variable)
Definition: ai_squads.gsc:13
‪RemoveSquad
‪function private RemoveSquad(squadName)
Definition: ai_squads.gsc:127
‪Squad::RemoveAIFromSqaud
‪function RemoveAIFromSqaud(ai)
Definition: ai_squads.gsc:87
‪isFollowingSquadLeader
‪function isFollowingSquadLeader(ai)
Definition: ai_squads.gsc:260
‪ORANGE
‪#define ORANGE
Definition: shared.gsh:179
‪add_spawn_function
‪function add_spawn_function(spawn_func, param1, param2, param3, param4, param5)
Definition: spawner_shared.gsc:3252
‪get_behavior_attribute
‪function get_behavior_attribute(attribute)
Definition: ai_shared.gsc:184
‪ARCHETYPE_ROBOT
‪#define ARCHETYPE_ROBOT
Definition: archetype_shared.gsh:8
‪Squad
Definition: ai_squads.gsc:34