|
|
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: flyer 24: 25: ============================================================================== 26: */ 27: 28: #include "g_local.h" 29: #include "m_flyer.h" 30: 31: qboolean visible (edict_t *self, edict_t *other); 32: 33: static int nextmove; // Used for start/stop frames 34: 35: static int sound_sight; 36: static int sound_idle; 37: static int sound_pain1; 38: static int sound_pain2; 39: static int sound_slash; 40: static int sound_sproing; 41: static int sound_die; 42: 43: 44: void flyer_check_melee(edict_t *self); 45: void flyer_loop_melee (edict_t *self); 46: void flyer_melee (edict_t *self); 47: void flyer_setstart (edict_t *self); 48: void flyer_stand (edict_t *self); 49: void flyer_nextmove (edict_t *self); 50: 51: 52: void flyer_sight (edict_t *self, edict_t *other) 53: { 54: gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0); 55: } 56: 57: void flyer_idle (edict_t *self) 58: { 59: gi.sound (self, CHAN_VOICE, sound_idle, 1, ATTN_IDLE, 0); 60: } 61: 62: void flyer_pop_blades (edict_t *self) 63: { 64: gi.sound (self, CHAN_VOICE, sound_sproing, 1, ATTN_NORM, 0); 65: } 66: 67: 68: mframe_t flyer_frames_stand [] = 69: { 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, 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: ai_stand, 0, NULL, 97: ai_stand, 0, NULL, 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, 108: ai_stand, 0, NULL, 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: }; 116: mmove_t flyer_move_stand = {FRAME_stand01, FRAME_stand45, flyer_frames_stand, NULL}; 117: 118: 119: mframe_t flyer_frames_walk [] = 120: { 121: ai_walk, 5, NULL, 122: ai_walk, 5, NULL, 123: ai_walk, 5, NULL, 124: ai_walk, 5, NULL, 125: ai_walk, 5, NULL, 126: ai_walk, 5, NULL, 127: ai_walk, 5, NULL, 128: ai_walk, 5, NULL, 129: ai_walk, 5, NULL, 130: ai_walk, 5, NULL, 131: ai_walk, 5, NULL, 132: ai_walk, 5, NULL, 133: ai_walk, 5, NULL, 134: ai_walk, 5, NULL, 135: ai_walk, 5, NULL, 136: ai_walk, 5, NULL, 137: ai_walk, 5, NULL, 138: ai_walk, 5, NULL, 139: ai_walk, 5, NULL, 140: ai_walk, 5, NULL, 141: ai_walk, 5, NULL, 142: ai_walk, 5, NULL, 143: ai_walk, 5, NULL, 144: ai_walk, 5, NULL, 145: ai_walk, 5, NULL, 146: ai_walk, 5, NULL, 147: ai_walk, 5, NULL, 148: ai_walk, 5, NULL, 149: ai_walk, 5, NULL, 150: ai_walk, 5, NULL, 151: ai_walk, 5, NULL, 152: ai_walk, 5, NULL, 153: ai_walk, 5, NULL, 154: ai_walk, 5, NULL, 155: ai_walk, 5, NULL, 156: ai_walk, 5, NULL, 157: ai_walk, 5, NULL, 158: ai_walk, 5, NULL, 159: ai_walk, 5, NULL, 160: ai_walk, 5, NULL, 161: ai_walk, 5, NULL, 162: ai_walk, 5, NULL, 163: ai_walk, 5, NULL, 164: ai_walk, 5, NULL, 165: ai_walk, 5, NULL 166: }; 167: mmove_t flyer_move_walk = {FRAME_stand01, FRAME_stand45, flyer_frames_walk, NULL}; 168: 169: mframe_t flyer_frames_run [] = 170: { 171: ai_run, 10, NULL, 172: ai_run, 10, NULL, 173: ai_run, 10, NULL, 174: ai_run, 10, NULL, 175: ai_run, 10, NULL, 176: ai_run, 10, NULL, 177: ai_run, 10, NULL, 178: ai_run, 10, NULL, 179: ai_run, 10, NULL, 180: ai_run, 10, NULL, 181: ai_run, 10, NULL, 182: ai_run, 10, NULL, 183: ai_run, 10, NULL, 184: ai_run, 10, NULL, 185: ai_run, 10, NULL, 186: ai_run, 10, NULL, 187: ai_run, 10, NULL, 188: ai_run, 10, NULL, 189: ai_run, 10, NULL, 190: ai_run, 10, NULL, 191: ai_run, 10, NULL, 192: ai_run, 10, NULL, 193: ai_run, 10, NULL, 194: ai_run, 10, NULL, 195: ai_run, 10, NULL, 196: ai_run, 10, NULL, 197: ai_run, 10, NULL, 198: ai_run, 10, NULL, 199: ai_run, 10, NULL, 200: ai_run, 10, NULL, 201: ai_run, 10, NULL, 202: ai_run, 10, NULL, 203: ai_run, 10, NULL, 204: ai_run, 10, NULL, 205: ai_run, 10, NULL, 206: ai_run, 10, NULL, 207: ai_run, 10, NULL, 208: ai_run, 10, NULL, 209: ai_run, 10, NULL, 210: ai_run, 10, NULL, 211: ai_run, 10, NULL, 212: ai_run, 10, NULL, 213: ai_run, 10, NULL, 214: ai_run, 10, NULL, 215: ai_run, 10, NULL 216: }; 217: mmove_t flyer_move_run = {FRAME_stand01, FRAME_stand45, flyer_frames_run, NULL}; 218: 219: void flyer_run (edict_t *self) 220: { 221: if (self->monsterinfo.aiflags & AI_STAND_GROUND) 222: self->monsterinfo.currentmove = &flyer_move_stand; 223: else 224: self->monsterinfo.currentmove = &flyer_move_run; 225: } 226: 227: void flyer_walk (edict_t *self) 228: { 229: self->monsterinfo.currentmove = &flyer_move_walk; 230: } 231: 232: void flyer_stand (edict_t *self) 233: { 234: self->monsterinfo.currentmove = &flyer_move_stand; 235: } 236: 237: mframe_t flyer_frames_start [] = 238: { 239: ai_move, 0, NULL, 240: ai_move, 0, NULL, 241: ai_move, 0, NULL, 242: ai_move, 0, NULL, 243: ai_move, 0, NULL, 244: ai_move, 0, flyer_nextmove 245: }; 246: mmove_t flyer_move_start = {FRAME_start01, FRAME_start06, flyer_frames_start, NULL}; 247: 248: mframe_t flyer_frames_stop [] = 249: { 250: ai_move, 0, NULL, 251: ai_move, 0, NULL, 252: ai_move, 0, NULL, 253: ai_move, 0, NULL, 254: ai_move, 0, NULL, 255: ai_move, 0, NULL, 256: ai_move, 0, flyer_nextmove 257: }; 258: mmove_t flyer_move_stop = {FRAME_stop01, FRAME_stop07, flyer_frames_stop, NULL}; 259: 260: void flyer_stop (edict_t *self) 261: { 262: self->monsterinfo.currentmove = &flyer_move_stop; 263: } 264: 265: void flyer_start (edict_t *self) 266: { 267: self->monsterinfo.currentmove = &flyer_move_start; 268: } 269: 270: 271: mframe_t flyer_frames_rollright [] = 272: { 273: ai_move, 0, NULL, 274: ai_move, 0, NULL, 275: ai_move, 0, NULL, 276: ai_move, 0, NULL, 277: ai_move, 0, NULL, 278: ai_move, 0, NULL, 279: ai_move, 0, NULL, 280: ai_move, 0, NULL, 281: ai_move, 0, NULL 282: }; 283: mmove_t flyer_move_rollright = {FRAME_rollr01, FRAME_rollr09, flyer_frames_rollright, NULL}; 284: 285: mframe_t flyer_frames_rollleft [] = 286: { 287: ai_move, 0, NULL, 288: ai_move, 0, NULL, 289: ai_move, 0, NULL, 290: ai_move, 0, NULL, 291: ai_move, 0, NULL, 292: ai_move, 0, NULL, 293: ai_move, 0, NULL, 294: ai_move, 0, NULL, 295: ai_move, 0, NULL 296: }; 297: mmove_t flyer_move_rollleft = {FRAME_rollf01, FRAME_rollf09, flyer_frames_rollleft, NULL}; 298: 299: mframe_t flyer_frames_pain3 [] = 300: { 301: ai_move, 0, NULL, 302: ai_move, 0, NULL, 303: ai_move, 0, NULL, 304: ai_move, 0, NULL 305: }; 306: mmove_t flyer_move_pain3 = {FRAME_pain301, FRAME_pain304, flyer_frames_pain3, flyer_run}; 307: 308: mframe_t flyer_frames_pain2 [] = 309: { 310: ai_move, 0, NULL, 311: ai_move, 0, NULL, 312: ai_move, 0, NULL, 313: ai_move, 0, NULL 314: }; 315: mmove_t flyer_move_pain2 = {FRAME_pain201, FRAME_pain204, flyer_frames_pain2, flyer_run}; 316: 317: mframe_t flyer_frames_pain1 [] = 318: { 319: ai_move, 0, NULL, 320: ai_move, 0, NULL, 321: ai_move, 0, NULL, 322: ai_move, 0, NULL, 323: ai_move, 0, NULL, 324: ai_move, 0, NULL, 325: ai_move, 0, NULL, 326: ai_move, 0, NULL, 327: ai_move, 0, NULL 328: }; 329: mmove_t flyer_move_pain1 = {FRAME_pain101, FRAME_pain109, flyer_frames_pain1, flyer_run}; 330: 331: mframe_t flyer_frames_defense [] = 332: { 333: ai_move, 0, NULL, 334: ai_move, 0, NULL, 335: ai_move, 0, NULL, // Hold this frame 336: ai_move, 0, NULL, 337: ai_move, 0, NULL, 338: ai_move, 0, NULL 339: }; 340: mmove_t flyer_move_defense = {FRAME_defens01, FRAME_defens06, flyer_frames_defense, NULL}; 341: 342: mframe_t flyer_frames_bankright [] = 343: { 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: ai_move, 0, NULL, 350: ai_move, 0, NULL 351: }; 352: mmove_t flyer_move_bankright = {FRAME_bankr01, FRAME_bankr07, flyer_frames_bankright, NULL}; 353: 354: mframe_t flyer_frames_bankleft [] = 355: { 356: ai_move, 0, NULL, 357: ai_move, 0, NULL, 358: ai_move, 0, NULL, 359: ai_move, 0, NULL, 360: ai_move, 0, NULL, 361: ai_move, 0, NULL, 362: ai_move, 0, NULL 363: }; 364: mmove_t flyer_move_bankleft = {FRAME_bankl01, FRAME_bankl07, flyer_frames_bankleft, NULL}; 365: 366: 367: void flyer_fire (edict_t *self, int flash_number) 368: { 369: vec3_t start; 370: vec3_t forward, right; 371: vec3_t end; 372: vec3_t dir; 373: int effect; 374: 375: if ((self->s.frame == FRAME_attak204) || (self->s.frame == FRAME_attak207) || (self->s.frame == FRAME_attak210)) 376: effect = EF_HYPERBLASTER; 377: else 378: effect = 0; 379: AngleVectors (self->s.angles, forward, right, NULL); 380: G_ProjectSource (self->s.origin, monster_flash_offset[flash_number], forward, right, start); 381: 382: VectorCopy (self->enemy->s.origin, end); 383: end[2] += self->enemy->viewheight; 384: VectorSubtract (end, start, dir); 385: 386: monster_fire_blaster (self, start, dir, 1, 1000, flash_number, effect); 387: } 388: 389: void flyer_fireleft (edict_t *self) 390: { 391: flyer_fire (self, MZ2_FLYER_BLASTER_1); 392: } 393: 394: void flyer_fireright (edict_t *self) 395: { 396: flyer_fire (self, MZ2_FLYER_BLASTER_2); 397: } 398: 399: 400: mframe_t flyer_frames_attack2 [] = 401: { 402: ai_charge, 0, NULL, 403: ai_charge, 0, NULL, 404: ai_charge, 0, NULL, 405: ai_charge, -10, flyer_fireleft, // left gun 406: ai_charge, -10, flyer_fireright, // right gun 407: ai_charge, -10, flyer_fireleft, // left gun 408: ai_charge, -10, flyer_fireright, // right gun 409: ai_charge, -10, flyer_fireleft, // left gun 410: ai_charge, -10, flyer_fireright, // right gun 411: ai_charge, -10, flyer_fireleft, // left gun 412: ai_charge, -10, flyer_fireright, // right gun 413: ai_charge, 0, NULL, 414: ai_charge, 0, NULL, 415: ai_charge, 0, NULL, 416: ai_charge, 0, NULL, 417: ai_charge, 0, NULL, 418: ai_charge, 0, NULL 419: }; 420: mmove_t flyer_move_attack2 = {FRAME_attak201, FRAME_attak217, flyer_frames_attack2, flyer_run}; 421: 422: 423: void flyer_slash_left (edict_t *self) 424: { 425: vec3_t aim; 426: 427: VectorSet (aim, MELEE_DISTANCE, self->mins[0], 0); 428: fire_hit (self, aim, 5, 0); 429: gi.sound (self, CHAN_WEAPON, sound_slash, 1, ATTN_NORM, 0); 430: } 431: 432: void flyer_slash_right (edict_t *self) 433: { 434: vec3_t aim; 435: 436: VectorSet (aim, MELEE_DISTANCE, self->maxs[0], 0); 437: fire_hit (self, aim, 5, 0); 438: gi.sound (self, CHAN_WEAPON, sound_slash, 1, ATTN_NORM, 0); 439: } 440: 441: mframe_t flyer_frames_start_melee [] = 442: { 443: ai_charge, 0, flyer_pop_blades, 444: ai_charge, 0, NULL, 445: ai_charge, 0, NULL, 446: ai_charge, 0, NULL, 447: ai_charge, 0, NULL, 448: ai_charge, 0, NULL 449: }; 450: mmove_t flyer_move_start_melee = {FRAME_attak101, FRAME_attak106, flyer_frames_start_melee, flyer_loop_melee}; 451: 452: mframe_t flyer_frames_end_melee [] = 453: { 454: ai_charge, 0, NULL, 455: ai_charge, 0, NULL, 456: ai_charge, 0, NULL 457: }; 458: mmove_t flyer_move_end_melee = {FRAME_attak119, FRAME_attak121, flyer_frames_end_melee, flyer_run}; 459: 460: 461: mframe_t flyer_frames_loop_melee [] = 462: { 463: ai_charge, 0, NULL, // Loop Start 464: ai_charge, 0, NULL, 465: ai_charge, 0, flyer_slash_left, // Left Wing Strike 466: ai_charge, 0, NULL, 467: ai_charge, 0, NULL, 468: ai_charge, 0, NULL, 469: ai_charge, 0, NULL, 470: ai_charge, 0, flyer_slash_right, // Right Wing Strike 471: ai_charge, 0, NULL, 472: ai_charge, 0, NULL, 473: ai_charge, 0, NULL, 474: ai_charge, 0, NULL // Loop Ends 475: 476: }; 477: mmove_t flyer_move_loop_melee = {FRAME_attak107, FRAME_attak118, flyer_frames_loop_melee, flyer_check_melee}; 478: 479: void flyer_loop_melee (edict_t *self) 480: { 481: /* if (random() <= 0.5) 482: self->monsterinfo.currentmove = &flyer_move_attack1; 483: else */ 484: self->monsterinfo.currentmove = &flyer_move_loop_melee; 485: } 486: 487: 488: 489: void flyer_attack (edict_t *self) 490: { 491: /* if (random() <= 0.5) 492: self->monsterinfo.currentmove = &flyer_move_attack1; 493: else */ 494: self->monsterinfo.currentmove = &flyer_move_attack2; 495: } 496: 497: void flyer_setstart (edict_t *self) 498: { 499: nextmove = ACTION_run; 500: self->monsterinfo.currentmove = &flyer_move_start; 501: } 502: 503: void flyer_nextmove (edict_t *self) 504: { 505: if (nextmove == ACTION_attack1) 506: self->monsterinfo.currentmove = &flyer_move_start_melee; 507: else if (nextmove == ACTION_attack2) 508: self->monsterinfo.currentmove = &flyer_move_attack2; 509: else if (nextmove == ACTION_run) 510: self->monsterinfo.currentmove = &flyer_move_run; 511: } 512: 513: void flyer_melee (edict_t *self) 514: { 515: // flyer.nextmove = ACTION_attack1; 516: // self->monsterinfo.currentmove = &flyer_move_stop; 517: self->monsterinfo.currentmove = &flyer_move_start_melee; 518: } 519: 520: void flyer_check_melee(edict_t *self) 521: { 522: if (range (self, self->enemy) == RANGE_MELEE) 523: if (random() <= 0.8) 524: self->monsterinfo.currentmove = &flyer_move_loop_melee; 525: else 526: self->monsterinfo.currentmove = &flyer_move_end_melee; 527: else 528: self->monsterinfo.currentmove = &flyer_move_end_melee; 529: } 530: 531: void flyer_pain (edict_t *self, edict_t *other, float kick, int damage) 532: { 533: int n; 534: 535: if (self->health < (self->max_health / 2)) 536: self->s.skinnum = 1; 537: 538: if (level.time < self->pain_debounce_time) 539: return; 540: 541: self->pain_debounce_time = level.time + 3; 542: if (skill->value == 3) 543: return; // no pain anims in nightmare 544: 545: n = rand() % 3; 546: if (n == 0) 547: { 548: gi.sound (self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0); 549: self->monsterinfo.currentmove = &flyer_move_pain1; 550: } 551: else if (n == 1) 552: { 553: gi.sound (self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0); 554: self->monsterinfo.currentmove = &flyer_move_pain2; 555: } 556: else 557: { 558: gi.sound (self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0); 559: self->monsterinfo.currentmove = &flyer_move_pain3; 560: } 561: } 562: 563: 564: void flyer_die(edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) 565: { 566: gi.sound (self, CHAN_VOICE, sound_die, 1, ATTN_NORM, 0); 567: BecomeExplosion1(self); 568: } 569: 570: 571: /*QUAKED monster_flyer (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight 572: */ 573: void SP_monster_flyer (edict_t *self) 574: { 575: if (deathmatch->value) 576: { 577: G_FreeEdict (self); 578: return; 579: } 580: 581: // fix a map bug in jail5.bsp 582: if (!Q_stricmp(level.mapname, "jail5") && (self->s.origin[2] == -104)) 583: { 584: self->targetname = self->target; 585: self->target = NULL; 586: } 587: 588: sound_sight = gi.soundindex ("flyer/flysght1.wav"); 589: sound_idle = gi.soundindex ("flyer/flysrch1.wav"); 590: sound_pain1 = gi.soundindex ("flyer/flypain1.wav"); 591: sound_pain2 = gi.soundindex ("flyer/flypain2.wav"); 592: sound_slash = gi.soundindex ("flyer/flyatck2.wav"); 593: sound_sproing = gi.soundindex ("flyer/flyatck1.wav"); 594: sound_die = gi.soundindex ("flyer/flydeth1.wav"); 595: 596: gi.soundindex ("flyer/flyatck3.wav"); 597: 598: self->s.modelindex = gi.modelindex ("models/monsters/flyer/tris.md2"); 599: VectorSet (self->mins, -16, -16, -24); 600: VectorSet (self->maxs, 16, 16, 32); 601: self->movetype = MOVETYPE_STEP; 602: self->solid = SOLID_BBOX; 603: 604: self->s.sound = gi.soundindex ("flyer/flyidle1.wav"); 605: 606: self->health = 50; 607: self->mass = 50; 608: 609: self->pain = flyer_pain; 610: self->die = flyer_die; 611: 612: self->monsterinfo.stand = flyer_stand; 613: self->monsterinfo.walk = flyer_walk; 614: self->monsterinfo.run = flyer_run; 615: self->monsterinfo.attack = flyer_attack; 616: self->monsterinfo.melee = flyer_melee; 617: self->monsterinfo.sight = flyer_sight; 618: self->monsterinfo.idle = flyer_idle; 619: 620: gi.linkentity (self); 621: 622: self->monsterinfo.currentmove = &flyer_move_stand; 623: self->monsterinfo.scale = MODEL_SCALE; 624: 625: flymonster_start (self); 626: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.