|
|
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: chick 24: 25: ============================================================================== 26: */ 27: 28: #include "g_local.h" 29: #include "m_chick.h" 30: 31: qboolean visible (edict_t *self, edict_t *other); 32: 33: void chick_stand (edict_t *self); 34: void chick_run (edict_t *self); 35: void chick_reslash(edict_t *self); 36: void chick_rerocket(edict_t *self); 37: void chick_attack1(edict_t *self); 38: 39: static int sound_missile_prelaunch; 40: static int sound_missile_launch; 41: static int sound_melee_swing; 42: static int sound_melee_hit; 43: static int sound_missile_reload; 44: static int sound_death1; 45: static int sound_death2; 46: static int sound_fall_down; 47: static int sound_idle1; 48: static int sound_idle2; 49: static int sound_pain1; 50: static int sound_pain2; 51: static int sound_pain3; 52: static int sound_sight; 53: static int sound_search; 54: 55: 56: void ChickMoan (edict_t *self) 57: { 58: if (random() < 0.5) 59: gi.sound (self, CHAN_VOICE, sound_idle1, 1, ATTN_IDLE, 0); 60: else 61: gi.sound (self, CHAN_VOICE, sound_idle2, 1, ATTN_IDLE, 0); 62: } 63: 64: mframe_t chick_frames_fidget [] = 65: { 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, ChickMoan, 75: ai_stand, 0, NULL, 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, 86: ai_stand, 0, NULL, 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: }; 97: mmove_t chick_move_fidget = {FRAME_stand201, FRAME_stand230, chick_frames_fidget, chick_stand}; 98: 99: void chick_fidget (edict_t *self) 100: { 101: if (self->monsterinfo.aiflags & AI_STAND_GROUND) 102: return; 103: if (random() <= 0.3) 104: self->monsterinfo.currentmove = &chick_move_fidget; 105: } 106: 107: mframe_t chick_frames_stand [] = 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, 119: ai_stand, 0, NULL, 120: ai_stand, 0, NULL, 121: ai_stand, 0, NULL, 122: ai_stand, 0, NULL, 123: ai_stand, 0, NULL, 124: ai_stand, 0, NULL, 125: ai_stand, 0, NULL, 126: ai_stand, 0, NULL, 127: ai_stand, 0, NULL, 128: ai_stand, 0, NULL, 129: ai_stand, 0, NULL, 130: ai_stand, 0, NULL, 131: ai_stand, 0, NULL, 132: ai_stand, 0, NULL, 133: ai_stand, 0, NULL, 134: ai_stand, 0, NULL, 135: ai_stand, 0, NULL, 136: ai_stand, 0, NULL, 137: ai_stand, 0, NULL, 138: ai_stand, 0, chick_fidget, 139: 140: }; 141: mmove_t chick_move_stand = {FRAME_stand101, FRAME_stand130, chick_frames_stand, NULL}; 142: 143: void chick_stand (edict_t *self) 144: { 145: self->monsterinfo.currentmove = &chick_move_stand; 146: } 147: 148: mframe_t chick_frames_start_run [] = 149: { 150: ai_run, 1, NULL, 151: ai_run, 0, NULL, 152: ai_run, 0, NULL, 153: ai_run, -1, NULL, 154: ai_run, -1, NULL, 155: ai_run, 0, NULL, 156: ai_run, 1, NULL, 157: ai_run, 3, NULL, 158: ai_run, 6, NULL, 159: ai_run, 3, NULL 160: }; 161: mmove_t chick_move_start_run = {FRAME_walk01, FRAME_walk10, chick_frames_start_run, chick_run}; 162: 163: mframe_t chick_frames_run [] = 164: { 165: ai_run, 6, NULL, 166: ai_run, 8, NULL, 167: ai_run, 13, NULL, 168: ai_run, 5, NULL, 169: ai_run, 7, NULL, 170: ai_run, 4, NULL, 171: ai_run, 11, NULL, 172: ai_run, 5, NULL, 173: ai_run, 9, NULL, 174: ai_run, 7, NULL 175: 176: }; 177: 178: mmove_t chick_move_run = {FRAME_walk11, FRAME_walk20, chick_frames_run, NULL}; 179: 180: mframe_t chick_frames_walk [] = 181: { 182: ai_walk, 6, NULL, 183: ai_walk, 8, NULL, 184: ai_walk, 13, NULL, 185: ai_walk, 5, NULL, 186: ai_walk, 7, NULL, 187: ai_walk, 4, NULL, 188: ai_walk, 11, NULL, 189: ai_walk, 5, NULL, 190: ai_walk, 9, NULL, 191: ai_walk, 7, NULL 192: }; 193: 194: mmove_t chick_move_walk = {FRAME_walk11, FRAME_walk20, chick_frames_walk, NULL}; 195: 196: void chick_walk (edict_t *self) 197: { 198: self->monsterinfo.currentmove = &chick_move_walk; 199: } 200: 201: void chick_run (edict_t *self) 202: { 203: if (self->monsterinfo.aiflags & AI_STAND_GROUND) 204: { 205: self->monsterinfo.currentmove = &chick_move_stand; 206: return; 207: } 208: 209: if (self->monsterinfo.currentmove == &chick_move_walk || 210: self->monsterinfo.currentmove == &chick_move_start_run) 211: { 212: self->monsterinfo.currentmove = &chick_move_run; 213: } 214: else 215: { 216: self->monsterinfo.currentmove = &chick_move_start_run; 217: } 218: } 219: 220: mframe_t chick_frames_pain1 [] = 221: { 222: ai_move, 0, NULL, 223: ai_move, 0, NULL, 224: ai_move, 0, NULL, 225: ai_move, 0, NULL, 226: ai_move, 0, NULL 227: }; 228: mmove_t chick_move_pain1 = {FRAME_pain101, FRAME_pain105, chick_frames_pain1, chick_run}; 229: 230: mframe_t chick_frames_pain2 [] = 231: { 232: ai_move, 0, NULL, 233: ai_move, 0, NULL, 234: ai_move, 0, NULL, 235: ai_move, 0, NULL, 236: ai_move, 0, NULL 237: }; 238: mmove_t chick_move_pain2 = {FRAME_pain201, FRAME_pain205, chick_frames_pain2, chick_run}; 239: 240: mframe_t chick_frames_pain3 [] = 241: { 242: ai_move, 0, NULL, 243: ai_move, 0, NULL, 244: ai_move, -6, NULL, 245: ai_move, 3, NULL, 246: ai_move, 11, NULL, 247: ai_move, 3, NULL, 248: ai_move, 0, NULL, 249: ai_move, 0, NULL, 250: ai_move, 4, NULL, 251: ai_move, 1, NULL, 252: ai_move, 0, NULL, 253: ai_move, -3, NULL, 254: ai_move, -4, NULL, 255: ai_move, 5, NULL, 256: ai_move, 7, NULL, 257: ai_move, -2, NULL, 258: ai_move, 3, NULL, 259: ai_move, -5, NULL, 260: ai_move, -2, NULL, 261: ai_move, -8, NULL, 262: ai_move, 2, NULL 263: }; 264: mmove_t chick_move_pain3 = {FRAME_pain301, FRAME_pain321, chick_frames_pain3, chick_run}; 265: 266: void chick_pain (edict_t *self, edict_t *other, float kick, int damage) 267: { 268: float r; 269: 270: if (self->health < (self->max_health / 2)) 271: self->s.skinnum = 1; 272: 273: if (level.time < self->pain_debounce_time) 274: return; 275: 276: self->pain_debounce_time = level.time + 3; 277: 278: r = random(); 279: if (r < 0.33) 280: gi.sound (self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0); 281: else if (r < 0.66) 282: gi.sound (self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0); 283: else 284: gi.sound (self, CHAN_VOICE, sound_pain3, 1, ATTN_NORM, 0); 285: 286: if (skill->value == 3) 287: return; // no pain anims in nightmare 288: 289: if (damage <= 10) 290: self->monsterinfo.currentmove = &chick_move_pain1; 291: else if (damage <= 25) 292: self->monsterinfo.currentmove = &chick_move_pain2; 293: else 294: self->monsterinfo.currentmove = &chick_move_pain3; 295: } 296: 297: void chick_dead (edict_t *self) 298: { 299: VectorSet (self->mins, -16, -16, 0); 300: VectorSet (self->maxs, 16, 16, 16); 301: self->movetype = MOVETYPE_TOSS; 302: self->svflags |= SVF_DEADMONSTER; 303: self->nextthink = 0; 304: gi.linkentity (self); 305: } 306: 307: mframe_t chick_frames_death2 [] = 308: { 309: ai_move, -6, NULL, 310: ai_move, 0, NULL, 311: ai_move, -1, NULL, 312: ai_move, -5, NULL, 313: ai_move, 0, NULL, 314: ai_move, -1, NULL, 315: ai_move, -2, NULL, 316: ai_move, 1, NULL, 317: ai_move, 10, NULL, 318: ai_move, 2, NULL, 319: ai_move, 3, NULL, 320: ai_move, 1, NULL, 321: ai_move, 2, NULL, 322: ai_move, 0, NULL, 323: ai_move, 3, NULL, 324: ai_move, 3, NULL, 325: ai_move, 1, NULL, 326: ai_move, -3, NULL, 327: ai_move, -5, NULL, 328: ai_move, 4, NULL, 329: ai_move, 15, NULL, 330: ai_move, 14, NULL, 331: ai_move, 1, NULL 332: }; 333: mmove_t chick_move_death2 = {FRAME_death201, FRAME_death223, chick_frames_death2, chick_dead}; 334: 335: mframe_t chick_frames_death1 [] = 336: { 337: ai_move, 0, NULL, 338: ai_move, 0, NULL, 339: ai_move, -7, NULL, 340: ai_move, 4, NULL, 341: ai_move, 11, NULL, 342: ai_move, 0, NULL, 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: 350: }; 351: mmove_t chick_move_death1 = {FRAME_death101, FRAME_death112, chick_frames_death1, chick_dead}; 352: 353: void chick_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) 354: { 355: int n; 356: 357: // check for gib 358: if (self->health <= self->gib_health) 359: { 360: gi.sound (self, CHAN_VOICE, gi.soundindex ("misc/udeath.wav"), 1, ATTN_NORM, 0); 361: for (n= 0; n < 2; n++) 362: ThrowGib (self, "models/objects/gibs/bone/tris.md2", damage, GIB_ORGANIC); 363: for (n= 0; n < 4; n++) 364: ThrowGib (self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC); 365: ThrowHead (self, "models/objects/gibs/head2/tris.md2", damage, GIB_ORGANIC); 366: self->deadflag = DEAD_DEAD; 367: return; 368: } 369: 370: if (self->deadflag == DEAD_DEAD) 371: return; 372: 373: // regular death 374: self->deadflag = DEAD_DEAD; 375: self->takedamage = DAMAGE_YES; 376: 377: n = rand() % 2; 378: if (n == 0) 379: { 380: self->monsterinfo.currentmove = &chick_move_death1; 381: gi.sound (self, CHAN_VOICE, sound_death1, 1, ATTN_NORM, 0); 382: } 383: else 384: { 385: self->monsterinfo.currentmove = &chick_move_death2; 386: gi.sound (self, CHAN_VOICE, sound_death2, 1, ATTN_NORM, 0); 387: } 388: } 389: 390: 391: void chick_duck_down (edict_t *self) 392: { 393: if (self->monsterinfo.aiflags & AI_DUCKED) 394: return; 395: self->monsterinfo.aiflags |= AI_DUCKED; 396: self->maxs[2] -= 32; 397: self->takedamage = DAMAGE_YES; 398: self->monsterinfo.pausetime = level.time + 1; 399: gi.linkentity (self); 400: } 401: 402: void chick_duck_hold (edict_t *self) 403: { 404: if (level.time >= self->monsterinfo.pausetime) 405: self->monsterinfo.aiflags &= ~AI_HOLD_FRAME; 406: else 407: self->monsterinfo.aiflags |= AI_HOLD_FRAME; 408: } 409: 410: void chick_duck_up (edict_t *self) 411: { 412: self->monsterinfo.aiflags &= ~AI_DUCKED; 413: self->maxs[2] += 32; 414: self->takedamage = DAMAGE_AIM; 415: gi.linkentity (self); 416: } 417: 418: mframe_t chick_frames_duck [] = 419: { 420: ai_move, 0, chick_duck_down, 421: ai_move, 1, NULL, 422: ai_move, 4, chick_duck_hold, 423: ai_move, -4, NULL, 424: ai_move, -5, chick_duck_up, 425: ai_move, 3, NULL, 426: ai_move, 1, NULL 427: }; 428: mmove_t chick_move_duck = {FRAME_duck01, FRAME_duck07, chick_frames_duck, chick_run}; 429: 430: void chick_dodge (edict_t *self, edict_t *attacker, float eta) 431: { 432: if (random() > 0.25) 433: return; 434: 435: if (!self->enemy) 436: self->enemy = attacker; 437: 438: self->monsterinfo.currentmove = &chick_move_duck; 439: } 440: 441: void ChickSlash (edict_t *self) 442: { 443: vec3_t aim; 444: 445: VectorSet (aim, MELEE_DISTANCE, self->mins[0], 10); 446: gi.sound (self, CHAN_WEAPON, sound_melee_swing, 1, ATTN_NORM, 0); 447: fire_hit (self, aim, (10 + (rand() %6)), 100); 448: } 449: 450: 451: void ChickRocket (edict_t *self) 452: { 453: vec3_t forward, right; 454: vec3_t start; 455: vec3_t dir; 456: vec3_t vec; 457: 458: AngleVectors (self->s.angles, forward, right, NULL); 459: G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_CHICK_ROCKET_1], forward, right, start); 460: 461: VectorCopy (self->enemy->s.origin, vec); 462: vec[2] += self->enemy->viewheight; 463: VectorSubtract (vec, start, dir); 464: VectorNormalize (dir); 465: 466: monster_fire_rocket (self, start, dir, 50, 500, MZ2_CHICK_ROCKET_1); 467: } 468: 469: void Chick_PreAttack1 (edict_t *self) 470: { 471: gi.sound (self, CHAN_VOICE, sound_missile_prelaunch, 1, ATTN_NORM, 0); 472: } 473: 474: void ChickReload (edict_t *self) 475: { 476: gi.sound (self, CHAN_VOICE, sound_missile_reload, 1, ATTN_NORM, 0); 477: } 478: 479: 480: mframe_t chick_frames_start_attack1 [] = 481: { 482: ai_charge, 0, Chick_PreAttack1, 483: ai_charge, 0, NULL, 484: ai_charge, 0, NULL, 485: ai_charge, 4, NULL, 486: ai_charge, 0, NULL, 487: ai_charge, -3, NULL, 488: ai_charge, 3, NULL, 489: ai_charge, 5, NULL, 490: ai_charge, 7, NULL, 491: ai_charge, 0, NULL, 492: ai_charge, 0, NULL, 493: ai_charge, 0, NULL, 494: ai_charge, 0, chick_attack1 495: }; 496: mmove_t chick_move_start_attack1 = {FRAME_attak101, FRAME_attak113, chick_frames_start_attack1, NULL}; 497: 498: 499: mframe_t chick_frames_attack1 [] = 500: { 501: ai_charge, 19, ChickRocket, 502: ai_charge, -6, NULL, 503: ai_charge, -5, NULL, 504: ai_charge, -2, NULL, 505: ai_charge, -7, NULL, 506: ai_charge, 0, NULL, 507: ai_charge, 1, NULL, 508: ai_charge, 10, ChickReload, 509: ai_charge, 4, NULL, 510: ai_charge, 5, NULL, 511: ai_charge, 6, NULL, 512: ai_charge, 6, NULL, 513: ai_charge, 4, NULL, 514: ai_charge, 3, chick_rerocket 515: 516: }; 517: mmove_t chick_move_attack1 = {FRAME_attak114, FRAME_attak127, chick_frames_attack1, NULL}; 518: 519: mframe_t chick_frames_end_attack1 [] = 520: { 521: ai_charge, -3, NULL, 522: ai_charge, 0, NULL, 523: ai_charge, -6, NULL, 524: ai_charge, -4, NULL, 525: ai_charge, -2, NULL 526: }; 527: mmove_t chick_move_end_attack1 = {FRAME_attak128, FRAME_attak132, chick_frames_end_attack1, chick_run}; 528: 529: void chick_rerocket(edict_t *self) 530: { 531: if (self->enemy->health > 0) 532: { 533: if (range (self, self->enemy) > RANGE_MELEE) 534: if ( visible (self, self->enemy) ) 535: if (random() <= 0.6) 536: { 537: self->monsterinfo.currentmove = &chick_move_attack1; 538: return; 539: } 540: } 541: self->monsterinfo.currentmove = &chick_move_end_attack1; 542: } 543: 544: void chick_attack1(edict_t *self) 545: { 546: self->monsterinfo.currentmove = &chick_move_attack1; 547: } 548: 549: mframe_t chick_frames_slash [] = 550: { 551: ai_charge, 1, NULL, 552: ai_charge, 7, ChickSlash, 553: ai_charge, -7, NULL, 554: ai_charge, 1, NULL, 555: ai_charge, -1, NULL, 556: ai_charge, 1, NULL, 557: ai_charge, 0, NULL, 558: ai_charge, 1, NULL, 559: ai_charge, -2, chick_reslash 560: }; 561: mmove_t chick_move_slash = {FRAME_attak204, FRAME_attak212, chick_frames_slash, NULL}; 562: 563: mframe_t chick_frames_end_slash [] = 564: { 565: ai_charge, -6, NULL, 566: ai_charge, -1, NULL, 567: ai_charge, -6, NULL, 568: ai_charge, 0, NULL 569: }; 570: mmove_t chick_move_end_slash = {FRAME_attak213, FRAME_attak216, chick_frames_end_slash, chick_run}; 571: 572: 573: void chick_reslash(edict_t *self) 574: { 575: if (self->enemy->health > 0) 576: { 577: if (range (self, self->enemy) == RANGE_MELEE) 578: if (random() <= 0.9) 579: { 580: self->monsterinfo.currentmove = &chick_move_slash; 581: return; 582: } 583: else 584: { 585: self->monsterinfo.currentmove = &chick_move_end_slash; 586: return; 587: } 588: } 589: self->monsterinfo.currentmove = &chick_move_end_slash; 590: } 591: 592: void chick_slash(edict_t *self) 593: { 594: self->monsterinfo.currentmove = &chick_move_slash; 595: } 596: 597: 598: mframe_t chick_frames_start_slash [] = 599: { 600: ai_charge, 1, NULL, 601: ai_charge, 8, NULL, 602: ai_charge, 3, NULL 603: }; 604: mmove_t chick_move_start_slash = {FRAME_attak201, FRAME_attak203, chick_frames_start_slash, chick_slash}; 605: 606: 607: 608: void chick_melee(edict_t *self) 609: { 610: self->monsterinfo.currentmove = &chick_move_start_slash; 611: } 612: 613: 614: void chick_attack(edict_t *self) 615: { 616: self->monsterinfo.currentmove = &chick_move_start_attack1; 617: } 618: 619: void chick_sight(edict_t *self, edict_t *other) 620: { 621: gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0); 622: } 623: 624: /*QUAKED monster_chick (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight 625: */ 626: void SP_monster_chick (edict_t *self) 627: { 628: if (deathmatch->value) 629: { 630: G_FreeEdict (self); 631: return; 632: } 633: 634: sound_missile_prelaunch = gi.soundindex ("chick/chkatck1.wav"); 635: sound_missile_launch = gi.soundindex ("chick/chkatck2.wav"); 636: sound_melee_swing = gi.soundindex ("chick/chkatck3.wav"); 637: sound_melee_hit = gi.soundindex ("chick/chkatck4.wav"); 638: sound_missile_reload = gi.soundindex ("chick/chkatck5.wav"); 639: sound_death1 = gi.soundindex ("chick/chkdeth1.wav"); 640: sound_death2 = gi.soundindex ("chick/chkdeth2.wav"); 641: sound_fall_down = gi.soundindex ("chick/chkfall1.wav"); 642: sound_idle1 = gi.soundindex ("chick/chkidle1.wav"); 643: sound_idle2 = gi.soundindex ("chick/chkidle2.wav"); 644: sound_pain1 = gi.soundindex ("chick/chkpain1.wav"); 645: sound_pain2 = gi.soundindex ("chick/chkpain2.wav"); 646: sound_pain3 = gi.soundindex ("chick/chkpain3.wav"); 647: sound_sight = gi.soundindex ("chick/chksght1.wav"); 648: sound_search = gi.soundindex ("chick/chksrch1.wav"); 649: 650: self->movetype = MOVETYPE_STEP; 651: self->solid = SOLID_BBOX; 652: self->s.modelindex = gi.modelindex ("models/monsters/bitch/tris.md2"); 653: VectorSet (self->mins, -16, -16, 0); 654: VectorSet (self->maxs, 16, 16, 56); 655: 656: self->health = 175; 657: self->gib_health = -70; 658: self->mass = 200; 659: 660: self->pain = chick_pain; 661: self->die = chick_die; 662: 663: self->monsterinfo.stand = chick_stand; 664: self->monsterinfo.walk = chick_walk; 665: self->monsterinfo.run = chick_run; 666: self->monsterinfo.dodge = chick_dodge; 667: self->monsterinfo.attack = chick_attack; 668: self->monsterinfo.melee = chick_melee; 669: self->monsterinfo.sight = chick_sight; 670: 671: gi.linkentity (self); 672: 673: self->monsterinfo.currentmove = &chick_move_stand; 674: self->monsterinfo.scale = MODEL_SCALE; 675: 676: walkmonster_start (self); 677: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.