|
|
1.1 root 1: /*
2: ==============================================================================
3:
4: chick
5:
6: ==============================================================================
7: */
8:
9: #include "g_local.h"
10: #include "m_chick.h"
11:
12: qboolean visible (edict_t *self, edict_t *other);
13:
14: void chick_stand (edict_t *self);
15: void chick_run (edict_t *self);
16: void chick_reslash(edict_t *self);
17: void chick_rerocket(edict_t *self);
18: void chick_attack1(edict_t *self);
19:
20: static int sound_missile_prelaunch;
21: static int sound_missile_launch;
22: static int sound_melee_swing;
23: static int sound_melee_hit;
24: static int sound_missile_reload;
25: static int sound_death1;
26: static int sound_death2;
27: static int sound_fall_down;
28: static int sound_idle1;
29: static int sound_idle2;
30: static int sound_pain1;
31: static int sound_pain2;
32: static int sound_pain3;
33: static int sound_sight;
34: static int sound_search;
35:
36:
37: void ChickMoan (edict_t *self)
38: {
39: if (random() < 0.5)
40: gi.sound (self, CHAN_VOICE, sound_idle1, 1, ATTN_IDLE, 0);
41: else
42: gi.sound (self, CHAN_VOICE, sound_idle2, 1, ATTN_IDLE, 0);
43: }
44:
45: mframe_t chick_frames_fidget [] =
46: {
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, ChickMoan,
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: };
78: mmove_t chick_move_fidget = {FRAME_stand201, FRAME_stand230, chick_frames_fidget, chick_stand};
79:
80: void chick_fidget (edict_t *self)
81: {
82: if (self->monsterinfo.aiflags & AI_STAND_GROUND)
83: return;
84: if (random() <= 0.3)
85: self->monsterinfo.currentmove = &chick_move_fidget;
86: }
87:
88: mframe_t chick_frames_stand [] =
89: {
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: 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: ai_stand, 0, NULL,
105: ai_stand, 0, NULL,
106: ai_stand, 0, NULL,
107: ai_stand, 0, NULL,
108: ai_stand, 0, NULL,
109: ai_stand, 0, NULL,
110: ai_stand, 0, NULL,
111: ai_stand, 0, NULL,
112: ai_stand, 0, NULL,
113: ai_stand, 0, NULL,
114: ai_stand, 0, NULL,
115: ai_stand, 0, NULL,
116: ai_stand, 0, NULL,
117: ai_stand, 0, NULL,
118: ai_stand, 0, NULL,
119: ai_stand, 0, chick_fidget,
120:
121: };
122: mmove_t chick_move_stand = {FRAME_stand101, FRAME_stand130, chick_frames_stand, NULL};
123:
124: void chick_stand (edict_t *self)
125: {
126: self->monsterinfo.currentmove = &chick_move_stand;
127: }
128:
129: mframe_t chick_frames_start_run [] =
130: {
131: ai_run, 1, NULL,
132: ai_run, 0, NULL,
133: ai_run, 0, NULL,
134: ai_run, -1, NULL,
135: ai_run, -1, NULL,
136: ai_run, 0, NULL,
137: ai_run, 1, NULL,
138: ai_run, 3, NULL,
139: ai_run, 6, NULL,
140: ai_run, 3, NULL
141: };
142: mmove_t chick_move_start_run = {FRAME_walk01, FRAME_walk10, chick_frames_start_run, chick_run};
143:
144: mframe_t chick_frames_run [] =
145: {
146: ai_run, 6, NULL,
147: ai_run, 8, NULL,
148: ai_run, 13, NULL,
149: ai_run, 5, NULL,
150: ai_run, 7, NULL,
151: ai_run, 4, NULL,
152: ai_run, 11, NULL,
153: ai_run, 5, NULL,
154: ai_run, 9, NULL,
155: ai_run, 7, NULL
156:
157: };
158:
159: mmove_t chick_move_run = {FRAME_walk11, FRAME_walk20, chick_frames_run, NULL};
160:
161: mframe_t chick_frames_walk [] =
162: {
163: ai_walk, 6, NULL,
164: ai_walk, 8, NULL,
165: ai_walk, 13, NULL,
166: ai_walk, 5, NULL,
167: ai_walk, 7, NULL,
168: ai_walk, 4, NULL,
169: ai_walk, 11, NULL,
170: ai_walk, 5, NULL,
171: ai_walk, 9, NULL,
172: ai_walk, 7, NULL
173: };
174:
175: mmove_t chick_move_walk = {FRAME_walk11, FRAME_walk20, chick_frames_walk, NULL};
176:
177: void chick_walk (edict_t *self)
178: {
179: self->monsterinfo.currentmove = &chick_move_walk;
180: }
181:
182: void chick_run (edict_t *self)
183: {
184: if (self->monsterinfo.aiflags & AI_STAND_GROUND)
185: {
186: self->monsterinfo.currentmove = &chick_move_stand;
187: return;
188: }
189:
190: if (self->monsterinfo.currentmove == &chick_move_walk ||
191: self->monsterinfo.currentmove == &chick_move_start_run)
192: {
193: self->monsterinfo.currentmove = &chick_move_run;
194: }
195: else
196: {
197: self->monsterinfo.currentmove = &chick_move_start_run;
198: }
199: }
200:
201: mframe_t chick_frames_pain1 [] =
202: {
203: ai_move, 0, NULL,
204: ai_move, 0, NULL,
205: ai_move, 0, NULL,
206: ai_move, 0, NULL,
207: ai_move, 0, NULL
208: };
209: mmove_t chick_move_pain1 = {FRAME_pain101, FRAME_pain105, chick_frames_pain1, chick_run};
210:
211: mframe_t chick_frames_pain2 [] =
212: {
213: ai_move, 0, NULL,
214: ai_move, 0, NULL,
215: ai_move, 0, NULL,
216: ai_move, 0, NULL,
217: ai_move, 0, NULL
218: };
219: mmove_t chick_move_pain2 = {FRAME_pain201, FRAME_pain205, chick_frames_pain2, chick_run};
220:
221: mframe_t chick_frames_pain3 [] =
222: {
223: ai_move, 0, NULL,
224: ai_move, 0, NULL,
225: ai_move, -6, NULL,
226: ai_move, 3, NULL,
227: ai_move, 11, NULL,
228: ai_move, 3, NULL,
229: ai_move, 0, NULL,
230: ai_move, 0, NULL,
231: ai_move, 4, NULL,
232: ai_move, 1, NULL,
233: ai_move, 0, NULL,
234: ai_move, -3, NULL,
235: ai_move, -4, NULL,
236: ai_move, 5, NULL,
237: ai_move, 7, NULL,
238: ai_move, -2, NULL,
239: ai_move, 3, NULL,
240: ai_move, -5, NULL,
241: ai_move, -2, NULL,
242: ai_move, -8, NULL,
243: ai_move, 2, NULL
244: };
245: mmove_t chick_move_pain3 = {FRAME_pain301, FRAME_pain321, chick_frames_pain3, chick_run};
246:
247: void chick_pain (edict_t *self, edict_t *other, float kick, int damage)
248: {
249: float r;
250:
251: if (self->health < (self->max_health / 2))
252: self->s.skinnum = 1;
253:
254: if (level.time < self->pain_debounce_time)
255: return;
256:
257: self->pain_debounce_time = level.time + 3;
258:
259: r = random();
260: if (r < 0.33)
261: gi.sound (self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0);
262: else if (r < 0.66)
263: gi.sound (self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0);
264: else
265: gi.sound (self, CHAN_VOICE, sound_pain3, 1, ATTN_NORM, 0);
266:
267: if (damage <= 10)
268: self->monsterinfo.currentmove = &chick_move_pain1;
269: else if (damage <= 25)
270: self->monsterinfo.currentmove = &chick_move_pain2;
271: else
272: self->monsterinfo.currentmove = &chick_move_pain3;
273: }
274:
275: void chick_dead (edict_t *self)
276: {
277: VectorSet (self->mins, -16, -16, 0);
278: VectorSet (self->maxs, 16, 16, 16);
279: self->movetype = MOVETYPE_TOSS;
280: self->svflags |= SVF_DEADMONSTER;
281: self->nextthink = 0;
282: gi.linkentity (self);
283: }
284:
285: mframe_t chick_frames_death2 [] =
286: {
287: ai_move, -6, NULL,
288: ai_move, 0, NULL,
289: ai_move, -1, NULL,
290: ai_move, -5, NULL,
291: ai_move, 0, NULL,
292: ai_move, -1, NULL,
293: ai_move, -2, NULL,
294: ai_move, 1, NULL,
295: ai_move, 10, NULL,
296: ai_move, 2, NULL,
297: ai_move, 3, NULL,
298: ai_move, 1, NULL,
299: ai_move, 2, NULL,
300: ai_move, 0, NULL,
301: ai_move, 3, NULL,
302: ai_move, 3, NULL,
303: ai_move, 1, NULL,
304: ai_move, -3, NULL,
305: ai_move, -5, NULL,
306: ai_move, 4, NULL,
307: ai_move, 15, NULL,
308: ai_move, 14, NULL,
309: ai_move, 1, NULL
310: };
311: mmove_t chick_move_death2 = {FRAME_death201, FRAME_death223, chick_frames_death2, chick_dead};
312:
313: mframe_t chick_frames_death1 [] =
314: {
315: ai_move, 0, NULL,
316: ai_move, 0, NULL,
317: ai_move, -7, NULL,
318: ai_move, 4, NULL,
319: ai_move, 11, NULL,
320: ai_move, 0, NULL,
321: ai_move, 0, NULL,
322: ai_move, 0, NULL,
323: ai_move, 0, NULL,
324: ai_move, 0, NULL,
325: ai_move, 0, NULL,
326: ai_move, 0, NULL
327:
328: };
329: mmove_t chick_move_death1 = {FRAME_death101, FRAME_death112, chick_frames_death1, chick_dead};
330:
331: void chick_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
332: {
333: int n;
334:
335: // check for gib
336: if (self->health <= self->gib_health)
337: {
338: gi.sound (self, CHAN_VOICE, gi.soundindex ("misc/udeath.wav"), 1, ATTN_NORM, 0);
339: for (n= 0; n < 2; n++)
340: ThrowGib (self, "models/objects/gibs/bone/tris.md2", damage, GIB_ORGANIC);
341: for (n= 0; n < 4; n++)
342: ThrowGib (self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC);
343: ThrowHead (self, "models/objects/gibs/head2/tris.md2", damage, GIB_ORGANIC);
344: self->deadflag = DEAD_DEAD;
345: return;
346: }
347:
348: if (self->deadflag == DEAD_DEAD)
349: return;
350:
351: // regular death
352: self->deadflag = DEAD_DEAD;
353: self->takedamage = DAMAGE_YES;
354:
355: n = rand() % 2;
356: if (n == 0)
357: {
358: self->monsterinfo.currentmove = &chick_move_death1;
359: gi.sound (self, CHAN_VOICE, sound_death1, 1, ATTN_NORM, 0);
360: }
361: else
362: {
363: self->monsterinfo.currentmove = &chick_move_death2;
364: gi.sound (self, CHAN_VOICE, sound_death2, 1, ATTN_NORM, 0);
365: }
366: }
367:
368:
369: void chick_duck_down (edict_t *self)
370: {
371: if (self->monsterinfo.aiflags & AI_DUCKED)
372: return;
373: self->monsterinfo.aiflags |= AI_DUCKED;
374: self->maxs[2] -= 32;
375: self->takedamage = DAMAGE_YES;
376: self->monsterinfo.pausetime = level.time + 1;
377: gi.linkentity (self);
378: }
379:
380: void chick_duck_hold (edict_t *self)
381: {
382: if (level.time >= self->monsterinfo.pausetime)
383: self->monsterinfo.aiflags &= ~AI_HOLD_FRAME;
384: else
385: self->monsterinfo.aiflags |= AI_HOLD_FRAME;
386: }
387:
388: void chick_duck_up (edict_t *self)
389: {
390: self->monsterinfo.aiflags &= ~AI_DUCKED;
391: self->maxs[2] += 32;
392: self->takedamage = DAMAGE_AIM;
393: gi.linkentity (self);
394: }
395:
396: mframe_t chick_frames_duck [] =
397: {
398: ai_move, 0, chick_duck_down,
399: ai_move, 1, NULL,
400: ai_move, 4, chick_duck_hold,
401: ai_move, -4, NULL,
402: ai_move, -5, chick_duck_up,
403: ai_move, 3, NULL,
404: ai_move, 1, NULL
405: };
406: mmove_t chick_move_duck = {FRAME_duck01, FRAME_duck07, chick_frames_duck, chick_run};
407:
408: void chick_dodge (edict_t *self, edict_t *attacker, float eta)
409: {
410: if (random() > 0.25)
411: return;
412:
413: if (!self->enemy)
414: self->enemy = attacker;
415:
416: self->monsterinfo.currentmove = &chick_move_duck;
417: }
418:
419: void ChickSlash (edict_t *self)
420: {
421: vec3_t aim;
422:
423: VectorSet (aim, MELEE_DISTANCE, self->mins[0], 10);
424: gi.sound (self, CHAN_WEAPON, sound_melee_swing, 1, ATTN_NORM, 0);
425: fire_hit (self, aim, (10 + (rand() %6)), 100);
426: }
427:
428:
429: void ChickRocket (edict_t *self)
430: {
431: vec3_t forward, right;
432: vec3_t start;
433: vec3_t dir;
434: vec3_t vec;
435: qboolean tone = true;
436:
437: AngleVectors (self->s.angles, forward, right, NULL);
438: G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_CHICK_ROCKET_1], forward, right, start);
439:
440: VectorCopy (self->enemy->s.origin, vec);
441: vec[2] += self->enemy->viewheight;
442: VectorSubtract (vec, start, dir);
443: VectorNormalize (dir);
444:
445: if (self->s.skinnum > 1)
446: monster_fire_heat (self, start, dir, 50, 500, MZ2_CHICK_ROCKET_1);
447: else
448: monster_fire_rocket (self, start, dir, 50, 500, MZ2_CHICK_ROCKET_1);
449:
450: }
451:
452: void Chick_PreAttack1 (edict_t *self)
453: {
454: gi.sound (self, CHAN_VOICE, sound_missile_prelaunch, 1, ATTN_NORM, 0);
455: }
456:
457: void ChickReload (edict_t *self)
458: {
459: gi.sound (self, CHAN_VOICE, sound_missile_reload, 1, ATTN_NORM, 0);
460: }
461:
462:
463: mframe_t chick_frames_start_attack1 [] =
464: {
465: ai_charge, 0, Chick_PreAttack1,
466: ai_charge, 0, NULL,
467: ai_charge, 0, NULL,
468: ai_charge, 4, NULL,
469: ai_charge, 0, NULL,
470: ai_charge, -3, NULL,
471: ai_charge, 3, NULL,
472: ai_charge, 5, NULL,
473: ai_charge, 7, NULL,
474: ai_charge, 0, NULL,
475: ai_charge, 0, NULL,
476: ai_charge, 0, NULL,
477: ai_charge, 0, chick_attack1
478: };
479: mmove_t chick_move_start_attack1 = {FRAME_attak101, FRAME_attak113, chick_frames_start_attack1, NULL};
480:
481:
482: mframe_t chick_frames_attack1 [] =
483: {
484: ai_charge, 19, ChickRocket,
485: ai_charge, -6, NULL,
486: ai_charge, -5, NULL,
487: ai_charge, -2, NULL,
488: ai_charge, -7, NULL,
489: ai_charge, 0, NULL,
490: ai_charge, 1, NULL,
491: ai_charge, 10, ChickReload,
492: ai_charge, 4, NULL,
493: ai_charge, 5, NULL,
494: ai_charge, 6, NULL,
495: ai_charge, 6, NULL,
496: ai_charge, 4, NULL,
497: ai_charge, 3, chick_rerocket
498:
499: };
500: mmove_t chick_move_attack1 = {FRAME_attak114, FRAME_attak127, chick_frames_attack1, NULL};
501:
502: mframe_t chick_frames_end_attack1 [] =
503: {
504: ai_charge, -3, NULL,
505: ai_charge, 0, NULL,
506: ai_charge, -6, NULL,
507: ai_charge, -4, NULL,
508: ai_charge, -2, NULL
509: };
510: mmove_t chick_move_end_attack1 = {FRAME_attak128, FRAME_attak132, chick_frames_end_attack1, chick_run};
511:
512: void chick_rerocket(edict_t *self)
513: {
514: if (self->enemy->health > 0)
515: {
516: if (range (self, self->enemy) > RANGE_MELEE)
517: if ( visible (self, self->enemy) )
518: if (random() <= 0.6)
519: {
520: self->monsterinfo.currentmove = &chick_move_attack1;
521: return;
522: }
523: }
524: self->monsterinfo.currentmove = &chick_move_end_attack1;
525: }
526:
527: void chick_attack1(edict_t *self)
528: {
529: self->monsterinfo.currentmove = &chick_move_attack1;
530: }
531:
532: mframe_t chick_frames_slash [] =
533: {
534: ai_charge, 1, NULL,
535: ai_charge, 7, ChickSlash,
536: ai_charge, -7, NULL,
537: ai_charge, 1, NULL,
538: ai_charge, -1, NULL,
539: ai_charge, 1, NULL,
540: ai_charge, 0, NULL,
541: ai_charge, 1, NULL,
542: ai_charge, -2, chick_reslash
543: };
544: mmove_t chick_move_slash = {FRAME_attak204, FRAME_attak212, chick_frames_slash, NULL};
545:
546: mframe_t chick_frames_end_slash [] =
547: {
548: ai_charge, -6, NULL,
549: ai_charge, -1, NULL,
550: ai_charge, -6, NULL,
551: ai_charge, 0, NULL
552: };
553: mmove_t chick_move_end_slash = {FRAME_attak213, FRAME_attak216, chick_frames_end_slash, chick_run};
554:
555:
556: void chick_reslash(edict_t *self)
557: {
558: if (self->enemy->health > 0)
559: {
560: if (range (self, self->enemy) == RANGE_MELEE)
561: if (random() <= 0.9)
562: {
563: self->monsterinfo.currentmove = &chick_move_slash;
564: return;
565: }
566: else
567: {
568: self->monsterinfo.currentmove = &chick_move_end_slash;
569: return;
570: }
571: }
572: self->monsterinfo.currentmove = &chick_move_end_slash;
573: }
574:
575: void chick_slash(edict_t *self)
576: {
577: self->monsterinfo.currentmove = &chick_move_slash;
578: }
579:
580:
581: mframe_t chick_frames_start_slash [] =
582: {
583: ai_charge, 1, NULL,
584: ai_charge, 8, NULL,
585: ai_charge, 3, NULL
586: };
587: mmove_t chick_move_start_slash = {FRAME_attak201, FRAME_attak203, chick_frames_start_slash, chick_slash};
588:
589:
590:
591: void chick_melee(edict_t *self)
592: {
593: self->monsterinfo.currentmove = &chick_move_start_slash;
594: }
595:
596:
597: void chick_attack(edict_t *self)
598: {
599: self->monsterinfo.currentmove = &chick_move_start_attack1;
600: }
601:
602: void chick_sight(edict_t *self, edict_t *other)
603: {
604: gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0);
605: }
606:
607:
608: /*QUAKED monster_chick (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight
609: */
610: void SP_monster_chick (edict_t *self)
611: {
612: if (deathmatch->value)
613: {
614: G_FreeEdict (self);
615: return;
616: }
617:
618: sound_missile_prelaunch = gi.soundindex ("chick/chkatck1.wav");
619: sound_missile_launch = gi.soundindex ("chick/chkatck2.wav");
620: sound_melee_swing = gi.soundindex ("chick/chkatck3.wav");
621: sound_melee_hit = gi.soundindex ("chick/chkatck4.wav");
622: sound_missile_reload = gi.soundindex ("chick/chkatck5.wav");
623: sound_death1 = gi.soundindex ("chick/chkdeth1.wav");
624: sound_death2 = gi.soundindex ("chick/chkdeth2.wav");
625: sound_fall_down = gi.soundindex ("chick/chkfall1.wav");
626: sound_idle1 = gi.soundindex ("chick/chkidle1.wav");
627: sound_idle2 = gi.soundindex ("chick/chkidle2.wav");
628: sound_pain1 = gi.soundindex ("chick/chkpain1.wav");
629: sound_pain2 = gi.soundindex ("chick/chkpain2.wav");
630: sound_pain3 = gi.soundindex ("chick/chkpain3.wav");
631: sound_sight = gi.soundindex ("chick/chksght1.wav");
632: sound_search = gi.soundindex ("chick/chksrch1.wav");
633:
634: self->movetype = MOVETYPE_STEP;
635: self->solid = SOLID_BBOX;
636: self->s.modelindex = gi.modelindex ("models/monsters/bitch/tris.md2");
637: VectorSet (self->mins, -16, -16, 0);
638: VectorSet (self->maxs, 16, 16, 56);
639:
640: self->health = 175;
641: self->gib_health = -70;
642: self->mass = 200;
643:
644: self->pain = chick_pain;
645: self->die = chick_die;
646:
647: self->monsterinfo.stand = chick_stand;
648: self->monsterinfo.walk = chick_walk;
649: self->monsterinfo.run = chick_run;
650: self->monsterinfo.dodge = chick_dodge;
651: self->monsterinfo.attack = chick_attack;
652: self->monsterinfo.melee = chick_melee;
653: self->monsterinfo.sight = chick_sight;
654:
655: gi.linkentity (self);
656:
657: self->monsterinfo.currentmove = &chick_move_stand;
658: self->monsterinfo.scale = MODEL_SCALE;
659:
660: walkmonster_start (self);
661: }
662:
663:
664: /*QUAKED monster_chick_heat (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight
665: */
666: void SP_monster_chick_heat (edict_t *self)
667: {
668: SP_monster_chick (self);
669: self->s.skinnum = 3;
670: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.