|
|
1.1 ! root 1: /* ! 2: ============================================================================== ! 3: ! 4: mutant ! 5: ! 6: ============================================================================== ! 7: */ ! 8: ! 9: #include "g_local.h" ! 10: #include "m_mutant.h" ! 11: ! 12: ! 13: static int sound_swing; ! 14: static int sound_hit; ! 15: static int sound_hit2; ! 16: static int sound_death; ! 17: static int sound_idle; ! 18: static int sound_pain1; ! 19: static int sound_pain2; ! 20: static int sound_sight; ! 21: static int sound_search; ! 22: static int sound_step1; ! 23: static int sound_step2; ! 24: static int sound_step3; ! 25: static int sound_thud; ! 26: ! 27: // ! 28: // SOUNDS ! 29: // ! 30: ! 31: void mutant_step (edict_t *self) ! 32: { ! 33: int n; ! 34: n = (rand() + 1) % 3; ! 35: if (n == 0) ! 36: gi.sound (self, CHAN_VOICE, sound_step1, 1, ATTN_NORM, 0); ! 37: else if (n == 1) ! 38: gi.sound (self, CHAN_VOICE, sound_step2, 1, ATTN_NORM, 0); ! 39: else ! 40: gi.sound (self, CHAN_VOICE, sound_step3, 1, ATTN_NORM, 0); ! 41: } ! 42: ! 43: void mutant_sight (edict_t *self, edict_t *other) ! 44: { ! 45: gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0); ! 46: } ! 47: ! 48: void mutant_search (edict_t *self) ! 49: { ! 50: gi.sound (self, CHAN_VOICE, sound_search, 1, ATTN_NORM, 0); ! 51: } ! 52: ! 53: void mutant_swing (edict_t *self) ! 54: { ! 55: gi.sound (self, CHAN_VOICE, sound_swing, 1, ATTN_NORM, 0); ! 56: } ! 57: ! 58: ! 59: // ! 60: // STAND ! 61: // ! 62: ! 63: mframe_t mutant_frames_stand [] = ! 64: { ! 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: ai_stand, 0, NULL, ! 73: ai_stand, 0, NULL, ! 74: ai_stand, 0, NULL, // 10 ! 75: ! 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: ! 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, ! 96: ai_stand, 0, NULL, // 30 ! 97: ! 98: ai_stand, 0, NULL, ! 99: ai_stand, 0, NULL, ! 100: ai_stand, 0, NULL, ! 101: ai_stand, 0, NULL, ! 102: ai_stand, 0, NULL, ! 103: ai_stand, 0, NULL, ! 104: ai_stand, 0, NULL, ! 105: ai_stand, 0, NULL, ! 106: ai_stand, 0, NULL, ! 107: ai_stand, 0, NULL, // 40 ! 108: ! 109: ai_stand, 0, NULL, ! 110: ai_stand, 0, NULL, ! 111: ai_stand, 0, NULL, ! 112: ai_stand, 0, 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, 0, NULL, // 50 ! 119: ! 120: ai_stand, 0, NULL ! 121: }; ! 122: mmove_t mutant_move_stand = {FRAME_stand101, FRAME_stand151, mutant_frames_stand, NULL}; ! 123: ! 124: void mutant_stand (edict_t *self) ! 125: { ! 126: self->monsterinfo.currentmove = &mutant_move_stand; ! 127: } ! 128: ! 129: ! 130: // ! 131: // IDLE ! 132: // ! 133: ! 134: void mutant_idle_loop (edict_t *self) ! 135: { ! 136: if (random() < 0.75) ! 137: self->monsterinfo.nextframe = FRAME_stand155; ! 138: } ! 139: ! 140: mframe_t mutant_frames_idle [] = ! 141: { ! 142: ai_stand, 0, NULL, ! 143: ai_stand, 0, NULL, ! 144: ai_stand, 0, NULL, ! 145: ai_stand, 0, NULL, // scratch loop start ! 146: ai_stand, 0, NULL, ! 147: ai_stand, 0, NULL, ! 148: ai_stand, 0, mutant_idle_loop, // scratch loop end ! 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: }; ! 156: mmove_t mutant_move_idle = {FRAME_stand152, FRAME_stand164, mutant_frames_idle, mutant_stand}; ! 157: ! 158: void mutant_idle (edict_t *self) ! 159: { ! 160: self->monsterinfo.currentmove = &mutant_move_idle; ! 161: gi.sound (self, CHAN_VOICE, sound_idle, 1, ATTN_IDLE, 0); ! 162: } ! 163: ! 164: ! 165: // ! 166: // WALK ! 167: // ! 168: ! 169: void mutant_walk (edict_t *self); ! 170: ! 171: mframe_t mutant_frames_walk [] = ! 172: { ! 173: ai_walk, 3, NULL, ! 174: ai_walk, 1, NULL, ! 175: ai_walk, 5, NULL, ! 176: ai_walk, 10, NULL, ! 177: ai_walk, 13, NULL, ! 178: ai_walk, 10, NULL, ! 179: ai_walk, 0, NULL, ! 180: ai_walk, 5, NULL, ! 181: ai_walk, 6, NULL, ! 182: ai_walk, 16, NULL, ! 183: ai_walk, 15, NULL, ! 184: ai_walk, 6, NULL ! 185: }; ! 186: mmove_t mutant_move_walk = {FRAME_walk05, FRAME_walk16, mutant_frames_walk, NULL}; ! 187: ! 188: void mutant_walk_loop (edict_t *self) ! 189: { ! 190: self->monsterinfo.currentmove = &mutant_move_walk; ! 191: } ! 192: ! 193: mframe_t mutant_frames_start_walk [] = ! 194: { ! 195: ai_walk, 5, NULL, ! 196: ai_walk, 5, NULL, ! 197: ai_walk, -2, NULL, ! 198: ai_walk, 1, NULL ! 199: }; ! 200: mmove_t mutant_move_start_walk = {FRAME_walk01, FRAME_walk04, mutant_frames_start_walk, mutant_walk_loop}; ! 201: ! 202: void mutant_walk (edict_t *self) ! 203: { ! 204: self->monsterinfo.currentmove = &mutant_move_start_walk; ! 205: } ! 206: ! 207: ! 208: // ! 209: // RUN ! 210: // ! 211: ! 212: mframe_t mutant_frames_run [] = ! 213: { ! 214: ai_run, 40, NULL, ! 215: ai_run, 40, mutant_step, ! 216: ai_run, 24, NULL, ! 217: ai_run, 5, mutant_step, ! 218: ai_run, 17, NULL, ! 219: ai_run, 10, NULL ! 220: }; ! 221: mmove_t mutant_move_run = {FRAME_run03, FRAME_run08, mutant_frames_run, NULL}; ! 222: ! 223: void mutant_run (edict_t *self) ! 224: { ! 225: if (self->monsterinfo.aiflags & AI_STAND_GROUND) ! 226: self->monsterinfo.currentmove = &mutant_move_stand; ! 227: else ! 228: self->monsterinfo.currentmove = &mutant_move_run; ! 229: } ! 230: ! 231: ! 232: // ! 233: // MELEE ! 234: // ! 235: ! 236: void mutant_hit_left (edict_t *self) ! 237: { ! 238: vec3_t aim; ! 239: ! 240: VectorSet (aim, MELEE_DISTANCE, self->mins[0], 8); ! 241: if (fire_hit (self, aim, (10 + (rand() %5)), 100)) ! 242: gi.sound (self, CHAN_WEAPON, sound_hit, 1, ATTN_NORM, 0); ! 243: else ! 244: gi.sound (self, CHAN_WEAPON, sound_swing, 1, ATTN_NORM, 0); ! 245: } ! 246: ! 247: void mutant_hit_right (edict_t *self) ! 248: { ! 249: vec3_t aim; ! 250: ! 251: VectorSet (aim, MELEE_DISTANCE, self->maxs[0], 8); ! 252: if (fire_hit (self, aim, (10 + (rand() %5)), 100)) ! 253: gi.sound (self, CHAN_WEAPON, sound_hit2, 1, ATTN_NORM, 0); ! 254: else ! 255: gi.sound (self, CHAN_WEAPON, sound_swing, 1, ATTN_NORM, 0); ! 256: } ! 257: ! 258: void mutant_check_refire (edict_t *self) ! 259: { ! 260: if (!self->enemy || !self->enemy->inuse || self->enemy->health <= 0) ! 261: return; ! 262: ! 263: if ( ((skill->value == 3) && (random() < 0.5)) || (range(self, self->enemy) == RANGE_MELEE) ) ! 264: self->monsterinfo.nextframe = FRAME_attack09; ! 265: } ! 266: ! 267: mframe_t mutant_frames_attack [] = ! 268: { ! 269: ai_charge, 0, NULL, ! 270: ai_charge, 0, NULL, ! 271: ai_charge, 0, mutant_hit_left, ! 272: ai_charge, 0, NULL, ! 273: ai_charge, 0, NULL, ! 274: ai_charge, 0, mutant_hit_right, ! 275: ai_charge, 0, mutant_check_refire ! 276: }; ! 277: mmove_t mutant_move_attack = {FRAME_attack09, FRAME_attack15, mutant_frames_attack, mutant_run}; ! 278: ! 279: void mutant_melee (edict_t *self) ! 280: { ! 281: self->monsterinfo.currentmove = &mutant_move_attack; ! 282: } ! 283: ! 284: ! 285: // ! 286: // ATTACK ! 287: // ! 288: ! 289: void mutant_jump_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) ! 290: { ! 291: if (self->health <= 0) ! 292: { ! 293: self->touch = NULL; ! 294: return; ! 295: } ! 296: ! 297: if (other->takedamage) ! 298: { ! 299: if (VectorLength(self->velocity) > 400) ! 300: { ! 301: vec3_t point; ! 302: vec3_t normal; ! 303: int damage; ! 304: ! 305: VectorCopy (self->velocity, normal); ! 306: VectorNormalize(normal); ! 307: VectorMA (self->s.origin, self->maxs[0], normal, point); ! 308: damage = 40 + 10 * random(); ! 309: T_Damage (other, self, self, self->velocity, point, normal, damage, damage, 0, MOD_UNKNOWN); ! 310: } ! 311: } ! 312: ! 313: if (!M_CheckBottom (self)) ! 314: { ! 315: if (self->groundentity) ! 316: { ! 317: self->monsterinfo.nextframe = FRAME_attack02; ! 318: self->touch = NULL; ! 319: } ! 320: return; ! 321: } ! 322: ! 323: self->touch = NULL; ! 324: } ! 325: ! 326: void mutant_jump_takeoff (edict_t *self) ! 327: { ! 328: vec3_t forward; ! 329: ! 330: gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0); ! 331: AngleVectors (self->s.angles, forward, NULL, NULL); ! 332: self->s.origin[2] += 1; ! 333: VectorScale (forward, 600, self->velocity); ! 334: self->velocity[2] = 250; ! 335: self->groundentity = NULL; ! 336: self->monsterinfo.aiflags |= AI_DUCKED; ! 337: self->monsterinfo.attack_finished = level.time + 3; ! 338: self->touch = mutant_jump_touch; ! 339: } ! 340: ! 341: void mutant_check_landing (edict_t *self) ! 342: { ! 343: if (self->groundentity) ! 344: { ! 345: gi.sound (self, CHAN_WEAPON, sound_thud, 1, ATTN_NORM, 0); ! 346: self->monsterinfo.attack_finished = 0; ! 347: self->monsterinfo.aiflags &= ~AI_DUCKED; ! 348: return; ! 349: } ! 350: ! 351: if (level.time > self->monsterinfo.attack_finished) ! 352: self->monsterinfo.nextframe = FRAME_attack02; ! 353: else ! 354: self->monsterinfo.nextframe = FRAME_attack05; ! 355: } ! 356: ! 357: mframe_t mutant_frames_jump [] = ! 358: { ! 359: ai_charge, 0, NULL, ! 360: ai_charge, 17, NULL, ! 361: ai_charge, 15, mutant_jump_takeoff, ! 362: ai_charge, 15, NULL, ! 363: ai_charge, 15, mutant_check_landing, ! 364: ai_charge, 0, NULL, ! 365: ai_charge, 3, NULL, ! 366: ai_charge, 0, NULL ! 367: }; ! 368: mmove_t mutant_move_jump = {FRAME_attack01, FRAME_attack08, mutant_frames_jump, mutant_run}; ! 369: ! 370: void mutant_jump (edict_t *self) ! 371: { ! 372: self->monsterinfo.currentmove = &mutant_move_jump; ! 373: } ! 374: ! 375: ! 376: // ! 377: // CHECKATTACK ! 378: // ! 379: ! 380: qboolean mutant_check_melee (edict_t *self) ! 381: { ! 382: if (range (self, self->enemy) == RANGE_MELEE) ! 383: return true; ! 384: return false; ! 385: } ! 386: ! 387: qboolean mutant_check_jump (edict_t *self) ! 388: { ! 389: vec3_t v; ! 390: float distance; ! 391: ! 392: if (self->absmin[2] > (self->enemy->absmin[2] + 0.75 * self->enemy->size[2])) ! 393: return false; ! 394: ! 395: if (self->absmax[2] < (self->enemy->absmin[2] + 0.25 * self->enemy->size[2])) ! 396: return false; ! 397: ! 398: v[0] = self->s.origin[0] - self->enemy->s.origin[0]; ! 399: v[1] = self->s.origin[1] - self->enemy->s.origin[1]; ! 400: v[2] = 0; ! 401: distance = VectorLength(v); ! 402: ! 403: if (distance < 100) ! 404: return false; ! 405: if (distance > 100) ! 406: { ! 407: if (random() < 0.9) ! 408: return false; ! 409: } ! 410: ! 411: return true; ! 412: } ! 413: ! 414: qboolean mutant_checkattack (edict_t *self) ! 415: { ! 416: if (!self->enemy || self->enemy->health <= 0) ! 417: return false; ! 418: ! 419: if (mutant_check_melee(self)) ! 420: { ! 421: self->monsterinfo.attack_state = AS_MELEE; ! 422: return true; ! 423: } ! 424: ! 425: if (mutant_check_jump(self)) ! 426: { ! 427: self->monsterinfo.attack_state = AS_MISSILE; ! 428: // FIXME play a jump sound here ! 429: return true; ! 430: } ! 431: ! 432: return false; ! 433: } ! 434: ! 435: ! 436: // ! 437: // PAIN ! 438: // ! 439: ! 440: mframe_t mutant_frames_pain1 [] = ! 441: { ! 442: ai_move, 4, NULL, ! 443: ai_move, -3, NULL, ! 444: ai_move, -8, NULL, ! 445: ai_move, 2, NULL, ! 446: ai_move, 5, NULL ! 447: }; ! 448: mmove_t mutant_move_pain1 = {FRAME_pain101, FRAME_pain105, mutant_frames_pain1, mutant_run}; ! 449: ! 450: mframe_t mutant_frames_pain2 [] = ! 451: { ! 452: ai_move, -24,NULL, ! 453: ai_move, 11, NULL, ! 454: ai_move, 5, NULL, ! 455: ai_move, -2, NULL, ! 456: ai_move, 6, NULL, ! 457: ai_move, 4, NULL ! 458: }; ! 459: mmove_t mutant_move_pain2 = {FRAME_pain201, FRAME_pain206, mutant_frames_pain2, mutant_run}; ! 460: ! 461: mframe_t mutant_frames_pain3 [] = ! 462: { ! 463: ai_move, -22,NULL, ! 464: ai_move, 3, NULL, ! 465: ai_move, 3, NULL, ! 466: ai_move, 2, NULL, ! 467: ai_move, 1, NULL, ! 468: ai_move, 1, NULL, ! 469: ai_move, 6, NULL, ! 470: ai_move, 3, NULL, ! 471: ai_move, 2, NULL, ! 472: ai_move, 0, NULL, ! 473: ai_move, 1, NULL ! 474: }; ! 475: mmove_t mutant_move_pain3 = {FRAME_pain301, FRAME_pain311, mutant_frames_pain3, mutant_run}; ! 476: ! 477: void mutant_pain (edict_t *self, edict_t *other, float kick, int damage) ! 478: { ! 479: float r; ! 480: ! 481: if (self->health < (self->max_health / 2)) ! 482: self->s.skinnum = 1; ! 483: ! 484: if (level.time < self->pain_debounce_time) ! 485: return; ! 486: ! 487: self->pain_debounce_time = level.time + 3; ! 488: ! 489: if (skill->value == 3) ! 490: return; // no pain anims in nightmare ! 491: ! 492: r = random(); ! 493: if (r < 0.33) ! 494: { ! 495: gi.sound (self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0); ! 496: self->monsterinfo.currentmove = &mutant_move_pain1; ! 497: } ! 498: else if (r < 0.66) ! 499: { ! 500: gi.sound (self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0); ! 501: self->monsterinfo.currentmove = &mutant_move_pain2; ! 502: } ! 503: else ! 504: { ! 505: gi.sound (self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0); ! 506: self->monsterinfo.currentmove = &mutant_move_pain3; ! 507: } ! 508: } ! 509: ! 510: ! 511: // ! 512: // DEATH ! 513: // ! 514: ! 515: void mutant_dead (edict_t *self) ! 516: { ! 517: VectorSet (self->mins, -16, -16, -24); ! 518: VectorSet (self->maxs, 16, 16, -8); ! 519: self->movetype = MOVETYPE_TOSS; ! 520: self->svflags |= SVF_DEADMONSTER; ! 521: gi.linkentity (self); ! 522: ! 523: M_FlyCheck (self); ! 524: } ! 525: ! 526: mframe_t mutant_frames_death1 [] = ! 527: { ! 528: ai_move, 0, NULL, ! 529: ai_move, 0, NULL, ! 530: ai_move, 0, NULL, ! 531: ai_move, 0, NULL, ! 532: ai_move, 0, NULL, ! 533: ai_move, 0, NULL, ! 534: ai_move, 0, NULL, ! 535: ai_move, 0, NULL, ! 536: ai_move, 0, NULL ! 537: }; ! 538: mmove_t mutant_move_death1 = {FRAME_death101, FRAME_death109, mutant_frames_death1, mutant_dead}; ! 539: ! 540: mframe_t mutant_frames_death2 [] = ! 541: { ! 542: ai_move, 0, NULL, ! 543: ai_move, 0, NULL, ! 544: ai_move, 0, NULL, ! 545: ai_move, 0, NULL, ! 546: ai_move, 0, NULL, ! 547: ai_move, 0, NULL, ! 548: ai_move, 0, NULL, ! 549: ai_move, 0, NULL, ! 550: ai_move, 0, NULL, ! 551: ai_move, 0, NULL ! 552: }; ! 553: mmove_t mutant_move_death2 = {FRAME_death201, FRAME_death210, mutant_frames_death2, mutant_dead}; ! 554: ! 555: void mutant_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) ! 556: { ! 557: int n; ! 558: ! 559: if (self->health <= self->gib_health) ! 560: { ! 561: gi.sound (self, CHAN_VOICE, gi.soundindex ("misc/udeath.wav"), 1, ATTN_NORM, 0); ! 562: for (n= 0; n < 2; n++) ! 563: ThrowGib (self, "models/objects/gibs/bone/tris.md2", damage, GIB_ORGANIC); ! 564: for (n= 0; n < 4; n++) ! 565: ThrowGib (self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC); ! 566: ThrowHead (self, "models/objects/gibs/head2/tris.md2", damage, GIB_ORGANIC); ! 567: self->deadflag = DEAD_DEAD; ! 568: return; ! 569: } ! 570: ! 571: if (self->deadflag == DEAD_DEAD) ! 572: return; ! 573: ! 574: gi.sound (self, CHAN_VOICE, sound_death, 1, ATTN_NORM, 0); ! 575: self->deadflag = DEAD_DEAD; ! 576: self->takedamage = DAMAGE_YES; ! 577: self->s.skinnum = 1; ! 578: ! 579: if (random() < 0.5) ! 580: self->monsterinfo.currentmove = &mutant_move_death1; ! 581: else ! 582: self->monsterinfo.currentmove = &mutant_move_death2; ! 583: } ! 584: ! 585: ! 586: // ! 587: // SPAWN ! 588: // ! 589: ! 590: /*QUAKED monster_mutant (1 .5 0) (-32 -32 -24) (32 32 32) Ambush Trigger_Spawn Sight ! 591: */ ! 592: void SP_monster_mutant (edict_t *self) ! 593: { ! 594: if (deathmatch->value) ! 595: { ! 596: G_FreeEdict (self); ! 597: return; ! 598: } ! 599: ! 600: sound_swing = gi.soundindex ("mutant/mutatck1.wav"); ! 601: sound_hit = gi.soundindex ("mutant/mutatck2.wav"); ! 602: sound_hit2 = gi.soundindex ("mutant/mutatck3.wav"); ! 603: sound_death = gi.soundindex ("mutant/mutdeth1.wav"); ! 604: sound_idle = gi.soundindex ("mutant/mutidle1.wav"); ! 605: sound_pain1 = gi.soundindex ("mutant/mutpain1.wav"); ! 606: sound_pain2 = gi.soundindex ("mutant/mutpain2.wav"); ! 607: sound_sight = gi.soundindex ("mutant/mutsght1.wav"); ! 608: sound_search = gi.soundindex ("mutant/mutsrch1.wav"); ! 609: sound_step1 = gi.soundindex ("mutant/step1.wav"); ! 610: sound_step2 = gi.soundindex ("mutant/step2.wav"); ! 611: sound_step3 = gi.soundindex ("mutant/step3.wav"); ! 612: sound_thud = gi.soundindex ("mutant/thud1.wav"); ! 613: ! 614: self->movetype = MOVETYPE_STEP; ! 615: self->solid = SOLID_BBOX; ! 616: self->s.modelindex = gi.modelindex ("models/monsters/mutant/tris.md2"); ! 617: VectorSet (self->mins, -32, -32, -24); ! 618: VectorSet (self->maxs, 32, 32, 48); ! 619: ! 620: self->health = 300; ! 621: self->gib_health = -120; ! 622: self->mass = 300; ! 623: ! 624: self->pain = mutant_pain; ! 625: self->die = mutant_die; ! 626: ! 627: self->monsterinfo.stand = mutant_stand; ! 628: self->monsterinfo.walk = mutant_walk; ! 629: self->monsterinfo.run = mutant_run; ! 630: self->monsterinfo.dodge = NULL; ! 631: self->monsterinfo.attack = mutant_jump; ! 632: self->monsterinfo.melee = mutant_melee; ! 633: self->monsterinfo.sight = mutant_sight; ! 634: self->monsterinfo.search = mutant_search; ! 635: self->monsterinfo.idle = mutant_idle; ! 636: self->monsterinfo.checkattack = mutant_checkattack; ! 637: ! 638: gi.linkentity (self); ! 639: ! 640: self->monsterinfo.currentmove = &mutant_move_stand; ! 641: ! 642: self->monsterinfo.scale = MODEL_SCALE; ! 643: walkmonster_start (self); ! 644: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.