|
|
1.1 ! root 1: /* ! 2: ============================================================================== ! 3: ! 4: flyer ! 5: ! 6: ============================================================================== ! 7: */ ! 8: ! 9: #include "g_local.h" ! 10: #include "m_flyer.h" ! 11: ! 12: qboolean visible (edict_t *self, edict_t *other); ! 13: ! 14: static int nextmove; // Used for start/stop frames ! 15: ! 16: static int sound_sight; ! 17: static int sound_idle; ! 18: static int sound_pain1; ! 19: static int sound_pain2; ! 20: static int sound_slash; ! 21: static int sound_sproing; ! 22: static int sound_die; ! 23: ! 24: ! 25: void flyer_check_melee(edict_t *self); ! 26: void flyer_loop_melee (edict_t *self); ! 27: void flyer_melee (edict_t *self); ! 28: void flyer_setstart (edict_t *self); ! 29: void flyer_stand (edict_t *self); ! 30: void flyer_nextmove (edict_t *self); ! 31: ! 32: // ROGUE - kamikaze stuff ! 33: void flyer_kamikaze (edict_t *self); ! 34: void flyer_kamikaze_check (edict_t *self); ! 35: void flyer_die(edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point); ! 36: ! 37: void showme1 (edict_t *self) ! 38: { ! 39: if (!self->dmg) ! 40: { ! 41: gi.dprintf ("straight - %d\n", self->monsterinfo.lefty); ! 42: self->dmg = 1; ! 43: } ! 44: } ! 45: ! 46: void showme2 (edict_t *self) ! 47: { ! 48: if (!self->dmg) ! 49: { ! 50: gi.dprintf ("strafe - %d\n", self->monsterinfo.lefty); ! 51: self->dmg = 1; ! 52: } ! 53: } ! 54: ! 55: ! 56: void flyer_sight (edict_t *self, edict_t *other) ! 57: { ! 58: gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0); ! 59: } ! 60: ! 61: void flyer_idle (edict_t *self) ! 62: { ! 63: gi.sound (self, CHAN_VOICE, sound_idle, 1, ATTN_IDLE, 0); ! 64: } ! 65: ! 66: void flyer_pop_blades (edict_t *self) ! 67: { ! 68: gi.sound (self, CHAN_VOICE, sound_sproing, 1, ATTN_NORM, 0); ! 69: } ! 70: ! 71: ! 72: mframe_t flyer_frames_stand [] = ! 73: { ! 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: ai_stand, 0, NULL, ! 116: ai_stand, 0, NULL, ! 117: ai_stand, 0, NULL, ! 118: ai_stand, 0, NULL ! 119: }; ! 120: mmove_t flyer_move_stand = {FRAME_stand01, FRAME_stand45, flyer_frames_stand, NULL}; ! 121: ! 122: ! 123: mframe_t flyer_frames_walk [] = ! 124: { ! 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: ai_walk, 5, NULL, ! 167: ai_walk, 5, NULL, ! 168: ai_walk, 5, NULL, ! 169: ai_walk, 5, NULL ! 170: }; ! 171: mmove_t flyer_move_walk = {FRAME_stand01, FRAME_stand45, flyer_frames_walk, NULL}; ! 172: ! 173: mframe_t flyer_frames_run [] = ! 174: { ! 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: ai_run, 10, NULL, ! 217: ai_run, 10, NULL, ! 218: ai_run, 10, NULL, ! 219: ai_run, 10, NULL ! 220: }; ! 221: mmove_t flyer_move_run = {FRAME_stand01, FRAME_stand45, flyer_frames_run, NULL}; ! 222: ! 223: mframe_t flyer_frames_kamizake [] = ! 224: { ! 225: ai_charge, 40, flyer_kamikaze_check, ! 226: ai_charge, 40, flyer_kamikaze_check, ! 227: ai_charge, 40, flyer_kamikaze_check, ! 228: ai_charge, 40, flyer_kamikaze_check, ! 229: ai_charge, 40, flyer_kamikaze_check ! 230: }; ! 231: mmove_t flyer_move_kamikaze = {FRAME_rollr02, FRAME_rollr06, flyer_frames_kamizake, flyer_kamikaze}; ! 232: ! 233: void flyer_run (edict_t *self) ! 234: { ! 235: if (self->mass > 50) ! 236: self->monsterinfo.currentmove = &flyer_move_kamikaze; ! 237: else ! 238: if (self->monsterinfo.aiflags & AI_STAND_GROUND) ! 239: self->monsterinfo.currentmove = &flyer_move_stand; ! 240: else ! 241: self->monsterinfo.currentmove = &flyer_move_run; ! 242: } ! 243: ! 244: void flyer_walk (edict_t *self) ! 245: { ! 246: if (self->mass > 50) ! 247: flyer_run (self); ! 248: else ! 249: self->monsterinfo.currentmove = &flyer_move_walk; ! 250: } ! 251: ! 252: void flyer_stand (edict_t *self) ! 253: { ! 254: if (self->mass > 50) ! 255: flyer_run (self); ! 256: else ! 257: self->monsterinfo.currentmove = &flyer_move_stand; ! 258: } ! 259: ! 260: // ROGUE - kamikaze stuff ! 261: ! 262: void flyer_kamikaze_explode (edict_t *self) ! 263: { ! 264: vec3_t dir; ! 265: ! 266: if (self->monsterinfo.commander && self->monsterinfo.commander->inuse && ! 267: !strcmp(self->monsterinfo.commander->classname, "monster_carrier")) ! 268: { ! 269: self->monsterinfo.commander->monsterinfo.monster_slots++; ! 270: if ((g_showlogic) && (g_showlogic->value)) ! 271: gi.dprintf ("suicide hit!. %d slots left\n", self->monsterinfo.commander->monsterinfo.monster_slots); ! 272: } ! 273: ! 274: // gi.dprintf ("boom!\n"); ! 275: // T_RadiusDamage(self, self->owner, 125, self, self->dmg_radius, MOD_NUKE); ! 276: // T_RadiusDamage(self, self->owner, 125, self, 150, MOD_NUKE); ! 277: if (self->enemy) ! 278: { ! 279: VectorSubtract (self->enemy->s.origin, self->s.origin, dir); ! 280: //void T_Damage (edict_t *targ, edict_t *inflictor, edict_t *attacker, vec3_t dir, vec3_t point, ! 281: // vec3_t normal, int damage, int knockback, int dflags, int mod) ! 282: T_Damage (self->enemy, self, self, dir, self->s.origin, vec3_origin, (int)50, (int)50, DAMAGE_RADIUS, MOD_UNKNOWN); ! 283: } ! 284: ! 285: flyer_die (self, NULL, NULL, 0, dir); ! 286: /* VectorMA (self->s.origin, -0.02, self->velocity, origin); ! 287: gi.WriteByte (svc_temp_entity); ! 288: gi.WriteByte (TE_ROCKET_EXPLOSION); ! 289: gi.WritePosition (origin); ! 290: gi.multicast (self->s.origin, MULTICAST_PHS); ! 291: ! 292: G_FreeEdict (self); ! 293: */ ! 294: } ! 295: ! 296: void flyer_kamikaze (edict_t *self) ! 297: { ! 298: self->monsterinfo.currentmove = &flyer_move_kamikaze; ! 299: } ! 300: ! 301: void flyer_kamikaze_check (edict_t *self) ! 302: { ! 303: float dist; ! 304: ! 305: // PMM - this needed because we could have gone away before we get here (blocked code) ! 306: if (!self->inuse) ! 307: return; ! 308: ! 309: if ((!self->enemy) || (!self->enemy->inuse)) ! 310: { ! 311: flyer_kamikaze_explode (self); ! 312: return; ! 313: } ! 314: ! 315: self->goalentity = self->enemy; ! 316: ! 317: dist = realrange (self, self->enemy); ! 318: ! 319: if (dist < 90) ! 320: flyer_kamikaze_explode (self); ! 321: } ! 322: ! 323: // rogue - kamikaze ! 324: ! 325: mframe_t flyer_frames_start [] = ! 326: { ! 327: ai_move, 0, NULL, ! 328: ai_move, 0, NULL, ! 329: ai_move, 0, NULL, ! 330: ai_move, 0, NULL, ! 331: ai_move, 0, NULL, ! 332: ai_move, 0, flyer_nextmove ! 333: }; ! 334: mmove_t flyer_move_start = {FRAME_start01, FRAME_start06, flyer_frames_start, NULL}; ! 335: ! 336: mframe_t flyer_frames_stop [] = ! 337: { ! 338: ai_move, 0, NULL, ! 339: ai_move, 0, NULL, ! 340: ai_move, 0, NULL, ! 341: ai_move, 0, NULL, ! 342: ai_move, 0, NULL, ! 343: ai_move, 0, NULL, ! 344: ai_move, 0, flyer_nextmove ! 345: }; ! 346: mmove_t flyer_move_stop = {FRAME_stop01, FRAME_stop07, flyer_frames_stop, NULL}; ! 347: ! 348: void flyer_stop (edict_t *self) ! 349: { ! 350: self->monsterinfo.currentmove = &flyer_move_stop; ! 351: } ! 352: ! 353: void flyer_start (edict_t *self) ! 354: { ! 355: self->monsterinfo.currentmove = &flyer_move_start; ! 356: } ! 357: ! 358: ! 359: mframe_t flyer_frames_rollright [] = ! 360: { ! 361: ai_move, 0, NULL, ! 362: ai_move, 0, NULL, ! 363: ai_move, 0, NULL, ! 364: ai_move, 0, NULL, ! 365: ai_move, 0, NULL, ! 366: ai_move, 0, NULL, ! 367: ai_move, 0, NULL, ! 368: ai_move, 0, NULL, ! 369: ai_move, 0, NULL ! 370: }; ! 371: mmove_t flyer_move_rollright = {FRAME_rollr01, FRAME_rollr09, flyer_frames_rollright, NULL}; ! 372: ! 373: mframe_t flyer_frames_rollleft [] = ! 374: { ! 375: ai_move, 0, NULL, ! 376: ai_move, 0, NULL, ! 377: ai_move, 0, NULL, ! 378: ai_move, 0, NULL, ! 379: ai_move, 0, NULL, ! 380: ai_move, 0, NULL, ! 381: ai_move, 0, NULL, ! 382: ai_move, 0, NULL, ! 383: ai_move, 0, NULL ! 384: }; ! 385: mmove_t flyer_move_rollleft = {FRAME_rollf01, FRAME_rollf09, flyer_frames_rollleft, NULL}; ! 386: ! 387: mframe_t flyer_frames_pain3 [] = ! 388: { ! 389: ai_move, 0, NULL, ! 390: ai_move, 0, NULL, ! 391: ai_move, 0, NULL, ! 392: ai_move, 0, NULL ! 393: }; ! 394: mmove_t flyer_move_pain3 = {FRAME_pain301, FRAME_pain304, flyer_frames_pain3, flyer_run}; ! 395: ! 396: mframe_t flyer_frames_pain2 [] = ! 397: { ! 398: ai_move, 0, NULL, ! 399: ai_move, 0, NULL, ! 400: ai_move, 0, NULL, ! 401: ai_move, 0, NULL ! 402: }; ! 403: mmove_t flyer_move_pain2 = {FRAME_pain201, FRAME_pain204, flyer_frames_pain2, flyer_run}; ! 404: ! 405: mframe_t flyer_frames_pain1 [] = ! 406: { ! 407: ai_move, 0, NULL, ! 408: ai_move, 0, NULL, ! 409: ai_move, 0, NULL, ! 410: ai_move, 0, NULL, ! 411: ai_move, 0, NULL, ! 412: ai_move, 0, NULL, ! 413: ai_move, 0, NULL, ! 414: ai_move, 0, NULL, ! 415: ai_move, 0, NULL ! 416: }; ! 417: mmove_t flyer_move_pain1 = {FRAME_pain101, FRAME_pain109, flyer_frames_pain1, flyer_run}; ! 418: ! 419: mframe_t flyer_frames_defense [] = ! 420: { ! 421: ai_move, 0, NULL, ! 422: ai_move, 0, NULL, ! 423: ai_move, 0, NULL, // Hold this frame ! 424: ai_move, 0, NULL, ! 425: ai_move, 0, NULL, ! 426: ai_move, 0, NULL ! 427: }; ! 428: mmove_t flyer_move_defense = {FRAME_defens01, FRAME_defens06, flyer_frames_defense, NULL}; ! 429: ! 430: mframe_t flyer_frames_bankright [] = ! 431: { ! 432: ai_move, 0, NULL, ! 433: ai_move, 0, NULL, ! 434: ai_move, 0, NULL, ! 435: ai_move, 0, NULL, ! 436: ai_move, 0, NULL, ! 437: ai_move, 0, NULL, ! 438: ai_move, 0, NULL ! 439: }; ! 440: mmove_t flyer_move_bankright = {FRAME_bankr01, FRAME_bankr07, flyer_frames_bankright, NULL}; ! 441: ! 442: mframe_t flyer_frames_bankleft [] = ! 443: { ! 444: ai_move, 0, NULL, ! 445: ai_move, 0, NULL, ! 446: ai_move, 0, NULL, ! 447: ai_move, 0, NULL, ! 448: ai_move, 0, NULL, ! 449: ai_move, 0, NULL, ! 450: ai_move, 0, NULL ! 451: }; ! 452: mmove_t flyer_move_bankleft = {FRAME_bankl01, FRAME_bankl07, flyer_frames_bankleft, NULL}; ! 453: ! 454: ! 455: void flyer_fire (edict_t *self, int flash_number) ! 456: { ! 457: vec3_t start; ! 458: vec3_t forward, right; ! 459: vec3_t end; ! 460: vec3_t dir; ! 461: int effect; ! 462: ! 463: if(!self->enemy || !self->enemy->inuse) //PGM ! 464: return; //PGM ! 465: ! 466: if ((self->s.frame == FRAME_attak204) || (self->s.frame == FRAME_attak207) || (self->s.frame == FRAME_attak210)) ! 467: effect = EF_HYPERBLASTER; ! 468: else ! 469: effect = 0; ! 470: AngleVectors (self->s.angles, forward, right, NULL); ! 471: G_ProjectSource (self->s.origin, monster_flash_offset[flash_number], forward, right, start); ! 472: ! 473: VectorCopy (self->enemy->s.origin, end); ! 474: end[2] += self->enemy->viewheight; ! 475: VectorSubtract (end, start, dir); ! 476: ! 477: monster_fire_blaster (self, start, dir, 1, 1000, flash_number, effect); ! 478: } ! 479: ! 480: void flyer_fireleft (edict_t *self) ! 481: { ! 482: flyer_fire (self, MZ2_FLYER_BLASTER_1); ! 483: } ! 484: ! 485: void flyer_fireright (edict_t *self) ! 486: { ! 487: flyer_fire (self, MZ2_FLYER_BLASTER_2); ! 488: } ! 489: ! 490: ! 491: mframe_t flyer_frames_attack2 [] = ! 492: { ! 493: ai_charge, 0, NULL, ! 494: ai_charge, 0, NULL, ! 495: ai_charge, 0, NULL, ! 496: ai_charge, -10, flyer_fireleft, // left gun ! 497: ai_charge, -10, flyer_fireright, // right gun ! 498: ai_charge, -10, flyer_fireleft, // left gun ! 499: ai_charge, -10, flyer_fireright, // right gun ! 500: ai_charge, -10, flyer_fireleft, // left gun ! 501: ai_charge, -10, flyer_fireright, // right gun ! 502: ai_charge, -10, flyer_fireleft, // left gun ! 503: ai_charge, -10, flyer_fireright, // right gun ! 504: ai_charge, 0, NULL, ! 505: ai_charge, 0, NULL, ! 506: ai_charge, 0, NULL, ! 507: ai_charge, 0, NULL, ! 508: ai_charge, 0, NULL, ! 509: ai_charge, 0, NULL ! 510: }; ! 511: mmove_t flyer_move_attack2 = {FRAME_attak201, FRAME_attak217, flyer_frames_attack2, flyer_run}; ! 512: ! 513: // PMM ! 514: // circle strafe frames ! 515: ! 516: mframe_t flyer_frames_attack3 [] = ! 517: { ! 518: ai_charge, 10, NULL, ! 519: ai_charge, 10, NULL, ! 520: ai_charge, 10, NULL, ! 521: ai_charge, 10, flyer_fireleft, // left gun ! 522: ai_charge, 10, flyer_fireright, // right gun ! 523: ai_charge, 10, flyer_fireleft, // left gun ! 524: ai_charge, 10, flyer_fireright, // right gun ! 525: ai_charge, 10, flyer_fireleft, // left gun ! 526: ai_charge, 10, flyer_fireright, // right gun ! 527: ai_charge, 10, flyer_fireleft, // left gun ! 528: ai_charge, 10, flyer_fireright, // right gun ! 529: ai_charge, 10, NULL, ! 530: ai_charge, 10, NULL, ! 531: ai_charge, 10, NULL, ! 532: ai_charge, 10, NULL, ! 533: ai_charge, 10, NULL, ! 534: ai_charge, 10, NULL ! 535: }; ! 536: mmove_t flyer_move_attack3 = {FRAME_attak201, FRAME_attak217, flyer_frames_attack3, flyer_run}; ! 537: // pmm ! 538: ! 539: void flyer_slash_left (edict_t *self) ! 540: { ! 541: vec3_t aim; ! 542: ! 543: VectorSet (aim, MELEE_DISTANCE, self->mins[0], 0); ! 544: fire_hit (self, aim, 5, 0); ! 545: gi.sound (self, CHAN_WEAPON, sound_slash, 1, ATTN_NORM, 0); ! 546: } ! 547: ! 548: void flyer_slash_right (edict_t *self) ! 549: { ! 550: vec3_t aim; ! 551: ! 552: VectorSet (aim, MELEE_DISTANCE, self->maxs[0], 0); ! 553: fire_hit (self, aim, 5, 0); ! 554: gi.sound (self, CHAN_WEAPON, sound_slash, 1, ATTN_NORM, 0); ! 555: } ! 556: ! 557: mframe_t flyer_frames_start_melee [] = ! 558: { ! 559: ai_charge, 0, flyer_pop_blades, ! 560: ai_charge, 0, NULL, ! 561: ai_charge, 0, NULL, ! 562: ai_charge, 0, NULL, ! 563: ai_charge, 0, NULL, ! 564: ai_charge, 0, NULL ! 565: }; ! 566: mmove_t flyer_move_start_melee = {FRAME_attak101, FRAME_attak106, flyer_frames_start_melee, flyer_loop_melee}; ! 567: ! 568: mframe_t flyer_frames_end_melee [] = ! 569: { ! 570: ai_charge, 0, NULL, ! 571: ai_charge, 0, NULL, ! 572: ai_charge, 0, NULL ! 573: }; ! 574: mmove_t flyer_move_end_melee = {FRAME_attak119, FRAME_attak121, flyer_frames_end_melee, flyer_run}; ! 575: ! 576: ! 577: mframe_t flyer_frames_loop_melee [] = ! 578: { ! 579: ai_charge, 0, NULL, // Loop Start ! 580: ai_charge, 0, NULL, ! 581: ai_charge, 0, flyer_slash_left, // Left Wing Strike ! 582: ai_charge, 0, NULL, ! 583: ai_charge, 0, NULL, ! 584: ai_charge, 0, NULL, ! 585: ai_charge, 0, NULL, ! 586: ai_charge, 0, flyer_slash_right, // Right Wing Strike ! 587: ai_charge, 0, NULL, ! 588: ai_charge, 0, NULL, ! 589: ai_charge, 0, NULL, ! 590: ai_charge, 0, NULL // Loop Ends ! 591: ! 592: }; ! 593: mmove_t flyer_move_loop_melee = {FRAME_attak107, FRAME_attak118, flyer_frames_loop_melee, flyer_check_melee}; ! 594: ! 595: void flyer_loop_melee (edict_t *self) ! 596: { ! 597: /* if (random() <= 0.5) ! 598: self->monsterinfo.currentmove = &flyer_move_attack1; ! 599: else */ ! 600: self->monsterinfo.currentmove = &flyer_move_loop_melee; ! 601: } ! 602: ! 603: ! 604: ! 605: void flyer_attack (edict_t *self) ! 606: { ! 607: float chance; ! 608: /* if (random() <= 0.5) ! 609: self->monsterinfo.currentmove = &flyer_move_attack1; ! 610: else */ ! 611: // 0% chance of circle in easy ! 612: // 50% chance in normal ! 613: // 75% chance in hard ! 614: // 86.67% chance in nightmare ! 615: ! 616: if (self->mass > 50) ! 617: { ! 618: flyer_run (self); ! 619: return; ! 620: } ! 621: ! 622: if (!skill->value) ! 623: chance = 0; ! 624: else ! 625: chance = 1.0 - (0.5/(float)(skill->value)); ! 626: ! 627: if (random() > chance) ! 628: { ! 629: self->monsterinfo.attack_state = AS_STRAIGHT; ! 630: self->monsterinfo.currentmove = &flyer_move_attack2; ! 631: } ! 632: else // circle strafe ! 633: { ! 634: if (random () <= 0.5) // switch directions ! 635: self->monsterinfo.lefty = 1 - self->monsterinfo.lefty; ! 636: self->monsterinfo.attack_state = AS_SLIDING; ! 637: self->monsterinfo.currentmove = &flyer_move_attack3; ! 638: } ! 639: } ! 640: ! 641: void flyer_setstart (edict_t *self) ! 642: { ! 643: nextmove = ACTION_run; ! 644: self->monsterinfo.currentmove = &flyer_move_start; ! 645: } ! 646: ! 647: void flyer_nextmove (edict_t *self) ! 648: { ! 649: if (nextmove == ACTION_attack1) ! 650: self->monsterinfo.currentmove = &flyer_move_start_melee; ! 651: else if (nextmove == ACTION_attack2) ! 652: self->monsterinfo.currentmove = &flyer_move_attack2; ! 653: else if (nextmove == ACTION_run) ! 654: self->monsterinfo.currentmove = &flyer_move_run; ! 655: } ! 656: ! 657: void flyer_melee (edict_t *self) ! 658: { ! 659: // flyer.nextmove = ACTION_attack1; ! 660: // self->monsterinfo.currentmove = &flyer_move_stop; ! 661: if (self->mass > 50) ! 662: flyer_run (self); ! 663: else ! 664: self->monsterinfo.currentmove = &flyer_move_start_melee; ! 665: } ! 666: ! 667: void flyer_check_melee(edict_t *self) ! 668: { ! 669: if (range (self, self->enemy) == RANGE_MELEE) ! 670: if (random() <= 0.8) ! 671: self->monsterinfo.currentmove = &flyer_move_loop_melee; ! 672: else ! 673: self->monsterinfo.currentmove = &flyer_move_end_melee; ! 674: else ! 675: self->monsterinfo.currentmove = &flyer_move_end_melee; ! 676: } ! 677: ! 678: void flyer_pain (edict_t *self, edict_t *other, float kick, int damage) ! 679: { ! 680: int n; ! 681: ! 682: // pmm - kamikaze's don't feel pain ! 683: if (self->mass != 50) ! 684: return; ! 685: // pmm ! 686: ! 687: if (self->health < (self->max_health / 2)) ! 688: self->s.skinnum = 1; ! 689: ! 690: if (level.time < self->pain_debounce_time) ! 691: return; ! 692: ! 693: self->pain_debounce_time = level.time + 3; ! 694: if (skill->value == 3) ! 695: return; // no pain anims in nightmare ! 696: ! 697: n = rand() % 3; ! 698: if (n == 0) ! 699: { ! 700: gi.sound (self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0); ! 701: self->monsterinfo.currentmove = &flyer_move_pain1; ! 702: } ! 703: else if (n == 1) ! 704: { ! 705: gi.sound (self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0); ! 706: self->monsterinfo.currentmove = &flyer_move_pain2; ! 707: } ! 708: else ! 709: { ! 710: gi.sound (self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0); ! 711: self->monsterinfo.currentmove = &flyer_move_pain3; ! 712: } ! 713: } ! 714: ! 715: ! 716: void flyer_die(edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) ! 717: { ! 718: gi.sound (self, CHAN_VOICE, sound_die, 1, ATTN_NORM, 0); ! 719: BecomeExplosion1(self); ! 720: } ! 721: ! 722: // PMM - kamikaze code .. blow up if blocked ! 723: int flyer_blocked (edict_t *self, float dist) ! 724: { ! 725: vec3_t origin; ! 726: ! 727: // kamikaze = 100, normal = 50 ! 728: if (self->mass == 100) ! 729: { ! 730: flyer_kamikaze_check(self); ! 731: ! 732: // if the above didn't blow us up (i.e. I got blocked by the player) ! 733: if (self->inuse) ! 734: { ! 735: if (self->monsterinfo.commander && self->monsterinfo.commander->inuse && ! 736: !strcmp(self->monsterinfo.commander->classname, "monster_carrier")) ! 737: { ! 738: self->monsterinfo.commander->monsterinfo.monster_slots++; ! 739: if ((g_showlogic) && (g_showlogic->value)) ! 740: gi.dprintf ("suicide blocked, exploding. %d slots left\n", self->monsterinfo.commander->monsterinfo.monster_slots); ! 741: } ! 742: ! 743: VectorMA (self->s.origin, -0.02, self->velocity, origin); ! 744: gi.WriteByte (svc_temp_entity); ! 745: gi.WriteByte (TE_ROCKET_EXPLOSION); ! 746: gi.WritePosition (origin); ! 747: gi.multicast (self->s.origin, MULTICAST_PHS); ! 748: ! 749: G_FreeEdict (self); ! 750: } ! 751: return true; ! 752: } ! 753: // we're a normal flyer ! 754: if(blocked_checkshot (self, 0.25 + (0.05 * skill->value) )) ! 755: return true; ! 756: ! 757: return false; ! 758: } ! 759: ! 760: /*QUAKED monster_flyer (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight ! 761: */ ! 762: void SP_monster_flyer (edict_t *self) ! 763: { ! 764: if (deathmatch->value) ! 765: { ! 766: G_FreeEdict (self); ! 767: return; ! 768: } ! 769: ! 770: // fix a map bug in jail5.bsp ! 771: if (!Q_stricmp(level.mapname, "jail5") && (self->s.origin[2] == -104)) ! 772: { ! 773: self->targetname = self->target; ! 774: self->target = NULL; ! 775: } ! 776: ! 777: sound_sight = gi.soundindex ("flyer/flysght1.wav"); ! 778: sound_idle = gi.soundindex ("flyer/flysrch1.wav"); ! 779: sound_pain1 = gi.soundindex ("flyer/flypain1.wav"); ! 780: sound_pain2 = gi.soundindex ("flyer/flypain2.wav"); ! 781: sound_slash = gi.soundindex ("flyer/flyatck2.wav"); ! 782: sound_sproing = gi.soundindex ("flyer/flyatck1.wav"); ! 783: sound_die = gi.soundindex ("flyer/flydeth1.wav"); ! 784: ! 785: gi.soundindex ("flyer/flyatck3.wav"); ! 786: ! 787: self->s.modelindex = gi.modelindex ("models/monsters/flyer/tris.md2"); ! 788: VectorSet (self->mins, -16, -16, -24); ! 789: // PMM - shortened to 16 from 32 ! 790: VectorSet (self->maxs, 16, 16, 16); ! 791: self->movetype = MOVETYPE_STEP; ! 792: self->solid = SOLID_BBOX; ! 793: ! 794: self->s.sound = gi.soundindex ("flyer/flyidle1.wav"); ! 795: ! 796: self->health = 50; ! 797: self->mass = 50; ! 798: ! 799: self->pain = flyer_pain; ! 800: self->die = flyer_die; ! 801: ! 802: self->monsterinfo.stand = flyer_stand; ! 803: self->monsterinfo.walk = flyer_walk; ! 804: self->monsterinfo.run = flyer_run; ! 805: self->monsterinfo.attack = flyer_attack; ! 806: self->monsterinfo.melee = flyer_melee; ! 807: self->monsterinfo.sight = flyer_sight; ! 808: self->monsterinfo.idle = flyer_idle; ! 809: self->monsterinfo.blocked = flyer_blocked; ! 810: ! 811: gi.linkentity (self); ! 812: ! 813: self->monsterinfo.currentmove = &flyer_move_stand; ! 814: self->monsterinfo.scale = MODEL_SCALE; ! 815: ! 816: flymonster_start (self); ! 817: } ! 818: ! 819: // PMM - suicide fliers ! 820: void SP_monster_kamikaze (edict_t *self) ! 821: { ! 822: if (deathmatch->value) ! 823: { ! 824: G_FreeEdict (self); ! 825: return; ! 826: } ! 827: ! 828: sound_sight = gi.soundindex ("flyer/flysght1.wav"); ! 829: sound_idle = gi.soundindex ("flyer/flysrch1.wav"); ! 830: sound_pain1 = gi.soundindex ("flyer/flypain1.wav"); ! 831: sound_pain2 = gi.soundindex ("flyer/flypain2.wav"); ! 832: sound_slash = gi.soundindex ("flyer/flyatck2.wav"); ! 833: sound_sproing = gi.soundindex ("flyer/flyatck1.wav"); ! 834: sound_die = gi.soundindex ("flyer/flydeth1.wav"); ! 835: ! 836: gi.soundindex ("flyer/flyatck3.wav"); ! 837: ! 838: self->s.modelindex = gi.modelindex ("models/monsters/flyer/tris.md2"); ! 839: VectorSet (self->mins, -16, -16, -24); ! 840: // used to be 32 tall .. was WAY too big ! 841: VectorSet (self->maxs, 16, 16, 16); ! 842: self->movetype = MOVETYPE_STEP; ! 843: self->solid = SOLID_BBOX; ! 844: ! 845: self->s.sound = gi.soundindex ("flyer/flyidle1.wav"); ! 846: ! 847: self->s.effects |= EF_ROCKET; ! 848: ! 849: self->health = 50; ! 850: // PMM - normal flyer has mass of 50 ! 851: self->mass = 100; ! 852: ! 853: self->pain = flyer_pain; ! 854: self->die = flyer_die; ! 855: ! 856: self->monsterinfo.stand = flyer_stand; ! 857: self->monsterinfo.walk = flyer_walk; ! 858: self->monsterinfo.run = flyer_run; ! 859: self->monsterinfo.attack = flyer_attack; ! 860: self->monsterinfo.melee = flyer_melee; ! 861: self->monsterinfo.sight = flyer_sight; ! 862: self->monsterinfo.idle = flyer_idle; ! 863: ! 864: self->monsterinfo.blocked = flyer_blocked; ! 865: ! 866: gi.linkentity (self); ! 867: ! 868: self->monsterinfo.currentmove = &flyer_move_stand; ! 869: self->monsterinfo.scale = MODEL_SCALE; ! 870: ! 871: flymonster_start (self); ! 872: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.