|
|
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: ! 29: mframe_t infantry_frames_stand [] = ! 30: { ! 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: ai_stand, 0, NULL ! 53: }; ! 54: mmove_t infantry_move_stand = {FRAME_stand50, FRAME_stand71, infantry_frames_stand, NULL}; ! 55: ! 56: void infantry_stand (edict_t *self) ! 57: { ! 58: self->monsterinfo.currentmove = &infantry_move_stand; ! 59: } ! 60: ! 61: ! 62: mframe_t infantry_frames_fidget [] = ! 63: { ! 64: ai_stand, 1, NULL, ! 65: ai_stand, 0, NULL, ! 66: ai_stand, 1, NULL, ! 67: ai_stand, 3, NULL, ! 68: ai_stand, 6, NULL, ! 69: ai_stand, 3, NULL, ! 70: ai_stand, 0, NULL, ! 71: ai_stand, 0, NULL, ! 72: ai_stand, 0, NULL, ! 73: ai_stand, 0, NULL, ! 74: ai_stand, 1, NULL, ! 75: ai_stand, 0, NULL, ! 76: ai_stand, 0, NULL, ! 77: ai_stand, 0, NULL, ! 78: ai_stand, 0, NULL, ! 79: ai_stand, 1, NULL, ! 80: ai_stand, 0, NULL, ! 81: ai_stand, -1, NULL, ! 82: ai_stand, 0, NULL, ! 83: ai_stand, 0, NULL, ! 84: ai_stand, 1, NULL, ! 85: ai_stand, 0, NULL, ! 86: ai_stand, -2, NULL, ! 87: ai_stand, 1, NULL, ! 88: ai_stand, 1, NULL, ! 89: ai_stand, 1, NULL, ! 90: ai_stand, -1, NULL, ! 91: ai_stand, 0, NULL, ! 92: ai_stand, 0, NULL, ! 93: ai_stand, -1, 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, -1, NULL, ! 100: ai_stand, 0, NULL, ! 101: ai_stand, 0, NULL, ! 102: ai_stand, 1, NULL, ! 103: ai_stand, 0, NULL, ! 104: ai_stand, 0, NULL, ! 105: ai_stand, -1, NULL, ! 106: ai_stand, -1, NULL, ! 107: ai_stand, 0, NULL, ! 108: ai_stand, -3, NULL, ! 109: ai_stand, -2, NULL, ! 110: ai_stand, -3, NULL, ! 111: ai_stand, -3, NULL, ! 112: ai_stand, -2, NULL ! 113: }; ! 114: mmove_t infantry_move_fidget = {FRAME_stand01, FRAME_stand49, infantry_frames_fidget, infantry_stand}; ! 115: ! 116: void infantry_fidget (edict_t *self) ! 117: { ! 118: self->monsterinfo.currentmove = &infantry_move_fidget; ! 119: gi.sound (self, CHAN_VOICE, sound_idle, 1, ATTN_IDLE, 0); ! 120: } ! 121: ! 122: mframe_t infantry_frames_walk [] = ! 123: { ! 124: ai_walk, 5, NULL, ! 125: ai_walk, 4, NULL, ! 126: ai_walk, 4, NULL, ! 127: ai_walk, 5, NULL, ! 128: ai_walk, 4, NULL, ! 129: ai_walk, 5, NULL, ! 130: ai_walk, 6, NULL, ! 131: ai_walk, 4, NULL, ! 132: ai_walk, 4, NULL, ! 133: ai_walk, 4, NULL, ! 134: ai_walk, 4, NULL, ! 135: ai_walk, 5, NULL ! 136: }; ! 137: mmove_t infantry_move_walk = {FRAME_walk03, FRAME_walk14, infantry_frames_walk, NULL}; ! 138: ! 139: void infantry_walk (edict_t *self) ! 140: { ! 141: self->monsterinfo.currentmove = &infantry_move_walk; ! 142: } ! 143: ! 144: mframe_t infantry_frames_run [] = ! 145: { ! 146: ai_run, 10, NULL, ! 147: ai_run, 20, NULL, ! 148: ai_run, 5, NULL, ! 149: ai_run, 7, NULL, ! 150: ai_run, 30, NULL, ! 151: ai_run, 35, NULL, ! 152: ai_run, 2, NULL, ! 153: ai_run, 6, NULL ! 154: }; ! 155: mmove_t infantry_move_run = {FRAME_run01, FRAME_run08, infantry_frames_run, NULL}; ! 156: ! 157: void infantry_run (edict_t *self) ! 158: { ! 159: if (self->monsterinfo.aiflags & AI_STAND_GROUND) ! 160: self->monsterinfo.currentmove = &infantry_move_stand; ! 161: else ! 162: self->monsterinfo.currentmove = &infantry_move_run; ! 163: } ! 164: ! 165: ! 166: mframe_t infantry_frames_pain1 [] = ! 167: { ! 168: ai_move, -3, NULL, ! 169: ai_move, -2, NULL, ! 170: ai_move, -1, NULL, ! 171: ai_move, -2, NULL, ! 172: ai_move, -1, NULL, ! 173: ai_move, 1, NULL, ! 174: ai_move, -1, NULL, ! 175: ai_move, 1, NULL, ! 176: ai_move, 6, NULL, ! 177: ai_move, 2, NULL ! 178: }; ! 179: mmove_t infantry_move_pain1 = {FRAME_pain101, FRAME_pain110, infantry_frames_pain1, infantry_run}; ! 180: ! 181: mframe_t infantry_frames_pain2 [] = ! 182: { ! 183: ai_move, -3, NULL, ! 184: ai_move, -3, NULL, ! 185: ai_move, 0, NULL, ! 186: ai_move, -1, NULL, ! 187: ai_move, -2, NULL, ! 188: ai_move, 0, NULL, ! 189: ai_move, 0, NULL, ! 190: ai_move, 2, NULL, ! 191: ai_move, 5, NULL, ! 192: ai_move, 2, NULL ! 193: }; ! 194: mmove_t infantry_move_pain2 = {FRAME_pain201, FRAME_pain210, infantry_frames_pain2, infantry_run}; ! 195: ! 196: void infantry_pain (edict_t *self, edict_t *other, float kick, int damage) ! 197: { ! 198: int n; ! 199: ! 200: if (self->health < (self->max_health / 2)) ! 201: self->s.skinnum = 1; ! 202: ! 203: if (level.time < self->pain_debounce_time) ! 204: return; ! 205: ! 206: self->pain_debounce_time = level.time + 3; ! 207: ! 208: if (skill->value == 3) ! 209: return; // no pain anims in nightmare ! 210: ! 211: n = rand() % 2; ! 212: if (n == 0) ! 213: { ! 214: self->monsterinfo.currentmove = &infantry_move_pain1; ! 215: gi.sound (self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0); ! 216: } ! 217: else ! 218: { ! 219: self->monsterinfo.currentmove = &infantry_move_pain2; ! 220: gi.sound (self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0); ! 221: } ! 222: } ! 223: ! 224: ! 225: vec3_t aimangles[] = ! 226: { ! 227: 0.0, 5.0, 0.0, ! 228: 10.0, 15.0, 0.0, ! 229: 20.0, 25.0, 0.0, ! 230: 25.0, 35.0, 0.0, ! 231: 30.0, 40.0, 0.0, ! 232: 30.0, 45.0, 0.0, ! 233: 25.0, 50.0, 0.0, ! 234: 20.0, 40.0, 0.0, ! 235: 15.0, 35.0, 0.0, ! 236: 40.0, 35.0, 0.0, ! 237: 70.0, 35.0, 0.0, ! 238: 90.0, 35.0, 0.0 ! 239: }; ! 240: ! 241: void InfantryMachineGun (edict_t *self) ! 242: { ! 243: vec3_t start, target; ! 244: vec3_t forward, right; ! 245: vec3_t vec; ! 246: int flash_number; ! 247: ! 248: if (self->s.frame == FRAME_attak111) ! 249: { ! 250: flash_number = MZ2_INFANTRY_MACHINEGUN_1; ! 251: AngleVectors (self->s.angles, forward, right, NULL); ! 252: G_ProjectSource (self->s.origin, monster_flash_offset[flash_number], forward, right, start); ! 253: ! 254: if (self->enemy) ! 255: { ! 256: VectorMA (self->enemy->s.origin, -0.2, self->enemy->velocity, target); ! 257: target[2] += self->enemy->viewheight; ! 258: VectorSubtract (target, start, forward); ! 259: VectorNormalize (forward); ! 260: } ! 261: else ! 262: { ! 263: AngleVectors (self->s.angles, forward, right, NULL); ! 264: } ! 265: } ! 266: else ! 267: { ! 268: flash_number = MZ2_INFANTRY_MACHINEGUN_2 + (self->s.frame - FRAME_death211); ! 269: ! 270: AngleVectors (self->s.angles, forward, right, NULL); ! 271: G_ProjectSource (self->s.origin, monster_flash_offset[flash_number], forward, right, start); ! 272: ! 273: VectorSubtract (self->s.angles, aimangles[flash_number-MZ2_INFANTRY_MACHINEGUN_2], vec); ! 274: AngleVectors (vec, forward, NULL, NULL); ! 275: } ! 276: ! 277: monster_fire_bullet (self, start, forward, 3, 4, DEFAULT_BULLET_HSPREAD, DEFAULT_BULLET_VSPREAD, flash_number); ! 278: } ! 279: ! 280: void infantry_sight (edict_t *self, edict_t *other) ! 281: { ! 282: gi.sound (self, CHAN_BODY, sound_sight, 1, ATTN_NORM, 0); ! 283: } ! 284: ! 285: void infantry_dead (edict_t *self) ! 286: { ! 287: VectorSet (self->mins, -16, -16, -24); ! 288: VectorSet (self->maxs, 16, 16, -8); ! 289: self->movetype = MOVETYPE_TOSS; ! 290: self->svflags |= SVF_DEADMONSTER; ! 291: gi.linkentity (self); ! 292: ! 293: M_FlyCheck (self); ! 294: } ! 295: ! 296: mframe_t infantry_frames_death1 [] = ! 297: { ! 298: ai_move, -4, NULL, ! 299: ai_move, 0, NULL, ! 300: ai_move, 0, NULL, ! 301: ai_move, -1, NULL, ! 302: ai_move, -4, NULL, ! 303: ai_move, 0, NULL, ! 304: ai_move, 0, NULL, ! 305: ai_move, 0, NULL, ! 306: ai_move, -1, NULL, ! 307: ai_move, 3, NULL, ! 308: ai_move, 1, NULL, ! 309: ai_move, 1, NULL, ! 310: ai_move, -2, NULL, ! 311: ai_move, 2, NULL, ! 312: ai_move, 2, NULL, ! 313: ai_move, 9, NULL, ! 314: ai_move, 9, NULL, ! 315: ai_move, 5, NULL, ! 316: ai_move, -3, NULL, ! 317: ai_move, -3, NULL ! 318: }; ! 319: mmove_t infantry_move_death1 = {FRAME_death101, FRAME_death120, infantry_frames_death1, infantry_dead}; ! 320: ! 321: // Off with his head ! 322: mframe_t infantry_frames_death2 [] = ! 323: { ! 324: ai_move, 0, NULL, ! 325: ai_move, 1, NULL, ! 326: ai_move, 5, NULL, ! 327: ai_move, -1, NULL, ! 328: ai_move, 0, NULL, ! 329: ai_move, 1, NULL, ! 330: ai_move, 1, NULL, ! 331: ai_move, 4, NULL, ! 332: ai_move, 3, NULL, ! 333: ai_move, 0, NULL, ! 334: ai_move, -2, InfantryMachineGun, ! 335: ai_move, -2, InfantryMachineGun, ! 336: ai_move, -3, InfantryMachineGun, ! 337: ai_move, -1, InfantryMachineGun, ! 338: ai_move, -2, InfantryMachineGun, ! 339: ai_move, 0, InfantryMachineGun, ! 340: ai_move, 2, InfantryMachineGun, ! 341: ai_move, 2, InfantryMachineGun, ! 342: ai_move, 3, InfantryMachineGun, ! 343: ai_move, -10, InfantryMachineGun, ! 344: ai_move, -7, InfantryMachineGun, ! 345: ai_move, -8, InfantryMachineGun, ! 346: ai_move, -6, NULL, ! 347: ai_move, 4, NULL, ! 348: ai_move, 0, NULL ! 349: }; ! 350: mmove_t infantry_move_death2 = {FRAME_death201, FRAME_death225, infantry_frames_death2, infantry_dead}; ! 351: ! 352: mframe_t infantry_frames_death3 [] = ! 353: { ! 354: ai_move, 0, NULL, ! 355: ai_move, 0, NULL, ! 356: ai_move, 0, NULL, ! 357: ai_move, -6, NULL, ! 358: ai_move, -11, NULL, ! 359: ai_move, -3, NULL, ! 360: ai_move, -11, NULL, ! 361: ai_move, 0, NULL, ! 362: ai_move, 0, NULL ! 363: }; ! 364: mmove_t infantry_move_death3 = {FRAME_death301, FRAME_death309, infantry_frames_death3, infantry_dead}; ! 365: ! 366: ! 367: void infantry_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) ! 368: { ! 369: int n; ! 370: ! 371: // check for gib ! 372: if (self->health <= self->gib_health) ! 373: { ! 374: gi.sound (self, CHAN_VOICE, gi.soundindex ("misc/udeath.wav"), 1, ATTN_NORM, 0); ! 375: for (n= 0; n < 2; n++) ! 376: ThrowGib (self, "models/objects/gibs/bone/tris.md2", damage, GIB_ORGANIC); ! 377: for (n= 0; n < 4; n++) ! 378: ThrowGib (self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC); ! 379: ThrowHead (self, "models/objects/gibs/head2/tris.md2", damage, GIB_ORGANIC); ! 380: self->deadflag = DEAD_DEAD; ! 381: return; ! 382: } ! 383: ! 384: if (self->deadflag == DEAD_DEAD) ! 385: return; ! 386: ! 387: // regular death ! 388: self->deadflag = DEAD_DEAD; ! 389: self->takedamage = DAMAGE_YES; ! 390: ! 391: n = rand() % 3; ! 392: if (n == 0) ! 393: { ! 394: self->monsterinfo.currentmove = &infantry_move_death1; ! 395: gi.sound (self, CHAN_VOICE, sound_die2, 1, ATTN_NORM, 0); ! 396: } ! 397: else if (n == 1) ! 398: { ! 399: self->monsterinfo.currentmove = &infantry_move_death2; ! 400: gi.sound (self, CHAN_VOICE, sound_die1, 1, ATTN_NORM, 0); ! 401: } ! 402: else ! 403: { ! 404: self->monsterinfo.currentmove = &infantry_move_death3; ! 405: gi.sound (self, CHAN_VOICE, sound_die2, 1, ATTN_NORM, 0); ! 406: } ! 407: } ! 408: ! 409: ! 410: void infantry_duck_down (edict_t *self) ! 411: { ! 412: if (self->monsterinfo.aiflags & AI_DUCKED) ! 413: return; ! 414: self->monsterinfo.aiflags |= AI_DUCKED; ! 415: self->maxs[2] -= 32; ! 416: self->takedamage = DAMAGE_YES; ! 417: self->monsterinfo.pausetime = level.time + 1; ! 418: gi.linkentity (self); ! 419: } ! 420: ! 421: void infantry_duck_hold (edict_t *self) ! 422: { ! 423: if (level.time >= self->monsterinfo.pausetime) ! 424: self->monsterinfo.aiflags &= ~AI_HOLD_FRAME; ! 425: else ! 426: self->monsterinfo.aiflags |= AI_HOLD_FRAME; ! 427: } ! 428: ! 429: void infantry_duck_up (edict_t *self) ! 430: { ! 431: self->monsterinfo.aiflags &= ~AI_DUCKED; ! 432: self->maxs[2] += 32; ! 433: self->takedamage = DAMAGE_AIM; ! 434: gi.linkentity (self); ! 435: } ! 436: ! 437: mframe_t infantry_frames_duck [] = ! 438: { ! 439: ai_move, -2, infantry_duck_down, ! 440: ai_move, -5, infantry_duck_hold, ! 441: ai_move, 3, NULL, ! 442: ai_move, 4, infantry_duck_up, ! 443: ai_move, 0, NULL ! 444: }; ! 445: mmove_t infantry_move_duck = {FRAME_duck01, FRAME_duck05, infantry_frames_duck, infantry_run}; ! 446: ! 447: void infantry_dodge (edict_t *self, edict_t *attacker, float eta) ! 448: { ! 449: if (random() > 0.25) ! 450: return; ! 451: ! 452: if (!self->enemy) ! 453: self->enemy = attacker; ! 454: ! 455: self->monsterinfo.currentmove = &infantry_move_duck; ! 456: } ! 457: ! 458: ! 459: void infantry_cock_gun (edict_t *self) ! 460: { ! 461: int n; ! 462: ! 463: gi.sound (self, CHAN_WEAPON, sound_weapon_cock, 1, ATTN_NORM, 0); ! 464: n = (rand() & 15) + 3 + 7; ! 465: self->monsterinfo.pausetime = level.time + n * FRAMETIME; ! 466: } ! 467: ! 468: void infantry_fire (edict_t *self) ! 469: { ! 470: InfantryMachineGun (self); ! 471: ! 472: if (level.time >= self->monsterinfo.pausetime) ! 473: self->monsterinfo.aiflags &= ~AI_HOLD_FRAME; ! 474: else ! 475: self->monsterinfo.aiflags |= AI_HOLD_FRAME; ! 476: } ! 477: ! 478: mframe_t infantry_frames_attack1 [] = ! 479: { ! 480: ai_charge, 4, NULL, ! 481: ai_charge, -1, NULL, ! 482: ai_charge, -1, NULL, ! 483: ai_charge, 0, infantry_cock_gun, ! 484: ai_charge, -1, NULL, ! 485: ai_charge, 1, NULL, ! 486: ai_charge, 1, NULL, ! 487: ai_charge, 2, NULL, ! 488: ai_charge, -2, NULL, ! 489: ai_charge, -3, NULL, ! 490: ai_charge, 1, infantry_fire, ! 491: ai_charge, 5, NULL, ! 492: ai_charge, -1, NULL, ! 493: ai_charge, -2, NULL, ! 494: ai_charge, -3, NULL ! 495: }; ! 496: mmove_t infantry_move_attack1 = {FRAME_attak101, FRAME_attak115, infantry_frames_attack1, infantry_run}; ! 497: ! 498: ! 499: void infantry_swing (edict_t *self) ! 500: { ! 501: gi.sound (self, CHAN_WEAPON, sound_punch_swing, 1, ATTN_NORM, 0); ! 502: } ! 503: ! 504: void infantry_smack (edict_t *self) ! 505: { ! 506: vec3_t aim; ! 507: ! 508: VectorSet (aim, MELEE_DISTANCE, 0, 0); ! 509: if (fire_hit (self, aim, (5 + (rand() % 5)), 50)) ! 510: gi.sound (self, CHAN_WEAPON, sound_punch_hit, 1, ATTN_NORM, 0); ! 511: } ! 512: ! 513: mframe_t infantry_frames_attack2 [] = ! 514: { ! 515: ai_charge, 3, NULL, ! 516: ai_charge, 6, NULL, ! 517: ai_charge, 0, infantry_swing, ! 518: ai_charge, 8, NULL, ! 519: ai_charge, 5, NULL, ! 520: ai_charge, 8, infantry_smack, ! 521: ai_charge, 6, NULL, ! 522: ai_charge, 3, NULL, ! 523: }; ! 524: mmove_t infantry_move_attack2 = {FRAME_attak201, FRAME_attak208, infantry_frames_attack2, infantry_run}; ! 525: ! 526: void infantry_attack(edict_t *self) ! 527: { ! 528: if (range (self, self->enemy) == RANGE_MELEE) ! 529: self->monsterinfo.currentmove = &infantry_move_attack2; ! 530: else ! 531: self->monsterinfo.currentmove = &infantry_move_attack1; ! 532: } ! 533: ! 534: ! 535: /*QUAKED monster_infantry (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight ! 536: */ ! 537: void SP_monster_infantry (edict_t *self) ! 538: { ! 539: if (deathmatch->value) ! 540: { ! 541: G_FreeEdict (self); ! 542: return; ! 543: } ! 544: ! 545: sound_pain1 = gi.soundindex ("infantry/infpain1.wav"); ! 546: sound_pain2 = gi.soundindex ("infantry/infpain2.wav"); ! 547: sound_die1 = gi.soundindex ("infantry/infdeth1.wav"); ! 548: sound_die2 = gi.soundindex ("infantry/infdeth2.wav"); ! 549: ! 550: sound_gunshot = gi.soundindex ("infantry/infatck1.wav"); ! 551: sound_weapon_cock = gi.soundindex ("infantry/infatck3.wav"); ! 552: sound_punch_swing = gi.soundindex ("infantry/infatck2.wav"); ! 553: sound_punch_hit = gi.soundindex ("infantry/melee2.wav"); ! 554: ! 555: sound_sight = gi.soundindex ("infantry/infsght1.wav"); ! 556: sound_search = gi.soundindex ("infantry/infsrch1.wav"); ! 557: sound_idle = gi.soundindex ("infantry/infidle1.wav"); ! 558: ! 559: ! 560: self->movetype = MOVETYPE_STEP; ! 561: self->solid = SOLID_BBOX; ! 562: self->s.modelindex = gi.modelindex("models/monsters/infantry/tris.md2"); ! 563: VectorSet (self->mins, -16, -16, -24); ! 564: VectorSet (self->maxs, 16, 16, 32); ! 565: ! 566: self->health = 100; ! 567: self->gib_health = -40; ! 568: self->mass = 200; ! 569: ! 570: self->pain = infantry_pain; ! 571: self->die = infantry_die; ! 572: ! 573: self->monsterinfo.stand = infantry_stand; ! 574: self->monsterinfo.walk = infantry_walk; ! 575: self->monsterinfo.run = infantry_run; ! 576: self->monsterinfo.dodge = infantry_dodge; ! 577: self->monsterinfo.attack = infantry_attack; ! 578: self->monsterinfo.melee = NULL; ! 579: self->monsterinfo.sight = infantry_sight; ! 580: self->monsterinfo.idle = infantry_fidget; ! 581: ! 582: gi.linkentity (self); ! 583: ! 584: self->monsterinfo.currentmove = &infantry_move_stand; ! 585: self->monsterinfo.scale = MODEL_SCALE; ! 586: ! 587: walkmonster_start (self); ! 588: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.