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