/* server/ai/zombie_core.qc zombie things Copyright (C) 2021-2024 NZ:P Team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to: Free Software Foundation, Inc. 59 Temple Place - Suite 330 Boston, MA 02111-1307, USA */ #define ZOMBIE_DAMAGE_THROUGH_WINDOW 60 void() Zombie_Walk_Setup; void() crawler_rip_board1; void() crawler_da1; void() crawler_die1; void() crawler_death_wunder1; void() LinkZombiesHitbox; float EMPTY_BBOX = 0; float BASE_BBOX = 1; float IDLE_BBOX = 2; //Rising from ground bbox float WALK1_BBOX = 4; float WALK2_BBOX = 5; float WALK3_BBOX = 6; float JOG_BBOX = 7; float RUN_BBOX = 8; float CRAWLER_BBOX = 9; void(float what) play_sound_z = { if(self.classname == "ai_zombie") { local float e; e = random(); if(what == 1)//attack { if (e < 0.125) sound(self, CHAN_WEAPON, "sounds/zombie/a0.wav", 1, ATTN_NORM); else if (e < 0.25) sound(self, CHAN_WEAPON, "sounds/zombie/a1.wav", 1, ATTN_NORM); else if (e < 0.375) sound(self, CHAN_WEAPON, "sounds/zombie/a2.wav", 1, ATTN_NORM); else if( e < 0.5) sound(self, CHAN_WEAPON, "sounds/zombie/a3.wav", 1, ATTN_NORM); else if( e < 0.625) sound(self, CHAN_WEAPON, "sounds/zombie/a4.wav", 1, ATTN_NORM); else if( e < 0.75) sound(self, CHAN_WEAPON, "sounds/zombie/a5.wav", 1, ATTN_NORM); else if( e < 0.875) sound(self, CHAN_WEAPON, "sounds/zombie/a6.wav", 1, ATTN_NORM); else sound(self, CHAN_WEAPON, "sounds/zombie/a7.wav", 1, ATTN_NORM); return; } if(what == 2)//walking! { if(self.s_time < time && self.s_time > 0) { sounds_playing --; self.s_time = 0; } if(sounds_playing >= 3) { return; } sounds_playing++; self.s_time = time + 1; if(self.sound_time < time) { play_sound_z(4); if(self.crawling == TRUE) { self.sound_time = time + 3 + random()*2; if(e < 0.2) sound(self, CHAN_VOICE, "sounds/zombie/t0.wav", 1, ATTN_NORM); else if (e < 0.4) sound(self, CHAN_VOICE, "sounds/zombie/t1.wav", 1, ATTN_NORM); else if (e < 0.6) sound(self, CHAN_VOICE, "sounds/zombie/t2.wav", 1, ATTN_NORM); else if (e < 0.8) sound(self, CHAN_VOICE, "sounds/zombie/t3.wav", 1, ATTN_NORM); else sound(self, CHAN_VOICE, "sounds/zombie/t4.wav", 1, ATTN_NORM); return; } if(self.walktype == 1 || self.walktype == 2 || self.walktype == 3) { self.sound_time = time + 3 + random(); if (e < 0.1) sound(self, CHAN_VOICE, "sounds/zombie/w0.wav", 1, ATTN_NORM); else if (e < 0.2) sound(self, CHAN_VOICE, "sounds/zombie/w1.wav", 1, ATTN_NORM); else if (e < 0.3) sound(self, CHAN_VOICE, "sounds/zombie/w2.wav", 1, ATTN_NORM); else if( e < 0.4) sound(self, CHAN_VOICE, "sounds/zombie/w3.wav", 1, ATTN_NORM); else if( e < 0.5) sound(self, CHAN_VOICE, "sounds/zombie/w4.wav", 1, ATTN_NORM); else if( e < 0.6) sound(self, CHAN_VOICE, "sounds/zombie/w5.wav", 1, ATTN_NORM); else if( e < 0.7) sound(self, CHAN_VOICE, "sounds/zombie/w6.wav", 1, ATTN_NORM); else if( e < 0.8) sound(self, CHAN_VOICE, "sounds/zombie/w7.wav", 1, ATTN_NORM); else if( e < 0.9) sound(self, CHAN_VOICE, "sounds/zombie/w8.wav", 1, ATTN_NORM); else sound(self, CHAN_VOICE, "sounds/zombie/w9.wav", 1, ATTN_NORM); return; } else if(self.walktype == 4 || self.walktype == 5) { self.sound_time = time + 4 + random()*2; if (e < 0.1) sound(self, CHAN_VOICE, "sounds/zombie/r0.wav", 1, ATTN_NORM); else if (e < 0.2) sound(self, CHAN_VOICE, "sounds/zombie/r1.wav", 1, ATTN_NORM); else if (e < 0.3) sound(self, CHAN_VOICE, "sounds/zombie/r2.wav", 1, ATTN_NORM); else if( e < 0.4) sound(self, CHAN_VOICE, "sounds/zombie/r3.wav", 1, ATTN_NORM); else if( e < 0.5) sound(self, CHAN_VOICE, "sounds/zombie/r4.wav", 1, ATTN_NORM); else if( e < 0.6) sound(self, CHAN_VOICE, "sounds/zombie/r5.wav", 1, ATTN_NORM); else if( e < 0.7) sound(self, CHAN_VOICE, "sounds/zombie/r6.wav", 1, ATTN_NORM); else if( e < 0.8) sound(self, CHAN_VOICE, "sounds/zombie/r7.wav", 1, ATTN_NORM); else if( e < 0.9) sound(self, CHAN_VOICE, "sounds/zombie/r8.wav", 1, ATTN_NORM); else sound(self, CHAN_VOICE, "sounds/zombie/r9.wav", 1, ATTN_NORM); return; } } } if(what == 3)//death! { if (e < 0.125) sound(self, CHAN_BODY, "sounds/zombie/d0.wav", 1, ATTN_NORM); else if (e < 0.25) sound(self, CHAN_BODY, "sounds/zombie/d1.wav", 1, ATTN_NORM); else if (e < 0.375) sound(self, CHAN_BODY, "sounds/zombie/d2.wav", 1, ATTN_NORM); else if( e < 0.5) sound(self, CHAN_BODY, "sounds/zombie/d3.wav", 1, ATTN_NORM); else if( e < 0.625) sound(self, CHAN_BODY, "sounds/zombie/d4.wav", 1, ATTN_NORM); else if( e < 0.75) sound(self, CHAN_BODY, "sounds/zombie/d5.wav", 1, ATTN_NORM); else if( e < 0.875) sound(self, CHAN_BODY, "sounds/zombie/d6.wav", 1, ATTN_NORM); else sound(self, CHAN_BODY, "sounds/zombie/d7.wav", 1, ATTN_NORM); return; } if(what == 4)//Taunt! { if(random() < 0.83) return; if(e < 0.2) sound(self, CHAN_ITEM, "sounds/zombie/t0.wav", 1, ATTN_NORM); else if (e < 0.4) sound(self, CHAN_ITEM, "sounds/zombie/t1.wav", 1, ATTN_NORM); else if (e < 0.6) sound(self, CHAN_ITEM, "sounds/zombie/t2.wav", 1, ATTN_NORM); else if (e < 0.8) sound(self, CHAN_ITEM, "sounds/zombie/t3.wav", 1, ATTN_NORM); else sound(self, CHAN_ITEM, "sounds/zombie/t4.wav", 1, ATTN_NORM); return; } if (what == 5) // Electric Zap { sound(self, CHAN_ITEM, "sounds/machines/elec_shock.wav", 1, ATTN_NORM); } } }; void(__inout vector what, float howmuch) vector_scale_hack = { what_x *= howmuch; what_y *= howmuch; what_z *= howmuch; } void(float which) SetZombieHitBox = { //Zombie's bbox is constant across all hitbox setups, so we don't update it. if(self.currentHitBoxSetup == which) return; //which = IDLE_BBOX; switch(which) { case EMPTY_BBOX: self.head.view_ofs = '0 0 0'; self.rarm.view_ofs = '0 0 0'; self.larm.view_ofs = '0 0 0'; break; case IDLE_BBOX: self.head.bbmins = '-5 -5 -5'; self.head.bbmaxs = '5 5 5'; self.head.view_ofs = '0 10 35'; self.larm.bbmins = '-5 -5 -15'; self.larm.bbmaxs = '5 5 15'; self.larm.view_ofs = '-10 10 10'; self.rarm.bbmins = '-5 -5 -15'; self.rarm.bbmaxs = '5 5 15'; self.rarm.view_ofs = '10 10 10'; break; case WALK1_BBOX: self.head.bbmins = '-5 -5 -5'; self.head.bbmaxs = '5 5 5'; self.head.view_ofs = '2 -3 35'; self.larm.bbmins = '-5 -7 -15'; self.larm.bbmaxs = '5 7 15'; self.larm.view_ofs = '-10 -4 15'; self.rarm.bbmins = '-5 -8 -11'; self.rarm.bbmaxs = '5 8 11'; self.rarm.view_ofs = '10 11 11'; break; case WALK2_BBOX: self.head.bbmins = '-7 -5 -5'; self.head.bbmaxs = '7 5 5'; self.head.view_ofs = '-11 6 36'; self.larm.bbmins = '-5 -6 -15'; self.larm.bbmaxs = '5 6 15'; self.larm.view_ofs = '-14 3 15'; self.rarm.bbmins = '-5 -5 -11'; self.rarm.bbmaxs = '5 5 11'; self.rarm.view_ofs = '4 13 11'; break; case WALK3_BBOX: self.head.bbmins = '-5 -5 -5'; self.head.bbmaxs = '5 5 5'; self.head.view_ofs = '-2 13 31'; self.larm.bbmins = '-4 -6 -14'; self.larm.bbmaxs = '4 6 14'; self.larm.view_ofs = '-12 3 11'; self.rarm.bbmins = '-5 -5 -11'; self.rarm.bbmaxs = '5 5 11'; self.rarm.view_ofs = '14 6 12'; break; case JOG_BBOX: self.head.bbmins = '-5 -5 -5'; self.head.bbmaxs = '5 5 5'; self.head.view_ofs = '0 5 36'; self.larm.bbmins = '-5 -13 -5'; self.larm.bbmaxs = '5 13 5'; self.larm.view_ofs = '-8 19 24'; self.rarm.bbmins = '-5 -13 -5'; self.rarm.bbmaxs = '5 13 5'; self.rarm.view_ofs = '10 19 24'; break; case RUN_BBOX: self.head.bbmins = '-5 -5 -5'; self.head.bbmaxs = '5 5 5'; self.head.view_ofs = '3 17 32'; self.larm.bbmins = '-4 -10 -9'; self.larm.bbmaxs = '4 10 9'; self.larm.view_ofs = '-12 28 18'; self.rarm.bbmins = '-4 -13 -10'; self.rarm.bbmaxs = '4 13 10'; self.rarm.view_ofs = '12 -2 19'; break; case CRAWLER_BBOX: self.head.bbmins = '-5 -5 -5'; self.head.bbmaxs = '5 5 5'; self.head.view_ofs = '2 18 -14'; self.larm.bbmins = '-4 -10 -9'; self.larm.bbmaxs = '4 10 9'; self.larm.view_ofs = '-9 24 -27'; self.rarm.bbmins = '-4 -13 -10'; self.rarm.bbmaxs = '4 13 10'; self.rarm.view_ofs = '12 15 -25'; break; default: //also known as BASE_BBOX self.head.bbmins = '-5 -5 -5'; self.head.bbmaxs = '5 5 5'; self.head.view_ofs = '0 0 35'; self.larm.bbmins = '-5 -5 -15'; self.larm.bbmaxs = '5 5 15'; self.larm.view_ofs = '-10 0 5'; self.rarm.bbmins = '-5 -5 -15'; self.rarm.bbmaxs = '5 5 15'; self.rarm.view_ofs = '10 0 5'; break; } self.currentHitBoxSetup = which; if (map_compatibility_mode == MAP_COMPAT_BETA) { vector_scale_hack(self.head.bbmins, self.head.scale); vector_scale_hack(self.head.bbmaxs, self.head.scale); vector_scale_hack(self.head.view_ofs, self.head.scale); vector_scale_hack(self.larm.bbmins, self.larm.scale); vector_scale_hack(self.larm.bbmaxs, self.larm.scale); vector_scale_hack(self.larm.view_ofs, self.larm.scale); vector_scale_hack(self.rarm.bbmins, self.rarm.scale); vector_scale_hack(self.rarm.bbmaxs, self.rarm.scale); vector_scale_hack(self.rarm.view_ofs, self.rarm.scale); } }; // // Zombie_ProcessRespawn() // Logic called by Zombie_Think for checking // the last origin every second, for determining // if a zombie is "stuck" inside and needs to re-spawn. // void() Zombie_ProcessRespawn = { // Check once every 3 seconds if (self.respawn_timer < time && !self.outside) { // Check if the Zombie has barely moved (16qu) if (vlen(self.new_ofs - self.origin) <= 16) { // Continue to iterate self.respawn_iterator++; // 30 seconds have passed -- assume properly stuck, respawn. if (self.respawn_iterator >= 10) { self.respawn_iterator = 0; // Kill it. self.th_die(); // This is a pseudo-hack that just tells the rounds core that we should // spawn another. Current_Zombies--; Remaining_Zombies++; } } else { // Set to zero -- Zombie is moving appropriately. self.respawn_iterator = 0; } // Iterate another 3 seconds. self.respawn_timer = time + 3; // Update our last origin self.new_ofs = self.origin; } } void() zombie_decide; void() Zombie_Think = //called every frame for zombies { if (self.onfire) { Effect_Fire(self.origin); if (self.ltime < time && self.onfire){ DamageHandler(self, self.firer, 300, S_FLAME); self.ltime = time + 2; if (self.fire_timeout < time) self.onfire = false; } } Zombie_ProcessRespawn(); // Electro-Shock Death if (self.death_timer < time && self.death_timer_activated == true) { self.th_die(); } if (self.bleedingtime < time && !self.head.deadflag) { self.bleedingtime = time + 1; DamageHandler (self, self.usedent, z_health * 0.2, S_HEADSHOT); } // If we're mid attack and our enemy has moved out of range if (self.is_attacking && vlen(self.enemy.origin - self.origin) > 64) { // Cancel the animation, start walking again to catch up. self.is_attacking = false; // zombie_decide() here used to call an idle loop if they were // outside, lesson learned. if (!self.outside) self.th_walk(); } } void() zombie_footstep { if(self.laststep == 1) { self.laststep = 0; sound(self, 5, "sounds/zombie/s0.wav", 0.6, ATTN_NORM); } else { self.laststep = 1; sound(self, 5, "sounds/zombie/s1.wav", 0.6, ATTN_NORM); } } ////////////////////////////////////////////////////////////////////// //37-52 $frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9 walk10 walk11 walk12 walk13 walk14 walk15 walk16 //walk15 //walk 1! void() zombie_walk1 =[ $walk1, zombie_walk2 ] {self.nextthink = time + 0.12;Zombie_Walk(8);SetZombieHitBox(WALK1_BBOX);/*if(freeze_time < time)*/ self.frame = 37;Zombie_Think();}; void() zombie_walk2 =[ $walk2, zombie_walk3 ] {self.nextthink = time + 0.12;Zombie_Walk(3.5); self.frame = 38;Zombie_Think();}; void() zombie_walk3 =[ $walk3, zombie_walk4 ] {self.nextthink = time + 0.12;Zombie_Walk(3.5); self.frame = 39;Zombie_Think();}; void() zombie_walk4 =[ $walk4, zombie_walk5 ] {self.nextthink = time + 0.12;Zombie_Walk(3.5); self.frame = 40;Zombie_Think();}; void() zombie_walk5 =[ $walk5, zombie_walk6 ] {self.nextthink = time + 0.12;Zombie_Walk(3.5); self.frame = 41;Zombie_Think();zombie_footstep();};//footstep void() zombie_walk6 =[ $walk6, zombie_walk7 ] {self.nextthink = time + 0.12;Zombie_Walk(3.5); self.frame = 42;Zombie_Think();}; void() zombie_walk7 =[ $walk7, zombie_walk8 ] {self.nextthink = time + 0.12;Zombie_Walk(8.8); self.frame = 43;Zombie_Think();}; void() zombie_walk8 =[ $walk8, zombie_walk9 ] {self.nextthink = time + 0.12;Zombie_Walk(9); self.frame = 44;Zombie_Think();zombie_footstep();};//footstep void() zombie_walk9 =[ $walk9, zombie_walk10 ] {self.nextthink = time + 0.12;Zombie_Walk(4); self.frame = 45;Zombie_Think();}; void() zombie_walk10 =[ $walk10, zombie_walk11 ] {self.nextthink = time + 0.12;Zombie_Walk(4); self.frame = 46;Zombie_Think();}; void() zombie_walk11 =[ $walk11, zombie_walk12 ] {self.nextthink = time + 0.12;Zombie_Walk(7.8); self.frame = 47;Zombie_Think();}; void() zombie_walk12 =[ $walk12, zombie_walk13 ] {self.nextthink = time + 0.12;Zombie_Walk(5.2); self.frame = 48;Zombie_Think();zombie_footstep();};//footstep void() zombie_walk13 =[ $walk13, zombie_walk14 ] {self.nextthink = time + 0.12;Zombie_Walk(2.4); self.frame = 49;Zombie_Think();}; void() zombie_walk14 =[ $walk14, zombie_walk15 ] {self.nextthink = time + 0.12;Zombie_Walk(2.8); self.frame = 50;Zombie_Think();}; void() zombie_walk15 =[ $walk15, zombie_walk16 ] {self.nextthink = time + 0.12;Zombie_Walk(6.5); self.frame = 51;Zombie_Think();}; void() zombie_walk16 =[ $walk16, Zombie_Walk_Setup ] {self.nextthink = time + 0.12;Zombie_Walk(7.7); self.frame = 52;Zombie_Think();zombie_footstep();};//footstep ///////////////////////////////////////////////////////////////////////// //53-66 //Walk 2! $frame bwalk1 bwalk2 bwalk3 bwalk4 bwalk5 bwalk6 bwalk7 bwalk8 bwalk9 bwalk10 bwalk11 bwalk12 bwalk13 bwalk14 void() zombie_walkb1 =[ $bwalk1, zombie_walkb2 ] {self.nextthink = time + 0.13;Zombie_Walk(4.2);SetZombieHitBox(WALK2_BBOX);/*if(freeze_time < time)*/ self.frame = 53;Zombie_Think();}; void() zombie_walkb2 =[ $bwalk2, zombie_walkb3 ] {self.nextthink = time + 0.13;Zombie_Walk(5.9); self.frame = 54;Zombie_Think();}; void() zombie_walkb3 =[ $bwalk3, zombie_walkb4 ] {self.nextthink = time + 0.13;Zombie_Walk(3); self.frame = 55;Zombie_Think();}; void() zombie_walkb4 =[ $bwalk4, zombie_walkb5 ] {self.nextthink = time + 0.13;Zombie_Walk(5.7); self.frame = 56;Zombie_Think();zombie_footstep();};//footstep void() zombie_walkb5 =[ $bwalk5, zombie_walkb6 ] {self.nextthink = time + 0.13;Zombie_Walk(4.2); self.frame = 57;Zombie_Think();}; void() zombie_walkb6 =[ $bwalk6, zombie_walkb7 ] {self.nextthink = time + 0.13;Zombie_Walk(7.2); self.frame = 58;Zombie_Think();}; void() zombie_walkb7 =[ $bwalk7, zombie_walkb8 ] {self.nextthink = time + 0.13;Zombie_Walk(4.5); self.frame = 59;Zombie_Think();zombie_footstep();};//footstep void() zombie_walkb8 =[ $bwalk8, zombie_walkb9 ] {self.nextthink = time + 0.13;Zombie_Walk(3.4); self.frame = 60;Zombie_Think();}; void() zombie_walkb9 =[ $bwalk9, zombie_walkb10 ] {self.nextthink = time + 0.13;Zombie_Walk(1.2); self.frame = 61;Zombie_Think();}; void() zombie_walkb10 =[ $bwalk10, zombie_walkb11 ] {self.nextthink = time + 0.13;Zombie_Walk(6.7); self.frame = 62;Zombie_Think();zombie_footstep();};//footstep void() zombie_walkb11 =[ $bwalk11, zombie_walkb12 ] {self.nextthink = time + 0.13;Zombie_Walk(8.4); self.frame = 63;Zombie_Think();}; void() zombie_walkb12 =[ $bwalk12, zombie_walkb13 ] {self.nextthink = time + 0.13;Zombie_Walk(1.3); self.frame = 64;Zombie_Think();}; void() zombie_walkb13 =[ $bwalk13, zombie_walkb14 ] {self.nextthink = time + 0.13;Zombie_Walk(6.3); self.frame = 65;Zombie_Think();}; void() zombie_walkb14 =[ $bwalk14, Zombie_Walk_Setup ] {self.nextthink = time + 0.13;Zombie_Walk(3.6); self.frame = 66;Zombie_Think();zombie_footstep();};//footstep ///////////////////////////////////////////////////////////////////////// //67-82 //Walk 3! $frame cwalk1 cwalk2 cwalk3 cwalk4 cwalk5 cwalk6 cwalk7 cwalk8 cwalk9 cwalk10 cwalk11 cwalk12 cwalk13 cwalk14 cwalk15 cwalk16 void() zombie_walkc1 =[ $cwalk1, zombie_walkc2 ] {self.nextthink = time + 0.13;Zombie_Walk(3.4);SetZombieHitBox(WALK3_BBOX);/*if(freeze_time < time)*/ self.frame = 67;Zombie_Think();}; void() zombie_walkc2 =[ $cwalk2, zombie_walkc3 ] {self.nextthink = time + 0.13;Zombie_Walk(2); self.frame = 68;Zombie_Think();}; void() zombie_walkc3 =[ $cwalk3, zombie_walkc4 ] {self.nextthink = time + 0.13;Zombie_Walk(5.4); self.frame = 69;Zombie_Think();}; void() zombie_walkc4 =[ $cwalk4, zombie_walkc5 ] {self.nextthink = time + 0.13;Zombie_Walk(5.6); self.frame = 70;Zombie_Think();zombie_footstep();};//footstep void() zombie_walkc5 =[ $cwalk5, zombie_walkc6 ] {self.nextthink = time + 0.13;Zombie_Walk(3); self.frame = 71;Zombie_Think();}; void() zombie_walkc6 =[ $cwalk6, zombie_walkc7 ] {self.nextthink = time + 0.13;Zombie_Walk(3.1); self.frame = 72;Zombie_Think();}; void() zombie_walkc7 =[ $cwalk7, zombie_walkc8 ] {self.nextthink = time + 0.13;Zombie_Walk(3); self.frame = 73;Zombie_Think();}; void() zombie_walkc8 =[ $cwalk8, zombie_walkc9 ] {self.nextthink = time + 0.13;Zombie_Walk(2.9); self.frame = 74;Zombie_Think();zombie_footstep();};//footstep void() zombie_walkc9 =[ $cwalk9, zombie_walkc10 ] {self.nextthink = time + 0.13;Zombie_Walk(3.3); self.frame = 75;Zombie_Think();}; void() zombie_walkc10 =[ $cwalk10, zombie_walkc11 ] {self.nextthink = time + 0.13;Zombie_Walk(2.2); self.frame = 76;Zombie_Think();}; void() zombie_walkc11 =[ $cwalk11, zombie_walkc12 ] {self.nextthink = time + 0.13;Zombie_Walk(3.7); self.frame = 77;Zombie_Think();}; void() zombie_walkc12 =[ $cwalk12, zombie_walkc13 ] {self.nextthink = time + 0.13;Zombie_Walk(4.2); self.frame = 78;Zombie_Think();zombie_footstep();};//footstep void() zombie_walkc13 =[ $cwalk13, zombie_walkc14 ] {self.nextthink = time + 0.13;Zombie_Walk(5.3); self.frame = 79;Zombie_Think();}; void() zombie_walkc14 =[ $cwalk14, zombie_walkc15 ] {self.nextthink = time + 0.13;Zombie_Walk(5.2); self.frame = 80;Zombie_Think();}; void() zombie_walkc15 =[ $cwalk15, zombie_walkc16 ] {self.nextthink = time + 0.13;Zombie_Walk(2.2); self.frame = 81;Zombie_Think();}; void() zombie_walkc16 =[ $cwalk16, Zombie_Walk_Setup ] {self.nextthink = time + 0.13;Zombie_Walk(2.4); self.frame = 82;Zombie_Think();zombie_footstep();};//footstep ///////////////////////////////////////////////////////////////////// //116- 129 $frame jog1 jog2 jog3 jog4 jog5 jog6 jog7 jog8 void() zombie_jog1 =[ $jog1, zombie_jog2 ] {self.nextthink = time + 0.08;Zombie_Walk(6);SetZombieHitBox(JOG_BBOX);/*if(freeze_time < time)*/ self.frame = 83;Zombie_Think();};//FOOTSTEP void() zombie_jog2 =[ $jog2, zombie_jog3 ] {self.nextthink = time + 0.08;Zombie_Walk(6); self.frame = 84;Zombie_Think();}; void() zombie_jog3 =[ $jog3, zombie_jog4 ] {self.nextthink = time + 0.08;Zombie_Walk(6); self.frame = 85;Zombie_Think();}; void() zombie_jog4 =[ $jog4, zombie_jog5 ] {self.nextthink = time + 0.08;Zombie_Walk(6); self.frame = 86;Zombie_Think();zombie_footstep();};//footstep void() zombie_jog5 =[ $jog5, zombie_jog6 ] {self.nextthink = time + 0.08;Zombie_Walk(6); self.frame = 87;Zombie_Think();}; void() zombie_jog6 =[ $jog6, zombie_jog7 ] {self.nextthink = time + 0.08;Zombie_Walk(6); self.frame = 88;Zombie_Think();}; void() zombie_jog7 =[ $jog7, zombie_jog8 ] {self.nextthink = time + 0.08;Zombie_Walk(6); self.frame = 89;Zombie_Think();}; void() zombie_jog8 =[ $jog8, Zombie_Walk_Setup ] {self.nextthink = time + 0.08;Zombie_Walk(6); self.frame = 90;Zombie_Think();zombie_footstep();};//footstep ///////////////////////////////////////////////////////////////////// //78-85 $frame run1 run2 run3 run4 run5 run6 run7 run8 run9 run10 //12 unless 14 void() zombie_run1 =[ $run1, zombie_run2 ] {Zombie_Walk(13);/*if(freeze_time < time)*/ self.frame = 92;SetZombieHitBox(RUN_BBOX);Zombie_Think();zombie_footstep();};//footstep void() zombie_run2 =[ $run2, zombie_run3 ] {Zombie_Walk(13);self.frame = 93;Zombie_Think();}; void() zombie_run3 =[ $run3, zombie_run4 ] {Zombie_Walk(13); self.frame = 94;Zombie_Think();zombie_footstep();};//footstep void() zombie_run4 =[ $run4, zombie_run5 ] {Zombie_Walk(13); self.frame = 95;Zombie_Think();}; void() zombie_run5 =[ $run5, zombie_run6 ] {Zombie_Walk(13); self.frame = 96;Zombie_Think();}; void() zombie_run6 =[ $run6, zombie_run7 ] {Zombie_Walk(13); self.frame = 97;Zombie_Think();zombie_footstep();};//footstep void() zombie_run7 =[ $run7, zombie_run8 ] {Zombie_Walk(13); self.frame = 98;Zombie_Think();}; void() zombie_run8 =[ $run8, zombie_run9 ] {Zombie_Walk(13); self.frame = 99;Zombie_Think();zombie_footstep();};//footstep void() zombie_run9 =[ $run9, zombie_run10 ] {Zombie_Walk(13); self.frame = 100;Zombie_Think();}; void() zombie_run10 =[ $run10, Zombie_Walk_Setup ] {Zombie_Walk(13); self.frame = 101;Zombie_Think();}; void() Zombie_Walk_Setup = { if(Remaining_Zombies == 1 && rounds >= 4) { self.walktype = 5; } if(self.walktype == 1) { zombie_walk1(); } else if(self.walktype == 2) { zombie_walkb1(); } else if(self.walktype == 3) { zombie_walkc1(); } else if(self.walktype == 4) { zombie_jog1(); } else if(self.walktype == 5) { zombie_run1(); } }; ///////////////////////////////////////////////////////////////////// ZOMBIE IDLE 1 //0-12 $frame idle1 idle2 idle3 idle4 idle5 idle6 idle7 idle8 idle9 idle10 idle11 idle12 idle13 idle14 void() zombie_idle =[ $idle1, zombie_idle1 ] {Zombie_Walk(0);self.frame = 0;SetZombieHitBox(IDLE_BBOX);Zombie_Think();}; void() zombie_idle1 =[ $idle2, zombie_idle2 ] {Zombie_Walk(0);self.frame = 1;Zombie_Think();}; void() zombie_idle2 =[ $idle3, zombie_idle3 ] {Zombie_Walk(0);self.frame = 2;Zombie_Think();}; void() zombie_idle3 =[ $idle4, zombie_idle4 ] {Zombie_Walk(0);self.frame = 3;Zombie_Think();}; void() zombie_idle4 =[ $idle5, zombie_idle5 ] {Zombie_Walk(0);self.frame = 4;Zombie_Think();}; void() zombie_idle5 =[ $idle6, zombie_idle6 ] {Zombie_Walk(0);self.frame = 5;Zombie_Think();}; void() zombie_idle6 =[ $idle7, zombie_idle7 ] {Zombie_Walk(0);self.frame = 6;Zombie_Think();}; void() zombie_idle7 =[ $idle8, zombie_idle8 ] {Zombie_Walk(0);self.frame = 7;Zombie_Think();}; void() zombie_idle8 =[ $idle9, zombie_idle9 ] {Zombie_Walk(0);self.frame = 8;Zombie_Think();}; void() zombie_idle9 =[ $idle10, zombie_idle10 ] {Zombie_Walk(0);self.frame = 9;Zombie_Think();}; void() zombie_idle10 =[ $idle12, zombie_idle11 ] {Zombie_Walk(0);self.frame = 10;Zombie_Think();}; void() zombie_idle11 =[ $idle13, zombie_idle12 ] {Zombie_Walk(0);self.frame = 11;Zombie_Think();}; void() zombie_idle12 =[ $idle14, zombie_idle1 ] {Zombie_Walk(0);self.frame = 12;Zombie_Think();}; void() zombie_decide = { if(self.outside == TRUE) { self.th_idle(); } else { self.th_walk(); } }; ///////////////////////////////////////////////////////// void() Window_Damage; void() Window_Damage_Setup = { local entity old_self; old_self = self; self = self.goalentity; Window_Damage(); self = old_self; }; void() zombie_attack2 = { if(self.outside == TRUE) { if(self.goalentity.classname == "window") { if(self.enemy.classname != "window") { self.enemy = self.goalentity; } } } if(self.goalentity.classname == "window") { Window_Damage_Setup(); } // motolegacy -- Prohibit damage to the Player if the Nuke Power-Up logic is currently // running. else if (self.enemy.classname == "player" && nuke_powerup_active == false) { if(vlen(self.enemy.origin - self.origin) < 64) { if (self.classname == "ai_dog") DamageHandler (self.enemy, self, 40, S_ZOMBIE); else DamageHandler (self.enemy, self, 50, S_ZOMBIE); } } else return; }; //////////////////////////////WINDOW HOPPING //113-122 void(float pushaway) moveforwardalittle = { makevectors(self.angles); local float amount; amount = 4.35;//was 8.7, but running twice as much so... if(self.crawling == TRUE) amount = 2.33; self.origin = self.origin + (v_forward * amount); setorigin(self, self.origin); self.zoom = 1; if(pushaway == 1) { local entity ent; ent = findradius(self.origin,50); while(ent) { if(ent.classname == "player" && !ent.downed) { ent.velocity = ent.velocity + (v_forward * 250); } ent = ent.chain; } } }; $frame hop1 hop2 hop3 hop4 hop5 hop6 hop7 hop8 hop9 hop10 void() zombie_hop1 =[ $hop1, zombie_hop1_5 ] {self.movetype = self.head.movetype = MOVETYPE_STEP;self.frame = self.head.frame = 113;self.nextthink = time + 0.05;moveforwardalittle(1); self.state = 1;Zombie_Think();}; void() zombie_hop1_5 =[ $hop1, zombie_hop2 ] {self.frame = self.head.frame = 113;self.nextthink = time + 0.05;moveforwardalittle(0); }; void() zombie_hop2 =[ $hop2, zombie_hop2_5 ] {self.frame = self.head.frame = 114;self.nextthink = time + 0.05;moveforwardalittle(1);Zombie_Think();}; void() zombie_hop2_5 =[ $hop2, zombie_hop3 ] {self.frame = self.head.frame = 114;self.nextthink = time+0.05;moveforwardalittle(0);}; void() zombie_hop3 =[ $hop3, zombie_hop3_5 ] {self.frame = self.head.frame = 115;self.nextthink = time+0.05;moveforwardalittle(1);Zombie_Think();}; void() zombie_hop3_5 =[ $hop3, zombie_hop4 ] {self.frame = self.head.frame = 115;self.nextthink = time+0.05;moveforwardalittle(0);}; void() zombie_hop4 =[ $hop4, zombie_hop4_5 ] {self.frame = self.head.frame = 116;self.nextthink = time+0.05;moveforwardalittle(1);Zombie_Think();}; void() zombie_hop4_5 =[ $hop4, zombie_hop5 ] {self.frame = self.head.frame = 116;self.nextthink = time+0.05;moveforwardalittle(1);}; void() zombie_hop5 =[ $hop5, zombie_hop5_5 ] {self.frame = self.head.frame = 117;self.nextthink = time+0.05;moveforwardalittle(1);Zombie_Think();}; void() zombie_hop5_5 =[ $hop5, zombie_hop6 ] {self.frame = self.head.frame = 117;self.nextthink = time+0.05;moveforwardalittle(1);}; void() zombie_hop6 =[ $hop6, zombie_hop6_5 ] {self.frame = self.head.frame = 118;self.nextthink = time+0.05;moveforwardalittle(1);Zombie_Think();}; void() zombie_hop6_5 =[ $hop6, zombie_hop7 ] {self.frame = self.head.frame = 118;self.nextthink = time+0.05;moveforwardalittle(1);}; void() zombie_hop7 =[ $hop7, zombie_hop7_5 ] {self.frame = self.head.frame = 119;self.nextthink = time+0.05;moveforwardalittle(1);Zombie_Think();}; void() zombie_hop7_5 =[ $hop7, zombie_hop8 ] {self.frame = self.head.frame = 119;self.nextthink = time+0.05;moveforwardalittle(1);}; void() zombie_hop8 =[ $hop8, zombie_hop8_5 ] {self.frame = self.head.frame = 120;self.nextthink = time+0.05;moveforwardalittle(1);Zombie_Think();zombie_footstep();}; void() zombie_hop8_5 =[ $hop8, zombie_hop9 ] {self.frame = self.head.frame = 120;self.nextthink = time+0.05;moveforwardalittle(1);}; void() zombie_hop9 =[ $hop9, zombie_hop9_5 ] {self.frame = self.head.frame = 121;self.nextthink = time+0.05;moveforwardalittle(1);Zombie_Think();}; void() zombie_hop9_5 =[ $hop9, zombie_hop10 ] {self.frame = self.head.frame = 121;self.nextthink = time+0.05;moveforwardalittle(0);}; void() zombie_hop10 =[ $hop10, zombie_hop10_5 ] {self.frame = self.head.frame = 122;self.nextthink = time+0.05;moveforwardalittle(1);Zombie_Think();}; void() zombie_hop10_5=[ $hop10, SUB_Null ] {self.frame = self.head.frame = 122; self.oldorigin = self.origin = self.goalentity.hop_spot; setorigin(self, self.origin); self.state = 0; self.hop_step = 6; if(self.crawling == 2) { makeCrawler(self); //return; } self.movetype = MOVETYPE_WALK; self.th_walk(); }; //ripboard1 //181-191 $frame zrip1 zrip2 zrip3 zrip4 zrip5 zrip6 zrip7 zrip8 zrip9 zrip10 zrip11 void() zombie_ripboardA1 =[ $zrip1, zombie_ripboardA2 ] {self.frame = 181;SetZombieHitBox(IDLE_BBOX);Zombie_Think();}; void() zombie_ripboardA2 =[ $zrip2, zombie_ripboardA3 ] {self.frame = 182;Zombie_Think();}; void() zombie_ripboardA3 =[ $zrip3, zombie_ripboardA4 ] {self.frame = 183;Zombie_Think();}; void() zombie_ripboardA4 =[ $zrip4, zombie_ripboardA5 ] {self.frame = 184;Zombie_Think();}; void() zombie_ripboardA5 =[ $zrip5, zombie_ripboardA6 ] {self.frame = 185;Zombie_Think();}; void() zombie_ripboardA6 =[ $zrip6, zombie_ripboardA7 ] {self.frame = 186;Zombie_Think();}; void() zombie_ripboardA7 =[ $zrip7, zombie_ripboardA8 ] {self.frame = 187;zombie_attack2();Zombie_Think();}; void() zombie_ripboardA8 =[ $zrip8, zombie_ripboardA9 ] {self.frame = 188;Zombie_Think();}; void() zombie_ripboardA9 =[ $zrip9, zombie_ripboardA10 ] {self.frame = 189;Zombie_Think();}; void() zombie_ripboardA10 =[ $zrip10, zombie_ripboardA11 ] {self.frame = 190;Zombie_Think();}; void() zombie_ripboardA11 =[ $zrip11, zombie_decide ] {self.frame = 191;Zombie_Think();}; ///////////////////////////////////////////////////////// //ripboard2 //192-201 $frame zripB1 zripB2 zripB3 zripB4 zripB5 zripB6 zripB7 zripB8 zripB9 zripB10 zripB11 void() zombie_ripboardB1 =[ $zripB1, zombie_ripboardB2 ] {self.frame = 192;SetZombieHitBox(IDLE_BBOX);Zombie_Think();}; void() zombie_ripboardB2 =[ $zripB2, zombie_ripboardB3 ] {self.frame = 193;Zombie_Think();}; void() zombie_ripboardB3 =[ $zripB3, zombie_ripboardB4 ] {self.frame = 194;Zombie_Think();}; void() zombie_ripboardB4 =[ $zripB4, zombie_ripboardB5 ] {self.frame = 195;Zombie_Think();}; void() zombie_ripboardB5 =[ $zripB5, zombie_ripboardB6 ] {self.frame = 196;Zombie_Think();}; void() zombie_ripboardB6 =[ $zripB6, zombie_ripboardB7 ] {self.frame = 197;zombie_attack2();Zombie_Think();}; void() zombie_ripboardB7 =[ $zripB7, zombie_ripboardB8 ] {self.frame = 198;Zombie_Think();}; void() zombie_ripboardB8 =[ $zripB8, zombie_ripboardB9 ] {self.frame = 199;Zombie_Think();}; void() zombie_ripboardB9 =[ $zripB9, zombie_ripboardB10 ] {self.frame = 200;Zombie_Think();}; void() zombie_ripboardB10 =[ $zripB10, zombie_decide ] {self.frame = 201;Zombie_Think();}; ///////////////////////////////////////////////////////// //attack through window //180-181 //181-185 //186-188 void() zombie_attack_through_window = { play_sound_z(1); local entity who; who = findradius(self.origin, 70); while(who) { if(who.classname == "player") { DamageHandler (who, self, ZOMBIE_DAMAGE_THROUGH_WINDOW, S_ZOMBIE); } who = who.chain; } }; //202-210 // // Zombie Attacks // void() zombie_attack2; $frame zatkw1 zatkw2 zatkw3 zatkw4 zatkw5 zatkw6 zatkw7 zatkw8 zatkw9 void() zombie_attack_through_w1 =[ $zatkw1, zombie_attack_through_w2 ] {self.is_attacking = true; self.frame = 202;SetZombieHitBox(IDLE_BBOX);Zombie_Think();};//START void() zombie_attack_through_w2 =[ $zatkw2, zombie_attack_through_w3 ] {self.frame = 203;zombie_attack_through_window();Zombie_Think();};//SWINGING void() zombie_attack_through_w3 =[ $zatkw3, zombie_attack_through_w4 ] {self.frame = 204;Zombie_Think();};//SWINGING void() zombie_attack_through_w4 =[ $zatkw4, zombie_attack_through_w5 ] {self.frame = 205;Zombie_Think();};//SWINGING void() zombie_attack_through_w5 =[ $zatkw5, zombie_attack_through_w6 ] {self.frame = 206;Zombie_Think();};//SWINGING void() zombie_attack_through_w6 =[ $zatkw6, zombie_attack_through_w7 ] {self.frame = 207;Zombie_Think();};//SWINGING void() zombie_attack_through_w7 =[ $zatkw2, zombie_attack_through_w8 ] {self.frame = 203;Zombie_Think();};//SWINGING void() zombie_attack_through_w8 =[ $zatkw3, zombie_attack_through_w9 ] {self.frame = 204;Zombie_Think();};//SWINGING void() zombie_attack_through_w9 =[ $zatkw4, zombie_attack_through_w10 ] {self.frame = 205;Zombie_Think();};//SWINGING void() zombie_attack_through_w10 =[ $zatkw5, zombie_attack_through_w11 ] {self.frame = 206;Zombie_Think();};//SWINGING void() zombie_attack_through_w11 =[ $zatkw6, zombie_attack_through_w12 ] {self.frame = 207;Zombie_Think();};//SWINGING void() zombie_attack_through_w12 =[ $zatkw2, zombie_attack_through_w13 ] {self.frame = 203;Zombie_Think();};//SWINGING void() zombie_attack_through_w13 =[ $zatkw3, zombie_attack_through_w14 ] {self.frame = 204;Zombie_Think();};//SWINGING void() zombie_attack_through_w14 =[ $zatkw4, zombie_attack_through_w15 ] {self.frame = 205;Zombie_Think();};//SWINGING void() zombie_attack_through_w15 =[ $zatkw5, zombie_attack_through_w16 ] {self.frame = 206;zombie_attack_through_window();Zombie_Think();};//SWINGING void() zombie_attack_through_w16 =[ $zatkw6, zombie_attack_through_w17 ] {self.frame = 207;Zombie_Think();};//SWINGING void() zombie_attack_through_w17 =[ $zatkw7, zombie_attack_through_w18 ] {self.frame = 208;Zombie_Think();};//ENDING void() zombie_attack_through_w18 =[ $zatkw8, zombie_attack_through_w19 ] {self.frame = 209;Zombie_Think();};//ENDING void() zombie_attack_through_w19 =[ $zatkw9, zombie_decide ] {self.is_attacking = false; self.frame = 210;Zombie_Think();};//ENDING void() zm_swipe_right_slow =[ 1, zm_swipe_right_slow1 ] {self.is_attacking = true; self.frame = 102; SetZombieHitBox(BASE_BBOX); Zombie_Think(); }; void() zm_swipe_right_slow1 =[ 2, zm_swipe_right_slow2 ] {self.frame = 103; Zombie_Think(); }; void() zm_swipe_right_slow2 =[ 3, zm_swipe_right_slow3 ] {self.frame = 104; Zombie_Think(); }; void() zm_swipe_right_slow3 =[ 4, zm_swipe_right_slow4 ] {zombie_attack2(); self.frame = 105; Zombie_Think(); }; void() zm_swipe_right_slow4 =[ 5, zombie_decide ] {self.is_attacking = false; self.frame = 106; Zombie_Think(); }; void() zm_swipe_right_fast =[ 1, zm_swipe_right_fast1 ] {self.is_attacking = true; self.frame = 104; Zombie_Think(); }; void() zm_swipe_right_fast1 =[ 2, zm_swipe_right_fast2 ] {zombie_attack2(); self.frame = 105; Zombie_Think(); }; void() zm_swipe_right_fast2 =[ 3, zombie_decide ] {self.is_attacking = false; self.frame = 106; Zombie_Think(); }; void() zm_swipe_left_slow =[ 1, zm_swipe_left_slow1 ] {self.is_attacking = true; self.frame = 107; SetZombieHitBox(BASE_BBOX); Zombie_Think(); }; void() zm_swipe_left_slow1 =[ 2, zm_swipe_left_slow2 ] {self.frame = 108; Zombie_Think(); }; void() zm_swipe_left_slow2 =[ 3, zm_swipe_left_slow3 ] {self.frame = 109; Zombie_Think(); }; void() zm_swipe_left_slow3 =[ 4, zm_swipe_left_slow4 ] {zombie_attack2(); self.frame = 110; Zombie_Think(); }; void() zm_swipe_left_slow4 =[ 5, zm_swipe_left_slow5 ] {self.frame = 111; Zombie_Think(); }; void() zm_swipe_left_slow5 =[ 6, zombie_decide ] {self.is_attacking = false; self.frame = 112; Zombie_Think(); }; void() zm_swipe_left_fast =[ 1, zm_swipe_left_fast1 ] {self.is_attacking = true; self.frame = 109; SetZombieHitBox(BASE_BBOX); Zombie_Think(); }; void() zm_swipe_left_fast1 =[ 2, zm_swipe_left_fast2 ] {zombie_attack2(); self.frame = 110; Zombie_Think(); }; void() zm_swipe_left_fast2 =[ 3, zm_swipe_left_fast3 ] {self.frame = 111; Zombie_Think(); }; void() zm_swipe_left_fast3 =[ 4, zombie_decide ] {self.is_attacking = false; self.frame = 112; Zombie_Think(); }; void() zm_swipe_both_slow =[ 1, zm_swipe_both_slow1 ] {self.is_attacking = true; self.frame = 102; SetZombieHitBox(BASE_BBOX); Zombie_Think(); }; void() zm_swipe_both_slow1 =[ 2, zm_swipe_both_slow2 ] {self.frame = 103; Zombie_Think(); }; void() zm_swipe_both_slow2 =[ 3, zm_swipe_both_slow3 ] {self.frame = 104; Zombie_Think(); }; void() zm_swipe_both_slow3 =[ 4, zm_swipe_both_slow4 ] {zombie_attack2(); self.frame = 105; Zombie_Think(); }; void() zm_swipe_both_slow4 =[ 5, zm_swipe_both_slow5 ] {self.frame = 106; Zombie_Think(); }; void() zm_swipe_both_slow5 =[ 6, zm_swipe_both_slow6 ] {self.frame = 107; Zombie_Think(); }; void() zm_swipe_both_slow6 =[ 7, zm_swipe_both_slow7 ] {self.frame = 108; Zombie_Think(); }; void() zm_swipe_both_slow7 =[ 8, zm_swipe_both_slow8 ] {self.frame = 109; Zombie_Think(); }; void() zm_swipe_both_slow8 =[ 9, zm_swipe_both_slow9 ] {self.frame = 110; Zombie_Think(); }; void() zm_swipe_both_slow9 =[ 10, zombie_decide ] {zombie_attack2(); self.is_attacking = false; self.frame = 111; Zombie_Think(); }; void() zm_swipe_both_fast =[ 1, zm_swipe_both_fast1 ] {self.is_attacking = true; self.frame = 104; SetZombieHitBox(BASE_BBOX); Zombie_Think(); }; void() zm_swipe_both_fast1 =[ 2, zm_swipe_both_fast2 ] {zombie_attack2(); self.frame = 105; Zombie_Think(); }; void() zm_swipe_both_fast2 =[ 3, zm_swipe_both_fast3 ] {self.frame = 106; Zombie_Think(); }; void() zm_swipe_both_fast3 =[ 4, zm_swipe_both_fast4 ] {self.frame = 109; Zombie_Think(); }; void() zm_swipe_both_fast4 =[ 5, zm_swipe_both_fast5 ] {self.frame = 110; Zombie_Think(); }; void() zm_swipe_both_fast5 =[ 6, zm_swipe_both_fast6 ] {self.frame = 111; Zombie_Think(); }; void() zm_swipe_both_fast6 =[ 7, zombie_decide ] {zombie_attack2(); self.is_attacking = false; self.frame = 112; Zombie_Think(); }; void(float which) zombie_attack_choose = { self.angles_y = vectoyaw(self.enemy.origin - self.origin); if(which != 1) { if(random() > 0.4) { return; } } play_sound_z(1); // // choose what attack to play // // cypress -- we used to do a really cool thing here where // zombies could only attack with an arm they had, but this // became problematic for repetitive animations + it really // made double-swiping stand out :( maybe one day we could // have this back! float attack_type = random(); float attack_is_slow = (random() < 0.5); // :^) // Right Arm if (attack_type < 0.33) { // Slow if (attack_is_slow) zm_swipe_right_slow(); // Fast else zm_swipe_right_fast(); } // Left Arm else if (attack_type < 0.66) { // Slow if (attack_is_slow) zm_swipe_left_slow(); // Fast else zm_swipe_left_fast(); } // Both (right, followed by left arm) else { // Slow if (attack_is_slow) zm_swipe_both_slow(); // Fast else zm_swipe_both_fast(); } }; $frame zda1 zda2 zda3 zda4 zda5 zda6 zda7 zda8 zda9 zda10 zda11 zda12 zda13 zda14 void() zombie_zda =[ $zda1, zombie_zda1 ] {self.frame = 0;zombie_attack_choose(0);SetZombieHitBox(IDLE_BBOX);Zombie_Think();}; void() zombie_zda1 =[ $zda2, zombie_zda2 ] {self.frame = 1;zombie_attack_choose(0);Zombie_Think();}; void() zombie_zda2 =[ $zda3, zombie_zda3 ] {self.frame = 2;zombie_attack_choose(0);Zombie_Think();}; void() zombie_zda3 =[ $zda4, zombie_zda4 ] {self.frame = 3;zombie_attack_choose(0);Zombie_Think();}; void() zombie_zda4 =[ $zda5, zombie_zda5 ] {self.frame = 4;zombie_attack_choose(0);Zombie_Think();}; void() zombie_zda5 =[ $zda6, zombie_zda6 ] {self.frame = 5;zombie_attack_choose(0);Zombie_Think();}; void() zombie_zda6 =[ $zda7, zombie_zda7 ] {self.frame = 6;zombie_attack_choose(0);Zombie_Think();}; void() zombie_zda7 =[ $zda8, zombie_zda8 ] {self.frame = 7;zombie_attack_choose(0);Zombie_Think();}; void() zombie_zda8 =[ $zda9, zombie_zda9 ] {self.frame = 8;zombie_attack_choose(0);Zombie_Think();}; void() zombie_zda9 =[ $zda10, zombie_zda10 ] {self.frame = 9;zombie_attack_choose(0);Zombie_Think();}; void() zombie_zda10 =[ $zda12, zombie_zda11 ] {self.frame = 10;zombie_attack_choose(0);Zombie_Think();}; void() zombie_zda11 =[ $zda13, zombie_zda12 ] {self.frame = 11;zombie_attack_choose(0);Zombie_Think();}; void() zombie_zda12 =[ $zda14, zombie_zda1 ] {self.frame = 12;zombie_attack_choose(1);Zombie_Think();}; void() zombie_attack = { self.velocity = '0 0 0'; if(self.state == 1) // If the zombie is in this state (rising, or something else) they shouldn't be able to attack! return; if (self.electro_targeted == true) return; if(self.outside == TRUE) { self.angles_y = self.goalentity.angles_y; } else { self.angles_y = vectoyaw(self.enemy.origin - self.origin); } if(self.crawling == TRUE) { if(self.outside == TRUE) crawler_rip_board1(); else crawler_da1();//crawler delay attack } else { //zombie_attack_through_w1(); if(self.outside == TRUE) { if(random() < 0.30) { local entity who; local float found; found = 0; who = findradius(self.origin, 70); while (who != world && found == false) { if(who.classname == "player") { found = true; } else who = who.chain; } if (found == true) { zombie_attack_through_w1(); return; } } if(random() < 0.5) zombie_ripboardA1(); else zombie_ripboardB1(); } else { zombie_zda();//Zombie Delay Attack } } }; //==========================Falling Code========================== void CheckLand() = { if ((self.flags & FL_ONGROUND)) { if (self.fall == TRUE) { self.fall = FALSE; self.th_land(); } } }; //Falling //149-152 $frame fall1 fall2 fall3 fall4 void() zombie_fall1 =[ $fall1, zombie_fall2 ] {self.frame = 149;SetZombieHitBox(BASE_BBOX);self.fall = TRUE;CheckLand();Zombie_Think();}; void() zombie_fall2 =[ $fall2, zombie_fall3 ] {self.frame = 150;CheckLand();Zombie_Think();}; void() zombie_fall3 =[ $fall3, zombie_fall4 ] {self.frame = 151;CheckLand();Zombie_Think();}; void() zombie_fall4 =[ $fall4, zombie_fall3 ] {self.frame = 152;CheckLand();Zombie_Think();}; //Landing //153-159 $frame land1 land2 land3 land4 land5 land6 land7 void() zombie_land1 =[ $land1, zombie_land2 ] {self.frame = 153;SetZombieHitBox(BASE_BBOX);Zombie_Think();zombie_footstep();zombie_footstep();}; void() zombie_land2 =[ $land2, zombie_land3 ] {self.frame = 154;Zombie_Think();}; void() zombie_land3 =[ $land3, zombie_land4 ] {self.frame = 155;Zombie_Think();}; void() zombie_land4 =[ $land4, zombie_land5 ] {self.frame = 156;Zombie_Think();}; void() zombie_land5 =[ $land5, zombie_land6 ] {self.frame = 157;Zombie_Think();}; void() zombie_land6 =[ $land6, zombie_land7 ] {self.frame = 158;Zombie_Think();}; void() zombie_land7 =[ $land7, Zombie_Walk_Setup ] {self.frame = 159;Zombie_Think();}; void() removeZombie = { self.aistatus = "0"; setmodel(self,""); // Hounds don't gib. if (self.classname != "ai_dog") { setmodel(self.larm,""); setmodel(self.rarm,""); setmodel(self.head,""); #ifdef FTE remove(self.larm); remove(self.rarm); remove(self.head); #else updateLimb (self, 0, world); updateLimb (self, 1, world); updateLimb (self, 2, world); #endif // FTE } setorigin(self,'0 0 0'); setorigin (self.goaldummy, '0 0 0'); // cypress (20 dec 2023) -- added a nextthink() call here // so the next server frame we'll have always run SUB_Null(). // there was some weird behavior here where a zombie's th_idle() // call would carry forward interrupting the procedure for walking // to a barricade. self.nextthink = time + 0.05; self.think = SUB_Null; self.classname = "freeZombieEntity"; self.goalentity = world; self.enemy = world; self.solid = 0; self.movetype = 0; self.outside = TRUE; self.hop_step = 0; self.onfire = false; self.fire_timeout = 0; self.calc_time = 0; self.tries = 0; self.takedamage = DAMAGE_NO; self.flags = 0; self.crawling = 0; self.bleedingtime = 0; self.iszomb = 0; // 1 for alive AI, 0 for corpses / unallocated reserevd ents self.owner = world; self.spawnflags = 0; self.is_attacking = false; self.yaw_speed = 0; self.health = 0; self.th_die = SUB_Null; self.th_walk = SUB_Null; self.th_melee = SUB_Null; self.th_idle = SUB_Null; self.th_windowhop = SUB_Null; self.th_fall = SUB_Null; self.th_falling = SUB_Null; self.th_land = SUB_Null; self.th_jump = SUB_Null; self.th_grabledge = SUB_Null; self.th_diewunder = SUB_Null; //Disabling collision bboxes SetZombieHitBox(EMPTY_BBOX); }; ///////////////////////////////////////////////////////////////////// ZOMBIE DEATH 1 //123-133 $frame death1 death2 death3 death4 death5 death6 death7 death8 death9 death10 death11 void() zombie_deathA1 =[ $death1, zombie_death2 ] {if (self.onfire) {Effect_Fire(self.origin);} self.frame = 123;}; void() zombie_death2 =[ $death2, zombie_death3 ] {self.frame = 124;}; void() zombie_death3 =[ $death3, zombie_death4 ] {self.frame = 125;}; void() zombie_death4 =[ $death4, zombie_death5 ] {if (self.onfire) {Effect_Fire(self.origin);} self.frame = 126;}; void() zombie_death5 =[ $death5, zombie_death6 ] {self.frame = 127;}; void() zombie_death6 =[ $death6, zombie_death7 ] {self.frame = 128;}; void() zombie_death7 =[ $death7, zombie_death8 ] {if (self.onfire) {Effect_Fire(self.origin);} self.frame = 129;}; void() zombie_death8 =[ $death8, zombie_death9 ] {self.frame = 130;}; void() zombie_death9 =[ $death9, zombie_death10 ] {self.frame = 131;}; void() zombie_death10 =[ $death10, zombie_death11 ] {self.frame = 132;zombie_footstep();}; void() zombie_death11 =[ $death11, SUB_Null ] {if (self.onfire) {Effect_Fire(self.origin);} self.iszomb = 0; self.nextthink = time + 3; self.think = removeZombie; self.frame = 133;}; //////////////////////////////////////////////////////////////////////////////////// ZOMBIE DEATH 2 //134-138 $frame deathB1 deathB2 deathB3 deathB4 deathB5 void() zombie_deathB1 =[ $deathB1, zombie_deathB2 ] {if (self.onfire) {Effect_Fire(self.origin);} self.frame = 134;}; void() zombie_deathB2 =[ $deathB2, zombie_deathB3 ] {self.frame = 135;}; void() zombie_deathB3 =[ $deathB3, zombie_deathB4 ] {if (self.onfire) {Effect_Fire(self.origin);} self.frame = 136;}; void() zombie_deathB4 =[ $deathB4, zombie_deathB5 ] {self.frame = 137;zombie_footstep();}; void() zombie_deathB5 =[ $deathB5, SUB_Null ] {if (self.onfire) {Effect_Fire(self.origin);} self.iszomb = 0; self.nextthink = time + 3; self.think = removeZombie; self.frame = 138;}; //////////////////////////////////////////////////////////////////////////////////// ZOMBIE DEATH 3 //139-148 $frame deathC1 deathC2 deathC3 deathC4 deathC5 deathC6 deathC7 deathC8 deathC9 deathC10 void() zombie_deathC1 =[ $deathC1, zombie_deathC2 ] {if (self.onfire) {Effect_Fire(self.origin);} self.frame = 139;}; void() zombie_deathC2 =[ $deathC2, zombie_deathC3 ] {self.frame = 140;}; void() zombie_deathC3 =[ $deathC3, zombie_deathC4 ] {self.frame = 141;}; void() zombie_deathC4 =[ $deathC4, zombie_deathC5 ] {if (self.onfire) {Effect_Fire(self.origin);} self.frame = 142;}; void() zombie_deathC5 =[ $deathC5, zombie_deathC6 ] {self.frame = 143;}; void() zombie_deathC6 =[ $deathC6, zombie_deathC7 ] {self.frame = 144;}; void() zombie_deathC7 =[ $deathC7, zombie_deathC8 ] {if (self.onfire) {Effect_Fire(self.origin);} self.frame = 145;}; void() zombie_deathC8 =[ $deathC8, zombie_deathC9 ] {self.frame = 146;zombie_footstep();}; void() zombie_deathC9 =[ $deathC9, zombie_deathC10 ] {self.frame = 147;}; void() zombie_deathC10 =[ $deathC10, SUB_Null ] {if (self.onfire) {Effect_Fire(self.origin);} self.iszomb = 0; self.nextthink = time + 3; self.think = removeZombie; self.frame = 148;}; void(entity ent) Zombie_Death_Cleanup = { // Already dead if(ent.aistatus == "0") { return; } // Insta-Kill should always cause the head to gib on Zombie death. if (ent.head && instakill_finished > time) { makevectors(ent.head.owner.angles); vector where = ent.origin + (ent.head.view_ofs_x * v_right) + (ent.head.view_ofs_y * v_forward) + (ent.head.view_ofs_z * v_up); spawn_gibs(where); ent.head.deadflag = false; ent.head.solid = SOLID_NOT; setmodel(ent.head, ""); ent.head.frame = 0; #ifndef FTE updateLimb (ent, 0, world); #endif // FTE } ent.aistatus = "0"; ent.solid = SOLID_NOT; ent.movetype = MOVETYPE_NONE; ent.takedamage = DAMAGE_NO; ent.head.classname = ""; ent.head.solid = SOLID_NOT; ent.head.movetype = MOVETYPE_NONE; ent.head.takedamage = DAMAGE_NO; ent.larm.solid = SOLID_NOT; ent.larm.movetype = MOVETYPE_NONE; ent.larm.takedamage = DAMAGE_NO; ent.rarm.solid = SOLID_NOT; ent.rarm.movetype = MOVETYPE_NONE; ent.rarm.takedamage = DAMAGE_NO; sound(ent, CHAN_WEAPON, "sounds/null.wav" ,1, ATTN_NORM); sound(ent, CHAN_VOICE, "sounds/null.wav" ,1, ATTN_NORM); sound(ent, CHAN_BODY, "sounds/null.wav" ,1, ATTN_NORM); sound(ent, CHAN_ITEM, "sounds/null.wav" ,1, ATTN_NORM); ent.usedent = world; if(ent.goalentity.classname == "window") { if(ent.goalentity.box1owner == ent) ent.goalentity.box1owner = world; if(ent.goalentity.box2owner == ent) ent.goalentity.box2owner = world; if(ent.goalentity.box3owner == ent) ent.goalentity.box3owner = world; if(ent.goalentity.usedent == ent) ent.goalentity.usedent = world; } ent.health = 0; ent.respawn_iterator = 0; Remaining_Zombies = Remaining_Zombies - 1; } void() Zombie_Death = { Zombie_Death_Cleanup(self); // Death Noises if (self.electro_targeted == false) play_sound_z(3); else play_sound_z(5); //Gotta' make sure we set it back down instead of glitching it up, yo' if(self.s_time > 0 && sounds_playing > 0) { sounds_playing --; self.s_time = 0; } if(self.outside == false && self.electro_targeted == false) { if (totalpowerups < POWERUPS_PER_ROUND) { if (total_powerup_points >= powerup_score_threshold) { Spawn_Powerup(self.origin, -1); powerup_activate *= 1.14; powerup_score_threshold = total_powerup_points + powerup_activate; } else if (random () <= 0.02) Spawn_Powerup(self.origin, -1); } } if(self.crawling == TRUE) { crawler_die1(); } else { if(random() < 0.3) { zombie_deathA1(); } else if(random() < 0.5) { zombie_deathB1(); } else { zombie_deathC1(); } } }; // // -------------------- // Electric Damage // -------------------- // // // Z_ElectroShock // Mark Zombie to die by non-Waffe Electricity. // void() Z_ElectroShock = { // Mark the Zombie as to-be-dead self.electro_targeted = true; // Determine a time for the Zombie to die. (0.1-1.25s) self.death_timer = (rint((random() * 11.5) + 1)/10) + time; self.death_timer_activated = true; // Spawn a Sparkle if(self.crawling == true) { tesla_spark(self.origin - '0 0 18'); } else { tesla_spark(self.origin + '0 0 13'); } // Zombie_Tesla_Light(); // Decide what to Gib float r = random(); // Head? if (r < 0.20 && self.head.deadflag) { self.head.frame = 0; self.head.health = 0; self.head.deadflag = false; self.head.solid = SOLID_NOT; setmodel(self.head, ""); makevectors(self.angles); spawn_gibs(self.origin + (self.head.view_ofs_x * v_right) + (self.head.view_ofs_y * v_forward) + (self.head.view_ofs_z * v_up)); SpawnBlood(self.origin, self.origin, 50); } // Right Arm? r = random(); if (r < 0.20 && self.rarm.deadflag) { self.rarm.frame = 0; self.rarm.health = 0; self.rarm.deadflag = false; self.rarm.solid = SOLID_NOT; setmodel(self.rarm, ""); makevectors(self.angles); spawn_gibs(self.origin + (self.rarm.view_ofs_x * v_right) + (self.rarm.view_ofs_y * v_forward) + (self.rarm.view_ofs_z * v_up)); SpawnBlood(self.origin, self.origin, 50); } // Left Arm? r = random(); if (r < 0.20 && self.larm.deadflag) { self.larm.frame = 0; self.larm.health = 0; self.larm.deadflag = false; self.larm.solid = SOLID_NOT; setmodel(self.larm, ""); makevectors(self.angles); spawn_gibs(self.origin + (self.larm.view_ofs_x * v_right) + (self.larm.view_ofs_y * v_forward) + (self.larm.view_ofs_z * v_up)); SpawnBlood(self.origin, self.origin, 50); } // Play the first Electro-Sound play_sound_z(5); } /////////////////////ZOMBIE WAFFE STUFF///////////////////// // Wunder'd // 149-152 (FIXME - animate wunder'd zombies) $frame wunder1 wunder2 wunder3 wunder4 wunder5 wunder6 wunder7 wunder8 wunder9 wunder10 void() zombie_wunder1 =[ $wunder1, zombie_wunder2 ] {tesla_arc(); play_sound_z(4); self.frame = 149;}; void() zombie_wunder2 =[ $wunder2, zombie_wunder3 ] {tesla_arc(); self.frame = 150;}; void() zombie_wunder3 =[ $wunder3, zombie_wunder4 ] {tesla_arc(); self.frame = 151;}; void() zombie_wunder4 =[ $wunder4, zombie_wunder5 ] {tesla_arc(); self.frame = 152;}; void() zombie_wunder5 =[ $wunder5, zombie_wunder6 ] {tesla_arc(); self.frame = 151;}; void() zombie_wunder6 =[ $wunder6, zombie_wunder7 ] {tesla_arc(); self.frame = 152;}; void() zombie_wunder7 =[ $wunder7, zombie_wunder8 ] {tesla_arc(); self.frame = 151;}; void() zombie_wunder8 =[ $wunder8, zombie_wunder9 ] {tesla_arc(); play_sound_z(3); self.frame = 152;}; void() zombie_wunder9 =[ $wunder9, zombie_wunder10 ] {tesla_arc(); self.frame = 151;}; void() zombie_wunder10 =[ $wunder10, SUB_Null ] { tesla_arc(); self.iszomb = 0; self.nextthink = time + 3; self.think = removeZombie;self.frame = 152; // Play final death anim: if(random() < 0.3) { zombie_deathA1(); } else if(random() < 0.5) { zombie_deathB1(); } else { zombie_deathC1(); } }; void() Zombie_Tesla_Death = { Zombie_Death_Cleanup(self); if(self.crawling == true) { tesla_spark(self.origin - '0 0 18'); crawler_death_wunder1(); } else { tesla_spark(self.origin + '0 0 13'); zombie_wunder1(); } }; // // Zombie_HeadCanGib(weapon) // Checks if a Zombie is in a state where // it's head can gib. // float(entity who, float weapon) Zombie_HeadCanGib = { // First, is this weapon even capable? if (!WepDef_WeaponCanGibEnemy(weapon)) return false; // Has it's head already been ripped off? if (!who.head.deadflag) return false; // If they have more than 10%(?) of health, // don't gib. float health_ratio = who.head.health / z_health; if (health_ratio > 0.10) return false; // Seems to pass, let it gib! return true; }; /////////////////////ZOMBIE SPAWNING///////////////////// void() zombieRise = { //better not move wile rising, would happen sometimes self.velocity_x = 0; self.velocity_y = 0; if(self.frame < 13)//begin { self.frame = 12;//since we're going to add one anyways self.state = 1;//don't make crawler, yo! } if(self.frame == 36) { self.state = 0; if(self.crawling == 2) { makeCrawler(self); return; } self.th_walk(); return; } self.frame ++; self.think = zombieRise; self.nextthink = time + 0.1; //LinkZombiesHitbox(); //bprint (PRINT_HIGH, "Linked hitboxes"); }; void() spawn_zombie = { setsize(self, '0 0 0', '0 0 0'); if (self.spawnflags & INACTIVE) { if (cvar("developer")) setmodel(self, "models/player.mdl"); self.classname = "spawn_zombie_in"; } else { if (cvar("developer")) setmodel(self, "models/ai/zfull.mdl"); self.classname = "spawn_zombie"; self.spawn_id = zombie_spawn_points; zombie_spawn_points++; } //self.think = zombie_spawn_think; //self.nextthink = time + 0.5; self.solid = SOLID_NOT; }; void(entity where) spawn_a_zombieB; void() set_z_health = { if(rounds <= 10) { z_health = 50 + (rounds * 100); } else { local float i; i = rounds - 10; z_health = 1040; while(i > 0) { z_health *= 1.1; i--; } } }; // // Zombie_ReassignSpawnIDs() // To be called whenever we mess with a spawn point, // this makes sure that spawn_a_zombieA() can never // try to spawn a zombie at a point which index is // inactive. // void() Zombie_ReassignSpawnIDs = { float num_spawns = zombie_spawn_points; // First, clear the list. zombie_spawn_points = 0; while(num_spawns > 0) { entity zombie_spawn = findfloat(world, spawn_id, num_spawns); if (zombie_spawn) { zombie_spawn.spawn_id = 0; } num_spawns--; if (num_spawns) zombie_spawn = findfloat(world, spawn_id, num_spawns); } // Now do the re-assignment entity zombie_spawns = find(world, classname, "spawn_zombie"); while(zombie_spawns) { zombie_spawns.spawn_id = zombie_spawn_points; zombie_spawn_points++; zombie_spawns = find(zombie_spawns, classname, "spawn_zombie"); } } inline entity() getFreeZombieEnt = { entity who; who = find(world,classname,"freeZombieEntity"); return who; }; float() spawn_a_zombieA = { // cypress (20 dec 2023) -- rewrote this routine to be a little less // needlessly bloaty/bogged down and be in greater parity. // don't bother doing anything if it's not even time yet (avoids needless // iteration over ent chain) if (zombie_spawn_timer > time) return false; // look for a free entity entity zombie_ent = getFreeZombieEnt(); // no free entity found, maximum are in play. if (!zombie_ent) return false; // look for a random spawn point. note -- before there was a routine that // prevented spawns from repeating one after the other before. i liked the // evened out use of the playspace at the beginning of the game but this // isn't standard CoD functionality and it has negative consequences with // larger areas. entity zombie_spawn; float zombie_spawn_id = rint((random() * (zombie_spawn_points - 1))); // starts at 0! zombie_spawn = find(world, classname, "spawn_zombie"); while(zombie_spawn != world) { if (zombie_spawn.spawn_id == zombie_spawn_id) break; zombie_spawn = find(zombie_spawn, classname, "spawn_zombie"); } if (zombie_spawn == world) { if (cvar("developer")) bprint(PRINT_HIGH, "spawn_a_zombieA: No active spawn point exists! Bailing!\n"); return false; } // prompt stage 2: the actual spawning of the zombie. spawn_a_zombieB(zombie_spawn); spawn_delay = time + delay_at_round; return true; }; void(float i) spawnSingleZombEnt = { local entity zSpawn; zSpawn = spawn(); zSpawn.classname = "freeZombieEntity"; zSpawn.aistatus = "0"; zSpawn.goaldummy = spawn(); if (cvar("developer")) { setmodel(zSpawn.goaldummy, "models/way/normal_way.spr"); } zSpawn.goaldummy.classname = "waypoint_target"; zSpawn.head = spawn(); zSpawn.head.classname = "in_ai_zombie_head"; zSpawn.head.owner = zSpawn; zSpawn.head.solid = SOLID_NOT; zSpawn.head.movetype = MOVETYPE_STEP; zSpawn.head.takedamage = DAMAGE_NO; #ifndef FTE updateLimb (zSpawn, 0, zSpawn.head); #endif // FTE zSpawn.larm = spawn(); zSpawn.larm.classname = "in_ai_zombie_larm"; zSpawn.larm.owner = zSpawn; zSpawn.larm.solid = SOLID_NOT; zSpawn.larm.movetype = MOVETYPE_STEP; zSpawn.larm.takedamage = DAMAGE_NO; #ifndef FTE updateLimb (zSpawn, 1, zSpawn.larm); #endif // FTE zSpawn.rarm = spawn(); zSpawn.rarm.classname = "in_ai_zombie_rarm"; zSpawn.rarm.owner = zSpawn; zSpawn.rarm.solid = SOLID_NOT; zSpawn.rarm.movetype = MOVETYPE_STEP; zSpawn.rarm.takedamage = DAMAGE_NO; #ifndef FTE updateLimb (zSpawn, 2, zSpawn.rarm); #endif // FTE }; void(entity szombie) SetUpHitBoxes = { szombie.head.solid = SOLID_CORPSE; szombie.head.movetype = MOVETYPE_STEP; szombie.head.classname = "ai_zombie_head"; szombie.head.takedamage = DAMAGE_YES; szombie.larm.solid = SOLID_CORPSE; szombie.larm.movetype = MOVETYPE_STEP; szombie.larm.classname = "ai_zombie_larm"; szombie.larm.takedamage = DAMAGE_YES; szombie.rarm.solid = SOLID_CORPSE; szombie.rarm.movetype = MOVETYPE_STEP; szombie.rarm.classname = "ai_zombie_rarm"; szombie.rarm.takedamage = DAMAGE_YES; #ifdef FTE szombie.head.dimension_solid = HITBOX_DIM_LIMBS; szombie.larm.dimension_solid = HITBOX_DIM_LIMBS; szombie.rarm.dimension_solid = HITBOX_DIM_LIMBS; #endif // FTE local entity oldself = self; self = szombie; SetZombieHitBox(BASE_BBOX); self = oldself; }; void(entity szombie) SetZombieWalk = { float zombie_move_speed_threshold = (rounds - 1) * 8; float walktype_chance = rint((random() * 35)) + zombie_move_speed_threshold; // Walking Zombie if (walktype_chance <= 35) { float which_walk_anim = random(); if (which_walk_anim < 0.33) szombie.walktype = 1; else if (which_walk_anim < 0.66) szombie.walktype = 2; else szombie.walktype = 3; } // Jogging Zombie else if (walktype_chance <= 70) { szombie.walktype = 4; } // Sprinting Zombie else { szombie.walktype = 5; } }; void() spawnAllZombEnts = { local float i; i = 0; // cypress -- let host engine dictate // max ai at once. #ifdef FTE while(i < 24) #else while(i < nzp_maxai()) #endif // FTE { spawnSingleZombEnt(i); i++; } }; void(entity where) spawn_a_zombieB = { local entity szombie;//USED FOR WHAT TO SPAWN //szombie = spawn(); szombie = getFreeZombieEnt(); if(szombie == world || zombie_spawn_timer > time) { //bprint(PRINT_HIGH, "STOPPED AT B\n"); //dprint("Out of zombie entities \n"); return; } #ifdef FTE szombie.head = spawn(); szombie.rarm = spawn(); szombie.larm = spawn(); szombie.head.owner = szombie.rarm.owner = szombie.larm.owner = szombie; #endif // FTE szombie.origin = where.origin; szombie.frame = 0; szombie.target = where.target; //blubsvel //szombie.movetype = MOVETYPE_STEP; szombie.head.deadflag = 1; szombie.larm.deadflag = 1; szombie.rarm.deadflag = 1; setmodel(szombie.head, "models/ai/zh^.mdl"); setmodel(szombie.rarm, "models/ai/zar(.mdl"); setmodel(szombie.larm, "models/ai/zal(.mdl"); #ifndef FTE updateLimb (szombie, 0, szombie.head); updateLimb (szombie, 1, szombie.larm); updateLimb (szombie, 2, szombie.rarm); #endif // FTE szombie.solid = SOLID_CORPSE; #ifdef FTE szombie.dimension_solid = HITBOX_DIM_ZOMBIES; #endif // FTE szombie.movetype = MOVETYPE_WALK; setmodel(szombie, "models/ai/zb%.mdl"); szombie.hop_step = 0; // cypress (20 dec 2023) -- see comment from removeZombie(), // this is just a sanity check just in case someone decides // to play around with a freeZombieEntity and breaks that check.. szombie.nextthink = time + 0.05; szombie.think = SUB_Null; szombie.gravity = 1.0; if (map_compatibility_mode == MAP_COMPAT_BETA) { szombie.mins = '-6 -6 -24'; szombie.maxs = '6 6 22'; #ifdef FTE // Need to force-set the hull for FTE or else Zombie setorigin() // calls will fail in tight spaces. szombie.hull = 1; #endif // FTE } else { szombie.mins = '-8 -8 -32'; szombie.maxs = '8 8 30'; } setsize (szombie, szombie.mins, szombie.maxs); //==================================== if(pointcontents(szombie.origin - '0 0 36') == -2) { while(pointcontents (szombie.origin - '0 0 36') == -2) { szombie.origin = szombie.origin + '0 0 1'; setorigin(szombie,szombie.origin ); } } szombie.classname = "ai_zombie"; szombie.aistatus = "1"; setorigin (szombie.goaldummy, '0 0 0'); szombie.origin_z = szombie.origin_z + 1; szombie.outside = true; szombie.takedamage = DAMAGE_YES; setorigin(szombie, szombie.origin); szombie.flags = szombie.flags | FL_PARTIALGROUND | FL_MONSTER; szombie.spawnflags = where.spawnflags; //////////FIX FOR OUTSIDE if(szombie.spawnflags & 4) { szombie.outside = FALSE; } ///////// szombie.ideal_yaw = szombie.angles_y; szombie.yaw_speed = 20; szombie.iszomb = 1; szombie.death_timer = 0; szombie.death_timer_activated = false; szombie.electro_targeted = false; // We used to set different limb health, too, but we now handle any limb damage differences in weapon stats. szombie.health = szombie.head.health = szombie.larm.health = szombie.rarm.health = z_health; szombie.th_die = Zombie_Death; szombie.th_walk = Zombie_Walk_Setup; szombie.th_melee = zombie_attack; szombie.th_idle = zombie_idle; szombie.th_windowhop = zombie_hop1; szombie.th_fall = zombie_fall1; szombie.th_land = zombie_land1; szombie.th_diewunder = Zombie_Tesla_Death; //szombie.th_jump = zombie_jump1; //szombie.th_grabledge = zombie_grabledge1; //================================================================================================== SetZombieWalk(szombie); //================================================================================================== SetUpHitBoxes(szombie); //szombie.walktype = 5; //////////////////////////////////////////////////// szombie.reload_delay = 30 + time;//save floats, equals respawn time. local entity old_self; old_self = self; self = szombie; if (self.spawnflags & 2)//RISER { zombieRise(); } else self.th_walk(); self = old_self; //LinkZombiesHitbox(); // // Zombie skin setting // float tex; tex = random(); if (tex > 0.75) szombie.skin = 0; else if (tex > 0.50) szombie.skin = 1; else if (tex > 0.25) szombie.skin = 2; else szombie.skin = 3; szombie.head.skin = szombie.larm.skin = szombie.rarm.skin = szombie.skin; if (map_compatibility_mode == MAP_COMPAT_BETA) szombie.head.scale = szombie.larm.scale = szombie.rarm.scale = szombie.scale = 0.73; // set up timer for next spawn zombie_spawn_timer = zombie_spawn_delay + time; }; void() zombie_dummy = { self.frame = 0; self.solid = SOLID_SLIDEBOX; self.movetype = MOVETYPE_STEP; setmodel(self, "models/ai/zfull.mdl"); setsize (self, '-8 -8 -32', '8 8 30'); setorigin(self, self.origin); self.classname = "ai_zombie"; self.takedamage = DAMAGE_YES; self.flags = self.flags | FL_PARTIALGROUND | FL_MONSTER; self.health = 999999; SetUpHitBoxes(self); };