|
|
1.1 ! root 1: /* ! 2: ============================================================================== ! 3: ! 4: INFANTRY ! 5: ! 6: ============================================================================== ! 7: */ ! 8: ! 9: #include "g_local.h" ! 10: #include "m_infantry.h" ! 11: ! 12: void InfantryMachineGun (edict_t *self); ! 13: ! 14: ! 15: static int sound_pain1; ! 16: static int sound_pain2; ! 17: static int sound_die1; ! 18: static int sound_die2; ! 19: ! 20: static int sound_gunshot; ! 21: static int sound_weapon_cock; ! 22: static int sound_punch_swing; ! 23: static int sound_punch_hit; ! 24: static int sound_sight; ! 25: static int sound_search; ! 26: static int sound_idle; ! 27: ! 28: mframe_t infantry_frames_stand [] = ! 29: { ! 30: ai_stand, 0, NULL, ! 31: ai_stand, 0, NULL, ! 32: ai_stand, 0, NULL, ! 33: ai_stand, 0, NULL, ! 34: ai_stand, 0, NULL, ! 35: ai_stand, 0, NULL, ! 36: ai_stand, 0, NULL, ! 37: ai_stand, 0, NULL, ! 38: ai_stand, 0, NULL, ! 39: ai_stand, 0, NULL, ! 40: ai_stand, 0, NULL, ! 41: ai_stand, 0, NULL, ! 42: ai_stand, 0, NULL, ! 43: ai_stand, 0, NULL, ! 44: ai_stand, 0, NULL, ! 45: ai_stand, 0, NULL, ! 46: ai_stand, 0, NULL, ! 47: ai_stand, 0, NULL, ! 48: ai_stand, 0, NULL, ! 49: ai_stand, 0, NULL, ! 50: ai_stand, 0, NULL, ! 51: ai_stand, 0, NULL ! 52: }; ! 53: mmove_t infantry_move_stand = {FRAME_stand50, FRAME_stand71, infantry_frames_stand, NULL}; ! 54: ! 55: void infantry_stand (edict_t *self) ! 56: { ! 57: self->monsterinfo.currentmove = &infantry_move_stand; ! 58: } ! 59: ! 60: ! 61: mframe_t infantry_frames_fidget [] = ! 62: { ! 63: ai_stand, 1, NULL, ! 64: ai_stand, 0, NULL, ! 65: ai_stand, 1, NULL, ! 66: ai_stand, 3, NULL, ! 67: ai_stand, 6, NULL, ! 68: ai_stand, 3, NULL, ! 69: ai_stand, 0, NULL, ! 70: ai_stand, 0, NULL, ! 71: ai_stand, 0, NULL, ! 72: ai_stand, 0, NULL, ! 73: ai_stand, 1, NULL, ! 74: ai_stand, 0, NULL, ! 75: ai_stand, 0, NULL, ! 76: ai_stand, 0, NULL, ! 77: ai_stand, 0, NULL, ! 78: ai_stand, 1, NULL, ! 79: ai_stand, 0, NULL, ! 80: ai_stand, -1, NULL, ! 81: ai_stand, 0, NULL, ! 82: ai_stand, 0, NULL, ! 83: ai_stand, 1, NULL, ! 84: ai_stand, 0, NULL, ! 85: ai_stand, -2, NULL, ! 86: ai_stand, 1, NULL, ! 87: ai_stand, 1, NULL, ! 88: ai_stand, 1, NULL, ! 89: ai_stand, -1, NULL, ! 90: ai_stand, 0, NULL, ! 91: ai_stand, 0, NULL, ! 92: ai_stand, -1, 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, -1, NULL, ! 99: ai_stand, 0, NULL, ! 100: ai_stand, 0, NULL, ! 101: ai_stand, 1, NULL, ! 102: ai_stand, 0, NULL, ! 103: ai_stand, 0, NULL, ! 104: ai_stand, -1, NULL, ! 105: ai_stand, -1, NULL, ! 106: ai_stand, 0, NULL, ! 107: ai_stand, -3, NULL, ! 108: ai_stand, -2, NULL, ! 109: ai_stand, -3, NULL, ! 110: ai_stand, -3, NULL, ! 111: ai_stand, -2, NULL ! 112: }; ! 113: mmove_t infantry_move_fidget = {FRAME_stand01, FRAME_stand49, infantry_frames_fidget, infantry_stand}; ! 114: ! 115: void infantry_fidget (edict_t *self) ! 116: { ! 117: self->monsterinfo.currentmove = &infantry_move_fidget; ! 118: gi.sound (self, CHAN_VOICE, sound_idle, 1, ATTN_IDLE, 0); ! 119: } ! 120: ! 121: mframe_t infantry_frames_walk [] = ! 122: { ! 123: ai_walk, 5, NULL, ! 124: ai_walk, 4, NULL, ! 125: ai_walk, 4, NULL, ! 126: ai_walk, 5, NULL, ! 127: ai_walk, 4, NULL, ! 128: ai_walk, 5, NULL, ! 129: ai_walk, 6, NULL, ! 130: ai_walk, 4, NULL, ! 131: ai_walk, 4, NULL, ! 132: ai_walk, 4, NULL, ! 133: ai_walk, 4, NULL, ! 134: ai_walk, 5, NULL ! 135: }; ! 136: mmove_t infantry_move_walk = {FRAME_walk03, FRAME_walk14, infantry_frames_walk, NULL}; ! 137: ! 138: void infantry_walk (edict_t *self) ! 139: { ! 140: self->monsterinfo.currentmove = &infantry_move_walk; ! 141: } ! 142: ! 143: mframe_t infantry_frames_run [] = ! 144: { ! 145: ai_run, 10, NULL, ! 146: ai_run, 20, NULL, ! 147: ai_run, 5, NULL, ! 148: ai_run, 7, monster_done_dodge, ! 149: ai_run, 30, NULL, ! 150: ai_run, 35, NULL, ! 151: ai_run, 2, NULL, ! 152: ai_run, 6, NULL ! 153: }; ! 154: mmove_t infantry_move_run = {FRAME_run01, FRAME_run08, infantry_frames_run, NULL}; ! 155: ! 156: void infantry_run (edict_t *self) ! 157: { ! 158: monster_done_dodge (self); ! 159: ! 160: if (self->monsterinfo.aiflags & AI_STAND_GROUND) ! 161: self->monsterinfo.currentmove = &infantry_move_stand; ! 162: else ! 163: self->monsterinfo.currentmove = &infantry_move_run; ! 164: } ! 165: ! 166: ! 167: mframe_t infantry_frames_pain1 [] = ! 168: { ! 169: ai_move, -3, NULL, ! 170: ai_move, -2, NULL, ! 171: ai_move, -1, NULL, ! 172: ai_move, -2, NULL, ! 173: ai_move, -1, NULL, ! 174: ai_move, 1, NULL, ! 175: ai_move, -1, NULL, ! 176: ai_move, 1, NULL, ! 177: ai_move, 6, NULL, ! 178: ai_move, 2, NULL ! 179: }; ! 180: mmove_t infantry_move_pain1 = {FRAME_pain101, FRAME_pain110, infantry_frames_pain1, infantry_run}; ! 181: ! 182: mframe_t infantry_frames_pain2 [] = ! 183: { ! 184: ai_move, -3, NULL, ! 185: ai_move, -3, NULL, ! 186: ai_move, 0, NULL, ! 187: ai_move, -1, NULL, ! 188: ai_move, -2, NULL, ! 189: ai_move, 0, NULL, ! 190: ai_move, 0, NULL, ! 191: ai_move, 2, NULL, ! 192: ai_move, 5, NULL, ! 193: ai_move, 2, NULL ! 194: }; ! 195: mmove_t infantry_move_pain2 = {FRAME_pain201, FRAME_pain210, infantry_frames_pain2, infantry_run}; ! 196: ! 197: void infantry_pain (edict_t *self, edict_t *other, float kick, int damage) ! 198: { ! 199: int n; ! 200: ! 201: if (self->health < (self->max_health / 2)) ! 202: self->s.skinnum = 1; ! 203: ! 204: if (!self->groundentity) ! 205: { ! 206: if ((g_showlogic) && (g_showlogic->value)) ! 207: gi.dprintf ("infantry: pain avoided due to no ground\n"); ! 208: return; ! 209: } ! 210: ! 211: monster_done_dodge (self); ! 212: ! 213: if (level.time < self->pain_debounce_time) ! 214: return; ! 215: ! 216: self->pain_debounce_time = level.time + 3; ! 217: ! 218: if (skill->value == 3) ! 219: return; // no pain anims in nightmare ! 220: ! 221: n = rand() % 2; ! 222: if (n == 0) ! 223: { ! 224: self->monsterinfo.currentmove = &infantry_move_pain1; ! 225: gi.sound (self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0); ! 226: } ! 227: else ! 228: { ! 229: self->monsterinfo.currentmove = &infantry_move_pain2; ! 230: gi.sound (self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0); ! 231: } ! 232: ! 233: // PMM - clear duck flag ! 234: if (self->monsterinfo.aiflags & AI_DUCKED) ! 235: monster_duck_up(self); ! 236: } ! 237: ! 238: ! 239: vec3_t aimangles[] = ! 240: { ! 241: 0.0, 5.0, 0.0, ! 242: 10.0, 15.0, 0.0, ! 243: 20.0, 25.0, 0.0, ! 244: 25.0, 35.0, 0.0, ! 245: 30.0, 40.0, 0.0, ! 246: 30.0, 45.0, 0.0, ! 247: 25.0, 50.0, 0.0, ! 248: 20.0, 40.0, 0.0, ! 249: 15.0, 35.0, 0.0, ! 250: 40.0, 35.0, 0.0, ! 251: 70.0, 35.0, 0.0, ! 252: 90.0, 35.0, 0.0 ! 253: }; ! 254: ! 255: void InfantryMachineGun (edict_t *self) ! 256: { ! 257: vec3_t start, target; ! 258: vec3_t forward, right; ! 259: vec3_t vec; ! 260: int flash_number; ! 261: ! 262: if(!self->enemy || !self->enemy->inuse) //PGM ! 263: return; //PGM ! 264: ! 265: // pmm - new attack start frame ! 266: if (self->s.frame == FRAME_attak104) ! 267: { ! 268: flash_number = MZ2_INFANTRY_MACHINEGUN_1; ! 269: AngleVectors (self->s.angles, forward, right, NULL); ! 270: G_ProjectSource (self->s.origin, monster_flash_offset[flash_number], forward, right, start); ! 271: ! 272: if (self->enemy) ! 273: { ! 274: VectorMA (self->enemy->s.origin, -0.2, self->enemy->velocity, target); ! 275: target[2] += self->enemy->viewheight; ! 276: VectorSubtract (target, start, forward); ! 277: VectorNormalize (forward); ! 278: } ! 279: else ! 280: { ! 281: AngleVectors (self->s.angles, forward, right, NULL); ! 282: } ! 283: } ! 284: else ! 285: { ! 286: flash_number = MZ2_INFANTRY_MACHINEGUN_2 + (self->s.frame - FRAME_death211); ! 287: ! 288: AngleVectors (self->s.angles, forward, right, NULL); ! 289: G_ProjectSource (self->s.origin, monster_flash_offset[flash_number], forward, right, start); ! 290: ! 291: VectorSubtract (self->s.angles, aimangles[flash_number-MZ2_INFANTRY_MACHINEGUN_2], vec); ! 292: AngleVectors (vec, forward, NULL, NULL); ! 293: } ! 294: ! 295: monster_fire_bullet (self, start, forward, 3, 4, DEFAULT_BULLET_HSPREAD, DEFAULT_BULLET_VSPREAD, flash_number); ! 296: } ! 297: ! 298: void infantry_sight (edict_t *self, edict_t *other) ! 299: { ! 300: gi.sound (self, CHAN_BODY, sound_sight, 1, ATTN_NORM, 0); ! 301: } ! 302: ! 303: void infantry_dead (edict_t *self) ! 304: { ! 305: VectorSet (self->mins, -16, -16, -24); ! 306: VectorSet (self->maxs, 16, 16, -8); ! 307: self->movetype = MOVETYPE_TOSS; ! 308: self->svflags |= SVF_DEADMONSTER; ! 309: gi.linkentity (self); ! 310: ! 311: M_FlyCheck (self); ! 312: } ! 313: ! 314: mframe_t infantry_frames_death1 [] = ! 315: { ! 316: ai_move, -4, NULL, ! 317: ai_move, 0, NULL, ! 318: ai_move, 0, NULL, ! 319: ai_move, -1, NULL, ! 320: ai_move, -4, NULL, ! 321: ai_move, 0, NULL, ! 322: ai_move, 0, NULL, ! 323: ai_move, 0, NULL, ! 324: ai_move, -1, NULL, ! 325: ai_move, 3, NULL, ! 326: ai_move, 1, NULL, ! 327: ai_move, 1, NULL, ! 328: ai_move, -2, NULL, ! 329: ai_move, 2, NULL, ! 330: ai_move, 2, NULL, ! 331: ai_move, 9, NULL, ! 332: ai_move, 9, NULL, ! 333: ai_move, 5, NULL, ! 334: ai_move, -3, NULL, ! 335: ai_move, -3, NULL ! 336: }; ! 337: mmove_t infantry_move_death1 = {FRAME_death101, FRAME_death120, infantry_frames_death1, infantry_dead}; ! 338: ! 339: // Off with his head ! 340: mframe_t infantry_frames_death2 [] = ! 341: { ! 342: ai_move, 0, NULL, ! 343: ai_move, 1, NULL, ! 344: ai_move, 5, NULL, ! 345: ai_move, -1, NULL, ! 346: ai_move, 0, NULL, ! 347: ai_move, 1, NULL, ! 348: ai_move, 1, NULL, ! 349: ai_move, 4, NULL, ! 350: ai_move, 3, NULL, ! 351: ai_move, 0, NULL, ! 352: ai_move, -2, InfantryMachineGun, ! 353: ai_move, -2, InfantryMachineGun, ! 354: ai_move, -3, InfantryMachineGun, ! 355: ai_move, -1, InfantryMachineGun, ! 356: ai_move, -2, InfantryMachineGun, ! 357: ai_move, 0, InfantryMachineGun, ! 358: ai_move, 2, InfantryMachineGun, ! 359: ai_move, 2, InfantryMachineGun, ! 360: ai_move, 3, InfantryMachineGun, ! 361: ai_move, -10, InfantryMachineGun, ! 362: ai_move, -7, InfantryMachineGun, ! 363: ai_move, -8, InfantryMachineGun, ! 364: ai_move, -6, NULL, ! 365: ai_move, 4, NULL, ! 366: ai_move, 0, NULL ! 367: }; ! 368: mmove_t infantry_move_death2 = {FRAME_death201, FRAME_death225, infantry_frames_death2, infantry_dead}; ! 369: ! 370: mframe_t infantry_frames_death3 [] = ! 371: { ! 372: ai_move, 0, NULL, ! 373: ai_move, 0, NULL, ! 374: ai_move, 0, NULL, ! 375: ai_move, -6, NULL, ! 376: ai_move, -11, NULL, ! 377: ai_move, -3, NULL, ! 378: ai_move, -11, NULL, ! 379: ai_move, 0, NULL, ! 380: ai_move, 0, NULL ! 381: }; ! 382: mmove_t infantry_move_death3 = {FRAME_death301, FRAME_death309, infantry_frames_death3, infantry_dead}; ! 383: ! 384: ! 385: void infantry_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) ! 386: { ! 387: int n; ! 388: ! 389: // check for gib ! 390: if (self->health <= self->gib_health) ! 391: { ! 392: gi.sound (self, CHAN_VOICE, gi.soundindex ("misc/udeath.wav"), 1, ATTN_NORM, 0); ! 393: for (n= 0; n < 2; n++) ! 394: ThrowGib (self, "models/objects/gibs/bone/tris.md2", damage, GIB_ORGANIC); ! 395: for (n= 0; n < 4; n++) ! 396: ThrowGib (self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC); ! 397: ThrowHead (self, "models/objects/gibs/head2/tris.md2", damage, GIB_ORGANIC); ! 398: self->deadflag = DEAD_DEAD; ! 399: return; ! 400: } ! 401: ! 402: if (self->deadflag == DEAD_DEAD) ! 403: return; ! 404: ! 405: // regular death ! 406: self->deadflag = DEAD_DEAD; ! 407: self->takedamage = DAMAGE_YES; ! 408: ! 409: n = rand() % 3; ! 410: if (n == 0) ! 411: { ! 412: self->monsterinfo.currentmove = &infantry_move_death1; ! 413: gi.sound (self, CHAN_VOICE, sound_die2, 1, ATTN_NORM, 0); ! 414: } ! 415: else if (n == 1) ! 416: { ! 417: self->monsterinfo.currentmove = &infantry_move_death2; ! 418: gi.sound (self, CHAN_VOICE, sound_die1, 1, ATTN_NORM, 0); ! 419: } ! 420: else ! 421: { ! 422: self->monsterinfo.currentmove = &infantry_move_death3; ! 423: gi.sound (self, CHAN_VOICE, sound_die2, 1, ATTN_NORM, 0); ! 424: } ! 425: } ! 426: ! 427: mframe_t infantry_frames_duck [] = ! 428: { ! 429: ai_move, -2, monster_duck_down, ! 430: ai_move, -5, monster_duck_hold, ! 431: ai_move, 3, NULL, ! 432: ai_move, 4, monster_duck_up, ! 433: ai_move, 0, NULL ! 434: }; ! 435: mmove_t infantry_move_duck = {FRAME_duck01, FRAME_duck05, infantry_frames_duck, infantry_run}; ! 436: ! 437: // PMM - dodge code moved below so I can see the attack frames ! 438: ! 439: ! 440: void infantry_cock_gun (edict_t *self) ! 441: { ! 442: // pmm .. code that was here no longer needed ! 443: gi.sound (self, CHAN_WEAPON, sound_weapon_cock, 1, ATTN_NORM, 0); ! 444: } ! 445: ! 446: void infantry_fire (edict_t *self) ! 447: { ! 448: InfantryMachineGun (self); ! 449: if (level.time >= self->monsterinfo.pausetime) ! 450: self->monsterinfo.aiflags &= ~AI_HOLD_FRAME; ! 451: else ! 452: self->monsterinfo.aiflags |= AI_HOLD_FRAME; ! 453: } ! 454: ! 455: // this is here instead of cock_gun ! 456: ! 457: void infantry_fire_prep (edict_t *self) ! 458: { ! 459: int n; ! 460: n = (rand() & 15) + 3 + 1; ! 461: self->monsterinfo.pausetime = level.time + n*FRAMETIME; ! 462: } ! 463: ! 464: // pmm ! 465: // frames reordered, tweaked for new frames ! 466: ! 467: mframe_t infantry_frames_attack1 [] = ! 468: { ! 469: ai_charge, -3, NULL, //101 ! 470: ai_charge, -2, NULL, //102 ! 471: ai_charge, -1, infantry_fire_prep, //103 ! 472: ai_charge, 5, infantry_fire, //104 ! 473: ai_charge, 1, NULL, //105 ! 474: ai_charge, -3, NULL, //106 ! 475: ai_charge, -2, NULL, //107 ! 476: ai_charge, 2, infantry_cock_gun, //108 ! 477: ai_charge, 1, NULL, //109 ! 478: ai_charge, 1, NULL, //110 ! 479: ai_charge, -1, NULL, //111 ! 480: ai_charge, 0, NULL, //112 ! 481: ai_charge, -1, NULL, //113 ! 482: ai_charge, -1, NULL, //114 ! 483: ai_charge, 4, NULL //115 ! 484: }; ! 485: mmove_t infantry_move_attack1 = {FRAME_attak101, FRAME_attak115, infantry_frames_attack1, infantry_run}; ! 486: ! 487: ! 488: void infantry_swing (edict_t *self) ! 489: { ! 490: gi.sound (self, CHAN_WEAPON, sound_punch_swing, 1, ATTN_NORM, 0); ! 491: } ! 492: ! 493: void infantry_smack (edict_t *self) ! 494: { ! 495: vec3_t aim; ! 496: ! 497: VectorSet (aim, MELEE_DISTANCE, 0, 0); ! 498: if (fire_hit (self, aim, (5 + (rand() % 5)), 50)) ! 499: gi.sound (self, CHAN_WEAPON, sound_punch_hit, 1, ATTN_NORM, 0); ! 500: } ! 501: ! 502: mframe_t infantry_frames_attack2 [] = ! 503: { ! 504: ai_charge, 3, NULL, ! 505: ai_charge, 6, NULL, ! 506: ai_charge, 0, infantry_swing, ! 507: ai_charge, 8, NULL, ! 508: ai_charge, 5, NULL, ! 509: ai_charge, 8, infantry_smack, ! 510: ai_charge, 6, NULL, ! 511: ai_charge, 3, NULL, ! 512: }; ! 513: mmove_t infantry_move_attack2 = {FRAME_attak201, FRAME_attak208, infantry_frames_attack2, infantry_run}; ! 514: ! 515: void infantry_attack(edict_t *self) ! 516: { ! 517: monster_done_dodge (self); ! 518: ! 519: if (range (self, self->enemy) == RANGE_MELEE) ! 520: self->monsterinfo.currentmove = &infantry_move_attack2; ! 521: else ! 522: self->monsterinfo.currentmove = &infantry_move_attack1; ! 523: } ! 524: ! 525: //=========== ! 526: //PGM ! 527: void infantry_jump_now (edict_t *self) ! 528: { ! 529: vec3_t forward,up; ! 530: ! 531: AngleVectors (self->s.angles, forward, NULL, up); ! 532: VectorMA(self->velocity, 100, forward, self->velocity); ! 533: VectorMA(self->velocity, 300, up, self->velocity); ! 534: } ! 535: ! 536: void infantry_jump2_now (edict_t *self) ! 537: { ! 538: vec3_t forward,up; ! 539: ! 540: AngleVectors (self->s.angles, forward, NULL, up); ! 541: VectorMA(self->velocity, 150, forward, self->velocity); ! 542: VectorMA(self->velocity, 400, up, self->velocity); ! 543: } ! 544: ! 545: void infantry_jump_wait_land (edict_t *self) ! 546: { ! 547: if(self->groundentity == NULL) ! 548: self->monsterinfo.nextframe = self->s.frame; ! 549: else ! 550: self->monsterinfo.nextframe = self->s.frame + 1; ! 551: } ! 552: ! 553: mframe_t infantry_frames_jump [] = ! 554: { ! 555: ai_move, 0, NULL, ! 556: ai_move, 0, NULL, ! 557: ai_move, 0, NULL, ! 558: ai_move, 0, infantry_jump_now, ! 559: ai_move, 0, NULL, ! 560: ai_move, 0, NULL, ! 561: ai_move, 0, NULL, ! 562: ai_move, 0, infantry_jump_wait_land, ! 563: ai_move, 0, NULL, ! 564: ai_move, 0, NULL ! 565: }; ! 566: mmove_t infantry_move_jump = { FRAME_jump01, FRAME_jump10, infantry_frames_jump, infantry_run }; ! 567: ! 568: mframe_t infantry_frames_jump2 [] = ! 569: { ! 570: ai_move, -8, NULL, ! 571: ai_move, -4, NULL, ! 572: ai_move, -4, NULL, ! 573: ai_move, 0, infantry_jump_now, ! 574: ai_move, 0, NULL, ! 575: ai_move, 0, NULL, ! 576: ai_move, 0, NULL, ! 577: ai_move, 0, infantry_jump_wait_land, ! 578: ai_move, 0, NULL, ! 579: ai_move, 0, NULL ! 580: }; ! 581: mmove_t infantry_move_jump2 = { FRAME_jump01, FRAME_jump10, infantry_frames_jump2, infantry_run }; ! 582: ! 583: void infantry_jump (edict_t *self) ! 584: { ! 585: if(!self->enemy) ! 586: return; ! 587: ! 588: monster_done_dodge(self); ! 589: ! 590: if(self->enemy->s.origin[2] > self->s.origin[2]) ! 591: self->monsterinfo.currentmove = &infantry_move_jump2; ! 592: else ! 593: self->monsterinfo.currentmove = &infantry_move_jump; ! 594: } ! 595: ! 596: qboolean infantry_blocked (edict_t *self, float dist) ! 597: { ! 598: if(blocked_checkshot (self, 0.25 + (0.05 * skill->value) )) ! 599: return true; ! 600: ! 601: if(blocked_checkjump (self, dist, 192, 40)) ! 602: { ! 603: infantry_jump(self); ! 604: return true; ! 605: } ! 606: ! 607: if(blocked_checkplat (self, dist)) ! 608: return true; ! 609: ! 610: return false; ! 611: } ! 612: //PGM ! 613: //=========== ! 614: /* ! 615: void infantry_dodge (edict_t *self, edict_t *attacker, float eta, trace_t *tr) ! 616: { ! 617: //=========== ! 618: //PMM - rogue rewrite of gunner dodge code. ! 619: float r; ! 620: float height; ! 621: int shooting = 0; ! 622: ! 623: if (!self->enemy) ! 624: { ! 625: self->enemy = attacker; ! 626: FoundTarget (self); ! 627: } ! 628: ! 629: // PMM - don't bother if it's going to hit anyway; fix for weird in-your-face etas (I was ! 630: // seeing numbers like 13 and 14) ! 631: if ((eta < 0.1) || (eta > 5)) ! 632: return; ! 633: ! 634: r = random(); ! 635: if (r > (0.25*((skill->value)+1))) ! 636: return; ! 637: ! 638: if ((self->monsterinfo.currentmove == &infantry_move_attack1) || ! 639: (self->monsterinfo.currentmove == &infantry_move_attack2)) ! 640: { ! 641: shooting = 1; ! 642: } ! 643: if (self->monsterinfo.aiflags & AI_DODGING) ! 644: { ! 645: height = self->absmax[2]; ! 646: } ! 647: else ! 648: { ! 649: height = self->absmax[2]-32-1; // the -1 is because the absmax is s.origin + maxs + 1 ! 650: } ! 651: ! 652: // check to see if it makes sense to duck ! 653: if (tr->endpos[2] <= height) ! 654: { ! 655: vec3_t right,diff; ! 656: ! 657: if (shooting) ! 658: { ! 659: self->monsterinfo.attack_state = AS_SLIDING; ! 660: return; ! 661: } ! 662: AngleVectors (self->s.angles, NULL, right, NULL); ! 663: VectorSubtract (tr->endpos, self->s.origin, diff); ! 664: if (DotProduct (right, diff) < 0) ! 665: { ! 666: self->monsterinfo.lefty = 1; ! 667: } ! 668: // if it doesn't sense to duck, try to strafe away ! 669: monster_done_dodge (self); ! 670: self->monsterinfo.currentmove = &infantry_move_run; ! 671: self->monsterinfo.attack_state = AS_SLIDING; ! 672: return; ! 673: } ! 674: ! 675: if (skill->value == 0) ! 676: { ! 677: self->monsterinfo.currentmove = &infantry_move_duck; ! 678: // PMM - stupid dodge ! 679: self->monsterinfo.duck_wait_time = level.time + eta + 1; ! 680: self->monsterinfo.aiflags |= AI_DODGING; ! 681: return; ! 682: } ! 683: ! 684: if (!shooting) ! 685: { ! 686: self->monsterinfo.currentmove = &infantry_move_duck; ! 687: self->monsterinfo.duck_wait_time = level.time + eta + (0.1 * (3 - skill->value)); ! 688: self->monsterinfo.aiflags |= AI_DODGING; ! 689: } ! 690: return; ! 691: //PMM ! 692: //=========== ! 693: */ ! 694: ! 695: void infantry_duck (edict_t *self, float eta) ! 696: { ! 697: // if we're jumping, don't dodge ! 698: if ((self->monsterinfo.currentmove == &infantry_move_jump) || ! 699: (self->monsterinfo.currentmove == &infantry_move_jump2)) ! 700: { ! 701: return; ! 702: } ! 703: ! 704: if ((self->monsterinfo.currentmove == &infantry_move_attack1) || ! 705: (self->monsterinfo.currentmove == &infantry_move_attack2)) ! 706: { ! 707: // if we're shooting, and not on easy, don't dodge ! 708: if (skill->value) ! 709: { ! 710: self->monsterinfo.aiflags &= ~AI_DUCKED; ! 711: return; ! 712: } ! 713: } ! 714: ! 715: if (skill->value == 0) ! 716: // PMM - stupid dodge ! 717: self->monsterinfo.duck_wait_time = level.time + eta + 1; ! 718: else ! 719: self->monsterinfo.duck_wait_time = level.time + eta + (0.1 * (3 - skill->value)); ! 720: ! 721: // has to be done immediately otherwise he can get stuck ! 722: monster_duck_down(self); ! 723: ! 724: self->monsterinfo.nextframe = FRAME_duck01; ! 725: self->monsterinfo.currentmove = &infantry_move_duck; ! 726: return; ! 727: } ! 728: ! 729: void infantry_sidestep (edict_t *self) ! 730: { ! 731: // if we're jumping, don't dodge ! 732: if ((self->monsterinfo.currentmove == &infantry_move_jump) || ! 733: (self->monsterinfo.currentmove == &infantry_move_jump2)) ! 734: { ! 735: return; ! 736: } ! 737: ! 738: if ((self->monsterinfo.currentmove == &infantry_move_attack1) || ! 739: (self->monsterinfo.currentmove == &infantry_move_attack2)) ! 740: { ! 741: // if we're shooting, and not on easy, don't dodge ! 742: if (skill->value) ! 743: { ! 744: self->monsterinfo.aiflags &= ~AI_DODGING; ! 745: return; ! 746: } ! 747: } ! 748: ! 749: if (self->monsterinfo.currentmove != &infantry_move_run) ! 750: self->monsterinfo.currentmove = &infantry_move_run; ! 751: } ! 752: ! 753: /*QUAKED monster_infantry (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight ! 754: */ ! 755: void SP_monster_infantry (edict_t *self) ! 756: { ! 757: if (deathmatch->value) ! 758: { ! 759: G_FreeEdict (self); ! 760: return; ! 761: } ! 762: ! 763: sound_pain1 = gi.soundindex ("infantry/infpain1.wav"); ! 764: sound_pain2 = gi.soundindex ("infantry/infpain2.wav"); ! 765: sound_die1 = gi.soundindex ("infantry/infdeth1.wav"); ! 766: sound_die2 = gi.soundindex ("infantry/infdeth2.wav"); ! 767: ! 768: sound_gunshot = gi.soundindex ("infantry/infatck1.wav"); ! 769: sound_weapon_cock = gi.soundindex ("infantry/infatck3.wav"); ! 770: sound_punch_swing = gi.soundindex ("infantry/infatck2.wav"); ! 771: sound_punch_hit = gi.soundindex ("infantry/melee2.wav"); ! 772: ! 773: sound_sight = gi.soundindex ("infantry/infsght1.wav"); ! 774: sound_search = gi.soundindex ("infantry/infsrch1.wav"); ! 775: sound_idle = gi.soundindex ("infantry/infidle1.wav"); ! 776: ! 777: ! 778: self->movetype = MOVETYPE_STEP; ! 779: self->solid = SOLID_BBOX; ! 780: self->s.modelindex = gi.modelindex("models/monsters/infantry/tris.md2"); ! 781: VectorSet (self->mins, -16, -16, -24); ! 782: VectorSet (self->maxs, 16, 16, 32); ! 783: ! 784: self->health = 100; ! 785: self->gib_health = -40; ! 786: self->mass = 200; ! 787: ! 788: self->pain = infantry_pain; ! 789: self->die = infantry_die; ! 790: ! 791: self->monsterinfo.stand = infantry_stand; ! 792: self->monsterinfo.walk = infantry_walk; ! 793: self->monsterinfo.run = infantry_run; ! 794: // pmm ! 795: self->monsterinfo.dodge = M_MonsterDodge; ! 796: self->monsterinfo.duck = infantry_duck; ! 797: self->monsterinfo.unduck = monster_duck_up; ! 798: self->monsterinfo.sidestep = infantry_sidestep; ! 799: // self->monsterinfo.dodge = infantry_dodge; ! 800: // pmm ! 801: self->monsterinfo.attack = infantry_attack; ! 802: self->monsterinfo.melee = NULL; ! 803: self->monsterinfo.sight = infantry_sight; ! 804: self->monsterinfo.idle = infantry_fidget; ! 805: self->monsterinfo.blocked = infantry_blocked; ! 806: ! 807: gi.linkentity (self); ! 808: ! 809: self->monsterinfo.currentmove = &infantry_move_stand; ! 810: self->monsterinfo.scale = MODEL_SCALE; ! 811: ! 812: walkmonster_start (self); ! 813: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.