1 #using scripts\codescripts\struct; 
    3 #using scripts\shared\array_shared; 
    4 #using scripts\shared\clientfield_shared; 
    5 #using scripts\shared\demo_shared; 
    6 #using scripts\shared\flag_shared; 
    7 #using scripts\shared\laststand_shared; 
    8 #using scripts\shared\util_shared; 
   10 #using scripts\shared\ai\zombie_death; 
   11 #using scripts\shared\ai\zombie_shared; 
   12 #using scripts\shared\ai\systems\gib; 
   13 #using scripts\shared\ai\zombie_utility; 
   15 #using scripts\zm\_util; 
   16 #using scripts\zm\_zm; 
   17 #using scripts\zm\_zm_audio; 
   18 #using scripts\zm\_zm_behavior; 
   19 #using scripts\zm\_zm_behavior_utility; 
   20 #using scripts\zm\_zm_blockers; 
   21 #using scripts\zm\_zm_bgb; 
   22 #using scripts\zm\_zm_equipment; 
   23 #using scripts\zm\_zm_laststand; 
   24 #using scripts\zm\_zm_net; 
   25 #using scripts\zm\_zm_pers_upgrades; 
   26 #using scripts\zm\_zm_pers_upgrades_functions; 
   27 #using scripts\zm\_zm_powerups; 
   28 #using scripts\zm\_zm_puppet; 
   29 #using scripts\zm\_zm_score; 
   30 #using scripts\zm\_zm_stats; 
   31 #using scripts\zm\_zm_utility; 
   32 #using scripts\zm\_zm_weapons; 
   34 #insert scripts\shared\shared.gsh; 
   35 #insert scripts\shared\version.gsh; 
   36 #insert scripts\shared\ai\zombie.gsh; 
   37 #insert scripts\shared\ai\systems\gib.gsh; 
   38 #insert scripts\zm\_zm.gsh; 
   39 #insert scripts\zm\_zm_perks.gsh; 
   41 #namespace zm_spawner; 
   45     level._CONTEXTUAL_GRAB_LERP_TIME = .3; 
 
   47     level.zombie_spawners = GetEntArray( 
"zombie_spawner", 
"script_noteworthy" );
 
   51     level.a_zombie_respawn_health = []; 
 
   54     level.a_zombie_respawn_type = [];   
 
   56     if(
IS_TRUE(level.use_multiple_spawns))
 
   58         level.zombie_spawn = [];
 
   59         for ( i = 0; i < level.zombie_spawners.size; i++ )
 
   61             if(IsDefined(level.zombie_spawners[i].script_int))
 
   63                 int = level.zombie_spawners[i].script_int;
 
   64                 if ( !IsDefined( level.zombie_spawn[
int] ))
 
   66                     level.zombie_spawn[int] = [];
 
   68                 level.zombie_spawn[int][level.zombie_spawn[int].size] = level.zombie_spawners[i];
 
   73     if ( IsDefined( level.ignore_spawner_func ) )
 
   75         for ( i = 0; i < level.zombie_spawners.size; i++ )
 
   77             ignore = [[ level.ignore_spawner_func ]]( level.zombie_spawners[i] );
 
   80                 ArrayRemoveValue(level.zombie_spawners, level.zombie_spawners[i]);
 
   85     if ( !IsDefined( level.attack_player_thru_boards_range ) )
 
   87         level.attack_player_thru_boards_range = 109.8;
 
   90     if(isdefined(level._game_module_custom_spawn_init_func))
 
   92         [[level._game_module_custom_spawn_init_func]]();
 
   96 function player_attacks_enemy( player, amount, type, point, weapon, direction_vec, tagName, modelName, partName, dFlags, inflictor, chargeLevel )
 
   99     if(isDefined(
self._race_team))
 
  101         team = 
self._race_team;
 
  107         [[ level.global_damage_func ]]( type, 
self.damagelocation, point, player, amount, team, weapon, direction_vec, tagName, modelName, partName, dFlags, inflictor, chargeLevel );
 
  114         [[ level.global_damage_func ]]( type, 
self.damagelocation, point, player, amount, team, weapon, direction_vec, tagName, modelName, partName, dFlags, inflictor, chargeLevel );
 
  119     [[ level.global_damage_func_ads ]]( type, 
self.damagelocation, point, player, amount, team, weapon, direction_vec, tagName, modelName, partName, dFlags, inflictor, chargeLevel );
 
  127     if ( IsPlayer(attacker) )
 
  136     self endon (
"death");
 
  140         self waittill( 
"damage", amount, attacker, direction_vec, point, type, tagName, modelName, partName, weapon, dFlags, inflictor, chargeLevel );
 
  142         if ( !isDefined(amount) )
 
  147         if ( !isalive( 
self ) )
 
  157         self.has_been_damaged_by_player = 
true;
 
  159         self player_attacks_enemy( attacker, amount, type, point, weapon, direction_vec, tagName, modelName, partName, dFlags, inflictor, chargeLevel );
 
  166     if( IsDefined( ent.targetname ) )
 
  168         targeters = GetEntArray( ent.targetname, 
"target" );
 
  170         for( i = 0; i < targeters.size; i++ )
 
  172             if( targeters[i].targetname == 
"zombie_door" || targeters[i].targetname == 
"zombie_debris" )
 
  190     if(!IsDefined(level._zombie_custom_spawn_logic))
 
  192         level._zombie_custom_spawn_logic = [];
 
  195     level._zombie_custom_spawn_logic[level._zombie_custom_spawn_logic.size] = func;
 
  202     if( !isDefined( animname_set ) )
 
  204         animname_set = 
false;
 
  207     self.targetname = 
"zombie";
 
  208     self.script_noteworthy = undefined;
 
  215         self.animname = 
"zombie";       
 
  226     self.zmb_vocals_attack = 
"zmb_vocals_zombie_attack";
 
  228     self.ignoreme = 
false;
 
  229     self.allowdeath = 
true;             
 
  230     self.force_gib = 
true;      
 
  231     self.is_zombie = 
true;          
 
  232     self allowedStances( 
"stand" );
 
  235     self.attackerCountThreatScale = 0;
 
  237     self.currentEnemyThreatScale = 0;
 
  239     self.recentAttackerThreatScale = 0;
 
  241     self.coverThreatScale = 0;
 
  244     self.fovcosinebusy = 0;
 
  246     self.zombie_damaged_by_bar_knockdown = 
false; 
 
  249     self.head_gibbed = 
false;
 
  256     self setPhysParams( 15, 0, 72 );
 
  257     self.goalradius = 32;
 
  259     self.disableArrivals = 
true; 
 
  260     self.disableExits = 
true; 
 
  261     self.grenadeawareness = 0;
 
  262     self.badplaceawareness = 0;
 
  264     self.ignoreSuppression = 
true;  
 
  265     self.suppressionThreshold = 1; 
 
  266     self.noDodgeMove = 
true; 
 
  267     self.dontShootWhileMoving = 
true;
 
  268     self.pathenemylookahead = 0;
 
  271     self.holdfire           = 
true; 
 
  273     self.badplaceawareness = 0;
 
  274     self.chatInitialized = 
false;
 
  275     self.missingLegs = 
false;
 
  277     if ( !isdefined( 
self.zombie_arms_position ) )
 
  279         if(randomint( 2 ) == 0)
 
  280             self.zombie_arms_position = 
"up";
 
  282             self.zombie_arms_position = 
"down";
 
  287         self.canStumble = 
true;
 
  290     self.a.disablepain = 
true;
 
  293     if ( isdefined( level.zombie_health ) )
 
  295         self.maxhealth = level.zombie_health; 
 
  297         if( IsDefined(level.a_zombie_respawn_health[ 
self.archetype ] ) && level.a_zombie_respawn_health[ 
self.archetype ].size > 0 )
 
  299             self.health = level.a_zombie_respawn_health[ 
self.archetype ][0];
 
  300             ArrayRemoveValue(level.a_zombie_respawn_health[ 
self.archetype ], level.a_zombie_respawn_health[ 
self.archetype ][0]);      
 
  304             self.health = level.zombie_health;
 
  309         self.maxhealth = level.zombie_vars[
"zombie_health_start"]; 
 
  310         self.health = 
self.maxhealth; 
 
  313     self.freezegun_damage = 0;
 
  316     self setAvoidanceMask( 
"avoid none" );
 
  319     self PathMode( 
"dont move" );
 
  333     if(IsDefined(level._zombie_custom_spawn_logic))
 
  335         if(IsArray(level._zombie_custom_spawn_logic))
 
  337             for(i = 0; i < level._zombie_custom_spawn_logic.size; i ++)
 
  339             self thread [[level._zombie_custom_spawn_logic[i]]]();
 
  344             self thread [[level._zombie_custom_spawn_logic]]();
 
  348     if ( !isdefined( 
self.no_eye_glow ) || !
self.no_eye_glow )
 
  356     self.flame_damage_time = 0;
 
  358     self.meleeDamage = 60;  
 
  359     self.no_powerups = 
true;
 
  361     self zombie_history( 
"zombie_spawn_init -> Spawned = " + 
self.origin );
 
  363     self.thundergun_knockdown_func = level.basic_zombie_thundergun_knockdown;
 
  366     self.team = level.zombie_team;
 
  369     self.updateSight = 
