‪Black Ops 3 Source Code Explorer  0.1
‪An script explorer for Black Ops 3 by ZeRoY
_zm_weapons.gsc
Go to the documentation of this file.
1 #using scripts\codescripts\struct;
2 
3 #using scripts\shared\aat_shared;
4 #using scripts\shared\callbacks_shared;
5 #using scripts\shared\clientfield_shared;
6 #using scripts\shared\util_shared;
7 #using scripts\shared\weapons\_weaponobjects;
8 
9 #insert scripts\shared\shared.gsh;
10 #insert scripts\shared\version.gsh;
11 
12 #using scripts\zm\gametypes\_weapons;
13 
14 #using scripts\zm\_util;
15 #using scripts\zm\_bb;
16 #using scripts\zm\_zm_audio;
17 #using scripts\zm\_zm_bgb;
18 #using scripts\zm\_zm_equipment;
19 #using scripts\zm\_zm_magicbox;
20 #using scripts\zm\_zm_melee_weapon;
21 #using scripts\zm\_zm_pack_a_punch_util;
22 #using scripts\zm\_zm_pers_upgrades_functions;
23 #using scripts\zm\_zm_placeable_mine;
24 #using scripts\zm\_zm_score;
25 #using scripts\zm\_zm_stats;
26 #using scripts\zm\_zm_unitrigger;
27 #using scripts\zm\_zm_utility;
28 #using scripts\zm\_zm_weap_ballistic_knife;
29 
30 #insert scripts\zm\_zm_perks.gsh;
31 #insert scripts\zm\_zm_utility.gsh;
32 #insert scripts\zm\_zm_weapons.gsh;
33 
34 #precache( "material", "minimap_icon_mystery_box" );
35 #precache( "material", "specialty_instakill_zombies" );
36 #precache( "material", "specialty_firesale_zombies" );
37 #precache( "string", "ZOMBIE_WEAPON_TOGGLE_DISABLED" );
38 #precache( "string", "ZOMBIE_WEAPON_TOGGLE_ACTIVATE" );
39 #precache( "string", "ZOMBIE_WEAPON_TOGGLE_DEACTIVATE" );
40 #precache( "string", "ZOMBIE_WEAPON_TOGGLE_ACQUIRED" );
41 
42 #precache( "triggerstring", "ZOMBIE_WEAPONAMMOONLY_CFILL" );
43 #precache( "triggerstring", "ZOMBIE_WEAPONAMMOONLY_CFILL_BGB_SECRET_SHOPPER" );
44 #precache( "triggerstring", "ZOMBIE_WEAPONCOSTONLY_CFILL" );
45 #precache( "triggerstring", "ZOMBIE_WEAPONCOSTONLY_CFILL_BGB_SECRET_SHOPPER" );
46 
47 #precache( "triggerstring", "ZOMBIE_WEAPONAMMOHACKED_CFILL" );
48 #precache( "triggerstring", "ZOMBIE_WEAPONAMMOHACKED_CFILL_BGB_SECRET_SHOPPER" );
49 
50 #namespace zm_weapons;
51 
52 function ‪init()
53 {
54  ‪DEFAULT( level.pack_a_punch_camo_index, 42 ); // Der Riese etching camo is the default
55 
56  ‪DEFAULT( level.weapon_cost_client_filled, true );
57  ‪DEFAULT( level.obsolete_prompt_format_needed, false );
58 
60  ‪init_weapon_upgrade(); //Wall buys
61 
62  level._weaponobjects_on_player_connect_override = &‪weaponobjects_on_player_connect_override;
63 
64  level._zombiemode_check_firesale_loc_valid_func = &‪default_check_firesale_loc_valid_func;
65 
66  level.missileEntities = [];
67 
68  level thread ‪onPlayerConnect();
69 }
70 
72 {
73  for(;;)
74  {
75  level waittill("connecting", player);
76  player thread ‪onPlayerSpawned();
77  }
78 }
79 
80 
82 {
83  self endon("disconnect");
84 
85  for(;;)
86  {
87  self waittill("spawned_player");
88  self thread ‪watchForGrenadeDuds();
89  self thread ‪watchForGrenadeLauncherDuds();
90  self.staticWeaponsStartTime = getTime();
91  }
92 }
93 
95 {
96  self endon( "spawned_player" );
97  self endon( "disconnect" );
98 
99  while ( true )
100  {
101  self waittill( "grenade_fire", grenade, weapon );
103  {
104  grenade thread ‪checkGrenadeForDud( weapon, true, self );
105  grenade thread ‪watchForScriptExplosion( weapon, true, self );
106  }
107  }
108 }
109 
111 {
112  self endon( "spawned_player" );
113  self endon( "disconnect" );
114 
115  while ( true )
116  {
117  self waittill( "grenade_launcher_fire", grenade, weapon );
118  grenade thread ‪checkGrenadeForDud( weapon, false, self );
119  grenade thread ‪watchForScriptExplosion( weapon, false, self );
120  }
121 }
122 
123 
124 function ‪grenade_safe_to_throw( player, weapon )
125 {
126  if ( IsDefined( level.grenade_safe_to_throw ) )
127  {
128  return self [[level.grenade_safe_to_throw]]( player, weapon );
129  }
130  return true;
131 }
132 
133 function ‪grenade_safe_to_bounce( player, weapon )
134 {
135  if ( IsDefined( level.grenade_safe_to_bounce ) )
136  {
137  return self [[level.grenade_safe_to_bounce]]( player, weapon );
138  }
139  return true;
140 }
141 
142 
144 {
145  self endon("death");
146  self notify("grenade_dud");
147  self makeGrenadeDud();
148  wait 3;
149  if (isdefined(self))
150  {
151  self delete();
152  }
153 }
154 
155 function ‪checkGrenadeForDud( weapon, isThrownGrenade, player )
156 {
157  self endon("death");
158  player endon("zombify");
159 
160  if ( !IsDefined( self ) )
161  {
162  // player must've been downed while throwing it
163  return;
164  }
165 
166  if ( !self ‪grenade_safe_to_throw( player, weapon ) )
167  {
168  self thread ‪makeGrenadeDudAndDestroy();
169  return;
170  }
171 
172  for ( ;; )
173  {
174  self ‪util::waittill_any_ex( 0.25, "grenade_bounce", "stationary", "death", player, "zombify" );
175  if ( !self ‪grenade_safe_to_bounce( player, weapon ) )
176  {
177  self thread ‪makeGrenadeDudAndDestroy();
178  return;
179  }
180  }
181 }
182 
183 
184 function ‪wait_explode()
185 {
186  self endon("grenade_dud");
187  self endon("done");
188  self waittill( "explode", position );
189  level.explode_position = position;
190  level.explode_position_valid = 1;
191  self notify("done");
192 }
193 
194 function ‪wait_timeout(time)
195 {
196  self endon("grenade_dud");
197  self endon("done");
198  self endon( "explode" );
199  wait( time );
200  if (IsDefined(self))
201  self notify("done");
202 }
203 
204 function ‪wait_for_explosion(time)
205 {
206  level.explode_position = (0,0,0);
207  level.explode_position_valid = 0;
208  self thread ‪wait_explode();
209  self thread ‪wait_timeout(time);
210  self waittill("done");
211  self notify("death_or_explode",level.explode_position_valid,level.explode_position);
212 }
213 
214 function ‪watchForScriptExplosion( weapon, isThrownGrenade, player )
215 {
216  self endon("grenade_dud");
217 
218  if ( ‪zm_utility::is_lethal_grenade( weapon ) || weapon.isLauncher )
219  {
220  self thread ‪wait_for_explosion(20);
221  self waittill( "death_or_explode", exploded, position );
222  if ( exploded )
223  {
224  level notify( "grenade_exploded", position, 256, 300, 75 );
225  }
226  }
227 }
228 
229 // must be called on player;
230 function ‪get_nonalternate_weapon( weapon )
231 {
232  if ( weapon.isAltMode )
233  {
234  return weapon.altWeapon;
235  }
236 
237  return weapon;
238 }
239 
240 function ‪switch_from_alt_weapon( weapon )
241 {
242  //Check for charge shot
243  if( weapon.ischargeshot )
244  {
245  return weapon;
246  }
247 
248  alt = ‪get_nonalternate_weapon( weapon );
249  if ( alt != weapon )
250  {
251  // skip switching weapons on dualoptic, they switch instantly which messes with the timing, and they don't seem to have an issue that requires a switch to begin with
252  if ( !WeaponHasAttachment( weapon, "dualoptic" ) )
253  {
254  self SwitchToWeaponImmediate( alt );
255  self ‪util::waittill_any_timeout( 1, "weapon_change_complete" );
256  }
257 
258  return alt;
259  }
260 
261  return weapon;
262 }
263 
264 function ‪give_start_weapons( takeAllWeapons, alreadySpawned )
265 {
266  self giveWeapon( level.weaponBaseMelee );
268 }
269 
270 function ‪give_fallback_weapon( immediate = false )
271 {
273 }
274 
276 {
278 }
279 
280 function ‪switch_back_primary_weapon( oldprimary, immediate = false )
281 {
282  if ( ‪IS_TRUE( self.laststand ) )
283  {
284  return;
285  }
286 
287  if ( !isdefined(oldprimary) ||
288  oldprimary == level.weaponNone ||
289  oldprimary.isFlourishWeapon ||
290  ‪zm_utility::is_melee_weapon( oldprimary ) ||
291  ‪zm_utility::is_placeable_mine( oldprimary ) ||
292  ‪zm_utility::is_lethal_grenade( oldprimary ) ||
293  ‪zm_utility::is_tactical_grenade( oldprimary ) ||
294  !self HasWeapon( oldprimary ) )
295  {
296  oldprimary = undefined;
297  }
298  else if ( ( oldprimary.isheroweapon || oldprimary.isgadget ) &&
299  ( !isdefined( self.hero_power ) || self.hero_power <= 0 ) )
300  {
301  oldprimary = undefined;
302  }
303 
304  primaryWeapons = self GetWeaponsListPrimaries();
305  if ( isdefined( oldprimary ) && IsInArray( primaryWeapons, oldprimary ) )
306  {
307  if( immediate )
308  {
309  self SwitchToWeaponImmediate( oldprimary );
310  }
311  else
312  {
313  self SwitchToWeapon( oldprimary );
314  }
315  }
316  else if ( primaryWeapons.size > 0 )
317  {
318  if( immediate )
319  {
320  self SwitchToWeaponImmediate();
321  }
322  else
323  {
324  self SwitchToWeapon();
325  }
326  }
327  else
328  {
329  ‪give_fallback_weapon( immediate );
330  }
331 }
332 
334 {
335  if ( !isdefined( level.retrievable_knife_init_names ) )
336  {
337  level.retrievable_knife_init_names = [];
338  }
339 
340  level.retrievable_knife_init_names[level.retrievable_knife_init_names.size] = ‪name;
341 }
342 
344 {
345  self endon( "death" );
346  self endon( "disconnect" );
347  level endon ( "game_ended" );
348 
349  for ( ;; )
350  {
351  self waittill ( "weapon_fired", curWeapon );
352  self.lastFireTime = GetTime();
353 
354  self.hasDoneCombat = true;
355 
356  switch ( curWeapon.weapClass )
357  {
358  case "rifle":
359  case "pistol":
360  case "pistolspread":
361  case "pistol spread":
362  case "mg":
363  case "smg":
364  case "spread":
365  self ‪weapons::trackWeaponFire( curWeapon );
366  level.globalShotsFired++;
367  break;
368  case "rocketlauncher":
369  case "grenade":
370  self AddWeaponStat( curWeapon, "shots", 1 );
371 
372  break;
373 
374  default:
375  break;
376  }
377  }
378 }
379 
381 {
382  self.currentWeapon = self getCurrentWeapon();
383  self.currentTime = getTime();
384  spawnid = getplayerspawnid( self );
385 
386  while ( 1 )
387  {
388  event = self ‪util::waittill_any_return( "weapon_change", "death", "disconnect", "bled_out" );
389  newTime = getTime();
390 
391  if ( event == "weapon_change" )
392  {
393  newWeapon = self getCurrentWeapon();
394  if ( newWeapon != level.weaponNone && newWeapon != self.currentWeapon )
395  {
397 
398  self.currentWeapon = newWeapon;
399  self.currentTime = newTime;
400  }
401  }
402  else
403  {
404  if ( event != "death" && event != "disconnect" )
405  {
406  ‪updateWeaponTimingsZM( newTime );
407  }
408 
409  return;
410  }
411  }
412 }
413 
415 {
416  if ( isDefined( self.currentWeapon ) && isDefined( self.currentTime ) )
417  {
418  curweapon = self.currentWeapon;
419  totalTime = int ( ( newTime - self.currentTime ) / 1000 );
420  if ( totalTime > 0 )
421  {
422  self AddWeaponStat( curweapon, "timeUsed", totalTime );
423  }
424  }
425 }
426 
427 function ‪updateWeaponTimingsZM( newTime )
428 {
429  if ( self ‪util::is_bot() )
430  {
431  return;
432  }
433 
435 
436  if ( !isDefined( self.staticWeaponsStartTime ) )
437  {
438  return;
439  }
440 
441  totalTime = int ( ( newTime - self.staticWeaponsStartTime ) / 1000 );
442 
443  if ( totalTime < 0 )
444  {
445  return;
446  }
447 
448  self.staticWeaponsStartTime = newTime;
449 }
450 
451 
453 {
454  self endon("death");
455  self endon("disconnect");
456 
457  self.lastDroppableWeapon = self GetCurrentWeapon();
458  self.hitsThisMag = [];
459 
460  weapon = self getCurrentWeapon();
461 
462  while ( 1 )
463  {
464  previous_weapon = self GetCurrentWeapon();
465  self waittill( "weapon_change", newWeapon );
466 
467  if ( ‪weapons::mayDropWeapon( newWeapon ) )
468  {
469  self.lastDroppableWeapon = newWeapon;
470  }
471  }
472 }
473 
474 
476 {
478 
479  //Ensure that the watcher name is the weapon name minus _mp if you want to add weapon specific functionality.
481 
482  for ( i = 0; i < level.retrievable_knife_init_names.size; i++ )
483  {
484  self ‪createBallisticKnifeWatcher_zm( level.retrievable_knife_init_names[i] );
485  }
486 
487  //set up retrievable specific fields
489 
490  if ( !IsDefined(self.weaponObjectWatcherArray) )
491  {
492  self.weaponObjectWatcherArray = [];
493  }
494 
495  self.concussionEndTime = 0;
496  self.hasDoneCombat = false;
497  self.lastFireTime = 0;
498  self thread ‪watchWeaponUsageZM();
499  self thread ‪weapons::watchGrenadeUsage();
500  self thread ‪weapons::watchMissileUsage();
501  self thread ‪watchWeaponChangeZM();
502  self thread ‪trackWeaponZM();
503 
504  self notify("weapon_watchers_created");
505 }
506 
508 {
509  ‪add_retrievable_knife_init_name( "knife_ballistic" );
510  ‪add_retrievable_knife_init_name( "knife_ballistic_upgraded" );
511 
513 }
514 
515 function ‪createBallisticKnifeWatcher_zm( weaponName ) // self == player
516 {
517  watcher = self ‪weaponobjects::createUseWeaponObjectWatcher( weaponName, self.team );
518  watcher.onSpawn = &‪_zm_weap_ballistic_knife::on_spawn;
519  watcher.onSpawnRetrieveTriggers = &‪_zm_weap_ballistic_knife::on_spawn_retrieve_trigger;
520  watcher.storeDifferentObject = true;
521  watcher.headIcon = false;
522 }
523 
525 {
526  return true;
527 }
528 
529 function ‪add_zombie_weapon( weapon_name, upgrade_name, hint, cost, weaponVO, weaponVOresp, ammo_cost, create_vox, ‪is_wonder_weapon, force_attachments )
530 {
531  weapon = GetWeapon( weapon_name );
532  upgrade = undefined;
533  if ( IsDefined( upgrade_name ) )
534  {
535  upgrade = GetWeapon( upgrade_name );
536  }
537  if ( IsDefined( level.zombie_include_weapons ) && !IsDefined( level.zombie_include_weapons[weapon] ) )
538  {
539  return;
540  }
541 
542  struct = SpawnStruct();
543 
544  if ( !IsDefined( level.zombie_weapons ) )
545  {
546  level.zombie_weapons = [];
547  }
548  if ( !IsDefined( level.zombie_weapons_upgraded ) )
549  {
550  level.zombie_weapons_upgraded = [];
551  }
552  if ( isDefined(upgrade_name) )
553  {
554  level.zombie_weapons_upgraded[upgrade] = weapon;
555  }
556 
557  struct.weapon = weapon;
558  struct.upgrade = upgrade;
559  struct.weapon_classname = "weapon_" + weapon_name + "_zm";
560  if ( ‪IS_TRUE( level.weapon_cost_client_filled ) )
561  {
562  struct.hint = &"ZOMBIE_WEAPONCOSTONLY_CFILL";
563  }
564  else
565  {
566  struct.hint = &"ZOMBIE_WEAPONCOSTONLYFILL";
567  }
568  struct.cost = cost;
569  struct.vox = weaponVO;
570  struct.vox_response = weaponVOresp;
571  struct.is_wonder_weapon = ‪is_wonder_weapon;
572  struct.force_attachments = [];
573 
574  if ( "" != force_attachments )
575  {
576  force_attachments_list = StrTok( force_attachments, " " );
577  assert( 6 >= force_attachments_list.size, weapon_name + " declared more than 6 force_attachments." );
578  foreach ( index, attachment in force_attachments_list )
579  {
580  struct.force_attachments[struct.force_attachments.size] = attachment;
581  }
582  }
583 
584 
585 
586  struct.is_in_box = level.zombie_include_weapons[weapon];
587 
588  if ( !IsDefined( ammo_cost ) )
589  {
590  ammo_cost = ‪zm_utility::round_up_to_ten( int( cost * 0.5 ) );
591  }
592  struct.ammo_cost = ammo_cost;
593 
594  if ( weapon.isEmp || (IsDefined( upgrade ) && upgrade.isEmp ) )
595  {
596  level.should_watch_for_emp = true;
597  }
598 
599  level.zombie_weapons[weapon] = struct;
600 
601  if ( ‪zm_pap_util::can_swap_attachments() && isdefined( upgrade_name ) )
602  {
603  ‪add_attachments( weapon_name, upgrade_name );
604  }
605 
606  if ( isDefined( create_vox ) )
607  {
608  level.vox ‪zm_audio::zmbVoxAdd( "player", "weapon_pickup", weapon, weaponVO ,undefined);
609  }
610 
611 }
612 
613 function ‪add_attachments( weapon, upgrade )
614 {
615  table = "gamedata/weapons/zm/pap_attach.csv";
616  if ( isdefined( level.weapon_attachment_table ) )
617  {
618  table = level.weapon_attachment_table;
619  }
620 
621  row = TableLookupRowNum( table, 0, upgrade );
622  if ( row > -1 )
623  {
624  level.zombie_weapons[weapon].default_attachment = TableLookUp( table, 0, upgrade.name, 1 );
625  level.zombie_weapons[weapon].addon_attachments = [];
626  index = 2;
627  next_addon = TableLookUp( table, 0, upgrade.name, index );
628  while ( isdefined( next_addon ) && next_addon.size > 0 )
629  {
630  level.zombie_weapons[weapon].addon_attachments[level.zombie_weapons[weapon].addon_attachments.size] = next_addon;
631  index++;
632  next_addon = TableLookUp( table, 0, upgrade.name, index );
633  }
634  }
635 }
636 
637 
638 function ‪is_weapon_included( weapon )
639 {
640  if ( !IsDefined( level.zombie_weapons ) )
641  {
642  return false;
643  }
644 
645  weapon = ‪get_nonalternate_weapon( weapon );
646 
647  return IsDefined( level.zombie_weapons[weapon.rootWeapon] );
648 }
649 
651 {
652  weapon = ‪get_nonalternate_weapon( weapon );
653 
654  return (IsDefined( level.zombie_weapons[weapon.rootWeapon] ) || IsDefined( level.zombie_weapons[‪get_base_weapon( weapon )] ));
655 }
656 
657 
658 function ‪include_zombie_weapon( weapon_name, in_box )
659 {
660  if ( !IsDefined( level.zombie_include_weapons ) )
661  {
662  level.zombie_include_weapons = [];
663  }
664  if ( !isDefined( in_box ) )
665  {
666  in_box = true;
667  }
668 
669 
670  level.zombie_include_weapons[GetWeapon( weapon_name )] = in_box;
671 }
672 
673 
674 function ‪init_weapons()
675 {
676  if ( IsDefined( level._zombie_custom_add_weapons ) )
677  {
678  [[level._zombie_custom_add_weapons]]();
679  }
680 }
681 
682 function ‪add_limited_weapon( weapon_name, amount )
683 {
684  if ( !IsDefined( level.limited_weapons ) )
685  {
686  level.limited_weapons = [];
687  }
688 
689  level.limited_weapons[GetWeapon( weapon_name )] = amount;
690 }
691 
692 
693 //*****************************************************************************
694 //*****************************************************************************
695 
696 function ‪limited_weapon_below_quota( weapon, ignore_player, pap_triggers )
697 {
698  if ( IsDefined( level.limited_weapons[weapon] ) )
699  {
700  if ( !isdefined( pap_triggers ) )
701  {
702  pap_triggers = ‪zm_pap_util::get_triggers();
703  }
704 
705  if ( ‪IS_TRUE( level.no_limited_weapons ) )
706  {
707  return false;
708  }
709 
710  upgradedweapon = weapon;
711  if ( IsDefined( level.zombie_weapons[weapon] ) && IsDefined( level.zombie_weapons[weapon].upgrade ) )
712  {
713  upgradedweapon = level.zombie_weapons[weapon].upgrade;
714  }
715 
716  players = GetPlayers();
717 
718  count = 0;
719  ‪limit = level.limited_weapons[weapon];
720 
721  for ( i = 0; i < players.size; i++ )
722  {
723  if ( isdefined( ignore_player ) && ignore_player == players[i] )
724  {
725  continue;
726  }
727 
728  if ( players[i] ‪has_weapon_or_upgrade( weapon ) )
729  {
730  count++;
731  if ( count >= ‪limit )
732  {
733  return false;
734  }
735  }
736  }
737 
738  // Check the pack a punch machines to see if they are holding what we're looking for
739  for ( k = 0; k < pap_triggers.size; k++ )
740  {
741  if ( IsDefined( pap_triggers[k].current_weapon ) && (pap_triggers[k].current_weapon == weapon || pap_triggers[k].current_weapon == upgradedweapon) )
742  {
743  count++;
744  if ( count >= ‪limit )
745  {
746  return false;
747  }
748  }
749  }
750 
751  // Check the other boxes so we don't offer something currently being offered during a fire sale
752  for ( chestIndex = 0; chestIndex < level.chests.size; chestIndex++ )
753  {
754  if ( IsDefined( level.chests[chestIndex].zbarrier.weapon ) && level.chests[chestIndex].zbarrier.weapon == weapon )
755  {
756  count++;
757  if ( count >= ‪limit )
758  {
759  return false;
760  }
761  }
762  }
763 
764  if ( IsDefined( level.custom_limited_weapon_checks ) )
765  {
766  foreach ( check in level.custom_limited_weapon_checks )
767  {
768  count += [[check]]( weapon );
769  }
770  if ( count >= ‪limit )
771  {
772  return false;
773  }
774  }
775 
776  if ( isdefined( level.random_weapon_powerups ) )
777  {
778  for ( powerupIndex = 0; powerupIndex < level.random_weapon_powerups.size; powerupIndex++ )
779  {
780  if ( IsDefined( level.random_weapon_powerups[powerupIndex] ) && level.random_weapon_powerups[powerupIndex].base_weapon == weapon )
781  {
782  count++;
783  if ( count >= ‪limit )
784  {
785  return false;
786  }
787  }
788  }
789  }
790  }
791 
792  return true;
793 }
794 
795 
797 {
798  if ( !IsDefined( level.custom_limited_weapon_checks ) )
799  {
800  level.custom_limited_weapon_checks = [];
801  }
802 
803  level.custom_limited_weapon_checks[level.custom_limited_weapon_checks.size] = ‪callback;
804 }
805 
806 
807 //*****************************************************************************
808 //*****************************************************************************
809 
810 function ‪add_weapon_to_content( weapon_name, package )
811 {
812  if ( !IsDefined( level.content_weapons ) )
813  {
814  level.content_weapons = [];
815  }
816 
817  level.content_weapons[GetWeapon( weapon_name )] = package;
818 }
819 
820 function ‪player_can_use_content( weapon )
821 {
822  if ( IsDefined( level.content_weapons ) )
823  {
824  if ( IsDefined( level.content_weapons[weapon] ) )
825  {
826  return self HasDLCAvailable( level.content_weapons[weapon] );
827  }
828  }
829 
830  return true;
831 }
832 
833 //*****************************************************************************
834 //*****************************************************************************
835 
837 {
838 
839  // spawn_list construction must be matched in _zm_weapons.csc function init() or your level will not load.
840 
841  spawn_list = [];
842  spawnable_weapon_spawns = ‪struct::get_array( "weapon_upgrade", "targetname" );
843  spawnable_weapon_spawns = ArrayCombine( spawnable_weapon_spawns, ‪struct::get_array( "bowie_upgrade", "targetname" ), true, false );
844  spawnable_weapon_spawns = ArrayCombine( spawnable_weapon_spawns, ‪struct::get_array( "sickle_upgrade", "targetname" ), true, false );
845  spawnable_weapon_spawns = ArrayCombine( spawnable_weapon_spawns, ‪struct::get_array( "tazer_upgrade", "targetname" ), true, false );
846  spawnable_weapon_spawns = ArrayCombine( spawnable_weapon_spawns, ‪struct::get_array( "buildable_wallbuy", "targetname" ), true, false );
847 
848  if ( ‪IS_TRUE( level.use_autofill_wallbuy ) )
849  {
850  spawnable_weapon_spawns = ArrayCombine( spawnable_weapon_spawns, level.active_autofill_wallbuys, true, false );
851  }
852 
853  if ( !‪IS_TRUE( level.headshots_only ) )
854  {
855  spawnable_weapon_spawns = ArrayCombine( spawnable_weapon_spawns, ‪struct::get_array( "claymore_purchase", "targetname" ), true, false );
856  }
857 
858  location = level.scr_zm_map_start_location;
859  if ( (location == "default" || location == "") && IsDefined( level.default_start_location ) )
860  {
861  location = level.default_start_location;
862  }
863 
864  match_string = level.scr_zm_ui_gametype;
865  if ( "" != location )
866  {
867  match_string = match_string + "_" + location;
868  }
869  match_string_plus_space = " " + match_string;
870 
871  for ( i = 0; i < spawnable_weapon_spawns.size; i++ )
872  {
873  spawnable_weapon = spawnable_weapon_spawns[i];
874 
875  spawnable_weapon.weapon = GetWeapon( spawnable_weapon.zombie_weapon_upgrade );
876  if ( isDefined( spawnable_weapon.zombie_weapon_upgrade ) && spawnable_weapon.weapon.isGrenadeWeapon && ‪IS_TRUE( level.headshots_only ) )
877  {
878  continue;
879  }
880 
881  if ( !isdefined( spawnable_weapon.script_noteworthy ) || spawnable_weapon.script_noteworthy == "" )
882  {
883  spawn_list[spawn_list.size] = spawnable_weapon;
884  }
885  else
886  {
887  matches = strTok( spawnable_weapon.script_noteworthy, "," );
888 
889  for ( j = 0; j < matches.size; j++ )
890  {
891  if ( matches[j] == match_string || matches[j] == match_string_plus_space )
892  {
893  spawn_list[spawn_list.size] = spawnable_weapon;
894  }
895  }
896 
897  }
898  }
899 
900  tempModel = ‪Spawn( "script_model", (0,0,0) );
901 
902  for ( i = 0; i < spawn_list.size; i++ )
903  {
904  clientFieldName = spawn_list[i].zombie_weapon_upgrade + "_" + spawn_list[i].origin; // Name has origin appended, in case there are more than one of the same weapon placed.
905 
906  numBits = 2;
907 
908  if ( isdefined( level._wallbuy_override_num_bits ) )
909  {
910  numBits = level._wallbuy_override_num_bits;
911  }
912 
913  ‪clientfield::register( "world", clientFieldName, ‪VERSION_SHIP, numBits, "int" ); // 2 bit int client field - bit 1 : 0 = not bought 1 = bought. bit 2: 0 = not hacked 1 = hacked.
914 
915  target_struct = ‪struct::get( spawn_list[i].target, "targetname" );
916 
917  if ( spawn_list[i].targetname == "buildable_wallbuy" )
918  {
919  // For buildable wallbuys we defer the remainder of the initialization until add_dynamic_wallbuy() is called
920  // we also need to register an additional clientfield for transferring the weapon index
921  bits = 4;
922  if ( IsDefined( level.buildable_wallbuy_weapons ) )
923  {
924  bits = GetMinBitCountForNum( level.buildable_wallbuy_weapons.size + 1 );
925  }
926  ‪clientfield::register( "world", clientfieldName + "_idx", ‪VERSION_SHIP, bits, "int" );
927  spawn_list[i].clientfieldName = clientfieldName;
928  continue;
929  }
930 
931  unitrigger_stub = spawnstruct();
932  unitrigger_stub.origin = spawn_list[i].origin;
933  unitrigger_stub.angles = spawn_list[i].angles;
934 
935  tempModel.origin = spawn_list[i].origin;
936  tempModel.angles = spawn_list[i].angles;
937 
938  mins = undefined;
939  maxs = undefined;
940  absMins = undefined;
941  absMaxs = undefined;
942 
943  tempModel setModel( target_struct.model );
944 
945  tempModel UseWeaponHideTags( spawn_list[i].weapon );
946 
947  mins = tempModel GetMins();
948  maxs = tempModel GetMaxs();
949 
950  absMins = tempModel GetAbsMins();
951  absMaxs = tempModel GetAbsMaxs();
952 
953  bounds = absMaxs - absMins;
954 
955  unitrigger_stub.script_length = bounds[0] * 0.25;
956  unitrigger_stub.script_width = bounds[1];
957  unitrigger_stub.script_height = bounds[2];
958 
959  unitrigger_stub.origin -= (AnglesToRight( unitrigger_stub.angles) * (unitrigger_stub.script_length * 0.4));
960 
961  unitrigger_stub.target = spawn_list[i].target;
962  unitrigger_stub.targetname = spawn_list[i].targetname;
963 
964  unitrigger_stub.cursor_hint = "HINT_NOICON";
965 
966  if ( spawn_list[i].targetname == "weapon_upgrade" )
967  {
968  unitrigger_stub.cost = ‪get_weapon_cost( spawn_list[i].weapon );
969  unitrigger_stub.hint_string = ‪get_weapon_hint( spawn_list[i].weapon );
970  if (!‪IS_TRUE( level.weapon_cost_client_filled ))
971  {
972  unitrigger_stub.hint_parm1 = unitrigger_stub.cost;
973  }
974  unitrigger_stub.cursor_hint = "HINT_WEAPON";
975  unitrigger_stub.cursor_hint_weapon = spawn_list[i].weapon;
976  }
977 
978  unitrigger_stub.weapon = spawn_list[i].weapon;
979 
980  unitrigger_stub.script_unitrigger_type = "unitrigger_box_use";
981  //TODO: Get a custom KVP for this
982  if (isdefined (spawn_list[i].script_string) && ‪IS_TRUE(Int(spawn_list[i].script_string)))
983  {
984  unitrigger_stub.require_look_toward = false;
985  unitrigger_stub.require_look_at = false;
986  unitrigger_stub.script_unitrigger_type = "unitrigger_box_use";
987  unitrigger_stub.script_length = bounds[0] * 0.4;
988  unitrigger_stub.script_width = bounds[1] * 2;
989  unitrigger_stub.script_height = bounds[2];
990  }
991  else
992  {
993  unitrigger_stub.require_look_at = true;
994  }
995  if ( ‪IS_TRUE( spawn_list[i].require_look_from ) )
996  {
997  unitrigger_stub.require_look_from = true;
998  }
999 
1000  unitrigger_stub.clientFieldName = clientFieldName;
1002 
1003  if ( unitrigger_stub.weapon.isMeleeWeapon || unitrigger_stub.weapon.isGrenadeWeapon )
1004  {
1005  if ( unitrigger_stub.weapon.name == "tazer_knuckles" && IsDefined( level.taser_trig_adjustment ) )
1006  {
1007  unitrigger_stub.origin = unitrigger_stub.origin + level.taser_trig_adjustment;
1008  }
1010  }
1011  else
1012  {
1013  unitrigger_stub.prompt_and_visibility_func = &‪wall_weapon_update_prompt;
1015  }
1016 
1017  spawn_list[i].trigger_stub = unitrigger_stub;
1018 
1019  }
1020 
1021  level._spawned_wallbuys = spawn_list;
1022 
1023  tempModel delete();
1024 
1025 }
1026 
1027 function ‪add_dynamic_wallbuy( weapon, wallbuy, pristine )
1028 {
1029  spawned_wallbuy = undefined;
1030 
1031  // spawned_wallbuy is roughly equivalent to spawn_list[i] in init_spawnable_weapon_upgrade()
1032  // find the appropriate item
1033  for ( i = 0; i < level._spawned_wallbuys.size; i++ )
1034  {
1035  if ( level._spawned_wallbuys[i].target == wallbuy )
1036  {
1037  spawned_wallbuy = level._spawned_wallbuys[i];
1038  break;
1039  }
1040 
1041  }
1042 
1043  if ( !isdefined( spawned_wallbuy ) )
1044  {
1045  AssertMsg( "Cannot find dynamic wallbuy" );
1046  return;
1047  }
1048 
1049  if ( isdefined( spawned_wallbuy.trigger_stub ) )
1050  {
1051  AssertMsg( "Dynamic wallbuy already added" );
1052  return;
1053  }
1054 
1055  target_struct = ‪struct::get( wallbuy, "targetname" );
1056 
1057  // this model is similar to tempModel above - it will only be deleted if the weapon exists in the list of known dynamic wallbuy weapons
1058  wallModel = ‪zm_utility::spawn_weapon_model( weapon, undefined, target_struct.origin, target_struct.angles, undefined );
1059 
1060  clientfieldName = spawned_wallbuy.clientfieldName;
1061 
1062  model = weapon.worldModel;
1063 
1064  unitrigger_stub = spawnstruct();
1065  unitrigger_stub.origin = target_struct.origin;
1066  unitrigger_stub.angles = target_struct.angles;
1067 
1068  wallModel.origin = target_struct.origin;
1069  wallModel.angles = target_struct.angles;
1070 
1071  mins = undefined;
1072  maxs = undefined;
1073  absMins = undefined;
1074  absMaxs = undefined;
1075 
1076  wallModel setModel( model );
1077 
1078  wallModel UseWeaponHideTags( weapon );
1079 
1080  mins = wallModel GetMins();
1081  maxs = wallModel GetMaxs();
1082 
1083  absMins = wallModel GetAbsMins();
1084  absMaxs = wallModel GetAbsMaxs();
1085 
1086  bounds = absMaxs - absMins;
1087 
1088  unitrigger_stub.script_length = bounds[0] * 0.25;
1089  unitrigger_stub.script_width = bounds[1];
1090  unitrigger_stub.script_height = bounds[2];
1091 
1092  unitrigger_stub.origin -= (AnglesToRight( unitrigger_stub.angles) * (unitrigger_stub.script_length * 0.4));
1093 
1094  unitrigger_stub.target = spawned_wallbuy.target;
1095  unitrigger_stub.targetname = "weapon_upgrade";
1096 
1097  unitrigger_stub.cursor_hint = "HINT_NOICON";
1098 
1099  unitrigger_stub.first_time_triggered = !pristine;
1100  if ( !weapon.isMeleeWeapon )
1101  {
1102  if ( pristine || ‪zm_utility::is_placeable_mine( weapon ) )
1103  {
1104  unitrigger_stub.hint_string = ‪get_weapon_hint( weapon );
1105  }
1106  else
1107  {
1108  unitrigger_stub.hint_string = ‪get_weapon_hint_ammo();
1109  }
1110  unitrigger_stub.cost = ‪get_weapon_cost( weapon );
1111  if (!‪IS_TRUE( level.weapon_cost_client_filled ))
1112  {
1113  unitrigger_stub.hint_parm1 = unitrigger_stub.cost;
1114  }
1115  }
1116 
1117  unitrigger_stub.weapon = weapon;
1118  unitrigger_stub.weapon_upgrade = weapon;
1119 
1120  unitrigger_stub.script_unitrigger_type = "unitrigger_box_use";
1121  unitrigger_stub.require_look_at = true;
1122  unitrigger_stub.clientFieldName = clientFieldName;
1124 
1125  if ( weapon.isMeleeWeapon )
1126  {
1127  if ( weapon == "tazer_knuckles" && IsDefined(level.taser_trig_adjustment ) )
1128  {
1129  unitrigger_stub.origin = unitrigger_stub.origin + level.taser_trig_adjustment;
1130  }
1131 
1132  ‪zm_melee_weapon::add_stub( unitrigger_stub, weapon );
1134  }
1135  else
1136  {
1137  unitrigger_stub.prompt_and_visibility_func = &‪wall_weapon_update_prompt;
1139  }
1140 
1141  spawned_wallbuy.trigger_stub = unitrigger_stub;
1142 
1143  // see if this is a known weapon for dynamic wallbuys
1144  weaponidx = undefined;
1145  if ( isdefined( level.buildable_wallbuy_weapons ) )
1146  {
1147  for ( i = 0; i < level.buildable_wallbuy_weapons.size; i++ )
1148  {
1149  if ( weapon == level.buildable_wallbuy_weapons[i] )
1150  {
1151  weaponidx = i;
1152  break;
1153  }
1154  }
1155  }
1156 
1157  if ( isdefined( weaponidx ) )
1158  {
1159  level ‪clientfield::set( clientFieldName + "_idx", weaponidx + 1 );
1160  wallModel delete();
1161  if ( !pristine )
1162  {
1163  level ‪clientfield::set( clientFieldName, 1 );
1164  }
1165 
1166  }
1167  else
1168  {
1169  // unknown weapon - should probably be an error
1170  level ‪clientfield::set( clientFieldName, 1 );
1171  wallModel show();
1172  }
1173 }
1174 
1175 
1177 {
1178  weapon = self.stub.weapon;
1179 
1180  // Allow people to get ammo off the wall for upgraded weapons
1181  player_has_weapon = player ‪has_weapon_or_upgrade( weapon );
1182 
1183  // Check for shared ammo weapon
1184  if ( !player_has_weapon && ‪IS_TRUE( level.weapons_using_ammo_sharing ) )
1185  {
1186  shared_ammo_weapon = player ‪get_shared_ammo_weapon( self.zombie_weapon_upgrade );
1187  if ( IsDefined( shared_ammo_weapon ) )
1188  {
1189  weapon = shared_ammo_weapon;
1190  player_has_weapon = true;
1191  }
1192  }
1193 
1194  if ( IsDefined(level.func_override_wallbuy_prompt) )
1195  {
1196  if ( !self [[level.func_override_wallbuy_prompt]]( player ) ) //can set hint text, disallows use of trigger if returns false
1197  {
1198  return false;
1199  }
1200  }
1201 
1202  if ( !player_has_weapon )
1203  {
1204  self.stub.cursor_hint = "HINT_WEAPON";
1205  cost = ‪get_weapon_cost( weapon );
1206  if ( ‪IS_TRUE( level.weapon_cost_client_filled ) )
1207  {
1208  if ( player ‪bgb::is_enabled( "zm_bgb_secret_shopper" ) && !‪is_wonder_weapon( player.currentweapon ) && ( player.currentweapon.type !== "melee" ) )
1209  {
1210  self.stub.hint_string = &"ZOMBIE_WEAPONCOSTONLY_CFILL_BGB_SECRET_SHOPPER";
1211  self SetHintString( self.stub.hint_string );
1212  }
1213  else
1214  {
1215  self.stub.hint_string = &"ZOMBIE_WEAPONCOSTONLY_CFILL";
1216  self SetHintString( self.stub.hint_string);
1217  }
1218  }
1219  else
1220  {
1221  if ( player ‪bgb::is_enabled( "zm_bgb_secret_shopper" ) && !‪is_wonder_weapon( player.currentweapon ) && ( player.currentweapon.type !== "melee" ) )
1222  {
1223  self.stub.hint_string = &"ZOMBIE_WEAPONCOSTONLYFILL_BGB_SECRET_SHOPPER";
1224  n_bgb_cost = player ‪get_ammo_cost_for_weapon( player.currentweapon );
1225  self SetHintString( self.stub.hint_string, cost, n_bgb_cost );
1226  }
1227  else
1228  {
1229  self.stub.hint_string = &"ZOMBIE_WEAPONCOSTONLYFILL";
1230  self SetHintString( self.stub.hint_string, cost);
1231  }
1232  }
1233  }
1234  else
1235  {
1236  if ( player ‪bgb::is_enabled( "zm_bgb_secret_shopper" ) && !‪is_wonder_weapon( player.currentweapon ) && ( player.currentweapon.type !== "melee" ) )
1237  {
1238  ammo_cost = player ‪get_ammo_cost_for_weapon( weapon );
1239  }
1240  else if ( player ‪has_upgrade( weapon ) && self.stub.hacked !== true )
1241  {
1242  ammo_cost = ‪get_upgraded_ammo_cost( weapon );
1243  }
1244  else
1245  {
1246  ammo_cost = ‪get_ammo_cost( weapon );
1247  }
1248 
1249  if ( ‪IS_TRUE( level.weapon_cost_client_filled ) )
1250  {
1251  if ( player ‪bgb::is_enabled( "zm_bgb_secret_shopper" ) && !‪is_wonder_weapon( player.currentweapon ) && ( player.currentweapon.type !== "melee" ) )
1252  {
1253  if ( ‪IS_TRUE( self.stub.hacked ) )
1254  self.stub.hint_string = &"ZOMBIE_WEAPONAMMOHACKED_CFILL_BGB_SECRET_SHOPPER";
1255  else
1256  self.stub.hint_string = &"ZOMBIE_WEAPONAMMOONLY_CFILL_BGB_SECRET_SHOPPER";
1257  self SetHintString( self.stub.hint_string );
1258  }
1259  else
1260  {
1261  if ( ‪IS_TRUE( self.stub.hacked ) )
1262  self.stub.hint_string = &"ZOMBIE_WEAPONAMMOHACKED_CFILL";
1263  else
1264  self.stub.hint_string = &"ZOMBIE_WEAPONAMMOONLY_CFILL";
1265  self SetHintString( self.stub.hint_string );
1266  }
1267  }
1268  else
1269  {
1270  if ( player ‪bgb::is_enabled( "zm_bgb_secret_shopper" ) && !‪is_wonder_weapon( player.currentweapon ) && ( player.currentweapon.type !== "melee" ) )
1271  {
1272  self.stub.hint_string = &"ZOMBIE_WEAPONAMMOONLY_BGB_SECRET_SHOPPER";
1273  n_bgb_cost = player ‪get_ammo_cost_for_weapon( player.currentweapon );
1274  self SetHintString( self.stub.hint_string, ammo_cost, n_bgb_cost );
1275  }
1276  else
1277  {
1278  self.stub.hint_string = &"ZOMBIE_WEAPONAMMOONLY"; //get_weapon_hint_ammo();
1279  self SetHintString( self.stub.hint_string, ammo_cost );
1280  }
1281  }
1282  }
1283 
1284  self.stub.cursor_hint = "HINT_WEAPON";
1285  self.stub.cursor_hint_weapon = weapon;
1286  self setCursorHint( self.stub.cursor_hint, self.stub.cursor_hint_weapon );
1287 
1288  return true;
1289 }
1290 
1291 
1293 {
1294  if ( ‪IS_TRUE( self.first_time_triggered ) )
1295  {
1296  self.first_time_triggered = false;
1297 
1298  if ( isdefined( self.clientFieldName ) )
1299  {
1300  level ‪clientfield::set( self.clientFieldName, 0 );
1301  }
1302 
1303  if ( ‪set_hint_string )
1304  {
1305  hint_string = ‪get_weapon_hint( self.weapon );
1306  cost = ‪get_weapon_cost( self.weapon );
1307 
1308  if ( ‪IS_TRUE( level.weapon_cost_client_filled ) )
1309  {
1310  self SetHintString( hint_string );
1311  }
1312  else
1313  {
1314  self SetHintString( hint_string, cost );
1315  }
1316  }
1317  }
1318 }
1319 
1321 {
1322  weapon_spawns = [];
1323  weapon_spawns = GetEntArray( "weapon_upgrade", "targetname");
1324 
1325  melee_and_grenade_spawns = [];
1326  melee_and_grenade_spawns = GetEntArray( "bowie_upgrade", "targetname" );
1327  melee_and_grenade_spawns = ArrayCombine( melee_and_grenade_spawns, GetEntArray( "sickle_upgrade", "targetname" ), true, false );
1328  melee_and_grenade_spawns = ArrayCombine( melee_and_grenade_spawns, GetEntArray( "tazer_upgrade", "targetname" ), true, false );
1329 
1330  if ( !‪IS_TRUE( level.headshots_only ) )
1331  {
1332  melee_and_grenade_spawns = ArrayCombine( melee_and_grenade_spawns, GetEntArray( "claymore_purchase", "targetname" ), true, false );
1333  }
1334 
1335  for ( i = 0; i < weapon_spawns.size; i++ )
1336  {
1337  weapon_spawns[i].weapon = GetWeapon( weapon_spawns[i].zombie_weapon_upgrade );
1338  weapon_spawns[i] ‪reset_wallbuy_internal( true );
1339  }
1340 
1341  for ( i = 0; i < melee_and_grenade_spawns.size; i++ )
1342  {
1343  melee_and_grenade_spawns[i].weapon = GetWeapon( melee_and_grenade_spawns[i].zombie_weapon_upgrade );
1344  melee_and_grenade_spawns[i] ‪reset_wallbuy_internal( false );
1345  }
1346 
1347  if ( isdefined( level._unitriggers ) )
1348  {
1349  candidates = [];
1350  for ( i = 0; i < level._unitriggers.trigger_stubs.size; i++ )
1351  {
1352  stub = level._unitriggers.trigger_stubs[i];
1353 
1354  tn = stub.targetname;
1355 
1356  if ( tn == "weapon_upgrade" || tn == "bowie_upgrade" || tn == "sickle_upgrade" || tn == "tazer_upgrade" || tn == "claymore_purchase" )
1357  {
1358  stub.first_time_triggered = false;
1359 
1360  if ( isdefined( stub.clientFieldName ) )
1361  {
1362  level ‪clientfield::set( stub.clientFieldName, 0 );
1363  }
1364 
1365  if ( tn == "weapon_upgrade" )
1366  {
1367  stub.hint_string = ‪get_weapon_hint( stub.weapon );
1368  stub.cost = ‪get_weapon_cost( stub.weapon );
1369  if (!‪IS_TRUE( level.weapon_cost_client_filled ))
1370  {
1371  stub.hint_parm1 = stub.cost;
1372  }
1373  }
1374  }
1375  }
1376  }
1377 }
1378 
1379 // For buying weapon upgrades in the environment
1381 {
1383 
1384  weapon_spawns = [];
1385  weapon_spawns = GetEntArray( "weapon_upgrade", "targetname" );
1386 
1387  for ( i = 0; i < weapon_spawns.size; i++ )
1388  {
1389  weapon_spawns[i].weapon = GetWeapon( weapon_spawns[i].zombie_weapon_upgrade );
1390 
1391  hint_string = ‪get_weapon_hint( weapon_spawns[i].weapon );
1392  cost = ‪get_weapon_cost( weapon_spawns[i].weapon );
1393 
1394  if ( ‪IS_TRUE( level.weapon_cost_client_filled ) )
1395  {
1396  weapon_spawns[i] SetHintString( hint_string );
1397  }
1398  else
1399  {
1400  weapon_spawns[i] SetHintString( hint_string, cost );
1401  }
1402  weapon_spawns[i] setCursorHint( "HINT_NOICON" );
1403 
1404  weapon_spawns[i] UseTriggerRequireLookAt();
1405 
1406  weapon_spawns[i] thread ‪weapon_spawn_think();
1407  model = getent( weapon_spawns[i].target, "targetname" );
1408  if ( isdefined( model ) )
1409  {
1410  model UseWeaponHideTags( weapon_spawns[i].weapon );
1411  model hide();
1412  }
1413  }
1414 }
1415 
1416 // returns the trigger hint string for the given weapon
1417 function ‪get_weapon_hint( weapon )
1418 {
1419  assert( IsDefined( level.zombie_weapons[weapon] ), weapon.name + " was not included or is not part of the zombie weapon list." );
1420 
1421  return level.zombie_weapons[weapon].hint;
1422 }
1423 
1424 function ‪get_weapon_cost( weapon )
1425 {
1426  assert( IsDefined( level.zombie_weapons[weapon] ), weapon.name + " was not included or is not part of the zombie weapon list." );
1427 
1428  return level.zombie_weapons[weapon].cost;
1429 }
1430 
1431 function ‪get_ammo_cost( weapon )
1432 {
1433  assert( IsDefined( level.zombie_weapons[weapon] ), weapon.name + " was not included or is not part of the zombie weapon list." );
1434 
1435  return level.zombie_weapons[weapon].ammo_cost;
1436 }
1437 
1438 function ‪get_upgraded_ammo_cost( weapon )
1439 {
1440  assert( IsDefined( level.zombie_weapons[weapon] ), weapon.name + " was not included or is not part of the zombie weapon list." );
1441 
1442  if (IsDefined(level.zombie_weapons[weapon].upgraded_ammo_cost))
1443  return level.zombie_weapons[weapon].upgraded_ammo_cost;
1444 
1445  return N_UPGRADED_WEAPON_AMMO_COST;
1446 }
1447 
1448 function ‪get_ammo_cost_for_weapon( w_current, n_base_non_wallbuy_cost, n_upgraded_non_wallbuy_cost )//self = player
1449 {
1450  //Default these here so we can keep secret shopper vars in one place
1451  ‪DEFAULT( n_base_non_wallbuy_cost, 750 );
1452  ‪DEFAULT( n_upgraded_non_wallbuy_cost, 5000 );
1453  const N_WALLBUY_UPGRADE_COST = 4000;
1454 
1455  w_root = w_current.rootweapon;
1456  if ( ‪is_weapon_upgraded( w_root ) )
1457  {
1458  w_root = ‪get_base_weapon( w_root );
1459  }
1460 
1461  if ( self ‪has_upgrade( w_root ) )
1462  {
1463  if ( ‪is_wallbuy( w_root ) )
1464  {
1465  n_ammo_cost = N_WALLBUY_UPGRADE_COST;
1466  }
1467  else
1468  {
1469  n_ammo_cost = n_upgraded_non_wallbuy_cost;
1470  }
1471  }
1472  else
1473  {
1474  if ( ‪is_wallbuy( w_root ) )
1475  {
1476  n_ammo_cost = ‪get_ammo_cost( w_root );
1477  n_ammo_cost = ‪zm_utility::halve_score( n_ammo_cost );
1478  }
1479  else
1480  {
1481  n_ammo_cost = n_base_non_wallbuy_cost;
1482  }
1483  }
1484 
1485  return n_ammo_cost;
1486 }
1487 
1488 function ‪get_is_in_box( weapon )
1489 {
1490  assert( IsDefined( level.zombie_weapons[weapon] ), weapon.name + " was not included or is not part of the zombie weapon list." );
1491 
1492  return level.zombie_weapons[weapon].is_in_box;
1493 }
1494 
1495 function ‪get_force_attachments( weapon )
1496 {
1497  assert( IsDefined( level.zombie_weapons[weapon] ), weapon.name + " was not included or is not part of the zombie weapon list." );
1498 
1499  return level.zombie_weapons[weapon].force_attachments;
1500 }
1501 
1503 {
1504  weapon = ‪get_base_weapon( weapon );
1505  attachment = level.zombie_weapons[weapon].default_attachment;
1506 
1507  return isdefined( attachment );
1508 }
1509 
1510 function ‪default_attachment( weapon )
1511 {
1512  weapon = ‪get_base_weapon( weapon );
1513  attachment = level.zombie_weapons[weapon].default_attachment;
1514 
1515  if ( isdefined( attachment ) )
1516  {
1517  return attachment;
1518  }
1519  else
1520  {
1521  return "none";
1522  }
1523 }
1524 
1525 
1527 {
1528  weapon = ‪get_base_weapon( weapon );
1529  attachments = level.zombie_weapons[weapon].addon_attachments;
1530 
1531  return (isdefined( attachments ) && attachments.size > 1);
1532 }
1533 
1534 function ‪random_attachment( weapon, exclude )
1535 {
1536  lo = 0;
1537  if ( isdefined( level.zombie_weapons[weapon].addon_attachments ) && level.zombie_weapons[weapon].addon_attachments.size > 0 )
1538  {
1539  attachments = level.zombie_weapons[weapon].addon_attachments;
1540  }
1541  else
1542  {
1543  attachments = weapon.supportedAttachments;
1544  lo = 1;
1545  }
1546 
1547  minatt = lo;
1548  if ( isdefined( exclude ) && exclude != "none" )
1549  {
1550  minatt = lo + 1;
1551  }
1552 
1553  if ( attachments.size > minatt )
1554  {
1555  while ( 1 )
1556  {
1557  idx = randomint( attachments.size - lo ) + lo;
1558  if ( !isdefined( exclude ) || attachments[idx] != exclude )
1559  {
1560  return attachments[idx];
1561  }
1562  }
1563  }
1564 
1565  return "none";
1566 }
1567 
1568 function ‪get_attachment_index( weapon )
1569 {
1570  attachments = weapon.attachments;
1571  if ( !attachments.size )
1572  {
1573  return -1;
1574  }
1575 
1576  weapon = ‪get_nonalternate_weapon( weapon );
1577 
1578  base = weapon.rootWeapon;
1579  if ( attachments[0] == level.zombie_weapons[base].default_attachment )
1580  {
1581  return 0;
1582  }
1583 
1584  if ( isdefined( level.zombie_weapons[base].addon_attachments ) )
1585  {
1586  for ( i = 0; i < level.zombie_weapons[base].addon_attachments.size; i++ )
1587  {
1588  if ( level.zombie_weapons[base].addon_attachments[i] == attachments[0] )
1589  {
1590  return i + 1;
1591  }
1592  }
1593  }
1594 
1595 
1596  return -1;
1597 }
1598 
1599 function ‪weapon_supports_this_attachment( weapon, att )
1600 {
1601  weapon = ‪get_nonalternate_weapon( weapon );
1602 
1603  base = weapon.rootWeapon;
1604  if ( att == level.zombie_weapons[base].default_attachment )
1605  {
1606  return true;
1607  }
1608 
1609  if ( isdefined( level.zombie_weapons[base].addon_attachments ) )
1610  {
1611  for ( i = 0; i < level.zombie_weapons[base].addon_attachments.size; i++ )
1612  {
1613  if ( level.zombie_weapons[base].addon_attachments[i] == att )
1614  {
1615  return true;
1616  }
1617  }
1618  }
1619 
1620  return false;
1621 }
1622 
1623 
1624 function ‪get_base_weapon( upgradedweapon )
1625 {
1626  upgradedweapon = ‪get_nonalternate_weapon( upgradedweapon );
1627 
1628  upgradedweapon = upgradedweapon.rootWeapon;
1629 
1630  if ( IsDefined( level.zombie_weapons_upgraded[upgradedweapon] ) )
1631  {
1632  return level.zombie_weapons_upgraded[upgradedweapon];
1633  }
1634 
1635  return upgradedweapon;
1636 }
1637 
1638 // Check to see if this is an upgraded version of another weapon
1639 function ‪get_upgrade_weapon( weapon, add_attachment )
1640 {
1641  weapon = ‪get_nonalternate_weapon( weapon );
1642 
1643  rootWeapon = weapon.rootWeapon;
1644  newWeapon = rootWeapon;
1645  baseWeapon = ‪get_base_weapon( weapon );
1646 
1647  if ( !‪is_weapon_upgraded( rootWeapon ) )
1648  {
1649  newWeapon = level.zombie_weapons[rootWeapon].upgrade;
1650  }
1651 
1652  if ( ‪IS_TRUE( add_attachment ) && ‪zm_pap_util::can_swap_attachments() )
1653  {
1654  oldatt = "none";
1655  if ( weapon.attachments.size )
1656  {
1657  oldatt = weapon.attachments[0];
1658  }
1659  att = ‪random_attachment( baseWeapon, oldatt );
1660  newWeapon = GetWeapon( newWeapon.name, att );
1661  }
1662  else
1663  {
1664  if ( isdefined( level.zombie_weapons[rootWeapon] ) && isdefined( level.zombie_weapons[rootWeapon].default_attachment ) )
1665  {
1666  att = level.zombie_weapons[rootWeapon].default_attachment;
1667  newWeapon = GetWeapon( newWeapon.name, att );
1668  }
1669  }
1670 
1671  return newWeapon;
1672 }
1673 
1674 // Check to see if this is an upgraded version of another weapon
1675 function ‪can_upgrade_weapon( weapon )
1676 {
1677  if ( weapon == level.weaponNone || weapon == level.weaponZMFists || !‪is_weapon_included( weapon ) )
1678  {
1679  return false;
1680  }
1681 
1682  weapon = ‪get_nonalternate_weapon( weapon );
1683 
1684  rootWeapon = weapon.rootWeapon;
1685 
1686  if ( !‪is_weapon_upgraded( rootWeapon ) )
1687  {
1688  return IsDefined( level.zombie_weapons[rootWeapon].upgrade );
1689  }
1690 
1692  {
1693  return true;
1694  }
1695 
1696  return false;
1697 }
1698 
1699 // Check to see if weapon can be equipped with an AAT
1700 function ‪weapon_supports_aat( weapon )
1701 {
1702  if ( weapon == level.weaponNone || weapon == level.weaponZMFists )
1703  {
1704  return false;
1705  }
1706 
1707  weaponToPack = ‪get_nonalternate_weapon( weapon );
1708 
1709  rootWeapon = weaponToPack.rootWeapon;
1710 
1711  if ( !‪is_weapon_upgraded( rootWeapon ) )
1712  {
1713  return false;
1714  }
1715 
1716  if ( !‪aat::is_exempt_weapon( weaponToPack ) )
1717  {
1718  return true;
1719  }
1720 
1721  return false;
1722 }
1723 
1724 // Check to see if this is an upgraded version of another weapon
1725 function ‪is_weapon_upgraded( weapon )
1726 {
1727  if ( weapon == level.weaponNone || weapon == level.weaponZMFists )
1728  {
1729  return false;
1730  }
1731 
1732  weapon = ‪get_nonalternate_weapon( weapon );
1733 
1734  rootWeapon = weapon.rootWeapon;
1735 
1736  if ( IsDefined( level.zombie_weapons_upgraded[rootWeapon] ) )
1737  {
1738  return true;
1739  }
1740 
1741  return false;
1742 }
1743 
1745 {
1746  weapon = ‪get_nonalternate_weapon( weapon );
1747 
1748  if ( self HasWeapon( weapon.rootWeapon, true ) )
1749  {
1750  upgraded = ‪is_weapon_upgraded( weapon );
1751 
1752  if ( ‪is_weapon_included( weapon ) )
1753  {
1754  force_attachments = ‪get_force_attachments( weapon.rootWeapon );
1755  }
1756 
1757  if ( IsDefined( force_attachments ) && force_attachments.size )
1758  {
1759  if ( upgraded )
1760  {
1761  packed_attachments = [];
1762  packed_attachments[packed_attachments.size] = "extclip";
1763  packed_attachments[packed_attachments.size] = "fmj";
1764  force_attachments = ArrayCombine( force_attachments, packed_attachments, false, false );
1765  }
1766 
1767  return GetWeapon( weapon.rootWeapon.name, force_attachments );
1768  }
1769  else
1770  {
1771  return self GetBuildKitWeapon( weapon.rootWeapon, upgraded );
1772  }
1773  }
1774 
1775  return undefined;
1776 }
1777 
1778 // Checks if proper weapon, regardless of attachments
1779 // self is a player
1781 {
1782  if ( self HasWeapon( weapon, true ) )
1783  {
1784  return true;
1785  }
1786 
1788  {
1789  rootWeapon = weapon.rootWeapon;
1790  weapons = self GetWeaponsList( true );
1791  foreach ( w in weapons )
1792  {
1793  if ( rootWeapon == w.rootWeapon )
1794  {
1795  return true;
1796  }
1797  }
1798  }
1799 
1800  return false;
1801 }
1802 
1803 
1804 // Check to see if the player has the upgraded version of the weapon
1805 // self is a player
1806 function ‪has_upgrade( weapon )
1807 {
1808  weapon = ‪get_nonalternate_weapon( weapon );
1809 
1810  rootWeapon = weapon.rootWeapon;
1811 
1812  ‪has_upgrade = false;
1813  if ( IsDefined( level.zombie_weapons[rootWeapon ] ) && IsDefined( level.zombie_weapons[rootWeapon ].upgrade ) )
1814  {
1815  ‪has_upgrade = self ‪has_weapon_or_attachments( level.zombie_weapons[rootWeapon].upgrade );
1816  }
1817 
1818  // double check for the bowie variant on the ballistic knife
1819  if ( !‪has_upgrade && rootWeapon.isBallisticKnife )
1820  {
1822  }
1823 
1824  return ‪has_upgrade;
1825 }
1826 
1827 
1828 // Check to see if the player has the normal or upgraded weapon
1829 // self is a player
1830 function ‪has_weapon_or_upgrade( weapon )
1831 {
1832  weapon = ‪get_nonalternate_weapon( weapon );
1833 
1834  rootWeapon = weapon.rootWeapon;
1835 
1836  upgradedweaponname = rootWeapon;
1837  if ( IsDefined( level.zombie_weapons[rootWeapon] ) && IsDefined( level.zombie_weapons[rootWeapon].upgrade ) )
1838  {
1839  upgradedweaponname = level.zombie_weapons[rootWeapon].upgrade;
1840  }
1841 
1842  has_weapon = false;
1843  // If the weapon you're checking doesn't exist, it will return undefined
1844  if ( IsDefined( level.zombie_weapons[rootWeapon] ) )
1845  {
1846  has_weapon = self ‪has_weapon_or_attachments( rootWeapon ) || self ‪has_upgrade( rootWeapon );
1847  }
1848 
1849  // double check for the bowie variant on the ballistic knife
1850  if ( !has_weapon && level.weaponBallisticKnife == rootWeapon )
1851  {
1852  has_weapon = self ‪zm_melee_weapon::has_any_ballistic_knife();
1853  }
1854 
1855  if ( !has_weapon && ‪zm_equipment::is_equipment( rootWeapon ) )
1856  {
1857  has_weapon = self ‪zm_equipment::is_active( rootWeapon );
1858  }
1859 
1860  return has_weapon;
1861 }
1862 
1863 
1864 // A "shared" ammo weapon will allow you to buy ammo off the wall of another weapon
1865 function ‪add_shared_ammo_weapon( weapon, base_weapon )
1866 {
1867  level.zombie_weapons[ weapon ].shared_ammo_weapon = base_weapon;
1868 }
1869 
1870 
1871 // Check if the player has a weapon that can "share" ammo with base_weapon
1872 // If so, return that weapon.
1873 // self is a player
1874 function ‪get_shared_ammo_weapon( weapon )
1875 {
1876  weapon = ‪get_nonalternate_weapon( weapon );
1877 
1878  rootWeapon = weapon.rootWeapon;
1879  weapons = self GetWeaponsList( true );
1880  foreach ( w in weapons )
1881  {
1882  w = w.rootWeapon;
1883 
1884  // If the weapon isn't in the zombie_weapons list, check to see if it's
1885  // in the upgraded weapons list. If it is, it will provide the
1886  // non-upgraded name for us.
1887  if ( !IsDefined( level.zombie_weapons[w] ) && IsDefined( level.zombie_weapons_upgraded[w] ) )
1888  {
1889  // check for an upgraded weapon
1890  w = level.zombie_weapons_upgraded[w];
1891  }
1892 
1893  if ( IsDefined( level.zombie_weapons[w] ) &&
1894  IsDefined( level.zombie_weapons[w].shared_ammo_weapon ) &&
1895  level.zombie_weapons[w].shared_ammo_weapon == rootWeapon )
1896  {
1897  return w;
1898  }
1899  }
1900 
1901  return undefined;
1902 }
1903 
1904 
1905 //
1906 // For most weapons if a player has any variety of the given weapon whether upgraded, or downgraded or with attachments added or whatever
1907 // this should find it
1908 //
1909 // This will not find different flavors of ballistic knives
1910 //
1912 {
1913  weapon = ‪get_nonalternate_weapon( weapon );
1914 
1915  rootWeapon = weapon.rootWeapon;
1916 
1917  retweapon = self ‪get_weapon_with_attachments( rootWeapon );
1918  if ( !isdefined( retweapon ) )
1919  {
1920  if ( isdefined( level.zombie_weapons[rootWeapon] ) )
1921  {
1922  if ( IsDefined(level.zombie_weapons[rootWeapon].upgrade) )
1923  {
1924  retweapon = self ‪get_weapon_with_attachments( level.zombie_weapons[rootWeapon].upgrade );
1925  }
1926  }
1927  else if ( IsDefined( level.zombie_weapons_upgraded[rootWeapon] ) )
1928  {
1929  retweapon = self ‪get_weapon_with_attachments( level.zombie_weapons_upgraded[rootWeapon] );
1930  }
1931  }
1932 
1933  return retweapon;
1934 }
1935 
1937 {
1938  if ( !‪IS_TRUE( level.obsolete_prompt_format_needed ) )
1939  {
1940  if ( ‪IS_TRUE( level.weapon_cost_client_filled ) )
1941  {
1942  return &"ZOMBIE_WEAPONCOSTONLY_CFILL";
1943  }
1944  else
1945  {
1946  return &"ZOMBIE_WEAPONCOSTONLYFILL";
1947  }
1948  }
1949  else
1950  // I'm 99% sure this branch is obsolete and should be removed
1951  {
1952  if ( isDefined( level.has_pack_a_punch ) && !level.has_pack_a_punch )
1953  {
1954  return &"ZOMBIE_WEAPONCOSTAMMO";
1955  }
1956  else
1957  {
1958  return &"ZOMBIE_WEAPONCOSTAMMO_UPGRADE";
1959  }
1960  }
1961 }
1962 
1963 
1964 function ‪weapon_set_first_time_hint( cost, ammo_cost )
1965 {
1966  if ( !‪IS_TRUE( level.obsolete_prompt_format_needed ) )
1967  {
1968  if ( ‪IS_TRUE( level.weapon_cost_client_filled ) )
1969  {
1970  self SetHintString( ‪get_weapon_hint_ammo() );
1971  }
1972  else
1973  {
1974  self SetHintString( ‪get_weapon_hint_ammo(), cost, ammo_cost );
1975  }
1976  }
1977  else
1978  {
1979  self SetHintString( ‪get_weapon_hint_ammo(), cost, ammo_cost );
1980  }
1981 
1982 }
1983 
1985 {
1986  if ( isdefined( w_weapon) && w_weapon == self ‪zm_utility::get_player_placeable_mine() )
1987  {
1988  return false;
1989  }
1990 
1991  return true;
1992 }
1993 
1995 {
1996  cost = ‪get_weapon_cost( self.weapon );
1997  ammo_cost = ‪get_ammo_cost( self.weapon );
1998  ‪is_grenade = self.weapon.isGrenadeWeapon;
1999  shared_ammo_weapon = undefined;
2000 
2001  if ( isdefined( self.parent_player ) && !‪is_grenade )
2002  {
2003  self.parent_player notify( "zm_bgb_secret_shopper", self );
2004  }
2005 
2006  second_endon = undefined;
2007 
2008  if ( isdefined( self.stub ) )
2009  {
2010  second_endon = "kill_trigger";
2011  self.first_time_triggered = self.stub.first_time_triggered;
2012  }
2013 
2014  onlyplayer = undefined;
2015  can_buy_weapon_extra_check_func = undefined;
2016  if ( IsDefined( self.stub ) && ‪IS_TRUE( self.stub.trigger_per_player ) )
2017  {
2018  onlyplayer = self.parent_player;
2019  if ( ‪zm_utility::is_placeable_mine( self.weapon ) )
2020  {
2021  can_buy_weapon_extra_check_func = &‪placeable_mine_can_buy_weapon_extra_check_func;
2022  }
2023  }
2024  self thread ‪zm_magicbox::decide_hide_show_hint( "stop_hint_logic", second_endon, onlyplayer, can_buy_weapon_extra_check_func );
2025 
2026  // we may want this instead
2027  // if( zm_utility::is_offhand_weapon( self.zombie_weapon_upgrade ) )
2028  if ( ‪is_grenade || ‪zm_utility::is_melee_weapon( self.weapon ) )
2029  {
2030  self.first_time_triggered = false;
2031  hint = ‪get_weapon_hint( self.weapon );
2032  if ( ‪IS_TRUE( level.weapon_cost_client_filled ) )
2033  {
2034  self SetHintString( hint );
2035  }
2036  else
2037  {
2038  self SetHintString( hint, cost );
2039  }
2040 
2041  cursor_hint = "HINT_WEAPON";
2042  cursor_hint_weapon = self.weapon;
2043  self setCursorHint( cursor_hint, cursor_hint_weapon );
2044  }
2045  else if ( !isdefined( self.first_time_triggered ) )
2046  {
2047  self.first_time_triggered = false;
2048  if ( isdefined( self.stub ) )
2049  {
2050  self.stub.first_time_triggered = false;
2051  }
2052  }
2053 
2054  for ( ;; )
2055  {
2056  self waittill( "trigger", player );
2057  // if not first time and they have the weapon give ammo
2058 
2059  if ( !‪zm_utility::is_player_valid( player ) )
2060  {
2061  player thread ‪zm_utility::ignore_triggers( 0.5 );
2062  continue;
2063  }
2064 
2065  if ( !player ‪zm_magicbox::can_buy_weapon() )
2066  {
2067  wait( 0.1 );
2068  continue;
2069  }
2070 
2071  if ( isdefined( self.stub ) && ‪IS_TRUE( self.stub.require_look_from ) )
2072  {
2073  toplayer = player ‪util::get_eye() - self.origin;
2074  forward = -1 * AnglesToRight( self.angles );
2075  dot = VectorDot( toplayer,forward );
2076  if ( dot < 0 )
2077  {
2078  continue;
2079  }
2080  }
2081 
2082 
2083  if ( player ‪zm_utility::has_powerup_weapon() )
2084  {
2085  wait( 0.1 );
2086  continue;
2087  }
2088 
2089  // Allow people to get ammo off the wall for upgraded weapons
2090  player_has_weapon = player ‪has_weapon_or_upgrade( self.weapon );
2091 
2092  // Check for shared ammo weapon
2093  if ( !player_has_weapon && ‪IS_TRUE( level.weapons_using_ammo_sharing ) )
2094  {
2095  shared_ammo_weapon = player ‪get_shared_ammo_weapon( self.weapon );
2096  if ( IsDefined( shared_ammo_weapon ) )
2097  {
2098  player_has_weapon = true;
2099  }
2100  }
2101 
2102  // If the player has the weapon, we may want to overide it with a persistent ability "reward" weapon
2103  if ( ‪IS_TRUE(level.pers_upgrade_nube ) )
2104  {
2105  player_has_weapon = ‪zm_pers_upgrades_functions::pers_nube_should_we_give_raygun( player_has_weapon, player, self.weapon );
2106  }
2107 
2108  cost = ‪get_weapon_cost( self.weapon );
2109  // If the player has the double points persistent upgrade, reduce the "cost" and "ammo cost"
2111  {
2112  cost = int( cost / 2 );
2113  }
2114 
2115  if ( IsDefined(player.check_override_wallbuy_purchase) )
2116  {
2117  if ( player [[player.check_override_wallbuy_purchase]]( self.weapon, self ) )
2118  {
2119  continue;
2120  }
2121  }
2122 
2123  // If the player does not have the weapon
2124  if ( !player_has_weapon )
2125  {
2126  // Else make the weapon show and give it
2127  if ( player ‪zm_score::can_player_purchase( cost ) )
2128  {
2129  if ( self.first_time_triggered == false )
2130  {
2131  self ‪show_all_weapon_buys( player, cost, ammo_cost, ‪is_grenade );
2132  }
2133 
2134  player ‪zm_score::minus_to_player_score( cost );
2135 
2136  level notify( "weapon_bought", player, self.weapon );
2137  player ‪zm_stats::increment_challenge_stat( "SURVIVALIST_BUY_WALLBUY" );
2138 
2139  if ( self.weapon.isriotshield )
2140  {
2141  player ‪zm_equipment::give( self.weapon );
2142  if ( isdefined( player.player_shield_reset_health ) )
2143  {
2144  player [[player.player_shield_reset_health]]();
2145  }
2146  }
2147  else
2148  {
2149  if ( ‪zm_utility::is_lethal_grenade( self.weapon ) )
2150  {
2152  player ‪zm_utility::set_player_lethal_grenade( self.weapon );
2153  }
2154 
2155  weapon = self.weapon;
2156 
2157  // Is the player persistent ability "nube" active?
2158  if ( ‪IS_TRUE( level.pers_upgrade_nube ) )
2159  {
2161  }
2162 
2163  if ( ‪should_upgrade_weapon( player ) )
2164  {
2165  if( player ‪zm_weapons::can_upgrade_weapon( weapon ) )
2166  {
2167  weapon = ‪get_upgrade_weapon( weapon );
2168  player notify( "zm_bgb_wall_power_used" );
2169  }
2170  }
2171 
2172  weapon = player ‪weapon_give( weapon );
2173  if( isdefined(weapon) )
2174  {
2175  player thread ‪aat::remove( weapon );
2176  }
2177  }
2178 
2179  //stat tracking
2180  if( isdefined(weapon) )
2181  {
2182  player ‪zm_stats::increment_client_stat( "wallbuy_weapons_purchased" );
2183  player ‪zm_stats::increment_player_stat( "wallbuy_weapons_purchased" );
2184  weaponIndex = undefined;
2185  if (isDefined(weaponIndex))
2186  {
2187  weaponIndex = MatchRecordGetWeaponIndex(weapon);
2188  }
2189 
2190  if (isDefined(weaponindex))
2191  {
2192  player RecordMapEvent(‪ZM_MAP_EVENT_PURCHASE_GUN, GetTime(), player.origin, level.round_number, weaponIndex, cost);
2193  }
2194  }
2195  }
2196  else
2197  {
2198  ‪zm_utility::play_sound_on_ent( "no_purchase" );
2199  player ‪zm_audio::create_and_play_dialog( "general", "outofmoney" );
2200 
2201  }
2202  }
2203  else // If the player HAS the weapon, check for ammo update
2204  {
2205  weapon = self.weapon;
2206 
2207  if ( IsDefined( shared_ammo_weapon ) )
2208  {
2209  weapon = shared_ammo_weapon;
2210  }
2211 
2212  if ( ‪IS_TRUE( level.pers_upgrade_nube ) )
2213  {
2215  }
2216 
2217  // MM - need to check and see if the player has an upgraded weapon. If so, the ammo cost is much higher
2218  // - hacked wall buys have their costs reversed...
2219  if ( ‪IS_TRUE( self.stub.hacked ) )
2220  {
2221  if ( !player ‪has_upgrade( weapon ) )
2222  {
2223  ammo_cost = N_UPGRADED_WEAPON_AMMO_COST;
2224  }
2225  else
2226  {
2227  ammo_cost = ‪get_ammo_cost( weapon );
2228  }
2229  }
2230  else
2231  {
2232  if ( player ‪has_upgrade( weapon ) )
2233  {
2234  ammo_cost = N_UPGRADED_WEAPON_AMMO_COST;
2235  }
2236  else
2237  {
2238  ammo_cost = ‪get_ammo_cost( weapon );
2239  }
2240  }
2241 
2242  // If we have the "nube" upgrade, we need to set the correct ammo cost if we are buying ammo for the olympia
2243  if ( ‪IS_TRUE( player.pers_upgrades_awarded["nube"] ) )
2244  {
2245  ammo_cost = ‪zm_pers_upgrades_functions::pers_nube_override_ammo_cost( player, self.weapon, ammo_cost );
2246  }
2247 
2248  // If the player has the double points persistent upgrade, reduce the "cost" and "ammo cost"
2250  {
2251  ammo_cost = int( ammo_cost / 2 );
2252  }
2253 
2254  if ( player ‪bgb::is_enabled( "zm_bgb_secret_shopper" ) && !‪zm_weapons::is_wonder_weapon( weapon ) )
2255  {
2256  ammo_cost = player ‪get_ammo_cost_for_weapon( weapon );
2257  }
2258 
2259  if ( weapon.isriotshield )
2260  {
2261  ‪zm_utility::play_sound_on_ent( "no_purchase" );
2262  }
2263  else if ( player ‪zm_score::can_player_purchase( ammo_cost ) ) // if the player does have this then give him ammo.
2264  {
2265  if ( self.first_time_triggered == false )
2266  {
2267  self ‪show_all_weapon_buys( player, cost, ammo_cost, ‪is_grenade );
2268  }
2269 
2270  // Stat tracking
2271  if ( player ‪has_upgrade( weapon ) )
2272  {
2273  player ‪zm_stats::increment_client_stat( "upgraded_ammo_purchased" );
2274  player ‪zm_stats::increment_player_stat( "upgraded_ammo_purchased" );
2275  }
2276  else
2277  {
2278  player ‪zm_stats::increment_client_stat( "ammo_purchased" );
2279  player ‪zm_stats::increment_player_stat( "ammo_purchased" );
2280  }
2281 
2282  if ( player ‪has_upgrade( weapon ) )
2283  {
2284  ammo_given = player ‪ammo_give( level.zombie_weapons[weapon].upgrade );
2285  }
2286  else
2287  {
2288  ammo_given = player ‪ammo_give( weapon );
2289  }
2290 
2291  if ( ammo_given )
2292  {
2293  player ‪zm_score::minus_to_player_score( ammo_cost ); // this give him ammo to early
2294  }
2295  weaponIndex = undefined;
2296  if (isDefined(weapon))
2297  {
2298  weaponIndex = MatchRecordGetWeaponIndex(weapon);
2299  }
2300 
2301  if (isDefined(weaponIndex))
2302  {
2303  player RecordMapEvent(‪ZM_MAP_EVENT_PURCHASE_AMMO, GetTime(), player.origin, level.round_number, weaponIndex, cost);
2304  }
2305  }
2306  else
2307  {
2308  ‪zm_utility::play_sound_on_ent( "no_purchase" );
2309  if ( isDefined( level.custom_generic_deny_vo_func ) )
2310  {
2311  player [[level.custom_generic_deny_vo_func]]();
2312  }
2313  else
2314  {
2315  player ‪zm_audio::create_and_play_dialog( "general", "outofmoney" );
2316  }
2317  }
2318  }
2319 
2320  if ( isdefined( self.stub ) && isdefined( self.stub.prompt_and_visibility_func ) )
2321  {
2322  self [[self.stub.prompt_and_visibility_func]]( player );
2323  }
2324 
2325  }
2326 }
2327 
2328 function ‪should_upgrade_weapon( player )
2329 {
2330  if( isdefined( level.wallbuy_should_upgrade_weapon_override ) )
2331  {
2332  return [[ level.wallbuy_should_upgrade_weapon_override ]]();
2333  }
2334 
2335  if( player ‪bgb::is_enabled( "zm_bgb_wall_power" ) )
2336  {
2337  return true;
2338  }
2339 
2340  return false;
2341 }
2342 
2343 function ‪show_all_weapon_buys( player, cost, ammo_cost, ‪is_grenade )
2344 {
2345  model = getent( self.target, "targetname" );
2346  is_melee = ‪zm_utility::is_melee_weapon( self.weapon );
2347  if ( isdefined( model ) )
2348  {
2349  model thread ‪weapon_show( player );
2350  }
2351  else if ( isdefined( self.clientFieldName ) )
2352  {
2353  level ‪clientfield::set( self.clientFieldName, 1 );
2354  }
2355 
2356  self.first_time_triggered = true;
2357  if ( isdefined( self.stub ) )
2358  {
2359  self.stub.first_time_triggered = true;
2360  }
2361 
2362  if ( !‪is_grenade && !is_melee )
2363  {
2364  self ‪weapon_set_first_time_hint( cost, ammo_cost );
2365  }
2366 
2367  if ( !‪IS_TRUE( level.dont_link_common_wallbuys ) && isdefined( level._spawned_wallbuys) )
2368  {
2369  for ( i = 0; i < level._spawned_wallbuys.size; i++ )
2370  {
2371  wallbuy = level._spawned_wallbuys[i];
2372 
2373  if ( isdefined( self.stub ) && isdefined( wallbuy.trigger_stub ) && ( self.stub.clientFieldName == wallbuy.trigger_stub.clientFieldName ) )
2374  {
2375  continue;
2376  }
2377 
2378  if ( self.weapon == wallbuy.weapon )
2379  {
2380  if ( isdefined( wallbuy.trigger_stub ) && isdefined( wallbuy.trigger_stub.clientFieldName ) )
2381  {
2382  level ‪clientfield::set( wallbuy.trigger_stub.clientFieldName, 1 );
2383  }
2384  else if ( isdefined( wallbuy.target ) )
2385  {
2386  model = getent( wallbuy.target, "targetname" );
2387  if ( isdefined( model ) )
2388  {
2389  model thread ‪weapon_show( player );
2390  }
2391  }
2392 
2393  if ( isdefined( wallbuy.trigger_stub ) )
2394  {
2395  wallbuy.trigger_stub.first_time_triggered = true;
2396 
2397  if ( isdefined( wallbuy.trigger_stub.trigger ) )
2398  {
2399  wallbuy.trigger_stub.trigger.first_time_triggered = true;
2400 
2401  if ( !‪is_grenade && !is_melee )
2402  {
2403  wallbuy.trigger_stub.trigger ‪weapon_set_first_time_hint( cost, ammo_cost );
2404  }
2405  }
2406  }
2407  else
2408  {
2409  if ( !‪is_grenade && !is_melee )
2410  {
2411  wallbuy ‪weapon_set_first_time_hint( cost, ammo_cost );
2412  }
2413  }
2414  }
2415  }
2416  }
2417 }
2418 
2419 function ‪weapon_show( player )
2420 {
2421  player_angles = VectorToAngles( player.origin - self.origin );
2422 
2423  player_yaw = player_angles[1];
2424  weapon_yaw = self.angles[1];
2425 
2426  if ( isdefined( self.script_int ) )
2427  {
2428  weapon_yaw -= self.script_int;
2429  }
2430 
2431  yaw_diff = AngleClamp180( player_yaw - weapon_yaw );
2432 
2433  if ( yaw_diff > 0 )
2434  {
2435  yaw = weapon_yaw - 90;
2436  }
2437  else
2438  {
2439  yaw = weapon_yaw + 90;
2440  }
2441 
2442  self.og_origin = self.origin;
2443  self.origin = self.origin + (AnglesToForward( ( 0, yaw, 0 ) ) * 8);
2444 
2446  self Show();
2447 
2448  ‪zm_utility::play_sound_at_pos( "weapon_show", self.origin, self );
2449 
2450  time = 1;
2451  if ( !isdefined( self._linked_ent ) )
2452  {
2453  self MoveTo( self.og_origin, time );
2454  }
2455 }
2456 
2457 function ‪get_pack_a_punch_camo_index( prev_pap_index )
2458 {
2459  if( isdefined(level.pack_a_punch_camo_index_number_variants) )
2460  {
2461  if( isdefined( prev_pap_index ) )
2462  {
2463  camo_variant = prev_pap_index + 1;
2464  if( camo_variant >= (level.pack_a_punch_camo_index+level.pack_a_punch_camo_index_number_variants) )
2465  {
2466  camo_variant = level.pack_a_punch_camo_index;
2467  }
2468  return camo_variant;
2469  }
2470  else
2471  {
2472  camo_variant = randomIntRange( 0, level.pack_a_punch_camo_index_number_variants );
2473  return level.pack_a_punch_camo_index + camo_variant;
2474  }
2475  }
2476  else
2477  {
2478  return level.pack_a_punch_camo_index;
2479  }
2480 }
2481 
2483 {
2484  if ( !isDefined( self.pack_a_punch_weapon_options ) )
2485  {
2486  self.pack_a_punch_weapon_options = [];
2487  }
2488 
2489  if ( !‪is_weapon_upgraded( weapon ) )
2490  {
2491  return self CalcWeaponOptions( 0, 0, 0, 0, 0 );
2492  }
2493 
2494  if ( isDefined( self.pack_a_punch_weapon_options[weapon] ) )
2495  {
2496  return self.pack_a_punch_weapon_options[weapon];
2497  }
2498 
2499  smiley_face_reticle_index = 1; // smiley face is reserved for the upgraded saritch
2500 
2501  camo_index = ‪get_pack_a_punch_camo_index( undefined );
2502 
2503  lens_index = randomIntRange( 0, 6 );
2504  reticle_index = randomIntRange( 0, 16 );
2505  reticle_color_index = randomIntRange( 0, 6 );
2506  plain_reticle_index = 16;
2507 
2508  use_plain = ( randomint( 10 ) < 1 );
2509 
2510  if ( "saritch_upgraded" == weapon.rootWeapon.name )
2511  {
2512  reticle_index = smiley_face_reticle_index;
2513  }
2514  else if ( use_plain )
2515  {
2516  reticle_index = plain_reticle_index;
2517  }
2518 
2519 
2520  scary_eyes_reticle_index = 8; // weapon_reticle_zom_eyes
2521  purple_reticle_color_index = 3; // 175 0 255
2522  if ( reticle_index == scary_eyes_reticle_index )
2523  {
2524  reticle_color_index = purple_reticle_color_index;
2525  }
2526  letter_a_reticle_index = 2; // weapon_reticle_zom_a
2527  pink_reticle_color_index = 6; // 255 105 180
2528  if ( reticle_index == letter_a_reticle_index )
2529  {
2530  reticle_color_index = pink_reticle_color_index;
2531  }
2532  letter_e_reticle_index = 7; // weapon_reticle_zom_e
2533  green_reticle_color_index = 1; // 0 255 0
2534  if ( reticle_index == letter_e_reticle_index )
2535  {
2536  reticle_color_index = green_reticle_color_index;
2537  }
2538 
2539  self.pack_a_punch_weapon_options[weapon] = self CalcWeaponOptions( camo_index, lens_index, reticle_index, reticle_color_index );
2540  return self.pack_a_punch_weapon_options[weapon];
2541 }
2542 
2543 function ‪give_build_kit_weapon( weapon )
2544 {
2545  upgraded = false;
2546  camo = undefined;
2547  base_weapon = weapon;
2548  if ( ‪is_weapon_upgraded( weapon ) )
2549  {
2550  if( isdefined(weapon.pap_camo_to_use) )
2551  {
2552  camo = weapon.pap_camo_to_use;
2553  }
2554  else
2555  {
2556  camo = ‪get_pack_a_punch_camo_index( undefined );
2557  }
2558  upgraded = true;
2559  base_weapon = ‪get_base_weapon( weapon );
2560  }
2561 
2562  if ( ‪is_weapon_included( base_weapon ) )
2563  {
2564  force_attachments = ‪get_force_attachments( base_weapon.rootWeapon );
2565  }
2566 
2567  if ( IsDefined( force_attachments ) && force_attachments.size )
2568  {
2569  if ( upgraded )
2570  {
2571  packed_attachments = [];
2572  packed_attachments[packed_attachments.size] = "extclip";
2573  packed_attachments[packed_attachments.size] = "fmj";
2574  force_attachments = ArrayCombine( force_attachments, packed_attachments, false, false );
2575  }
2576 
2577  weapon = GetWeapon( weapon.rootWeapon.name, force_attachments );
2578 
2579  if ( !IsDefined( camo ) )
2580  {
2581  camo = 0;
2582  }
2583 
2584  weapon_options = self CalcWeaponOptions( camo, 0, 0 );
2585 
2586  acvi = 0;
2587  }
2588  else
2589  {
2590  weapon = self GetBuildKitWeapon( weapon, upgraded );
2591 
2592  weapon_options = self GetBuildKitWeaponOptions( weapon, camo );
2593 
2594  acvi = self GetBuildKitAttachmentCosmeticVariantIndexes( weapon, upgraded );
2595  }
2596 
2597  self GiveWeapon( weapon, weapon_options, acvi );
2598 
2599  return weapon;
2600 }
2601 
2602 // T8 TODO - get rid of is_upgrade and magic_box
2603 function ‪weapon_give( weapon, is_upgrade = false, magic_box = false, nosound = false, b_switch_weapon = true ) // is_upgrade and magic_box are ignored
2604 {
2605  primaryWeapons = self GetWeaponsListPrimaries();
2606  initial_current_weapon = self getCurrentWeapon();
2607  current_weapon = self ‪zm_weapons::switch_from_alt_weapon( initial_current_weapon );
2608 
2609  assert( self ‪player_can_use_content( weapon ) );
2610 
2611  //if is not an upgraded perk purchase
2612  if( !IsDefined( is_upgrade ) )
2613  {
2614  is_upgrade = false;
2615  }
2616 
2617  weapon_limit = ‪zm_utility::get_player_weapon_limit( self );
2618 
2619  if ( ‪zm_equipment::is_equipment( weapon ) )
2620  {
2621  self ‪zm_equipment::give( weapon );
2622  }
2623 
2624  if ( weapon.isriotshield )
2625  {
2626  if ( isdefined( self.player_shield_reset_health ) )
2627  {
2628  self [[self.player_shield_reset_health]]();
2629  }
2630  }
2631 
2632  if ( self HasWeapon( weapon ) )
2633  {
2634  if ( weapon.isBallisticKnife )
2635  {
2636  self notify( "zmb_lost_knife" );
2637  }
2638 
2639  self GiveStartAmmo( weapon );
2640  if ( !‪zm_utility::is_offhand_weapon( weapon ) )
2641  {
2642  self SwitchToWeapon( weapon );
2643  }
2644 
2645  self notify( "weapon_give", weapon );
2646  return weapon;
2647  }
2648 
2649  // check for ray gun variation if already have a ray gun
2650  if( weapon.name == "ray_gun" || weapon.name == "raygun_mark2" )
2651  {
2652  // if have mark2 and pulled mark1 just give ammo
2653  if ( self ‪has_weapon_or_upgrade( GetWeapon( "raygun_mark2" ) ) && weapon.name == "ray_gun" )
2654  {
2655  for( i = 0; i < primaryWeapons.size; i++ )
2656  {
2657  if( IsSubstr( primaryWeapons[i].‪name, "raygun_mark2" ) )
2658  {
2659  self GiveStartAmmo( primaryWeapons[i] );
2660  break;
2661  }
2662  }
2663 
2664  self notify( "weapon_give", weapon );
2665  return weapon;
2666  }
2667  else if( self ‪has_weapon_or_upgrade( GetWeapon( "ray_gun" ) ) && weapon.name == "raygun_mark2" )
2668  {
2669  // change out ray gun for mark 2
2670  for( i = 0; i < primaryWeapons.size; i++ )
2671  {
2672  if( IsSubstr( primaryWeapons[i].‪name, "ray_gun" ) )
2673  {
2674  self ‪weapon_take( primaryWeapons[i] );
2675  break;
2676  }
2677  }
2678 
2679  weapon = self ‪give_build_kit_weapon( weapon );
2680  self notify( "weapon_give", weapon );
2681 
2682  self GiveStartAmmo( weapon );
2683 
2684  self SwitchToWeapon( weapon );
2685  return weapon;
2686  }
2687  }
2688 
2689  if ( ‪zm_utility::is_melee_weapon( weapon ) )
2690  {
2691  current_weapon=‪zm_melee_weapon::change_melee_weapon( weapon, current_weapon );
2692  }
2693  else if ( ‪zm_utility::is_hero_weapon( weapon ) )
2694  {
2695  old_hero = self ‪zm_utility::get_player_hero_weapon();
2696  if ( old_hero != level.weaponNone )
2697  {
2698  self ‪weapon_take( old_hero );
2699  }
2700 
2702  }
2703  else if ( ‪zm_utility::is_lethal_grenade( weapon ) )
2704  {
2705  old_lethal = self ‪zm_utility::get_player_lethal_grenade();
2706  if ( old_lethal != level.weaponNone )
2707  {
2708  self ‪weapon_take( old_lethal );
2709  }
2710 
2712  }
2713  else if ( ‪zm_utility::is_tactical_grenade( weapon ) )
2714  {
2715  old_tactical = self ‪zm_utility::get_player_tactical_grenade();
2716  if ( old_tactical != level.weaponNone )
2717  {
2718  self ‪weapon_take( old_tactical );
2719  }
2720 
2722  }
2723  else if ( ‪zm_utility::is_placeable_mine( weapon ) )
2724  {
2725  old_mine = self ‪zm_utility::get_player_placeable_mine();
2726  if ( old_mine != level.weaponNone )
2727  {
2728  self ‪weapon_take( old_mine );
2729  }
2730 
2732  }
2733 
2734  if ( !‪zm_utility::is_offhand_weapon( weapon ) )
2735  {
2737  }
2738 
2739  // This should never be true for the first time.
2740  if ( primaryWeapons.size >= weapon_limit )
2741  {
2742 
2743  if ( ‪zm_utility::is_placeable_mine( current_weapon ) || ‪zm_equipment::is_equipment( current_weapon ) )
2744  {
2745  current_weapon = undefined;
2746  }
2747 
2748  if ( isdefined( current_weapon ) )
2749  {
2750  if ( !‪zm_utility::is_offhand_weapon( weapon ) )
2751  {
2752  if ( current_weapon.isBallisticKnife )
2753  {
2754  self notify( "zmb_lost_knife" );
2755  }
2756 
2757  self ‪weapon_take( current_weapon );
2758 
2759  // If its a dualoptic weapon there are two weapons that need to be removed
2760  if ( isdefined(initial_current_weapon) && IsSubStr(initial_current_weapon.name, "dualoptic") )
2761  {
2762  self ‪weapon_take( initial_current_weapon );
2763  }
2764  }
2765  }
2766  }
2767 
2768  if ( IsDefined( level.zombiemode_offhand_weapon_give_override ) )
2769  {
2770  if ( self [[ level.zombiemode_offhand_weapon_give_override ]]( weapon ) )
2771  {
2772  self notify( "weapon_give", weapon );
2773  self ‪zm_utility::play_sound_on_ent( "purchase" );
2774  return weapon;
2775  }
2776  }
2777 
2778  if ( weapon.isBallisticKnife )
2779  {
2780  weapon = self ‪zm_melee_weapon::give_ballistic_knife( weapon, ‪is_weapon_upgraded( weapon ) );
2781  }
2782  else if( ‪zm_utility::is_placeable_mine( weapon ) )
2783  {
2784  self thread ‪zm_placeable_mine::setup_for_player(weapon);
2785  self ‪play_weapon_vo( weapon, magic_box );
2786  self notify( "weapon_give", weapon );
2787  return weapon;
2788  }
2789 
2790  // run any custom weapon callbacks here
2791  if ( IsDefined( level.zombie_weapons_callbacks ) && IsDefined( level.zombie_weapons_callbacks[ weapon ] ) )
2792  {
2793  self thread [[ level.zombie_weapons_callbacks[ weapon ] ]]();
2794  ‪play_weapon_vo( weapon, magic_box );
2795  self notify( "weapon_give", weapon );
2796  return weapon;
2797  }
2798 
2799  if ( !‪IS_TRUE( nosound ) )
2800  {
2801  self ‪zm_utility::play_sound_on_ent( "purchase" );
2802  }
2803 
2804  weapon = self ‪give_build_kit_weapon( weapon );
2805  self notify( "weapon_give", weapon );
2806 
2807  self GiveStartAmmo( weapon );
2808 
2809  if ( b_switch_weapon && !‪zm_utility::is_offhand_weapon( weapon ) )
2810  {
2811  if( !‪zm_utility::is_melee_weapon( weapon ) )
2812  {
2813  self SwitchToWeapon( weapon );
2814  }
2815  else
2816  {
2817  self SwitchToWeapon( current_weapon );
2818  }
2819  }
2820 
2821  if ( !‪IS_TRUE( nosound ) )
2822  {
2823  self ‪play_weapon_vo( weapon, magic_box );
2824  }
2825 
2826  return weapon;
2827 }
2828 
2829 function ‪weapon_take( weapon )
2830 {
2831  self notify("weapon_take",weapon);
2832  if ( self HasWeapon( weapon ) )
2833  {
2834  self TakeWeapon( weapon );
2835  }
2836 }
2837 
2838 function ‪play_weapon_vo( weapon, magic_box )
2839 {
2840  //Added this in for special instances of New characters with differing favorite weapons
2841  if ( isDefined( level._audio_custom_weapon_check ) )
2842  {
2843  type = self [[ level._audio_custom_weapon_check ]]( weapon, magic_box );
2844  }
2845  else
2846  {
2847  type = self ‪weapon_type_check( weapon );
2848  }
2849 
2850  if ( !IsDefined(type) )
2851  {
2852  return;
2853  }
2854 
2855  if( isdefined(level.sndWeaponPickupOverride))
2856  {
2857  foreach( override in level.sndWeaponPickupOverride )
2858  {
2859  if( weapon.name === override )
2860  {
2861  self ‪zm_audio::create_and_play_dialog( "weapon_pickup", override );
2862  return;
2863  }
2864  }
2865  }
2866 
2867  if( ‪IS_TRUE(magic_box) )
2868  {
2869  self ‪zm_audio::create_and_play_dialog( "box_pickup", type );
2870  }
2871  else
2872  {
2873  if( type == "upgrade" )
2874  {
2875  self ‪zm_audio::create_and_play_dialog( "weapon_pickup", "upgrade" );
2876  }
2877  else if( randomintrange(0,100) <= 50 )
2878  {
2879  self ‪zm_audio::create_and_play_dialog( "weapon_pickup", type );
2880  }
2881  else
2882  {
2883  self ‪zm_audio::create_and_play_dialog( "weapon_pickup", "generic" );
2884  }
2885  }
2886 }
2887 
2888 function ‪weapon_type_check( weapon )
2889 {
2890  if( weapon.name == "zombie_beast_grapple_dwr" ||
2891  weapon.name == "zombie_beast_lightning_dwl" ||
2892  weapon.name == "zombie_beast_lightning_dwl2" ||
2893  weapon.name == "zombie_beast_lightning_dwl3" )
2894  {
2895  return undefined;
2896  }
2897 
2898  if ( !IsDefined( self.entity_num ) )
2899  {
2900  return "crappy";
2901  }
2902 
2903  weapon = ‪get_nonalternate_weapon( weapon );
2904 
2905  weapon = weapon.rootWeapon;
2906 
2907  if ( ‪is_weapon_upgraded( weapon ) )
2908  {
2909  return "upgrade";
2910  }
2911  else
2912  {
2913  if ( IsDefined(level.zombie_weapons[weapon]) )
2914  return level.zombie_weapons[weapon].vox;
2915  return "crappy";
2916  }
2917 }
2918 
2919 function ‪ammo_give( weapon )
2920 {
2921  // We assume before calling this function we already checked to see if the player has this weapon...
2922 
2923  // Should we give ammo to the player
2924  give_ammo = false;
2925 
2926  // Check to see if ammo belongs to a primary weapon
2927  if ( !‪zm_utility::is_offhand_weapon( weapon ) )
2928  {
2929  weapon = self ‪get_weapon_with_attachments( weapon );
2930 
2931  if ( isdefined( weapon ) )
2932  {
2933  // get the max allowed ammo on the current weapon
2934  stockMax = 0; // scope declaration
2935  stockMax = weapon.maxammo;
2936 
2937  // Get the current weapon clip count
2938  clipCount = self GetWeaponAmmoClip( weapon );
2939  dw_clipcount = self GetWeaponAmmoClip( weapon.dualwieldweapon );//Check for dual wield weapon like the starting pistols
2940 
2941  currStock = self GetAmmoCount( weapon );
2942 
2943  // compare it with the ammo player actually has, if more or equal just dont give the ammo, else do
2944  if ( currStock - clipcount + dw_clipcount >= stockMax )
2945  {
2946  give_ammo = false;
2947  }
2948  else
2949  {
2950  give_ammo = true; // give the ammo to the player
2951  }
2952  }
2953  }
2954  else
2955  {
2956  // Ammo belongs to secondary weapon
2957  if ( self ‪has_weapon_or_upgrade( weapon ) )
2958  {
2959  // Check if the player has less than max stock, if no give ammo
2960  if ( self getammocount( weapon ) < weapon.maxAmmo )
2961  {
2962  // give the ammo to the player
2963  give_ammo = true;
2964  }
2965  }
2966  }
2967 
2968  if ( give_ammo )
2969  {
2970  self ‪zm_utility::play_sound_on_ent( "purchase" );
2971  self GiveMaxAmmo( weapon );
2972 
2973  alt_weap = weapon.altWeapon;
2974  if ( level.weaponNone != alt_weap )
2975  {
2976  self GiveMaxAmmo( alt_weap );
2977  }
2978 
2979  return true;
2980  }
2981 
2982  if ( !give_ammo )
2983  {
2984  return false;
2985  }
2986 }
2987 
2988 function ‪get_default_weapondata( weapon )
2989 {
2990  weapondata = [];
2991 
2992  weapondata["weapon"] = weapon;
2993 
2994  dw_weapon = weapon.dualWieldWeapon;
2995  alt_weapon = weapon.altWeapon;
2996 
2997  weaponNone = GetWeapon( "none" );
2998  if ( IsDefined(level.weaponNone) )
2999  weaponNone = level.weaponNone;
3000 
3001  if ( weapon != weaponNone )
3002  {
3003  weapondata["clip"] = weapon.clipSize;
3004  weapondata["stock"] = weapon.maxAmmo;
3005  weapondata["fuel"] = weapon.fuelLife;
3006  weapondata["heat"] = 0;
3007  weapondata["overheat"] = 0;
3008  }
3009 
3010  if ( dw_weapon != weaponNone )
3011  {
3012  weapondata["lh_clip"] = dw_weapon.clipSize;
3013  }
3014  else
3015  {
3016  weapondata["lh_clip"] = 0;
3017  }
3018 
3019  if ( alt_weapon != weaponNone )
3020  {
3021  weapondata["alt_clip"] = alt_weapon.clipSize;
3022  weapondata["alt_stock"] = alt_weapon.maxAmmo;
3023  }
3024  else
3025  {
3026  weapondata["alt_clip"] = 0;
3027  weapondata["alt_stock"] = 0;
3028  }
3029 
3030  return weapondata;
3031 }
3032 
3033 function ‪get_player_weapondata( player, weapon )
3034 {
3035  weapondata = [];
3036  if ( !isdefined( weapon ) )
3037  {
3038  weapon = player GetCurrentWeapon();
3039  }
3040 
3041  weapondata["weapon"] = weapon;
3042 
3043  if ( weapondata["weapon"] != level.weaponNone )
3044  {
3045  weapondata["clip"] = player GetWeaponAmmoClip( weapon );
3046  weapondata["stock"] = player GetWeaponAmmoStock( weapon );
3047  weapondata["fuel"] = player GetWeaponAmmoFuel( weapon );
3048  weapondata["heat"] = player IsWeaponOverheating( 1, weapon );
3049  weapondata["overheat"] = player IsWeaponOverheating( 0, weapon );
3050  }
3051  else
3052  {
3053  weapondata["clip"] = 0;
3054  weapondata["stock"] = 0;
3055  weapondata["fuel"] = 0;
3056  weapondata["heat"] = 0;
3057  weapondata["overheat"] = 0;
3058  }
3059 
3060  dw_weapon = weapon.dualWieldWeapon;
3061  if ( dw_weapon != level.weaponNone )
3062  {
3063  weapondata["lh_clip"] = player GetWeaponAmmoClip( dw_weapon );
3064  }
3065  else
3066  {
3067  weapondata["lh_clip"] = 0;
3068  }
3069 
3070  alt_weapon = weapon.altWeapon;
3071  if ( alt_weapon != level.weaponNone )
3072  {
3073  weapondata["alt_clip"] = player GetWeaponAmmoClip( alt_weapon );
3074  weapondata["alt_stock"] = player GetWeaponAmmoStock( alt_weapon );
3075  }
3076  else
3077  {
3078  weapondata["alt_clip"] = 0;
3079  weapondata["alt_stock"] = 0;
3080  }
3081 
3082  return weapondata;
3083 }
3084 
3085 
3086 
3087 function ‪weapon_is_better( left, right )
3088 {
3089  if ( left != right )
3090  {
3091  left_upgraded = !IsDefined( level.zombie_weapons[ left ] );
3092  right_upgraded = !IsDefined( level.zombie_weapons[ right ] );
3093  if ( left_upgraded && right_upgraded )
3094  {
3095  leftatt = ‪get_attachment_index( left );
3096  rightatt = ‪get_attachment_index( right );
3097  return (leftatt > rightatt);
3098  }
3099  else if ( left_upgraded )
3100  {
3101  return true;
3102  }
3103  }
3104  return false;
3105 }
3106 
3107 
3108 function ‪merge_weapons( oldweapondata, newweapondata )
3109 {
3110  weapondata = [];
3111 
3112  if ( ‪weapon_is_better( oldweapondata["weapon"], newweapondata["weapon"] ) )
3113  {
3114  weapondata["weapon"] = oldweapondata["weapon"];
3115  }
3116  else
3117  {
3118  weapondata["weapon"] = newweapondata["weapon"];
3119  }
3120 
3121  weapon = weapondata["weapon"];
3122 
3123  dw_weapon = weapon.dualWieldWeapon;
3124  alt_weapon = weapon.altWeapon;
3125 
3126  if ( weapon != level.weaponNone )
3127  {
3128  weapondata["clip"] = newweapondata["clip"] + oldweapondata["clip"];
3129  weapondata["clip"] = int( min( weapondata["clip"], weapon.clipSize ) );
3130  weapondata["stock"] = newweapondata["stock"] + oldweapondata["stock"];
3131  weapondata["stock"] = int( min( weapondata["stock"], weapon.maxAmmo ) );
3132  weapondata["fuel"] = newweapondata["fuel"] + oldweapondata["fuel"];
3133  weapondata["fuel"] = int( min( weapondata["fuel"], weapon.fuelLife ) );
3134  weapondata["heat"] = int( min( newweapondata["heat"], oldweapondata["heat"] ) );
3135  weapondata["overheat"] = int( min( newweapondata["overheat"], oldweapondata["overheat"] ) );
3136  }
3137 
3138  if ( dw_weapon != level.weaponNone )
3139  {
3140  weapondata["lh_clip"] = newweapondata["lh_clip"] + oldweapondata["lh_clip"];
3141  weapondata["lh_clip"] = int( min( weapondata["lh_clip"], dw_weapon.clipSize ) );
3142  }
3143 
3144  if ( alt_weapon != level.weaponNone )
3145  {
3146  weapondata["alt_clip"] = newweapondata["alt_clip"] + oldweapondata["alt_clip"];
3147  weapondata["alt_clip"] = int( min( weapondata["alt_clip"], alt_weapon.clipSize ) );
3148  weapondata["alt_stock"] = newweapondata["alt_stock"] + oldweapondata["alt_stock"];
3149  weapondata["alt_stock"] = int( min( weapondata["alt_stock"], alt_weapon.maxAmmo ) );
3150  }
3151 
3152  return weapondata;
3153 }
3154 
3155 
3156 
3157 
3158 function ‪weapondata_give( weapondata )
3159 {
3160  current = self ‪get_player_weapon_with_same_base( weapondata["weapon"] );
3161  if ( isdefined( current ) )
3162  {
3163  curweapondata = ‪get_player_weapondata( self, current );
3164  self ‪weapon_take( current );
3165 
3166  weapondata = ‪merge_weapons( curweapondata, weapondata );
3167  }
3168 
3169  weapon = weapondata["weapon"];
3170 
3171  ‪weapon_give( weapon, undefined, undefined, true );
3172 
3173  if ( weapon != level.weaponNone )
3174  {
3175  self SetWeaponAmmoClip( weapon, weapondata["clip"] );
3176  self SetWeaponAmmoStock( weapon, weapondata["stock"] );
3177  if ( IsDefined( weapondata["fuel"] ) )
3178  {
3179  self SetWeaponAmmoFuel( weapon, weapondata["fuel"] );
3180  }
3181  if ( IsDefined( weapondata["heat"] ) && IsDefined( weapondata["overheat"] ) )
3182  {
3183  self SetWeaponOverheating( weapondata["overheat"], weapondata["heat"], weapon );
3184  }
3185  }
3186 
3187  dw_weapon = weapon.dualWieldWeapon;
3188  if ( dw_weapon != level.weaponNone )
3189  {
3190  if ( !self HasWeapon( dw_weapon ) )
3191  {
3192  self GiveWeapon( dw_weapon );
3193  }
3194  self SetWeaponAmmoClip( dw_weapon, weapondata["lh_clip"] );
3195  }
3196 
3197  alt_weapon = weapon.altWeapon;
3198  if ( alt_weapon != level.weaponNone && alt_weapon.altweapon == weapon )
3199  {
3200  if ( !self HasWeapon( alt_weapon ) )
3201  {
3202  self GiveWeapon( alt_weapon );
3203  }
3204  self SetWeaponAmmoClip( alt_weapon, weapondata["alt_clip"] );
3205  self SetWeaponAmmoStock( alt_weapon, weapondata["alt_stock"] );
3206  }
3207 }
3208 
3209 function ‪weapondata_take( weapondata )
3210 {
3211  weapon = weapondata["weapon"];
3212  if ( weapon != level.weaponNone )
3213  {
3214  if ( self HasWeapon( weapon ) )
3215  {
3216  self ‪weapon_take( weapon );
3217  }
3218  }
3219 
3220  dw_weapon = weapon.dualWieldWeapon;
3221  if ( dw_weapon != level.weaponNone )
3222  {
3223  if ( self HasWeapon( dw_weapon ) )
3224  {
3225  self ‪weapon_take( dw_weapon );
3226  }
3227  }
3228 
3229  alt_weapon = weapon.altWeapon;
3230  while ( alt_weapon != level.weaponNone )
3231  {
3232  if ( self HasWeapon( alt_weapon ) )
3233  {
3234  self ‪weapon_take( alt_weapon );
3235  }
3236  alt_weapon = alt_weapon.altWeapon;
3237  }
3238 }
3239 
3240 // Create a loadout from an array of weapons that can later be applied to a player
3241 function ‪create_loadout( weapons )
3242 {
3243  weaponNone = GetWeapon( "none" );
3244  if ( IsDefined(level.weaponNone) )
3245  weaponNone = level.weaponNone;
3246  loadout = SpawnStruct();
3247  loadout.weapons = [];
3248  foreach ( weapon in weapons )
3249  {
3250  if ( IsString(weapon) )
3251  weapon = GetWeapon(weapon);
3252  if ( weapon == weaponNone )
3253  {
3254 
3255  }
3256  loadout.weapons[weapon.name] = ‪get_default_weapondata( weapon );
3257  // use first weapon as current
3258  if (!IsDefined(loadout.current))
3259  loadout.current = weapon;
3260  }
3261  return loadout;
3262 }
3263 
3264 // Get the player's existing loadout for later restoration
3266 {
3267  loadout = SpawnStruct();
3268  loadout.current = self GetCurrentWeapon();
3269  loadout.stowed = self GetStowedWeapon();
3270  loadout.weapons = [];
3271  foreach ( weapon in self GetWeaponsList() )
3272  {
3273  loadout.weapons[weapon.name] = ‪get_player_weapondata( self, weapon );
3274  }
3275 
3276  return loadout;
3277 }
3278 
3279 // Give a saved or created loadout to a player
3280 function ‪player_give_loadout( loadout, replace_existing = true, immediate_switch = false )
3281 {
3282  if ( ‪IS_TRUE(replace_existing) )
3283  self TakeAllWeapons();
3284  foreach ( weapondata in loadout.weapons )
3285  {
3286  self ‪weapondata_give( weapondata );
3287  }
3288  if ( !‪zm_utility::is_offhand_weapon( loadout.current ) )
3289  {
3290  if ( immediate_switch )
3291  Self SwitchToWeaponImmediate(loadout.current);
3292  else
3293  Self SwitchToWeapon(loadout.current);
3294  }
3295  else
3296  {
3297  if ( immediate_switch )
3298  Self SwitchToWeaponImmediate();
3299  else
3300  Self SwitchToWeapon();
3301  }
3302  if ( IsDefined(loadout.stowed) )
3303  self SetStowedWeapon(loadout.stowed);
3304 }
3305 
3306 // Take all weapons in a loadout away from a player
3307 function ‪player_take_loadout( loadout )
3308 {
3309  foreach ( weapondata in loadout.weapons )
3310  {
3311  self ‪weapondata_take( weapondata );
3312  }
3313 }
3314 
3315 
3316 // This function will be run when the player picks up the weapon for the first time
3317 function ‪register_zombie_weapon_callback( weapon, func )
3318 {
3319  if ( !IsDefined( level.zombie_weapons_callbacks ) )
3320  {
3321  level.zombie_weapons_callbacks = [];
3322  }
3323 
3324  if ( !IsDefined( level.zombie_weapons_callbacks[weapon] ) )
3325  {
3326  level.zombie_weapons_callbacks[weapon] = func;
3327  }
3328 }
3329 
3330 
3331 function ‪set_stowed_weapon( weapon )
3332 {
3333  self.weapon_stowed = weapon;
3334  if ( !‪IS_TRUE(self.stowed_weapon_suppressed) )
3335  {
3336  self SetStowedWeapon( self.weapon_stowed );
3337  }
3338 }
3339 
3341 {
3342  self.weapon_stowed = undefined;
3343  self ClearStowedWeapon();
3344 }
3345 
3346 function ‪suppress_stowed_weapon( onOff )
3347 {
3348  self.stowed_weapon_suppressed = onOff;
3349  if ( onOff || !IsDefined(self.weapon_stowed) )
3350  self ClearStowedWeapon();
3351  else
3352  self SetStowedWeapon( self.weapon_stowed );
3353 }
3354 
3355 function ‪checkStringValid( str )
3356 {
3357  if( str != "" )
3358  return str;
3359  return undefined;
3360 }
3361 
3362 function ‪load_weapon_spec_from_table( table, first_row )
3363 {
3364  gametype = GetDvarString( "ui_gametype" );
3365  index = 1;
3366  row = TableLookupRow( table, index );
3367  while ( isdefined( row ) )
3368  {
3369  //Get this weapons data from the current tablerow
3370  weapon_name = ‪checkStringValid( row[ ‪WEAPON_TABLE_COL_NAME ] );
3371  upgrade_name = ‪checkStringValid( row[ ‪WEAPON_TABLE_COL_UPGRADE_NAME ] );
3373  cost = int( row[ ‪WEAPON_TABLE_COL_COST ] );
3374  weaponVO = ‪checkStringValid( row[ ‪WEAPON_TABLE_COL_VO ] );
3375  weaponVOresp = ‪checkStringValid( row[ ‪WEAPON_TABLE_COL_VO_RESPOND ] );
3376 
3377  ammo_cost = undefined; // if unspecified, default to half the cost using undefined
3378  if ( "" != row[‪WEAPON_TABLE_COL_AMMO_COST] )
3379  {
3380  ammo_cost = int( row[‪WEAPON_TABLE_COL_AMMO_COST] );
3381  }
3382 
3383  create_vox = ‪checkStringValid( row[ ‪WEAPON_TABLE_COL_CREATE_VOX ] );
3384  is_zcleansed = ( ToLower( row[ ‪WEAPON_TABLE_COL_IS_ZCLEANSED ] ) == "true" );
3385  in_box = ( ToLower( row[ ‪WEAPON_TABLE_COL_IN_BOX ] ) == "true" );
3386  upgrade_in_box = ( ToLower( row[ ‪WEAPON_TABLE_COL_UPGRADE_IN_BOX ] ) == "true" );
3387  ‪is_limited = ( ToLower( row[ ‪WEAPON_TABLE_COL_IS_LIMITED ] ) == "true" );
3388  is_aat_exempt = ( ToLower( row[ ‪WEAPON_TABLE_COL_AAT_EXEMPT ] ) == "true" );
3389  ‪limit = int( row[ ‪WEAPON_TABLE_COL_LIMIT ] );
3390  upgrade_limit = int( row[ ‪WEAPON_TABLE_COL_UPGRADE_LIMIT ] );
3391  content_restrict = row[ ‪WEAPON_TABLE_COL_CONTENT_RESTRICT ];
3392  wallbuy_autospawn = ( ToLower( row[ ‪WEAPON_TABLE_COL_AUTOSPAWN ] ) == "true" );
3393  weapon_class = ‪checkStringValid( row[ ‪WEAPON_TABLE_COL_CLASS ] );
3394  ‪is_wonder_weapon = ( ToLower( row[ ‪WEAPON_TABLE_COL_IS_WONDER_WEAPON ] ) == "true" );
3395  force_attachments = ToLower( row[ ‪WEAPON_TABLE_COL_FORCE_ATTACHMENTS ] );
3396 
3397  //Now use this data to include the weapon
3398  ‪zm_utility::include_weapon( weapon_name, in_box );
3399  if ( isdefined( upgrade_name ) )
3400  {
3401  ‪zm_utility::include_weapon( upgrade_name, upgrade_in_box );
3402  }
3403 
3404  ‪add_zombie_weapon( weapon_name, upgrade_name, hint, cost, weaponVO, weaponVOresp, ammo_cost, create_vox, ‪is_wonder_weapon, force_attachments );
3405  if ( ‪is_limited )
3406  {
3407  if ( isdefined( ‪limit ) )
3408  {
3409  ‪add_limited_weapon( weapon_name, ‪limit );
3410  }
3411  if ( isdefined( upgrade_limit ) && isdefined( upgrade_name ) )
3412  {
3413  ‪add_limited_weapon( upgrade_name, upgrade_limit );
3414  }
3415  }
3416 
3417  if ( is_aat_exempt && isdefined( upgrade_name ) )
3418  {
3419  ‪aat::register_aat_exemption( GetWeapon( upgrade_name ) );
3420  }
3421 
3422 
3423  /* if ( IS_TRUE( content_restrict ) )
3424  {
3425  add_weapon_to_content( weapon_name, content_restrict );
3426  }*/
3427 
3428  /*weapon = GetWeapon( weapon_name );
3429  if ( !isdefined( level.wallbuy_autofill_weapons ) )
3430  {
3431  level.wallbuy_autofill_weapons = [];
3432  level.wallbuy_autofill_weapons["all"] = [];
3433  }
3434  level.wallbuy_autofill_weapons["all"][weapon] = wallbuy_autospawn;
3435 
3436  if ( weapon_class != "" )
3437  {
3438  if ( !isdefined( level.wallbuy_autofill_weapons[weapon_class] ) )
3439  {
3440  level.wallbuy_autofill_weapons[weapon_class] = [];
3441  }
3442  level.wallbuy_autofill_weapons[weapon_class][weapon] = weapon;
3443  }*/
3444 
3445  index++;
3446  row = TableLookupRow( table, index );
3447  }
3448 }
3449 
3451 {
3452  wallbuys = ‪struct::get_array("wallbuy_autofill","targetname");
3453 
3454  if (!isdefined(wallbuys) || wallbuys.size == 0 || !isdefined(level.wallbuy_autofill_weapons) || level.wallbuy_autofill_weapons.size == 0 )
3455  return;
3456 
3457  level.use_autofill_wallbuy = true;
3458  level.active_autofill_wallbuys = [];
3459 
3460  array_keys["all"] = GetArrayKeys(level.wallbuy_autofill_weapons["all"]);
3461  class_all = [];
3462  index = 0;
3463 
3464  //Loop through all autospawn wallbuys
3465  foreach (wallbuy in wallbuys)
3466  {
3467  weapon_class = wallbuy.script_string;
3468  weapon = undefined;
3469 
3470  //If this wallbuy needs a specific class of weapons
3471  if (isdefined(weapon_class) && weapon_class != "")
3472  {
3473  //Check if there's any weapon of this class included
3474  if (!isdefined(array_keys[weapon_class]) && isdefined(level.wallbuy_autofill_weapons[weapon_class]))
3475  array_keys[weapon_class] = GetArrayKeys(level.wallbuy_autofill_weapons[weapon_class]);
3476  if (isdefined(array_keys[weapon_class]))
3477  {
3478  //Find the first not spawned weapon of this type
3479  for (i = 0 ; i < array_keys[weapon_class].size; i ++)
3480  {
3481  if (level.wallbuy_autofill_weapons["all"][array_keys[weapon_class][i]])
3482  {
3483  weapon = array_keys[weapon_class][i];
3484  //Mark this weapon spawned
3485  level.wallbuy_autofill_weapons["all"][weapon] = false;
3486  break;
3487  }
3488  }
3489  }
3490  else
3491  {
3492  continue;
3493  }
3494  }
3495  else
3496  {
3497  //Save for later
3498  class_all[class_all.size] = wallbuy;
3499  continue;
3500  }
3501 
3502  //No more weapon can be assigned to this wallbuy, skip it
3503  if (!isdefined(weapon))
3504  continue;
3505 
3506  wallbuy.zombie_weapon_upgrade = weapon.name;
3507  wallbuy.weapon = weapon;
3508 
3509  //Fix for the blue light effect
3510  right = AnglesToRight(wallbuy.angles);
3511  wallbuy.origin -= right * 2;
3512 
3513  wallbuy.target = "autofill_wallbuy_" + index;
3514 
3515  target_struct = SpawnStruct();
3516  target_struct.targetname = wallbuy.target;
3517  target_struct.angles = wallbuy.angles;
3518  target_struct.origin = wallbuy.origin;
3519 
3520  model = wallbuy.weapon.worldModel;
3521  target_struct.model = model;
3522  target_struct ‪struct::init();
3523  level.active_autofill_wallbuys[level.active_autofill_wallbuys.size] = wallbuy;
3524  index ++;
3525  }
3526 
3527  foreach (wallbuy in class_all)
3528  {
3529  weapon = undefined;
3530  //Find the first available weapon in all weapons included
3531  for (i = 0 ; i < array_keys["all"].size; i ++)
3532  {
3533  if (level.wallbuy_autofill_weapons["all"][array_keys["all"][i]])
3534  {
3535  weapon = array_keys["all"][i];
3536  level.wallbuy_autofill_weapons["all"][weapon] = false;
3537  break;
3538  }
3539  }
3540 
3541  //No more weapon can be assigned to class all
3542  if (!isdefined(weapon))
3543  break;
3544 
3545  wallbuy.zombie_weapon_upgrade = weapon.name;
3546  wallbuy.weapon = weapon;
3547 
3548  //Fix for the blue light effect
3549  right = AnglesToRight(wallbuy.angles);
3550  wallbuy.origin -= right * 2;
3551 
3552  wallbuy.target = "autofill_wallbuy_" + index;
3553 
3554  target_struct = SpawnStruct();
3555  target_struct.targetname = wallbuy.target;
3556  target_struct.angles = wallbuy.angles;
3557  target_struct.origin = wallbuy.origin;
3558 
3559  model = wallbuy.weapon.worldModel;
3560  target_struct.model = model;
3561  target_struct ‪struct::init();
3562  level.active_autofill_wallbuys[level.active_autofill_wallbuys.size] = wallbuy;
3563  index ++;
3564  }
3565 }
3566 
3567 //Check whether this weapon is a wallbuy weapon or not
3568 function ‪is_wallbuy( w_to_check )
3569 {
3570  w_base = ‪get_base_weapon( w_to_check );
3571  foreach( s_wallbuy in level._spawned_wallbuys )
3572  {
3573  if( s_wallbuy.weapon == w_base )
3574  {
3575  return true;
3576  }
3577  }
3578 
3579  return false;
3580 }
3581 
3582 function ‪is_wonder_weapon( w_to_check )
3583 {
3584  w_base = ‪get_base_weapon( w_to_check );
3585  if( isdefined( level.zombie_weapons[w_base] ) && level.zombie_weapons[w_base].is_wonder_weapon )
3586  {
3587  return true;
3588  }
3589 
3590  return false;
3591 }
‪createBaseWatchers
‪function createBaseWatchers()
Definition: _weaponobjects.gsc:226
‪get_nonalternate_weapon
‪function get_nonalternate_weapon(weapon)
Definition: _zm_weapons.gsc:230
‪wait_for_explosion
‪function wait_for_explosion(time)
Definition: _zm_weapons.gsc:204
‪is_active
‪function is_active(str_scenedef)
Definition: scene_shared.csc:2314
‪is_weapon_included
‪function is_weapon_included(weapon)
Definition: _zm_weapons.gsc:638
‪create_loadout
‪function create_loadout(weapons)
Definition: _zm_weapons.gsc:3241
‪is_equipment
‪function is_equipment(weapon)
Definition: _zm_equipment.gsc:691
‪callback
‪function callback(event, localclientnum, params)
Definition: callbacks_shared.csc:13
‪weapon_supports_attachments
‪function weapon_supports_attachments(weapon)
Definition: _zm_weapons.gsc:1526
‪add_custom_limited_weapon_check
‪function add_custom_limited_weapon_check(callback)
Definition: _zm_weapons.gsc:796
‪get_ammo_cost_for_weapon
‪function get_ammo_cost_for_weapon(w_current, n_base_non_wallbuy_cost, n_upgraded_non_wallbuy_cost)
Definition: _zm_weapons.gsc:1448
‪WEAPON_TABLE_COL_VO
‪#define WEAPON_TABLE_COL_VO
Definition: _zm_weapons.gsh:5
‪setup_for_player
‪function setup_for_player(wpn_type, ui_model="hudItems.showDpadRight")
Definition: _zm_placeable_mine.gsc:161
‪is_weapon_or_base_included
‪function is_weapon_or_base_included(weapon)
Definition: _zm_weapons.gsc:650
‪weapon_type_check
‪function weapon_type_check(weapon)
Definition: _zm_weapons.gsc:2888
‪add_zombie_weapon
‪function add_zombie_weapon(weapon_name, upgrade_name, hint, cost, weaponVO, weaponVOresp, ammo_cost, create_vox, is_wonder_weapon, force_attachments)
Definition: _zm_weapons.gsc:529
‪give_ballistic_knife
‪function give_ballistic_knife(weapon, upgraded)
Definition: _zm_melee_weapon.gsc:325
‪WEAPON_TABLE_COL_IS_LIMITED
‪#define WEAPON_TABLE_COL_IS_LIMITED
Definition: _zm_weapons.gsh:12
‪should_upgrade_weapon
‪function should_upgrade_weapon(player)
Definition: _zm_weapons.gsc:2328
‪onPlayerSpawned
‪function onPlayerSpawned()
Definition: _zm_weapons.gsc:81
‪checkStringValid
‪function checkStringValid(str)
Definition: _zm_weapons.gsc:3355
‪set_stowed_weapon
‪function set_stowed_weapon(weapon)
Definition: _zm_weapons.gsc:3331
‪increment_client_stat
‪function increment_client_stat(stat_name, include_gametype)
Definition: _zm_stats.gsc:389
‪is_bot
‪function is_bot()
Definition: util_shared.gsc:2488
‪round_up_to_ten
‪function round_up_to_ten(score)
Definition: _zm_utility.csc:48
‪has_upgraded_ballistic_knife
‪function has_upgraded_ballistic_knife()
Definition: _zm_melee_weapon.gsc:310
‪show_all_weapon_buys
‪function show_all_weapon_buys(player, cost, ammo_cost, is_grenade)
Definition: _zm_weapons.gsc:2343
‪watchWeaponUsageZM
‪function watchWeaponUsageZM()
Definition: _zm_weapons.gsc:343
‪is_lethal_grenade
‪function is_lethal_grenade(weapon)
Definition: _zm_utility.gsc:4145
‪play_sound_at_pos
‪function play_sound_at_pos(ref, pos, ent)
Definition: _zm_utility.gsc:3040
‪watchForGrenadeDuds
‪function watchForGrenadeDuds()
Definition: _zm_weapons.gsc:94
‪play_sound_on_ent
‪function play_sound_on_ent(ref)
Definition: _zm_utility.gsc:3070
‪get_player_weapon_limit
‪function get_player_weapon_limit(player)
Definition: _zm_utility.gsc:5865
‪reset_wallbuy_internal
‪function reset_wallbuy_internal(set_hint_string)
Definition: _zm_weapons.gsc:1292
‪get_is_in_box
‪function get_is_in_box(weapon)
Definition: _zm_weapons.gsc:1488
‪watchMissileUsage
‪function watchMissileUsage()
Definition: _weapons.gsc:543
‪wait_explode
‪function wait_explode()
Definition: _zm_weapons.gsc:184
‪weapon_set_first_time_hint
‪function weapon_set_first_time_hint(cost, ammo_cost)
Definition: _zm_weapons.gsc:1964
‪increment_player_stat
‪function increment_player_stat(stat_name)
Definition: _zm_stats.gsc:369
‪load_weapon_spec_from_table
‪function load_weapon_spec_from_table(table, first_row)
Definition: _zm_weapons.gsc:3362
‪weapon_supports_aat
‪function weapon_supports_aat(weapon)
Definition: _zm_weapons.gsc:1700
‪limited_weapon_below_quota
‪function limited_weapon_below_quota(weapon, ignore_player, pap_triggers)
Definition: _zm_weapons.gsc:696
‪has_weapon_or_attachments
‪function has_weapon_or_attachments(weapon)
Definition: _zm_weapons.gsc:1780
‪pers_nube_override_ammo_cost
‪function pers_nube_override_ammo_cost(player, weapon, ammo_cost)
Definition: _zm_pers_upgrades_functions.gsc:25
‪weapon_supports_default_attachment
‪function weapon_supports_default_attachment(weapon)
Definition: _zm_weapons.gsc:1502
‪limit
‪function limit(equipment_name, limited)
Definition: _zm_equipment.gsc:140
‪ZM_MAP_EVENT_PURCHASE_GUN
‪#define ZM_MAP_EVENT_PURCHASE_GUN
Definition: _zm_utility.gsh:42
‪updateWeaponTimingsZM
‪function updateWeaponTimingsZM(newTime)
Definition: _zm_weapons.gsc:427
‪get_weapon_with_attachments
‪function get_weapon_with_attachments(weapon)
Definition: _zm_weapons.gsc:1744
‪reset_wallbuys
‪function reset_wallbuys()
Definition: _zm_weapons.gsc:1320
‪WEAPON_TABLE_COL_LIMIT
‪#define WEAPON_TABLE_COL_LIMIT
Definition: _zm_weapons.gsh:13
‪get_triggers
‪function get_triggers()
Definition: _zm_pack_a_punch_util.gsc:77
‪add_limited_weapon
‪function add_limited_weapon(weapon_name, amount)
Definition: _zm_weapons.gsc:682
‪VERSION_SHIP
‪#define VERSION_SHIP
Definition: version.gsh:36
‪add_attachments
‪function add_attachments(weapon, upgrade)
Definition: _zm_weapons.gsc:613
‪makeGrenadeDudAndDestroy
‪function makeGrenadeDudAndDestroy()
Definition: _zm_weapons.gsc:143
‪give_start_weapon
‪function give_start_weapon(b_switch_weapon)
Definition: _zm_utility.gsc:4530
‪waittill_any_return
‪function waittill_any_return(string1, string2, string3, string4, string5, string6, string7)
Definition: util_shared.csc:212
‪weapon_show
‪function weapon_show(player)
Definition: _zm_weapons.gsc:2419
‪get_shared_ammo_weapon
‪function get_shared_ammo_weapon(weapon)
Definition: _zm_weapons.gsc:1874
‪get_array
‪function get_array(kvp_value, kvp_key="targetname")
Definition: struct.csc:34
‪watchForScriptExplosion
‪function watchForScriptExplosion(weapon, isThrownGrenade, player)
Definition: _zm_weapons.gsc:214
‪WEAPON_TABLE_COL_CREATE_VOX
‪#define WEAPON_TABLE_COL_CREATE_VOX
Definition: _zm_weapons.gsh:8
‪WEAPON_TABLE_COL_IS_ZCLEANSED
‪#define WEAPON_TABLE_COL_IS_ZCLEANSED
Definition: _zm_weapons.gsh:9
‪remove
‪function remove(weapon)
Definition: aat_shared.gsc:499
‪WEAPON_TABLE_COL_NAME
‪#define WEAPON_TABLE_COL_NAME
Definition: _zm_weapons.gsh:1
‪mayDropWeapon
‪function mayDropWeapon(weapon)
Definition: _weapons.gsc:261
‪pers_nube_weapon_ammo_check
‪function pers_nube_weapon_ammo_check(player, weapon)
Definition: _zm_pers_upgrades_functions.gsc:24
‪player_get_loadout
‪function player_get_loadout()
Definition: _zm_weapons.gsc:3265
‪get_force_attachments
‪function get_force_attachments(weapon)
Definition: _zm_weapons.gsc:1495
‪get_weapon_hint
‪function get_weapon_hint(weapon)
Definition: _zm_weapons.gsc:1417
‪get_player_hero_weapon
‪function get_player_hero_weapon()
Definition: _zm_utility.gsc:4430
‪ammo_give
‪function ammo_give(weapon)
Definition: _zm_weapons.gsc:2919
‪WEAPON_TABLE_COL_CLASS
‪#define WEAPON_TABLE_COL_CLASS
Definition: _zm_weapons.gsh:17
‪default_attachment
‪function default_attachment(weapon)
Definition: _zm_weapons.gsc:1510
‪get_attachment_index
‪function get_attachment_index(weapon)
Definition: _zm_weapons.gsc:1568
‪WEAPON_TABLE_COL_UPGRADE_IN_BOX
‪#define WEAPON_TABLE_COL_UPGRADE_IN_BOX
Definition: _zm_weapons.gsh:11
‪is_wonder_weapon
‪function is_wonder_weapon(w_to_check)
Definition: _zm_weapons.gsc:3582
‪merge_weapons
‪function merge_weapons(oldweapondata, newweapondata)
Definition: _zm_weapons.gsc:3108
‪waittill_any_timeout
‪function waittill_any_timeout(n_timeout, string1, string2, string3, string4, string5)
Definition: util_shared.csc:423
‪IS_TRUE
‪#define IS_TRUE(__a)
Definition: shared.gsh:251
‪is_exempt_weapon
‪function is_exempt_weapon(weapon)
Definition: aat_shared.gsc:374
‪get
‪function get(kvp_value, kvp_key="targetname")
Definition: struct.csc:13
‪get_default_weapondata
‪function get_default_weapondata(weapon)
Definition: _zm_weapons.gsc:2988
‪onPlayerConnect
‪function onPlayerConnect()
Definition: _zm_weapons.gsc:71
‪WEAPON_TABLE_COL_VO_RESPOND
‪#define WEAPON_TABLE_COL_VO_RESPOND
Definition: _zm_weapons.gsh:6
‪is_player_valid
‪function is_player_valid(player, checkIgnoreMeFlag, ignore_laststand_players)
Definition: skeleton.gsc:256
‪createBallisticKnifeWatcher_zm
‪function createBallisticKnifeWatcher_zm(weaponName)
Definition: _zm_weapons.gsc:515
‪is_tactical_grenade
‪function is_tactical_grenade(weapon)
Definition: _zm_utility.gsc:4215
‪on_spawn
‪function on_spawn(watcher, owner)
Definition: _decoy.gsc:35
‪init_weapon_upgrade
‪function init_weapon_upgrade()
Definition: _zm_weapons.gsc:1380
‪change_melee_weapon
‪function change_melee_weapon(weapon, current_weapon)
Definition: _zm_melee_weapon.gsc:344
‪has_upgrade
‪function has_upgrade(weapon)
Definition: _zm_weapons.gsc:1806
‪get_weapon_cost
‪function get_weapon_cost(weapon)
Definition: _zm_weapons.gsc:1424
‪is_wallbuy
‪function is_wallbuy(w_to_check)
Definition: _zm_weapons.gsc:3568
‪ZM_MAP_EVENT_PURCHASE_AMMO
‪#define ZM_MAP_EVENT_PURCHASE_AMMO
Definition: _zm_utility.gsh:46
‪switch_back_primary_weapon
‪function switch_back_primary_weapon(oldprimary, immediate=false)
Definition: _zm_weapons.gsc:280
‪increment_challenge_stat
‪function increment_challenge_stat(stat_name, amount=1)
Definition: _zm_stats.gsc:478
‪watchWeaponChangeZM
‪function watchWeaponChangeZM()
Definition: _zm_weapons.gsc:452
‪pers_nube_should_we_give_raygun
‪function pers_nube_should_we_give_raygun(player_has_weapon, player, weapon_buy)
Definition: _zm_pers_upgrades_functions.gsc:22
‪player_give_loadout
‪function player_give_loadout(loadout, replace_existing=true, immediate_switch=false)
Definition: _zm_weapons.gsc:3280
‪WEAPON_TABLE_COL_AMMO_COST
‪#define WEAPON_TABLE_COL_AMMO_COST
Definition: _zm_weapons.gsh:7
‪init_spawnable_weapon_upgrade
‪function init_spawnable_weapon_upgrade()
Definition: _zm_weapons.gsc:836
‪is_weapon_upgraded
‪function is_weapon_upgraded(weapon)
Definition: _zm_weapons.gsc:1725
‪wall_weapon_update_prompt
‪function wall_weapon_update_prompt(player)
Definition: _zm_weapons.gsc:1176
‪DEFAULT
‪#define DEFAULT(__var, __default)
Definition: shared.gsh:270
‪grenade_safe_to_throw
‪function grenade_safe_to_throw(player, weapon)
Definition: _zm_weapons.gsc:124
‪watchForGrenadeLauncherDuds
‪function watchForGrenadeLauncherDuds()
Definition: _zm_weapons.gsc:110
‪wait_timeout
‪function wait_timeout(time)
Definition: _zm_weapons.gsc:194
‪can_upgrade_weapon
‪function can_upgrade_weapon(weapon)
Definition: _zm_weapons.gsc:1675
‪get_base_weapon
‪function get_base_weapon(upgradedweapon)
Definition: _zm_weapons.gsc:1624
‪waittill_any_ex
‪function waittill_any_ex(...)
Definition: util_shared.csc:270
‪weapondata_take
‪function weapondata_take(weapondata)
Definition: _zm_weapons.gsc:3209
‪get_weapon_hint_ammo
‪function get_weapon_hint_ammo()
Definition: _zm_weapons.gsc:1936
‪minus_to_player_score
‪function minus_to_player_score(points)
Definition: _zm_score.gsc:551
‪include_zombie_weapon
‪function include_zombie_weapon(weapon_name, in_box)
Definition: _zm_weapons.gsc:658
‪can_player_purchase
‪function can_player_purchase(n_cost)
Definition: _zm_score.gsc:655
‪has_powerup_weapon
‪function has_powerup_weapon()
Definition: _zm_utility.gsc:4519
‪get_upgraded_ammo_cost
‪function get_upgraded_ammo_cost(weapon)
Definition: _zm_weapons.gsc:1438
‪weapondata_give
‪function weapondata_give(weapondata)
Definition: _zm_weapons.gsc:3158
‪clear_stowed_weapon
‪function clear_stowed_weapon()
Definition: _zm_weapons.gsc:3340
‪set_player_tactical_grenade
‪function set_player_tactical_grenade(weapon)
Definition: _zm_utility.gsc:4250
‪set_player_placeable_mine
‪function set_player_placeable_mine(weapon)
Definition: _zm_utility.gsc:4304
‪init_weapons
‪function init_weapons()
Definition: _zm_weapons.gsc:674
‪pers_nube_weapon_upgrade_check
‪function pers_nube_weapon_upgrade_check(player, weapon)
Definition: _zm_pers_upgrades_functions.gsc:23
‪get_player_placeable_mine
‪function get_player_placeable_mine()
Definition: _zm_utility.gsc:4291
‪WEAPON_TABLE_COL_UPGRADE_LIMIT
‪#define WEAPON_TABLE_COL_UPGRADE_LIMIT
Definition: _zm_weapons.gsh:14
‪WEAPON_TABLE_COL_AUTOSPAWN
‪#define WEAPON_TABLE_COL_AUTOSPAWN
Definition: _zm_weapons.gsh:16
‪register_zombie_weapon_callback
‪function register_zombie_weapon_callback(weapon, func)
Definition: _zm_weapons.gsc:3317
‪is_enabled
‪function is_enabled(name)
Definition: _zm_bgb.gsc:4
‪include_weapon
‪function include_weapon(weapon_name, in_box)
Definition: _zm_utility.gsc:3515
‪halve_score
‪function halve_score(n_score)
Definition: _zm_utility.csc:70
‪is_offhand_weapon
‪function is_offhand_weapon(weapon)
Definition: _zm_utility.gsc:4507
‪init
‪function init()
Definition: _zm_weapons.gsc:52
‪give_build_kit_weapon
‪function give_build_kit_weapon(weapon)
Definition: _zm_weapons.gsc:2543
‪give_start_weapons
‪function give_start_weapons(takeAllWeapons, alreadySpawned)
Definition: _zm_weapons.gsc:264
‪weaponobjects_on_player_connect_override_internal
‪function weaponobjects_on_player_connect_override_internal()
Definition: _zm_weapons.gsc:475
‪WEAPON_TABLE_COL_HINT
‪#define WEAPON_TABLE_COL_HINT
Definition: _zm_weapons.gsh:3
‪is_pers_double_points_active
‪function is_pers_double_points_active()
Definition: _zm_pers_upgrades_functions.gsc:12
‪weapon_supports_this_attachment
‪function weapon_supports_this_attachment(weapon, att)
Definition: _zm_weapons.gsc:1599
‪register_aat_exemption
‪function register_aat_exemption(weapon)
Definition: aat_shared.gsc:366
‪has_weapon_or_upgrade
‪function has_weapon_or_upgrade(weapon)
Definition: _zm_weapons.gsc:1830
‪get_ammo_cost
‪function get_ammo_cost(weapon)
Definition: _zm_weapons.gsc:1431
‪player_take_loadout
‪function player_take_loadout(loadout)
Definition: _zm_weapons.gsc:3307
‪can_swap_attachments
‪function can_swap_attachments()
Definition: _zm_pack_a_punch_util.gsc:94
‪is_hero_weapon
‪function is_hero_weapon(weapon)
Definition: _zm_utility.gsc:4408
‪switch_from_alt_weapon
‪function switch_from_alt_weapon(weapon)
Definition: _zm_weapons.gsc:240
‪decide_hide_show_hint
‪function decide_hide_show_hint(endon_notify, second_endon_notify, onlyplayer, can_buy_weapon_extra_check_func)
Definition: _zm_magicbox.gsc:1302
‪get_player_tactical_grenade
‪function get_player_tactical_grenade()
Definition: _zm_utility.gsc:4237
‪add_dynamic_wallbuy
‪function add_dynamic_wallbuy(weapon, wallbuy, pristine)
Definition: _zm_weapons.gsc:1027
‪Spawn
‪function Spawn(parent, onDeathCallback)
Definition: _flak_drone.gsc:427
‪weapon_take
‪function weapon_take(weapon)
Definition: _zm_weapons.gsc:2829
‪is_limited
‪function is_limited(equipment)
Definition: _zm_equipment.gsc:438
‪get_player_weapon_with_same_base
‪function get_player_weapon_with_same_base(weapon)
Definition: _zm_weapons.gsc:1911
‪melee_weapon_think
‪function melee_weapon_think(weapon, cost, flourish_fn, vo_dialog_id, flourish_weapon, ballistic_weapon, ballistic_upgraded_weapon)
Definition: _zm_melee_weapon.gsc:415
‪suppress_stowed_weapon
‪function suppress_stowed_weapon(onOff)
Definition: _zm_weapons.gsc:3346
‪autofill_wallbuys_init
‪function autofill_wallbuys_init()
Definition: _zm_weapons.gsc:3450
‪WEAPON_TABLE_COL_IS_WONDER_WEAPON
‪#define WEAPON_TABLE_COL_IS_WONDER_WEAPON
Definition: _zm_weapons.gsh:19
‪set_player_hero_weapon
‪function set_player_hero_weapon(weapon)
Definition: _zm_utility.gsc:4443
‪placeable_mine_can_buy_weapon_extra_check_func
‪function placeable_mine_can_buy_weapon_extra_check_func(w_weapon)
Definition: _zm_weapons.gsc:1984
‪ignore_triggers
‪function ignore_triggers(timer)
Definition: _zm_utility.csc:21
‪checkGrenadeForDud
‪function checkGrenadeForDud(weapon, isThrownGrenade, player)
Definition: _zm_weapons.gsc:155
‪WEAPON_TABLE_COL_COST
‪#define WEAPON_TABLE_COL_COST
Definition: _zm_weapons.gsh:4
‪weapon_spawn_think
‪function weapon_spawn_think()
Definition: _zm_weapons.gsc:1994
‪has_any_ballistic_knife
‪function has_any_ballistic_knife()
Definition: _zm_melee_weapon.gsc:295
‪play_weapon_vo
‪function play_weapon_vo(weapon, magic_box)
Definition: _zm_weapons.gsc:2838
‪set
‪function set(str_field_name, n_value)
Definition: clientfield_shared.gsc:34
‪is_grenade
‪function is_grenade(weapon)
Definition: weapons_shared.gsc:30
‪setupRetrievableWatcher
‪function setupRetrievableWatcher()
Definition: _weaponobjects.gsc:241
‪get_player_lethal_grenade
‪function get_player_lethal_grenade()
Definition: _zm_utility.gsc:4167
‪WEAPON_TABLE_COL_UPGRADE_NAME
‪#define WEAPON_TABLE_COL_UPGRADE_NAME
Definition: _zm_weapons.gsh:2
‪createUseWeaponObjectWatcher
‪function createUseWeaponObjectWatcher(weaponname, ownerTeam)
Definition: _weaponobjects.gsc:1297
‪add_weapon_to_content
‪function add_weapon_to_content(weapon_name, package)
Definition: _zm_weapons.gsc:810
‪get_upgrade_weapon
‪function get_upgrade_weapon(weapon, add_attachment)
Definition: _zm_weapons.gsc:1639
‪random_attachment
‪function random_attachment(weapon, exclude)
Definition: _zm_weapons.gsc:1534
‪get_pack_a_punch_camo_index
‪function get_pack_a_punch_camo_index(prev_pap_index)
Definition: _zm_weapons.gsc:2457
‪zmbVoxAdd
‪function zmbVoxAdd(category, subcategory, suffix, percentage, response, delayBeforePlayAgain=0)
Definition: _zm_audio.gsc:580
‪take_fallback_weapon
‪function take_fallback_weapon()
Definition: _zm_weapons.gsc:275
‪trackWeaponFire
‪function trackWeaponFire(curWeapon)
Definition: _weapons.gsc:465
‪updateLastHeldWeaponTimingsZM
‪function updateLastHeldWeaponTimingsZM(newTime)
Definition: _zm_weapons.gsc:414
‪is_melee_weapon
‪function is_melee_weapon(weapon)
Definition: _zm_utility.gsc:4339
‪set_hint_string
‪function set_hint_string(ent, default_ref, cost)
Definition: _zm_utility.gsc:2948
‪WEAPON_TABLE_COL_AAT_EXEMPT
‪#define WEAPON_TABLE_COL_AAT_EXEMPT
Definition: _zm_weapons.gsh:18
‪trackWeaponZM
‪function trackWeaponZM()
Definition: _zm_weapons.gsc:380
‪weapon_give
‪function weapon_give(weapon, is_upgrade=false, magic_box=false, nosound=false, b_switch_weapon=true)
Definition: _zm_weapons.gsc:2603
‪setup_watchers
‪function setup_watchers()
Definition: _zm_placeable_mine.gsc:391
‪get_pack_a_punch_weapon_options
‪function get_pack_a_punch_weapon_options(weapon)
Definition: _zm_weapons.gsc:2482
‪weapon_is_better
‪function weapon_is_better(left, right)
Definition: _zm_weapons.gsc:3087
‪register
‪function register()
Definition: _ai_tank.gsc:126
‪WEAPON_TABLE_COL_IN_BOX
‪#define WEAPON_TABLE_COL_IN_BOX
Definition: _zm_weapons.gsh:10
‪WEAPON_TABLE_COL_FORCE_ATTACHMENTS
‪#define WEAPON_TABLE_COL_FORCE_ATTACHMENTS
Definition: _zm_weapons.gsh:20
‪create_and_play_dialog
‪function create_and_play_dialog(category, subcategory, force_variant)
Definition: _zm_audio.gsc:603
‪unitrigger_force_per_player_triggers
‪function unitrigger_force_per_player_triggers(unitrigger_stub, opt_on_off)
Definition: _zm_unitrigger.gsc:58
‪set_player_lethal_grenade
‪function set_player_lethal_grenade(weapon)
Definition: _zm_utility.gsc:4180
‪give
‪function give(killstreakType, streak, suppressNotification, noXP, toBottom)
Definition: _killstreaks.gsc:539
‪on_connect
‪function on_connect()
Definition: _arena.gsc:20
‪WEAPON_TABLE_COL_CONTENT_RESTRICT
‪#define WEAPON_TABLE_COL_CONTENT_RESTRICT
Definition: _zm_weapons.gsh:15
‪on_spawn_retrieve_trigger
‪function private on_spawn_retrieve_trigger(watcher, player)
Definition: _zm_placeable_mine.gsc:411
‪register_static_unitrigger
‪function register_static_unitrigger(unitrigger_stub, trigger_func, recalculate_zone)
Definition: _zm_unitrigger.gsc:236
‪name
‪class GroundFx name
‪is_placeable_mine
‪function is_placeable_mine(weapon)
Definition: _zm_utility.gsc:4267
‪give_fallback_weapon
‪function give_fallback_weapon(immediate=false)
Definition: _zm_weapons.gsc:270
‪get_player_weapondata
‪function get_player_weapondata(player, weapon)
Definition: _zm_weapons.gsc:3033
‪watchGrenadeUsage
‪function watchGrenadeUsage()
Definition: _weapons.gsc:508
‪add_stub
‪function add_stub(stub, weapon)
Definition: _zm_melee_weapon.gsc:154
‪default_check_firesale_loc_valid_func
‪function default_check_firesale_loc_valid_func()
Definition: _zm_weapons.gsc:524
‪add_retrievable_knife_init_name
‪function add_retrievable_knife_init_name(name)
Definition: _zm_weapons.gsc:333
‪weaponobjects_on_player_connect_override
‪function weaponobjects_on_player_connect_override()
Definition: _zm_weapons.gsc:507
‪can_buy_weapon
‪function can_buy_weapon()
Definition: _zm_magicbox.gsc:937
‪spawn_weapon_model
‪function spawn_weapon_model(localClientNum, origin, angles)
Definition: _weapon_customization_icon.csc:141
‪player_can_use_content
‪function player_can_use_content(weapon)
Definition: _zm_weapons.gsc:820
‪grenade_safe_to_bounce
‪function grenade_safe_to_bounce(player, weapon)
Definition: _zm_weapons.gsc:133
‪WAIT_SERVER_FRAME
‪#define WAIT_SERVER_FRAME
Definition: shared.gsh:265
‪add_shared_ammo_weapon
‪function add_shared_ammo_weapon(weapon, base_weapon)
Definition: _zm_weapons.gsc:1865
‪get_eye
‪function get_eye()
Definition: util_shared.csc:948