IL-GSC/BO1/PC/ZM/maps/_zombiemode_spawner.gsc
2024-02-18 17:32:07 -05:00

3174 lines
87 KiB
Plaintext
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include maps\_utility;
#include common_scripts\utility;
#include maps\_zombiemode_utility;
#include maps\_zombiemode_net;
#include maps\_zombiemode_audio;
#using_animtree( "generic_human" );
init()
{
level._CONTEXTUAL_GRAB_LERP_TIME = .3;
zombies = getEntArray( "zombie_spawner", "script_noteworthy" );
for( i = 0; i < zombies.size; i++ )
{
if( is_spawner_targeted_by_blocker( zombies[i] ) )
{
zombies[i].is_enabled = false;
}
}
array_thread(zombies, ::add_spawn_function, ::zombie_spawn_init);
array_thread(zombies, ::add_spawn_function, maps\_zombiemode::round_spawn_failsafe);
}
#using_animtree( "generic_human" );
is_spawner_targeted_by_blocker( ent )
{
if( IsDefined( ent.targetname ) )
{
targeters = GetEntArray( ent.targetname, "target" );
for( i = 0; i < targeters.size; i++ )
{
if( targeters[i].targetname == "zombie_door" || targeters[i].targetname == "zombie_debris" )
{
return true;
}
result = is_spawner_targeted_by_blocker( targeters[i] );
if( result )
{
return true;
}
}
}
return false;
}
zombie_spawn_init( animname_set )
{
if( !isDefined( animname_set ) )
{
animname_set = false;
}
self.targetname = "zombie";
self.script_noteworthy = undefined;
if( !animname_set )
{
self.animname = "zombie";
}
self thread play_ambient_zombie_vocals();
self.ignoreall = true;
self.ignoreme = true;
self.allowdeath = true;
self.force_gib = true;
self.is_zombie = true;
self.has_legs = true;
self allowedStances( "stand" );
self.zombie_damaged_by_bar_knockdown = false;
self.gibbed = false;
self.head_gibbed = false;
self PushPlayer( true );
self.disableArrivals = true;
self.disableExits = true;
self.grenadeawareness = 0;
self.badplaceawareness = 0;
self.ignoreSuppression = true;
self.suppressionThreshold = 1;
self.noDodgeMove = true;
self.dontShootWhileMoving = true;
self.pathenemylookahead = 0;
self.badplaceawareness = 0;
self.chatInitialized = false;
self.a.disablepain = true;
self disable_react();
self.maxhealth = level.zombie_health;
self.health = level.zombie_health;
self.freezegun_damage = 0;
self.dropweapon = false;
level thread zombie_death_event( self );
self set_zombie_run_cycle();
self thread zombie_think();
self thread zombie_gib_on_damage();
self thread zombie_damage_failsafe();
if ( !isdefined( self.no_eye_glow ) || !self.no_eye_glow )
{
self thread delayed_zombie_eye_glow();
}
self.deathFunction = ::zombie_death_animscript;
self.flame_damage_time = 0;
self.meleeDamage = 60;
self zombie_history( "zombie_spawn_init -> Spawned = " + self.origin );
self.thundergun_disintegrate_func = ::zombie_disintegrate;
self.thundergun_knockdown_func = ::zombie_knockdown;
self.tesla_head_gib_func = ::zombie_tesla_head_gib;
self setTeamForEntity( "axis" );
self notify( "zombie_init_done" );
}
delayed_zombie_eye_glow()
{
self endon("zombie_delete");
wait .5;
self zombie_eye_glow();
}
zombie_damage_failsafe()
{
self endon ("death");
continue_failsafe_damage = false;
while (1)
{
wait 0.5;
if ( !isdefined( self.enemy ) || !IsPlayer( self.enemy ) )
{
continue;
}
if (self istouching(self.enemy))
{
old_org = self.origin;
if (!continue_failsafe_damage)
{
wait 5;
}
if (!isdefined(self.enemy) || !IsPlayer( self.enemy ) || self.enemy hasperk("specialty_armorvest") )
{
continue;
}
if (self istouching(self.enemy)
&& !self.enemy maps\_laststand::player_is_in_laststand()
&& isalive(self.enemy))
{
if (distancesquared(old_org, self.origin) < (60 * 60) )
{
setsaveddvar("player_deathInvulnerableTime", 0);
self.enemy DoDamage( self.enemy.health + 1000, self.enemy.origin, undefined, undefined, "riflebullet" );
setsaveddvar("player_deathInvulnerableTime", level.startInvulnerableTime);
continue_failsafe_damage = true;
}
}
}
else
{
continue_failsafe_damage = false;
}
}
}
set_zombie_run_cycle( new_move_speed )
{
if ( isDefined( new_move_speed ) )
{
self.zombie_move_speed = new_move_speed;
}
else
{
self set_run_speed();
self.zombie_move_speed_original = self.zombie_move_speed;
}
self.needs_run_update = true;
death_anims = level._zombie_deaths[self.animname];
self.deathanim = random(death_anims);
switch(self.zombie_move_speed)
{
case "walk":
var = randomintrange(1, 8);
self set_run_anim( "walk" + var );
self.run_combatanim = level.scr_anim[self.animname]["walk" + var];
break;
case "run":
var = randomintrange(1, 6);
self set_run_anim( "run" + var );
self.run_combatanim = level.scr_anim[self.animname]["run" + var];
break;
case "sprint":
var = randomintrange(1, 4);
self set_run_anim( "sprint" + var );
self.run_combatanim = level.scr_anim[self.animname]["sprint" + var];
break;
}
}
set_run_speed()
{
rand = randomintrange( level.zombie_move_speed, level.zombie_move_speed + 35 );
if( rand <= 35 )
{
self.zombie_move_speed = "walk";
}
else if( rand <= 70 )
{
self.zombie_move_speed = "run";
}
else
{
self.zombie_move_speed = "sprint";
}
}
should_skip_teardown( rise_struct_string )
{
if( IsDefined(rise_struct_string) && rise_struct_string == "find_flesh" )
{
return true;
}
if( isDefined( self.script_string ) && self.script_string == "zombie_chaser" )
{
return true;
}
return false;
}
zombie_think()
{
self endon( "death" );
assert( !self.isdog );
rise_struct_string = undefined;
if (GetDvarInt( #"zombie_rise_test") || (isDefined(self.script_string) && self.script_string == "riser" ))
{
self thread do_zombie_rise();
self waittill("risen", rise_struct_string );
}
else
{
self notify("no_rise");
}
node = undefined;
desired_nodes = [];
self.entrance_nodes = [];
if ( IsDefined( level.max_barrier_search_dist_override ) )
{
max_dist = level.max_barrier_search_dist_override;
}
else
{
max_dist = 500;
}
if( IsDefined( self.target ) && self.target != "" )
{
desired_origin = get_desired_origin();
AssertEx( IsDefined( desired_origin ), "Spawner @ " + self.origin + " has a .target but did not find a target" );
origin = desired_origin;
node = getclosest( origin, level.exterior_goals );
self.entrance_nodes[0] = node;
self zombie_history( "zombie_think -> #1 entrance (script_forcegoal) origin = " + self.entrance_nodes[0].origin );
}
else if ( self should_skip_teardown( rise_struct_string ) )
{
self zombie_setup_attack_properties();
if (isDefined(self.target))
{
end_at_node = GetNode(self.target, "targetname");
if (isDefined(end_at_node))
{
self setgoalnode (end_at_node);
self waittill("goal");
}
}
self thread find_flesh();
return;
}
else
{
origin = self.origin;
desired_origin = get_desired_origin();
if( IsDefined( desired_origin ) )
{
origin = desired_origin;
}
nodes = get_array_of_closest( origin, level.exterior_goals, undefined, 3 );
desired_nodes[0] = nodes[0];
prev_dist = Distance( self.origin, nodes[0].origin );
for( i = 1; i < nodes.size; i++ )
{
dist = Distance( self.origin, nodes[i].origin );
if( ( dist - prev_dist ) > max_dist )
{
break;
}
prev_dist = dist;
desired_nodes[i] = nodes[i];
}
node = desired_nodes[0];
if( desired_nodes.size > 1 )
{
node = desired_nodes[RandomInt(desired_nodes.size)];
}
self.entrance_nodes = desired_nodes;
self zombie_history( "zombie_think -> #1 entrance origin = " + node.origin );
self thread zombie_assure_node();
}
AssertEx( IsDefined( node ), "Did not find a node!!! [Should not see this!]" );
level thread draw_line_ent_to_pos( self, node.origin, "goal" );
self.first_node = node;
self thread zombie_goto_entrance( node );
}
get_desired_origin()
{
if( IsDefined( self.target ) )
{
ent = GetEnt( self.target, "targetname" );
if( !IsDefined( ent ) )
{
ent = getstruct( self.target, "targetname" );
}
if( !IsDefined( ent ) )
{
ent = GetNode( self.target, "targetname" );
}
AssertEx( IsDefined( ent ), "Cannot find the targeted ent/node/struct, \"" + self.target + "\" at " + self.origin );
return ent.origin;
}
return undefined;
}
zombie_goto_entrance( node, endon_bad_path )
{
assert( !self.isdog );
self endon( "death" );
level endon( "intermission" );
if( IsDefined( endon_bad_path ) && endon_bad_path )
{
self endon( "bad_path" );
}
self zombie_history( "zombie_goto_entrance -> start goto entrance " + node.origin );
self.got_to_entrance = false;
self.goalradius = 128;
self SetGoalPos( node.origin );
self waittill( "goal" );
self.got_to_entrance = true;
self zombie_history( "zombie_goto_entrance -> reached goto entrance " + node.origin );
self tear_into_building();
if(isDefined(self.first_node.clip))
{
if(!isDefined(self.first_node.clip.disabled) || !self.first_node.clip.disabled)
{
self.first_node.clip disable_trigger();
self.first_node.clip connectpaths();
}
}
self zombie_setup_attack_properties();
if( isDefined( level.pre_aggro_pathfinding_func ) )
{
self [[ level.pre_aggro_pathfinding_func ]]();
}
self thread find_flesh();
}
zombie_assure_node()
{
self endon( "death" );
self endon( "goal" );
level endon( "intermission" );
start_pos = self.origin;
if(IsDefined(self.entrance_nodes))
{
for( i = 0; i < self.entrance_nodes.size; i++ )
{
if( self zombie_bad_path() )
{
self zombie_history( "zombie_assure_node -> assigned assured node = " + self.entrance_nodes[i].origin );
println( "^1Zombie @ " + self.origin + " did not move for 1 second. Going to next closest node @ " + self.entrance_nodes[i].origin );
level thread draw_line_ent_to_pos( self, self.entrance_nodes[i].origin, "goal" );
self.first_node = self.entrance_nodes[i];
self SetGoalPos( self.entrance_nodes[i].origin );
}
else
{
return;
}
}
}
wait(2);
nodes = get_array_of_closest( self.origin, level.exterior_goals, undefined, 20 );
if(IsDefined(nodes))
{
self.entrance_nodes = nodes;
for( i = 0; i < self.entrance_nodes.size; i++ )
{
if( self zombie_bad_path() )
{
self zombie_history( "zombie_assure_node -> assigned assured node = " + self.entrance_nodes[i].origin );
println( "^1Zombie @ " + self.origin + " did not move for 1 second. Going to next closest node @ " + self.entrance_nodes[i].origin );
level thread draw_line_ent_to_pos( self, self.entrance_nodes[i].origin, "goal" );
self.first_node = self.entrance_nodes[i];
self SetGoalPos( self.entrance_nodes[i].origin );
}
else
{
return;
}
}
}
self zombie_history( "zombie_assure_node -> failed to find a good entrance point" );
wait(20);
self DoDamage( self.health + 10, self.origin );
}
zombie_bad_path()
{
self endon( "death" );
self endon( "goal" );
self thread zombie_bad_path_notify();
self thread zombie_bad_path_timeout();
self.zombie_bad_path = undefined;
while( !IsDefined( self.zombie_bad_path ) )
{
wait( 0.05 );
}
self notify( "stop_zombie_bad_path" );
return self.zombie_bad_path;
}
zombie_bad_path_notify()
{
self endon( "death" );
self endon( "stop_zombie_bad_path" );
self waittill( "bad_path" );
self.zombie_bad_path = true;
}
zombie_bad_path_timeout()
{
self endon( "death" );
self endon( "stop_zombie_bad_path" );
wait( 2 );
self.zombie_bad_path = false;
}
tear_into_building()
{
self endon( "death" );
self endon("teleporting");
self zombie_history( "tear_into_building -> start" );
while( 1 )
{
if( IsDefined( self.first_node.script_noteworthy ) )
{
if( self.first_node.script_noteworthy == "no_blocker" )
{
return;
}
}
if( !IsDefined( self.first_node.target ) )
{
return;
}
if( all_chunks_destroyed( self.first_node.barrier_chunks ) )
{
self zombie_history( "tear_into_building -> all chunks destroyed" );
}
if( !get_attack_spot( self.first_node ) )
{
self zombie_history( "tear_into_building -> Could not find an attack spot" );
self thread do_a_taunt();
wait( 0.5 );
continue;
}
self.goalradius = 2;
self SetGoalPos( self.attacking_spot, self.first_node.angles );
attacking_spot1a = self.attacking_spot;
self waittill( "goal" );
self waittill_notify_or_timeout( "orientdone", 1 );
self zombie_history( "tear_into_building -> Reach position and orientated" );
if( all_chunks_destroyed( self.first_node.barrier_chunks ) )
{
self zombie_history( "tear_into_building -> all chunks destroyed" );
for( i = 0; i < self.first_node.attack_spots_taken.size; i++ )
{
self.first_node.attack_spots_taken[i] = false;
}
return;
}
while( 1 )
{
chunk = get_closest_non_destroyed_chunk( self.origin, self.first_node.barrier_chunks );
if( !IsDefined( chunk ) )
{
if( !all_chunks_destroyed( self.first_node.barrier_chunks ) )
{
attack = self should_attack_player_thru_boards();
if(isDefined(attack) && !attack && self.has_legs)
{
self do_a_taunt();
}
else
{
wait_network_frame();
}
continue;
}
for( i = 0; i < self.first_node.attack_spots_taken.size; i++ )
{
self.first_node.attack_spots_taken[i] = false;
}
return;
}
self zombie_history( "tear_into_building -> animating" );
tear_anim = get_tear_anim(chunk, self);
chunk maps\_zombiemode_blockers::update_states("target_by_zombie");
self thread maps\_zombiemode_audio::do_zombies_playvocals( "teardown", self.animname );
self AnimScripted( "tear_anim", attacking_spot1a, self.first_node.angles, tear_anim, "normal", undefined, 1, 0.3 );
if ( tear_anim == %ai_zombie_bar_bend_l || tear_anim == %ai_zombie_bar_bend_l_2 || tear_anim == %ai_zombie_bar_bend_r || tear_anim == %ai_zombie_bar_bend_r_2 || tear_anim == %ai_zombie_bar_bend_m_1 || tear_anim == %ai_zombie_bar_bend_m_2 )
{
self playsound( "zmb_bar_bend" );
}
self zombie_tear_notetracks( "tear_anim", chunk, self.first_node );
attack = self should_attack_player_thru_boards();
if(isDefined(attack) && !attack && self.has_legs)
{
self do_a_taunt();
}
if( all_chunks_destroyed( self.first_node.barrier_chunks ) )
{
for( i = 0; i < self.first_node.attack_spots_taken.size; i++ )
{
self.first_node.attack_spots_taken[i] = false;
}
return;
}
}
self reset_attack_spot();
}
}
do_a_taunt()
{
self endon ("death");
if( !self.has_legs)
{
return false;
}
self.old_origin = self.origin;
if(GetDvar( #"zombie_taunt_freq") == "")
{
setdvar("zombie_taunt_freq","5");
}
freq = GetDvarInt( #"zombie_taunt_freq");
if( freq >= randomint(100) )
{
anime = random(level._zombie_board_taunt[self.animname]);
self thread maps\_zombiemode_audio::do_zombies_playvocals( "taunt", self.animname );
self animscripted("zombie_taunt",self.origin,self.angles,anime, "normal", undefined, 1, 0.4 );
wait(getanimlength(anime));
self ForceTeleport(self.old_origin);
}
}
should_attack_player_thru_boards()
{
if( !self.has_legs)
{
return false;
}
if(IsDefined(self.first_node.barrier_chunks))
{
for(i=0;i<self.first_node.barrier_chunks.size;i++)
{
if(IsDefined(self.first_node.barrier_chunks[i].unbroken) && self.first_node.barrier_chunks[i].unbroken == true )
{
return false;
}
}
}
if(GetDvar( #"zombie_reachin_freq") == "")
{
setdvar("zombie_reachin_freq","50");
}
freq = GetDvarInt( #"zombie_reachin_freq");
players = get_players();
attack = false;
self.player_targets = [];
for(i=0;i<players.size;i++)
{
if(distance2d(self.origin,players[i].origin) <= 72)
{
self.player_targets[self.player_targets.size] = players[i];
attack = true;
}
}
if(attack && freq >= randomint(100) )
{
self.old_origin = self.origin;
if(self.attacking_spot_index == 0)
{
if(randomint(100) > 50)
{
self thread maps\_zombiemode_audio::do_zombies_playvocals( "attack", self.animname );
self animscripted("window_melee",self.origin,self.angles,%ai_zombie_window_attack_arm_l_out, "normal", undefined, 1, 0.3 );
}
else
{
self thread maps\_zombiemode_audio::do_zombies_playvocals( "attack", self.animname );
self animscripted("window_melee",self.origin,self.angles,%ai_zombie_window_attack_arm_r_out, "normal", undefined, 1, 0.3 );
}
self window_notetracks( "window_melee" );
}
else if(self.attacking_spot_index == 2)
{
self thread maps\_zombiemode_audio::do_zombies_playvocals( "attack", self.animname );
self animscripted("window_melee",self.origin,self.angles,%ai_zombie_window_attack_arm_r_out, "normal", undefined, 1, 0.3 );
self window_notetracks( "window_melee" );
}
else if(self.attacking_spot_index == 1)
{
self thread maps\_zombiemode_audio::do_zombies_playvocals( "attack", self.animname );
self animscripted("window_melee",self.origin,self.angles,%ai_zombie_window_attack_arm_l_out, "normal", undefined, 1, 0.3 );
self window_notetracks( "window_melee" );
}
}
else
{
return false;
}
}
window_notetracks(msg)
{
while(1)
{
self waittill( msg, notetrack );
if( notetrack == "end" )
{
self teleport(self.old_origin);
return;
}
if( notetrack == "fire" )
{
if(self.ignoreall)
{
self.ignoreall = false;
}
if ( isDefined( self.first_node ) )
{
_MELEE_DIST_SQ = 72*72;
_TRIGGER_DIST_SQ = 37*37;
for ( i = 0; i < self.player_targets.size; i++ )
{
playerDistSq = Distance2DSquared( self.player_targets[i].origin, self.origin );
heightDiff = abs( self.player_targets[i].origin[2] - self.origin[2] );
if ( playerDistSq < _MELEE_DIST_SQ && (heightDiff * heightDiff) < _MELEE_DIST_SQ )
{
triggerDistSq = Distance2DSquared( self.player_targets[i].origin, self.first_node.trigger_location.origin );
heightDiff = abs( self.player_targets[i].origin[2] - self.first_node.trigger_location.origin[2] );
if ( triggerDistSq < _TRIGGER_DIST_SQ && (heightDiff * heightDiff) < _TRIGGER_DIST_SQ )
{
self.player_targets[i] DoDamage( self.meleeDamage, self.player_targets[i].origin, self, 0, "MOD_MELEE" );
break;
}
}
}
}
else
{
self melee();
}
}
}
}
reset_attack_spot()
{
if( IsDefined( self.attacking_node ) )
{
node = self.attacking_node;
index = self.attacking_spot_index;
node.attack_spots_taken[index] = false;
self.attacking_node = undefined;
self.attacking_spot_index = undefined;
}
}
get_attack_spot( node )
{
index = get_attack_spot_index( node );
if( !IsDefined( index ) )
{
return false;
}
self.attacking_node = node;
self.attacking_spot_index = index;
node.attack_spots_taken[index] = true;
self.attacking_spot = node.attack_spots[index];
return true;
}
get_attack_spot_index( node )
{
indexes = [];
for( i = 0; i < node.attack_spots.size; i++ )
{
if( !node.attack_spots_taken[i] )
{
indexes[indexes.size] = i;
}
}
if( indexes.size == 0 )
{
return undefined;
}
return indexes[RandomInt( indexes.size )];
}
zombie_tear_notetracks( msg, chunk, node )
{
random_chance = undefined;
self endon("death");
chunk thread check_for_zombie_death(self);
while( 1 )
{
self waittill( msg, notetrack );
if( notetrack == "end" )
{
return;
}
if( notetrack == "board" )
{
if( !chunk.destroyed )
{
self.lastchunk_destroy_time = getTime();
PlayFx( level._effect["wood_chunk_destory"], chunk.origin );
if(chunk.script_noteworthy == "4" || chunk.script_noteworthy == "6")
{
chunk thread zombie_boardtear_offset_fx_horizontle(chunk, node);
}
else
{
chunk thread zombie_boardtear_offset_fx_verticle(chunk, node);
}
zomb = self;
level thread maps\_zombiemode_blockers::remove_chunk( chunk, node, true, zomb );
chunk notify("destroyed");
}
}
else if( notetrack == "bar_bend" )
{
if( !chunk.destroyed )
{
self.lastchunk_destroy_time = getTime();
if( chunk.script_noteworthy == "3" )
{
if( IsDefined( chunk.script_string ) )
{
if( chunk.script_string == "prestine_bend" )
{
bar_bend_left = spawn( "script_model", chunk.origin);
bar_bend_left RotateTo( chunk.angles , 0.2, 0.1, 0.1 );
bar_bend_left waittill("rotatedone");
bar_bend_left SetModel( "p_zom_win_cell_bars_01_vert01_bent" );
chunk Hide();
thread bar_repair_bend_left( bar_bend_left, chunk);
}
else if ( chunk.script_string == "bar_bend" )
{
bar_bend_left = spawn( "script_model", chunk.origin);
bar_bend_left RotateTo( chunk.angles , 0.2, 0.1, 0.1 );
bar_bend_left waittill("rotatedone");
bar_bend_left SetModel( "p_zom_win_cell_bars_bent_01_vert01_bent" );
chunk Hide();
thread bar_repair_bend_left( bar_bend_left, chunk);
}
}
}
if( chunk.script_noteworthy == "5" )
{
if( IsDefined( chunk.script_string ) )
{
if( chunk.script_string == "prestine_bend" )
{
bar_bend_right = spawn( "script_model", chunk.origin);
bar_bend_right RotateTo( chunk.angles , 0.2, 0.1, 0.1 );
bar_bend_right waittill("rotatedone");
bar_bend_right SetModel( "p_zom_win_cell_bars_01_vert04_bent" );
chunk Hide();
thread bar_repair_bend_right( bar_bend_right, chunk);
}
else if ( chunk.script_string == "bar_bend" )
{
bar_bend_right = spawn( "script_model", chunk.origin);
bar_bend_right RotateTo( chunk.angles , 0.2, 0.1, 0.1 );
bar_bend_right waittill("rotatedone");
bar_bend_right SetModel( "p_zom_win_cell_bars_bent_01_vert04_bent" );
chunk Hide();
thread bar_repair_bend_right( bar_bend_right, chunk);
}
}
}
zomb = self;
chunk thread zombie_bartear_offset_fx_verticle( chunk );
level thread maps\_zombiemode_blockers::remove_chunk( chunk, node, true, zomb );
chunk notify( "destroyed" );
}
}
else if( notetrack == "bar" )
{
if( !chunk.destroyed )
{
self.lastchunk_destroy_time = getTime();
if(chunk.script_noteworthy == "4" || chunk.script_noteworthy == "6")
{
if ( IsDefined( chunk.script_squadname ) && ( chunk.script_squadname == "cosmodrome_storage_area" ) )
{
}
if (!IsDefined( chunk.script_squadname ) )
{
chunk thread zombie_bartear_offset_fx_horizontle(chunk);
}
}
else
{
if ( IsDefined( chunk.script_squadname ) && ( chunk.script_squadname == "cosmodrome_storage_area" ) )
{
}
if (!IsDefined( chunk.script_squadname ) )
{
chunk thread zombie_bartear_offset_fx_verticle(chunk);
}
}
level thread maps\_zombiemode_blockers::remove_chunk( chunk, node, true, self );
chunk notify("destroyed");
}
}
}
}
bar_repair_bend_left( bar_bend_left, chunk )
{
while(1)
{
wait(0.2);
if( chunk get_chunk_state() == "repaired" )
{
bar_bend_left delete();
break;
}
}
}
bar_repair_bend_right( bar_bend_right, chunk )
{
while(1)
{
wait(0.2);
if( chunk get_chunk_state() == "repaired" )
{
bar_bend_right delete();
break;
}
}
}
zombie_boardtear_offset_fx_horizontle( chunk, node )
{
if ( IsDefined( chunk.script_parameters ) && ( chunk.script_parameters == "repair_board" ) )
{
if(IsDefined(chunk.unbroken) && chunk.unbroken == true)
{
if(IsDefined(chunk.material) && chunk.material == "glass")
{
PlayFX( level._effect["glass_break"], chunk.origin, node.angles );
chunk.unbroken = false;
}
else if(IsDefined(chunk.material) && chunk.material == "metal")
{
PlayFX( level._effect["fx_zombie_bar_break"], chunk.origin );
chunk.unbroken = false;
}
else
{
PlayFX( level._effect["wall_break"], chunk.origin );
chunk.unbroken = false;
}
}
}
else
{
PlayFx( level._effect["wood_chunk_destory"], chunk.origin + (0, 0, 30));
wait( randomfloat( 0.2, 0.4 ));
PlayFx( level._effect["wood_chunk_destory"], chunk.origin + (0, 0, -30));
}
}
zombie_boardtear_offset_fx_verticle( chunk, node )
{
if ( IsDefined( chunk.script_parameters ) && ( chunk.script_parameters == "repair_board" ) )
{
if(IsDefined(chunk.unbroken) && chunk.unbroken == true)
{
if(IsDefined(chunk.material) && chunk.material == "glass")
{
PlayFX( level._effect["glass_break"], chunk.origin, node.angles );
chunk.unbroken = false;
}
else if(IsDefined(chunk.material) && chunk.material == "metal")
{
PlayFX( level._effect["fx_zombie_bar_break"], chunk.origin );
chunk.unbroken = false;
}
else
{
PlayFX( level._effect["wall_break"], chunk.origin );
chunk.unbroken = false;
}
}
}
else
{
PlayFx( level._effect["wood_chunk_destory"], chunk.origin + (30, 0, 0));
wait( randomfloat( 0.2, 0.4 ));
PlayFx( level._effect["wood_chunk_destory"], chunk.origin + (-30, 0, 0));
}
}
zombie_bartear_offset_fx_verticle( chunk )
{
if ( IsDefined ( chunk.script_parameters ) && ( chunk.script_parameters == "bar" ) || ( chunk.script_noteworthy == "board" ))
{
possible_tag_array_1 = [];
possible_tag_array_1[0] = "Tag_fx_top";
possible_tag_array_1[1] = "";
possible_tag_array_1[2] = "Tag_fx_top";
possible_tag_array_1[3] = "";
possible_tag_array_2 = [];
possible_tag_array_2[0] = "";
possible_tag_array_2[1] = "Tag_fx_bottom";
possible_tag_array_2[2] = "";
possible_tag_array_2[3] = "Tag_fx_bottom";
possible_tag_array_2 = array_randomize( possible_tag_array_2 );
random_fx = [];
random_fx[0] = level._effect["fx_zombie_bar_break"];
random_fx[1] = level._effect["fx_zombie_bar_break_lite"];
random_fx[2] = level._effect["fx_zombie_bar_break"];
random_fx[3] = level._effect["fx_zombie_bar_break_lite"];
random_fx = array_randomize( random_fx );
switch( randomInt( 9 ) )
{
case 0:
PlayFXOnTag( level._effect["fx_zombie_bar_break_lite"], chunk, "Tag_fx_top" );
wait( randomfloat( 0.0, 0.3 ));
PlayFXOnTag( level._effect["fx_zombie_bar_break_lite"], chunk, "Tag_fx_bottom" );
break;
case 1:
PlayFXOnTag( level._effect["fx_zombie_bar_break"], chunk, "Tag_fx_top" );
wait( randomfloat( 0.0, 0.3 ));
PlayFXOnTag( level._effect["fx_zombie_bar_break"], chunk, "Tag_fx_bottom" );
break;
case 2:
PlayFXOnTag( level._effect["fx_zombie_bar_break_lite"], chunk, "Tag_fx_top" );
wait( randomfloat( 0.0, 0.3 ));
PlayFXOnTag( level._effect["fx_zombie_bar_break"], chunk, "Tag_fx_bottom" );
break;
case 3:
PlayFXOnTag( level._effect["fx_zombie_bar_break"], chunk, "Tag_fx_top" );
wait( randomfloat( 0.0, 0.3 ));
PlayFXOnTag( level._effect["fx_zombie_bar_break_lite"], chunk, "Tag_fx_bottom" );
break;
case 4:
PlayFXOnTag( level._effect["fx_zombie_bar_break_lite"], chunk, "Tag_fx_top" );
wait( randomfloat( 0.0, 0.3 ));
PlayFXOnTag( level._effect["fx_zombie_bar_break_lite"], chunk, "Tag_fx_bottom" );
break;
case 5:
PlayFXOnTag( level._effect["fx_zombie_bar_break_lite"], chunk, "Tag_fx_top" );
break;
case 6:
PlayFXOnTag( level._effect["fx_zombie_bar_break_lite"], chunk, "Tag_fx_bottom" );
break;
case 7:
PlayFXOnTag( level._effect["fx_zombie_bar_break"], chunk, "Tag_fx_top" );
break;
case 8:
PlayFXOnTag( level._effect["fx_zombie_bar_break"], chunk, "Tag_fx_bottom" );
break;
}
}
if ( IsDefined ( chunk.script_parameters ) && ( chunk.script_parameters == "grate" ) )
{
EarthQuake( RandomFloatRange( 0.3, 0.4 ), RandomFloatRange(0.2, 0.4), chunk.origin, 150 );
chunk play_sound_on_ent( "bar_rebuild_slam" );
switch( randomInt( 9 ) )
{
case 0:
PlayFX( level._effect["fx_zombie_bar_break"], chunk.origin + (-30, 0, 0) );
wait( randomfloat( 0.0, 0.3 ));
PlayFX( level._effect["fx_zombie_bar_break_lite"], chunk.origin + (-30, 0, 0) );
break;
case 1:
PlayFX( level._effect["fx_zombie_bar_break"], chunk.origin + (-30, 0, 0) );
wait( randomfloat( 0.0, 0.3 ));
PlayFX( level._effect["fx_zombie_bar_break"], chunk.origin + (-30, 0, 0) );
break;
case 2:
PlayFX( level._effect["fx_zombie_bar_break_lite"], chunk.origin + (-30, 0, 0) );
wait( randomfloat( 0.0, 0.3 ));
PlayFX( level._effect["fx_zombie_bar_break"], chunk.origin + (-30, 0, 0) );
break;
case 3:
PlayFX( level._effect["fx_zombie_bar_break"], chunk.origin + (-30, 0, 0) );
wait( randomfloat( 0.0, 0.3 ));
PlayFX( level._effect["fx_zombie_bar_break_lite"], chunk.origin + (-30, 0, 0) );
break;
case 4:
PlayFX( level._effect["fx_zombie_bar_break_lite"], chunk.origin + (-30, 0, 0) );
wait( randomfloat( 0.0, 0.3 ));
PlayFX( level._effect["fx_zombie_bar_break_lite"], chunk.origin + (-30, 0, 0) );
break;
case 5:
PlayFX( level._effect["fx_zombie_bar_break_lite"], chunk.origin + (-30, 0, 0) );
break;
case 6:
PlayFX( level._effect["fx_zombie_bar_break_lite"], chunk.origin + (-30, 0, 0) );
break;
case 7:
PlayFX( level._effect["fx_zombie_bar_break"], chunk.origin + (-30, 0, 0) );
break;
case 8:
PlayFX( level._effect["fx_zombie_bar_break"], chunk.origin + (-30, 0, 0) );
break;
}
}
}
zombie_bartear_offset_fx_horizontle( chunk )
{
if ( IsDefined ( chunk.script_parameters ) && ( chunk.script_parameters == "bar" ) || ( chunk.script_noteworthy == "board" ))
{
switch( randomInt( 10 ) )
{
case 0:
PlayFXOnTag( level._effect["fx_zombie_bar_break_lite"], chunk, "Tag_fx_left" );
wait( randomfloat( 0.0, 0.3 ));
PlayFXOnTag( level._effect["fx_zombie_bar_break_lite"], chunk, "Tag_fx_right" );
break;
case 1:
PlayFXOnTag( level._effect["fx_zombie_bar_break"], chunk, "Tag_fx_left" );
wait( randomfloat( 0.0, 0.3 ));
PlayFXOnTag( level._effect["fx_zombie_bar_break"], chunk, "Tag_fx_right" );
break;
case 2:
PlayFXOnTag( level._effect["fx_zombie_bar_break_lite"], chunk, "Tag_fx_left" );
wait( randomfloat( 0.0, 0.3 ));
PlayFXOnTag( level._effect["fx_zombie_bar_break"], chunk, "Tag_fx_right" );
break;
case 3:
PlayFXOnTag( level._effect["fx_zombie_bar_break"], chunk, "Tag_fx_left" );
wait( randomfloat( 0.0, 0.3 ));
PlayFXOnTag( level._effect["fx_zombie_bar_break_lite"], chunk, "Tag_fx_right" );
break;
case 4:
PlayFXOnTag( level._effect["fx_zombie_bar_break_lite"], chunk, "Tag_fx_left" );
wait( randomfloat( 0.0, 0.3 ));
PlayFXOnTag( level._effect["fx_zombie_bar_break_lite"], chunk, "Tag_fx_right" );
break;
case 5:
PlayFXOnTag( level._effect["fx_zombie_bar_break_lite"], chunk, "Tag_fx_left" );
break;
case 6:
PlayFXOnTag( level._effect["fx_zombie_bar_break_lite"], chunk, "Tag_fx_right" );
break;
case 7:
PlayFXOnTag( level._effect["fx_zombie_bar_break"], chunk, "Tag_fx_right" );
break;
case 8:
PlayFXOnTag( level._effect["fx_zombie_bar_break"], chunk, "Tag_fx_right" );
break;
}
}
}
check_for_zombie_death(zombie)
{
self endon("destroyed");
wait(2.5);
self maps\_zombiemode_blockers::update_states("repaired");
}
get_tear_anim( chunk, zombo )
{
anims = [];
anims[anims.size] = %ai_zombie_door_tear_high;
anims[anims.size] = %ai_zombie_door_tear_low;
anims[anims.size] = %ai_zombie_door_tear_left;
anims[anims.size] = %ai_zombie_door_tear_right;
anims[anims.size] = %ai_zombie_door_tear_v1;
anims[anims.size] = %ai_zombie_door_tear_v2;
anims[anims.size] = %ai_zombie_door_pound_v1;
anims[anims.size] = %ai_zombie_door_pound_v2;
tear_anim = anims[RandomInt( anims.size )];
if(isdefined(chunk.script_parameters))
{
if( chunk.script_parameters == "board" || chunk.script_parameters == "repair_board")
{
if( self.has_legs )
{
if(isdefined(chunk.script_noteworthy))
{
if(IsDefined(chunk.unbroken) && chunk.unbroken == true)
{
if(IsDefined(chunk.material) && chunk.material == "metal")
{
if(chunk.script_noteworthy == "1")
{
tear_anim = %ai_zombie_boardtear_m_1;
}
if(chunk.script_noteworthy == "2")
{
tear_anim = %ai_zombie_boardtear_m_4;
}
if(chunk.script_noteworthy == "3")
{
tear_anim = %ai_zombie_door_tear_low;
}
if(chunk.script_noteworthy == "4")
{
tear_anim = %ai_zombie_boardtear_m_5;
}
if(chunk.script_noteworthy == "5")
{
tear_anim = %ai_zombie_door_tear_low;
}
if(chunk.script_noteworthy == "6")
{
tear_anim = %ai_zombie_boardtear_m_6;
}
}
else
{
if(zombo.attacking_spot_index == 0)
{
tear_anim = %ai_zombie_door_pound_v1;
}
else
{
tear_anim = %ai_zombie_door_pound_v2;
}
}
}
else if(zombo.attacking_spot_index == 0)
{
if(chunk.script_noteworthy == "1")
{
tear_anim = %ai_zombie_boardtear_m_1;
}
else if(chunk.script_noteworthy == "2")
{
tear_anim = %ai_zombie_boardtear_m_2;
}
else if(chunk.script_noteworthy == "3")
{
tear_anim = %ai_zombie_boardtear_m_3;
}
else if(chunk.script_noteworthy == "4")
{
tear_anim = %ai_zombie_boardtear_m_4;
}
else if(chunk.script_noteworthy == "5")
{
tear_anim = %ai_zombie_boardtear_m_5;
}
else if(chunk.script_noteworthy == "6")
{
tear_anim = %ai_zombie_boardtear_m_6;
}
}
else if(zombo.attacking_spot_index == 1)
{
if(chunk.script_noteworthy == "1")
{
tear_anim = %ai_zombie_boardtear_r_1;
}
else if(chunk.script_noteworthy == "3")
{
tear_anim = %ai_zombie_boardtear_r_3;
}
else if(chunk.script_noteworthy == "4")
{
tear_anim = %ai_zombie_boardtear_r_4;
}
else if(chunk.script_noteworthy == "5")
{
tear_anim = %ai_zombie_boardtear_r_5;
}
else if(chunk.script_noteworthy == "6")
{
tear_anim = %ai_zombie_boardtear_r_6;
}
else if(chunk.script_noteworthy == "2")
{
tear_anim = %ai_zombie_boardtear_r_2;
}
}
else if(zombo.attacking_spot_index == 2)
{
if(chunk.script_noteworthy == "1")
{
tear_anim = %ai_zombie_boardtear_l_1;
}
else if(chunk.script_noteworthy == "2")
{
tear_anim = %ai_zombie_boardtear_l_2;
}
else if(chunk.script_noteworthy == "4")
{
tear_anim = %ai_zombie_boardtear_l_4;
}
else if(chunk.script_noteworthy == "5")
{
tear_anim = %ai_zombie_boardtear_l_5;
}
else if(chunk.script_noteworthy == "6")
{
tear_anim = %ai_zombie_boardtear_l_6;
}
else if(chunk.script_noteworthy == "3")
{
tear_anim = %ai_zombie_boardtear_l_3;
}
}
}
}
}
}
if(isdefined(chunk.script_parameters))
{
if( chunk.script_parameters == "bar" )
{
if( self.has_legs )
{
if(isdefined(chunk.script_noteworthy))
{
if(zombo.attacking_spot_index == 0)
{
if(chunk.script_noteworthy == "4")
{
tear_anim = %ai_zombie_bartear_m_5;
}
else if(chunk.script_noteworthy == "6")
{
tear_anim = %ai_zombie_bartear_m_6;
}
else if(chunk.script_noteworthy == "1")
{
tear_anim = %ai_zombie_bartear_m_3;
}
else if(chunk.script_noteworthy == "2")
{
tear_anim = %ai_zombie_bartear_m_2;
}
else if(chunk.script_noteworthy == "3")
{
tear_anim = %ai_zombie_bar_bend_m_2;
}
else if(chunk.script_noteworthy == "5")
{
tear_anim = %ai_zombie_bar_bend_m_1;
}
}
else if(zombo.attacking_spot_index == 1)
{
if(chunk.script_noteworthy == "4")
{
tear_anim = %ai_zombie_bartear_r_5;
}
else if(chunk.script_noteworthy == "6")
{
tear_anim = %ai_zombie_bartear_r_6;
}
else if(chunk.script_noteworthy == "1")
{
tear_anim = %ai_zombie_bartear_r_3;
}
else if(chunk.script_noteworthy == "3")
{
tear_anim = %ai_zombie_bar_bend_r;
}
else if(chunk.script_noteworthy == "2")
{
tear_anim = %ai_zombie_bartear_r_2;
}
else if(chunk.script_noteworthy == "5")
{
tear_anim = %ai_zombie_bar_bend_r_2;
}
}
else if(zombo.attacking_spot_index == 2)
{
if(chunk.script_noteworthy == "4")
{
tear_anim = %ai_zombie_bartear_l_5;
}
else if(chunk.script_noteworthy == "6")
{
tear_anim = %ai_zombie_bartear_l_6;
}
else if(chunk.script_noteworthy == "1")
{
tear_anim = %ai_zombie_bartear_l_3;
}
else if(chunk.script_noteworthy == "2")
{
tear_anim = %ai_zombie_bartear_l_2;
}
else if(chunk.script_noteworthy == "5")
{
tear_anim = %ai_zombie_bar_bend_l;
}
else if(chunk.script_noteworthy == "3")
{
tear_anim = %ai_zombie_bar_bend_L_2;
}
}
}
}
}
}
if(isdefined(chunk.script_parameters))
{
if( chunk.script_parameters == "grate" )
{
if( self.has_legs )
{
if(isdefined(chunk.script_noteworthy))
{
if(zombo.attacking_spot_index == 0)
{
if(chunk.script_noteworthy == "1")
{
tear_anim = %ai_zombie_boardtear_m_1;
}
else if(chunk.script_noteworthy == "2")
{
tear_anim = %ai_zombie_boardtear_m_2;
}
else if(chunk.script_noteworthy == "3")
{
tear_anim = %ai_zombie_boardtear_m_3;
}
else if(chunk.script_noteworthy == "4")
{
tear_anim = %ai_zombie_boardtear_m_4;
}
else if(chunk.script_noteworthy == "5")
{
tear_anim = %ai_zombie_boardtear_m_5;
}
else if(chunk.script_noteworthy == "6")
{
tear_anim = %ai_zombie_boardtear_m_6;
}
}
else if(zombo.attacking_spot_index == 1)
{
if(chunk.script_noteworthy == "1")
{
tear_anim = %ai_zombie_boardtear_r_1;
}
else if(chunk.script_noteworthy == "3")
{
tear_anim = %ai_zombie_boardtear_r_3;
}
else if(chunk.script_noteworthy == "4")
{
tear_anim = %ai_zombie_boardtear_r_4;
}
else if(chunk.script_noteworthy == "5")
{
tear_anim = %ai_zombie_boardtear_r_5;
}
else if(chunk.script_noteworthy == "6")
{
tear_anim = %ai_zombie_boardtear_r_6;
}
else if(chunk.script_noteworthy == "2")
{
tear_anim = %ai_zombie_boardtear_r_2;
}
}
else if(zombo.attacking_spot_index == 2)
{
if(chunk.script_noteworthy == "1")
{
tear_anim = %ai_zombie_boardtear_l_1;
}
else if(chunk.script_noteworthy == "2")
{
tear_anim = %ai_zombie_boardtear_l_2;
}
else if(chunk.script_noteworthy == "4")
{
tear_anim = %ai_zombie_boardtear_l_4;
}
else if(chunk.script_noteworthy == "5")
{
tear_anim = %ai_zombie_boardtear_l_5;
}
else if(chunk.script_noteworthy == "6")
{
tear_anim = %ai_zombie_boardtear_l_6;
}
else if(chunk.script_noteworthy == "3")
{
tear_anim = %ai_zombie_boardtear_l_3;
}
}
}
}
}
}
if(isdefined(chunk.script_parameters))
{
if( chunk.script_parameters == "board" || chunk.script_parameters == "repair_board")
{
if( self.has_legs == false )
{
if(isdefined(chunk.script_noteworthy))
{
if(zombo.attacking_spot_index == 0)
{
if(chunk.script_noteworthy == "1")
{
tear_anim = %ai_zombie_boardtear_crawl_m_1;
}
else if(chunk.script_noteworthy == "2")
{
tear_anim = %ai_zombie_boardtear_crawl_m_2;
}
else if(chunk.script_noteworthy == "3")
{
tear_anim = %ai_zombie_boardtear_crawl_m_3;
}
else if(chunk.script_noteworthy == "4")
{
tear_anim = %ai_zombie_boardtear_crawl_m_4;
}
else if(chunk.script_noteworthy == "5")
{
tear_anim = %ai_zombie_boardtear_crawl_m_5;
}
else if(chunk.script_noteworthy == "6")
{
tear_anim = %ai_zombie_boardtear_crawl_m_6;
}
}
else if(zombo.attacking_spot_index == 1)
{
if(chunk.script_noteworthy == "1")
{
tear_anim = %ai_zombie_boardtear_crawl_r_1;
}
else if(chunk.script_noteworthy == "3")
{
tear_anim = %ai_zombie_boardtear_crawl_r_3;
}
else if(chunk.script_noteworthy == "4")
{
tear_anim = %ai_zombie_boardtear_crawl_r_4;
}
else if(chunk.script_noteworthy == "5")
{
tear_anim = %ai_zombie_boardtear_crawl_r_5;
}
else if(chunk.script_noteworthy == "6")
{
tear_anim = %ai_zombie_boardtear_crawl_r_6;
}
else if(chunk.script_noteworthy == "2")
{
tear_anim = %ai_zombie_boardtear_crawl_r_2;
}
}
else if(zombo.attacking_spot_index == 2)
{
if(chunk.script_noteworthy == "1")
{
tear_anim = %ai_zombie_boardtear_crawl_l_1;
}
else if(chunk.script_noteworthy == "2")
{
tear_anim = %ai_zombie_boardtear_crawl_l_2;
}
else if(chunk.script_noteworthy == "4")
{
tear_anim = %ai_zombie_boardtear_crawl_l_4;
}
else if(chunk.script_noteworthy == "5")
{
tear_anim = %ai_zombie_boardtear_crawl_l_5;
}
else if(chunk.script_noteworthy == "6")
{
tear_anim = %ai_zombie_boardtear_crawl_l_6;
}
else if(chunk.script_noteworthy == "3")
{
tear_anim = %ai_zombie_boardtear_crawl_l_3;
}
}
}
}
}
}
if(isdefined(chunk.script_parameters))
{
if( chunk.script_parameters == "bar" )
{
if( self.has_legs == false )
{
if(isdefined(chunk.script_noteworthy))
{
if(zombo.attacking_spot_index == 0)
{
if(chunk.script_noteworthy == "1")
{
tear_anim = %ai_zombie_bartear_crawl_m_2;
}
else if(chunk.script_noteworthy == "2")
{
tear_anim = %ai_zombie_bartear_crawl_m_3;
}
else if(chunk.script_noteworthy == "3")
{
tear_anim = %ai_zombie_bartear_crawl_m_1;
}
else if(chunk.script_noteworthy == "4")
{
tear_anim = %ai_zombie_bartear_crawl_m_5;
}
else if(chunk.script_noteworthy == "5")
{
tear_anim = %ai_zombie_bartear_crawl_m_4;
}
else if(chunk.script_noteworthy == "6")
{
tear_anim = %ai_zombie_bartear_crawl_m_6;
}
}
else if(zombo.attacking_spot_index == 1)
{
if(chunk.script_noteworthy == "1")
{
tear_anim = %ai_zombie_bartear_crawl_r_2;
}
else if(chunk.script_noteworthy == "3")
{
tear_anim = %ai_zombie_bartear_crawl_r_1;
}
else if(chunk.script_noteworthy == "2")
{
tear_anim = %ai_zombie_bartear_crawl_r_3;
}
else if(chunk.script_noteworthy == "5")
{
tear_anim = %ai_zombie_bartear_crawl_r_4;
}
else if(chunk.script_noteworthy == "6")
{
tear_anim = %ai_zombie_bartear_crawl_r_6;
}
else if(chunk.script_noteworthy == "4")
{
tear_anim = %ai_zombie_bartear_crawl_r_5;
}
}
else if(zombo.attacking_spot_index == 2)
{
if(chunk.script_noteworthy == "1")
{
tear_anim = %ai_zombie_bartear_crawl_l_2;
}
else if(chunk.script_noteworthy == "2")
{
tear_anim = %ai_zombie_bartear_crawl_l_3;
}
else if(chunk.script_noteworthy == "4")
{
tear_anim = %ai_zombie_bartear_crawl_l_5;
}
else if(chunk.script_noteworthy == "5")
{
tear_anim = %ai_zombie_bartear_crawl_l_4;
}
else if(chunk.script_noteworthy == "6")
{
tear_anim = %ai_zombie_bartear_crawl_l_6;
}
else if(chunk.script_noteworthy == "3")
{
tear_anim = %ai_zombie_bartear_crawl_l_1;
}
}
}
}
else if( self.has_legs == false)
{
anims = [];
anims[anims.size] = %ai_zombie_attack_crawl;
anims[anims.size] = %ai_zombie_attack_crawl_lunge;
tear_anim = anims[RandomInt( anims.size )];
}
}
}
return tear_anim;
}
cap_zombie_head_gibs()
{
if( !isDefined( level.max_head_gibs_per_frame ) )
{
level.max_head_gibs_per_frame = 4;
}
while( true )
{
level.head_gibs_this_frame = 0;
wait_network_frame();
}
}
zombie_head_gib( attacker, means_of_death )
{
self endon( "death" );
if ( !is_mature() )
{
return false;
}
if ( is_german_build() )
{
return;
}
if( IsDefined( self.head_gibbed ) && self.head_gibbed )
{
return;
}
if( !isDefined( level.head_gibs_this_frame ) )
{
level thread cap_zombie_head_gibs();
}
if( level.head_gibs_this_frame >= level.max_head_gibs_per_frame )
{
return;
}
level.head_gibs_this_frame++;
self.head_gibbed = true;
self zombie_eye_glow_stop();
size = self GetAttachSize();
for( i = 0; i < size; i++ )
{
model = self GetAttachModelName( i );
if( IsSubStr( model, "head" ) )
{
if(isdefined(self.hatmodel))
{
self detach( self.hatModel, "" );
}
self Detach( model, "", true );
if ( isDefined(self.torsoDmg5) )
{
self Attach( self.torsoDmg5, "", true );
}
break;
}
}
temp_array = [];
temp_array[0] = level._ZOMBIE_GIB_PIECE_INDEX_HEAD;
self gib( "normal", temp_array );
self thread damage_over_time( self.health * 0.2, 1, attacker, means_of_death );
}
damage_over_time( dmg, delay, attacker, means_of_death )
{
self endon( "death" );
if( !IsAlive( self ) )
{
return;
}
if( !IsPlayer( attacker ) )
{
attacker = undefined;
}
while( 1 )
{
if( IsDefined( delay ) )
{
wait( delay );
}
self DoDamage( dmg, self.origin, attacker, undefined, means_of_death, self.damagelocation );
}
}
head_should_gib( attacker, type, point )
{
if ( !is_mature() )
{
return false;
}
if ( is_german_build() )
{
return false;
}
if( self.head_gibbed )
{
return false;
}
if( !IsDefined( attacker ) || !IsPlayer( attacker ) )
{
return false;
}
low_health_percent = ( self.health / self.maxhealth ) * 100;
if( low_health_percent > 10 )
{
return false;
}
weapon = attacker GetCurrentWeapon();
if( type != "MOD_RIFLE_BULLET" && type != "MOD_PISTOL_BULLET" )
{
if( type == "MOD_GRENADE" || type == "MOD_GRENADE_SPLASH" )
{
if( Distance( point, self GetTagOrigin( "j_head" ) ) > 55 )
{
return false;
}
else
{
return true;
}
}
else if( type == "MOD_PROJECTILE" )
{
if( Distance( point, self GetTagOrigin( "j_head" ) ) > 10 )
{
return false;
}
else
{
return true;
}
}
else if( WeaponClass( weapon ) != "spread" )
{
return false;
}
}
if( !animscripts\utility::damageLocationIsAny( "head", "helmet", "neck" ) )
{
return false;
}
if( weapon == "none" || weapon == "m1911_zm" || WeaponIsGasWeapon( self.weapon ) )
{
return false;
}
return true;
}
headshot_blood_fx()
{
if( !IsDefined( self ) )
{
return;
}
if( !is_mature() )
{
return;
}
fxTag = "j_neck";
fxOrigin = self GetTagOrigin( fxTag );
upVec = AnglesToUp( self GetTagAngles( fxTag ) );
forwardVec = AnglesToForward( self GetTagAngles( fxTag ) );
PlayFX( level._effect["headshot"], fxOrigin, forwardVec, upVec );
PlayFX( level._effect["headshot_nochunks"], fxOrigin, forwardVec, upVec );
wait( 0.3 );
if(IsDefined( self ))
{
if( self maps\_zombiemode_weap_tesla::enemy_killed_by_tesla() )
{
PlayFxOnTag( level._effect["tesla_head_light"], self, fxTag );
}
else
{
PlayFxOnTag( level._effect["bloodspurt"], self, fxTag );
}
}
}
zombie_gib_on_damage()
{
while( 1 )
{
self waittill( "damage", amount, attacker, direction_vec, point, type );
if( !IsDefined( self ) )
{
return;
}
if( !self zombie_should_gib( amount, attacker, type ) )
{
continue;
}
if( self head_should_gib( attacker, type, point ) && type != "MOD_BURNED" )
{
self zombie_head_gib( attacker, type );
if(IsDefined(attacker.headshot_count))
{
attacker.headshot_count++;
}
else
{
attacker.headshot_count = 1;
}
attacker.stats["headshots"] = attacker.headshot_count;
attacker.stats["zombie_gibs"]++;
continue;
}
if( !self.gibbed )
{
if( self animscripts\utility::damageLocationIsAny( "head", "helmet", "neck" ) )
{
continue;
}
refs = [];
switch( self.damageLocation )
{
case "torso_upper":
case "torso_lower":
refs[refs.size] = "guts";
refs[refs.size] = "right_arm";
break;
case "right_arm_upper":
case "right_arm_lower":
case "right_hand":
refs[refs.size] = "right_arm";
break;
case "left_arm_upper":
case "left_arm_lower":
case "left_hand":
refs[refs.size] = "left_arm";
break;
case "right_leg_upper":
case "right_leg_lower":
case "right_foot":
if( self.health <= 0 )
{
refs[refs.size] = "right_leg";
refs[refs.size] = "right_leg";
refs[refs.size] = "right_leg";
refs[refs.size] = "no_legs";
}
break;
case "left_leg_upper":
case "left_leg_lower":
case "left_foot":
if( self.health <= 0 )
{
refs[refs.size] = "left_leg";
refs[refs.size] = "left_leg";
refs[refs.size] = "left_leg";
refs[refs.size] = "no_legs";
}
break;
default:
if( self.damageLocation == "none" )
{
if( type == "MOD_GRENADE" || type == "MOD_GRENADE_SPLASH" || type == "MOD_PROJECTILE" || type == "MOD_PROJECTILE_SPLASH" )
{
refs = self derive_damage_refs( point );
break;
}
}
else
{
refs[refs.size] = "guts";
refs[refs.size] = "right_arm";
refs[refs.size] = "left_arm";
refs[refs.size] = "right_leg";
refs[refs.size] = "left_leg";
refs[refs.size] = "no_legs";
break;
}
}
if( refs.size )
{
self.a.gib_ref = animscripts\zombie_death::get_random( refs );
if( ( self.a.gib_ref == "no_legs" || self.a.gib_ref == "right_leg" || self.a.gib_ref == "left_leg" ) && self.health > 0 )
{
self.has_legs = false;
self AllowedStances( "crouch" );
self thread kill_crawler_over_time( (10 + RandomInt(40)) );
self setPhysParams( 15, 0, 24 );
health = self.health;
health = health * 0.1;
which_anim = RandomInt( 5 );
if(self.a.gib_ref == "no_legs")
{
if(randomint(100) < 50)
{
self.deathanim = %ai_zombie_crawl_death_v1;
self set_run_anim( "death3" );
self.run_combatanim = level.scr_anim[self.animname]["crawl_hand_1"];
self.crouchRunAnim = level.scr_anim[self.animname]["crawl_hand_1"];
self.crouchrun_combatanim = level.scr_anim[self.animname]["crawl_hand_1"];
}
else
{
self.deathanim = %ai_zombie_crawl_death_v1;
self set_run_anim( "death3" );
self.run_combatanim = level.scr_anim[self.animname]["crawl_hand_2"];
self.crouchRunAnim = level.scr_anim[self.animname]["crawl_hand_2"];
self.crouchrun_combatanim = level.scr_anim[self.animname]["crawl_hand_2"];
}
}
else if( which_anim == 0 )
{
self.deathanim = %ai_zombie_crawl_death_v1;
self set_run_anim( "death3" );
self.run_combatanim = level.scr_anim[self.animname]["crawl1"];
self.crouchRunAnim = level.scr_anim[self.animname]["crawl1"];
self.crouchrun_combatanim = level.scr_anim[self.animname]["crawl1"];
}
else if( which_anim == 1 )
{
self.deathanim = %ai_zombie_crawl_death_v2;
self set_run_anim( "death4" );
self.run_combatanim = level.scr_anim[self.animname]["crawl2"];
self.crouchRunAnim = level.scr_anim[self.animname]["crawl2"];
self.crouchrun_combatanim = level.scr_anim[self.animname]["crawl2"];
}
else if( which_anim == 2 )
{
self.deathanim = %ai_zombie_crawl_death_v1;
self set_run_anim( "death3" );
self.run_combatanim = level.scr_anim[self.animname]["crawl3"];
self.crouchRunAnim = level.scr_anim[self.animname]["crawl3"];
self.crouchrun_combatanim = level.scr_anim[self.animname]["crawl3"];
}
else if( which_anim == 3 )
{
self.deathanim = %ai_zombie_crawl_death_v2;
self set_run_anim( "death4" );
self.run_combatanim = level.scr_anim[self.animname]["crawl4"];
self.crouchRunAnim = level.scr_anim[self.animname]["crawl4"];
self.crouchrun_combatanim = level.scr_anim[self.animname]["crawl4"];
}
else if( which_anim == 4 )
{
self.deathanim = %ai_zombie_crawl_death_v1;
self set_run_anim( "death3" );
self.run_combatanim = level.scr_anim[self.animname]["crawl5"];
self.crouchRunAnim = level.scr_anim[self.animname]["crawl5"];
self.crouchrun_combatanim = level.scr_anim[self.animname]["crawl5"];
}
}
}
if( self.health > 0 )
{
self thread animscripts\zombie_death::do_gib();
if ( IsPlayer( self ) )
{
attacker.stats["zombie_gibs"]++;
}
}
}
}
}
kill_crawler_over_time( delay )
{
self endon( "death" );
if( !IsAlive( self ) )
{
return;
}
wait( delay );
self DoDamage( self.health+100, self.origin );
}
zombie_should_gib( amount, attacker, type )
{
if ( !is_mature() )
{
return false;
}
if ( is_german_build() )
{
return false;
}
if( !IsDefined( type ) )
{
return false;
}
if ( IsDefined( self.no_gib ) && ( self.no_gib == 1 ) )
{
return false;
}
if ( self maps\_zombiemode_weap_freezegun::is_freezegun_damage( type ) )
{
return false;
}
switch( type )
{
case "MOD_UNKNOWN":
case "MOD_CRUSH":
case "MOD_TELEFRAG":
case "MOD_FALLING":
case "MOD_SUICIDE":
case "MOD_TRIGGER_HURT":
case "MOD_BURNED":
return false;
case "MOD_MELEE":
{
return false;
}
}
if( type == "MOD_PISTOL_BULLET" || type == "MOD_RIFLE_BULLET" )
{
if( !IsDefined( attacker ) || !IsPlayer( attacker ) )
{
return false;
}
weapon = attacker GetCurrentWeapon();
if( weapon == "none" || weapon == "m1911_zm" )
{
return false;
}
if( WeaponIsGasWeapon( self.weapon ) )
{
return false;
}
}
prev_health = amount + self.health;
if( prev_health <= 0 )
{
prev_health = 1;
}
damage_percent = ( amount / prev_health ) * 100;
if( damage_percent < 10 )
{
return false;
}
return true;
}
derive_damage_refs( point )
{
if( !IsDefined( level.gib_tags ) )
{
init_gib_tags();
}
closestTag = undefined;
for( i = 0; i < level.gib_tags.size; i++ )
{
if( !IsDefined( closestTag ) )
{
closestTag = level.gib_tags[i];
}
else
{
if( DistanceSquared( point, self GetTagOrigin( level.gib_tags[i] ) ) < DistanceSquared( point, self GetTagOrigin( closestTag ) ) )
{
closestTag = level.gib_tags[i];
}
}
}
refs = [];
if( closestTag == "J_SpineLower" || closestTag == "J_SpineUpper" || closestTag == "J_Spine4" )
{
refs[refs.size] = "guts";
refs[refs.size] = "right_arm";
}
else if( closestTag == "J_Shoulder_LE" || closestTag == "J_Elbow_LE" || closestTag == "J_Wrist_LE" )
{
refs[refs.size] = "left_arm";
}
else if( closestTag == "J_Shoulder_RI" || closestTag == "J_Elbow_RI" || closestTag == "J_Wrist_RI" )
{
refs[refs.size] = "right_arm";
}
else if( closestTag == "J_Hip_LE" || closestTag == "J_Knee_LE" || closestTag == "J_Ankle_LE" )
{
refs[refs.size] = "left_leg";
refs[refs.size] = "no_legs";
}
else if( closestTag == "J_Hip_RI" || closestTag == "J_Knee_RI" || closestTag == "J_Ankle_RI" )
{
refs[refs.size] = "right_leg";
refs[refs.size] = "no_legs";
}
ASSERTEX( array_validate( refs ), "get_closest_damage_refs(): couldn't derive refs from closestTag " + closestTag );
return refs;
}
init_gib_tags()
{
tags = [];
tags[tags.size] = "J_SpineLower";
tags[tags.size] = "J_SpineUpper";
tags[tags.size] = "J_Spine4";
tags[tags.size] = "J_Shoulder_LE";
tags[tags.size] = "J_Elbow_LE";
tags[tags.size] = "J_Wrist_LE";
tags[tags.size] = "J_Shoulder_RI";
tags[tags.size] = "J_Elbow_RI";
tags[tags.size] = "J_Wrist_RI";
tags[tags.size] = "J_Hip_LE";
tags[tags.size] = "J_Knee_LE";
tags[tags.size] = "J_Ankle_LE";
tags[tags.size] = "J_Hip_RI";
tags[tags.size] = "J_Knee_RI";
tags[tags.size] = "J_Ankle_RI";
level.gib_tags = tags;
}
zombie_can_drop_powerups( zombie )
{
if( level.mutators["mutator_noPowerups"] )
{
return false;
}
if( zombie.damageweapon == "zombie_cymbal_monkey" || !flag( "zombie_drop_powerups" ) )
{
return false;
}
if ( isdefined(zombie.no_powerups) )
{
return false;
}
return true;
}
zombie_death_points( origin, mod, hit_location, attacker, zombie )
{
if( !IsDefined( attacker ) || !IsPlayer( attacker ) )
{
return;
}
if( zombie_can_drop_powerups( zombie ) )
{
level thread maps\_zombiemode_powerups::powerup_drop( origin );
}
level thread maps\_zombiemode_audio::player_zombie_kill_vox( hit_location, attacker, mod, zombie );
event = "death";
if ( issubstr( zombie.damageweapon, "knife_ballistic_" ) )
{
event = "ballistic_knife_death";
}
attacker maps\_zombiemode_score::player_add_points( event, mod, hit_location );
}
get_number_variants(aliasPrefix)
{
for(i=0; i<100; i++)
{
if( !SoundExists( aliasPrefix + "_" + i) )
{
return i;
}
}
}
dragons_breath_flame_death_fx()
{
if ( self.isdog )
{
return;
}
if( !IsDefined( level._effect ) || !IsDefined( level._effect["character_fire_death_sm"] ) )
{
return;
}
PlayFxOnTag( level._effect["character_fire_death_sm"], self, "J_SpineLower" );
tagArray = [];
if( !IsDefined( self.a.gib_ref ) || self.a.gib_ref != "left_arm" )
{
tagArray[tagArray.size] = "J_Elbow_LE";
tagArray[tagArray.size] = "J_Wrist_LE";
}
if( !IsDefined( self.a.gib_ref ) || self.a.gib_ref != "right_arm" )
{
tagArray[tagArray.size] = "J_Elbow_RI";
tagArray[tagArray.size] = "J_Wrist_RI";
}
if( !IsDefined( self.a.gib_ref ) || (self.a.gib_ref != "no_legs" && self.a.gib_ref != "left_leg") )
{
tagArray[tagArray.size] = "J_Knee_LE";
tagArray[tagArray.size] = "J_Ankle_LE";
}
if( !IsDefined( self.a.gib_ref ) || (self.a.gib_ref != "no_legs" && self.a.gib_ref != "right_leg") )
{
tagArray[tagArray.size] = "J_Knee_RI";
tagArray[tagArray.size] = "J_Ankle_RI";
}
tagArray = array_randomize( tagArray );
PlayFxOnTag( level._effect["character_fire_death_sm"], self, tagArray[0] );
}
zombie_death_animscript()
{
self reset_attack_spot();
if( self maps\_zombiemode_weap_tesla::enemy_killed_by_tesla() || self maps\_zombiemode_weap_thundergun::enemy_killed_by_thundergun() )
{
return false;
}
if ( self maps\_zombiemode_weap_freezegun::should_do_freezegun_death( self.damagemod ) )
{
self thread maps\_zombiemode_weap_freezegun::freezegun_death( self.damagelocation, self.origin, self.attacker );
if ( "MOD_EXPLOSIVE" == self.damagemod )
{
return false;
}
}
if( self.has_legs && IsDefined( self.a.gib_ref ) && self.a.gib_ref == "no_legs" )
{
self.deathanim = %ai_gib_bothlegs_gib;
}
self.grenadeAmmo = 0;
if ( IsDefined( self.nuked ) )
{
if( zombie_can_drop_powerups( self ) )
{
level thread maps\_zombiemode_powerups::powerup_drop( self.origin );
}
}
else
{
level zombie_death_points( self.origin, self.damagemod, self.damagelocation, self.attacker, self );
}
if( isdefined( self.attacker ) && isai( self.attacker ) )
{
self.attacker notify( "killed", self );
}
if( "rottweil72_upgraded_zm" == self.damageweapon && "MOD_RIFLE_BULLET" == self.damagemod )
{
self thread dragons_breath_flame_death_fx();
}
if( self.damagemod == "MOD_BURNED" )
{
self thread animscripts\zombie_death::flame_death_fx();
}
if( self.damagemod == "MOD_GRENADE" || self.damagemod == "MOD_GRENADE_SPLASH" )
{
level notify( "zombie_grenade_death", self.origin );
}
return false;
}
damage_on_fire( player )
{
self endon ("death");
self endon ("stop_flame_damage");
wait( 2 );
while( isdefined( self.is_on_fire) && self.is_on_fire )
{
if( level.round_number < 6 )
{
dmg = level.zombie_health * RandomFloatRange( 0.2, 0.3 );
}
else if( level.round_number < 9 )
{
dmg = level.zombie_health * RandomFloatRange( 0.15, 0.25 );
}
else if( level.round_number < 11 )
{
dmg = level.zombie_health * RandomFloatRange( 0.1, 0.2 );
}
else
{
dmg = level.zombie_health * RandomFloatRange( 0.1, 0.15 );
}
if ( Isdefined( player ) && Isalive( player ) )
{
self DoDamage( dmg, self.origin, player );
}
else
{
self DoDamage( dmg, self.origin, level );
}
wait( randomfloatrange( 1.0, 3.0 ) );
}
}
player_using_hi_score_weapon( player )
{
weapon = player GetCurrentWeapon();
if( weapon == "none" || WeaponIsSemiAuto( weapon ) )
{
return( 1 );
}
return( 0 );
}
zombie_damage( mod, hit_location, hit_origin, player, amount )
{
if( is_magic_bullet_shield_enabled( self ) )
{
return;
}
player.use_weapon_type = mod;
if(isDefined(self.marked_for_death))
{
return;
}
if( !IsDefined( player ) )
{
return;
}
if( self zombie_flame_damage( mod, player ) )
{
if( self zombie_give_flame_damage_points() )
{
player maps\_zombiemode_score::player_add_points( "damage", mod, hit_location, self.isdog );
}
}
else if( self maps\_zombiemode_weap_tesla::is_tesla_damage( mod ) )
{
self maps\_zombiemode_weap_tesla::tesla_damage_init( hit_location, hit_origin, player );
return;
}
else
{
if ( self maps\_zombiemode_weap_freezegun::is_freezegun_damage( self.damagemod ) )
{
self thread maps\_zombiemode_weap_freezegun::freezegun_damage_response( player, amount );
}
if ( !self maps\_zombiemode_weap_freezegun::is_freezegun_shatter_damage( self.damagemod ) )
{
if( player_using_hi_score_weapon( player ) )
{
damage_type = "damage";
}
else
{
damage_type = "damage_light";
}
player maps\_zombiemode_score::player_add_points( damage_type, mod, hit_location, self.isdog );
}
}
if ( IsDefined( self.zombie_damage_fx_func ) )
{
self [[ self.zombie_damage_fx_func ]]( mod, hit_location, hit_origin, player );
}
modName = remove_mod_from_methodofdeath( mod );
if ( self maps\_zombiemode_weap_freezegun::is_freezegun_damage( self.damagemod ) )
{
;
}
else if( self.damageweapon == "claymore_zm" )
{
if ( IsDefined( self.zombie_damage_claymore_func ) )
{
self [[ self.zombie_damage_claymore_func ]]( mod, hit_location, hit_origin, player );
}
else if ( isdefined( player ) && isalive( player ) )
{
self DoDamage( level.round_number * randomintrange( 100, 200 ), self.origin, player);
}
else
{
self DoDamage( level.round_number * randomintrange( 100, 200 ), self.origin, undefined );
}
}
else if ( mod == "MOD_GRENADE" || mod == "MOD_GRENADE_SPLASH" )
{
if ( isdefined( player ) && isalive( player ) )
{
self DoDamage( level.round_number + randomintrange( 100, 200 ), self.origin, player, 0, modName, hit_location);
}
else
{
self DoDamage( level.round_number + randomintrange( 100, 200 ), self.origin, undefined, 0, modName, hit_location );
}
}
else if( mod == "MOD_PROJECTILE" || mod == "MOD_EXPLOSIVE" || mod == "MOD_PROJECTILE_SPLASH" )
{
if ( isdefined( player ) && isalive( player ) )
{
self DoDamage( level.round_number * randomintrange( 0, 100 ), self.origin, player, 0, modName, hit_location);
}
else
{
self DoDamage( level.round_number * randomintrange( 0, 100 ), self.origin, undefined, 0, modName, hit_location );
}
}
if( IsDefined( self.a.gib_ref ) && (self.a.gib_ref == "no_legs") && isalive( self ) )
{
if ( isdefined( player ) )
{
rand = randomintrange(0, 100);
if(rand < 10)
{
player create_and_play_dialog( "general", "crawl_spawn" );
}
}
}
else if( IsDefined( self.a.gib_ref ) && ( (self.a.gib_ref == "right_arm") || (self.a.gib_ref == "left_arm") ) )
{
if( self.has_legs && isalive( self ) )
{
if ( isdefined( player ) )
{
rand = randomintrange(0, 100);
if(rand < 3)
{
player create_and_play_dialog( "general", "shoot_arm" );
}
}
}
}
self thread maps\_zombiemode_powerups::check_for_instakill( player, mod, hit_location );
}
zombie_damage_ads( mod, hit_location, hit_origin, player, amount )
{
if( is_magic_bullet_shield_enabled( self ) )
{
return;
}
player.use_weapon_type = mod;
if( !IsDefined( player ) )
{
return;
}
if( self zombie_flame_damage( mod, player ) )
{
if( self zombie_give_flame_damage_points() )
{
player maps\_zombiemode_score::player_add_points( "damage_ads", mod, hit_location );
}
}
else if( self maps\_zombiemode_weap_tesla::is_tesla_damage( mod ) )
{
self maps\_zombiemode_weap_tesla::tesla_damage_init( hit_location, hit_origin, player );
return;
}
else
{
if ( self maps\_zombiemode_weap_freezegun::is_freezegun_damage( self.damagemod ) )
{
self thread maps\_zombiemode_weap_freezegun::freezegun_damage_response( player, amount );
}
if ( !self maps\_zombiemode_weap_freezegun::is_freezegun_shatter_damage( self.damagemod ) )
{
if( player_using_hi_score_weapon( player ) )
{
damage_type = "damage";
}
else
{
damage_type = "damage_light";
}
player maps\_zombiemode_score::player_add_points( damage_type, mod, hit_location );
}
}
self thread maps\_zombiemode_powerups::check_for_instakill( player, mod, hit_location );
}
zombie_give_flame_damage_points()
{
if( GetTime() > self.flame_damage_time )
{
self.flame_damage_time = GetTime() + level.zombie_vars["zombie_flame_dmg_point_delay"];
return true;
}
return false;
}
zombie_flame_damage( mod, player )
{
if( mod == "MOD_BURNED" )
{
self.moveplaybackrate = 0.8;
if( !IsDefined( self.is_on_fire ) || ( Isdefined( self.is_on_fire ) && !self.is_on_fire ) )
{
self thread damage_on_fire( player );
}
do_flame_death = true;
dist = 100 * 100;
ai = GetAiArray( "axis" );
for( i = 0; i < ai.size; i++ )
{
if( IsDefined( ai[i].is_on_fire ) && ai[i].is_on_fire )
{
if( DistanceSquared( ai[i].origin, self.origin ) < dist )
{
do_flame_death = false;
break;
}
}
}
if( do_flame_death )
{
self thread animscripts\zombie_death::flame_death_fx();
}
return true;
}
return false;
}
zombie_death_event( zombie )
{
zombie waittill( "death" );
if ( !IsDefined( zombie ) )
{
return;
}
if ( !zombie maps\_zombiemode_weap_freezegun::should_do_freezegun_death( zombie.damagemod ) )
{
zombie thread maps\_zombiemode_audio::do_zombies_playvocals( "death", zombie.animname );
zombie thread zombie_eye_glow_stop();
}
if ( maps\_zombiemode_weapons::is_weapon_included( "freezegun_zm" ) )
{
zombie thread maps\_zombiemode_weap_freezegun::freezegun_clear_extremity_damage_fx();
zombie thread maps\_zombiemode_weap_freezegun::freezegun_clear_torso_damage_fx();
}
if(isdefined (zombie.attacker) && isplayer(zombie.attacker) )
{
if(!isdefined ( zombie.attacker.killcounter))
{
zombie.attacker.killcounter = 1;
}
else
{
zombie.attacker.killcounter ++;
}
if ( IsDefined( zombie.sound_damage_player ) && zombie.sound_damage_player == zombie.attacker )
{
zombie.attacker maps\_zombiemode_audio::create_and_play_dialog( "kill", "damage" );
}
zombie.attacker notify("zom_kill");
damageloc = zombie.damagelocation;
damagemod = zombie.damagemod;
attacker = zombie.attacker;
weapon = zombie.damageWeapon;
bbPrint( "zombie_kills: round %d zombietype zombie damagetype %s damagelocation %s playername %s playerweapon %s playerx %f playery %f playerz %f zombiex %f zombiey %f zombiez %f",
level.round_number, damagemod, damageloc, attacker.playername, weapon, attacker.origin, zombie.origin );
}
level notify( "zom_kill" );
level.total_zombies_killed++;
}
zombie_setup_attack_properties()
{
self zombie_history( "zombie_setup_attack_properties()" );
self.ignoreall = false;
self PushPlayer( true );
self.pathEnemyFightDist = 64;
self.meleeAttackDist = 64;
self.maxsightdistsqrd = 128 * 128;
self.disableArrivals = true;
self.disableExits = true;
}
find_flesh()
{
self endon( "death" );
level endon( "intermission" );
self endon( "stop_find_flesh" );
if( level.intermission )
{
return;
}
self.helitarget = true;
self.ignoreme = false;
self.ignore_player = [];
self zombie_history( "find flesh -> start" );
self.goalradius = 32;
while( 1 )
{
near_zombies = getaiarray("axis");
same_enemy_count = 0;
for (i = 0; i < near_zombies.size; i++)
{
if ( isdefined( near_zombies[i] ) && isalive( near_zombies[i] ) )
{
if ( isdefined( near_zombies[i].favoriteenemy ) && isdefined( self.favoriteenemy )
&& near_zombies[i].favoriteenemy == self.favoriteenemy )
{
if ( distancesquared( near_zombies[i].origin, self.favoriteenemy.origin ) < 225 * 225
&& distancesquared( near_zombies[i].origin, self.origin ) > 525 * 525)
{
same_enemy_count++;
}
}
}
}
if (same_enemy_count > 12)
{
self.ignore_player[self.ignore_player.size] = self.favoriteenemy;
}
if (isDefined(level.zombieTheaterTeleporterSeekLogicFunc) )
{
self [[ level.zombieTheaterTeleporterSeekLogicFunc ]]();
}
zombie_poi = self get_zombie_point_of_interest( self.origin );
players = get_players();
if( players.size == 1 )
{
self.ignore_player = [];
}
else
{
for(i = 0; i < self.ignore_player.size; i++)
{
if( IsDefined( self.ignore_player[i] ) && IsDefined( self.ignore_player[i].ignore_counter ) && self.ignore_player[i].ignore_counter > 3 )
{
self.ignore_player[i].ignore_counter = 0;
self.ignore_player = array_remove( self.ignore_player, self.ignore_player[i] );
}
}
}
player = get_closest_valid_player( self.origin, self.ignore_player );
if( !isDefined( player ) && !isDefined( zombie_poi ) )
{
self zombie_history( "find flesh -> can't find player, continue" );
if( IsDefined( self.ignore_player ) )
{
self.ignore_player = [];
}
wait( 1 );
continue;
}
self.enemyoverride = zombie_poi;
self.favoriteenemy = player;
self thread zombie_pathing();
if( players.size > 1 )
{
for(i = 0; i < self.ignore_player.size; i++)
{
if( IsDefined( self.ignore_player[i] ) )
{
if( !IsDefined( self.ignore_player[i].ignore_counter ) )
self.ignore_player[i].ignore_counter = 0;
else
self.ignore_player[i].ignore_counter += 1;
}
}
}
self thread attractors_generated_listener();
self.zombie_path_timer = GetTime() + ( RandomFloatRange( 1, 3 ) * 1000 );
while( GetTime() < self.zombie_path_timer )
{
wait( 0.1 );
}
self notify( "path_timer_done" );
self zombie_history( "find flesh -> bottom of loop" );
debug_print( "Zombie is re-acquiring enemy, ending breadcrumb search" );
self notify( "zombie_acquire_enemy" );
}
}
attractors_generated_listener()
{
self endon( "death" );
level endon( "intermission" );
self endon( "stop_find_flesh" );
self endon( "path_timer_done" );
level waittill( "attractor_positions_generated" );
self.zombie_path_timer = 0;
}
zombie_pathing()
{
self endon( "death" );
self endon( "zombie_acquire_enemy" );
level endon( "intermission" );
assert( IsDefined( self.favoriteenemy ) || IsDefined( self.enemyoverride ) );
self thread zombie_follow_enemy();
self waittill( "bad_path" );
if( isDefined( self.enemyoverride ) )
{
debug_print( "Zombie couldn't path to point of interest at origin: " + self.enemyoverride[0] + " Falling back to breadcrumb system" );
if( isDefined( self.enemyoverride[1] ) )
{
self.enemyoverride = self.enemyoverride[1] invalidate_attractor_pos( self.enemyoverride, self );
self.zombie_path_timer = 0;
return;
}
}
else
{
debug_print( "Zombie couldn't path to player at origin: " + self.favoriteenemy.origin + " Falling back to breadcrumb system" );
}
if( !isDefined( self.favoriteenemy ) )
{
self.zombie_path_timer = 0;
return;
}
else
{
self.favoriteenemy endon( "disconnect" );
}
players = get_players();
valid_player_num = 0;
for( i = 0; i < players.size; i++ )
{
if( is_player_valid( players[i], true ) )
{
valid_player_num += 1;
}
}
if( players.size > 1 )
{
if( array_check_for_dupes( self.ignore_player, self.favoriteenemy) )
{
self.ignore_player[self.ignore_player.size] = self.favoriteenemy;
}
if( self.ignore_player.size < valid_player_num )
{
self.zombie_path_timer = 0;
return;
}
}
crumb_list = self.favoriteenemy.zombie_breadcrumbs;
bad_crumbs = [];
while( 1 )
{
if( !is_player_valid( self.favoriteenemy, true ) )
{
self.zombie_path_timer = 0;
return;
}
goal = zombie_pathing_get_breadcrumb( self.favoriteenemy.origin, crumb_list, bad_crumbs, ( RandomInt( 100 ) < 20 ) );
if ( !IsDefined( goal ) )
{
debug_print( "Zombie exhausted breadcrumb search" );
goal = self.favoriteenemy.spectator_respawn.origin;
}
debug_print( "Setting current breadcrumb to " + goal );
self.zombie_path_timer += 100;
self SetGoalPos( goal );
self waittill( "bad_path" );
debug_print( "Zombie couldn't path to breadcrumb at " + goal + " Finding next breadcrumb" );
for( i = 0; i < crumb_list.size; i++ )
{
if( goal == crumb_list[i] )
{
bad_crumbs[bad_crumbs.size] = i;
break;
}
}
}
}
zombie_pathing_get_breadcrumb( origin, breadcrumbs, bad_crumbs, pick_random )
{
assert( IsDefined( origin ) );
assert( IsDefined( breadcrumbs ) );
assert( IsArray( breadcrumbs ) );
for( i = 0; i < breadcrumbs.size; i++ )
{
if ( pick_random )
{
crumb_index = RandomInt( breadcrumbs.size );
}
else
{
crumb_index = i;
}
if( crumb_is_bad( crumb_index, bad_crumbs ) )
{
continue;
}
return breadcrumbs[crumb_index];
}
return undefined;
}
crumb_is_bad( crumb, bad_crumbs )
{
for ( i = 0; i < bad_crumbs.size; i++ )
{
if ( bad_crumbs[i] == crumb )
{
return true;
}
}
return false;
}
jitter_enemies_bad_breadcrumbs( start_crumb )
{
trace_distance = 35;
jitter_distance = 2;
index = start_crumb;
while (isdefined(self.favoriteenemy.zombie_breadcrumbs[ index + 1 ]))
{
current_crumb = self.favoriteenemy.zombie_breadcrumbs[ index ];
next_crumb = self.favoriteenemy.zombie_breadcrumbs[ index + 1 ];
angles = vectortoangles(current_crumb - next_crumb);
right = anglestoright(angles);
left = anglestoright(angles + (0,180,0));
dist_pos = current_crumb + vector_scale( right, trace_distance );
trace = bulletTrace( current_crumb, dist_pos, true, undefined );
vector = trace["position"];
if (distance(vector, current_crumb) < 17 )
{
self.favoriteenemy.zombie_breadcrumbs[ index ] = current_crumb + vector_scale( left, jitter_distance );
continue;
}
dist_pos = current_crumb + vector_scale( left, trace_distance );
trace = bulletTrace( current_crumb, dist_pos, true, undefined );
vector = trace["position"];
if (distance(vector, current_crumb) < 17 )
{
self.favoriteenemy.zombie_breadcrumbs[ index ] = current_crumb + vector_scale( right, jitter_distance );
continue;
}
index++;
}
}
zombie_follow_enemy()
{
self endon( "death" );
self endon( "zombie_acquire_enemy" );
self endon( "bad_path" );
level endon( "intermission" );
while( 1 )
{
if( isDefined( self.enemyoverride ) && isDefined( self.enemyoverride[1] ) )
{
if( distanceSquared( self.origin, self.enemyoverride[0] ) > 1*1 )
{
self OrientMode( "face motion" );
}
else
{
self OrientMode( "face point", self.enemyoverride[1].origin );
}
self.ignoreall = true;
self SetGoalPos( self.enemyoverride[0] );
}
else if( IsDefined( self.favoriteenemy ) )
{
self.ignoreall = false;
self OrientMode( "face default" );
self SetGoalPos( self.favoriteenemy.origin );
}
if( isDefined( level.inaccesible_player_func ) )
{
self [[ level.inaccessible_player_func ]]();
}
wait( 0.1 );
}
}
zombie_eye_glow()
{
if(!IsDefined(self))
{
return;
}
if ( !isdefined( self.no_eye_glow ) || !self.no_eye_glow )
{
self haseyes(1);
}
}
zombie_eye_glow_stop()
{
if(!IsDefined(self))
{
return;
}
if ( !isdefined( self.no_eye_glow ) || !self.no_eye_glow )
{
self haseyes(0);
}
}
zombie_history( msg )
{
}
do_zombie_rise()
{
self endon("death");
self.zombie_rise_version = (RandomInt(99999) % 2) + 1;
if (self.zombie_move_speed != "walk")
{
self.zombie_rise_version = 1;
}
self.in_the_ground = true;
self.anchor = spawn("script_origin", self.origin);
self.anchor.angles = self.angles;
self linkto(self.anchor);
if ( IsDefined( self.zone_name ) )
{
spots = level.zones[ self.zone_name ].rise_locations;
}
else if ( IsDefined( self.rise_target_name ) )
{
spots = GetStructArray(self.rise_target_name, "targetname");
}
else if( IsDefined( level.zombie_rise_spawners ) )
{
if ( IsArray( level.zombie_rise_spawners ) )
{
spots = level.zombie_rise_spawners[ self.script_index ];
}
else
{
spots = level.zombie_rise_spawners;
}
}
else
{
spots = GetStructArray("zombie_rise", "targetname");
}
if( spots.size < 1 )
{
self unlink();
self.anchor delete();
return;
}
else
spot = random(spots);
if( !isDefined( spot.angles ) )
{
spot.angles = (0, 0, 0);
}
anim_org = spot.origin;
anim_ang = spot.angles;
if (self.zombie_rise_version == 2)
{
anim_org = anim_org + (0, 0, -14);
}
else
{
anim_org = anim_org + (0, 0, -45);
}
self Hide();
self.anchor moveto(anim_org, .05);
self.anchor waittill("movedone");
target_org = maps\_zombiemode_spawner::get_desired_origin();
if (IsDefined(target_org))
{
anim_ang = VectorToAngles(target_org - self.origin);
self.anchor RotateTo((0, anim_ang[1], 0), .05);
self.anchor waittill("rotatedone");
}
self unlink();
self.anchor delete();
self thread hide_pop();
level thread zombie_rise_death(self, spot);
spot thread zombie_rise_fx(self);
self AnimScripted("rise", self.origin, spot.angles, self get_rise_anim());
self animscripts\zombie_shared::DoNoteTracks("rise", ::handle_rise_notetracks, undefined, spot);
self notify("rise_anim_finished");
spot notify("stop_zombie_rise_fx");
self.in_the_ground = false;
self notify("risen", spot.script_noteworthy );
}
hide_pop()
{
wait .5;
self Show();
}
handle_rise_notetracks(note, spot)
{
if (note == "deathout" || note == "deathhigh")
{
self.zombie_rise_death_out = true;
self notify("zombie_rise_death_out");
wait 2;
spot notify("stop_zombie_rise_fx");
}
}
zombie_rise_death(zombie, spot)
{
zombie.zombie_rise_death_out = false;
zombie endon("rise_anim_finished");
while (zombie.health > 1)
{
zombie waittill("damage", amount);
}
spot notify("stop_zombie_rise_fx");
zombie.deathanim = zombie get_rise_death_anim();
zombie StopAnimScripted();
}
zombie_rise_fx(zombie)
{
self thread zombie_rise_dust_fx(zombie);
self thread zombie_rise_burst_fx();
playsoundatposition ("zmb_zombie_spawn", self.origin);
zombie endon("death");
self endon("stop_zombie_rise_fx");
wait 1;
if (zombie.zombie_move_speed != "sprint")
{
wait 1;
}
}
zombie_rise_burst_fx()
{
self endon("stop_zombie_rise_fx");
self endon("rise_anim_finished");
if(IsDefined(self.script_string) && self.script_string == "in_water")
{
playfx(level._effect["rise_burst_water"],self.origin + ( 0,0,randomintrange(5,10) ) );
wait(.25);
playfx(level._effect["rise_billow_water"],self.origin + ( randomintrange(-10,10),randomintrange(-10,10),randomintrange(5,10) ) );
}
else
{
playfx(level._effect["rise_burst"],self.origin + ( 0,0,randomintrange(5,10) ) );
wait(.25);
playfx(level._effect["rise_billow"],self.origin + ( randomintrange(-10,10),randomintrange(-10,10),randomintrange(5,10) ) );
}
}
zombie_rise_dust_fx(zombie)
{
dust_tag = "J_SpineUpper";
self endon("stop_zombie_rise_dust_fx");
self thread stop_zombie_rise_dust_fx(zombie);
dust_time = 7.5;
dust_interval = .1;
if(IsDefined(self.script_string) && self.script_string == "in_water")
{
for (t = 0; t < dust_time; t += dust_interval)
{
PlayfxOnTag(level._effect["rise_dust_water"], zombie, dust_tag);
wait dust_interval;
}
}
else
{
for (t = 0; t < dust_time; t += dust_interval)
{
PlayfxOnTag(level._effect["rise_dust"], zombie, dust_tag);
wait dust_interval;
}
}
}
stop_zombie_rise_dust_fx(zombie)
{
zombie waittill("death");
self notify("stop_zombie_rise_dust_fx");
}
get_rise_anim()
{
speed = self.zombie_move_speed;
return random(level._zombie_rise_anims[self.animname][self.zombie_rise_version][speed]);
}
get_rise_death_anim()
{
possible_anims = [];
if (self.zombie_rise_death_out)
{
possible_anims = level._zombie_rise_death_anims[self.animname][self.zombie_rise_version]["out"];
}
else
{
possible_anims = level._zombie_rise_death_anims[self.animname][self.zombie_rise_version]["in"];
}
return random(possible_anims);
}
make_crawler()
{
if( !IsDefined( self ) )
{
return;
}
self.has_legs = false;
self.needs_run_update = true;
self AllowedStances( "crouch" );
damage_type[0] = "right_foot";
damage_type[1] = "left_foot";
refs = [];
switch( damage_type[ RandomInt(damage_type.size) ] )
{
case "right_leg_upper":
case "right_leg_lower":
case "right_foot":
refs[refs.size] = "right_leg";
refs[refs.size] = "right_leg";
refs[refs.size] = "right_leg";
refs[refs.size] = "no_legs";
break;
case "left_leg_upper":
case "left_leg_lower":
case "left_foot":
refs[refs.size] = "left_leg";
refs[refs.size] = "left_leg";
refs[refs.size] = "left_leg";
refs[refs.size] = "no_legs";
break;
}
if( refs.size )
{
self.a.gib_ref = animscripts\zombie_death::get_random( refs );
if( ( self.a.gib_ref == "no_legs" || self.a.gib_ref == "right_leg" || self.a.gib_ref == "left_leg" ) && self.health > 0 )
{
self.has_legs = false;
self AllowedStances( "crouch" );
which_anim = RandomInt( 5 );
if(self.a.gib_ref == "no_legs")
{
if(randomint(100) < 50)
{
self.deathanim = %ai_zombie_crawl_death_v1;
self set_run_anim( "death3" );
self.run_combatanim = level.scr_anim[self.animname]["crawl_hand_1"];
self.crouchRunAnim = level.scr_anim[self.animname]["crawl_hand_1"];
self.crouchrun_combatanim = level.scr_anim[self.animname]["crawl_hand_1"];
}
else
{
self.deathanim = %ai_zombie_crawl_death_v1;
self set_run_anim( "death3" );
self.run_combatanim = level.scr_anim[self.animname]["crawl_hand_2"];
self.crouchRunAnim = level.scr_anim[self.animname]["crawl_hand_2"];
self.crouchrun_combatanim = level.scr_anim[self.animname]["crawl_hand_2"];
}
}
else if( which_anim == 0 )
{
self.deathanim = %ai_zombie_crawl_death_v1;
self set_run_anim( "death3" );
self.run_combatanim = level.scr_anim[self.animname]["crawl1"];
self.crouchRunAnim = level.scr_anim[self.animname]["crawl1"];
self.crouchrun_combatanim = level.scr_anim[self.animname]["crawl1"];
}
else if( which_anim == 1 )
{
self.deathanim = %ai_zombie_crawl_death_v2;
self set_run_anim( "death4" );
self.run_combatanim = level.scr_anim[self.animname]["crawl2"];
self.crouchRunAnim = level.scr_anim[self.animname]["crawl2"];
self.crouchrun_combatanim = level.scr_anim[self.animname]["crawl2"];
}
else if( which_anim == 2 )
{
self.deathanim = %ai_zombie_crawl_death_v1;
self set_run_anim( "death3" );
self.run_combatanim = level.scr_anim[self.animname]["crawl3"];
self.crouchRunAnim = level.scr_anim[self.animname]["crawl3"];
self.crouchrun_combatanim = level.scr_anim[self.animname]["crawl3"];
}
else if( which_anim == 3 )
{
self.deathanim = %ai_zombie_crawl_death_v2;
self set_run_anim( "death4" );
self.run_combatanim = level.scr_anim[self.animname]["crawl4"];
self.crouchRunAnim = level.scr_anim[self.animname]["crawl4"];
self.crouchrun_combatanim = level.scr_anim[self.animname]["crawl4"];
}
else if( which_anim == 4 )
{
self.deathanim = %ai_zombie_crawl_death_v1;
self set_run_anim( "death3" );
self.run_combatanim = level.scr_anim[self.animname]["crawl5"];
self.crouchRunAnim = level.scr_anim[self.animname]["crawl5"];
self.crouchrun_combatanim = level.scr_anim[self.animname]["crawl5"];
}
}
}
}
zombie_disintegrate( player )
{
self DoDamage( self.health + 666, player.origin, player );
if ( self.health <= 0 )
{
player maps\_zombiemode_score::player_add_points( "death", "", "", self.isdog );
if( self.has_legs )
{
self.deathanim = random( level._zombie_knockdowns[self.animname]["front"]["has_legs"] );
}
else
{
self.deathanim = random( level._zombie_tesla_crawl_death[self.animname] );
}
self swap_to_dissolve_models();
self setDeathContents( level.CONTENTS_CORPSE );
self playweapondeatheffects( player GetCurrentWeapon() );
self.thundergun_death = true;
self.thundergun_disintegrated_death = true;
self.skip_death_notetracks = true;
self.nodeathragdoll = true;
wait( GetDvarFloat( #"cg_dissolveTransitionTime" ) + 4 );
self_delete();
}
}
zombie_knockdown( player, gib )
{
if ( gib && !self.gibbed )
{
self.a.gib_ref = random( level.thundergun_gib_refs );
self thread animscripts\zombie_death::do_gib();
}
self.thundergun_handle_pain_notetracks = maps\_zombiemode_weap_thundergun::handle_thundergun_pain_notetracks;
self DoDamage( level.zombie_vars["thundergun_knockdown_damage"], player.origin, player );
}
zombie_tesla_head_gib()
{
if( RandomInt( 100 ) < level.zombie_vars["tesla_head_gib_chance"] )
{
wait( RandomFloat( 0.53, 1.0 ) );
self zombie_head_gib();
}
else
{
network_safe_play_fx_on_tag( "tesla_death_fx", 2, level._effect["tesla_shock_eyes"], self, "J_Eyeball_LE" );
}
}
play_ambient_zombie_vocals()
{
self endon( "death" );
while(1)
{
type = "ambient";
float = 2;
if( !IsDefined( self.zombie_move_speed ) )
{
wait(.5);
continue;
}
switch(self.zombie_move_speed)
{
case "walk": type="ambient"; float=4; break;
case "run": type="sprint"; float=4; break;
case "sprint": type="sprint"; float=4; break;
}
if( self.animname == "zombie" && !self.has_legs )
{
type = "crawler";
}
else if( self.animname == "thief_zombie" )
{
float = 1.2;
}
self thread maps\_zombiemode_audio::do_zombies_playvocals( type, self.animname );
wait(RandomFloatRange(1,float));
}
}