m_hover.c (14149B)
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 hover 24 25 ============================================================================== 26 */ 27 28 #include "g_local.h" 29 #include "m_hover.h" 30 31 qboolean visible (edict_t *self, edict_t *other); 32 33 34 static int sound_pain1; 35 static int sound_pain2; 36 static int sound_death1; 37 static int sound_death2; 38 static int sound_sight; 39 static int sound_search1; 40 static int sound_search2; 41 42 43 void hover_sight (edict_t *self, edict_t *other) 44 { 45 gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0); 46 } 47 48 void hover_search (edict_t *self) 49 { 50 if (random() < 0.5) 51 gi.sound (self, CHAN_VOICE, sound_search1, 1, ATTN_NORM, 0); 52 else 53 gi.sound (self, CHAN_VOICE, sound_search2, 1, ATTN_NORM, 0); 54 } 55 56 57 void hover_run (edict_t *self); 58 void hover_stand (edict_t *self); 59 void hover_dead (edict_t *self); 60 void hover_attack (edict_t *self); 61 void hover_reattack (edict_t *self); 62 void hover_fire_blaster (edict_t *self); 63 void hover_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point); 64 65 mframe_t hover_frames_stand [] = 66 { 67 ai_stand, 0, NULL, 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 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 }; 98 mmove_t hover_move_stand = {FRAME_stand01, FRAME_stand30, hover_frames_stand, NULL}; 99 100 mframe_t hover_frames_stop1 [] = 101 { 102 ai_move, 0, NULL, 103 ai_move, 0, NULL, 104 ai_move, 0, NULL, 105 ai_move, 0, NULL, 106 ai_move, 0, NULL, 107 ai_move, 0, NULL, 108 ai_move, 0, NULL, 109 ai_move, 0, NULL, 110 ai_move, 0, NULL 111 }; 112 mmove_t hover_move_stop1 = {FRAME_stop101, FRAME_stop109, hover_frames_stop1, NULL}; 113 114 mframe_t hover_frames_stop2 [] = 115 { 116 ai_move, 0, NULL, 117 ai_move, 0, NULL, 118 ai_move, 0, NULL, 119 ai_move, 0, NULL, 120 ai_move, 0, NULL, 121 ai_move, 0, NULL, 122 ai_move, 0, NULL, 123 ai_move, 0, NULL 124 }; 125 mmove_t hover_move_stop2 = {FRAME_stop201, FRAME_stop208, hover_frames_stop2, NULL}; 126 127 mframe_t hover_frames_takeoff [] = 128 { 129 ai_move, 0, NULL, 130 ai_move, -2, NULL, 131 ai_move, 5, NULL, 132 ai_move, -1, NULL, 133 ai_move, 1, NULL, 134 ai_move, 0, NULL, 135 ai_move, 0, NULL, 136 ai_move, -1, NULL, 137 ai_move, -1, NULL, 138 ai_move, -1, NULL, 139 ai_move, 0, NULL, 140 ai_move, 2, NULL, 141 ai_move, 2, NULL, 142 ai_move, 1, NULL, 143 ai_move, 1, NULL, 144 ai_move, -6, NULL, 145 ai_move, -9, NULL, 146 ai_move, 1, NULL, 147 ai_move, 0, NULL, 148 ai_move, 2, NULL, 149 ai_move, 2, NULL, 150 ai_move, 1, NULL, 151 ai_move, 1, NULL, 152 ai_move, 1, NULL, 153 ai_move, 2, NULL, 154 ai_move, 0, NULL, 155 ai_move, 2, NULL, 156 ai_move, 3, NULL, 157 ai_move, 2, NULL, 158 ai_move, 0, NULL 159 }; 160 mmove_t hover_move_takeoff = {FRAME_takeof01, FRAME_takeof30, hover_frames_takeoff, NULL}; 161 162 mframe_t hover_frames_pain3 [] = 163 { 164 ai_move, 0, NULL, 165 ai_move, 0, NULL, 166 ai_move, 0, NULL, 167 ai_move, 0, NULL, 168 ai_move, 0, NULL, 169 ai_move, 0, NULL, 170 ai_move, 0, NULL, 171 ai_move, 0, NULL, 172 ai_move, 0, NULL 173 }; 174 mmove_t hover_move_pain3 = {FRAME_pain301, FRAME_pain309, hover_frames_pain3, hover_run}; 175 176 mframe_t hover_frames_pain2 [] = 177 { 178 ai_move, 0, NULL, 179 ai_move, 0, NULL, 180 ai_move, 0, NULL, 181 ai_move, 0, NULL, 182 ai_move, 0, NULL, 183 ai_move, 0, NULL, 184 ai_move, 0, NULL, 185 ai_move, 0, NULL, 186 ai_move, 0, NULL, 187 ai_move, 0, NULL, 188 ai_move, 0, NULL, 189 ai_move, 0, NULL 190 }; 191 mmove_t hover_move_pain2 = {FRAME_pain201, FRAME_pain212, hover_frames_pain2, hover_run}; 192 193 mframe_t hover_frames_pain1 [] = 194 { 195 ai_move, 0, NULL, 196 ai_move, 0, NULL, 197 ai_move, 2, NULL, 198 ai_move, -8, NULL, 199 ai_move, -4, NULL, 200 ai_move, -6, NULL, 201 ai_move, -4, NULL, 202 ai_move, -3, NULL, 203 ai_move, 1, NULL, 204 ai_move, 0, NULL, 205 ai_move, 0, NULL, 206 ai_move, 0, NULL, 207 ai_move, 3, NULL, 208 ai_move, 1, NULL, 209 ai_move, 0, NULL, 210 ai_move, 2, NULL, 211 ai_move, 3, NULL, 212 ai_move, 2, NULL, 213 ai_move, 7, NULL, 214 ai_move, 1, NULL, 215 ai_move, 0, NULL, 216 ai_move, 0, NULL, 217 ai_move, 2, NULL, 218 ai_move, 0, NULL, 219 ai_move, 0, NULL, 220 ai_move, 5, NULL, 221 ai_move, 3, NULL, 222 ai_move, 4, NULL 223 }; 224 mmove_t hover_move_pain1 = {FRAME_pain101, FRAME_pain128, hover_frames_pain1, hover_run}; 225 226 mframe_t hover_frames_land [] = 227 { 228 ai_move, 0, NULL 229 }; 230 mmove_t hover_move_land = {FRAME_land01, FRAME_land01, hover_frames_land, NULL}; 231 232 mframe_t hover_frames_forward [] = 233 { 234 ai_move, 0, NULL, 235 ai_move, 0, NULL, 236 ai_move, 0, NULL, 237 ai_move, 0, NULL, 238 ai_move, 0, NULL, 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, NULL, 245 ai_move, 0, NULL, 246 ai_move, 0, NULL, 247 ai_move, 0, NULL, 248 ai_move, 0, NULL, 249 ai_move, 0, NULL, 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, NULL, 257 ai_move, 0, NULL, 258 ai_move, 0, NULL, 259 ai_move, 0, NULL, 260 ai_move, 0, NULL, 261 ai_move, 0, NULL, 262 ai_move, 0, NULL, 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 }; 270 mmove_t hover_move_forward = {FRAME_forwrd01, FRAME_forwrd35, hover_frames_forward, NULL}; 271 272 mframe_t hover_frames_walk [] = 273 { 274 ai_walk, 4, NULL, 275 ai_walk, 4, NULL, 276 ai_walk, 4, NULL, 277 ai_walk, 4, NULL, 278 ai_walk, 4, NULL, 279 ai_walk, 4, NULL, 280 ai_walk, 4, NULL, 281 ai_walk, 4, NULL, 282 ai_walk, 4, NULL, 283 ai_walk, 4, NULL, 284 ai_walk, 4, NULL, 285 ai_walk, 4, NULL, 286 ai_walk, 4, NULL, 287 ai_walk, 4, NULL, 288 ai_walk, 4, NULL, 289 ai_walk, 4, NULL, 290 ai_walk, 4, NULL, 291 ai_walk, 4, NULL, 292 ai_walk, 4, NULL, 293 ai_walk, 4, NULL, 294 ai_walk, 4, NULL, 295 ai_walk, 4, NULL, 296 ai_walk, 4, NULL, 297 ai_walk, 4, NULL, 298 ai_walk, 4, NULL, 299 ai_walk, 4, NULL, 300 ai_walk, 4, NULL, 301 ai_walk, 4, NULL, 302 ai_walk, 4, NULL, 303 ai_walk, 4, NULL, 304 ai_walk, 4, NULL, 305 ai_walk, 4, NULL, 306 ai_walk, 4, NULL, 307 ai_walk, 4, NULL, 308 ai_walk, 4, NULL 309 }; 310 mmove_t hover_move_walk = {FRAME_forwrd01, FRAME_forwrd35, hover_frames_walk, NULL}; 311 312 mframe_t hover_frames_run [] = 313 { 314 ai_run, 10, NULL, 315 ai_run, 10, NULL, 316 ai_run, 10, NULL, 317 ai_run, 10, NULL, 318 ai_run, 10, NULL, 319 ai_run, 10, NULL, 320 ai_run, 10, NULL, 321 ai_run, 10, NULL, 322 ai_run, 10, NULL, 323 ai_run, 10, NULL, 324 ai_run, 10, NULL, 325 ai_run, 10, NULL, 326 ai_run, 10, NULL, 327 ai_run, 10, NULL, 328 ai_run, 10, NULL, 329 ai_run, 10, NULL, 330 ai_run, 10, NULL, 331 ai_run, 10, NULL, 332 ai_run, 10, NULL, 333 ai_run, 10, NULL, 334 ai_run, 10, NULL, 335 ai_run, 10, NULL, 336 ai_run, 10, NULL, 337 ai_run, 10, NULL, 338 ai_run, 10, NULL, 339 ai_run, 10, NULL, 340 ai_run, 10, NULL, 341 ai_run, 10, NULL, 342 ai_run, 10, NULL, 343 ai_run, 10, NULL, 344 ai_run, 10, NULL, 345 ai_run, 10, NULL, 346 ai_run, 10, NULL, 347 ai_run, 10, NULL, 348 ai_run, 10, NULL 349 }; 350 mmove_t hover_move_run = {FRAME_forwrd01, FRAME_forwrd35, hover_frames_run, NULL}; 351 352 mframe_t hover_frames_death1 [] = 353 { 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, -10,NULL, 361 ai_move, 3, NULL, 362 ai_move, 5, NULL, 363 ai_move, 4, NULL, 364 ai_move, 7, NULL 365 }; 366 mmove_t hover_move_death1 = {FRAME_death101, FRAME_death111, hover_frames_death1, hover_dead}; 367 368 mframe_t hover_frames_backward [] = 369 { 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 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 ai_move, 0, NULL, 385 ai_move, 0, NULL, 386 ai_move, 0, NULL, 387 ai_move, 0, NULL, 388 ai_move, 0, NULL, 389 ai_move, 0, NULL, 390 ai_move, 0, NULL, 391 ai_move, 0, NULL, 392 ai_move, 0, NULL, 393 ai_move, 0, NULL 394 }; 395 mmove_t hover_move_backward = {FRAME_backwd01, FRAME_backwd24, hover_frames_backward, NULL}; 396 397 mframe_t hover_frames_start_attack [] = 398 { 399 ai_charge, 1, NULL, 400 ai_charge, 1, NULL, 401 ai_charge, 1, NULL 402 }; 403 mmove_t hover_move_start_attack = {FRAME_attak101, FRAME_attak103, hover_frames_start_attack, hover_attack}; 404 405 mframe_t hover_frames_attack1 [] = 406 { 407 ai_charge, -10, hover_fire_blaster, 408 ai_charge, -10, hover_fire_blaster, 409 ai_charge, 0, hover_reattack, 410 }; 411 mmove_t hover_move_attack1 = {FRAME_attak104, FRAME_attak106, hover_frames_attack1, NULL}; 412 413 414 mframe_t hover_frames_end_attack [] = 415 { 416 ai_charge, 1, NULL, 417 ai_charge, 1, NULL 418 }; 419 mmove_t hover_move_end_attack = {FRAME_attak107, FRAME_attak108, hover_frames_end_attack, hover_run}; 420 421 void hover_reattack (edict_t *self) 422 { 423 if (self->enemy->health > 0 ) 424 if (visible (self, self->enemy) ) 425 if (random() <= 0.6) 426 { 427 self->monsterinfo.currentmove = &hover_move_attack1; 428 return; 429 } 430 self->monsterinfo.currentmove = &hover_move_end_attack; 431 } 432 433 434 void hover_fire_blaster (edict_t *self) 435 { 436 vec3_t start; 437 vec3_t forward, right; 438 vec3_t end; 439 vec3_t dir; 440 int effect; 441 442 if (self->s.frame == FRAME_attak104) 443 effect = EF_HYPERBLASTER; 444 else 445 effect = 0; 446 447 AngleVectors (self->s.angles, forward, right, NULL); 448 G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_HOVER_BLASTER_1], forward, right, start); 449 450 VectorCopy (self->enemy->s.origin, end); 451 end[2] += self->enemy->viewheight; 452 VectorSubtract (end, start, dir); 453 454 monster_fire_blaster (self, start, dir, 1, 1000, MZ2_HOVER_BLASTER_1, effect); 455 } 456 457 458 void hover_stand (edict_t *self) 459 { 460 self->monsterinfo.currentmove = &hover_move_stand; 461 } 462 463 void hover_run (edict_t *self) 464 { 465 if (self->monsterinfo.aiflags & AI_STAND_GROUND) 466 self->monsterinfo.currentmove = &hover_move_stand; 467 else 468 self->monsterinfo.currentmove = &hover_move_run; 469 } 470 471 void hover_walk (edict_t *self) 472 { 473 self->monsterinfo.currentmove = &hover_move_walk; 474 } 475 476 void hover_start_attack (edict_t *self) 477 { 478 self->monsterinfo.currentmove = &hover_move_start_attack; 479 } 480 481 void hover_attack(edict_t *self) 482 { 483 self->monsterinfo.currentmove = &hover_move_attack1; 484 } 485 486 487 void hover_pain (edict_t *self, edict_t *other, float kick, int damage) 488 { 489 if (self->health < (self->max_health / 2)) 490 self->s.skinnum = 1; 491 492 if (level.time < self->pain_debounce_time) 493 return; 494 495 self->pain_debounce_time = level.time + 3; 496 497 if (skill->value == 3) 498 return; // no pain anims in nightmare 499 500 if (damage <= 25) 501 { 502 if (random() < 0.5) 503 { 504 gi.sound (self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0); 505 self->monsterinfo.currentmove = &hover_move_pain3; 506 } 507 else 508 { 509 gi.sound (self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0); 510 self->monsterinfo.currentmove = &hover_move_pain2; 511 } 512 } 513 else 514 { 515 gi.sound (self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0); 516 self->monsterinfo.currentmove = &hover_move_pain1; 517 } 518 } 519 520 void hover_deadthink (edict_t *self) 521 { 522 if (!self->groundentity && level.time < self->timestamp) 523 { 524 self->nextthink = level.time + FRAMETIME; 525 return; 526 } 527 BecomeExplosion1(self); 528 } 529 530 void hover_dead (edict_t *self) 531 { 532 VectorSet (self->mins, -16, -16, -24); 533 VectorSet (self->maxs, 16, 16, -8); 534 self->movetype = MOVETYPE_TOSS; 535 self->think = hover_deadthink; 536 self->nextthink = level.time + FRAMETIME; 537 self->timestamp = level.time + 15; 538 gi.linkentity (self); 539 } 540 541 void hover_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) 542 { 543 int n; 544 545 // check for gib 546 if (self->health <= self->gib_health) 547 { 548 gi.sound (self, CHAN_VOICE, gi.soundindex ("misc/udeath.wav"), 1, ATTN_NORM, 0); 549 for (n= 0; n < 2; n++) 550 ThrowGib (self, "models/objects/gibs/bone/tris.md2", damage, GIB_ORGANIC); 551 for (n= 0; n < 2; n++) 552 ThrowGib (self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC); 553 ThrowHead (self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC); 554 self->deadflag = DEAD_DEAD; 555 return; 556 } 557 558 if (self->deadflag == DEAD_DEAD) 559 return; 560 561 // regular death 562 if (random() < 0.5) 563 gi.sound (self, CHAN_VOICE, sound_death1, 1, ATTN_NORM, 0); 564 else 565 gi.sound (self, CHAN_VOICE, sound_death2, 1, ATTN_NORM, 0); 566 self->deadflag = DEAD_DEAD; 567 self->takedamage = DAMAGE_YES; 568 self->monsterinfo.currentmove = &hover_move_death1; 569 } 570 571 /*QUAKED monster_hover (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight 572 */ 573 void SP_monster_hover (edict_t *self) 574 { 575 if (deathmatch->value) 576 { 577 G_FreeEdict (self); 578 return; 579 } 580 581 sound_pain1 = gi.soundindex ("hover/hovpain1.wav"); 582 sound_pain2 = gi.soundindex ("hover/hovpain2.wav"); 583 sound_death1 = gi.soundindex ("hover/hovdeth1.wav"); 584 sound_death2 = gi.soundindex ("hover/hovdeth2.wav"); 585 sound_sight = gi.soundindex ("hover/hovsght1.wav"); 586 sound_search1 = gi.soundindex ("hover/hovsrch1.wav"); 587 sound_search2 = gi.soundindex ("hover/hovsrch2.wav"); 588 589 gi.soundindex ("hover/hovatck1.wav"); 590 591 self->s.sound = gi.soundindex ("hover/hovidle1.wav"); 592 593 self->movetype = MOVETYPE_STEP; 594 self->solid = SOLID_BBOX; 595 self->s.modelindex = gi.modelindex("models/monsters/hover/tris.md2"); 596 VectorSet (self->mins, -24, -24, -24); 597 VectorSet (self->maxs, 24, 24, 32); 598 599 self->health = 240; 600 self->gib_health = -100; 601 self->mass = 150; 602 603 self->pain = hover_pain; 604 self->die = hover_die; 605 606 self->monsterinfo.stand = hover_stand; 607 self->monsterinfo.walk = hover_walk; 608 self->monsterinfo.run = hover_run; 609 // self->monsterinfo.dodge = hover_dodge; 610 self->monsterinfo.attack = hover_start_attack; 611 self->monsterinfo.sight = hover_sight; 612 self->monsterinfo.search = hover_search; 613 614 gi.linkentity (self); 615 616 self->monsterinfo.currentmove = &hover_move_stand; 617 self->monsterinfo.scale = MODEL_SCALE; 618 619 flymonster_start (self); 620 }