|
|
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.