|
|
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 (skill->value == 3)
268: return; // no pain anims in nightmare
269:
270: if (damage <= 10)
271: self->monsterinfo.currentmove = &chick_move_pain1;
272: else if (damage <= 25)
273: self->monsterinfo.currentmove = &chick_move_pain2;
274: else
275: self->monsterinfo.currentmove = &chick_move_pain3;
276: }
277:
278: void chick_dead (edict_t *self)
279: {
280: VectorSet (self->mins, -16, -16, 0);
281: VectorSet (self->maxs, 16, 16, 16);
282: self->movetype = MOVETYPE_TOSS;
283: self->svflags |= SVF_DEADMONSTER;
284: self->nextthink = 0;
285: gi.linkentity (self);
286: }
287:
288: mframe_t chick_frames_death2 [] =
289: {
290: ai_move, -6, NULL,
291: ai_move, 0, NULL,
292: ai_move, -1, NULL,
293: ai_move, -5, NULL,
294: ai_move, 0, NULL,
295: ai_move, -1, NULL,
296: ai_move, -2, NULL,
297: ai_move, 1, NULL,
298: ai_move, 10, NULL,
299: ai_move, 2, NULL,
300: ai_move, 3, NULL,
301: ai_move, 1, NULL,
302: ai_move, 2, NULL,
303: ai_move, 0, NULL,
304: ai_move, 3, NULL,
305: ai_move, 3, NULL,
306: ai_move, 1, NULL,
307: ai_move, -3, NULL,
308: ai_move, -5, NULL,
309: ai_move, 4, NULL,
310: ai_move, 15, NULL,
311: ai_move, 14, NULL,
312: ai_move, 1, NULL
313: };
314: mmove_t chick_move_death2 = {FRAME_death201, FRAME_death223, chick_frames_death2, chick_dead};
315:
316: mframe_t chick_frames_death1 [] =
317: {
318: ai_move, 0, NULL,
319: ai_move, 0, NULL,
320: ai_move, -7, NULL,
321: ai_move, 4, NULL,
322: ai_move, 11, NULL,
323: ai_move, 0, NULL,
324: ai_move, 0, NULL,
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:
331: };
332: mmove_t chick_move_death1 = {FRAME_death101, FRAME_death112, chick_frames_death1, chick_dead};
333:
334: void chick_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
335: {
336: int n;
337:
338: // check for gib
339: if (self->health <= self->gib_health)
340: {
341: gi.sound (self, CHAN_VOICE, gi.soundindex ("misc/udeath.wav"), 1, ATTN_NORM, 0);
342: for (n= 0; n < 2; n++)
343: ThrowGib (self, "models/objects/gibs/bone/tris.md2", damage, GIB_ORGANIC);
344: for (n= 0; n < 4; n++)
345: ThrowGib (self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC);
346: ThrowHead (self, "models/objects/gibs/head2/tris.md2", damage, GIB_ORGANIC);
347: self->deadflag = DEAD_DEAD;
348: return;
349: }
350:
351: if (self->deadflag == DEAD_DEAD)
352: return;
353:
354: // regular death
355: self->deadflag = DEAD_DEAD;
356: self->takedamage = DAMAGE_YES;
357:
358: n = rand() % 2;
359: if (n == 0)
360: {
361: self->monsterinfo.currentmove = &chick_move_death1;
362: gi.sound (self, CHAN_VOICE, sound_death1, 1, ATTN_NORM, 0);
363: }
364: else
365: {
366: self->monsterinfo.currentmove = &chick_move_death2;
367: gi.sound (self, CHAN_VOICE, sound_death2, 1, ATTN_NORM, 0);
368: }
369: }
370:
371:
372: void chick_duck_down (edict_t *self)
373: {
374: if (self->monsterinfo.aiflags & AI_DUCKED)
375: return;
376: self->monsterinfo.aiflags |= AI_DUCKED;
377: self->maxs[2] -= 32;
378: self->takedamage = DAMAGE_YES;
379: self->monsterinfo.pausetime = level.time + 1;
380: gi.linkentity (self);
381: }
382:
383: void chick_duck_hold (edict_t *self)
384: {
385: if (level.time >= self->monsterinfo.pausetime)
386: self->monsterinfo.aiflags &= ~AI_HOLD_FRAME;
387: else
388: self->monsterinfo.aiflags |= AI_HOLD_FRAME;
389: }
390:
391: void chick_duck_up (edict_t *self)
392: {
393: self->monsterinfo.aiflags &= ~AI_DUCKED;
394: self->maxs[2] += 32;
395: self->takedamage = DAMAGE_AIM;
396: gi.linkentity (self);
397: }
398:
399: mframe_t chick_frames_duck [] =
400: {
401: ai_move, 0, chick_duck_down,
402: ai_move, 1, NULL,
403: ai_move, 4, chick_duck_hold,
404: ai_move, -4, NULL,
405: ai_move, -5, chick_duck_up,
406: ai_move, 3, NULL,
407: ai_move, 1, NULL
408: };
409: mmove_t chick_move_duck = {FRAME_duck01, FRAME_duck07, chick_frames_duck, chick_run};
410:
411: void chick_dodge (edict_t *self, edict_t *attacker, float eta)
412: {
413: if (random() > 0.25)
414: return;
415:
416: if (!self->enemy)
417: self->enemy = attacker;
418:
419: self->monsterinfo.currentmove = &chick_move_duck;
420: }
421:
422: void ChickSlash (edict_t *self)
423: {
424: vec3_t aim;
425:
426: VectorSet (aim, MELEE_DISTANCE, self->mins[0], 10);
427: gi.sound (self, CHAN_WEAPON, sound_melee_swing, 1, ATTN_NORM, 0);
428: fire_hit (self, aim, (10 + (rand() %6)), 100);
429: }
430:
431:
432: void ChickRocket (edict_t *self)
433: {
434: vec3_t forward, right;
435: vec3_t start;
436: vec3_t dir;
437: vec3_t vec;
438:
439: AngleVectors (self->s.angles, forward, right, NULL);
440: G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_CHICK_ROCKET_1], forward, right, start);
441:
442: VectorCopy (self->enemy->s.origin, vec);
443: vec[2] += self->enemy->viewheight;
444: VectorSubtract (vec, start, dir);
445: VectorNormalize (dir);
446:
447: monster_fire_rocket (self, start, dir, 50, 500, MZ2_CHICK_ROCKET_1);
448: }
449:
450: void Chick_PreAttack1 (edict_t *self)
451: {
452: gi.sound (self, CHAN_VOICE, sound_missile_prelaunch, 1, ATTN_NORM, 0);
453: }
454:
455: void ChickReload (edict_t *self)
456: {
457: gi.sound (self, CHAN_VOICE, sound_missile_reload, 1, ATTN_NORM, 0);
458: }
459:
460:
461: mframe_t chick_frames_start_attack1 [] =
462: {
463: ai_charge, 0, Chick_PreAttack1,
464: ai_charge, 0, NULL,
465: ai_charge, 0, NULL,
466: ai_charge, 4, NULL,
467: ai_charge, 0, NULL,
468: ai_charge, -3, NULL,
469: ai_charge, 3, NULL,
470: ai_charge, 5, NULL,
471: ai_charge, 7, NULL,
472: ai_charge, 0, NULL,
473: ai_charge, 0, NULL,
474: ai_charge, 0, NULL,
475: ai_charge, 0, chick_attack1
476: };
477: mmove_t chick_move_start_attack1 = {FRAME_attak101, FRAME_attak113, chick_frames_start_attack1, NULL};
478:
479:
480: mframe_t chick_frames_attack1 [] =
481: {
482: ai_charge, 19, ChickRocket,
483: ai_charge, -6, NULL,
484: ai_charge, -5, NULL,
485: ai_charge, -2, NULL,
486: ai_charge, -7, NULL,
487: ai_charge, 0, NULL,
488: ai_charge, 1, NULL,
489: ai_charge, 10, ChickReload,
490: ai_charge, 4, NULL,
491: ai_charge, 5, NULL,
492: ai_charge, 6, NULL,
493: ai_charge, 6, NULL,
494: ai_charge, 4, NULL,
495: ai_charge, 3, chick_rerocket
496:
497: };
498: mmove_t chick_move_attack1 = {FRAME_attak114, FRAME_attak127, chick_frames_attack1, NULL};
499:
500: mframe_t chick_frames_end_attack1 [] =
501: {
502: ai_charge, -3, NULL,
503: ai_charge, 0, NULL,
504: ai_charge, -6, NULL,
505: ai_charge, -4, NULL,
506: ai_charge, -2, NULL
507: };
508: mmove_t chick_move_end_attack1 = {FRAME_attak128, FRAME_attak132, chick_frames_end_attack1, chick_run};
509:
510: void chick_rerocket(edict_t *self)
511: {
512: if (self->enemy->health > 0)
513: {
514: if (range (self, self->enemy) > RANGE_MELEE)
515: if ( visible (self, self->enemy) )
516: if (random() <= 0.6)
517: {
518: self->monsterinfo.currentmove = &chick_move_attack1;
519: return;
520: }
521: }
522: self->monsterinfo.currentmove = &chick_move_end_attack1;
523: }
524:
525: void chick_attack1(edict_t *self)
526: {
527: self->monsterinfo.currentmove = &chick_move_attack1;
528: }
529:
530: mframe_t chick_frames_slash [] =
531: {
532: ai_charge, 1, NULL,
533: ai_charge, 7, ChickSlash,
534: ai_charge, -7, NULL,
535: ai_charge, 1, NULL,
536: ai_charge, -1, NULL,
537: ai_charge, 1, NULL,
538: ai_charge, 0, NULL,
539: ai_charge, 1, NULL,
540: ai_charge, -2, chick_reslash
541: };
542: mmove_t chick_move_slash = {FRAME_attak204, FRAME_attak212, chick_frames_slash, NULL};
543:
544: mframe_t chick_frames_end_slash [] =
545: {
546: ai_charge, -6, NULL,
547: ai_charge, -1, NULL,
548: ai_charge, -6, NULL,
549: ai_charge, 0, NULL
550: };
551: mmove_t chick_move_end_slash = {FRAME_attak213, FRAME_attak216, chick_frames_end_slash, chick_run};
552:
553:
554: void chick_reslash(edict_t *self)
555: {
556: if (self->enemy->health > 0)
557: {
558: if (range (self, self->enemy) == RANGE_MELEE)
559: if (random() <= 0.9)
560: {
561: self->monsterinfo.currentmove = &chick_move_slash;
562: return;
563: }
564: else
565: {
566: self->monsterinfo.currentmove = &chick_move_end_slash;
567: return;
568: }
569: }
570: self->monsterinfo.currentmove = &chick_move_end_slash;
571: }
572:
573: void chick_slash(edict_t *self)
574: {
575: self->monsterinfo.currentmove = &chick_move_slash;
576: }
577:
578:
579: mframe_t chick_frames_start_slash [] =
580: {
581: ai_charge, 1, NULL,
582: ai_charge, 8, NULL,
583: ai_charge, 3, NULL
584: };
585: mmove_t chick_move_start_slash = {FRAME_attak201, FRAME_attak203, chick_frames_start_slash, chick_slash};
586:
587:
588:
589: void chick_melee(edict_t *self)
590: {
591: self->monsterinfo.currentmove = &chick_move_start_slash;
592: }
593:
594:
595: void chick_attack(edict_t *self)
596: {
597: self->monsterinfo.currentmove = &chick_move_start_attack1;
598: }
599:
600: void chick_sight(edict_t *self, edict_t *other)
601: {
602: gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0);
603: }
604:
605: /*QUAKED monster_chick (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight
606: */
607: void SP_monster_chick (edict_t *self)
608: {
609: if (deathmatch->value)
610: {
611: G_FreeEdict (self);
612: return;
613: }
614:
615: sound_missile_prelaunch = gi.soundindex ("chick/chkatck1.wav");
616: sound_missile_launch = gi.soundindex ("chick/chkatck2.wav");
617: sound_melee_swing = gi.soundindex ("chick/chkatck3.wav");
618: sound_melee_hit = gi.soundindex ("chick/chkatck4.wav");
619: sound_missile_reload = gi.soundindex ("chick/chkatck5.wav");
620: sound_death1 = gi.soundindex ("chick/chkdeth1.wav");
621: sound_death2 = gi.soundindex ("chick/chkdeth2.wav");
622: sound_fall_down = gi.soundindex ("chick/chkfall1.wav");
623: sound_idle1 = gi.soundindex ("chick/chkidle1.wav");
624: sound_idle2 = gi.soundindex ("chick/chkidle2.wav");
625: sound_pain1 = gi.soundindex ("chick/chkpain1.wav");
626: sound_pain2 = gi.soundindex ("chick/chkpain2.wav");
627: sound_pain3 = gi.soundindex ("chick/chkpain3.wav");
628: sound_sight = gi.soundindex ("chick/chksght1.wav");
629: sound_search = gi.soundindex ("chick/chksrch1.wav");
630:
631: self->movetype = MOVETYPE_STEP;
632: self->solid = SOLID_BBOX;
633: self->s.modelindex = gi.modelindex ("models/monsters/bitch/tris.md2");
634: VectorSet (self->mins, -16, -16, 0);
635: VectorSet (self->maxs, 16, 16, 56);
636:
637: self->health = 175;
638: self->gib_health = -70;
639: self->mass = 200;
640:
641: self->pain = chick_pain;
642: self->die = chick_die;
643:
644: self->monsterinfo.stand = chick_stand;
645: self->monsterinfo.walk = chick_walk;
646: self->monsterinfo.run = chick_run;
647: self->monsterinfo.dodge = chick_dodge;
648: self->monsterinfo.attack = chick_attack;
649: self->monsterinfo.melee = chick_melee;
650: self->monsterinfo.sight = chick_sight;
651:
652: gi.linkentity (self);
653:
654: self->monsterinfo.currentmove = &chick_move_stand;
655: self->monsterinfo.scale = MODEL_SCALE;
656:
657: walkmonster_start (self);
658: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.