m_boss31.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750
  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. jorg
  18. ==============================================================================
  19. */
  20. #include "g_local.h"
  21. #include "m_boss31.h"
  22. extern SP_monster_makron (edict_t *self);
  23. qboolean visible (edict_t *self, edict_t *other);
  24. static int sound_pain1;
  25. static int sound_pain2;
  26. static int sound_pain3;
  27. static int sound_idle;
  28. static int sound_death;
  29. static int sound_search1;
  30. static int sound_search2;
  31. static int sound_search3;
  32. static int sound_attack1;
  33. static int sound_attack2;
  34. static int sound_firegun;
  35. static int sound_step_left;
  36. static int sound_step_right;
  37. static int sound_death_hit;
  38. void BossExplode (edict_t *self);
  39. void MakronToss (edict_t *self);
  40. void jorg_search (edict_t *self)
  41. {
  42. float r;
  43. r = random();
  44. if (r <= 0.3)
  45. gi.sound (self, CHAN_VOICE, sound_search1, 1, ATTN_NORM, 0);
  46. else if (r <= 0.6)
  47. gi.sound (self, CHAN_VOICE, sound_search2, 1, ATTN_NORM, 0);
  48. else
  49. gi.sound (self, CHAN_VOICE, sound_search3, 1, ATTN_NORM, 0);
  50. }
  51. void jorg_dead (edict_t *self);
  52. void jorgBFG (edict_t *self);
  53. void jorgMachineGun (edict_t *self);
  54. void jorg_firebullet (edict_t *self);
  55. void jorg_reattack1(edict_t *self);
  56. void jorg_attack1(edict_t *self);
  57. void jorg_idle(edict_t *self);
  58. void jorg_step_left(edict_t *self);
  59. void jorg_step_right(edict_t *self);
  60. void jorg_death_hit(edict_t *self);
  61. //
  62. // stand
  63. //
  64. mframe_t jorg_frames_stand []=
  65. {
  66. ai_stand, 0, jorg_idle,
  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, // 10
  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, // 20
  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. ai_stand, 0, NULL,
  92. ai_stand, 0, NULL,
  93. ai_stand, 0, NULL,
  94. ai_stand, 0, NULL,
  95. ai_stand, 0, NULL, // 30
  96. ai_stand, 0, NULL,
  97. ai_stand, 0, NULL,
  98. ai_stand, 0, NULL,
  99. ai_stand, 19, NULL,
  100. ai_stand, 11, jorg_step_left,
  101. ai_stand, 0, NULL,
  102. ai_stand, 0, NULL,
  103. ai_stand, 6, NULL,
  104. ai_stand, 9, jorg_step_right,
  105. ai_stand, 0, NULL, // 40
  106. ai_stand, 0, NULL,
  107. ai_stand, 0, NULL,
  108. ai_stand, 0, NULL,
  109. ai_stand, 0, NULL,
  110. ai_stand, 0, NULL,
  111. ai_stand, 0, NULL,
  112. ai_stand, -2, NULL,
  113. ai_stand, -17, jorg_step_left,
  114. ai_stand, 0, NULL,
  115. ai_stand, -12, NULL, // 50
  116. ai_stand, -14, jorg_step_right // 51
  117. };
  118. mmove_t jorg_move_stand = {FRAME_stand01, FRAME_stand51, jorg_frames_stand, NULL};
  119. void jorg_idle (edict_t *self)
  120. {
  121. gi.sound (self, CHAN_VOICE, sound_idle, 1, ATTN_NORM,0);
  122. }
  123. void jorg_death_hit (edict_t *self)
  124. {
  125. gi.sound (self, CHAN_BODY, sound_death_hit, 1, ATTN_NORM,0);
  126. }
  127. void jorg_step_left (edict_t *self)
  128. {
  129. gi.sound (self, CHAN_BODY, sound_step_left, 1, ATTN_NORM,0);
  130. }
  131. void jorg_step_right (edict_t *self)
  132. {
  133. gi.sound (self, CHAN_BODY, sound_step_right, 1, ATTN_NORM,0);
  134. }
  135. void jorg_stand (edict_t *self)
  136. {
  137. self->monsterinfo.currentmove = &jorg_move_stand;
  138. }
  139. mframe_t jorg_frames_run [] =
  140. {
  141. ai_run, 17, jorg_step_left,
  142. ai_run, 0, NULL,
  143. ai_run, 0, NULL,
  144. ai_run, 0, NULL,
  145. ai_run, 12, NULL,
  146. ai_run, 8, NULL,
  147. ai_run, 10, NULL,
  148. ai_run, 33, jorg_step_right,
  149. ai_run, 0, NULL,
  150. ai_run, 0, NULL,
  151. ai_run, 0, NULL,
  152. ai_run, 9, NULL,
  153. ai_run, 9, NULL,
  154. ai_run, 9, NULL
  155. };
  156. mmove_t jorg_move_run = {FRAME_walk06, FRAME_walk19, jorg_frames_run, NULL};
  157. //
  158. // walk
  159. //
  160. mframe_t jorg_frames_start_walk [] =
  161. {
  162. ai_walk, 5, NULL,
  163. ai_walk, 6, NULL,
  164. ai_walk, 7, NULL,
  165. ai_walk, 9, NULL,
  166. ai_walk, 15, NULL
  167. };
  168. mmove_t jorg_move_start_walk = {FRAME_walk01, FRAME_walk05, jorg_frames_start_walk, NULL};
  169. mframe_t jorg_frames_walk [] =
  170. {
  171. ai_walk, 17, NULL,
  172. ai_walk, 0, NULL,
  173. ai_walk, 0, NULL,
  174. ai_walk, 0, NULL,
  175. ai_walk, 12, NULL,
  176. ai_walk, 8, NULL,
  177. ai_walk, 10, NULL,
  178. ai_walk, 33, NULL,
  179. ai_walk, 0, NULL,
  180. ai_walk, 0, NULL,
  181. ai_walk, 0, NULL,
  182. ai_walk, 9, NULL,
  183. ai_walk, 9, NULL,
  184. ai_walk, 9, NULL
  185. };
  186. mmove_t jorg_move_walk = {FRAME_walk06, FRAME_walk19, jorg_frames_walk, NULL};
  187. mframe_t jorg_frames_end_walk [] =
  188. {
  189. ai_walk, 11, NULL,
  190. ai_walk, 0, NULL,
  191. ai_walk, 0, NULL,
  192. ai_walk, 0, NULL,
  193. ai_walk, 8, NULL,
  194. ai_walk, -8, NULL
  195. };
  196. mmove_t jorg_move_end_walk = {FRAME_walk20, FRAME_walk25, jorg_frames_end_walk, NULL};
  197. void jorg_walk (edict_t *self)
  198. {
  199. self->monsterinfo.currentmove = &jorg_move_walk;
  200. }
  201. void jorg_run (edict_t *self)
  202. {
  203. if (self->monsterinfo.aiflags & AI_STAND_GROUND)
  204. self->monsterinfo.currentmove = &jorg_move_stand;
  205. else
  206. self->monsterinfo.currentmove = &jorg_move_run;
  207. }
  208. mframe_t jorg_frames_pain3 [] =
  209. {
  210. ai_move, -28, NULL,
  211. ai_move, -6, NULL,
  212. ai_move, -3, jorg_step_left,
  213. ai_move, -9, NULL,
  214. ai_move, 0, jorg_step_right,
  215. ai_move, 0, NULL,
  216. ai_move, 0, NULL,
  217. ai_move, 0, NULL,
  218. ai_move, -7, NULL,
  219. ai_move, 1, NULL,
  220. ai_move, -11, NULL,
  221. ai_move, -4, NULL,
  222. ai_move, 0, NULL,
  223. ai_move, 0, NULL,
  224. ai_move, 10, NULL,
  225. ai_move, 11, NULL,
  226. ai_move, 0, NULL,
  227. ai_move, 10, NULL,
  228. ai_move, 3, NULL,
  229. ai_move, 10, NULL,
  230. ai_move, 7, jorg_step_left,
  231. ai_move, 17, NULL,
  232. ai_move, 0, NULL,
  233. ai_move, 0, NULL,
  234. ai_move, 0, jorg_step_right
  235. };
  236. mmove_t jorg_move_pain3 = {FRAME_pain301, FRAME_pain325, jorg_frames_pain3, jorg_run};
  237. mframe_t jorg_frames_pain2 [] =
  238. {
  239. ai_move, 0, NULL,
  240. ai_move, 0, NULL,
  241. ai_move, 0, NULL
  242. };
  243. mmove_t jorg_move_pain2 = {FRAME_pain201, FRAME_pain203, jorg_frames_pain2, jorg_run};
  244. mframe_t jorg_frames_pain1 [] =
  245. {
  246. ai_move, 0, NULL,
  247. ai_move, 0, NULL,
  248. ai_move, 0, NULL
  249. };
  250. mmove_t jorg_move_pain1 = {FRAME_pain101, FRAME_pain103, jorg_frames_pain1, jorg_run};
  251. mframe_t jorg_frames_death1 [] =
  252. {
  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. ai_move, 0, NULL, // 10
  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,
  268. ai_move, 0, NULL,
  269. ai_move, 0, NULL,
  270. ai_move, 0, NULL,
  271. ai_move, 0, NULL,
  272. ai_move, 0, NULL, // 20
  273. ai_move, 0, NULL,
  274. ai_move, 0, NULL,
  275. ai_move, 0, NULL,
  276. ai_move, 0, NULL,
  277. ai_move, 0, NULL,
  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, // 30
  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,
  288. ai_move, 0, NULL,
  289. ai_move, 0, NULL,
  290. ai_move, 0, NULL,
  291. ai_move, 0, NULL,
  292. ai_move, 0, NULL, // 40
  293. ai_move, 0, NULL,
  294. ai_move, 0, NULL,
  295. ai_move, 0, NULL,
  296. ai_move, 0, NULL,
  297. ai_move, 0, NULL,
  298. ai_move, 0, NULL,
  299. ai_move, 0, NULL,
  300. ai_move, 0, NULL,
  301. ai_move, 0, MakronToss,
  302. ai_move, 0, BossExplode // 50
  303. };
  304. mmove_t jorg_move_death = {FRAME_death01, FRAME_death50, jorg_frames_death1, jorg_dead};
  305. mframe_t jorg_frames_attack2 []=
  306. {
  307. ai_charge, 0, NULL,
  308. ai_charge, 0, NULL,
  309. ai_charge, 0, NULL,
  310. ai_charge, 0, NULL,
  311. ai_charge, 0, NULL,
  312. ai_charge, 0, NULL,
  313. ai_charge, 0, jorgBFG,
  314. ai_move, 0, NULL,
  315. ai_move, 0, NULL,
  316. ai_move, 0, NULL,
  317. ai_move, 0, NULL,
  318. ai_move, 0, NULL,
  319. ai_move, 0, NULL
  320. };
  321. mmove_t jorg_move_attack2 = {FRAME_attak201, FRAME_attak213, jorg_frames_attack2, jorg_run};
  322. mframe_t jorg_frames_start_attack1 [] =
  323. {
  324. ai_charge, 0, NULL,
  325. ai_charge, 0, NULL,
  326. ai_charge, 0, NULL,
  327. ai_charge, 0, NULL,
  328. ai_charge, 0, NULL,
  329. ai_charge, 0, NULL,
  330. ai_charge, 0, NULL,
  331. ai_charge, 0, NULL
  332. };
  333. mmove_t jorg_move_start_attack1 = {FRAME_attak101, FRAME_attak108, jorg_frames_start_attack1, jorg_attack1};
  334. mframe_t jorg_frames_attack1[]=
  335. {
  336. ai_charge, 0, jorg_firebullet,
  337. ai_charge, 0, jorg_firebullet,
  338. ai_charge, 0, jorg_firebullet,
  339. ai_charge, 0, jorg_firebullet,
  340. ai_charge, 0, jorg_firebullet,
  341. ai_charge, 0, jorg_firebullet
  342. };
  343. mmove_t jorg_move_attack1 = {FRAME_attak109, FRAME_attak114, jorg_frames_attack1, jorg_reattack1};
  344. mframe_t jorg_frames_end_attack1[]=
  345. {
  346. ai_move, 0, NULL,
  347. ai_move, 0, NULL,
  348. ai_move, 0, NULL,
  349. ai_move, 0, NULL
  350. };
  351. mmove_t jorg_move_end_attack1 = {FRAME_attak115, FRAME_attak118, jorg_frames_end_attack1, jorg_run};
  352. void jorg_reattack1(edict_t *self)
  353. {
  354. if (visible(self, self->enemy))
  355. if (random() < 0.9)
  356. self->monsterinfo.currentmove = &jorg_move_attack1;
  357. else
  358. {
  359. self->s.sound = 0;
  360. self->monsterinfo.currentmove = &jorg_move_end_attack1;
  361. }
  362. else
  363. {
  364. self->s.sound = 0;
  365. self->monsterinfo.currentmove = &jorg_move_end_attack1;
  366. }
  367. }
  368. void jorg_attack1(edict_t *self)
  369. {
  370. self->monsterinfo.currentmove = &jorg_move_attack1;
  371. }
  372. void jorg_pain (edict_t *self, edict_t *other, float kick, int damage)
  373. {
  374. if (self->health < (self->max_health / 2))
  375. self->s.skinnum = 1;
  376. self->s.sound = 0;
  377. if (level.time < self->pain_debounce_time)
  378. return;
  379. // Lessen the chance of him going into his pain frames if he takes little damage
  380. if (damage <= 40)
  381. if (random()<=0.6)
  382. return;
  383. /*
  384. If he's entering his attack1 or using attack1, lessen the chance of him
  385. going into pain
  386. */
  387. if ( (self->s.frame >= FRAME_attak101) && (self->s.frame <= FRAME_attak108) )
  388. if (random() <= 0.005)
  389. return;
  390. if ( (self->s.frame >= FRAME_attak109) && (self->s.frame <= FRAME_attak114) )
  391. if (random() <= 0.00005)
  392. return;
  393. if ( (self->s.frame >= FRAME_attak201) && (self->s.frame <= FRAME_attak208) )
  394. if (random() <= 0.005)
  395. return;
  396. self->pain_debounce_time = level.time + 3;
  397. if (skill->value == 3)
  398. return; // no pain anims in nightmare
  399. if (damage <= 50)
  400. {
  401. gi.sound (self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM,0);
  402. self->monsterinfo.currentmove = &jorg_move_pain1;
  403. }
  404. else if (damage <= 100)
  405. {
  406. gi.sound (self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM,0);
  407. self->monsterinfo.currentmove = &jorg_move_pain2;
  408. }
  409. else
  410. {
  411. if (random() <= 0.3)
  412. {
  413. gi.sound (self, CHAN_VOICE, sound_pain3, 1, ATTN_NORM,0);
  414. self->monsterinfo.currentmove = &jorg_move_pain3;
  415. }
  416. }
  417. };
  418. void jorgBFG (edict_t *self)
  419. {
  420. vec3_t forward, right;
  421. vec3_t start;
  422. vec3_t dir;
  423. vec3_t vec;
  424. AngleVectors (self->s.angles, forward, right, NULL);
  425. G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_JORG_BFG_1], forward, right, start);
  426. VectorCopy (self->enemy->s.origin, vec);
  427. vec[2] += self->enemy->viewheight;
  428. VectorSubtract (vec, start, dir);
  429. VectorNormalize (dir);
  430. gi.sound (self, CHAN_VOICE, sound_attack2, 1, ATTN_NORM, 0);
  431. /*void monster_fire_bfg (edict_t *self,
  432. vec3_t start,
  433. vec3_t aimdir,
  434. int damage,
  435. int speed,
  436. int kick,
  437. float damage_radius,
  438. int flashtype)*/
  439. monster_fire_bfg (self, start, dir, 50, 300, 100, 200, MZ2_JORG_BFG_1);
  440. }
  441. void jorg_firebullet_right (edict_t *self)
  442. {
  443. vec3_t forward, right, target;
  444. vec3_t start;
  445. AngleVectors (self->s.angles, forward, right, NULL);
  446. G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_JORG_MACHINEGUN_R1], forward, right, start);
  447. VectorMA (self->enemy->s.origin, -0.2, self->enemy->velocity, target);
  448. target[2] += self->enemy->viewheight;
  449. VectorSubtract (target, start, forward);
  450. VectorNormalize (forward);
  451. monster_fire_bullet (self, start, forward, 6, 4, DEFAULT_BULLET_HSPREAD, DEFAULT_BULLET_VSPREAD, MZ2_JORG_MACHINEGUN_R1);
  452. }
  453. void jorg_firebullet_left (edict_t *self)
  454. {
  455. vec3_t forward, right, target;
  456. vec3_t start;
  457. AngleVectors (self->s.angles, forward, right, NULL);
  458. G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_JORG_MACHINEGUN_L1], forward, right, start);
  459. VectorMA (self->enemy->s.origin, -0.2, self->enemy->velocity, target);
  460. target[2] += self->enemy->viewheight;
  461. VectorSubtract (target, start, forward);
  462. VectorNormalize (forward);
  463. monster_fire_bullet (self, start, forward, 6, 4, DEFAULT_BULLET_HSPREAD, DEFAULT_BULLET_VSPREAD, MZ2_JORG_MACHINEGUN_L1);
  464. }
  465. void jorg_firebullet (edict_t *self)
  466. {
  467. jorg_firebullet_left(self);
  468. jorg_firebullet_right(self);
  469. };
  470. void jorg_attack(edict_t *self)
  471. {
  472. vec3_t vec;
  473. float range;
  474. VectorSubtract (self->enemy->s.origin, self->s.origin, vec);
  475. range = VectorLength (vec);
  476. if (random() <= 0.75)
  477. {
  478. gi.sound (self, CHAN_VOICE, sound_attack1, 1, ATTN_NORM,0);
  479. self->s.sound = gi.soundindex ("boss3/w_loop.wav");
  480. self->monsterinfo.currentmove = &jorg_move_start_attack1;
  481. }
  482. else
  483. {
  484. gi.sound (self, CHAN_VOICE, sound_attack2, 1, ATTN_NORM,0);
  485. self->monsterinfo.currentmove = &jorg_move_attack2;
  486. }
  487. }
  488. void jorg_dead (edict_t *self)
  489. {
  490. #if 0
  491. edict_t *tempent;
  492. /*
  493. VectorSet (self->mins, -16, -16, -24);
  494. VectorSet (self->maxs, 16, 16, -8);
  495. */
  496. // Jorg is on modelindex2. Do not clear him.
  497. VectorSet (self->mins, -60, -60, 0);
  498. VectorSet (self->maxs, 60, 60, 72);
  499. self->movetype = MOVETYPE_TOSS;
  500. self->nextthink = 0;
  501. gi.linkentity (self);
  502. tempent = G_Spawn();
  503. VectorCopy (self->s.origin, tempent->s.origin);
  504. VectorCopy (self->s.angles, tempent->s.angles);
  505. tempent->killtarget = self->killtarget;
  506. tempent->target = self->target;
  507. tempent->activator = self->enemy;
  508. self->killtarget = 0;
  509. self->target = 0;
  510. SP_monster_makron (tempent);
  511. #endif
  512. }
  513. void jorg_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
  514. {
  515. gi.sound (self, CHAN_VOICE, sound_death, 1, ATTN_NORM, 0);
  516. self->deadflag = DEAD_DEAD;
  517. self->takedamage = DAMAGE_NO;
  518. self->s.sound = 0;
  519. self->count = 0;
  520. self->monsterinfo.currentmove = &jorg_move_death;
  521. }
  522. qboolean Jorg_CheckAttack (edict_t *self)
  523. {
  524. vec3_t spot1, spot2;
  525. vec3_t temp;
  526. float chance;
  527. trace_t tr;
  528. qboolean enemy_infront;
  529. int enemy_range;
  530. float enemy_yaw;
  531. if (self->enemy->health > 0)
  532. {
  533. // see if any entities are in the way of the shot
  534. VectorCopy (self->s.origin, spot1);
  535. spot1[2] += self->viewheight;
  536. VectorCopy (self->enemy->s.origin, spot2);
  537. spot2[2] += self->enemy->viewheight;
  538. tr = gi.trace (spot1, NULL, NULL, spot2, self, CONTENTS_SOLID|CONTENTS_MONSTER|CONTENTS_SLIME|CONTENTS_LAVA);
  539. // do we have a clear shot?
  540. if (tr.ent != self->enemy)
  541. return false;
  542. }
  543. enemy_infront = infront(self, self->enemy);
  544. enemy_range = range(self, self->enemy);
  545. VectorSubtract (self->enemy->s.origin, self->s.origin, temp);
  546. enemy_yaw = vectoyaw(temp);
  547. self->ideal_yaw = enemy_yaw;
  548. // melee attack
  549. if (enemy_range == RANGE_MELEE)
  550. {
  551. if (self->monsterinfo.melee)
  552. self->monsterinfo.attack_state = AS_MELEE;
  553. else
  554. self->monsterinfo.attack_state = AS_MISSILE;
  555. return true;
  556. }
  557. // missile attack
  558. if (!self->monsterinfo.attack)
  559. return false;
  560. if (level.time < self->monsterinfo.attack_finished)
  561. return false;
  562. if (enemy_range == RANGE_FAR)
  563. return false;
  564. if (self->monsterinfo.aiflags & AI_STAND_GROUND)
  565. {
  566. chance = 0.4;
  567. }
  568. else if (enemy_range == RANGE_MELEE)
  569. {
  570. chance = 0.8;
  571. }
  572. else if (enemy_range == RANGE_NEAR)
  573. {
  574. chance = 0.4;
  575. }
  576. else if (enemy_range == RANGE_MID)
  577. {
  578. chance = 0.2;
  579. }
  580. else
  581. {
  582. return false;
  583. }
  584. if (random () < chance)
  585. {
  586. self->monsterinfo.attack_state = AS_MISSILE;
  587. self->monsterinfo.attack_finished = level.time + 2*random();
  588. return true;
  589. }
  590. if (self->flags & FL_FLY)
  591. {
  592. if (random() < 0.3)
  593. self->monsterinfo.attack_state = AS_SLIDING;
  594. else
  595. self->monsterinfo.attack_state = AS_STRAIGHT;
  596. }
  597. return false;
  598. }
  599. void MakronPrecache (void);
  600. /*QUAKED monster_jorg (1 .5 0) (-80 -80 0) (90 90 140) Ambush Trigger_Spawn Sight
  601. */
  602. void SP_monster_jorg (edict_t *self)
  603. {
  604. if (deathmatch->value)
  605. {
  606. G_FreeEdict (self);
  607. return;
  608. }
  609. sound_pain1 = gi.soundindex ("boss3/bs3pain1.wav");
  610. sound_pain2 = gi.soundindex ("boss3/bs3pain2.wav");
  611. sound_pain3 = gi.soundindex ("boss3/bs3pain3.wav");
  612. sound_death = gi.soundindex ("boss3/bs3deth1.wav");
  613. sound_attack1 = gi.soundindex ("boss3/bs3atck1.wav");
  614. sound_attack2 = gi.soundindex ("boss3/bs3atck2.wav");
  615. sound_search1 = gi.soundindex ("boss3/bs3srch1.wav");
  616. sound_search2 = gi.soundindex ("boss3/bs3srch2.wav");
  617. sound_search3 = gi.soundindex ("boss3/bs3srch3.wav");
  618. sound_idle = gi.soundindex ("boss3/bs3idle1.wav");
  619. sound_step_left = gi.soundindex ("boss3/step1.wav");
  620. sound_step_right = gi.soundindex ("boss3/step2.wav");
  621. sound_firegun = gi.soundindex ("boss3/xfire.wav");
  622. sound_death_hit = gi.soundindex ("boss3/d_hit.wav");
  623. MakronPrecache ();
  624. self->movetype = MOVETYPE_STEP;
  625. self->solid = SOLID_BBOX;
  626. self->s.modelindex = gi.modelindex ("models/monsters/boss3/rider/tris.md2");
  627. self->s.modelindex2 = gi.modelindex ("models/monsters/boss3/jorg/tris.md2");
  628. VectorSet (self->mins, -80, -80, 0);
  629. VectorSet (self->maxs, 80, 80, 140);
  630. self->health = 3000;
  631. self->gib_health = -2000;
  632. self->mass = 1000;
  633. self->pain = jorg_pain;
  634. self->die = jorg_die;
  635. self->monsterinfo.stand = jorg_stand;
  636. self->monsterinfo.walk = jorg_walk;
  637. self->monsterinfo.run = jorg_run;
  638. self->monsterinfo.dodge = NULL;
  639. self->monsterinfo.attack = jorg_attack;
  640. self->monsterinfo.search = jorg_search;
  641. self->monsterinfo.melee = NULL;
  642. self->monsterinfo.sight = NULL;
  643. self->monsterinfo.checkattack = Jorg_CheckAttack;
  644. gi.linkentity (self);
  645. self->monsterinfo.currentmove = &jorg_move_stand;
  646. self->monsterinfo.scale = MODEL_SCALE;
  647. walkmonster_start(self);
  648. }