Quake II RTX doxygen  1.0 dev
m_flipper.c
Go to the documentation of this file.
1 /*
2 Copyright (C) 1997-2001 Id Software, Inc.
3 
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (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. See the
12 GNU General Public License for more details.
13 
14 You should have received a copy of the GNU General Public License along
15 with this program; if not, write to the Free Software Foundation, Inc.,
16 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18 /*
19 ==============================================================================
20 
21 FLIPPER
22 
23 ==============================================================================
24 */
25 
26 #include "g_local.h"
27 #include "m_flipper.h"
28 
29 
30 static int sound_chomp;
31 static int sound_attack;
32 static int sound_pain1;
33 static int sound_pain2;
34 static int sound_death;
35 static int sound_idle;
36 static int sound_search;
37 static int sound_sight;
38 
39 
40 void flipper_stand(edict_t *self);
41 
43  { ai_stand, 0, NULL }
44 };
45 
47 
48 void flipper_stand(edict_t *self)
49 {
50  self->monsterinfo.currentmove = &flipper_move_stand;
51 }
52 
53 #define FLIPPER_RUN_SPEED 24
54 
56  { ai_run, FLIPPER_RUN_SPEED, NULL }, // 6
57  { ai_run, FLIPPER_RUN_SPEED, NULL },
58  { ai_run, FLIPPER_RUN_SPEED, NULL },
59  { ai_run, FLIPPER_RUN_SPEED, NULL },
60  { ai_run, FLIPPER_RUN_SPEED, NULL }, // 10
61 
62  { ai_run, FLIPPER_RUN_SPEED, NULL },
63  { ai_run, FLIPPER_RUN_SPEED, NULL },
64  { ai_run, FLIPPER_RUN_SPEED, NULL },
65  { ai_run, FLIPPER_RUN_SPEED, NULL },
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 }, // 20
72 
73  { ai_run, FLIPPER_RUN_SPEED, NULL },
74  { ai_run, FLIPPER_RUN_SPEED, NULL },
75  { ai_run, FLIPPER_RUN_SPEED, NULL },
76  { ai_run, FLIPPER_RUN_SPEED, NULL },
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 } // 29
82 };
84 
85 void flipper_run_loop(edict_t *self)
86 {
87  self->monsterinfo.currentmove = &flipper_move_run_loop;
88 }
89 
91  { ai_run, 8, NULL },
92  { ai_run, 8, NULL },
93  { ai_run, 8, NULL },
94  { ai_run, 8, NULL },
95  { ai_run, 8, NULL },
96  { ai_run, 8, NULL }
97 };
99 
100 void flipper_run(edict_t *self)
101 {
102  self->monsterinfo.currentmove = &flipper_move_run_start;
103 }
104 
105 /* Standard Swimming */
107  { ai_walk, 4, NULL },
108  { ai_walk, 4, NULL },
109  { ai_walk, 4, NULL },
110  { ai_walk, 4, NULL },
111  { ai_walk, 4, NULL },
112  { ai_walk, 4, NULL },
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 };
133 
134 void flipper_walk(edict_t *self)
135 {
136  self->monsterinfo.currentmove = &flipper_move_walk;
137 }
138 
140  { ai_run, 8, NULL },
141  { ai_run, 8, NULL },
142  { ai_run, 8, NULL },
143  { ai_run, 8, NULL },
144  { ai_run, 8, flipper_run }
145 };
147 
148 void flipper_start_run(edict_t *self)
149 {
150  self->monsterinfo.currentmove = &flipper_move_start_run;
151 }
152 
154  { ai_move, 0, NULL },
155  { ai_move, 0, NULL },
156  { ai_move, 0, NULL },
157  { ai_move, 0, NULL },
158  { ai_move, 0, NULL }
159 };
161 
163  { ai_move, 0, NULL },
164  { ai_move, 0, NULL },
165  { ai_move, 0, NULL },
166  { ai_move, 0, NULL },
167  { ai_move, 0, NULL }
168 };
170 
171 void flipper_bite(edict_t *self)
172 {
173  vec3_t aim;
174 
175  VectorSet(aim, MELEE_DISTANCE, 0, 0);
176  fire_hit(self, aim, 5, 0);
177 }
178 
179 void flipper_preattack(edict_t *self)
180 {
181  gi.sound(self, CHAN_WEAPON, sound_chomp, 1, ATTN_NORM, 0);
182 }
183 
186  { ai_charge, 0, NULL },
187  { ai_charge, 0, NULL },
188  { ai_charge, 0, NULL },
189  { ai_charge, 0, NULL },
190  { ai_charge, 0, NULL },
191  { ai_charge, 0, NULL },
192  { ai_charge, 0, NULL },
193  { ai_charge, 0, NULL },
194  { ai_charge, 0, NULL },
195  { ai_charge, 0, NULL },
196  { ai_charge, 0, NULL },
197  { ai_charge, 0, NULL },
198  { ai_charge, 0, flipper_bite },
199  { ai_charge, 0, NULL },
200  { ai_charge, 0, NULL },
201  { ai_charge, 0, NULL },
202  { ai_charge, 0, NULL },
203  { ai_charge, 0, flipper_bite },
204  { ai_charge, 0, NULL }
205 };
207 
208 void flipper_melee(edict_t *self)
209 {
210  self->monsterinfo.currentmove = &flipper_move_attack;
211 }
212 
213 void flipper_pain(edict_t *self, edict_t *other, float kick, int damage)
214 {
215  int n;
216 
217  if (self->health < (self->max_health / 2))
218  self->s.skinnum = 1;
219 
220  if (level.time < self->pain_debounce_time)
221  return;
222 
223  self->pain_debounce_time = level.time + 3;
224 
225  if (skill->value == 3)
226  return; // no pain anims in nightmare
227 
228  n = (rand() + 1) % 2;
229  if (n == 0) {
230  gi.sound(self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0);
231  self->monsterinfo.currentmove = &flipper_move_pain1;
232  } else {
233  gi.sound(self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0);
234  self->monsterinfo.currentmove = &flipper_move_pain2;
235  }
236 }
237 
238 void flipper_dead(edict_t *self)
239 {
240  VectorSet(self->mins, -16, -16, -24);
241  VectorSet(self->maxs, 16, 16, -8);
242  self->movetype = MOVETYPE_TOSS;
243  self->svflags |= SVF_DEADMONSTER;
244  self->nextthink = 0;
245  gi.linkentity(self);
246 }
247 
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 
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  { ai_move, 0, NULL },
270 
271  { ai_move, 0, NULL },
272  { ai_move, 0, NULL },
273  { ai_move, 0, NULL },
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 
282  { ai_move, 0, NULL },
283  { ai_move, 0, NULL },
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 
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 
304  { ai_move, 0, NULL },
305  { ai_move, 0, NULL },
306  { ai_move, 0, NULL },
307  { ai_move, 0, NULL },
308  { ai_move, 0, NULL },
309  { ai_move, 0, NULL }
310 };
312 
313 void flipper_sight(edict_t *self, edict_t *other)
314 {
315  gi.sound(self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0);
316 }
317 
318 void flipper_die(edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
319 {
320  int n;
321 
322 // check for gib
323  if (self->health <= self->gib_health) {
324  gi.sound(self, CHAN_VOICE, gi.soundindex("misc/udeath.wav"), 1, ATTN_NORM, 0);
325  for (n = 0; n < 2; n++)
326  ThrowGib(self, "models/objects/gibs/bone/tris.md2", damage, GIB_ORGANIC);
327  for (n = 0; n < 2; n++)
328  ThrowGib(self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC);
329  ThrowHead(self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC);
330  self->deadflag = DEAD_DEAD;
331  return;
332  }
333 
334  if (self->deadflag == DEAD_DEAD)
335  return;
336 
337 // regular death
338  gi.sound(self, CHAN_VOICE, sound_death, 1, ATTN_NORM, 0);
339  self->deadflag = DEAD_DEAD;
340  self->takedamage = DAMAGE_YES;
341  self->monsterinfo.currentmove = &flipper_move_death;
342 }
343 
344 /*QUAKED monster_flipper (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight
345 */
346 void SP_monster_flipper(edict_t *self)
347 {
348  if (deathmatch->value) {
349  G_FreeEdict(self);
350  return;
351  }
352 
353  sound_pain1 = gi.soundindex("flipper/flppain1.wav");
354  sound_pain2 = gi.soundindex("flipper/flppain2.wav");
355  sound_death = gi.soundindex("flipper/flpdeth1.wav");
356  sound_chomp = gi.soundindex("flipper/flpatck1.wav");
357  sound_attack = gi.soundindex("flipper/flpatck2.wav");
358  sound_idle = gi.soundindex("flipper/flpidle1.wav");
359  sound_search = gi.soundindex("flipper/flpsrch1.wav");
360  sound_sight = gi.soundindex("flipper/flpsght1.wav");
361 
362  self->movetype = MOVETYPE_STEP;
363  self->solid = SOLID_BBOX;
364  self->s.modelindex = gi.modelindex("models/monsters/flipper/tris.md2");
365  VectorSet(self->mins, -16, -16, 0);
366  VectorSet(self->maxs, 16, 16, 32);
367 
368  self->health = 50;
369  self->gib_health = -30;
370  self->mass = 100;
371 
372  self->pain = flipper_pain;
373  self->die = flipper_die;
374 
375  self->monsterinfo.stand = flipper_stand;
376  self->monsterinfo.walk = flipper_walk;
377  self->monsterinfo.run = flipper_start_run;
378  self->monsterinfo.melee = flipper_melee;
379  self->monsterinfo.sight = flipper_sight;
380 
381  gi.linkentity(self);
382 
383  self->monsterinfo.currentmove = &flipper_move_stand;
384  self->monsterinfo.scale = MODEL_SCALE;
385 
386  swimmonster_start(self);
387 }
gi
game_import_t gi
Definition: g_main.c:23
sound_sight
static int sound_sight
Definition: m_flipper.c:37
flipper_move_run_loop
mmove_t flipper_move_run_loop
Definition: m_flipper.c:83
deathmatch
cvar_t * deathmatch
Definition: g_main.c:33
flipper_melee
void flipper_melee(edict_t *self)
Definition: m_flipper.c:208
sound_chomp
static int sound_chomp
Definition: m_flipper.c:30
DEAD_DEAD
#define DEAD_DEAD
Definition: g_local.h:112
flipper_frames_stand
mframe_t flipper_frames_stand[]
Definition: m_flipper.c:42
ThrowGib
void ThrowGib(edict_t *self, char *gibname, int damage, int type)
Definition: g_misc.c:130
MELEE_DISTANCE
#define MELEE_DISTANCE
Definition: g_local.h:82
flipper_frames_pain2
mframe_t flipper_frames_pain2[]
Definition: m_flipper.c:153
ai_charge
void ai_charge(edict_t *self, float dist)
Definition: g_ai.c:175
flipper_move_stand
mmove_t flipper_move_stand
Definition: m_flipper.c:46
flipper_stand
void flipper_stand(edict_t *self)
Definition: m_flipper.c:48
flipper_preattack
void flipper_preattack(edict_t *self)
Definition: m_flipper.c:179
flipper_frames_run
mframe_t flipper_frames_run[]
Definition: m_flipper.c:55
SP_monster_flipper
void SP_monster_flipper(edict_t *self)
Definition: m_flipper.c:346
flipper_move_walk
mmove_t flipper_move_walk
Definition: m_flipper.c:132
sound_idle
static int sound_idle
Definition: m_flipper.c:35
flipper_move_attack
mmove_t flipper_move_attack
Definition: m_flipper.c:206
flipper_walk
void flipper_walk(edict_t *self)
Definition: m_flipper.c:134
MODEL_SCALE
#define MODEL_SCALE
Definition: m_actor.h:504
DAMAGE_YES
@ DAMAGE_YES
Definition: g_local.h:88
FRAME_flppn205
#define FRAME_flppn205
Definition: m_flipper.h:125
flipper_move_death
mmove_t flipper_move_death
Definition: m_flipper.c:311
flipper_move_start_run
mmove_t flipper_move_start_run
Definition: m_flipper.c:146
FRAME_flphor05
#define FRAME_flphor05
Definition: m_flipper.h:67
FRAME_flphor01
#define FRAME_flphor01
Definition: m_flipper.h:63
fire_hit
qboolean fire_hit(edict_t *self, vec3_t aim, int damage, int kick)
Definition: g_weapon.c:59
other
@ other
Definition: ogg.c:63
sound_attack
static int sound_attack
Definition: m_flipper.c:31
MOVETYPE_STEP
@ MOVETYPE_STEP
Definition: g_local.h:192
flipper_start_run
void flipper_start_run(edict_t *self)
Definition: m_flipper.c:148
flipper_frames_attack
mframe_t flipper_frames_attack[]
Definition: m_flipper.c:184
FRAME_flpver06
#define FRAME_flpver06
Definition: m_flipper.h:92
flipper_move_pain2
mmove_t flipper_move_pain2
Definition: m_flipper.c:160
flipper_bite
void flipper_bite(edict_t *self)
Definition: m_flipper.c:171
flipper_frames_death
mframe_t flipper_frames_death[]
Definition: m_flipper.c:248
flipper_sight
void flipper_sight(edict_t *self, edict_t *other)
Definition: m_flipper.c:313
FRAME_flpdth01
#define FRAME_flpdth01
Definition: m_flipper.h:126
G_FreeEdict
void G_FreeEdict(edict_t *e)
Definition: g_utils.c:421
FRAME_flpdth56
#define FRAME_flpdth56
Definition: m_flipper.h:181
FRAME_flpbit01
#define FRAME_flpbit01
Definition: m_flipper.h:22
FRAME_flpbit20
#define FRAME_flpbit20
Definition: m_flipper.h:41
FRAME_flphor24
#define FRAME_flphor24
Definition: m_flipper.h:86
sound_pain1
static int sound_pain1
Definition: m_flipper.c:32
sound_search
static int sound_search
Definition: m_flipper.c:36
swimmonster_start
void swimmonster_start(edict_t *self)
Definition: g_monster.c:673
mframe_t
Definition: g_local.h:394
mmove_t
Definition: g_local.h:400
flipper_run_loop
void flipper_run_loop(edict_t *self)
Definition: m_flipper.c:85
FLIPPER_RUN_SPEED
#define FLIPPER_RUN_SPEED
Definition: m_flipper.c:53
ai_walk
void ai_walk(edict_t *self, float dist)
Definition: g_ai.c:148
flipper_frames_walk
mframe_t flipper_frames_walk[]
Definition: m_flipper.c:106
FRAME_flpver01
#define FRAME_flpver01
Definition: m_flipper.h:87
flipper_pain
void flipper_pain(edict_t *self, edict_t *other, float kick, int damage)
Definition: m_flipper.c:213
flipper_die
void flipper_die(edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
Definition: m_flipper.c:318
skill
cvar_t * skill
Definition: g_main.c:36
FRAME_flppn201
#define FRAME_flppn201
Definition: m_flipper.h:121
ai_move
void ai_move(edict_t *self, float dist)
Definition: g_ai.c:86
level_locals_t::time
float time
Definition: g_local.h:299
FRAME_flppn101
#define FRAME_flppn101
Definition: m_flipper.h:116
flipper_frames_start_run
mframe_t flipper_frames_start_run[]
Definition: m_flipper.c:139
FRAME_flppn105
#define FRAME_flppn105
Definition: m_flipper.h:120
FRAME_flpver29
#define FRAME_flpver29
Definition: m_flipper.h:115
ai_run
void ai_run(edict_t *self, float dist)
Definition: g_ai.c:821
flipper_move_run_start
mmove_t flipper_move_run_start
Definition: m_flipper.c:98
GIB_ORGANIC
#define GIB_ORGANIC
Definition: g_local.h:122
flipper_run
void flipper_run(edict_t *self)
Definition: m_flipper.c:100
level
level_locals_t level
Definition: g_main.c:22
sound_pain2
static int sound_pain2
Definition: m_flipper.c:33
flipper_move_pain1
mmove_t flipper_move_pain1
Definition: m_flipper.c:169
sound_death
static int sound_death
Definition: m_flipper.c:34
flipper_frames_pain1
mframe_t flipper_frames_pain1[]
Definition: m_flipper.c:162
ThrowHead
void ThrowHead(edict_t *self, char *gibname, int damage, int type)
Definition: g_misc.c:175
MOVETYPE_TOSS
@ MOVETYPE_TOSS
Definition: g_local.h:194
flipper_frames_run_start
mframe_t flipper_frames_run_start[]
Definition: m_flipper.c:90
flipper_dead
void flipper_dead(edict_t *self)
Definition: m_flipper.c:238
m_flipper.h
ai_stand
void ai_stand(edict_t *self, float dist)
Definition: g_ai.c:100
g_local.h