Quake II RTX doxygen  1.0 dev
m_gladiator.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 GLADIATOR
22 
23 ==============================================================================
24 */
25 
26 #include "g_local.h"
27 #include "m_gladiator.h"
28 
29 
30 static int sound_pain1;
31 static int sound_pain2;
32 static int sound_die;
33 static int sound_gun;
35 static int sound_cleaver_hit;
36 static int sound_cleaver_miss;
37 static int sound_idle;
38 static int sound_search;
39 static int sound_sight;
40 
41 
42 void gladiator_idle(edict_t *self)
43 {
44  gi.sound(self, CHAN_VOICE, sound_idle, 1, ATTN_IDLE, 0);
45 }
46 
47 void gladiator_sight(edict_t *self, edict_t *other)
48 {
49  gi.sound(self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0);
50 }
51 
52 void gladiator_search(edict_t *self)
53 {
54  gi.sound(self, CHAN_VOICE, sound_search, 1, ATTN_NORM, 0);
55 }
56 
57 void gladiator_cleaver_swing(edict_t *self)
58 {
59  gi.sound(self, CHAN_WEAPON, sound_cleaver_swing, 1, ATTN_NORM, 0);
60 }
61 
63  { ai_stand, 0, NULL },
64  { ai_stand, 0, NULL },
65  { ai_stand, 0, NULL },
66  { ai_stand, 0, NULL },
67  { ai_stand, 0, NULL },
68  { ai_stand, 0, NULL },
69  { ai_stand, 0, NULL }
70 };
72 
73 void gladiator_stand(edict_t *self)
74 {
75  self->monsterinfo.currentmove = &gladiator_move_stand;
76 }
77 
78 
80  { ai_walk, 15, NULL },
81  { ai_walk, 7, NULL },
82  { ai_walk, 6, NULL },
83  { ai_walk, 5, NULL },
84  { ai_walk, 2, NULL },
85  { ai_walk, 0, NULL },
86  { ai_walk, 2, NULL },
87  { ai_walk, 8, NULL },
88  { ai_walk, 12, NULL },
89  { ai_walk, 8, NULL },
90  { ai_walk, 5, NULL },
91  { ai_walk, 5, NULL },
92  { ai_walk, 2, NULL },
93  { ai_walk, 2, NULL },
94  { ai_walk, 1, NULL },
95  { ai_walk, 8, NULL }
96 };
98 
99 void gladiator_walk(edict_t *self)
100 {
101  self->monsterinfo.currentmove = &gladiator_move_walk;
102 }
103 
104 
106  { ai_run, 23, NULL },
107  { ai_run, 14, NULL },
108  { ai_run, 14, NULL },
109  { ai_run, 21, NULL },
110  { ai_run, 12, NULL },
111  { ai_run, 13, NULL }
112 };
114 
115 void gladiator_run(edict_t *self)
116 {
117  if (self->monsterinfo.aiflags & AI_STAND_GROUND)
118  self->monsterinfo.currentmove = &gladiator_move_stand;
119  else
120  self->monsterinfo.currentmove = &gladiator_move_run;
121 }
122 
123 
124 void GaldiatorMelee(edict_t *self)
125 {
126  vec3_t aim;
127 
128  VectorSet(aim, MELEE_DISTANCE, self->mins[0], -4);
129  if (fire_hit(self, aim, (20 + (rand() % 5)), 300))
130  gi.sound(self, CHAN_AUTO, sound_cleaver_hit, 1, ATTN_NORM, 0);
131  else
132  gi.sound(self, CHAN_AUTO, sound_cleaver_miss, 1, ATTN_NORM, 0);
133 }
134 
136  { ai_charge, 0, NULL },
137  { ai_charge, 0, NULL },
138  { ai_charge, 0, NULL },
139  { ai_charge, 0, NULL },
141  { ai_charge, 0, NULL },
142  { ai_charge, 0, GaldiatorMelee },
143  { ai_charge, 0, NULL },
144  { ai_charge, 0, NULL },
145  { ai_charge, 0, NULL },
147  { ai_charge, 0, NULL },
148  { ai_charge, 0, NULL },
149  { ai_charge, 0, GaldiatorMelee },
150  { ai_charge, 0, NULL },
151  { ai_charge, 0, NULL },
152  { ai_charge, 0, NULL }
153 };
155 
156 void gladiator_melee(edict_t *self)
157 {
158  self->monsterinfo.currentmove = &gladiator_move_attack_melee;
159 }
160 
161 
162 void GladiatorGun(edict_t *self)
163 {
164  vec3_t start;
165  vec3_t dir;
166  vec3_t forward, right;
167 
168  AngleVectors(self->s.angles, forward, right, NULL);
169  G_ProjectSource(self->s.origin, monster_flash_offset[MZ2_GLADIATOR_RAILGUN_1], forward, right, start);
170 
171  // calc direction to where we targted
172  VectorSubtract(self->pos1, start, dir);
173  VectorNormalize(dir);
174 
175  monster_fire_railgun(self, start, dir, 50, 100, MZ2_GLADIATOR_RAILGUN_1);
176 }
177 
179  { ai_charge, 0, NULL },
180  { ai_charge, 0, NULL },
181  { ai_charge, 0, NULL },
182  { ai_charge, 0, GladiatorGun },
183  { ai_charge, 0, NULL },
184  { ai_charge, 0, NULL },
185  { ai_charge, 0, NULL },
186  { ai_charge, 0, NULL },
187  { ai_charge, 0, NULL }
188 };
190 
191 void gladiator_attack(edict_t *self)
192 {
193  float range;
194  vec3_t v;
195 
196  // a small safe zone
197  VectorSubtract(self->s.origin, self->enemy->s.origin, v);
198  range = VectorLength(v);
199  if (range <= (MELEE_DISTANCE + 32))
200  return;
201 
202  // charge up the railgun
203  gi.sound(self, CHAN_WEAPON, sound_gun, 1, ATTN_NORM, 0);
204  VectorCopy(self->enemy->s.origin, self->pos1); //save for aiming the shot
205  self->pos1[2] += self->enemy->viewheight;
206  self->monsterinfo.currentmove = &gladiator_move_attack_gun;
207 }
208 
209 
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 };
219 
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 };
230 
231 void gladiator_pain(edict_t *self, edict_t *other, float kick, int damage)
232 {
233 
234  if (self->health < (self->max_health / 2))
235  self->s.skinnum = 1;
236 
237  if (level.time < self->pain_debounce_time) {
238  if ((self->velocity[2] > 100) && (self->monsterinfo.currentmove == &gladiator_move_pain))
239  self->monsterinfo.currentmove = &gladiator_move_pain_air;
240  return;
241  }
242 
243  self->pain_debounce_time = level.time + 3;
244 
245  if (random() < 0.5)
246  gi.sound(self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0);
247  else
248  gi.sound(self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0);
249 
250  if (skill->value == 3)
251  return; // no pain anims in nightmare
252 
253  if (self->velocity[2] > 100)
254  self->monsterinfo.currentmove = &gladiator_move_pain_air;
255  else
256  self->monsterinfo.currentmove = &gladiator_move_pain;
257 
258 }
259 
260 
261 void gladiator_dead(edict_t *self)
262 {
263  VectorSet(self->mins, -16, -16, -24);
264  VectorSet(self->maxs, 16, 16, -8);
265  self->movetype = MOVETYPE_TOSS;
266  self->svflags |= SVF_DEADMONSTER;
267  self->nextthink = 0;
268  gi.linkentity(self);
269 }
270 
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  { ai_move, 0, NULL },
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  { ai_move, 0, NULL },
293  { ai_move, 0, NULL }
294 };
296 
297 void gladiator_die(edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
298 {
299  int n;
300 
301 // check for gib
302  if (self->health <= self->gib_health) {
303  gi.sound(self, CHAN_VOICE, gi.soundindex("misc/udeath.wav"), 1, ATTN_NORM, 0);
304  for (n = 0; n < 2; n++)
305  ThrowGib(self, "models/objects/gibs/bone/tris.md2", damage, GIB_ORGANIC);
306  for (n = 0; n < 4; n++)
307  ThrowGib(self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC);
308  ThrowHead(self, "models/objects/gibs/head2/tris.md2", damage, GIB_ORGANIC);
309  self->deadflag = DEAD_DEAD;
310  return;
311  }
312 
313  if (self->deadflag == DEAD_DEAD)
314  return;
315 
316 // regular death
317  gi.sound(self, CHAN_VOICE, sound_die, 1, ATTN_NORM, 0);
318  self->deadflag = DEAD_DEAD;
319  self->takedamage = DAMAGE_YES;
320 
321  self->monsterinfo.currentmove = &gladiator_move_death;
322 }
323 
324 
325 /*QUAKED monster_gladiator (1 .5 0) (-32 -32 -24) (32 32 64) Ambush Trigger_Spawn Sight
326 */
327 void SP_monster_gladiator(edict_t *self)
328 {
329  if (deathmatch->value) {
330  G_FreeEdict(self);
331  return;
332  }
333 
334 
335  sound_pain1 = gi.soundindex("gladiator/pain.wav");
336  sound_pain2 = gi.soundindex("gladiator/gldpain2.wav");
337  sound_die = gi.soundindex("gladiator/glddeth2.wav");
338  sound_gun = gi.soundindex("gladiator/railgun.wav");
339  sound_cleaver_swing = gi.soundindex("gladiator/melee1.wav");
340  sound_cleaver_hit = gi.soundindex("gladiator/melee2.wav");
341  sound_cleaver_miss = gi.soundindex("gladiator/melee3.wav");
342  sound_idle = gi.soundindex("gladiator/gldidle1.wav");
343  sound_search = gi.soundindex("gladiator/gldsrch1.wav");
344  sound_sight = gi.soundindex("gladiator/sight.wav");
345 
346  self->movetype = MOVETYPE_STEP;
347  self->solid = SOLID_BBOX;
348  self->s.modelindex = gi.modelindex("models/monsters/gladiatr/tris.md2");
349  VectorSet(self->mins, -32, -32, -24);
350  VectorSet(self->maxs, 32, 32, 64);
351 
352  self->health = 400;
353  self->gib_health = -175;
354  self->mass = 400;
355 
356  self->pain = gladiator_pain;
357  self->die = gladiator_die;
358 
359  self->monsterinfo.stand = gladiator_stand;
360  self->monsterinfo.walk = gladiator_walk;
361  self->monsterinfo.run = gladiator_run;
362  self->monsterinfo.dodge = NULL;
363  self->monsterinfo.attack = gladiator_attack;
364  self->monsterinfo.melee = gladiator_melee;
365  self->monsterinfo.sight = gladiator_sight;
366  self->monsterinfo.idle = gladiator_idle;
367  self->monsterinfo.search = gladiator_search;
368 
369  gi.linkentity(self);
370  self->monsterinfo.currentmove = &gladiator_move_stand;
371  self->monsterinfo.scale = MODEL_SCALE;
372 
373  walkmonster_start(self);
374 }
gi
game_import_t gi
Definition: g_main.c:23
gladiator_die
void gladiator_die(edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
Definition: m_gladiator.c:297
gladiator_melee
void gladiator_melee(edict_t *self)
Definition: m_gladiator.c:156
FRAME_melee17
#define FRAME_melee17
Definition: m_gladiator.h:67
deathmatch
cvar_t * deathmatch
Definition: g_main.c:33
G_ProjectSource
void G_ProjectSource(const vec3_t point, const vec3_t distance, const vec3_t forward, const vec3_t right, vec3_t result)
Definition: g_utils.c:23
monster_fire_railgun
void monster_fire_railgun(edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick, int flashtype)
Definition: g_monster.c:79
DEAD_DEAD
#define DEAD_DEAD
Definition: g_local.h:112
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
FRAME_attack1
#define FRAME_attack1
Definition: m_boss2.h:92
gladiator_cleaver_swing
void gladiator_cleaver_swing(edict_t *self)
Definition: m_gladiator.c:57
ai_charge
void ai_charge(edict_t *self, float dist)
Definition: g_ai.c:175
FRAME_run6
#define FRAME_run6
Definition: m_berserk.h:63
FRAME_walk16
#define FRAME_walk16
Definition: m_boss2.h:87
gladiator_frames_pain
mframe_t gladiator_frames_pain[]
Definition: m_gladiator.c:210
gladiator_move_pain
mmove_t gladiator_move_pain
Definition: m_gladiator.c:218
sound_gun
static int sound_gun
Definition: m_gladiator.c:33
FRAME_pain1
#define FRAME_pain1
Definition: m_gladiator.h:77
AI_STAND_GROUND
#define AI_STAND_GROUND
Definition: g_local.h:126
sound_idle
static int sound_idle
Definition: m_gladiator.c:37
MODEL_SCALE
#define MODEL_SCALE
Definition: m_actor.h:504
DAMAGE_YES
@ DAMAGE_YES
Definition: g_local.h:88
gladiator_frames_walk
mframe_t gladiator_frames_walk[]
Definition: m_gladiator.c:79
sound_pain2
static int sound_pain2
Definition: m_gladiator.c:31
gladiator_sight
void gladiator_sight(edict_t *self, edict_t *other)
Definition: m_gladiator.c:47
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
walkmonster_start
void walkmonster_start(edict_t *self)
Definition: g_monster.c:630
MOVETYPE_STEP
@ MOVETYPE_STEP
Definition: g_local.h:192
FRAME_melee1
#define FRAME_melee1
Definition: m_gladiator.h:51
gladiator_move_attack_gun
mmove_t gladiator_move_attack_gun
Definition: m_gladiator.c:189
gladiator_move_pain_air
mmove_t gladiator_move_pain_air
Definition: m_gladiator.c:229
gladiator_pain
void gladiator_pain(edict_t *self, edict_t *other, float kick, int damage)
Definition: m_gladiator.c:231
FRAME_stand7
#define FRAME_stand7
Definition: m_boss2.h:49
FRAME_death1
#define FRAME_death1
Definition: m_berserk.h:245
sound_cleaver_swing
static int sound_cleaver_swing
Definition: m_gladiator.c:34
G_FreeEdict
void G_FreeEdict(edict_t *e)
Definition: g_utils.c:421
m_gladiator.h
gladiator_frames_stand
mframe_t gladiator_frames_stand[]
Definition: m_gladiator.c:62
FRAME_pain6
#define FRAME_pain6
Definition: m_boss2.h:136
gladiator_search
void gladiator_search(edict_t *self)
Definition: m_gladiator.c:52
sound_sight
static int sound_sight
Definition: m_gladiator.c:39
sound_search
static int sound_search
Definition: m_gladiator.c:38
FRAME_painup7
#define FRAME_painup7
Definition: m_gladiator.h:111
forward
static vec3_t forward
Definition: p_view.c:27
gladiator_attack
void gladiator_attack(edict_t *self)
Definition: m_gladiator.c:191
mframe_t
Definition: g_local.h:394
mmove_t
Definition: g_local.h:400
gladiator_idle
void gladiator_idle(edict_t *self)
Definition: m_gladiator.c:42
SP_monster_gladiator
void SP_monster_gladiator(edict_t *self)
Definition: m_gladiator.c:327
ai_walk
void ai_walk(edict_t *self, float dist)
Definition: g_ai.c:148
FRAME_attack9
#define FRAME_attack9
Definition: m_boss2.h:100
random
#define random()
Definition: g_local.h:504
AngleVectors
void AngleVectors(vec3_t angles, vec3_t forward, vec3_t right, vec3_t up)
Definition: shared.c:23
FRAME_stand1
#define FRAME_stand1
Definition: m_berserk.h:22
gladiator_dead
void gladiator_dead(edict_t *self)
Definition: m_gladiator.c:261
gladiator_move_stand
mmove_t gladiator_move_stand
Definition: m_gladiator.c:71
FRAME_death22
#define FRAME_death22
Definition: m_boss2.h:174
GaldiatorMelee
void GaldiatorMelee(edict_t *self)
Definition: m_gladiator.c:124
gladiator_move_run
mmove_t gladiator_move_run
Definition: m_gladiator.c:113
skill
cvar_t * skill
Definition: g_main.c:36
gladiator_move_walk
mmove_t gladiator_move_walk
Definition: m_gladiator.c:97
GladiatorGun
void GladiatorGun(edict_t *self)
Definition: m_gladiator.c:162
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_walk1
#define FRAME_walk1
Definition: m_boss2.h:72
gladiator_move_attack_melee
mmove_t gladiator_move_attack_melee
Definition: m_gladiator.c:154
gladiator_frames_pain_air
mframe_t gladiator_frames_pain_air[]
Definition: m_gladiator.c:220
FRAME_painup1
#define FRAME_painup1
Definition: m_gladiator.h:105
gladiator_frames_death
mframe_t gladiator_frames_death[]
Definition: m_gladiator.c:271
right
static vec3_t right
Definition: p_view.c:27
ai_run
void ai_run(edict_t *self, float dist)
Definition: g_ai.c:821
GIB_ORGANIC
#define GIB_ORGANIC
Definition: g_local.h:122
FRAME_run1
#define FRAME_run1
Definition: m_berserk.h:58
level
level_locals_t level
Definition: g_main.c:22
monster_flash_offset
const vec3_t monster_flash_offset[256]
Definition: m_flash.c:25
gladiator_walk
void gladiator_walk(edict_t *self)
Definition: m_gladiator.c:99
ThrowHead
void ThrowHead(edict_t *self, char *gibname, int damage, int type)
Definition: g_misc.c:175
gladiator_frames_attack_melee
mframe_t gladiator_frames_attack_melee[]
Definition: m_gladiator.c:135
sound_cleaver_hit
static int sound_cleaver_hit
Definition: m_gladiator.c:35
MOVETYPE_TOSS
@ MOVETYPE_TOSS
Definition: g_local.h:194
range
int range(edict_t *self, edict_t *other)
Definition: g_ai.c:245
gladiator_frames_attack_gun
mframe_t gladiator_frames_attack_gun[]
Definition: m_gladiator.c:178
gladiator_stand
void gladiator_stand(edict_t *self)
Definition: m_gladiator.c:73
sound_cleaver_miss
static int sound_cleaver_miss
Definition: m_gladiator.c:36
sound_die
static int sound_die
Definition: m_gladiator.c:32
sound_pain1
static int sound_pain1
Definition: m_gladiator.c:30
gladiator_run
void gladiator_run(edict_t *self)
Definition: m_gladiator.c:115
VectorNormalize
vec_t VectorNormalize(vec3_t v)
Definition: shared.c:55
gladiator_frames_run
mframe_t gladiator_frames_run[]
Definition: m_gladiator.c:105
ai_stand
void ai_stand(edict_t *self, float dist)
Definition: g_ai.c:100
gladiator_move_death
mmove_t gladiator_move_death
Definition: m_gladiator.c:295
g_local.h