|
|
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:
29: mframe_t infantry_frames_stand [] =
30: {
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: ai_stand, 0, NULL
53: };
54: mmove_t infantry_move_stand = {FRAME_stand50, FRAME_stand71, infantry_frames_stand, NULL};
55:
56: void infantry_stand (edict_t *self)
57: {
58: self->monsterinfo.currentmove = &infantry_move_stand;
59: }
60:
61:
62: mframe_t infantry_frames_fidget [] =
63: {
64: ai_stand, 1, NULL,
65: ai_stand, 0, NULL,
66: ai_stand, 1, NULL,
67: ai_stand, 3, NULL,
68: ai_stand, 6, NULL,
69: ai_stand, 3, NULL,
70: ai_stand, 0, NULL,
71: ai_stand, 0, NULL,
72: ai_stand, 0, NULL,
73: ai_stand, 0, NULL,
74: ai_stand, 1, NULL,
75: ai_stand, 0, NULL,
76: ai_stand, 0, NULL,
77: ai_stand, 0, NULL,
78: ai_stand, 0, NULL,
79: ai_stand, 1, NULL,
80: ai_stand, 0, NULL,
81: ai_stand, -1, NULL,
82: ai_stand, 0, NULL,
83: ai_stand, 0, NULL,
84: ai_stand, 1, NULL,
85: ai_stand, 0, NULL,
86: ai_stand, -2, NULL,
87: ai_stand, 1, NULL,
88: ai_stand, 1, NULL,
89: ai_stand, 1, NULL,
90: ai_stand, -1, NULL,
91: ai_stand, 0, NULL,
92: ai_stand, 0, NULL,
93: ai_stand, -1, NULL,
94: ai_stand, 0, NULL,
95: ai_stand, 0, NULL,
96: ai_stand, 0, NULL,
97: ai_stand, 0, NULL,
98: ai_stand, 0, NULL,
99: ai_stand, -1, NULL,
100: ai_stand, 0, NULL,
101: ai_stand, 0, NULL,
102: ai_stand, 1, NULL,
103: ai_stand, 0, NULL,
104: ai_stand, 0, NULL,
105: ai_stand, -1, NULL,
106: ai_stand, -1, NULL,
107: ai_stand, 0, NULL,
108: ai_stand, -3, NULL,
109: ai_stand, -2, NULL,
110: ai_stand, -3, NULL,
111: ai_stand, -3, NULL,
112: ai_stand, -2, NULL
113: };
114: mmove_t infantry_move_fidget = {FRAME_stand01, FRAME_stand49, infantry_frames_fidget, infantry_stand};
115:
116: void infantry_fidget (edict_t *self)
117: {
118: self->monsterinfo.currentmove = &infantry_move_fidget;
119: gi.sound (self, CHAN_VOICE, sound_idle, 1, ATTN_IDLE, 0);
120: }
121:
122: mframe_t infantry_frames_walk [] =
123: {
124: ai_walk, 5, NULL,
125: ai_walk, 4, NULL,
126: ai_walk, 4, NULL,
127: ai_walk, 5, NULL,
128: ai_walk, 4, NULL,
129: ai_walk, 5, NULL,
130: ai_walk, 6, NULL,
131: ai_walk, 4, NULL,
132: ai_walk, 4, NULL,
133: ai_walk, 4, NULL,
134: ai_walk, 4, NULL,
135: ai_walk, 5, NULL
136: };
137: mmove_t infantry_move_walk = {FRAME_walk03, FRAME_walk14, infantry_frames_walk, NULL};
138:
139: void infantry_walk (edict_t *self)
140: {
141: self->monsterinfo.currentmove = &infantry_move_walk;
142: }
143:
144: mframe_t infantry_frames_run [] =
145: {
146: ai_run, 10, NULL,
147: ai_run, 20, NULL,
148: ai_run, 5, NULL,
149: ai_run, 7, NULL,
150: ai_run, 30, NULL,
151: ai_run, 35, NULL,
152: ai_run, 2, NULL,
153: ai_run, 6, NULL
154: };
155: mmove_t infantry_move_run = {FRAME_run01, FRAME_run08, infantry_frames_run, NULL};
156:
157: void infantry_run (edict_t *self)
158: {
159: if (self->monsterinfo.aiflags & AI_STAND_GROUND)
160: self->monsterinfo.currentmove = &infantry_move_stand;
161: else
162: self->monsterinfo.currentmove = &infantry_move_run;
163: }
164:
165:
166: mframe_t infantry_frames_pain1 [] =
167: {
168: ai_move, -3, NULL,
169: ai_move, -2, NULL,
170: ai_move, -1, NULL,
171: ai_move, -2, NULL,
172: ai_move, -1, NULL,
173: ai_move, 1, NULL,
174: ai_move, -1, NULL,
175: ai_move, 1, NULL,
176: ai_move, 6, NULL,
177: ai_move, 2, NULL
178: };
179: mmove_t infantry_move_pain1 = {FRAME_pain101, FRAME_pain110, infantry_frames_pain1, infantry_run};
180:
181: mframe_t infantry_frames_pain2 [] =
182: {
183: ai_move, -3, NULL,
184: ai_move, -3, NULL,
185: ai_move, 0, NULL,
186: ai_move, -1, NULL,
187: ai_move, -2, NULL,
188: ai_move, 0, NULL,
189: ai_move, 0, NULL,
190: ai_move, 2, NULL,
191: ai_move, 5, NULL,
192: ai_move, 2, NULL
193: };
194: mmove_t infantry_move_pain2 = {FRAME_pain201, FRAME_pain210, infantry_frames_pain2, infantry_run};
195:
196: void infantry_pain (edict_t *self, edict_t *other, float kick, int damage)
197: {
198: int n;
199:
200: if (self->health < (self->max_health / 2))
201: self->s.skinnum = 1;
202:
203: if (level.time < self->pain_debounce_time)
204: return;
205:
206: self->pain_debounce_time = level.time + 3;
207:
208: if (skill->value == 3)
209: return; // no pain anims in nightmare
210:
211: n = rand() % 2;
212: if (n == 0)
213: {
214: self->monsterinfo.currentmove = &infantry_move_pain1;
215: gi.sound (self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0);
216: }
217: else
218: {
219: self->monsterinfo.currentmove = &infantry_move_pain2;
220: gi.sound (self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0);
221: }
222: }
223:
224:
225: vec3_t aimangles[] =
226: {
227: 0.0, 5.0, 0.0,
228: 10.0, 15.0, 0.0,
229: 20.0, 25.0, 0.0,
230: 25.0, 35.0, 0.0,
231: 30.0, 40.0, 0.0,
232: 30.0, 45.0, 0.0,
233: 25.0, 50.0, 0.0,
234: 20.0, 40.0, 0.0,
235: 15.0, 35.0, 0.0,
236: 40.0, 35.0, 0.0,
237: 70.0, 35.0, 0.0,
238: 90.0, 35.0, 0.0
239: };
240:
241: void InfantryMachineGun (edict_t *self)
242: {
243: vec3_t start, target;
244: vec3_t forward, right;
245: vec3_t vec;
246: int flash_number;
247:
248: if (self->s.frame == FRAME_attak111)
249: {
250: flash_number = MZ2_INFANTRY_MACHINEGUN_1;
251: AngleVectors (self->s.angles, forward, right, NULL);
252: G_ProjectSource (self->s.origin, monster_flash_offset[flash_number], forward, right, start);
253:
254: if (self->enemy)
255: {
256: VectorMA (self->enemy->s.origin, -0.2, self->enemy->velocity, target);
257: target[2] += self->enemy->viewheight;
258: VectorSubtract (target, start, forward);
259: VectorNormalize (forward);
260: }
261: else
262: {
263: AngleVectors (self->s.angles, forward, right, NULL);
264: }
265: }
266: else
267: {
268: flash_number = MZ2_INFANTRY_MACHINEGUN_2 + (self->s.frame - FRAME_death211);
269:
270: AngleVectors (self->s.angles, forward, right, NULL);
271: G_ProjectSource (self->s.origin, monster_flash_offset[flash_number], forward, right, start);
272:
273: VectorSubtract (self->s.angles, aimangles[flash_number-MZ2_INFANTRY_MACHINEGUN_2], vec);
274: AngleVectors (vec, forward, NULL, NULL);
275: }
276:
277: monster_fire_bullet (self, start, forward, 3, 4, DEFAULT_BULLET_HSPREAD, DEFAULT_BULLET_VSPREAD, flash_number);
278: }
279:
280: void infantry_sight (edict_t *self, edict_t *other)
281: {
282: gi.sound (self, CHAN_BODY, sound_sight, 1, ATTN_NORM, 0);
283: }
284:
285: void infantry_dead (edict_t *self)
286: {
287: VectorSet (self->mins, -16, -16, -24);
288: VectorSet (self->maxs, 16, 16, -8);
289: self->movetype = MOVETYPE_TOSS;
290: self->svflags |= SVF_DEADMONSTER;
291: gi.linkentity (self);
292:
293: M_FlyCheck (self);
294: }
295:
296: mframe_t infantry_frames_death1 [] =
297: {
298: ai_move, -4, NULL,
299: ai_move, 0, NULL,
300: ai_move, 0, NULL,
301: ai_move, -1, NULL,
302: ai_move, -4, NULL,
303: ai_move, 0, NULL,
304: ai_move, 0, NULL,
305: ai_move, 0, NULL,
306: ai_move, -1, NULL,
307: ai_move, 3, NULL,
308: ai_move, 1, NULL,
309: ai_move, 1, NULL,
310: ai_move, -2, NULL,
311: ai_move, 2, NULL,
312: ai_move, 2, NULL,
313: ai_move, 9, NULL,
314: ai_move, 9, NULL,
315: ai_move, 5, NULL,
316: ai_move, -3, NULL,
317: ai_move, -3, NULL
318: };
319: mmove_t infantry_move_death1 = {FRAME_death101, FRAME_death120, infantry_frames_death1, infantry_dead};
320:
321: // Off with his head
322: mframe_t infantry_frames_death2 [] =
323: {
324: ai_move, 0, NULL,
325: ai_move, 1, NULL,
326: ai_move, 5, NULL,
327: ai_move, -1, NULL,
328: ai_move, 0, NULL,
329: ai_move, 1, NULL,
330: ai_move, 1, NULL,
331: ai_move, 4, NULL,
332: ai_move, 3, NULL,
333: ai_move, 0, NULL,
334: ai_move, -2, InfantryMachineGun,
335: ai_move, -2, InfantryMachineGun,
336: ai_move, -3, InfantryMachineGun,
337: ai_move, -1, InfantryMachineGun,
338: ai_move, -2, InfantryMachineGun,
339: ai_move, 0, InfantryMachineGun,
340: ai_move, 2, InfantryMachineGun,
341: ai_move, 2, InfantryMachineGun,
342: ai_move, 3, InfantryMachineGun,
343: ai_move, -10, InfantryMachineGun,
344: ai_move, -7, InfantryMachineGun,
345: ai_move, -8, InfantryMachineGun,
346: ai_move, -6, NULL,
347: ai_move, 4, NULL,
348: ai_move, 0, NULL
349: };
350: mmove_t infantry_move_death2 = {FRAME_death201, FRAME_death225, infantry_frames_death2, infantry_dead};
351:
352: mframe_t infantry_frames_death3 [] =
353: {
354: ai_move, 0, NULL,
355: ai_move, 0, NULL,
356: ai_move, 0, NULL,
357: ai_move, -6, NULL,
358: ai_move, -11, NULL,
359: ai_move, -3, NULL,
360: ai_move, -11, NULL,
361: ai_move, 0, NULL,
362: ai_move, 0, NULL
363: };
364: mmove_t infantry_move_death3 = {FRAME_death301, FRAME_death309, infantry_frames_death3, infantry_dead};
365:
366:
367: void infantry_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
368: {
369: int n;
370:
371: // check for gib
372: if (self->health <= self->gib_health)
373: {
374: gi.sound (self, CHAN_VOICE, gi.soundindex ("misc/udeath.wav"), 1, ATTN_NORM, 0);
375: for (n= 0; n < 2; n++)
376: ThrowGib (self, "models/objects/gibs/bone/tris.md2", damage, GIB_ORGANIC);
377: for (n= 0; n < 4; n++)
378: ThrowGib (self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC);
379: ThrowHead (self, "models/objects/gibs/head2/tris.md2", damage, GIB_ORGANIC);
380: self->deadflag = DEAD_DEAD;
381: return;
382: }
383:
384: if (self->deadflag == DEAD_DEAD)
385: return;
386:
387: // regular death
388: self->deadflag = DEAD_DEAD;
389: self->takedamage = DAMAGE_YES;
390:
391: n = rand() % 3;
392: if (n == 0)
393: {
394: self->monsterinfo.currentmove = &infantry_move_death1;
395: gi.sound (self, CHAN_VOICE, sound_die2, 1, ATTN_NORM, 0);
396: }
397: else if (n == 1)
398: {
399: self->monsterinfo.currentmove = &infantry_move_death2;
400: gi.sound (self, CHAN_VOICE, sound_die1, 1, ATTN_NORM, 0);
401: }
402: else
403: {
404: self->monsterinfo.currentmove = &infantry_move_death3;
405: gi.sound (self, CHAN_VOICE, sound_die2, 1, ATTN_NORM, 0);
406: }
407: }
408:
409:
410: void infantry_duck_down (edict_t *self)
411: {
412: if (self->monsterinfo.aiflags & AI_DUCKED)
413: return;
414: self->monsterinfo.aiflags |= AI_DUCKED;
415: self->maxs[2] -= 32;
416: self->takedamage = DAMAGE_YES;
417: self->monsterinfo.pausetime = level.time + 1;
418: gi.linkentity (self);
419: }
420:
421: void infantry_duck_hold (edict_t *self)
422: {
423: if (level.time >= self->monsterinfo.pausetime)
424: self->monsterinfo.aiflags &= ~AI_HOLD_FRAME;
425: else
426: self->monsterinfo.aiflags |= AI_HOLD_FRAME;
427: }
428:
429: void infantry_duck_up (edict_t *self)
430: {
431: self->monsterinfo.aiflags &= ~AI_DUCKED;
432: self->maxs[2] += 32;
433: self->takedamage = DAMAGE_AIM;
434: gi.linkentity (self);
435: }
436:
437: mframe_t infantry_frames_duck [] =
438: {
439: ai_move, -2, infantry_duck_down,
440: ai_move, -5, infantry_duck_hold,
441: ai_move, 3, NULL,
442: ai_move, 4, infantry_duck_up,
443: ai_move, 0, NULL
444: };
445: mmove_t infantry_move_duck = {FRAME_duck01, FRAME_duck05, infantry_frames_duck, infantry_run};
446:
447: void infantry_dodge (edict_t *self, edict_t *attacker, float eta)
448: {
449: if (random() > 0.25)
450: return;
451:
452: if (!self->enemy)
453: self->enemy = attacker;
454:
455: self->monsterinfo.currentmove = &infantry_move_duck;
456: }
457:
458:
459: void infantry_cock_gun (edict_t *self)
460: {
461: int n;
462:
463: gi.sound (self, CHAN_WEAPON, sound_weapon_cock, 1, ATTN_NORM, 0);
464: n = (rand() & 15) + 3 + 7;
465: self->monsterinfo.pausetime = level.time + n * FRAMETIME;
466: }
467:
468: void infantry_fire (edict_t *self)
469: {
470: InfantryMachineGun (self);
471:
472: if (level.time >= self->monsterinfo.pausetime)
473: self->monsterinfo.aiflags &= ~AI_HOLD_FRAME;
474: else
475: self->monsterinfo.aiflags |= AI_HOLD_FRAME;
476: }
477:
478: mframe_t infantry_frames_attack1 [] =
479: {
480: ai_charge, 4, NULL,
481: ai_charge, -1, NULL,
482: ai_charge, -1, NULL,
483: ai_charge, 0, infantry_cock_gun,
484: ai_charge, -1, NULL,
485: ai_charge, 1, NULL,
486: ai_charge, 1, NULL,
487: ai_charge, 2, NULL,
488: ai_charge, -2, NULL,
489: ai_charge, -3, NULL,
490: ai_charge, 1, infantry_fire,
491: ai_charge, 5, NULL,
492: ai_charge, -1, NULL,
493: ai_charge, -2, NULL,
494: ai_charge, -3, NULL
495: };
496: mmove_t infantry_move_attack1 = {FRAME_attak101, FRAME_attak115, infantry_frames_attack1, infantry_run};
497:
498:
499: void infantry_swing (edict_t *self)
500: {
501: gi.sound (self, CHAN_WEAPON, sound_punch_swing, 1, ATTN_NORM, 0);
502: }
503:
504: void infantry_smack (edict_t *self)
505: {
506: vec3_t aim;
507:
508: VectorSet (aim, MELEE_DISTANCE, 0, 0);
509: if (fire_hit (self, aim, (5 + (rand() % 5)), 50))
510: gi.sound (self, CHAN_WEAPON, sound_punch_hit, 1, ATTN_NORM, 0);
511: }
512:
513: mframe_t infantry_frames_attack2 [] =
514: {
515: ai_charge, 3, NULL,
516: ai_charge, 6, NULL,
517: ai_charge, 0, infantry_swing,
518: ai_charge, 8, NULL,
519: ai_charge, 5, NULL,
520: ai_charge, 8, infantry_smack,
521: ai_charge, 6, NULL,
522: ai_charge, 3, NULL,
523: };
524: mmove_t infantry_move_attack2 = {FRAME_attak201, FRAME_attak208, infantry_frames_attack2, infantry_run};
525:
526: void infantry_attack(edict_t *self)
527: {
528: if (range (self, self->enemy) == RANGE_MELEE)
529: self->monsterinfo.currentmove = &infantry_move_attack2;
530: else
531: self->monsterinfo.currentmove = &infantry_move_attack1;
532: }
533:
534:
535: /*QUAKED monster_infantry (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight
536: */
537: void SP_monster_infantry (edict_t *self)
538: {
539: if (deathmatch->value)
540: {
541: G_FreeEdict (self);
542: return;
543: }
544:
545: sound_pain1 = gi.soundindex ("infantry/infpain1.wav");
546: sound_pain2 = gi.soundindex ("infantry/infpain2.wav");
547: sound_die1 = gi.soundindex ("infantry/infdeth1.wav");
548: sound_die2 = gi.soundindex ("infantry/infdeth2.wav");
549:
550: sound_gunshot = gi.soundindex ("infantry/infatck1.wav");
551: sound_weapon_cock = gi.soundindex ("infantry/infatck3.wav");
552: sound_punch_swing = gi.soundindex ("infantry/infatck2.wav");
553: sound_punch_hit = gi.soundindex ("infantry/melee2.wav");
554:
555: sound_sight = gi.soundindex ("infantry/infsght1.wav");
556: sound_search = gi.soundindex ("infantry/infsrch1.wav");
557: sound_idle = gi.soundindex ("infantry/infidle1.wav");
558:
559:
560: self->movetype = MOVETYPE_STEP;
561: self->solid = SOLID_BBOX;
562: self->s.modelindex = gi.modelindex("models/monsters/infantry/tris.md2");
563: VectorSet (self->mins, -16, -16, -24);
564: VectorSet (self->maxs, 16, 16, 32);
565:
566: self->health = 100;
567: self->gib_health = -40;
568: self->mass = 200;
569:
570: self->pain = infantry_pain;
571: self->die = infantry_die;
572:
573: self->monsterinfo.stand = infantry_stand;
574: self->monsterinfo.walk = infantry_walk;
575: self->monsterinfo.run = infantry_run;
576: self->monsterinfo.dodge = infantry_dodge;
577: self->monsterinfo.attack = infantry_attack;
578: self->monsterinfo.melee = NULL;
579: self->monsterinfo.sight = infantry_sight;
580: self->monsterinfo.idle = infantry_fidget;
581:
582: gi.linkentity (self);
583:
584: self->monsterinfo.currentmove = &infantry_move_stand;
585: self->monsterinfo.scale = MODEL_SCALE;
586:
587: walkmonster_start (self);
588: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.