1 /*
2 Copyright (C) 1997-2001 Id Software, Inc.
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (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.
12
13 See the GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19 */
20 /*
21 ==============================================================================
22
23 floater
24
25 ==============================================================================
26 */
27
28 #include "g_local.h"
29 #include "m_float.h"
30
31
32 static int sound_attack2;
33 static int sound_attack3;
34 static int sound_death1;
35 static int sound_idle;
36 static int sound_pain1;
37 static int sound_pain2;
38 static int sound_sight;
39
40
floater_sight(edict_t * self,edict_t * other)41 void floater_sight (edict_t *self, edict_t *other)
42 {
43 gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0);
44 }
45
floater_idle(edict_t * self)46 void floater_idle (edict_t *self)
47 {
48 gi.sound (self, CHAN_VOICE, sound_idle, 1, ATTN_IDLE, 0);
49 }
50
51
52 //void floater_stand1 (edict_t *self);
53 void floater_dead (edict_t *self);
54 void floater_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point);
55 void floater_run (edict_t *self);
56 void floater_wham (edict_t *self);
57 void floater_zap (edict_t *self);
58
59
floater_fire_blaster(edict_t * self)60 void floater_fire_blaster (edict_t *self)
61 {
62 vec3_t start;
63 vec3_t forward, right;
64 vec3_t end;
65 vec3_t dir;
66 int effect;
67
68 if ((self->s.frame == FRAME_attak104) || (self->s.frame == FRAME_attak107))
69 effect = EF_HYPERBLASTER;
70 else
71 effect = 0;
72 Angles_Vectors (self->s.angles, forward, right, NULL);
73 G_ProjectSource (self->s.origin, dumb_and_hacky_monster_MuzzFlashOffset[MZ2_FLOAT_BLASTER_1], forward, right, start);
74
75 Vec3Copy (self->enemy->s.origin, end);
76 end[2] += self->enemy->viewheight;
77 Vec3Subtract (end, start, dir);
78
79 monster_fire_blaster (self, start, dir, 1, 1000, MZ2_FLOAT_BLASTER_1, effect);
80 }
81
82
83 mframe_t floater_frames_stand1 [] =
84 {
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 ai_stand, 0, NULL,
103 ai_stand, 0, NULL,
104 ai_stand, 0, NULL,
105 ai_stand, 0, NULL,
106 ai_stand, 0, NULL,
107 ai_stand, 0, NULL,
108 ai_stand, 0, NULL,
109 ai_stand, 0, NULL,
110 ai_stand, 0, NULL,
111 ai_stand, 0, NULL,
112 ai_stand, 0, NULL,
113 ai_stand, 0, NULL,
114 ai_stand, 0, NULL,
115 ai_stand, 0, NULL,
116 ai_stand, 0, NULL,
117 ai_stand, 0, NULL,
118 ai_stand, 0, NULL,
119 ai_stand, 0, NULL,
120 ai_stand, 0, NULL,
121 ai_stand, 0, NULL,
122 ai_stand, 0, NULL,
123 ai_stand, 0, NULL,
124 ai_stand, 0, NULL,
125 ai_stand, 0, NULL,
126 ai_stand, 0, NULL,
127 ai_stand, 0, NULL,
128 ai_stand, 0, NULL,
129 ai_stand, 0, NULL,
130 ai_stand, 0, NULL,
131 ai_stand, 0, NULL,
132 ai_stand, 0, NULL,
133 ai_stand, 0, NULL,
134 ai_stand, 0, NULL,
135 ai_stand, 0, NULL,
136 ai_stand, 0, NULL
137 };
138 mmove_t floater_move_stand1 = {FRAME_stand101, FRAME_stand152, floater_frames_stand1, NULL};
139
140 mframe_t floater_frames_stand2 [] =
141 {
142 ai_stand, 0, NULL,
143 ai_stand, 0, NULL,
144 ai_stand, 0, NULL,
145 ai_stand, 0, NULL,
146 ai_stand, 0, NULL,
147 ai_stand, 0, NULL,
148 ai_stand, 0, NULL,
149 ai_stand, 0, NULL,
150 ai_stand, 0, NULL,
151 ai_stand, 0, NULL,
152 ai_stand, 0, NULL,
153 ai_stand, 0, NULL,
154 ai_stand, 0, NULL,
155 ai_stand, 0, NULL,
156 ai_stand, 0, NULL,
157 ai_stand, 0, NULL,
158 ai_stand, 0, NULL,
159 ai_stand, 0, NULL,
160 ai_stand, 0, NULL,
161 ai_stand, 0, NULL,
162 ai_stand, 0, NULL,
163 ai_stand, 0, NULL,
164 ai_stand, 0, NULL,
165 ai_stand, 0, NULL,
166 ai_stand, 0, NULL,
167 ai_stand, 0, NULL,
168 ai_stand, 0, NULL,
169 ai_stand, 0, NULL,
170 ai_stand, 0, NULL,
171 ai_stand, 0, NULL,
172 ai_stand, 0, NULL,
173 ai_stand, 0, NULL,
174 ai_stand, 0, NULL,
175 ai_stand, 0, NULL,
176 ai_stand, 0, NULL,
177 ai_stand, 0, NULL,
178 ai_stand, 0, NULL,
179 ai_stand, 0, NULL,
180 ai_stand, 0, NULL,
181 ai_stand, 0, NULL,
182 ai_stand, 0, NULL,
183 ai_stand, 0, NULL,
184 ai_stand, 0, NULL,
185 ai_stand, 0, NULL,
186 ai_stand, 0, NULL,
187 ai_stand, 0, NULL,
188 ai_stand, 0, NULL,
189 ai_stand, 0, NULL,
190 ai_stand, 0, NULL,
191 ai_stand, 0, NULL,
192 ai_stand, 0, NULL,
193 ai_stand, 0, NULL
194 };
195 mmove_t floater_move_stand2 = {FRAME_stand201, FRAME_stand252, floater_frames_stand2, NULL};
196
floater_stand(edict_t * self)197 void floater_stand (edict_t *self)
198 {
199 if (random() <= 0.5)
200 self->monsterinfo.currentmove = &floater_move_stand1;
201 else
202 self->monsterinfo.currentmove = &floater_move_stand2;
203 }
204
205 mframe_t floater_frames_activate [] =
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 ai_move, 0, NULL,
214 ai_move, 0, NULL,
215 ai_move, 0, NULL,
216 ai_move, 0, NULL,
217 ai_move, 0, NULL,
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 ai_move, 0, NULL,
226 ai_move, 0, NULL,
227 ai_move, 0, NULL,
228 ai_move, 0, NULL,
229 ai_move, 0, NULL,
230 ai_move, 0, NULL,
231 ai_move, 0, NULL,
232 ai_move, 0, NULL,
233 ai_move, 0, NULL,
234 ai_move, 0, NULL,
235 ai_move, 0, NULL,
236 ai_move, 0, NULL
237 };
238 mmove_t floater_move_activate = {FRAME_actvat01, FRAME_actvat31, floater_frames_activate, NULL};
239
240 mframe_t floater_frames_attack1 [] =
241 {
242 ai_charge, 0, NULL, // Blaster attack
243 ai_charge, 0, NULL,
244 ai_charge, 0, NULL,
245 ai_charge, 0, floater_fire_blaster, // BOOM (0, -25.8, 32.5) -- LOOP Starts
246 ai_charge, 0, floater_fire_blaster,
247 ai_charge, 0, floater_fire_blaster,
248 ai_charge, 0, floater_fire_blaster,
249 ai_charge, 0, floater_fire_blaster,
250 ai_charge, 0, floater_fire_blaster,
251 ai_charge, 0, floater_fire_blaster,
252 ai_charge, 0, NULL,
253 ai_charge, 0, NULL,
254 ai_charge, 0, NULL,
255 ai_charge, 0, NULL // -- LOOP Ends
256 };
257 mmove_t floater_move_attack1 = {FRAME_attak101, FRAME_attak114, floater_frames_attack1, floater_run};
258
259 mframe_t floater_frames_attack2 [] =
260 {
261 ai_charge, 0, NULL, // Claws
262 ai_charge, 0, NULL,
263 ai_charge, 0, NULL,
264 ai_charge, 0, NULL,
265 ai_charge, 0, NULL,
266 ai_charge, 0, NULL,
267 ai_charge, 0, NULL,
268 ai_charge, 0, NULL,
269 ai_charge, 0, NULL,
270 ai_charge, 0, NULL,
271 ai_charge, 0, NULL,
272 ai_charge, 0, floater_wham, // WHAM (0, -45, 29.6) -- LOOP Starts
273 ai_charge, 0, NULL,
274 ai_charge, 0, NULL,
275 ai_charge, 0, NULL,
276 ai_charge, 0, NULL,
277 ai_charge, 0, NULL,
278 ai_charge, 0, NULL,
279 ai_charge, 0, NULL, // -- LOOP Ends
280 ai_charge, 0, NULL,
281 ai_charge, 0, NULL,
282 ai_charge, 0, NULL,
283 ai_charge, 0, NULL,
284 ai_charge, 0, NULL,
285 ai_charge, 0, NULL
286 };
287 mmove_t floater_move_attack2 = {FRAME_attak201, FRAME_attak225, floater_frames_attack2, floater_run};
288
289 mframe_t floater_frames_attack3 [] =
290 {
291 ai_charge, 0, NULL,
292 ai_charge, 0, NULL,
293 ai_charge, 0, NULL,
294 ai_charge, 0, NULL,
295 ai_charge, 0, NULL,
296 ai_charge, 0, NULL,
297 ai_charge, 0, NULL,
298 ai_charge, 0, NULL,
299 ai_charge, 0, floater_zap, // -- LOOP Starts
300 ai_charge, 0, NULL,
301 ai_charge, 0, NULL,
302 ai_charge, 0, NULL,
303 ai_charge, 0, NULL,
304 ai_charge, 0, NULL,
305 ai_charge, 0, NULL,
306 ai_charge, 0, NULL,
307 ai_charge, 0, NULL,
308 ai_charge, 0, NULL,
309 ai_charge, 0, NULL,
310 ai_charge, 0, NULL,
311 ai_charge, 0, NULL,
312 ai_charge, 0, NULL,
313 ai_charge, 0, NULL,
314 ai_charge, 0, NULL,
315 ai_charge, 0, NULL,
316 ai_charge, 0, NULL,
317 ai_charge, 0, NULL,
318 ai_charge, 0, NULL,
319 ai_charge, 0, NULL, // -- LOOP Ends
320 ai_charge, 0, NULL,
321 ai_charge, 0, NULL,
322 ai_charge, 0, NULL,
323 ai_charge, 0, NULL,
324 ai_charge, 0, NULL
325 };
326 mmove_t floater_move_attack3 = {FRAME_attak301, FRAME_attak334, floater_frames_attack3, floater_run};
327
328 mframe_t floater_frames_death [] =
329 {
330 ai_move, 0, NULL,
331 ai_move, 0, NULL,
332 ai_move, 0, NULL,
333 ai_move, 0, NULL,
334 ai_move, 0, NULL,
335 ai_move, 0, NULL,
336 ai_move, 0, NULL,
337 ai_move, 0, NULL,
338 ai_move, 0, NULL,
339 ai_move, 0, NULL,
340 ai_move, 0, NULL,
341 ai_move, 0, NULL,
342 ai_move, 0, NULL
343 };
344 mmove_t floater_move_death = {FRAME_death01, FRAME_death13, floater_frames_death, floater_dead};
345
346 mframe_t floater_frames_pain1 [] =
347 {
348 ai_move, 0, NULL,
349 ai_move, 0, NULL,
350 ai_move, 0, NULL,
351 ai_move, 0, NULL,
352 ai_move, 0, NULL,
353 ai_move, 0, NULL,
354 ai_move, 0, NULL
355 };
356 mmove_t floater_move_pain1 = {FRAME_pain101, FRAME_pain107, floater_frames_pain1, floater_run};
357
358 mframe_t floater_frames_pain2 [] =
359 {
360 ai_move, 0, NULL,
361 ai_move, 0, NULL,
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 };
369 mmove_t floater_move_pain2 = {FRAME_pain201, FRAME_pain208, floater_frames_pain2, floater_run};
370
371 mframe_t floater_frames_pain3 [] =
372 {
373 ai_move, 0, NULL,
374 ai_move, 0, NULL,
375 ai_move, 0, NULL,
376 ai_move, 0, NULL,
377 ai_move, 0, NULL,
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 };
386 mmove_t floater_move_pain3 = {FRAME_pain301, FRAME_pain312, floater_frames_pain3, floater_run};
387
388 mframe_t floater_frames_walk [] =
389 {
390 ai_walk, 5, NULL,
391 ai_walk, 5, NULL,
392 ai_walk, 5, NULL,
393 ai_walk, 5, NULL,
394 ai_walk, 5, NULL,
395 ai_walk, 5, NULL,
396 ai_walk, 5, NULL,
397 ai_walk, 5, NULL,
398 ai_walk, 5, NULL,
399 ai_walk, 5, NULL,
400 ai_walk, 5, NULL,
401 ai_walk, 5, NULL,
402 ai_walk, 5, NULL,
403 ai_walk, 5, NULL,
404 ai_walk, 5, NULL,
405 ai_walk, 5, NULL,
406 ai_walk, 5, NULL,
407 ai_walk, 5, NULL,
408 ai_walk, 5, NULL,
409 ai_walk, 5, NULL,
410 ai_walk, 5, NULL,
411 ai_walk, 5, NULL,
412 ai_walk, 5, NULL,
413 ai_walk, 5, NULL,
414 ai_walk, 5, NULL,
415 ai_walk, 5, NULL,
416 ai_walk, 5, NULL,
417 ai_walk, 5, NULL,
418 ai_walk, 5, NULL,
419 ai_walk, 5, NULL,
420 ai_walk, 5, NULL,
421 ai_walk, 5, NULL,
422 ai_walk, 5, NULL,
423 ai_walk, 5, NULL,
424 ai_walk, 5, NULL,
425 ai_walk, 5, NULL,
426 ai_walk, 5, NULL,
427 ai_walk, 5, NULL,
428 ai_walk, 5, NULL,
429 ai_walk, 5, NULL,
430 ai_walk, 5, NULL,
431 ai_walk, 5, NULL,
432 ai_walk, 5, NULL,
433 ai_walk, 5, NULL,
434 ai_walk, 5, NULL,
435 ai_walk, 5, NULL,
436 ai_walk, 5, NULL,
437 ai_walk, 5, NULL,
438 ai_walk, 5, NULL,
439 ai_walk, 5, NULL,
440 ai_walk, 5, NULL,
441 ai_walk, 5, NULL
442 };
443 mmove_t floater_move_walk = {FRAME_stand101, FRAME_stand152, floater_frames_walk, NULL};
444
445 mframe_t floater_frames_run [] =
446 {
447 ai_run, 13, NULL,
448 ai_run, 13, NULL,
449 ai_run, 13, NULL,
450 ai_run, 13, NULL,
451 ai_run, 13, NULL,
452 ai_run, 13, NULL,
453 ai_run, 13, NULL,
454 ai_run, 13, NULL,
455 ai_run, 13, NULL,
456 ai_run, 13, NULL,
457 ai_run, 13, NULL,
458 ai_run, 13, NULL,
459 ai_run, 13, NULL,
460 ai_run, 13, NULL,
461 ai_run, 13, NULL,
462 ai_run, 13, NULL,
463 ai_run, 13, NULL,
464 ai_run, 13, NULL,
465 ai_run, 13, NULL,
466 ai_run, 13, NULL,
467 ai_run, 13, NULL,
468 ai_run, 13, NULL,
469 ai_run, 13, NULL,
470 ai_run, 13, NULL,
471 ai_run, 13, NULL,
472 ai_run, 13, NULL,
473 ai_run, 13, NULL,
474 ai_run, 13, NULL,
475 ai_run, 13, NULL,
476 ai_run, 13, NULL,
477 ai_run, 13, NULL,
478 ai_run, 13, NULL,
479 ai_run, 13, NULL,
480 ai_run, 13, NULL,
481 ai_run, 13, NULL,
482 ai_run, 13, NULL,
483 ai_run, 13, NULL,
484 ai_run, 13, NULL,
485 ai_run, 13, NULL,
486 ai_run, 13, NULL,
487 ai_run, 13, NULL,
488 ai_run, 13, NULL,
489 ai_run, 13, NULL,
490 ai_run, 13, NULL,
491 ai_run, 13, NULL,
492 ai_run, 13, NULL,
493 ai_run, 13, NULL,
494 ai_run, 13, NULL,
495 ai_run, 13, NULL,
496 ai_run, 13, NULL,
497 ai_run, 13, NULL,
498 ai_run, 13, NULL
499 };
500 mmove_t floater_move_run = {FRAME_stand101, FRAME_stand152, floater_frames_run, NULL};
501
floater_run(edict_t * self)502 void floater_run (edict_t *self)
503 {
504 if (self->monsterinfo.aiflags & AI_STAND_GROUND)
505 self->monsterinfo.currentmove = &floater_move_stand1;
506 else
507 self->monsterinfo.currentmove = &floater_move_run;
508 }
509
floater_walk(edict_t * self)510 void floater_walk (edict_t *self)
511 {
512 self->monsterinfo.currentmove = &floater_move_walk;
513 }
514
floater_wham(edict_t * self)515 void floater_wham (edict_t *self)
516 {
517 static vec3_t aim = {MELEE_DISTANCE, 0, 0};
518 gi.sound (self, CHAN_WEAPON, sound_attack3, 1, ATTN_NORM, 0);
519 fire_hit (self, aim, 5 + rand() % 6, -50);
520 }
521
floater_zap(edict_t * self)522 void floater_zap (edict_t *self)
523 {
524 vec3_t forward, right;
525 vec3_t origin;
526 vec3_t dir;
527 vec3_t offset;
528
529 Vec3Subtract (self->enemy->s.origin, self->s.origin, dir);
530
531 Angles_Vectors (self->s.angles, forward, right, NULL);
532 //FIXME use a flash and replace these two lines with the commented one
533 Vec3Set (offset, 18.5f, -0.9f, 10);
534 G_ProjectSource (self->s.origin, offset, forward, right, origin);
535 // G_ProjectSource (self->s.origin, dumb_and_hacky_monster_MuzzFlashOffset[flash_number], forward, right, origin);
536
537 gi.sound (self, CHAN_WEAPON, sound_attack2, 1, ATTN_NORM, 0);
538
539 //FIXME use the flash, Luke
540 gi.WriteByte (SVC_TEMP_ENTITY);
541 gi.WriteByte (TE_SPLASH);
542 gi.WriteByte (32);
543 gi.WritePosition (origin);
544 gi.WriteDir (dir);
545 gi.WriteByte (1); //sparks
546 gi.multicast (origin, MULTICAST_PVS);
547
548 T_Damage (self->enemy, self, self, dir, self->enemy->s.origin, vec3Origin, 5 + rand() % 6, -10, DAMAGE_ENERGY, MOD_UNKNOWN);
549 }
550
floater_attack(edict_t * self)551 void floater_attack(edict_t *self)
552 {
553 self->monsterinfo.currentmove = &floater_move_attack1;
554 }
555
556
floater_melee(edict_t * self)557 void floater_melee(edict_t *self)
558 {
559 if (random() < 0.5)
560 self->monsterinfo.currentmove = &floater_move_attack3;
561 else
562 self->monsterinfo.currentmove = &floater_move_attack2;
563 }
564
565
floater_pain(edict_t * self,edict_t * other,float kick,int damage)566 void floater_pain (edict_t *self, edict_t *other, float kick, int damage)
567 {
568 int n;
569
570 if (self->health < (self->max_health / 2))
571 self->s.skinNum = 1;
572
573 if (level.time < self->pain_debounce_time)
574 return;
575
576 self->pain_debounce_time = level.time + 3;
577 if (skill->floatVal == 3)
578 return; // no pain anims in nightmare
579
580 n = (rand() + 1) % 3;
581 if (n == 0)
582 {
583 gi.sound (self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0);
584 self->monsterinfo.currentmove = &floater_move_pain1;
585 }
586 else
587 {
588 gi.sound (self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0);
589 self->monsterinfo.currentmove = &floater_move_pain2;
590 }
591 }
592
floater_dead(edict_t * self)593 void floater_dead (edict_t *self)
594 {
595 Vec3Set (self->mins, -16, -16, -24);
596 Vec3Set (self->maxs, 16, 16, -8);
597 self->movetype = MOVETYPE_TOSS;
598 self->svFlags |= SVF_DEADMONSTER;
599 self->nextthink = 0;
600 gi.linkentity (self);
601 }
602
floater_die(edict_t * self,edict_t * inflictor,edict_t * attacker,int damage,vec3_t point)603 void floater_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
604 {
605 gi.sound (self, CHAN_VOICE, sound_death1, 1, ATTN_NORM, 0);
606 BecomeExplosion1(self);
607 }
608
609 /*QUAKED monster_floater (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight
610 */
SP_monster_floater(edict_t * self)611 void SP_monster_floater (edict_t *self)
612 {
613 if (deathmatch->floatVal)
614 {
615 G_FreeEdict (self);
616 return;
617 }
618
619 sound_attack2 = gi.soundindex ("floater/fltatck2.wav");
620 sound_attack3 = gi.soundindex ("floater/fltatck3.wav");
621 sound_death1 = gi.soundindex ("floater/fltdeth1.wav");
622 sound_idle = gi.soundindex ("floater/fltidle1.wav");
623 sound_pain1 = gi.soundindex ("floater/fltpain1.wav");
624 sound_pain2 = gi.soundindex ("floater/fltpain2.wav");
625 sound_sight = gi.soundindex ("floater/fltsght1.wav");
626
627 gi.soundindex ("floater/fltatck1.wav");
628
629 self->s.sound = gi.soundindex ("floater/fltsrch1.wav");
630
631 self->movetype = MOVETYPE_STEP;
632 self->solid = SOLID_BBOX;
633 self->s.modelIndex = gi.modelindex ("models/monsters/float/tris.md2");
634 Vec3Set (self->mins, -24, -24, -24);
635 Vec3Set (self->maxs, 24, 24, 32);
636
637 self->health = 200;
638 self->gib_health = -80;
639 self->mass = 300;
640
641 self->pain = floater_pain;
642 self->die = floater_die;
643
644 self->monsterinfo.stand = floater_stand;
645 self->monsterinfo.walk = floater_walk;
646 self->monsterinfo.run = floater_run;
647 // self->monsterinfo.dodge = floater_dodge;
648 self->monsterinfo.attack = floater_attack;
649 self->monsterinfo.melee = floater_melee;
650 self->monsterinfo.sight = floater_sight;
651 self->monsterinfo.idle = floater_idle;
652
653 gi.linkentity (self);
654
655 if (random() <= 0.5)
656 self->monsterinfo.currentmove = &floater_move_stand1;
657 else
658 self->monsterinfo.currentmove = &floater_move_stand2;
659
660 self->monsterinfo.scale = MODEL_SCALE;
661
662 flymonster_start (self);
663 }
664