shalrath.qc 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  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. SHAL-RATH
  18. ==============================================================================
  19. */
  20. $cd /raid/quake/id1/models/shalrath
  21. $origin 0 0 24
  22. $base base
  23. $skin skin
  24. $scale 0.7
  25. $frame attack1 attack2 attack3 attack4 attack5 attack6 attack7 attack8
  26. $frame attack9 attack10 attack11
  27. $frame pain1 pain2 pain3 pain4 pain5
  28. $frame death1 death2 death3 death4 death5 death6 death7
  29. $frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9 walk10
  30. $frame walk11 walk12
  31. void() shalrath_pain;
  32. void() ShalMissile;
  33. void() shal_stand =[ $walk1, shal_stand ] {ai_stand();};
  34. void() shal_walk1 =[ $walk2, shal_walk2 ] {
  35. if (random() < 0.2)
  36. sound (self, CHAN_VOICE, "shalrath/idle.wav", 1, ATTN_IDLE);
  37. ai_walk(6);};
  38. void() shal_walk2 =[ $walk3, shal_walk3 ] {ai_walk(4);};
  39. void() shal_walk3 =[ $walk4, shal_walk4 ] {ai_walk(0);};
  40. void() shal_walk4 =[ $walk5, shal_walk5 ] {ai_walk(0);};
  41. void() shal_walk5 =[ $walk6, shal_walk6 ] {ai_walk(0);};
  42. void() shal_walk6 =[ $walk7, shal_walk7 ] {ai_walk(0);};
  43. void() shal_walk7 =[ $walk8, shal_walk8 ] {ai_walk(5);};
  44. void() shal_walk8 =[ $walk9, shal_walk9 ] {ai_walk(6);};
  45. void() shal_walk9 =[ $walk10, shal_walk10 ] {ai_walk(5);};
  46. void() shal_walk10 =[ $walk11, shal_walk11 ] {ai_walk(0);};
  47. void() shal_walk11 =[ $walk12, shal_walk12 ] {ai_walk(4);};
  48. void() shal_walk12 =[ $walk1, shal_walk1 ] {ai_walk(5);};
  49. void() shal_run1 =[ $walk2, shal_run2 ] {
  50. if (random() < 0.2)
  51. sound (self, CHAN_VOICE, "shalrath/idle.wav", 1, ATTN_IDLE);
  52. ai_run(6);};
  53. void() shal_run2 =[ $walk3, shal_run3 ] {ai_run(4);};
  54. void() shal_run3 =[ $walk4, shal_run4 ] {ai_run(0);};
  55. void() shal_run4 =[ $walk5, shal_run5 ] {ai_run(0);};
  56. void() shal_run5 =[ $walk6, shal_run6 ] {ai_run(0);};
  57. void() shal_run6 =[ $walk7, shal_run7 ] {ai_run(0);};
  58. void() shal_run7 =[ $walk8, shal_run8 ] {ai_run(5);};
  59. void() shal_run8 =[ $walk9, shal_run9 ] {ai_run(6);};
  60. void() shal_run9 =[ $walk10, shal_run10 ] {ai_run(5);};
  61. void() shal_run10 =[ $walk11, shal_run11 ] {ai_run(0);};
  62. void() shal_run11 =[ $walk12, shal_run12 ] {ai_run(4);};
  63. void() shal_run12 =[ $walk1, shal_run1 ] {ai_run(5);};
  64. void() shal_attack1 =[ $attack1, shal_attack2 ] {
  65. sound (self, CHAN_VOICE, "shalrath/attack.wav", 1, ATTN_NORM);
  66. ai_face();
  67. };
  68. void() shal_attack2 =[ $attack2, shal_attack3 ] {ai_face();};
  69. void() shal_attack3 =[ $attack3, shal_attack4 ] {ai_face();};
  70. void() shal_attack4 =[ $attack4, shal_attack5 ] {ai_face();};
  71. void() shal_attack5 =[ $attack5, shal_attack6 ] {ai_face();};
  72. void() shal_attack6 =[ $attack6, shal_attack7 ] {ai_face();};
  73. void() shal_attack7 =[ $attack7, shal_attack8 ] {ai_face();};
  74. void() shal_attack8 =[ $attack8, shal_attack9 ] {ai_face();};
  75. void() shal_attack9 =[ $attack9, shal_attack10 ] {ShalMissile();};
  76. void() shal_attack10 =[ $attack10, shal_attack11 ] {ai_face();};
  77. void() shal_attack11 =[ $attack11, shal_run1 ] {};
  78. void() shal_pain1 =[ $pain1, shal_pain2 ] {};
  79. void() shal_pain2 =[ $pain2, shal_pain3 ] {};
  80. void() shal_pain3 =[ $pain3, shal_pain4 ] {};
  81. void() shal_pain4 =[ $pain4, shal_pain5 ] {};
  82. void() shal_pain5 =[ $pain5, shal_run1 ] {};
  83. void() shal_death1 =[ $death1, shal_death2 ] {};
  84. void() shal_death2 =[ $death2, shal_death3 ] {};
  85. void() shal_death3 =[ $death3, shal_death4 ] {};
  86. void() shal_death4 =[ $death4, shal_death5 ] {};
  87. void() shal_death5 =[ $death5, shal_death6 ] {};
  88. void() shal_death6 =[ $death6, shal_death7 ] {};
  89. void() shal_death7 =[ $death7, shal_death7 ] {};
  90. void() shalrath_pain =
  91. {
  92. if (self.pain_finished > time)
  93. return;
  94. sound (self, CHAN_VOICE, "shalrath/pain.wav", 1, ATTN_NORM);
  95. shal_pain1();
  96. self.pain_finished = time + 3;
  97. };
  98. void() shalrath_die =
  99. {
  100. // check for gib
  101. if (self.health < -90)
  102. {
  103. sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
  104. ThrowHead ("progs/h_shal.mdl", self.health);
  105. ThrowGib ("progs/gib1.mdl", self.health);
  106. ThrowGib ("progs/gib2.mdl", self.health);
  107. ThrowGib ("progs/gib3.mdl", self.health);
  108. return;
  109. }
  110. sound (self, CHAN_VOICE, "shalrath/death.wav", 1, ATTN_NORM);
  111. shal_death1();
  112. self.solid = SOLID_NOT;
  113. // insert death sounds here
  114. };
  115. /*
  116. ================
  117. ShalMissile
  118. ================
  119. */
  120. void() ShalMissileTouch;
  121. void() ShalHome;
  122. void() ShalMissile =
  123. {
  124. local entity missile;
  125. local vector dir;
  126. local float dist, flytime;
  127. dir = normalize((self.enemy.origin + '0 0 10') - self.origin);
  128. dist = vlen (self.enemy.origin - self.origin);
  129. flytime = dist * 0.002;
  130. if (flytime < 0.1)
  131. flytime = 0.1;
  132. self.effects = self.effects | EF_MUZZLEFLASH;
  133. sound (self, CHAN_WEAPON, "shalrath/attack2.wav", 1, ATTN_NORM);
  134. missile = spawn ();
  135. missile.owner = self;
  136. missile.solid = SOLID_BBOX;
  137. missile.movetype = MOVETYPE_FLYMISSILE;
  138. setmodel (missile, "progs/v_spike.mdl");
  139. setsize (missile, '0 0 0', '0 0 0');
  140. missile.origin = self.origin + '0 0 10';
  141. missile.velocity = dir * 400;
  142. missile.avelocity = '300 300 300';
  143. missile.nextthink = flytime + time;
  144. missile.think = ShalHome;
  145. missile.enemy = self.enemy;
  146. missile.touch = ShalMissileTouch;
  147. };
  148. void() ShalHome =
  149. {
  150. local vector dir, vtemp;
  151. vtemp = self.enemy.origin + '0 0 10';
  152. if (self.enemy.health < 1)
  153. {
  154. remove(self);
  155. return;
  156. }
  157. dir = normalize(vtemp - self.origin);
  158. self.velocity = dir * 250;
  159. self.nextthink = time + 0.2;
  160. self.think = ShalHome;
  161. };
  162. void() ShalMissileTouch =
  163. {
  164. if (other == self.owner)
  165. return; // don't explode on owner
  166. if (other.classname == "monster_zombie")
  167. T_Damage (other, self, self, 110);
  168. T_RadiusDamage (self, self.owner, 40, world);
  169. sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM);
  170. WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  171. WriteByte (MSG_BROADCAST, TE_EXPLOSION);
  172. WriteCoord (MSG_BROADCAST, self.origin_x);
  173. WriteCoord (MSG_BROADCAST, self.origin_y);
  174. WriteCoord (MSG_BROADCAST, self.origin_z);
  175. self.velocity = '0 0 0';
  176. self.touch = SUB_Null;
  177. setmodel (self, "progs/s_explod.spr");
  178. self.solid = SOLID_NOT;
  179. s_explode1 ();
  180. };
  181. //=================================================================
  182. /*QUAKED monster_shalrath (1 0 0) (-32 -32 -24) (32 32 48) Ambush
  183. */
  184. void() monster_shalrath =
  185. {
  186. if (deathmatch)
  187. {
  188. remove(self);
  189. return;
  190. }
  191. precache_model2 ("progs/shalrath.mdl");
  192. precache_model2 ("progs/h_shal.mdl");
  193. precache_model2 ("progs/v_spike.mdl");
  194. precache_sound2 ("shalrath/attack.wav");
  195. precache_sound2 ("shalrath/attack2.wav");
  196. precache_sound2 ("shalrath/death.wav");
  197. precache_sound2 ("shalrath/idle.wav");
  198. precache_sound2 ("shalrath/pain.wav");
  199. precache_sound2 ("shalrath/sight.wav");
  200. self.solid = SOLID_SLIDEBOX;
  201. self.movetype = MOVETYPE_STEP;
  202. setmodel (self, "progs/shalrath.mdl");
  203. setsize (self, VEC_HULL2_MIN, VEC_HULL2_MAX);
  204. self.health = 400;
  205. self.th_stand = shal_stand;
  206. self.th_walk = shal_walk1;
  207. self.th_run = shal_run1;
  208. self.th_die = shalrath_die;
  209. self.th_pain = shalrath_pain;
  210. self.th_missile = shal_attack1;
  211. self.think = walkmonster_start;
  212. self.nextthink = time + 0.1 + random ()*0.1;
  213. };