|
|
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: BERSERK 24: 25: ============================================================================== 26: */ 27: 28: #include "g_local.h" 29: #include "m_berserk.h" 30: 31: 32: static int sound_pain; 33: static int sound_die; 34: static int sound_idle; 35: static int sound_punch; 36: static int sound_sight; 37: static int sound_search; 38: 39: void berserk_sight (edict_t *self, edict_t *other) 40: { 41: gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0); 42: } 43: 44: void berserk_search (edict_t *self) 45: { 46: gi.sound (self, CHAN_VOICE, sound_search, 1, ATTN_NORM, 0); 47: } 48: 49: 50: void berserk_fidget (edict_t *self); 51: mframe_t berserk_frames_stand [] = 52: { 53: ai_stand, 0, berserk_fidget, 54: ai_stand, 0, NULL, 55: ai_stand, 0, NULL, 56: ai_stand, 0, NULL, 57: ai_stand, 0, NULL 58: }; 59: mmove_t berserk_move_stand = {FRAME_stand1, FRAME_stand5, berserk_frames_stand, NULL}; 60: 61: void berserk_stand (edict_t *self) 62: { 63: self->monsterinfo.currentmove = &berserk_move_stand; 64: } 65: 66: mframe_t berserk_frames_stand_fidget [] = 67: { 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, 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: }; 89: mmove_t berserk_move_stand_fidget = {FRAME_standb1, FRAME_standb20, berserk_frames_stand_fidget, berserk_stand}; 90: 91: void berserk_fidget (edict_t *self) 92: { 93: if (self->monsterinfo.aiflags & AI_STAND_GROUND) 94: return; 95: if (random() > 0.15) 96: return; 97: 98: self->monsterinfo.currentmove = &berserk_move_stand_fidget; 99: gi.sound (self, CHAN_WEAPON, sound_idle, 1, ATTN_IDLE, 0); 100: } 101: 102: 103: mframe_t berserk_frames_walk [] = 104: { 105: ai_walk, 9.1, NULL, 106: ai_walk, 6.3, NULL, 107: ai_walk, 4.9, NULL, 108: ai_walk, 6.7, NULL, 109: ai_walk, 6.0, NULL, 110: ai_walk, 8.2, NULL, 111: ai_walk, 7.2, NULL, 112: ai_walk, 6.1, NULL, 113: ai_walk, 4.9, NULL, 114: ai_walk, 4.7, NULL, 115: ai_walk, 4.7, NULL, 116: ai_walk, 4.8, NULL 117: }; 118: mmove_t berserk_move_walk = {FRAME_walkc1, FRAME_walkc11, berserk_frames_walk, NULL}; 119: 120: void berserk_walk (edict_t *self) 121: { 122: self->monsterinfo.currentmove = &berserk_move_walk; 123: } 124: 125: /* 126: 127: ***************************** 128: SKIPPED THIS FOR NOW! 129: ***************************** 130: 131: Running -> Arm raised in air 132: 133: void() berserk_runb1 =[ $r_att1 , berserk_runb2 ] {ai_run(21);}; 134: void() berserk_runb2 =[ $r_att2 , berserk_runb3 ] {ai_run(11);}; 135: void() berserk_runb3 =[ $r_att3 , berserk_runb4 ] {ai_run(21);}; 136: void() berserk_runb4 =[ $r_att4 , berserk_runb5 ] {ai_run(25);}; 137: void() berserk_runb5 =[ $r_att5 , berserk_runb6 ] {ai_run(18);}; 138: void() berserk_runb6 =[ $r_att6 , berserk_runb7 ] {ai_run(19);}; 139: // running with arm in air : start loop 140: void() berserk_runb7 =[ $r_att7 , berserk_runb8 ] {ai_run(21);}; 141: void() berserk_runb8 =[ $r_att8 , berserk_runb9 ] {ai_run(11);}; 142: void() berserk_runb9 =[ $r_att9 , berserk_runb10 ] {ai_run(21);}; 143: void() berserk_runb10 =[ $r_att10 , berserk_runb11 ] {ai_run(25);}; 144: void() berserk_runb11 =[ $r_att11 , berserk_runb12 ] {ai_run(18);}; 145: void() berserk_runb12 =[ $r_att12 , berserk_runb7 ] {ai_run(19);}; 146: // running with arm in air : end loop 147: */ 148: 149: 150: mframe_t berserk_frames_run1 [] = 151: { 152: ai_run, 21, NULL, 153: ai_run, 11, NULL, 154: ai_run, 21, NULL, 155: ai_run, 25, NULL, 156: ai_run, 18, NULL, 157: ai_run, 19, NULL 158: }; 159: mmove_t berserk_move_run1 = {FRAME_run1, FRAME_run6, berserk_frames_run1, NULL}; 160: 161: void berserk_run (edict_t *self) 162: { 163: if (self->monsterinfo.aiflags & AI_STAND_GROUND) 164: self->monsterinfo.currentmove = &berserk_move_stand; 165: else 166: self->monsterinfo.currentmove = &berserk_move_run1; 167: } 168: 169: 170: void berserk_attack_spike (edict_t *self) 171: { 172: static vec3_t aim = {MELEE_DISTANCE, 0, -24}; 173: fire_hit (self, aim, (15 + (rand() % 6)), 400); // Faster attack -- upwards and backwards 174: } 175: 176: 177: void berserk_swing (edict_t *self) 178: { 179: gi.sound (self, CHAN_WEAPON, sound_punch, 1, ATTN_NORM, 0); 180: } 181: 182: mframe_t berserk_frames_attack_spike [] = 183: { 184: ai_charge, 0, NULL, 185: ai_charge, 0, NULL, 186: ai_charge, 0, berserk_swing, 187: ai_charge, 0, berserk_attack_spike, 188: ai_charge, 0, NULL, 189: ai_charge, 0, NULL, 190: ai_charge, 0, NULL, 191: ai_charge, 0, NULL 192: }; 193: mmove_t berserk_move_attack_spike = {FRAME_att_c1, FRAME_att_c8, berserk_frames_attack_spike, berserk_run}; 194: 195: 196: void berserk_attack_club (edict_t *self) 197: { 198: vec3_t aim; 199: 200: VectorSet (aim, MELEE_DISTANCE, self->mins[0], -4); 201: fire_hit (self, aim, (5 + (rand() % 6)), 400); // Slower attack 202: } 203: 204: mframe_t berserk_frames_attack_club [] = 205: { 206: ai_charge, 0, NULL, 207: ai_charge, 0, NULL, 208: ai_charge, 0, NULL, 209: ai_charge, 0, NULL, 210: ai_charge, 0, berserk_swing, 211: ai_charge, 0, NULL, 212: ai_charge, 0, NULL, 213: ai_charge, 0, NULL, 214: ai_charge, 0, berserk_attack_club, 215: ai_charge, 0, NULL, 216: ai_charge, 0, NULL, 217: ai_charge, 0, NULL 218: }; 219: mmove_t berserk_move_attack_club = {FRAME_att_c9, FRAME_att_c20, berserk_frames_attack_club, berserk_run}; 220: 221: 222: void berserk_strike (edict_t *self) 223: { 224: //FIXME play impact sound 225: } 226: 227: 228: mframe_t berserk_frames_attack_strike [] = 229: { 230: ai_move, 0, NULL, 231: ai_move, 0, NULL, 232: ai_move, 0, NULL, 233: ai_move, 0, berserk_swing, 234: ai_move, 0, NULL, 235: ai_move, 0, NULL, 236: ai_move, 0, NULL, 237: ai_move, 0, berserk_strike, 238: ai_move, 0, NULL, 239: ai_move, 0, NULL, 240: ai_move, 0, NULL, 241: ai_move, 0, NULL, 242: ai_move, 9.7, NULL, 243: ai_move, 13.6, NULL 244: }; 245: 246: mmove_t berserk_move_attack_strike = {FRAME_att_c21, FRAME_att_c34, berserk_frames_attack_strike, berserk_run}; 247: 248: 249: void berserk_melee (edict_t *self) 250: { 251: if ((rand() % 2) == 0) 252: self->monsterinfo.currentmove = &berserk_move_attack_spike; 253: else 254: self->monsterinfo.currentmove = &berserk_move_attack_club; 255: } 256: 257: 258: /* 259: void() berserk_atke1 =[ $r_attb1, berserk_atke2 ] {ai_run(9);}; 260: void() berserk_atke2 =[ $r_attb2, berserk_atke3 ] {ai_run(6);}; 261: void() berserk_atke3 =[ $r_attb3, berserk_atke4 ] {ai_run(18.4);}; 262: void() berserk_atke4 =[ $r_attb4, berserk_atke5 ] {ai_run(25);}; 263: void() berserk_atke5 =[ $r_attb5, berserk_atke6 ] {ai_run(14);}; 264: void() berserk_atke6 =[ $r_attb6, berserk_atke7 ] {ai_run(20);}; 265: void() berserk_atke7 =[ $r_attb7, berserk_atke8 ] {ai_run(8.5);}; 266: void() berserk_atke8 =[ $r_attb8, berserk_atke9 ] {ai_run(3);}; 267: void() berserk_atke9 =[ $r_attb9, berserk_atke10 ] {ai_run(17.5);}; 268: void() berserk_atke10 =[ $r_attb10, berserk_atke11 ] {ai_run(17);}; 269: void() berserk_atke11 =[ $r_attb11, berserk_atke12 ] {ai_run(9);}; 270: void() berserk_atke12 =[ $r_attb12, berserk_atke13 ] {ai_run(25);}; 271: void() berserk_atke13 =[ $r_attb13, berserk_atke14 ] {ai_run(3.7);}; 272: void() berserk_atke14 =[ $r_attb14, berserk_atke15 ] {ai_run(2.6);}; 273: void() berserk_atke15 =[ $r_attb15, berserk_atke16 ] {ai_run(19);}; 274: void() berserk_atke16 =[ $r_attb16, berserk_atke17 ] {ai_run(25);}; 275: void() berserk_atke17 =[ $r_attb17, berserk_atke18 ] {ai_run(19.6);}; 276: void() berserk_atke18 =[ $r_attb18, berserk_run1 ] {ai_run(7.8);}; 277: */ 278: 279: 280: mframe_t berserk_frames_pain1 [] = 281: { 282: ai_move, 0, NULL, 283: ai_move, 0, NULL, 284: ai_move, 0, NULL, 285: ai_move, 0, NULL 286: }; 287: mmove_t berserk_move_pain1 = {FRAME_painc1, FRAME_painc4, berserk_frames_pain1, berserk_run}; 288: 289: 290: mframe_t berserk_frames_pain2 [] = 291: { 292: ai_move, 0, NULL, 293: ai_move, 0, NULL, 294: ai_move, 0, NULL, 295: ai_move, 0, NULL, 296: ai_move, 0, NULL, 297: ai_move, 0, NULL, 298: ai_move, 0, NULL, 299: ai_move, 0, NULL, 300: ai_move, 0, NULL, 301: ai_move, 0, NULL, 302: ai_move, 0, NULL, 303: ai_move, 0, NULL, 304: ai_move, 0, NULL, 305: ai_move, 0, NULL, 306: ai_move, 0, NULL, 307: ai_move, 0, NULL, 308: ai_move, 0, NULL, 309: ai_move, 0, NULL, 310: ai_move, 0, NULL, 311: ai_move, 0, NULL 312: }; 313: mmove_t berserk_move_pain2 = {FRAME_painb1, FRAME_painb20, berserk_frames_pain2, berserk_run}; 314: 315: void berserk_pain (edict_t *self, edict_t *other, float kick, int damage) 316: { 317: if (self->health < (self->max_health / 2)) 318: self->s.skinnum = 1; 319: 320: if (level.time < self->pain_debounce_time) 321: return; 322: 323: self->pain_debounce_time = level.time + 3; 324: gi.sound (self, CHAN_VOICE, sound_pain, 1, ATTN_NORM, 0); 325: 326: if (skill->value == 3) 327: return; // no pain anims in nightmare 328: 329: if ((damage < 20) || (random() < 0.5)) 330: self->monsterinfo.currentmove = &berserk_move_pain1; 331: else 332: self->monsterinfo.currentmove = &berserk_move_pain2; 333: } 334: 335: 336: void berserk_dead (edict_t *self) 337: { 338: VectorSet (self->mins, -16, -16, -24); 339: VectorSet (self->maxs, 16, 16, -8); 340: self->movetype = MOVETYPE_TOSS; 341: self->svflags |= SVF_DEADMONSTER; 342: self->nextthink = 0; 343: gi.linkentity (self); 344: } 345: 346: 347: mframe_t berserk_frames_death1 [] = 348: { 349: ai_move, 0, NULL, 350: ai_move, 0, NULL, 351: ai_move, 0, NULL, 352: ai_move, 0, NULL, 353: ai_move, 0, NULL, 354: ai_move, 0, NULL, 355: ai_move, 0, NULL, 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: 363: }; 364: mmove_t berserk_move_death1 = {FRAME_death1, FRAME_death13, berserk_frames_death1, berserk_dead}; 365: 366: 367: mframe_t berserk_frames_death2 [] = 368: { 369: ai_move, 0, NULL, 370: ai_move, 0, NULL, 371: ai_move, 0, NULL, 372: ai_move, 0, NULL, 373: ai_move, 0, NULL, 374: ai_move, 0, NULL, 375: ai_move, 0, NULL, 376: ai_move, 0, NULL 377: }; 378: mmove_t berserk_move_death2 = {FRAME_deathc1, FRAME_deathc8, berserk_frames_death2, berserk_dead}; 379: 380: 381: void berserk_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) 382: { 383: int n; 384: 385: if (self->health <= self->gib_health) 386: { 387: gi.sound (self, CHAN_VOICE, gi.soundindex ("misc/udeath.wav"), 1, ATTN_NORM, 0); 388: for (n= 0; n < 2; n++) 389: ThrowGib (self, "models/objects/gibs/bone/tris.md2", damage, GIB_ORGANIC); 390: for (n= 0; n < 4; n++) 391: ThrowGib (self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC); 392: ThrowHead (self, "models/objects/gibs/head2/tris.md2", damage, GIB_ORGANIC); 393: self->deadflag = DEAD_DEAD; 394: return; 395: } 396: 397: if (self->deadflag == DEAD_DEAD) 398: return; 399: 400: gi.sound (self, CHAN_VOICE, sound_die, 1, ATTN_NORM, 0); 401: self->deadflag = DEAD_DEAD; 402: self->takedamage = DAMAGE_YES; 403: 404: if (damage >= 50) 405: self->monsterinfo.currentmove = &berserk_move_death1; 406: else 407: self->monsterinfo.currentmove = &berserk_move_death2; 408: } 409: 410: 411: /*QUAKED monster_berserk (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight 412: */ 413: void SP_monster_berserk (edict_t *self) 414: { 415: if (deathmatch->value) 416: { 417: G_FreeEdict (self); 418: return; 419: } 420: 421: // pre-caches 422: sound_pain = gi.soundindex ("berserk/berpain2.wav"); 423: sound_die = gi.soundindex ("berserk/berdeth2.wav"); 424: sound_idle = gi.soundindex ("berserk/beridle1.wav"); 425: sound_punch = gi.soundindex ("berserk/attack.wav"); 426: sound_search = gi.soundindex ("berserk/bersrch1.wav"); 427: sound_sight = gi.soundindex ("berserk/sight.wav"); 428: 429: self->s.modelindex = gi.modelindex("models/monsters/berserk/tris.md2"); 430: VectorSet (self->mins, -16, -16, -24); 431: VectorSet (self->maxs, 16, 16, 32); 432: self->movetype = MOVETYPE_STEP; 433: self->solid = SOLID_BBOX; 434: 435: self->health = 240; 436: self->gib_health = -60; 437: self->mass = 250; 438: 439: self->pain = berserk_pain; 440: self->die = berserk_die; 441: 442: self->monsterinfo.stand = berserk_stand; 443: self->monsterinfo.walk = berserk_walk; 444: self->monsterinfo.run = berserk_run; 445: self->monsterinfo.dodge = NULL; 446: self->monsterinfo.attack = NULL; 447: self->monsterinfo.melee = berserk_melee; 448: self->monsterinfo.sight = berserk_sight; 449: self->monsterinfo.search = berserk_search; 450: 451: self->monsterinfo.currentmove = &berserk_move_stand; 452: self->monsterinfo.scale = MODEL_SCALE; 453: 454: gi.linkentity (self); 455: 456: walkmonster_start (self); 457: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.