false;
 
  374     if ( isDefined(level.achievement_monitor_func) )
 
  376         self [[level.achievement_monitor_func]]();
 
  385     if ( isDefined( level.zombie_init_done ) )
 
  387         self [[ level.zombie_init_done ]]();
 
  389     self.zombie_init_done = 
true;
 
  391     self notify( 
"zombie_init_done" );
 
  396     self endon (
"death");
 
  398     continue_failsafe_damage = 
false;   
 
  404         if ( !isdefined( 
self.enemy ) || !IsPlayer( 
self.enemy ) )
 
  409         if (
self istouching(
self.enemy))
 
  411             old_org = 
self.origin;
 
  412             if (!continue_failsafe_damage)
 
  418             if (!isdefined(
self.enemy) || !IsPlayer( 
self.enemy ) || 
self.enemy hasperk( 
PERK_JUGGERNOG ) )
 
  424         if (
self istouching(
self.enemy) 
 
  426                 && isalive(
self.enemy))
 
  430                 if (distancesquared(old_org, 
self.origin) < (60 * 60) ) 
 
  432                     self.enemy DoDamage( 
self.enemy.health + 1000, 
self.enemy.origin, 
self, 
self, 
"none", 
"MOD_RIFLE_BULLET" );
 
  434                     continue_failsafe_damage = 
true;
 
  440             continue_failsafe_damage = 
false;
 
  449     if( IsDefined(find_flesh_struct_string) && find_flesh_struct_string == 
"find_flesh" ) 
 
  454     if( isDefined( 
self.script_string ) && 
self.script_string == 
"find_flesh" ) 
 
  468     self.entrance_nodes = [];
 
  470     if ( IsDefined( level.max_barrier_search_dist_override ) )
 
  472         max_dist = level.max_barrier_search_dist_override;
 
  479     if( !IsDefined(
self.find_flesh_struct_string) && IsDefined( 
self.target ) && 
self.target != 
"" )
 
  483         assert( IsDefined( desired_origin ), 
"Spawner @ " + 
self.origin + 
" has a .target but did not find a target" );
 
  485         origin = desired_origin;
 
  487         node = ArrayGetClosest( origin, level.exterior_goals );     
 
  488         self.entrance_nodes[
self.entrance_nodes.size] = node;
 
  490         self zombie_history( 
"zombie_think -> #1 entrance (script_forcegoal) origin = " + 
self.entrance_nodes[0].origin );
 
  498         if (isDefined(
self.target))
 
  500             end_at_node = GetNode(
self.target, 
"targetname");
 
  501             if (isDefined(end_at_node))
 
  503                 self setgoalnode (end_at_node);
 
  504                 self waittill(
"goal");
 
  518     else if( IsDefined(
self.find_flesh_struct_string) )
 
  520         for( i=0; i<level.exterior_goals.size; i++ )
 
  522             if( IsDefined(level.exterior_goals[i].script_string) && level.exterior_goals[i].script_string == 
self.find_flesh_struct_string )
 
  524                 node = level.exterior_goals[i];
 
  528         self.entrance_nodes[
self.entrance_nodes.size] = node;
 
  530         self zombie_history( 
"zombie_think -> #1 entrance origin = " + node.origin );
 
  536     assert( IsDefined( node ), 
"Did not find a node!!! [Should not see this!]" );
 
  540     self.first_node = node; 
 
  547     self endon( 
"death" ); 
 
  548     assert( !
self.isdog );
 
  550     self.ai_state = 
"zombie_think";
 
  556     find_flesh_struct_string = undefined;
 
  558     if ( IsDefined(level.zombie_custom_think_logic) )
 
  560         shouldWait = 
self [[ level.zombie_custom_think_logic ]]();
 
  563             self waittill(
"zombie_custom_think_done", find_flesh_struct_string);
 
  566     else if ( 
IS_TRUE( 
self.start_inert ) )
 
  568         find_flesh_struct_string = 
"find_flesh";
 
  572         if ( isdefined( 
self.custom_location ) )
 
  574             self thread [[ 
self.custom_location ]]();
 
  581         self waittill(
"risen", find_flesh_struct_string );
 
  583     self.find_flesh_struct_string = find_flesh_struct_string;
 
  588     self SetGoal( 
self.origin );
 
  589     self PathMode( 
"move allowed" );
 
  590     self.zombie_think_done = 
true;
 
  595     self endon( 
"death" );
 
  597     if ( !IsDefined( level.playable_areas ) )
 
  599         level.playable_areas = GetEntArray(
"player_volume", 
"script_noteworthy" );
 
  604         foreach(area 
in level.playable_areas)
 
  606             if(
self IsTouching(area))
 
  618     assert( !
self.isdog );
 
  620     self endon( 
"death" );
 
  621     self endon( 
"stop_zombie_goto_entrance" );
 
  622     level endon( 
"intermission" );
 
  624     self.ai_state = 
"zombie_goto_entrance";
 
  626     if( IsDefined( endon_bad_path ) && endon_bad_path )
 
  630         self endon( 
"bad_path" );
 
  635     self zombie_history( 
"zombie_goto_entrance -> start goto entrance " + node.origin );
 
  637     self.got_to_entrance = 
false;
 
  642     self.goalradius = 128; 
 
  643     self SetGoal( node.origin );
 
  644     self waittill( 
"goal" ); 
 
  645     self.got_to_entrance = 
true;
 
  647     self zombie_history( 
"zombie_goto_entrance -> reached goto entrance " + node.origin );
 
  653     if( isDefined( level.pre_aggro_pathfinding_func ) )
 
  655         self [[ level.pre_aggro_pathfinding_func ]]();
 
  659     barrier_pos[0] = 
"m";
 
  660     barrier_pos[1] = 
"r";
 
  661     barrier_pos[2] = 
"l";
 
  663     self.barricade_enter = 
true;
 
  667     self AnimScripted( 
"barricade_enter_anim", 
self.first_node.zbarrier.origin, 
self.first_node.zbarrier.angles, 
"ai_zombie_barricade_enter_m_v1" );
 
  676     self.barricade_enter = 
false;
 
  683     self endon( 
"death" );
 
  684     self endon( 
"goal" );
 
  685     level endon( 
"intermission" );
 
  687     start_pos = 
self.origin;
 
  688     if(IsDefined(
self.entrance_nodes))
 
  690         for( i = 0; i < 
self.entrance_nodes.size; i++ )
 
  694                 self zombie_history( 
"zombie_assure_node -> assigned assured node = " + 
self.entrance_nodes[i].origin );
 
  698                 self.first_node = 
self.entrance_nodes[i];
 
  699                 self SetGoal( 
self.entrance_nodes[i].origin );
 
  709     nodes = array::get_all_closest( 
self.origin, level.exterior_goals, undefined, 20 );
 
  714         self.entrance_nodes = nodes;
 
  715         for( i = 0; i < 
self.entrance_nodes.size; i++ )
 
  719                 self zombie_history( 
"zombie_assure_node -> assigned assured node = " + 
self.entrance_nodes[i].origin );
 
  723                 self.first_node = 
self.entrance_nodes[i];
 
  724                 self SetGoal( 
self.entrance_nodes[i].origin );
 
  733     self zombie_history( 
"zombie_assure_node -> failed to find a good entrance point" );
 
  740     self DoDamage( 
self.health + 10, 
self.origin );
 
  743     if(
IS_TRUE(level.put_timed_out_zombies_back_in_queue ) && !
IS_TRUE(
self.has_been_damaged_by_player))
 
  745         level.zombie_total++;
 
  746         level.zombie_total_subtract++;                  
 
  750     level.zombies_timeout_spawn++;
 
  756     self endon( 
"death" );
 
  757     self endon( 
"goal" );
 
  762     self.zombie_bad_path = undefined;
 
  768     self notify( 
"stop_zombie_bad_path" );
 
  770     return self.zombie_bad_path;
 
  775     self endon( 
"death" );
 
  776     self endon( 
"stop_zombie_bad_path" );
 
  778     self waittill( 
"bad_path" );
 
  781     self.zombie_bad_path = 
true;
 
  786     self endon( 
"death" );
 
  787     self endon( 
"stop_zombie_bad_path" );
 
  790     self.zombie_bad_path = 
false;
 
  799     self endon( 
"death" ); 
 
  800     self endon(
"teleporting");
 
  809             if( IsDefined( 
self.first_node.script_noteworthy ) )
 
  811                 if( 
self.first_node.script_noteworthy == 
"no_blocker" )
 
  817             if( !IsDefined( 
self.first_node.target ) )
 
  835                 self zombie_history( 
"tear_into_building -> Could not find an attack spot" );
 
  847             self.at_entrance_tear_spot = 
false;
 
  848             if ( isdefined( level.tear_into_position ) )
 
  850                 self [[ level.tear_into_position ]]();
 
  854                 angles = 
self.first_node.zbarrier.angles;
 
  856                 self SetGoal( 
self.attacking_spot );
 
  858             self waittill( 
"goal" );
 
  859             self.at_entrance_tear_spot = 
true;
 
  863             if ( isdefined( level.tear_into_wait ) )
 
  865                 self [[ level.tear_into_wait ]]();
 
  872             self zombie_history( 
"tear_into_building -> Reach position and orientated" );       
 
  879                 for( i = 0; i < 
self.first_node.attack_spots_taken.size; i++ )
 
  881                     self.first_node.attack_spots_taken[i] = 
