|
|
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: static qboolean brain_tounge_attack_ok (vec3_t start, vec3_t end)
493: {
494: vec3_t dir, angles;
495:
496: // check for max distance
497: VectorSubtract (start, end, dir);
498: if (VectorLength(dir) > 512)
499: return false;
500:
501: // check for min/max pitch
502: vectoangles (dir, angles);
503: if (angles[0] < -180)
504: angles[0] += 360;
505: if (fabs(angles[0]) > 30)
506: return false;
507:
508: return true;
509: }
510:
511: void brain_tounge_attack (edict_t *self)
512: {
513: vec3_t offset, start, f, r, end, dir;
514: trace_t tr;
515: int damage;
516:
517: AngleVectors (self->s.angles, f, r, NULL);
518: // VectorSet (offset, 24, 0, 6);
519: VectorSet (offset, 24, 0, 16);
520: G_ProjectSource (self->s.origin, offset, f, r, start);
521:
522: VectorCopy (self->enemy->s.origin, end);
523: if (!brain_tounge_attack_ok(start, end))
524: {
525: end[2] = self->enemy->s.origin[2] + self->enemy->maxs[2] - 8;
526: if (!brain_tounge_attack_ok(start, end))
527: {
528: end[2] = self->enemy->s.origin[2] + self->enemy->mins[2] + 8;
529: if (!brain_tounge_attack_ok(start, end))
530: return;
531: }
532: }
533: VectorCopy (self->enemy->s.origin, end);
534:
535: tr = gi.trace (start, NULL, NULL, end, self, MASK_SHOT);
536: if (tr.ent != self->enemy)
537: return;
538:
539: damage = 5;
540: gi.sound (self, CHAN_WEAPON, sound_tentacles_retract, 1, ATTN_NORM, 0);
541:
542: gi.WriteByte (svc_temp_entity);
543: gi.WriteByte (TE_PARASITE_ATTACK);
544: gi.WriteShort (self - g_edicts);
545: gi.WritePosition (start);
546: gi.WritePosition (end);
547: gi.multicast (self->s.origin, MULTICAST_PVS);
548:
549: VectorSubtract (start, end, dir);
550: T_Damage (self->enemy, self, self, dir, self->enemy->s.origin, vec3_origin, damage, 0, DAMAGE_NO_KNOCKBACK, MOD_BRAINTENTACLE);
551:
552: // pull the enemy in
553: {
554: vec3_t forward;
555: self->s.origin[2] += 1;
556: AngleVectors (self->s.angles, forward, NULL, NULL);
557: VectorScale (forward, -1200, self->enemy->velocity);
558: }
559:
560: }
561:
562: // Brian right eye center
563:
564: struct r_eyeball
565: {
566: float x;
567: float y;
568: float z;
569: } brain_reye [11] = {
570: { 0.746700, 0.238370, 34.167690 },
571: { -1.076390, 0.238370, 33.386372 },
572: { -1.335500, 5.334300, 32.177170 },
573: { -0.175360, 8.846370, 30.635479 },
574: { -2.757590, 7.804610, 30.150860 },
575: { -5.575090, 5.152840, 30.056160 },
576: { -7.017550, 3.262470, 30.552521 },
577: { -7.915740, 0.638800, 33.176189 },
578: { -3.915390, 8.285730, 33.976349 },
579: { -0.913540, 10.933030, 34.141811 },
580: { -0.369900, 8.923900, 34.189079 }
581: };
582:
583:
584:
585: // Brain left eye center
586: struct l_eyeball
587: {
588: float x;
589: float y;
590: float z;
591: } brain_leye [11] = {
592: { -3.364710, 0.327750, 33.938381 },
593: { -5.140450, 0.493480, 32.659851 },
594: { -5.341980, 5.646980, 31.277901 },
595: { -4.134480, 9.277440, 29.925621 },
596: { -6.598340, 6.815090, 29.322620 },
597: { -8.610840, 2.529650, 29.251591 },
598: { -9.231360, 0.093280, 29.747959 },
599: { -11.004110, 1.936930, 32.395260 },
600: { -7.878310, 7.648190, 33.148151 },
601: { -4.947370, 11.430050, 33.313610 },
602: { -4.332820, 9.444570, 33.526340 }
603: };
604:
605: // note to self
606: // need to get an x,y,z offset for
607: // each frame of the run cycle
608: void brain_laserbeam (edict_t *self)
609: {
610:
611: vec3_t forward, right, up;
612: vec3_t tempang, start;
613: vec3_t dir, angles, end;
614: edict_t *ent;
615:
616: // RAFAEL
617: // cant call sound this frequent
618: if (random() > 0.8)
619: gi.sound(self, CHAN_AUTO, gi.soundindex("misc/lasfly.wav"), 1, ATTN_STATIC, 0);
620:
621: // check for max distance
622:
623: VectorCopy (self->s.origin, start);
624: VectorCopy (self->enemy->s.origin, end);
625: VectorSubtract (end, start, dir);
626: vectoangles (dir, angles);
627:
628: // dis is my right eye
629: ent = G_Spawn ();
630: VectorCopy (self->s.origin, ent->s.origin);
631: VectorCopy (angles, tempang);
632: AngleVectors (tempang, forward, right, up);
633: VectorCopy (tempang, ent->s.angles);
634: VectorCopy (ent->s.origin, start);
635: VectorMA (start, brain_reye[self->s.frame - FRAME_walk101].x, right, start);
636: VectorMA (start, brain_reye[self->s.frame - FRAME_walk101].y, forward, start);
637: VectorMA (start, brain_reye[self->s.frame - FRAME_walk101].z, up, start);
638: VectorCopy (start, ent->s.origin);
639: ent->enemy = self->enemy;
640: ent->owner = self;
641: ent->dmg = 1;
642: monster_dabeam (ent);
643:
644: // dis is me left eye
645: ent = G_Spawn ();
646: VectorCopy (self->s.origin, ent->s.origin);
647: VectorCopy (angles, tempang);
648: AngleVectors (tempang, forward, right, up);
649: VectorCopy (tempang, ent->s.angles);
650: VectorCopy (ent->s.origin, start);
651: VectorMA (start, brain_leye[self->s.frame - FRAME_walk101].x, right, start);
652: VectorMA (start, brain_leye[self->s.frame - FRAME_walk101].y, forward, start);
653: VectorMA (start, brain_leye[self->s.frame - FRAME_walk101].z, up, start);
654: VectorCopy (start, ent->s.origin);
655: ent->enemy = self->enemy;
656: ent->owner = self;
657: ent->dmg = 1;
658: monster_dabeam (ent);
659:
660: }
661:
662: void brain_laserbeam_reattack (edict_t *self)
663: {
664: if (random() < 0.5)
665: if (visible (self, self->enemy))
666: if (self->enemy->health > 0)
667: self->s.frame = FRAME_walk101;
668: }
669:
670:
671: mframe_t brain_frames_attack3 [] =
672: {
673: ai_charge, 5, NULL,
674: ai_charge, -4, NULL,
675: ai_charge, -4, NULL,
676: ai_charge, -3, NULL,
677: ai_charge, 0, brain_chest_open,
678: ai_charge, 0, brain_tounge_attack,
679: ai_charge, 13, NULL,
680: ai_charge, 0, brain_tentacle_attack,
681: ai_charge, 2, NULL,
682: ai_charge, 0, brain_tounge_attack,
683: ai_charge, -9, brain_chest_closed,
684: ai_charge, 0, NULL,
685: ai_charge, 4, NULL,
686: ai_charge, 3, NULL,
687: ai_charge, 2, NULL,
688: ai_charge, -3, NULL,
689: ai_charge, -6, NULL
690: };
691: mmove_t brain_move_attack3 = {FRAME_attak201, FRAME_attak217, brain_frames_attack3, brain_run};
692:
693: mframe_t brain_frames_attack4 [] =
694: {
695: ai_charge, 9, brain_laserbeam,
696: ai_charge, 2, brain_laserbeam,
697: ai_charge, 3, brain_laserbeam,
698: ai_charge, 3, brain_laserbeam,
699: ai_charge, 1, brain_laserbeam,
700: ai_charge, 0, brain_laserbeam,
701: ai_charge, 0, brain_laserbeam,
702: ai_charge, 10, brain_laserbeam,
703: ai_charge, -4, brain_laserbeam,
704: ai_charge, -1, brain_laserbeam,
705: ai_charge, 2, brain_laserbeam_reattack
706: };
707: mmove_t brain_move_attack4 = {FRAME_walk101, FRAME_walk111, brain_frames_attack4, brain_run};
708:
709:
710: // RAFAEL
711: void brain_attack (edict_t *self)
712: {
713: int r;
714:
715: if (random() < 0.8)
716: {
717: r = range (self, self->enemy);
718: if (r == RANGE_NEAR)
719: {
720: if (random() < 0.5)
721: self->monsterinfo.currentmove = &brain_move_attack3;
722: else
723: self->monsterinfo.currentmove = &brain_move_attack4;
724: }
725: else if (r > RANGE_NEAR)
726: self->monsterinfo.currentmove = &brain_move_attack4;
727: }
728:
729: }
730:
731: //
732: // RUN
733: //
734:
735: mframe_t brain_frames_run [] =
736: {
737: ai_run, 9, NULL,
738: ai_run, 2, NULL,
739: ai_run, 3, NULL,
740: ai_run, 3, NULL,
741: ai_run, 1, NULL,
742: ai_run, 0, NULL,
743: ai_run, 0, NULL,
744: ai_run, 10, NULL,
745: ai_run, -4, NULL,
746: ai_run, -1, NULL,
747: ai_run, 2, NULL
748: };
749: mmove_t brain_move_run = {FRAME_walk101, FRAME_walk111, brain_frames_run, NULL};
750:
751: void brain_run (edict_t *self)
752: {
753: self->monsterinfo.power_armor_type = POWER_ARMOR_SCREEN;
754: if (self->monsterinfo.aiflags & AI_STAND_GROUND)
755: self->monsterinfo.currentmove = &brain_move_stand;
756: else
757: self->monsterinfo.currentmove = &brain_move_run;
758: }
759:
760:
761: void brain_pain (edict_t *self, edict_t *other, float kick, int damage)
762: {
763: float r;
764:
765: if (self->health < (self->max_health / 2))
766: self->s.skinnum = 1;
767:
768: if (level.time < self->pain_debounce_time)
769: return;
770:
771: self->pain_debounce_time = level.time + 3;
772:
773: r = random();
774: if (r < 0.33)
775: {
776: gi.sound (self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0);
777: self->monsterinfo.currentmove = &brain_move_pain1;
778: }
779: else if (r < 0.66)
780: {
781: gi.sound (self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0);
782: self->monsterinfo.currentmove = &brain_move_pain2;
783: }
784: else
785: {
786: gi.sound (self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0);
787: self->monsterinfo.currentmove = &brain_move_pain3;
788: }
789: }
790:
791: void brain_dead (edict_t *self)
792: {
793: VectorSet (self->mins, -16, -16, -24);
794: VectorSet (self->maxs, 16, 16, -8);
795: self->movetype = MOVETYPE_TOSS;
796: self->svflags |= SVF_DEADMONSTER;
797: self->nextthink = 0;
798: gi.linkentity (self);
799: }
800:
801:
802:
803: void brain_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
804: {
805: int n;
806:
807: self->s.effects = 0;
808: self->monsterinfo.power_armor_type = POWER_ARMOR_NONE;
809:
810: // check for gib
811: if (self->health <= self->gib_health)
812: {
813: gi.sound (self, CHAN_VOICE, gi.soundindex ("misc/udeath.wav"), 1, ATTN_NORM, 0);
814: for (n= 0; n < 2; n++)
815: ThrowGib (self, "models/objects/gibs/bone/tris.md2", damage, GIB_ORGANIC);
816: for (n= 0; n < 4; n++)
817: ThrowGib (self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC);
818: ThrowHead (self, "models/objects/gibs/head2/tris.md2", damage, GIB_ORGANIC);
819: self->deadflag = DEAD_DEAD;
820: return;
821: }
822:
823: if (self->deadflag == DEAD_DEAD)
824: return;
825:
826: // regular death
827: gi.sound (self, CHAN_VOICE, sound_death, 1, ATTN_NORM, 0);
828: self->deadflag = DEAD_DEAD;
829: self->takedamage = DAMAGE_YES;
830: if (random() <= 0.5)
831: self->monsterinfo.currentmove = &brain_move_death1;
832: else
833: self->monsterinfo.currentmove = &brain_move_death2;
834: }
835:
836: /*QUAKED monster_brain (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight
837: */
838: void SP_monster_brain (edict_t *self)
839: {
840: if (deathmatch->value)
841: {
842: G_FreeEdict (self);
843: return;
844: }
845:
846: sound_chest_open = gi.soundindex ("brain/brnatck1.wav");
847: sound_tentacles_extend = gi.soundindex ("brain/brnatck2.wav");
848: sound_tentacles_retract = gi.soundindex ("brain/brnatck3.wav");
849: sound_death = gi.soundindex ("brain/brndeth1.wav");
850: sound_idle1 = gi.soundindex ("brain/brnidle1.wav");
851: sound_idle2 = gi.soundindex ("brain/brnidle2.wav");
852: sound_idle3 = gi.soundindex ("brain/brnlens1.wav");
853: sound_pain1 = gi.soundindex ("brain/brnpain1.wav");
854: sound_pain2 = gi.soundindex ("brain/brnpain2.wav");
855: sound_sight = gi.soundindex ("brain/brnsght1.wav");
856: sound_search = gi.soundindex ("brain/brnsrch1.wav");
857: sound_melee1 = gi.soundindex ("brain/melee1.wav");
858: sound_melee2 = gi.soundindex ("brain/melee2.wav");
859: sound_melee3 = gi.soundindex ("brain/melee3.wav");
860:
861: self->movetype = MOVETYPE_STEP;
862: self->solid = SOLID_BBOX;
863: self->s.modelindex = gi.modelindex ("models/monsters/brain/tris.md2");
864: VectorSet (self->mins, -16, -16, -24);
865: VectorSet (self->maxs, 16, 16, 32);
866:
867: self->health = 300;
868: self->gib_health = -150;
869: self->mass = 400;
870:
871: self->pain = brain_pain;
872: self->die = brain_die;
873:
874: self->monsterinfo.stand = brain_stand;
875: self->monsterinfo.walk = brain_walk;
876: self->monsterinfo.run = brain_run;
877: self->monsterinfo.dodge = brain_dodge;
878: self->monsterinfo.attack = brain_attack;
879: self->monsterinfo.melee = brain_melee;
880: self->monsterinfo.sight = brain_sight;
881: self->monsterinfo.search = brain_search;
882: self->monsterinfo.idle = brain_idle;
883:
884: self->monsterinfo.power_armor_type = POWER_ARMOR_SCREEN;
885: self->monsterinfo.power_armor_power = 100;
886:
887: gi.linkentity (self);
888:
889: self->monsterinfo.currentmove = &brain_move_stand;
890: self->monsterinfo.scale = MODEL_SCALE;
891:
892: walkmonster_start (self);
893: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.