Advertisement
Guest User

Untitled

a guest
Dec 23rd, 2015
120
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 100.10 KB | None | 0 0
  1. #include maps\_utility;
  2. #include common_scripts\utility;
  3. #include maps\_zombiemode_utility;
  4. #include maps\_zombiemode_net;
  5. #include maps\_zombiemode_audio;
  6. #using_animtree( "generic_human" );
  7. init()
  8. {
  9. level._CONTEXTUAL_GRAB_LERP_TIME = .3;
  10. zombies = getEntArray( "zombie_spawner", "script_noteworthy" );
  11. for( i = 0; i < zombies.size; i++ )
  12. {
  13. if( is_spawner_targeted_by_blocker( zombies[i] ) )
  14. {
  15. zombies[i].is_enabled = false;
  16. }
  17. }
  18.  
  19. array_thread(zombies, ::add_spawn_function, ::zombie_spawn_init);
  20. array_thread(zombies, ::add_spawn_function, maps\_zombiemode::round_spawn_failsafe);
  21.  
  22.  
  23. level thread track_players_intersection_tracker();
  24. }
  25. track_players_intersection_tracker()
  26. {
  27. self endon( "disconnect" );
  28. self endon( "death" );
  29. level endon( "end_game" );
  30. wait( 5 );
  31.  
  32. while ( 1 )
  33. {
  34. killed_players = false;
  35. players = get_players();
  36. for ( i = 0; i < players.size; i++ )
  37. {
  38. if ( players[i] maps\_laststand::player_is_in_laststand() || "spectator" == players[i].sessionstate )
  39. {
  40. continue;
  41. }
  42.  
  43. for ( j = 0; j < players.size; j++ )
  44. {
  45. if ( i == j || players[j] maps\_laststand::player_is_in_laststand() || "spectator" == players[j].sessionstate )
  46. {
  47. continue;
  48. }
  49.  
  50. if ( isDefined( level.player_intersection_tracker_override ) )
  51. {
  52. if ( players[i] [[level.player_intersection_tracker_override]]( players[j] ) )
  53. {
  54. continue;
  55. }
  56. }
  57. playerI_origin = players[i].origin;
  58. playerJ_origin = players[j].origin;
  59.  
  60.  
  61. if ( abs(playerI_origin[2] - playerJ_origin[2] ) > 60 )
  62. continue;
  63.  
  64.  
  65. distance_apart = distance2d( playerI_origin, playerJ_origin );
  66.  
  67.  
  68. if ( abs(distance_apart) > 18 )
  69. continue;
  70.  
  71.  
  72. players[i] dodamage( 1000, (0, 0, 0) );
  73. players[j] dodamage( 1000, (0, 0, 0) );
  74. if ( !killed_players )
  75. {
  76. players[i] playsound( "zmb_laugh_child" );
  77. }
  78. killed_players = true;
  79. }
  80. }
  81. wait( .5 );
  82. }
  83. }
  84. #using_animtree( "generic_human" );
  85. is_spawner_targeted_by_blocker( ent )
  86. {
  87. if( IsDefined( ent.targetname ) )
  88. {
  89. targeters = GetEntArray( ent.targetname, "target" );
  90. for( i = 0; i < targeters.size; i++ )
  91. {
  92. if( targeters[i].targetname == "zombie_door" || targeters[i].targetname == "zombie_debris" )
  93. {
  94. return true;
  95. }
  96. result = is_spawner_targeted_by_blocker( targeters[i] );
  97. if( result )
  98. {
  99. return true;
  100. }
  101. }
  102. }
  103. return false;
  104. }
  105. zombie_spawn_init( animname_set )
  106. {
  107. if( IsDefined( self.script_noteworthy ) && self.script_noteworthy == "player_ai" )
  108. {
  109. return;
  110. }
  111.  
  112.  
  113. if( !isDefined( animname_set ) )
  114. {
  115. animname_set = false;
  116. }
  117.  
  118. self.targetname = "zombie";
  119. self.script_noteworthy = undefined;
  120. if( !animname_set )
  121. {
  122. self.animname = "zombie";
  123. }
  124.  
  125. self thread play_ambient_zombie_vocals();
  126.  
  127. self.ignoreall = true;
  128. self.ignoreme = true;
  129. self.allowdeath = true;
  130. self.force_gib = true;
  131. self.is_zombie = true;
  132. self.has_legs = true;
  133.  
  134. self allowedStances( "stand" );
  135.  
  136. self.zombie_damaged_by_bar_knockdown = false;
  137. self.gibbed = false;
  138. self.head_gibbed = false;
  139.  
  140.  
  141. self.disableArrivals = true;
  142. self.disableExits = true;
  143. self.grenadeawareness = 0;
  144. self.badplaceawareness = 0;
  145. self.ignoreSuppression = true;
  146. self.suppressionThreshold = 1;
  147. self.noDodgeMove = true;
  148. self.dontShootWhileMoving = true;
  149. self.pathenemylookahead = 0;
  150. self.badplaceawareness = 0;
  151. self.chatInitialized = false;
  152. self.a.disablepain = true;
  153. self disable_react();
  154. self.maxhealth = level.zombie_health;
  155. self.health = level.zombie_health;
  156. self.freezegun_damage = 0;
  157. self.dropweapon = false;
  158. level thread zombie_death_event( self );
  159.  
  160. self set_zombie_run_cycle();
  161. self thread zombie_think();
  162. self thread zombie_gib_on_damage();
  163. self thread zombie_damage_failsafe();
  164.  
  165.  
  166. if ( !isdefined( self.no_eye_glow ) || !self.no_eye_glow )
  167. {
  168. self thread delayed_zombie_eye_glow();
  169. }
  170. self.deathFunction = ::zombie_death_animscript;
  171. self.flame_damage_time = 0;
  172. self.meleeDamage = 60;
  173.  
  174. self zombie_history( "zombie_spawn_init -> Spawned = " + self.origin );
  175. self.thundergun_disintegrate_func = ::zombie_disintegrate;
  176. self.thundergun_knockdown_func = ::zombie_knockdown;
  177. self.tesla_head_gib_func = ::zombie_tesla_head_gib;
  178. self setTeamForEntity( "axis" );
  179. if ( isDefined(level.achievement_monitor_func) )
  180. {
  181. self [[level.achievement_monitor_func]]();
  182. }
  183. if ( isDefined( level.zombie_init_done ) )
  184. {
  185. self [[ level.zombie_init_done ]]();
  186. }
  187. self.zombie_init_done = true;
  188. self notify( "zombie_init_done" );
  189. }
  190. delayed_zombie_eye_glow()
  191. {
  192. self endon("zombie_delete");
  193.  
  194. wait .5;
  195. self zombie_eye_glow();
  196. }
  197. zombie_damage_failsafe()
  198. {
  199. self endon ("death");
  200. continue_failsafe_damage = false;
  201. while (1)
  202. {
  203.  
  204. wait 0.5;
  205.  
  206. if ( !isdefined( self.enemy ) || !IsPlayer( self.enemy ) )
  207. {
  208. continue;
  209. }
  210.  
  211. if (self istouching(self.enemy))
  212. {
  213. old_org = self.origin;
  214. if (!continue_failsafe_damage)
  215. {
  216. wait 5;
  217. }
  218.  
  219.  
  220. if (!isdefined(self.enemy) || !IsPlayer( self.enemy ) || self.enemy hasperk("specialty_armorvest") )
  221. {
  222. continue;
  223. }
  224.  
  225. if (self istouching(self.enemy)
  226. && !self.enemy maps\_laststand::player_is_in_laststand()
  227. && isalive(self.enemy))
  228. {
  229.  
  230.  
  231. if (distancesquared(old_org, self.origin) < (60 * 60) )
  232. {
  233. setsaveddvar("player_deathInvulnerableTime", 0);
  234. self.enemy DoDamage( self.enemy.health + 1000, self.enemy.origin, undefined, undefined, "riflebullet" );
  235. setsaveddvar("player_deathInvulnerableTime", level.startInvulnerableTime);
  236.  
  237. continue_failsafe_damage = true;
  238. }
  239. }
  240. }
  241. else
  242. {
  243. continue_failsafe_damage = false;
  244. }
  245. }
  246. }
  247. set_zombie_run_cycle( new_move_speed )
  248. {
  249. if ( isDefined( new_move_speed ) )
  250. {
  251. self.zombie_move_speed = new_move_speed;
  252. }
  253. else
  254. {
  255. self set_run_speed();
  256. self.zombie_move_speed_original = self.zombie_move_speed;
  257. }
  258. self.needs_run_update = true;
  259. death_anims = level._zombie_deaths[self.animname];
  260. self.deathanim = random(death_anims);
  261. switch(self.zombie_move_speed)
  262. {
  263. case "walk":
  264. var = randomintrange(1, 8);
  265. self set_run_anim( "walk" + var );
  266. self.run_combatanim = level.scr_anim[self.animname]["walk" + var];
  267. break;
  268. case "run":
  269. var = randomintrange(1, 6);
  270. self set_run_anim( "run" + var );
  271. self.run_combatanim = level.scr_anim[self.animname]["run" + var];
  272. break;
  273. case "sprint":
  274. var = randomintrange(1, 4);
  275. self set_run_anim( "sprint" + var );
  276. self.run_combatanim = level.scr_anim[self.animname]["sprint" + var];
  277. break;
  278. }
  279. }
  280. set_run_speed()
  281. {
  282. if(level.round_number < 6)
  283. {
  284. self.zombie_move_speed = "run";
  285. }
  286.  
  287. rand = randomintrange( level.zombie_move_speed, level.zombie_move_speed + 35 );
  288. //if( rand <= 35 )
  289. //{
  290. // self.zombie_move_speed = "walk";
  291. //}
  292. if( rand <= 70 )
  293. {
  294. self.zombie_move_speed = "run";
  295. }
  296. else
  297. {
  298. self.zombie_move_speed = "sprint";
  299. }
  300. }
  301. should_skip_teardown( find_flesh_struct_string )
  302. {
  303.  
  304. if( IsDefined(find_flesh_struct_string) && find_flesh_struct_string == "find_flesh" )
  305. {
  306. return true;
  307. }
  308.  
  309. if( isDefined( self.script_string ) && self.script_string == "zombie_chaser" )
  310. {
  311. return true;
  312. }
  313.  
  314. return false;
  315. }
  316. zombie_think()
  317. {
  318. self endon( "death" );
  319. assert( !self.isdog );
  320.  
  321.  
  322.  
  323.  
  324.  
  325. find_flesh_struct_string = undefined;
  326.  
  327. if (GetDvarInt( #"zombie_rise_test") || (isDefined(self.script_string) && self.script_string == "riser" ))
  328. {
  329.  
  330. self thread do_zombie_rise();
  331. self waittill("risen", find_flesh_struct_string );
  332. }
  333. else
  334. {
  335. self notify("no_rise");
  336. }
  337.  
  338. if ( IsDefined(level.zombie_custom_think_logic) )
  339. {
  340. shouldWait = self [[ level.zombie_custom_think_logic ]]();
  341. if ( shouldWait )
  342. {
  343. self waittill("zombie_custom_think_done", find_flesh_struct_string);
  344. }
  345. }
  346.  
  347. node = undefined;
  348. desired_nodes = [];
  349. self.entrance_nodes = [];
  350. if ( IsDefined( level.max_barrier_search_dist_override ) )
  351. {
  352. max_dist = level.max_barrier_search_dist_override;
  353. }
  354. else
  355. {
  356. max_dist = 500;
  357. }
  358. if( !IsDefined(find_flesh_struct_string) && IsDefined( self.target ) && self.target != "" )
  359. {
  360. desired_origin = get_desired_origin();
  361. AssertEx( IsDefined( desired_origin ), "Spawner @ " + self.origin + " has a .target but did not find a target" );
  362.  
  363. origin = desired_origin;
  364.  
  365. node = getclosest( origin, level.exterior_goals );
  366. self.entrance_nodes[0] = node;
  367. self zombie_history( "zombie_think -> #1 entrance (script_forcegoal) origin = " + self.entrance_nodes[0].origin );
  368. }
  369.  
  370.  
  371. else if ( self should_skip_teardown( find_flesh_struct_string ) )
  372. {
  373. self zombie_setup_attack_properties();
  374.  
  375. if (isDefined(self.target))
  376. {
  377. end_at_node = GetNode(self.target, "targetname");
  378. if (isDefined(end_at_node))
  379. {
  380. self setgoalnode (end_at_node);
  381. self waittill("goal");
  382. }
  383. }
  384. self thread find_flesh();
  385. self zombie_complete_emerging_into_playable_area();
  386. return;
  387. }
  388. else
  389. {
  390. origin = self.origin;
  391. desired_origin = get_desired_origin();
  392. if( IsDefined( desired_origin ) )
  393. {
  394. origin = desired_origin;
  395. }
  396.  
  397.  
  398. nodes = get_array_of_closest( origin, level.exterior_goals, undefined, 3 );
  399.  
  400. desired_nodes[0] = nodes[0];
  401. prev_dist = Distance( self.origin, nodes[0].origin );
  402. for( i = 1; i < nodes.size; i++ )
  403. {
  404. dist = Distance( self.origin, nodes[i].origin );
  405. if( ( dist - prev_dist ) > max_dist )
  406. {
  407. break;
  408. }
  409. prev_dist = dist;
  410. desired_nodes[i] = nodes[i];
  411. }
  412. node = desired_nodes[0];
  413. if( desired_nodes.size > 1 )
  414. {
  415. node = desired_nodes[RandomInt(desired_nodes.size)];
  416. }
  417. self.entrance_nodes = desired_nodes;
  418. self zombie_history( "zombie_think -> #1 entrance origin = " + node.origin );
  419.  
  420. self thread zombie_assure_node();
  421. }
  422. AssertEx( IsDefined( node ), "Did not find a node!!! [Should not see this!]" );
  423. level thread draw_line_ent_to_pos( self, node.origin, "goal" );
  424.  
  425. self.first_node = node;
  426.  
  427.  
  428. self thread zombie_goto_entrance( node );
  429. }
  430. get_desired_origin()
  431. {
  432. if( IsDefined( self.target ) )
  433. {
  434. ent = GetEnt( self.target, "targetname" );
  435. if( !IsDefined( ent ) )
  436. {
  437. ent = getstruct( self.target, "targetname" );
  438. }
  439.  
  440. if( !IsDefined( ent ) )
  441. {
  442. ent = GetNode( self.target, "targetname" );
  443. }
  444.  
  445. AssertEx( IsDefined( ent ), "Cannot find the targeted ent/node/struct, \"" + self.target + "\" at " + self.origin );
  446.  
  447. return ent.origin;
  448. }
  449. return undefined;
  450. }
  451. zombie_goto_entrance( node, endon_bad_path )
  452. {
  453. assert( !self.isdog );
  454.  
  455. self endon( "death" );
  456. level endon( "intermission" );
  457. if( IsDefined( endon_bad_path ) && endon_bad_path )
  458. {
  459.  
  460.  
  461. self endon( "bad_path" );
  462. }
  463. self zombie_history( "zombie_goto_entrance -> start goto entrance " + node.origin );
  464. self.got_to_entrance = false;
  465.  
  466.  
  467.  
  468.  
  469. self.goalradius = 128;
  470. self SetGoalPos( node.origin );
  471. self waittill( "goal" );
  472. self.got_to_entrance = true;
  473. self zombie_history( "zombie_goto_entrance -> reached goto entrance " + node.origin );
  474.  
  475.  
  476. self tear_into_building();
  477.  
  478.  
  479. if(isDefined(self.first_node.clip))
  480. {
  481. if(!isDefined(self.first_node.clip.disabled) || !self.first_node.clip.disabled)
  482. {
  483. self.first_node.clip disable_trigger();
  484. self.first_node.clip connectpaths();
  485.  
  486. }
  487. }
  488.  
  489.  
  490.  
  491. self zombie_setup_attack_properties();
  492.  
  493. if( isDefined( level.pre_aggro_pathfinding_func ) )
  494. {
  495. self [[ level.pre_aggro_pathfinding_func ]]();
  496. }
  497.  
  498. self thread find_flesh();
  499.  
  500. self waittill( "zombie_start_traverse" );
  501. self waittill( "zombie_end_traverse" );
  502. self zombie_complete_emerging_into_playable_area();
  503. }
  504. zombie_assure_node()
  505. {
  506. self endon( "death" );
  507. self endon( "goal" );
  508. level endon( "intermission" );
  509. start_pos = self.origin;
  510. if(IsDefined(self.entrance_nodes))
  511. {
  512. for( i = 0; i < self.entrance_nodes.size; i++ )
  513. {
  514. if( self zombie_bad_path() )
  515. {
  516. self zombie_history( "zombie_assure_node -> assigned assured node = " + self.entrance_nodes[i].origin );
  517.  
  518. println( "^1Zombie @ " + self.origin + " did not move for 1 second. Going to next closest node @ " + self.entrance_nodes[i].origin );
  519. level thread draw_line_ent_to_pos( self, self.entrance_nodes[i].origin, "goal" );
  520. self.first_node = self.entrance_nodes[i];
  521. self SetGoalPos( self.entrance_nodes[i].origin );
  522. }
  523. else
  524. {
  525. return;
  526. }
  527. }
  528. }
  529.  
  530.  
  531. wait(2);
  532.  
  533. nodes = get_array_of_closest( self.origin, level.exterior_goals, undefined, 20 );
  534. if(IsDefined(nodes))
  535. {
  536. self.entrance_nodes = nodes;
  537. for( i = 0; i < self.entrance_nodes.size; i++ )
  538. {
  539. if( self zombie_bad_path() )
  540. {
  541. self zombie_history( "zombie_assure_node -> assigned assured node = " + self.entrance_nodes[i].origin );
  542.  
  543. println( "^1Zombie @ " + self.origin + " did not move for 1 second. Going to next closest node @ " + self.entrance_nodes[i].origin );
  544. level thread draw_line_ent_to_pos( self, self.entrance_nodes[i].origin, "goal" );
  545. self.first_node = self.entrance_nodes[i];
  546. self SetGoalPos( self.entrance_nodes[i].origin );
  547. }
  548. else
  549. {
  550. return;
  551. }
  552. }
  553. }
  554. self zombie_history( "zombie_assure_node -> failed to find a good entrance point" );
  555.  
  556.  
  557. wait(20);
  558.  
  559. self DoDamage( self.health + 10, self.origin );
  560.  
  561.  
  562.  
  563. level.zombies_timeout_spawn++;
  564.  
  565. }
  566. zombie_bad_path()
  567. {
  568. self endon( "death" );
  569. self endon( "goal" );
  570. self thread zombie_bad_path_notify();
  571. self thread zombie_bad_path_timeout();
  572. self.zombie_bad_path = undefined;
  573. while( !IsDefined( self.zombie_bad_path ) )
  574. {
  575. wait( 0.05 );
  576. }
  577. self notify( "stop_zombie_bad_path" );
  578. return self.zombie_bad_path;
  579. }
  580. zombie_bad_path_notify()
  581. {
  582. self endon( "death" );
  583. self endon( "stop_zombie_bad_path" );
  584. self waittill( "bad_path" );
  585. self.zombie_bad_path = true;
  586. }
  587. zombie_bad_path_timeout()
  588. {
  589. self endon( "death" );
  590. self endon( "stop_zombie_bad_path" );
  591. wait( 2 );
  592. self.zombie_bad_path = false;
  593. }
  594. tear_into_building()
  595. {
  596.  
  597.  
  598.  
  599. self endon( "death" );
  600. self endon("teleporting");
  601. self zombie_history( "tear_into_building -> start" );
  602. while( 1 )
  603. {
  604.  
  605.  
  606.  
  607.  
  608. if( IsDefined( self.first_node.script_noteworthy ) )
  609. {
  610. if( self.first_node.script_noteworthy == "no_blocker" )
  611. {
  612. return;
  613. }
  614. }
  615. if( !IsDefined( self.first_node.target ) )
  616. {
  617. return;
  618. }
  619.  
  620.  
  621. if( all_chunks_destroyed( self.first_node.barrier_chunks ) )
  622. {
  623.  
  624.  
  625. self zombie_history( "tear_into_building -> all chunks destroyed" );
  626. }
  627.  
  628.  
  629. if( !get_attack_spot( self.first_node ) )
  630. {
  631. self zombie_history( "tear_into_building -> Could not find an attack spot" );
  632.  
  633.  
  634.  
  635. self thread do_a_taunt();
  636. wait( 0.5 );
  637. continue;
  638. }
  639.  
  640.  
  641. self.goalradius = 2;
  642.  
  643. self SetGoalPos( self.attacking_spot, self.first_node.angles );
  644. attacking_spot1a = self.attacking_spot;
  645. self waittill( "goal" );
  646.  
  647.  
  648.  
  649. self waittill_notify_or_timeout( "orientdone", 1 );
  650. self zombie_history( "tear_into_building -> Reach position and orientated" );
  651.  
  652.  
  653. if( all_chunks_destroyed( self.first_node.barrier_chunks ) )
  654. {
  655. self zombie_history( "tear_into_building -> all chunks destroyed" );
  656. for( i = 0; i < self.first_node.attack_spots_taken.size; i++ )
  657. {
  658. self.first_node.attack_spots_taken[i] = false;
  659. }
  660. return;
  661. }
  662.  
  663.  
  664.  
  665. while( 1 )
  666. {
  667.  
  668.  
  669.  
  670.  
  671. chunk = get_closest_non_destroyed_chunk( self.origin, self.first_node.barrier_chunks );
  672.  
  673.  
  674.  
  675.  
  676. if( !IsDefined( chunk ) )
  677. {
  678. if( !all_chunks_destroyed( self.first_node.barrier_chunks ) )
  679. {
  680. attack = self should_attack_player_thru_boards();
  681. if(isDefined(attack) && !attack && self.has_legs)
  682. {
  683. self do_a_taunt();
  684. }
  685. else
  686. {
  687. wait_network_frame();
  688. }
  689. continue;
  690. }
  691. for( i = 0; i < self.first_node.attack_spots_taken.size; i++ )
  692. {
  693. self.first_node.attack_spots_taken[i] = false;
  694. }
  695. return;
  696. }
  697. self zombie_history( "tear_into_building -> animating" );
  698.  
  699. tear_anim = get_tear_anim(chunk, self);
  700.  
  701.  
  702. chunk maps\_zombiemode_blockers::update_states("target_by_zombie");
  703.  
  704.  
  705.  
  706.  
  707.  
  708.  
  709.  
  710.  
  711.  
  712.  
  713.  
  714.  
  715. self thread maps\_zombiemode_audio::do_zombies_playvocals( "teardown", self.animname );
  716. self AnimScripted( "tear_anim", attacking_spot1a, self.first_node.angles, tear_anim, "normal", undefined, 1, 0.3 );
  717.  
  718.  
  719.  
  720.  
  721.  
  722.  
  723.  
  724.  
  725.  
  726.  
  727. 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 )
  728. {
  729. self playsound( "zmb_bar_bend" );
  730. }
  731.  
  732.  
  733.  
  734.  
  735.  
  736. self zombie_tear_notetracks( "tear_anim", chunk, self.first_node );
  737.  
  738.  
  739.  
  740.  
  741. attack = self should_attack_player_thru_boards();
  742. if(isDefined(attack) && !attack && self.has_legs)
  743. {
  744. self do_a_taunt();
  745. }
  746.  
  747. if( all_chunks_destroyed( self.first_node.barrier_chunks ) )
  748. {
  749. for( i = 0; i < self.first_node.attack_spots_taken.size; i++ )
  750. {
  751. self.first_node.attack_spots_taken[i] = false;
  752. }
  753. return;
  754. }
  755. }
  756.  
  757. self reset_attack_spot();
  758. }
  759. }
  760. do_a_taunt()
  761. {
  762. self endon ("death");
  763. if( !self.has_legs)
  764. {
  765. return false;
  766. }
  767. self.old_origin = self.origin;
  768. if(GetDvar( #"zombie_taunt_freq") == "")
  769. {
  770. setdvar("zombie_taunt_freq","5");
  771. }
  772. freq = GetDvarInt( #"zombie_taunt_freq");
  773.  
  774. if( freq >= randomint(100) )
  775. {
  776. anime = random(level._zombie_board_taunt[self.animname]);
  777. self thread maps\_zombiemode_audio::do_zombies_playvocals( "taunt", self.animname );
  778. self animscripted("zombie_taunt",self.origin,self.angles,anime, "normal", undefined, 1, 0.4 );
  779.  
  780. wait(getanimlength(anime));
  781. self ForceTeleport(self.old_origin);
  782. }
  783. }
  784. should_attack_player_thru_boards()
  785. {
  786.  
  787. if( !self.has_legs)
  788. {
  789. return false;
  790. }
  791.  
  792.  
  793. if(IsDefined(self.first_node.barrier_chunks))
  794. {
  795. for(i=0;i<self.first_node.barrier_chunks.size;i++)
  796. {
  797. if(IsDefined(self.first_node.barrier_chunks[i].unbroken) && self.first_node.barrier_chunks[i].unbroken == true )
  798. {
  799. return false;
  800. }
  801. }
  802. }
  803.  
  804. if(GetDvar( #"zombie_reachin_freq") == "")
  805. {
  806. setdvar("zombie_reachin_freq","50");
  807. }
  808. freq = GetDvarInt( #"zombie_reachin_freq");
  809.  
  810. players = get_players();
  811. attack = false;
  812. self.player_targets = [];
  813. for(i=0;i<players.size;i++)
  814. {
  815. if ( isAlive( players[i] ) && !isDefined( players[i].revivetrigger ) && distance2d( self.origin, players[i].origin ) <= 90 )
  816. {
  817. self.player_targets[self.player_targets.size] = players[i];
  818. attack = true;
  819. }
  820. }
  821. if(attack && freq >= randomint(100) )
  822. {
  823.  
  824.  
  825.  
  826. self.old_origin = self.origin;
  827. if(self.attacking_spot_index == 0)
  828. {
  829.  
  830. if(randomint(100) > 50)
  831. {
  832.  
  833. self thread maps\_zombiemode_audio::do_zombies_playvocals( "attack", self.animname );
  834. self animscripted("window_melee",self.origin,self.angles,%ai_zombie_window_attack_arm_l_out, "normal", undefined, 1, 0.3 );
  835. }
  836. else
  837. {
  838.  
  839. self thread maps\_zombiemode_audio::do_zombies_playvocals( "attack", self.animname );
  840. self animscripted("window_melee",self.origin,self.angles,%ai_zombie_window_attack_arm_r_out, "normal", undefined, 1, 0.3 );
  841. }
  842. self window_notetracks( "window_melee" );
  843. }
  844. else if(self.attacking_spot_index == 2)
  845. {
  846.  
  847. self thread maps\_zombiemode_audio::do_zombies_playvocals( "attack", self.animname );
  848. self animscripted("window_melee",self.origin,self.angles,%ai_zombie_window_attack_arm_r_out, "normal", undefined, 1, 0.3 );
  849. self window_notetracks( "window_melee" );
  850. }
  851. else if(self.attacking_spot_index == 1)
  852. {
  853.  
  854. self thread maps\_zombiemode_audio::do_zombies_playvocals( "attack", self.animname );
  855. self animscripted("window_melee",self.origin,self.angles,%ai_zombie_window_attack_arm_l_out, "normal", undefined, 1, 0.3 );
  856. self window_notetracks( "window_melee" );
  857. }
  858. }
  859. else
  860. {
  861. return false;
  862. }
  863. }
  864. window_notetracks(msg)
  865. {
  866. while(1)
  867. {
  868. self waittill( msg, notetrack );
  869. if( notetrack == "end" )
  870. {
  871.  
  872. self teleport(self.old_origin);
  873. return;
  874. }
  875. if( notetrack == "fire" )
  876. {
  877. if(self.ignoreall)
  878. {
  879. self.ignoreall = false;
  880. }
  881.  
  882. if ( isDefined( self.first_node ) )
  883. {
  884. _MELEE_DIST_SQ = 90*90;
  885. _TRIGGER_DIST_SQ = 51*51;
  886. for ( i = 0; i < self.player_targets.size; i++ )
  887. {
  888. playerDistSq = Distance2DSquared( self.player_targets[i].origin, self.origin );
  889. heightDiff = abs( self.player_targets[i].origin[2] - self.origin[2] );
  890. if ( playerDistSq < _MELEE_DIST_SQ && (heightDiff * heightDiff) < _MELEE_DIST_SQ )
  891. {
  892. triggerDistSq = Distance2DSquared( self.player_targets[i].origin, self.first_node.trigger_location.origin );
  893. heightDiff = abs( self.player_targets[i].origin[2] - self.first_node.trigger_location.origin[2] );
  894. if ( triggerDistSq < _TRIGGER_DIST_SQ && (heightDiff * heightDiff) < _TRIGGER_DIST_SQ )
  895. {
  896. self.player_targets[i] DoDamage( self.meleeDamage, self.origin, self, 0, "MOD_MELEE" );
  897. break;
  898. }
  899. }
  900. }
  901. }
  902. else
  903. {
  904. self melee();
  905. }
  906. }
  907. }
  908. }
  909. reset_attack_spot()
  910. {
  911. if( IsDefined( self.attacking_node ) )
  912. {
  913. node = self.attacking_node;
  914. index = self.attacking_spot_index;
  915. node.attack_spots_taken[index] = false;
  916. self.attacking_node = undefined;
  917. self.attacking_spot_index = undefined;
  918. }
  919. }
  920. get_attack_spot( node )
  921. {
  922. index = get_attack_spot_index( node );
  923. if( !IsDefined( index ) )
  924. {
  925. return false;
  926. }
  927. self.attacking_node = node;
  928. self.attacking_spot_index = index;
  929. node.attack_spots_taken[index] = true;
  930. self.attacking_spot = node.attack_spots[index];
  931. return true;
  932. }
  933. get_attack_spot_index( node )
  934. {
  935. indexes = [];
  936. for( i = 0; i < node.attack_spots.size; i++ )
  937. {
  938. if( !node.attack_spots_taken[i] )
  939. {
  940. indexes[indexes.size] = i;
  941. }
  942. }
  943. if( indexes.size == 0 )
  944. {
  945. return undefined;
  946. }
  947. return indexes[RandomInt( indexes.size )];
  948. }
  949. zombie_tear_notetracks( msg, chunk, node )
  950. {
  951.  
  952. random_chance = undefined;
  953. self endon("death");
  954. chunk thread check_for_zombie_death(self);
  955.  
  956. while( 1 )
  957. {
  958. self waittill( msg, notetrack );
  959. if( notetrack == "end" )
  960. {
  961. return;
  962. }
  963. if( notetrack == "board" )
  964. {
  965. if( !chunk.destroyed )
  966. {
  967. self.lastchunk_destroy_time = getTime();
  968. PlayFx( level._effect["wood_chunk_destory"], chunk.origin );
  969.  
  970. if(chunk.script_noteworthy == "4" || chunk.script_noteworthy == "6" || chunk.script_noteworthy == "5" || chunk.script_noteworthy == "1")
  971. {
  972. chunk thread zombie_boardtear_offset_fx_horizontle(chunk, node);
  973. }
  974. else
  975. {
  976. chunk thread zombie_boardtear_offset_fx_verticle(chunk, node);
  977. }
  978. zomb = self;
  979. level thread maps\_zombiemode_blockers::remove_chunk( chunk, node, true, zomb );
  980. chunk notify("destroyed");
  981. }
  982. }
  983.  
  984.  
  985.  
  986. else if( notetrack == "bar_bend" )
  987. {
  988. if( !chunk.destroyed )
  989. {
  990. self.lastchunk_destroy_time = getTime();
  991.  
  992. if( chunk.script_noteworthy == "3" )
  993. {
  994. if( IsDefined( chunk.script_string ) )
  995. {
  996. if( chunk.script_string == "prestine_bend" )
  997. {
  998.  
  999.  
  1000.  
  1001.  
  1002. bar_bend_left = spawn( "script_model", chunk.origin);
  1003.  
  1004. bar_bend_left RotateTo( chunk.angles , 0.2, 0.1, 0.1 );
  1005. bar_bend_left waittill("rotatedone");
  1006. bar_bend_left SetModel( "p_zom_win_cell_bars_01_vert01_bent" );
  1007. chunk Hide();
  1008. thread bar_repair_bend_left( bar_bend_left, chunk);
  1009.  
  1010.  
  1011.  
  1012.  
  1013.  
  1014.  
  1015.  
  1016.  
  1017. }
  1018.  
  1019.  
  1020. else if ( chunk.script_string == "bar_bend" )
  1021. {
  1022. bar_bend_left = spawn( "script_model", chunk.origin);
  1023. bar_bend_left RotateTo( chunk.angles , 0.2, 0.1, 0.1 );
  1024. bar_bend_left waittill("rotatedone");
  1025. bar_bend_left SetModel( "p_zom_win_cell_bars_bent_01_vert01_bent" );
  1026. chunk Hide();
  1027. thread bar_repair_bend_left( bar_bend_left, chunk);
  1028. }
  1029. }
  1030. }
  1031.  
  1032.  
  1033.  
  1034. if( chunk.script_noteworthy == "5" )
  1035. {
  1036. if( IsDefined( chunk.script_string ) )
  1037. {
  1038. if( chunk.script_string == "prestine_bend" )
  1039. {
  1040.  
  1041.  
  1042.  
  1043.  
  1044. bar_bend_right = spawn( "script_model", chunk.origin);
  1045.  
  1046. bar_bend_right RotateTo( chunk.angles , 0.2, 0.1, 0.1 );
  1047. bar_bend_right waittill("rotatedone");
  1048. bar_bend_right SetModel( "p_zom_win_cell_bars_01_vert04_bent" );
  1049. chunk Hide();
  1050. thread bar_repair_bend_right( bar_bend_right, chunk);
  1051.  
  1052.  
  1053.  
  1054.  
  1055.  
  1056.  
  1057.  
  1058.  
  1059. }
  1060.  
  1061.  
  1062. else if ( chunk.script_string == "bar_bend" )
  1063. {
  1064. bar_bend_right = spawn( "script_model", chunk.origin);
  1065. bar_bend_right RotateTo( chunk.angles , 0.2, 0.1, 0.1 );
  1066. bar_bend_right waittill("rotatedone");
  1067. bar_bend_right SetModel( "p_zom_win_cell_bars_bent_01_vert04_bent" );
  1068. chunk Hide();
  1069. thread bar_repair_bend_right( bar_bend_right, chunk);
  1070. }
  1071. }
  1072. }
  1073.  
  1074.  
  1075.  
  1076. zomb = self;
  1077. chunk thread zombie_bartear_offset_fx_verticle( chunk );
  1078. level thread maps\_zombiemode_blockers::remove_chunk( chunk, node, true, zomb );
  1079. chunk notify( "destroyed" );
  1080. }
  1081. }
  1082.  
  1083.  
  1084. else if( notetrack == "bar" )
  1085. {
  1086. if( !chunk.destroyed )
  1087. {
  1088. self.lastchunk_destroy_time = getTime();
  1089.  
  1090.  
  1091. if(chunk.script_noteworthy == "4" || chunk.script_noteworthy == "6")
  1092. {
  1093. if ( IsDefined( chunk.script_squadname ) && ( chunk.script_squadname == "cosmodrome_storage_area" ) )
  1094. {
  1095.  
  1096. }
  1097. if (!IsDefined( chunk.script_squadname ) )
  1098. {
  1099.  
  1100. chunk thread zombie_bartear_offset_fx_horizontle(chunk);
  1101. }
  1102. }
  1103.  
  1104.  
  1105. else
  1106. {
  1107. if ( IsDefined( chunk.script_squadname ) && ( chunk.script_squadname == "cosmodrome_storage_area" ) )
  1108. {
  1109.  
  1110. }
  1111. if (!IsDefined( chunk.script_squadname ) )
  1112. {
  1113.  
  1114. chunk thread zombie_bartear_offset_fx_verticle(chunk);
  1115. }
  1116.  
  1117.  
  1118.  
  1119. }
  1120.  
  1121. level thread maps\_zombiemode_blockers::remove_chunk( chunk, node, true, self );
  1122. chunk notify("destroyed");
  1123. }
  1124. }
  1125.  
  1126.  
  1127.  
  1128.  
  1129.  
  1130.  
  1131.  
  1132.  
  1133. }
  1134. }
  1135. bar_repair_bend_left( bar_bend_left, chunk )
  1136. {
  1137. while(1)
  1138. {
  1139. wait(0.2);
  1140. if( chunk get_chunk_state() == "repaired" )
  1141. {
  1142. bar_bend_left delete();
  1143. break;
  1144. }
  1145. }
  1146.  
  1147.  
  1148.  
  1149.  
  1150. }
  1151. bar_repair_bend_right( bar_bend_right, chunk )
  1152. {
  1153. while(1)
  1154. {
  1155. wait(0.2);
  1156. if( chunk get_chunk_state() == "repaired" )
  1157. {
  1158. bar_bend_right delete();
  1159. break;
  1160. }
  1161. }
  1162. }
  1163. zombie_boardtear_offset_fx_horizontle( chunk, node )
  1164. {
  1165.  
  1166. if ( IsDefined( chunk.script_parameters ) && ( chunk.script_parameters == "repair_board" ) )
  1167. {
  1168. if(IsDefined(chunk.unbroken) && chunk.unbroken == true)
  1169. {
  1170. if(IsDefined(chunk.material) && chunk.material == "glass")
  1171. {
  1172. PlayFX( level._effect["glass_break"], chunk.origin, node.angles );
  1173. chunk.unbroken = false;
  1174. }
  1175. else if(IsDefined(chunk.material) && chunk.material == "metal")
  1176. {
  1177. PlayFX( level._effect["fx_zombie_bar_break"], chunk.origin );
  1178. chunk.unbroken = false;
  1179. }
  1180. else
  1181. {
  1182. if( is_true(level.use_clientside_rock_tearin_fx))
  1183. {
  1184. chunk setclientflag(level._ZOMBIE_SCRIPTMOVER_FLAG_ROCK_FX);
  1185. }
  1186. else
  1187. {
  1188. PlayFX( level._effect["wall_break"], chunk.origin );
  1189. }
  1190. chunk.unbroken = false;
  1191. }
  1192. }
  1193. }
  1194. else
  1195. {
  1196. if(isDefined(level.use_clientside_board_fx))
  1197. {
  1198. chunk setclientflag(level._ZOMBIE_SCRIPTMOVER_FLAG_BOARD_HORIZONTAL_FX);
  1199. }
  1200. else
  1201. {
  1202. PlayFx( level._effect["wood_chunk_destory"], chunk.origin + (0, 0, 30));
  1203. wait( randomfloat( 0.2, 0.4 ));
  1204. PlayFx( level._effect["wood_chunk_destory"], chunk.origin + (0, 0, -30));
  1205. }
  1206. }
  1207. }
  1208. zombie_boardtear_offset_fx_verticle( chunk, node )
  1209. {
  1210.  
  1211. if ( IsDefined( chunk.script_parameters ) && ( chunk.script_parameters == "repair_board" ) )
  1212. {
  1213. if(IsDefined(chunk.unbroken) && chunk.unbroken == true)
  1214. {
  1215. if(IsDefined(chunk.material) && chunk.material == "glass")
  1216. {
  1217. PlayFX( level._effect["glass_break"], chunk.origin, node.angles );
  1218. chunk.unbroken = false;
  1219. }
  1220. else if(IsDefined(chunk.material) && chunk.material == "metal")
  1221. {
  1222. PlayFX( level._effect["fx_zombie_bar_break"], chunk.origin );
  1223. chunk.unbroken = false;
  1224. }
  1225. else
  1226. {
  1227. if( is_true(level.use_clientside_rock_tearin_fx))
  1228. {
  1229. chunk setclientflag(level._ZOMBIE_SCRIPTMOVER_FLAG_ROCK_FX);
  1230. }
  1231. else
  1232. {
  1233. PlayFX( level._effect["wall_break"], chunk.origin );
  1234. }
  1235. chunk.unbroken = false;
  1236. }
  1237. }
  1238. }
  1239. else
  1240. {
  1241. if(isDefined(level.use_clientside_board_fx))
  1242. {
  1243. chunk setclientflag(level._ZOMBIE_SCRIPTMOVER_FLAG_BOARD_VERTICAL_FX);
  1244. }
  1245. else
  1246. {
  1247. PlayFx( level._effect["wood_chunk_destory"], chunk.origin + (30, 0, 0));
  1248. wait( randomfloat( 0.2, 0.4 ));
  1249. PlayFx( level._effect["wood_chunk_destory"], chunk.origin + (-30, 0, 0));
  1250. }
  1251. }
  1252. }
  1253. zombie_bartear_offset_fx_verticle( chunk )
  1254. {
  1255. if ( IsDefined ( chunk.script_parameters ) && ( chunk.script_parameters == "bar" ) || ( chunk.script_noteworthy == "board" ))
  1256. {
  1257.  
  1258.  
  1259. possible_tag_array_1 = [];
  1260. possible_tag_array_1[0] = "Tag_fx_top";
  1261. possible_tag_array_1[1] = "";
  1262. possible_tag_array_1[2] = "Tag_fx_top";
  1263. possible_tag_array_1[3] = "";
  1264.  
  1265. possible_tag_array_2 = [];
  1266. possible_tag_array_2[0] = "";
  1267. possible_tag_array_2[1] = "Tag_fx_bottom";
  1268. possible_tag_array_2[2] = "";
  1269. possible_tag_array_2[3] = "Tag_fx_bottom";
  1270.  
  1271. possible_tag_array_2 = array_randomize( possible_tag_array_2 );
  1272.  
  1273. random_fx = [];
  1274. random_fx[0] = level._effect["fx_zombie_bar_break"];
  1275. random_fx[1] = level._effect["fx_zombie_bar_break_lite"];
  1276. random_fx[2] = level._effect["fx_zombie_bar_break"];
  1277. random_fx[3] = level._effect["fx_zombie_bar_break_lite"];
  1278.  
  1279. random_fx = array_randomize( random_fx );
  1280.  
  1281. switch( randomInt( 9 ) )
  1282. {
  1283. case 0:
  1284. PlayFXOnTag( level._effect["fx_zombie_bar_break_lite"], chunk, "Tag_fx_top" );
  1285. wait( randomfloat( 0.0, 0.3 ));
  1286. PlayFXOnTag( level._effect["fx_zombie_bar_break_lite"], chunk, "Tag_fx_bottom" );
  1287. break;
  1288.  
  1289. case 1:
  1290. PlayFXOnTag( level._effect["fx_zombie_bar_break"], chunk, "Tag_fx_top" );
  1291. wait( randomfloat( 0.0, 0.3 ));
  1292. PlayFXOnTag( level._effect["fx_zombie_bar_break"], chunk, "Tag_fx_bottom" );
  1293. break;
  1294.  
  1295. case 2:
  1296. PlayFXOnTag( level._effect["fx_zombie_bar_break_lite"], chunk, "Tag_fx_top" );
  1297. wait( randomfloat( 0.0, 0.3 ));
  1298. PlayFXOnTag( level._effect["fx_zombie_bar_break"], chunk, "Tag_fx_bottom" );
  1299. break;
  1300.  
  1301. case 3:
  1302. PlayFXOnTag( level._effect["fx_zombie_bar_break"], chunk, "Tag_fx_top" );
  1303. wait( randomfloat( 0.0, 0.3 ));
  1304. PlayFXOnTag( level._effect["fx_zombie_bar_break_lite"], chunk, "Tag_fx_bottom" );
  1305. break;
  1306.  
  1307. case 4:
  1308. PlayFXOnTag( level._effect["fx_zombie_bar_break_lite"], chunk, "Tag_fx_top" );
  1309. wait( randomfloat( 0.0, 0.3 ));
  1310. PlayFXOnTag( level._effect["fx_zombie_bar_break_lite"], chunk, "Tag_fx_bottom" );
  1311. break;
  1312.  
  1313. case 5:
  1314. PlayFXOnTag( level._effect["fx_zombie_bar_break_lite"], chunk, "Tag_fx_top" );
  1315. break;
  1316. case 6:
  1317. PlayFXOnTag( level._effect["fx_zombie_bar_break_lite"], chunk, "Tag_fx_bottom" );
  1318. break;
  1319. case 7:
  1320. PlayFXOnTag( level._effect["fx_zombie_bar_break"], chunk, "Tag_fx_top" );
  1321. break;
  1322. case 8:
  1323. PlayFXOnTag( level._effect["fx_zombie_bar_break"], chunk, "Tag_fx_bottom" );
  1324. break;
  1325. }
  1326. }
  1327.  
  1328. if ( IsDefined ( chunk.script_parameters ) && ( chunk.script_parameters == "grate" ) )
  1329. {
  1330. EarthQuake( RandomFloatRange( 0.3, 0.4 ), RandomFloatRange(0.2, 0.4), chunk.origin, 150 );
  1331. chunk play_sound_on_ent( "bar_rebuild_slam" );
  1332.  
  1333. switch( randomInt( 9 ) )
  1334. {
  1335. case 0:
  1336. PlayFX( level._effect["fx_zombie_bar_break"], chunk.origin + (-30, 0, 0) );
  1337. wait( randomfloat( 0.0, 0.3 ));
  1338. PlayFX( level._effect["fx_zombie_bar_break_lite"], chunk.origin + (-30, 0, 0) );
  1339. break;
  1340.  
  1341. case 1:
  1342. PlayFX( level._effect["fx_zombie_bar_break"], chunk.origin + (-30, 0, 0) );
  1343. wait( randomfloat( 0.0, 0.3 ));
  1344. PlayFX( level._effect["fx_zombie_bar_break"], chunk.origin + (-30, 0, 0) );
  1345.  
  1346. break;
  1347.  
  1348. case 2:
  1349. PlayFX( level._effect["fx_zombie_bar_break_lite"], chunk.origin + (-30, 0, 0) );
  1350. wait( randomfloat( 0.0, 0.3 ));
  1351. PlayFX( level._effect["fx_zombie_bar_break"], chunk.origin + (-30, 0, 0) );
  1352.  
  1353. break;
  1354.  
  1355. case 3:
  1356. PlayFX( level._effect["fx_zombie_bar_break"], chunk.origin + (-30, 0, 0) );
  1357. wait( randomfloat( 0.0, 0.3 ));
  1358. PlayFX( level._effect["fx_zombie_bar_break_lite"], chunk.origin + (-30, 0, 0) );
  1359.  
  1360. break;
  1361.  
  1362. case 4:
  1363. PlayFX( level._effect["fx_zombie_bar_break_lite"], chunk.origin + (-30, 0, 0) );
  1364. wait( randomfloat( 0.0, 0.3 ));
  1365. PlayFX( level._effect["fx_zombie_bar_break_lite"], chunk.origin + (-30, 0, 0) );
  1366. break;
  1367.  
  1368. case 5:
  1369. PlayFX( level._effect["fx_zombie_bar_break_lite"], chunk.origin + (-30, 0, 0) );
  1370. break;
  1371. case 6:
  1372. PlayFX( level._effect["fx_zombie_bar_break_lite"], chunk.origin + (-30, 0, 0) );
  1373. break;
  1374. case 7:
  1375. PlayFX( level._effect["fx_zombie_bar_break"], chunk.origin + (-30, 0, 0) );
  1376. break;
  1377. case 8:
  1378. PlayFX( level._effect["fx_zombie_bar_break"], chunk.origin + (-30, 0, 0) );
  1379. break;
  1380. }
  1381. }
  1382. }
  1383. zombie_bartear_offset_fx_horizontle( chunk )
  1384. {
  1385. if ( IsDefined ( chunk.script_parameters ) && ( chunk.script_parameters == "bar" ) || ( chunk.script_noteworthy == "board" ))
  1386. {
  1387. switch( randomInt( 10 ) )
  1388. {
  1389. case 0:
  1390. PlayFXOnTag( level._effect["fx_zombie_bar_break_lite"], chunk, "Tag_fx_left" );
  1391. wait( randomfloat( 0.0, 0.3 ));
  1392. PlayFXOnTag( level._effect["fx_zombie_bar_break_lite"], chunk, "Tag_fx_right" );
  1393. break;
  1394.  
  1395. case 1:
  1396. PlayFXOnTag( level._effect["fx_zombie_bar_break"], chunk, "Tag_fx_left" );
  1397. wait( randomfloat( 0.0, 0.3 ));
  1398. PlayFXOnTag( level._effect["fx_zombie_bar_break"], chunk, "Tag_fx_right" );
  1399. break;
  1400.  
  1401. case 2:
  1402. PlayFXOnTag( level._effect["fx_zombie_bar_break_lite"], chunk, "Tag_fx_left" );
  1403. wait( randomfloat( 0.0, 0.3 ));
  1404. PlayFXOnTag( level._effect["fx_zombie_bar_break"], chunk, "Tag_fx_right" );
  1405. break;
  1406.  
  1407. case 3:
  1408. PlayFXOnTag( level._effect["fx_zombie_bar_break"], chunk, "Tag_fx_left" );
  1409. wait( randomfloat( 0.0, 0.3 ));
  1410. PlayFXOnTag( level._effect["fx_zombie_bar_break_lite"], chunk, "Tag_fx_right" );
  1411. break;
  1412.  
  1413. case 4:
  1414. PlayFXOnTag( level._effect["fx_zombie_bar_break_lite"], chunk, "Tag_fx_left" );
  1415. wait( randomfloat( 0.0, 0.3 ));
  1416. PlayFXOnTag( level._effect["fx_zombie_bar_break_lite"], chunk, "Tag_fx_right" );
  1417. break;
  1418.  
  1419. case 5:
  1420. PlayFXOnTag( level._effect["fx_zombie_bar_break_lite"], chunk, "Tag_fx_left" );
  1421. break;
  1422. case 6:
  1423. PlayFXOnTag( level._effect["fx_zombie_bar_break_lite"], chunk, "Tag_fx_right" );
  1424. break;
  1425. case 7:
  1426. PlayFXOnTag( level._effect["fx_zombie_bar_break"], chunk, "Tag_fx_right" );
  1427. break;
  1428. case 8:
  1429. PlayFXOnTag( level._effect["fx_zombie_bar_break"], chunk, "Tag_fx_right" );
  1430. break;
  1431. }
  1432. }
  1433. }
  1434. check_for_zombie_death(zombie)
  1435. {
  1436. self endon("destroyed");
  1437.  
  1438. wait(2.5);
  1439. self maps\_zombiemode_blockers::update_states("repaired");
  1440. }
  1441. get_tear_anim( chunk, zombo )
  1442. {
  1443.  
  1444.  
  1445.  
  1446.  
  1447.  
  1448.  
  1449.  
  1450.  
  1451.  
  1452.  
  1453.  
  1454.  
  1455.  
  1456.  
  1457.  
  1458.  
  1459.  
  1460.  
  1461.  
  1462. anims = [];
  1463. anims[anims.size] = %ai_zombie_door_tear_high;
  1464. anims[anims.size] = %ai_zombie_door_tear_low;
  1465. anims[anims.size] = %ai_zombie_door_tear_left;
  1466. anims[anims.size] = %ai_zombie_door_tear_right;
  1467. anims[anims.size] = %ai_zombie_door_tear_v1;
  1468. anims[anims.size] = %ai_zombie_door_tear_v2;
  1469. anims[anims.size] = %ai_zombie_door_pound_v1;
  1470. anims[anims.size] = %ai_zombie_door_pound_v2;
  1471.  
  1472. tear_anim = anims[RandomInt( anims.size )];
  1473.  
  1474.  
  1475.  
  1476. if(isdefined(chunk.script_parameters))
  1477. {
  1478.  
  1479. if( chunk.script_parameters == "board" || chunk.script_parameters == "repair_board")
  1480. {
  1481. if( self.has_legs )
  1482. {
  1483.  
  1484. if(isdefined(chunk.script_noteworthy))
  1485. {
  1486. if(IsDefined(chunk.unbroken) && chunk.unbroken == true)
  1487. {
  1488.  
  1489. if(IsDefined(chunk.material) && chunk.material == "metal")
  1490. {
  1491. if(chunk.script_noteworthy == "1")
  1492. {
  1493. tear_anim = %ai_zombie_boardtear_m_1;
  1494. }
  1495. if(chunk.script_noteworthy == "2")
  1496. {
  1497. tear_anim = %ai_zombie_boardtear_m_4;
  1498. }
  1499. if(chunk.script_noteworthy == "3")
  1500. {
  1501. tear_anim = %ai_zombie_door_tear_low;
  1502. }
  1503. if(chunk.script_noteworthy == "4")
  1504. {
  1505. tear_anim = %ai_zombie_boardtear_m_5;
  1506. }
  1507. if(chunk.script_noteworthy == "5")
  1508. {
  1509. tear_anim = %ai_zombie_door_tear_low;
  1510. }
  1511. if(chunk.script_noteworthy == "6")
  1512. {
  1513. tear_anim = %ai_zombie_boardtear_m_6;
  1514. }
  1515. }
  1516. else
  1517. {
  1518. if(zombo.attacking_spot_index == 0)
  1519. {
  1520. tear_anim = %ai_zombie_door_pound_v1;
  1521. }
  1522. else
  1523. {
  1524. tear_anim = %ai_zombie_door_pound_v2;
  1525. }
  1526. }
  1527. }
  1528. else if(zombo.attacking_spot_index == 0)
  1529. {
  1530.  
  1531. if(chunk.script_noteworthy == "1")
  1532. {
  1533.  
  1534. tear_anim = %ai_zombie_boardtear_m_1;
  1535.  
  1536. }
  1537. else if(chunk.script_noteworthy == "2")
  1538. {
  1539.  
  1540. tear_anim = %ai_zombie_boardtear_m_2;
  1541. }
  1542. else if(chunk.script_noteworthy == "3")
  1543. {
  1544.  
  1545. tear_anim = %ai_zombie_boardtear_m_3;
  1546. }
  1547. else if(chunk.script_noteworthy == "4")
  1548. {
  1549.  
  1550. tear_anim = %ai_zombie_boardtear_m_4;
  1551. }
  1552. else if(chunk.script_noteworthy == "5")
  1553. {
  1554.  
  1555. tear_anim = %ai_zombie_boardtear_m_5;
  1556. }
  1557. else if(chunk.script_noteworthy == "6")
  1558. {
  1559.  
  1560. tear_anim = %ai_zombie_boardtear_m_6;
  1561. }
  1562.  
  1563. }
  1564. else if(zombo.attacking_spot_index == 1)
  1565. {
  1566. if(chunk.script_noteworthy == "1")
  1567. {
  1568.  
  1569. tear_anim = %ai_zombie_boardtear_r_1;
  1570.  
  1571. }
  1572. else if(chunk.script_noteworthy == "3")
  1573. {
  1574.  
  1575. tear_anim = %ai_zombie_boardtear_r_3;
  1576. }
  1577. else if(chunk.script_noteworthy == "4")
  1578. {
  1579.  
  1580. tear_anim = %ai_zombie_boardtear_r_4;
  1581. }
  1582. else if(chunk.script_noteworthy == "5")
  1583. {
  1584.  
  1585. tear_anim = %ai_zombie_boardtear_r_5;
  1586. }
  1587. else if(chunk.script_noteworthy == "6")
  1588. {
  1589. tear_anim = %ai_zombie_boardtear_r_6;
  1590. }
  1591. else if(chunk.script_noteworthy == "2")
  1592. {
  1593.  
  1594. tear_anim = %ai_zombie_boardtear_r_2;
  1595. }
  1596.  
  1597. }
  1598. else if(zombo.attacking_spot_index == 2)
  1599. {
  1600. if(chunk.script_noteworthy == "1")
  1601. {
  1602.  
  1603. tear_anim = %ai_zombie_boardtear_l_1;
  1604.  
  1605. }
  1606. else if(chunk.script_noteworthy == "2")
  1607. {
  1608.  
  1609. tear_anim = %ai_zombie_boardtear_l_2;
  1610. }
  1611. else if(chunk.script_noteworthy == "4")
  1612. {
  1613.  
  1614. tear_anim = %ai_zombie_boardtear_l_4;
  1615. }
  1616. else if(chunk.script_noteworthy == "5")
  1617. {
  1618.  
  1619. tear_anim = %ai_zombie_boardtear_l_5;
  1620. }
  1621. else if(chunk.script_noteworthy == "6")
  1622. {
  1623. tear_anim = %ai_zombie_boardtear_l_6;
  1624. }
  1625. else if(chunk.script_noteworthy == "3")
  1626. {
  1627.  
  1628. tear_anim = %ai_zombie_boardtear_l_3;
  1629. }
  1630.  
  1631. }
  1632. }
  1633. }
  1634. }
  1635. }
  1636.  
  1637.  
  1638.  
  1639.  
  1640.  
  1641. if(isdefined(chunk.script_parameters))
  1642. {
  1643.  
  1644. if( chunk.script_parameters == "bar" )
  1645. {
  1646.  
  1647. if( self.has_legs )
  1648. {
  1649.  
  1650. if(isdefined(chunk.script_noteworthy))
  1651. {
  1652.  
  1653. if(zombo.attacking_spot_index == 0)
  1654. {
  1655.  
  1656. if(chunk.script_noteworthy == "4")
  1657. {
  1658.  
  1659. tear_anim = %ai_zombie_bartear_m_5;
  1660. }
  1661.  
  1662. else if(chunk.script_noteworthy == "6")
  1663. {
  1664.  
  1665. tear_anim = %ai_zombie_bartear_m_6;
  1666. }
  1667.  
  1668. else if(chunk.script_noteworthy == "1")
  1669. {
  1670.  
  1671. tear_anim = %ai_zombie_bartear_m_3;
  1672.  
  1673.  
  1674. }
  1675. else if(chunk.script_noteworthy == "2")
  1676. {
  1677.  
  1678. tear_anim = %ai_zombie_bartear_m_2;
  1679.  
  1680. }
  1681. else if(chunk.script_noteworthy == "3")
  1682. {
  1683. tear_anim = %ai_zombie_bar_bend_m_2;
  1684.  
  1685. }
  1686.  
  1687. else if(chunk.script_noteworthy == "5")
  1688. {
  1689. tear_anim = %ai_zombie_bar_bend_m_1;
  1690. }
  1691.  
  1692. }
  1693. else if(zombo.attacking_spot_index == 1)
  1694. {
  1695. if(chunk.script_noteworthy == "4")
  1696. {
  1697. tear_anim = %ai_zombie_bartear_r_5;
  1698.  
  1699. }
  1700. else if(chunk.script_noteworthy == "6")
  1701. {
  1702. tear_anim = %ai_zombie_bartear_r_6;
  1703. }
  1704.  
  1705.  
  1706. else if(chunk.script_noteworthy == "1")
  1707. {
  1708. tear_anim = %ai_zombie_bartear_r_3;
  1709. }
  1710. else if(chunk.script_noteworthy == "3")
  1711. {
  1712. tear_anim = %ai_zombie_bar_bend_r;
  1713. }
  1714. else if(chunk.script_noteworthy == "2")
  1715. {
  1716. tear_anim = %ai_zombie_bartear_r_2;
  1717. }
  1718. else if(chunk.script_noteworthy == "5")
  1719. {
  1720. tear_anim = %ai_zombie_bar_bend_r_2;
  1721. }
  1722.  
  1723. }
  1724. else if(zombo.attacking_spot_index == 2)
  1725. {
  1726. if(chunk.script_noteworthy == "4")
  1727. {
  1728. tear_anim = %ai_zombie_bartear_l_5;
  1729. }
  1730. else if(chunk.script_noteworthy == "6")
  1731. {
  1732. tear_anim = %ai_zombie_bartear_l_6;
  1733. }
  1734.  
  1735.  
  1736. else if(chunk.script_noteworthy == "1")
  1737. {
  1738.  
  1739. tear_anim = %ai_zombie_bartear_l_3;
  1740.  
  1741. }
  1742. else if(chunk.script_noteworthy == "2")
  1743. {
  1744.  
  1745. tear_anim = %ai_zombie_bartear_l_2;
  1746. }
  1747. else if(chunk.script_noteworthy == "5")
  1748. {
  1749. tear_anim = %ai_zombie_bar_bend_l;
  1750. }
  1751. else if(chunk.script_noteworthy == "3")
  1752. {
  1753. tear_anim = %ai_zombie_bar_bend_L_2;
  1754. }
  1755.  
  1756. }
  1757. }
  1758. }
  1759. }
  1760. }
  1761.  
  1762.  
  1763.  
  1764.  
  1765.  
  1766. if(isdefined(chunk.script_parameters))
  1767. {
  1768. if( chunk.script_parameters == "grate" )
  1769. {
  1770. if( self.has_legs )
  1771. {
  1772.  
  1773. if(isdefined(chunk.script_noteworthy))
  1774. {
  1775.  
  1776. if(zombo.attacking_spot_index == 0)
  1777. {
  1778. if(chunk.script_noteworthy == "1")
  1779. {
  1780.  
  1781. tear_anim = %ai_zombie_boardtear_m_1;
  1782.  
  1783. }
  1784. else if(chunk.script_noteworthy == "2")
  1785. {
  1786.  
  1787. tear_anim = %ai_zombie_boardtear_m_2;
  1788. }
  1789. else if(chunk.script_noteworthy == "3")
  1790. {
  1791.  
  1792. tear_anim = %ai_zombie_boardtear_m_3;
  1793. }
  1794. else if(chunk.script_noteworthy == "4")
  1795. {
  1796.  
  1797. tear_anim = %ai_zombie_boardtear_m_4;
  1798. }
  1799. else if(chunk.script_noteworthy == "5")
  1800. {
  1801.  
  1802. tear_anim = %ai_zombie_boardtear_m_5;
  1803. }
  1804. else if(chunk.script_noteworthy == "6")
  1805. {
  1806.  
  1807. tear_anim = %ai_zombie_boardtear_m_6;
  1808. }
  1809.  
  1810. }
  1811. else if(zombo.attacking_spot_index == 1)
  1812. {
  1813. if(chunk.script_noteworthy == "1")
  1814. {
  1815.  
  1816. tear_anim = %ai_zombie_boardtear_r_1;
  1817.  
  1818. }
  1819. else if(chunk.script_noteworthy == "3")
  1820. {
  1821.  
  1822. tear_anim = %ai_zombie_boardtear_r_3;
  1823. }
  1824. else if(chunk.script_noteworthy == "4")
  1825. {
  1826.  
  1827. tear_anim = %ai_zombie_boardtear_r_4;
  1828. }
  1829. else if(chunk.script_noteworthy == "5")
  1830. {
  1831.  
  1832. tear_anim = %ai_zombie_boardtear_r_5;
  1833. }
  1834. else if(chunk.script_noteworthy == "6")
  1835. {
  1836. tear_anim = %ai_zombie_boardtear_r_6;
  1837. }
  1838. else if(chunk.script_noteworthy == "2")
  1839. {
  1840.  
  1841. tear_anim = %ai_zombie_boardtear_r_2;
  1842. }
  1843.  
  1844. }
  1845. else if(zombo.attacking_spot_index == 2)
  1846. {
  1847. if(chunk.script_noteworthy == "1")
  1848. {
  1849.  
  1850. tear_anim = %ai_zombie_boardtear_l_1;
  1851.  
  1852. }
  1853. else if(chunk.script_noteworthy == "2")
  1854. {
  1855.  
  1856. tear_anim = %ai_zombie_boardtear_l_2;
  1857. }
  1858. else if(chunk.script_noteworthy == "4")
  1859. {
  1860.  
  1861. tear_anim = %ai_zombie_boardtear_l_4;
  1862. }
  1863. else if(chunk.script_noteworthy == "5")
  1864. {
  1865.  
  1866. tear_anim = %ai_zombie_boardtear_l_5;
  1867. }
  1868. else if(chunk.script_noteworthy == "6")
  1869. {
  1870. tear_anim = %ai_zombie_boardtear_l_6;
  1871. }
  1872. else if(chunk.script_noteworthy == "3")
  1873. {
  1874.  
  1875. tear_anim = %ai_zombie_boardtear_l_3;
  1876. }
  1877.  
  1878. }
  1879. }
  1880. }
  1881. }
  1882. }
  1883.  
  1884.  
  1885.  
  1886.  
  1887.  
  1888.  
  1889. if(isdefined(chunk.script_parameters))
  1890. {
  1891.  
  1892. if( chunk.script_parameters == "board" || chunk.script_parameters == "repair_board")
  1893. {
  1894. if( self.has_legs == false )
  1895. {
  1896.  
  1897. if(isdefined(chunk.script_noteworthy))
  1898. {
  1899.  
  1900. if(zombo.attacking_spot_index == 0)
  1901. {
  1902. if(chunk.script_noteworthy == "1")
  1903. {
  1904.  
  1905. tear_anim = %ai_zombie_boardtear_crawl_m_1;
  1906.  
  1907. }
  1908. else if(chunk.script_noteworthy == "2")
  1909. {
  1910.  
  1911. tear_anim = %ai_zombie_boardtear_crawl_m_2;
  1912. }
  1913. else if(chunk.script_noteworthy == "3")
  1914. {
  1915.  
  1916. tear_anim = %ai_zombie_boardtear_crawl_m_3;
  1917. }
  1918. else if(chunk.script_noteworthy == "4")
  1919. {
  1920.  
  1921. tear_anim = %ai_zombie_boardtear_crawl_m_4;
  1922. }
  1923. else if(chunk.script_noteworthy == "5")
  1924. {
  1925.  
  1926. tear_anim = %ai_zombie_boardtear_crawl_m_5;
  1927. }
  1928. else if(chunk.script_noteworthy == "6")
  1929. {
  1930.  
  1931. tear_anim = %ai_zombie_boardtear_crawl_m_6;
  1932. }
  1933.  
  1934. }
  1935. else if(zombo.attacking_spot_index == 1)
  1936. {
  1937. if(chunk.script_noteworthy == "1")
  1938. {
  1939.  
  1940. tear_anim = %ai_zombie_boardtear_crawl_r_1;
  1941.  
  1942. }
  1943. else if(chunk.script_noteworthy == "3")
  1944. {
  1945.  
  1946. tear_anim = %ai_zombie_boardtear_crawl_r_3;
  1947. }
  1948. else if(chunk.script_noteworthy == "4")
  1949. {
  1950.  
  1951. tear_anim = %ai_zombie_boardtear_crawl_r_4;
  1952. }
  1953. else if(chunk.script_noteworthy == "5")
  1954. {
  1955.  
  1956. tear_anim = %ai_zombie_boardtear_crawl_r_5;
  1957. }
  1958. else if(chunk.script_noteworthy == "6")
  1959. {
  1960. tear_anim = %ai_zombie_boardtear_crawl_r_6;
  1961. }
  1962. else if(chunk.script_noteworthy == "2")
  1963. {
  1964.  
  1965. tear_anim = %ai_zombie_boardtear_crawl_r_2;
  1966. }
  1967.  
  1968. }
  1969. else if(zombo.attacking_spot_index == 2)
  1970. {
  1971. if(chunk.script_noteworthy == "1")
  1972. {
  1973.  
  1974. tear_anim = %ai_zombie_boardtear_crawl_l_1;
  1975.  
  1976. }
  1977. else if(chunk.script_noteworthy == "2")
  1978. {
  1979.  
  1980. tear_anim = %ai_zombie_boardtear_crawl_l_2;
  1981. }
  1982. else if(chunk.script_noteworthy == "4")
  1983. {
  1984.  
  1985. tear_anim = %ai_zombie_boardtear_crawl_l_4;
  1986. }
  1987. else if(chunk.script_noteworthy == "5")
  1988. {
  1989.  
  1990. tear_anim = %ai_zombie_boardtear_crawl_l_5;
  1991. }
  1992. else if(chunk.script_noteworthy == "6")
  1993. {
  1994. tear_anim = %ai_zombie_boardtear_crawl_l_6;
  1995. }
  1996. else if(chunk.script_noteworthy == "3")
  1997. {
  1998.  
  1999. tear_anim = %ai_zombie_boardtear_crawl_l_3;
  2000. }
  2001.  
  2002. }
  2003. }
  2004. }
  2005. }
  2006. }
  2007.  
  2008.  
  2009.  
  2010.  
  2011. if(isdefined(chunk.script_parameters))
  2012. {
  2013.  
  2014. if( chunk.script_parameters == "bar" )
  2015. {
  2016.  
  2017. if( self.has_legs == false )
  2018. {
  2019.  
  2020. if(isdefined(chunk.script_noteworthy))
  2021. {
  2022.  
  2023. if(zombo.attacking_spot_index == 0)
  2024. {
  2025. if(chunk.script_noteworthy == "1")
  2026. {
  2027.  
  2028. tear_anim = %ai_zombie_bartear_crawl_m_2;
  2029.  
  2030. }
  2031. else if(chunk.script_noteworthy == "2")
  2032. {
  2033.  
  2034. tear_anim = %ai_zombie_bartear_crawl_m_3;
  2035.  
  2036. }
  2037. else if(chunk.script_noteworthy == "3")
  2038. {
  2039.  
  2040. tear_anim = %ai_zombie_bartear_crawl_m_1;
  2041. }
  2042. else if(chunk.script_noteworthy == "4")
  2043. {
  2044.  
  2045. tear_anim = %ai_zombie_bartear_crawl_m_5;
  2046. }
  2047. else if(chunk.script_noteworthy == "5")
  2048. {
  2049.  
  2050. tear_anim = %ai_zombie_bartear_crawl_m_4;
  2051. }
  2052. else if(chunk.script_noteworthy == "6")
  2053. {
  2054.  
  2055. tear_anim = %ai_zombie_bartear_crawl_m_6;
  2056. }
  2057.  
  2058. }
  2059. else if(zombo.attacking_spot_index == 1)
  2060. {
  2061. if(chunk.script_noteworthy == "1")
  2062. {
  2063. tear_anim = %ai_zombie_bartear_crawl_r_2;
  2064. }
  2065. else if(chunk.script_noteworthy == "3")
  2066. {
  2067. tear_anim = %ai_zombie_bartear_crawl_r_1;
  2068. }
  2069. else if(chunk.script_noteworthy == "2")
  2070. {
  2071. tear_anim = %ai_zombie_bartear_crawl_r_3;
  2072. }
  2073. else if(chunk.script_noteworthy == "5")
  2074. {
  2075. tear_anim = %ai_zombie_bartear_crawl_r_4;
  2076. }
  2077. else if(chunk.script_noteworthy == "6")
  2078. {
  2079. tear_anim = %ai_zombie_bartear_crawl_r_6;
  2080. }
  2081. else if(chunk.script_noteworthy == "4")
  2082. {
  2083. tear_anim = %ai_zombie_bartear_crawl_r_5;
  2084.  
  2085. }
  2086.  
  2087.  
  2088. }
  2089. else if(zombo.attacking_spot_index == 2)
  2090. {
  2091. if(chunk.script_noteworthy == "1")
  2092. {
  2093.  
  2094. tear_anim = %ai_zombie_bartear_crawl_l_2;
  2095.  
  2096. }
  2097. else if(chunk.script_noteworthy == "2")
  2098. {
  2099.  
  2100. tear_anim = %ai_zombie_bartear_crawl_l_3;
  2101. }
  2102. else if(chunk.script_noteworthy == "4")
  2103. {
  2104.  
  2105. tear_anim = %ai_zombie_bartear_crawl_l_5;
  2106. }
  2107. else if(chunk.script_noteworthy == "5")
  2108. {
  2109.  
  2110. tear_anim = %ai_zombie_bartear_crawl_l_4;
  2111. }
  2112. else if(chunk.script_noteworthy == "6")
  2113. {
  2114. tear_anim = %ai_zombie_bartear_crawl_l_6;
  2115. }
  2116. else if(chunk.script_noteworthy == "3")
  2117. {
  2118.  
  2119. tear_anim = %ai_zombie_bartear_crawl_l_1;
  2120. }
  2121.  
  2122. }
  2123. }
  2124. }
  2125.  
  2126. else if( self.has_legs == false)
  2127. {
  2128. anims = [];
  2129. anims[anims.size] = %ai_zombie_attack_crawl;
  2130. anims[anims.size] = %ai_zombie_attack_crawl_lunge;
  2131. tear_anim = anims[RandomInt( anims.size )];
  2132. }
  2133. }
  2134.  
  2135. }
  2136.  
  2137. return tear_anim;
  2138. }
  2139. cap_zombie_head_gibs()
  2140. {
  2141. if( !isDefined( level.max_head_gibs_per_frame ) )
  2142. {
  2143. level.max_head_gibs_per_frame = 4;
  2144. }
  2145.  
  2146. while( true )
  2147. {
  2148. level.head_gibs_this_frame = 0;
  2149. wait_network_frame();
  2150. }
  2151. }
  2152. zombie_head_gib( attacker, means_of_death )
  2153. {
  2154. self endon( "death" );
  2155. if ( !is_mature() )
  2156. {
  2157. return false;
  2158. }
  2159. if ( is_german_build() )
  2160. {
  2161. return;
  2162. }
  2163. if( IsDefined( self.head_gibbed ) && self.head_gibbed )
  2164. {
  2165. return;
  2166. }
  2167.  
  2168. if( !isDefined( level.head_gibs_this_frame ) )
  2169. {
  2170. level thread cap_zombie_head_gibs();
  2171. }
  2172.  
  2173. if( level.head_gibs_this_frame >= level.max_head_gibs_per_frame )
  2174. {
  2175. return;
  2176. }
  2177. level.head_gibs_this_frame++;
  2178. self.head_gibbed = true;
  2179.  
  2180. self zombie_eye_glow_stop();
  2181. size = self GetAttachSize();
  2182. for( i = 0; i < size; i++ )
  2183. {
  2184. model = self GetAttachModelName( i );
  2185. if( IsSubStr( model, "head" ) )
  2186. {
  2187.  
  2188. if(isdefined(self.hatmodel))
  2189. {
  2190. self detach( self.hatModel, "" );
  2191. }
  2192. self play_sound_on_ent( "zombie_head_gib" );
  2193.  
  2194. self Detach( model, "", true );
  2195. if ( isDefined(self.torsoDmg5) )
  2196. {
  2197. self Attach( self.torsoDmg5, "", true );
  2198. }
  2199. break;
  2200. }
  2201. }
  2202. temp_array = [];
  2203. temp_array[0] = level._ZOMBIE_GIB_PIECE_INDEX_HEAD;
  2204. self gib( "normal", temp_array );
  2205. self thread damage_over_time( self.health * 0.2, 1, attacker, means_of_death );
  2206. }
  2207. damage_over_time( dmg, delay, attacker, means_of_death )
  2208. {
  2209. self endon( "death" );
  2210. if( !IsAlive( self ) )
  2211. {
  2212. return;
  2213. }
  2214. if( !IsPlayer( attacker ) )
  2215. {
  2216. attacker = undefined;
  2217. }
  2218. while( 1 )
  2219. {
  2220. if( IsDefined( delay ) )
  2221. {
  2222. wait( delay );
  2223. }
  2224. self DoDamage( dmg, self.origin, attacker, undefined, means_of_death, self.damagelocation );
  2225. }
  2226. }
  2227. head_should_gib( attacker, type, point )
  2228. {
  2229. if ( !is_mature() )
  2230. {
  2231. return false;
  2232. }
  2233.  
  2234. if ( is_german_build() )
  2235. {
  2236. return false;
  2237. }
  2238. if( self.head_gibbed )
  2239. {
  2240. return false;
  2241. }
  2242.  
  2243. if( !IsDefined( attacker ) || !IsPlayer( attacker ) )
  2244. {
  2245. return false;
  2246. }
  2247.  
  2248. low_health_percent = ( self.health / self.maxhealth ) * 100;
  2249. if( low_health_percent > 10 )
  2250. {
  2251. return false;
  2252. }
  2253. weapon = attacker GetCurrentWeapon();
  2254.  
  2255.  
  2256.  
  2257. if( type != "MOD_RIFLE_BULLET" && type != "MOD_PISTOL_BULLET" )
  2258. {
  2259.  
  2260. if( type == "MOD_GRENADE" || type == "MOD_GRENADE_SPLASH" )
  2261. {
  2262. if( Distance( point, self GetTagOrigin( "j_head" ) ) > 55 )
  2263. {
  2264. return false;
  2265. }
  2266. else
  2267. {
  2268.  
  2269. return true;
  2270. }
  2271. }
  2272. else if( type == "MOD_PROJECTILE" )
  2273. {
  2274. if( Distance( point, self GetTagOrigin( "j_head" ) ) > 10 )
  2275. {
  2276. return false;
  2277. }
  2278. else
  2279. {
  2280. return true;
  2281. }
  2282. }
  2283.  
  2284. else if( WeaponClass( weapon ) != "spread" )
  2285. {
  2286. return false;
  2287. }
  2288. }
  2289.  
  2290. if( !animscripts\utility::damageLocationIsAny( "head", "helmet", "neck" ) )
  2291. {
  2292. return false;
  2293. }
  2294.  
  2295. if( weapon == "none" || weapon == "m1911_zm" || WeaponIsGasWeapon( self.weapon ) )
  2296. {
  2297. return false;
  2298. }
  2299. return true;
  2300. }
  2301. headshot_blood_fx()
  2302. {
  2303. if( !IsDefined( self ) )
  2304. {
  2305. return;
  2306. }
  2307. if( !is_mature() )
  2308. {
  2309. return;
  2310. }
  2311. fxTag = "j_neck";
  2312. fxOrigin = self GetTagOrigin( fxTag );
  2313. upVec = AnglesToUp( self GetTagAngles( fxTag ) );
  2314. forwardVec = AnglesToForward( self GetTagAngles( fxTag ) );
  2315.  
  2316.  
  2317. PlayFX( level._effect["headshot"], fxOrigin, forwardVec, upVec );
  2318. PlayFX( level._effect["headshot_nochunks"], fxOrigin, forwardVec, upVec );
  2319.  
  2320. wait( 0.3 );
  2321. if(IsDefined( self ))
  2322. {
  2323. if( self maps\_zombiemode_weap_tesla::enemy_killed_by_tesla() )
  2324. {
  2325. PlayFxOnTag( level._effect["tesla_head_light"], self, fxTag );
  2326. }
  2327. else
  2328. {
  2329. PlayFxOnTag( level._effect["bloodspurt"], self, fxTag );
  2330. }
  2331. }
  2332. }
  2333. zombie_gib_on_damage()
  2334. {
  2335. while( 1 )
  2336. {
  2337. self waittill( "damage", amount, attacker, direction_vec, point, type );
  2338. if( !IsDefined( self ) )
  2339. {
  2340. return;
  2341. }
  2342. if( !self zombie_should_gib( amount, attacker, type ) )
  2343. {
  2344. continue;
  2345. }
  2346. if( self head_should_gib( attacker, type, point ) && type != "MOD_BURNED" )
  2347. {
  2348. self zombie_head_gib( attacker, type );
  2349. if(IsDefined(attacker.headshot_count))
  2350. {
  2351. attacker.headshot_count++;
  2352. }
  2353. else
  2354. {
  2355. attacker.headshot_count = 1;
  2356. }
  2357.  
  2358. attacker.stats["headshots"] = attacker.headshot_count;
  2359. attacker.stats["zombie_gibs"]++;
  2360. continue;
  2361. }
  2362. if( !self.gibbed )
  2363. {
  2364.  
  2365. if( self animscripts\utility::damageLocationIsAny( "head", "helmet", "neck" ) )
  2366. {
  2367. continue;
  2368. }
  2369. refs = [];
  2370. switch( self.damageLocation )
  2371. {
  2372. case "torso_upper":
  2373. case "torso_lower":
  2374.  
  2375.  
  2376. refs[refs.size] = "guts";
  2377. refs[refs.size] = "right_arm";
  2378. break;
  2379.  
  2380. case "right_arm_upper":
  2381. case "right_arm_lower":
  2382. case "right_hand":
  2383.  
  2384.  
  2385.  
  2386. refs[refs.size] = "right_arm";
  2387.  
  2388.  
  2389. break;
  2390.  
  2391. case "left_arm_upper":
  2392. case "left_arm_lower":
  2393. case "left_hand":
  2394.  
  2395.  
  2396.  
  2397. refs[refs.size] = "left_arm";
  2398.  
  2399.  
  2400. break;
  2401.  
  2402. case "right_leg_upper":
  2403. case "right_leg_lower":
  2404. case "right_foot":
  2405. if( self.health <= 0 )
  2406. {
  2407.  
  2408. refs[refs.size] = "right_leg";
  2409. refs[refs.size] = "right_leg";
  2410. refs[refs.size] = "right_leg";
  2411. refs[refs.size] = "no_legs";
  2412. }
  2413. break;
  2414.  
  2415. case "left_leg_upper":
  2416. case "left_leg_lower":
  2417. case "left_foot":
  2418. if( self.health <= 0 )
  2419. {
  2420.  
  2421. refs[refs.size] = "left_leg";
  2422. refs[refs.size] = "left_leg";
  2423. refs[refs.size] = "left_leg";
  2424. refs[refs.size] = "no_legs";
  2425. }
  2426. break;
  2427. default:
  2428.  
  2429. if( self.damageLocation == "none" )
  2430. {
  2431.  
  2432. if( type == "MOD_GRENADE" || type == "MOD_GRENADE_SPLASH" || type == "MOD_PROJECTILE" || type == "MOD_PROJECTILE_SPLASH" )
  2433. {
  2434.  
  2435. refs = self derive_damage_refs( point );
  2436. break;
  2437. }
  2438. }
  2439. else
  2440. {
  2441. refs[refs.size] = "guts";
  2442. refs[refs.size] = "right_arm";
  2443. refs[refs.size] = "left_arm";
  2444. refs[refs.size] = "right_leg";
  2445. refs[refs.size] = "left_leg";
  2446. refs[refs.size] = "no_legs";
  2447. break;
  2448. }
  2449. }
  2450. if( refs.size )
  2451. {
  2452. self.a.gib_ref = animscripts\zombie_death::get_random( refs );
  2453.  
  2454.  
  2455. if( ( self.a.gib_ref == "no_legs" || self.a.gib_ref == "right_leg" || self.a.gib_ref == "left_leg" ) && self.health > 0 )
  2456. {
  2457. self.has_legs = false;
  2458. self AllowedStances( "crouch" );
  2459.  
  2460.  
  2461. self setPhysParams( 15, 0, 24 );
  2462.  
  2463. health = self.health;
  2464. health = health * 0.1;
  2465.  
  2466. which_anim = RandomInt( 5 );
  2467. if(self.a.gib_ref == "no_legs")
  2468. {
  2469.  
  2470. if(randomint(100) < 50)
  2471. {
  2472. self.deathanim = %ai_zombie_crawl_death_v1;
  2473. self set_run_anim( "death3" );
  2474. self.run_combatanim = level.scr_anim[self.animname]["crawl_hand_1"];
  2475. self.crouchRunAnim = level.scr_anim[self.animname]["crawl_hand_1"];
  2476. self.crouchrun_combatanim = level.scr_anim[self.animname]["crawl_hand_1"];
  2477. }
  2478. else
  2479. {
  2480. self.deathanim = %ai_zombie_crawl_death_v1;
  2481. self set_run_anim( "death3" );
  2482. self.run_combatanim = level.scr_anim[self.animname]["crawl_hand_2"];
  2483. self.crouchRunAnim = level.scr_anim[self.animname]["crawl_hand_2"];
  2484. self.crouchrun_combatanim = level.scr_anim[self.animname]["crawl_hand_2"];
  2485. }
  2486. }
  2487. else if( which_anim == 0 )
  2488. {
  2489. self.deathanim = %ai_zombie_crawl_death_v1;
  2490. self set_run_anim( "death3" );
  2491. self.run_combatanim = level.scr_anim[self.animname]["crawl1"];
  2492. self.crouchRunAnim = level.scr_anim[self.animname]["crawl1"];
  2493. self.crouchrun_combatanim = level.scr_anim[self.animname]["crawl1"];
  2494. }
  2495. else if( which_anim == 1 )
  2496. {
  2497. self.deathanim = %ai_zombie_crawl_death_v2;
  2498. self set_run_anim( "death4" );
  2499. self.run_combatanim = level.scr_anim[self.animname]["crawl2"];
  2500. self.crouchRunAnim = level.scr_anim[self.animname]["crawl2"];
  2501. self.crouchrun_combatanim = level.scr_anim[self.animname]["crawl2"];
  2502. }
  2503. else if( which_anim == 2 )
  2504. {
  2505. self.deathanim = %ai_zombie_crawl_death_v1;
  2506. self set_run_anim( "death3" );
  2507. self.run_combatanim = level.scr_anim[self.animname]["crawl3"];
  2508. self.crouchRunAnim = level.scr_anim[self.animname]["crawl3"];
  2509. self.crouchrun_combatanim = level.scr_anim[self.animname]["crawl3"];
  2510. }
  2511. else if( which_anim == 3 )
  2512. {
  2513. self.deathanim = %ai_zombie_crawl_death_v2;
  2514. self set_run_anim( "death4" );
  2515. self.run_combatanim = level.scr_anim[self.animname]["crawl4"];
  2516. self.crouchRunAnim = level.scr_anim[self.animname]["crawl4"];
  2517. self.crouchrun_combatanim = level.scr_anim[self.animname]["crawl4"];
  2518. }
  2519. else if( which_anim == 4 )
  2520. {
  2521. self.deathanim = %ai_zombie_crawl_death_v1;
  2522. self set_run_anim( "death3" );
  2523. self.run_combatanim = level.scr_anim[self.animname]["crawl5"];
  2524. self.crouchRunAnim = level.scr_anim[self.animname]["crawl5"];
  2525. self.crouchrun_combatanim = level.scr_anim[self.animname]["crawl5"];
  2526. }
  2527.  
  2528. }
  2529. }
  2530. if( self.health > 0 )
  2531. {
  2532.  
  2533. self thread animscripts\zombie_death::do_gib();
  2534.  
  2535. if ( IsPlayer( self ) )
  2536. {
  2537. attacker.stats["zombie_gibs"]++;
  2538. }
  2539. }
  2540. }
  2541. }
  2542. }
  2543. zombie_should_gib( amount, attacker, type )
  2544. {
  2545. if ( !is_mature() )
  2546. {
  2547. return false;
  2548. }
  2549.  
  2550. if ( is_german_build() )
  2551. {
  2552. return false;
  2553. }
  2554. if( !IsDefined( type ) )
  2555. {
  2556. return false;
  2557. }
  2558. if ( IsDefined( self.no_gib ) && ( self.no_gib == 1 ) )
  2559. {
  2560. return false;
  2561. }
  2562. if ( self maps\_zombiemode_weap_freezegun::is_freezegun_damage( type ) )
  2563. {
  2564. return false;
  2565. }
  2566. switch( type )
  2567. {
  2568. case "MOD_UNKNOWN":
  2569. case "MOD_CRUSH":
  2570. case "MOD_TELEFRAG":
  2571. case "MOD_FALLING":
  2572. case "MOD_SUICIDE":
  2573. case "MOD_TRIGGER_HURT":
  2574. case "MOD_BURNED":
  2575. return false;
  2576. case "MOD_MELEE":
  2577. {
  2578. return false;
  2579. }
  2580. }
  2581. if( type == "MOD_PISTOL_BULLET" || type == "MOD_RIFLE_BULLET" )
  2582. {
  2583. if( !IsDefined( attacker ) || !IsPlayer( attacker ) )
  2584. {
  2585. return false;
  2586. }
  2587. weapon = attacker GetCurrentWeapon();
  2588. if( weapon == "none" || weapon == "m1911_zm" )
  2589. {
  2590. return false;
  2591. }
  2592. if( WeaponIsGasWeapon( self.weapon ) )
  2593. {
  2594. return false;
  2595. }
  2596. }
  2597. prev_health = amount + self.health;
  2598. if( prev_health <= 0 )
  2599. {
  2600. prev_health = 1;
  2601. }
  2602. damage_percent = ( amount / prev_health ) * 100;
  2603. if( damage_percent < 10 )
  2604. {
  2605. return false;
  2606. }
  2607. return true;
  2608. }
  2609. derive_damage_refs( point )
  2610. {
  2611. if( !IsDefined( level.gib_tags ) )
  2612. {
  2613. init_gib_tags();
  2614. }
  2615.  
  2616. closestTag = undefined;
  2617.  
  2618. for( i = 0; i < level.gib_tags.size; i++ )
  2619. {
  2620. if( !IsDefined( closestTag ) )
  2621. {
  2622. closestTag = level.gib_tags[i];
  2623. }
  2624. else
  2625. {
  2626. if( DistanceSquared( point, self GetTagOrigin( level.gib_tags[i] ) ) < DistanceSquared( point, self GetTagOrigin( closestTag ) ) )
  2627. {
  2628. closestTag = level.gib_tags[i];
  2629. }
  2630. }
  2631. }
  2632.  
  2633. refs = [];
  2634.  
  2635.  
  2636. if( closestTag == "J_SpineLower" || closestTag == "J_SpineUpper" || closestTag == "J_Spine4" )
  2637. {
  2638.  
  2639.  
  2640. refs[refs.size] = "guts";
  2641. refs[refs.size] = "right_arm";
  2642. }
  2643. else if( closestTag == "J_Shoulder_LE" || closestTag == "J_Elbow_LE" || closestTag == "J_Wrist_LE" )
  2644. {
  2645. refs[refs.size] = "left_arm";
  2646. }
  2647. else if( closestTag == "J_Shoulder_RI" || closestTag == "J_Elbow_RI" || closestTag == "J_Wrist_RI" )
  2648. {
  2649. refs[refs.size] = "right_arm";
  2650. }
  2651. else if( closestTag == "J_Hip_LE" || closestTag == "J_Knee_LE" || closestTag == "J_Ankle_LE" )
  2652. {
  2653. refs[refs.size] = "left_leg";
  2654. refs[refs.size] = "no_legs";
  2655. }
  2656. else if( closestTag == "J_Hip_RI" || closestTag == "J_Knee_RI" || closestTag == "J_Ankle_RI" )
  2657. {
  2658. refs[refs.size] = "right_leg";
  2659. refs[refs.size] = "no_legs";
  2660. }
  2661.  
  2662. ASSERTEX( array_validate( refs ), "get_closest_damage_refs(): couldn't derive refs from closestTag " + closestTag );
  2663.  
  2664. return refs;
  2665. }
  2666. init_gib_tags()
  2667. {
  2668. tags = [];
  2669.  
  2670.  
  2671.  
  2672.  
  2673. tags[tags.size] = "J_SpineLower";
  2674. tags[tags.size] = "J_SpineUpper";
  2675. tags[tags.size] = "J_Spine4";
  2676.  
  2677.  
  2678. tags[tags.size] = "J_Shoulder_LE";
  2679. tags[tags.size] = "J_Elbow_LE";
  2680. tags[tags.size] = "J_Wrist_LE";
  2681.  
  2682.  
  2683. tags[tags.size] = "J_Shoulder_RI";
  2684. tags[tags.size] = "J_Elbow_RI";
  2685. tags[tags.size] = "J_Wrist_RI";
  2686.  
  2687.  
  2688. tags[tags.size] = "J_Hip_LE";
  2689. tags[tags.size] = "J_Knee_LE";
  2690. tags[tags.size] = "J_Ankle_LE";
  2691.  
  2692.  
  2693. tags[tags.size] = "J_Hip_RI";
  2694. tags[tags.size] = "J_Knee_RI";
  2695. tags[tags.size] = "J_Ankle_RI";
  2696.  
  2697. level.gib_tags = tags;
  2698. }
  2699. zombie_can_drop_powerups( zombie )
  2700. {
  2701. if( level.mutators["mutator_noPowerups"] )
  2702. {
  2703. return false;
  2704. }
  2705. if( is_tactical_grenade( zombie.damageweapon ) || !flag( "zombie_drop_powerups" ) )
  2706. {
  2707. return false;
  2708. }
  2709. if ( isdefined(zombie.no_powerups) && zombie.no_powerups )
  2710. {
  2711. return false;
  2712. }
  2713. if( zombie.animname == "quad_zombie" )
  2714. {
  2715. return false;
  2716. }
  2717.  
  2718. return true;
  2719. }
  2720. zombie_death_points( origin, mod, hit_location, attacker, zombie )
  2721. {
  2722. if( !IsDefined( attacker ) || !IsPlayer( attacker ) )
  2723. {
  2724. return;
  2725. }
  2726. if( zombie_can_drop_powerups( zombie ) )
  2727. {
  2728.  
  2729. if(IsDefined(zombie.in_the_ground) && zombie.in_the_ground == true)
  2730. {
  2731. trace = BulletTrace(zombie.origin + (0, 0, 100), zombie.origin + (0, 0, -100), false, undefined);
  2732. origin = trace["position"];
  2733. level thread maps\_zombiemode_powerups::powerup_drop( origin );
  2734. }
  2735. else
  2736. {
  2737. trace = GroundTrace(zombie.origin + (0, 0, 5), zombie.origin + (0, 0, -300), false, undefined);
  2738. origin = trace["position"];
  2739. level thread maps\_zombiemode_powerups::powerup_drop( origin );
  2740. }
  2741. }
  2742.  
  2743. level thread maps\_zombiemode_audio::player_zombie_kill_vox( hit_location, attacker, mod, zombie );
  2744. event = "death";
  2745. if ( issubstr( zombie.damageweapon, "knife_ballistic_" ) )
  2746. {
  2747. event = "ballistic_knife_death";
  2748. }
  2749.  
  2750. attacker maps\_zombiemode_score::player_add_points( event, mod, hit_location );
  2751. }
  2752. get_number_variants(aliasPrefix)
  2753. {
  2754. for(i=0; i<100; i++)
  2755. {
  2756. if( !SoundExists( aliasPrefix + "_" + i) )
  2757. {
  2758.  
  2759. return i;
  2760. }
  2761. }
  2762. }
  2763. dragons_breath_flame_death_fx()
  2764. {
  2765. if ( self.isdog )
  2766. {
  2767. return;
  2768. }
  2769. if( !IsDefined( level._effect ) || !IsDefined( level._effect["character_fire_death_sm"] ) )
  2770. {
  2771. return;
  2772. }
  2773. PlayFxOnTag( level._effect["character_fire_death_sm"], self, "J_SpineLower" );
  2774. tagArray = [];
  2775. if( !IsDefined( self.a.gib_ref ) || self.a.gib_ref != "left_arm" )
  2776. {
  2777. tagArray[tagArray.size] = "J_Elbow_LE";
  2778. tagArray[tagArray.size] = "J_Wrist_LE";
  2779. }
  2780. if( !IsDefined( self.a.gib_ref ) || self.a.gib_ref != "right_arm" )
  2781. {
  2782. tagArray[tagArray.size] = "J_Elbow_RI";
  2783. tagArray[tagArray.size] = "J_Wrist_RI";
  2784. }
  2785. if( !IsDefined( self.a.gib_ref ) || (self.a.gib_ref != "no_legs" && self.a.gib_ref != "left_leg") )
  2786. {
  2787. tagArray[tagArray.size] = "J_Knee_LE";
  2788. tagArray[tagArray.size] = "J_Ankle_LE";
  2789. }
  2790. if( !IsDefined( self.a.gib_ref ) || (self.a.gib_ref != "no_legs" && self.a.gib_ref != "right_leg") )
  2791. {
  2792. tagArray[tagArray.size] = "J_Knee_RI";
  2793. tagArray[tagArray.size] = "J_Ankle_RI";
  2794. }
  2795. tagArray = array_randomize( tagArray );
  2796. PlayFxOnTag( level._effect["character_fire_death_sm"], self, tagArray[0] );
  2797. }
  2798. zombie_death_animscript()
  2799. {
  2800. self reset_attack_spot();
  2801. if ( self check_zombie_death_animscript_callbacks() )
  2802. {
  2803. return false;
  2804. }
  2805. if( self maps\_zombiemode_weap_tesla::enemy_killed_by_tesla() || self maps\_zombiemode_weap_thundergun::enemy_killed_by_thundergun() )
  2806. {
  2807. return false;
  2808. }
  2809. if ( self maps\_zombiemode_weap_freezegun::should_do_freezegun_death( self.damagemod ) )
  2810. {
  2811. self thread maps\_zombiemode_weap_freezegun::freezegun_death( self.damagelocation, self.origin, self.attacker );
  2812. if ( "MOD_EXPLOSIVE" == self.damagemod )
  2813. {
  2814.  
  2815. return false;
  2816. }
  2817. }
  2818.  
  2819.  
  2820. if( IsDefined( level.zombie_death_animscript_override ) )
  2821. {
  2822. self [ [ level.zombie_death_animscript_override ] ] ();
  2823. }
  2824.  
  2825. if( self.has_legs && IsDefined( self.a.gib_ref ) && self.a.gib_ref == "no_legs" )
  2826. {
  2827. self.deathanim = %ai_gib_bothlegs_gib;
  2828. }
  2829. self.grenadeAmmo = 0;
  2830.  
  2831. if ( IsDefined( self.nuked ) )
  2832. {
  2833. if( zombie_can_drop_powerups( self ) )
  2834. {
  2835.  
  2836. if(IsDefined(self.in_the_ground) && self.in_the_ground == true)
  2837. {
  2838. trace = BulletTrace(self.origin + (0, 0, 100), self.origin + (0, 0, -100), false, undefined);
  2839. origin = trace["position"];
  2840. level thread maps\_zombiemode_powerups::powerup_drop( origin );
  2841. }
  2842. else
  2843. {
  2844. trace = GroundTrace(self.origin + (0, 0, 5), self.origin + (0, 0, -300), false, undefined);
  2845. origin = trace["position"];
  2846. level thread maps\_zombiemode_powerups::powerup_drop( self.origin );
  2847. }
  2848. }
  2849. }
  2850. else
  2851. {
  2852.  
  2853.  
  2854. level zombie_death_points( self.origin, self.damagemod, self.damagelocation, self.attacker, self );
  2855. }
  2856.  
  2857. if( isdefined( self.attacker ) && isai( self.attacker ) )
  2858. {
  2859. self.attacker notify( "killed", self );
  2860. }
  2861.  
  2862. if( "rottweil72_upgraded_zm" == self.damageweapon && "MOD_RIFLE_BULLET" == self.damagemod )
  2863. {
  2864. self thread dragons_breath_flame_death_fx();
  2865. }
  2866. if( self.damagemod == "MOD_BURNED" )
  2867. {
  2868. self thread animscripts\zombie_death::flame_death_fx();
  2869. }
  2870. if( self.damagemod == "MOD_GRENADE" || self.damagemod == "MOD_GRENADE_SPLASH" )
  2871. {
  2872. level notify( "zombie_grenade_death", self.origin );
  2873. }
  2874. return false;
  2875. }
  2876. check_zombie_death_animscript_callbacks()
  2877. {
  2878. if ( !isdefined( level.zombie_death_animscript_callbacks ) )
  2879. {
  2880. return false;
  2881. }
  2882. for ( i = 0; i < level.zombie_death_animscript_callbacks.size; i++ )
  2883. {
  2884. if ( self [[ level.zombie_death_animscript_callbacks[i] ]]() )
  2885. {
  2886. return true;
  2887. }
  2888. }
  2889. return false;
  2890. }
  2891. register_zombie_death_animscript_callback( func )
  2892. {
  2893. if ( !isdefined( level.zombie_death_animscript_callbacks ) )
  2894. {
  2895. level.zombie_death_animscript_callbacks = [];
  2896. }
  2897. level.zombie_death_animscript_callbacks[level.zombie_death_animscript_callbacks.size] = func;
  2898. }
  2899. damage_on_fire( player )
  2900. {
  2901. self endon ("death");
  2902. self endon ("stop_flame_damage");
  2903. wait( 2 );
  2904.  
  2905. while( isdefined( self.is_on_fire) && self.is_on_fire )
  2906. {
  2907. if( level.round_number < 6 )
  2908. {
  2909. dmg = level.zombie_health * RandomFloatRange( 0.2, 0.3 );
  2910. }
  2911. else if( level.round_number < 9 )
  2912. {
  2913. dmg = level.zombie_health * RandomFloatRange( 0.15, 0.25 );
  2914. }
  2915. else if( level.round_number < 11 )
  2916. {
  2917. dmg = level.zombie_health * RandomFloatRange( 0.1, 0.2 );
  2918. }
  2919. else
  2920. {
  2921. dmg = level.zombie_health * RandomFloatRange( 0.1, 0.15 );
  2922. }
  2923. if ( Isdefined( player ) && Isalive( player ) )
  2924. {
  2925. self DoDamage( dmg, self.origin, player );
  2926. }
  2927. else
  2928. {
  2929. self DoDamage( dmg, self.origin, level );
  2930. }
  2931.  
  2932. wait( randomfloatrange( 1.0, 3.0 ) );
  2933. }
  2934. }
  2935. player_using_hi_score_weapon( player )
  2936. {
  2937. weapon = player GetCurrentWeapon();
  2938. if( weapon == "none" || WeaponIsSemiAuto( weapon ) )
  2939. {
  2940. return( 1 );
  2941. }
  2942. return( 0 );
  2943. }
  2944. zombie_damage( mod, hit_location, hit_origin, player, amount )
  2945. {
  2946. if( is_magic_bullet_shield_enabled( self ) )
  2947. {
  2948. return;
  2949. }
  2950.  
  2951. player.use_weapon_type = mod;
  2952. if(isDefined(self.marked_for_death))
  2953. {
  2954. return;
  2955. }
  2956. if( !IsDefined( player ) )
  2957. {
  2958. return;
  2959. }
  2960. if ( self check_zombie_damage_callbacks( mod, hit_location, hit_origin, player, amount ) )
  2961. {
  2962. return;
  2963. }
  2964. else if( self zombie_flame_damage( mod, player ) )
  2965. {
  2966. if( self zombie_give_flame_damage_points() )
  2967. {
  2968. player maps\_zombiemode_score::player_add_points( "damage", mod, hit_location, self.isdog );
  2969. }
  2970. }
  2971. else if( self maps\_zombiemode_weap_tesla::is_tesla_damage( mod ) )
  2972. {
  2973. self maps\_zombiemode_weap_tesla::tesla_damage_init( hit_location, hit_origin, player );
  2974. return;
  2975. }
  2976. else
  2977. {
  2978. if ( self maps\_zombiemode_weap_freezegun::is_freezegun_damage( self.damagemod ) )
  2979. {
  2980. self thread maps\_zombiemode_weap_freezegun::freezegun_damage_response( player, amount );
  2981. }
  2982.  
  2983. if ( !self maps\_zombiemode_weap_freezegun::is_freezegun_shatter_damage( self.damagemod ) )
  2984. {
  2985. if( player_using_hi_score_weapon( player ) )
  2986. {
  2987. damage_type = "damage";
  2988. }
  2989. else
  2990. {
  2991. damage_type = "damage_light";
  2992. }
  2993. if ( !is_true( self.no_damage_points ) )
  2994. {
  2995. player maps\_zombiemode_score::player_add_points( damage_type, mod, hit_location, self.isdog );
  2996. }
  2997. }
  2998. }
  2999. if ( IsDefined( self.zombie_damage_fx_func ) )
  3000. {
  3001. self [[ self.zombie_damage_fx_func ]]( mod, hit_location, hit_origin, player );
  3002. }
  3003. modName = remove_mod_from_methodofdeath( mod );
  3004. if ( self maps\_zombiemode_weap_freezegun::is_freezegun_damage( self.damagemod ) )
  3005. {
  3006. ;
  3007. }
  3008. else if( is_placeable_mine( self.damageweapon ) )
  3009. {
  3010. if ( IsDefined( self.zombie_damage_claymore_func ) )
  3011. {
  3012. self [[ self.zombie_damage_claymore_func ]]( mod, hit_location, hit_origin, player );
  3013. }
  3014. else if ( isdefined( player ) && isalive( player ) )
  3015. {
  3016. self DoDamage( level.round_number * randomintrange( 100, 200 ), self.origin, player);
  3017. }
  3018. else
  3019. {
  3020. self DoDamage( level.round_number * randomintrange( 100, 200 ), self.origin, undefined );
  3021. }
  3022. }
  3023. else if ( mod == "MOD_GRENADE" || mod == "MOD_GRENADE_SPLASH" )
  3024. {
  3025. if ( isdefined( player ) && isalive( player ) )
  3026. {
  3027. self DoDamage( level.round_number + randomintrange( 100, 200 ), self.origin, player, 0, modName, hit_location);
  3028. }
  3029. else
  3030. {
  3031. self DoDamage( level.round_number + randomintrange( 100, 200 ), self.origin, undefined, 0, modName, hit_location );
  3032. }
  3033. }
  3034. else if( mod == "MOD_PROJECTILE" || mod == "MOD_EXPLOSIVE" || mod == "MOD_PROJECTILE_SPLASH" )
  3035. {
  3036. if ( isdefined( player ) && isalive( player ) )
  3037. {
  3038. self DoDamage( level.round_number * randomintrange( 0, 100 ), self.origin, player, 0, modName, hit_location);
  3039. }
  3040. else
  3041. {
  3042. self DoDamage( level.round_number * randomintrange( 0, 100 ), self.origin, undefined, 0, modName, hit_location );
  3043. }
  3044. }
  3045.  
  3046.  
  3047. if( IsDefined( self.a.gib_ref ) && (self.a.gib_ref == "no_legs") && isalive( self ) )
  3048. {
  3049. if ( isdefined( player ) )
  3050. {
  3051. rand = randomintrange(0, 100);
  3052. if(rand < 10)
  3053. {
  3054. player create_and_play_dialog( "general", "crawl_spawn" );
  3055. }
  3056. }
  3057. }
  3058. else if( IsDefined( self.a.gib_ref ) && ( (self.a.gib_ref == "right_arm") || (self.a.gib_ref == "left_arm") ) )
  3059. {
  3060. if( self.has_legs && isalive( self ) )
  3061. {
  3062. if ( isdefined( player ) )
  3063. {
  3064. rand = randomintrange(0, 100);
  3065. if(rand < 7)
  3066. {
  3067. player create_and_play_dialog( "general", "shoot_arm" );
  3068. }
  3069. }
  3070. }
  3071. }
  3072. if(player HasPerk("specialty_deadshot") && (hit_location == "head" || hit_location == "neck" || hit_location == "helmet"))
  3073. {
  3074. self doDamage( amount, hit_origin, player );
  3075. //self.health -= amount;
  3076. //iprintln(hit_location);
  3077. }
  3078. if(player.half_damage == true)
  3079. {
  3080. amount = int(amount / 2);
  3081. self.health += amount;
  3082. //iprintln(self.health);
  3083. }
  3084. //iprintln("MOD: ", mod);
  3085. //iprintln("LOCATION: ", hit_location);
  3086. //iprintln("ORIGIN: ", hit_origin);
  3087. }
  3088. zombie_damage_ads( mod, hit_location, hit_origin, player, amount )
  3089. {
  3090. if( is_magic_bullet_shield_enabled( self ) )
  3091. {
  3092. return;
  3093. }
  3094. player.use_weapon_type = mod;
  3095. if( !IsDefined( player ) )
  3096. {
  3097. return;
  3098. }
  3099. if ( self check_zombie_damage_callbacks( mod, hit_location, hit_origin, player, amount ) )
  3100. {
  3101. return;
  3102. }
  3103. else if( self zombie_flame_damage( mod, player ) )
  3104. {
  3105. if( self zombie_give_flame_damage_points() )
  3106. {
  3107. player maps\_zombiemode_score::player_add_points( "damage_ads", mod, hit_location );
  3108. }
  3109. }
  3110. else if( self maps\_zombiemode_weap_tesla::is_tesla_damage( mod ) )
  3111. {
  3112. self maps\_zombiemode_weap_tesla::tesla_damage_init( hit_location, hit_origin, player );
  3113. return;
  3114. }
  3115. else
  3116. {
  3117. if ( self maps\_zombiemode_weap_freezegun::is_freezegun_damage( self.damagemod ) )
  3118. {
  3119. self thread maps\_zombiemode_weap_freezegun::freezegun_damage_response( player, amount );
  3120. }
  3121.  
  3122. if ( !self maps\_zombiemode_weap_freezegun::is_freezegun_shatter_damage( self.damagemod ) )
  3123. {
  3124. if( player_using_hi_score_weapon( player ) )
  3125. {
  3126. damage_type = "damage";
  3127. }
  3128. else
  3129. {
  3130. damage_type = "damage_light";
  3131. }
  3132. if ( !is_true( self.no_damage_points ) )
  3133. {
  3134. player maps\_zombiemode_score::player_add_points( damage_type, mod, hit_location );
  3135. }
  3136. }
  3137. }
  3138. if(player HasPerk("specialty_deadshot") && (hit_location == "head" || hit_location == "neck" || hit_location == "helmet"))
  3139. {
  3140. self doDamage( amount, hit_origin, player );
  3141. //self.health -= amount;
  3142. //iprintln(hit_location);
  3143. }
  3144. if(player.half_damage == true)
  3145. {
  3146. amount = int(amount / 2);
  3147. self.health += amount;
  3148. //iprintln(self.health);
  3149. }
  3150. }
  3151. check_zombie_damage_callbacks( mod, hit_location, hit_origin, player, amount )
  3152. {
  3153. if ( !isdefined( level.zombie_damage_callbacks ) )
  3154. {
  3155. return false;
  3156. }
  3157. for ( i = 0; i < level.zombie_damage_callbacks.size; i++ )
  3158. {
  3159. if ( self [[ level.zombie_damage_callbacks[i] ]]( mod, hit_location, hit_origin, player, amount ) )
  3160. {
  3161. return true;
  3162. }
  3163. }
  3164. return false;
  3165. }
  3166. register_zombie_damage_callback( func )
  3167. {
  3168. if ( !isdefined( level.zombie_damage_callbacks ) )
  3169. {
  3170. level.zombie_damage_callbacks = [];
  3171. }
  3172. level.zombie_damage_callbacks[level.zombie_damage_callbacks.size] = func;
  3173. }
  3174. zombie_give_flame_damage_points()
  3175. {
  3176. if( GetTime() > self.flame_damage_time )
  3177. {
  3178. self.flame_damage_time = GetTime() + level.zombie_vars["zombie_flame_dmg_point_delay"];
  3179. return true;
  3180. }
  3181. return false;
  3182. }
  3183. zombie_flame_damage( mod, player )
  3184. {
  3185. if( mod == "MOD_BURNED" )
  3186. {
  3187. self.moveplaybackrate = 0.8;
  3188.  
  3189. if( !IsDefined( self.is_on_fire ) || ( Isdefined( self.is_on_fire ) && !self.is_on_fire ) )
  3190. {
  3191. self thread damage_on_fire( player );
  3192. }
  3193. do_flame_death = true;
  3194. dist = 100 * 100;
  3195. ai = GetAiArray( "axis" );
  3196. for( i = 0; i < ai.size; i++ )
  3197. {
  3198. if( IsDefined( ai[i].is_on_fire ) && ai[i].is_on_fire )
  3199. {
  3200. if( DistanceSquared( ai[i].origin, self.origin ) < dist )
  3201. {
  3202. do_flame_death = false;
  3203. break;
  3204. }
  3205. }
  3206. }
  3207. if( do_flame_death )
  3208. {
  3209. self thread animscripts\zombie_death::flame_death_fx();
  3210. }
  3211. return true;
  3212. }
  3213. return false;
  3214. }
  3215. zombie_death_event( zombie )
  3216. {
  3217. zombie waittill( "death" );
  3218.  
  3219. if ( !IsDefined( zombie ) )
  3220. {
  3221. return;
  3222. }
  3223.  
  3224.  
  3225. level.global_zombies_killed++;
  3226.  
  3227. if(isDefined(zombie.marked_for_death) && !isDefined(zombie.nuked))
  3228. {
  3229. level.zombie_trap_killed_count++;
  3230. }
  3231.  
  3232. zombie check_zombie_death_event_callbacks();
  3233.  
  3234. if ( !zombie maps\_zombiemode_weap_freezegun::should_do_freezegun_death( zombie.damagemod ) )
  3235. {
  3236. zombie thread maps\_zombiemode_audio::do_zombies_playvocals( "death", zombie.animname );
  3237. zombie thread zombie_eye_glow_stop();
  3238. }
  3239. if ( maps\_zombiemode_weapons::is_weapon_included( "freezegun_zm" ) )
  3240. {
  3241. zombie thread maps\_zombiemode_weap_freezegun::freezegun_clear_extremity_damage_fx();
  3242. zombie thread maps\_zombiemode_weap_freezegun::freezegun_clear_torso_damage_fx();
  3243. }
  3244.  
  3245. if(isdefined (zombie.attacker) && isplayer(zombie.attacker) )
  3246. {
  3247.  
  3248.  
  3249. level.zombie_player_killed_count++;
  3250.  
  3251. if(!isdefined ( zombie.attacker.killcounter))
  3252. {
  3253. zombie.attacker.killcounter = 1;
  3254. }
  3255. else
  3256. {
  3257. zombie.attacker.killcounter ++;
  3258. }
  3259.  
  3260. if ( IsDefined( zombie.sound_damage_player ) && zombie.sound_damage_player == zombie.attacker )
  3261. {
  3262. zombie.attacker maps\_zombiemode_audio::create_and_play_dialog( "kill", "damage" );
  3263. }
  3264. zombie.attacker notify( "zom_kill", zombie );
  3265. damageloc = zombie.damagelocation;
  3266. damagemod = zombie.damagemod;
  3267. attacker = zombie.attacker;
  3268. weapon = zombie.damageWeapon;
  3269. 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",
  3270. level.round_number, damagemod, damageloc, attacker.playername, weapon, attacker.origin, zombie.origin );
  3271. }
  3272. else
  3273. {
  3274. if(zombie.ignoreall && !is_true(zombie.marked_for_death) )
  3275. {
  3276. level.zombies_timeout_spawn++;
  3277. }
  3278. }
  3279.  
  3280. level notify( "zom_kill" );
  3281. level.total_zombies_killed++;
  3282. }
  3283. check_zombie_death_event_callbacks()
  3284. {
  3285. if ( !isdefined( level.zombie_death_event_callbacks ) )
  3286. {
  3287. return;
  3288. }
  3289. for ( i = 0; i < level.zombie_death_event_callbacks.size; i++ )
  3290. {
  3291. self [[ level.zombie_death_event_callbacks[i] ]]();
  3292. }
  3293. }
  3294. register_zombie_death_event_callback( func )
  3295. {
  3296. if ( !isdefined( level.zombie_death_event_callbacks ) )
  3297. {
  3298. level.zombie_death_event_callbacks = [];
  3299. }
  3300. level.zombie_death_event_callbacks[level.zombie_death_event_callbacks.size] = func;
  3301. }
  3302. zombie_setup_attack_properties()
  3303. {
  3304. self zombie_history( "zombie_setup_attack_properties()" );
  3305.  
  3306. self.ignoreall = false;
  3307.  
  3308.  
  3309. self.pathEnemyFightDist = 64;
  3310. self.meleeAttackDist = 64;
  3311.  
  3312.  
  3313. self.maxsightdistsqrd = 128 * 128;
  3314.  
  3315. self.disableArrivals = true;
  3316. self.disableExits = true;
  3317. }
  3318. find_flesh()
  3319. {
  3320. self endon( "death" );
  3321. level endon( "intermission" );
  3322. self endon( "stop_find_flesh" );
  3323. if( level.intermission )
  3324. {
  3325. return;
  3326. }
  3327.  
  3328. self.helitarget = true;
  3329. self.ignoreme = false;
  3330. self.noDodgeMove = true;
  3331.  
  3332.  
  3333. self.ignore_player = [];
  3334. self zombie_history( "find flesh -> start" );
  3335. self.goalradius = 32;
  3336. while( 1 )
  3337. {
  3338.  
  3339.  
  3340.  
  3341. near_zombies = getaiarray("axis");
  3342. same_enemy_count = 0;
  3343. for (i = 0; i < near_zombies.size; i++)
  3344. {
  3345. if ( isdefined( near_zombies[i] ) && isalive( near_zombies[i] ) )
  3346. {
  3347. if ( isdefined( near_zombies[i].favoriteenemy ) && isdefined( self.favoriteenemy )
  3348. && near_zombies[i].favoriteenemy == self.favoriteenemy )
  3349. {
  3350. if ( distancesquared( near_zombies[i].origin, self.favoriteenemy.origin ) < 225 * 225
  3351. && distancesquared( near_zombies[i].origin, self.origin ) > 525 * 525)
  3352. {
  3353. same_enemy_count++;
  3354. }
  3355. }
  3356. }
  3357. }
  3358.  
  3359. if (same_enemy_count > 12)
  3360. {
  3361. self.ignore_player[self.ignore_player.size] = self.favoriteenemy;
  3362. }
  3363.  
  3364.  
  3365.  
  3366. if (isDefined(level.zombieTheaterTeleporterSeekLogicFunc) )
  3367. {
  3368. self [[ level.zombieTheaterTeleporterSeekLogicFunc ]]();
  3369. }
  3370.  
  3371. zombie_poi = self get_zombie_point_of_interest( self.origin );
  3372.  
  3373. players = get_players();
  3374.  
  3375.  
  3376. if( players.size == 1 )
  3377. {
  3378. self.ignore_player = [];
  3379. }
  3380.  
  3381. else
  3382. {
  3383. for(i = 0; i < self.ignore_player.size; i++)
  3384. {
  3385. if( IsDefined( self.ignore_player[i] ) && IsDefined( self.ignore_player[i].ignore_counter ) && self.ignore_player[i].ignore_counter > 3 )
  3386. {
  3387. self.ignore_player[i].ignore_counter = 0;
  3388. self.ignore_player = array_remove( self.ignore_player, self.ignore_player[i] );
  3389. }
  3390. }
  3391. }
  3392.  
  3393. player = get_closest_valid_player( self.origin, self.ignore_player );
  3394. if( !isDefined( player ) && !isDefined( zombie_poi ) )
  3395. {
  3396. self zombie_history( "find flesh -> can't find player, continue" );
  3397. if( IsDefined( self.ignore_player ) )
  3398. {
  3399. self.ignore_player = [];
  3400. }
  3401. wait( 1 );
  3402. continue;
  3403. }
  3404.  
  3405.  
  3406.  
  3407. //if ( !isDefined( level.check_for_alternate_poi ) || ![[level.check_for_alternate_poi]]() )
  3408. {
  3409. self.enemyoverride = zombie_poi;
  3410. self.favoriteenemy = player;
  3411. }
  3412.  
  3413. self thread zombie_pathing();
  3414.  
  3415.  
  3416. if( players.size > 1 )
  3417. {
  3418. for(i = 0; i < self.ignore_player.size; i++)
  3419. {
  3420. if( IsDefined( self.ignore_player[i] ) )
  3421. {
  3422. if( !IsDefined( self.ignore_player[i].ignore_counter ) )
  3423. self.ignore_player[i].ignore_counter = 0;
  3424. else
  3425. self.ignore_player[i].ignore_counter += 1;
  3426. }
  3427. }
  3428. }
  3429.  
  3430. self thread attractors_generated_listener();
  3431. self.zombie_path_timer = GetTime() + ( RandomFloatRange( 1, 3 ) * 1000 );
  3432. while( GetTime() < self.zombie_path_timer )
  3433. {
  3434. wait( 0.1 );
  3435. }
  3436. self notify( "path_timer_done" );
  3437. self zombie_history( "find flesh -> bottom of loop" );
  3438. debug_print( "Zombie is re-acquiring enemy, ending breadcrumb search" );
  3439. self notify( "zombie_acquire_enemy" );
  3440. }
  3441. }
  3442. attractors_generated_listener()
  3443. {
  3444. self endon( "death" );
  3445. level endon( "intermission" );
  3446. self endon( "stop_find_flesh" );
  3447. self endon( "path_timer_done" );
  3448. level waittill( "attractor_positions_generated" );
  3449. self.zombie_path_timer = 0;
  3450. }
  3451. zombie_pathing()
  3452. {
  3453. self endon( "death" );
  3454. self endon( "zombie_acquire_enemy" );
  3455. level endon( "intermission" );
  3456.  
  3457. assert( IsDefined( self.favoriteenemy ) || IsDefined( self.enemyoverride ) );
  3458. self thread zombie_follow_enemy();
  3459. self waittill( "bad_path" );
  3460.  
  3461. level.zombie_pathing_failed ++;
  3462.  
  3463.  
  3464.  
  3465.  
  3466. if( isDefined( self.enemyoverride ) )
  3467. {
  3468. debug_print( "Zombie couldn't path to point of interest at origin: " + self.enemyoverride[0] + " Falling back to breadcrumb system" );
  3469. if( isDefined( self.enemyoverride[1] ) )
  3470. {
  3471. self.enemyoverride = self.enemyoverride[1] invalidate_attractor_pos( self.enemyoverride, self );
  3472. self.zombie_path_timer = 0;
  3473. return;
  3474. }
  3475. }
  3476. else
  3477. {
  3478. debug_print( "Zombie couldn't path to player at origin: " + self.favoriteenemy.origin + " Falling back to breadcrumb system" );
  3479. }
  3480.  
  3481. if( !isDefined( self.favoriteenemy ) )
  3482. {
  3483. self.zombie_path_timer = 0;
  3484. return;
  3485. }
  3486. else
  3487. {
  3488. self.favoriteenemy endon( "disconnect" );
  3489. }
  3490.  
  3491.  
  3492. players = get_players();
  3493. valid_player_num = 0;
  3494. for( i = 0; i < players.size; i++ )
  3495. {
  3496. if( is_player_valid( players[i], true ) )
  3497. {
  3498. valid_player_num += 1;
  3499. }
  3500. }
  3501.  
  3502. if( players.size > 1 )
  3503. {
  3504. if( array_check_for_dupes( self.ignore_player, self.favoriteenemy) )
  3505. {
  3506. self.ignore_player[self.ignore_player.size] = self.favoriteenemy;
  3507. }
  3508. if( self.ignore_player.size < valid_player_num )
  3509. {
  3510. self.zombie_path_timer = 0;
  3511. return;
  3512. }
  3513. }
  3514.  
  3515. crumb_list = self.favoriteenemy.zombie_breadcrumbs;
  3516. bad_crumbs = [];
  3517.  
  3518. while( 1 )
  3519. {
  3520. if( !is_player_valid( self.favoriteenemy, true ) )
  3521. {
  3522. self.zombie_path_timer = 0;
  3523. return;
  3524. }
  3525. goal = zombie_pathing_get_breadcrumb( self.favoriteenemy.origin, crumb_list, bad_crumbs, ( RandomInt( 100 ) < 20 ) );
  3526.  
  3527. if ( !IsDefined( goal ) )
  3528. {
  3529. debug_print( "Zombie exhausted breadcrumb search" );
  3530.  
  3531.  
  3532. level.zombie_breadcrumb_failed ++;
  3533.  
  3534. goal = self.favoriteenemy.spectator_respawn.origin;
  3535. }
  3536. debug_print( "Setting current breadcrumb to " + goal );
  3537. self.zombie_path_timer += 100;
  3538. self SetGoalPos( goal );
  3539. self waittill( "bad_path" );
  3540. debug_print( "Zombie couldn't path to breadcrumb at " + goal + " Finding next breadcrumb" );
  3541. for( i = 0; i < crumb_list.size; i++ )
  3542. {
  3543. if( goal == crumb_list[i] )
  3544. {
  3545. bad_crumbs[bad_crumbs.size] = i;
  3546. break;
  3547. }
  3548. }
  3549. }
  3550.  
  3551. }
  3552. zombie_pathing_get_breadcrumb( origin, breadcrumbs, bad_crumbs, pick_random )
  3553. {
  3554. assert( IsDefined( origin ) );
  3555. assert( IsDefined( breadcrumbs ) );
  3556. assert( IsArray( breadcrumbs ) );
  3557.  
  3558.  
  3559. for( i = 0; i < breadcrumbs.size; i++ )
  3560. {
  3561. if ( pick_random )
  3562. {
  3563. crumb_index = RandomInt( breadcrumbs.size );
  3564. }
  3565. else
  3566. {
  3567. crumb_index = i;
  3568. }
  3569.  
  3570. if( crumb_is_bad( crumb_index, bad_crumbs ) )
  3571. {
  3572. continue;
  3573. }
  3574. return breadcrumbs[crumb_index];
  3575. }
  3576. return undefined;
  3577. }
  3578. crumb_is_bad( crumb, bad_crumbs )
  3579. {
  3580. for ( i = 0; i < bad_crumbs.size; i++ )
  3581. {
  3582. if ( bad_crumbs[i] == crumb )
  3583. {
  3584. return true;
  3585. }
  3586. }
  3587. return false;
  3588. }
  3589. jitter_enemies_bad_breadcrumbs( start_crumb )
  3590. {
  3591. trace_distance = 35;
  3592. jitter_distance = 2;
  3593.  
  3594. index = start_crumb;
  3595.  
  3596. while (isdefined(self.favoriteenemy.zombie_breadcrumbs[ index + 1 ]))
  3597. {
  3598. current_crumb = self.favoriteenemy.zombie_breadcrumbs[ index ];
  3599. next_crumb = self.favoriteenemy.zombie_breadcrumbs[ index + 1 ];
  3600.  
  3601. angles = vectortoangles(current_crumb - next_crumb);
  3602.  
  3603. right = anglestoright(angles);
  3604. left = anglestoright(angles + (0,180,0));
  3605.  
  3606. dist_pos = current_crumb + vector_scale( right, trace_distance );
  3607.  
  3608. trace = bulletTrace( current_crumb, dist_pos, true, undefined );
  3609. vector = trace["position"];
  3610.  
  3611. if (distance(vector, current_crumb) < 17 )
  3612. {
  3613. self.favoriteenemy.zombie_breadcrumbs[ index ] = current_crumb + vector_scale( left, jitter_distance );
  3614. continue;
  3615. }
  3616.  
  3617.  
  3618.  
  3619. dist_pos = current_crumb + vector_scale( left, trace_distance );
  3620.  
  3621. trace = bulletTrace( current_crumb, dist_pos, true, undefined );
  3622. vector = trace["position"];
  3623.  
  3624. if (distance(vector, current_crumb) < 17 )
  3625. {
  3626. self.favoriteenemy.zombie_breadcrumbs[ index ] = current_crumb + vector_scale( right, jitter_distance );
  3627. continue;
  3628. }
  3629.  
  3630. index++;
  3631. }
  3632.  
  3633. }
  3634. zombie_follow_enemy()
  3635. {
  3636. self endon( "death" );
  3637. self endon( "zombie_acquire_enemy" );
  3638. self endon( "bad_path" );
  3639.  
  3640. level endon( "intermission" );
  3641. while( 1 )
  3642. {
  3643. if( isDefined( self.enemyoverride ) && isDefined( self.enemyoverride[1] ) )
  3644. {
  3645. if( distanceSquared( self.origin, self.enemyoverride[0] ) > 1*1 )
  3646. {
  3647. self OrientMode( "face motion" );
  3648. }
  3649. else
  3650. {
  3651. self OrientMode( "face point", self.enemyoverride[1].origin );
  3652. }
  3653. self.ignoreall = true;
  3654. self SetGoalPos( self.enemyoverride[0] );
  3655. }
  3656. else if( IsDefined( self.favoriteenemy ) )
  3657. {
  3658. self.ignoreall = false;
  3659. self OrientMode( "face default" );
  3660. self SetGoalPos( self.favoriteenemy.origin );
  3661. distSq = distanceSquared( self.origin, self.favoriteenemy.origin );
  3662.  
  3663. extra_wait_time = 0;
  3664. if( distSq > 3200 * 3200 )
  3665. {
  3666. extra_wait_time = 2.0 + randomFloat( 1.0 );
  3667. }
  3668. else if( distSq > 2200 * 2200 )
  3669. {
  3670. extra_wait_time = 1.0 + randomFloat( 0.5 );
  3671. }
  3672. else if( distSq > 1200 * 1200 )
  3673. {
  3674. extra_wait_time = 0.5 + randomFloat( 0.5 );
  3675. }
  3676. if( extra_wait_time > 0 )
  3677. {
  3678. wait extra_wait_time;
  3679. }
  3680. }
  3681.  
  3682.  
  3683. if( isDefined( level.inaccesible_player_func ) )
  3684. {
  3685. self [[ level.inaccessible_player_func ]]();
  3686. }
  3687.  
  3688. wait( 0.1 );
  3689. }
  3690. }
  3691. zombie_eye_glow()
  3692. {
  3693. if(!IsDefined(self))
  3694. {
  3695. return;
  3696. }
  3697. if ( !isdefined( self.no_eye_glow ) || !self.no_eye_glow )
  3698. {
  3699. self haseyes(1);
  3700. }
  3701. }
  3702. zombie_eye_glow_stop()
  3703. {
  3704. if(!IsDefined(self))
  3705. {
  3706. return;
  3707. }
  3708. if ( !isdefined( self.no_eye_glow ) || !self.no_eye_glow )
  3709. {
  3710. self haseyes(0);
  3711. }
  3712. }
  3713. zombie_history( msg )
  3714. {
  3715. }
  3716. do_zombie_rise()
  3717. {
  3718. self endon("death");
  3719. self.zombie_rise_version = (RandomInt(99999) % 2) + 1;
  3720. if (self.zombie_move_speed != "walk")
  3721. {
  3722.  
  3723. self.zombie_rise_version = 1;
  3724. }
  3725. self.in_the_ground = true;
  3726.  
  3727. self.anchor = spawn("script_origin", self.origin);
  3728. self.anchor.angles = self.angles;
  3729. self linkto(self.anchor);
  3730. if ( IsDefined( self.zone_name ) )
  3731. {
  3732. spots = level.zones[ self.zone_name ].rise_locations;
  3733. }
  3734. else if ( IsDefined( self.rise_target_name ) )
  3735. {
  3736. spots = GetStructArray(self.rise_target_name, "targetname");
  3737. }
  3738.  
  3739. else if( IsDefined( level.zombie_rise_spawners ) )
  3740. {
  3741. if ( IsArray( level.zombie_rise_spawners ) )
  3742. {
  3743. spots = level.zombie_rise_spawners[ self.script_index ];
  3744. }
  3745. else
  3746. {
  3747. spots = level.zombie_rise_spawners;
  3748. }
  3749. }
  3750. else
  3751. {
  3752. spots = GetStructArray("zombie_rise", "targetname");
  3753. }
  3754. if( spots.size < 1 )
  3755. {
  3756. self unlink();
  3757. self.anchor delete();
  3758. return;
  3759. }
  3760. else
  3761. spot = random(spots);
  3762.  
  3763. if( !isDefined( spot.angles ) )
  3764. {
  3765. spot.angles = (0, 0, 0);
  3766. }
  3767. anim_org = spot.origin;
  3768. anim_ang = spot.angles;
  3769.  
  3770. if (self.zombie_rise_version == 2)
  3771. {
  3772. anim_org = anim_org + (0, 0, -14);
  3773. }
  3774. else
  3775. {
  3776. anim_org = anim_org + (0, 0, -45);
  3777. }
  3778.  
  3779. self Hide();
  3780. self.anchor moveto(anim_org, .05);
  3781. self.anchor waittill("movedone");
  3782.  
  3783. target_org = maps\_zombiemode_spawner::get_desired_origin();
  3784. if (IsDefined(target_org))
  3785. {
  3786. anim_ang = VectorToAngles(target_org - self.origin);
  3787. self.anchor RotateTo((0, anim_ang[1], 0), .05);
  3788. self.anchor waittill("rotatedone");
  3789. }
  3790. self unlink();
  3791. self.anchor delete();
  3792. self thread hide_pop();
  3793. level thread zombie_rise_death(self, spot);
  3794. spot thread zombie_rise_fx(self);
  3795.  
  3796.  
  3797. self AnimScripted("rise", self.origin, spot.angles, self get_rise_anim());
  3798. self animscripts\zombie_shared::DoNoteTracks("rise", ::handle_rise_notetracks, undefined, spot);
  3799. self notify("rise_anim_finished");
  3800. spot notify("stop_zombie_rise_fx");
  3801. self.in_the_ground = false;
  3802. self notify("risen", spot.script_noteworthy );
  3803. }
  3804. hide_pop()
  3805. {
  3806. self endon( "death" );
  3807. wait( 0.5 );
  3808. if ( IsDefined( self ) )
  3809. {
  3810. self Show();
  3811. }
  3812. }
  3813. handle_rise_notetracks(note, spot)
  3814. {
  3815.  
  3816.  
  3817. if (note == "deathout" || note == "deathhigh")
  3818. {
  3819. self.zombie_rise_death_out = true;
  3820. self notify("zombie_rise_death_out");
  3821. wait 2;
  3822. spot notify("stop_zombie_rise_fx");
  3823. }
  3824. }
  3825. zombie_rise_death(zombie, spot)
  3826. {
  3827.  
  3828. zombie.zombie_rise_death_out = false;
  3829. zombie endon("rise_anim_finished");
  3830. while (zombie.health > 1)
  3831. {
  3832. zombie waittill("damage", amount);
  3833. }
  3834. spot notify("stop_zombie_rise_fx");
  3835. zombie.deathanim = zombie get_rise_death_anim();
  3836. zombie StopAnimScripted();
  3837. }
  3838. zombie_rise_fx(zombie)
  3839. {
  3840.  
  3841. if(!is_true(level.riser_fx_on_client))
  3842. {
  3843. self thread zombie_rise_dust_fx(zombie);
  3844. self thread zombie_rise_burst_fx(zombie);
  3845. }
  3846. else
  3847. {
  3848. self thread zombie_rise_burst_fx(zombie);
  3849. }
  3850. zombie endon("death");
  3851. self endon("stop_zombie_rise_fx");
  3852. wait 1;
  3853. if (zombie.zombie_move_speed != "sprint")
  3854. {
  3855.  
  3856. wait 1;
  3857. }
  3858. }
  3859. zombie_rise_burst_fx(zombie)
  3860. {
  3861. self endon("stop_zombie_rise_fx");
  3862. self endon("rise_anim_finished");
  3863.  
  3864. if(IsDefined(self.script_string) && self.script_string == "in_water")
  3865. {
  3866. if(is_true(level.riser_fx_on_client))
  3867. {
  3868. zombie setclientflag(level._ZOMBIE_ACTOR_ZOMBIE_RISER_FX_WATER);
  3869. }
  3870. else
  3871. {
  3872. playsoundatposition ("zmb_zombie_spawn_water", self.origin);
  3873. playfx(level._effect["rise_burst_water"],self.origin + ( 0,0,randomintrange(5,10) ) );
  3874. wait(.25);
  3875. playfx(level._effect["rise_billow_water"],self.origin + ( randomintrange(-10,10),randomintrange(-10,10),randomintrange(5,10) ) );
  3876. }
  3877. }
  3878. else if(IsDefined(self.script_string) && self.script_string == "in_snow")
  3879. {
  3880.  
  3881. if(is_true(level.riser_fx_on_client))
  3882. {
  3883.  
  3884. zombie setclientflag(level._ZOMBIE_ACTOR_ZOMBIE_RISER_FX);
  3885. }
  3886. else
  3887. {
  3888.  
  3889. playsoundatposition ("zmb_zombie_spawn_snow", self.origin);
  3890. playfx(level._effect["rise_burst_snow"],self.origin + ( 0,0,randomintrange(5,10) ) );
  3891. wait(.25);
  3892. playfx(level._effect["rise_billow_snow"],self.origin + ( randomintrange(-10,10),randomintrange(-10,10),randomintrange(5,10) ) );
  3893. }
  3894. }
  3895. else
  3896. {
  3897. if(is_true(level.riser_fx_on_client))
  3898. {
  3899. zombie setclientflag(level._ZOMBIE_ACTOR_ZOMBIE_RISER_FX);
  3900. }
  3901. else
  3902. {
  3903. playsoundatposition ("zmb_zombie_spawn", self.origin);
  3904. playfx(level._effect["rise_burst"],self.origin + ( 0,0,randomintrange(5,10) ) );
  3905. wait(.25);
  3906. playfx(level._effect["rise_billow"],self.origin + ( randomintrange(-10,10),randomintrange(-10,10),randomintrange(5,10) ) );
  3907. }
  3908. }
  3909. }
  3910. zombie_rise_dust_fx(zombie)
  3911. {
  3912. dust_tag = "J_SpineUpper";
  3913.  
  3914. self endon("stop_zombie_rise_dust_fx");
  3915. self thread stop_zombie_rise_dust_fx(zombie);
  3916. dust_time = 7.5;
  3917. dust_interval = .1;
  3918.  
  3919.  
  3920. if(IsDefined(self.script_string) && self.script_string == "in_water")
  3921. {
  3922. for (t = 0; t < dust_time; t += dust_interval)
  3923. {
  3924. PlayfxOnTag(level._effect["rise_dust_water"], zombie, dust_tag);
  3925. wait dust_interval;
  3926. }
  3927. }
  3928. else if(IsDefined(self.script_string) && self.script_string == "in_snow")
  3929. {
  3930. for (t = 0; t < dust_time; t += dust_interval)
  3931. {
  3932. PlayfxOnTag(level._effect["rise_dust_snow"], zombie, dust_tag);
  3933. wait dust_interval;
  3934. }
  3935. }
  3936. else
  3937. {
  3938. for (t = 0; t < dust_time; t += dust_interval)
  3939. {
  3940. PlayfxOnTag(level._effect["rise_dust"], zombie, dust_tag);
  3941. wait dust_interval;
  3942. }
  3943. }
  3944. }
  3945. stop_zombie_rise_dust_fx(zombie)
  3946. {
  3947. zombie waittill("death");
  3948. self notify("stop_zombie_rise_dust_fx");
  3949. }
  3950. get_rise_anim()
  3951. {
  3952.  
  3953. speed = self.zombie_move_speed;
  3954. return random(level._zombie_rise_anims[self.animname][self.zombie_rise_version][speed]);
  3955.  
  3956.  
  3957.  
  3958.  
  3959. }
  3960. get_rise_death_anim()
  3961. {
  3962. possible_anims = [];
  3963. if (self.zombie_rise_death_out)
  3964. {
  3965. possible_anims = level._zombie_rise_death_anims[self.animname][self.zombie_rise_version]["out"];
  3966. }
  3967. else
  3968. {
  3969. possible_anims = level._zombie_rise_death_anims[self.animname][self.zombie_rise_version]["in"];
  3970. }
  3971. return random(possible_anims);
  3972. }
  3973. make_crawler()
  3974. {
  3975.  
  3976. if( !IsDefined( self ) )
  3977. {
  3978. return;
  3979. }
  3980. self.has_legs = false;
  3981. self.needs_run_update = true;
  3982. self AllowedStances( "crouch" );
  3983. damage_type[0] = "right_foot";
  3984. damage_type[1] = "left_foot";
  3985.  
  3986. refs = [];
  3987. switch( damage_type[ RandomInt(damage_type.size) ] )
  3988. {
  3989. case "right_leg_upper":
  3990. case "right_leg_lower":
  3991. case "right_foot":
  3992.  
  3993. refs[refs.size] = "right_leg";
  3994. refs[refs.size] = "right_leg";
  3995. refs[refs.size] = "right_leg";
  3996. refs[refs.size] = "no_legs";
  3997. break;
  3998. case "left_leg_upper":
  3999. case "left_leg_lower":
  4000. case "left_foot":
  4001.  
  4002. refs[refs.size] = "left_leg";
  4003. refs[refs.size] = "left_leg";
  4004. refs[refs.size] = "left_leg";
  4005. refs[refs.size] = "no_legs";
  4006. break;
  4007. }
  4008. if( refs.size )
  4009. {
  4010. self.a.gib_ref = animscripts\zombie_death::get_random( refs );
  4011.  
  4012. if( ( self.a.gib_ref == "no_legs" || self.a.gib_ref == "right_leg" || self.a.gib_ref == "left_leg" ) && self.health > 0 )
  4013. {
  4014. self.has_legs = false;
  4015. self AllowedStances( "crouch" );
  4016. which_anim = RandomInt( 5 );
  4017. if(self.a.gib_ref == "no_legs")
  4018. {
  4019. if(randomint(100) < 50)
  4020. {
  4021. self.deathanim = %ai_zombie_crawl_death_v1;
  4022. self set_run_anim( "death3" );
  4023. self.run_combatanim = level.scr_anim[self.animname]["crawl_hand_1"];
  4024. self.crouchRunAnim = level.scr_anim[self.animname]["crawl_hand_1"];
  4025. self.crouchrun_combatanim = level.scr_anim[self.animname]["crawl_hand_1"];
  4026. }
  4027. else
  4028. {
  4029. self.deathanim = %ai_zombie_crawl_death_v1;
  4030. self set_run_anim( "death3" );
  4031. self.run_combatanim = level.scr_anim[self.animname]["crawl_hand_2"];
  4032. self.crouchRunAnim = level.scr_anim[self.animname]["crawl_hand_2"];
  4033. self.crouchrun_combatanim = level.scr_anim[self.animname]["crawl_hand_2"];
  4034. }
  4035. }
  4036. else if( which_anim == 0 )
  4037. {
  4038. self.deathanim = %ai_zombie_crawl_death_v1;
  4039. self set_run_anim( "death3" );
  4040. self.run_combatanim = level.scr_anim[self.animname]["crawl1"];
  4041. self.crouchRunAnim = level.scr_anim[self.animname]["crawl1"];
  4042. self.crouchrun_combatanim = level.scr_anim[self.animname]["crawl1"];
  4043. }
  4044. else if( which_anim == 1 )
  4045. {
  4046. self.deathanim = %ai_zombie_crawl_death_v2;
  4047. self set_run_anim( "death4" );
  4048. self.run_combatanim = level.scr_anim[self.animname]["crawl2"];
  4049. self.crouchRunAnim = level.scr_anim[self.animname]["crawl2"];
  4050. self.crouchrun_combatanim = level.scr_anim[self.animname]["crawl2"];
  4051. }
  4052. else if( which_anim == 2 )
  4053. {
  4054. self.deathanim = %ai_zombie_crawl_death_v1;
  4055. self set_run_anim( "death3" );
  4056. self.run_combatanim = level.scr_anim[self.animname]["crawl3"];
  4057. self.crouchRunAnim = level.scr_anim[self.animname]["crawl3"];
  4058. self.crouchrun_combatanim = level.scr_anim[self.animname]["crawl3"];
  4059. }
  4060. else if( which_anim == 3 )
  4061. {
  4062. self.deathanim = %ai_zombie_crawl_death_v2;
  4063. self set_run_anim( "death4" );
  4064. self.run_combatanim = level.scr_anim[self.animname]["crawl4"];
  4065. self.crouchRunAnim = level.scr_anim[self.animname]["crawl4"];
  4066. self.crouchrun_combatanim = level.scr_anim[self.animname]["crawl4"];
  4067. }
  4068. else if( which_anim == 4 )
  4069. {
  4070. self.deathanim = %ai_zombie_crawl_death_v1;
  4071. self set_run_anim( "death3" );
  4072. self.run_combatanim = level.scr_anim[self.animname]["crawl5"];
  4073. self.crouchRunAnim = level.scr_anim[self.animname]["crawl5"];
  4074. self.crouchrun_combatanim = level.scr_anim[self.animname]["crawl5"];
  4075. }
  4076. }
  4077. }
  4078. }
  4079. zombie_disintegrate( player )
  4080. {
  4081. self DoDamage( self.health + 666, player.origin, player );
  4082. if ( self.health <= 0 )
  4083. {
  4084. player maps\_zombiemode_score::player_add_points( "death", "", "", self.isdog );
  4085.  
  4086. if( self.has_legs )
  4087. {
  4088. self.deathanim = random( level._zombie_knockdowns[self.animname]["front"]["has_legs"] );
  4089. }
  4090. else
  4091. {
  4092. self.deathanim = random( level._zombie_tesla_crawl_death[self.animname] );
  4093. }
  4094. self swap_to_dissolve_models();
  4095. self setDeathContents( level.CONTENTS_CORPSE );
  4096. self playweapondeatheffects( player GetCurrentWeapon() );
  4097. self.thundergun_death = true;
  4098. self.thundergun_disintegrated_death = true;
  4099. self.skip_death_notetracks = true;
  4100. self.nodeathragdoll = true;
  4101. wait( GetDvarFloat( #"cg_dissolveTransitionTime" ) + 4 );
  4102. self_delete();
  4103. }
  4104. }
  4105. zombie_knockdown( player, gib )
  4106. {
  4107. if ( gib && !self.gibbed )
  4108. {
  4109. self.a.gib_ref = random( level.thundergun_gib_refs );
  4110. self thread animscripts\zombie_death::do_gib();
  4111. }
  4112. self.thundergun_handle_pain_notetracks = maps\_zombiemode_weap_thundergun::handle_thundergun_pain_notetracks;
  4113. self DoDamage( level.zombie_vars["thundergun_knockdown_damage"], player.origin, player );
  4114. }
  4115. zombie_tesla_head_gib()
  4116. {
  4117. if( RandomInt( 100 ) < level.zombie_vars["tesla_head_gib_chance"] )
  4118. {
  4119. wait( RandomFloat( 0.53, 1.0 ) );
  4120. self zombie_head_gib();
  4121. }
  4122. else
  4123. {
  4124. network_safe_play_fx_on_tag( "tesla_death_fx", 2, level._effect["tesla_shock_eyes"], self, "J_Eyeball_LE" );
  4125. }
  4126. }
  4127. play_ambient_zombie_vocals()
  4128. {
  4129. self endon( "death" );
  4130.  
  4131. if( self.animname == "monkey_zombie" )
  4132. {
  4133. return;
  4134. }
  4135.  
  4136. while(1)
  4137. {
  4138. type = "ambient";
  4139. float = 2;
  4140.  
  4141. if( !IsDefined( self.zombie_move_speed ) )
  4142. {
  4143. wait(.5);
  4144. continue;
  4145. }
  4146.  
  4147. switch(self.zombie_move_speed)
  4148. {
  4149. case "walk": type="ambient"; float=4; break;
  4150. case "run": type="sprint"; float=4; break;
  4151. case "sprint": type="sprint"; float=4; break;
  4152. }
  4153.  
  4154. if( self.animname == "zombie" && !self.has_legs )
  4155. {
  4156. type = "crawler";
  4157. }
  4158. else if( self.animname == "thief_zombie" )
  4159. {
  4160. float = 1.2;
  4161. }
  4162.  
  4163. self thread maps\_zombiemode_audio::do_zombies_playvocals( type, self.animname );
  4164.  
  4165. wait(RandomFloatRange(1,float));
  4166. }
  4167. }
  4168. zombie_complete_emerging_into_playable_area()
  4169. {
  4170. self.completed_emerging_into_playable_area = true;
  4171. self notify( "completed_emerging_into_playable_area" );
  4172. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement