|
|
1.1 root 1: /*
2: ==============================================================================
3:
4: flyer
5:
6: ==============================================================================
7: */
8:
9: #include "g_local.h"
10: #include "m_flyer.h"
11:
12: qboolean visible (edict_t *self, edict_t *other);
13:
14: static int nextmove; // Used for start/stop frames
15:
16: static int sound_sight;
17: static int sound_idle;
18: static int sound_pain1;
19: static int sound_pain2;
20: static int sound_slash;
21: static int sound_sproing;
22: static int sound_die;
23:
24:
25: void flyer_check_melee(edict_t *self);
26: void flyer_loop_melee (edict_t *self);
27: void flyer_melee (edict_t *self);
28: void flyer_setstart (edict_t *self);
29: void flyer_stand (edict_t *self);
30: void flyer_nextmove (edict_t *self);
31:
32:
33: void flyer_sight (edict_t *self, edict_t *other)
34: {
35: gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0);
36: }
37:
38: void flyer_idle (edict_t *self)
39: {
40: gi.sound (self, CHAN_VOICE, sound_idle, 1, ATTN_IDLE, 0);
41: }
42:
43: void flyer_pop_blades (edict_t *self)
44: {
45: gi.sound (self, CHAN_VOICE, sound_sproing, 1, ATTN_NORM, 0);
46: }
47:
48:
49: mframe_t flyer_frames_stand [] =
50: {
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: ai_stand, 0, NULL,
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: ai_stand, 0, NULL,
68: ai_stand, 0, NULL,
69: ai_stand, 0, NULL,
70: ai_stand, 0, NULL,
71: ai_stand, 0, NULL,
72: ai_stand, 0, NULL,
73: ai_stand, 0, NULL,
74: ai_stand, 0, NULL,
75: ai_stand, 0, NULL,
76: ai_stand, 0, NULL,
77: ai_stand, 0, NULL,
78: ai_stand, 0, NULL,
79: ai_stand, 0, NULL,
80: ai_stand, 0, NULL,
81: ai_stand, 0, NULL,
82: ai_stand, 0, NULL,
83: ai_stand, 0, NULL,
84: ai_stand, 0, NULL,
85: ai_stand, 0, NULL,
86: ai_stand, 0, NULL,
87: ai_stand, 0, NULL,
88: ai_stand, 0, NULL,
89: ai_stand, 0, NULL,
90: ai_stand, 0, NULL,
91: ai_stand, 0, NULL,
92: ai_stand, 0, NULL,
93: ai_stand, 0, NULL,
94: ai_stand, 0, NULL,
95: ai_stand, 0, NULL
96: };
97: mmove_t flyer_move_stand = {FRAME_stand01, FRAME_stand45, flyer_frames_stand, NULL};
98:
99:
100: mframe_t flyer_frames_walk [] =
101: {
102: ai_walk, 5, NULL,
103: ai_walk, 5, NULL,
104: ai_walk, 5, NULL,
105: ai_walk, 5, NULL,
106: ai_walk, 5, NULL,
107: ai_walk, 5, NULL,
108: ai_walk, 5, NULL,
109: ai_walk, 5, NULL,
110: ai_walk, 5, NULL,
111: ai_walk, 5, NULL,
112: ai_walk, 5, NULL,
113: ai_walk, 5, NULL,
114: ai_walk, 5, NULL,
115: ai_walk, 5, NULL,
116: ai_walk, 5, NULL,
117: ai_walk, 5, NULL,
118: ai_walk, 5, NULL,
119: ai_walk, 5, NULL,
120: ai_walk, 5, NULL,
121: ai_walk, 5, NULL,
122: ai_walk, 5, NULL,
123: ai_walk, 5, NULL,
124: ai_walk, 5, NULL,
125: ai_walk, 5, NULL,
126: ai_walk, 5, NULL,
127: ai_walk, 5, NULL,
128: ai_walk, 5, NULL,
129: ai_walk, 5, NULL,
130: ai_walk, 5, NULL,
131: ai_walk, 5, NULL,
132: ai_walk, 5, NULL,
133: ai_walk, 5, NULL,
134: ai_walk, 5, NULL,
135: ai_walk, 5, NULL,
136: ai_walk, 5, NULL,
137: ai_walk, 5, NULL,
138: ai_walk, 5, NULL,
139: ai_walk, 5, NULL,
140: ai_walk, 5, NULL,
141: ai_walk, 5, NULL,
142: ai_walk, 5, NULL,
143: ai_walk, 5, NULL,
144: ai_walk, 5, NULL,
145: ai_walk, 5, NULL,
146: ai_walk, 5, NULL
147: };
148: mmove_t flyer_move_walk = {FRAME_stand01, FRAME_stand45, flyer_frames_walk, NULL};
149:
150: mframe_t flyer_frames_run [] =
151: {
152: ai_run, 10, NULL,
153: ai_run, 10, NULL,
154: ai_run, 10, NULL,
155: ai_run, 10, NULL,
156: ai_run, 10, NULL,
157: ai_run, 10, NULL,
158: ai_run, 10, NULL,
159: ai_run, 10, NULL,
160: ai_run, 10, NULL,
161: ai_run, 10, NULL,
162: ai_run, 10, NULL,
163: ai_run, 10, NULL,
164: ai_run, 10, NULL,
165: ai_run, 10, NULL,
166: ai_run, 10, NULL,
167: ai_run, 10, NULL,
168: ai_run, 10, NULL,
169: ai_run, 10, NULL,
170: ai_run, 10, NULL,
171: ai_run, 10, NULL,
172: ai_run, 10, NULL,
173: ai_run, 10, NULL,
174: ai_run, 10, NULL,
175: ai_run, 10, NULL,
176: ai_run, 10, NULL,
177: ai_run, 10, NULL,
178: ai_run, 10, NULL,
179: ai_run, 10, NULL,
180: ai_run, 10, NULL,
181: ai_run, 10, NULL,
182: ai_run, 10, NULL,
183: ai_run, 10, NULL,
184: ai_run, 10, NULL,
185: ai_run, 10, NULL,
186: ai_run, 10, NULL,
187: ai_run, 10, NULL,
188: ai_run, 10, NULL,
189: ai_run, 10, NULL,
190: ai_run, 10, NULL,
191: ai_run, 10, NULL,
192: ai_run, 10, NULL,
193: ai_run, 10, NULL,
194: ai_run, 10, NULL,
195: ai_run, 10, NULL,
196: ai_run, 10, NULL
197: };
198: mmove_t flyer_move_run = {FRAME_stand01, FRAME_stand45, flyer_frames_run, NULL};
199:
200: void flyer_run (edict_t *self)
201: {
202: if (self->monsterinfo.aiflags & AI_STAND_GROUND)
203: self->monsterinfo.currentmove = &flyer_move_stand;
204: else
205: self->monsterinfo.currentmove = &flyer_move_run;
206: }
207:
208: void flyer_walk (edict_t *self)
209: {
210: self->monsterinfo.currentmove = &flyer_move_walk;
211: }
212:
213: void flyer_stand (edict_t *self)
214: {
215: self->monsterinfo.currentmove = &flyer_move_stand;
216: }
217:
218: mframe_t flyer_frames_start [] =
219: {
220: ai_move, 0, NULL,
221: ai_move, 0, NULL,
222: ai_move, 0, NULL,
223: ai_move, 0, NULL,
224: ai_move, 0, NULL,
225: ai_move, 0, flyer_nextmove
226: };
227: mmove_t flyer_move_start = {FRAME_start01, FRAME_start06, flyer_frames_start, NULL};
228:
229: mframe_t flyer_frames_stop [] =
230: {
231: ai_move, 0, NULL,
232: ai_move, 0, NULL,
233: ai_move, 0, NULL,
234: ai_move, 0, NULL,
235: ai_move, 0, NULL,
236: ai_move, 0, NULL,
237: ai_move, 0, flyer_nextmove
238: };
239: mmove_t flyer_move_stop = {FRAME_stop01, FRAME_stop07, flyer_frames_stop, NULL};
240:
241: void flyer_stop (edict_t *self)
242: {
243: self->monsterinfo.currentmove = &flyer_move_stop;
244: }
245:
246: void flyer_start (edict_t *self)
247: {
248: self->monsterinfo.currentmove = &flyer_move_start;
249: }
250:
251:
252: mframe_t flyer_frames_rollright [] =
253: {
254: ai_move, 0, NULL,
255: ai_move, 0, NULL,
256: ai_move, 0, NULL,
257: ai_move, 0, NULL,
258: ai_move, 0, NULL,
259: ai_move, 0, NULL,
260: ai_move, 0, NULL,
261: ai_move, 0, NULL,
262: ai_move, 0, NULL
263: };
264: mmove_t flyer_move_rollright = {FRAME_rollr01, FRAME_rollr09, flyer_frames_rollright, NULL};
265:
266: mframe_t flyer_frames_rollleft [] =
267: {
268: ai_move, 0, NULL,
269: ai_move, 0, NULL,
270: ai_move, 0, NULL,
271: ai_move, 0, NULL,
272: ai_move, 0, NULL,
273: ai_move, 0, NULL,
274: ai_move, 0, NULL,
275: ai_move, 0, NULL,
276: ai_move, 0, NULL
277: };
278: mmove_t flyer_move_rollleft = {FRAME_rollf01, FRAME_rollf09, flyer_frames_rollleft, NULL};
279:
280: mframe_t flyer_frames_pain3 [] =
281: {
282: ai_move, 0, NULL,
283: ai_move, 0, NULL,
284: ai_move, 0, NULL,
285: ai_move, 0, NULL
286: };
287: mmove_t flyer_move_pain3 = {FRAME_pain301, FRAME_pain304, flyer_frames_pain3, flyer_run};
288:
289: mframe_t flyer_frames_pain2 [] =
290: {
291: ai_move, 0, NULL,
292: ai_move, 0, NULL,
293: ai_move, 0, NULL,
294: ai_move, 0, NULL
295: };
296: mmove_t flyer_move_pain2 = {FRAME_pain201, FRAME_pain204, flyer_frames_pain2, flyer_run};
297:
298: mframe_t flyer_frames_pain1 [] =
299: {
300: ai_move, 0, NULL,
301: ai_move, 0, NULL,
302: ai_move, 0, NULL,
303: ai_move, 0, NULL,
304: ai_move, 0, NULL,
305: ai_move, 0, NULL,
306: ai_move, 0, NULL,
307: ai_move, 0, NULL,
308: ai_move, 0, NULL
309: };
310: mmove_t flyer_move_pain1 = {FRAME_pain101, FRAME_pain109, flyer_frames_pain1, flyer_run};
311:
312: mframe_t flyer_frames_defense [] =
313: {
314: ai_move, 0, NULL,
315: ai_move, 0, NULL,
316: ai_move, 0, NULL, // Hold this frame
317: ai_move, 0, NULL,
318: ai_move, 0, NULL,
319: ai_move, 0, NULL
320: };
321: mmove_t flyer_move_defense = {FRAME_defens01, FRAME_defens06, flyer_frames_defense, NULL};
322:
323: mframe_t flyer_frames_bankright [] =
324: {
325: ai_move, 0, NULL,
326: ai_move, 0, NULL,
327: ai_move, 0, NULL,
328: ai_move, 0, NULL,
329: ai_move, 0, NULL,
330: ai_move, 0, NULL,
331: ai_move, 0, NULL
332: };
333: mmove_t flyer_move_bankright = {FRAME_bankr01, FRAME_bankr07, flyer_frames_bankright, NULL};
334:
335: mframe_t flyer_frames_bankleft [] =
336: {
337: ai_move, 0, NULL,
338: ai_move, 0, NULL,
339: ai_move, 0, NULL,
340: ai_move, 0, NULL,
341: ai_move, 0, NULL,
342: ai_move, 0, NULL,
343: ai_move, 0, NULL
344: };
345: mmove_t flyer_move_bankleft = {FRAME_bankl01, FRAME_bankl07, flyer_frames_bankleft, NULL};
346:
347:
348: void flyer_fire (edict_t *self, int flash_number)
349: {
350: vec3_t start;
351: vec3_t forward, right;
352: vec3_t end;
353: vec3_t dir;
354: int effect;
355:
356: if ((self->s.frame == FRAME_attak204) || (self->s.frame == FRAME_attak207) || (self->s.frame == FRAME_attak210))
357: effect = EF_HYPERBLASTER;
358: else
359: effect = 0;
360: AngleVectors (self->s.angles, forward, right, NULL);
361: G_ProjectSource (self->s.origin, monster_flash_offset[flash_number], forward, right, start);
362:
363: VectorCopy (self->enemy->s.origin, end);
364: end[2] += self->enemy->viewheight;
365: VectorSubtract (end, start, dir);
366:
367: monster_fire_blaster (self, start, dir, 1, 1000, flash_number, effect);
368: }
369:
370: void flyer_fireleft (edict_t *self)
371: {
372: flyer_fire (self, MZ2_FLYER_BLASTER_1);
373: }
374:
375: void flyer_fireright (edict_t *self)
376: {
377: flyer_fire (self, MZ2_FLYER_BLASTER_2);
378: }
379:
380:
381: mframe_t flyer_frames_attack2 [] =
382: {
383: ai_charge, 0, NULL,
384: ai_charge, 0, NULL,
385: ai_charge, 0, NULL,
386: ai_charge, -10, flyer_fireleft, // left gun
387: ai_charge, -10, flyer_fireright, // right gun
388: ai_charge, -10, flyer_fireleft, // left gun
389: ai_charge, -10, flyer_fireright, // right gun
390: ai_charge, -10, flyer_fireleft, // left gun
391: ai_charge, -10, flyer_fireright, // right gun
392: ai_charge, -10, flyer_fireleft, // left gun
393: ai_charge, -10, flyer_fireright, // right gun
394: ai_charge, 0, NULL,
395: ai_charge, 0, NULL,
396: ai_charge, 0, NULL,
397: ai_charge, 0, NULL,
398: ai_charge, 0, NULL,
399: ai_charge, 0, NULL
400: };
401: mmove_t flyer_move_attack2 = {FRAME_attak201, FRAME_attak217, flyer_frames_attack2, flyer_run};
402:
403:
404: void flyer_slash_left (edict_t *self)
405: {
406: vec3_t aim;
407:
408: VectorSet (aim, MELEE_DISTANCE, self->mins[0], 0);
409: fire_hit (self, aim, 5, 0);
410: gi.sound (self, CHAN_WEAPON, sound_slash, 1, ATTN_NORM, 0);
411: }
412:
413: void flyer_slash_right (edict_t *self)
414: {
415: vec3_t aim;
416:
417: VectorSet (aim, MELEE_DISTANCE, self->maxs[0], 0);
418: fire_hit (self, aim, 5, 0);
419: gi.sound (self, CHAN_WEAPON, sound_slash, 1, ATTN_NORM, 0);
420: }
421:
422: mframe_t flyer_frames_start_melee [] =
423: {
424: ai_charge, 0, flyer_pop_blades,
425: ai_charge, 0, NULL,
426: ai_charge, 0, NULL,
427: ai_charge, 0, NULL,
428: ai_charge, 0, NULL,
429: ai_charge, 0, NULL
430: };
431: mmove_t flyer_move_start_melee = {FRAME_attak101, FRAME_attak106, flyer_frames_start_melee, flyer_loop_melee};
432:
433: mframe_t flyer_frames_end_melee [] =
434: {
435: ai_charge, 0, NULL,
436: ai_charge, 0, NULL,
437: ai_charge, 0, NULL
438: };
439: mmove_t flyer_move_end_melee = {FRAME_attak119, FRAME_attak121, flyer_frames_end_melee, flyer_run};
440:
441:
442: mframe_t flyer_frames_loop_melee [] =
443: {
444: ai_charge, 0, NULL, // Loop Start
445: ai_charge, 0, NULL,
446: ai_charge, 0, flyer_slash_left, // Left Wing Strike
447: ai_charge, 0, NULL,
448: ai_charge, 0, NULL,
449: ai_charge, 0, NULL,
450: ai_charge, 0, NULL,
451: ai_charge, 0, flyer_slash_right, // Right Wing Strike
452: ai_charge, 0, NULL,
453: ai_charge, 0, NULL,
454: ai_charge, 0, NULL,
455: ai_charge, 0, NULL // Loop Ends
456:
457: };
458: mmove_t flyer_move_loop_melee = {FRAME_attak107, FRAME_attak118, flyer_frames_loop_melee, flyer_check_melee};
459:
460: void flyer_loop_melee (edict_t *self)
461: {
462: /* if (random() <= 0.5)
463: self->monsterinfo.currentmove = &flyer_move_attack1;
464: else */
465: self->monsterinfo.currentmove = &flyer_move_loop_melee;
466: }
467:
468:
469:
470: void flyer_attack (edict_t *self)
471: {
472: /* if (random() <= 0.5)
473: self->monsterinfo.currentmove = &flyer_move_attack1;
474: else */
475: self->monsterinfo.currentmove = &flyer_move_attack2;
476: }
477:
478: void flyer_setstart (edict_t *self)
479: {
480: nextmove = ACTION_run;
481: self->monsterinfo.currentmove = &flyer_move_start;
482: }
483:
484: void flyer_nextmove (edict_t *self)
485: {
486: if (nextmove == ACTION_attack1)
487: self->monsterinfo.currentmove = &flyer_move_start_melee;
488: else if (nextmove == ACTION_attack2)
489: self->monsterinfo.currentmove = &flyer_move_attack2;
490: else if (nextmove == ACTION_run)
491: self->monsterinfo.currentmove = &flyer_move_run;
492: }
493:
494: void flyer_melee (edict_t *self)
495: {
496: // flyer.nextmove = ACTION_attack1;
497: // self->monsterinfo.currentmove = &flyer_move_stop;
498: self->monsterinfo.currentmove = &flyer_move_start_melee;
499: }
500:
501: void flyer_check_melee(edict_t *self)
502: {
503: if (range (self, self->enemy) == RANGE_MELEE)
504: if (random() <= 0.8)
505: self->monsterinfo.currentmove = &flyer_move_loop_melee;
506: else
507: self->monsterinfo.currentmove = &flyer_move_end_melee;
508: else
509: self->monsterinfo.currentmove = &flyer_move_end_melee;
510: }
511:
512: void flyer_pain (edict_t *self, edict_t *other, float kick, int damage)
513: {
514: int n;
515:
516: if (self->health < (self->max_health / 2))
517: self->s.skinnum = 1;
518:
519: if (level.time < self->pain_debounce_time)
520: return;
521:
522: self->pain_debounce_time = level.time + 3;
523: if (skill->value == 3)
524: return; // no pain anims in nightmare
525:
526: n = rand() % 3;
527: if (n == 0)
528: {
529: gi.sound (self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0);
530: self->monsterinfo.currentmove = &flyer_move_pain1;
531: }
532: else if (n == 1)
533: {
534: gi.sound (self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0);
535: self->monsterinfo.currentmove = &flyer_move_pain2;
536: }
537: else
538: {
539: gi.sound (self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0);
540: self->monsterinfo.currentmove = &flyer_move_pain3;
541: }
542: }
543:
544:
545: void flyer_die(edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
546: {
547: gi.sound (self, CHAN_VOICE, sound_die, 1, ATTN_NORM, 0);
548: BecomeExplosion1(self);
549: }
550:
551:
552: /*QUAKED monster_flyer (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight
553: */
554: void SP_monster_flyer (edict_t *self)
555: {
556: if (deathmatch->value)
557: {
558: G_FreeEdict (self);
559: return;
560: }
561:
562: // fix a map bug in jail5.bsp
563: if (!Q_stricmp(level.mapname, "jail5") && (self->s.origin[2] == -104))
564: {
565: self->targetname = self->target;
566: self->target = NULL;
567: }
568:
569: sound_sight = gi.soundindex ("flyer/flysght1.wav");
570: sound_idle = gi.soundindex ("flyer/flysrch1.wav");
571: sound_pain1 = gi.soundindex ("flyer/flypain1.wav");
572: sound_pain2 = gi.soundindex ("flyer/flypain2.wav");
573: sound_slash = gi.soundindex ("flyer/flyatck2.wav");
574: sound_sproing = gi.soundindex ("flyer/flyatck1.wav");
575: sound_die = gi.soundindex ("flyer/flydeth1.wav");
576:
577: gi.soundindex ("flyer/flyatck3.wav");
578:
579: self->s.modelindex = gi.modelindex ("models/monsters/flyer/tris.md2");
580: VectorSet (self->mins, -16, -16, -24);
581: VectorSet (self->maxs, 16, 16, 32);
582: self->movetype = MOVETYPE_STEP;
583: self->solid = SOLID_BBOX;
584:
585: self->s.sound = gi.soundindex ("flyer/flyidle1.wav");
586:
587: self->health = 50;
588: self->mass = 50;
589:
590: self->pain = flyer_pain;
591: self->die = flyer_die;
592:
593: self->monsterinfo.stand = flyer_stand;
594: self->monsterinfo.walk = flyer_walk;
595: self->monsterinfo.run = flyer_run;
596: self->monsterinfo.attack = flyer_attack;
597: self->monsterinfo.melee = flyer_melee;
598: self->monsterinfo.sight = flyer_sight;
599: self->monsterinfo.idle = flyer_idle;
600:
601: gi.linkentity (self);
602:
603: self->monsterinfo.currentmove = &flyer_move_stand;
604: self->monsterinfo.scale = MODEL_SCALE;
605:
606: flymonster_start (self);
607: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.