m_supertank.c (16293B)
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 SUPERTANK 24 25 ============================================================================== 26 */ 27 28 #include "g_local.h" 29 #include "m_supertank.h" 30 31 qboolean visible (edict_t *self, edict_t *other); 32 33 static int sound_pain1; 34 static int sound_pain2; 35 static int sound_pain3; 36 static int sound_death; 37 static int sound_search1; 38 static int sound_search2; 39 40 static int tread_sound; 41 42 void BossExplode (edict_t *self); 43 44 void TreadSound (edict_t *self) 45 { 46 gi.sound (self, CHAN_VOICE, tread_sound, 1, ATTN_NORM, 0); 47 } 48 49 void supertank_search (edict_t *self) 50 { 51 if (random() < 0.5) 52 gi.sound (self, CHAN_VOICE, sound_search1, 1, ATTN_NORM, 0); 53 else 54 gi.sound (self, CHAN_VOICE, sound_search2, 1, ATTN_NORM, 0); 55 } 56 57 58 void supertank_dead (edict_t *self); 59 void supertankRocket (edict_t *self); 60 void supertankMachineGun (edict_t *self); 61 void supertank_reattack1(edict_t *self); 62 63 64 // 65 // stand 66 // 67 68 mframe_t supertank_frames_stand []= 69 { 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 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 ai_stand, 0, NULL, 120 ai_stand, 0, NULL, 121 ai_stand, 0, NULL, 122 ai_stand, 0, NULL, 123 ai_stand, 0, NULL, 124 ai_stand, 0, NULL, 125 ai_stand, 0, NULL, 126 ai_stand, 0, NULL, 127 ai_stand, 0, NULL, 128 ai_stand, 0, NULL, 129 ai_stand, 0, NULL 130 }; 131 mmove_t supertank_move_stand = {FRAME_stand_1, FRAME_stand_60, supertank_frames_stand, NULL}; 132 133 void supertank_stand (edict_t *self) 134 { 135 self->monsterinfo.currentmove = &supertank_move_stand; 136 } 137 138 139 mframe_t supertank_frames_run [] = 140 { 141 ai_run, 12, TreadSound, 142 ai_run, 12, NULL, 143 ai_run, 12, NULL, 144 ai_run, 12, NULL, 145 ai_run, 12, NULL, 146 ai_run, 12, NULL, 147 ai_run, 12, NULL, 148 ai_run, 12, NULL, 149 ai_run, 12, NULL, 150 ai_run, 12, NULL, 151 ai_run, 12, NULL, 152 ai_run, 12, NULL, 153 ai_run, 12, NULL, 154 ai_run, 12, NULL, 155 ai_run, 12, NULL, 156 ai_run, 12, NULL, 157 ai_run, 12, NULL, 158 ai_run, 12, NULL 159 }; 160 mmove_t supertank_move_run = {FRAME_forwrd_1, FRAME_forwrd_18, supertank_frames_run, NULL}; 161 162 // 163 // walk 164 // 165 166 167 mframe_t supertank_frames_forward [] = 168 { 169 ai_walk, 4, TreadSound, 170 ai_walk, 4, NULL, 171 ai_walk, 4, NULL, 172 ai_walk, 4, NULL, 173 ai_walk, 4, NULL, 174 ai_walk, 4, NULL, 175 ai_walk, 4, NULL, 176 ai_walk, 4, NULL, 177 ai_walk, 4, NULL, 178 ai_walk, 4, NULL, 179 ai_walk, 4, NULL, 180 ai_walk, 4, NULL, 181 ai_walk, 4, NULL, 182 ai_walk, 4, NULL, 183 ai_walk, 4, NULL, 184 ai_walk, 4, NULL, 185 ai_walk, 4, NULL, 186 ai_walk, 4, NULL 187 }; 188 mmove_t supertank_move_forward = {FRAME_forwrd_1, FRAME_forwrd_18, supertank_frames_forward, NULL}; 189 190 void supertank_forward (edict_t *self) 191 { 192 self->monsterinfo.currentmove = &supertank_move_forward; 193 } 194 195 void supertank_walk (edict_t *self) 196 { 197 self->monsterinfo.currentmove = &supertank_move_forward; 198 } 199 200 void supertank_run (edict_t *self) 201 { 202 if (self->monsterinfo.aiflags & AI_STAND_GROUND) 203 self->monsterinfo.currentmove = &supertank_move_stand; 204 else 205 self->monsterinfo.currentmove = &supertank_move_run; 206 } 207 208 mframe_t supertank_frames_turn_right [] = 209 { 210 ai_move, 0, TreadSound, 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 ai_move, 0, NULL, 219 ai_move, 0, NULL, 220 ai_move, 0, NULL, 221 ai_move, 0, NULL, 222 ai_move, 0, NULL, 223 ai_move, 0, NULL, 224 ai_move, 0, NULL, 225 ai_move, 0, NULL, 226 ai_move, 0, NULL, 227 ai_move, 0, NULL 228 }; 229 mmove_t supertank_move_turn_right = {FRAME_right_1, FRAME_right_18, supertank_frames_turn_right, supertank_run}; 230 231 mframe_t supertank_frames_turn_left [] = 232 { 233 ai_move, 0, TreadSound, 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 }; 252 mmove_t supertank_move_turn_left = {FRAME_left_1, FRAME_left_18, supertank_frames_turn_left, supertank_run}; 253 254 255 mframe_t supertank_frames_pain3 [] = 256 { 257 ai_move, 0, NULL, 258 ai_move, 0, NULL, 259 ai_move, 0, NULL, 260 ai_move, 0, NULL 261 }; 262 mmove_t supertank_move_pain3 = {FRAME_pain3_9, FRAME_pain3_12, supertank_frames_pain3, supertank_run}; 263 264 mframe_t supertank_frames_pain2 [] = 265 { 266 ai_move, 0, NULL, 267 ai_move, 0, NULL, 268 ai_move, 0, NULL, 269 ai_move, 0, NULL 270 }; 271 mmove_t supertank_move_pain2 = {FRAME_pain2_5, FRAME_pain2_8, supertank_frames_pain2, supertank_run}; 272 273 mframe_t supertank_frames_pain1 [] = 274 { 275 ai_move, 0, NULL, 276 ai_move, 0, NULL, 277 ai_move, 0, NULL, 278 ai_move, 0, NULL 279 }; 280 mmove_t supertank_move_pain1 = {FRAME_pain1_1, FRAME_pain1_4, supertank_frames_pain1, supertank_run}; 281 282 mframe_t supertank_frames_death1 [] = 283 { 284 ai_move, 0, NULL, 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 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, BossExplode 308 }; 309 mmove_t supertank_move_death = {FRAME_death_1, FRAME_death_24, supertank_frames_death1, supertank_dead}; 310 311 mframe_t supertank_frames_backward[] = 312 { 313 ai_walk, 0, TreadSound, 314 ai_walk, 0, NULL, 315 ai_walk, 0, NULL, 316 ai_walk, 0, NULL, 317 ai_walk, 0, NULL, 318 ai_walk, 0, NULL, 319 ai_walk, 0, NULL, 320 ai_walk, 0, NULL, 321 ai_walk, 0, NULL, 322 ai_walk, 0, NULL, 323 ai_walk, 0, NULL, 324 ai_walk, 0, NULL, 325 ai_walk, 0, NULL, 326 ai_walk, 0, NULL, 327 ai_walk, 0, NULL, 328 ai_walk, 0, NULL, 329 ai_walk, 0, NULL, 330 ai_walk, 0, NULL 331 }; 332 mmove_t supertank_move_backward = {FRAME_backwd_1, FRAME_backwd_18, supertank_frames_backward, NULL}; 333 334 mframe_t supertank_frames_attack4[]= 335 { 336 ai_move, 0, NULL, 337 ai_move, 0, NULL, 338 ai_move, 0, NULL, 339 ai_move, 0, NULL, 340 ai_move, 0, NULL, 341 ai_move, 0, NULL 342 }; 343 mmove_t supertank_move_attack4 = {FRAME_attak4_1, FRAME_attak4_6, supertank_frames_attack4, supertank_run}; 344 345 mframe_t supertank_frames_attack3[]= 346 { 347 ai_move, 0, NULL, 348 ai_move, 0, NULL, 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 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 ai_move, 0, NULL, 371 ai_move, 0, NULL, 372 ai_move, 0, NULL, 373 ai_move, 0, NULL 374 }; 375 mmove_t supertank_move_attack3 = {FRAME_attak3_1, FRAME_attak3_27, supertank_frames_attack3, supertank_run}; 376 377 mframe_t supertank_frames_attack2[]= 378 { 379 ai_charge, 0, NULL, 380 ai_charge, 0, NULL, 381 ai_charge, 0, NULL, 382 ai_charge, 0, NULL, 383 ai_charge, 0, NULL, 384 ai_charge, 0, NULL, 385 ai_charge, 0, NULL, 386 ai_charge, 0, supertankRocket, 387 ai_move, 0, NULL, 388 ai_move, 0, NULL, 389 ai_move, 0, supertankRocket, 390 ai_move, 0, NULL, 391 ai_move, 0, NULL, 392 ai_move, 0, supertankRocket, 393 ai_move, 0, NULL, 394 ai_move, 0, NULL, 395 ai_move, 0, NULL, 396 ai_move, 0, NULL, 397 ai_move, 0, NULL, 398 ai_move, 0, NULL, 399 ai_move, 0, NULL, 400 ai_move, 0, NULL, 401 ai_move, 0, NULL, 402 ai_move, 0, NULL, 403 ai_move, 0, NULL, 404 ai_move, 0, NULL, 405 ai_move, 0, NULL 406 }; 407 mmove_t supertank_move_attack2 = {FRAME_attak2_1, FRAME_attak2_27, supertank_frames_attack2, supertank_run}; 408 409 mframe_t supertank_frames_attack1[]= 410 { 411 ai_charge, 0, supertankMachineGun, 412 ai_charge, 0, supertankMachineGun, 413 ai_charge, 0, supertankMachineGun, 414 ai_charge, 0, supertankMachineGun, 415 ai_charge, 0, supertankMachineGun, 416 ai_charge, 0, supertankMachineGun, 417 418 }; 419 mmove_t supertank_move_attack1 = {FRAME_attak1_1, FRAME_attak1_6, supertank_frames_attack1, supertank_reattack1}; 420 421 mframe_t supertank_frames_end_attack1[]= 422 { 423 ai_move, 0, NULL, 424 ai_move, 0, NULL, 425 ai_move, 0, NULL, 426 ai_move, 0, NULL, 427 ai_move, 0, NULL, 428 ai_move, 0, NULL, 429 ai_move, 0, NULL, 430 ai_move, 0, NULL, 431 ai_move, 0, NULL, 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 }; 438 mmove_t supertank_move_end_attack1 = {FRAME_attak1_7, FRAME_attak1_20, supertank_frames_end_attack1, supertank_run}; 439 440 441 void supertank_reattack1(edict_t *self) 442 { 443 if (visible(self, self->enemy)) 444 if (random() < 0.9) 445 self->monsterinfo.currentmove = &supertank_move_attack1; 446 else 447 self->monsterinfo.currentmove = &supertank_move_end_attack1; 448 else 449 self->monsterinfo.currentmove = &supertank_move_end_attack1; 450 } 451 452 void supertank_pain (edict_t *self, edict_t *other, float kick, int damage) 453 { 454 455 if (self->health < (self->max_health / 2)) 456 self->s.skinnum = 1; 457 458 if (level.time < self->pain_debounce_time) 459 return; 460 461 // Lessen the chance of him going into his pain frames 462 if (damage <=25) 463 if (random()<0.2) 464 return; 465 466 // Don't go into pain if he's firing his rockets 467 if (skill->value >= 2) 468 if ( (self->s.frame >= FRAME_attak2_1) && (self->s.frame <= FRAME_attak2_14) ) 469 return; 470 471 self->pain_debounce_time = level.time + 3; 472 473 if (skill->value == 3) 474 return; // no pain anims in nightmare 475 476 if (damage <= 10) 477 { 478 gi.sound (self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM,0); 479 self->monsterinfo.currentmove = &supertank_move_pain1; 480 } 481 else if (damage <= 25) 482 { 483 gi.sound (self, CHAN_VOICE, sound_pain3, 1, ATTN_NORM,0); 484 self->monsterinfo.currentmove = &supertank_move_pain2; 485 } 486 else 487 { 488 gi.sound (self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM,0); 489 self->monsterinfo.currentmove = &supertank_move_pain3; 490 } 491 }; 492 493 494 void supertankRocket (edict_t *self) 495 { 496 vec3_t forward, right; 497 vec3_t start; 498 vec3_t dir; 499 vec3_t vec; 500 int flash_number; 501 502 if (self->s.frame == FRAME_attak2_8) 503 flash_number = MZ2_SUPERTANK_ROCKET_1; 504 else if (self->s.frame == FRAME_attak2_11) 505 flash_number = MZ2_SUPERTANK_ROCKET_2; 506 else // (self->s.frame == FRAME_attak2_14) 507 flash_number = MZ2_SUPERTANK_ROCKET_3; 508 509 AngleVectors (self->s.angles, forward, right, NULL); 510 G_ProjectSource (self->s.origin, monster_flash_offset[flash_number], forward, right, start); 511 512 VectorCopy (self->enemy->s.origin, vec); 513 vec[2] += self->enemy->viewheight; 514 VectorSubtract (vec, start, dir); 515 VectorNormalize (dir); 516 517 monster_fire_rocket (self, start, dir, 50, 500, flash_number); 518 } 519 520 void supertankMachineGun (edict_t *self) 521 { 522 vec3_t dir; 523 vec3_t vec; 524 vec3_t start; 525 vec3_t forward, right; 526 int flash_number; 527 528 flash_number = MZ2_SUPERTANK_MACHINEGUN_1 + (self->s.frame - FRAME_attak1_1); 529 530 //FIXME!!! 531 dir[0] = 0; 532 dir[1] = self->s.angles[1]; 533 dir[2] = 0; 534 535 AngleVectors (dir, forward, right, NULL); 536 G_ProjectSource (self->s.origin, monster_flash_offset[flash_number], forward, right, start); 537 538 if (self->enemy) 539 { 540 VectorCopy (self->enemy->s.origin, vec); 541 VectorMA (vec, 0, self->enemy->velocity, vec); 542 vec[2] += self->enemy->viewheight; 543 VectorSubtract (vec, start, forward); 544 VectorNormalize (forward); 545 } 546 547 monster_fire_bullet (self, start, forward, 6, 4, DEFAULT_BULLET_HSPREAD, DEFAULT_BULLET_VSPREAD, flash_number); 548 } 549 550 551 void supertank_attack(edict_t *self) 552 { 553 vec3_t vec; 554 float range; 555 //float r; 556 557 VectorSubtract (self->enemy->s.origin, self->s.origin, vec); 558 range = VectorLength (vec); 559 560 //r = random(); 561 562 // Attack 1 == Chaingun 563 // Attack 2 == Rocket Launcher 564 565 if (range <= 160) 566 { 567 self->monsterinfo.currentmove = &supertank_move_attack1; 568 } 569 else 570 { // fire rockets more often at distance 571 if (random() < 0.3) 572 self->monsterinfo.currentmove = &supertank_move_attack1; 573 else 574 self->monsterinfo.currentmove = &supertank_move_attack2; 575 } 576 } 577 578 579 // 580 // death 581 // 582 583 void supertank_dead (edict_t *self) 584 { 585 VectorSet (self->mins, -60, -60, 0); 586 VectorSet (self->maxs, 60, 60, 72); 587 self->movetype = MOVETYPE_TOSS; 588 self->svflags |= SVF_DEADMONSTER; 589 self->nextthink = 0; 590 gi.linkentity (self); 591 } 592 593 594 void BossExplode (edict_t *self) 595 { 596 vec3_t org; 597 int n; 598 599 self->think = BossExplode; 600 VectorCopy (self->s.origin, org); 601 org[2] += 24 + (rand()&15); 602 switch (self->count++) 603 { 604 case 0: 605 org[0] -= 24; 606 org[1] -= 24; 607 break; 608 case 1: 609 org[0] += 24; 610 org[1] += 24; 611 break; 612 case 2: 613 org[0] += 24; 614 org[1] -= 24; 615 break; 616 case 3: 617 org[0] -= 24; 618 org[1] += 24; 619 break; 620 case 4: 621 org[0] -= 48; 622 org[1] -= 48; 623 break; 624 case 5: 625 org[0] += 48; 626 org[1] += 48; 627 break; 628 case 6: 629 org[0] -= 48; 630 org[1] += 48; 631 break; 632 case 7: 633 org[0] += 48; 634 org[1] -= 48; 635 break; 636 case 8: 637 self->s.sound = 0; 638 for (n= 0; n < 4; n++) 639 ThrowGib (self, "models/objects/gibs/sm_meat/tris.md2", 500, GIB_ORGANIC); 640 for (n= 0; n < 8; n++) 641 ThrowGib (self, "models/objects/gibs/sm_metal/tris.md2", 500, GIB_METALLIC); 642 ThrowGib (self, "models/objects/gibs/chest/tris.md2", 500, GIB_ORGANIC); 643 ThrowHead (self, "models/objects/gibs/gear/tris.md2", 500, GIB_METALLIC); 644 self->deadflag = DEAD_DEAD; 645 return; 646 } 647 648 gi.WriteByte (svc_temp_entity); 649 gi.WriteByte (TE_EXPLOSION1); 650 gi.WritePosition (org); 651 gi.multicast (self->s.origin, MULTICAST_PVS); 652 653 self->nextthink = level.time + 0.1; 654 } 655 656 657 void supertank_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) 658 { 659 gi.sound (self, CHAN_VOICE, sound_death, 1, ATTN_NORM, 0); 660 self->deadflag = DEAD_DEAD; 661 self->takedamage = DAMAGE_NO; 662 self->count = 0; 663 self->monsterinfo.currentmove = &supertank_move_death; 664 } 665 666 // 667 // monster_supertank 668 // 669 670 /*QUAKED monster_supertank (1 .5 0) (-64 -64 0) (64 64 72) Ambush Trigger_Spawn Sight 671 */ 672 void SP_monster_supertank (edict_t *self) 673 { 674 if (deathmatch->value) 675 { 676 G_FreeEdict (self); 677 return; 678 } 679 680 sound_pain1 = gi.soundindex ("bosstank/btkpain1.wav"); 681 sound_pain2 = gi.soundindex ("bosstank/btkpain2.wav"); 682 sound_pain3 = gi.soundindex ("bosstank/btkpain3.wav"); 683 sound_death = gi.soundindex ("bosstank/btkdeth1.wav"); 684 sound_search1 = gi.soundindex ("bosstank/btkunqv1.wav"); 685 sound_search2 = gi.soundindex ("bosstank/btkunqv2.wav"); 686 687 // self->s.sound = gi.soundindex ("bosstank/btkengn1.wav"); 688 tread_sound = gi.soundindex ("bosstank/btkengn1.wav"); 689 690 self->movetype = MOVETYPE_STEP; 691 self->solid = SOLID_BBOX; 692 self->s.modelindex = gi.modelindex ("models/monsters/boss1/tris.md2"); 693 VectorSet (self->mins, -64, -64, 0); 694 VectorSet (self->maxs, 64, 64, 112); 695 696 self->health = 1500; 697 self->gib_health = -500; 698 self->mass = 800; 699 700 self->pain = supertank_pain; 701 self->die = supertank_die; 702 self->monsterinfo.stand = supertank_stand; 703 self->monsterinfo.walk = supertank_walk; 704 self->monsterinfo.run = supertank_run; 705 self->monsterinfo.dodge = NULL; 706 self->monsterinfo.attack = supertank_attack; 707 self->monsterinfo.search = supertank_search; 708 self->monsterinfo.melee = NULL; 709 self->monsterinfo.sight = NULL; 710 711 gi.linkentity (self); 712 713 self->monsterinfo.currentmove = &supertank_move_stand; 714 self->monsterinfo.scale = MODEL_SCALE; 715 716 walkmonster_start(self); 717 }