false;
 
  890             if ( isDefined( 
self.zombie_board_tear_down_callback ) )
 
  892                 self [[
self.zombie_board_tear_down_callback]]();
 
  898             if ( !IsDefined( 
self.chunk ) )
 
  903                     if(isDefined(attack) && !attack && !
self.missingLegs)
 
  915                 for( i = 0; i < 
self.first_node.attack_spots_taken.size; i++ )
 
  917                     self.first_node.attack_spots_taken[i] = 
false;
 
  924             self.first_node.zbarrier SetZBarrierPieceState(
self.chunk, 
"targetted_by_zombie");
 
  928             self notify( 
"bhtn_action_notify", 
"teardown" );
 
  945             self AnimScripted( 
"tear_anim", 
self.first_node.zbarrier.origin, 
self.first_node.zbarrier.angles, 
"ai_zombie_boardtear_aligned_m_1_grab" );
 
  950             while(0 < 
self.first_node.zbarrier.chunk_health[
self.chunk])
 
  953                 self AnimScripted( 
"tear_anim", 
self.first_node.zbarrier.origin, 
self.first_node.zbarrier.angles, 
"ai_zombie_boardtear_aligned_m_1_hold" );
 
  955                 self.first_node.zbarrier.chunk_health[
self.chunk]--;
 
  959             self AnimScripted( 
"tear_anim", 
self.first_node.zbarrier.origin, 
self.first_node.zbarrier.angles, 
"ai_zombie_boardtear_aligned_m_1_pull" );
 
  960             self waittill(
"temp proceed");
 
  963             self.lastchunk_destroy_time = GetTime();
 
  966             if ( isDefined( attack ) && !attack && !
self.missingLegs )
 
  974                 for( i = 0; i < 
self.first_node.attack_spots_taken.size; i++ )
 
  976                     self.first_node.attack_spots_taken[i] = 
false;
 
  979                 level notify( 
"last_board_torn", 
self.first_node.zbarrier.origin );
 
  996     self endon (
"death"); 
 
  997     if( 
self.missingLegs )
 
 1002     if(!
self.first_node.zbarrier ZBarrierSupportsZombieTaunts())
 
 1007     self.old_origin = 
self.origin;
 
 1008     if(GetDvarString( 
"zombie_taunt_freq") == 
"")
 
 1010         SetDvar(
"zombie_taunt_freq",
"5");
 
 1012     freq = GetDvarInt( 
"zombie_taunt_freq");
 
 1014     if( freq >= randomint(100) )
 
 1016         self notify( 
"bhtn_action_notify", 
"taunt" );
 
 1018         tauntState = 
"zm_taunt";
 
 1020         if(isdefined(
self.first_node.zbarrier) && 
self.first_node.zbarrier GetZBarrierTauntAnimState() != 
"")
 
 1022             tauntState = 
self.first_node.zbarrier GetZBarrierTauntAnimState();
 
 1026         self animscripted( 
"taunt_anim", 
self.origin, 
self.angles, 
"ai_zombie_taunts_4" );
 
 1033     self endon(
"death");
 
 1037         self waittill( msg, notetrack );
 
 1039         if( notetrack == 
"end" )
 
 1041             self ForceTeleport(
self.old_origin);
 
 1057     if( 
self.missingLegs )
 
 1062     if(isdefined(
self.first_node.zbarrier))
 
 1064         if(!
self.first_node.zbarrier ZBarrierSupportsZombieReachThroughAttacks())
 
 1070     if(GetDvarString( 
"zombie_reachin_freq") == 
"")
 
 1072         SetDvar(
"zombie_reachin_freq",
"50");
 
 1074     freq = GetDvarInt( 
"zombie_reachin_freq");
 
 1076     players = GetPlayers();
 
 1079     self.player_targets = [];
 
 1080     for(i=0;i<players.size;i++)
 
 1082         if ( isAlive( players[i] ) && !isDefined( players[i].revivetrigger ) && distance2d( 
self.origin, players[i].origin ) <= level.attack_player_thru_boards_range && !
IS_TRUE( players[i].zombie_vars[ 
"zombie_powerup_zombie_blood_on" ] ) )
 
 1084             self.player_targets[
self.player_targets.size] = players[i];
 
 1089     if ( !attack || freq < randomint(100) )
 
 1094     self.old_origin = 
self.origin;
 
 1096     attackAnimState = 
"zm_window_melee";
 
 1098     if(isdefined(
self.first_node.zbarrier) && 
self.first_node.zbarrier GetZBarrierReachThroughAttackAnimState() != 
"")
 
 1100         attackAnimState = 
self.first_node.zbarrier GetZBarrierReachThroughAttackAnimState();
 
 1104     self notify( 
"bhtn_action_notify", 
"attack" );
 
 1106     self AnimScripted( 
"window_melee_anim", 
self.origin, 
self.angles, 
"ai_zombie_window_attack_arm_l_out" ); 
 
 1114     self endon(
"death");
 
 1118         self waittill( msg, notetrack );
 
 1120         if( notetrack == 
"end" )
 
 1127         if( notetrack == 
"fire" )
 
 1131                 self.ignoreall = 
false;
 
 1135             if ( isDefined( 
self.first_node ) )
 
 1137                 _MELEE_DIST_SQ = 90*90;
 
 1139                 if ( IsDefined( level.attack_player_thru_boards_range ) )
 
 1141                     _MELEE_DIST_SQ =  level.attack_player_thru_boards_range * level.attack_player_thru_boards_range;
 
 1144                 _TRIGGER_DIST_SQ = 51*51;
 
 1146                 for ( i = 0; i < 
self.player_targets.size; i++ )
 
 1148                     playerDistSq = Distance2DSquared( 
self.player_targets[i].origin, 
self.origin );
 
 1149                     heightDiff = abs( 
self.player_targets[i].origin[2] - 
self.origin[2] ); 
 
 1150                     if ( playerDistSq < _MELEE_DIST_SQ && (heightDiff * heightDiff) < _MELEE_DIST_SQ )
 
 1152                         triggerDistSq = Distance2DSquared( 
self.player_targets[i].origin, 
self.first_node.trigger_location.origin );
 
 1153                         heightDiff = abs( 
self.player_targets[i].origin[2] - 
self.first_node.trigger_location.origin[2] ); 
 
 1154                         if ( triggerDistSq < _TRIGGER_DIST_SQ && (heightDiff * heightDiff) < _TRIGGER_DIST_SQ )
 
 1156                             self.player_targets[i] DoDamage( 
self.meleeDamage, 
self.origin, 
self, 
self, 
"none", 
"MOD_MELEE" );
 
 1173     if( !IsDefined( index ) )
 
 1178     self.attacking_node = node;
 
 1179     self.attacking_spot_index = index;
 
 1180     node.attack_spots_taken[index] = 
true;
 
 1181     self.attacking_spot = node.attack_spots[index];
 
 1190     for( i = 0; i < node.attack_spots.size; i++ )
 
 1192         if( !node.attack_spots_taken[i] )
 
 1194             indexes[indexes.size] = i;
 
 1198     if( indexes.size == 0 )
 
 1203     return indexes[RandomInt( indexes.size )];
 
 1209     self endon(
"death");
 
 1213         self waittill( msg, notetrack );
 
 1215         if ( notetrack == 
"end" )
 
 1220         if ( notetrack == 
"board" || notetrack == 
"destroy_piece" || notetrack == 
"bar")
 
 1222             if( isdefined( level.zbarrier_zombie_tear_notetrack_override ) )
 
 1224                 self thread [[ level.zbarrier_zombie_tear_notetrack_override ]]( node, chunk );
 
 1226             node.zbarrier SetZBarrierPieceState(chunk, 
"opening");
 
 1238     if ( IsDefined( chunk.script_parameters ) && ( chunk.script_parameters == 
"repair_board"  || chunk.script_parameters == 
"board") )
 
 1240         if(IsDefined(chunk.unbroken) && chunk.unbroken == 
true)
 
 1242             if(IsDefined(chunk.material) && chunk.material == 
"glass")
 
 1244                 PlayFX( level._effect[
"glass_break"], chunk.origin, node.angles );
 
 1245                 chunk.unbroken = 
false;
 
 1247             else if(IsDefined(chunk.material) && chunk.material == 
"metal")
 
 1249                 PlayFX( level._effect[
"fx_zombie_bar_break"], chunk.origin );
 
 1250                 chunk.unbroken = 
false;
 
 1252             else if(IsDefined(chunk.material) && chunk.material == 
"rock")
 
 1254                 if( 
IS_TRUE(level.use_clientside_rock_tearin_fx))
 
 1260                     PlayFX( level._effect[
"wall_break"], chunk.origin );
 
 1262                 chunk.unbroken = 
false;
 
 1266     if ( IsDefined( chunk.script_parameters ) && ( chunk.script_parameters == 
"barricade_vents" ) )
 
 1268         if( 
IS_TRUE(level.use_clientside_board_fx))
 
 1274             PlayFX( level._effect[
"fx_zombie_bar_break"], chunk.origin );
 
 1277     else if(IsDefined(chunk.material) && chunk.material == 
"rock")
 
 1279         if( 
IS_TRUE(level.use_clientside_rock_tearin_fx))
 
 1287         if(isDefined(level.use_clientside_board_fx))
 
 1294             wait( randomfloatrange( 0.2, 0.4 ));
 
 1303     if ( IsDefined( chunk.script_parameters ) && ( chunk.script_parameters == 
"repair_board"  || chunk.script_parameters == 
"board") )
 
 1305         if(IsDefined(chunk.unbroken) && chunk.unbroken == 
true)
 
 1307             if(IsDefined(chunk.material) && chunk.material == 
"glass")
 
 1309                 PlayFX( level._effect[
"glass_break"], chunk.origin, node.angles );
 
 1310                 chunk.unbroken = 
