‪Black Ops 3 Source Code Explorer  0.1
‪An script explorer for Black Ops 3 by ZeRoY
_zm_weap_gravityspikes.gsc
Go to the documentation of this file.
1 #using scripts\codescripts\struct;
2 
3 #using scripts\shared\array_shared;
4 #using scripts\shared\callbacks_shared;
5 #using scripts\shared\clientfield_shared;
6 #using scripts\shared\flag_shared;
7 #using scripts\shared\hud_util_shared;
8 #using scripts\shared\laststand_shared;
9 #using scripts\shared\math_shared;
10 #using scripts\shared\system_shared;
11 #using scripts\shared\throttle_shared;
12 #using scripts\shared\util_shared;
13 #using scripts\shared\scene_shared;
14 
15 #using scripts\zm\_zm;
16 #using scripts\zm\_zm_audio;
17 #using scripts\zm\_zm_bgb;
18 #using scripts\zm\_zm_equipment;
19 #using scripts\zm\_zm_laststand;
20 #using scripts\zm\_zm_net;
21 #using scripts\zm\_zm_powerups;
22 #using scripts\zm\_zm_spawner;
23 #using scripts\zm\_zm_unitrigger;
24 #using scripts\zm\_zm_utility;
25 #using scripts\zm\_zm_weapons;
26 #using scripts\zm\_zm_hero_weapon;
27 
28 #using scripts\shared\ai\systems\gib;
29 #using scripts\shared\ai\zombie_death;
30 #using scripts\shared\ai\zombie_shared;
31 #using scripts\shared\ai\zombie_utility;
32 #using scripts\shared\ai\zombie_vortex;
33 
34 #using scripts\shared\abilities\_ability_player;
35 
36 #insert scripts\shared\ai\systems\blackboard.gsh;
37 #insert scripts\shared\shared.gsh;
38 #insert scripts\shared\version.gsh;
39 #insert scripts\shared\abilities\_ability_util.gsh;
40 #insert scripts\zm\_zm_utility.gsh;
41 #insert scripts\zm\_zm_weap_gravityspikes.gsh;
42 #insert scripts\shared\archetype_shared\archetype_shared.gsh;
43 #insert scripts\shared\ai\zombie_vortex.gsh;
44 
45 #precache( "string", "ZOMBIE_GRAVITYSPIKE_RECHARGED" );
46 #precache( "model", "wpn_zmb_dlc1_talon_spike_single_world" );
47 
48 #namespace zm_weap_gravityspikes;
49 
50 ‪REGISTER_SYSTEM( "zm_weap_gravityspikes", &‪__init__, undefined )
51 
52 #define V_GROUND_OFFSET_FUDGE ( 0, 0, 32 )
53 
54 #define N_GRAVITYSPIKES_ACTIVE_TIME 20
55 #define V_PHYSICSTRACE_CAPSULE_MIN ( -16, -16, -16 )
56 #define V_PHYSICSTRACE_CAPSULE_MAX ( 16, 16, 16 )
57 
58 #define N_MAX_ZOMBIES_LIFTED_FOR_RAGDOLL 12
59 #define N_GRAVITYSPIKES_LOS_HEIGHT_OFFSET 50
60 
61 #define N_GRAVITYSPIKES_MELEE_KILL_RADIUS 200
62 #define N_GRAVITYSPIKES_KNOCKDOWN_RADIUS 400
63 
64 #define N_GRAVITYSPIKES_MELEE_HEIGHT 96
65 #define N_GRAVITYSPIKES_MELEE_PUSH_AWAY 128
66 #define N_GRAVITY_MELEE_LIFT_HEIGHT_MIN 128
67 #define N_GRAVITY_MELEE_LIFT_HEIGHT_MAX 200
68 #define N_GRAVITY_MELEE_MIN_LIFT_SPEED 150
69 #define N_GRAVITY_MELEE_MAX_LIFT_SPEED 200
70 
71 #define N_GRAVITY_TRAP_SEPERATION 24
72 #define N_GRAVITY_TRAP_HEIGHT 96
73 #define N_GRAVITY_TRAP_PUSH_AWAY 0
74 #define N_GRAVITY_TRAP_LIFT_HEIGHT_MIN 184
75 #define N_GRAVITY_TRAP_LIFT_HEIGHT_MAX 284
76 #define N_GRAVITY_TRAP_MIN_LIFT_SPEED 64
77 #define N_GRAVITY_TRAP_MAX_LIFT_SPEED 128
78 #define N_GRAVITY_TRAP_MAX_LIFT_TIME 10
79 #define V_GRAVITY_TRAP_LIFT_AMOUNT_OFFSET ( 0, 0, -24 )
80 
81 #define N_GRAVITYSPIKE_HINT_TIMER 3
82 
83 #define B_DISABLE_GIBBING 0
84 #define SPIKES_CHOP_CONE_RANGE 120
85 
86 function ‪__init__()
87 {
88  level.n_zombies_lifted_for_ragdoll = 0;
89 
90  level.spikes_chop_cone_range = ‪SPIKES_CHOP_CONE_RANGE;
91  level.spikes_chop_cone_range_sq = level.spikes_chop_cone_range * level.spikes_chop_cone_range;
92 
93  // throttle used to spread the lifting behavior/reaction of the gravity spikes
94  level.ai_gravity_throttle = new ‪Throttle();
95  [[ level.ai_gravity_throttle ]]->Initialize( 2, 0.1 );
96 
97  // throttle used for spreading chopping of actors
98  level.ai_spikes_chop_throttle = new ‪Throttle();
99  [[ level.ai_spikes_chop_throttle ]]->Initialize( 6, 0.1 );
100 
102 
104 
105  ‪zm_hero_weapon::register_hero_weapon( ‪STR_GRAVITYSPIKES_NAME ); // prevents Gravity Spikes from replacing a weapon in player's inventory
109 
111 }
112 
114 {
115  ‪clientfield::register( "actor", "gravity_slam_down", ‪VERSION_SHIP, 1, "int" );
116  ‪clientfield::register( "scriptmover", "gravity_trap_fx", ‪VERSION_SHIP, 1, "int" );
117  ‪clientfield::register( "scriptmover", "gravity_trap_spike_spark", ‪VERSION_SHIP, 1, "int" );
118  ‪clientfield::register( "scriptmover", "gravity_trap_destroy", ‪VERSION_SHIP, 1, "counter" );
119  ‪clientfield::register( "scriptmover", "gravity_trap_location", ‪VERSION_SHIP, 1, "int" );
120  ‪clientfield::register( "scriptmover", "gravity_slam_fx", ‪VERSION_SHIP, 1, "int" );
121  ‪clientfield::register("toplayer", "gravity_slam_player_fx", ‪VERSION_SHIP, 1, "counter" );
122  ‪clientfield::register( "actor", "sparky_beam_fx", ‪VERSION_SHIP, 1, "int" );
123  ‪clientfield::register("actor", "sparky_zombie_fx", ‪VERSION_SHIP, 1, "int" );
124  ‪clientfield::register("actor", "sparky_zombie_trail_fx", ‪VERSION_SHIP, 1, "int" );
125  ‪clientfield::register("toplayer", "gravity_trap_rumble", ‪VERSION_SHIP, 1, "int" );
126  ‪clientfield::register("actor", "ragdoll_impact_watch", ‪VERSION_SHIP, 1, "int" );
127  ‪clientfield::register( "actor", "gravity_spike_zombie_explode_fx", ‪VERSION_TU12, 1, "counter" );
128 }
129 
130 function private ‪on_connect_func_for_gravityspikes() // self == a player
131 {
132  self endon( "disconnect" );
133  self endon( "bled_out" );
134  self endon( "death" );
135  self endon( "gravity_spike_expired" );
136 
137  w_gravityspike = GetWeapon( ‪STR_GRAVITYSPIKES_NAME );
139  self.b_gravity_trap_spikes_in_ground = false;
140  self.disable_hero_power_charging = false;
141  self.b_gravity_trap_fx_on = false;
142 
143  // This will cleanup status of Gravity Spikes if player bleeeds out and loses all weapons
144  self thread ‪reset_after_bleeding_out();
145 
146  // Wait for player to pick up Gravity Spikes
147  do
148  {
149  self waittill( "new_hero_weapon", weapon ); // from zm_utility::set_player_hero_weapon() which is called by zm_weapons::weapon_give()
150  }
151  while( weapon != w_gravityspike );
152 
153  if( isdefined( self.a_gravityspikes_prev_ammo_clip ) && isdefined( self.a_gravityspikes_prev_ammo_clip[ ‪STR_GRAVITYSPIKES_NAME ] ) )
154  {
155  self SetWeaponAmmoClip( w_gravityspike, self.a_gravityspikes_prev_ammo_clip[ ‪STR_GRAVITYSPIKES_NAME ] );
156  self.a_gravityspikes_prev_ammo_clip = undefined;
157  }
158  else
159  {
160  self SetWeaponAmmoClip( w_gravityspike, w_gravityspike.clipSize );
161  }
162 
163  if( isdefined( self.saved_spike_power ) )
164  {
165  self GadgetPowerSet( self GadgetGetSlot( w_gravityspike ), self.saved_spike_power );
166  self.saved_spike_power = undefined;
167  }
168  else
169  {
170  self GadgetPowerSet( self GadgetGetSlot( w_gravityspike ), 100 );
171  }
172 
173  self.gravity_trap_unitrigger_stub = undefined;
174 
175  self thread ‪weapon_drop_watcher();
176  self thread ‪weapon_change_watcher();
177 
178 }
179 
180 // ------------------------------------------------------------------------------------------------------------
181 function ‪reset_after_bleeding_out() // self == a player
182 {
183  self endon( "disconnect" );
184 
185  w_gravityspike = GetWeapon( ‪STR_GRAVITYSPIKES_NAME );
186 
187  // Give back weapon if they had it when bled out and reset its ammo
188  if( ‪IS_TRUE( self.b_has_gravityspikes ) )
189  {
190  ‪util::wait_network_frame(); // wait for connect function to wait.
191 
192  self ‪zm_weapons::weapon_give( w_gravityspike, false, true );
194  }
195 
196  self waittill( "bled_out" ); //, "gravity_spike_expired" );
197 
198  // Upon bleeding out save ammo state and if have weapon.
199  if ( self HasWeapon( w_gravityspike ) )
200  {
201  self.b_has_gravityspikes = true;
202 
203  self.saved_spike_power = self GadgetPowerGet( self GadgetGetSlot( w_gravityspike ) );
204 
205  // if full power no need to save off.
206  if( self.saved_spike_power >= 100 )
207  {
208  self.saved_spike_power = undefined;
209  }
210 
211  self.a_gravityspikes_prev_ammo_clip[ ‪STR_GRAVITYSPIKES_NAME ] = self GetWeaponAmmoClip( w_gravityspike );
212  }
213 
214  if( isdefined( self.gravity_trap_unitrigger_stub ) )
215  {
216  ‪zm_unitrigger::unregister_unitrigger( self.gravity_trap_unitrigger_stub );
217  self.gravity_trap_unitrigger_stub = undefined;
218  }
219 
220  self waittill("spawned_player");
221 
223 }
224 
225 // ------------------------------------------------------------------------------------------------------------
226 function ‪gravityspikes_power_override( e_player, ai_enemy ) // self = level
227 {
228  const N_HERO_MINPOWER = 0;
229  const N_HERO_MAXPOWER = 100;
230 
231  //no recharge in last stand
232  if ( e_player ‪laststand::player_is_in_laststand() )
233  {
234  return;
235  }
236 
237  // no recharge from the gravity spikes themselves
238  if ( ‪IS_EQUAL( ai_enemy.damageweapon, GetWeapon( ‪STR_GRAVITYSPIKES_NAME ) ) )
239  {
240  return;
241  }
242 
243  // do not allow spikes to recharge if player has not picked up.
244  if( ‪IS_TRUE( e_player.disable_hero_power_charging ) )
245  {
246  return;
247  }
248 
249  if( isdefined( e_player ) && isdefined(e_player.hero_power) )
250  {
251  w_gravityspike = GetWeapon( ‪STR_GRAVITYSPIKES_NAME );
252  if( isdefined( ai_enemy.heroweapon_kill_power ) )
253  {
254  n_perk_factor = 1.0;
255  if ( e_player hasperk( "specialty_overcharge" ) )
256  {
257  n_perk_factor = GetDvarFloat( "gadgetPowerOverchargePerkScoreFactor" );
258  }
259 
260  //reduce elemental bow power gains by 0.25
261  if ( IsDefined(ai_enemy.damageweapon) &&
262  (IsSubStr( ai_enemy.damageweapon.name, "elemental_bow_demongate" ) || IsSubStr( ai_enemy.damageweapon.name, "elemental_bow_run_prison" ) ||
263  IsSubStr( ai_enemy.damageweapon.name, "elemental_bow_storm" ) || IsSubStr( ai_enemy.damageweapon.name, "elemental_bow_wolf_howl" )) )
264  {
265  n_perk_factor = 0.25;
266  }
267 
268  e_player.hero_power = e_player.hero_power + n_perk_factor * ( ai_enemy.heroweapon_kill_power );
269 
270  e_player.hero_power = ‪math::clamp( e_player.hero_power, N_HERO_MINPOWER, N_HERO_MAXPOWER );
271  if ( e_player.hero_power >= e_player.hero_power_prev )
272  {
273  e_player GadgetPowerSet( e_player GadgetGetSlot( w_gravityspike ), e_player.hero_power );
274  e_player ‪clientfield::set_player_uimodel( "zmhud.swordEnergy", e_player.hero_power / 100 );
275  e_player ‪clientfield::increment_uimodel( "zmhud.swordChargeUpdate" );
276  }
277 
278  if( e_player.hero_power >= 100 )
279  {
281  }
282  }
283  }
284 }
285 
286 // ------------------------------------------------------------------------------------------------------------
287 function ‪wield_gravityspikes( wpn_gravityspikes ) //self = player
288 {
289  self ‪zm_hero_weapon::default_wield( wpn_gravityspikes );
290 
291  if( !‪IS_TRUE( self.b_used_spikes ) )
292  {
293  if ( isdefined(self.hintelem) ) // if hint text still on screen destroy immediately
294  {
295  self.hintelem settext("");
296  self.hintelem ‪destroy();
297  }
298 
299  self thread ‪zm_equipment::show_hint_text( &"ZOMBIE_GRAVITYSPIKE_INSTRUCTIONS", ‪N_GRAVITYSPIKE_HINT_TIMER );
300  self.b_used_spikes = true;
301  }
302 
304 
305  self thread ‪gravityspikes_attack_watcher( wpn_gravityspikes ); // RT attack
306  self thread ‪gravityspikes_stuck_above_zombie_watcher( wpn_gravityspikes ); //RT attack - stuck above zombies
307  self thread ‪gravityspikes_altfire_watcher( wpn_gravityspikes ); // LT attack
308  self thread ‪gravityspikes_swipe_watcher( wpn_gravityspikes ); // R3 attack
309 }
310 
311 function ‪unwield_gravityspikes( wpn_gravityspikes )
312 {
313  self ‪zm_hero_weapon::default_unwield( wpn_gravityspikes );
314 
315  self notify( "gravityspikes_attack_watchers_end" );
316 
317  if( ‪IS_TRUE( self.b_gravity_trap_spikes_in_ground ) )
318  {
319  self.disable_hero_power_charging = true;
320  self thread ‪zm_hero_weapon::continue_draining_hero_weapon( wpn_gravityspikes );
321  // Gravity Trap logic
322  self thread ‪gravity_trap_loop( self.v_gravity_trap_pos, wpn_gravityspikes );
323  }
324 }
325 
326 function ‪weapon_drop_watcher() // self = player
327 {
328  self endon( "disconnect" );
329 
330  while ( true )
331  {
332  self waittill( "weapon_switch_started", w_current );
333  if ( ‪zm_utility::is_hero_weapon( w_current ) )
334  {
335  self SetWeaponAmmoClip( w_current, 0 );
336  }
337  }
338 }
339 
340 function ‪weapon_change_watcher() // self = player
341 {
342  self endon( "disconnect" );
343 
344  while ( true )
345  {
346  self waittill( "weapon_change", w_current, w_previous );
347  if ( isdefined( w_previous ) && ‪zm_utility::is_hero_weapon( w_current ) )
348  {
349  self.w_gravityspikes_wpn_prev = w_previous;
350  }
351  }
352 }
353 
354 function ‪gravityspikes_attack_watcher( wpn_gravityspikes ) // self == a player
355 {
356  self endon( "gravityspikes_attack_watchers_end" );
357  self endon( "disconnect" );
358  self endon( "bled_out" );
359  self endon( "death" );
360  self endon( "gravity_spike_expired" );
361 
362  while ( true )
363  {
364  self waittill( "weapon_melee_power", weapon );
365 
366  if ( weapon == wpn_gravityspikes )
367  {
368  self PlayRumbleOnEntity( "talon_spike" );
369  self thread ‪knockdown_zombies_slam();
370  self thread ‪no_damage_gravityspikes_slam(); // prevent player from getting hurt while slamming
371  }
372  }
373 }
374 
375 function ‪gravityspikes_stuck_above_zombie_watcher( wpn_gravityspikes )
376 {
377  self endon( "gravityspikes_attack_watchers_end" );
378  self endon( "disconnect" );
379  self endon( "bled_out" );
380  self endon( "death" );
381  self endon( "gravity_spike_expired" );
382 
383  first_half_traces = true;
384 
385  while ( ‪zm_utility::is_player_valid( self ) )
386  {
387  if( !(self IsSlamming()) )
388  {
389  wait 0.05;
390  continue;
391  }
392 
393  while ( (self IsSlamming()) && (self GetCurrentWeapon()) == wpn_gravityspikes )
394  {
395  //Apply 6 traces around the player while he is slamming to detect if he is stuck
396  player_angles = self GetPlayerAngles();
397 
398  forward_vec = AnglesToForward( (0, player_angles[1], 0) );
399 
400  if(forward_vec[0] == 0 && forward_vec[1] == 0 && forward_vec[2] == 0)
401  {
402  wait 0.05;
403  continue;
404  }
405 
406  forward_right_45_vec = RotatePoint(forward_vec, (0, 45, 0));
407  forward_left_45_vec = RotatePoint(forward_vec, (0, -45, 0));
408 
409  right_vec = AnglesToRight(player_angles);
410 
411  //end_height = GetDvarInt("gravityspikes_stuck_end_height", -35);
412  end_height = -35;
413 
414  start_point = self.origin + ( 0, 0, 50 );
415  end_point = self.origin + ( 0, 0, end_height );
416 
417  //end_radius = GetDvarInt("gravityspikes_stuck_end_radius", 30);
418  end_radius = 30;
419 
420  trace_end_points = [];
421 
422  if(first_half_traces) //forward, right, left
423  {
424  trace_end_points[0] = end_point + VectorScale(forward_vec, end_radius);
425  trace_end_points[1] = end_point + VectorScale(right_vec, end_radius);
426  trace_end_points[2] = end_point - VectorScale(right_vec, end_radius);
427 
428  first_half_traces = false;
429  }
430  else //forward_45_right, forward_45_left, backward
431  {
432  trace_end_points[0] = end_point + VectorScale(forward_right_45_vec, end_radius);
433  trace_end_points[1] = end_point + VectorScale(forward_left_45_vec, end_radius);
434  trace_end_points[2] = end_point - VectorScale(forward_vec, end_radius);
435 
436 
437  first_half_traces = true;
438  }
439 
440  for( i = 0; i < 3; i++ )
441  {
442  ‪trace = BulletTrace(start_point, trace_end_points[i], true, self);
443 
444  if( ‪trace["fraction"] < 1 )
445  {
446  if( IsActor(‪trace["entity"]) && (‪trace["entity"].Health > 0) && (‪trace["entity"].archetype == ‪ARCHETYPE_ZOMBIE || ‪trace["entity"].archetype == ‪ARCHETYPE_ZOMBIE_DOG) )
447  {
448  self thread ‪knockdown_zombies_slam();
449  self thread ‪no_damage_gravityspikes_slam(); // prevent player from getting hurt while slamming
450 
451  wait 1;
452  break;
453  }
454  }
455  }
456 
457  wait 0.05;
458  }
459 
460  wait 0.05;
461  }
462 }
463 
464 function ‪gravityspikes_altfire_watcher( wpn_gravityspikes ) // self == a player
465 {
466  self endon( "gravityspikes_attack_watchers_end" );
467  self endon( "disconnect" );
468  self endon( "bled_out" );
469  self endon( "death" );
470  self endon( "gravity_spike_expired" );
471 
472  while ( true )
473  {
474  self waittill( "weapon_melee_power_left", weapon );
475 
476  if ( weapon == wpn_gravityspikes && self ‪gravity_spike_position_valid() )
477  {
478  self thread ‪plant_gravity_trap( wpn_gravityspikes );
479  }
480  }
481 }
482 
483 //check to make sure position is valid
484 function ‪gravity_spike_position_valid() // self = player
485 {
486  if( isdefined( level.gravityspike_position_check ) )
487  {
488  return ( self [[level.gravityspike_position_check]]() );
489  }
490  else if( IsPointOnNavMesh( self.origin, self ) )
491  {
492  return true;
493  }
494 }
495 
496 function ‪chop_actor( ai, leftswing, weapon = level.weaponNone )
497 {
498  self endon( "disconnect" );
499 
500  const N_SPIKES_AUTOKILL_DAMAGE = 3594; //round23
501 
502  if( !isdefined( ai ) || !IsAlive( ai ) )
503  {
504  // guy died on us
505  return;
506  }
507 
508  if ( N_SPIKES_AUTOKILL_DAMAGE >= ai.health )
509  {
510  ai.ignoreMelee = true;
511  }
512 
513  [[ level.ai_spikes_chop_throttle ]]->WaitInQueue( ai );
514 
515  ai DoDamage( N_SPIKES_AUTOKILL_DAMAGE, self.origin, self, self, "none", "MOD_UNKNOWN", 0, weapon );
516 
518 }
519 
520 function ‪chop_zombies( first_time, leftswing, weapon = level.weaponNone )
521 {
522  view_pos = self GetWeaponMuzzlePoint();
523  forward_view_angles = self GetWeaponForwardDir();
524 
525 
526  zombie_list = GetAITeamArray( level.zombie_team );
527  foreach( ai in zombie_list )
528  {
529  if ( !IsDefined( ai ) || !IsAlive( ai ) )
530  {
531  continue;
532  }
533 
534  if( first_time )
535  {
536  ai.chopped = false; //reset on first swipe
537  }
538  else if( ‪IS_TRUE(ai.chopped) )
539  {
540  continue;
541  }
542 
543  test_origin = ai getcentroid();
544  dist_sq = DistanceSquared( view_pos, test_origin );
545 
546  dist_to_check = level.spikes_chop_cone_range_sq;
547  if ( dist_sq > dist_to_check )
548  {
549  continue;
550  }
551 
552  normal = VectorNormalize( test_origin - view_pos );
553  dot = VectorDot( forward_view_angles, normal );
554  if (dot <= 0.0 )
555  {
556  continue;
557  }
558 
559  if ( 0 == ai DamageConeTrace( view_pos, self ) )
560  {
561  // guy can't actually be hit from where we are
562  continue;
563  }
564 
565  ai.chopped = true;
566 
567  if ( isdefined( ai.chop_actor_cb ) )
568  {
569  self thread [[ ai.chop_actor_cb ]]( ai, self, weapon );
570  }
571  else
572  {
573  self thread ‪chop_actor( ai, leftswing, weapon );
574  }
575  }
576 }
577 
578 function ‪spikesarc_swipe( player )
579 {
580  player thread ‪chop_zombies( true, true, self );
581  wait( 0.3 );
582  player thread ‪chop_zombies( false, true, self );
583  wait( 0.5 );
584  player thread ‪chop_zombies( false, false, self );
585 }
586 
587 function ‪gravityspikes_swipe_watcher( wpn_gravityspikes ) // self == a player
588 {
589  self endon( "gravityspikes_attack_watchers_end" );
590  self endon( "disconnect" );
591  self endon( "bled_out" );
592  self endon( "death" );
593  self endon( "gravity_spike_expired" );
594 
595  while ( true )
596  {
597  self waittill( "weapon_melee", weapon );
598 
599  weapon thread ‪spikesarc_swipe( self );
600  }
601 }
602 
604 // Power Update - Recharges power as player kills zombies
605 //
607 
608 function ‪gravityspikes_power_update( player ) // self == level
609 {
610  if( !‪IS_TRUE( player.disable_hero_power_charging ) )
611  {
612  player GadgetPowerSet( 0, 100 );
613 
615  }
616 }
617 
619 {
621  self notify( "stop_draining_hero_weapon" );
622  self notify( "gravityspikes_timer_end" );
623 }
624 
626 // Invulnerability - Special cases
627 //
629 
630 function ‪player_invulnerable_during_gravityspike_slam( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, psOffsetTime, boneIndex )
631 {
632  if( self.gravityspikes_state === ‪GRAVITYSPIKES_STATE_INUSE && ( self IsSlamming() || ‪IS_TRUE( self.gravityspikes_slam ) ) )
633  {
634  return 0;
635  }
636  else
637  {
638  return -1;
639  }
640 }
641 
642 function ‪no_damage_gravityspikes_slam() // self == a player
643 {
644  self.gravityspikes_slam = true;
645  wait 1.5; // amount of invulnerability time for player
646  self.gravityspikes_slam = false;
647 }
648 
649 // ------------------------------------------------------------------------------------------------------------
650 // Gravity Trap Planted - Player near
651 // ------------------------------------------------------------------------------------------------------------
652 function ‪player_near_gravity_vortex( v_vortex_origin ) // self = player that planted trap
653 {
654  self endon( "disconnect" );
655  self endon( "bled_out" );
656  self endon( "death" );
657 
658  while( ‪IS_TRUE( self.b_gravity_trap_spikes_in_ground ) && ‪IS_EQUAL( self.gravityspikes_state, ‪GRAVITYSPIKES_STATE_INUSE ) )
659  {
660  foreach( e_player in level.activeplayers )
661  {
662  if( isdefined(e_player) && !‪IS_TRUE( e_player.idgun_vision_on ) )
663  {
664  // If Player is within vortex range, apply vision overlay
665  if( Distance( e_player.origin, v_vortex_origin ) < Float( ‪N_GRAVITY_TRAP_RADIUS / 2 ) )
666  {
668  if( !‪IS_TRUE( e_player.vortex_rumble ) )
669  {
670  self thread ‪player_vortex_rumble( e_player, v_vortex_origin );
671  }
672  }
673  }
674  }
676  }
677 }
678 
679 function ‪player_vortex_rumble( e_player, v_vortex_origin ) // self = player that planted trap
680 {
681  e_player endon( "disconnect" );
682  e_player endon( "bled_out" );
683  e_player endon( "death" );
684 
685  e_player.vortex_rumble = true;
686 
687  e_player ‪clientfield::set_to_player( "gravity_trap_rumble", 1 );
688 
689  while( Distance( e_player.origin, v_vortex_origin ) < Float( ‪N_GRAVITY_TRAP_RADIUS / 2 ) && ‪IS_EQUAL( self.gravityspikes_state, ‪GRAVITYSPIKES_STATE_INUSE ) )
690  {
692  }
693 
694  e_player ‪clientfield::set_to_player( "gravity_trap_rumble", 0 );
695  e_player.vortex_rumble = undefined;
696 }
697 
698 // ------------------------------------------------------------------------------------------------------------
699 // Gravity Trap Planted - Alt fire
700 // ------------------------------------------------------------------------------------------------------------
701 function ‪plant_gravity_trap( wpn_gravityspikes ) // self == a player
702 {
703  self endon( "disconnect" );
704  self endon( "bled_out" );
705  self endon( "death" );
706 
707  v_forward = AnglesToForward( self.angles );
708  v_right = AnglesToRight( self.angles );
709  // Set starting positions
710  v_spawn_pos_right = self.origin + ‪V_GROUND_OFFSET_FUDGE;
711  v_spawn_pos_left = v_spawn_pos_right;
712  // Trace to the right & left
713  a_trace = PhysicsTraceEx( v_spawn_pos_right, v_spawn_pos_right + ( v_right * ‪N_GRAVITY_TRAP_SEPERATION ), ‪V_PHYSICSTRACE_CAPSULE_MIN, ‪V_PHYSICSTRACE_CAPSULE_MAX, self );
714  v_spawn_pos_right += ( v_right * ( a_trace[ "fraction" ] * ‪N_GRAVITY_TRAP_SEPERATION ) );
715  a_trace = PhysicsTraceEx( v_spawn_pos_left, v_spawn_pos_left + ( v_right * -‪N_GRAVITY_TRAP_SEPERATION ), ‪V_PHYSICSTRACE_CAPSULE_MIN, ‪V_PHYSICSTRACE_CAPSULE_MAX, self );
716  v_spawn_pos_left += ( v_right * ( a_trace[ "fraction" ] * -‪N_GRAVITY_TRAP_SEPERATION ) );
717  // Find the ground position
718  v_spawn_pos_right = ‪util::ground_position( v_spawn_pos_right, 1000, 24 );
719  v_spawn_pos_left = ‪util::ground_position( v_spawn_pos_left, 1000, 24 );
720  // "Plant" spikes in ground
721  a_v_spawn_pos = ‪array( v_spawn_pos_right, v_spawn_pos_left );
722  self ‪create_gravity_trap_spikes_in_ground( a_v_spawn_pos );
723 
724  if( self IsOnGround() )
725  {
726  // If player's on the ground, use player's position as center of gravity trap
727  v_gravity_trap_pos = self.origin + ‪V_GROUND_OFFSET_FUDGE;
728  }
729  else
730  {
731  // Find position between planted spikes for FX
732  v_gravity_trap_pos = ‪util::ground_position( self.origin, 1000, Length( ‪V_GROUND_OFFSET_FUDGE ) );
733  }
734  self ‪gravity_trap_fx_on( v_gravity_trap_pos );
735 
736  self ‪zm_weapons::switch_back_primary_weapon( self.w_gravityspikes_wpn_prev, true );
737 
738  self SetWeaponAmmoClip( wpn_gravityspikes, 0 );
739 
740  self.b_gravity_trap_spikes_in_ground = true;
741  self.v_gravity_trap_pos = v_gravity_trap_pos;
742  self notify( "gravity_trap_planted" );
743 
744  // will play blur if player gets near planted trap.
745  self thread ‪player_near_gravity_vortex( v_gravity_trap_pos );
746 
747  // Clean up: will wait for notify
749 
750  self ‪util::waittill_any( "gravity_trap_spikes_retrieved", "disconnect","bled_out" );
751 
752  if( isdefined( self ) )
753  {
754  self.b_gravity_trap_spikes_in_ground = false;
755  self.disable_hero_power_charging = false;
756  self notify( "destroy_ground_spikes" );
757  }
758 }
759 
760 // ------------------------------------------------------------------------------------------------------------
761 function ‪gravity_trap_loop( v_gravity_trap_pos, wpn_gravityspikes ) // self == a player
762 {
763  self endon( "gravity_trap_spikes_retrieved" );
764  self endon( "disconnect" );
765  self endon( "bled_out" );
766  self endon( "death" );
767 
768  is_gravity_trap_fx_on = true;
769 
770  while( true )
771  {
772  // checking to make sure not only in use but has power
773  if( self ‪zm_hero_weapon::is_hero_weapon_in_use() && ( self.hero_power > 0 ) )
774  {
775  a_zombies = GetAITeamArray( level.zombie_team );
776  a_zombies = array::filter( a_zombies, false, &‪gravityspikes_target_filtering );
777  array::thread_all( a_zombies, &‪gravity_trap_check, self );
778  }
779  else if( is_gravity_trap_fx_on )
780  {
781  self ‪gravity_trap_fx_off();
782  is_gravity_trap_fx_on = false;
783 
785 
786  ‪util::wait_network_frame(); // wait to create unitrigger till all else set to avoid retrieved notify too soon
787 
788  // Create unitrigger so player can retrieve the planted spikes
789  self ‪create_gravity_trap_unitrigger( v_gravity_trap_pos, wpn_gravityspikes );
790 
791  // fix for hero weapon possibly set as still in use
793  {
794  self ‪gravityspikes_power_expired( wpn_gravityspikes );
795  }
796 
797  return;
798  }
799 
800  wait 0.1; // loop delay
801  }
802 }
803 
804 function ‪gravity_trap_check( player ) // self == a zombie
805 {
806  player endon( "gravity_trap_spikes_retrieved" );
807  player endon( "disconnect" );
808  player endon( "bled_out" );
809  player endon( "death" );
810 
811  assert( IsDefined( level.ai_gravity_throttle ) );
812  assert( IsDefined( player ) );
813 
814  n_gravity_trap_radius_sq = ‪N_GRAVITY_TRAP_RADIUS * ‪N_GRAVITY_TRAP_RADIUS;
815  v_gravity_trap_origin = player.mdl_gravity_trap_fx_source.origin;
816 
817  // Don't do anything if zombie's dead or has already been caught by trap
818  if( !isdefined( self ) || !IsAlive( self ) )
819  {
820  return;
821  }
822 
823  if( self ‪check_for_range_and_los( v_gravity_trap_origin, ‪N_GRAVITY_TRAP_HEIGHT, n_gravity_trap_radius_sq ) )
824  {
825  if( self.in_gravity_trap === true )
826  {
827  return;
828  }
829  self.in_gravity_trap = true;
830 
831  // this zombie is in trap, wait for thottle to allow the zombie lifting behavior
832  // level.ai_gravity_throttle will spread the gravity spike reaction over multiple frames for better network performace
833  [[level.ai_gravity_throttle]]->WaitInQueue(self);
834 
835  if( IsDefined(self) && IsAlive(self) )
836  {
837  self ‪zombie_lift( player,
838  v_gravity_trap_origin,
839  0,
843  }
844  }
845 }
846 
847 
849 // Gravity Trap util functions
850 // TODO?: Spawning these models could also be client sided?
852 
853 function ‪create_gravity_trap_spikes_in_ground( a_v_spawn_pos ) // self == a player
854 {
855  if( !isdefined( self.mdl_gravity_trap_spikes ) )
856  {
857  self.mdl_gravity_trap_spikes = [];
858  }
859 
860  for( i = 0; i < a_v_spawn_pos.size; i++ )
861  {
862  if( !isdefined( self.mdl_gravity_trap_spikes[ i ] ) )
863  {
864  self.mdl_gravity_trap_spikes[ i ] = ‪util::spawn_model( "wpn_zmb_dlc1_talon_spike_single_world", a_v_spawn_pos[ i ] );
865  }
866 
867  self.mdl_gravity_trap_spikes[ i ].origin = a_v_spawn_pos[ i ];
868 
869  // angle spikes based on players angles when planted
870  self.mdl_gravity_trap_spikes[ i ].angles = self.angles;
871  self.mdl_gravity_trap_spikes[ i ] Show();
872 
873  ‪WAIT_SERVER_FRAME; // Need this wait here so the updated position gets used for clientside FX
874 
875  self.mdl_gravity_trap_spikes[ i ] thread ‪gravity_spike_planted_play();
876  self.mdl_gravity_trap_spikes[ i ] ‪clientfield::set( "gravity_trap_spike_spark", 1 );
877 
878  // can trigger things off of placing the gravity trap spikes in level-specific override
879  if( isdefined( level.gravity_trap_spike_watcher ) )
880  {
881  [[ level.gravity_trap_spike_watcher ]]( self.mdl_gravity_trap_spikes[ i ] );
882  }
883  }
884 }
885 
886 function ‪gravity_spike_planted_play() // self = gravity spike model.
887 {
888  const N_TIME_INIT = 2;
889 
890  wait N_TIME_INIT; // wait till finished planted to open.
891 
892  self thread ‪scene::play( "cin_zm_dlc1_spike_plant_loop", self );
893 }
894 
895 
896 function ‪destroy_gravity_trap_spikes_in_ground() // self == a player
897 {
898  mdl_spike_source = self.mdl_gravity_trap_fx_source;
899  mdl_gravity_trap_spikes = self.mdl_gravity_trap_spikes;
900 
901  self ‪util::waittill_any( "destroy_ground_spikes", "disconnect", "bled_out" );
902 
903  if( isdefined( mdl_spike_source ) )
904  {
905  mdl_spike_source ‪clientfield::set( "gravity_trap_location", 0 );
906  mdl_spike_source Ghost();
907 
908  if(!isdefined( self ) ) // if player disconnected or bled out delete.
909  {
910  mdl_spike_source Delete();
911  }
912  }
913 
914  if( !isdefined( mdl_gravity_trap_spikes ) )
915  {
916  return;
917  }
918 
919  for( i = 0; i < mdl_gravity_trap_spikes.size; i++ )
920  {
921  //self.mdl_gravity_trap_spikes[ i ] clientfield::increment( "gravity_trap_destroy" ); in case they decide to bring it back
922 
923  mdl_gravity_trap_spikes[ i ] thread ‪scene::stop( "cin_zm_dlc1_spike_plant_loop" );
924  mdl_gravity_trap_spikes[ i ] ‪clientfield::set( "gravity_trap_spike_spark", 0 );
925 
926  mdl_gravity_trap_spikes[ i ] Ghost();
927 
928  if(!isdefined( self ) ) // if player disconnected or bled out delete.
929  {
930  mdl_gravity_trap_spikes[ i ] Delete();
931  }
932  }
933 }
934 
935 function ‪gravity_trap_fx_on( v_spawn_pos ) // self == a player
936 {
937  if( !isdefined( self.mdl_gravity_trap_fx_source ) )
938  {
939  self.mdl_gravity_trap_fx_source = ‪util::spawn_model( "tag_origin", v_spawn_pos );
940  }
941  self.mdl_gravity_trap_fx_source.origin = v_spawn_pos;
942  self.mdl_gravity_trap_fx_source Show();
943 
944  ‪WAIT_SERVER_FRAME; // Need this wait here so the updated position gets used for clientside FX
945 
946  self.mdl_gravity_trap_fx_source ‪clientfield::set( "gravity_trap_fx", 1 );
947 }
948 
949 function ‪gravity_trap_fx_off() // self == a player
950 {
951  if( !isdefined( self.mdl_gravity_trap_fx_source ) )
952  {
953  return;
954  }
955  self.mdl_gravity_trap_fx_source ‪clientfield::set( "gravity_trap_fx", 0 );
956 
957  self.mdl_gravity_trap_fx_source ‪clientfield::set( "gravity_trap_location", 1 );
958 }
959 
961 // Gravity Trap unitrigger stuff
962 //
964 
965 function ‪create_gravity_trap_unitrigger( v_origin, wpn_gravityspikes ) // self == the player what created this here Gravity Trap
966 {
967  // fix for jump and creating 2 triggers
968  if( isdefined( self.gravity_trap_unitrigger_stub ) )
969  {
970  return;
971  }
972 
973  unitrigger_stub = spawnstruct();
974  unitrigger_stub.origin = v_origin;
975  unitrigger_stub.script_unitrigger_type = "unitrigger_radius_use";
976  unitrigger_stub.cursor_hint = "HINT_NOICON";
977  unitrigger_stub.radius = ‪N_GRAVITY_TRAP_RADIUS;
978  unitrigger_stub.require_look_at = false;
979  unitrigger_stub.gravityspike_owner = self;
980  unitrigger_stub.wpn_gravityspikes = wpn_gravityspikes;
981 
982  self.gravity_trap_unitrigger_stub = unitrigger_stub;
983 
985 
986  unitrigger_stub.prompt_and_visibility_func = &‪gravity_trap_trigger_visibility;
988 }
989 
990 // self = unitrigger
992 {
993  if( player == self.stub.gravityspike_owner )
994  {
995  self SetHintString( &"ZOMBIE_GRAVITYSPIKE_PICKUP" );
996  return true;
997  }
998  else
999  {
1000  self setInvisibleToPlayer( player );
1001  return false;
1002  }
1003 }
1004 
1005 // self = unitrigger
1007 {
1008  while( true )
1009  {
1010  self waittill( "trigger", player ); // wait until someone uses the trigger
1011 
1012  if( player ‪zm_utility::in_revive_trigger() ) // revive triggers override trap triggers
1013  {
1014  continue;
1015  }
1016 
1017  if( ‪IS_DRINKING( player.is_drinking ) )
1018  {
1019  continue;
1020  }
1021 
1022  if( !‪zm_utility::is_player_valid( player ) ) // ensure valid player
1023  {
1024  continue;
1025  }
1026 
1027  level thread ‪gravity_trap_trigger_activate( self.stub, player );
1028 
1029  break;
1030  }
1031 }
1032 
1033 function ‪gravity_trap_trigger_activate( trig_stub, player )
1034 {
1035  if( player == trig_stub.gravityspike_owner )
1036  {
1037  player notify( "gravity_trap_spikes_retrieved" );
1038 
1039  player playsound ("fly_talon_pickup");
1040 
1041  if( player.gravityspikes_state == ‪GRAVITYSPIKES_STATE_INUSE )
1042  {
1043  player.w_gravityspikes_wpn_prev = player GetCurrentWeapon();
1044  player GiveWeapon( trig_stub.wpn_gravityspikes );
1045  player GiveMaxAmmo( trig_stub.wpn_gravityspikes );
1046  player SetWeaponAmmoClip( trig_stub.wpn_gravityspikes, trig_stub.wpn_gravityspikes.clipSize );
1047  player SwitchToWeapon( trig_stub.wpn_gravityspikes );
1048  }
1049 
1050  // remove this unitrigger, now that the object is picked up
1052  player.gravity_trap_unitrigger_stub = undefined;
1053  }
1054 }
1055 
1056 
1057 // ------------------------------------------------------------------------------------------------------------
1058 // Utility Functions
1059 // ------------------------------------------------------------------------------------------------------------
1060 function ‪update_gravityspikes_state( n_gravityspikes_state ) // self == a player
1061 {
1062  self.gravityspikes_state = n_gravityspikes_state;
1063 }
1064 
1065 function ‪update_gravityspikes_energy( n_gravityspikes_power ) // self == a player
1066 {
1067  self.n_gravityspikes_power = n_gravityspikes_power;
1068  self ‪clientfield::set_player_uimodel( "zmhud.swordEnergy", self.n_gravityspikes_power );
1069 }
1070 
1071 function ‪check_for_range_and_los( v_attack_source, n_allowed_z_diff, n_radius_sq ) // self == a zombie
1072 {
1073  if( IsAlive( self ) )
1074  {
1075  n_z_diff = self.origin[ 2 ] - v_attack_source[ 2 ];
1076  if( abs( n_z_diff ) < n_allowed_z_diff )
1077  {
1078  if( Distance2DSquared( self.origin, v_attack_source ) < n_radius_sq )
1079  {
1080  v_offset = ( 0, 0, ‪N_GRAVITYSPIKES_LOS_HEIGHT_OFFSET );
1081  if( BulletTracePassed( self.origin + v_offset, v_attack_source + v_offset, false, self ) )
1082  {
1083  return true;
1084  }
1085  }
1086  }
1087  }
1088  return false;
1089 }
1090 
1092 {
1093  b_callback_result = true;
1094  if( isdefined( level.gravityspikes_target_filter_callback ) )
1095  {
1096  b_callback_result = [[ level.gravityspikes_target_filter_callback ]]( ai_enemy );
1097  }
1098  return b_callback_result;
1099 }
1100 
1101 function ‪zombie_lift( player, v_attack_source, n_push_away, n_lift_height, v_lift_offset, n_lift_speed ) // self == a zombie
1102 {
1103  wpn_gravityspikes = GetWeapon( ‪STR_GRAVITYSPIKES_NAME );
1104 
1105  if( IsDefined( self.zombie_lift_override ) )
1106  {
1107  self thread [[ self.zombie_lift_override ]]( player, v_attack_source, n_push_away, n_lift_height, v_lift_offset, n_lift_speed );
1108  return;
1109  }
1110 
1111  if( ‪IS_TRUE( self.isdog ) || ‪IS_TRUE( self.ignore_zombie_lift ) ) // Just kill dogs since they can't do ragdoll
1112  {
1113  self.no_powerups = true; // don't drop powerups
1114  self DoDamage( self.health + 100, self.origin, player, player, undefined, "MOD_UNKNOWN", 0, wpn_gravityspikes );
1115  self playsound ("zmb_talon_electrocute_swt");
1116  }
1117  else
1118  {
1119  // Control the number of zombies getting lifted up for ragdoll kill
1120  if( level.n_zombies_lifted_for_ragdoll < ‪N_MAX_ZOMBIES_LIFTED_FOR_RAGDOLL )
1121  {
1122  self thread ‪track_lifted_for_ragdoll_count();
1123 
1124  v_away_from_source = VectorNormalize( self.origin - v_attack_source );
1125  v_away_from_source = v_away_from_source * n_push_away;
1126  v_away_from_source = ( v_away_from_source[ 0 ], v_away_from_source[ 1 ], n_lift_height );
1127  // Determine how far up we can lift the zombie
1128  a_trace = PhysicsTraceEx( self.origin + ‪V_GROUND_OFFSET_FUDGE, // The fudge prevents PhysicsTraceEx from colliding with the ground
1129  self.origin + v_away_from_source,
1132  self );
1133 
1134  v_lift = a_trace[ "fraction" ] * v_away_from_source;
1135  v_lift = ( v_lift + v_lift_offset );
1136  n_lift_time = Length( v_lift ) / n_lift_speed;
1137 
1138 
1139  // For slam just launch zombie
1140  if( isdefined( self ) && ‪IS_TRUE( self.b_melee_kill ) )
1141  {
1142  self SetPlayerCollision( false );
1143 
1144  const N_FLING_FORCE = 150;
1145 
1146  if ( !‪IS_TRUE( level.ignore_gravityspikes_ragdoll ) )
1147  {
1148  self StartRagdoll();
1149  self LaunchRagdoll( N_FLING_FORCE * AnglesToUp( self.angles ) + ( v_away_from_source[ 0 ], v_away_from_source[ 1 ], 0 ) );
1150  }
1151 
1152  self ‪clientfield::set( "ragdoll_impact_watch", 1 );
1153 
1154  self ‪clientfield::set( "sparky_zombie_trail_fx", 1 );
1155 
1157  }
1158  // Only lift the zombie if the lift Z is positive and lift vector is longer than the lift offset
1159  else if( isdefined( self ) && v_lift[ 2 ] > 0 && Length( v_lift ) > Length( v_lift_offset ) )
1160  {
1161  // no player collision for rising zombies.
1162  self SetPlayerCollision( false );
1163 
1164  // play beam and sparky fx ( sparky fx may be used seperately )
1165  self ‪clientfield::set( "sparky_beam_fx", 1 );
1166  self ‪clientfield::set( "sparky_zombie_fx", 1 );
1167  self playsound ("zmb_talon_electrocute");
1168 
1169  if( ‪IS_TRUE( self.missingLegs ) )
1170  {
1171  self thread ‪scene::play( "cin_zm_dlc1_zombie_crawler_talonspike_a_loop", self );
1172  }
1173  else
1174  {
1175  self thread ‪scene::play( "cin_zm_dlc1_zombie_talonspike_loop", self );
1176  }
1177 
1178  self.mdl_trap_mover = ‪util::spawn_model( "tag_origin", self.origin, self.angles );
1179  self thread ‪util::delete_on_death( self.mdl_trap_mover );
1180  self LinkTo( self.mdl_trap_mover, "tag_origin" );
1181 
1182  self.mdl_trap_mover MoveTo( self.origin + v_lift, n_lift_time, 0, n_lift_time * 0.4 );
1183  self thread ‪zombie_lift_wacky_rotate( n_lift_time, player );
1184 
1185  // Wait 'til lift finishes, zombie is killed, or Gravity Trap expires, player disconnects, etc.
1186  self thread ‪gravity_trap_notify_watcher( player );
1187  self waittill( "gravity_trap_complete" );
1188 
1189  // slam down
1190  if ( isdefined(self) )
1191  {
1192  self Unlink();
1193 
1194  self ‪scene::stop();
1195  self StartRagdoll( true );
1196  self ‪clientfield::set( "gravity_slam_down", 1 );
1197  self ‪clientfield::set( "sparky_beam_fx", 0 );
1198  self ‪clientfield::set( "sparky_zombie_fx", 0 );
1199  self ‪clientfield::set( "sparky_zombie_trail_fx", 1 );
1200 
1201  self thread ‪corpse_off_navmesh_watcher();
1202  self ‪clientfield::set( "ragdoll_impact_watch", 1 );
1203 
1204  // Wait so zombie hitting ground and damage + gibbing are synced
1205  v_land_pos = ‪util::ground_position( self.origin, 1000 );
1206  n_fall_dist = abs( self.origin[ 2 ] - v_land_pos[ 2 ] );
1207  n_slam_wait = ( n_fall_dist / ‪GRAVITY_SLAM_SPEED ) * 0.75;
1208  if( n_slam_wait > 0 )
1209  {
1210  wait n_slam_wait; // wait here so slam down and killing/gibbing are synced
1211  }
1212  }
1213  }
1214 
1215  if( IsAlive( self ) )
1216  {
1217  self ‪zombie_kill_and_gib( player );
1218  self playsound ("zmb_talon_ai_slam");
1219  }
1220  }
1221  // If there's too many ragdoll zombies, just gib and die
1222  else
1223  {
1224  self ‪zombie_kill_and_gib( player );
1225  self playsound ("zmb_talon_ai_slam");
1226  }
1227  }
1228 }
1229 
1230 function ‪gravity_trap_notify_watcher( player ) // self = ai zombie
1231 {
1232  self endon( "gravity_trap_complete" );
1233 
1234  self thread ‪gravity_trap_timeout_watcher();
1235 
1236  ‪util::waittill_any_ents( self, "death",
1237  player, "gravity_trap_spikes_retrieved",
1238  player, "gravityspikes_timer_end",
1239  player, "disconnect",
1240  player, "bled_out" );
1241 
1242  self notify( "gravity_trap_complete" );
1243 }
1244 
1245 function ‪gravity_trap_timeout_watcher() // self = ai zombie
1246 {
1247  self endon( "gravity_trap_complete" );
1248 
1249  self.mdl_trap_mover ‪util::waittill_any_timeout( 4, "movedone", "gravity_trap_complete" );
1250 
1251  // float in the air a bit, slight pause when zombie reaches max lift height
1252  if( IsAlive( self ) && !‪IS_TRUE( self.b_melee_kill ) )
1253  {
1254  wait RandomFloatRange( 0.2, 1.0 );
1255  }
1256 
1257  self notify( "gravity_trap_complete" );
1258 }
1259 
1260 function ‪zombie_lift_wacky_rotate( n_lift_time, player ) // self == a zombie caught in Gravity Trap
1261 {
1262  player endon( "gravityspikes_timer_end" );
1263  self endon( "death" );
1264 
1265  // Adding a bit of random rotation to zombies caught in Gravity Trap
1266  while( true )
1267  {
1268  negative_x = ( RandomIntRange( 0, 10 ) < 5 ? 1 : -1 );
1269  negative_z = ( RandomIntRange( 0, 10 ) < 5 ? 1 : -1 );
1270 
1271  self.mdl_trap_mover RotateTo( ( RandomIntRange( 90, 180 ) * negative_x,
1272  RandomIntRange( -90, 90 ),
1273  RandomIntRange( 90, 180 ) * negative_z ),
1274  ( n_lift_time > 2 ? n_lift_time : ‪N_GRAVITY_TRAP_MAX_LIFT_TIME * 0.5 ),
1275  0 );
1276  self.mdl_trap_mover waittill( "rotatedone" );
1277  }
1278 }
1279 
1280 function ‪zombie_kill_and_gib( player ) // self == a zombie
1281 {
1282  wpn_gravityspikes = GetWeapon( ‪STR_GRAVITYSPIKES_NAME );
1283 
1284  self.no_powerups = true; // don't drop powerups
1285  // TODO: May not want to kill zombies in later rounds? But then we can't use ragdoll though...
1286  self DoDamage( self.health + 100, self.origin, player, player, undefined, "MOD_UNKNOWN", 0, wpn_gravityspikes );
1287  if( !‪B_DISABLE_GIBBING )
1288  {
1289  n_random = RandomInt( 100 );
1290 
1291 /* //Commenting out for now, seems to be going back and forth on full exploding death
1292  if( n_random >= 60 ) // 40% full annhilator exploding
1293  {
1294  self zombie_utility::gib_random_parts();
1295  GibServerUtils::Annihilate( self );
1296  }
1297  else if( n_random <= 40 ) // 40% chance single limb gibbing
1298  {
1299  self zombie_utility::gib_random_parts();
1300  }
1301 */
1302  if( n_random >= 20 ) // 80% random gib
1303  {
1305  }
1306 
1307  // 20% chance no gibbing
1308  }
1309 }
1310 
1311 function ‪track_lifted_for_ragdoll_count() // self == a lifted zombie
1312 {
1313  level.n_zombies_lifted_for_ragdoll++;
1314  self waittill( "death" );
1315  level.n_zombies_lifted_for_ragdoll--;
1316  // TODO: Maybe reset this var to 0 every round, just in case something wacky happens?
1317 }
1318 
1319 function ‪corpse_off_navmesh_watcher() // self = zombie
1320 {
1321  self waittill( "actor_corpse", e_corpse ); // Wait until killed zombie turns into corpse
1322 
1323  v_pos = GetClosestPointOnNavMesh( e_corpse.origin, 256 );
1324 
1325  if( !isdefined( v_pos ) || ( e_corpse.origin[2] > ( v_pos[2] + 64 ) ) )
1326  {
1327  e_corpse thread ‪do_zombie_explode();
1328  }
1329 }
1330 
1331 function private ‪do_zombie_explode() // self = zombie corpse
1332 {
1333  ‪util::wait_network_frame(); // wait for spawned ent for counter fx.
1334 
1335  if( isDefined( self ))
1336  {
1338 
1339  self ‪clientfield::increment( "gravity_spike_zombie_explode_fx" );
1340 
1341  self Ghost();
1342  self ‪util::delay( 0.25, undefined, &‪zm_utility::self_delete );
1343  }
1344 }
1345 
1346 // ------------------------------------------------------------------------
1347 // Melee Attack
1348 // ------------------------------------------------------------------------
1349 function ‪gravity_spike_melee_kill( v_position, player ) // self == ai zombie
1350 {
1351  self.b_melee_kill = true;
1352 
1353  // Adjusting radius to be egg shaped, so it's longer in front of player and shorter behind player
1355 
1356  if( self ‪check_for_range_and_los( v_position, ‪N_GRAVITYSPIKES_MELEE_HEIGHT, n_gravity_spike_melee_radius_sq ) )
1357  {
1358  self ‪zombie_lift( player, v_position,
1361  ( 0, 0, 0 ),
1363  }
1364 }
1365 
1366 // ------------------------------------------------------------------------
1367 // Knockdown Zombies
1368 // ------------------------------------------------------------------------
1369 function ‪knockdown_zombies_slam() // self = player
1370 {
1371  const N_DISTANCE_OFFSET = 24;
1372 
1373  //offset slam position in front of player
1374  v_forward = AnglesToForward(self GetPlayerAngles());
1375  v_pos = self.origin + VectorScale( v_forward, N_DISTANCE_OFFSET );
1376 
1377  a_ai = GetAITeamArray( level.zombie_team );
1378  a_ai = array::filter( a_ai, false, &‪gravityspikes_target_filtering );
1379  a_ai_kill_zombies = ArraySortClosest( a_ai, v_pos, a_ai.size, 0, ‪N_GRAVITYSPIKES_MELEE_KILL_RADIUS );
1380  array::thread_all( a_ai_kill_zombies, &‪gravity_spike_melee_kill, v_pos, self );
1381 
1382  a_ai_slam_zombies = ArraySortClosest( a_ai, v_pos, a_ai.size, ‪N_GRAVITYSPIKES_MELEE_KILL_RADIUS, ‪N_GRAVITYSPIKES_KNOCKDOWN_RADIUS );
1383  array::thread_all( a_ai_slam_zombies, &‪zombie_slam_direction, v_pos );
1384 
1385  self thread ‪play_slam_fx( v_pos );
1386 }
1387 
1388 function ‪play_slam_fx( v_pos ) // self = player
1389 {
1390  mdl_fx_pos = ‪util::spawn_model( "tag_origin", v_pos, ( -90, 0, 0 ) );
1391 
1392  ‪WAIT_SERVER_FRAME; // wait to send to client
1393 
1394  mdl_fx_pos ‪clientfield::set( "gravity_slam_fx", 1 );
1395  self ‪clientfield::increment_to_player( "gravity_slam_player_fx" );
1396 
1397  ‪WAIT_SERVER_FRAME; // wait to send to client
1398 
1399  mdl_fx_pos Delete();
1400 }
1401 
1402 function ‪zombie_slam_direction( v_position ) // self = ai zombie
1403 {
1404  self endon( "death" );
1405 
1406  if ( !‪IS_EQUAL(self.archetype,‪ARCHETYPE_ZOMBIE ) )
1407  {
1408  return;
1409  }
1410 
1411  self.knockdown = true;
1412 
1413  v_zombie_to_player = v_position - self.origin;
1414  v_zombie_to_player_2d = VectorNormalize( ( v_zombie_to_player[0], v_zombie_to_player[1], 0 ) );
1415 
1416  v_zombie_forward = AnglesToForward( self.angles );
1417  v_zombie_forward_2d = VectorNormalize( ( v_zombie_forward[0], v_zombie_forward[1], 0 ) );
1418 
1419  v_zombie_right = AnglesToRight( self.angles );
1420  v_zombie_right_2d = VectorNormalize( ( v_zombie_right[0], v_zombie_right[1], 0 ) );
1421 
1422  v_dot = VectorDot( v_zombie_to_player_2d, v_zombie_forward_2d );
1423 
1424  if( v_dot >= 0.5 )
1425  {
1426  self.knockdown_direction = "front";
1427  self.getup_direction = ‪GETUP_BACK;
1428  }
1429  else if ( v_dot < 0.5 && v_dot > -0.5 )
1430  {
1431  v_dot = VectorDot( v_zombie_to_player_2d, v_zombie_right_2d );
1432  if( v_dot > 0 )
1433  {
1434  self.knockdown_direction = "right";
1435 
1436  if ( ‪math::cointoss() )
1437  {
1438  self.getup_direction = ‪GETUP_BACK;
1439  }
1440  else
1441  {
1442  self.getup_direction = ‪GETUP_BELLY;
1443  }
1444  }
1445  else
1446  {
1447  self.knockdown_direction = "left";
1448  self.getup_direction = ‪GETUP_BELLY;
1449  }
1450  }
1451  else
1452  {
1453  self.knockdown_direction = "back";
1454  self.getup_direction = ‪GETUP_BELLY;
1455  }
1456 
1457  wait 1; // wait till knocked down then reset.
1458 
1459  self.knockdown = false;
1460 }
1461 
‪gravity_spike_melee_kill
‪function gravity_spike_melee_kill(v_position, player)
Definition: _zm_weap_gravityspikes.gsc:1349
‪default_power_empty
‪function default_power_empty(weapon)
Definition: _zm_hero_weapon.gsc:185
‪N_GRAVITY_MELEE_MIN_LIFT_SPEED
‪#define N_GRAVITY_MELEE_MIN_LIFT_SPEED
Definition: _zm_weap_gravityspikes.gsc:68
‪player_vortex_visionset
‪function player_vortex_visionset(name)
Definition: zombie_vortex.gsc:379
‪N_GRAVITYSPIKES_MELEE_KILL_RADIUS
‪#define N_GRAVITYSPIKES_MELEE_KILL_RADIUS
Definition: _zm_weap_gravityspikes.gsc:61
‪N_GRAVITY_MELEE_MAX_LIFT_SPEED
‪#define N_GRAVITY_MELEE_MAX_LIFT_SPEED
Definition: _zm_weap_gravityspikes.gsc:69
‪gravityspikes_altfire_watcher
‪function gravityspikes_altfire_watcher(wpn_gravityspikes)
Definition: _zm_weap_gravityspikes.gsc:464
‪player_vortex_rumble
‪function player_vortex_rumble(e_player, v_vortex_origin)
Definition: _zm_weap_gravityspikes.gsc:679
‪update_gravityspikes_energy
‪function update_gravityspikes_energy(n_gravityspikes_power)
Definition: _zm_weap_gravityspikes.gsc:1065
‪do_zombie_explode
‪function private do_zombie_explode()
Definition: _zm_weap_gravityspikes.gsc:1331
‪zombie_slam_direction
‪function zombie_slam_direction(v_position)
Definition: _zm_weap_gravityspikes.gsc:1402
‪gravity_trap_trigger_activate
‪function gravity_trap_trigger_activate(trig_stub, player)
Definition: _zm_weap_gravityspikes.gsc:1033
‪zombie_kill_and_gib
‪function zombie_kill_and_gib(player)
Definition: _zm_weap_gravityspikes.gsc:1280
‪on_connect_func_for_gravityspikes
‪function private on_connect_func_for_gravityspikes()
Definition: _zm_weap_gravityspikes.gsc:130
‪GRAVITYSPIKES_STATE_DEPLETED
‪#define GRAVITYSPIKES_STATE_DEPLETED
Definition: _zm_weap_gravityspikes.gsh:7
‪ground_position
‪function ground_position(v_start, n_max_dist=5000, n_ground_offset=0, e_ignore, b_ignore_water=false, b_ignore_glass=false)
Definition: util_shared.gsc:3774
‪destroy_gravity_trap_spikes_in_ground
‪function destroy_gravity_trap_spikes_in_ground()
Definition: _zm_weap_gravityspikes.gsc:896
‪N_GRAVITY_TRAP_SEPERATION
‪#define N_GRAVITY_TRAP_SEPERATION
Definition: _zm_weap_gravityspikes.gsc:71
‪set_to_player
‪function set_to_player(str_field_name, n_value)
Definition: clientfield_shared.gsc:58
‪chop_actor
‪function chop_actor(ai, leftswing, weapon=level.weaponNone)
Definition: _zm_weap_gravityspikes.gsc:496
‪Throttle
Definition: throttle_shared.gsc:15
‪play
‪function play(animation, v_origin_or_ent, v_angles_or_tag, n_rate=1, n_blend_in=.2, n_blend_out=.2, n_lerp, b_link=false)
Definition: animation_shared.csc:44
‪spikesarc_swipe
‪function spikesarc_swipe(player)
Definition: _zm_weap_gravityspikes.gsc:578
‪VERSION_SHIP
‪#define VERSION_SHIP
Definition: version.gsh:36
‪gravity_trap_timeout_watcher
‪function gravity_trap_timeout_watcher()
Definition: _zm_weap_gravityspikes.gsc:1245
‪gravityspikes_power_override
‪function gravityspikes_power_override(e_player, ai_enemy)
Definition: _zm_weap_gravityspikes.gsc:226
‪track_lifted_for_ragdoll_count
‪function track_lifted_for_ragdoll_count()
Definition: _zm_weap_gravityspikes.gsc:1311
‪cointoss
‪function cointoss()
Definition: math_shared.csc:171
‪N_GRAVITY_TRAP_RADIUS
‪#define N_GRAVITY_TRAP_RADIUS
Definition: _zm_weap_gravityspikes.gsh:9
‪GRAVITYSPIKES_STATE_INUSE
‪#define GRAVITYSPIKES_STATE_INUSE
Definition: _zm_weap_gravityspikes.gsh:6
‪trace
‪function trace(from, to, target)
Definition: grapple.gsc:369
‪weapon_change_watcher
‪function weapon_change_watcher()
Definition: _zm_weap_gravityspikes.gsc:340
‪GRAVITYSPIKES_STATE_NOT_PICKED_UP
‪#define GRAVITYSPIKES_STATE_NOT_PICKED_UP
Definition: _zm_weap_gravityspikes.gsh:3
‪register_player_damage_callback
‪function register_player_damage_callback(func)
Definition: _zm.gsc:5522
‪self_delete
‪function self_delete()
Definition: _util.gsc:739
‪B_DISABLE_GIBBING
‪#define B_DISABLE_GIBBING
Definition: _zm_weap_gravityspikes.gsc:83
‪create_gravity_trap_unitrigger
‪function create_gravity_trap_unitrigger(v_origin, wpn_gravityspikes)
Definition: _zm_weap_gravityspikes.gsc:965
‪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
‪gravityspikes_stuck_above_zombie_watcher
‪function gravityspikes_stuck_above_zombie_watcher(wpn_gravityspikes)
Definition: _zm_weap_gravityspikes.gsc:375
‪create_gravity_trap_spikes_in_ground
‪function create_gravity_trap_spikes_in_ground(a_v_spawn_pos)
Definition: _zm_weap_gravityspikes.gsc:853
‪delay
‪function delay(time_or_notify, str_endon, func, arg1, arg2, arg3, arg4, arg5, arg6)
Definition: util_shared.csc:784
‪spawn_model
‪function spawn_model(n_client, str_model, origin=(0, 0, 0), angles=(0, 0, 0))
Definition: util_shared.csc:92
‪is_player_valid
‪function is_player_valid(player, checkIgnoreMeFlag, ignore_laststand_players)
Definition: skeleton.gsc:256
‪N_GRAVITY_TRAP_LIFT_HEIGHT_MAX
‪#define N_GRAVITY_TRAP_LIFT_HEIGHT_MAX
Definition: _zm_weap_gravityspikes.gsc:75
‪N_GRAVITYSPIKES_KNOCKDOWN_RADIUS
‪#define N_GRAVITYSPIKES_KNOCKDOWN_RADIUS
Definition: _zm_weap_gravityspikes.gsc:62
‪N_GRAVITY_TRAP_LIFT_HEIGHT_MIN
‪#define N_GRAVITY_TRAP_LIFT_HEIGHT_MIN
Definition: _zm_weap_gravityspikes.gsc:74
‪default_unwield
‪function default_unwield(weapon)
Definition: _zm_hero_weapon.gsc:163
‪register_hero_weapon
‪function register_hero_weapon(weapon_name)
Definition: _zm_hero_weapon.gsc:95
‪gravityspikes_power_expired
‪function gravityspikes_power_expired(weapon)
Definition: _zm_weap_gravityspikes.gsc:618
‪plant_gravity_trap
‪function plant_gravity_trap(wpn_gravityspikes)
Definition: _zm_weap_gravityspikes.gsc:701
‪unregister_unitrigger
‪function unregister_unitrigger(unitrigger_stub)
Definition: _zm_unitrigger.gsc:173
‪switch_back_primary_weapon
‪function switch_back_primary_weapon(oldprimary, immediate=false)
Definition: _zm_weapons.gsc:280
‪gravity_trap_loop
‪function gravity_trap_loop(v_gravity_trap_pos, wpn_gravityspikes)
Definition: _zm_weap_gravityspikes.gsc:761
‪weapon_drop_watcher
‪function weapon_drop_watcher()
Definition: _zm_weap_gravityspikes.gsc:326
‪VORTEX_SCREEN_EFFECT_NAME
‪#define VORTEX_SCREEN_EFFECT_NAME
Definition: zombie_vortex.gsh:15
‪no_damage_gravityspikes_slam
‪function no_damage_gravityspikes_slam()
Definition: _zm_weap_gravityspikes.gsc:642
‪__init__
‪function __init__()
Definition: _zm_weap_gravityspikes.gsc:86
‪update_gravityspikes_state
‪function update_gravityspikes_state(n_gravityspikes_state)
Definition: _zm_weap_gravityspikes.gsc:1060
‪GRAVITY_SLAM_SPEED
‪#define GRAVITY_SLAM_SPEED
Definition: _zm_weap_gravityspikes.gsh:11
‪gravity_spike_planted_play
‪function gravity_spike_planted_play()
Definition: _zm_weap_gravityspikes.gsc:886
‪N_GRAVITYSPIKE_HINT_TIMER
‪#define N_GRAVITYSPIKE_HINT_TIMER
Definition: _zm_weap_gravityspikes.gsc:81
‪reset_after_bleeding_out
‪function reset_after_bleeding_out()
Definition: _zm_weap_gravityspikes.gsc:181
‪gravity_trap_notify_watcher
‪function gravity_trap_notify_watcher(player)
Definition: _zm_weap_gravityspikes.gsc:1230
‪register_hero_weapon_power_callbacks
‪function register_hero_weapon_power_callbacks(weapon_name, power_full_fn=&default_power_full, power_empty_fn=&default_power_empty)
Definition: _zm_hero_weapon.gsc:168
‪V_GRAVITY_TRAP_LIFT_AMOUNT_OFFSET
‪#define V_GRAVITY_TRAP_LIFT_AMOUNT_OFFSET
Definition: _zm_weap_gravityspikes.gsc:79
‪wait_network_frame
‪function wait_network_frame(n_count=1)
Definition: util_shared.gsc:64
‪gravity_trap_trigger_think
‪function gravity_trap_trigger_think()
Definition: _zm_weap_gravityspikes.gsc:1006
‪gravityspikes_attack_watcher
‪function gravityspikes_attack_watcher(wpn_gravityspikes)
Definition: _zm_weap_gravityspikes.gsc:354
‪N_GRAVITY_TRAP_MAX_LIFT_SPEED
‪#define N_GRAVITY_TRAP_MAX_LIFT_SPEED
Definition: _zm_weap_gravityspikes.gsc:77
‪show_hint_text
‪function show_hint_text(str_text_to_show, b_should_blink=false, str_turn_off_notify=HINT_TEXT_TURN_OFF_NOTIFY, n_display_time=HINT_TEXT_DISPLAY_TIME_DEFAULT)
Definition: _util.gsc:1042
‪N_MAX_ZOMBIES_LIFTED_FOR_RAGDOLL
‪#define N_MAX_ZOMBIES_LIFTED_FOR_RAGDOLL
Definition: _zm_weap_gravityspikes.gsc:58
‪player_near_gravity_vortex
‪function player_near_gravity_vortex(v_vortex_origin)
Definition: _zm_weap_gravityspikes.gsc:652
‪V_GROUND_OFFSET_FUDGE
‪#define V_GROUND_OFFSET_FUDGE
Definition: _zm_weap_gravityspikes.gsc:52
‪increment_to_player
‪function increment_to_player(str_field_name, n_increment_count=1)
Definition: clientfield_shared.gsc:169
‪waittill_any
‪function waittill_any(str_notify1, str_notify2, str_notify3, str_notify4, str_notify5)
Definition: util_shared.csc:375
‪zombie_eye_glow_stop
‪function zombie_eye_glow_stop()
Definition: zombie_utility.gsc:1733
‪gravity_trap_trigger_visibility
‪function gravity_trap_trigger_visibility(player)
Definition: _zm_weap_gravityspikes.gsc:991
‪gravity_trap_fx_on
‪function gravity_trap_fx_on(v_spawn_pos)
Definition: _zm_weap_gravityspikes.gsc:935
‪is_hero_weapon_in_use
‪function is_hero_weapon_in_use()
Definition: _zm_hero_weapon.gsc:402
‪gravityspikes_target_filtering
‪function gravityspikes_target_filtering(ai_enemy)
Definition: _zm_weap_gravityspikes.gsc:1091
‪increment
‪function increment(str_field_name, n_increment_count=1)
Definition: clientfield_shared.gsc:110
‪REGISTER_SYSTEM
‪#define REGISTER_SYSTEM(__sys, __func_init_preload, __reqs)
Definition: shared.gsh:204
‪increment_uimodel
‪function increment_uimodel(str_field_name, n_increment_count=1)
Definition: clientfield_shared.gsc:136
‪gravityspikes_power_update
‪function gravityspikes_power_update(player)
Definition: _zm_weap_gravityspikes.gsc:608
‪register_clientfields
‪function register_clientfields()
Definition: _zm_weap_gravityspikes.gsc:113
‪array
‪function filter array
Definition: array_shared.csc:16
‪knockdown_zombies_slam
‪function knockdown_zombies_slam()
Definition: _zm_weap_gravityspikes.gsc:1369
‪continue_draining_hero_weapon
‪function continue_draining_hero_weapon(w_weapon)
Definition: _zm_hero_weapon.gsc:302
‪V_PHYSICSTRACE_CAPSULE_MAX
‪#define V_PHYSICSTRACE_CAPSULE_MAX
Definition: _zm_weap_gravityspikes.gsc:56
‪is_hero_weapon
‪function is_hero_weapon(weapon)
Definition: _zm_utility.gsc:4408
‪GRAVITYSPIKES_STATE_READY
‪#define GRAVITYSPIKES_STATE_READY
Definition: _zm_weap_gravityspikes.gsh:5
‪player_invulnerable_during_gravityspike_slam
‪function player_invulnerable_during_gravityspike_slam(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, psOffsetTime, boneIndex)
Definition: _zm_weap_gravityspikes.gsc:630
‪chop_zombies
‪function chop_zombies(first_time, leftswing, weapon=level.weaponNone)
Definition: _zm_weap_gravityspikes.gsc:520
‪VERSION_TU12
‪#define VERSION_TU12
Definition: version.gsh:64
‪waittill_any_ents
‪function waittill_any_ents(ent1, string1, ent2, string2, ent3, string3, ent4, string4, ent5, string5, ent6, string6, ent7, string7)
Definition: util_shared.csc:496
‪ARCHETYPE_ZOMBIE
‪#define ARCHETYPE_ZOMBIE
Definition: archetype_shared.gsh:10
‪stop
‪function stop(n_blend=0.2)
Definition: animation_shared.gsc:97
‪STR_GRAVITYSPIKES_NAME
‪#define STR_GRAVITYSPIKES_NAME
Definition: _zm_weap_gravityspikes.gsh:1
‪N_GRAVITYSPIKES_MELEE_HEIGHT
‪#define N_GRAVITYSPIKES_MELEE_HEIGHT
Definition: _zm_weap_gravityspikes.gsc:64
‪corpse_off_navmesh_watcher
‪function corpse_off_navmesh_watcher()
Definition: _zm_weap_gravityspikes.gsc:1319
‪GETUP_BELLY
‪#define GETUP_BELLY
Definition: blackboard.gsh:206
‪unwield_gravityspikes
‪function unwield_gravityspikes(wpn_gravityspikes)
Definition: _zm_weap_gravityspikes.gsc:311
‪N_GRAVITY_TRAP_HEIGHT
‪#define N_GRAVITY_TRAP_HEIGHT
Definition: _zm_weap_gravityspikes.gsc:72
‪set
‪function set(str_field_name, n_value)
Definition: clientfield_shared.gsc:34
‪IS_EQUAL
‪#define IS_EQUAL(__a, __b)
Definition: shared.gsh:250
‪gib_random_parts
‪function gib_random_parts()
Definition: zombie_utility.gsc:2979
‪gravity_trap_check
‪function gravity_trap_check(player)
Definition: _zm_weap_gravityspikes.gsc:804
‪player_is_in_laststand
‪function player_is_in_laststand()
Definition: laststand_shared.gsc:18
‪play_slam_fx
‪function play_slam_fx(v_pos)
Definition: _zm_weap_gravityspikes.gsc:1388
‪N_GRAVITY_MELEE_LIFT_HEIGHT_MAX
‪#define N_GRAVITY_MELEE_LIFT_HEIGHT_MAX
Definition: _zm_weap_gravityspikes.gsc:67
‪V_PHYSICSTRACE_CAPSULE_MIN
‪#define V_PHYSICSTRACE_CAPSULE_MIN
Definition: _zm_weap_gravityspikes.gsc:55
‪set_player_uimodel
‪function set_player_uimodel(str_field_name, n_value)
Definition: clientfield_shared.gsc:75
‪weapon_give
‪function weapon_give(weapon, is_upgrade=false, magic_box=false, nosound=false, b_switch_weapon=true)
Definition: _zm_weapons.gsc:2603
‪destroy
‪function destroy(watcher, owner)
Definition: _decoy.gsc:108
‪register
‪function register()
Definition: _ai_tank.gsc:126
‪SPIKES_CHOP_CONE_RANGE
‪#define SPIKES_CHOP_CONE_RANGE
Definition: _zm_weap_gravityspikes.gsc:84
‪N_GRAVITY_TRAP_MIN_LIFT_SPEED
‪#define N_GRAVITY_TRAP_MIN_LIFT_SPEED
Definition: _zm_weap_gravityspikes.gsc:76
‪unitrigger_force_per_player_triggers
‪function unitrigger_force_per_player_triggers(unitrigger_stub, opt_on_off)
Definition: _zm_unitrigger.gsc:58
‪gravity_spike_position_valid
‪function gravity_spike_position_valid()
Definition: _zm_weap_gravityspikes.gsc:484
‪register_hero_weapon_wield_unwield_callbacks
‪function register_hero_weapon_wield_unwield_callbacks(weapon_name, wield_fn=&default_wield, unwield_fn=&default_unwield)
Definition: _zm_hero_weapon.gsc:147
‪in_revive_trigger
‪function in_revive_trigger()
Definition: _zm_utility.gsc:1684
‪default_wield
‪function default_wield(weapon)
Definition: _zm_hero_weapon.gsc:158
‪zombie_lift_wacky_rotate
‪function zombie_lift_wacky_rotate(n_lift_time, player)
Definition: _zm_weap_gravityspikes.gsc:1260
‪clamp
‪function clamp(val, val_min, val_max)
Definition: math_shared.csc:16
‪on_connect
‪function on_connect()
Definition: _arena.gsc:20
‪N_GRAVITY_TRAP_MAX_LIFT_TIME
‪#define N_GRAVITY_TRAP_MAX_LIFT_TIME
Definition: _zm_weap_gravityspikes.gsc:78
‪delete_on_death
‪function delete_on_death(ent)
Definition: util_shared.gsc:1796
‪IS_DRINKING
‪#define IS_DRINKING(_is_drinking)
Definition: _zm_utility.gsh:1
‪N_GRAVITYSPIKES_LOS_HEIGHT_OFFSET
‪#define N_GRAVITYSPIKES_LOS_HEIGHT_OFFSET
Definition: _zm_weap_gravityspikes.gsc:59
‪register_static_unitrigger
‪function register_static_unitrigger(unitrigger_stub, trigger_func, recalculate_zone)
Definition: _zm_unitrigger.gsc:236
‪register_hero_recharge_event
‪function register_hero_recharge_event(w_hero, func)
Definition: _zm_hero_weapon.gsc:328
‪gravity_trap_fx_off
‪function gravity_trap_fx_off()
Definition: _zm_weap_gravityspikes.gsc:949
‪ARCHETYPE_ZOMBIE_DOG
‪#define ARCHETYPE_ZOMBIE_DOG
Definition: archetype_shared.gsh:11
‪zombie_lift
‪function zombie_lift(player, v_attack_source, n_push_away, n_lift_height, v_lift_offset, n_lift_speed)
Definition: _zm_weap_gravityspikes.gsc:1101
‪wield_gravityspikes
‪function wield_gravityspikes(wpn_gravityspikes)
Definition: _zm_weap_gravityspikes.gsc:287
‪gravityspikes_swipe_watcher
‪function gravityspikes_swipe_watcher(wpn_gravityspikes)
Definition: _zm_weap_gravityspikes.gsc:587
‪N_GRAVITYSPIKES_MELEE_PUSH_AWAY
‪#define N_GRAVITYSPIKES_MELEE_PUSH_AWAY
Definition: _zm_weap_gravityspikes.gsc:65
‪N_GRAVITY_MELEE_LIFT_HEIGHT_MIN
‪#define N_GRAVITY_MELEE_LIFT_HEIGHT_MIN
Definition: _zm_weap_gravityspikes.gsc:66
‪WAIT_SERVER_FRAME
‪#define WAIT_SERVER_FRAME
Definition: shared.gsh:265
‪GETUP_BACK
‪#define GETUP_BACK
Definition: blackboard.gsh:205
‪check_for_range_and_los
‪function check_for_range_and_los(v_attack_source, n_allowed_z_diff, n_radius_sq)
Definition: _zm_weap_gravityspikes.gsc:1071