|
|
1.1 ! root 1: /* ! 2: ============================================================================== ! 3: ! 4: GLADIATOR ! 5: ! 6: ============================================================================== ! 7: */ ! 8: ! 9: #include "g_local.h" ! 10: #include "m_gladiator.h" ! 11: ! 12: ! 13: static int sound_pain1; ! 14: static int sound_pain2; ! 15: static int sound_die; ! 16: static int sound_gun; ! 17: static int sound_cleaver_swing; ! 18: static int sound_cleaver_hit; ! 19: static int sound_cleaver_miss; ! 20: static int sound_idle; ! 21: static int sound_search; ! 22: static int sound_sight; ! 23: ! 24: ! 25: void gladiator_idle (edict_t *self) ! 26: { ! 27: gi.sound (self, CHAN_VOICE, sound_idle, 1, ATTN_IDLE, 0); ! 28: } ! 29: ! 30: void gladiator_sight (edict_t *self, edict_t *other) ! 31: { ! 32: gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0); ! 33: } ! 34: ! 35: void gladiator_search (edict_t *self) ! 36: { ! 37: gi.sound (self, CHAN_VOICE, sound_search, 1, ATTN_NORM, 0); ! 38: } ! 39: ! 40: void gladiator_cleaver_swing (edict_t *self) ! 41: { ! 42: gi.sound (self, CHAN_WEAPON, sound_cleaver_swing, 1, ATTN_NORM, 0); ! 43: } ! 44: ! 45: mframe_t gladiator_frames_stand [] = ! 46: { ! 47: ai_stand, 0, NULL, ! 48: ai_stand, 0, NULL, ! 49: ai_stand, 0, NULL, ! 50: ai_stand, 0, NULL, ! 51: ai_stand, 0, NULL, ! 52: ai_stand, 0, NULL, ! 53: ai_stand, 0, NULL ! 54: }; ! 55: mmove_t gladiator_move_stand = {FRAME_stand1, FRAME_stand7, gladiator_frames_stand, NULL}; ! 56: ! 57: void gladiator_stand (edict_t *self) ! 58: { ! 59: self->monsterinfo.currentmove = &gladiator_move_stand; ! 60: } ! 61: ! 62: ! 63: mframe_t gladiator_frames_walk [] = ! 64: { ! 65: ai_walk, 15, NULL, ! 66: ai_walk, 7, NULL, ! 67: ai_walk, 6, NULL, ! 68: ai_walk, 5, NULL, ! 69: ai_walk, 2, NULL, ! 70: ai_walk, 0, NULL, ! 71: ai_walk, 2, NULL, ! 72: ai_walk, 8, NULL, ! 73: ai_walk, 12, NULL, ! 74: ai_walk, 8, NULL, ! 75: ai_walk, 5, NULL, ! 76: ai_walk, 5, NULL, ! 77: ai_walk, 2, NULL, ! 78: ai_walk, 2, NULL, ! 79: ai_walk, 1, NULL, ! 80: ai_walk, 8, NULL ! 81: }; ! 82: mmove_t gladiator_move_walk = {FRAME_walk1, FRAME_walk16, gladiator_frames_walk, NULL}; ! 83: ! 84: void gladiator_walk (edict_t *self) ! 85: { ! 86: self->monsterinfo.currentmove = &gladiator_move_walk; ! 87: } ! 88: ! 89: ! 90: mframe_t gladiator_frames_run [] = ! 91: { ! 92: ai_run, 23, NULL, ! 93: ai_run, 14, NULL, ! 94: ai_run, 14, NULL, ! 95: ai_run, 21, NULL, ! 96: ai_run, 12, NULL, ! 97: ai_run, 13, NULL ! 98: }; ! 99: mmove_t gladiator_move_run = {FRAME_run1, FRAME_run6, gladiator_frames_run, NULL}; ! 100: ! 101: void gladiator_run (edict_t *self) ! 102: { ! 103: if (self->monsterinfo.aiflags & AI_STAND_GROUND) ! 104: self->monsterinfo.currentmove = &gladiator_move_stand; ! 105: else ! 106: self->monsterinfo.currentmove = &gladiator_move_run; ! 107: } ! 108: ! 109: ! 110: void GaldiatorMelee (edict_t *self) ! 111: { ! 112: vec3_t aim; ! 113: ! 114: VectorSet (aim, MELEE_DISTANCE, self->mins[0], -4); ! 115: if (fire_hit (self, aim, (20 + (rand() %5)), 300)) ! 116: gi.sound (self, CHAN_AUTO, sound_cleaver_hit, 1, ATTN_NORM, 0); ! 117: else ! 118: gi.sound (self, CHAN_AUTO, sound_cleaver_miss, 1, ATTN_NORM, 0); ! 119: } ! 120: ! 121: mframe_t gladiator_frames_attack_melee [] = ! 122: { ! 123: ai_charge, 0, NULL, ! 124: ai_charge, 0, NULL, ! 125: ai_charge, 0, NULL, ! 126: ai_charge, 0, NULL, ! 127: ai_charge, 0, gladiator_cleaver_swing, ! 128: ai_charge, 0, NULL, ! 129: ai_charge, 0, GaldiatorMelee, ! 130: ai_charge, 0, NULL, ! 131: ai_charge, 0, NULL, ! 132: ai_charge, 0, NULL, ! 133: ai_charge, 0, gladiator_cleaver_swing, ! 134: ai_charge, 0, NULL, ! 135: ai_charge, 0, NULL, ! 136: ai_charge, 0, GaldiatorMelee, ! 137: ai_charge, 0, NULL, ! 138: ai_charge, 0, NULL, ! 139: ai_charge, 0, NULL ! 140: }; ! 141: mmove_t gladiator_move_attack_melee = {FRAME_melee1, FRAME_melee17, gladiator_frames_attack_melee, gladiator_run}; ! 142: ! 143: void gladiator_melee(edict_t *self) ! 144: { ! 145: self->monsterinfo.currentmove = &gladiator_move_attack_melee; ! 146: } ! 147: ! 148: ! 149: void GladiatorGun (edict_t *self) ! 150: { ! 151: vec3_t start; ! 152: vec3_t dir; ! 153: vec3_t forward, right; ! 154: ! 155: AngleVectors (self->s.angles, forward, right, NULL); ! 156: G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_GLADIATOR_RAILGUN_1], forward, right, start); ! 157: ! 158: // calc direction to where we targted ! 159: VectorSubtract (self->pos1, start, dir); ! 160: VectorNormalize (dir); ! 161: ! 162: monster_fire_railgun (self, start, dir, 50, 100, MZ2_GLADIATOR_RAILGUN_1); ! 163: } ! 164: ! 165: mframe_t gladiator_frames_attack_gun [] = ! 166: { ! 167: ai_charge, 0, NULL, ! 168: ai_charge, 0, NULL, ! 169: ai_charge, 0, NULL, ! 170: ai_charge, 0, GladiatorGun, ! 171: ai_charge, 0, NULL, ! 172: ai_charge, 0, NULL, ! 173: ai_charge, 0, NULL, ! 174: ai_charge, 0, NULL, ! 175: ai_charge, 0, NULL ! 176: }; ! 177: mmove_t gladiator_move_attack_gun = {FRAME_attack1, FRAME_attack9, gladiator_frames_attack_gun, gladiator_run}; ! 178: ! 179: void gladiator_attack(edict_t *self) ! 180: { ! 181: float range; ! 182: vec3_t v; ! 183: ! 184: // a small safe zone ! 185: VectorSubtract (self->s.origin, self->enemy->s.origin, v); ! 186: range = VectorLength(v); ! 187: if (range <= (MELEE_DISTANCE + 32)) ! 188: return; ! 189: ! 190: // charge up the railgun ! 191: gi.sound (self, CHAN_WEAPON, sound_gun, 1, ATTN_NORM, 0); ! 192: VectorCopy (self->enemy->s.origin, self->pos1); //save for aiming the shot ! 193: self->pos1[2] += self->enemy->viewheight; ! 194: self->monsterinfo.currentmove = &gladiator_move_attack_gun; ! 195: } ! 196: ! 197: ! 198: mframe_t gladiator_frames_pain [] = ! 199: { ! 200: ai_move, 0, NULL, ! 201: ai_move, 0, NULL, ! 202: ai_move, 0, NULL, ! 203: ai_move, 0, NULL, ! 204: ai_move, 0, NULL, ! 205: ai_move, 0, NULL ! 206: }; ! 207: mmove_t gladiator_move_pain = {FRAME_pain1, FRAME_pain6, gladiator_frames_pain, gladiator_run}; ! 208: ! 209: mframe_t gladiator_frames_pain_air [] = ! 210: { ! 211: ai_move, 0, NULL, ! 212: ai_move, 0, NULL, ! 213: ai_move, 0, NULL, ! 214: ai_move, 0, NULL, ! 215: ai_move, 0, NULL, ! 216: ai_move, 0, NULL, ! 217: ai_move, 0, NULL ! 218: }; ! 219: mmove_t gladiator_move_pain_air = {FRAME_painup1, FRAME_painup7, gladiator_frames_pain_air, gladiator_run}; ! 220: ! 221: void gladiator_pain (edict_t *self, edict_t *other, float kick, int damage) ! 222: { ! 223: ! 224: if (self->health < (self->max_health / 2)) ! 225: self->s.skinnum = 1; ! 226: ! 227: if (level.time < self->pain_debounce_time) ! 228: { ! 229: if ((self->velocity[2] > 100) && (self->monsterinfo.currentmove == &gladiator_move_pain)) ! 230: self->monsterinfo.currentmove = &gladiator_move_pain_air; ! 231: return; ! 232: } ! 233: ! 234: self->pain_debounce_time = level.time + 3; ! 235: ! 236: if (random() < 0.5) ! 237: gi.sound (self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0); ! 238: else ! 239: gi.sound (self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0); ! 240: ! 241: if (skill->value == 3) ! 242: return; // no pain anims in nightmare ! 243: ! 244: if (self->velocity[2] > 100) ! 245: self->monsterinfo.currentmove = &gladiator_move_pain_air; ! 246: else ! 247: self->monsterinfo.currentmove = &gladiator_move_pain; ! 248: ! 249: } ! 250: ! 251: ! 252: void gladiator_dead (edict_t *self) ! 253: { ! 254: VectorSet (self->mins, -16, -16, -24); ! 255: VectorSet (self->maxs, 16, 16, -8); ! 256: self->movetype = MOVETYPE_TOSS; ! 257: self->svflags |= SVF_DEADMONSTER; ! 258: self->nextthink = 0; ! 259: gi.linkentity (self); ! 260: } ! 261: ! 262: mframe_t gladiator_frames_death [] = ! 263: { ! 264: ai_move, 0, NULL, ! 265: ai_move, 0, NULL, ! 266: ai_move, 0, NULL, ! 267: ai_move, 0, NULL, ! 268: ai_move, 0, NULL, ! 269: ai_move, 0, NULL, ! 270: ai_move, 0, NULL, ! 271: ai_move, 0, NULL, ! 272: ai_move, 0, NULL, ! 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: ai_move, 0, NULL, ! 283: ai_move, 0, NULL, ! 284: ai_move, 0, NULL, ! 285: ai_move, 0, NULL ! 286: }; ! 287: mmove_t gladiator_move_death = {FRAME_death1, FRAME_death22, gladiator_frames_death, gladiator_dead}; ! 288: ! 289: void gladiator_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) ! 290: { ! 291: int n; ! 292: ! 293: // check for gib ! 294: if (self->health <= self->gib_health) ! 295: { ! 296: gi.sound (self, CHAN_VOICE, gi.soundindex ("misc/udeath.wav"), 1, ATTN_NORM, 0); ! 297: for (n= 0; n < 2; n++) ! 298: ThrowGib (self, "models/objects/gibs/bone/tris.md2", damage, GIB_ORGANIC); ! 299: for (n= 0; n < 4; n++) ! 300: ThrowGib (self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC); ! 301: ThrowHead (self, "models/objects/gibs/head2/tris.md2", damage, GIB_ORGANIC); ! 302: self->deadflag = DEAD_DEAD; ! 303: return; ! 304: } ! 305: ! 306: if (self->deadflag == DEAD_DEAD) ! 307: return; ! 308: ! 309: // regular death ! 310: gi.sound (self, CHAN_VOICE, sound_die, 1, ATTN_NORM, 0); ! 311: self->deadflag = DEAD_DEAD; ! 312: self->takedamage = DAMAGE_YES; ! 313: ! 314: self->monsterinfo.currentmove = &gladiator_move_death; ! 315: } ! 316: ! 317: ! 318: /*QUAKED monster_gladiator (1 .5 0) (-32 -32 -24) (32 32 64) Ambush Trigger_Spawn Sight ! 319: */ ! 320: void SP_monster_gladiator (edict_t *self) ! 321: { ! 322: if (deathmatch->value) ! 323: { ! 324: G_FreeEdict (self); ! 325: return; ! 326: } ! 327: ! 328: ! 329: sound_pain1 = gi.soundindex ("gladiator/pain.wav"); ! 330: sound_pain2 = gi.soundindex ("gladiator/gldpain2.wav"); ! 331: sound_die = gi.soundindex ("gladiator/glddeth2.wav"); ! 332: sound_gun = gi.soundindex ("gladiator/railgun.wav"); ! 333: sound_cleaver_swing = gi.soundindex ("gladiator/melee1.wav"); ! 334: sound_cleaver_hit = gi.soundindex ("gladiator/melee2.wav"); ! 335: sound_cleaver_miss = gi.soundindex ("gladiator/melee3.wav"); ! 336: sound_idle = gi.soundindex ("gladiator/gldidle1.wav"); ! 337: sound_search = gi.soundindex ("gladiator/gldsrch1.wav"); ! 338: sound_sight = gi.soundindex ("gladiator/sight.wav"); ! 339: ! 340: self->movetype = MOVETYPE_STEP; ! 341: self->solid = SOLID_BBOX; ! 342: self->s.modelindex = gi.modelindex ("models/monsters/gladiatr/tris.md2"); ! 343: VectorSet (self->mins, -32, -32, -24); ! 344: VectorSet (self->maxs, 32, 32, 64); ! 345: ! 346: self->health = 400; ! 347: self->gib_health = -175; ! 348: self->mass = 400; ! 349: ! 350: self->pain = gladiator_pain; ! 351: self->die = gladiator_die; ! 352: ! 353: self->monsterinfo.stand = gladiator_stand; ! 354: self->monsterinfo.walk = gladiator_walk; ! 355: self->monsterinfo.run = gladiator_run; ! 356: self->monsterinfo.dodge = NULL; ! 357: self->monsterinfo.attack = gladiator_attack; ! 358: self->monsterinfo.melee = gladiator_melee; ! 359: self->monsterinfo.sight = gladiator_sight; ! 360: self->monsterinfo.idle = gladiator_idle; ! 361: self->monsterinfo.search = gladiator_search; ! 362: ! 363: gi.linkentity (self); ! 364: self->monsterinfo.currentmove = &gladiator_move_stand; ! 365: self->monsterinfo.scale = MODEL_SCALE; ! 366: ! 367: walkmonster_start (self); ! 368: } ! 369:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.