false;
 
 1312             else if(IsDefined(chunk.material) && chunk.material == 
"metal")
 
 1314                 PlayFX( level._effect[
"fx_zombie_bar_break"], chunk.origin );
 
 1315                 chunk.unbroken = 
false;
 
 1317             else if(IsDefined(chunk.material) && chunk.material == 
"rock")
 
 1319                 if( 
IS_TRUE(level.use_clientside_rock_tearin_fx))
 
 1325                     PlayFX( level._effect[
"wall_break"], chunk.origin );
 
 1327                 chunk.unbroken = 
false;
 
 1331     if ( IsDefined( chunk.script_parameters ) && ( chunk.script_parameters == 
"barricade_vents" ) )
 
 1333         if(isDefined(level.use_clientside_board_fx))
 
 1339             PlayFX( level._effect[
"fx_zombie_bar_break"], chunk.origin );
 
 1342     else if(IsDefined(chunk.material) && chunk.material == 
"rock")
 
 1344         if( 
IS_TRUE(level.use_clientside_rock_tearin_fx))
 
 1351         if(isDefined(level.use_clientside_board_fx))
 
 1358             wait( randomfloatrange( 0.2, 0.4 ));
 
 1367     if ( IsDefined ( chunk.script_parameters ) && ( chunk.script_parameters == 
"bar" ) || ( chunk.script_noteworthy == 
"board" ))
 
 1371         possible_tag_array_1 = [];
 
 1372         possible_tag_array_1[0] = 
"Tag_fx_top";
 
 1373         possible_tag_array_1[1] = 
"";
 
 1374         possible_tag_array_1[2] = 
"Tag_fx_top";
 
 1375         possible_tag_array_1[3] = 
"";
 
 1377         possible_tag_array_2 = [];
 
 1378         possible_tag_array_2[0] = 
"";
 
 1379         possible_tag_array_2[1] = 
"Tag_fx_bottom";
 
 1380         possible_tag_array_2[2] = 
"";
 
 1381         possible_tag_array_2[3] = 
"Tag_fx_bottom";
 
 1383         possible_tag_array_2 = array::randomize( possible_tag_array_2 );
 
 1386         random_fx[0] = level._effect[
"fx_zombie_bar_break"];
 
 1387         random_fx[1] = level._effect[
"fx_zombie_bar_break_lite"];
 
 1388         random_fx[2] = level._effect[
"fx_zombie_bar_break"];
 
 1389         random_fx[3] = level._effect[
"fx_zombie_bar_break_lite"];
 
 1391         random_fx = array::randomize( random_fx );   
 
 1393         switch( randomInt( 9 ) ) 
 
 1396                             PlayFXOnTag( level._effect[
"fx_zombie_bar_break_lite"], chunk, 
"Tag_fx_top" );
 
 1397                             wait( randomfloatrange( 0.0, 0.3 ));
 
 1398                             PlayFXOnTag( level._effect[
"fx_zombie_bar_break_lite"], chunk, 
"Tag_fx_bottom" );
 
 1402                             PlayFXOnTag( level._effect[
"fx_zombie_bar_break"], chunk, 
"Tag_fx_top" );
 
 1403                             wait( randomfloatrange( 0.0, 0.3 ));
 
 1404                             PlayFXOnTag( level._effect[
"fx_zombie_bar_break"], chunk, 
"Tag_fx_bottom" );
 
 1408                             PlayFXOnTag( level._effect[
"fx_zombie_bar_break_lite"], chunk, 
"Tag_fx_top" );
 
 1409                             wait( randomfloatrange( 0.0, 0.3 ));
 
 1410                             PlayFXOnTag( level._effect[
"fx_zombie_bar_break"], chunk, 
"Tag_fx_bottom" );
 
 1414                             PlayFXOnTag( level._effect[
"fx_zombie_bar_break"], chunk, 
"Tag_fx_top" );
 
 1415                             wait( randomfloatrange( 0.0, 0.3 ));
 
 1416                             PlayFXOnTag( level._effect[
"fx_zombie_bar_break_lite"], chunk, 
"Tag_fx_bottom" );
 
 1420                             PlayFXOnTag( level._effect[
"fx_zombie_bar_break_lite"], chunk, 
"Tag_fx_top" );
 
 1421                             wait( randomfloatrange( 0.0, 0.3 ));
 
 1422                             PlayFXOnTag( level._effect[
"fx_zombie_bar_break_lite"], chunk, 
"Tag_fx_bottom" );
 
 1426                             PlayFXOnTag( level._effect[
"fx_zombie_bar_break_lite"], chunk, 
"Tag_fx_top" );
 
 1429                             PlayFXOnTag( level._effect[
"fx_zombie_bar_break_lite"], chunk, 
"Tag_fx_bottom" );
 
 1432                             PlayFXOnTag( level._effect[
"fx_zombie_bar_break"], chunk, 
"Tag_fx_top" );
 
 1435                             PlayFXOnTag( level._effect[
"fx_zombie_bar_break"], chunk, 
"Tag_fx_bottom" );
 
 1444     if ( IsDefined ( chunk.script_parameters ) && ( chunk.script_parameters == 
"bar" ) || ( chunk.script_noteworthy == 
"board" ))
 
 1446         switch( randomInt( 10 ) ) 
 
 1449                             PlayFXOnTag( level._effect[
"fx_zombie_bar_break_lite"], chunk, 
"Tag_fx_left" );
 
 1450                             wait( randomfloatrange( 0.0, 0.3 ));
 
 1451                             PlayFXOnTag( level._effect[
"fx_zombie_bar_break_lite"], chunk, 
"Tag_fx_right" );
 
 1455                             PlayFXOnTag( level._effect[
"fx_zombie_bar_break"], chunk, 
"Tag_fx_left" );
 
 1456                             wait( randomfloatrange( 0.0, 0.3 ));
 
 1457                             PlayFXOnTag( level._effect[
"fx_zombie_bar_break"], chunk, 
"Tag_fx_right" );
 
 1461                             PlayFXOnTag( level._effect[
"fx_zombie_bar_break_lite"], chunk, 
"Tag_fx_left" );
 
 1462                             wait( randomfloatrange( 0.0, 0.3 ));
 
 1463                             PlayFXOnTag( level._effect[
"fx_zombie_bar_break"], chunk, 
"Tag_fx_right" );
 
 1467                             PlayFXOnTag( level._effect[
"fx_zombie_bar_break"], chunk, 
"Tag_fx_left" );
 
 1468                             wait( randomfloatrange( 0.0, 0.3 ));
 
 1469                             PlayFXOnTag( level._effect[
"fx_zombie_bar_break_lite"], chunk, 
"Tag_fx_right" );
 
 1473                             PlayFXOnTag( level._effect[
"fx_zombie_bar_break_lite"], chunk, 
"Tag_fx_left" );
 
 1474                             wait( randomfloatrange( 0.0, 0.3 ));
 
 1475                             PlayFXOnTag( level._effect[
"fx_zombie_bar_break_lite"], chunk, 
"Tag_fx_right" );
 
 1479                             PlayFXOnTag( level._effect[
"fx_zombie_bar_break_lite"], chunk, 
"Tag_fx_left" );
 
 1482                             PlayFXOnTag( level._effect[
"fx_zombie_bar_break_lite"], chunk, 
"Tag_fx_right" );
 
 1485                             PlayFXOnTag( level._effect[
"fx_zombie_bar_break"], chunk, 
"Tag_fx_right" );
 
 1488                             PlayFXOnTag( level._effect[
"fx_zombie_bar_break"], chunk, 
"Tag_fx_right" );
 
 1496     zombie endon( 
"completed_emerging_into_playable_area" );
 
 1498     zombie waittill( 
"stop_zombie_goto_entrance" );
 
 1500     if ( zbarrier GetZBarrierPieceState(chunk_index) == 
"targetted_by_zombie" )
 
 1502         zbarrier SetZBarrierPieceState(chunk_index, 
"closed");
 
 1510         if(zbarrier GetZBarrierPieceState(chunk_index) != 
"targetted_by_zombie")
 
 1515         if(!isdefined(zombie) || !IsAlive(zombie))
 
 1517             zbarrier SetZBarrierPieceState(chunk_index, 
"closed");
 
 1527     self endon(
"destroyed");
 
 1536     if ( IsDefined(
self) && 
IS_TRUE(
self.inhibit_scoring_from_zombies) ) 
 
 1552     if ( isdefined(zombie.no_powerups) && zombie.no_powerups )
 
 1562     if ( 
IS_TRUE( level.use_powerup_volumes ) )
 
 1564         volumes = GetEntArray( 
"no_powerups", 
"targetname" );
 
 1565         foreach( volume 
in volumes )
 
 1567             if ( zombie IsTouching( volume ) )
 
 1587     if( !IsDefined( attacker ) || !IsPlayer( attacker ) )
 
 1594         zombie.marked_for_recycle = 1;
 
 1601         if(IsDefined(zombie.in_the_ground) && zombie.in_the_ground == 
true)
 
 1603             trace = BulletTrace(zombie.origin + (0, 0, 100), zombie.origin + (0, 0, -100), 
false, undefined);
 
 1604             origin = 
