m_boss31.c (17733B)
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 jorg 24 25 ============================================================================== 26 */ 27 28 #include "g_local.h" 29 #include "m_boss31.h" 30 31 extern SP_monster_makron (edict_t *self); 32 qboolean visible (edict_t *self, edict_t *other); 33 34 static int sound_pain1; 35 static int sound_pain2; 36 static int sound_pain3; 37 static int sound_idle; 38 static int sound_death; 39 static int sound_search1; 40 static int sound_search2; 41 static int sound_search3; 42 static int sound_attack1; 43 static int sound_attack2; 44 static int sound_firegun; 45 static int sound_step_left; 46 static int sound_step_right; 47 static int sound_death_hit; 48 49 void BossExplode (edict_t *self); 50 void MakronToss (edict_t *self); 51 52 53 void jorg_search (edict_t *self) 54 { 55 float r; 56 57 r = random(); 58 59 if (r <= 0.3) 60 gi.sound (self, CHAN_VOICE, sound_search1, 1, ATTN_NORM, 0); 61 else if (r <= 0.6) 62 gi.sound (self, CHAN_VOICE, sound_search2, 1, ATTN_NORM, 0); 63 else 64 gi.sound (self, CHAN_VOICE, sound_search3, 1, ATTN_NORM, 0); 65 } 66 67 68 void jorg_dead (edict_t *self); 69 void jorgBFG (edict_t *self); 70 void jorgMachineGun (edict_t *self); 71 void jorg_firebullet (edict_t *self); 72 void jorg_reattack1(edict_t *self); 73 void jorg_attack1(edict_t *self); 74 void jorg_idle(edict_t *self); 75 void jorg_step_left(edict_t *self); 76 void jorg_step_right(edict_t *self); 77 void jorg_death_hit(edict_t *self); 78 79 // 80 // stand 81 // 82 83 mframe_t jorg_frames_stand []= 84 { 85 ai_stand, 0, jorg_idle, 86 ai_stand, 0, NULL, 87 ai_stand, 0, NULL, 88 ai_stand, 0, NULL, 89 ai_stand, 0, NULL, 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, // 10 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, // 20 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, // 30 115 ai_stand, 0, NULL, 116 ai_stand, 0, NULL, 117 ai_stand, 0, NULL, 118 ai_stand, 19, NULL, 119 ai_stand, 11, jorg_step_left, 120 ai_stand, 0, NULL, 121 ai_stand, 0, NULL, 122 ai_stand, 6, NULL, 123 ai_stand, 9, jorg_step_right, 124 ai_stand, 0, NULL, // 40 125 ai_stand, 0, NULL, 126 ai_stand, 0, NULL, 127 ai_stand, 0, NULL, 128 ai_stand, 0, NULL, 129 ai_stand, 0, NULL, 130 ai_stand, 0, NULL, 131 ai_stand, -2, NULL, 132 ai_stand, -17, jorg_step_left, 133 ai_stand, 0, NULL, 134 ai_stand, -12, NULL, // 50 135 ai_stand, -14, jorg_step_right // 51 136 }; 137 mmove_t jorg_move_stand = {FRAME_stand01, FRAME_stand51, jorg_frames_stand, NULL}; 138 139 void jorg_idle (edict_t *self) 140 { 141 gi.sound (self, CHAN_VOICE, sound_idle, 1, ATTN_NORM,0); 142 } 143 144 void jorg_death_hit (edict_t *self) 145 { 146 gi.sound (self, CHAN_BODY, sound_death_hit, 1, ATTN_NORM,0); 147 } 148 149 150 void jorg_step_left (edict_t *self) 151 { 152 gi.sound (self, CHAN_BODY, sound_step_left, 1, ATTN_NORM,0); 153 } 154 155 void jorg_step_right (edict_t *self) 156 { 157 gi.sound (self, CHAN_BODY, sound_step_right, 1, ATTN_NORM,0); 158 } 159 160 161 void jorg_stand (edict_t *self) 162 { 163 self->monsterinfo.currentmove = &jorg_move_stand; 164 } 165 166 mframe_t jorg_frames_run [] = 167 { 168 ai_run, 17, jorg_step_left, 169 ai_run, 0, NULL, 170 ai_run, 0, NULL, 171 ai_run, 0, NULL, 172 ai_run, 12, NULL, 173 ai_run, 8, NULL, 174 ai_run, 10, NULL, 175 ai_run, 33, jorg_step_right, 176 ai_run, 0, NULL, 177 ai_run, 0, NULL, 178 ai_run, 0, NULL, 179 ai_run, 9, NULL, 180 ai_run, 9, NULL, 181 ai_run, 9, NULL 182 }; 183 mmove_t jorg_move_run = {FRAME_walk06, FRAME_walk19, jorg_frames_run, NULL}; 184 185 // 186 // walk 187 // 188 189 mframe_t jorg_frames_start_walk [] = 190 { 191 ai_walk, 5, NULL, 192 ai_walk, 6, NULL, 193 ai_walk, 7, NULL, 194 ai_walk, 9, NULL, 195 ai_walk, 15, NULL 196 }; 197 mmove_t jorg_move_start_walk = {FRAME_walk01, FRAME_walk05, jorg_frames_start_walk, NULL}; 198 199 mframe_t jorg_frames_walk [] = 200 { 201 ai_walk, 17, NULL, 202 ai_walk, 0, NULL, 203 ai_walk, 0, NULL, 204 ai_walk, 0, NULL, 205 ai_walk, 12, NULL, 206 ai_walk, 8, NULL, 207 ai_walk, 10, NULL, 208 ai_walk, 33, NULL, 209 ai_walk, 0, NULL, 210 ai_walk, 0, NULL, 211 ai_walk, 0, NULL, 212 ai_walk, 9, NULL, 213 ai_walk, 9, NULL, 214 ai_walk, 9, NULL 215 }; 216 mmove_t jorg_move_walk = {FRAME_walk06, FRAME_walk19, jorg_frames_walk, NULL}; 217 218 mframe_t jorg_frames_end_walk [] = 219 { 220 ai_walk, 11, NULL, 221 ai_walk, 0, NULL, 222 ai_walk, 0, NULL, 223 ai_walk, 0, NULL, 224 ai_walk, 8, NULL, 225 ai_walk, -8, NULL 226 }; 227 mmove_t jorg_move_end_walk = {FRAME_walk20, FRAME_walk25, jorg_frames_end_walk, NULL}; 228 229 void jorg_walk (edict_t *self) 230 { 231 self->monsterinfo.currentmove = &jorg_move_walk; 232 } 233 234 void jorg_run (edict_t *self) 235 { 236 if (self->monsterinfo.aiflags & AI_STAND_GROUND) 237 self->monsterinfo.currentmove = &jorg_move_stand; 238 else 239 self->monsterinfo.currentmove = &jorg_move_run; 240 } 241 242 mframe_t jorg_frames_pain3 [] = 243 { 244 ai_move, -28, NULL, 245 ai_move, -6, NULL, 246 ai_move, -3, jorg_step_left, 247 ai_move, -9, NULL, 248 ai_move, 0, jorg_step_right, 249 ai_move, 0, NULL, 250 ai_move, 0, NULL, 251 ai_move, 0, NULL, 252 ai_move, -7, NULL, 253 ai_move, 1, NULL, 254 ai_move, -11, NULL, 255 ai_move, -4, NULL, 256 ai_move, 0, NULL, 257 ai_move, 0, NULL, 258 ai_move, 10, NULL, 259 ai_move, 11, NULL, 260 ai_move, 0, NULL, 261 ai_move, 10, NULL, 262 ai_move, 3, NULL, 263 ai_move, 10, NULL, 264 ai_move, 7, jorg_step_left, 265 ai_move, 17, NULL, 266 ai_move, 0, NULL, 267 ai_move, 0, NULL, 268 ai_move, 0, jorg_step_right 269 }; 270 mmove_t jorg_move_pain3 = {FRAME_pain301, FRAME_pain325, jorg_frames_pain3, jorg_run}; 271 272 mframe_t jorg_frames_pain2 [] = 273 { 274 ai_move, 0, NULL, 275 ai_move, 0, NULL, 276 ai_move, 0, NULL 277 }; 278 mmove_t jorg_move_pain2 = {FRAME_pain201, FRAME_pain203, jorg_frames_pain2, jorg_run}; 279 280 mframe_t jorg_frames_pain1 [] = 281 { 282 ai_move, 0, NULL, 283 ai_move, 0, NULL, 284 ai_move, 0, NULL 285 }; 286 mmove_t jorg_move_pain1 = {FRAME_pain101, FRAME_pain103, jorg_frames_pain1, jorg_run}; 287 288 mframe_t jorg_frames_death1 [] = 289 { 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, 0, NULL, 298 ai_move, 0, NULL, 299 ai_move, 0, NULL, // 10 300 ai_move, 0, NULL, 301 ai_move, 0, NULL, 302 ai_move, 0, NULL, 303 ai_move, 0, NULL, 304 ai_move, 0, NULL, 305 ai_move, 0, NULL, 306 ai_move, 0, NULL, 307 ai_move, 0, NULL, 308 ai_move, 0, NULL, 309 ai_move, 0, NULL, // 20 310 ai_move, 0, NULL, 311 ai_move, 0, NULL, 312 ai_move, 0, NULL, 313 ai_move, 0, NULL, 314 ai_move, 0, NULL, 315 ai_move, 0, NULL, 316 ai_move, 0, NULL, 317 ai_move, 0, NULL, 318 ai_move, 0, NULL, 319 ai_move, 0, NULL, // 30 320 ai_move, 0, NULL, 321 ai_move, 0, NULL, 322 ai_move, 0, 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, // 40 330 ai_move, 0, NULL, 331 ai_move, 0, NULL, 332 ai_move, 0, NULL, 333 ai_move, 0, NULL, 334 ai_move, 0, NULL, 335 ai_move, 0, NULL, 336 ai_move, 0, NULL, 337 ai_move, 0, NULL, 338 ai_move, 0, MakronToss, 339 ai_move, 0, BossExplode // 50 340 }; 341 mmove_t jorg_move_death = {FRAME_death01, FRAME_death50, jorg_frames_death1, jorg_dead}; 342 343 mframe_t jorg_frames_attack2 []= 344 { 345 ai_charge, 0, NULL, 346 ai_charge, 0, NULL, 347 ai_charge, 0, NULL, 348 ai_charge, 0, NULL, 349 ai_charge, 0, NULL, 350 ai_charge, 0, NULL, 351 ai_charge, 0, jorgBFG, 352 ai_move, 0, NULL, 353 ai_move, 0, NULL, 354 ai_move, 0, NULL, 355 ai_move, 0, NULL, 356 ai_move, 0, NULL, 357 ai_move, 0, NULL 358 }; 359 mmove_t jorg_move_attack2 = {FRAME_attak201, FRAME_attak213, jorg_frames_attack2, jorg_run}; 360 361 mframe_t jorg_frames_start_attack1 [] = 362 { 363 ai_charge, 0, NULL, 364 ai_charge, 0, NULL, 365 ai_charge, 0, NULL, 366 ai_charge, 0, NULL, 367 ai_charge, 0, NULL, 368 ai_charge, 0, NULL, 369 ai_charge, 0, NULL, 370 ai_charge, 0, NULL 371 }; 372 mmove_t jorg_move_start_attack1 = {FRAME_attak101, FRAME_attak108, jorg_frames_start_attack1, jorg_attack1}; 373 374 mframe_t jorg_frames_attack1[]= 375 { 376 ai_charge, 0, jorg_firebullet, 377 ai_charge, 0, jorg_firebullet, 378 ai_charge, 0, jorg_firebullet, 379 ai_charge, 0, jorg_firebullet, 380 ai_charge, 0, jorg_firebullet, 381 ai_charge, 0, jorg_firebullet 382 }; 383 mmove_t jorg_move_attack1 = {FRAME_attak109, FRAME_attak114, jorg_frames_attack1, jorg_reattack1}; 384 385 mframe_t jorg_frames_end_attack1[]= 386 { 387 ai_move, 0, NULL, 388 ai_move, 0, NULL, 389 ai_move, 0, NULL, 390 ai_move, 0, NULL 391 }; 392 mmove_t jorg_move_end_attack1 = {FRAME_attak115, FRAME_attak118, jorg_frames_end_attack1, jorg_run}; 393 394 void jorg_reattack1(edict_t *self) 395 { 396 if (visible(self, self->enemy)) 397 if (random() < 0.9) 398 self->monsterinfo.currentmove = &jorg_move_attack1; 399 else 400 { 401 self->s.sound = 0; 402 self->monsterinfo.currentmove = &jorg_move_end_attack1; 403 } 404 else 405 { 406 self->s.sound = 0; 407 self->monsterinfo.currentmove = &jorg_move_end_attack1; 408 } 409 } 410 411 void jorg_attack1(edict_t *self) 412 { 413 self->monsterinfo.currentmove = &jorg_move_attack1; 414 } 415 416 void jorg_pain (edict_t *self, edict_t *other, float kick, int damage) 417 { 418 419 if (self->health < (self->max_health / 2)) 420 self->s.skinnum = 1; 421 422 self->s.sound = 0; 423 424 if (level.time < self->pain_debounce_time) 425 return; 426 427 // Lessen the chance of him going into his pain frames if he takes little damage 428 if (damage <= 40) 429 if (random()<=0.6) 430 return; 431 432 /* 433 If he's entering his attack1 or using attack1, lessen the chance of him 434 going into pain 435 */ 436 437 if ( (self->s.frame >= FRAME_attak101) && (self->s.frame <= FRAME_attak108) ) 438 if (random() <= 0.005) 439 return; 440 441 if ( (self->s.frame >= FRAME_attak109) && (self->s.frame <= FRAME_attak114) ) 442 if (random() <= 0.00005) 443 return; 444 445 446 if ( (self->s.frame >= FRAME_attak201) && (self->s.frame <= FRAME_attak208) ) 447 if (random() <= 0.005) 448 return; 449 450 451 self->pain_debounce_time = level.time + 3; 452 if (skill->value == 3) 453 return; // no pain anims in nightmare 454 455 if (damage <= 50) 456 { 457 gi.sound (self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM,0); 458 self->monsterinfo.currentmove = &jorg_move_pain1; 459 } 460 else if (damage <= 100) 461 { 462 gi.sound (self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM,0); 463 self->monsterinfo.currentmove = &jorg_move_pain2; 464 } 465 else 466 { 467 if (random() <= 0.3) 468 { 469 gi.sound (self, CHAN_VOICE, sound_pain3, 1, ATTN_NORM,0); 470 self->monsterinfo.currentmove = &jorg_move_pain3; 471 } 472 } 473 }; 474 475 void jorgBFG (edict_t *self) 476 { 477 vec3_t forward, right; 478 vec3_t start; 479 vec3_t dir; 480 vec3_t vec; 481 482 AngleVectors (self->s.angles, forward, right, NULL); 483 G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_JORG_BFG_1], forward, right, start); 484 485 VectorCopy (self->enemy->s.origin, vec); 486 vec[2] += self->enemy->viewheight; 487 VectorSubtract (vec, start, dir); 488 VectorNormalize (dir); 489 gi.sound (self, CHAN_VOICE, sound_attack2, 1, ATTN_NORM, 0); 490 /*void monster_fire_bfg (edict_t *self, 491 vec3_t start, 492 vec3_t aimdir, 493 int damage, 494 int speed, 495 int kick, 496 float damage_radius, 497 int flashtype)*/ 498 monster_fire_bfg (self, start, dir, 50, 300, 100, 200, MZ2_JORG_BFG_1); 499 } 500 501 void jorg_firebullet_right (edict_t *self) 502 { 503 vec3_t forward, right, target; 504 vec3_t start; 505 506 AngleVectors (self->s.angles, forward, right, NULL); 507 G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_JORG_MACHINEGUN_R1], forward, right, start); 508 509 VectorMA (self->enemy->s.origin, -0.2, self->enemy->velocity, target); 510 target[2] += self->enemy->viewheight; 511 VectorSubtract (target, start, forward); 512 VectorNormalize (forward); 513 514 monster_fire_bullet (self, start, forward, 6, 4, DEFAULT_BULLET_HSPREAD, DEFAULT_BULLET_VSPREAD, MZ2_JORG_MACHINEGUN_R1); 515 } 516 517 void jorg_firebullet_left (edict_t *self) 518 { 519 vec3_t forward, right, target; 520 vec3_t start; 521 522 AngleVectors (self->s.angles, forward, right, NULL); 523 G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_JORG_MACHINEGUN_L1], forward, right, start); 524 525 VectorMA (self->enemy->s.origin, -0.2, self->enemy->velocity, target); 526 target[2] += self->enemy->viewheight; 527 VectorSubtract (target, start, forward); 528 VectorNormalize (forward); 529 530 monster_fire_bullet (self, start, forward, 6, 4, DEFAULT_BULLET_HSPREAD, DEFAULT_BULLET_VSPREAD, MZ2_JORG_MACHINEGUN_L1); 531 } 532 533 void jorg_firebullet (edict_t *self) 534 { 535 jorg_firebullet_left(self); 536 jorg_firebullet_right(self); 537 }; 538 539 void jorg_attack(edict_t *self) 540 { 541 vec3_t vec; 542 float range; 543 544 VectorSubtract (self->enemy->s.origin, self->s.origin, vec); 545 range = VectorLength (vec); 546 547 if (random() <= 0.75) 548 { 549 gi.sound (self, CHAN_VOICE, sound_attack1, 1, ATTN_NORM,0); 550 self->s.sound = gi.soundindex ("boss3/w_loop.wav"); 551 self->monsterinfo.currentmove = &jorg_move_start_attack1; 552 } 553 else 554 { 555 gi.sound (self, CHAN_VOICE, sound_attack2, 1, ATTN_NORM,0); 556 self->monsterinfo.currentmove = &jorg_move_attack2; 557 } 558 } 559 560 void jorg_dead (edict_t *self) 561 { 562 #if 0 563 edict_t *tempent; 564 /* 565 VectorSet (self->mins, -16, -16, -24); 566 VectorSet (self->maxs, 16, 16, -8); 567 */ 568 569 // Jorg is on modelindex2. Do not clear him. 570 VectorSet (self->mins, -60, -60, 0); 571 VectorSet (self->maxs, 60, 60, 72); 572 self->movetype = MOVETYPE_TOSS; 573 self->nextthink = 0; 574 gi.linkentity (self); 575 576 tempent = G_Spawn(); 577 VectorCopy (self->s.origin, tempent->s.origin); 578 VectorCopy (self->s.angles, tempent->s.angles); 579 tempent->killtarget = self->killtarget; 580 tempent->target = self->target; 581 tempent->activator = self->enemy; 582 self->killtarget = 0; 583 self->target = 0; 584 SP_monster_makron (tempent); 585 #endif 586 } 587 588 589 void jorg_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) 590 { 591 gi.sound (self, CHAN_VOICE, sound_death, 1, ATTN_NORM, 0); 592 self->deadflag = DEAD_DEAD; 593 self->takedamage = DAMAGE_NO; 594 self->s.sound = 0; 595 self->count = 0; 596 self->monsterinfo.currentmove = &jorg_move_death; 597 } 598 599 qboolean Jorg_CheckAttack (edict_t *self) 600 { 601 vec3_t spot1, spot2; 602 vec3_t temp; 603 float chance; 604 trace_t tr; 605 qboolean enemy_infront; 606 int enemy_range; 607 float enemy_yaw; 608 609 if (self->enemy->health > 0) 610 { 611 // see if any entities are in the way of the shot 612 VectorCopy (self->s.origin, spot1); 613 spot1[2] += self->viewheight; 614 VectorCopy (self->enemy->s.origin, spot2); 615 spot2[2] += self->enemy->viewheight; 616 617 tr = gi.trace (spot1, NULL, NULL, spot2, self, CONTENTS_SOLID|CONTENTS_MONSTER|CONTENTS_SLIME|CONTENTS_LAVA); 618 619 // do we have a clear shot? 620 if (tr.ent != self->enemy) 621 return false; 622 } 623 624 enemy_infront = infront(self, self->enemy); 625 enemy_range = range(self, self->enemy); 626 VectorSubtract (self->enemy->s.origin, self->s.origin, temp); 627 enemy_yaw = vectoyaw(temp); 628 629 self->ideal_yaw = enemy_yaw; 630 631 632 // melee attack 633 if (enemy_range == RANGE_MELEE) 634 { 635 if (self->monsterinfo.melee) 636 self->monsterinfo.attack_state = AS_MELEE; 637 else 638 self->monsterinfo.attack_state = AS_MISSILE; 639 return true; 640 } 641 642 // missile attack 643 if (!self->monsterinfo.attack) 644 return false; 645 646 if (level.time < self->monsterinfo.attack_finished) 647 return false; 648 649 if (enemy_range == RANGE_FAR) 650 return false; 651 652 if (self->monsterinfo.aiflags & AI_STAND_GROUND) 653 { 654 chance = 0.4; 655 } 656 else if (enemy_range == RANGE_MELEE) 657 { 658 chance = 0.8; 659 } 660 else if (enemy_range == RANGE_NEAR) 661 { 662 chance = 0.4; 663 } 664 else if (enemy_range == RANGE_MID) 665 { 666 chance = 0.2; 667 } 668 else 669 { 670 return false; 671 } 672 673 if (random () < chance) 674 { 675 self->monsterinfo.attack_state = AS_MISSILE; 676 self->monsterinfo.attack_finished = level.time + 2*random(); 677 return true; 678 } 679 680 if (self->flags & FL_FLY) 681 { 682 if (random() < 0.3) 683 self->monsterinfo.attack_state = AS_SLIDING; 684 else 685 self->monsterinfo.attack_state = AS_STRAIGHT; 686 } 687 688 return false; 689 } 690 691 692 void MakronPrecache (void); 693 694 /*QUAKED monster_jorg (1 .5 0) (-80 -80 0) (90 90 140) Ambush Trigger_Spawn Sight 695 */ 696 void SP_monster_jorg (edict_t *self) 697 { 698 if (deathmatch->value) 699 { 700 G_FreeEdict (self); 701 return; 702 } 703 704 sound_pain1 = gi.soundindex ("boss3/bs3pain1.wav"); 705 sound_pain2 = gi.soundindex ("boss3/bs3pain2.wav"); 706 sound_pain3 = gi.soundindex ("boss3/bs3pain3.wav"); 707 sound_death = gi.soundindex ("boss3/bs3deth1.wav"); 708 sound_attack1 = gi.soundindex ("boss3/bs3atck1.wav"); 709 sound_attack2 = gi.soundindex ("boss3/bs3atck2.wav"); 710 sound_search1 = gi.soundindex ("boss3/bs3srch1.wav"); 711 sound_search2 = gi.soundindex ("boss3/bs3srch2.wav"); 712 sound_search3 = gi.soundindex ("boss3/bs3srch3.wav"); 713 sound_idle = gi.soundindex ("boss3/bs3idle1.wav"); 714 sound_step_left = gi.soundindex ("boss3/step1.wav"); 715 sound_step_right = gi.soundindex ("boss3/step2.wav"); 716 sound_firegun = gi.soundindex ("boss3/xfire.wav"); 717 sound_death_hit = gi.soundindex ("boss3/d_hit.wav"); 718 719 MakronPrecache (); 720 721 self->movetype = MOVETYPE_STEP; 722 self->solid = SOLID_BBOX; 723 self->s.modelindex = gi.modelindex ("models/monsters/boss3/rider/tris.md2"); 724 self->s.modelindex2 = gi.modelindex ("models/monsters/boss3/jorg/tris.md2"); 725 VectorSet (self->mins, -80, -80, 0); 726 VectorSet (self->maxs, 80, 80, 140); 727 728 self->health = 3000; 729 self->gib_health = -2000; 730 self->mass = 1000; 731 732 self->pain = jorg_pain; 733 self->die = jorg_die; 734 self->monsterinfo.stand = jorg_stand; 735 self->monsterinfo.walk = jorg_walk; 736 self->monsterinfo.run = jorg_run; 737 self->monsterinfo.dodge = NULL; 738 self->monsterinfo.attack = jorg_attack; 739 self->monsterinfo.search = jorg_search; 740 self->monsterinfo.melee = NULL; 741 self->monsterinfo.sight = NULL; 742 self->monsterinfo.checkattack = Jorg_CheckAttack; 743 gi.linkentity (self); 744 745 self->monsterinfo.currentmove = &jorg_move_stand; 746 self->monsterinfo.scale = MODEL_SCALE; 747 748 walkmonster_start(self); 749 }