zombie.qc 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701
  1. /* Copyright (C) 1996-2022 id Software LLC
  2. This program is free software; you can redistribute it and/or modify
  3. it under the terms of the GNU General Public License as published by
  4. the Free Software Foundation; either version 2 of the License, or
  5. (at your option) any later version.
  6. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  9. GNU General Public License for more details.
  10. You should have received a copy of the GNU General Public License
  11. along with this program; if not, write to the Free Software
  12. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  13. See file, 'COPYING', for details.
  14. */
  15. /*
  16. ==============================================================================
  17. ZOMBIE
  18. ==============================================================================
  19. */
  20. $cd /raid/quake/id1/models/zombie
  21. $origin 0 0 24
  22. $base base
  23. $skin skin
  24. $frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8
  25. $frame stand9 stand10 stand11 stand12 stand13 stand14 stand15
  26. $frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9 walk10 walk11
  27. $frame walk12 walk13 walk14 walk15 walk16 walk17 walk18 walk19
  28. $frame run1 run2 run3 run4 run5 run6 run7 run8 run9 run10 run11 run12
  29. $frame run13 run14 run15 run16 run17 run18
  30. $frame atta1 atta2 atta3 atta4 atta5 atta6 atta7 atta8 atta9 atta10 atta11
  31. $frame atta12 atta13
  32. $frame attb1 attb2 attb3 attb4 attb5 attb6 attb7 attb8 attb9 attb10 attb11
  33. $frame attb12 attb13 attb14
  34. $frame attc1 attc2 attc3 attc4 attc5 attc6 attc7 attc8 attc9 attc10 attc11
  35. $frame attc12
  36. $frame paina1 paina2 paina3 paina4 paina5 paina6 paina7 paina8 paina9 paina10
  37. $frame paina11 paina12
  38. $frame painb1 painb2 painb3 painb4 painb5 painb6 painb7 painb8 painb9 painb10
  39. $frame painb11 painb12 painb13 painb14 painb15 painb16 painb17 painb18 painb19
  40. $frame painb20 painb21 painb22 painb23 painb24 painb25 painb26 painb27 painb28
  41. $frame painc1 painc2 painc3 painc4 painc5 painc6 painc7 painc8 painc9 painc10
  42. $frame painc11 painc12 painc13 painc14 painc15 painc16 painc17 painc18
  43. $frame paind1 paind2 paind3 paind4 paind5 paind6 paind7 paind8 paind9 paind10
  44. $frame paind11 paind12 paind13
  45. $frame paine1 paine2 paine3 paine4 paine5 paine6 paine7 paine8 paine9 paine10
  46. $frame paine11 paine12 paine13 paine14 paine15 paine16 paine17 paine18 paine19
  47. $frame paine20 paine21 paine22 paine23 paine24 paine25 paine26 paine27 paine28
  48. $frame paine29 paine30
  49. $frame cruc_1 cruc_2 cruc_3 cruc_4 cruc_5 cruc_6 cruc_7
  50. $frame cruc_8 cruc_9 cruc_10 cruc_11 cruc_12 cruc_13
  51. $frame cruc_14 cruc_15 cruc_16
  52. float SPAWN_CRUCIFIED = 1;
  53. float SPAWN_LYING = 2;
  54. float SPAWN_AMBUSH = 4;
  55. float SPAWN_SNEAKY = 8;
  56. //=============================================================================
  57. .float inpain;
  58. void() zombie_escape1;
  59. void() zombie_stand1 =[ $stand1, zombie_stand2 ] {ai_stand();};
  60. void() zombie_stand2 =[ $stand2, zombie_stand3 ] {ai_stand();};
  61. void() zombie_stand3 =[ $stand3, zombie_stand4 ] {ai_stand();};
  62. void() zombie_stand4 =[ $stand4, zombie_stand5 ] {ai_stand();};
  63. void() zombie_stand5 =[ $stand5, zombie_stand6 ] {ai_stand();};
  64. void() zombie_stand6 =[ $stand6, zombie_stand7 ] {ai_stand();};
  65. void() zombie_stand7 =[ $stand7, zombie_stand8 ] {ai_stand();};
  66. void() zombie_stand8 =[ $stand8, zombie_stand9 ] {ai_stand();};
  67. void() zombie_stand9 =[ $stand9, zombie_stand10 ] {ai_stand();};
  68. void() zombie_stand10 =[ $stand10, zombie_stand11 ] {ai_stand();};
  69. void() zombie_stand11 =[ $stand11, zombie_stand12 ] {ai_stand();};
  70. void() zombie_stand12 =[ $stand12, zombie_stand13 ] {ai_stand();};
  71. void() zombie_stand13 =[ $stand13, zombie_stand14 ] {ai_stand();};
  72. void() zombie_stand14 =[ $stand14, zombie_stand15 ] {ai_stand();};
  73. void() zombie_stand15 =[ $stand15, zombie_stand1 ] {ai_stand();};
  74. // zombie_lurk is an improved version of what zombie did in zombie_crucXX
  75. // with an added check for enemies if they're sneaky types...
  76. void() zombie_lurk =
  77. {
  78. if (self.spawnflags & SPAWN_SNEAKY)
  79. {
  80. // not pausing before attack, but looking for player.
  81. if (!self.pain_finished)
  82. {
  83. if(FindTarget ())
  84. return;
  85. }
  86. else
  87. {
  88. // if we've waited long enough, pounce!
  89. if ( self.pain_finished < time )
  90. {
  91. self.think = zombie_escape1;
  92. self.nextthink = time + 0.1;
  93. return;
  94. }
  95. }
  96. }
  97. self.nextthink = time + 0.1 + random()*0.1;
  98. };
  99. void() zombie_cruc1 = [ $cruc_1, zombie_cruc2 ]
  100. {
  101. zombie_lurk();
  102. if (random() < 0.1)
  103. sound (self, CHAN_VOICE, "zombie/idle_w2.wav", 1, ATTN_STATIC);
  104. };
  105. void() zombie_cruc2 = [ $cruc_2, zombie_cruc3 ] { zombie_lurk(); };
  106. void() zombie_cruc3 = [ $cruc_3, zombie_cruc4 ] { zombie_lurk(); };
  107. void() zombie_cruc4 = [ $cruc_4, zombie_cruc5 ] { zombie_lurk(); };
  108. void() zombie_cruc5 = [ $cruc_5, zombie_cruc6 ] { zombie_lurk(); };
  109. void() zombie_cruc6 = [ $cruc_6, zombie_cruc1 ] { zombie_lurk(); };
  110. void() zombie_walk1 =[ $walk1, zombie_walk2 ] {ai_walk(0);};
  111. void() zombie_walk2 =[ $walk2, zombie_walk3 ] {ai_walk(2);};
  112. void() zombie_walk3 =[ $walk3, zombie_walk4 ] {ai_walk(3);};
  113. void() zombie_walk4 =[ $walk4, zombie_walk5 ] {ai_walk(2);};
  114. void() zombie_walk5 =[ $walk5, zombie_walk6 ] {ai_walk(1);};
  115. void() zombie_walk6 =[ $walk6, zombie_walk7 ] {ai_walk(0);};
  116. void() zombie_walk7 =[ $walk7, zombie_walk8 ] {ai_walk(0);};
  117. void() zombie_walk8 =[ $walk8, zombie_walk9 ] {ai_walk(0);};
  118. void() zombie_walk9 =[ $walk9, zombie_walk10 ] {ai_walk(0);};
  119. void() zombie_walk10 =[ $walk10, zombie_walk11 ] {ai_walk(0);};
  120. void() zombie_walk11 =[ $walk11, zombie_walk12 ] {ai_walk(2);};
  121. void() zombie_walk12 =[ $walk12, zombie_walk13 ] {ai_walk(2);};
  122. void() zombie_walk13 =[ $walk13, zombie_walk14 ] {ai_walk(1);};
  123. void() zombie_walk14 =[ $walk14, zombie_walk15 ] {ai_walk(0);};
  124. void() zombie_walk15 =[ $walk15, zombie_walk16 ] {ai_walk(0);};
  125. void() zombie_walk16 =[ $walk16, zombie_walk17 ] {ai_walk(0);};
  126. void() zombie_walk17 =[ $walk17, zombie_walk18 ] {ai_walk(0);};
  127. void() zombie_walk18 =[ $walk18, zombie_walk19 ] {ai_walk(0);};
  128. void() zombie_walk19 =[ $walk19, zombie_walk1 ] {
  129. ai_walk(0);
  130. if (random() < 0.2)
  131. sound (self, CHAN_VOICE, "zombie/z_idle.wav", 1, ATTN_IDLE);};
  132. void() zombie_run1 =[ $run1, zombie_run2 ] {ai_run(1);self.inpain = 0;};
  133. void() zombie_run2 =[ $run2, zombie_run3 ] {ai_run(1);};
  134. void() zombie_run3 =[ $run3, zombie_run4 ] {ai_run(0);};
  135. void() zombie_run4 =[ $run4, zombie_run5 ] {ai_run(1);};
  136. void() zombie_run5 =[ $run5, zombie_run6 ] {ai_run(2);};
  137. void() zombie_run6 =[ $run6, zombie_run7 ] {ai_run(3);};
  138. void() zombie_run7 =[ $run7, zombie_run8 ] {ai_run(4);};
  139. void() zombie_run8 =[ $run8, zombie_run9 ] {ai_run(4);};
  140. void() zombie_run9 =[ $run9, zombie_run10 ] {ai_run(2);};
  141. void() zombie_run10 =[ $run10, zombie_run11 ] {ai_run(0);};
  142. void() zombie_run11 =[ $run11, zombie_run12 ] {ai_run(0);};
  143. void() zombie_run12 =[ $run12, zombie_run13 ] {ai_run(0);};
  144. void() zombie_run13 =[ $run13, zombie_run14 ] {ai_run(2);};
  145. void() zombie_run14 =[ $run14, zombie_run15 ] {ai_run(4);};
  146. void() zombie_run15 =[ $run15, zombie_run16 ] {ai_run(6);};
  147. void() zombie_run16 =[ $run16, zombie_run17 ] {ai_run(7);};
  148. void() zombie_run17 =[ $run17, zombie_run18 ] {ai_run(3);};
  149. void() zombie_run18 =[ $run18, zombie_run1 ] {
  150. ai_run(8);
  151. if (random() < 0.2)
  152. sound (self, CHAN_VOICE, "zombie/z_idle.wav", 1, ATTN_IDLE);
  153. if (random() > 0.8)
  154. sound (self, CHAN_VOICE, "zombie/z_idle1.wav", 1, ATTN_IDLE);
  155. };
  156. /*
  157. =============================================================================
  158. ATTACKS
  159. =============================================================================
  160. */
  161. void() ZombieGrenadeTouch =
  162. {
  163. if (other == self.owner)
  164. return; // don't explode on owner
  165. if (other.takedamage)
  166. {
  167. T_Damage (other, self, self.owner, 10 );
  168. sound (self, CHAN_WEAPON, "zombie/z_hit.wav", 1, ATTN_NORM);
  169. remove (self);
  170. return;
  171. }
  172. sound (self, CHAN_WEAPON, "zombie/z_miss.wav", 1, ATTN_NORM); // bounce sound
  173. self.velocity = '0 0 0';
  174. self.avelocity = '0 0 0';
  175. self.touch = SUB_Remove;
  176. };
  177. /*
  178. ================
  179. ZombieFireGrenade
  180. ================
  181. */
  182. void(vector st) ZombieFireGrenade =
  183. {
  184. local entity missile, mpuff;
  185. local vector org;
  186. sound (self, CHAN_WEAPON, "zombie/z_shot1.wav", 1, ATTN_NORM);
  187. missile = spawn ();
  188. missile.owner = self;
  189. missile.movetype = MOVETYPE_BOUNCE;
  190. missile.solid = SOLID_BBOX;
  191. // calc org
  192. org = self.origin + st_x * v_forward + st_y * v_right + (st_z - 24) * v_up;
  193. // set missile speed
  194. makevectors (self.angles);
  195. missile.velocity = normalize(self.enemy.origin - org);
  196. missile.velocity = missile.velocity * 600;
  197. missile.velocity_z = 200;
  198. missile.avelocity = '3000 1000 2000';
  199. missile.touch = ZombieGrenadeTouch;
  200. // set missile duration
  201. missile.nextthink = time + 2.5;
  202. missile.think = SUB_Remove;
  203. setmodel (missile, "progs/zom_gib.mdl");
  204. setsize (missile, '0 0 0', '0 0 0');
  205. setorigin (missile, org);
  206. };
  207. void() zombie_atta1 =[ $atta1, zombie_atta2 ] {ai_face();};
  208. void() zombie_atta2 =[ $atta2, zombie_atta3 ] {ai_face();};
  209. void() zombie_atta3 =[ $atta3, zombie_atta4 ] {ai_face();};
  210. void() zombie_atta4 =[ $atta4, zombie_atta5 ] {ai_face();};
  211. void() zombie_atta5 =[ $atta5, zombie_atta6 ] {ai_face();};
  212. void() zombie_atta6 =[ $atta6, zombie_atta7 ] {ai_face();};
  213. void() zombie_atta7 =[ $atta7, zombie_atta8 ] {ai_face();};
  214. void() zombie_atta8 =[ $atta8, zombie_atta9 ] {ai_face();};
  215. void() zombie_atta9 =[ $atta9, zombie_atta10 ] {ai_face();};
  216. void() zombie_atta10 =[ $atta10, zombie_atta11 ] {ai_face();};
  217. void() zombie_atta11 =[ $atta11, zombie_atta12 ] {ai_face();};
  218. void() zombie_atta12 =[ $atta12, zombie_atta13 ] {ai_face();};
  219. void() zombie_atta13 =[ $atta13, zombie_run1 ] {ai_face();ZombieFireGrenade('-10 -22 30');};
  220. void() zombie_attb1 =[ $attb1, zombie_attb2 ] {ai_face();};
  221. void() zombie_attb2 =[ $attb2, zombie_attb3 ] {ai_face();};
  222. void() zombie_attb3 =[ $attb3, zombie_attb4 ] {ai_face();};
  223. void() zombie_attb4 =[ $attb4, zombie_attb5 ] {ai_face();};
  224. void() zombie_attb5 =[ $attb5, zombie_attb6 ] {ai_face();};
  225. void() zombie_attb6 =[ $attb6, zombie_attb7 ] {ai_face();};
  226. void() zombie_attb7 =[ $attb7, zombie_attb8 ] {ai_face();};
  227. void() zombie_attb8 =[ $attb8, zombie_attb9 ] {ai_face();};
  228. void() zombie_attb9 =[ $attb9, zombie_attb10 ] {ai_face();};
  229. void() zombie_attb10 =[ $attb10, zombie_attb11 ] {ai_face();};
  230. void() zombie_attb11 =[ $attb11, zombie_attb12 ] {ai_face();};
  231. void() zombie_attb12 =[ $attb12, zombie_attb13 ] {ai_face();};
  232. void() zombie_attb13 =[ $attb13, zombie_attb14 ] {ai_face();};
  233. void() zombie_attb14 =[ $attb13, zombie_run1 ] {ai_face();ZombieFireGrenade('-10 -24 29');};
  234. void() zombie_attc1 =[ $attc1, zombie_attc2 ] {ai_face();};
  235. void() zombie_attc2 =[ $attc2, zombie_attc3 ] {ai_face();};
  236. void() zombie_attc3 =[ $attc3, zombie_attc4 ] {ai_face();};
  237. void() zombie_attc4 =[ $attc4, zombie_attc5 ] {ai_face();};
  238. void() zombie_attc5 =[ $attc5, zombie_attc6 ] {ai_face();};
  239. void() zombie_attc6 =[ $attc6, zombie_attc7 ] {ai_face();};
  240. void() zombie_attc7 =[ $attc7, zombie_attc8 ] {ai_face();};
  241. void() zombie_attc8 =[ $attc8, zombie_attc9 ] {ai_face();};
  242. void() zombie_attc9 =[ $attc9, zombie_attc10 ] {ai_face();};
  243. void() zombie_attc10 =[ $attc10, zombie_attc11 ] {ai_face();};
  244. void() zombie_attc11 =[ $attc11, zombie_attc12 ] {ai_face();};
  245. void() zombie_attc12 =[ $attc12, zombie_run1 ] {ai_face();ZombieFireGrenade('-12 -19 29');};
  246. void() zombie_missile =
  247. {
  248. local float r;
  249. droptofloor();
  250. r = random();
  251. if (r < 0.3)
  252. zombie_atta1 ();
  253. else if (r < 0.6)
  254. zombie_attb1 ();
  255. else
  256. zombie_attc1 ();
  257. };
  258. /*
  259. =============================================================================
  260. PAIN
  261. =============================================================================
  262. */
  263. void() zombie_paina1 =[ $paina1, zombie_paina2 ] {sound (self, CHAN_VOICE, "zombie/z_pain.wav", 1, ATTN_NORM);};
  264. void() zombie_paina2 =[ $paina2, zombie_paina3 ] {ai_painforward(3);};
  265. void() zombie_paina3 =[ $paina3, zombie_paina4 ] {ai_painforward(1);};
  266. void() zombie_paina4 =[ $paina4, zombie_paina5 ] {ai_pain(1);};
  267. void() zombie_paina5 =[ $paina5, zombie_paina6 ] {ai_pain(3);};
  268. void() zombie_paina6 =[ $paina6, zombie_paina7 ] {ai_pain(1);};
  269. void() zombie_paina7 =[ $paina7, zombie_paina8 ] {};
  270. void() zombie_paina8 =[ $paina8, zombie_paina9 ] {};
  271. void() zombie_paina9 =[ $paina9, zombie_paina10 ] {};
  272. void() zombie_paina10 =[ $paina10, zombie_paina11 ] {};
  273. void() zombie_paina11 =[ $paina11, zombie_paina12 ] {};
  274. void() zombie_paina12 =[ $paina12, zombie_run1 ] {};
  275. void() zombie_painb1 =[ $painb1, zombie_painb2 ] {sound (self, CHAN_VOICE, "zombie/z_pain1.wav", 1, ATTN_NORM);};
  276. void() zombie_painb2 =[ $painb2, zombie_painb3 ] {ai_pain(2);};
  277. void() zombie_painb3 =[ $painb3, zombie_painb4 ] {ai_pain(8);};
  278. void() zombie_painb4 =[ $painb4, zombie_painb5 ] {ai_pain(6);};
  279. void() zombie_painb5 =[ $painb5, zombie_painb6 ] {ai_pain(2);};
  280. void() zombie_painb6 =[ $painb6, zombie_painb7 ] {};
  281. void() zombie_painb7 =[ $painb7, zombie_painb8 ] {};
  282. void() zombie_painb8 =[ $painb8, zombie_painb9 ] {};
  283. void() zombie_painb9 =[ $painb9, zombie_painb10 ] {sound (self, CHAN_BODY, "zombie/z_fall.wav", 1, ATTN_NORM);};
  284. void() zombie_painb10 =[ $painb10, zombie_painb11 ] {};
  285. void() zombie_painb11 =[ $painb11, zombie_painb12 ] {};
  286. void() zombie_painb12 =[ $painb12, zombie_painb13 ] {};
  287. void() zombie_painb13 =[ $painb13, zombie_painb14 ] {};
  288. void() zombie_painb14 =[ $painb14, zombie_painb15 ] {};
  289. void() zombie_painb15 =[ $painb15, zombie_painb16 ] {};
  290. void() zombie_painb16 =[ $painb16, zombie_painb17 ] {};
  291. void() zombie_painb17 =[ $painb17, zombie_painb18 ] {};
  292. void() zombie_painb18 =[ $painb18, zombie_painb19 ] {};
  293. void() zombie_painb19 =[ $painb19, zombie_painb20 ] {};
  294. void() zombie_painb20 =[ $painb20, zombie_painb21 ] {};
  295. void() zombie_painb21 =[ $painb21, zombie_painb22 ] {};
  296. void() zombie_painb22 =[ $painb22, zombie_painb23 ] {};
  297. void() zombie_painb23 =[ $painb23, zombie_painb24 ] {};
  298. void() zombie_painb24 =[ $painb24, zombie_painb25 ] {};
  299. void() zombie_painb25 =[ $painb25, zombie_painb26 ] {ai_painforward(1);};
  300. void() zombie_painb26 =[ $painb26, zombie_painb27 ] {};
  301. void() zombie_painb27 =[ $painb27, zombie_painb28 ] {};
  302. void() zombie_painb28 =[ $painb28, zombie_run1 ] {};
  303. void() zombie_painc1 =[ $painc1, zombie_painc2 ] {sound (self, CHAN_VOICE, "zombie/z_pain1.wav", 1, ATTN_NORM);};
  304. void() zombie_painc2 =[ $painc2, zombie_painc3 ] {};
  305. void() zombie_painc3 =[ $painc3, zombie_painc4 ] {ai_pain(3);};
  306. void() zombie_painc4 =[ $painc4, zombie_painc5 ] {ai_pain(1);};
  307. void() zombie_painc5 =[ $painc5, zombie_painc6 ] {};
  308. void() zombie_painc6 =[ $painc6, zombie_painc7 ] {};
  309. void() zombie_painc7 =[ $painc7, zombie_painc8 ] {};
  310. void() zombie_painc8 =[ $painc8, zombie_painc9 ] {};
  311. void() zombie_painc9 =[ $painc9, zombie_painc10 ] {};
  312. void() zombie_painc10 =[ $painc10, zombie_painc11 ] {};
  313. void() zombie_painc11 =[ $painc11, zombie_painc12 ] {ai_painforward(1);};
  314. void() zombie_painc12 =[ $painc12, zombie_painc13 ] {ai_painforward(1);};
  315. void() zombie_painc13 =[ $painc13, zombie_painc14 ] {};
  316. void() zombie_painc14 =[ $painc14, zombie_painc15 ] {};
  317. void() zombie_painc15 =[ $painc15, zombie_painc16 ] {};
  318. void() zombie_painc16 =[ $painc16, zombie_painc17 ] {};
  319. void() zombie_painc17 =[ $painc17, zombie_painc18 ] {};
  320. void() zombie_painc18 =[ $painc18, zombie_run1 ] {};
  321. void() zombie_paind1 =[ $paind1, zombie_paind2 ]
  322. {
  323. sound (self, CHAN_VOICE, "zombie/z_pain.wav", 1, ATTN_NORM);
  324. droptofloor();
  325. };
  326. void() zombie_paind2 =[ $paind2, zombie_paind3 ] {};
  327. void() zombie_paind3 =[ $paind3, zombie_paind4 ] {};
  328. void() zombie_paind4 =[ $paind4, zombie_paind5 ] {};
  329. void() zombie_paind5 =[ $paind5, zombie_paind6 ] {};
  330. void() zombie_paind6 =[ $paind6, zombie_paind7 ] {};
  331. void() zombie_paind7 =[ $paind7, zombie_paind8 ] {};
  332. void() zombie_paind8 =[ $paind8, zombie_paind9 ] {};
  333. void() zombie_paind9 =[ $paind9, zombie_paind10 ] {ai_pain(1);};
  334. void() zombie_paind10 =[ $paind10, zombie_paind11 ] {};
  335. void() zombie_paind11 =[ $paind11, zombie_paind12 ] {};
  336. void() zombie_paind12 =[ $paind12, zombie_paind13 ] {};
  337. void() zombie_paind13 =[ $paind13, zombie_run1 ] {};
  338. void() zombie_paine1 =[ $paine1, zombie_paine2 ]
  339. {
  340. sound (self, CHAN_VOICE, "zombie/z_pain.wav", 1, ATTN_NORM);
  341. self.health = 60;
  342. };
  343. void() zombie_paine2 =[ $paine2, zombie_paine3 ] {ai_pain(8);};
  344. void() zombie_paine3 =[ $paine3, zombie_paine4 ] {ai_pain(5);};
  345. void() zombie_paine4 =[ $paine4, zombie_paine5 ] {ai_pain(3);};
  346. void() zombie_paine5 =[ $paine5, zombie_paine6 ] {ai_pain(1);};
  347. void() zombie_paine6 =[ $paine6, zombie_paine7 ] {ai_pain(2);};
  348. void() zombie_paine7 =[ $paine7, zombie_paine8 ] {ai_pain(1);};
  349. void() zombie_paine8 =[ $paine8, zombie_paine9 ] {ai_pain(1);};
  350. void() zombie_paine9 =[ $paine9, zombie_paine10 ] {ai_pain(2);};
  351. void() zombie_paine10 =[ $paine10, zombie_paine11 ]
  352. {
  353. sound (self, CHAN_BODY, "zombie/z_fall.wav", 1, ATTN_NORM);
  354. self.solid = SOLID_NOT;
  355. };
  356. void() zombie_paine11 =[ $paine11, zombie_paine12 ]
  357. {
  358. droptofloor();
  359. self.nextthink = self.nextthink + 5;
  360. self.health = 60;
  361. };
  362. void() zombie_paine12 =[ $paine12, zombie_paine13 ]
  363. {
  364. // see if ok to stand up
  365. droptofloor();
  366. self.health = 60;
  367. sound (self, CHAN_VOICE, "zombie/z_idle.wav", 1, ATTN_IDLE);
  368. setsize (self, VEC_HULL_MIN, VEC_HULL_MAX);
  369. self.solid = SOLID_SLIDEBOX;
  370. if (!walkmove (0, 0))
  371. {
  372. self.think = zombie_paine11;
  373. self.solid = SOLID_NOT;
  374. return;
  375. }
  376. };
  377. void() zombie_paine13 =[ $paine13, zombie_paine14 ] {};
  378. void() zombie_paine14 =[ $paine14, zombie_paine15 ] {};
  379. void() zombie_paine15 =[ $paine15, zombie_paine16 ] {};
  380. void() zombie_paine16 =[ $paine16, zombie_paine17 ] {};
  381. void() zombie_paine17 =[ $paine17, zombie_paine18 ] {};
  382. void() zombie_paine18 =[ $paine18, zombie_paine19 ] {};
  383. void() zombie_paine19 =[ $paine19, zombie_paine20 ] {};
  384. void() zombie_paine20 =[ $paine20, zombie_paine21 ] {};
  385. void() zombie_paine21 =[ $paine21, zombie_paine22 ] {};
  386. void() zombie_paine22 =[ $paine22, zombie_paine23 ] {};
  387. void() zombie_paine23 =[ $paine23, zombie_paine24 ] {};
  388. void() zombie_paine24 =[ $paine24, zombie_paine25 ] {};
  389. void() zombie_paine25 =[ $paine25, zombie_paine26 ] {ai_painforward(5);};
  390. void() zombie_paine26 =[ $paine26, zombie_paine27 ] {ai_painforward(3);};
  391. void() zombie_paine27 =[ $paine27, zombie_paine28 ] {ai_painforward(1);};
  392. void() zombie_paine28 =[ $paine28, zombie_paine29 ] {ai_pain(1);};
  393. void() zombie_paine29 =[ $paine29, zombie_paine30 ] {};
  394. void() zombie_paine30 =[ $paine30, zombie_run1 ]
  395. { };
  396. void() zombie_die =
  397. {
  398. sound (self, CHAN_VOICE, "zombie/z_gib.wav", 1, ATTN_NORM);
  399. ThrowHead ("progs/h_zombie.mdl", self.health);
  400. ThrowGib ("progs/gib1.mdl", self.health);
  401. ThrowGib ("progs/gib2.mdl", self.health);
  402. ThrowGib ("progs/gib3.mdl", self.health);
  403. };
  404. /*
  405. =================
  406. zombie_pain
  407. Zombies can only be killed (gibbed) by doing 60 hit points of damage
  408. in a single frame (rockets, grenades, quad shotgun, quad nailgun).
  409. A hit of 25 points or more (super shotgun, quad nailgun) will allways put it
  410. down to the ground.
  411. A hit of from 10 to 40 points in one frame will cause it to go down if it
  412. has been twice in two seconds, otherwise it goes into one of the four
  413. fast pain frames.
  414. A hit of less than 10 points of damage (winged by a shotgun) will be ignored.
  415. FIXME: don't use pain_finished because of nightmare hack
  416. =================
  417. */
  418. void(entity attacker, float take) zombie_pain =
  419. {
  420. local float r;
  421. self.health = 60; // allways reset health
  422. if (take < 9)
  423. return; // totally ignore
  424. if (self.inpain == 2)
  425. return; // down on ground, so don't reset any counters
  426. // go down immediately if a big enough hit
  427. if (take >= 25)
  428. {
  429. self.inpain = 2;
  430. zombie_paine1 ();
  431. return;
  432. }
  433. if (self.inpain)
  434. {
  435. // if hit again in next gre seconds while not in pain frames, definately drop
  436. self.pain_finished = time + 3;
  437. return; // currently going through an animation, don't change
  438. }
  439. if (self.pain_finished > time)
  440. {
  441. // hit again, so drop down
  442. self.inpain = 2;
  443. zombie_paine1 ();
  444. return;
  445. }
  446. // gp into one of the fast pain animations
  447. self.inpain = 1;
  448. r = random();
  449. if (r < 0.25)
  450. zombie_paina1 ();
  451. else if (r < 0.5)
  452. zombie_painb1 ();
  453. else if (r < 0.75)
  454. zombie_painc1 ();
  455. else
  456. zombie_paind1 ();
  457. };
  458. void() zombie_sleep = [ $paine11, zombie_sleep ] { ai_stand(); };
  459. void() zombie_wake =
  460. {
  461. self.th_stand = zombie_stand1;
  462. self.th_walk = zombie_walk1;
  463. self.th_pain = zombie_pain;
  464. self.th_run = zombie_run1;
  465. self.th_missile = zombie_missile;
  466. // paine12 will handle setting solid, just make the size box correct.
  467. // self.solid = SOLID_SLIDEBOX;
  468. // setsize (self, '-16 -16 -24', '16 16 40');
  469. zombie_paine12();
  470. };
  471. void() zombie_escape1=[ $cruc_1, zombie_escape2 ] {self.nextthink=time+0.20;};
  472. void() zombie_escape2=[ $cruc_2, zombie_escape3 ] {self.nextthink=time+0.20;};
  473. void() zombie_escape3=[ $cruc_3, zombie_escape4 ] {self.nextthink=time+0.20;};
  474. void() zombie_escape4=[ $cruc_4, zombie_escape5 ] {self.nextthink=time+0.20;};
  475. void() zombie_escape5=[ $cruc_5, zombie_escape6 ] {self.nextthink=time+0.15;};
  476. void() zombie_escape6=[ $cruc_6, zombie_escape7 ] {self.nextthink=time+0.15;};
  477. void() zombie_escape7=[ $cruc_7, zombie_escape8 ] {self.nextthink=time+0.15;};
  478. void() zombie_escape8=[ $cruc_8, zombie_escape9 ] {self.nextthink=time+0.15;};
  479. void() zombie_escape9=[ $cruc_9, zombie_escape10 ] {self.nextthink=time+0.15;};
  480. void() zombie_escape10=[$cruc_10, zombie_escape11] {self.nextthink=time+0.15;};
  481. void() zombie_escape11=[$cruc_11, zombie_escape12] {self.nextthink=time+0.10;};
  482. void() zombie_escape12=[$cruc_12, zombie_escape13] {self.nextthink=time+0.10;};
  483. void() zombie_escape13=[$cruc_13, zombie_escape14] {self.nextthink=time+0.10;};
  484. void() zombie_escape14=[$cruc_14, zombie_escape15]
  485. {
  486. makevectors (self.angles);
  487. setorigin ( self, self.origin + v_forward * 8);
  488. self.nextthink=time+0.15;
  489. };
  490. void() zombie_escape15=[ $cruc_15, zombie_escape16]
  491. {
  492. makevectors (self.angles);
  493. setorigin ( self, self.origin + v_forward * 8);
  494. self.nextthink=time+0.15;
  495. };
  496. void() zombie_escape16 = [ $cruc_16, zombie_run1 ]
  497. {
  498. self.solid = SOLID_SLIDEBOX;
  499. self.movetype = MOVETYPE_STEP;
  500. self.takedamage = DAMAGE_AIM;
  501. self.th_stand = zombie_stand1;
  502. self.th_walk = zombie_walk1;
  503. self.th_pain = zombie_pain;
  504. self.th_run = zombie_run1;
  505. self.th_missile = zombie_missile;
  506. self.health = 60;
  507. sound (self, CHAN_VOICE, "zombie/z_idle.wav", 1, ATTN_IDLE);
  508. droptofloor();
  509. };
  510. void() zombie_escape =
  511. {
  512. if (!self.pain_finished)
  513. {
  514. self.pain_finished = time + self.delay;
  515. }
  516. self.think = zombie_cruc1;
  517. self.nextthink = time + 0.1;
  518. };
  519. //============================================================================
  520. /*QUAKED monster_zombie (1 0 0) (-16 -16 -24) (16 16 32) Crucified Lying ambush Sneaky
  521. Crucified - Zombie stays stuck in the wall, moans and writhes.
  522. Lying - Zombie will start lying down, and stand when player spotted.
  523. Ambush - Just like all the other ambush flags.
  524. Sneaky - Zombie stays stuck in the wall, but breaks his chains, hops off the wall, and attacks after seeing the player.
  525. If crucified, stick the bounding box 12 pixels back into a wall to look right.
  526. */
  527. void() monster_zombie =
  528. {
  529. if (deathmatch)
  530. {
  531. remove(self);
  532. return;
  533. }
  534. precache_model ("progs/zombie.mdl");
  535. precache_model ("progs/h_zombie.mdl");
  536. precache_model ("progs/zom_gib.mdl");
  537. precache_sound ("zombie/z_idle.wav");
  538. precache_sound ("zombie/z_idle1.wav");
  539. precache_sound ("zombie/z_shot1.wav");
  540. precache_sound ("zombie/z_gib.wav");
  541. precache_sound ("zombie/z_pain.wav");
  542. precache_sound ("zombie/z_pain1.wav");
  543. precache_sound ("zombie/z_fall.wav");
  544. precache_sound ("zombie/z_miss.wav");
  545. precache_sound ("zombie/z_hit.wav");
  546. precache_sound ("zombie/idle_w2.wav");
  547. self.solid = SOLID_SLIDEBOX;
  548. self.movetype = MOVETYPE_STEP;
  549. setmodel (self, "progs/zombie.mdl");
  550. setsize (self, VEC_HULL_MIN, VEC_HULL_MAX);
  551. self.health = 60;
  552. self.th_stand = zombie_stand1;
  553. self.th_walk = zombie_walk1;
  554. self.th_run = zombie_run1;
  555. self.th_pain = zombie_pain;
  556. self.th_die = zombie_die;
  557. self.th_missile = zombie_missile;
  558. if (self.spawnflags & SPAWN_CRUCIFIED)
  559. {
  560. self.movetype = MOVETYPE_NONE;
  561. zombie_cruc1 ();
  562. }
  563. else if (self.spawnflags & SPAWN_LYING)
  564. {
  565. self.solid = SOLID_NOT;
  566. self.th_stand = zombie_sleep;
  567. self.th_run = zombie_wake;
  568. self.th_walk = zombie_wake;
  569. self.th_pain = zombie_wake;
  570. self.th_missile = zombie_wake;
  571. setsize (self, '-16 -16 -24', '16 16 -16');
  572. // HOLY HACK, BATMAN! - Don't blame me. Check out FindTarget in ai.qc!
  573. if ( self.spawnflags & SPAWN_AMBUSH)
  574. self.spawnflags = SPAWN_LYING;
  575. walkmonster_start();
  576. }
  577. else if (self.spawnflags & SPAWN_SNEAKY)
  578. {
  579. self.movetype = MOVETYPE_NONE;
  580. self.solid = SOLID_NOT;
  581. self.th_stand = zombie_cruc1;
  582. self.th_run = zombie_escape;
  583. self.th_walk = zombie_escape;
  584. self.th_pain = zombie_escape;
  585. self.th_missile = zombie_escape;
  586. if (!self.delay)
  587. self.delay = 3;
  588. self.ideal_yaw = self.angles * '0 1 0';
  589. if (!self.yaw_speed)
  590. self.yaw_speed = 20;
  591. self.view_ofs = '0 0 25';
  592. self.flags = self.flags | FL_MONSTER;
  593. self.th_stand ();
  594. self.nextthink = self.nextthink + random()*0.5;
  595. total_monsters = total_monsters + 1;
  596. }
  597. else
  598. {
  599. if (self.spawnflags & SPAWN_AMBUSH)
  600. self.spawnflags = SPAWN_LYING;
  601. walkmonster_start();
  602. }
  603. };