trace[
"position"];
 
 1609             trace = GroundTrace(zombie.origin + (0, 0, 5), zombie.origin + (0, 0, -300), 
false, undefined);
 
 1610             origin = 
trace[
"position"];
 
 1619     if ( zombie.damageweapon.isBallisticKnife && (mod == 
"MOD_MELEE" || mod == 
"MOD_IMPACT") )
 
 1621         event = 
"ballistic_knife_death";
 
 1624     if(
IS_TRUE(zombie.deathpoints_already_given))
 
 1629     zombie.deathpoints_already_given = 
true;
 
 1634     death_weapon = attacker.currentweapon;
 
 1635     if ( IsDefined( zombie.damageweapon ) )
 
 1637         death_weapon = zombie.damageweapon;
 
 1640     if ( IsDefined(attacker) )
 
 1645     if( isdefined(level.hero_power_update))
 
 1647         level thread [[level.hero_power_update]](attacker, zombie);
 
 1653         for(i=0; i<100; i++)
 
 1655             if( !SoundExists( aliasPrefix + 
"_" + i) )
 
 1671     if( !IsDefined( level._effect ) || !IsDefined( level._effect[
"character_fire_death_sm"] ) )
 
 1676     PlayFxOnTag( level._effect[
"character_fire_death_sm"], 
self, 
"J_SpineLower" );
 
 1679     if( !IsDefined( 
self.
a.gib_ref ) || 
self.a.gib_ref != 
"left_arm" )
 
 1681         tagArray[tagArray.size] = 
"J_Elbow_LE";
 
 1682         tagArray[tagArray.size] = 
"J_Wrist_LE";
 
 1684     if( !IsDefined( 
self.
a.gib_ref ) || 
self.a.gib_ref != 
"right_arm" )
 
 1686         tagArray[tagArray.size] = 
"J_Elbow_RI";
 
 1687         tagArray[tagArray.size] = 
"J_Wrist_RI";
 
 1689     if( !IsDefined( 
self.
a.gib_ref ) || (
self.a.gib_ref != 
"no_legs" && 
self.a.gib_ref != 
"left_leg") )
 
 1691         tagArray[tagArray.size] = 
"J_Knee_LE";
 
 1692         tagArray[tagArray.size] = 
"J_Ankle_LE";
 
 1694     if( !IsDefined( 
self.
a.gib_ref ) || (
self.a.gib_ref != 
"no_legs" && 
self.a.gib_ref != 
"right_leg") )
 
 1696         tagArray[tagArray.size] = 
"J_Knee_RI";
 
 1697         tagArray[tagArray.size] = 
"J_Ankle_RI";
 
 1700     tagArray = array::randomize( tagArray ); 
 
 1701     PlayFxOnTag( level._effect[
"character_fire_death_sm"], 
self, tagArray[0] );
 
 1706     if (!isdefined(
self))
 
 1711     self notify( 
"exploding" );
 
 1712     self notify( 
"end_melee" );
 
 1713     self notify( 
"death", attacker );
 
 1717     self.dont_die_on_me = 
true;
 
 1718     self.exploding = 
true;
 
 1719     self.a.nodeath = 
true;
 
 1720     self.dont_throw_gib = 
true;
 
 1721     self StartRagdoll();
 
 1722     self SetPlayerCollision(0); 
 
 1725     if (isdefined(launchvector))
 
 1726         self LaunchRagdoll( launchvector );
 
 1729     if (isdefined(
self))
 
 1746     if(isDefined(
self._race_team))
 
 1748         team = 
self._race_team;
 
 1759     if( IsDefined( level.zombie_death_animscript_override ) )
 
 1761         self [ [ level.zombie_death_animscript_override ] ] ();
 
 1764     self.grenadeAmmo = 0;
 
 1767     if ( IsDefined( 
self.nuked ) )
 
 1772             if(IsDefined(
self.in_the_ground) && 
self.in_the_ground == 
true)
 
 1774                 trace = BulletTrace(
self.origin + (0, 0, 100), 
self.origin + (0, 0, -100), 
false, undefined);
 
 1775                 origin = 
trace[
"position"];
 
 1780                 trace = GroundTrace(
self.origin + (0, 0, 5), 
self.origin + (0, 0, -300), 
false, undefined);
 
 1781                 origin = 
trace[
"position"];
 
 1790         level 
zombie_death_points( 
self.origin, 
self.damagemod, 
self.damagelocation, 
self.attacker, 
self ,team);
 
 1794     if( isdefined( 
self.attacker ) && isai( 
self.attacker ) )
 
 1796         self.attacker notify( 
"killed", 
self );
 
 1800     if( 
"rottweil72_upgraded" == 
self.damageweapon.name && 
"MOD_RIFLE_BULLET" == 
self.damagemod )
 
 1804     if( 
"tazer_knuckles" == 
self.damageweapon.name && 
"MOD_MELEE" == 
self.damagemod )
 
 1806         self.is_on_fire = 
false;
 
 1807         self notify(
"stop_flame_damage");
 
 1809     if( 
self.damagemod == 
"MOD_BURNED" )
 
 1813     if( 
self.damagemod == 
"MOD_GRENADE" || 
self.damagemod == 
"MOD_GRENADE_SPLASH" ) 
 
 1815         level notify( 
"zombie_grenade_death", 
self.origin );
 
 1824     if ( !isdefined( level.zombie_death_animscript_callbacks ) )
 
 1829     for ( i = 0; i < level.zombie_death_animscript_callbacks.size; i++ )
 
 1831         if ( 
self [[ level.zombie_death_animscript_callbacks[i] ]]() )
 
 1843     if ( !isdefined( level.zombie_death_animscript_callbacks ) )
 
 1845         level.zombie_death_animscript_callbacks = [];
 
 1848     level.zombie_death_animscript_callbacks[level.zombie_death_animscript_callbacks.size] = func;
 
 1854     self endon (
"death");
 
 1855     self endon (
"stop_flame_damage");
 
 1858     while( isdefined( 
self.is_on_fire) && 
self.is_on_fire )
 
 1860         if( level.round_number < 6 )
 
 1862             dmg = level.zombie_health * RandomFloatRange( 0.2, 0.3 ); 
 
 1864         else if( level.round_number < 9 )
 
 1866             dmg = level.zombie_health * RandomFloatRange( 0.15, 0.25 );
 
 1868         else if( level.round_number < 11 )
 
 1870             dmg = level.zombie_health * RandomFloatRange( 0.1, 0.2 );
 
 1874             dmg = level.zombie_health * RandomFloatRange( 0.1, 0.15 );
 
 1877         if ( Isdefined( player ) && Isalive( player ) )
 
 1879             self DoDamage( dmg, 
self.origin, player );
 
 1883             self DoDamage( dmg, 
self.origin, level );
 
 1886         wait( randomfloatrange( 1.0, 3.0 ) );
 
 1892     if( IsPlayer( player) ) 
 
 1894         weapon = player GetCurrentWeapon();
 
 1896         return (weapon == level.weaponNone || weapon.isSemiAuto);
 
 1902 function zombie_damage( mod, hit_location, hit_origin, player, amount, team, weapon, direction_vec, tagName, modelName, partName, dFlags, inflictor, chargeLevel )
 
 1910     player.use_weapon_type = mod;
 
 1911     if(isDefined(
self.marked_for_death))
 
 1916     if( !IsDefined( player ) )
 
 1921     if (isdefined(hit_origin))
 
 1922         self.damagehit_origin = hit_origin;
 
 1924         self.damagehit_origin = player GetWeaponMuzzlePoint();
 
 1926     if ( 
self check_zombie_damage_callbacks( mod, hit_location, hit_origin, player, amount, weapon, direction_vec, tagName, modelName, partName, dFlags, inflictor, chargeLevel ) )
 
 1934     else if ( IsDefined(weapon) && weapon.isriotshield )
 
 1948             damage_type = 
"damage";
 
 1952             damage_type = 
"damage_light";
 
 1955         if ( !
IS_TRUE( 
self.no_damage_points ) )
 
 1961     if ( IsDefined( 
self.zombie_damage_fx_func ) )
 
 1963         self [[ 
self.zombie_damage_fx_func ]]( mod, hit_location, hit_origin, player, direction_vec );
 
 1968         if ( IsDefined( 
self.zombie_damage_claymore_func ) )
 
 1970             self [[ 
self.zombie_damage_claymore_func ]]( mod, hit_location, hit_origin, player );
 
 1972         else if ( isdefined( player ) && isalive( player ) )
 
 1974             self DoDamage( level.round_number * randomintrange( 100, 200 ), 
self.origin, player, 
self, hit_location, mod, 0, weapon );
 
 1978             self DoDamage( level.round_number * randomintrange( 100, 200 ), 
self.origin, undefined, 
self, hit_location, mod, 0, weapon );
 
 1981     else if ( mod == 
"MOD_GRENADE" || mod == 
"MOD_GRENADE_SPLASH" )
 
 1983         if ( isdefined( player ) && isalive( player ) )
 
 1985             player.grenade_multiattack_count++;
 
 1986             player.grenade_multiattack_ent = 
