m_boss32.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914
  1. /*
  2. Copyright (C) 1997-2001 Id Software, Inc.
  3. This program is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU General Public License
  5. as published by the Free Software Foundation; either version 2
  6. of the License, or (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. See the GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  14. */
  15. /*
  16. ==============================================================================
  17. Makron -- Final Boss
  18. ==============================================================================
  19. */
  20. #include "g_local.h"
  21. #include "m_boss32.h"
  22. qboolean visible (edict_t *self, edict_t *other);
  23. void MakronRailgun (edict_t *self);
  24. void MakronSaveloc (edict_t *self);
  25. void MakronHyperblaster (edict_t *self);
  26. void makron_step_left (edict_t *self);
  27. void makron_step_right (edict_t *self);
  28. void makronBFG (edict_t *self);
  29. void makron_dead (edict_t *self);
  30. static int sound_pain4;
  31. static int sound_pain5;
  32. static int sound_pain6;
  33. static int sound_death;
  34. static int sound_step_left;
  35. static int sound_step_right;
  36. static int sound_attack_bfg;
  37. static int sound_brainsplorch;
  38. static int sound_prerailgun;
  39. static int sound_popup;
  40. static int sound_taunt1;
  41. static int sound_taunt2;
  42. static int sound_taunt3;
  43. static int sound_hit;
  44. void makron_taunt (edict_t *self)
  45. {
  46. float r;
  47. r=random();
  48. if (r <= 0.3)
  49. gi.sound (self, CHAN_AUTO, sound_taunt1, 1, ATTN_NONE, 0);
  50. else if (r <= 0.6)
  51. gi.sound (self, CHAN_AUTO, sound_taunt2, 1, ATTN_NONE, 0);
  52. else
  53. gi.sound (self, CHAN_AUTO, sound_taunt3, 1, ATTN_NONE, 0);
  54. }
  55. //
  56. // stand
  57. //
  58. mframe_t makron_frames_stand []=
  59. {
  60. ai_stand, 0, NULL,
  61. ai_stand, 0, NULL,
  62. ai_stand, 0, NULL,
  63. ai_stand, 0, NULL,
  64. ai_stand, 0, NULL,
  65. ai_stand, 0, NULL,
  66. ai_stand, 0, NULL,
  67. ai_stand, 0, NULL,
  68. ai_stand, 0, NULL,
  69. ai_stand, 0, NULL, // 10
  70. ai_stand, 0, NULL,
  71. ai_stand, 0, NULL,
  72. ai_stand, 0, NULL,
  73. ai_stand, 0, NULL,
  74. ai_stand, 0, NULL,
  75. ai_stand, 0, NULL,
  76. ai_stand, 0, NULL,
  77. ai_stand, 0, NULL,
  78. ai_stand, 0, NULL,
  79. ai_stand, 0, NULL, // 20
  80. ai_stand, 0, NULL,
  81. ai_stand, 0, NULL,
  82. ai_stand, 0, NULL,
  83. ai_stand, 0, NULL,
  84. ai_stand, 0, NULL,
  85. ai_stand, 0, NULL,
  86. ai_stand, 0, NULL,
  87. ai_stand, 0, NULL,
  88. ai_stand, 0, NULL,
  89. ai_stand, 0, NULL, // 30
  90. ai_stand, 0, NULL,
  91. ai_stand, 0, NULL,
  92. ai_stand, 0, NULL,
  93. ai_stand, 0, NULL,
  94. ai_stand, 0, NULL,
  95. ai_stand, 0, NULL,
  96. ai_stand, 0, NULL,
  97. ai_stand, 0, NULL,
  98. ai_stand, 0, NULL,
  99. ai_stand, 0, NULL, // 40
  100. ai_stand, 0, NULL,
  101. ai_stand, 0, NULL,
  102. ai_stand, 0, NULL,
  103. ai_stand, 0, NULL,
  104. ai_stand, 0, NULL,
  105. ai_stand, 0, NULL,
  106. ai_stand, 0, NULL,
  107. ai_stand, 0, NULL,
  108. ai_stand, 0, NULL,
  109. ai_stand, 0, NULL, // 50
  110. ai_stand, 0, NULL,
  111. ai_stand, 0, NULL,
  112. ai_stand, 0, NULL,
  113. ai_stand, 0, NULL,
  114. ai_stand, 0, NULL,
  115. ai_stand, 0, NULL,
  116. ai_stand, 0, NULL,
  117. ai_stand, 0, NULL,
  118. ai_stand, 0, NULL,
  119. ai_stand, 0, NULL // 60
  120. };
  121. mmove_t makron_move_stand = {FRAME_stand201, FRAME_stand260, makron_frames_stand, NULL};
  122. void makron_stand (edict_t *self)
  123. {
  124. self->monsterinfo.currentmove = &makron_move_stand;
  125. }
  126. mframe_t makron_frames_run [] =
  127. {
  128. ai_run, 3, makron_step_left,
  129. ai_run, 12, NULL,
  130. ai_run, 8, NULL,
  131. ai_run, 8, NULL,
  132. ai_run, 8, makron_step_right,
  133. ai_run, 6, NULL,
  134. ai_run, 12, NULL,
  135. ai_run, 9, NULL,
  136. ai_run, 6, NULL,
  137. ai_run, 12, NULL
  138. };
  139. mmove_t makron_move_run = {FRAME_walk204, FRAME_walk213, makron_frames_run, NULL};
  140. void makron_hit (edict_t *self)
  141. {
  142. gi.sound (self, CHAN_AUTO, sound_hit, 1, ATTN_NONE,0);
  143. }
  144. void makron_popup (edict_t *self)
  145. {
  146. gi.sound (self, CHAN_BODY, sound_popup, 1, ATTN_NONE,0);
  147. }
  148. void makron_step_left (edict_t *self)
  149. {
  150. gi.sound (self, CHAN_BODY, sound_step_left, 1, ATTN_NORM,0);
  151. }
  152. void makron_step_right (edict_t *self)
  153. {
  154. gi.sound (self, CHAN_BODY, sound_step_right, 1, ATTN_NORM,0);
  155. }
  156. void makron_brainsplorch (edict_t *self)
  157. {
  158. gi.sound (self, CHAN_VOICE, sound_brainsplorch, 1, ATTN_NORM,0);
  159. }
  160. void makron_prerailgun (edict_t *self)
  161. {
  162. gi.sound (self, CHAN_WEAPON, sound_prerailgun, 1, ATTN_NORM,0);
  163. }
  164. mframe_t makron_frames_walk [] =
  165. {
  166. ai_walk, 3, makron_step_left,
  167. ai_walk, 12, NULL,
  168. ai_walk, 8, NULL,
  169. ai_walk, 8, NULL,
  170. ai_walk, 8, makron_step_right,
  171. ai_walk, 6, NULL,
  172. ai_walk, 12, NULL,
  173. ai_walk, 9, NULL,
  174. ai_walk, 6, NULL,
  175. ai_walk, 12, NULL
  176. };
  177. mmove_t makron_move_walk = {FRAME_walk204, FRAME_walk213, makron_frames_run, NULL};
  178. void makron_walk (edict_t *self)
  179. {
  180. self->monsterinfo.currentmove = &makron_move_walk;
  181. }
  182. void makron_run (edict_t *self)
  183. {
  184. if (self->monsterinfo.aiflags & AI_STAND_GROUND)
  185. self->monsterinfo.currentmove = &makron_move_stand;
  186. else
  187. self->monsterinfo.currentmove = &makron_move_run;
  188. }
  189. mframe_t makron_frames_pain6 [] =
  190. {
  191. ai_move, 0, NULL,
  192. ai_move, 0, NULL,
  193. ai_move, 0, NULL,
  194. ai_move, 0, NULL,
  195. ai_move, 0, NULL,
  196. ai_move, 0, NULL,
  197. ai_move, 0, NULL,
  198. ai_move, 0, NULL,
  199. ai_move, 0, NULL,
  200. ai_move, 0, NULL, // 10
  201. ai_move, 0, NULL,
  202. ai_move, 0, NULL,
  203. ai_move, 0, NULL,
  204. ai_move, 0, NULL,
  205. ai_move, 0, NULL,
  206. ai_move, 0, makron_popup,
  207. ai_move, 0, NULL,
  208. ai_move, 0, NULL,
  209. ai_move, 0, NULL,
  210. ai_move, 0, NULL, // 20
  211. ai_move, 0, NULL,
  212. ai_move, 0, NULL,
  213. ai_move, 0, NULL,
  214. ai_move, 0, makron_taunt,
  215. ai_move, 0, NULL,
  216. ai_move, 0, NULL,
  217. ai_move, 0, NULL
  218. };
  219. mmove_t makron_move_pain6 = {FRAME_pain601, FRAME_pain627, makron_frames_pain6, makron_run};
  220. mframe_t makron_frames_pain5 [] =
  221. {
  222. ai_move, 0, NULL,
  223. ai_move, 0, NULL,
  224. ai_move, 0, NULL,
  225. ai_move, 0, NULL
  226. };
  227. mmove_t makron_move_pain5 = {FRAME_pain501, FRAME_pain504, makron_frames_pain5, makron_run};
  228. mframe_t makron_frames_pain4 [] =
  229. {
  230. ai_move, 0, NULL,
  231. ai_move, 0, NULL,
  232. ai_move, 0, NULL,
  233. ai_move, 0, NULL
  234. };
  235. mmove_t makron_move_pain4 = {FRAME_pain401, FRAME_pain404, makron_frames_pain4, makron_run};
  236. mframe_t makron_frames_death2 [] =
  237. {
  238. ai_move, -15, NULL,
  239. ai_move, 3, NULL,
  240. ai_move, -12, NULL,
  241. ai_move, 0, makron_step_left,
  242. ai_move, 0, NULL,
  243. ai_move, 0, NULL,
  244. ai_move, 0, NULL,
  245. ai_move, 0, NULL,
  246. ai_move, 0, NULL,
  247. ai_move, 0, NULL, // 10
  248. ai_move, 0, NULL,
  249. ai_move, 0, NULL,
  250. ai_move, 0, NULL,
  251. ai_move, 0, NULL,
  252. ai_move, 0, NULL,
  253. ai_move, 11, NULL,
  254. ai_move, 12, NULL,
  255. ai_move, 11, makron_step_right,
  256. ai_move, 0, NULL,
  257. ai_move, 0, NULL, // 20
  258. ai_move, 0, NULL,
  259. ai_move, 0, NULL,
  260. ai_move, 0, NULL,
  261. ai_move, 0, NULL,
  262. ai_move, 0, NULL,
  263. ai_move, 0, NULL,
  264. ai_move, 0, NULL,
  265. ai_move, 0, NULL,
  266. ai_move, 0, NULL,
  267. ai_move, 0, NULL, // 30
  268. ai_move, 0, NULL,
  269. ai_move, 0, NULL,
  270. ai_move, 0, NULL,
  271. ai_move, 5, NULL,
  272. ai_move, 7, NULL,
  273. ai_move, 6, makron_step_left,
  274. ai_move, 0, NULL,
  275. ai_move, 0, NULL,
  276. ai_move, -1, NULL,
  277. ai_move, 2, NULL, // 40
  278. ai_move, 0, NULL,
  279. ai_move, 0, NULL,
  280. ai_move, 0, NULL,
  281. ai_move, 0, NULL,
  282. ai_move, 0, NULL,
  283. ai_move, 0, NULL,
  284. ai_move, 0, NULL,
  285. ai_move, 0, NULL,
  286. ai_move, 0, NULL,
  287. ai_move, 0, NULL, // 50
  288. ai_move, 0, NULL,
  289. ai_move, 0, NULL,
  290. ai_move, 0, NULL,
  291. ai_move, -6, NULL,
  292. ai_move, -4, NULL,
  293. ai_move, -6, makron_step_right,
  294. ai_move, -4, NULL,
  295. ai_move, -4, makron_step_left,
  296. ai_move, 0, NULL,
  297. ai_move, 0, NULL, // 60
  298. ai_move, 0, NULL,
  299. ai_move, 0, NULL,
  300. ai_move, -2, NULL,
  301. ai_move, -5, NULL,
  302. ai_move, -3, makron_step_right,
  303. ai_move, -8, NULL,
  304. ai_move, -3, makron_step_left,
  305. ai_move, -7, NULL,
  306. ai_move, -4, NULL,
  307. ai_move, -4, makron_step_right, // 70
  308. ai_move, -6, NULL,
  309. ai_move, -7, NULL,
  310. ai_move, 0, makron_step_left,
  311. ai_move, 0, NULL,
  312. ai_move, 0, NULL,
  313. ai_move, 0, NULL,
  314. ai_move, 0, NULL,
  315. ai_move, 0, NULL,
  316. ai_move, 0, NULL,
  317. ai_move, 0, NULL, // 80
  318. ai_move, 0, NULL,
  319. ai_move, 0, NULL,
  320. ai_move, 0, NULL,
  321. ai_move, 0, NULL,
  322. ai_move, 0, NULL,
  323. ai_move, -2, NULL,
  324. ai_move, 0, NULL,
  325. ai_move, 0, NULL,
  326. ai_move, 2, NULL,
  327. ai_move, 0, NULL, // 90
  328. ai_move, 27, makron_hit,
  329. ai_move, 26, NULL,
  330. ai_move, 0, makron_brainsplorch,
  331. ai_move, 0, NULL,
  332. ai_move, 0, NULL // 95
  333. };
  334. mmove_t makron_move_death2 = {FRAME_death201, FRAME_death295, makron_frames_death2, makron_dead};
  335. mframe_t makron_frames_death3 [] =
  336. {
  337. ai_move, 0, NULL,
  338. ai_move, 0, NULL,
  339. ai_move, 0, NULL,
  340. ai_move, 0, NULL,
  341. ai_move, 0, NULL,
  342. ai_move, 0, NULL,
  343. ai_move, 0, NULL,
  344. ai_move, 0, NULL,
  345. ai_move, 0, NULL,
  346. ai_move, 0, NULL,
  347. ai_move, 0, NULL,
  348. ai_move, 0, NULL,
  349. ai_move, 0, NULL,
  350. ai_move, 0, NULL,
  351. ai_move, 0, NULL,
  352. ai_move, 0, NULL,
  353. ai_move, 0, NULL,
  354. ai_move, 0, NULL,
  355. ai_move, 0, NULL,
  356. ai_move, 0, NULL
  357. };
  358. mmove_t makron_move_death3 = {FRAME_death301, FRAME_death320, makron_frames_death3, NULL};
  359. mframe_t makron_frames_sight [] =
  360. {
  361. ai_move, 0, NULL,
  362. ai_move, 0, NULL,
  363. ai_move, 0, NULL,
  364. ai_move, 0, NULL,
  365. ai_move, 0, NULL,
  366. ai_move, 0, NULL,
  367. ai_move, 0, NULL,
  368. ai_move, 0, NULL,
  369. ai_move, 0, NULL,
  370. ai_move, 0, NULL,
  371. ai_move, 0, NULL,
  372. ai_move, 0, NULL,
  373. ai_move, 0, NULL
  374. };
  375. mmove_t makron_move_sight= {FRAME_active01, FRAME_active13, makron_frames_sight, makron_run};
  376. void makronBFG (edict_t *self)
  377. {
  378. vec3_t forward, right;
  379. vec3_t start;
  380. vec3_t dir;
  381. vec3_t vec;
  382. AngleVectors (self->s.angles, forward, right, NULL);
  383. G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_MAKRON_BFG], forward, right, start);
  384. VectorCopy (self->enemy->s.origin, vec);
  385. vec[2] += self->enemy->viewheight;
  386. VectorSubtract (vec, start, dir);
  387. VectorNormalize (dir);
  388. gi.sound (self, CHAN_VOICE, sound_attack_bfg, 1, ATTN_NORM, 0);
  389. monster_fire_bfg (self, start, dir, 50, 300, 100, 300, MZ2_MAKRON_BFG);
  390. }
  391. mframe_t makron_frames_attack3 []=
  392. {
  393. ai_charge, 0, NULL,
  394. ai_charge, 0, NULL,
  395. ai_charge, 0, NULL,
  396. ai_charge, 0, makronBFG, // FIXME: BFG Attack here
  397. ai_move, 0, NULL,
  398. ai_move, 0, NULL,
  399. ai_move, 0, NULL,
  400. ai_move, 0, NULL
  401. };
  402. mmove_t makron_move_attack3 = {FRAME_attak301, FRAME_attak308, makron_frames_attack3, makron_run};
  403. mframe_t makron_frames_attack4[]=
  404. {
  405. ai_charge, 0, NULL,
  406. ai_charge, 0, NULL,
  407. ai_charge, 0, NULL,
  408. ai_charge, 0, NULL,
  409. ai_move, 0, MakronHyperblaster, // fire
  410. ai_move, 0, MakronHyperblaster, // fire
  411. ai_move, 0, MakronHyperblaster, // fire
  412. ai_move, 0, MakronHyperblaster, // fire
  413. ai_move, 0, MakronHyperblaster, // fire
  414. ai_move, 0, MakronHyperblaster, // fire
  415. ai_move, 0, MakronHyperblaster, // fire
  416. ai_move, 0, MakronHyperblaster, // fire
  417. ai_move, 0, MakronHyperblaster, // fire
  418. ai_move, 0, MakronHyperblaster, // fire
  419. ai_move, 0, MakronHyperblaster, // fire
  420. ai_move, 0, MakronHyperblaster, // fire
  421. ai_move, 0, MakronHyperblaster, // fire
  422. ai_move, 0, MakronHyperblaster, // fire
  423. ai_move, 0, MakronHyperblaster, // fire
  424. ai_move, 0, MakronHyperblaster, // fire
  425. ai_move, 0, MakronHyperblaster, // fire
  426. ai_move, 0, NULL,
  427. ai_move, 0, NULL,
  428. ai_move, 0, NULL,
  429. ai_move, 0, NULL,
  430. ai_move, 0, NULL
  431. };
  432. mmove_t makron_move_attack4 = {FRAME_attak401, FRAME_attak426, makron_frames_attack4, makron_run};
  433. mframe_t makron_frames_attack5[]=
  434. {
  435. ai_charge, 0, makron_prerailgun,
  436. ai_charge, 0, NULL,
  437. ai_charge, 0, NULL,
  438. ai_charge, 0, NULL,
  439. ai_charge, 0, NULL,
  440. ai_charge, 0, NULL,
  441. ai_charge, 0, NULL,
  442. ai_charge, 0, MakronSaveloc,
  443. ai_move, 0, MakronRailgun, // Fire railgun
  444. ai_move, 0, NULL,
  445. ai_move, 0, NULL,
  446. ai_move, 0, NULL,
  447. ai_move, 0, NULL,
  448. ai_move, 0, NULL,
  449. ai_move, 0, NULL,
  450. ai_move, 0, NULL
  451. };
  452. mmove_t makron_move_attack5 = {FRAME_attak501, FRAME_attak516, makron_frames_attack5, makron_run};
  453. void MakronSaveloc (edict_t *self)
  454. {
  455. VectorCopy (self->enemy->s.origin, self->pos1); //save for aiming the shot
  456. self->pos1[2] += self->enemy->viewheight;
  457. };
  458. // FIXME: He's not firing from the proper Z
  459. void MakronRailgun (edict_t *self)
  460. {
  461. vec3_t start;
  462. vec3_t dir;
  463. vec3_t forward, right;
  464. AngleVectors (self->s.angles, forward, right, NULL);
  465. G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_MAKRON_RAILGUN_1], forward, right, start);
  466. // calc direction to where we targted
  467. VectorSubtract (self->pos1, start, dir);
  468. VectorNormalize (dir);
  469. monster_fire_railgun (self, start, dir, 50, 100, MZ2_MAKRON_RAILGUN_1);
  470. }
  471. // FIXME: This is all wrong. He's not firing at the proper angles.
  472. void MakronHyperblaster (edict_t *self)
  473. {
  474. vec3_t dir;
  475. vec3_t vec;
  476. vec3_t start;
  477. vec3_t forward, right;
  478. int flash_number;
  479. flash_number = MZ2_MAKRON_BLASTER_1 + (self->s.frame - FRAME_attak405);
  480. AngleVectors (self->s.angles, forward, right, NULL);
  481. G_ProjectSource (self->s.origin, monster_flash_offset[flash_number], forward, right, start);
  482. if (self->enemy)
  483. {
  484. VectorCopy (self->enemy->s.origin, vec);
  485. vec[2] += self->enemy->viewheight;
  486. VectorSubtract (vec, start, vec);
  487. vectoangles (vec, vec);
  488. dir[0] = vec[0];
  489. }
  490. else
  491. {
  492. dir[0] = 0;
  493. }
  494. if (self->s.frame <= FRAME_attak413)
  495. dir[1] = self->s.angles[1] - 10 * (self->s.frame - FRAME_attak413);
  496. else
  497. dir[1] = self->s.angles[1] + 10 * (self->s.frame - FRAME_attak421);
  498. dir[2] = 0;
  499. AngleVectors (dir, forward, NULL, NULL);
  500. monster_fire_blaster (self, start, forward, 15, 1000, MZ2_MAKRON_BLASTER_1, EF_BLASTER);
  501. }
  502. void makron_pain (edict_t *self, edict_t *other, float kick, int damage)
  503. {
  504. if (self->health < (self->max_health / 2))
  505. self->s.skinnum = 1;
  506. if (level.time < self->pain_debounce_time)
  507. return;
  508. // Lessen the chance of him going into his pain frames
  509. if (damage <=25)
  510. if (random()<0.2)
  511. return;
  512. self->pain_debounce_time = level.time + 3;
  513. if (skill->value == 3)
  514. return; // no pain anims in nightmare
  515. if (damage <= 40)
  516. {
  517. gi.sound (self, CHAN_VOICE, sound_pain4, 1, ATTN_NONE,0);
  518. self->monsterinfo.currentmove = &makron_move_pain4;
  519. }
  520. else if (damage <= 110)
  521. {
  522. gi.sound (self, CHAN_VOICE, sound_pain5, 1, ATTN_NONE,0);
  523. self->monsterinfo.currentmove = &makron_move_pain5;
  524. }
  525. else
  526. {
  527. if (damage <= 150)
  528. if (random() <= 0.45)
  529. {
  530. gi.sound (self, CHAN_VOICE, sound_pain6, 1, ATTN_NONE,0);
  531. self->monsterinfo.currentmove = &makron_move_pain6;
  532. }
  533. else
  534. if (random() <= 0.35)
  535. {
  536. gi.sound (self, CHAN_VOICE, sound_pain6, 1, ATTN_NONE,0);
  537. self->monsterinfo.currentmove = &makron_move_pain6;
  538. }
  539. }
  540. };
  541. void makron_sight(edict_t *self, edict_t *other)
  542. {
  543. self->monsterinfo.currentmove = &makron_move_sight;
  544. };
  545. void makron_attack(edict_t *self)
  546. {
  547. vec3_t vec;
  548. float range;
  549. float r;
  550. r = random();
  551. VectorSubtract (self->enemy->s.origin, self->s.origin, vec);
  552. range = VectorLength (vec);
  553. if (r <= 0.3)
  554. self->monsterinfo.currentmove = &makron_move_attack3;
  555. else if (r <= 0.6)
  556. self->monsterinfo.currentmove = &makron_move_attack4;
  557. else
  558. self->monsterinfo.currentmove = &makron_move_attack5;
  559. }
  560. /*
  561. ---
  562. Makron Torso. This needs to be spawned in
  563. ---
  564. */
  565. void makron_torso_think (edict_t *self)
  566. {
  567. if (++self->s.frame < 365)
  568. self->nextthink = level.time + FRAMETIME;
  569. else
  570. {
  571. self->s.frame = 346;
  572. self->nextthink = level.time + FRAMETIME;
  573. }
  574. }
  575. void makron_torso (edict_t *ent)
  576. {
  577. ent->movetype = MOVETYPE_NONE;
  578. ent->solid = SOLID_NOT;
  579. VectorSet (ent->mins, -8, -8, 0);
  580. VectorSet (ent->maxs, 8, 8, 8);
  581. ent->s.frame = 346;
  582. ent->s.modelindex = gi.modelindex ("models/monsters/boss3/rider/tris.md2");
  583. ent->think = makron_torso_think;
  584. ent->nextthink = level.time + 2 * FRAMETIME;
  585. ent->s.sound = gi.soundindex ("makron/spine.wav");
  586. gi.linkentity (ent);
  587. }
  588. //
  589. // death
  590. //
  591. void makron_dead (edict_t *self)
  592. {
  593. VectorSet (self->mins, -60, -60, 0);
  594. VectorSet (self->maxs, 60, 60, 72);
  595. self->movetype = MOVETYPE_TOSS;
  596. self->svflags |= SVF_DEADMONSTER;
  597. self->nextthink = 0;
  598. gi.linkentity (self);
  599. }
  600. void makron_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
  601. {
  602. edict_t *tempent;
  603. int n;
  604. self->s.sound = 0;
  605. // check for gib
  606. if (self->health <= self->gib_health)
  607. {
  608. gi.sound (self, CHAN_VOICE, gi.soundindex ("misc/udeath.wav"), 1, ATTN_NORM, 0);
  609. for (n= 0; n < 1 /*4*/; n++)
  610. ThrowGib (self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC);
  611. for (n= 0; n < 4; n++)
  612. ThrowGib (self, "models/objects/gibs/sm_metal/tris.md2", damage, GIB_METALLIC);
  613. ThrowHead (self, "models/objects/gibs/gear/tris.md2", damage, GIB_METALLIC);
  614. self->deadflag = DEAD_DEAD;
  615. return;
  616. }
  617. if (self->deadflag == DEAD_DEAD)
  618. return;
  619. // regular death
  620. gi.sound (self, CHAN_VOICE, sound_death, 1, ATTN_NONE, 0);
  621. self->deadflag = DEAD_DEAD;
  622. self->takedamage = DAMAGE_YES;
  623. tempent = G_Spawn();
  624. VectorCopy (self->s.origin, tempent->s.origin);
  625. VectorCopy (self->s.angles, tempent->s.angles);
  626. tempent->s.origin[1] -= 84;
  627. makron_torso (tempent);
  628. self->monsterinfo.currentmove = &makron_move_death2;
  629. }
  630. qboolean Makron_CheckAttack (edict_t *self)
  631. {
  632. vec3_t spot1, spot2;
  633. vec3_t temp;
  634. float chance;
  635. trace_t tr;
  636. qboolean enemy_infront;
  637. int enemy_range;
  638. float enemy_yaw;
  639. if (self->enemy->health > 0)
  640. {
  641. // see if any entities are in the way of the shot
  642. VectorCopy (self->s.origin, spot1);
  643. spot1[2] += self->viewheight;
  644. VectorCopy (self->enemy->s.origin, spot2);
  645. spot2[2] += self->enemy->viewheight;
  646. tr = gi.trace (spot1, NULL, NULL, spot2, self, CONTENTS_SOLID|CONTENTS_MONSTER|CONTENTS_SLIME|CONTENTS_LAVA);
  647. // do we have a clear shot?
  648. if (tr.ent != self->enemy)
  649. return false;
  650. }
  651. enemy_infront = infront(self, self->enemy);
  652. enemy_range = range(self, self->enemy);
  653. VectorSubtract (self->enemy->s.origin, self->s.origin, temp);
  654. enemy_yaw = vectoyaw(temp);
  655. self->ideal_yaw = enemy_yaw;
  656. // melee attack
  657. if (enemy_range == RANGE_MELEE)
  658. {
  659. if (self->monsterinfo.melee)
  660. self->monsterinfo.attack_state = AS_MELEE;
  661. else
  662. self->monsterinfo.attack_state = AS_MISSILE;
  663. return true;
  664. }
  665. // missile attack
  666. if (!self->monsterinfo.attack)
  667. return false;
  668. if (level.time < self->monsterinfo.attack_finished)
  669. return false;
  670. if (enemy_range == RANGE_FAR)
  671. return false;
  672. if (self->monsterinfo.aiflags & AI_STAND_GROUND)
  673. {
  674. chance = 0.4;
  675. }
  676. else if (enemy_range == RANGE_MELEE)
  677. {
  678. chance = 0.8;
  679. }
  680. else if (enemy_range == RANGE_NEAR)
  681. {
  682. chance = 0.4;
  683. }
  684. else if (enemy_range == RANGE_MID)
  685. {
  686. chance = 0.2;
  687. }
  688. else
  689. {
  690. return false;
  691. }
  692. if (random () < chance)
  693. {
  694. self->monsterinfo.attack_state = AS_MISSILE;
  695. self->monsterinfo.attack_finished = level.time + 2*random();
  696. return true;
  697. }
  698. if (self->flags & FL_FLY)
  699. {
  700. if (random() < 0.3)
  701. self->monsterinfo.attack_state = AS_SLIDING;
  702. else
  703. self->monsterinfo.attack_state = AS_STRAIGHT;
  704. }
  705. return false;
  706. }
  707. //
  708. // monster_makron
  709. //
  710. void MakronPrecache (void)
  711. {
  712. sound_pain4 = gi.soundindex ("makron/pain3.wav");
  713. sound_pain5 = gi.soundindex ("makron/pain2.wav");
  714. sound_pain6 = gi.soundindex ("makron/pain1.wav");
  715. sound_death = gi.soundindex ("makron/death.wav");
  716. sound_step_left = gi.soundindex ("makron/step1.wav");
  717. sound_step_right = gi.soundindex ("makron/step2.wav");
  718. sound_attack_bfg = gi.soundindex ("makron/bfg_fire.wav");
  719. sound_brainsplorch = gi.soundindex ("makron/brain1.wav");
  720. sound_prerailgun = gi.soundindex ("makron/rail_up.wav");
  721. sound_popup = gi.soundindex ("makron/popup.wav");
  722. sound_taunt1 = gi.soundindex ("makron/voice4.wav");
  723. sound_taunt2 = gi.soundindex ("makron/voice3.wav");
  724. sound_taunt3 = gi.soundindex ("makron/voice.wav");
  725. sound_hit = gi.soundindex ("makron/bhit.wav");
  726. gi.modelindex ("models/monsters/boss3/rider/tris.md2");
  727. }
  728. /*QUAKED monster_makron (1 .5 0) (-30 -30 0) (30 30 90) Ambush Trigger_Spawn Sight
  729. */
  730. void SP_monster_makron (edict_t *self)
  731. {
  732. if (deathmatch->value)
  733. {
  734. G_FreeEdict (self);
  735. return;
  736. }
  737. MakronPrecache ();
  738. self->movetype = MOVETYPE_STEP;
  739. self->solid = SOLID_BBOX;
  740. self->s.modelindex = gi.modelindex ("models/monsters/boss3/rider/tris.md2");
  741. VectorSet (self->mins, -30, -30, 0);
  742. VectorSet (self->maxs, 30, 30, 90);
  743. self->health = 3000;
  744. self->gib_health = -2000;
  745. self->mass = 500;
  746. self->pain = makron_pain;
  747. self->die = makron_die;
  748. self->monsterinfo.stand = makron_stand;
  749. self->monsterinfo.walk = makron_walk;
  750. self->monsterinfo.run = makron_run;
  751. self->monsterinfo.dodge = NULL;
  752. self->monsterinfo.attack = makron_attack;
  753. self->monsterinfo.melee = NULL;
  754. self->monsterinfo.sight = makron_sight;
  755. self->monsterinfo.checkattack = Makron_CheckAttack;
  756. gi.linkentity (self);
  757. // self->monsterinfo.currentmove = &makron_move_stand;
  758. self->monsterinfo.currentmove = &makron_move_sight;
  759. self->monsterinfo.scale = MODEL_SCALE;
  760. walkmonster_start(self);
  761. }
  762. /*
  763. =================
  764. MakronSpawn
  765. =================
  766. */
  767. void MakronSpawn (edict_t *self)
  768. {
  769. vec3_t vec;
  770. edict_t *player;
  771. SP_monster_makron (self);
  772. // jump at player
  773. player = level.sight_client;
  774. if (!player)
  775. return;
  776. VectorSubtract (player->s.origin, self->s.origin, vec);
  777. self->s.angles[YAW] = vectoyaw(vec);
  778. VectorNormalize (vec);
  779. VectorMA (vec3_origin, 400, vec, self->velocity);
  780. self->velocity[2] = 200;
  781. self->groundentity = NULL;
  782. }
  783. /*
  784. =================
  785. MakronToss
  786. Jorg is just about dead, so set up to launch Makron out
  787. =================
  788. */
  789. void MakronToss (edict_t *self)
  790. {
  791. edict_t *ent;
  792. ent = G_Spawn ();
  793. ent->nextthink = level.time + 0.8;
  794. ent->think = MakronSpawn;
  795. ent->target = self->target;
  796. VectorCopy (self->s.origin, ent->s.origin);
  797. }