‪Black Ops 3 Source Code Explorer  0.1
‪An script explorer for Black Ops 3 by ZeRoY
_trophy_system.gsc
Go to the documentation of this file.
1 #using scripts\codescripts\struct;
2 
3 #using scripts\shared\callbacks_shared;
4 #using scripts\shared\challenges_shared;
5 #using scripts\shared\clientfield_shared;
6 #using scripts\shared\damagefeedback_shared;
7 #using scripts\shared\scoreevents_shared;
8 #using scripts\shared\system_shared;
9 #using scripts\shared\util_shared;
10 #using scripts\shared\weapons\_tacticalinsertion;
11 #using scripts\shared\weapons\_weaponobjects;
12 
13 #insert scripts\shared\shared.gsh;
14 #insert scripts\shared\version.gsh;
15 
16 #using_animtree ( "mp_trophy_system" );
17 
18 #define TROPHY_STUN_TIME_SECONDS 1
19 #define TROPHY_AMMO_COUNT 3
20 #define TROPHY_ACTIVE_RADIUS 512
21 #define TROPHY_ACTIVATION_DELAY_SECONDS 0.1
22 #define TROPHY_SYSTEM_HEALTH 20
23 #define TROPHY_FLAK_Z 15
24 #define TROPHY_TRACE_Z 29
25 
26 #precache( "fx", "weapon/fx_trophy_flash" );
27 #precache( "fx", "weapon/fx_trophy_detonation" );
28 #precache( "fx", "weapon/fx_trophy_radius_indicator" );
29 #precache( "triggerstring", "MP_TROPHY_SYSTEM_PICKUP" );
30 #precache( "triggerstring", "MP_TROPHY_SYSTEM_DESTROY" );
31 #precache( "triggerstring", "MP_TROPHY_SYSTEM_HACKING" );
32 
33 #namespace trophy_system;
34 
35 function ‪init_shared()
36 {
37  level.trophyLongFlashFX = "weapon/fx_trophy_flash";
38  level.trophyDetonationFX = "weapon/fx_trophy_detonation";
39  level.fx_trophy_radius_indicator = "weapon/fx_trophy_radius_indicator";
40 
41  trophyDeployAnim = %o_trophy_deploy;
42  trophySpinAnim = %o_trophy_spin;
43 
44  level thread register();
45 
47 }
48 
49 //******************************************************************
50 // *
51 // *
52 //******************************************************************
53 function register()
54 {
55  ‪clientfield::register( "missile", "trophy_system_state", ‪VERSION_SHIP, 2, "int" );
56  ‪clientfield::register( "scriptmover", "trophy_system_state", ‪VERSION_SHIP, 2, "int" );
57 }
58 
59 //******************************************************************
60 // *
61 // *
62 //******************************************************************
63 function ‪createTrophySystemWatcher() // self == player
64 {
65  watcher = self ‪weaponobjects::createUseWeaponObjectWatcher( "trophy_system", self.team );
66 
67  watcher.onDetonateCallback =&‪trophySystemDetonate;
68  watcher.activateSound = "wpn_claymore_alert";
69  watcher.hackable = true;
70  watcher.hackerToolRadius = level.equipmentHackerToolRadius;
71  watcher.hackerToolTimeMs = level.equipmentHackerToolTimeMs;
72  watcher.ownerGetsAssist = true;
73  watcher.ignoreDirection = true;
74  watcher.activationDelay = ‪TROPHY_ACTIVATION_DELAY_SECONDS;
75  watcher.headIcon = false;
76 
77  watcher.enemyDestroy = true;
78 
79  watcher.onSpawn =&‪onTrophySystemSpawn;
80  watcher.onDamage =&‪watchTrophySystemDamage;
81  watcher.onDestroyed =&‪onTrophySystemSmashed;
82 
83  watcher.onStun =&‪weaponobjects::weaponStun;
84  watcher.stunTime = ‪TROPHY_STUN_TIME_SECONDS;
85 }
86 
87 //******************************************************************
88 // *
89 // *
90 //******************************************************************
91 function ‪onTrophySystemSpawn( watcher, player ) // self == trophy system
92 {
93  player endon( "death" );
94  player endon( "disconnect" );
95  level endon( "game_ended" );
96  self endon( "death" );
97  self UseAnimTree( #animtree );
98  self ‪weaponobjects::onSpawnUseWeaponObject( watcher, player );
99  self.trophySystemStationary = false;
100 
101  moveState = self ‪util::waitTillRollingOrNotMoving();
102 
103  if ( moveState == "rolling" )
104  {
105  self SetAnim( %o_trophy_deploy, 1.0 );
106  self ‪clientfield::set( "trophy_system_state", ‪TROPHY_SYSTEM_ROLLING );
107 
109  }
110 
111  self.trophySystemStationary = true;
112 
113  player AddWeaponStat( self.weapon, "used", 1 );
114 
115  self.ammo = player ‪ammo_get( self.weapon );
116  self thread ‪trophyActive( player );
117  self thread ‪trophyWatchHack();
118 
119  self SetAnim( %o_trophy_deploy, 0.0 );
120  self SetAnim( %o_trophy_spin, 1.0 );
121  self ‪clientfield::set( "trophy_system_state", ‪TROPHY_SYSTEM_STATIONARY );
122 
123  self playsound("wpn_trophy_deploy_start");
124 
125  self PlayLoopSound( "wpn_trophy_spin", 0.25 );
126 
128 }
129 
130 function ‪setReconModelDeployed() // self == trophy system
131 {
132  if ( isdefined( self.reconModelEntity ) )
133  {
134  self.reconModelEntity ‪clientfield::set( "trophy_system_state", ‪TROPHY_SYSTEM_STATIONARY );
135  }
136 }
137 
138 //******************************************************************
139 // *
140 // *
141 //******************************************************************
142 function ‪trophyWatchHack() // self == trophy system
143 {
144  self endon( "death" );
145 
146  self waittill( "hacked", player );
147 
148  self ‪clientfield::set( "trophy_system_state", ‪TROPHY_SYSTEM_INIT );
149 }
150 
151 //******************************************************************
152 // *
153 // *
154 //******************************************************************
155 function ‪onTrophySystemSmashed( attacker ) // self == trophy system
156 {
157  PlayFX( level._effect["tacticalInsertionFizzle"], self.origin );
158  self playsound ("dst_trophy_smash");
159 
160  if( isdefined( level.playEquipmentDestroyedOnPlayer ) )
161  {
162  self.owner [[level.playEquipmentDestroyedOnPlayer]]( );
163  }
164 
165  if ( isdefined(attacker) && self.owner ‪util::IsEnemyPlayer( attacker ) )
166  {
168  ‪scoreevents::processScoreEvent( "destroyed_trophy_system", attacker, self.owner );
169  }
170 
171  self delete();
172 }
173 
174 //******************************************************************
175 // *
176 // *
177 //******************************************************************
178 function ‪trophyActive( owner ) // self == trophy system
179 {
180  owner endon( "disconnect" );
181  self endon( "death" );
182  self endon( "hacked" );
183 
184  while( true )
185  {
186  if ( !isdefined( self ) )
187  {
188  return;
189  }
190 
191  if (( level.missileEntities.size < 1 ) || isdefined( self.disabled ))
192  {
193  wait( .05 );
194  continue;
195  }
196 
197  for ( index=0; index < level.missileEntities.size; index++ )
198  {
199  wait( .05 ); // only handle 1 missile per frame
200 
201  if ( !isdefined( self ) )
202  {
203  return;
204  }
205 
206  grenade = level.missileEntities[index];
207 
208  if ( !isdefined(grenade) )
209  continue;
210 
211  if ( grenade == self )
212  continue;
213 
214  if ( !grenade.weapon.destroyableByTrophySystem )
215  {
216  continue;
217  }
218 
219  switch( grenade.model )
220  {
221  case "t6_wpn_grenade_supply_projectile":
222  continue;
223  }
224 
225  if ( grenade.weapon == self.weapon )
226  {
227  if ( self.trophySystemStationary == false && grenade.trophySystemStationary == true )
228  {
229  continue;
230  }
231  }
232 
233  if ( !isdefined( grenade.owner ) )
234  {
235  grenade.owner = GetMissileOwner( grenade );
236  }
237 
238  if ( isdefined( grenade.owner ))
239  {
240  if ( level.teamBased )
241  {
242  if ( grenade.owner.team == owner.team )
243  {
244  continue;
245  }
246  }
247  else
248  {
249  if ( grenade.owner == owner )
250  {
251  continue;
252  }
253  }
254 
255  grenadeDistanceSquared = DistanceSquared( grenade.origin, self.origin );
256 
257  if ( grenadeDistanceSquared < ( ‪TROPHY_ACTIVE_RADIUS * ‪TROPHY_ACTIVE_RADIUS ))
258  {
259  if ( BulletTracePassed( grenade.origin, self.origin + (0,0,‪TROPHY_TRACE_Z), false, self, grenade, false, true ) )
260  {
261  playFX( level.trophyLongFlashFX, self.origin + (0,0,‪TROPHY_FLAK_Z), ( grenade.origin - self.origin ), AnglesToUp( self.angles ) );
262 
263  // projectileExplode deletes the missile ent
264  // so need to update index on shuffled-down level.missileEntities[]
265  owner thread ‪projectileExplode( grenade, self );
266  index--;
267 
268  //Eckert - Plays sound when destroying projectile/grenade
269  self playsound ( "wpn_trophy_alert" );
270 
271  if ( GetDvarint( "player_sustainAmmo" ) == 0 )
272  {
273  self.ammo--;
274  if ( self.ammo <= 0 )
275  {
276  self thread ‪trophySystemDetonate();
277  }
278  }
279 
280  }
281  }
282  }
283  }
284  }
285 
286 }
287 
288 //******************************************************************
289 // *
290 // *
291 //******************************************************************
292 function ‪projectileExplode( projectile, trophy ) // self == trophy owning player
293 {
294  self endon( "death" );
295 
296  projPosition = projectile.origin;
297 
298  playFX( level.trophyDetonationFX, projPosition );
299  projectile notify ( "trophy_destroyed" );
300 
301  trophy RadiusDamage( projPosition, 128, 105, 10, self );
302 
303  ‪scoreevents::processScoreEvent( "trophy_defense", self );
305 
306  if ( self ‪util::is_item_purchased( "trophy_system" ) )
307  {
308  self AddPlayerStat( "destroy_explosive_with_trophy", 1 );
309  }
310  self AddWeaponStat( trophy.weapon, "CombatRecordStat", 1 );
311 
312  projectile delete();
313 }
314 
315 //******************************************************************
316 // *
317 // *
318 //******************************************************************
319 function ‪trophyDestroyTacInsert( tacInsert, trophy ) // self == trophy system owner
320 {
321  self endon( "death" );
322 
323  tacPos = tacInsert.origin;
324  playFX( level.trophyDetonationFX, tacInsert.origin );
325 
327  trophy RadiusDamage( tacPos, 128, 105, 10, self );
328 
329  ‪scoreevents::processScoreEvent( "trophy_defense", self );
330  if ( self ‪util::is_item_purchased( "trophy_system" ) )
331  {
332  self AddPlayerStat( "destroy_explosive_with_trophy", 1 );
333  }
334  self AddWeaponStat( trophy.weapon, "CombatRecordStat", 1 );
335 }
336 
337 //******************************************************************
338 // *
339 // *
340 //******************************************************************
341 function ‪trophySystemDetonate(attacker, weapon, target)
342 {
343  if ( !isdefined( weapon ) || !weapon.isEmp )
344  {
345  PlayFX( level._equipment_explode_fx_lg, self.origin );
346  }
347 
348  if ( isdefined(attacker) && self.owner ‪util::IsEnemyPlayer( attacker ) )
349  {
350  attacker ‪challenges::destroyedEquipment( weapon );
351  ‪scoreevents::processScoreEvent( "destroyed_trophy_system", attacker, self.owner, weapon );
352  }
353 
354  PlaySoundAtPosition ( "exp_trophy_system", self.origin );
355  self delete();
356 }
357 
358 //******************************************************************
359 // *
360 // *
361 //******************************************************************
362 function ‪watchTrophySystemDamage( watcher ) // self == trophy system
363 {
364  self endon( "death" );
365  self endon( "hacked" );
366 
367  self SetCanDamage( true );
368  damageMax = ‪TROPHY_SYSTEM_HEALTH;
369 
370  if ( !self ‪util::isHacked() )
371  {
372  self.damageTaken = 0;
373  }
374 
375  self.maxhealth = 10000;
376  self.health = self.maxhealth;
377 
378  self setmaxhealth( self.maxhealth );
379 
380  attacker = undefined;
381 
382  while( true )
383  {
384  self waittill ( "damage", ‪damage, attacker, direction_vec, point, type, modelName, tagName, partName, weapon, iDFlags );
385 
386  attacker = self [[ level.figure_out_attacker ]]( attacker );
387 
388  if( !isplayer( attacker ))
389  {
390  continue;
391  }
392 
393  if ( level.teambased )
394  {
395  // if we're not hardcore and the team is the same, do not destroy
396  if( !level.hardcoreMode && self.owner.team == attacker.pers["team"] && self.owner != attacker )
397  {
398  continue;
399  }
400  }
401 
402  // most equipment should be flash/concussion-able, so it'll disable for a short period of time
403  // check to see if the equipment has been flashed/concussed and disable it (checking damage < 5 is a bad idea, so check the weapon name)
404  // we're currently allowing the owner/teammate to flash their own
405  // do damage feedback
406  if ( watcher.stunTime > 0 && weapon.doStun )
407  {
408  self thread ‪weaponobjects::stunStart( watcher, watcher.stunTime );
409  }
410 
411  if ( weapon.doDamageFeedback )
412  {
413  // if we're not on the same team then show damage feedback
414  if ( level.teambased && self.owner.team != attacker.team )
415  {
416  if ( ‪damagefeedback::doDamageFeedback( weapon, attacker ) )
417  attacker ‪damagefeedback::update();
418  }
419  // for ffa just make sure the owner isn't the same
420  else if ( !level.teambased && self.owner != attacker )
421  {
422  if ( ‪damagefeedback::doDamageFeedback( weapon, attacker ) )
423  attacker ‪damagefeedback::update();
424  }
425  }
426 
427  if ( type == "MOD_MELEE" || weapon.isEmp || weapon.destroysEquipment )
428  {
429  self.damageTaken = damageMax;
430  }
431  else
432  {
433  self.damageTaken += ‪damage;
434  }
435 
436  if( self.damageTaken >= damageMax )
437  {
438  watcher thread ‪weaponobjects::waitAndDetonate( self, 0.05, attacker, weapon );
439  return;
440  }
441  }
442 }
443 
444 function ‪ammo_scavenger( weapon )
445 {
446  self ‪ammo_reset();
447 }
448 
449 function ‪ammo_reset()
450 {
451  self._trophy_system_ammo1 = undefined;
452  self._trophy_system_ammo2 = undefined;
453 }
454 
455 function ‪ammo_get( weapon )
456 {
457  totalAmmo = weapon.ammoCountEquipment;
458 
459  if ( isdefined( self._trophy_system_ammo1 ) && !self ‪util::isHacked() )
460  {
461  totalAmmo = self._trophy_system_ammo1;
462  self._trophy_system_ammo1 = undefined;
463 
464  if ( isdefined( self._trophy_system_ammo2 ) )
465  {
466  self._trophy_system_ammo1 = self._trophy_system_ammo2;
467  self._trophy_system_ammo2 = undefined;
468  }
469  }
470 
471  return totalAmmo;
472 }
473 
474 function ‪ammo_weapon_pickup( ammo )
475 {
476  if ( isdefined( ammo ) )
477  {
478  if ( isdefined( self._trophy_system_ammo1 ) )
479  {
480  self._trophy_system_ammo2 = self._trophy_system_ammo1;
481  self._trophy_system_ammo1 = ammo;
482  }
483  else
484  {
485  self._trophy_system_ammo1 = ammo;
486  }
487  }
488 }
489 
490 function ‪ammo_weapon_hacked( ammo )
491 {
492  self ‪ammo_weapon_pickup( ammo );
493 }
‪processScoreEvent
‪function processScoreEvent(event, player, victim, weapon)
Definition: scoreevents_shared.gsc:19
‪onSpawnUseWeaponObject
‪function onSpawnUseWeaponObject(watcher, owner)
Definition: _weaponobjects.gsc:1597
‪weaponStun
‪function weaponStun()
Definition: _weaponobjects.gsc:1128
‪TROPHY_FLAK_Z
‪#define TROPHY_FLAK_Z
Definition: _trophy_system.gsc:23
‪ammo_scavenger
‪function ammo_scavenger(weapon)
Definition: _trophy_system.gsc:444
‪tacticalInsertionDestroyedByTrophySystem
‪function tacticalInsertionDestroyedByTrophySystem(attacker, trophySystem)
Definition: _tacticalinsertion.gsc:421
‪destroyedEquipment
‪function destroyedEquipment(weapon)
Definition: challenges_shared.gsc:43
‪trophySystemDetonate
‪function trophySystemDetonate(attacker, weapon, target)
Definition: _trophy_system.gsc:341
‪TROPHY_SYSTEM_HEALTH
‪#define TROPHY_SYSTEM_HEALTH
Definition: _trophy_system.gsc:22
‪VERSION_SHIP
‪#define VERSION_SHIP
Definition: version.gsh:36
‪onTrophySystemSpawn
‪function onTrophySystemSpawn(watcher, player)
Definition: _trophy_system.gsc:91
‪register
‪function register()
Definition: _trophy_system.gsc:53
‪TROPHY_TRACE_Z
‪#define TROPHY_TRACE_Z
Definition: _trophy_system.gsc:24
‪init_shared
‪function init_shared()
Definition: _trophy_system.gsc:35
‪TROPHY_SYSTEM_ROLLING
‪#define TROPHY_SYSTEM_ROLLING
Definition: shared.gsh:321
‪waitAndDetonate
‪function waitAndDetonate(object, delay, attacker, weapon)
Definition: _weaponobjects.gsc:615
‪projectileExplode
‪function projectileExplode(projectile, trophy)
Definition: _trophy_system.gsc:292
‪IsEnemyPlayer
‪function IsEnemyPlayer(player)
Definition: util_shared.csc:1220
‪damage
‪function damage(trap)
Definition: _zm_trap_electric.gsc:116
‪waitTillRollingOrNotMoving
‪function waitTillRollingOrNotMoving()
Definition: util_shared.gsc:2647
‪is_item_purchased
‪function is_item_purchased(ref)
Definition: util_shared.gsc:4063
‪on_spawned
‪function on_spawned(func, obj)
Definition: callbacks_shared.csc:245
‪ammo_weapon_hacked
‪function ammo_weapon_hacked(ammo)
Definition: _trophy_system.gsc:490
‪TROPHY_STUN_TIME_SECONDS
‪#define TROPHY_STUN_TIME_SECONDS
Definition: _trophy_system.gsc:18
‪trophy_defense
‪function trophy_defense(origin, radius)
Definition: challenges_shared.gsc:1987
‪onTrophySystemSmashed
‪function onTrophySystemSmashed(attacker)
Definition: _trophy_system.gsc:155
‪trophyActive
‪function trophyActive(owner)
Definition: _trophy_system.gsc:178
‪doDamageFeedback
‪function doDamageFeedback(weapon, eInflictor, iDamage, sMeansOfDeath)
Definition: damagefeedback_shared.gsc:423
‪trophyDestroyTacInsert
‪function trophyDestroyTacInsert(tacInsert, trophy)
Definition: _trophy_system.gsc:319
‪ammo_reset
‪function ammo_reset()
Definition: _trophy_system.gsc:449
‪createTrophySystemWatcher
‪function createTrophySystemWatcher()
Definition: _trophy_system.gsc:63
‪watchTrophySystemDamage
‪function watchTrophySystemDamage(watcher)
Definition: _trophy_system.gsc:362
‪TROPHY_ACTIVATION_DELAY_SECONDS
‪#define TROPHY_ACTIVATION_DELAY_SECONDS
Definition: _trophy_system.gsc:21
‪TROPHY_SYSTEM_STATIONARY
‪#define TROPHY_SYSTEM_STATIONARY
Definition: shared.gsh:322
‪set
‪function set(str_field_name, n_value)
Definition: clientfield_shared.gsc:34
‪ammo_get
‪function ammo_get(weapon)
Definition: _trophy_system.gsc:455
‪waitTillNotMoving
‪function waitTillNotMoving()
Definition: util_shared.gsc:2621
‪trophyWatchHack
‪function trophyWatchHack()
Definition: _trophy_system.gsc:142
‪createUseWeaponObjectWatcher
‪function createUseWeaponObjectWatcher(weaponname, ownerTeam)
Definition: _weaponobjects.gsc:1297
‪setReconModelDeployed
‪function setReconModelDeployed()
Definition: _trophy_system.gsc:130
‪update
‪function update()
Definition: _serversettings.gsc:71
‪stunStart
‪function stunStart(watcher, time)
Definition: _weaponobjects.gsc:1077
‪isHacked
‪function isHacked()
Definition: util_shared.gsc:2493
‪TROPHY_SYSTEM_INIT
‪#define TROPHY_SYSTEM_INIT
Definition: shared.gsh:320
‪ammo_weapon_pickup
‪function ammo_weapon_pickup(ammo)
Definition: _trophy_system.gsc:474
‪TROPHY_ACTIVE_RADIUS
‪#define TROPHY_ACTIVE_RADIUS
Definition: _trophy_system.gsc:20