self;
 
 1988             self DoDamage( level.round_number + randomintrange( 100, 200 ), 
self.origin, player, 
self, hit_location, mod, 0, weapon );
 
 1992             self DoDamage( level.round_number + randomintrange( 100, 200 ), 
self.origin, undefined, 
self, hit_location, mod, 0, weapon );
 
 1995     else if( mod == 
"MOD_PROJECTILE" || mod == 
"MOD_EXPLOSIVE" || mod == 
"MOD_PROJECTILE_SPLASH" )
 
 1997         if ( isdefined( player ) && isalive( player ) )
 
 1999             self DoDamage( level.round_number * randomintrange( 0, 100 ), 
self.origin, player, 
self, hit_location, mod, 0, weapon );
 
 2003             self DoDamage( level.round_number * randomintrange( 0, 100 ), 
self.origin, undefined, 
self, hit_location, mod, 0, weapon );
 
 2010         if( 
IS_TRUE( 
self.missinglegs ) && isalive(
self)  )
 
 2012             if ( isdefined( player ) )
 
 2017         else if( IsDefined( 
self.
a.gib_ref ) && ( (
self.a.gib_ref == 
"right_arm") || (
self.a.gib_ref == 
"left_arm") ) )
 
 2019             if( !
self.missingLegs && isalive( 
self ) )
 
 2021                 if ( isdefined( player ) )
 
 2023                     rand = randomintrange(0, 100);
 
 2035 function zombie_damage_ads( mod, hit_location, hit_origin, player, amount, team, weapon, direction_vec, tagName, modelName, partName, dFlags, inflictor, chargeLevel )
 
 2043     player.use_weapon_type = mod;
 
 2044     if( !IsDefined( player ) )
 
 2049     if (isdefined(hit_origin))
 
 2050         self.damagehit_origin = hit_origin;
 
 2052         self.damagehit_origin = player GetWeaponMuzzlePoint();
 
 2055     if ( 
self check_zombie_damage_callbacks( mod, hit_location, hit_origin, player, amount, weapon, direction_vec, tagName, modelName, partName, dFlags, inflictor, chargeLevel ) )
 
 2073             damage_type = 
"damage";
 
 2077             damage_type = 
"damage_light";
 
 2080         if ( !
IS_TRUE( 
self.no_damage_points ) )
 
 2086     if ( IsDefined( 
self.zombie_damage_fx_func ) )
 
 2088         self [[ 
self.zombie_damage_fx_func ]]( mod, hit_location, hit_origin, player, direction_vec );
 
 2095 function check_zombie_damage_callbacks( mod, hit_location, hit_origin, player, amount, weapon, direction_vec, tagName, modelName, partName, dFlags, inflictor, chargeLevel )
 
 2097     if ( !isdefined( level.zombie_damage_callbacks ) )
 
 2102     for ( i = 0; i < level.zombie_damage_callbacks.size; i++ )
 
 2104         if ( 
self [[ level.zombie_damage_callbacks[i] ]]( mod, hit_location, hit_origin, player, amount, weapon, direction_vec, tagName, modelName, partName, dFlags, inflictor, chargeLevel ) )
 
 2116     if ( !isdefined( level.zombie_damage_callbacks ) )
 
 2118         level.zombie_damage_callbacks = [];
 
 2121     level.zombie_damage_callbacks[level.zombie_damage_callbacks.size] = func;
 
 2126     if( !isDefined( 
self.flame_damage_time ) || GetTime() > 
self.flame_damage_time )
 
 2128         self.flame_damage_time = GetTime() + level.zombie_vars[
"zombie_flame_dmg_point_delay"];
 
 2137     if( mod == 
"MOD_BURNED" )
 
 2139         if( !IsDefined( 
self.is_on_fire ) || ( Isdefined( 
self.is_on_fire ) && !
self.is_on_fire ) )
 
 2144         do_flame_death = 
true;
 
 2146         ai = GetAiTeamArray( level.zombie_team );
 
 2147         for( i = 0; i < ai.size; i++ )
 
 2149             if( IsDefined( ai[i].is_on_fire ) && ai[i].is_on_fire )
 
 2151                 if( DistanceSquared( ai[i].origin, 
self.origin ) < dist )
 
 2153                     do_flame_death = 
false;
 
 2159         if( do_flame_death )
 
 2172     return (weapon.weapClass == 
"spread");
 
 2177     if ( isdefined(
self) && IsActor(
self) )
 
 2179         if( (!random_gibs) || (randomint(100) < 50) )
 
 2180             gibserverutils::gibhead( 
self );
 
 2181         if( (!random_gibs) || (randomint(100) < 50) )
 
 2182             gibserverutils::gibleftarm( 
self );
 
 2183         if( (!random_gibs) || (randomint(100) < 50) )
 
 2184             gibserverutils::gibrightarm( 
self );
 
 2185         if( (!random_gibs) || (randomint(100) < 50) )
 
 2186             gibserverutils::giblegs( 
self );
 
 2197     zombie.marked_for_recycle = 0;
 
 2202     zombie waittill( 
"death", attacker);
 
 2203     time_of_death = gettime();
 
 2205     if(isDefined(zombie))
 
 2207         zombie StopSounds();
 
 2211     if( IsDefined(zombie) && IsDefined(zombie.marked_for_insta_upgraded_death) )
 
 2216     if ( IsDefined(zombie) && !isdefined( zombie.damagehit_origin ) && isdefined( attacker ) && IsAlive( attacker ) && !IsVehicle( attacker ) )
 
 2218         zombie.damagehit_origin = attacker GetWeaponMuzzlePoint();
 
 2225         if( isdefined(zombie.script_parameters) )
 
 2227             attacker notify( 
"zombie_death_params", zombie.script_parameters, 
IS_TRUE(zombie.completed_emerging_into_playable_area) );
 
 2231         if( isdefined(zombie.b_widows_wine_cocoon) && isdefined(zombie.e_widows_wine_player) )
 
 2233             attacker notify( 
"widows_wine_kill", zombie.e_widows_wine_player );
 
 2237         if( 
IS_TRUE(level.pers_upgrade_carpenter) )
 
 2243         if( 
IS_TRUE(level.pers_upgrade_sniper) )
 
 2248         if(isDefined(zombie) && isDefined(zombie.damagelocation) )
 
 2252                 attacker.headshots++;
 
 2254                 attacker AddWeaponStat(zombie.damageWeapon, 
"headshots", 1);
 
 2267                 attacker notify(
"zombie_death_no_headshot");
 
 2271         if(isDefined(zombie) && isDefined(zombie.damagemod) && zombie.damagemod == 
"MOD_MELEE")
 
 2275             attacker notify( 
"melee_kill" );
 
 2291         if ( 
IS_TRUE(level.pers_upgrade_pistol_points) )
 
 2296         if ( isDefined( zombie ) && isDefined( zombie.damageweapon ) )
 
 2298             attacker AddWeaponStat(zombie.damageWeapon, 
"kills", 1);
 
 2307         if ( isDefined( zombie ) && 
IS_TRUE( zombie.missingLegs ) )
 
 2320         if( 
IS_TRUE(level.pers_upgrade_nube) )
 
 2322             attacker notify( 
"pers_player_zombie_kill" );
 
 2330     if ( !IsDefined( zombie ) )
 
 2336     level.global_zombies_killed++;
 
 2339     if(isDefined(zombie.marked_for_death) && !isDefined(zombie.nuked))
 
 2341         level.zombie_trap_killed_count++;
 
 2348     if ( !IsDefined( zombie ) )
 
 2353     name = zombie.animname;
 
 2354     if( isdefined( zombie.sndname ) )
 
 2356         name = zombie.sndname;
 
 2359     self notify( 
"bhtn_action_notify", 
"death" );
 
 2362     if( IsActor( zombie ) )
 
 2364         if( 
IS_TRUE(zombie.damageweapon.doannihilate) )
 
 2372                  ( (zombie.damagemod === 
"MOD_GRENADE") || (zombie.damagemod === 
"MOD_GRENADE_SPLASH") || (zombie.damagemod === 
"MOD_EXPLOSIVE") || (force_explode == 1) ) )
 
 2374                 splode_dist = 12 * 15;
 
 2375                 if ( isdefined(zombie.damagehit_origin) && distancesquared(zombie.origin,zombie.damagehit_origin) < splode_dist * splode_dist )
 
 2377                     tag = 
"J_SpineLower";
 
 2397                 if ( isdefined(attacker) && IsPlayer( attacker ) && !
is_weapon_shotgun( zombie.damageweapon ) )
 
 2404         if ( zombie.damagemod === 
"MOD_GRENADE" || zombie.damagemod === 
"MOD_GRENADE_SPLASH" )
 
 2406             if ( isdefined( attacker ) && isalive( attacker )  &&isPlayer( attacker ) )
 
 2408                 attacker.grenade_multiattack_count++;
 
 2409                 attacker.grenade_multiattack_ent = zombie;
 
 2410                 attacker.grenade_multikill_count++; 
 
 2416     if ( !
IS_TRUE(zombie.has_been_damaged_by_player) && 
IS_TRUE(zombie.marked_for_recycle))
 
 2418         level.zombie_total++;
 
 2419         level.zombie_total_subtract++;
 
 2421     else if(isdefined (zombie.attacker) && isplayer(zombie.attacker) )
 
 2425         level.zombie_player_killed_count++;     
 
 2427         if ( IsDefined( zombie.sound_damage_player ) && zombie.sound_damage_player == zombie.attacker )
 
 2432         zombie.attacker notify( 
"zom_kill", zombie );
 
 2436         if(zombie.ignoreall && !
IS_TRUE(zombie.marked_for_death)  )
 
 2438             level.zombies_timeout_spawn++;
 
 2442     level notify( 
"zom_kill" );
 
 2443     level.total_zombies_killed++;
 
 2451     if ( !isdefined( level.zombie_death_event_callbacks ) )
 
 2456     for ( i = 0; i < level.zombie_death_event_callbacks.size; i++ )
 
 2458         self [[ level.zombie_death_event_callbacks[i] ]]( attacker );
 
 2465     if ( !isdefined( level.zombie_death_event_callbacks ) )
 
 2467         level.zombie_death_event_callbacks = [];
 
 2470     level.zombie_death_event_callbacks[level.zombie_death_event_callbacks.size] = func;
 
 2475     if (isdefined( level.zombie_death_event_callbacks ) )
 
 2477         ArrayRemoveValue(level.zombie_death_event_callbacks,func);
 
 2488     self.ignoreall = 
