1 #using scripts\codescripts\struct;
3 #using scripts\shared\array_shared;
4 #using scripts\shared\callbacks_shared;
5 #using scripts\shared\clientfield_shared;
6 #using scripts\shared\demo_shared;
7 #using scripts\shared\laststand_shared;
8 #using scripts\shared\system_shared;
9 #using scripts\shared\util_shared;
11 #using scripts\shared\ai\zombie_utility;
13 #insert scripts\shared\shared.gsh;
14 #insert scripts\shared\version.gsh;
15 #insert scripts\shared\archetype_shared\archetype_shared.gsh;
17 #using scripts\zm\_util;
18 #using scripts\zm\_zm_audio;
19 #using scripts\zm\_zm_laststand;
20 #using scripts\zm\_zm_net;
21 #using scripts\zm\_zm_score;
22 #using scripts\zm\_zm_stats;
23 #using scripts\zm\_zm_spawner;
24 #using scripts\zm\_zm_utility;
25 #using scripts\zm\_zm_weapons;
27 #insert scripts\zm\_zm_lightning_chain.gsh;
29 #namespace lightning_chain;
34 #define FX_LC_BOLT "zombie/fx_tesla_bolt_secondary_zmb"
35 #define FX_LC_SHOCK "zombie/fx_tesla_shock_zmb"
36 #define FX_LC_SHOCK_SECONDARY "zombie/fx_tesla_bolt_secondary_zmb"
37 #define FX_LC_SHOCK_EYES "zombie/fx_tesla_shock_eyes_zmb"
38 #define FX_LC_SHOCK_NONFATAL "zombie/fx_bmode_shock_os_zod_zmb"
41 #precache( "fx", FX_LC_BOLT );
42 #precache( "fx", FX_LC_SHOCK );
43 #precache( "fx", FX_LC_SHOCK_SECONDARY );
44 #precache( "fx", FX_LC_SHOCK_NONFATAL );
45 #precache( "fx", FX_LC_SHOCK_EYES );
70 max_enemies_killed = 10,
74 arc_travel_time = 0.11,
75 kills_for_powerup = 10,
76 min_fx_distance = 128,
77 network_death_choke = 4,
78 should_kill_enemies =
true,
80 arc_fx_sound = undefined,
82 prevent_weapon_kill_credit =
false
86 lcp.max_arcs = max_arcs;
87 lcp.max_enemies_killed = max_enemies_killed;
88 lcp.radius_start = radius_start;
89 lcp.radius_decay = radius_decay;
90 lcp.head_gib_chance = head_gib_chance;
91 lcp.arc_travel_time = arc_travel_time;
92 lcp.kills_for_powerup = kills_for_powerup;
93 lcp.min_fx_distance = min_fx_distance;
94 lcp.network_death_choke = network_death_choke;
95 lcp.should_kill_enemies = should_kill_enemies;
96 lcp.clientside_fx = clientside_fx;
97 lcp.arc_fx_sound = arc_fx_sound;
99 lcp.prevent_weapon_kill_credit = prevent_weapon_kill_credit;
106 self endon(
"disconnect" );
107 self endon(
"death" );
108 self waittill(
"spawned_player" );
110 self.tesla_network_death_choke = 0;
115 self.tesla_network_death_choke = 0;
120 function arc_damage( source_enemy, player, arc_num, params = level.default_lightning_chain_params )
123 player endon(
"disconnect" );
125 DEFAULT( player.tesla_network_death_choke, 0 );
126 DEFAULT( player.tesla_enemies_hit, 0 );
128 zm_utility::debug_print(
"TESLA: Evaulating arc damage for arc: " + arc_num +
" Current enemies hit: " + player.tesla_enemies_hit );
132 radius_decay = params.radius_decay * arc_num;
133 origin =
self GetTagOrigin(
"j_head" );
134 if ( !IsDefined( origin ) )
136 origin =
self.origin;
144 self thread
lc_do_damage( source_enemy, arc_num, player, params );
148 for( i = 0; i < enemies.size; i++ )
150 if( !isdefined(enemies[i]) || enemies[i] ==
self )
161 player.tesla_enemies_hit++;
163 enemies[i]
arc_damage(
self, player, arc_num + 1, params );
168 function arc_damage_ent( player, arc_num, params = level.default_lightning_chain_params )
176 if ( arc_num >= params.max_arcs )
183 if ( enemies_hit_num >= params.max_enemies_killed )
189 radius_decay = params.radius_decay * arc_num;
190 if ( params.radius_start - radius_decay <= 0 )
203 distance_squared = distance * distance;
206 if ( !IsDefined( player.tesla_enemies ) )
209 if( player.tesla_enemies.size>0 )
211 player.tesla_enemies = array::get_all_closest( origin, player.tesla_enemies );
215 zombies = player.tesla_enemies;
217 if ( IsDefined( zombies ) )
219 for ( i = 0; i < zombies.size; i++ )
221 if ( !IsDefined( zombies[i] ) )
226 if (
IS_TRUE( zombies[i].lightning_chain_immune ) )
231 test_origin = zombies[i] GetTagOrigin(
"j_head" );
232 if ( !IsDefined( test_origin ) )
234 test_origin = zombies[i].origin;
237 if ( IsDefined( zombies[i].zombie_tesla_hit ) && zombies[i].zombie_tesla_hit ==
true )
247 if ( DistanceSquared( origin, test_origin ) > distance_squared )
252 if ( !BulletTracePassed( origin, test_origin,
false, undefined ) )
257 enemies[enemies.size] = zombies[i];
267 if( IsDefined( enemy ) )
269 if( IsArray( enemy ) )
271 for( i = 0; i < enemy.size; i++ )
273 if ( IsDefined(enemy[i]) )
274 enemy[i].zombie_tesla_hit = hit;
279 if ( IsDefined(enemy) )
280 enemy.zombie_tesla_hit = hit;
288 player endon(
"disconnect" );
292 wait( randomfloatrange( 0.2, 0.6 ) * arc_num );
295 if( !IsDefined(
self ) || !IsAlive(
self ) )
301 if ( params.clientside_fx )
309 if( !IsDefined(
self ) || !IsAlive(
self ) )
315 if( IsDefined( source_enemy ) && source_enemy !=
self )
317 if ( player.tesla_arc_count > 3 )
320 player.tesla_arc_count = 0;
323 player.tesla_arc_count++;
327 while ( player.tesla_network_death_choke > params.network_death_choke )
329 zm_utility::debug_print(
"TESLA: Choking Tesla Damage. Dead enemies this network frame: " + player.tesla_network_death_choke );
333 if( !IsDefined(
self ) || !IsAlive(
self ) )
339 player.tesla_network_death_choke++;
343 self.tesla_death = params.should_kill_enemies;
346 origin = player.origin;
347 if ( IsDefined( source_enemy ) && source_enemy !=
self )
349 origin = source_enemy.origin;
352 if( !IsDefined(
self ) || !IsAlive(
self ) )
357 if( params.should_kill_enemies )
359 if ( IsDefined(
self.tesla_damage_func ) )
361 self [[
self.tesla_damage_func ]]( origin, player );
364 else if(
IS_TRUE( params.prevent_weapon_kill_credit ) )
366 self DoDamage(
self.health + 666, origin, player, undefined,
"none",
"MOD_UNKNOWN", 0, level.weaponNone );
370 weapon = level.weaponNone;
371 if ( isdefined(params.weapon) )
373 weapon = params.weapon;
375 self DoDamage(
self.health + 666, origin, player, undefined,
"none",
"MOD_UNKNOWN", 0, weapon );
379 self.deathpoints_already_given =
true;
383 if ( IsDefined( params.challenge_stat_name ) && IsDefined( player ) && IsPlayer( player ) )
399 tag =
"J_SpineUpper";
403 b_can_clientside =
true;
410 if( isdefined(
self.teslafxtag) )
412 b_can_clientside =
false;
413 tag =
self.teslafxtag;
422 fx =
"tesla_shock_secondary";
426 if ( !params.should_kill_enemies )
428 fx =
"tesla_shock_nonfatal";
435 else if ( params.clientside_fx && b_can_clientside )
444 if ( IsDefined(
self.tesla_head_gib_func ) && !
self.head_gibbed && params.should_kill_enemies && !
IS_TRUE(
self.no_gib) )
446 [[
self.tesla_head_gib_func ]]();
453 if ( !IsDefined(
self ) || !IsDefined( target ) )
456 wait( params.arc_travel_time );
460 tag =
"J_SpineUpper";
471 target_tag =
"J_SpineUpper";
475 target_tag =
"J_Spine1";
482 origin =
self GetTagOrigin( tag );
483 target_origin = target GetTagOrigin( target_tag );
484 distance_squared = params.min_fx_distance * params.min_fx_distance;
486 if ( DistanceSquared( origin, target_origin ) < distance_squared )
494 fx = PlayFxOnTag( level._effect[
"tesla_bolt"], fxOrg,
"tag_origin" );
495 if( isdefined( params.arc_fx_sound ) )
497 PlaySoundAtPosition( params.arc_fx_sound, fxOrg.origin );
500 fxOrg MoveTo( target_origin, params.arc_travel_time );
501 fxOrg waittill(
"movedone" );