1
2 /*
3 ==============================================================================
4
5 GLADIATOR BOSS
6
7 ==============================================================================
8 */
9
10 #include "g_local.h"
11 #include "m_gladiator.h"
12
13
14 static int sound_pain1;
15 static int sound_pain2;
16 static int sound_die;
17 static int sound_gun;
18 static int sound_cleaver_swing;
19 static int sound_cleaver_hit;
20 static int sound_cleaver_miss;
21 static int sound_idle;
22 static int sound_search;
23 static int sound_sight;
24
25
gladb_idle(edict_t * self)26 void gladb_idle (edict_t *self)
27 {
28 gi.sound (self, CHAN_VOICE, sound_idle, 1, ATTN_IDLE, 0);
29 }
30
gladb_sight(edict_t * self,edict_t * other)31 void gladb_sight (edict_t *self, edict_t *other)
32 {
33 gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0);
34 }
35
gladb_search(edict_t * self)36 void gladb_search (edict_t *self)
37 {
38 gi.sound (self, CHAN_VOICE, sound_search, 1, ATTN_NORM, 0);
39 }
40
gladb_cleaver_swing(edict_t * self)41 void gladb_cleaver_swing (edict_t *self)
42 {
43 gi.sound (self, CHAN_WEAPON, sound_cleaver_swing, 1, ATTN_NORM, 0);
44 }
45
46 mframe_t gladb_frames_stand [] =
47 {
48 ai_stand, 0, NULL,
49 ai_stand, 0, NULL,
50 ai_stand, 0, NULL,
51 ai_stand, 0, NULL,
52 ai_stand, 0, NULL,
53 ai_stand, 0, NULL,
54 ai_stand, 0, NULL
55 };
56 mmove_t gladb_move_stand = {FRAME_stand1, FRAME_stand7, gladb_frames_stand, NULL};
57
gladb_stand(edict_t * self)58 void gladb_stand (edict_t *self)
59 {
60 self->monsterinfo.currentmove = &gladb_move_stand;
61 }
62
63
64 mframe_t gladb_frames_walk [] =
65 {
66 ai_walk, 15, NULL,
67 ai_walk, 7, NULL,
68 ai_walk, 6, NULL,
69 ai_walk, 5, NULL,
70 ai_walk, 2, NULL,
71 ai_walk, 0, NULL,
72 ai_walk, 2, NULL,
73 ai_walk, 8, NULL,
74 ai_walk, 12, NULL,
75 ai_walk, 8, NULL,
76 ai_walk, 5, NULL,
77 ai_walk, 5, NULL,
78 ai_walk, 2, NULL,
79 ai_walk, 2, NULL,
80 ai_walk, 1, NULL,
81 ai_walk, 8, NULL
82 };
83 mmove_t gladb_move_walk = {FRAME_walk1, FRAME_walk16, gladb_frames_walk, NULL};
84
gladb_walk(edict_t * self)85 void gladb_walk (edict_t *self)
86 {
87 self->monsterinfo.currentmove = &gladb_move_walk;
88 }
89
90
91 mframe_t gladb_frames_run [] =
92 {
93 ai_run, 23, NULL,
94 ai_run, 14, NULL,
95 ai_run, 14, NULL,
96 ai_run, 21, NULL,
97 ai_run, 12, NULL,
98 ai_run, 13, NULL
99 };
100 mmove_t gladb_move_run = {FRAME_run1, FRAME_run6, gladb_frames_run, NULL};
101
gladb_run(edict_t * self)102 void gladb_run (edict_t *self)
103 {
104 if (self->monsterinfo.aiflags & AI_STAND_GROUND)
105 self->monsterinfo.currentmove = &gladb_move_stand;
106 else
107 self->monsterinfo.currentmove = &gladb_move_run;
108 }
109
110
GladbMelee(edict_t * self)111 void GladbMelee (edict_t *self)
112 {
113 vec3_t aim;
114
115 VectorSet (aim, MELEE_DISTANCE, self->mins[0], -4);
116 if (fire_hit (self, aim, (20 + (rand() %5)), 300))
117 gi.sound (self, CHAN_AUTO, sound_cleaver_hit, 1, ATTN_NORM, 0);
118 else
119 gi.sound (self, CHAN_AUTO, sound_cleaver_miss, 1, ATTN_NORM, 0);
120 }
121
122 mframe_t gladb_frames_attack_melee [] =
123 {
124 ai_charge, 0, NULL,
125 ai_charge, 0, NULL,
126 ai_charge, 0, NULL,
127 ai_charge, 0, NULL,
128 ai_charge, 0, gladb_cleaver_swing,
129 ai_charge, 0, NULL,
130 ai_charge, 0, GladbMelee,
131 ai_charge, 0, NULL,
132 ai_charge, 0, NULL,
133 ai_charge, 0, NULL,
134 ai_charge, 0, gladb_cleaver_swing,
135 ai_charge, 0, NULL,
136 ai_charge, 0, NULL,
137 ai_charge, 0, GladbMelee,
138 ai_charge, 0, NULL,
139 ai_charge, 0, NULL,
140 ai_charge, 0, NULL
141 };
142 mmove_t gladb_move_attack_melee = {FRAME_melee1, FRAME_melee17, gladb_frames_attack_melee, gladb_run};
143
gladb_melee(edict_t * self)144 void gladb_melee(edict_t *self)
145 {
146 self->monsterinfo.currentmove = &gladb_move_attack_melee;
147 }
148
149
gladbGun(edict_t * self)150 void gladbGun (edict_t *self)
151 {
152 vec3_t start;
153 vec3_t dir;
154 vec3_t forward, right;
155
156 AngleVectors (self->s.angles, forward, right, NULL);
157 G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_GLADIATOR_RAILGUN_1], forward, right, start);
158
159 // calc direction to where we targted
160 VectorSubtract (self->pos1, start, dir);
161 VectorNormalize (dir);
162
163 fire_plasma (self, start, dir, 100, 725, 60, 60);
164 }
165
gladbGun_check(edict_t * self)166 void gladbGun_check (edict_t *self)
167 {
168 if (skill->value == 3)
169 gladbGun (self);
170 }
171
172 mframe_t gladb_frames_attack_gun [] =
173 {
174 ai_charge, 0, NULL,
175 ai_charge, 0, NULL,
176 ai_charge, 0, gladbGun,
177 ai_charge, 0, NULL,
178 ai_charge, 0, NULL,
179 ai_charge, 0, gladbGun,
180 ai_charge, 0, NULL,
181 ai_charge, 0, NULL,
182 ai_charge, 0, gladbGun_check
183 };
184 mmove_t gladb_move_attack_gun = {FRAME_attack1, FRAME_attack9, gladb_frames_attack_gun, gladb_run};
185
gladb_attack(edict_t * self)186 void gladb_attack(edict_t *self)
187 {
188 float range;
189 vec3_t v;
190
191 // a small safe zone
192 VectorSubtract (self->s.origin, self->enemy->s.origin, v);
193 range = VectorLength(v);
194 if (range <= (MELEE_DISTANCE + 32))
195 return;
196
197 // charge up the railgun
198 gi.sound (self, CHAN_WEAPON, sound_gun, 1, ATTN_NORM, 0);
199 VectorCopy (self->enemy->s.origin, self->pos1); //save for aiming the shot
200 self->pos1[2] += self->enemy->viewheight;
201 self->monsterinfo.currentmove = &gladb_move_attack_gun;
202 }
203
204
205 mframe_t gladb_frames_pain [] =
206 {
207 ai_move, 0, NULL,
208 ai_move, 0, NULL,
209 ai_move, 0, NULL,
210 ai_move, 0, NULL,
211 ai_move, 0, NULL,
212 ai_move, 0, NULL
213 };
214 mmove_t gladb_move_pain = {FRAME_pain1, FRAME_pain6, gladb_frames_pain, gladb_run};
215
216 mframe_t gladb_frames_pain_air [] =
217 {
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 };
226 mmove_t gladb_move_pain_air = {FRAME_painup1, FRAME_painup7, gladb_frames_pain_air, gladb_run};
227
gladb_pain(edict_t * self,edict_t * other,float kick,int damage)228 void gladb_pain (edict_t *self, edict_t *other, float kick, int damage)
229 {
230
231 if (self->health < (self->max_health / 2))
232 self->s.skinnum = 1;
233
234 if (level.time < self->pain_debounce_time)
235 {
236 if ((self->velocity[2] > 100) && (self->monsterinfo.currentmove == &gladb_move_pain))
237 self->monsterinfo.currentmove = &gladb_move_pain_air;
238 return;
239 }
240
241 self->pain_debounce_time = level.time + 3;
242
243 if (random() < 0.5)
244 gi.sound (self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0);
245 else
246 gi.sound (self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0);
247
248 if (self->velocity[2] > 100)
249 self->monsterinfo.currentmove = &gladb_move_pain_air;
250 else
251 self->monsterinfo.currentmove = &gladb_move_pain;
252
253 }
254
255
gladb_dead(edict_t * self)256 void gladb_dead (edict_t *self)
257 {
258 VectorSet (self->mins, -16, -16, -24);
259 VectorSet (self->maxs, 16, 16, -8);
260 self->movetype = MOVETYPE_TOSS;
261 self->svflags |= SVF_DEADMONSTER;
262 self->nextthink = 0;
263 gi.linkentity (self);
264 }
265
266 mframe_t gladb_frames_death [] =
267 {
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 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 };
291 mmove_t gladb_move_death = {FRAME_death1, FRAME_death22, gladb_frames_death, gladb_dead};
292
gladb_die(edict_t * self,edict_t * inflictor,edict_t * attacker,int damage,vec3_t point)293 void gladb_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
294 {
295 int n;
296
297 // check for gib
298 if (self->health <= self->gib_health)
299 {
300 gi.sound (self, CHAN_VOICE, gi.soundindex ("misc/udeath.wav"), 1, ATTN_NORM, 0);
301 for (n= 0; n < 2; n++)
302 ThrowGib (self, "models/objects/gibs/bone/tris.md2", damage, GIB_ORGANIC);
303 for (n= 0; n < 4; n++)
304 ThrowGib (self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC);
305 ThrowHead (self, "models/objects/gibs/head2/tris.md2", damage, GIB_ORGANIC);
306 self->deadflag = DEAD_DEAD;
307 return;
308 }
309
310 if (self->deadflag == DEAD_DEAD)
311 return;
312
313 // regular death
314 gi.sound (self, CHAN_VOICE, sound_die, 1, ATTN_NORM, 0);
315 self->deadflag = DEAD_DEAD;
316 self->takedamage = DAMAGE_YES;
317
318 self->monsterinfo.currentmove = &gladb_move_death;
319 }
320
321
322 /*QUAKED monster_gladb (1 .5 0) (-32 -32 -24) (32 32 64) Ambush Trigger_Spawn Sight
323 */
SP_monster_gladb(edict_t * self)324 void SP_monster_gladb (edict_t *self)
325 {
326 if (deathmatch->value)
327 {
328 G_FreeEdict (self);
329 return;
330 }
331
332
333 sound_pain1 = gi.soundindex ("gladiator/pain.wav");
334 sound_pain2 = gi.soundindex ("gladiator/gldpain2.wav");
335 sound_die = gi.soundindex ("gladiator/glddeth2.wav");
336 // note to self
337 // need to change to PHALANX sound
338 sound_gun = gi.soundindex ("weapons/plasshot.wav");
339
340 sound_cleaver_swing = gi.soundindex ("gladiator/melee1.wav");
341 sound_cleaver_hit = gi.soundindex ("gladiator/melee2.wav");
342 sound_cleaver_miss = gi.soundindex ("gladiator/melee3.wav");
343 sound_idle = gi.soundindex ("gladiator/gldidle1.wav");
344 sound_search = gi.soundindex ("gladiator/gldsrch1.wav");
345 sound_sight = gi.soundindex ("gladiator/sight.wav");
346
347 self->movetype = MOVETYPE_STEP;
348 self->solid = SOLID_BBOX;
349 self->s.modelindex = gi.modelindex ("models/monsters/gladb/tris.md2");
350 VectorSet (self->mins, -32, -32, -24);
351 VectorSet (self->maxs, 32, 32, 64);
352
353 self->health = 800;
354 self->gib_health = -175;
355 self->mass = 350;
356
357 self->pain = gladb_pain;
358 self->die = gladb_die;
359
360 self->monsterinfo.stand = gladb_stand;
361 self->monsterinfo.walk = gladb_walk;
362 self->monsterinfo.run = gladb_run;
363 self->monsterinfo.dodge = NULL;
364 self->monsterinfo.attack = gladb_attack;
365 self->monsterinfo.melee = gladb_melee;
366 self->monsterinfo.sight = gladb_sight;
367 self->monsterinfo.idle = gladb_idle;
368 self->monsterinfo.search = gladb_search;
369
370 gi.linkentity (self);
371 self->monsterinfo.currentmove = &gladb_move_stand;
372 self->monsterinfo.scale = MODEL_SCALE;
373
374 self->monsterinfo.power_armor_type = POWER_ARMOR_SHIELD;
375 self->monsterinfo.power_armor_power = 400;
376
377
378 walkmonster_start (self);
379 }
380
381