false; 
 
 2494     self.meleeAttackDist = 64;
 
 2497     self.maxsightdistsqrd = 128 * 128;
 
 2500     self.disableArrivals = 
true; 
 
 2501     self.disableExits = 
true; 
 
 2508     self endon( 
"death" );
 
 2509     level endon( 
"intermission" );
 
 2510     self endon( 
"stop_find_flesh" );
 
 2511     self endon( 
"path_timer_done" );
 
 2513     level waittill( 
"attractor_positions_generated" );
 
 2514     self.zombie_path_timer = 0;
 
 2520     self endon( 
"death" );
 
 2521     self endon( 
"zombie_acquire_enemy" );
 
 2522     level endon( 
"intermission" );
 
 2524     assert( IsDefined( 
self.favoriteenemy ) || IsDefined( 
self.enemyoverride ) );
 
 2526     self._skip_pathing_first_delay = 
true;
 
 2528     self waittill( 
"bad_path" );
 
 2530     level.zombie_pathing_failed ++;
 
 2535     if( isDefined( 
self.enemyoverride ) ) 
 
 2537         zm_utility::debug_print( 
"Zombie couldn't path to point of interest at origin: " + 
self.enemyoverride[0] + 
" Falling back to breadcrumb system" );
 
 2538         if( isDefined( 
self.enemyoverride[1] ) )
 
 2541             self.zombie_path_timer = 0;
 
 2547         if(isDefined(
self.favoriteenemy))
 
 2549             zm_utility::debug_print( 
"Zombie couldn't path to player at origin: " + 
self.favoriteenemy.origin + 
" Falling back to breadcrumb system" );
 
 2553             zm_utility::debug_print( 
"Zombie couldn't path to a player ( the other 'prefered' player might be ignored for encounters mode ). Falling back to breadcrumb system" );
 
 2557     if( !isDefined( 
self.favoriteenemy ) )
 
 2559         self.zombie_path_timer = 0;
 
 2564         self.favoriteenemy endon( 
"disconnect" );
 
 2568     players = GetPlayers();
 
 2569     valid_player_num = 0;
 
 2570     for( i = 0; i < players.size; i++ )
 
 2574             valid_player_num += 1;
 
 2578     if( players.size > 1 )
 
 2580         if(isDefined(level._should_skip_ignore_player_logic) && [[level._should_skip_ignore_player_logic]]() )
 
 2582             self.zombie_path_timer = 0;
 
 2585         if( !IsInArray( 
self.ignore_player, 
self.favoriteenemy) )
 
 2587             self.ignore_player[
self.ignore_player.size] = 
self.favoriteenemy;
 
 2590         if( 
self.ignore_player.size < valid_player_num )
 
 2592             self.zombie_path_timer = 0;
 
 2598     crumb_list = 
self.favoriteenemy.zombie_breadcrumbs;
 
 2605             self.zombie_path_timer = 0;
 
 2611         if ( !IsDefined( goal ) )
 
 2616             level.zombie_breadcrumb_failed ++;
 
 2618             goal = 
self.favoriteenemy.spectator_respawn.origin;
 
 2623         self.zombie_path_timer += 100;
 
 2624         self SetGoal( goal );
 
 2625         self waittill( 
"bad_path" );
 
 2628         for( i = 0; i < crumb_list.size; i++ )
 
 2630             if( goal == crumb_list[i] )
 
 2632                 bad_crumbs[bad_crumbs.size] = i;
 
 2641     assert( IsDefined( origin ) );
 
 2642     assert( IsDefined( breadcrumbs ) );
 
 2643     assert( IsArray( breadcrumbs ) );
 
 2645     for( i = 0; i < breadcrumbs.size; i++ )
 
 2649             crumb_index = RandomInt( breadcrumbs.size );
 
 2661         return breadcrumbs[crumb_index];
 
 2669     for ( i = 0; i < bad_crumbs.size; i++ )
 
 2671         if ( bad_crumbs[i] == crumb )
 
 2682     trace_distance = 35;
 
 2683     jitter_distance = 2;
 
 2685     index = start_crumb;
 
 2687     while (isdefined(
self.favoriteenemy.zombie_breadcrumbs[ index + 1 ]))
 
 2689         current_crumb = 
self.favoriteenemy.zombie_breadcrumbs[ index ];
 
 2690         next_crumb = 
self.favoriteenemy.zombie_breadcrumbs[ index + 1 ];
 
 2692         angles = vectortoangles(current_crumb - next_crumb);
 
 2694         right = anglestoright(angles);
 
 2695         left = anglestoright(angles + (0,180,0));
 
 2697         dist_pos = current_crumb + VectorScale( right, trace_distance );
 
 2699         trace = bulletTrace( current_crumb, dist_pos, 
true, undefined );
 
 2700         vector = 
trace[
"position"];
 
 2702         if (distance(vector, current_crumb) < 17 )
 
 2704             self.favoriteenemy.zombie_breadcrumbs[ index ] = current_crumb + VectorScale( left, jitter_distance );
 
 2710         dist_pos = current_crumb + VectorScale( left, trace_distance );
 
 2712         trace = bulletTrace( current_crumb, dist_pos, 
true, undefined );
 
 2713         vector = 
trace[
"position"];
 
 2715         if (distance(vector, current_crumb) < 17 )
 
 2717             self.favoriteenemy.zombie_breadcrumbs[ index ] = current_crumb + VectorScale( right, jitter_distance );
 
 2732     for(i = 0; i < 4; i ++)
 
 2734         notes[notes.size] = 
"zombie_repath_notify_"+i;
 
 2739         level notify(notes[note]);
 
 2741         note = (note + 1) % 4;
 
 2748     self endon( 
"death" );
 
 2749     self endon( 
"zombie_acquire_enemy" );
 
 2750     self endon( 
"bad_path" );
 
 2752     level endon( 
"intermission" );
 
 2754     if(!isdefined(level.repathNotifierStarted))
 
 2756         level.repathNotifierStarted = 
true;
 
 2761     if(!isdefined(
self.zombie_repath_notify))
 
 2763         self.zombie_repath_notify = 
"zombie_repath_notify_" + (
self getentitynumber() % 4);
 
 2768         if(!isdefined(
self._skip_pathing_first_delay))
 
 2770             level waittill(
self.zombie_repath_notify);
 
 2774             self._skip_pathing_first_delay = undefined;
 
 2777         if( !
IS_TRUE( 
self.ignore_enemyoverride ) && isDefined( 
self.enemyoverride ) && isDefined( 
self.enemyoverride[1] ) )
 
 2779             if( distanceSquared( 
self.origin, 
self.enemyoverride[0] ) > 1*1 )
 
 2781                 self OrientMode( 
"face motion" );
 
 2785                 self OrientMode( 
"face point", 
self.enemyoverride[1].origin );
 
 2787             self.ignoreall = 
true;
 
 2789             goalPos = 
self.enemyoverride[0];
 
 2790             if ( IsDefined( level.adjust_enemyoverride_func ) )
 
 2792                 goalPos = 
self [[ level.adjust_enemyoverride_func ]]();
 
 2794             self SetGoal( goalPos );
 
 2796         else if( IsDefined( 
self.favoriteenemy ) )
 
 2798             self.ignoreall = 
false;
 
 2801             if ( IsDefined( level.enemy_location_override_func ) )
 
 2803                 goalPos = [[ level.enemy_location_override_func ]]( 
self, 
self.favoriteenemy );
 
 2805                 if ( IsDefined( goalPos ) )
 
 2807                     self SetGoal( goalPos );
 
 2814             else if( 
IS_TRUE(
self.is_rat_test) )
 
 2822             else if ( IsDefined( 
self.favoriteenemy.last_valid_position ) )
 
 2824                 self SetGoal( 
self.favoriteenemy.last_valid_position );     
 
 2831             if ( !IsDefined( level.ignore_path_delays ) )
 
 2833                 distSq = distanceSquared( 
self.origin, 
self.favoriteenemy.origin );
 
 2835                 if( distSq > 3200 * 3200 )
 
 2837                     wait(2.0 + randomFloat( 1.0 ));
 
 2839                 else if( distSq > 2200 * 2200 )
 
 2841                     wait(1.0 + randomFloat( 0.5 ));
 
 2843                 else if( distSq > 1200 * 1200 )
 
 2845                     wait(0.5 + randomFloat( 0.5 ));
 
 2852         if( isDefined( level.inaccesible_player_func ) )
 
 2854             self [[ level.inaccessible_player_func ]]();
 
 2869     self endon(
"death");
 
 2874     if(isDefined(
self._rise_spot))
 
 2876         spot = 
