|
|
1.1 ! root 1: /* ! 2: ============================================================================== ! 3: ! 4: boss2 ! 5: ! 6: ============================================================================== ! 7: */ ! 8: ! 9: #include "g_local.h" ! 10: #include "m_boss2.h" ! 11: ! 12: void BossExplode (edict_t *self); ! 13: ! 14: qboolean infront (edict_t *self, edict_t *other); ! 15: ! 16: static int sound_pain1; ! 17: static int sound_pain2; ! 18: static int sound_pain3; ! 19: static int sound_death; ! 20: static int sound_search1; ! 21: ! 22: void boss2_search (edict_t *self) ! 23: { ! 24: if (random() < 0.5) ! 25: gi.sound (self, CHAN_VOICE, sound_search1, 1, ATTN_NONE, 0); ! 26: } ! 27: ! 28: void boss2_run (edict_t *self); ! 29: void boss2_stand (edict_t *self); ! 30: void boss2_dead (edict_t *self); ! 31: void boss2_attack (edict_t *self); ! 32: void boss2_attack_mg (edict_t *self); ! 33: void boss2_reattack_mg (edict_t *self); ! 34: void boss2_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point); ! 35: ! 36: void Boss2Rocket (edict_t *self) ! 37: { ! 38: vec3_t forward, right; ! 39: vec3_t start; ! 40: vec3_t dir; ! 41: vec3_t vec; ! 42: ! 43: AngleVectors (self->s.angles, forward, right, NULL); ! 44: ! 45: //1 ! 46: G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_BOSS2_ROCKET_1], forward, right, start); ! 47: VectorCopy (self->enemy->s.origin, vec); ! 48: vec[2] += self->enemy->viewheight; ! 49: VectorSubtract (vec, start, dir); ! 50: VectorNormalize (dir); ! 51: monster_fire_rocket (self, start, dir, 50, 500, MZ2_BOSS2_ROCKET_1); ! 52: ! 53: //2 ! 54: G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_BOSS2_ROCKET_2], forward, right, start); ! 55: VectorCopy (self->enemy->s.origin, vec); ! 56: vec[2] += self->enemy->viewheight; ! 57: VectorSubtract (vec, start, dir); ! 58: VectorNormalize (dir); ! 59: monster_fire_rocket (self, start, dir, 50, 500, MZ2_BOSS2_ROCKET_2); ! 60: ! 61: //3 ! 62: G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_BOSS2_ROCKET_3], forward, right, start); ! 63: VectorCopy (self->enemy->s.origin, vec); ! 64: vec[2] += self->enemy->viewheight; ! 65: VectorSubtract (vec, start, dir); ! 66: VectorNormalize (dir); ! 67: monster_fire_rocket (self, start, dir, 50, 500, MZ2_BOSS2_ROCKET_3); ! 68: ! 69: //4 ! 70: G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_BOSS2_ROCKET_4], forward, right, start); ! 71: VectorCopy (self->enemy->s.origin, vec); ! 72: vec[2] += self->enemy->viewheight; ! 73: VectorSubtract (vec, start, dir); ! 74: VectorNormalize (dir); ! 75: monster_fire_rocket (self, start, dir, 50, 500, MZ2_BOSS2_ROCKET_4); ! 76: } ! 77: ! 78: void boss2_firebullet_right (edict_t *self) ! 79: { ! 80: vec3_t forward, right, target; ! 81: vec3_t start; ! 82: ! 83: AngleVectors (self->s.angles, forward, right, NULL); ! 84: G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_BOSS2_MACHINEGUN_R1], forward, right, start); ! 85: ! 86: VectorMA (self->enemy->s.origin, -0.2, self->enemy->velocity, target); ! 87: target[2] += self->enemy->viewheight; ! 88: VectorSubtract (target, start, forward); ! 89: VectorNormalize (forward); ! 90: ! 91: monster_fire_bullet (self, start, forward, 6, 4, DEFAULT_BULLET_HSPREAD, DEFAULT_BULLET_VSPREAD, MZ2_BOSS2_MACHINEGUN_R1); ! 92: } ! 93: ! 94: void boss2_firebullet_left (edict_t *self) ! 95: { ! 96: vec3_t forward, right, target; ! 97: vec3_t start; ! 98: ! 99: AngleVectors (self->s.angles, forward, right, NULL); ! 100: G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_BOSS2_MACHINEGUN_L1], forward, right, start); ! 101: ! 102: VectorMA (self->enemy->s.origin, -0.2, self->enemy->velocity, target); ! 103: ! 104: target[2] += self->enemy->viewheight; ! 105: VectorSubtract (target, start, forward); ! 106: VectorNormalize (forward); ! 107: ! 108: monster_fire_bullet (self, start, forward, 6, 4, DEFAULT_BULLET_HSPREAD, DEFAULT_BULLET_VSPREAD, MZ2_BOSS2_MACHINEGUN_L1); ! 109: } ! 110: ! 111: void Boss2MachineGun (edict_t *self) ! 112: { ! 113: /* vec3_t forward, right; ! 114: vec3_t start; ! 115: vec3_t dir; ! 116: vec3_t vec; ! 117: int flash_number; ! 118: ! 119: AngleVectors (self->s.angles, forward, right, NULL); ! 120: ! 121: flash_number = MZ2_BOSS2_MACHINEGUN_1 + (self->s.frame - FRAME_attack10); ! 122: G_ProjectSource (self->s.origin, monster_flash_offset[flash_number], forward, right, start); ! 123: ! 124: VectorCopy (self->enemy->s.origin, vec); ! 125: vec[2] += self->enemy->viewheight; ! 126: VectorSubtract (vec, start, dir); ! 127: VectorNormalize (dir); ! 128: monster_fire_bullet (self, start, dir, 3, 4, DEFAULT_BULLET_HSPREAD, DEFAULT_BULLET_VSPREAD, flash_number); ! 129: */ ! 130: boss2_firebullet_left(self); ! 131: boss2_firebullet_right(self); ! 132: } ! 133: ! 134: ! 135: mframe_t boss2_frames_stand [] = ! 136: { ! 137: ai_stand, 0, NULL, ! 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: ai_stand, 0, NULL, ! 149: ai_stand, 0, NULL, ! 150: ai_stand, 0, NULL, ! 151: ai_stand, 0, NULL, ! 152: ai_stand, 0, NULL, ! 153: ai_stand, 0, NULL, ! 154: ai_stand, 0, NULL, ! 155: ai_stand, 0, NULL, ! 156: ai_stand, 0, NULL, ! 157: ai_stand, 0, NULL ! 158: }; ! 159: mmove_t boss2_move_stand = {FRAME_stand30, FRAME_stand50, boss2_frames_stand, NULL}; ! 160: ! 161: mframe_t boss2_frames_fidget [] = ! 162: { ! 163: ai_stand, 0, NULL, ! 164: ai_stand, 0, NULL, ! 165: ai_stand, 0, NULL, ! 166: ai_stand, 0, NULL, ! 167: ai_stand, 0, NULL, ! 168: ai_stand, 0, NULL, ! 169: ai_stand, 0, NULL, ! 170: ai_stand, 0, NULL, ! 171: ai_stand, 0, NULL, ! 172: ai_stand, 0, NULL, ! 173: ai_stand, 0, NULL, ! 174: ai_stand, 0, NULL, ! 175: ai_stand, 0, NULL, ! 176: ai_stand, 0, NULL, ! 177: ai_stand, 0, NULL, ! 178: ai_stand, 0, NULL, ! 179: ai_stand, 0, NULL, ! 180: ai_stand, 0, NULL, ! 181: ai_stand, 0, NULL, ! 182: ai_stand, 0, NULL, ! 183: ai_stand, 0, NULL, ! 184: ai_stand, 0, NULL, ! 185: ai_stand, 0, NULL, ! 186: ai_stand, 0, NULL, ! 187: ai_stand, 0, NULL, ! 188: ai_stand, 0, NULL, ! 189: ai_stand, 0, NULL, ! 190: ai_stand, 0, NULL, ! 191: ai_stand, 0, NULL, ! 192: ai_stand, 0, NULL ! 193: }; ! 194: mmove_t boss2_move_fidget = {FRAME_stand1, FRAME_stand30, boss2_frames_fidget, NULL}; ! 195: ! 196: mframe_t boss2_frames_walk [] = ! 197: { ! 198: ai_walk, 8, NULL, ! 199: ai_walk, 8, NULL, ! 200: ai_walk, 8, NULL, ! 201: ai_walk, 8, NULL, ! 202: ai_walk, 8, NULL, ! 203: ai_walk, 8, NULL, ! 204: ai_walk, 8, NULL, ! 205: ai_walk, 8, NULL, ! 206: ai_walk, 8, NULL, ! 207: ai_walk, 8, NULL, ! 208: ai_walk, 8, NULL, ! 209: ai_walk, 8, NULL, ! 210: ai_walk, 8, NULL, ! 211: ai_walk, 8, NULL, ! 212: ai_walk, 8, NULL, ! 213: ai_walk, 8, NULL, ! 214: ai_walk, 8, NULL, ! 215: ai_walk, 8, NULL, ! 216: ai_walk, 8, NULL, ! 217: ai_walk, 8, NULL ! 218: }; ! 219: mmove_t boss2_move_walk = {FRAME_walk1, FRAME_walk20, boss2_frames_walk, NULL}; ! 220: ! 221: ! 222: mframe_t boss2_frames_run [] = ! 223: { ! 224: ai_run, 8, NULL, ! 225: ai_run, 8, NULL, ! 226: ai_run, 8, NULL, ! 227: ai_run, 8, NULL, ! 228: ai_run, 8, NULL, ! 229: ai_run, 8, NULL, ! 230: ai_run, 8, NULL, ! 231: ai_run, 8, NULL, ! 232: ai_run, 8, NULL, ! 233: ai_run, 8, NULL, ! 234: ai_run, 8, NULL, ! 235: ai_run, 8, NULL, ! 236: ai_run, 8, NULL, ! 237: ai_run, 8, NULL, ! 238: ai_run, 8, NULL, ! 239: ai_run, 8, NULL, ! 240: ai_run, 8, NULL, ! 241: ai_run, 8, NULL, ! 242: ai_run, 8, NULL, ! 243: ai_run, 8, NULL ! 244: }; ! 245: mmove_t boss2_move_run = {FRAME_walk1, FRAME_walk20, boss2_frames_run, NULL}; ! 246: ! 247: mframe_t boss2_frames_attack_pre_mg [] = ! 248: { ! 249: ai_charge, 1, NULL, ! 250: ai_charge, 1, NULL, ! 251: ai_charge, 1, NULL, ! 252: ai_charge, 1, NULL, ! 253: ai_charge, 1, NULL, ! 254: ai_charge, 1, NULL, ! 255: ai_charge, 1, NULL, ! 256: ai_charge, 1, NULL, ! 257: ai_charge, 1, boss2_attack_mg ! 258: }; ! 259: mmove_t boss2_move_attack_pre_mg = {FRAME_attack1, FRAME_attack9, boss2_frames_attack_pre_mg, NULL}; ! 260: ! 261: ! 262: // Loop this ! 263: mframe_t boss2_frames_attack_mg [] = ! 264: { ! 265: ai_charge, 1, Boss2MachineGun, ! 266: ai_charge, 1, Boss2MachineGun, ! 267: ai_charge, 1, Boss2MachineGun, ! 268: ai_charge, 1, Boss2MachineGun, ! 269: ai_charge, 1, Boss2MachineGun, ! 270: ai_charge, 1, boss2_reattack_mg ! 271: }; ! 272: mmove_t boss2_move_attack_mg = {FRAME_attack10, FRAME_attack15, boss2_frames_attack_mg, NULL}; ! 273: ! 274: mframe_t boss2_frames_attack_post_mg [] = ! 275: { ! 276: ai_charge, 1, NULL, ! 277: ai_charge, 1, NULL, ! 278: ai_charge, 1, NULL, ! 279: ai_charge, 1, NULL ! 280: }; ! 281: mmove_t boss2_move_attack_post_mg = {FRAME_attack16, FRAME_attack19, boss2_frames_attack_post_mg, boss2_run}; ! 282: ! 283: mframe_t boss2_frames_attack_rocket [] = ! 284: { ! 285: ai_charge, 1, NULL, ! 286: ai_charge, 1, NULL, ! 287: ai_charge, 1, NULL, ! 288: ai_charge, 1, NULL, ! 289: ai_charge, 1, NULL, ! 290: ai_charge, 1, NULL, ! 291: ai_charge, 1, NULL, ! 292: ai_charge, 1, NULL, ! 293: ai_charge, 1, NULL, ! 294: ai_charge, 1, NULL, ! 295: ai_charge, 1, NULL, ! 296: ai_charge, 1, NULL, ! 297: ai_move, -20, Boss2Rocket, ! 298: ai_charge, 1, NULL, ! 299: ai_charge, 1, NULL, ! 300: ai_charge, 1, NULL, ! 301: ai_charge, 1, NULL, ! 302: ai_charge, 1, NULL, ! 303: ai_charge, 1, NULL, ! 304: ai_charge, 1, NULL, ! 305: ai_charge, 1, NULL ! 306: }; ! 307: mmove_t boss2_move_attack_rocket = {FRAME_attack20, FRAME_attack40, boss2_frames_attack_rocket, boss2_run}; ! 308: ! 309: mframe_t boss2_frames_pain_heavy [] = ! 310: { ! 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, ! 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: }; ! 330: mmove_t boss2_move_pain_heavy = {FRAME_pain2, FRAME_pain19, boss2_frames_pain_heavy, boss2_run}; ! 331: ! 332: mframe_t boss2_frames_pain_light [] = ! 333: { ! 334: ai_move, 0, NULL, ! 335: ai_move, 0, NULL, ! 336: ai_move, 0, NULL, ! 337: ai_move, 0, NULL ! 338: }; ! 339: mmove_t boss2_move_pain_light = {FRAME_pain20, FRAME_pain23, boss2_frames_pain_light, boss2_run}; ! 340: ! 341: mframe_t boss2_frames_death [] = ! 342: { ! 343: ai_move, 0, NULL, ! 344: ai_move, 0, NULL, ! 345: ai_move, 0, NULL, ! 346: ai_move, 0, NULL, ! 347: ai_move, 0, NULL, ! 348: ai_move, 0, NULL, ! 349: ai_move, 0, NULL, ! 350: ai_move, 0, NULL, ! 351: ai_move, 0, NULL, ! 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: ai_move, 0, NULL, ! 359: ai_move, 0, NULL, ! 360: ai_move, 0, NULL, ! 361: ai_move, 0, 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: ai_move, 0, NULL, ! 377: ai_move, 0, NULL, ! 378: ai_move, 0, NULL, ! 379: ai_move, 0, NULL, ! 380: ai_move, 0, 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, BossExplode ! 392: }; ! 393: mmove_t boss2_move_death = {FRAME_death2, FRAME_death50, boss2_frames_death, boss2_dead}; ! 394: ! 395: void boss2_stand (edict_t *self) ! 396: { ! 397: self->monsterinfo.currentmove = &boss2_move_stand; ! 398: } ! 399: ! 400: void boss2_run (edict_t *self) ! 401: { ! 402: if (self->monsterinfo.aiflags & AI_STAND_GROUND) ! 403: self->monsterinfo.currentmove = &boss2_move_stand; ! 404: else ! 405: self->monsterinfo.currentmove = &boss2_move_run; ! 406: } ! 407: ! 408: void boss2_walk (edict_t *self) ! 409: { ! 410: self->monsterinfo.currentmove = &boss2_move_walk; ! 411: } ! 412: ! 413: void boss2_attack (edict_t *self) ! 414: { ! 415: vec3_t vec; ! 416: float range; ! 417: ! 418: VectorSubtract (self->enemy->s.origin, self->s.origin, vec); ! 419: range = VectorLength (vec); ! 420: ! 421: if (range <= 125) ! 422: { ! 423: self->monsterinfo.currentmove = &boss2_move_attack_pre_mg; ! 424: } ! 425: else ! 426: { ! 427: if (random() <= 0.6) ! 428: self->monsterinfo.currentmove = &boss2_move_attack_pre_mg; ! 429: else ! 430: self->monsterinfo.currentmove = &boss2_move_attack_rocket; ! 431: } ! 432: } ! 433: ! 434: void boss2_attack_mg (edict_t *self) ! 435: { ! 436: self->monsterinfo.currentmove = &boss2_move_attack_mg; ! 437: } ! 438: ! 439: void boss2_reattack_mg (edict_t *self) ! 440: { ! 441: if ( infront(self, self->enemy) ) ! 442: if (random() <= 0.7) ! 443: self->monsterinfo.currentmove = &boss2_move_attack_mg; ! 444: else ! 445: self->monsterinfo.currentmove = &boss2_move_attack_post_mg; ! 446: else ! 447: self->monsterinfo.currentmove = &boss2_move_attack_post_mg; ! 448: } ! 449: ! 450: ! 451: void boss2_pain (edict_t *self, edict_t *other, float kick, int damage) ! 452: { ! 453: if (self->health < (self->max_health / 2)) ! 454: self->s.skinnum = 1; ! 455: ! 456: if (level.time < self->pain_debounce_time) ! 457: return; ! 458: ! 459: self->pain_debounce_time = level.time + 3; ! 460: // American wanted these at no attenuation ! 461: if (damage < 10) ! 462: { ! 463: gi.sound (self, CHAN_VOICE, sound_pain3, 1, ATTN_NONE, 0); ! 464: self->monsterinfo.currentmove = &boss2_move_pain_light; ! 465: } ! 466: else if (damage < 30) ! 467: { ! 468: gi.sound (self, CHAN_VOICE, sound_pain1, 1, ATTN_NONE, 0); ! 469: self->monsterinfo.currentmove = &boss2_move_pain_light; ! 470: } ! 471: else ! 472: { ! 473: gi.sound (self, CHAN_VOICE, sound_pain2, 1, ATTN_NONE, 0); ! 474: self->monsterinfo.currentmove = &boss2_move_pain_heavy; ! 475: } ! 476: } ! 477: ! 478: void boss2_dead (edict_t *self) ! 479: { ! 480: VectorSet (self->mins, -56, -56, 0); ! 481: VectorSet (self->maxs, 56, 56, 80); ! 482: self->movetype = MOVETYPE_TOSS; ! 483: self->svflags |= SVF_DEADMONSTER; ! 484: self->nextthink = 0; ! 485: gi.linkentity (self); ! 486: } ! 487: ! 488: void boss2_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) ! 489: { ! 490: gi.sound (self, CHAN_VOICE, sound_death, 1, ATTN_NONE, 0); ! 491: self->deadflag = DEAD_DEAD; ! 492: self->takedamage = DAMAGE_NO; ! 493: self->count = 0; ! 494: self->monsterinfo.currentmove = &boss2_move_death; ! 495: #if 0 ! 496: int n; ! 497: ! 498: self->s.sound = 0; ! 499: // check for gib ! 500: if (self->health <= self->gib_health) ! 501: { ! 502: gi.sound (self, CHAN_VOICE, gi.soundindex ("misc/udeath.wav"), 1, ATTN_NORM, 0); ! 503: for (n= 0; n < 2; n++) ! 504: ThrowGib (self, "models/objects/gibs/bone/tris.md2", damage, GIB_ORGANIC); ! 505: for (n= 0; n < 4; n++) ! 506: ThrowGib (self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC); ! 507: ThrowHead (self, "models/objects/gibs/head2/tris.md2", damage, GIB_ORGANIC); ! 508: self->deadflag = DEAD_DEAD; ! 509: return; ! 510: } ! 511: ! 512: if (self->deadflag == DEAD_DEAD) ! 513: return; ! 514: ! 515: self->deadflag = DEAD_DEAD; ! 516: self->takedamage = DAMAGE_YES; ! 517: self->monsterinfo.currentmove = &boss2_move_death; ! 518: #endif ! 519: } ! 520: ! 521: qboolean Boss2_CheckAttack (edict_t *self) ! 522: { ! 523: vec3_t spot1, spot2; ! 524: vec3_t temp; ! 525: float chance; ! 526: trace_t tr; ! 527: qboolean enemy_infront; ! 528: int enemy_range; ! 529: float enemy_yaw; ! 530: ! 531: if (self->enemy->health > 0) ! 532: { ! 533: // see if any entities are in the way of the shot ! 534: VectorCopy (self->s.origin, spot1); ! 535: spot1[2] += self->viewheight; ! 536: VectorCopy (self->enemy->s.origin, spot2); ! 537: spot2[2] += self->enemy->viewheight; ! 538: ! 539: tr = gi.trace (spot1, NULL, NULL, spot2, self, CONTENTS_SOLID|CONTENTS_MONSTER|CONTENTS_SLIME|CONTENTS_LAVA); ! 540: ! 541: // do we have a clear shot? ! 542: if (tr.ent != self->enemy) ! 543: return false; ! 544: } ! 545: ! 546: enemy_infront = infront(self, self->enemy); ! 547: enemy_range = range(self, self->enemy); ! 548: VectorSubtract (self->enemy->s.origin, self->s.origin, temp); ! 549: enemy_yaw = vectoyaw(temp); ! 550: ! 551: self->ideal_yaw = enemy_yaw; ! 552: ! 553: ! 554: // melee attack ! 555: if (enemy_range == RANGE_MELEE) ! 556: { ! 557: if (self->monsterinfo.melee) ! 558: self->monsterinfo.attack_state = AS_MELEE; ! 559: else ! 560: self->monsterinfo.attack_state = AS_MISSILE; ! 561: return true; ! 562: } ! 563: ! 564: // missile attack ! 565: if (!self->monsterinfo.attack) ! 566: return false; ! 567: ! 568: if (level.time < self->monsterinfo.attack_finished) ! 569: return false; ! 570: ! 571: if (enemy_range == RANGE_FAR) ! 572: return false; ! 573: ! 574: if (self->monsterinfo.aiflags & AI_STAND_GROUND) ! 575: { ! 576: chance = 0.4; ! 577: } ! 578: else if (enemy_range == RANGE_MELEE) ! 579: { ! 580: chance = 0.8; ! 581: } ! 582: else if (enemy_range == RANGE_NEAR) ! 583: { ! 584: chance = 0.8; ! 585: } ! 586: else if (enemy_range == RANGE_MID) ! 587: { ! 588: chance = 0.8; ! 589: } ! 590: else ! 591: { ! 592: return false; ! 593: } ! 594: ! 595: if (random () < chance) ! 596: { ! 597: self->monsterinfo.attack_state = AS_MISSILE; ! 598: self->monsterinfo.attack_finished = level.time + 2*random(); ! 599: return true; ! 600: } ! 601: ! 602: if (self->flags & FL_FLY) ! 603: { ! 604: if (random() < 0.3) ! 605: self->monsterinfo.attack_state = AS_SLIDING; ! 606: else ! 607: self->monsterinfo.attack_state = AS_STRAIGHT; ! 608: } ! 609: ! 610: return false; ! 611: } ! 612: ! 613: ! 614: ! 615: /*QUAKED monster_boss2 (1 .5 0) (-56 -56 0) (56 56 80) Ambush Trigger_Spawn Sight ! 616: */ ! 617: void SP_monster_boss2 (edict_t *self) ! 618: { ! 619: if (deathmatch->value) ! 620: { ! 621: G_FreeEdict (self); ! 622: return; ! 623: } ! 624: ! 625: sound_pain1 = gi.soundindex ("bosshovr/bhvpain1.wav"); ! 626: sound_pain2 = gi.soundindex ("bosshovr/bhvpain2.wav"); ! 627: sound_pain3 = gi.soundindex ("bosshovr/bhvpain3.wav"); ! 628: sound_death = gi.soundindex ("bosshovr/bhvdeth1.wav"); ! 629: sound_search1 = gi.soundindex ("bosshovr/bhvunqv1.wav"); ! 630: ! 631: self->s.sound = gi.soundindex ("bosshovr/bhvengn1.wav"); ! 632: ! 633: self->movetype = MOVETYPE_STEP; ! 634: self->solid = SOLID_BBOX; ! 635: self->s.modelindex = gi.modelindex ("models/monsters/boss2/tris.md2"); ! 636: VectorSet (self->mins, -56, -56, 0); ! 637: VectorSet (self->maxs, 56, 56, 80); ! 638: ! 639: self->health = 2000; ! 640: self->gib_health = -200; ! 641: self->mass = 1000; ! 642: ! 643: self->flags |= FL_IMMUNE_LASER; ! 644: ! 645: self->pain = boss2_pain; ! 646: self->die = boss2_die; ! 647: ! 648: self->monsterinfo.stand = boss2_stand; ! 649: self->monsterinfo.walk = boss2_walk; ! 650: self->monsterinfo.run = boss2_run; ! 651: self->monsterinfo.attack = boss2_attack; ! 652: self->monsterinfo.search = boss2_search; ! 653: self->monsterinfo.checkattack = Boss2_CheckAttack; ! 654: gi.linkentity (self); ! 655: ! 656: self->monsterinfo.currentmove = &boss2_move_stand; ! 657: self->monsterinfo.scale = MODEL_SCALE; ! 658: ! 659: flymonster_start (self); ! 660: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.