|
|
1.1 root 1: /*
2: ==============================================================================
3:
4: INFANTRY
5:
6: ==============================================================================
7: */
8:
9: #include "g_local.h"
10: #include "m_infantry.h"
11:
12: void InfantryMachineGun (edict_t *self);
13:
14:
15: static int sound_pain1;
16: static int sound_pain2;
17: static int sound_die1;
18: static int sound_die2;
19:
20: static int sound_gunshot;
21: static int sound_weapon_cock;
22: static int sound_punch_swing;
23: static int sound_punch_hit;
24: static int sound_sight;
25: static int sound_search;
26: static int sound_idle;
27:
28: mframe_t infantry_frames_stand [] =
29: {
30: ai_stand, 0, NULL,
31: ai_stand, 0, NULL,
32: ai_stand, 0, NULL,
33: ai_stand, 0, NULL,
34: ai_stand, 0, NULL,
35: ai_stand, 0, NULL,
36: ai_stand, 0, NULL,
37: ai_stand, 0, NULL,
38: ai_stand, 0, NULL,
39: ai_stand, 0, NULL,
40: ai_stand, 0, NULL,
41: ai_stand, 0, NULL,
42: ai_stand, 0, NULL,
43: ai_stand, 0, NULL,
44: ai_stand, 0, NULL,
45: ai_stand, 0, NULL,
46: ai_stand, 0, NULL,
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: };
53: mmove_t infantry_move_stand = {FRAME_stand50, FRAME_stand71, infantry_frames_stand, NULL};
54:
55: void infantry_stand (edict_t *self)
56: {
57: self->monsterinfo.currentmove = &infantry_move_stand;
58: }
59:
60:
61: mframe_t infantry_frames_fidget [] =
62: {
63: ai_stand, 1, NULL,
64: ai_stand, 0, NULL,
65: ai_stand, 1, NULL,
66: ai_stand, 3, NULL,
67: ai_stand, 6, NULL,
68: ai_stand, 3, NULL,
69: ai_stand, 0, NULL,
70: ai_stand, 0, NULL,
71: ai_stand, 0, NULL,
72: ai_stand, 0, NULL,
73: ai_stand, 1, NULL,
74: ai_stand, 0, NULL,
75: ai_stand, 0, NULL,
76: ai_stand, 0, NULL,
77: ai_stand, 0, NULL,
78: ai_stand, 1, NULL,
79: ai_stand, 0, NULL,
80: ai_stand, -1, NULL,
81: ai_stand, 0, NULL,
82: ai_stand, 0, NULL,
83: ai_stand, 1, NULL,
84: ai_stand, 0, NULL,
85: ai_stand, -2, NULL,
86: ai_stand, 1, NULL,
87: ai_stand, 1, NULL,
88: ai_stand, 1, NULL,
89: ai_stand, -1, NULL,
90: ai_stand, 0, NULL,
91: ai_stand, 0, NULL,
92: ai_stand, -1, NULL,
93: ai_stand, 0, NULL,
94: ai_stand, 0, NULL,
95: ai_stand, 0, NULL,
96: ai_stand, 0, NULL,
97: ai_stand, 0, NULL,
98: ai_stand, -1, NULL,
99: ai_stand, 0, NULL,
100: ai_stand, 0, NULL,
101: ai_stand, 1, NULL,
102: ai_stand, 0, NULL,
103: ai_stand, 0, NULL,
104: ai_stand, -1, NULL,
105: ai_stand, -1, NULL,
106: ai_stand, 0, NULL,
107: ai_stand, -3, NULL,
108: ai_stand, -2, NULL,
109: ai_stand, -3, NULL,
110: ai_stand, -3, NULL,
111: ai_stand, -2, NULL
112: };
113: mmove_t infantry_move_fidget = {FRAME_stand01, FRAME_stand49, infantry_frames_fidget, infantry_stand};
114:
115: void infantry_fidget (edict_t *self)
116: {
117: self->monsterinfo.currentmove = &infantry_move_fidget;
118: gi.sound (self, CHAN_VOICE, sound_idle, 1, ATTN_IDLE, 0);
119: }
120:
121: mframe_t infantry_frames_walk [] =
122: {
123: ai_walk, 5, NULL,
124: ai_walk, 4, NULL,
125: ai_walk, 4, NULL,
126: ai_walk, 5, NULL,
127: ai_walk, 4, NULL,
128: ai_walk, 5, NULL,
129: ai_walk, 6, NULL,
130: ai_walk, 4, NULL,
131: ai_walk, 4, NULL,
132: ai_walk, 4, NULL,
133: ai_walk, 4, NULL,
134: ai_walk, 5, NULL
135: };
136: mmove_t infantry_move_walk = {FRAME_walk03, FRAME_walk14, infantry_frames_walk, NULL};
137:
138: void infantry_walk (edict_t *self)
139: {
140: self->monsterinfo.currentmove = &infantry_move_walk;
141: }
142:
143: mframe_t infantry_frames_run [] =
144: {
145: ai_run, 10, NULL,
146: ai_run, 20, NULL,
147: ai_run, 5, NULL,
148: ai_run, 7, monster_done_dodge,
149: ai_run, 30, NULL,
150: ai_run, 35, NULL,
151: ai_run, 2, NULL,
152: ai_run, 6, NULL
153: };
154: mmove_t infantry_move_run = {FRAME_run01, FRAME_run08, infantry_frames_run, NULL};
155:
156: void infantry_run (edict_t *self)
157: {
158: monster_done_dodge (self);
159:
160: if (self->monsterinfo.aiflags & AI_STAND_GROUND)
161: self->monsterinfo.currentmove = &infantry_move_stand;
162: else
163: self->monsterinfo.currentmove = &infantry_move_run;
164: }
165:
166:
167: mframe_t infantry_frames_pain1 [] =
168: {
169: ai_move, -3, NULL,
170: ai_move, -2, NULL,
171: ai_move, -1, NULL,
172: ai_move, -2, NULL,
173: ai_move, -1, NULL,
174: ai_move, 1, NULL,
175: ai_move, -1, NULL,
176: ai_move, 1, NULL,
177: ai_move, 6, NULL,
178: ai_move, 2, NULL
179: };
180: mmove_t infantry_move_pain1 = {FRAME_pain101, FRAME_pain110, infantry_frames_pain1, infantry_run};
181:
182: mframe_t infantry_frames_pain2 [] =
183: {
184: ai_move, -3, NULL,
185: ai_move, -3, NULL,
186: ai_move, 0, NULL,
187: ai_move, -1, NULL,
188: ai_move, -2, NULL,
189: ai_move, 0, NULL,
190: ai_move, 0, NULL,
191: ai_move, 2, NULL,
192: ai_move, 5, NULL,
193: ai_move, 2, NULL
194: };
195: mmove_t infantry_move_pain2 = {FRAME_pain201, FRAME_pain210, infantry_frames_pain2, infantry_run};
196:
197: void infantry_pain (edict_t *self, edict_t *other, float kick, int damage)
198: {
199: int n;
200:
201: if (self->health < (self->max_health / 2))
202: self->s.skinnum = 1;
203:
204: if (!self->groundentity)
205: {
206: if ((g_showlogic) && (g_showlogic->value))
207: gi.dprintf ("infantry: pain avoided due to no ground\n");
208: return;
209: }
210:
211: monster_done_dodge (self);
212:
213: if (level.time < self->pain_debounce_time)
214: return;
215:
216: self->pain_debounce_time = level.time + 3;
217:
218: if (skill->value == 3)
219: return; // no pain anims in nightmare
220:
221: n = rand() % 2;
222: if (n == 0)
223: {
224: self->monsterinfo.currentmove = &infantry_move_pain1;
225: gi.sound (self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0);
226: }
227: else
228: {
229: self->monsterinfo.currentmove = &infantry_move_pain2;
230: gi.sound (self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0);
231: }
232:
233: // PMM - clear duck flag
234: if (self->monsterinfo.aiflags & AI_DUCKED)
235: monster_duck_up(self);
236: }
237:
238:
239: vec3_t aimangles[] =
240: {
241: 0.0, 5.0, 0.0,
242: 10.0, 15.0, 0.0,
243: 20.0, 25.0, 0.0,
244: 25.0, 35.0, 0.0,
245: 30.0, 40.0, 0.0,
246: 30.0, 45.0, 0.0,
247: 25.0, 50.0, 0.0,
248: 20.0, 40.0, 0.0,
249: 15.0, 35.0, 0.0,
250: 40.0, 35.0, 0.0,
251: 70.0, 35.0, 0.0,
252: 90.0, 35.0, 0.0
253: };
254:
255: void InfantryMachineGun (edict_t *self)
256: {
257: vec3_t start, target;
258: vec3_t forward, right;
259: vec3_t vec;
260: int flash_number;
261:
262: if(!self->enemy || !self->enemy->inuse) //PGM
263: return; //PGM
264:
265: // pmm - new attack start frame
266: if (self->s.frame == FRAME_attak104)
267: {
268: flash_number = MZ2_INFANTRY_MACHINEGUN_1;
269: AngleVectors (self->s.angles, forward, right, NULL);
270: G_ProjectSource (self->s.origin, monster_flash_offset[flash_number], forward, right, start);
271:
272: if (self->enemy)
273: {
274: VectorMA (self->enemy->s.origin, -0.2, self->enemy->velocity, target);
275: target[2] += self->enemy->viewheight;
276: VectorSubtract (target, start, forward);
277: VectorNormalize (forward);
278: }
279: else
280: {
281: AngleVectors (self->s.angles, forward, right, NULL);
282: }
283: }
284: else
285: {
286: flash_number = MZ2_INFANTRY_MACHINEGUN_2 + (self->s.frame - FRAME_death211);
287:
288: AngleVectors (self->s.angles, forward, right, NULL);
289: G_ProjectSource (self->s.origin, monster_flash_offset[flash_number], forward, right, start);
290:
291: VectorSubtract (self->s.angles, aimangles[flash_number-MZ2_INFANTRY_MACHINEGUN_2], vec);
292: AngleVectors (vec, forward, NULL, NULL);
293: }
294:
295: monster_fire_bullet (self, start, forward, 3, 4, DEFAULT_BULLET_HSPREAD, DEFAULT_BULLET_VSPREAD, flash_number);
296: }
297:
298: void infantry_sight (edict_t *self, edict_t *other)
299: {
300: gi.sound (self, CHAN_BODY, sound_sight, 1, ATTN_NORM, 0);
301: }
302:
303: void infantry_dead (edict_t *self)
304: {
305: VectorSet (self->mins, -16, -16, -24);
306: VectorSet (self->maxs, 16, 16, -8);
307: self->movetype = MOVETYPE_TOSS;
308: self->svflags |= SVF_DEADMONSTER;
309: gi.linkentity (self);
310:
311: M_FlyCheck (self);
312: }
313:
314: mframe_t infantry_frames_death1 [] =
315: {
316: ai_move, -4, NULL,
317: ai_move, 0, NULL,
318: ai_move, 0, NULL,
319: ai_move, -1, NULL,
320: ai_move, -4, NULL,
321: ai_move, 0, NULL,
322: ai_move, 0, NULL,
323: ai_move, 0, NULL,
324: ai_move, -1, NULL,
325: ai_move, 3, NULL,
326: ai_move, 1, NULL,
327: ai_move, 1, NULL,
328: ai_move, -2, NULL,
329: ai_move, 2, NULL,
330: ai_move, 2, NULL,
331: ai_move, 9, NULL,
332: ai_move, 9, NULL,
333: ai_move, 5, NULL,
334: ai_move, -3, NULL,
335: ai_move, -3, NULL
336: };
337: mmove_t infantry_move_death1 = {FRAME_death101, FRAME_death120, infantry_frames_death1, infantry_dead};
338:
339: // Off with his head
340: mframe_t infantry_frames_death2 [] =
341: {
342: ai_move, 0, NULL,
343: ai_move, 1, NULL,
344: ai_move, 5, NULL,
345: ai_move, -1, NULL,
346: ai_move, 0, NULL,
347: ai_move, 1, NULL,
348: ai_move, 1, NULL,
349: ai_move, 4, NULL,
350: ai_move, 3, NULL,
351: ai_move, 0, NULL,
352: ai_move, -2, InfantryMachineGun,
353: ai_move, -2, InfantryMachineGun,
354: ai_move, -3, InfantryMachineGun,
355: ai_move, -1, InfantryMachineGun,
356: ai_move, -2, InfantryMachineGun,
357: ai_move, 0, InfantryMachineGun,
358: ai_move, 2, InfantryMachineGun,
359: ai_move, 2, InfantryMachineGun,
360: ai_move, 3, InfantryMachineGun,
361: ai_move, -10, InfantryMachineGun,
362: ai_move, -7, InfantryMachineGun,
363: ai_move, -8, InfantryMachineGun,
364: ai_move, -6, NULL,
365: ai_move, 4, NULL,
366: ai_move, 0, NULL
367: };
368: mmove_t infantry_move_death2 = {FRAME_death201, FRAME_death225, infantry_frames_death2, infantry_dead};
369:
370: mframe_t infantry_frames_death3 [] =
371: {
372: ai_move, 0, NULL,
373: ai_move, 0, NULL,
374: ai_move, 0, NULL,
375: ai_move, -6, NULL,
376: ai_move, -11, NULL,
377: ai_move, -3, NULL,
378: ai_move, -11, NULL,
379: ai_move, 0, NULL,
380: ai_move, 0, NULL
381: };
382: mmove_t infantry_move_death3 = {FRAME_death301, FRAME_death309, infantry_frames_death3, infantry_dead};
383:
384:
385: void infantry_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
386: {
387: int n;
388:
389: // check for gib
390: if (self->health <= self->gib_health)
391: {
392: gi.sound (self, CHAN_VOICE, gi.soundindex ("misc/udeath.wav"), 1, ATTN_NORM, 0);
393: for (n= 0; n < 2; n++)
394: ThrowGib (self, "models/objects/gibs/bone/tris.md2", damage, GIB_ORGANIC);
395: for (n= 0; n < 4; n++)
396: ThrowGib (self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC);
397: ThrowHead (self, "models/objects/gibs/head2/tris.md2", damage, GIB_ORGANIC);
398: self->deadflag = DEAD_DEAD;
399: return;
400: }
401:
402: if (self->deadflag == DEAD_DEAD)
403: return;
404:
405: // regular death
406: self->deadflag = DEAD_DEAD;
407: self->takedamage = DAMAGE_YES;
408:
409: n = rand() % 3;
410: if (n == 0)
411: {
412: self->monsterinfo.currentmove = &infantry_move_death1;
413: gi.sound (self, CHAN_VOICE, sound_die2, 1, ATTN_NORM, 0);
414: }
415: else if (n == 1)
416: {
417: self->monsterinfo.currentmove = &infantry_move_death2;
418: gi.sound (self, CHAN_VOICE, sound_die1, 1, ATTN_NORM, 0);
419: }
420: else
421: {
422: self->monsterinfo.currentmove = &infantry_move_death3;
423: gi.sound (self, CHAN_VOICE, sound_die2, 1, ATTN_NORM, 0);
424: }
425: }
426:
427: mframe_t infantry_frames_duck [] =
428: {
429: ai_move, -2, monster_duck_down,
430: ai_move, -5, monster_duck_hold,
431: ai_move, 3, NULL,
432: ai_move, 4, monster_duck_up,
433: ai_move, 0, NULL
434: };
435: mmove_t infantry_move_duck = {FRAME_duck01, FRAME_duck05, infantry_frames_duck, infantry_run};
436:
437: // PMM - dodge code moved below so I can see the attack frames
438:
439:
440: void infantry_cock_gun (edict_t *self)
441: {
442: // pmm .. code that was here no longer needed
443: gi.sound (self, CHAN_WEAPON, sound_weapon_cock, 1, ATTN_NORM, 0);
444: }
445:
446: void infantry_fire (edict_t *self)
447: {
448: InfantryMachineGun (self);
449: if (level.time >= self->monsterinfo.pausetime)
450: self->monsterinfo.aiflags &= ~AI_HOLD_FRAME;
451: else
452: self->monsterinfo.aiflags |= AI_HOLD_FRAME;
453: }
454:
455: // this is here instead of cock_gun
456:
457: void infantry_fire_prep (edict_t *self)
458: {
459: int n;
460: n = (rand() & 15) + 3 + 1;
461: self->monsterinfo.pausetime = level.time + n*FRAMETIME;
462: }
463:
464: // pmm
465: // frames reordered, tweaked for new frames
466:
467: mframe_t infantry_frames_attack1 [] =
468: {
469: ai_charge, -3, NULL, //101
470: ai_charge, -2, NULL, //102
471: ai_charge, -1, infantry_fire_prep, //103
472: ai_charge, 5, infantry_fire, //104
473: ai_charge, 1, NULL, //105
474: ai_charge, -3, NULL, //106
475: ai_charge, -2, NULL, //107
476: ai_charge, 2, infantry_cock_gun, //108
477: ai_charge, 1, NULL, //109
478: ai_charge, 1, NULL, //110
479: ai_charge, -1, NULL, //111
480: ai_charge, 0, NULL, //112
481: ai_charge, -1, NULL, //113
482: ai_charge, -1, NULL, //114
483: ai_charge, 4, NULL //115
484: };
485: mmove_t infantry_move_attack1 = {FRAME_attak101, FRAME_attak115, infantry_frames_attack1, infantry_run};
486:
487:
488: void infantry_swing (edict_t *self)
489: {
490: gi.sound (self, CHAN_WEAPON, sound_punch_swing, 1, ATTN_NORM, 0);
491: }
492:
493: void infantry_smack (edict_t *self)
494: {
495: vec3_t aim;
496:
497: VectorSet (aim, MELEE_DISTANCE, 0, 0);
498: if (fire_hit (self, aim, (5 + (rand() % 5)), 50))
499: gi.sound (self, CHAN_WEAPON, sound_punch_hit, 1, ATTN_NORM, 0);
500: }
501:
502: mframe_t infantry_frames_attack2 [] =
503: {
504: ai_charge, 3, NULL,
505: ai_charge, 6, NULL,
506: ai_charge, 0, infantry_swing,
507: ai_charge, 8, NULL,
508: ai_charge, 5, NULL,
509: ai_charge, 8, infantry_smack,
510: ai_charge, 6, NULL,
511: ai_charge, 3, NULL,
512: };
513: mmove_t infantry_move_attack2 = {FRAME_attak201, FRAME_attak208, infantry_frames_attack2, infantry_run};
514:
515: void infantry_attack(edict_t *self)
516: {
517: monster_done_dodge (self);
518:
519: if (range (self, self->enemy) == RANGE_MELEE)
520: self->monsterinfo.currentmove = &infantry_move_attack2;
521: else
522: self->monsterinfo.currentmove = &infantry_move_attack1;
523: }
524:
525: //===========
526: //PGM
527: void infantry_jump_now (edict_t *self)
528: {
529: vec3_t forward,up;
530:
531: AngleVectors (self->s.angles, forward, NULL, up);
532: VectorMA(self->velocity, 100, forward, self->velocity);
533: VectorMA(self->velocity, 300, up, self->velocity);
534: }
535:
536: void infantry_jump2_now (edict_t *self)
537: {
538: vec3_t forward,up;
539:
540: AngleVectors (self->s.angles, forward, NULL, up);
541: VectorMA(self->velocity, 150, forward, self->velocity);
542: VectorMA(self->velocity, 400, up, self->velocity);
543: }
544:
545: void infantry_jump_wait_land (edict_t *self)
546: {
547: if(self->groundentity == NULL)
548: self->monsterinfo.nextframe = self->s.frame;
549: else
550: self->monsterinfo.nextframe = self->s.frame + 1;
551: }
552:
553: mframe_t infantry_frames_jump [] =
554: {
555: ai_move, 0, NULL,
556: ai_move, 0, NULL,
557: ai_move, 0, NULL,
558: ai_move, 0, infantry_jump_now,
559: ai_move, 0, NULL,
560: ai_move, 0, NULL,
561: ai_move, 0, NULL,
562: ai_move, 0, infantry_jump_wait_land,
563: ai_move, 0, NULL,
564: ai_move, 0, NULL
565: };
566: mmove_t infantry_move_jump = { FRAME_jump01, FRAME_jump10, infantry_frames_jump, infantry_run };
567:
568: mframe_t infantry_frames_jump2 [] =
569: {
570: ai_move, -8, NULL,
571: ai_move, -4, NULL,
572: ai_move, -4, NULL,
573: ai_move, 0, infantry_jump_now,
574: ai_move, 0, NULL,
575: ai_move, 0, NULL,
576: ai_move, 0, NULL,
577: ai_move, 0, infantry_jump_wait_land,
578: ai_move, 0, NULL,
579: ai_move, 0, NULL
580: };
581: mmove_t infantry_move_jump2 = { FRAME_jump01, FRAME_jump10, infantry_frames_jump2, infantry_run };
582:
583: void infantry_jump (edict_t *self)
584: {
585: if(!self->enemy)
586: return;
587:
588: monster_done_dodge(self);
589:
590: if(self->enemy->s.origin[2] > self->s.origin[2])
591: self->monsterinfo.currentmove = &infantry_move_jump2;
592: else
593: self->monsterinfo.currentmove = &infantry_move_jump;
594: }
595:
596: qboolean infantry_blocked (edict_t *self, float dist)
597: {
598: if(blocked_checkshot (self, 0.25 + (0.05 * skill->value) ))
599: return true;
600:
601: if(blocked_checkjump (self, dist, 192, 40))
602: {
603: infantry_jump(self);
604: return true;
605: }
606:
607: if(blocked_checkplat (self, dist))
608: return true;
609:
610: return false;
611: }
612: //PGM
613: //===========
614: /*
615: void infantry_dodge (edict_t *self, edict_t *attacker, float eta, trace_t *tr)
616: {
617: //===========
618: //PMM - rogue rewrite of gunner dodge code.
619: float r;
620: float height;
621: int shooting = 0;
622:
623: if (!self->enemy)
624: {
625: self->enemy = attacker;
626: FoundTarget (self);
627: }
628:
629: // PMM - don't bother if it's going to hit anyway; fix for weird in-your-face etas (I was
630: // seeing numbers like 13 and 14)
631: if ((eta < 0.1) || (eta > 5))
632: return;
633:
634: r = random();
635: if (r > (0.25*((skill->value)+1)))
636: return;
637:
638: if ((self->monsterinfo.currentmove == &infantry_move_attack1) ||
639: (self->monsterinfo.currentmove == &infantry_move_attack2))
640: {
641: shooting = 1;
642: }
643: if (self->monsterinfo.aiflags & AI_DODGING)
644: {
645: height = self->absmax[2];
646: }
647: else
648: {
649: height = self->absmax[2]-32-1; // the -1 is because the absmax is s.origin + maxs + 1
650: }
651:
652: // check to see if it makes sense to duck
653: if (tr->endpos[2] <= height)
654: {
655: vec3_t right,diff;
656:
657: if (shooting)
658: {
659: self->monsterinfo.attack_state = AS_SLIDING;
660: return;
661: }
662: AngleVectors (self->s.angles, NULL, right, NULL);
663: VectorSubtract (tr->endpos, self->s.origin, diff);
664: if (DotProduct (right, diff) < 0)
665: {
666: self->monsterinfo.lefty = 1;
667: }
668: // if it doesn't sense to duck, try to strafe away
669: monster_done_dodge (self);
670: self->monsterinfo.currentmove = &infantry_move_run;
671: self->monsterinfo.attack_state = AS_SLIDING;
672: return;
673: }
674:
675: if (skill->value == 0)
676: {
677: self->monsterinfo.currentmove = &infantry_move_duck;
678: // PMM - stupid dodge
679: self->monsterinfo.duck_wait_time = level.time + eta + 1;
680: self->monsterinfo.aiflags |= AI_DODGING;
681: return;
682: }
683:
684: if (!shooting)
685: {
686: self->monsterinfo.currentmove = &infantry_move_duck;
687: self->monsterinfo.duck_wait_time = level.time + eta + (0.1 * (3 - skill->value));
688: self->monsterinfo.aiflags |= AI_DODGING;
689: }
690: return;
691: //PMM
692: //===========
693: */
694:
695: void infantry_duck (edict_t *self, float eta)
696: {
697: // if we're jumping, don't dodge
698: if ((self->monsterinfo.currentmove == &infantry_move_jump) ||
699: (self->monsterinfo.currentmove == &infantry_move_jump2))
700: {
701: return;
702: }
703:
704: if ((self->monsterinfo.currentmove == &infantry_move_attack1) ||
705: (self->monsterinfo.currentmove == &infantry_move_attack2))
706: {
707: // if we're shooting, and not on easy, don't dodge
708: if (skill->value)
709: {
710: self->monsterinfo.aiflags &= ~AI_DUCKED;
711: return;
712: }
713: }
714:
715: if (skill->value == 0)
716: // PMM - stupid dodge
717: self->monsterinfo.duck_wait_time = level.time + eta + 1;
718: else
719: self->monsterinfo.duck_wait_time = level.time + eta + (0.1 * (3 - skill->value));
720:
721: // has to be done immediately otherwise he can get stuck
722: monster_duck_down(self);
723:
724: self->monsterinfo.nextframe = FRAME_duck01;
725: self->monsterinfo.currentmove = &infantry_move_duck;
726: return;
727: }
728:
729: void infantry_sidestep (edict_t *self)
730: {
731: // if we're jumping, don't dodge
732: if ((self->monsterinfo.currentmove == &infantry_move_jump) ||
733: (self->monsterinfo.currentmove == &infantry_move_jump2))
734: {
735: return;
736: }
737:
738: if ((self->monsterinfo.currentmove == &infantry_move_attack1) ||
739: (self->monsterinfo.currentmove == &infantry_move_attack2))
740: {
741: // if we're shooting, and not on easy, don't dodge
742: if (skill->value)
743: {
744: self->monsterinfo.aiflags &= ~AI_DODGING;
745: return;
746: }
747: }
748:
749: if (self->monsterinfo.currentmove != &infantry_move_run)
750: self->monsterinfo.currentmove = &infantry_move_run;
751: }
752:
753: /*QUAKED monster_infantry (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight
754: */
755: void SP_monster_infantry (edict_t *self)
756: {
757: if (deathmatch->value)
758: {
759: G_FreeEdict (self);
760: return;
761: }
762:
763: sound_pain1 = gi.soundindex ("infantry/infpain1.wav");
764: sound_pain2 = gi.soundindex ("infantry/infpain2.wav");
765: sound_die1 = gi.soundindex ("infantry/infdeth1.wav");
766: sound_die2 = gi.soundindex ("infantry/infdeth2.wav");
767:
768: sound_gunshot = gi.soundindex ("infantry/infatck1.wav");
769: sound_weapon_cock = gi.soundindex ("infantry/infatck3.wav");
770: sound_punch_swing = gi.soundindex ("infantry/infatck2.wav");
771: sound_punch_hit = gi.soundindex ("infantry/melee2.wav");
772:
773: sound_sight = gi.soundindex ("infantry/infsght1.wav");
774: sound_search = gi.soundindex ("infantry/infsrch1.wav");
775: sound_idle = gi.soundindex ("infantry/infidle1.wav");
776:
777:
778: self->movetype = MOVETYPE_STEP;
779: self->solid = SOLID_BBOX;
780: self->s.modelindex = gi.modelindex("models/monsters/infantry/tris.md2");
781: VectorSet (self->mins, -16, -16, -24);
782: VectorSet (self->maxs, 16, 16, 32);
783:
784: self->health = 100;
785: self->gib_health = -40;
786: self->mass = 200;
787:
788: self->pain = infantry_pain;
789: self->die = infantry_die;
790:
791: self->monsterinfo.stand = infantry_stand;
792: self->monsterinfo.walk = infantry_walk;
793: self->monsterinfo.run = infantry_run;
794: // pmm
795: self->monsterinfo.dodge = M_MonsterDodge;
796: self->monsterinfo.duck = infantry_duck;
797: self->monsterinfo.unduck = monster_duck_up;
798: self->monsterinfo.sidestep = infantry_sidestep;
799: // self->monsterinfo.dodge = infantry_dodge;
800: // pmm
801: self->monsterinfo.attack = infantry_attack;
802: self->monsterinfo.melee = NULL;
803: self->monsterinfo.sight = infantry_sight;
804: self->monsterinfo.idle = infantry_fidget;
805: self->monsterinfo.blocked = infantry_blocked;
806:
807: gi.linkentity (self);
808:
809: self->monsterinfo.currentmove = &infantry_move_stand;
810: self->monsterinfo.scale = MODEL_SCALE;
811:
812: walkmonster_start (self);
813: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.