Quake-2

Quake 2 GPL Source Release
Log | Files | Refs

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 }