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