|
|
1.1 root 1: /*
2: ==============================================================================
3:
4: brain
5:
6: ==============================================================================
7: */
8:
9: #include "g_local.h"
10: #include "m_brain.h"
11:
12:
13: static int sound_chest_open;
14: static int sound_tentacles_extend;
15: static int sound_tentacles_retract;
16: static int sound_death;
17: static int sound_idle1;
18: static int sound_idle2;
19: static int sound_idle3;
20: static int sound_pain1;
21: static int sound_pain2;
22: static int sound_sight;
23: static int sound_search;
24: static int sound_melee1;
25: static int sound_melee2;
26: static int sound_melee3;
27:
28:
29: void brain_sight (edict_t *self, edict_t *other)
30: {
31: gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0);
32: }
33:
34: void brain_search (edict_t *self)
35: {
36: gi.sound (self, CHAN_VOICE, sound_search, 1, ATTN_NORM, 0);
37: }
38:
39:
40: void brain_run (edict_t *self);
41: void brain_dead (edict_t *self);
42:
43:
44: //
45: // STAND
46: //
47:
48: mframe_t brain_frames_stand [] =
49: {
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, NULL,
56: ai_stand, 0, NULL,
57: ai_stand, 0, NULL,
58: ai_stand, 0, NULL,
59: ai_stand, 0, NULL,
60:
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:
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: };
83: mmove_t brain_move_stand = {FRAME_stand01, FRAME_stand30, brain_frames_stand, NULL};
84:
85: void brain_stand (edict_t *self)
86: {
87: self->monsterinfo.currentmove = &brain_move_stand;
88: }
89:
90:
91: //
92: // IDLE
93: //
94:
95: mframe_t brain_frames_idle [] =
96: {
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:
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:
119: ai_stand, 0, NULL,
120: ai_stand, 0, NULL,
121: ai_stand, 0, NULL,
122: ai_stand, 0, NULL,
123: ai_stand, 0, NULL,
124: ai_stand, 0, NULL,
125: ai_stand, 0, NULL,
126: ai_stand, 0, NULL,
127: ai_stand, 0, NULL,
128: ai_stand, 0, NULL
129: };
130: mmove_t brain_move_idle = {FRAME_stand31, FRAME_stand60, brain_frames_idle, brain_stand};
131:
132: void brain_idle (edict_t *self)
133: {
134: gi.sound (self, CHAN_AUTO, sound_idle3, 1, ATTN_IDLE, 0);
135: self->monsterinfo.currentmove = &brain_move_idle;
136: }
137:
138:
139: //
140: // WALK
141: //
142: mframe_t brain_frames_walk1 [] =
143: {
144: ai_walk, 7, NULL,
145: ai_walk, 2, NULL,
146: ai_walk, 3, NULL,
147: ai_walk, 3, NULL,
148: ai_walk, 1, NULL,
149: ai_walk, 0, NULL,
150: ai_walk, 0, NULL,
151: ai_walk, 9, NULL,
152: ai_walk, -4, NULL,
153: ai_walk, -1, NULL,
154: ai_walk, 2, NULL
155: };
156: mmove_t brain_move_walk1 = {FRAME_walk101, FRAME_walk111, brain_frames_walk1, NULL};
157:
158: // walk2 is FUBAR, do not use
159: #if 0
160: void brain_walk2_cycle (edict_t *self)
161: {
162: if (random() > 0.1)
163: self->monsterinfo.nextframe = FRAME_walk220;
164: }
165:
166: mframe_t brain_frames_walk2 [] =
167: {
168: ai_walk, 3, NULL,
169: ai_walk, -2, NULL,
170: ai_walk, -4, NULL,
171: ai_walk, -3, NULL,
172: ai_walk, 0, NULL,
173: ai_walk, 1, NULL,
174: ai_walk, 12, NULL,
175: ai_walk, 0, NULL,
176: ai_walk, -3, NULL,
177: ai_walk, 0, NULL,
178:
179: ai_walk, -2, NULL,
180: ai_walk, 0, NULL,
181: ai_walk, 0, NULL,
182: ai_walk, 1, NULL,
183: ai_walk, 0, NULL,
184: ai_walk, 0, NULL,
185: ai_walk, 0, NULL,
186: ai_walk, 0, NULL,
187: ai_walk, 0, NULL,
188: ai_walk, 10, NULL, // Cycle Start
189:
190: ai_walk, -1, NULL,
191: ai_walk, 7, NULL,
192: ai_walk, 0, NULL,
193: ai_walk, 3, NULL,
194: ai_walk, -3, NULL,
195: ai_walk, 2, NULL,
196: ai_walk, 4, NULL,
197: ai_walk, -3, NULL,
198: ai_walk, 2, NULL,
199: ai_walk, 0, NULL,
200:
201: ai_walk, 4, brain_walk2_cycle,
202: ai_walk, -1, NULL,
203: ai_walk, -1, NULL,
204: ai_walk, -8, NULL,
205: ai_walk, 0, NULL,
206: ai_walk, 1, NULL,
207: ai_walk, 5, NULL,
208: ai_walk, 2, NULL,
209: ai_walk, -1, NULL,
210: ai_walk, -5, NULL
211: };
212: mmove_t brain_move_walk2 = {FRAME_walk201, FRAME_walk240, brain_frames_walk2, NULL};
213: #endif
214:
215: void brain_walk (edict_t *self)
216: {
217: // if (random() <= 0.5)
218: self->monsterinfo.currentmove = &brain_move_walk1;
219: // else
220: // self->monsterinfo.currentmove = &brain_move_walk2;
221: }
222:
223:
224:
225: mframe_t brain_frames_defense [] =
226: {
227: ai_move, 0, NULL,
228: ai_move, 0, NULL,
229: ai_move, 0, NULL,
230: ai_move, 0, NULL,
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: };
237: mmove_t brain_move_defense = {FRAME_defens01, FRAME_defens08, brain_frames_defense, NULL};
238:
239: mframe_t brain_frames_pain3 [] =
240: {
241: ai_move, -2, NULL,
242: ai_move, 2, NULL,
243: ai_move, 1, NULL,
244: ai_move, 3, NULL,
245: ai_move, 0, NULL,
246: ai_move, -4, NULL
247: };
248: mmove_t brain_move_pain3 = {FRAME_pain301, FRAME_pain306, brain_frames_pain3, brain_run};
249:
250: mframe_t brain_frames_pain2 [] =
251: {
252: ai_move, -2, NULL,
253: ai_move, 0, NULL,
254: ai_move, 0, NULL,
255: ai_move, 0, NULL,
256: ai_move, 0, NULL,
257: ai_move, 3, NULL,
258: ai_move, 1, NULL,
259: ai_move, -2, NULL
260: };
261: mmove_t brain_move_pain2 = {FRAME_pain201, FRAME_pain208, brain_frames_pain2, brain_run};
262:
263: mframe_t brain_frames_pain1 [] =
264: {
265: ai_move, -6, NULL,
266: ai_move, -2, NULL,
267: ai_move, -6, NULL,
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: ai_move, 0, NULL,
278: ai_move, 2, NULL,
279: ai_move, 0, NULL,
280: ai_move, 2, NULL,
281: ai_move, 1, NULL,
282: ai_move, 7, NULL,
283: ai_move, 0, NULL,
284: ai_move, 3, NULL,
285: ai_move, -1, NULL
286: };
287: mmove_t brain_move_pain1 = {FRAME_pain101, FRAME_pain121, brain_frames_pain1, brain_run};
288:
289:
290: //
291: // DUCK
292: //
293:
294: void brain_duck_down (edict_t *self)
295: {
296: if (self->monsterinfo.aiflags & AI_DUCKED)
297: return;
298: self->monsterinfo.aiflags |= AI_DUCKED;
299: self->maxs[2] -= 32;
300: self->takedamage = DAMAGE_YES;
301: gi.linkentity (self);
302: }
303:
304: void brain_duck_hold (edict_t *self)
305: {
306: if (level.time >= self->monsterinfo.pausetime)
307: self->monsterinfo.aiflags &= ~AI_HOLD_FRAME;
308: else
309: self->monsterinfo.aiflags |= AI_HOLD_FRAME;
310: }
311:
312: void brain_duck_up (edict_t *self)
313: {
314: self->monsterinfo.aiflags &= ~AI_DUCKED;
315: self->maxs[2] += 32;
316: self->takedamage = DAMAGE_AIM;
317: gi.linkentity (self);
318: }
319:
320: mframe_t brain_frames_duck [] =
321: {
322: ai_move, 0, NULL,
323: ai_move, -2, brain_duck_down,
324: ai_move, 17, brain_duck_hold,
325: ai_move, -3, NULL,
326: ai_move, -1, brain_duck_up,
327: ai_move, -5, NULL,
328: ai_move, -6, NULL,
329: ai_move, -6, NULL
330: };
331: mmove_t brain_move_duck = {FRAME_duck01, FRAME_duck08, brain_frames_duck, brain_run};
332:
333: void brain_dodge (edict_t *self, edict_t *attacker, float eta)
334: {
335: if (random() > 0.25)
336: return;
337:
338: if (!self->enemy)
339: self->enemy = attacker;
340:
341: self->monsterinfo.pausetime = level.time + eta + 0.5;
342: self->monsterinfo.currentmove = &brain_move_duck;
343: }
344:
345:
346: mframe_t brain_frames_death2 [] =
347: {
348: ai_move, 0, NULL,
349: ai_move, 0, NULL,
350: ai_move, 0, NULL,
351: ai_move, 9, NULL,
352: ai_move, 0, NULL
353: };
354: mmove_t brain_move_death2 = {FRAME_death201, FRAME_death205, brain_frames_death2, brain_dead};
355:
356: mframe_t brain_frames_death1 [] =
357: {
358: ai_move, 0, NULL,
359: ai_move, 0, NULL,
360: ai_move, -2, NULL,
361: ai_move, 9, NULL,
362: ai_move, 0, NULL,
363: ai_move, 0, NULL,
364: ai_move, 0, NULL,
365: ai_move, 0, NULL,
366: ai_move, 0, NULL,
367: ai_move, 0, NULL,
368: ai_move, 0, NULL,
369: ai_move, 0, NULL,
370: ai_move, 0, NULL,
371: ai_move, 0, NULL,
372: ai_move, 0, NULL,
373: ai_move, 0, NULL,
374: ai_move, 0, NULL,
375: ai_move, 0, NULL
376: };
377: mmove_t brain_move_death1 = {FRAME_death101, FRAME_death118, brain_frames_death1, brain_dead};
378:
379:
380: //
381: // MELEE
382: //
383:
384: void brain_swing_right (edict_t *self)
385: {
386: gi.sound (self, CHAN_BODY, sound_melee1, 1, ATTN_NORM, 0);
387: }
388:
389: void brain_hit_right (edict_t *self)
390: {
391: vec3_t aim;
392:
393: VectorSet (aim, MELEE_DISTANCE, self->maxs[0], 8);
394: if (fire_hit (self, aim, (15 + (rand() %5)), 40))
395: gi.sound (self, CHAN_WEAPON, sound_melee3, 1, ATTN_NORM, 0);
396: }
397:
398: void brain_swing_left (edict_t *self)
399: {
400: gi.sound (self, CHAN_BODY, sound_melee2, 1, ATTN_NORM, 0);
401: }
402:
403: void brain_hit_left (edict_t *self)
404: {
405: vec3_t aim;
406:
407: VectorSet (aim, MELEE_DISTANCE, self->mins[0], 8);
408: if (fire_hit (self, aim, (15 + (rand() %5)), 40))
409: gi.sound (self, CHAN_WEAPON, sound_melee3, 1, ATTN_NORM, 0);
410: }
411:
412: mframe_t brain_frames_attack1 [] =
413: {
414: ai_charge, 8, NULL,
415: ai_charge, 3, NULL,
416: ai_charge, 5, NULL,
417: ai_charge, 0, NULL,
418: ai_charge, -3, brain_swing_right,
419: ai_charge, 0, NULL,
420: ai_charge, -5, NULL,
421: ai_charge, -7, brain_hit_right,
422: ai_charge, 0, NULL,
423: ai_charge, 6, brain_swing_left,
424: ai_charge, 1, NULL,
425: ai_charge, 2, brain_hit_left,
426: ai_charge, -3, NULL,
427: ai_charge, 6, NULL,
428: ai_charge, -1, NULL,
429: ai_charge, -3, NULL,
430: ai_charge, 2, NULL,
431: ai_charge, -11,NULL
432: };
433: mmove_t brain_move_attack1 = {FRAME_attak101, FRAME_attak118, brain_frames_attack1, brain_run};
434:
435: void brain_chest_open (edict_t *self)
436: {
437: self->spawnflags &= ~65536;
438: self->monsterinfo.power_armor_type = POWER_ARMOR_NONE;
439: gi.sound (self, CHAN_BODY, sound_chest_open, 1, ATTN_NORM, 0);
440: }
441:
442: void brain_tentacle_attack (edict_t *self)
443: {
444: vec3_t aim;
445:
446: VectorSet (aim, MELEE_DISTANCE, 0, 8);
447: if (fire_hit (self, aim, (10 + (rand() %5)), -600) && skill->value > 0)
448: self->spawnflags |= 65536;
449: gi.sound (self, CHAN_WEAPON, sound_tentacles_retract, 1, ATTN_NORM, 0);
450: }
451:
452: void brain_chest_closed (edict_t *self)
453: {
454: self->monsterinfo.power_armor_type = POWER_ARMOR_SCREEN;
455: if (self->spawnflags & 65536)
456: {
457: self->spawnflags &= ~65536;
458: self->monsterinfo.currentmove = &brain_move_attack1;
459: }
460: }
461:
462: mframe_t brain_frames_attack2 [] =
463: {
464: ai_charge, 5, NULL,
465: ai_charge, -4, NULL,
466: ai_charge, -4, NULL,
467: ai_charge, -3, NULL,
468: ai_charge, 0, brain_chest_open,
469: ai_charge, 0, NULL,
470: ai_charge, 13, brain_tentacle_attack,
471: ai_charge, 0, NULL,
472: ai_charge, 2, NULL,
473: ai_charge, 0, NULL,
474: ai_charge, -9, brain_chest_closed,
475: ai_charge, 0, NULL,
476: ai_charge, 4, NULL,
477: ai_charge, 3, NULL,
478: ai_charge, 2, NULL,
479: ai_charge, -3, NULL,
480: ai_charge, -6, NULL
481: };
482: mmove_t brain_move_attack2 = {FRAME_attak201, FRAME_attak217, brain_frames_attack2, brain_run};
483:
484: void brain_melee(edict_t *self)
485: {
486: if (random() <= 0.5)
487: self->monsterinfo.currentmove = &brain_move_attack1;
488: else
489: self->monsterinfo.currentmove = &brain_move_attack2;
490: }
491:
492:
493: //
494: // RUN
495: //
496:
497: mframe_t brain_frames_run [] =
498: {
499: ai_run, 9, NULL,
500: ai_run, 2, NULL,
501: ai_run, 3, NULL,
502: ai_run, 3, NULL,
503: ai_run, 1, NULL,
504: ai_run, 0, NULL,
505: ai_run, 0, NULL,
506: ai_run, 10, NULL,
507: ai_run, -4, NULL,
508: ai_run, -1, NULL,
509: ai_run, 2, NULL
510: };
511: mmove_t brain_move_run = {FRAME_walk101, FRAME_walk111, brain_frames_run, NULL};
512:
513: void brain_run (edict_t *self)
514: {
515: self->monsterinfo.power_armor_type = POWER_ARMOR_SCREEN;
516: if (self->monsterinfo.aiflags & AI_STAND_GROUND)
517: self->monsterinfo.currentmove = &brain_move_stand;
518: else
519: self->monsterinfo.currentmove = &brain_move_run;
520: }
521:
522:
523: void brain_pain (edict_t *self, edict_t *other, float kick, int damage)
524: {
525: float r;
526:
527: if (self->health < (self->max_health / 2))
528: self->s.skinnum = 1;
529:
530: if (level.time < self->pain_debounce_time)
531: return;
532:
533: self->pain_debounce_time = level.time + 3;
534: if (skill->value == 3)
535: return; // no pain anims in nightmare
536:
537: r = random();
538: if (r < 0.33)
539: {
540: gi.sound (self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0);
541: self->monsterinfo.currentmove = &brain_move_pain1;
542: }
543: else if (r < 0.66)
544: {
545: gi.sound (self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0);
546: self->monsterinfo.currentmove = &brain_move_pain2;
547: }
548: else
549: {
550: gi.sound (self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0);
551: self->monsterinfo.currentmove = &brain_move_pain3;
552: }
553: }
554:
555: void brain_dead (edict_t *self)
556: {
557: VectorSet (self->mins, -16, -16, -24);
558: VectorSet (self->maxs, 16, 16, -8);
559: self->movetype = MOVETYPE_TOSS;
560: self->svflags |= SVF_DEADMONSTER;
561: self->nextthink = 0;
562: gi.linkentity (self);
563: }
564:
565:
566:
567: void brain_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
568: {
569: int n;
570:
571: self->s.effects = 0;
572: self->monsterinfo.power_armor_type = POWER_ARMOR_NONE;
573:
574: // check for gib
575: if (self->health <= self->gib_health)
576: {
577: gi.sound (self, CHAN_VOICE, gi.soundindex ("misc/udeath.wav"), 1, ATTN_NORM, 0);
578: for (n= 0; n < 2; n++)
579: ThrowGib (self, "models/objects/gibs/bone/tris.md2", damage, GIB_ORGANIC);
580: for (n= 0; n < 4; n++)
581: ThrowGib (self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC);
582: ThrowHead (self, "models/objects/gibs/head2/tris.md2", damage, GIB_ORGANIC);
583: self->deadflag = DEAD_DEAD;
584: return;
585: }
586:
587: if (self->deadflag == DEAD_DEAD)
588: return;
589:
590: // regular death
591: gi.sound (self, CHAN_VOICE, sound_death, 1, ATTN_NORM, 0);
592: self->deadflag = DEAD_DEAD;
593: self->takedamage = DAMAGE_YES;
594: if (random() <= 0.5)
595: self->monsterinfo.currentmove = &brain_move_death1;
596: else
597: self->monsterinfo.currentmove = &brain_move_death2;
598: }
599:
600: /*QUAKED monster_brain (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight
601: */
602: void SP_monster_brain (edict_t *self)
603: {
604: if (deathmatch->value)
605: {
606: G_FreeEdict (self);
607: return;
608: }
609:
610: sound_chest_open = gi.soundindex ("brain/brnatck1.wav");
611: sound_tentacles_extend = gi.soundindex ("brain/brnatck2.wav");
612: sound_tentacles_retract = gi.soundindex ("brain/brnatck3.wav");
613: sound_death = gi.soundindex ("brain/brndeth1.wav");
614: sound_idle1 = gi.soundindex ("brain/brnidle1.wav");
615: sound_idle2 = gi.soundindex ("brain/brnidle2.wav");
616: sound_idle3 = gi.soundindex ("brain/brnlens1.wav");
617: sound_pain1 = gi.soundindex ("brain/brnpain1.wav");
618: sound_pain2 = gi.soundindex ("brain/brnpain2.wav");
619: sound_sight = gi.soundindex ("brain/brnsght1.wav");
620: sound_search = gi.soundindex ("brain/brnsrch1.wav");
621: sound_melee1 = gi.soundindex ("brain/melee1.wav");
622: sound_melee2 = gi.soundindex ("brain/melee2.wav");
623: sound_melee3 = gi.soundindex ("brain/melee3.wav");
624:
625: self->movetype = MOVETYPE_STEP;
626: self->solid = SOLID_BBOX;
627: self->s.modelindex = gi.modelindex ("models/monsters/brain/tris.md2");
628: VectorSet (self->mins, -16, -16, -24);
629: VectorSet (self->maxs, 16, 16, 32);
630:
631: self->health = 300;
632: self->gib_health = -150;
633: self->mass = 400;
634:
635: self->pain = brain_pain;
636: self->die = brain_die;
637:
638: self->monsterinfo.stand = brain_stand;
639: self->monsterinfo.walk = brain_walk;
640: self->monsterinfo.run = brain_run;
641: self->monsterinfo.dodge = brain_dodge;
642: // self->monsterinfo.attack = brain_attack;
643: self->monsterinfo.melee = brain_melee;
644: self->monsterinfo.sight = brain_sight;
645: self->monsterinfo.search = brain_search;
646: self->monsterinfo.idle = brain_idle;
647:
648: self->monsterinfo.power_armor_type = POWER_ARMOR_SCREEN;
649: self->monsterinfo.power_armor_power = 100;
650:
651: gi.linkentity (self);
652:
653: self->monsterinfo.currentmove = &brain_move_stand;
654: self->monsterinfo.scale = MODEL_SCALE;
655:
656: walkmonster_start (self);
657: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.