m_hover.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793
  1. // Copyright (c) ZeniMax Media Inc.
  2. // Licensed under the GNU General Public License 2.0.
  3. /*
  4. ==============================================================================
  5. hover
  6. ==============================================================================
  7. */
  8. #include "g_local.h"
  9. #include "m_hover.h"
  10. qboolean visible (edict_t *self, edict_t *other);
  11. static int sound_pain1;
  12. static int sound_pain2;
  13. static int sound_death1;
  14. static int sound_death2;
  15. static int sound_sight;
  16. static int sound_search1;
  17. static int sound_search2;
  18. // daedalus sounds
  19. static int daed_sound_pain1;
  20. static int daed_sound_pain2;
  21. static int daed_sound_death1;
  22. static int daed_sound_death2;
  23. static int daed_sound_sight;
  24. static int daed_sound_search1;
  25. static int daed_sound_search2;
  26. void hover_sight (edict_t *self, edict_t *other)
  27. {
  28. // PMM - daedalus sounds
  29. if (self->mass < 225)
  30. gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0);
  31. else
  32. gi.sound (self, CHAN_VOICE, daed_sound_sight, 1, ATTN_NORM, 0);
  33. }
  34. void hover_search (edict_t *self)
  35. {
  36. // PMM - daedalus sounds
  37. if (self->mass < 225)
  38. {
  39. if (random() < 0.5)
  40. gi.sound (self, CHAN_VOICE, sound_search1, 1, ATTN_NORM, 0);
  41. else
  42. gi.sound (self, CHAN_VOICE, sound_search2, 1, ATTN_NORM, 0);
  43. }
  44. else
  45. {
  46. if (random() < 0.5)
  47. gi.sound (self, CHAN_VOICE, daed_sound_search1, 1, ATTN_NORM, 0);
  48. else
  49. gi.sound (self, CHAN_VOICE, daed_sound_search2, 1, ATTN_NORM, 0);
  50. }
  51. }
  52. void hover_run (edict_t *self);
  53. void hover_stand (edict_t *self);
  54. void hover_dead (edict_t *self);
  55. void hover_attack (edict_t *self);
  56. void hover_reattack (edict_t *self);
  57. void hover_fire_blaster (edict_t *self);
  58. void hover_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point);
  59. mframe_t hover_frames_stand [] =
  60. {
  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,
  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,
  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,
  90. ai_stand, 0, NULL
  91. };
  92. mmove_t hover_move_stand = {FRAME_stand01, FRAME_stand30, hover_frames_stand, NULL};
  93. /*
  94. mframe_t hover_frames_stop1 [] =
  95. {
  96. ai_move, 0, NULL,
  97. ai_move, 0, NULL,
  98. ai_move, 0, NULL,
  99. ai_move, 0, NULL,
  100. ai_move, 0, NULL,
  101. ai_move, 0, NULL,
  102. ai_move, 0, NULL,
  103. ai_move, 0, NULL,
  104. ai_move, 0, NULL
  105. };
  106. mmove_t hover_move_stop1 = {FRAME_stop101, FRAME_stop109, hover_frames_stop1, NULL};
  107. mframe_t hover_frames_stop2 [] =
  108. {
  109. ai_move, 0, NULL,
  110. ai_move, 0, NULL,
  111. ai_move, 0, NULL,
  112. ai_move, 0, NULL,
  113. ai_move, 0, NULL,
  114. ai_move, 0, NULL,
  115. ai_move, 0, NULL,
  116. ai_move, 0, NULL
  117. };
  118. mmove_t hover_move_stop2 = {FRAME_stop201, FRAME_stop208, hover_frames_stop2, NULL};
  119. */
  120. /*
  121. mframe_t hover_frames_takeoff [] =
  122. {
  123. ai_move, 0, NULL,
  124. ai_move, -2, NULL,
  125. ai_move, 5, NULL,
  126. ai_move, -1, NULL,
  127. ai_move, 1, NULL,
  128. ai_move, 0, NULL,
  129. ai_move, 0, NULL,
  130. ai_move, -1, NULL,
  131. ai_move, -1, NULL,
  132. ai_move, -1, NULL,
  133. ai_move, 0, NULL,
  134. ai_move, 2, NULL,
  135. ai_move, 2, NULL,
  136. ai_move, 1, NULL,
  137. ai_move, 1, NULL,
  138. ai_move, -6, NULL,
  139. ai_move, -9, NULL,
  140. ai_move, 1, NULL,
  141. ai_move, 0, NULL,
  142. ai_move, 2, NULL,
  143. ai_move, 2, NULL,
  144. ai_move, 1, NULL,
  145. ai_move, 1, NULL,
  146. ai_move, 1, NULL,
  147. ai_move, 2, NULL,
  148. ai_move, 0, NULL,
  149. ai_move, 2, NULL,
  150. ai_move, 3, NULL,
  151. ai_move, 2, NULL,
  152. ai_move, 0, NULL
  153. };
  154. mmove_t hover_move_takeoff = {FRAME_takeof01, FRAME_takeof30, hover_frames_takeoff, NULL};
  155. */
  156. mframe_t hover_frames_pain3 [] =
  157. {
  158. ai_move, 0, NULL,
  159. ai_move, 0, NULL,
  160. ai_move, 0, NULL,
  161. ai_move, 0, NULL,
  162. ai_move, 0, NULL,
  163. ai_move, 0, NULL,
  164. ai_move, 0, NULL,
  165. ai_move, 0, NULL,
  166. ai_move, 0, NULL
  167. };
  168. mmove_t hover_move_pain3 = {FRAME_pain301, FRAME_pain309, hover_frames_pain3, hover_run};
  169. mframe_t hover_frames_pain2 [] =
  170. {
  171. ai_move, 0, NULL,
  172. ai_move, 0, NULL,
  173. ai_move, 0, NULL,
  174. ai_move, 0, NULL,
  175. ai_move, 0, NULL,
  176. ai_move, 0, NULL,
  177. ai_move, 0, NULL,
  178. ai_move, 0, NULL,
  179. ai_move, 0, NULL,
  180. ai_move, 0, NULL,
  181. ai_move, 0, NULL,
  182. ai_move, 0, NULL
  183. };
  184. mmove_t hover_move_pain2 = {FRAME_pain201, FRAME_pain212, hover_frames_pain2, hover_run};
  185. mframe_t hover_frames_pain1 [] =
  186. {
  187. ai_move, 0, NULL,
  188. ai_move, 0, NULL,
  189. ai_move, 2, NULL,
  190. ai_move, -8, NULL,
  191. ai_move, -4, NULL,
  192. ai_move, -6, NULL,
  193. ai_move, -4, NULL,
  194. ai_move, -3, NULL,
  195. ai_move, 1, NULL,
  196. ai_move, 0, NULL,
  197. ai_move, 0, NULL,
  198. ai_move, 0, NULL,
  199. ai_move, 3, NULL,
  200. ai_move, 1, NULL,
  201. ai_move, 0, NULL,
  202. ai_move, 2, NULL,
  203. ai_move, 3, NULL,
  204. ai_move, 2, NULL,
  205. ai_move, 7, NULL,
  206. ai_move, 1, NULL,
  207. ai_move, 0, NULL,
  208. ai_move, 0, NULL,
  209. ai_move, 2, NULL,
  210. ai_move, 0, NULL,
  211. ai_move, 0, NULL,
  212. ai_move, 5, NULL,
  213. ai_move, 3, NULL,
  214. ai_move, 4, NULL
  215. };
  216. mmove_t hover_move_pain1 = {FRAME_pain101, FRAME_pain128, hover_frames_pain1, hover_run};
  217. /*
  218. mframe_t hover_frames_land [] =
  219. {
  220. ai_move, 0, NULL
  221. };
  222. mmove_t hover_move_land = {FRAME_land01, FRAME_land01, hover_frames_land, NULL};
  223. */
  224. /*
  225. mframe_t hover_frames_forward [] =
  226. {
  227. ai_move, 0, NULL,
  228. ai_move, 0, NULL,
  229. ai_move, 0, NULL,
  230. ai_move, 0, NULL,
  231. ai_move, 0, NULL,
  232. ai_move, 0, NULL,
  233. ai_move, 0, NULL,
  234. ai_move, 0, NULL,
  235. ai_move, 0, NULL,
  236. ai_move, 0, NULL,
  237. ai_move, 0, NULL,
  238. ai_move, 0, NULL,
  239. ai_move, 0, NULL,
  240. ai_move, 0, NULL,
  241. ai_move, 0, NULL,
  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,
  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, 0, NULL,
  254. ai_move, 0, NULL,
  255. ai_move, 0, NULL,
  256. ai_move, 0, NULL,
  257. ai_move, 0, NULL,
  258. ai_move, 0, NULL,
  259. ai_move, 0, NULL,
  260. ai_move, 0, NULL,
  261. ai_move, 0, NULL
  262. };
  263. mmove_t hover_move_forward = {FRAME_forwrd01, FRAME_forwrd35, hover_frames_forward, NULL};
  264. */
  265. mframe_t hover_frames_walk [] =
  266. {
  267. ai_walk, 4, NULL,
  268. ai_walk, 4, NULL,
  269. ai_walk, 4, NULL,
  270. ai_walk, 4, NULL,
  271. ai_walk, 4, NULL,
  272. ai_walk, 4, NULL,
  273. ai_walk, 4, NULL,
  274. ai_walk, 4, NULL,
  275. ai_walk, 4, NULL,
  276. ai_walk, 4, NULL,
  277. ai_walk, 4, NULL,
  278. ai_walk, 4, NULL,
  279. ai_walk, 4, NULL,
  280. ai_walk, 4, NULL,
  281. ai_walk, 4, NULL,
  282. ai_walk, 4, NULL,
  283. ai_walk, 4, NULL,
  284. ai_walk, 4, NULL,
  285. ai_walk, 4, NULL,
  286. ai_walk, 4, NULL,
  287. ai_walk, 4, NULL,
  288. ai_walk, 4, NULL,
  289. ai_walk, 4, NULL,
  290. ai_walk, 4, NULL,
  291. ai_walk, 4, NULL,
  292. ai_walk, 4, NULL,
  293. ai_walk, 4, NULL,
  294. ai_walk, 4, NULL,
  295. ai_walk, 4, NULL,
  296. ai_walk, 4, NULL,
  297. ai_walk, 4, NULL,
  298. ai_walk, 4, NULL,
  299. ai_walk, 4, NULL,
  300. ai_walk, 4, NULL,
  301. ai_walk, 4, NULL
  302. };
  303. mmove_t hover_move_walk = {FRAME_forwrd01, FRAME_forwrd35, hover_frames_walk, NULL};
  304. mframe_t hover_frames_run [] =
  305. {
  306. ai_run, 10, NULL,
  307. ai_run, 10, NULL,
  308. ai_run, 10, NULL,
  309. ai_run, 10, NULL,
  310. ai_run, 10, NULL,
  311. ai_run, 10, NULL,
  312. ai_run, 10, NULL,
  313. ai_run, 10, NULL,
  314. ai_run, 10, NULL,
  315. ai_run, 10, NULL,
  316. ai_run, 10, NULL,
  317. ai_run, 10, NULL,
  318. ai_run, 10, NULL,
  319. ai_run, 10, NULL,
  320. ai_run, 10, NULL,
  321. ai_run, 10, NULL,
  322. ai_run, 10, NULL,
  323. ai_run, 10, NULL,
  324. ai_run, 10, NULL,
  325. ai_run, 10, NULL,
  326. ai_run, 10, NULL,
  327. ai_run, 10, NULL,
  328. ai_run, 10, NULL,
  329. ai_run, 10, NULL,
  330. ai_run, 10, NULL,
  331. ai_run, 10, NULL,
  332. ai_run, 10, NULL,
  333. ai_run, 10, NULL,
  334. ai_run, 10, NULL,
  335. ai_run, 10, NULL,
  336. ai_run, 10, NULL,
  337. ai_run, 10, NULL,
  338. ai_run, 10, NULL,
  339. ai_run, 10, NULL,
  340. ai_run, 10, NULL
  341. };
  342. mmove_t hover_move_run = {FRAME_forwrd01, FRAME_forwrd35, hover_frames_run, NULL};
  343. mframe_t hover_frames_death1 [] =
  344. {
  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, -10,NULL,
  352. ai_move, 3, NULL,
  353. ai_move, 5, NULL,
  354. ai_move, 4, NULL,
  355. ai_move, 7, NULL
  356. };
  357. mmove_t hover_move_death1 = {FRAME_death101, FRAME_death111, hover_frames_death1, hover_dead};
  358. /*
  359. mframe_t hover_frames_backward [] =
  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. ai_move, 0, NULL,
  375. ai_move, 0, NULL,
  376. ai_move, 0, NULL,
  377. ai_move, 0, NULL,
  378. ai_move, 0, NULL,
  379. ai_move, 0, NULL,
  380. ai_move, 0, NULL,
  381. ai_move, 0, NULL,
  382. ai_move, 0, NULL,
  383. ai_move, 0, NULL,
  384. ai_move, 0, NULL
  385. };
  386. mmove_t hover_move_backward = {FRAME_backwd01, FRAME_backwd24, hover_frames_backward, NULL};
  387. */
  388. mframe_t hover_frames_start_attack [] =
  389. {
  390. ai_charge, 1, NULL,
  391. ai_charge, 1, NULL,
  392. ai_charge, 1, NULL
  393. };
  394. mmove_t hover_move_start_attack = {FRAME_attak101, FRAME_attak103, hover_frames_start_attack, hover_attack};
  395. mframe_t hover_frames_attack1 [] =
  396. {
  397. ai_charge, -10, hover_fire_blaster,
  398. ai_charge, -10, hover_fire_blaster,
  399. ai_charge, 0, hover_reattack,
  400. };
  401. mmove_t hover_move_attack1 = {FRAME_attak104, FRAME_attak106, hover_frames_attack1, NULL};
  402. mframe_t hover_frames_end_attack [] =
  403. {
  404. ai_charge, 1, NULL,
  405. ai_charge, 1, NULL
  406. };
  407. mmove_t hover_move_end_attack = {FRAME_attak107, FRAME_attak108, hover_frames_end_attack, hover_run};
  408. /* PMM - circle strafing code */
  409. mframe_t hover_frames_start_attack2 [] =
  410. {
  411. ai_charge, 15, NULL,
  412. ai_charge, 15, NULL,
  413. ai_charge, 15, NULL
  414. };
  415. mmove_t hover_move_start_attack2 = {FRAME_attak101, FRAME_attak103, hover_frames_start_attack2, hover_attack};
  416. mframe_t hover_frames_attack2 [] =
  417. {
  418. ai_charge, 10, hover_fire_blaster,
  419. ai_charge, 10, hover_fire_blaster,
  420. ai_charge, 10, hover_reattack,
  421. };
  422. mmove_t hover_move_attack2 = {FRAME_attak104, FRAME_attak106, hover_frames_attack2, NULL};
  423. mframe_t hover_frames_end_attack2 [] =
  424. {
  425. ai_charge, 15, NULL,
  426. ai_charge, 15, NULL
  427. };
  428. mmove_t hover_move_end_attack2 = {FRAME_attak107, FRAME_attak108, hover_frames_end_attack2, hover_run};
  429. // end of circle strafe
  430. void hover_reattack (edict_t *self)
  431. {
  432. if (self->enemy->health > 0 )
  433. if (visible (self, self->enemy) )
  434. if (random() <= 0.6)
  435. {
  436. if (self->monsterinfo.attack_state == AS_STRAIGHT)
  437. {
  438. self->monsterinfo.currentmove = &hover_move_attack1;
  439. return;
  440. }
  441. else if (self->monsterinfo.attack_state == AS_SLIDING)
  442. {
  443. self->monsterinfo.currentmove = &hover_move_attack2;
  444. return;
  445. }
  446. else
  447. gi.dprintf ("hover_reattack: unexpected state %d\n", self->monsterinfo.attack_state);
  448. }
  449. self->monsterinfo.currentmove = &hover_move_end_attack;
  450. }
  451. void hover_fire_blaster (edict_t *self)
  452. {
  453. vec3_t start;
  454. vec3_t forward, right;
  455. vec3_t end;
  456. vec3_t dir;
  457. int effect;
  458. if(!self->enemy || !self->enemy->inuse) //PGM
  459. return; //PGM
  460. if (self->s.frame == FRAME_attak104)
  461. effect = EF_HYPERBLASTER;
  462. else
  463. effect = 0;
  464. AngleVectors (self->s.angles, forward, right, NULL);
  465. G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_HOVER_BLASTER_1], forward, right, start);
  466. VectorCopy (self->enemy->s.origin, end);
  467. end[2] += self->enemy->viewheight;
  468. VectorSubtract (end, start, dir);
  469. //PGM - daedalus fires blaster2
  470. if(self->mass < 200)
  471. monster_fire_blaster (self, start, dir, 1, 1000, MZ2_HOVER_BLASTER_1, effect);
  472. else
  473. monster_fire_blaster2 (self, start, dir, 1, 1000, MZ2_DAEDALUS_BLASTER, EF_BLASTER);
  474. // fixme - different muzzle flash
  475. //PGM
  476. }
  477. void hover_stand (edict_t *self)
  478. {
  479. self->monsterinfo.currentmove = &hover_move_stand;
  480. }
  481. void hover_run (edict_t *self)
  482. {
  483. if (self->monsterinfo.aiflags & AI_STAND_GROUND)
  484. self->monsterinfo.currentmove = &hover_move_stand;
  485. else
  486. self->monsterinfo.currentmove = &hover_move_run;
  487. }
  488. void hover_walk (edict_t *self)
  489. {
  490. self->monsterinfo.currentmove = &hover_move_walk;
  491. }
  492. void hover_start_attack (edict_t *self)
  493. {
  494. self->monsterinfo.currentmove = &hover_move_start_attack;
  495. }
  496. void hover_attack(edict_t *self)
  497. {
  498. float chance;
  499. /* if (random() <= 0.5)
  500. self->monsterinfo.currentmove = &flyer_move_attack1;
  501. else */
  502. // 0% chance of circle in easy
  503. // 50% chance in normal
  504. // 75% chance in hard
  505. // 86.67% chance in nightmare
  506. if (!skill->value)
  507. chance = 0;
  508. else
  509. chance = 1.0 - (0.5/(float)(skill->value));
  510. if (self->mass > 150) // the daedalus strafes more
  511. chance += 0.1;
  512. if (random() > chance)
  513. {
  514. self->monsterinfo.currentmove = &hover_move_attack1;
  515. self->monsterinfo.attack_state = AS_STRAIGHT;
  516. }
  517. else // circle strafe
  518. {
  519. if (random () <= 0.5) // switch directions
  520. self->monsterinfo.lefty = 1 - self->monsterinfo.lefty;
  521. self->monsterinfo.currentmove = &hover_move_attack2;
  522. self->monsterinfo.attack_state = AS_SLIDING;
  523. }
  524. }
  525. void hover_pain (edict_t *self, edict_t *other, float kick, int damage)
  526. {
  527. if (self->health < (self->max_health / 2))
  528. self->s.skinnum |= 1; // PGM support for skins 2 & 3.
  529. if (level.time < self->pain_debounce_time)
  530. return;
  531. self->pain_debounce_time = level.time + 3;
  532. if (skill->value == 3)
  533. return; // no pain anims in nightmare
  534. if (damage <= 25)
  535. {
  536. if (random() < 0.5)
  537. {
  538. // PMM - daedalus sounds
  539. if (self->mass < 225)
  540. gi.sound (self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0);
  541. else
  542. gi.sound (self, CHAN_VOICE, daed_sound_pain1, 1, ATTN_NORM, 0);
  543. self->monsterinfo.currentmove = &hover_move_pain3;
  544. }
  545. else
  546. {
  547. // PMM - daedalus sounds
  548. if (self->mass < 225)
  549. gi.sound (self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0);
  550. else
  551. gi.sound (self, CHAN_VOICE, daed_sound_pain2, 1, ATTN_NORM, 0);
  552. self->monsterinfo.currentmove = &hover_move_pain2;
  553. }
  554. }
  555. else
  556. {
  557. //====
  558. //PGM pain sequence is WAY too long
  559. if (random() < (0.45 - (0.1 * skill->value)))
  560. {
  561. // PMM - daedalus sounds
  562. if (self->mass < 225)
  563. gi.sound (self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0);
  564. else
  565. gi.sound (self, CHAN_VOICE, daed_sound_pain1, 1, ATTN_NORM, 0);
  566. self->monsterinfo.currentmove = &hover_move_pain1;
  567. }
  568. else
  569. {
  570. // PMM - daedalus sounds
  571. if (self->mass < 225)
  572. gi.sound (self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0);
  573. else
  574. gi.sound (self, CHAN_VOICE, daed_sound_pain2, 1, ATTN_NORM, 0);
  575. self->monsterinfo.currentmove = &hover_move_pain2;
  576. }
  577. //PGM
  578. //====
  579. }
  580. }
  581. void hover_deadthink (edict_t *self)
  582. {
  583. if (!self->groundentity && level.time < self->timestamp)
  584. {
  585. self->nextthink = level.time + FRAMETIME;
  586. return;
  587. }
  588. BecomeExplosion1(self);
  589. }
  590. void hover_dead (edict_t *self)
  591. {
  592. VectorSet (self->mins, -16, -16, -24);
  593. VectorSet (self->maxs, 16, 16, -8);
  594. self->movetype = MOVETYPE_TOSS;
  595. self->think = hover_deadthink;
  596. self->nextthink = level.time + FRAMETIME;
  597. self->timestamp = level.time + 15;
  598. gi.linkentity (self);
  599. }
  600. void hover_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
  601. {
  602. int n;
  603. self->s.effects = 0;
  604. self->monsterinfo.power_armor_type = POWER_ARMOR_NONE;
  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 < 2; n++)
  610. ThrowGib (self, "models/objects/gibs/bone/tris.md2", damage, GIB_ORGANIC);
  611. for (n= 0; n < 2; n++)
  612. ThrowGib (self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC);
  613. ThrowHead (self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC);
  614. self->deadflag = DEAD_DEAD;
  615. return;
  616. }
  617. if (self->deadflag == DEAD_DEAD)
  618. return;
  619. // regular death
  620. // PMM - daedalus sounds
  621. if (self->mass < 225)
  622. {
  623. if (random() < 0.5)
  624. gi.sound (self, CHAN_VOICE, sound_death1, 1, ATTN_NORM, 0);
  625. else
  626. gi.sound (self, CHAN_VOICE, sound_death2, 1, ATTN_NORM, 0);
  627. }
  628. else
  629. {
  630. if (random() < 0.5)
  631. gi.sound (self, CHAN_VOICE, daed_sound_death1, 1, ATTN_NORM, 0);
  632. else
  633. gi.sound (self, CHAN_VOICE, daed_sound_death2, 1, ATTN_NORM, 0);
  634. }
  635. self->deadflag = DEAD_DEAD;
  636. self->takedamage = DAMAGE_YES;
  637. self->monsterinfo.currentmove = &hover_move_death1;
  638. }
  639. //===========
  640. //PGM
  641. qboolean hover_blocked (edict_t *self, float dist)
  642. {
  643. if(blocked_checkshot (self, 0.25 + (0.05 * skill->value) ))
  644. return true;
  645. return false;
  646. }
  647. //PGM
  648. //===========
  649. /*QUAKED monster_hover (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight
  650. */
  651. /*QUAKED monster_daedalus (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight
  652. This is the improved icarus monster.
  653. */
  654. void SP_monster_hover (edict_t *self)
  655. {
  656. if (deathmatch->value)
  657. {
  658. G_FreeEdict (self);
  659. return;
  660. }
  661. self->movetype = MOVETYPE_STEP;
  662. self->solid = SOLID_BBOX;
  663. self->s.modelindex = gi.modelindex("models/monsters/hover/tris.md2");
  664. VectorSet (self->mins, -24, -24, -24);
  665. VectorSet (self->maxs, 24, 24, 32);
  666. self->health = 240;
  667. self->gib_health = -100;
  668. self->mass = 150;
  669. self->pain = hover_pain;
  670. self->die = hover_die;
  671. self->monsterinfo.stand = hover_stand;
  672. self->monsterinfo.walk = hover_walk;
  673. self->monsterinfo.run = hover_run;
  674. // self->monsterinfo.dodge = hover_dodge;
  675. self->monsterinfo.attack = hover_start_attack;
  676. self->monsterinfo.sight = hover_sight;
  677. self->monsterinfo.search = hover_search;
  678. self->monsterinfo.blocked = hover_blocked; // PGM
  679. //PGM
  680. if (strcmp(self->classname, "monster_daedalus") == 0)
  681. {
  682. self->health = 450;
  683. self->mass = 225;
  684. self->yaw_speed = 25;
  685. self->monsterinfo.power_armor_type = POWER_ARMOR_SCREEN;
  686. self->monsterinfo.power_armor_power = 100;
  687. // PMM - daedalus sounds
  688. self->s.sound = gi.soundindex ("daedalus/daedidle1.wav");
  689. daed_sound_pain1 = gi.soundindex ("daedalus/daedpain1.wav");
  690. daed_sound_pain2 = gi.soundindex ("daedalus/daedpain2.wav");
  691. daed_sound_death1 = gi.soundindex ("daedalus/daeddeth1.wav");
  692. daed_sound_death2 = gi.soundindex ("daedalus/daeddeth2.wav");
  693. daed_sound_sight = gi.soundindex ("daedalus/daedsght1.wav");
  694. daed_sound_search1 = gi.soundindex ("daedalus/daedsrch1.wav");
  695. daed_sound_search2 = gi.soundindex ("daedalus/daedsrch2.wav");
  696. gi.soundindex ("tank/tnkatck3.wav");
  697. // pmm
  698. }
  699. else
  700. {
  701. sound_pain1 = gi.soundindex ("hover/hovpain1.wav");
  702. sound_pain2 = gi.soundindex ("hover/hovpain2.wav");
  703. sound_death1 = gi.soundindex ("hover/hovdeth1.wav");
  704. sound_death2 = gi.soundindex ("hover/hovdeth2.wav");
  705. sound_sight = gi.soundindex ("hover/hovsght1.wav");
  706. sound_search1 = gi.soundindex ("hover/hovsrch1.wav");
  707. sound_search2 = gi.soundindex ("hover/hovsrch2.wav");
  708. gi.soundindex ("hover/hovatck1.wav");
  709. self->s.sound = gi.soundindex ("hover/hovidle1.wav");
  710. }
  711. //PGM
  712. gi.linkentity (self);
  713. self->monsterinfo.currentmove = &hover_move_stand;
  714. self->monsterinfo.scale = MODEL_SCALE;
  715. flymonster_start (self);
  716. //PGM
  717. if (strcmp(self->classname, "monster_daedalus") == 0)
  718. self->s.skinnum = 2;
  719. //PGM
  720. }