m_flipper.c (9692B)
1 /* 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 /* 21 ============================================================================== 22 23 FLIPPER 24 25 ============================================================================== 26 */ 27 28 #include "g_local.h" 29 #include "m_flipper.h" 30 31 32 static int sound_chomp; 33 static int sound_attack; 34 static int sound_pain1; 35 static int sound_pain2; 36 static int sound_death; 37 static int sound_idle; 38 static int sound_search; 39 static int sound_sight; 40 41 42 void flipper_stand (edict_t *self); 43 44 mframe_t flipper_frames_stand [] = 45 { 46 ai_stand, 0, NULL 47 }; 48 49 mmove_t flipper_move_stand = {FRAME_flphor01, FRAME_flphor01, flipper_frames_stand, NULL}; 50 51 void flipper_stand (edict_t *self) 52 { 53 self->monsterinfo.currentmove = &flipper_move_stand; 54 } 55 56 #define FLIPPER_RUN_SPEED 24 57 58 mframe_t flipper_frames_run [] = 59 { 60 ai_run, FLIPPER_RUN_SPEED, NULL, // 6 61 ai_run, FLIPPER_RUN_SPEED, NULL, 62 ai_run, FLIPPER_RUN_SPEED, NULL, 63 ai_run, FLIPPER_RUN_SPEED, NULL, 64 ai_run, FLIPPER_RUN_SPEED, NULL, // 10 65 66 ai_run, FLIPPER_RUN_SPEED, NULL, 67 ai_run, FLIPPER_RUN_SPEED, NULL, 68 ai_run, FLIPPER_RUN_SPEED, NULL, 69 ai_run, FLIPPER_RUN_SPEED, NULL, 70 ai_run, FLIPPER_RUN_SPEED, NULL, 71 ai_run, FLIPPER_RUN_SPEED, NULL, 72 ai_run, FLIPPER_RUN_SPEED, NULL, 73 ai_run, FLIPPER_RUN_SPEED, NULL, 74 ai_run, FLIPPER_RUN_SPEED, NULL, 75 ai_run, FLIPPER_RUN_SPEED, NULL, // 20 76 77 ai_run, FLIPPER_RUN_SPEED, NULL, 78 ai_run, FLIPPER_RUN_SPEED, NULL, 79 ai_run, FLIPPER_RUN_SPEED, NULL, 80 ai_run, FLIPPER_RUN_SPEED, NULL, 81 ai_run, FLIPPER_RUN_SPEED, NULL, 82 ai_run, FLIPPER_RUN_SPEED, NULL, 83 ai_run, FLIPPER_RUN_SPEED, NULL, 84 ai_run, FLIPPER_RUN_SPEED, NULL, 85 ai_run, FLIPPER_RUN_SPEED, NULL // 29 86 }; 87 mmove_t flipper_move_run_loop = {FRAME_flpver06, FRAME_flpver29, flipper_frames_run, NULL}; 88 89 void flipper_run_loop (edict_t *self) 90 { 91 self->monsterinfo.currentmove = &flipper_move_run_loop; 92 } 93 94 mframe_t flipper_frames_run_start [] = 95 { 96 ai_run, 8, NULL, 97 ai_run, 8, NULL, 98 ai_run, 8, NULL, 99 ai_run, 8, NULL, 100 ai_run, 8, NULL, 101 ai_run, 8, NULL 102 }; 103 mmove_t flipper_move_run_start = {FRAME_flpver01, FRAME_flpver06, flipper_frames_run_start, flipper_run_loop}; 104 105 void flipper_run (edict_t *self) 106 { 107 self->monsterinfo.currentmove = &flipper_move_run_start; 108 } 109 110 /* Standard Swimming */ 111 mframe_t flipper_frames_walk [] = 112 { 113 ai_walk, 4, NULL, 114 ai_walk, 4, NULL, 115 ai_walk, 4, NULL, 116 ai_walk, 4, NULL, 117 ai_walk, 4, NULL, 118 ai_walk, 4, NULL, 119 ai_walk, 4, NULL, 120 ai_walk, 4, NULL, 121 ai_walk, 4, NULL, 122 ai_walk, 4, NULL, 123 ai_walk, 4, NULL, 124 ai_walk, 4, NULL, 125 ai_walk, 4, NULL, 126 ai_walk, 4, NULL, 127 ai_walk, 4, NULL, 128 ai_walk, 4, NULL, 129 ai_walk, 4, NULL, 130 ai_walk, 4, NULL, 131 ai_walk, 4, NULL, 132 ai_walk, 4, NULL, 133 ai_walk, 4, NULL, 134 ai_walk, 4, NULL, 135 ai_walk, 4, NULL, 136 ai_walk, 4, NULL 137 }; 138 mmove_t flipper_move_walk = {FRAME_flphor01, FRAME_flphor24, flipper_frames_walk, NULL}; 139 140 void flipper_walk (edict_t *self) 141 { 142 self->monsterinfo.currentmove = &flipper_move_walk; 143 } 144 145 mframe_t flipper_frames_start_run [] = 146 { 147 ai_run, 8, NULL, 148 ai_run, 8, NULL, 149 ai_run, 8, NULL, 150 ai_run, 8, NULL, 151 ai_run, 8, flipper_run 152 }; 153 mmove_t flipper_move_start_run = {FRAME_flphor01, FRAME_flphor05, flipper_frames_start_run, NULL}; 154 155 void flipper_start_run (edict_t *self) 156 { 157 self->monsterinfo.currentmove = &flipper_move_start_run; 158 } 159 160 mframe_t flipper_frames_pain2 [] = 161 { 162 ai_move, 0, NULL, 163 ai_move, 0, NULL, 164 ai_move, 0, NULL, 165 ai_move, 0, NULL, 166 ai_move, 0, NULL 167 }; 168 mmove_t flipper_move_pain2 = {FRAME_flppn101, FRAME_flppn105, flipper_frames_pain2, flipper_run}; 169 170 mframe_t flipper_frames_pain1 [] = 171 { 172 ai_move, 0, NULL, 173 ai_move, 0, NULL, 174 ai_move, 0, NULL, 175 ai_move, 0, NULL, 176 ai_move, 0, NULL 177 }; 178 mmove_t flipper_move_pain1 = {FRAME_flppn201, FRAME_flppn205, flipper_frames_pain1, flipper_run}; 179 180 void flipper_bite (edict_t *self) 181 { 182 vec3_t aim; 183 184 VectorSet (aim, MELEE_DISTANCE, 0, 0); 185 fire_hit (self, aim, 5, 0); 186 } 187 188 void flipper_preattack (edict_t *self) 189 { 190 gi.sound (self, CHAN_WEAPON, sound_chomp, 1, ATTN_NORM, 0); 191 } 192 193 mframe_t flipper_frames_attack [] = 194 { 195 ai_charge, 0, flipper_preattack, 196 ai_charge, 0, NULL, 197 ai_charge, 0, NULL, 198 ai_charge, 0, NULL, 199 ai_charge, 0, NULL, 200 ai_charge, 0, NULL, 201 ai_charge, 0, NULL, 202 ai_charge, 0, NULL, 203 ai_charge, 0, NULL, 204 ai_charge, 0, NULL, 205 ai_charge, 0, NULL, 206 ai_charge, 0, NULL, 207 ai_charge, 0, NULL, 208 ai_charge, 0, flipper_bite, 209 ai_charge, 0, NULL, 210 ai_charge, 0, NULL, 211 ai_charge, 0, NULL, 212 ai_charge, 0, NULL, 213 ai_charge, 0, flipper_bite, 214 ai_charge, 0, NULL 215 }; 216 mmove_t flipper_move_attack = {FRAME_flpbit01, FRAME_flpbit20, flipper_frames_attack, flipper_run}; 217 218 void flipper_melee(edict_t *self) 219 { 220 self->monsterinfo.currentmove = &flipper_move_attack; 221 } 222 223 void flipper_pain (edict_t *self, edict_t *other, float kick, int damage) 224 { 225 int n; 226 227 if (self->health < (self->max_health / 2)) 228 self->s.skinnum = 1; 229 230 if (level.time < self->pain_debounce_time) 231 return; 232 233 self->pain_debounce_time = level.time + 3; 234 235 if (skill->value == 3) 236 return; // no pain anims in nightmare 237 238 n = (rand() + 1) % 2; 239 if (n == 0) 240 { 241 gi.sound (self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0); 242 self->monsterinfo.currentmove = &flipper_move_pain1; 243 } 244 else 245 { 246 gi.sound (self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0); 247 self->monsterinfo.currentmove = &flipper_move_pain2; 248 } 249 } 250 251 void flipper_dead (edict_t *self) 252 { 253 VectorSet (self->mins, -16, -16, -24); 254 VectorSet (self->maxs, 16, 16, -8); 255 self->movetype = MOVETYPE_TOSS; 256 self->svflags |= SVF_DEADMONSTER; 257 self->nextthink = 0; 258 gi.linkentity (self); 259 } 260 261 mframe_t flipper_frames_death [] = 262 { 263 ai_move, 0, NULL, 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 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 285 ai_move, 0, NULL, 286 ai_move, 0, NULL, 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 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 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 ai_move, 0, NULL, 313 ai_move, 0, NULL, 314 ai_move, 0, NULL, 315 ai_move, 0, NULL, 316 ai_move, 0, NULL, 317 318 ai_move, 0, NULL, 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 }; 325 mmove_t flipper_move_death = {FRAME_flpdth01, FRAME_flpdth56, flipper_frames_death, flipper_dead}; 326 327 void flipper_sight (edict_t *self, edict_t *other) 328 { 329 gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0); 330 } 331 332 void flipper_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) 333 { 334 int n; 335 336 // check for gib 337 if (self->health <= self->gib_health) 338 { 339 gi.sound (self, CHAN_VOICE, gi.soundindex ("misc/udeath.wav"), 1, ATTN_NORM, 0); 340 for (n= 0; n < 2; n++) 341 ThrowGib (self, "models/objects/gibs/bone/tris.md2", damage, GIB_ORGANIC); 342 for (n= 0; n < 2; n++) 343 ThrowGib (self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC); 344 ThrowHead (self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC); 345 self->deadflag = DEAD_DEAD; 346 return; 347 } 348 349 if (self->deadflag == DEAD_DEAD) 350 return; 351 352 // regular death 353 gi.sound (self, CHAN_VOICE, sound_death, 1, ATTN_NORM, 0); 354 self->deadflag = DEAD_DEAD; 355 self->takedamage = DAMAGE_YES; 356 self->monsterinfo.currentmove = &flipper_move_death; 357 } 358 359 /*QUAKED monster_flipper (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight 360 */ 361 void SP_monster_flipper (edict_t *self) 362 { 363 if (deathmatch->value) 364 { 365 G_FreeEdict (self); 366 return; 367 } 368 369 sound_pain1 = gi.soundindex ("flipper/flppain1.wav"); 370 sound_pain2 = gi.soundindex ("flipper/flppain2.wav"); 371 sound_death = gi.soundindex ("flipper/flpdeth1.wav"); 372 sound_chomp = gi.soundindex ("flipper/flpatck1.wav"); 373 sound_attack = gi.soundindex ("flipper/flpatck2.wav"); 374 sound_idle = gi.soundindex ("flipper/flpidle1.wav"); 375 sound_search = gi.soundindex ("flipper/flpsrch1.wav"); 376 sound_sight = gi.soundindex ("flipper/flpsght1.wav"); 377 378 self->movetype = MOVETYPE_STEP; 379 self->solid = SOLID_BBOX; 380 self->s.modelindex = gi.modelindex ("models/monsters/flipper/tris.md2"); 381 VectorSet (self->mins, -16, -16, 0); 382 VectorSet (self->maxs, 16, 16, 32); 383 384 self->health = 50; 385 self->gib_health = -30; 386 self->mass = 100; 387 388 self->pain = flipper_pain; 389 self->die = flipper_die; 390 391 self->monsterinfo.stand = flipper_stand; 392 self->monsterinfo.walk = flipper_walk; 393 self->monsterinfo.run = flipper_start_run; 394 self->monsterinfo.melee = flipper_melee; 395 self->monsterinfo.sight = flipper_sight; 396 397 gi.linkentity (self); 398 399 self->monsterinfo.currentmove = &flipper_move_stand; 400 self->monsterinfo.scale = MODEL_SCALE; 401 402 swimmonster_start (self); 403 }