Quake-2

Quake 2 GPL Source Release
Log | Files | Refs

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 }