self._rise_spot;
 
 2882     if ( 
IS_TRUE( level.use_multiple_spawns ) && isdefined( 
self.script_int ) )
 
 2884         foreach( loc 
in level.zm_loc_types[ 
"zombie_location" ] )
 
 2886             if ( !(IsDefined( level.spawner_int ) && (level.spawner_int == 
self.script_int)) &&
 
 2887                 !(IsDefined( loc.script_int ) || IsDefined( level.zones[ loc.zone_name ].script_int )) )
 
 2892             if ( IsDefined( loc.script_int ) && ( loc.script_int != 
self.script_int ) )
 
 2896             else if ( IsDefined( level.zones[ loc.zone_name ].script_int ) && ( level.zones[ loc.zone_name ].script_int != 
self.script_int ) )
 
 2901             spots[spots.size] = loc;
 
 2906         spots = level.zm_loc_types[ 
"zombie_location" ];
 
 2909         if ( GetDvarInt(
"scr_zombie_spawn_in_view") )
 
 2911             player = GetPlayers()[0];
 
 2914             look_loc = undefined;
 
 2915             foreach ( loc 
in level.zm_loc_types[ 
"zombie_location" ] )
 
 2917                 player_vec = VectorNormalize( AnglesToForward( player GetPlayerAngles() ) );
 
 2918                 player_vec_2d = ( player_vec[0], player_vec[1], 0 );
 
 2919                 player_spawn = VectorNormalize( loc.origin - player.origin );
 
 2920                 player_spawn_2d = ( player_spawn[0], player_spawn[1], 0 );
 
 2921                 dot = VectorDot( player_vec_2d, player_spawn_2d );
 
 2922                 dist = Distance( loc.origin, player.origin );
 
 2923                 if ( dot > 0.707 && dist <= GetDvarInt( 
"scr_zombie_spawn_in_view_dist" ) )
 
 2925                     if ( dot > max_dot )
 
 2935             if ( isdefined( look_loc ) )
 
 2937                 spots[ spots.size ] = look_loc;
 
 2941             if ( spots.size <= 0 )
 
 2943                 spots[spots.size] = level.zm_loc_types[ 
"zombie_location" ][0];
 
 2944                 iprintln( 
"no spawner in view" );
 
 2948     assert( spots.size > 0, 
"No spawn locations found" );
 
 2950     if( isdefined(level.zm_custom_spawn_location_selection) )
 
 2952         spot = [[level.zm_custom_spawn_location_selection]](spots);
 
 2956         spot = array::random(spots);
 
 2958     self.spawn_point = spot;
 
 2961     self thread [[level.move_spawn_func]](spot);
 
 2971     self endon(
"death");
 
 2973     self.in_the_ground = 
true;
 
 2975     if ( IsDefined( 
self.anchor ) )
 
 2977         self.anchor Delete();
 
 2980     self.anchor = 
spawn(
"script_origin", 
self.origin);
 
 2981     self.anchor.angles = 
self.angles;
 
 2982     self linkto(
self.anchor);
 
 2984     if( !isDefined( spot.angles ) )
 
 2986         spot.angles = (0, 0, 0);
 
 2989     anim_org = spot.origin;
 
 2990     anim_ang = spot.angles;
 
 2992     anim_org = anim_org + (0, 0, 0);    
 
 2997     self.anchor moveto(anim_org, .05);
 
 2998     self.anchor waittill(
"movedone");
 
 3002     if (IsDefined(target_org))
 
 3004         anim_ang = VectorToAngles(target_org - 
self.origin);
 
 3005         self.anchor RotateTo((0, anim_ang[1], 0), .05);
 
 3006         self.anchor waittill(
"rotatedone");
 
 3011     if(isDefined(
self.anchor))
 
 3013         self.anchor 
delete();
 
 3022     if ( 
self.zombie_move_speed == 
"walk" )
 
 3024         substate = RandomInt( 2 );
 
 3026     else if ( 
self.zombie_move_speed == 
"run" )
 
 3030     else if ( 
self.zombie_move_speed == 
"sprint" )
 
 3035     self OrientMode( 
"face default" );
 
 3037     if( isdefined( level.custom_riseanim ) )
 
 3039         self AnimScripted( 
"rise_anim", 
self.origin, spot.angles, level.custom_riseanim );  
 
 3041     else if( isdefined( level.custom_rise_func ) ) 
 
 3043         self [[ level.custom_rise_func ]]( spot );
 
 3047         self AnimScripted( 
"rise_anim", 
self.origin, spot.angles, 
"ai_zombie_traverse_ground_climbout_fast" );      
 
 3052     self notify(
"rise_anim_finished");
 
 3053     spot notify(
"stop_zombie_rise_fx");
 
 3054     self.in_the_ground = 
false;
 
 3055     self notify(
"risen", spot.script_string );
 
 3066     if(!
IS_TRUE(level.riser_fx_on_client))
 
 3075     zombie endon(
"death");
 
 3076     self endon(
"stop_zombie_rise_fx");
 
 3078     if (zombie.zombie_move_speed != 
"sprint")
 
 3087     self endon(
"stop_zombie_rise_fx");
 
 3088     self endon(
"rise_anim_finished");
 
 3090     if(IsDefined(
self.script_parameters) && 
self.script_parameters == 
"in_water" && (!
IS_TRUE(level._no_water_risers)) )
 
 3094     else if(IsDefined(
self.script_parameters) && 
self.script_parameters == 
"in_foliage" && (
IS_TRUE(level._foliage_risers)) )
 
 3098     else if(IsDefined(
self.script_parameters) && 
self.script_parameters == 
"in_snow")
 
 3106         if(isDefined(zombie.zone_name ) && isDefined(level.zones[zombie.zone_name]) )
 
 3108             low_g_zones = getentarray(zombie.zone_name,
"targetname");
 
 3110             if(isDefined(low_g_zones[0].script_string) && low_g_zones[0].script_string == 
"lowgravity")
 
 3132     dust_tag = 
"J_SpineUpper";
 
 3134     self endon(
"stop_zombie_rise_dust_fx");
 
 3141     if(IsDefined(
self.script_parameters) && 
self.script_parameters == 
"in_water")
 
 3144         for (t = 0; t < dust_time; t += dust_interval)
 
 3146             PlayfxOnTag(level._effect[
"rise_dust_water"], zombie, dust_tag);
 
 3151     else if(IsDefined(
self.script_parameters) && 
self.script_parameters == 
"in_snow")
 
 3154         for (t = 0; t < dust_time; t += dust_interval)
 
 3156             PlayfxOnTag(level._effect[
"rise_dust_snow"], zombie, dust_tag);
 
 3161     else if(IsDefined(
self.script_parameters) && 
self.script_parameters == 
"in_foliage")
 
 3164         for (t = 0; t < dust_time; t += dust_interval)
 
 3166             PlayfxOnTag(level._effect[
"rise_dust_foliage"], zombie, dust_tag);
 
 3173         for (t = 0; t < dust_time; t += dust_interval)
 
 3175         PlayfxOnTag(level._effect[
"rise_dust"], zombie, dust_tag);
 
 3183     zombie waittill(
"death");
 
 3184     self notify(
"stop_zombie_rise_dust_fx");
 
 3190     self endon(
"death");
 
 3192     if(
self.animname == 
"quad_zombie")
 
 3197     if( RandomInt( 100 ) < level.zombie_vars[
"tesla_head_gib_chance"] )
 
 3199         wait( randomfloatrange( 0.53, 1.0 ) );
 
 3210     self endon( 
"death" );
 
 3217         if( isdefined( 
self.zombie_move_speed ) )
 
 3219             switch(
self.zombie_move_speed)
 
 3221                 case "walk":    type=
"ambient"; 
float=4;    
break;
 
 3222                 case "run":     type=
"sprint";  
float=4;    
break;
 
 3223                 case "sprint":  type=
"sprint";  
float=4;    
break;
 
 3227         if( 
self.animname == 
"zombie" && 
self.missingLegs )
 
 3231         else if( 
self.animname == 
"thief_zombie" || 
self.animname == 
"leaper_zombie" )
 
 3235         else if( 
self.voicePrefix == 
"keeper" )
 
 3240         name = 
self.animname;
 
 3241         if( isdefined( 
self.sndname ) )
 
 3243             name = 
self.sndname;
 
 3247         self notify( 
"bhtn_action_notify", type );
 
 3249         wait(RandomFloatRange(1,
float));
 
 3255     self.should_turn = 
false;
 
 3256     self.completed_emerging_into_playable_area = 
true;
 
 3257     self.no_powerups = 
false;
 
 3258     self notify( 
"completed_emerging_into_playable_area" );
 
 3259     if( IsDefined( 
self.backedUpGoal ) )
 
 3261         self SetGoal( 
self.backedUpGoal );
 
 3262         self.backedUpGoal = undefined;
 
 3271     self endon( 
"death" );
 
 3274     if ( !IsDefined( 
self ) )
 
 3278     self SetFreeCameraLockOnAllowed( 
true );
 
 3283     self endon( 
"death" );
 
 3286     if ( !IsDefined( 
self ) )
 
 3290     self PushActors( 
true );