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