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