‪Black Ops 3 Source Code Explorer  0.1
‪An script explorer for Black Ops 3 by ZeRoY
shared.gsc
Go to the documentation of this file.
1 #using scripts\shared\ai_shared;
2 #using scripts\shared\math_shared;
3 #using scripts\shared\sound_shared;
4 #using scripts\shared\throttle_shared;
5 #using scripts\shared\util_shared;
6 
7 #using scripts\shared\ai\systems\debug;
8 #using scripts\shared\ai\systems\init;
9 #using scripts\shared\ai\archetype_utility;
10 #using scripts\shared\ai\systems\weaponList;
11 
12 #insert scripts\shared\shared.gsh;
13 #insert scripts\shared\ai\utility.gsh;
14 
15 #using_animtree("generic");
16 
17 function autoexec ‪main()
18 {
19  level.ai_weapon_throttle = new ‪Throttle();
20  [[ level.ai_weapon_throttle ]]->Initialize( 1, 0.1 );
21 }
22 
23 function private ‪_throwStowedWeapon( entity, weapon, weaponModel )
24 {
25  entity waittill( "death" );
26 
27  if(IsDefined(entity))
28  {
29  weaponModel Unlink();
30  entity ‪shared::ThrowWeapon( weapon, ‪getTagForPos( "back" ), false );
31  }
32 
33  weaponModel Delete();
34 }
35 
36 function ‪StowWeapon( weapon, positionOffset, orientationOffset )
37 {
38  entity = self;
39 
40  if ( !IsDefined( positionOffset ) )
41  {
42  positionOffset = (0, 0, 0);
43  }
44 
45  if ( !IsDefined( orientationOffset ) )
46  {
47  orientationOffset = (0, 0, 0);
48  }
49 
50  weaponModel = ‪Spawn( "script_model", (0, 0, 0) );
51  weaponModel SetModel( weapon.worldmodel );
52 
53  weaponModel LinkTo( entity, "tag_stowed_back", positionOffset, orientationOffset );
54 
55  entity thread ‪_throwStowedWeapon( entity, weapon, weaponModel );
56 }
57 
58 function ‪placeWeaponOn( weapon, position )
59 {
60  self notify("weapon_position_change");
61 
62  if ( IsString( weapon ) )
63  {
64  weapon = GetWeapon( weapon );
65  }
66 
67  if (!isdefined(self.weaponInfo[weapon.name]))
68  self ‪init::initWeapon( weapon );
69 
70  curPosition = self.weaponInfo[weapon.name].position;
71 
72  // make sure we're not out of sync
73  assert( curPosition == "none" || self.‪a.weaponPos[curPosition] == weapon );
74 
75  if ( !IsArray( self.‪a.weaponPos ) )
76  {
77  self.a.weaponPos = [];
78  }
79 
80  assert( IsArray( self.‪a.weaponPos ) );
81  assert( position == "none" || IsDefined( self.‪a.weaponPos[position] ), "Weapon position \"" + position + "\"" );
82  assert( IsWeapon( weapon ) );
83 
84  // weapon already in place
85  if ( position != "none" && self.‪a.weaponPos[position] == weapon )
86  return;
87 
88  //println("detach all (" + weapon.name + ", " + position + ")");
90 
91  // detach if we're already in a position
92  if ( curPosition != "none" )
93  self ‪detachWeapon( weapon );
94 
95  // nothing more to do
96  if ( position == "none" )
97  {
98  //println("update(1) all (" + weapon.name + ", " + position + ")");
100  self ‪AiUtility::setCurrentWeapon( level.weaponNone );
101  return;
102  }
103 
104  if ( self.‪a.weaponPos[position] != level.weaponNone )
105  self ‪detachWeapon( self.‪a.weaponPos[position] );
106 
107  // to ensure that the correct tags for the active weapon are used, we need to make sure it gets attached first
108  if ( position == "left" || position == "right" )
109  {
110  self ‪updateScriptWeaponInfoAndPos( weapon, position );
111  self ‪AiUtility::setCurrentWeapon(weapon);
112  }
113  else
114  {
115  self ‪updateScriptWeaponInfoAndPos( weapon, position );
116  }
117 
119 
120  // make sure we don't have a weapon in each hand
121  assert( self.‪a.weaponPos["left"] == level.weaponNone || self.a.weaponPos["right"] == level.weaponNone );
122 }
123 
124 function ‪detachWeapon( weapon )
125 {
126  self.a.weaponPos[self.weaponInfo[weapon.name].position] = level.weaponNone;
127  self.weaponInfo[weapon.name].position = "none";
128 }
129 
130 
131 function ‪updateScriptWeaponInfoAndPos( weapon, position )
132 {
133  self.weaponInfo[weapon.name].position = position;
134  self.a.weaponPos[position] = weapon;
135 }
136 
138 {
139  if( isdefined(self.weapon_positions) )
140  {
141  for ( index = 0; index < self.weapon_positions.size; index++ )
142  {
143  weapon = self.a.weaponPos[self.weapon_positions[index]];
144 
145  if ( weapon == level.weaponNone )
146  continue;
147 
148  self SetActorWeapon( level.weaponNone, self GetActorWeaponOptions() );
149  }
150  }
151 }
152 
154 {
155  if( isdefined(self.weapon_positions) )
156  {
157  for ( index = 0; index < self.weapon_positions.size; index++ )
158  {
159  weapon = self.a.weaponPos[self.weapon_positions[index]];
160 
161  if ( weapon == level.weaponNone )
162  continue;
163 
164  // weapon should only be assigned (means self.weapon will be set) to the weapon if its set to go to "right"
165  if( self.weapon_positions[index] != "right" )
166  continue;
167 
168  self SetActorWeapon( weapon, self GetActorWeaponOptions() );
169 
170  if ( self.weaponInfo[weapon.name].useClip && !self.weaponInfo[weapon.name].hasClip )
171  self hidepart( "tag_clip" );
172  }
173  }
174 }
175 
176 function ‪getTagForPos( position )
177 {
178  switch ( position )
179  {
180  case "chest":
181  return "tag_weapon_chest";
182  case "back":
183  return "tag_stowed_back";
184  case "left":
185  return "tag_weapon_left";
186  case "right":
187  return "tag_weapon_right";
188  case "hand":
189  return "tag_inhand";
190  default:
191  assertMsg( "unknown weapon placement position: " + position );
192  break;
193  }
194 }
195 
196 function ‪ThrowWeapon( weapon, positionTag, scavenger )
197 {
198  waitTime = 0.1;
199  linearScalar = 2.0;
200  angularScalar = 10;
201 
202  // Calculate the linear and angular velocity to launch the weapon.
203  startPosition = self GetTagOrigin( positionTag );
204  startAngles = self GetTagAngles( positionTag );
205 
206  // Wait two server frames to calculate velocity.
207  wait( waitTime );
208 
209  if ( IsDefined( self ) )
210  {
211  endPosition = self GetTagOrigin( positionTag );
212  endAngles = self GetTagAngles( positionTag );
213 
214  linearVelocity = ( endPosition - startPosition ) * ( 1.0 / waitTime ) * linearScalar;
215  angularVelocity = VectorNormalize( endAngles - startAngles ) * angularScalar;
216 
217  throwWeapon = self DropWeapon( weapon, positionTag, linearVelocity, angularVelocity, scavenger );
218  if ( IsDefined( throwWeapon ) )
219  {
220  throwWeapon SetContents( throwWeapon SetContents( 0 ) & ~( ‪CONTENTS_ACTOR | ‪CONTENTS_CORPSE | ‪CONTENTS_VEHICLE | ‪CONTENTS_PLAYER ) );
221  }
222  return throwWeapon;
223  }
224 }
225 
226 function ‪DropAIWeapon()
227 {
228  self endon("death");
229 
230  if( self.weapon == level.weaponNone )
231  {
232  return;
233  }
234 
235  if (‪IS_TRUE(self.script_nodropsecondaryweapon) && (self.weapon == self.initial_secondaryweapon))
236  {
237  /#PrintLn("Not dropping secondary weapon '" + self.weapon.name + "'");#/
238  return;
239  }
240  else if (‪IS_TRUE(self.script_nodropsidearm) && (self.weapon == self.sidearm))
241  {
242  /#PrintLn("Not dropping sidearm '" + self.weapon.name + "'");#/
243  return;
244  }
245 
246  [[ level.ai_weapon_throttle ]]->WaitInQueue( self );
247 
248  current_weapon = self.weapon;
249  dropWeaponName = ‪player_weapon_drop( current_weapon );
250  position = self.weaponInfo[ current_weapon.name ].position;
251 
252  shouldDropWeapon = !IsDefined( self.dontDropWeapon ) || self.dontDropWeapon === false;
253 
254  if( current_weapon.isScavengable == false )
255  {
256  shouldDropWeapon = false;
257  }
258 
259  if ( shouldDropWeapon && self.dropWeapon )
260  {
261  self.dontDropWeapon = true;
262 
263  positionTag = ‪getTagForPos( position );
264 
265  ‪ThrowWeapon( dropWeaponName, positionTag, false );
266  }
267 
268  if ( self.weapon != level.weaponNone )
269  {
270  ‪shared::placeWeaponOn( current_weapon, "none" );
271 
272  if( self.weapon == self.primaryweapon )
273  {
274  self ‪AiUtility::setPrimaryWeapon( level.weaponNone );
275  }
276  else if( self.weapon == self.secondaryweapon )
277  {
278  self ‪AiUtility::setSecondaryWeapon( level.weaponNone );
279  }
280  }
281 
282  self ‪AiUtility::setCurrentWeapon( level.weaponNone );
283 }
284 
286 {
287  if (‪IS_TRUE(self.‪a.dropping_weapons))
288  {
289  // already called
290  return;
291  }
292 
293  if( !self.dropweapon )
294  {
295  if( self.weapon != level.weaponNone )
296  {
297  ‪shared::placeWeaponOn( self.weapon, "none" );
298  self ‪AiUtility::setCurrentWeapon( level.weaponNone );
299  }
300 
301  return;
302  }
303 
304  self.a.dropping_weapons = true;
305 
307 
308  droppedSideArm = false;
309 
310  if( isdefined(self.weapon_positions) )
311  {
312  for ( index = 0; index < self.weapon_positions.size; index++ )
313  {
314  weapon = self.a.weaponPos[ self.weapon_positions[ index ] ];
315 
316  if ( weapon != level.weaponNone )
317  {
318  self.weaponInfo[ weapon.name ].position = "none";
319  self.a.weaponPos[ self.weapon_positions[ index ] ] = level.weaponNone;
320 
321  if (‪IS_TRUE(self.script_nodropsecondaryweapon) && (weapon == self.initial_secondaryweapon))
322  {
323  /#PrintLn("Not dropping secondary weapon '" + weapon.name + "'");#/
324  }
325  else if (‪IS_TRUE(self.script_nodropsidearm) && (weapon == self.sidearm))
326  {
327  /#PrintLn("Not dropping sidearm '" + weapon.name + "'");#/
328  }
329  else
330  {
331 
332  velocity = self GetVelocity();
333  speed = Length( velocity ) * 0.5;
334 
335  weapon = ‪player_weapon_drop(weapon);
336 
337  droppedWeapon = self DropWeapon( weapon, self.weapon_positions[ index ], speed );
338 
339  if ( self.sideArm != level.weaponNone )
340  {
341  if ( weapon == self.sideArm )
342  droppedSideArm = true;
343  }
344  }
345  }
346  }
347  }
348 
349  if( !droppedSideArm && self.sideArm != level.weaponNone )
350  {
351  // 10% chance of dropping sidearm
352  if( RandomInt(100) <= 10 )
353  {
354  velocity = self GetVelocity();
355  speed = Length( velocity ) * 0.5;
356 
357  droppedWeapon = self DropWeapon( self.sideArm, "chest", speed );
358  }
359  }
360 
361  self ‪AiUtility::setCurrentWeapon( level.weaponNone );
362 
363  self.a.dropping_weapons = undefined;
364 }
365 
366 function ‪player_weapon_drop( weapon )
367 {
368  if ( IsSubStr( weapon.name, "rpg" ) )
369  {
370  return GetWeapon( "rpg_player" );
371  }
372 
373  return weapon;
374 }
375 
376 
377 function ‪HandleNoteTrack( note, flagName, customFunction, var1 )
378 {
379 
380 }
381 
382 // DoNoteTracks waits for and responds to standard noteTracks on the animation, returning when it gets an "end" or a "finish"
383 // For level scripts, a pointer to a custom function should be passed as the second argument, which handles notetracks not
384 // already handled by the generic function. This call should take the form DoNoteTracks(flagName,&customFunction);
385 // The custom function will be called for each notetrack not recognized, and will pass the notetrack name. Note that this
386 // function could be called multiple times for a single animation.
387 function ‪DoNoteTracks( flagName, customFunction, debugIdentifier, var1 ) // debugIdentifier isn't even used. we should get rid of it.
388 {
389  for (;;)
390  {
391  self waittill (flagName, note);
392 
393  if ( !isdefined( note ) )
394  {
395  note = "undefined";
396  }
397 
398  val = self ‪HandleNoteTrack( note, flagName, customFunction, var1 );
399 
400  if ( isdefined( val ) )
401  {
402  return val;
403  }
404  }
405 }
406 
407 
408 function ‪DoNoteTracksIntercept( flagName, interceptFunction, debugIdentifier ) // debugIdentifier isn't even used. we should get rid of it.
409 {
410  assert( isdefined( interceptFunction ) );
411 
412  for (;;)
413  {
414  self waittill ( flagName, note );
415 
416  if ( !isdefined( note ) )
417  {
418  note = "undefined";
419  }
420 
421  intercepted = [[interceptFunction]]( note );
422  if ( isdefined( intercepted ) && intercepted )
423  {
424  continue;
425  }
426 
427  val = self ‪HandleNoteTrack( note, flagName );
428 
429  if ( isdefined( val ) )
430  {
431  return val;
432  }
433  }
434 }
435 
436 
437 function ‪DoNoteTracksPostCallback( flagName, postFunction )
438 {
439  assert( isdefined( postFunction ) );
440 
441  for (;;)
442  {
443  self waittill ( flagName, note );
444 
445  if ( !isdefined( note ) )
446  {
447  note = "undefined";
448  }
449 
450  val = self ‪HandleNoteTrack( note, flagName );
451 
452  [[postFunction]]( note );
453 
454  if ( isdefined( val ) )
455  {
456  return val;
457  }
458  }
459 }
460 
461 // Don't call this function except as a thread you're going to kill - it lasts forever.
462 function ‪DoNoteTracksForever(flagName, killString, customFunction, debugIdentifier)
463 {
464  ‪DoNoteTracksForeverProc(&‪DoNoteTracks, flagName, killString, customFunction, debugIdentifier);
465 }
466 
467 function ‪DoNoteTracksForeverIntercept(flagName, killString, interceptFunction, debugIdentifier)
468 {
469  ‪DoNoteTracksForeverProc(&‪DoNoteTracksIntercept, flagName, killString, interceptFunction, debugIdentifier );
470 }
471 
472 function ‪DoNoteTracksForeverProc( notetracksFunc, flagName, killString, customFunction, debugIdentifier )
473 {
474  if (isdefined (killString))
475  {
476  self endon (killString);
477  }
478 
479  self endon ("killanimscript");
480 
481  if (!isdefined(debugIdentifier))
482  {
483  debugIdentifier = "undefined";
484  }
485 
486  for (;;)
487  {
488  time = GetTime();
489  returnedNote = [[notetracksFunc]](flagName, customFunction, debugIdentifier);
490  timetaken = GetTime() - time;
491  if ( timetaken < 0.05)
492  {
493  time = GetTime();
494  returnedNote = [[notetracksFunc]](flagName, customFunction, debugIdentifier);
495  timetaken = GetTime() - time;
496  if ( timetaken < 0.05)
497  {
498  /#println (GetTime()+" "+debugIdentifier+" shared::DoNoteTracksForever is trying to cause an infinite loop on anim "+flagName+", returned "+returnedNote+".");#/
499  wait ( 0.05 - timetaken );
500  }
501  }
502  //(GetTime()+" "+debugIdentifier+" DoNoteTracksForever returned in "+timetaken+" ms.");#/
503  }
504 }
505 
506 // Designed for using DoNoteTracks on looping animations, so you can wait for a time instead of the "end" parameter
507 function ‪DoNoteTracksForTime(time, flagName, customFunction, debugIdentifier)
508 {
509  ent = SpawnStruct();
510  ent thread ‪doNoteTracksForTimeEndNotify(time);
511  ‪DoNoteTracksForTimeProc(&‪DoNoteTracksForever, time, flagName, customFunction, debugIdentifier, ent);
512 }
513 
514 function ‪DoNoteTracksForTimeIntercept( time, flagName, interceptFunction, debugIdentifier)
515 {
516  ent = SpawnStruct();
517  ent thread ‪doNoteTracksForTimeEndNotify(time);
518  ‪DoNoteTracksForTimeProc(&‪DoNoteTracksForeverIntercept, time, flagName, interceptFunction, debugIdentifier, ent);
519 }
520 
521 function ‪DoNoteTracksForTimeProc( doNoteTracksForeverFunc, time, flagName, customFunction, debugIdentifier, ent)
522 {
523  ent endon ("stop_notetracks");
524  [[doNoteTracksForeverFunc]](flagName, undefined, customFunction, debugIdentifier);
525 }
526 
528 {
529  wait (time);
530  self notify ("stop_notetracks");
531 }
532 
‪doNoteTracksForTimeEndNotify
‪function doNoteTracksForTimeEndNotify(time)
Definition: shared.gsc:527
‪updateAttachedWeaponModels
‪function updateAttachedWeaponModels()
Definition: shared.gsc:153
‪player_weapon_drop
‪function player_weapon_drop(weapon)
Definition: shared.gsc:366
‪CONTENTS_ACTOR
‪#define CONTENTS_ACTOR
Definition: shared.gsh:112
‪setCurrentWeapon
‪function setCurrentWeapon(weapon)
Definition: archetype_utility.gsc:2152
‪initWeapon
‪function initWeapon(weapon)
Definition: init.gsc:18
‪DropAIWeapon
‪function DropAIWeapon()
Definition: shared.gsc:226
‪CONTENTS_VEHICLE
‪#define CONTENTS_VEHICLE
Definition: shared.gsh:119
‪setPrimaryWeapon
‪function setPrimaryWeapon(weapon)
Definition: archetype_utility.gsc:2163
‪detachWeapon
‪function detachWeapon(weapon)
Definition: shared.gsc:124
‪Throttle
Definition: throttle_shared.gsc:15
‪DoNoteTracksIntercept
‪function DoNoteTracksIntercept(flagName, interceptFunction, debugIdentifier)
Definition: shared.gsc:408
‪setSecondaryWeapon
‪function setSecondaryWeapon(weapon)
Definition: archetype_utility.gsc:2172
‪IS_TRUE
‪#define IS_TRUE(__a)
Definition: shared.gsh:251
‪a
‪function add_remove_list a
Definition: util_shared.csc:906
‪HandleNoteTrack
‪function HandleNoteTrack(note, flagName, customFunction, var1)
Definition: shared.gsc:377
‪main
‪function autoexec main()
Definition: shared.gsc:17
‪DoNoteTracksForever
‪function DoNoteTracksForever(flagName, killString, customFunction, debugIdentifier)
Definition: shared.gsc:462
‪DoNoteTracksForeverProc
‪function DoNoteTracksForeverProc(notetracksFunc, flagName, killString, customFunction, debugIdentifier)
Definition: shared.gsc:472
‪DoNoteTracks
‪function DoNoteTracks(flagName, customFunction, debugIdentifier, var1)
Definition: shared.gsc:387
‪updateScriptWeaponInfoAndPos
‪function updateScriptWeaponInfoAndPos(weapon, position)
Definition: shared.gsc:131
‪CONTENTS_CORPSE
‪#define CONTENTS_CORPSE
Definition: shared.gsh:122
‪Spawn
‪function Spawn(parent, onDeathCallback)
Definition: _flak_drone.gsc:427
‪detachAllWeaponModels
‪function detachAllWeaponModels()
Definition: shared.gsc:137
‪DoNoteTracksForTimeProc
‪function DoNoteTracksForTimeProc(doNoteTracksForeverFunc, time, flagName, customFunction, debugIdentifier, ent)
Definition: shared.gsc:521
‪DoNoteTracksForTime
‪function DoNoteTracksForTime(time, flagName, customFunction, debugIdentifier)
Definition: shared.gsc:507
‪DoNoteTracksForTimeIntercept
‪function DoNoteTracksForTimeIntercept(time, flagName, interceptFunction, debugIdentifier)
Definition: shared.gsc:514
‪getTagForPos
‪function getTagForPos(position)
Definition: shared.gsc:176
‪CONTENTS_PLAYER
‪#define CONTENTS_PLAYER
Definition: shared.gsh:121
‪_throwStowedWeapon
‪function private _throwStowedWeapon(entity, weapon, weaponModel)
Definition: shared.gsc:23
‪StowWeapon
‪function StowWeapon(weapon, positionOffset, orientationOffset)
Definition: shared.gsc:36
‪DropAllAIWeapons
‪function DropAllAIWeapons()
Definition: shared.gsc:285
‪DoNoteTracksPostCallback
‪function DoNoteTracksPostCallback(flagName, postFunction)
Definition: shared.gsc:437
‪placeWeaponOn
‪function placeWeaponOn(weapon, position)
Definition: shared.gsc:58
‪ThrowWeapon
‪function ThrowWeapon(weapon, positionTag, scavenger)
Definition: shared.gsc:196
‪DoNoteTracksForeverIntercept
‪function DoNoteTracksForeverIntercept(flagName, killString, interceptFunction, debugIdentifier)
Definition: shared.gsc:467