1 /*
2 ==============================================================================
3 
4 hover
5 
6 ==============================================================================
7 */
8 
9 #include "g_local.h"
10 #include "m_hover.h"
11 
12 qboolean visible (edict_t *self, edict_t *other);
13 
14 
15 static int	sound_pain1;
16 static int	sound_pain2;
17 static int	sound_death1;
18 static int	sound_death2;
19 static int	sound_sight;
20 static int	sound_search1;
21 static int	sound_search2;
22 
23 // daedalus sounds
24 static int	daed_sound_pain1;
25 static int	daed_sound_pain2;
26 static int	daed_sound_death1;
27 static int	daed_sound_death2;
28 static int	daed_sound_sight;
29 static int	daed_sound_search1;
30 static int	daed_sound_search2;
31 
32 
hover_sight(edict_t * self,edict_t * other)33 void hover_sight (edict_t *self, edict_t *other)
34 {
35 	// PMM - daedalus sounds
36 	if (self->mass < 225)
37 		gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0);
38 	else
39 		gi.sound (self, CHAN_VOICE, daed_sound_sight, 1, ATTN_NORM, 0);
40 }
41 
hover_search(edict_t * self)42 void hover_search (edict_t *self)
43 {
44 	// PMM - daedalus sounds
45 	if (self->mass < 225)
46 	{
47 		if (random() < 0.5)
48 			gi.sound (self, CHAN_VOICE, sound_search1, 1, ATTN_NORM, 0);
49 		else
50 			gi.sound (self, CHAN_VOICE, sound_search2, 1, ATTN_NORM, 0);
51 	}
52 	else
53 	{
54 		if (random() < 0.5)
55 			gi.sound (self, CHAN_VOICE, daed_sound_search1, 1, ATTN_NORM, 0);
56 		else
57 			gi.sound (self, CHAN_VOICE, daed_sound_search2, 1, ATTN_NORM, 0);
58 	}
59 }
60 
61 
62 void hover_run (edict_t *self);
63 void hover_stand (edict_t *self);
64 void hover_dead (edict_t *self);
65 void hover_attack (edict_t *self);
66 void hover_reattack (edict_t *self);
67 void hover_fire_blaster (edict_t *self);
68 void hover_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point);
69 
70 mframe_t hover_frames_stand [] =
71 {
72 	ai_stand, 0, NULL,
73 	ai_stand, 0, NULL,
74 	ai_stand, 0, NULL,
75 	ai_stand, 0, NULL,
76 	ai_stand, 0, NULL,
77 	ai_stand, 0, NULL,
78 	ai_stand, 0, NULL,
79 	ai_stand, 0, NULL,
80 	ai_stand, 0, NULL,
81 	ai_stand, 0, NULL,
82 	ai_stand, 0, NULL,
83 	ai_stand, 0, NULL,
84 	ai_stand, 0, NULL,
85 	ai_stand, 0, NULL,
86 	ai_stand, 0, NULL,
87 	ai_stand, 0, NULL,
88 	ai_stand, 0, NULL,
89 	ai_stand, 0, NULL,
90 	ai_stand, 0, NULL,
91 	ai_stand, 0, NULL,
92 	ai_stand, 0, NULL,
93 	ai_stand, 0, NULL,
94 	ai_stand, 0, NULL,
95 	ai_stand, 0, NULL,
96 	ai_stand, 0, NULL,
97 	ai_stand, 0, NULL,
98 	ai_stand, 0, NULL,
99 	ai_stand, 0, NULL,
100 	ai_stand, 0, NULL,
101 	ai_stand, 0, NULL
102 };
103 mmove_t	hover_move_stand = {FRAME_stand01, FRAME_stand30, hover_frames_stand, NULL};
104 /*
105 mframe_t hover_frames_stop1 [] =
106 {
107 	ai_move,	0,	NULL,
108 	ai_move,	0,	NULL,
109 	ai_move,	0,	NULL,
110 	ai_move,	0,	NULL,
111 	ai_move,	0,	NULL,
112 	ai_move,	0,	NULL,
113 	ai_move,	0,	NULL,
114 	ai_move,	0,	NULL,
115 	ai_move,	0,	NULL
116 };
117 mmove_t hover_move_stop1 = {FRAME_stop101, FRAME_stop109, hover_frames_stop1, NULL};
118 
119 mframe_t hover_frames_stop2 [] =
120 {
121 	ai_move,	0,	NULL,
122 	ai_move,	0,	NULL,
123 	ai_move,	0,	NULL,
124 	ai_move,	0,	NULL,
125 	ai_move,	0,	NULL,
126 	ai_move,	0,	NULL,
127 	ai_move,	0,	NULL,
128 	ai_move,	0,	NULL
129 };
130 mmove_t hover_move_stop2 = {FRAME_stop201, FRAME_stop208, hover_frames_stop2, NULL};
131 */
132 /*
133 mframe_t hover_frames_takeoff [] =
134 {
135 	ai_move,	0,	NULL,
136 	ai_move,	-2,	NULL,
137 	ai_move,	5,	NULL,
138 	ai_move,	-1,	NULL,
139 	ai_move,	1,	NULL,
140 	ai_move,	0,	NULL,
141 	ai_move,	0,	NULL,
142 	ai_move,	-1,	NULL,
143 	ai_move,	-1,	NULL,
144 	ai_move,	-1,	NULL,
145 	ai_move,	0,	NULL,
146 	ai_move,	2,	NULL,
147 	ai_move,	2,	NULL,
148 	ai_move,	1,	NULL,
149 	ai_move,	1,	NULL,
150 	ai_move,	-6,	NULL,
151 	ai_move,	-9,	NULL,
152 	ai_move,	1,	NULL,
153 	ai_move,	0,	NULL,
154 	ai_move,	2,	NULL,
155 	ai_move,	2,	NULL,
156 	ai_move,	1,	NULL,
157 	ai_move,	1,	NULL,
158 	ai_move,	1,	NULL,
159 	ai_move,	2,	NULL,
160 	ai_move,	0,	NULL,
161 	ai_move,	2,	NULL,
162 	ai_move,	3,	NULL,
163 	ai_move,	2,	NULL,
164 	ai_move,	0,	NULL
165 };
166 mmove_t hover_move_takeoff = {FRAME_takeof01, FRAME_takeof30, hover_frames_takeoff, NULL};
167 */
168 mframe_t hover_frames_pain3 [] =
169 {
170 	ai_move,	0,	NULL,
171 	ai_move,	0,	NULL,
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 	ai_move,	0,	NULL,
178 	ai_move,	0,	NULL
179 };
180 mmove_t hover_move_pain3 = {FRAME_pain301, FRAME_pain309, hover_frames_pain3, hover_run};
181 
182 mframe_t hover_frames_pain2 [] =
183 {
184 	ai_move,	0,	NULL,
185 	ai_move,	0,	NULL,
186 	ai_move,	0,	NULL,
187 	ai_move,	0,	NULL,
188 	ai_move,	0,	NULL,
189 	ai_move,	0,	NULL,
190 	ai_move,	0,	NULL,
191 	ai_move,	0,	NULL,
192 	ai_move,	0,	NULL,
193 	ai_move,	0,	NULL,
194 	ai_move,	0,	NULL,
195 	ai_move,	0,	NULL
196 };
197 mmove_t hover_move_pain2 = {FRAME_pain201, FRAME_pain212, hover_frames_pain2, hover_run};
198 
199 mframe_t hover_frames_pain1 [] =
200 {
201 	ai_move,	0,	NULL,
202 	ai_move,	0,	NULL,
203 	ai_move,	2,	NULL,
204 	ai_move,	-8,	NULL,
205 	ai_move,	-4,	NULL,
206 	ai_move,	-6,	NULL,
207 	ai_move,	-4,	NULL,
208 	ai_move,	-3,	NULL,
209 	ai_move,	1,	NULL,
210 	ai_move,	0,	NULL,
211 	ai_move,	0,	NULL,
212 	ai_move,	0,	NULL,
213 	ai_move,	3,	NULL,
214 	ai_move,	1,	NULL,
215 	ai_move,	0,	NULL,
216 	ai_move,	2,	NULL,
217 	ai_move,	3,	NULL,
218 	ai_move,	2,	NULL,
219 	ai_move,	7,	NULL,
220 	ai_move,	1,	NULL,
221 	ai_move,	0,	NULL,
222 	ai_move,	0,	NULL,
223 	ai_move,	2,	NULL,
224 	ai_move,	0,	NULL,
225 	ai_move,	0,	NULL,
226 	ai_move,	5,	NULL,
227 	ai_move,	3,	NULL,
228 	ai_move,	4,	NULL
229 };
230 mmove_t hover_move_pain1 = {FRAME_pain101, FRAME_pain128, hover_frames_pain1, hover_run};
231 
232 /*
233 mframe_t hover_frames_land [] =
234 {
235 	ai_move,	0,	NULL
236 };
237 mmove_t hover_move_land = {FRAME_land01, FRAME_land01, hover_frames_land, NULL};
238 */
239 /*
240 mframe_t hover_frames_forward [] =
241 {
242 	ai_move,	0,	NULL,
243 	ai_move,	0,	NULL,
244 	ai_move,	0,	NULL,
245 	ai_move,	0,	NULL,
246 	ai_move,	0,	NULL,
247 	ai_move,	0,	NULL,
248 	ai_move,	0,	NULL,
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 	ai_move,	0,	NULL,
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 	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 };
278 mmove_t hover_move_forward = {FRAME_forwrd01, FRAME_forwrd35, hover_frames_forward, NULL};
279 */
280 mframe_t hover_frames_walk [] =
281 {
282 	ai_walk,	4,	NULL,
283 	ai_walk,	4,	NULL,
284 	ai_walk,	4,	NULL,
285 	ai_walk,	4,	NULL,
286 	ai_walk,	4,	NULL,
287 	ai_walk,	4,	NULL,
288 	ai_walk,	4,	NULL,
289 	ai_walk,	4,	NULL,
290 	ai_walk,	4,	NULL,
291 	ai_walk,	4,	NULL,
292 	ai_walk,	4,	NULL,
293 	ai_walk,	4,	NULL,
294 	ai_walk,	4,	NULL,
295 	ai_walk,	4,	NULL,
296 	ai_walk,	4,	NULL,
297 	ai_walk,	4,	NULL,
298 	ai_walk,	4,	NULL,
299 	ai_walk,	4,	NULL,
300 	ai_walk,	4,	NULL,
301 	ai_walk,	4,	NULL,
302 	ai_walk,	4,	NULL,
303 	ai_walk,	4,	NULL,
304 	ai_walk,	4,	NULL,
305 	ai_walk,	4,	NULL,
306 	ai_walk,	4,	NULL,
307 	ai_walk,	4,	NULL,
308 	ai_walk,	4,	NULL,
309 	ai_walk,	4,	NULL,
310 	ai_walk,	4,	NULL,
311 	ai_walk,	4,	NULL,
312 	ai_walk,	4,	NULL,
313 	ai_walk,	4,	NULL,
314 	ai_walk,	4,	NULL,
315 	ai_walk,	4,	NULL,
316 	ai_walk,	4,	NULL
317 };
318 mmove_t hover_move_walk = {FRAME_forwrd01, FRAME_forwrd35, hover_frames_walk, NULL};
319 
320 mframe_t hover_frames_run [] =
321 {
322 	ai_run,	10,	NULL,
323 	ai_run,	10,	NULL,
324 	ai_run,	10,	NULL,
325 	ai_run,	10,	NULL,
326 	ai_run,	10,	NULL,
327 	ai_run,	10,	NULL,
328 	ai_run,	10,	NULL,
329 	ai_run,	10,	NULL,
330 	ai_run,	10,	NULL,
331 	ai_run,	10,	NULL,
332 	ai_run,	10,	NULL,
333 	ai_run,	10,	NULL,
334 	ai_run,	10,	NULL,
335 	ai_run,	10,	NULL,
336 	ai_run,	10,	NULL,
337 	ai_run,	10,	NULL,
338 	ai_run,	10,	NULL,
339 	ai_run,	10,	NULL,
340 	ai_run,	10,	NULL,
341 	ai_run,	10,	NULL,
342 	ai_run,	10,	NULL,
343 	ai_run,	10,	NULL,
344 	ai_run,	10,	NULL,
345 	ai_run,	10,	NULL,
346 	ai_run,	10,	NULL,
347 	ai_run,	10,	NULL,
348 	ai_run,	10,	NULL,
349 	ai_run,	10,	NULL,
350 	ai_run,	10,	NULL,
351 	ai_run,	10,	NULL,
352 	ai_run,	10,	NULL,
353 	ai_run,	10,	NULL,
354 	ai_run,	10,	NULL,
355 	ai_run,	10,	NULL,
356 	ai_run,	10,	NULL
357 };
358 mmove_t hover_move_run = {FRAME_forwrd01, FRAME_forwrd35, hover_frames_run, NULL};
359 
360 mframe_t hover_frames_death1 [] =
361 {
362 	ai_move,	0,	NULL,
363 	ai_move,	0,	NULL,
364 	ai_move,	0,	NULL,
365 	ai_move,	0,	NULL,
366 	ai_move,	0,	NULL,
367 	ai_move,	0,	NULL,
368 	ai_move,	-10,NULL,
369 	ai_move,	3,	NULL,
370 	ai_move,	5,	NULL,
371 	ai_move,	4,	NULL,
372 	ai_move,	7,	NULL
373 };
374 mmove_t hover_move_death1 = {FRAME_death101, FRAME_death111, hover_frames_death1, hover_dead};
375 /*
376 mframe_t hover_frames_backward [] =
377 {
378 	ai_move,	0,	NULL,
379 	ai_move,	0,	NULL,
380 	ai_move,	0,	NULL,
381 	ai_move,	0,	NULL,
382 	ai_move,	0,	NULL,
383 	ai_move,	0,	NULL,
384 	ai_move,	0,	NULL,
385 	ai_move,	0,	NULL,
386 	ai_move,	0,	NULL,
387 	ai_move,	0,	NULL,
388 	ai_move,	0,	NULL,
389 	ai_move,	0,	NULL,
390 	ai_move,	0,	NULL,
391 	ai_move,	0,	NULL,
392 	ai_move,	0,	NULL,
393 	ai_move,	0,	NULL,
394 	ai_move,	0,	NULL,
395 	ai_move,	0,	NULL,
396 	ai_move,	0,	NULL,
397 	ai_move,	0,	NULL,
398 	ai_move,	0,	NULL,
399 	ai_move,	0,	NULL,
400 	ai_move,	0,	NULL,
401 	ai_move,	0,	NULL
402 };
403 mmove_t hover_move_backward = {FRAME_backwd01, FRAME_backwd24, hover_frames_backward, NULL};
404 */
405 mframe_t hover_frames_start_attack [] =
406 {
407 	ai_charge,	1,	NULL,
408 	ai_charge,	1,	NULL,
409 	ai_charge,	1,	NULL
410 };
411 mmove_t hover_move_start_attack = {FRAME_attak101, FRAME_attak103, hover_frames_start_attack, hover_attack};
412 
413 mframe_t hover_frames_attack1 [] =
414 {
415 	ai_charge,	-10,	hover_fire_blaster,
416 	ai_charge,	-10,	hover_fire_blaster,
417 	ai_charge,	0,		hover_reattack,
418 };
419 mmove_t hover_move_attack1 = {FRAME_attak104, FRAME_attak106, hover_frames_attack1, NULL};
420 
421 
422 mframe_t hover_frames_end_attack [] =
423 {
424 	ai_charge,	1,	NULL,
425 	ai_charge,	1,	NULL
426 };
427 mmove_t hover_move_end_attack = {FRAME_attak107, FRAME_attak108, hover_frames_end_attack, hover_run};
428 
429 /* PMM - circle strafing code */
430 
431 mframe_t hover_frames_start_attack2 [] =
432 {
433 	ai_charge,	15,	NULL,
434 	ai_charge,	15,	NULL,
435 	ai_charge,	15,	NULL
436 };
437 mmove_t hover_move_start_attack2 = {FRAME_attak101, FRAME_attak103, hover_frames_start_attack2, hover_attack};
438 
439 mframe_t hover_frames_attack2 [] =
440 {
441 	ai_charge,	10,	hover_fire_blaster,
442 	ai_charge,	10,	hover_fire_blaster,
443 	ai_charge,	10,		hover_reattack,
444 };
445 mmove_t hover_move_attack2 = {FRAME_attak104, FRAME_attak106, hover_frames_attack2, NULL};
446 
447 
448 mframe_t hover_frames_end_attack2 [] =
449 {
450 	ai_charge,	15,	NULL,
451 	ai_charge,	15,	NULL
452 };
453 mmove_t hover_move_end_attack2 = {FRAME_attak107, FRAME_attak108, hover_frames_end_attack2, hover_run};
454 
455 // end of circle strafe
456 
457 
hover_reattack(edict_t * self)458 void hover_reattack (edict_t *self)
459 {
460 	if (self->enemy->health > 0 )
461 		if (visible (self, self->enemy) )
462 			if (random() <= 0.6)
463 			{
464 				if (self->monsterinfo.attack_state == AS_STRAIGHT)
465 				{
466 					self->monsterinfo.currentmove = &hover_move_attack1;
467 					return;
468 				}
469 				else if (self->monsterinfo.attack_state == AS_SLIDING)
470 				{
471 					self->monsterinfo.currentmove = &hover_move_attack2;
472 					return;
473 				}
474 				else
475 					gi.dprintf ("hover_reattack: unexpected state %d\n", self->monsterinfo.attack_state);
476 			}
477 	self->monsterinfo.currentmove = &hover_move_end_attack;
478 }
479 
480 
hover_fire_blaster(edict_t * self)481 void hover_fire_blaster (edict_t *self)
482 {
483 	vec3_t	start;
484 	vec3_t	forward, right;
485 	vec3_t	end;
486 	vec3_t	dir;
487 	int		effect;
488 
489 	if(!self->enemy || !self->enemy->inuse)		//PGM
490 		return;									//PGM
491 
492 	if (self->s.frame == FRAME_attak104)
493 		effect = EF_HYPERBLASTER;
494 	else
495 		effect = 0;
496 
497 	AngleVectors (self->s.angles, forward, right, NULL);
498 	G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_HOVER_BLASTER_1], forward, right, start);
499 
500 	VectorCopy (self->enemy->s.origin, end);
501 	end[2] += self->enemy->viewheight;
502 	VectorSubtract (end, start, dir);
503 
504 //PGM	- daedalus fires blaster2
505 	if(self->mass < 200)
506 		monster_fire_blaster (self, start, dir, 1, 1000, MZ2_HOVER_BLASTER_1, effect);
507 	else
508 		monster_fire_blaster2 (self, start, dir, 1, 1000, MZ2_DAEDALUS_BLASTER, EF_BLASTER);
509 		// fixme - different muzzle flash
510 //PGM
511 }
512 
513 
hover_stand(edict_t * self)514 void hover_stand (edict_t *self)
515 {
516 		self->monsterinfo.currentmove = &hover_move_stand;
517 }
518 
hover_run(edict_t * self)519 void hover_run (edict_t *self)
520 {
521 	if (self->monsterinfo.aiflags & AI_STAND_GROUND)
522 		self->monsterinfo.currentmove = &hover_move_stand;
523 	else
524 		self->monsterinfo.currentmove = &hover_move_run;
525 }
526 
hover_walk(edict_t * self)527 void hover_walk (edict_t *self)
528 {
529 	self->monsterinfo.currentmove = &hover_move_walk;
530 }
531 
hover_start_attack(edict_t * self)532 void hover_start_attack (edict_t *self)
533 {
534 	self->monsterinfo.currentmove = &hover_move_start_attack;
535 }
536 
hover_attack(edict_t * self)537 void hover_attack(edict_t *self)
538 {
539 	float chance;
540 /*	if (random() <= 0.5)
541 		self->monsterinfo.currentmove = &flyer_move_attack1;
542 	else */
543 	// 0% chance of circle in easy
544 	// 50% chance in normal
545 	// 75% chance in hard
546 	// 86.67% chance in nightmare
547 	if (!skill->value)
548 		chance = 0;
549 	else
550 		chance = 1.0 - (0.5/(float)(skill->value));
551 
552 	if (self->mass > 150)  // the daedalus strafes more
553 		chance += 0.1;
554 
555 	if (random() > chance)
556 	{
557 		self->monsterinfo.currentmove = &hover_move_attack1;
558 		self->monsterinfo.attack_state = AS_STRAIGHT;
559 	}
560 	else // circle strafe
561 	{
562 		if (random () <= 0.5) // switch directions
563 			self->monsterinfo.lefty = 1 - self->monsterinfo.lefty;
564 		self->monsterinfo.currentmove = &hover_move_attack2;
565 		self->monsterinfo.attack_state = AS_SLIDING;
566 	}
567 }
568 
569 
hover_pain(edict_t * self,edict_t * other,float kick,int damage)570 void hover_pain (edict_t *self, edict_t *other, float kick, int damage)
571 {
572 	if (self->health < (self->max_health / 2))
573 		self->s.skinnum |= 1;	// PGM support for skins 2 & 3.
574 
575 	if (level.time < self->pain_debounce_time)
576 		return;
577 
578 	self->pain_debounce_time = level.time + 3;
579 
580 	if (skill->value == 3)
581 		return;		// no pain anims in nightmare
582 
583 	if (damage <= 25)
584 	{
585 		if (random() < 0.5)
586 		{
587 			// PMM - daedalus sounds
588 			if (self->mass < 225)
589 				gi.sound (self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0);
590 			else
591 				gi.sound (self, CHAN_VOICE, daed_sound_pain1, 1, ATTN_NORM, 0);
592 			self->monsterinfo.currentmove = &hover_move_pain3;
593 		}
594 		else
595 		{
596 			// PMM - daedalus sounds
597 			if (self->mass < 225)
598 				gi.sound (self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0);
599 			else
600 				gi.sound (self, CHAN_VOICE, daed_sound_pain2, 1, ATTN_NORM, 0);
601 			self->monsterinfo.currentmove = &hover_move_pain2;
602 		}
603 	}
604 	else
605 	{
606 //====
607 //PGM pain sequence is WAY too long
608 		if (random() < (0.45 - (0.1 * skill->value)))
609 		{
610 			// PMM - daedalus sounds
611 			if (self->mass < 225)
612 				gi.sound (self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0);
613 			else
614 				gi.sound (self, CHAN_VOICE, daed_sound_pain1, 1, ATTN_NORM, 0);
615 			self->monsterinfo.currentmove = &hover_move_pain1;
616 		}
617 		else
618 		{
619 			// PMM - daedalus sounds
620 			if (self->mass < 225)
621 				gi.sound (self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0);
622 			else
623 				gi.sound (self, CHAN_VOICE, daed_sound_pain2, 1, ATTN_NORM, 0);
624 			self->monsterinfo.currentmove = &hover_move_pain2;
625 		}
626 //PGM
627 //====
628 	}
629 }
630 
hover_deadthink(edict_t * self)631 void hover_deadthink (edict_t *self)
632 {
633 	if (!self->groundentity && level.time < self->timestamp)
634 	{
635 		self->nextthink = level.time + FRAMETIME;
636 		return;
637 	}
638 	BecomeExplosion1(self);
639 }
640 
hover_dead(edict_t * self)641 void hover_dead (edict_t *self)
642 {
643 	VectorSet (self->mins, -16, -16, -24);
644 	VectorSet (self->maxs, 16, 16, -8);
645 	self->movetype = MOVETYPE_TOSS;
646 	self->think = hover_deadthink;
647 	self->nextthink = level.time + FRAMETIME;
648 	self->timestamp = level.time + 15;
649 	gi.linkentity (self);
650 }
651 
hover_die(edict_t * self,edict_t * inflictor,edict_t * attacker,int damage,vec3_t point)652 void hover_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
653 {
654 	int		n;
655 
656 	self->s.effects = 0;
657 	self->monsterinfo.power_armor_type = POWER_ARMOR_NONE;
658 
659 // check for gib
660 	if (self->health <= self->gib_health)
661 	{
662 		gi.sound (self, CHAN_VOICE, gi.soundindex ("misc/udeath.wav"), 1, ATTN_NORM, 0);
663 		for (n= 0; n < 2; n++)
664 			ThrowGib (self, "models/objects/gibs/bone/tris.md2", damage, GIB_ORGANIC);
665 		for (n= 0; n < 2; n++)
666 			ThrowGib (self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC);
667 		ThrowHead (self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC);
668 		self->deadflag = DEAD_DEAD;
669 		return;
670 	}
671 
672 	if (self->deadflag == DEAD_DEAD)
673 		return;
674 
675 // regular death
676 	// PMM - daedalus sounds
677 	if (self->mass < 225)
678 	{
679 		if (random() < 0.5)
680 			gi.sound (self, CHAN_VOICE, sound_death1, 1, ATTN_NORM, 0);
681 		else
682 			gi.sound (self, CHAN_VOICE, sound_death2, 1, ATTN_NORM, 0);
683 	}
684 	else
685 	{
686 		if (random() < 0.5)
687 			gi.sound (self, CHAN_VOICE, daed_sound_death1, 1, ATTN_NORM, 0);
688 		else
689 			gi.sound (self, CHAN_VOICE, daed_sound_death2, 1, ATTN_NORM, 0);
690 	}
691 	self->deadflag = DEAD_DEAD;
692 	self->takedamage = DAMAGE_YES;
693 	self->monsterinfo.currentmove = &hover_move_death1;
694 }
695 
696 //===========
697 //PGM
hover_blocked(edict_t * self,float dist)698 qboolean hover_blocked (edict_t *self, float dist)
699 {
700 	if(blocked_checkshot (self, 0.25 + (0.05 * skill->value) ))
701 		return true;
702 
703 	return false;
704 }
705 //PGM
706 //===========
707 
708 /*QUAKED monster_hover (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight
709 */
710 /*QUAKED monster_daedalus (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight
711 This is the improved icarus monster.
712 */
SP_monster_hover(edict_t * self)713 void SP_monster_hover (edict_t *self)
714 {
715 	if (deathmatch->value)
716 	{
717 		G_FreeEdict (self);
718 		return;
719 	}
720 
721 	self->movetype = MOVETYPE_STEP;
722 	self->solid = SOLID_BBOX;
723 	self->s.modelindex = gi.modelindex("models/monsters/hover/tris.md2");
724 	VectorSet (self->mins, -24, -24, -24);
725 	VectorSet (self->maxs, 24, 24, 32);
726 
727 	self->health = 240;
728 	self->gib_health = -100;
729 	self->mass = 150;
730 
731 	self->pain = hover_pain;
732 	self->die = hover_die;
733 
734 	self->monsterinfo.stand = hover_stand;
735 	self->monsterinfo.walk = hover_walk;
736 	self->monsterinfo.run = hover_run;
737 //	self->monsterinfo.dodge = hover_dodge;
738 	self->monsterinfo.attack = hover_start_attack;
739 	self->monsterinfo.sight = hover_sight;
740 	self->monsterinfo.search = hover_search;
741 	self->monsterinfo.blocked = hover_blocked;		// PGM
742 
743 //PGM
744 	if (strcmp(self->classname, "monster_daedalus") == 0)
745 	{
746 		self->health = 450;
747 		self->mass = 225;
748 		self->yaw_speed = 25;
749 		self->monsterinfo.power_armor_type = POWER_ARMOR_SCREEN;
750 		self->monsterinfo.power_armor_power = 100;
751 		// PMM - daedalus sounds
752 		self->s.sound = gi.soundindex ("daedalus/daedidle1.wav");
753 		daed_sound_pain1 = gi.soundindex ("daedalus/daedpain1.wav");
754 		daed_sound_pain2 = gi.soundindex ("daedalus/daedpain2.wav");
755 		daed_sound_death1 = gi.soundindex ("daedalus/daeddeth1.wav");
756 		daed_sound_death2 = gi.soundindex ("daedalus/daeddeth2.wav");
757 		daed_sound_sight = gi.soundindex ("daedalus/daedsght1.wav");
758 		daed_sound_search1 = gi.soundindex ("daedalus/daedsrch1.wav");
759 		daed_sound_search2 = gi.soundindex ("daedalus/daedsrch2.wav");
760 		gi.soundindex ("tank/tnkatck3.wav");
761 		// pmm
762 	}
763 	else
764 	{
765 		sound_pain1 = gi.soundindex ("hover/hovpain1.wav");
766 		sound_pain2 = gi.soundindex ("hover/hovpain2.wav");
767 		sound_death1 = gi.soundindex ("hover/hovdeth1.wav");
768 		sound_death2 = gi.soundindex ("hover/hovdeth2.wav");
769 		sound_sight = gi.soundindex ("hover/hovsght1.wav");
770 		sound_search1 = gi.soundindex ("hover/hovsrch1.wav");
771 		sound_search2 = gi.soundindex ("hover/hovsrch2.wav");
772 		gi.soundindex ("hover/hovatck1.wav");
773 
774 		self->s.sound = gi.soundindex ("hover/hovidle1.wav");
775 	}
776 //PGM
777 
778 	gi.linkentity (self);
779 
780 	self->monsterinfo.currentmove = &hover_move_stand;
781 	self->monsterinfo.scale = MODEL_SCALE;
782 
783 	flymonster_start (self);
784 
785 //PGM
786 	if (strcmp(self->classname, "monster_daedalus") == 0)
787 		self->s.skinnum = 2;
788 //PGM
789 
790 }
791