|
|
1.1 root 1: /*
2: ==============================================================================
3:
4: SOLDIER
5:
6: ==============================================================================
7: */
8:
9: #include "g_local.h"
10: #include "m_soldier.h"
11:
12:
13: static int sound_idle;
14: static int sound_sight1;
15: static int sound_sight2;
16: static int sound_pain_light;
17: static int sound_pain;
18: static int sound_pain_ss;
19: static int sound_death_light;
20: static int sound_death;
21: static int sound_death_ss;
22: static int sound_cock;
23:
24:
25: void soldier_idle (edict_t *self)
26: {
27: if (random() > 0.8)
28: gi.sound (self, CHAN_VOICE, sound_idle, 1, ATTN_IDLE, 0);
29: }
30:
31: void soldier_cock (edict_t *self)
32: {
33: if (self->s.frame == FRAME_stand322)
34: gi.sound (self, CHAN_WEAPON, sound_cock, 1, ATTN_IDLE, 0);
35: else
36: gi.sound (self, CHAN_WEAPON, sound_cock, 1, ATTN_NORM, 0);
37: }
38:
39:
40: // STAND
41:
42: void soldier_stand (edict_t *self);
43:
44: mframe_t soldier_frames_stand1 [] =
45: {
46: ai_stand, 0, soldier_idle,
47: ai_stand, 0, NULL,
48: ai_stand, 0, NULL,
49: ai_stand, 0, NULL,
50: ai_stand, 0, NULL,
51: ai_stand, 0, NULL,
52: ai_stand, 0, NULL,
53: ai_stand, 0, NULL,
54: ai_stand, 0, NULL,
55: ai_stand, 0, NULL,
56:
57: ai_stand, 0, NULL,
58: ai_stand, 0, NULL,
59: ai_stand, 0, NULL,
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:
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: };
79: mmove_t soldier_move_stand1 = {FRAME_stand101, FRAME_stand130, soldier_frames_stand1, soldier_stand};
80:
81: mframe_t soldier_frames_stand3 [] =
82: {
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: ai_stand, 0, NULL,
92: ai_stand, 0, NULL,
93:
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,
100: ai_stand, 0, NULL,
101: ai_stand, 0, NULL,
102: ai_stand, 0, NULL,
103: ai_stand, 0, NULL,
104:
105: ai_stand, 0, NULL,
106: ai_stand, 0, soldier_cock,
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, 0, NULL,
113: ai_stand, 0, NULL,
114: ai_stand, 0, NULL,
115:
116: ai_stand, 0, NULL,
117: ai_stand, 0, NULL,
118: ai_stand, 0, NULL,
119: ai_stand, 0, NULL,
120: ai_stand, 0, NULL,
121: ai_stand, 0, NULL,
122: ai_stand, 0, NULL,
123: ai_stand, 0, NULL,
124: ai_stand, 0, NULL
125: };
126: mmove_t soldier_move_stand3 = {FRAME_stand301, FRAME_stand339, soldier_frames_stand3, soldier_stand};
127:
128: #if 0
129: mframe_t soldier_frames_stand4 [] =
130: {
131: ai_stand, 0, NULL,
132: ai_stand, 0, NULL,
133: ai_stand, 0, NULL,
134: ai_stand, 0, NULL,
135: ai_stand, 0, NULL,
136: ai_stand, 0, NULL,
137: ai_stand, 0, NULL,
138: ai_stand, 0, NULL,
139: ai_stand, 0, NULL,
140: ai_stand, 0, NULL,
141:
142: ai_stand, 0, NULL,
143: ai_stand, 0, NULL,
144: ai_stand, 0, NULL,
145: ai_stand, 0, NULL,
146: ai_stand, 0, NULL,
147: ai_stand, 0, NULL,
148: ai_stand, 0, NULL,
149: ai_stand, 0, NULL,
150: ai_stand, 0, NULL,
151: ai_stand, 0, NULL,
152:
153: ai_stand, 0, NULL,
154: ai_stand, 0, NULL,
155: ai_stand, 0, NULL,
156: ai_stand, 0, NULL,
157: ai_stand, 0, NULL,
158: ai_stand, 0, NULL,
159: ai_stand, 0, NULL,
160: ai_stand, 0, NULL,
161: ai_stand, 0, NULL,
162: ai_stand, 0, NULL,
163:
164: ai_stand, 0, NULL,
165: ai_stand, 0, NULL,
166: ai_stand, 0, NULL,
167: ai_stand, 0, NULL,
168: ai_stand, 0, NULL,
169: ai_stand, 0, NULL,
170: ai_stand, 0, NULL,
171: ai_stand, 0, NULL,
172: ai_stand, 0, NULL,
173: ai_stand, 0, NULL,
174:
175: ai_stand, 0, NULL,
176: ai_stand, 0, NULL,
177: ai_stand, 0, NULL,
178: ai_stand, 0, NULL,
179: ai_stand, 0, NULL,
180: ai_stand, 0, NULL,
181: ai_stand, 4, NULL,
182: ai_stand, 1, NULL,
183: ai_stand, -1, NULL,
184: ai_stand, -2, NULL,
185:
186: ai_stand, 0, NULL,
187: ai_stand, 0, NULL
188: };
189: mmove_t soldier_move_stand4 = {FRAME_stand401, FRAME_stand452, soldier_frames_stand4, NULL};
190: #endif
191:
192: void soldier_stand (edict_t *self)
193: {
194: if ((self->monsterinfo.currentmove == &soldier_move_stand3) || (random() < 0.8))
195: self->monsterinfo.currentmove = &soldier_move_stand1;
196: else
197: self->monsterinfo.currentmove = &soldier_move_stand3;
198: }
199:
200:
201: //
202: // WALK
203: //
204:
205: void soldier_walk1_random (edict_t *self)
206: {
207: if (random() > 0.1)
208: self->monsterinfo.nextframe = FRAME_walk101;
209: }
210:
211: mframe_t soldier_frames_walk1 [] =
212: {
213: ai_walk, 3, NULL,
214: ai_walk, 6, NULL,
215: ai_walk, 2, NULL,
216: ai_walk, 2, NULL,
217: ai_walk, 2, NULL,
218: ai_walk, 1, NULL,
219: ai_walk, 6, NULL,
220: ai_walk, 5, NULL,
221: ai_walk, 3, NULL,
222: ai_walk, -1, soldier_walk1_random,
223: ai_walk, 0, NULL,
224: ai_walk, 0, NULL,
225: ai_walk, 0, NULL,
226: ai_walk, 0, NULL,
227: ai_walk, 0, NULL,
228: ai_walk, 0, NULL,
229: ai_walk, 0, NULL,
230: ai_walk, 0, NULL,
231: ai_walk, 0, NULL,
232: ai_walk, 0, NULL,
233: ai_walk, 0, NULL,
234: ai_walk, 0, NULL,
235: ai_walk, 0, NULL,
236: ai_walk, 0, NULL,
237: ai_walk, 0, NULL,
238: ai_walk, 0, NULL,
239: ai_walk, 0, NULL,
240: ai_walk, 0, NULL,
241: ai_walk, 0, NULL,
242: ai_walk, 0, NULL,
243: ai_walk, 0, NULL,
244: ai_walk, 0, NULL,
245: ai_walk, 0, NULL
246: };
247: mmove_t soldier_move_walk1 = {FRAME_walk101, FRAME_walk133, soldier_frames_walk1, NULL};
248:
249: mframe_t soldier_frames_walk2 [] =
250: {
251: ai_walk, 4, NULL,
252: ai_walk, 4, NULL,
253: ai_walk, 9, NULL,
254: ai_walk, 8, NULL,
255: ai_walk, 5, NULL,
256: ai_walk, 1, NULL,
257: ai_walk, 3, NULL,
258: ai_walk, 7, NULL,
259: ai_walk, 6, NULL,
260: ai_walk, 7, NULL
261: };
262: mmove_t soldier_move_walk2 = {FRAME_walk209, FRAME_walk218, soldier_frames_walk2, NULL};
263:
264: void soldier_walk (edict_t *self)
265: {
266: if (random() < 0.5)
267: self->monsterinfo.currentmove = &soldier_move_walk1;
268: else
269: self->monsterinfo.currentmove = &soldier_move_walk2;
270: }
271:
272:
273: //
274: // RUN
275: //
276:
277: void soldier_run (edict_t *self);
278:
279: mframe_t soldier_frames_start_run [] =
280: {
281: ai_run, 7, NULL,
282: ai_run, 5, NULL
283: };
284: mmove_t soldier_move_start_run = {FRAME_run01, FRAME_run02, soldier_frames_start_run, soldier_run};
285:
286: mframe_t soldier_frames_run [] =
287: {
288: ai_run, 10, NULL,
289: ai_run, 11, NULL,
290: ai_run, 11, NULL,
291: ai_run, 16, NULL,
292: ai_run, 10, NULL,
293: ai_run, 15, NULL
294: };
295: mmove_t soldier_move_run = {FRAME_run03, FRAME_run08, soldier_frames_run, NULL};
296:
297: void soldier_run (edict_t *self)
298: {
299: if (self->monsterinfo.aiflags & AI_STAND_GROUND)
300: {
301: self->monsterinfo.currentmove = &soldier_move_stand1;
302: return;
303: }
304:
305: if (self->monsterinfo.currentmove == &soldier_move_walk1 ||
306: self->monsterinfo.currentmove == &soldier_move_walk2 ||
307: self->monsterinfo.currentmove == &soldier_move_start_run)
308: {
309: self->monsterinfo.currentmove = &soldier_move_run;
310: }
311: else
312: {
313: self->monsterinfo.currentmove = &soldier_move_start_run;
314: }
315: }
316:
317:
318: //
319: // PAIN
320: //
321:
322: mframe_t soldier_frames_pain1 [] =
323: {
324: ai_move, -3, NULL,
325: ai_move, 4, NULL,
326: ai_move, 1, NULL,
327: ai_move, 1, NULL,
328: ai_move, 0, NULL
329: };
330: mmove_t soldier_move_pain1 = {FRAME_pain101, FRAME_pain105, soldier_frames_pain1, soldier_run};
331:
332: mframe_t soldier_frames_pain2 [] =
333: {
334: ai_move, -13, NULL,
335: ai_move, -1, NULL,
336: ai_move, 2, NULL,
337: ai_move, 4, NULL,
338: ai_move, 2, NULL,
339: ai_move, 3, NULL,
340: ai_move, 2, NULL
341: };
342: mmove_t soldier_move_pain2 = {FRAME_pain201, FRAME_pain207, soldier_frames_pain2, soldier_run};
343:
344: mframe_t soldier_frames_pain3 [] =
345: {
346: ai_move, -8, NULL,
347: ai_move, 10, NULL,
348: ai_move, -4, NULL,
349: ai_move, -1, NULL,
350: ai_move, -3, NULL,
351: ai_move, 0, NULL,
352: ai_move, 3, NULL,
353: ai_move, 0, NULL,
354: ai_move, 0, NULL,
355: ai_move, 0, NULL,
356: ai_move, 0, NULL,
357: ai_move, 1, NULL,
358: ai_move, 0, NULL,
359: ai_move, 1, NULL,
360: ai_move, 2, NULL,
361: ai_move, 4, NULL,
362: ai_move, 3, NULL,
363: ai_move, 2, NULL
364: };
365: mmove_t soldier_move_pain3 = {FRAME_pain301, FRAME_pain318, soldier_frames_pain3, soldier_run};
366:
367: mframe_t soldier_frames_pain4 [] =
368: {
369: ai_move, 0, NULL,
370: ai_move, 0, NULL,
371: ai_move, 0, NULL,
372: ai_move, -10, NULL,
373: ai_move, -6, NULL,
374: ai_move, 8, NULL,
375: ai_move, 4, NULL,
376: ai_move, 1, NULL,
377: ai_move, 0, NULL,
378: ai_move, 2, NULL,
379: ai_move, 5, NULL,
380: ai_move, 2, NULL,
381: ai_move, -1, NULL,
382: ai_move, -1, NULL,
383: ai_move, 3, NULL,
384: ai_move, 2, NULL,
385: ai_move, 0, NULL
386: };
387: mmove_t soldier_move_pain4 = {FRAME_pain401, FRAME_pain417, soldier_frames_pain4, soldier_run};
388:
389:
390: void soldier_pain (edict_t *self, edict_t *other, float kick, int damage)
391: {
392: float r;
393: int n;
394:
395: if (self->health < (self->max_health / 2))
396: self->s.skinnum |= 1;
397:
398: if (level.time < self->pain_debounce_time)
399: {
400: if ((self->velocity[2] > 100) && ( (self->monsterinfo.currentmove == &soldier_move_pain1) || (self->monsterinfo.currentmove == &soldier_move_pain2) || (self->monsterinfo.currentmove == &soldier_move_pain3)))
401: self->monsterinfo.currentmove = &soldier_move_pain4;
402: return;
403: }
404:
405: self->pain_debounce_time = level.time + 3;
406:
407: n = self->s.skinnum | 1;
408: if (n == 1)
409: gi.sound (self, CHAN_VOICE, sound_pain_light, 1, ATTN_NORM, 0);
410: else if (n == 3)
411: gi.sound (self, CHAN_VOICE, sound_pain, 1, ATTN_NORM, 0);
412: else
413: gi.sound (self, CHAN_VOICE, sound_pain_ss, 1, ATTN_NORM, 0);
414:
415: if (self->velocity[2] > 100)
416: {
417: self->monsterinfo.currentmove = &soldier_move_pain4;
418: return;
419: }
420:
421: if (skill->value == 3)
422: return; // no pain anims in nightmare
423:
424: r = random();
425:
426: if (r < 0.33)
427: self->monsterinfo.currentmove = &soldier_move_pain1;
428: else if (r < 0.66)
429: self->monsterinfo.currentmove = &soldier_move_pain2;
430: else
431: self->monsterinfo.currentmove = &soldier_move_pain3;
432: }
433:
434:
435: //
436: // ATTACK
437: //
438:
439: static int blaster_flash [] = {MZ2_SOLDIER_BLASTER_1, MZ2_SOLDIER_BLASTER_2, MZ2_SOLDIER_BLASTER_3, MZ2_SOLDIER_BLASTER_4, MZ2_SOLDIER_BLASTER_5, MZ2_SOLDIER_BLASTER_6, MZ2_SOLDIER_BLASTER_7, MZ2_SOLDIER_BLASTER_8};
440: static int shotgun_flash [] = {MZ2_SOLDIER_SHOTGUN_1, MZ2_SOLDIER_SHOTGUN_2, MZ2_SOLDIER_SHOTGUN_3, MZ2_SOLDIER_SHOTGUN_4, MZ2_SOLDIER_SHOTGUN_5, MZ2_SOLDIER_SHOTGUN_6, MZ2_SOLDIER_SHOTGUN_7, MZ2_SOLDIER_SHOTGUN_8};
441: static int machinegun_flash [] = {MZ2_SOLDIER_MACHINEGUN_1, MZ2_SOLDIER_MACHINEGUN_2, MZ2_SOLDIER_MACHINEGUN_3, MZ2_SOLDIER_MACHINEGUN_4, MZ2_SOLDIER_MACHINEGUN_5, MZ2_SOLDIER_MACHINEGUN_6, MZ2_SOLDIER_MACHINEGUN_7, MZ2_SOLDIER_MACHINEGUN_8};
442:
443: void soldier_fire (edict_t *self, int flash_number)
444: {
445: vec3_t start;
446: vec3_t forward, right, up;
447: vec3_t aim;
448: vec3_t dir;
449: vec3_t end;
450: float r, u;
451: int flash_index;
452:
453: if (self->s.skinnum < 2)
454: flash_index = blaster_flash[flash_number];
455: else if (self->s.skinnum < 4)
456: flash_index = shotgun_flash[flash_number];
457: else
458: flash_index = machinegun_flash[flash_number];
459:
460: AngleVectors (self->s.angles, forward, right, NULL);
461: G_ProjectSource (self->s.origin, monster_flash_offset[flash_index], forward, right, start);
462:
463: if (flash_number == 5 || flash_number == 6)
464: {
465: VectorCopy (forward, aim);
466: }
467: else
468: {
469: VectorCopy (self->enemy->s.origin, end);
470: end[2] += self->enemy->viewheight;
471: VectorSubtract (end, start, aim);
472: vectoangles (aim, dir);
473: AngleVectors (dir, forward, right, up);
474:
475: r = crandom()*1000;
476: u = crandom()*500;
477: VectorMA (start, 8192, forward, end);
478: VectorMA (end, r, right, end);
479: VectorMA (end, u, up, end);
480:
481: VectorSubtract (end, start, aim);
482: VectorNormalize (aim);
483: }
484:
485: if (self->s.skinnum <= 1)
486: {
487: monster_fire_blaster (self, start, aim, 5, 600, flash_index, EF_BLASTER);
488: }
489: else if (self->s.skinnum <= 3)
490: {
491: monster_fire_shotgun (self, start, aim, 2, 1, DEFAULT_SHOTGUN_HSPREAD, DEFAULT_SHOTGUN_VSPREAD, DEFAULT_SHOTGUN_COUNT, flash_index);
492: }
493: else
494: {
495: if (!(self->monsterinfo.aiflags & AI_HOLD_FRAME))
496: self->monsterinfo.pausetime = level.time + (3 + rand() % 8) * FRAMETIME;
497:
498: monster_fire_bullet (self, start, aim, 2, 4, DEFAULT_BULLET_HSPREAD, DEFAULT_BULLET_VSPREAD, flash_index);
499:
500: if (level.time >= self->monsterinfo.pausetime)
501: self->monsterinfo.aiflags &= ~AI_HOLD_FRAME;
502: else
503: self->monsterinfo.aiflags |= AI_HOLD_FRAME;
504: }
505: }
506:
507: // ATTACK1 (blaster/shotgun)
508:
509: void soldier_fire1 (edict_t *self)
510: {
511: soldier_fire (self, 0);
512: }
513:
514: void soldier_attack1_refire1 (edict_t *self)
515: {
516: if (self->s.skinnum > 1)
517: return;
518:
519: if (self->enemy->health <= 0)
520: return;
521:
522: if ( ((skill->value == 3) && (random() < 0.5)) || (range(self, self->enemy) == RANGE_MELEE) )
523: self->monsterinfo.nextframe = FRAME_attak102;
524: else
525: self->monsterinfo.nextframe = FRAME_attak110;
526: }
527:
528: void soldier_attack1_refire2 (edict_t *self)
529: {
530: if (self->s.skinnum < 2)
531: return;
532:
533: if (self->enemy->health <= 0)
534: return;
535:
536: if ( ((skill->value == 3) && (random() < 0.5)) || (range(self, self->enemy) == RANGE_MELEE) )
537: self->monsterinfo.nextframe = FRAME_attak102;
538: }
539:
540: mframe_t soldier_frames_attack1 [] =
541: {
542: ai_charge, 0, NULL,
543: ai_charge, 0, NULL,
544: ai_charge, 0, soldier_fire1,
545: ai_charge, 0, NULL,
546: ai_charge, 0, NULL,
547: ai_charge, 0, soldier_attack1_refire1,
548: ai_charge, 0, NULL,
549: ai_charge, 0, soldier_cock,
550: ai_charge, 0, soldier_attack1_refire2,
551: ai_charge, 0, NULL,
552: ai_charge, 0, NULL,
553: ai_charge, 0, NULL
554: };
555: mmove_t soldier_move_attack1 = {FRAME_attak101, FRAME_attak112, soldier_frames_attack1, soldier_run};
556:
557: // ATTACK2 (blaster/shotgun)
558:
559: void soldier_fire2 (edict_t *self)
560: {
561: soldier_fire (self, 1);
562: }
563:
564: void soldier_attack2_refire1 (edict_t *self)
565: {
566: if (self->s.skinnum > 1)
567: return;
568:
569: if (self->enemy->health <= 0)
570: return;
571:
572: if ( ((skill->value == 3) && (random() < 0.5)) || (range(self, self->enemy) == RANGE_MELEE) )
573: self->monsterinfo.nextframe = FRAME_attak204;
574: else
575: self->monsterinfo.nextframe = FRAME_attak216;
576: }
577:
578: void soldier_attack2_refire2 (edict_t *self)
579: {
580: if (self->s.skinnum < 2)
581: return;
582:
583: if (self->enemy->health <= 0)
584: return;
585:
586: if ( ((skill->value == 3) && (random() < 0.5)) || (range(self, self->enemy) == RANGE_MELEE) )
587: self->monsterinfo.nextframe = FRAME_attak204;
588: }
589:
590: mframe_t soldier_frames_attack2 [] =
591: {
592: ai_charge, 0, NULL,
593: ai_charge, 0, NULL,
594: ai_charge, 0, NULL,
595: ai_charge, 0, NULL,
596: ai_charge, 0, soldier_fire2,
597: ai_charge, 0, NULL,
598: ai_charge, 0, NULL,
599: ai_charge, 0, soldier_attack2_refire1,
600: ai_charge, 0, NULL,
601: ai_charge, 0, NULL,
602: ai_charge, 0, NULL,
603: ai_charge, 0, NULL,
604: ai_charge, 0, soldier_cock,
605: ai_charge, 0, NULL,
606: ai_charge, 0, soldier_attack2_refire2,
607: ai_charge, 0, NULL,
608: ai_charge, 0, NULL,
609: ai_charge, 0, NULL
610: };
611: mmove_t soldier_move_attack2 = {FRAME_attak201, FRAME_attak218, soldier_frames_attack2, soldier_run};
612:
613: // ATTACK3 (duck and shoot)
614:
615: void soldier_duck_down (edict_t *self)
616: {
617: if (self->monsterinfo.aiflags & AI_DUCKED)
618: return;
619: self->monsterinfo.aiflags |= AI_DUCKED;
620: self->maxs[2] -= 32;
621: self->takedamage = DAMAGE_YES;
622: self->monsterinfo.pausetime = level.time + 1;
623: gi.linkentity (self);
624: }
625:
626: void soldier_duck_up (edict_t *self)
627: {
628: self->monsterinfo.aiflags &= ~AI_DUCKED;
629: self->maxs[2] += 32;
630: self->takedamage = DAMAGE_AIM;
631: gi.linkentity (self);
632: }
633:
634: void soldier_fire3 (edict_t *self)
635: {
636: soldier_duck_down (self);
637: soldier_fire (self, 2);
638: }
639:
640: void soldier_attack3_refire (edict_t *self)
641: {
642: if ((level.time + 0.4) < self->monsterinfo.pausetime)
643: self->monsterinfo.nextframe = FRAME_attak303;
644: }
645:
646: mframe_t soldier_frames_attack3 [] =
647: {
648: ai_charge, 0, NULL,
649: ai_charge, 0, NULL,
650: ai_charge, 0, soldier_fire3,
651: ai_charge, 0, NULL,
652: ai_charge, 0, NULL,
653: ai_charge, 0, soldier_attack3_refire,
654: ai_charge, 0, soldier_duck_up,
655: ai_charge, 0, NULL,
656: ai_charge, 0, NULL
657: };
658: mmove_t soldier_move_attack3 = {FRAME_attak301, FRAME_attak309, soldier_frames_attack3, soldier_run};
659:
660: // ATTACK4 (machinegun)
661:
662: void soldier_fire4 (edict_t *self)
663: {
664: soldier_fire (self, 3);
665: //
666: // if (self->enemy->health <= 0)
667: // return;
668: //
669: // if ( ((skill->value == 3) && (random() < 0.5)) || (range(self, self->enemy) == RANGE_MELEE) )
670: // self->monsterinfo.nextframe = FRAME_attak402;
671: }
672:
673: mframe_t soldier_frames_attack4 [] =
674: {
675: ai_charge, 0, NULL,
676: ai_charge, 0, NULL,
677: ai_charge, 0, soldier_fire4,
678: ai_charge, 0, NULL,
679: ai_charge, 0, NULL,
680: ai_charge, 0, NULL
681: };
682: mmove_t soldier_move_attack4 = {FRAME_attak401, FRAME_attak406, soldier_frames_attack4, soldier_run};
683:
684: #if 0
685: // ATTACK5 (prone)
686:
687: void soldier_fire5 (edict_t *self)
688: {
689: soldier_fire (self, 4);
690: }
691:
692: void soldier_attack5_refire (edict_t *self)
693: {
694: if (self->enemy->health <= 0)
695: return;
696:
697: if ( ((skill->value == 3) && (random() < 0.5)) || (range(self, self->enemy) == RANGE_MELEE) )
698: self->monsterinfo.nextframe = FRAME_attak505;
699: }
700:
701: mframe_t soldier_frames_attack5 [] =
702: {
703: ai_charge, 8, NULL,
704: ai_charge, 8, NULL,
705: ai_charge, 0, NULL,
706: ai_charge, 0, NULL,
707: ai_charge, 0, soldier_fire5,
708: ai_charge, 0, NULL,
709: ai_charge, 0, NULL,
710: ai_charge, 0, soldier_attack5_refire
711: };
712: mmove_t soldier_move_attack5 = {FRAME_attak501, FRAME_attak508, soldier_frames_attack5, soldier_run};
713: #endif
714:
715: // ATTACK6 (run & shoot)
716:
717: void soldier_fire8 (edict_t *self)
718: {
719: soldier_fire (self, 7);
720: }
721:
722: void soldier_attack6_refire (edict_t *self)
723: {
724: if (self->enemy->health <= 0)
725: return;
726:
727: if (range(self, self->enemy) < RANGE_MID)
728: return;
729:
730: if (skill->value == 3)
731: self->monsterinfo.nextframe = FRAME_runs03;
732: }
733:
734: mframe_t soldier_frames_attack6 [] =
735: {
736: ai_charge, 10, NULL,
737: ai_charge, 4, NULL,
738: ai_charge, 12, NULL,
739: ai_charge, 11, soldier_fire8,
740: ai_charge, 13, NULL,
741: ai_charge, 18, NULL,
742: ai_charge, 15, NULL,
743: ai_charge, 14, NULL,
744: ai_charge, 11, NULL,
745: ai_charge, 8, NULL,
746: ai_charge, 11, NULL,
747: ai_charge, 12, NULL,
748: ai_charge, 12, NULL,
749: ai_charge, 17, soldier_attack6_refire
750: };
751: mmove_t soldier_move_attack6 = {FRAME_runs01, FRAME_runs14, soldier_frames_attack6, soldier_run};
752:
753: void soldier_attack(edict_t *self)
754: {
755: if (self->s.skinnum < 4)
756: {
757: if (random() < 0.5)
758: self->monsterinfo.currentmove = &soldier_move_attack1;
759: else
760: self->monsterinfo.currentmove = &soldier_move_attack2;
761: }
762: else
763: {
764: self->monsterinfo.currentmove = &soldier_move_attack4;
765: }
766: }
767:
768:
769: //
770: // SIGHT
771: //
772:
773: void soldier_sight(edict_t *self, edict_t *other)
774: {
775: if (random() < 0.5)
776: gi.sound (self, CHAN_VOICE, sound_sight1, 1, ATTN_NORM, 0);
777: else
778: gi.sound (self, CHAN_VOICE, sound_sight2, 1, ATTN_NORM, 0);
779:
780: if ((skill->value > 0) && (range(self, self->enemy) >= RANGE_MID))
781: {
782: if (random() > 0.5)
783: self->monsterinfo.currentmove = &soldier_move_attack6;
784: }
785: }
786:
787: //
788: // DUCK
789: //
790:
791: void soldier_duck_hold (edict_t *self)
792: {
793: if (level.time >= self->monsterinfo.pausetime)
794: self->monsterinfo.aiflags &= ~AI_HOLD_FRAME;
795: else
796: self->monsterinfo.aiflags |= AI_HOLD_FRAME;
797: }
798:
799: mframe_t soldier_frames_duck [] =
800: {
801: ai_move, 5, soldier_duck_down,
802: ai_move, -1, soldier_duck_hold,
803: ai_move, 1, NULL,
804: ai_move, 0, soldier_duck_up,
805: ai_move, 5, NULL
806: };
807: mmove_t soldier_move_duck = {FRAME_duck01, FRAME_duck05, soldier_frames_duck, soldier_run};
808:
809: void soldier_dodge (edict_t *self, edict_t *attacker, float eta)
810: {
811: float r;
812:
813: r = random();
814: if (r > 0.25)
815: return;
816:
817: if (!self->enemy)
818: self->enemy = attacker;
819:
820: if (skill->value == 0)
821: {
822: self->monsterinfo.currentmove = &soldier_move_duck;
823: return;
824: }
825:
826: self->monsterinfo.pausetime = level.time + eta + 0.3;
827: r = random();
828:
829: if (skill->value == 1)
830: {
831: if (r > 0.33)
832: self->monsterinfo.currentmove = &soldier_move_duck;
833: else
834: self->monsterinfo.currentmove = &soldier_move_attack3;
835: return;
836: }
837:
838: if (skill->value >= 2)
839: {
840: if (r > 0.66)
841: self->monsterinfo.currentmove = &soldier_move_duck;
842: else
843: self->monsterinfo.currentmove = &soldier_move_attack3;
844: return;
845: }
846:
847: self->monsterinfo.currentmove = &soldier_move_attack3;
848: }
849:
850:
851: //
852: // DEATH
853: //
854:
855: void soldier_fire6 (edict_t *self)
856: {
857: soldier_fire (self, 5);
858: }
859:
860: void soldier_fire7 (edict_t *self)
861: {
862: soldier_fire (self, 6);
863: }
864:
865: void soldier_dead (edict_t *self)
866: {
867: VectorSet (self->mins, -16, -16, -24);
868: VectorSet (self->maxs, 16, 16, -8);
869: self->movetype = MOVETYPE_TOSS;
870: self->svflags |= SVF_DEADMONSTER;
871: self->nextthink = 0;
872: gi.linkentity (self);
873: }
874:
875: mframe_t soldier_frames_death1 [] =
876: {
877: ai_move, 0, NULL,
878: ai_move, -10, NULL,
879: ai_move, -10, NULL,
880: ai_move, -10, NULL,
881: ai_move, -5, NULL,
882: ai_move, 0, NULL,
883: ai_move, 0, NULL,
884: ai_move, 0, NULL,
885: ai_move, 0, NULL,
886: ai_move, 0, NULL,
887:
888: ai_move, 0, NULL,
889: ai_move, 0, NULL,
890: ai_move, 0, NULL,
891: ai_move, 0, NULL,
892: ai_move, 0, NULL,
893: ai_move, 0, NULL,
894: ai_move, 0, NULL,
895: ai_move, 0, NULL,
896: ai_move, 0, NULL,
897: ai_move, 0, NULL,
898:
899: ai_move, 0, NULL,
900: ai_move, 0, soldier_fire6,
901: ai_move, 0, NULL,
902: ai_move, 0, NULL,
903: ai_move, 0, soldier_fire7,
904: ai_move, 0, NULL,
905: ai_move, 0, NULL,
906: ai_move, 0, NULL,
907: ai_move, 0, NULL,
908: ai_move, 0, NULL,
909:
910: ai_move, 0, NULL,
911: ai_move, 0, NULL,
912: ai_move, 0, NULL,
913: ai_move, 0, NULL,
914: ai_move, 0, NULL,
915: ai_move, 0, NULL
916: };
917: mmove_t soldier_move_death1 = {FRAME_death101, FRAME_death136, soldier_frames_death1, soldier_dead};
918:
919: mframe_t soldier_frames_death2 [] =
920: {
921: ai_move, -5, NULL,
922: ai_move, -5, NULL,
923: ai_move, -5, NULL,
924: ai_move, 0, NULL,
925: ai_move, 0, NULL,
926: ai_move, 0, NULL,
927: ai_move, 0, NULL,
928: ai_move, 0, NULL,
929: ai_move, 0, NULL,
930: ai_move, 0, NULL,
931:
932: ai_move, 0, NULL,
933: ai_move, 0, NULL,
934: ai_move, 0, NULL,
935: ai_move, 0, NULL,
936: ai_move, 0, NULL,
937: ai_move, 0, NULL,
938: ai_move, 0, NULL,
939: ai_move, 0, NULL,
940: ai_move, 0, NULL,
941: ai_move, 0, NULL,
942:
943: ai_move, 0, NULL,
944: ai_move, 0, NULL,
945: ai_move, 0, NULL,
946: ai_move, 0, NULL,
947: ai_move, 0, NULL,
948: ai_move, 0, NULL,
949: ai_move, 0, NULL,
950: ai_move, 0, NULL,
951: ai_move, 0, NULL,
952: ai_move, 0, NULL,
953:
954: ai_move, 0, NULL,
955: ai_move, 0, NULL,
956: ai_move, 0, NULL,
957: ai_move, 0, NULL,
958: ai_move, 0, NULL
959: };
960: mmove_t soldier_move_death2 = {FRAME_death201, FRAME_death235, soldier_frames_death2, soldier_dead};
961:
962: mframe_t soldier_frames_death3 [] =
963: {
964: ai_move, -5, NULL,
965: ai_move, -5, NULL,
966: ai_move, -5, NULL,
967: ai_move, 0, NULL,
968: ai_move, 0, NULL,
969: ai_move, 0, NULL,
970: ai_move, 0, NULL,
971: ai_move, 0, NULL,
972: ai_move, 0, NULL,
973: ai_move, 0, NULL,
974:
975: ai_move, 0, NULL,
976: ai_move, 0, NULL,
977: ai_move, 0, NULL,
978: ai_move, 0, NULL,
979: ai_move, 0, NULL,
980: ai_move, 0, NULL,
981: ai_move, 0, NULL,
982: ai_move, 0, NULL,
983: ai_move, 0, NULL,
984: ai_move, 0, NULL,
985:
986: ai_move, 0, NULL,
987: ai_move, 0, NULL,
988: ai_move, 0, NULL,
989: ai_move, 0, NULL,
990: ai_move, 0, NULL,
991: ai_move, 0, NULL,
992: ai_move, 0, NULL,
993: ai_move, 0, NULL,
994: ai_move, 0, NULL,
995: ai_move, 0, NULL,
996:
997: ai_move, 0, NULL,
998: ai_move, 0, NULL,
999: ai_move, 0, NULL,
1000: ai_move, 0, NULL,
1001: ai_move, 0, NULL,
1002: ai_move, 0, NULL,
1003: ai_move, 0, NULL,
1004: ai_move, 0, NULL,
1005: ai_move, 0, NULL,
1006: ai_move, 0, NULL,
1007:
1008: ai_move, 0, NULL,
1009: ai_move, 0, NULL,
1010: ai_move, 0, NULL,
1011: ai_move, 0, NULL,
1012: ai_move, 0, NULL,
1013: };
1014: mmove_t soldier_move_death3 = {FRAME_death301, FRAME_death345, soldier_frames_death3, soldier_dead};
1015:
1016: mframe_t soldier_frames_death4 [] =
1017: {
1018: ai_move, 0, NULL,
1019: ai_move, 0, NULL,
1020: ai_move, 0, NULL,
1021: ai_move, 0, NULL,
1022: ai_move, 0, NULL,
1023: ai_move, 0, NULL,
1024: ai_move, 0, NULL,
1025: ai_move, 0, NULL,
1026: ai_move, 0, NULL,
1027: ai_move, 0, NULL,
1028:
1029: ai_move, 0, NULL,
1030: ai_move, 0, NULL,
1031: ai_move, 0, NULL,
1032: ai_move, 0, NULL,
1033: ai_move, 0, NULL,
1034: ai_move, 0, NULL,
1035: ai_move, 0, NULL,
1036: ai_move, 0, NULL,
1037: ai_move, 0, NULL,
1038: ai_move, 0, NULL,
1039:
1040: ai_move, 0, NULL,
1041: ai_move, 0, NULL,
1042: ai_move, 0, NULL,
1043: ai_move, 0, NULL,
1044: ai_move, 0, NULL,
1045: ai_move, 0, NULL,
1046: ai_move, 0, NULL,
1047: ai_move, 0, NULL,
1048: ai_move, 0, NULL,
1049: ai_move, 0, NULL,
1050:
1051: ai_move, 0, NULL,
1052: ai_move, 0, NULL,
1053: ai_move, 0, NULL,
1054: ai_move, 0, NULL,
1055: ai_move, 0, NULL,
1056: ai_move, 0, NULL,
1057: ai_move, 0, NULL,
1058: ai_move, 0, NULL,
1059: ai_move, 0, NULL,
1060: ai_move, 0, NULL,
1061:
1062: ai_move, 0, NULL,
1063: ai_move, 0, NULL,
1064: ai_move, 0, NULL,
1065: ai_move, 0, NULL,
1066: ai_move, 0, NULL,
1067: ai_move, 0, NULL,
1068: ai_move, 0, NULL,
1069: ai_move, 0, NULL,
1070: ai_move, 0, NULL,
1071: ai_move, 0, NULL,
1072:
1073: ai_move, 0, NULL,
1074: ai_move, 0, NULL,
1075: ai_move, 0, NULL
1076: };
1077: mmove_t soldier_move_death4 = {FRAME_death401, FRAME_death453, soldier_frames_death4, soldier_dead};
1078:
1079: mframe_t soldier_frames_death5 [] =
1080: {
1081: ai_move, -5, NULL,
1082: ai_move, -5, NULL,
1083: ai_move, -5, NULL,
1084: ai_move, 0, NULL,
1085: ai_move, 0, NULL,
1086: ai_move, 0, NULL,
1087: ai_move, 0, NULL,
1088: ai_move, 0, NULL,
1089: ai_move, 0, NULL,
1090: ai_move, 0, NULL,
1091:
1092: ai_move, 0, NULL,
1093: ai_move, 0, NULL,
1094: ai_move, 0, NULL,
1095: ai_move, 0, NULL,
1096: ai_move, 0, NULL,
1097: ai_move, 0, NULL,
1098: ai_move, 0, NULL,
1099: ai_move, 0, NULL,
1100: ai_move, 0, NULL,
1101: ai_move, 0, NULL,
1102:
1103: ai_move, 0, NULL,
1104: ai_move, 0, NULL,
1105: ai_move, 0, NULL,
1106: ai_move, 0, NULL
1107: };
1108: mmove_t soldier_move_death5 = {FRAME_death501, FRAME_death524, soldier_frames_death5, soldier_dead};
1109:
1110: mframe_t soldier_frames_death6 [] =
1111: {
1112: ai_move, 0, NULL,
1113: ai_move, 0, NULL,
1114: ai_move, 0, NULL,
1115: ai_move, 0, NULL,
1116: ai_move, 0, NULL,
1117: ai_move, 0, NULL,
1118: ai_move, 0, NULL,
1119: ai_move, 0, NULL,
1120: ai_move, 0, NULL,
1121: ai_move, 0, NULL
1122: };
1123: mmove_t soldier_move_death6 = {FRAME_death601, FRAME_death610, soldier_frames_death6, soldier_dead};
1124:
1125: void soldier_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
1126: {
1127: int n;
1128:
1129: // check for gib
1130: if (self->health <= self->gib_health)
1131: {
1132: gi.sound (self, CHAN_VOICE, gi.soundindex ("misc/udeath.wav"), 1, ATTN_NORM, 0);
1133: for (n= 0; n < 3; n++)
1134: ThrowGib (self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC);
1135: ThrowGib (self, "models/objects/gibs/chest/tris.md2", damage, GIB_ORGANIC);
1136: ThrowHead (self, "models/objects/gibs/head2/tris.md2", damage, GIB_ORGANIC);
1137: self->deadflag = DEAD_DEAD;
1138: return;
1139: }
1140:
1141: if (self->deadflag == DEAD_DEAD)
1142: return;
1143:
1144: // regular death
1145: self->deadflag = DEAD_DEAD;
1146: self->takedamage = DAMAGE_YES;
1147: self->s.skinnum |= 1;
1148:
1149: if (self->s.skinnum == 1)
1150: gi.sound (self, CHAN_VOICE, sound_death_light, 1, ATTN_NORM, 0);
1151: else if (self->s.skinnum == 3)
1152: gi.sound (self, CHAN_VOICE, sound_death, 1, ATTN_NORM, 0);
1153: else // (self->s.skinnum == 5)
1154: gi.sound (self, CHAN_VOICE, sound_death_ss, 1, ATTN_NORM, 0);
1155:
1156: if (fabs((self->s.origin[2] + self->viewheight) - point[2]) <= 4)
1157: {
1158: // head shot
1159: self->monsterinfo.currentmove = &soldier_move_death3;
1160: return;
1161: }
1162:
1163: n = rand() % 5;
1164: if (n == 0)
1165: self->monsterinfo.currentmove = &soldier_move_death1;
1166: else if (n == 1)
1167: self->monsterinfo.currentmove = &soldier_move_death2;
1168: else if (n == 2)
1169: self->monsterinfo.currentmove = &soldier_move_death4;
1170: else if (n == 3)
1171: self->monsterinfo.currentmove = &soldier_move_death5;
1172: else
1173: self->monsterinfo.currentmove = &soldier_move_death6;
1174: }
1175:
1176:
1177: //
1178: // SPAWN
1179: //
1180:
1181: void SP_monster_soldier_x (edict_t *self)
1182: {
1183:
1184: self->s.modelindex = gi.modelindex ("models/monsters/soldier/tris.md2");
1185: self->monsterinfo.scale = MODEL_SCALE;
1186: VectorSet (self->mins, -16, -16, -24);
1187: VectorSet (self->maxs, 16, 16, 32);
1188: self->movetype = MOVETYPE_STEP;
1189: self->solid = SOLID_BBOX;
1190:
1191: sound_idle = gi.soundindex ("soldier/solidle1.wav");
1192: sound_sight1 = gi.soundindex ("soldier/solsght1.wav");
1193: sound_sight2 = gi.soundindex ("soldier/solsrch1.wav");
1194: sound_cock = gi.soundindex ("infantry/infatck3.wav");
1195:
1196: self->mass = 100;
1197:
1198: self->pain = soldier_pain;
1199: self->die = soldier_die;
1200:
1201: self->monsterinfo.stand = soldier_stand;
1202: self->monsterinfo.walk = soldier_walk;
1203: self->monsterinfo.run = soldier_run;
1204: self->monsterinfo.dodge = soldier_dodge;
1205: self->monsterinfo.attack = soldier_attack;
1206: self->monsterinfo.melee = NULL;
1207: self->monsterinfo.sight = soldier_sight;
1208:
1209: gi.linkentity (self);
1210:
1211: self->monsterinfo.stand (self);
1212:
1213: walkmonster_start (self);
1214: }
1215:
1216:
1217: /*QUAKED monster_soldier_light (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight
1218: */
1219: void SP_monster_soldier_light (edict_t *self)
1220: {
1221: if (deathmatch->value)
1222: {
1223: G_FreeEdict (self);
1224: return;
1225: }
1226:
1227: SP_monster_soldier_x (self);
1228:
1229: sound_pain_light = gi.soundindex ("soldier/solpain2.wav");
1230: sound_death_light = gi.soundindex ("soldier/soldeth2.wav");
1231: gi.modelindex ("models/objects/laser/tris.md2");
1232: gi.soundindex ("misc/lasfly.wav");
1233: gi.soundindex ("soldier/solatck2.wav");
1234:
1235: self->s.skinnum = 0;
1236: self->health = 20;
1237: self->gib_health = -30;
1238: }
1239:
1240: /*QUAKED monster_soldier (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight
1241: */
1242: void SP_monster_soldier (edict_t *self)
1243: {
1244: if (deathmatch->value)
1245: {
1246: G_FreeEdict (self);
1247: return;
1248: }
1249:
1250: SP_monster_soldier_x (self);
1251:
1252: sound_pain = gi.soundindex ("soldier/solpain1.wav");
1253: sound_death = gi.soundindex ("soldier/soldeth1.wav");
1254: gi.soundindex ("soldier/solatck1.wav");
1255:
1256: self->s.skinnum = 2;
1257: self->health = 30;
1258: self->gib_health = -30;
1259: }
1260:
1261: /*QUAKED monster_soldier_ss (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight
1262: */
1263: void SP_monster_soldier_ss (edict_t *self)
1264: {
1265: if (deathmatch->value)
1266: {
1267: G_FreeEdict (self);
1268: return;
1269: }
1270:
1271: SP_monster_soldier_x (self);
1272:
1273: sound_pain_ss = gi.soundindex ("soldier/solpain3.wav");
1274: sound_death_ss = gi.soundindex ("soldier/soldeth3.wav");
1275: gi.soundindex ("soldier/solatck3.wav");
1276:
1277: self->s.skinnum = 4;
1278: self->health = 40;
1279: self->gib_health = -30;
1280: }
1281:
1282:
1283: // RAFAEL 13-APR-98
1284:
1285:
1286: #include "m_soldierh.h"
1287:
1288: void soldierh_idle (edict_t *self)
1289: {
1290: if (random() > 0.8)
1291: gi.sound (self, CHAN_VOICE, sound_idle, 1, ATTN_IDLE, 0);
1292: }
1293:
1294: void soldierh_cock (edict_t *self)
1295: {
1296: if (self->s.frame == FRAME_stand322)
1297: gi.sound (self, CHAN_WEAPON, sound_cock, 1, ATTN_IDLE, 0);
1298: else
1299: gi.sound (self, CHAN_WEAPON, sound_cock, 1, ATTN_NORM, 0);
1300: }
1301:
1302:
1303: // STAND
1304:
1305: void soldierh_stand (edict_t *self);
1306:
1307: mframe_t soldierh_frames_stand1 [] =
1308: {
1309: ai_stand, 0, soldierh_idle,
1310: ai_stand, 0, NULL,
1311: ai_stand, 0, NULL,
1312: ai_stand, 0, NULL,
1313: ai_stand, 0, NULL,
1314: ai_stand, 0, NULL,
1315: ai_stand, 0, NULL,
1316: ai_stand, 0, NULL,
1317: ai_stand, 0, NULL,
1318: ai_stand, 0, NULL,
1319:
1320: ai_stand, 0, NULL,
1321: ai_stand, 0, NULL,
1322: ai_stand, 0, NULL,
1323: ai_stand, 0, NULL,
1324: ai_stand, 0, NULL,
1325: ai_stand, 0, NULL,
1326: ai_stand, 0, NULL,
1327: ai_stand, 0, NULL,
1328: ai_stand, 0, NULL,
1329: ai_stand, 0, NULL,
1330:
1331: ai_stand, 0, NULL,
1332: ai_stand, 0, NULL,
1333: ai_stand, 0, NULL,
1334: ai_stand, 0, NULL,
1335: ai_stand, 0, NULL,
1336: ai_stand, 0, NULL,
1337: ai_stand, 0, NULL,
1338: ai_stand, 0, NULL,
1339: ai_stand, 0, NULL,
1340: ai_stand, 0, NULL
1341: };
1342: mmove_t soldierh_move_stand1 = {FRAME_stand101, FRAME_stand130, soldierh_frames_stand1, soldierh_stand};
1343:
1344: mframe_t soldierh_frames_stand3 [] =
1345: {
1346: ai_stand, 0, NULL,
1347: ai_stand, 0, NULL,
1348: ai_stand, 0, NULL,
1349: ai_stand, 0, NULL,
1350: ai_stand, 0, NULL,
1351: ai_stand, 0, NULL,
1352: ai_stand, 0, NULL,
1353: ai_stand, 0, NULL,
1354: ai_stand, 0, NULL,
1355: ai_stand, 0, NULL,
1356:
1357: ai_stand, 0, NULL,
1358: ai_stand, 0, NULL,
1359: ai_stand, 0, NULL,
1360: ai_stand, 0, NULL,
1361: ai_stand, 0, NULL,
1362: ai_stand, 0, NULL,
1363: ai_stand, 0, NULL,
1364: ai_stand, 0, NULL,
1365: ai_stand, 0, NULL,
1366: ai_stand, 0, NULL,
1367:
1368: ai_stand, 0, NULL,
1369: ai_stand, 0, soldierh_cock,
1370: ai_stand, 0, NULL,
1371: ai_stand, 0, NULL,
1372: ai_stand, 0, NULL,
1373: ai_stand, 0, NULL,
1374: ai_stand, 0, NULL,
1375: ai_stand, 0, NULL,
1376: ai_stand, 0, NULL,
1377: ai_stand, 0, NULL,
1378:
1379: ai_stand, 0, NULL,
1380: ai_stand, 0, NULL,
1381: ai_stand, 0, NULL,
1382: ai_stand, 0, NULL,
1383: ai_stand, 0, NULL,
1384: ai_stand, 0, NULL,
1385: ai_stand, 0, NULL,
1386: ai_stand, 0, NULL,
1387: ai_stand, 0, NULL
1388: };
1389: mmove_t soldierh_move_stand3 = {FRAME_stand301, FRAME_stand339, soldierh_frames_stand3, soldierh_stand};
1390:
1391:
1392: void soldierh_stand (edict_t *self)
1393: {
1394: if ((self->monsterinfo.currentmove == &soldierh_move_stand3) || (random() < 0.8))
1395: self->monsterinfo.currentmove = &soldierh_move_stand1;
1396: else
1397: self->monsterinfo.currentmove = &soldierh_move_stand3;
1398: }
1399:
1400:
1401: //
1402: // WALK
1403: //
1404:
1405: void soldierh_walk1_random (edict_t *self)
1406: {
1407: if (random() > 0.1)
1408: self->monsterinfo.nextframe = FRAME_walk101;
1409: }
1410:
1411: mframe_t soldierh_frames_walk1 [] =
1412: {
1413: ai_walk, 3, NULL,
1414: ai_walk, 6, NULL,
1415: ai_walk, 2, NULL,
1416: ai_walk, 2, NULL,
1417: ai_walk, 2, NULL,
1418: ai_walk, 1, NULL,
1419: ai_walk, 6, NULL,
1420: ai_walk, 5, NULL,
1421: ai_walk, 3, NULL,
1422: ai_walk, -1, soldierh_walk1_random,
1423: ai_walk, 0, NULL,
1424: ai_walk, 0, NULL,
1425: ai_walk, 0, NULL,
1426: ai_walk, 0, NULL,
1427: ai_walk, 0, NULL,
1428: ai_walk, 0, NULL,
1429: ai_walk, 0, NULL,
1430: ai_walk, 0, NULL,
1431: ai_walk, 0, NULL,
1432: ai_walk, 0, NULL,
1433: ai_walk, 0, NULL,
1434: ai_walk, 0, NULL,
1435: ai_walk, 0, NULL,
1436: ai_walk, 0, NULL,
1437: ai_walk, 0, NULL,
1438: ai_walk, 0, NULL,
1439: ai_walk, 0, NULL,
1440: ai_walk, 0, NULL,
1441: ai_walk, 0, NULL,
1442: ai_walk, 0, NULL,
1443: ai_walk, 0, NULL,
1444: ai_walk, 0, NULL,
1445: ai_walk, 0, NULL
1446: };
1447: mmove_t soldierh_move_walk1 = {FRAME_walk101, FRAME_walk133, soldierh_frames_walk1, NULL};
1448:
1449: mframe_t soldierh_frames_walk2 [] =
1450: {
1451: ai_walk, 4, NULL,
1452: ai_walk, 4, NULL,
1453: ai_walk, 9, NULL,
1454: ai_walk, 8, NULL,
1455: ai_walk, 5, NULL,
1456: ai_walk, 1, NULL,
1457: ai_walk, 3, NULL,
1458: ai_walk, 7, NULL,
1459: ai_walk, 6, NULL,
1460: ai_walk, 7, NULL
1461: };
1462: mmove_t soldierh_move_walk2 = {FRAME_walk209, FRAME_walk218, soldierh_frames_walk2, NULL};
1463:
1464: void soldierh_walk (edict_t *self)
1465: {
1466: if (random() < 0.5)
1467: self->monsterinfo.currentmove = &soldierh_move_walk1;
1468: else
1469: self->monsterinfo.currentmove = &soldierh_move_walk2;
1470: }
1471:
1472:
1473: //
1474: // RUN
1475: //
1476:
1477: void soldierh_run (edict_t *self);
1478:
1479: mframe_t soldierh_frames_start_run [] =
1480: {
1481: ai_run, 7, NULL,
1482: ai_run, 5, NULL
1483: };
1484: mmove_t soldierh_move_start_run = {FRAME_run01, FRAME_run02, soldierh_frames_start_run, soldierh_run};
1485:
1486: mframe_t soldierh_frames_run [] =
1487: {
1488: ai_run, 10, NULL,
1489: ai_run, 11, NULL,
1490: ai_run, 11, NULL,
1491: ai_run, 16, NULL,
1492: ai_run, 10, NULL,
1493: ai_run, 15, NULL
1494: };
1495: mmove_t soldierh_move_run = {FRAME_run03, FRAME_run08, soldierh_frames_run, NULL};
1496:
1497: void soldierh_run (edict_t *self)
1498: {
1499: if (self->monsterinfo.aiflags & AI_STAND_GROUND)
1500: {
1501: self->monsterinfo.currentmove = &soldierh_move_stand1;
1502: return;
1503: }
1504:
1505: if (self->monsterinfo.currentmove == &soldierh_move_walk1 ||
1506: self->monsterinfo.currentmove == &soldierh_move_walk2 ||
1507: self->monsterinfo.currentmove == &soldierh_move_start_run)
1508: {
1509: self->monsterinfo.currentmove = &soldierh_move_run;
1510: }
1511: else
1512: {
1513: self->monsterinfo.currentmove = &soldierh_move_start_run;
1514: }
1515: }
1516:
1517:
1518: //
1519: // PAIN
1520: //
1521:
1522: mframe_t soldierh_frames_pain1 [] =
1523: {
1524: ai_move, -3, NULL,
1525: ai_move, 4, NULL,
1526: ai_move, 1, NULL,
1527: ai_move, 1, NULL,
1528: ai_move, 0, NULL
1529: };
1530: mmove_t soldierh_move_pain1 = {FRAME_pain101, FRAME_pain105, soldierh_frames_pain1, soldierh_run};
1531:
1532: mframe_t soldierh_frames_pain2 [] =
1533: {
1534: ai_move, -13, NULL,
1535: ai_move, -1, NULL,
1536: ai_move, 2, NULL,
1537: ai_move, 4, NULL,
1538: ai_move, 2, NULL,
1539: ai_move, 3, NULL,
1540: ai_move, 2, NULL
1541: };
1542: mmove_t soldierh_move_pain2 = {FRAME_pain201, FRAME_pain207, soldierh_frames_pain2, soldierh_run};
1543:
1544: mframe_t soldierh_frames_pain3 [] =
1545: {
1546: ai_move, -8, NULL,
1547: ai_move, 10, NULL,
1548: ai_move, -4, NULL,
1549: ai_move, -1, NULL,
1550: ai_move, -3, NULL,
1551: ai_move, 0, NULL,
1552: ai_move, 3, NULL,
1553: ai_move, 0, NULL,
1554: ai_move, 0, NULL,
1555: ai_move, 0, NULL,
1556: ai_move, 0, NULL,
1557: ai_move, 1, NULL,
1558: ai_move, 0, NULL,
1559: ai_move, 1, NULL,
1560: ai_move, 2, NULL,
1561: ai_move, 4, NULL,
1562: ai_move, 3, NULL,
1563: ai_move, 2, NULL
1564: };
1565: mmove_t soldierh_move_pain3 = {FRAME_pain301, FRAME_pain318, soldierh_frames_pain3, soldierh_run};
1566:
1567: mframe_t soldierh_frames_pain4 [] =
1568: {
1569: ai_move, 0, NULL,
1570: ai_move, 0, NULL,
1571: ai_move, 0, NULL,
1572: ai_move, -10, NULL,
1573: ai_move, -6, NULL,
1574: ai_move, 8, NULL,
1575: ai_move, 4, NULL,
1576: ai_move, 1, NULL,
1577: ai_move, 0, NULL,
1578: ai_move, 2, NULL,
1579: ai_move, 5, NULL,
1580: ai_move, 2, NULL,
1581: ai_move, -1, NULL,
1582: ai_move, -1, NULL,
1583: ai_move, 3, NULL,
1584: ai_move, 2, NULL,
1585: ai_move, 0, NULL
1586: };
1587: mmove_t soldierh_move_pain4 = {FRAME_pain401, FRAME_pain417, soldierh_frames_pain4, soldierh_run};
1588:
1589: void soldierh_pain (edict_t *self, edict_t *other, float kick, int damage)
1590: {
1591: float r;
1592: int n;
1593:
1594: if (self->health < (self->max_health / 2))
1595: self->s.skinnum |= 1;
1596:
1597: if (level.time < self->pain_debounce_time)
1598: {
1599: if ((self->velocity[2] > 100) && ( (self->monsterinfo.currentmove == &soldierh_move_pain1) || (self->monsterinfo.currentmove == &soldierh_move_pain2) || (self->monsterinfo.currentmove == &soldierh_move_pain3)))
1600: self->monsterinfo.currentmove = &soldierh_move_pain4;
1601: return;
1602: }
1603:
1604: self->pain_debounce_time = level.time + 3;
1605:
1606: n = self->s.skinnum | 1;
1607: if (n == 1)
1608: gi.sound (self, CHAN_VOICE, sound_pain_light, 1, ATTN_NORM, 0);
1609: else if (n == 3)
1610: gi.sound (self, CHAN_VOICE, sound_pain, 1, ATTN_NORM, 0);
1611: else
1612: gi.sound (self, CHAN_VOICE, sound_pain_ss, 1, ATTN_NORM, 0);
1613:
1614: if (self->velocity[2] > 100)
1615: {
1616: self->monsterinfo.currentmove = &soldierh_move_pain4;
1617: return;
1618: }
1619:
1620: if (skill->value == 3)
1621: return; // no pain anims in nightmare
1622:
1623: r = random();
1624:
1625: if (r < 0.33)
1626: self->monsterinfo.currentmove = &soldierh_move_pain1;
1627: else if (r < 0.66)
1628: self->monsterinfo.currentmove = &soldierh_move_pain2;
1629: else
1630: self->monsterinfo.currentmove = &soldierh_move_pain3;
1631: }
1632:
1633:
1634: //
1635: // ATTACK
1636: //
1637:
1638: extern void brain_dabeam (edict_t *self);
1639:
1640: void soldierh_laserbeam (edict_t *self, int flash_index)
1641: {
1642:
1643: vec3_t forward, right, up;
1644: vec3_t tempang, start;
1645: vec3_t dir, angles, end;
1646: vec3_t tempvec;
1647: edict_t *ent;
1648:
1649: // RAFAEL
1650: // this sound can't be called this frequent
1651: if (random() > 0.8)
1652: gi.sound(self, CHAN_AUTO, gi.soundindex("misc/lasfly.wav"), 1, ATTN_STATIC, 0);
1653:
1654: VectorCopy (self->s.origin, start);
1655: VectorCopy (self->enemy->s.origin, end);
1656: VectorSubtract (end, start, dir);
1657: vectoangles (dir, angles);
1658: VectorCopy (monster_flash_offset[flash_index], tempvec);
1659:
1660: ent = G_Spawn ();
1661: VectorCopy (self->s.origin, ent->s.origin);
1662: VectorCopy (angles, tempang);
1663: AngleVectors (tempang, forward, right, up);
1664: VectorCopy (tempang, ent->s.angles);
1665: VectorCopy (ent->s.origin, start);
1666:
1667: if (flash_index == 85)
1668: {
1669: VectorMA (start, tempvec[0]-14, right, start);
1670: VectorMA (start, tempvec[2]+8, up, start);
1671: VectorMA (start, tempvec[1], forward, start);
1672: }
1673: else
1674: {
1675: VectorMA (start, tempvec[0]+2, right, start);
1676: VectorMA (start, tempvec[2]+8, up, start);
1677: VectorMA (start, tempvec[1], forward, start);
1678: }
1679:
1680: VectorCopy (start, ent->s.origin);
1681: ent->enemy = self->enemy;
1682: ent->owner = self;
1683:
1684: ent->dmg = 1;
1685:
1686: monster_dabeam (ent);
1687:
1688: }
1689:
1690:
1691: void soldierh_fire (edict_t *self, int flash_number)
1692: {
1693: vec3_t start;
1694: vec3_t forward, right, up;
1695: vec3_t aim;
1696: vec3_t dir;
1697: vec3_t end;
1698: float r, u;
1699: int flash_index;
1700: qboolean tone = true;
1701:
1702: if (self->s.skinnum < 2)
1703: flash_index = blaster_flash[flash_number]; // ripper
1704: else if (self->s.skinnum < 4)
1705: flash_index = blaster_flash[flash_number]; // hyperblaster
1706: else
1707: flash_index = machinegun_flash[flash_number]; // laserbeam
1708:
1709: AngleVectors (self->s.angles, forward, right, NULL);
1710: G_ProjectSource (self->s.origin, monster_flash_offset[flash_index], forward, right, start);
1711:
1712: if (flash_number == 5 || flash_number == 6)
1713: {
1714: VectorCopy (forward, aim);
1715: }
1716: else
1717: {
1718: VectorCopy (self->enemy->s.origin, end);
1719: end[2] += self->enemy->viewheight;
1720: VectorSubtract (end, start, aim);
1721: vectoangles (aim, dir);
1722: AngleVectors (dir, forward, right, up);
1723:
1724: r = crandom()*100;
1725: u = crandom()*50;
1726: VectorMA (start, 8192, forward, end);
1727: VectorMA (end, r, right, end);
1728: VectorMA (end, u, up, end);
1729:
1730: VectorSubtract (end, start, aim);
1731: VectorNormalize (aim);
1732: }
1733:
1734: if (self->s.skinnum <= 1)
1735: {
1736: // RAFAEL 24-APR-98
1737: // droped the damage from 15 to 5
1738: monster_fire_ionripper (self, start, aim, 5, 600, flash_index, EF_IONRIPPER);
1739:
1740: }
1741: else if (self->s.skinnum <= 3)
1742: {
1743:
1744: monster_fire_blueblaster (self, start, aim, 1, 600, MZ_BLUEHYPERBLASTER, EF_BLUEHYPERBLASTER);
1745:
1746: }
1747: else
1748: {
1749: if (!(self->monsterinfo.aiflags & AI_HOLD_FRAME))
1750: self->monsterinfo.pausetime = level.time + (3 + rand() % 8) * FRAMETIME;
1751:
1752: soldierh_laserbeam (self, flash_index);
1753:
1754: if (level.time >= self->monsterinfo.pausetime)
1755: self->monsterinfo.aiflags &= ~AI_HOLD_FRAME;
1756: else
1757: self->monsterinfo.aiflags |= AI_HOLD_FRAME;
1758: }
1759: }
1760:
1761: // ATTACK1 (blaster/shotgun)
1762:
1763: void soldierh_hyper_refire1 (edict_t *self)
1764: {
1765: if (self->s.skinnum < 2)
1766: return;
1767: else if (self->s.skinnum < 4)
1768: {
1769: if (random() < 0.7)
1770: self->s.frame = FRAME_attak103;
1771: else
1772: gi.sound(self, CHAN_AUTO, gi.soundindex("weapons/hyprbd1a.wav"), 1, ATTN_NORM, 0);
1773: }
1774: }
1775:
1776: void soldierh_ripper1 (edict_t *self)
1777: {
1778: if (self->s.skinnum < 2)
1779: soldierh_fire (self, 0);
1780: else if (self->s.skinnum < 4)
1781: soldierh_fire (self, 0);
1782: }
1783:
1784:
1785: void soldierh_fire1 (edict_t *self)
1786: {
1787: soldierh_fire (self, 0);
1788: }
1789:
1790: void soldierh_attack1_refire1 (edict_t *self)
1791: {
1792: if (self->s.skinnum > 1)
1793: return;
1794:
1795: if (self->enemy->health <= 0)
1796: return;
1797:
1798: if ( ((skill->value == 3) && (random() < 0.5)) || (range(self, self->enemy) == RANGE_MELEE) )
1799: self->monsterinfo.nextframe = FRAME_attak102;
1800: else
1801: self->monsterinfo.nextframe = FRAME_attak110;
1802: }
1803:
1804: void soldierh_attack1_refire2 (edict_t *self)
1805: {
1806: if (self->s.skinnum < 2)
1807: return;
1808:
1809: if (self->enemy->health <= 0)
1810: return;
1811:
1812: if ( ((skill->value == 3) && (random() < 0.5)) || (range(self, self->enemy) == RANGE_MELEE) )
1813: self->monsterinfo.nextframe = FRAME_attak102;
1814: }
1815:
1816: void soldierh_hyper_sound (edict_t *self)
1817: {
1818: if (self->s.skinnum < 2)
1819: return;
1820: else if (self->s.skinnum < 4)
1821: gi.sound(self, CHAN_AUTO, gi.soundindex("weapons/hyprbl1a.wav"), 1, ATTN_NORM, 0);
1822: else
1823: return;
1824: }
1825:
1826: mframe_t soldierh_frames_attack1 [] =
1827: {
1828: ai_charge, 0, NULL,
1829: ai_charge, 0, soldierh_hyper_sound,
1830: ai_charge, 0, soldierh_fire1,
1831: ai_charge, 0, soldierh_ripper1,
1832: ai_charge, 0, soldierh_ripper1,
1833: ai_charge, 0, soldierh_attack1_refire1,
1834: ai_charge, 0, soldierh_hyper_refire1,
1835: ai_charge, 0, soldierh_cock,
1836: ai_charge, 0, soldierh_attack1_refire2,
1837: ai_charge, 0, NULL,
1838: ai_charge, 0, NULL,
1839: ai_charge, 0, NULL
1840: };
1841: mmove_t soldierh_move_attack1 = {FRAME_attak101, FRAME_attak112, soldierh_frames_attack1, soldierh_run};
1842:
1843: // ATTACK2 (blaster/shotgun)
1844:
1845: void soldierh_hyper_refire2 (edict_t *self)
1846: {
1847: if (self->s.skinnum < 2)
1848: return;
1849: else if (self->s.skinnum < 4)
1850: {
1851: if (random() < 0.7)
1852: self->s.frame = FRAME_attak205;
1853: else
1854: gi.sound(self, CHAN_AUTO, gi.soundindex("weapons/hyprbd1a.wav"), 1, ATTN_NORM, 0);
1855: }
1856: }
1857:
1858: void soldierh_ripper2 (edict_t *self)
1859: {
1860: if (self->s.skinnum < 2)
1861: soldierh_fire (self, 1);
1862: else if (self->s.skinnum < 4)
1863: soldierh_fire (self, 1);
1864: }
1865:
1866: void soldierh_fire2 (edict_t *self)
1867: {
1868: soldierh_fire (self, 1);
1869: }
1870:
1871:
1872: void soldierh_attack2_refire1 (edict_t *self)
1873: {
1874: if (self->s.skinnum > 1)
1875: return;
1876:
1877: if (self->enemy->health <= 0)
1878: return;
1879:
1880: if ( ((skill->value == 3) && (random() < 0.5)) || (range(self, self->enemy) == RANGE_MELEE))
1881: self->monsterinfo.nextframe = FRAME_attak204;
1882: else
1883: self->monsterinfo.nextframe = FRAME_attak216;
1884: }
1885:
1886: void soldierh_attack2_refire2 (edict_t *self)
1887: {
1888: if (self->s.skinnum < 2)
1889: return;
1890:
1891: if (self->enemy->health <= 0)
1892: return;
1893:
1894: if ( ((skill->value == 3) && (random() < 0.5)) || (range(self, self->enemy) == RANGE_MELEE) && self->s.skinnum < 4)
1895: self->monsterinfo.nextframe = FRAME_attak204;
1896: }
1897:
1898: mframe_t soldierh_frames_attack2 [] =
1899: {
1900: ai_charge, 0, NULL,
1901: ai_charge, 0, NULL,
1902: ai_charge, 0, NULL,
1903: ai_charge, 0, soldierh_hyper_sound,
1904: ai_charge, 0, soldierh_fire2,
1905: ai_charge, 0, soldierh_ripper2,
1906: ai_charge, 0, soldierh_ripper2,
1907: ai_charge, 0, soldierh_attack2_refire1,
1908: ai_charge, 0, soldierh_hyper_refire2,
1909: ai_charge, 0, NULL,
1910: ai_charge, 0, NULL,
1911: ai_charge, 0, NULL,
1912: ai_charge, 0, soldierh_cock,
1913: ai_charge, 0, NULL,
1914: ai_charge, 0, soldierh_attack2_refire2,
1915: ai_charge, 0, NULL,
1916: ai_charge, 0, NULL,
1917: ai_charge, 0, NULL
1918: };
1919: mmove_t soldierh_move_attack2 = {FRAME_attak201, FRAME_attak218, soldierh_frames_attack2, soldierh_run};
1920:
1921: // ATTACK3 (duck and shoot)
1922:
1923: void soldierh_duck_down (edict_t *self)
1924: {
1925: if (self->monsterinfo.aiflags & AI_DUCKED)
1926: return;
1927: self->monsterinfo.aiflags |= AI_DUCKED;
1928: self->maxs[2] -= 32;
1929: self->takedamage = DAMAGE_YES;
1930: self->monsterinfo.pausetime = level.time + 1;
1931: gi.linkentity (self);
1932: }
1933:
1934: void soldierh_duck_up (edict_t *self)
1935: {
1936: self->monsterinfo.aiflags &= ~AI_DUCKED;
1937: self->maxs[2] += 32;
1938: self->takedamage = DAMAGE_AIM;
1939: gi.linkentity (self);
1940: }
1941:
1942: void soldierh_fire3 (edict_t *self)
1943: {
1944: soldierh_duck_down (self);
1945: soldierh_fire (self, 2);
1946: }
1947:
1948: void soldierh_attack3_refire (edict_t *self)
1949: {
1950: if ((level.time + 0.4) < self->monsterinfo.pausetime)
1951: self->monsterinfo.nextframe = FRAME_attak303;
1952: }
1953:
1954: mframe_t soldierh_frames_attack3 [] =
1955: {
1956: ai_charge, 0, NULL,
1957: ai_charge, 0, NULL,
1958: ai_charge, 0, soldierh_fire3,
1959: ai_charge, 0, NULL,
1960: ai_charge, 0, NULL,
1961: ai_charge, 0, soldierh_attack3_refire,
1962: ai_charge, 0, soldierh_duck_up,
1963: ai_charge, 0, NULL,
1964: ai_charge, 0, NULL
1965: };
1966: mmove_t soldierh_move_attack3 = {FRAME_attak301, FRAME_attak309, soldierh_frames_attack3, soldierh_run};
1967:
1968: // ATTACK4 (machinegun)
1969:
1970: void soldierh_fire4 (edict_t *self)
1971: {
1972: soldierh_fire (self, 3);
1973: //
1974: // if (self->enemy->health <= 0)
1975: // return;
1976: //
1977: // if ( ((skill->value == 3) && (random() < 0.5)) || (range(self, self->enemy) == RANGE_MELEE) )
1978: // self->monsterinfo.nextframe = FRAME_attak402;
1979: }
1980:
1981: mframe_t soldierh_frames_attack4 [] =
1982: {
1983: ai_charge, 0, NULL,
1984: ai_charge, 0, NULL,
1985: ai_charge, 0, soldierh_fire4,
1986: ai_charge, 0, NULL,
1987: ai_charge, 0, NULL,
1988: ai_charge, 0, NULL
1989: };
1990: mmove_t soldierh_move_attack4 = {FRAME_attak401, FRAME_attak406, soldierh_frames_attack4, soldierh_run};
1991:
1992: #if 0
1993: // ATTACK5 (prone)
1994:
1995: void soldierh_fire5 (edict_t *self)
1996: {
1997: soldierh_fire (self, 4);
1998: }
1999:
2000: void soldierh_attack5_refire (edict_t *self)
2001: {
2002: if (self->enemy->health <= 0)
2003: return;
2004:
2005: if ( ((skill->value == 3) && (random() < 0.5)) || (range(self, self->enemy) == RANGE_MELEE) )
2006: self->monsterinfo.nextframe = FRAME_attak505;
2007: }
2008:
2009: mframe_t soldierh_frames_attack5 [] =
2010: {
2011: ai_charge, 8, NULL,
2012: ai_charge, 8, NULL,
2013: ai_charge, 0, NULL,
2014: ai_charge, 0, NULL,
2015: ai_charge, 0, soldierh_fire5,
2016: ai_charge, 0, NULL,
2017: ai_charge, 0, NULL,
2018: ai_charge, 0, soldierh_attack5_refire
2019: };
2020: mmove_t soldierh_move_attack5 = {FRAME_attak501, FRAME_attak508, soldierh_frames_attack5, soldierh_run};
2021: #endif
2022:
2023: // ATTACK6 (run & shoot)
2024:
2025: void soldierh_fire8 (edict_t *self)
2026: {
2027: soldierh_fire (self, 7);
2028: }
2029:
2030: void soldierh_attack6_refire (edict_t *self)
2031: {
2032: if (self->enemy->health <= 0)
2033: return;
2034:
2035: if (range(self, self->enemy) < RANGE_MID)
2036: return;
2037:
2038: if (skill->value == 3)
2039: self->monsterinfo.nextframe = FRAME_runs03;
2040: }
2041:
2042: mframe_t soldierh_frames_attack6 [] =
2043: {
2044: ai_charge, 10, NULL,
2045: ai_charge, 4, NULL,
2046: ai_charge, 12, NULL,
2047: ai_charge, 11, soldierh_fire8,
2048: ai_charge, 13, NULL,
2049: ai_charge, 18, NULL,
2050: ai_charge, 15, NULL,
2051: ai_charge, 14, NULL,
2052: ai_charge, 11, NULL,
2053: ai_charge, 8, NULL,
2054: ai_charge, 11, NULL,
2055: ai_charge, 12, NULL,
2056: ai_charge, 12, NULL,
2057: ai_charge, 17, soldierh_attack6_refire
2058: };
2059: mmove_t soldierh_move_attack6 = {FRAME_runs01, FRAME_runs14, soldierh_frames_attack6, soldierh_run};
2060:
2061: void soldierh_attack(edict_t *self)
2062: {
2063: if (self->s.skinnum < 4)
2064: {
2065: if (random() < 0.5)
2066: self->monsterinfo.currentmove = &soldierh_move_attack1;
2067: else
2068: self->monsterinfo.currentmove = &soldierh_move_attack2;
2069: }
2070: else
2071: {
2072: self->monsterinfo.currentmove = &soldierh_move_attack4;
2073: }
2074: }
2075:
2076:
2077: //
2078: // SIGHT
2079: //
2080:
2081: void soldierh_sight(edict_t *self, edict_t *other)
2082: {
2083: if (random() < 0.5)
2084: gi.sound (self, CHAN_VOICE, sound_sight1, 1, ATTN_NORM, 0);
2085: else
2086: gi.sound (self, CHAN_VOICE, sound_sight2, 1, ATTN_NORM, 0);
2087:
2088: if ((skill->value > 0) && (range(self, self->enemy) >= RANGE_MID))
2089: {
2090: if (random() > 0.5)
2091: {
2092: if (self->s.skinnum < 4)
2093: self->monsterinfo.currentmove = &soldierh_move_attack6;
2094: else
2095: self->monsterinfo.currentmove = &soldierh_move_attack4;
2096: }
2097: }
2098: }
2099:
2100: //
2101: // DUCK
2102: //
2103:
2104: void soldierh_duck_hold (edict_t *self)
2105: {
2106: if (level.time >= self->monsterinfo.pausetime)
2107: self->monsterinfo.aiflags &= ~AI_HOLD_FRAME;
2108: else
2109: self->monsterinfo.aiflags |= AI_HOLD_FRAME;
2110: }
2111:
2112: mframe_t soldierh_frames_duck [] =
2113: {
2114: ai_move, 5, soldierh_duck_down,
2115: ai_move, -1, soldierh_duck_hold,
2116: ai_move, 1, NULL,
2117: ai_move, 0, soldierh_duck_up,
2118: ai_move, 5, NULL
2119: };
2120: mmove_t soldierh_move_duck = {FRAME_duck01, FRAME_duck05, soldierh_frames_duck, soldierh_run};
2121:
2122: void soldierh_dodge (edict_t *self, edict_t *attacker, float eta)
2123: {
2124: float r;
2125:
2126: r = random();
2127: if (r > 0.25)
2128: return;
2129:
2130: if (!self->enemy)
2131: self->enemy = attacker;
2132:
2133: if (skill->value == 0)
2134: {
2135: self->monsterinfo.currentmove = &soldierh_move_duck;
2136: return;
2137: }
2138:
2139: self->monsterinfo.pausetime = level.time + eta + 0.3;
2140: r = random();
2141:
2142: if (skill->value == 1)
2143: {
2144: if (r > 0.33)
2145: self->monsterinfo.currentmove = &soldierh_move_duck;
2146: else
2147: self->monsterinfo.currentmove = &soldierh_move_attack3;
2148: return;
2149: }
2150:
2151: if (skill->value >= 2)
2152: {
2153: if (r > 0.66)
2154: self->monsterinfo.currentmove = &soldierh_move_duck;
2155: else
2156: self->monsterinfo.currentmove = &soldierh_move_attack3;
2157: return;
2158: }
2159:
2160: self->monsterinfo.currentmove = &soldierh_move_attack3;
2161: }
2162:
2163:
2164: //
2165: // DEATH
2166: //
2167:
2168: void soldierh_fire6 (edict_t *self)
2169: {
2170:
2171: // no fire laser
2172: if (self->s.skinnum < 4)
2173: soldierh_fire (self, 5);
2174:
2175: }
2176:
2177: void soldierh_fire7 (edict_t *self)
2178: {
2179:
2180: // no fire laser
2181: if (self->s.skinnum < 4)
2182: soldierh_fire (self, 6);
2183:
2184: }
2185:
2186: void soldierh_dead (edict_t *self)
2187: {
2188: VectorSet (self->mins, -16, -16, -24);
2189: VectorSet (self->maxs, 16, 16, -8);
2190: self->movetype = MOVETYPE_TOSS;
2191: self->svflags |= SVF_DEADMONSTER;
2192: self->nextthink = 0;
2193: gi.linkentity (self);
2194: }
2195:
2196: mframe_t soldierh_frames_death1 [] =
2197: {
2198: ai_move, 0, NULL,
2199: ai_move, -10, NULL,
2200: ai_move, -10, NULL,
2201: ai_move, -10, NULL,
2202: ai_move, -5, NULL,
2203: ai_move, 0, NULL,
2204: ai_move, 0, NULL,
2205: ai_move, 0, NULL,
2206: ai_move, 0, NULL,
2207: ai_move, 0, NULL,
2208:
2209: ai_move, 0, NULL,
2210: ai_move, 0, NULL,
2211: ai_move, 0, NULL,
2212: ai_move, 0, NULL,
2213: ai_move, 0, NULL,
2214: ai_move, 0, NULL,
2215: ai_move, 0, NULL,
2216: ai_move, 0, NULL,
2217: ai_move, 0, NULL,
2218: ai_move, 0, NULL,
2219:
2220: ai_move, 0, NULL,
2221: ai_move, 0, soldierh_fire6,
2222: ai_move, 0, NULL,
2223: ai_move, 0, NULL,
2224: ai_move, 0, soldierh_fire7,
2225: ai_move, 0, NULL,
2226: ai_move, 0, NULL,
2227: ai_move, 0, NULL,
2228: ai_move, 0, NULL,
2229: ai_move, 0, NULL,
2230:
2231: ai_move, 0, NULL,
2232: ai_move, 0, NULL,
2233: ai_move, 0, NULL,
2234: ai_move, 0, NULL,
2235: ai_move, 0, NULL,
2236: ai_move, 0, NULL
2237: };
2238: mmove_t soldierh_move_death1 = {FRAME_death101, FRAME_death136, soldierh_frames_death1, soldierh_dead};
2239:
2240: mframe_t soldierh_frames_death2 [] =
2241: {
2242: ai_move, -5, NULL,
2243: ai_move, -5, NULL,
2244: ai_move, -5, NULL,
2245: ai_move, 0, NULL,
2246: ai_move, 0, NULL,
2247: ai_move, 0, NULL,
2248: ai_move, 0, NULL,
2249: ai_move, 0, NULL,
2250: ai_move, 0, NULL,
2251: ai_move, 0, NULL,
2252:
2253: ai_move, 0, NULL,
2254: ai_move, 0, NULL,
2255: ai_move, 0, NULL,
2256: ai_move, 0, NULL,
2257: ai_move, 0, NULL,
2258: ai_move, 0, NULL,
2259: ai_move, 0, NULL,
2260: ai_move, 0, NULL,
2261: ai_move, 0, NULL,
2262: ai_move, 0, NULL,
2263:
2264: ai_move, 0, NULL,
2265: ai_move, 0, NULL,
2266: ai_move, 0, NULL,
2267: ai_move, 0, NULL,
2268: ai_move, 0, NULL,
2269: ai_move, 0, NULL,
2270: ai_move, 0, NULL,
2271: ai_move, 0, NULL,
2272: ai_move, 0, NULL,
2273: ai_move, 0, NULL,
2274:
2275: ai_move, 0, NULL,
2276: ai_move, 0, NULL,
2277: ai_move, 0, NULL,
2278: ai_move, 0, NULL,
2279: ai_move, 0, NULL
2280: };
2281: mmove_t soldierh_move_death2 = {FRAME_death201, FRAME_death235, soldierh_frames_death2, soldierh_dead};
2282:
2283: mframe_t soldierh_frames_death3 [] =
2284: {
2285: ai_move, -5, NULL,
2286: ai_move, -5, NULL,
2287: ai_move, -5, NULL,
2288: ai_move, 0, NULL,
2289: ai_move, 0, NULL,
2290: ai_move, 0, NULL,
2291: ai_move, 0, NULL,
2292: ai_move, 0, NULL,
2293: ai_move, 0, NULL,
2294: ai_move, 0, NULL,
2295:
2296: ai_move, 0, NULL,
2297: ai_move, 0, NULL,
2298: ai_move, 0, NULL,
2299: ai_move, 0, NULL,
2300: ai_move, 0, NULL,
2301: ai_move, 0, NULL,
2302: ai_move, 0, NULL,
2303: ai_move, 0, NULL,
2304: ai_move, 0, NULL,
2305: ai_move, 0, NULL,
2306:
2307: ai_move, 0, NULL,
2308: ai_move, 0, NULL,
2309: ai_move, 0, NULL,
2310: ai_move, 0, NULL,
2311: ai_move, 0, NULL,
2312: ai_move, 0, NULL,
2313: ai_move, 0, NULL,
2314: ai_move, 0, NULL,
2315: ai_move, 0, NULL,
2316: ai_move, 0, NULL,
2317:
2318: ai_move, 0, NULL,
2319: ai_move, 0, NULL,
2320: ai_move, 0, NULL,
2321: ai_move, 0, NULL,
2322: ai_move, 0, NULL,
2323: ai_move, 0, NULL,
2324: ai_move, 0, NULL,
2325: ai_move, 0, NULL,
2326: ai_move, 0, NULL,
2327: ai_move, 0, NULL,
2328:
2329: ai_move, 0, NULL,
2330: ai_move, 0, NULL,
2331: ai_move, 0, NULL,
2332: ai_move, 0, NULL,
2333: ai_move, 0, NULL,
2334: };
2335: mmove_t soldierh_move_death3 = {FRAME_death301, FRAME_death345, soldierh_frames_death3, soldierh_dead};
2336:
2337: mframe_t soldierh_frames_death4 [] =
2338: {
2339: ai_move, 0, NULL,
2340: ai_move, 0, NULL,
2341: ai_move, 0, NULL,
2342: ai_move, 0, NULL,
2343: ai_move, 0, NULL,
2344: ai_move, 0, NULL,
2345: ai_move, 0, NULL,
2346: ai_move, 0, NULL,
2347: ai_move, 0, NULL,
2348: ai_move, 0, NULL,
2349:
2350: ai_move, 0, NULL,
2351: ai_move, 0, NULL,
2352: ai_move, 0, NULL,
2353: ai_move, 0, NULL,
2354: ai_move, 0, NULL,
2355: ai_move, 0, NULL,
2356: ai_move, 0, NULL,
2357: ai_move, 0, NULL,
2358: ai_move, 0, NULL,
2359: ai_move, 0, NULL,
2360:
2361: ai_move, 0, NULL,
2362: ai_move, 0, NULL,
2363: ai_move, 0, NULL,
2364: ai_move, 0, NULL,
2365: ai_move, 0, NULL,
2366: ai_move, 0, NULL,
2367: ai_move, 0, NULL,
2368: ai_move, 0, NULL,
2369: ai_move, 0, NULL,
2370: ai_move, 0, NULL,
2371:
2372: ai_move, 0, NULL,
2373: ai_move, 0, NULL,
2374: ai_move, 0, NULL,
2375: ai_move, 0, NULL,
2376: ai_move, 0, NULL,
2377: ai_move, 0, NULL,
2378: ai_move, 0, NULL,
2379: ai_move, 0, NULL,
2380: ai_move, 0, NULL,
2381: ai_move, 0, NULL,
2382:
2383: ai_move, 0, NULL,
2384: ai_move, 0, NULL,
2385: ai_move, 0, NULL,
2386: ai_move, 0, NULL,
2387: ai_move, 0, NULL,
2388: ai_move, 0, NULL,
2389: ai_move, 0, NULL,
2390: ai_move, 0, NULL,
2391: ai_move, 0, NULL,
2392: ai_move, 0, NULL,
2393:
2394: ai_move, 0, NULL,
2395: ai_move, 0, NULL,
2396: ai_move, 0, NULL
2397: };
2398: mmove_t soldierh_move_death4 = {FRAME_death401, FRAME_death453, soldierh_frames_death4, soldierh_dead};
2399:
2400: mframe_t soldierh_frames_death5 [] =
2401: {
2402: ai_move, -5, NULL,
2403: ai_move, -5, NULL,
2404: ai_move, -5, NULL,
2405: ai_move, 0, NULL,
2406: ai_move, 0, NULL,
2407: ai_move, 0, NULL,
2408: ai_move, 0, NULL,
2409: ai_move, 0, NULL,
2410: ai_move, 0, NULL,
2411: ai_move, 0, NULL,
2412:
2413: ai_move, 0, NULL,
2414: ai_move, 0, NULL,
2415: ai_move, 0, NULL,
2416: ai_move, 0, NULL,
2417: ai_move, 0, NULL,
2418: ai_move, 0, NULL,
2419: ai_move, 0, NULL,
2420: ai_move, 0, NULL,
2421: ai_move, 0, NULL,
2422: ai_move, 0, NULL,
2423:
2424: ai_move, 0, NULL,
2425: ai_move, 0, NULL,
2426: ai_move, 0, NULL,
2427: ai_move, 0, NULL
2428: };
2429: mmove_t soldierh_move_death5 = {FRAME_death501, FRAME_death524, soldierh_frames_death5, soldierh_dead};
2430:
2431: mframe_t soldierh_frames_death6 [] =
2432: {
2433: ai_move, 0, NULL,
2434: ai_move, 0, NULL,
2435: ai_move, 0, NULL,
2436: ai_move, 0, NULL,
2437: ai_move, 0, NULL,
2438: ai_move, 0, NULL,
2439: ai_move, 0, NULL,
2440: ai_move, 0, NULL,
2441: ai_move, 0, NULL,
2442: ai_move, 0, NULL
2443: };
2444: mmove_t soldierh_move_death6 = {FRAME_death601, FRAME_death610, soldierh_frames_death6, soldierh_dead};
2445:
2446: void soldierh_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
2447: {
2448: int n;
2449:
2450: // check for gib
2451: if (self->health <= self->gib_health)
2452: {
2453: gi.sound (self, CHAN_VOICE, gi.soundindex ("misc/udeath.wav"), 1, ATTN_NORM, 0);
2454: for (n= 0; n < 3; n++)
2455: ThrowGib (self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC);
2456: ThrowGib (self, "models/objects/gibs/chest/tris.md2", damage, GIB_ORGANIC);
2457: ThrowHead (self, "models/objects/gibs/head2/tris.md2", damage, GIB_ORGANIC);
2458:
2459: self->deadflag = DEAD_DEAD;
2460: return;
2461: }
2462:
2463: if (self->deadflag == DEAD_DEAD)
2464: return;
2465:
2466: // regular death
2467: self->deadflag = DEAD_DEAD;
2468: self->takedamage = DAMAGE_YES;
2469: self->s.skinnum |= 1;
2470:
2471: if (self->s.skinnum == 1)
2472: gi.sound (self, CHAN_VOICE, sound_death_light, 1, ATTN_NORM, 0);
2473: else if (self->s.skinnum == 3)
2474: gi.sound (self, CHAN_VOICE, sound_death, 1, ATTN_NORM, 0);
2475: else // (self->s.skinnum == 5)
2476: gi.sound (self, CHAN_VOICE, sound_death_ss, 1, ATTN_NORM, 0);
2477:
2478: if (fabs((self->s.origin[2] + self->viewheight) - point[2]) <= 4)
2479: {
2480: // head shot
2481: self->monsterinfo.currentmove = &soldierh_move_death3;
2482: return;
2483: }
2484:
2485: n = rand() % 5;
2486: if (n == 0)
2487: self->monsterinfo.currentmove = &soldierh_move_death1;
2488: else if (n == 1)
2489: self->monsterinfo.currentmove = &soldierh_move_death2;
2490: else if (n == 2)
2491: self->monsterinfo.currentmove = &soldierh_move_death4;
2492: else if (n == 3)
2493: self->monsterinfo.currentmove = &soldierh_move_death5;
2494: else
2495: self->monsterinfo.currentmove = &soldierh_move_death6;
2496: }
2497:
2498:
2499: //
2500: // SPAWN
2501: //
2502:
2503: void SP_monster_soldier_h (edict_t *self)
2504: {
2505:
2506: self->s.modelindex = gi.modelindex ("models/monsters/soldierh/tris.md2");
2507: self->monsterinfo.scale = MODEL_SCALE;
2508: VectorSet (self->mins, -16, -16, -24);
2509: VectorSet (self->maxs, 16, 16, 32);
2510: self->movetype = MOVETYPE_STEP;
2511: self->solid = SOLID_BBOX;
2512:
2513: sound_idle = gi.soundindex ("soldier/solidle1.wav");
2514: sound_sight1 = gi.soundindex ("soldier/solsght1.wav");
2515: sound_sight2 = gi.soundindex ("soldier/solsrch1.wav");
2516: sound_cock = gi.soundindex ("infantry/infatck3.wav");
2517:
2518: self->mass = 100;
2519:
2520: self->pain = soldierh_pain;
2521: self->die = soldierh_die;
2522:
2523: self->monsterinfo.stand = soldierh_stand;
2524: self->monsterinfo.walk = soldierh_walk;
2525: self->monsterinfo.run = soldierh_run;
2526: self->monsterinfo.dodge = soldierh_dodge;
2527: self->monsterinfo.attack = soldierh_attack;
2528: self->monsterinfo.melee = NULL;
2529: self->monsterinfo.sight = soldierh_sight;
2530:
2531: gi.linkentity (self);
2532:
2533: // self->monsterinfo.stand (self);
2534: self->monsterinfo.currentmove = &soldierh_move_stand3;
2535:
2536: walkmonster_start (self);
2537: }
2538:
2539:
2540: /*QUAKED monster_soldier_ripper (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight
2541: */
2542: void SP_monster_soldier_ripper (edict_t *self)
2543: {
2544: if (deathmatch->value)
2545: {
2546: G_FreeEdict (self);
2547: return;
2548: }
2549:
2550: SP_monster_soldier_h (self);
2551:
2552: sound_pain_light = gi.soundindex ("soldier/solpain2.wav");
2553: sound_death_light = gi.soundindex ("soldier/soldeth2.wav");
2554:
2555: gi.modelindex ("models/objects/boomrang/tris.md2");
2556: gi.soundindex ("misc/lasfly.wav");
2557: gi.soundindex ("soldier/solatck2.wav");
2558:
2559: self->s.skinnum = 0;
2560: self->health = 50;
2561: self->gib_health = -30;
2562: }
2563:
2564: /*QUAKED monster_soldier_hypergun (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight
2565: */
2566: void SP_monster_soldier_hypergun (edict_t *self)
2567: {
2568: if (deathmatch->value)
2569: {
2570: G_FreeEdict (self);
2571: return;
2572: }
2573:
2574: SP_monster_soldier_h (self);
2575:
2576: gi.modelindex ("models/objects/blaser/tris.md2");
2577: sound_pain = gi.soundindex ("soldier/solpain1.wav");
2578: sound_death = gi.soundindex ("soldier/soldeth1.wav");
2579: gi.soundindex ("soldier/solatck1.wav");
2580:
2581: self->s.skinnum = 2;
2582: self->health = 60;
2583: self->gib_health = -30;
2584: }
2585:
2586: /*QUAKED monster_soldier_lasergun (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight
2587: */
2588: void SP_monster_soldier_lasergun (edict_t *self)
2589: {
2590: if (deathmatch->value)
2591: {
2592: G_FreeEdict (self);
2593: return;
2594: }
2595:
2596: SP_monster_soldier_h (self);
2597:
2598: sound_pain_ss = gi.soundindex ("soldier/solpain3.wav");
2599: sound_death_ss = gi.soundindex ("soldier/soldeth3.wav");
2600: gi.soundindex ("soldier/solatck3.wav");
2601:
2602: self->s.skinnum = 4;
2603: self->health = 70;
2604: self->gib_health = -30;
2605:
2606: }
2607:
2608: // END 13-APR-98
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.