thirtyflightsofloving/missionpack/m_float.c
Knightmare66 7b6f4281ad Added POSTTHINK_CHILD_MOVEMENT macro to new movewith host entities in g_spawn.c->SpawnEntities() in default Lazarus DLL.
Added Zaero flare gun to no-autoswitch in p_weapon.c->Pickup_Weapon() in missionpack DLL.
Added LM plasma rifle to p_weapon.c->NoAmmoWeaponChange() in missionpack DLL.
Added output of modelindex5&6, alpha, and attenuation to properties command  in missionpack DLL.
Added nogib and environment spawnflags to trigger_hurt and trigger_hurt_boox in missionpack DLL.
Added MONSTER_KNOWS_MIRRORS flag to berserker, barracuda shark, and mutant in missionpack DLL.
Added entity class IDs to misc_actor and target_actor in missionpack DLL.
Added syntax whitespacing to some files in missionpack DLL.
Added backpack drop to certain monsters in missionpack DLL.
Changed some sound paths for new monsters and weapons in missionpack DLL.
2020-10-29 13:03:20 -04:00

754 lines
18 KiB
C

/*
==============================================================================
floater
==============================================================================
*/
#include "g_local.h"
#include "m_float.h"
static int sound_attack2;
static int sound_attack3;
static int sound_death1;
static int sound_idle;
static int sound_pain1;
static int sound_pain2;
static int sound_sight;
void floater_sight (edict_t *self, edict_t *other)
{
gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0);
}
void floater_idle (edict_t *self)
{
if (!(self->spawnflags & SF_MONSTER_AMBUSH))
gi.sound (self, CHAN_VOICE, sound_idle, 1, ATTN_IDLE, 0);
}
//void floater_stand1 (edict_t *self);
void floater_dead (edict_t *self);
void floater_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point);
void floater_run (edict_t *self);
void floater_wham (edict_t *self);
void floater_zap (edict_t *self);
void floater_fire_blaster (edict_t *self)
{
vec3_t start;
vec3_t forward, right;
vec3_t end;
vec3_t dir;
int effect;
if (!self->enemy || !self->enemy->inuse) //PGM
return; //PGM
if ((self->s.frame == FRAME_attak104) || (self->s.frame == FRAME_attak107))
effect = EF_HYPERBLASTER;
else
effect = 0;
AngleVectors (self->s.angles, forward, right, NULL);
G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_FLOAT_BLASTER_1], forward, right, start);
VectorCopy (self->enemy->s.origin, end);
end[2] += self->enemy->viewheight;
// Lazarus fog reduction of accuracy
if (self->monsterinfo.visibility < FOG_CANSEEGOOD)
{
end[0] += crandom() * 640 * (FOG_CANSEEGOOD - self->monsterinfo.visibility);
end[1] += crandom() * 640 * (FOG_CANSEEGOOD - self->monsterinfo.visibility);
end[2] += crandom() * 320 * (FOG_CANSEEGOOD - self->monsterinfo.visibility);
}
VectorSubtract (end, start, dir);
monster_fire_blaster (self, start, dir, 1, 1000, MZ2_FLOAT_BLASTER_1, effect, BLASTER_ORANGE);
}
mframe_t floater_frames_stand1 [] =
{
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL
};
mmove_t floater_move_stand1 = {FRAME_stand101, FRAME_stand152, floater_frames_stand1, NULL};
mframe_t floater_frames_stand2 [] =
{
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL,
ai_stand, 0, NULL
};
mmove_t floater_move_stand2 = {FRAME_stand201, FRAME_stand252, floater_frames_stand2, NULL};
void floater_stand (edict_t *self)
{
if (random() <= 0.5)
self->monsterinfo.currentmove = &floater_move_stand1;
else
self->monsterinfo.currentmove = &floater_move_stand2;
}
mframe_t floater_frames_activate [] =
{
ai_move, 0, NULL,
ai_move, 0, NULL,
ai_move, 0, NULL,
ai_move, 0, NULL,
ai_move, 0, NULL,
ai_move, 0, NULL,
ai_move, 0, NULL,
ai_move, 0, NULL,
ai_move, 0, NULL,
ai_move, 0, NULL,
ai_move, 0, NULL,
ai_move, 0, NULL,
ai_move, 0, NULL,
ai_move, 0, NULL,
ai_move, 0, NULL,
ai_move, 0, NULL,
ai_move, 0, NULL,
ai_move, 0, NULL,
ai_move, 0, NULL,
ai_move, 0, NULL,
ai_move, 0, NULL,
ai_move, 0, NULL,
ai_move, 0, NULL,
ai_move, 0, NULL,
ai_move, 0, NULL,
ai_move, 0, NULL,
ai_move, 0, NULL,
ai_move, 0, NULL,
ai_move, 0, NULL,
ai_move, 0, NULL
};
mmove_t floater_move_activate = {FRAME_actvat01, FRAME_actvat31, floater_frames_activate, NULL};
mframe_t floater_frames_attack1 [] =
{
ai_charge, 0, NULL, // Blaster attack
ai_charge, 0, NULL,
ai_charge, 0, NULL,
ai_charge, 0, floater_fire_blaster, // BOOM (0, -25.8, 32.5) -- LOOP Starts
ai_charge, 0, floater_fire_blaster,
ai_charge, 0, floater_fire_blaster,
ai_charge, 0, floater_fire_blaster,
ai_charge, 0, floater_fire_blaster,
ai_charge, 0, floater_fire_blaster,
ai_charge, 0, floater_fire_blaster,
ai_charge, 0, NULL,
ai_charge, 0, NULL,
ai_charge, 0, NULL,
ai_charge, 0, NULL // -- LOOP Ends
};
mmove_t floater_move_attack1 = {FRAME_attak101, FRAME_attak114, floater_frames_attack1, floater_run};
// PMM - circle strafe frames
mframe_t floater_frames_attack1a [] =
{
ai_charge, 10, NULL, // Blaster attack
ai_charge, 10, NULL,
ai_charge, 10, NULL,
ai_charge, 10, floater_fire_blaster, // BOOM (0, -25.8, 32.5) -- LOOP Starts
ai_charge, 10, floater_fire_blaster,
ai_charge, 10, floater_fire_blaster,
ai_charge, 10, floater_fire_blaster,
ai_charge, 10, floater_fire_blaster,
ai_charge, 10, floater_fire_blaster,
ai_charge, 10, floater_fire_blaster,
ai_charge, 10, NULL,
ai_charge, 10, NULL,
ai_charge, 10, NULL,
ai_charge, 10, NULL // -- LOOP Ends
};
mmove_t floater_move_attack1a = {FRAME_attak101, FRAME_attak114, floater_frames_attack1a, floater_run};
//pmm
mframe_t floater_frames_attack2 [] =
{
ai_charge, 0, NULL, // Claws
ai_charge, 0, NULL,
ai_charge, 0, NULL,
ai_charge, 0, NULL,
ai_charge, 0, NULL,
ai_charge, 0, NULL,
ai_charge, 0, NULL,
ai_charge, 0, NULL,
ai_charge, 0, NULL,
ai_charge, 0, NULL,
ai_charge, 0, NULL,
ai_charge, 0, floater_wham, // WHAM (0, -45, 29.6) -- LOOP Starts
ai_charge, 0, NULL,
ai_charge, 0, NULL,
ai_charge, 0, NULL,
ai_charge, 0, NULL,
ai_charge, 0, NULL,
ai_charge, 0, NULL,
ai_charge, 0, NULL, // -- LOOP Ends
ai_charge, 0, NULL,
ai_charge, 0, NULL,
ai_charge, 0, NULL,
ai_charge, 0, NULL,
ai_charge, 0, NULL,
ai_charge, 0, NULL
};
mmove_t floater_move_attack2 = {FRAME_attak201, FRAME_attak225, floater_frames_attack2, floater_run};
mframe_t floater_frames_attack3 [] =
{
ai_charge, 0, NULL,
ai_charge, 0, NULL,
ai_charge, 0, NULL,
ai_charge, 0, NULL,
ai_charge, 0, NULL,
ai_charge, 0, NULL,
ai_charge, 0, NULL,
ai_charge, 0, NULL,
ai_charge, 0, floater_zap, // -- LOOP Starts
ai_charge, 0, NULL,
ai_charge, 0, NULL,
ai_charge, 0, NULL,
ai_charge, 0, NULL,
ai_charge, 0, NULL,
ai_charge, 0, NULL,
ai_charge, 0, NULL,
ai_charge, 0, NULL,
ai_charge, 0, NULL,
ai_charge, 0, NULL,
ai_charge, 0, NULL,
ai_charge, 0, NULL,
ai_charge, 0, NULL,
ai_charge, 0, NULL,
ai_charge, 0, NULL,
ai_charge, 0, NULL,
ai_charge, 0, NULL,
ai_charge, 0, NULL,
ai_charge, 0, NULL,
ai_charge, 0, NULL, // -- LOOP Ends
ai_charge, 0, NULL,
ai_charge, 0, NULL,
ai_charge, 0, NULL,
ai_charge, 0, NULL,
ai_charge, 0, NULL
};
mmove_t floater_move_attack3 = {FRAME_attak301, FRAME_attak334, floater_frames_attack3, floater_run};
mframe_t floater_frames_death [] =
{
ai_move, 0, NULL,
ai_move, 0, NULL,
ai_move, 0, NULL,
ai_move, 0, NULL,
ai_move, 0, NULL,
ai_move, 0, NULL,
ai_move, 0, NULL,
ai_move, 0, NULL,
ai_move, 0, NULL,
ai_move, 0, NULL,
ai_move, 0, NULL,
ai_move, 0, NULL,
ai_move, 0, NULL
};
mmove_t floater_move_death = {FRAME_death01, FRAME_death13, floater_frames_death, floater_dead};
mframe_t floater_frames_pain1 [] =
{
ai_move, 0, NULL,
ai_move, 0, NULL,
ai_move, 0, NULL,
ai_move, 0, NULL,
ai_move, 0, NULL,
ai_move, 0, NULL,
ai_move, 0, NULL
};
mmove_t floater_move_pain1 = {FRAME_pain101, FRAME_pain107, floater_frames_pain1, floater_run};
mframe_t floater_frames_pain2 [] =
{
ai_move, 0, NULL,
ai_move, 0, NULL,
ai_move, 0, NULL,
ai_move, 0, NULL,
ai_move, 0, NULL,
ai_move, 0, NULL,
ai_move, 0, NULL,
ai_move, 0, NULL
};
mmove_t floater_move_pain2 = {FRAME_pain201, FRAME_pain208, floater_frames_pain2, floater_run};
mframe_t floater_frames_pain3 [] =
{
ai_move, 0, NULL,
ai_move, 0, NULL,
ai_move, 0, NULL,
ai_move, 0, NULL,
ai_move, 0, NULL,
ai_move, 0, NULL,
ai_move, 0, NULL,
ai_move, 0, NULL,
ai_move, 0, NULL,
ai_move, 0, NULL,
ai_move, 0, NULL,
ai_move, 0, NULL
};
mmove_t floater_move_pain3 = {FRAME_pain301, FRAME_pain312, floater_frames_pain3, floater_run};
mframe_t floater_frames_walk [] =
{
ai_walk, 5, NULL,
ai_walk, 5, NULL,
ai_walk, 5, NULL,
ai_walk, 5, NULL,
ai_walk, 5, NULL,
ai_walk, 5, NULL,
ai_walk, 5, NULL,
ai_walk, 5, NULL,
ai_walk, 5, NULL,
ai_walk, 5, NULL,
ai_walk, 5, NULL,
ai_walk, 5, NULL,
ai_walk, 5, NULL,
ai_walk, 5, NULL,
ai_walk, 5, NULL,
ai_walk, 5, NULL,
ai_walk, 5, NULL,
ai_walk, 5, NULL,
ai_walk, 5, NULL,
ai_walk, 5, NULL,
ai_walk, 5, NULL,
ai_walk, 5, NULL,
ai_walk, 5, NULL,
ai_walk, 5, NULL,
ai_walk, 5, NULL,
ai_walk, 5, NULL,
ai_walk, 5, NULL,
ai_walk, 5, NULL,
ai_walk, 5, NULL,
ai_walk, 5, NULL,
ai_walk, 5, NULL,
ai_walk, 5, NULL,
ai_walk, 5, NULL,
ai_walk, 5, NULL,
ai_walk, 5, NULL,
ai_walk, 5, NULL,
ai_walk, 5, NULL,
ai_walk, 5, NULL,
ai_walk, 5, NULL,
ai_walk, 5, NULL,
ai_walk, 5, NULL,
ai_walk, 5, NULL,
ai_walk, 5, NULL,
ai_walk, 5, NULL,
ai_walk, 5, NULL,
ai_walk, 5, NULL,
ai_walk, 5, NULL,
ai_walk, 5, NULL,
ai_walk, 5, NULL,
ai_walk, 5, NULL,
ai_walk, 5, NULL,
ai_walk, 5, NULL
};
mmove_t floater_move_walk = {FRAME_stand101, FRAME_stand152, floater_frames_walk, NULL};
mframe_t floater_frames_run [] =
{
ai_run, 13, NULL,
ai_run, 13, NULL,
ai_run, 13, NULL,
ai_run, 13, NULL,
ai_run, 13, NULL,
ai_run, 13, NULL,
ai_run, 13, NULL,
ai_run, 13, NULL,
ai_run, 13, NULL,
ai_run, 13, NULL,
ai_run, 13, NULL,
ai_run, 13, NULL,
ai_run, 13, NULL,
ai_run, 13, NULL,
ai_run, 13, NULL,
ai_run, 13, NULL,
ai_run, 13, NULL,
ai_run, 13, NULL,
ai_run, 13, NULL,
ai_run, 13, NULL,
ai_run, 13, NULL,
ai_run, 13, NULL,
ai_run, 13, NULL,
ai_run, 13, NULL,
ai_run, 13, NULL,
ai_run, 13, NULL,
ai_run, 13, NULL,
ai_run, 13, NULL,
ai_run, 13, NULL,
ai_run, 13, NULL,
ai_run, 13, NULL,
ai_run, 13, NULL,
ai_run, 13, NULL,
ai_run, 13, NULL,
ai_run, 13, NULL,
ai_run, 13, NULL,
ai_run, 13, NULL,
ai_run, 13, NULL,
ai_run, 13, NULL,
ai_run, 13, NULL,
ai_run, 13, NULL,
ai_run, 13, NULL,
ai_run, 13, NULL,
ai_run, 13, NULL,
ai_run, 13, NULL,
ai_run, 13, NULL,
ai_run, 13, NULL,
ai_run, 13, NULL,
ai_run, 13, NULL,
ai_run, 13, NULL,
ai_run, 13, NULL,
ai_run, 13, NULL
};
mmove_t floater_move_run = {FRAME_stand101, FRAME_stand152, floater_frames_run, NULL};
void floater_run (edict_t *self)
{
if (self->monsterinfo.aiflags & AI_STAND_GROUND)
self->monsterinfo.currentmove = &floater_move_stand1;
else
self->monsterinfo.currentmove = &floater_move_run;
}
void floater_walk (edict_t *self)
{
self->monsterinfo.currentmove = &floater_move_walk;
}
void floater_wham (edict_t *self)
{
static vec3_t aim = {MELEE_DISTANCE, 0, 0};
gi.sound (self, CHAN_WEAPON, sound_attack3, 1, ATTN_NORM, 0);
fire_hit (self, aim, 5 + rand() % 6, -50);
}
void floater_zap (edict_t *self)
{
vec3_t forward, right;
vec3_t origin;
vec3_t dir;
vec3_t offset;
VectorSubtract (self->enemy->s.origin, self->s.origin, dir);
AngleVectors (self->s.angles, forward, right, NULL);
//FIXME use a flash and replace these two lines with the commented one
VectorSet (offset, 18.5, -0.9, 10);
G_ProjectSource (self->s.origin, offset, forward, right, origin);
// G_ProjectSource (self->s.origin, monster_flash_offset[flash_number], forward, right, origin);
gi.sound (self, CHAN_WEAPON, sound_attack2, 1, ATTN_NORM, 0);
//FIXME use the flash, Luke
gi.WriteByte (svc_temp_entity);
gi.WriteByte (TE_SPLASH);
gi.WriteByte (32);
gi.WritePosition (origin);
gi.WriteDir (dir);
gi.WriteByte (1); //sparks
gi.multicast (origin, MULTICAST_PVS);
T_Damage (self->enemy, self, self, dir, self->enemy->s.origin, vec3_origin, 5 + rand() % 6, -10, DAMAGE_ENERGY, MOD_UNKNOWN);
}
void floater_attack(edict_t *self)
{
float chance;
/* if (random() <= 0.5)
self->monsterinfo.currentmove = &flyer_move_attack1;
else */
// 0% chance of circle in easy
// 50% chance in normal
// 75% chance in hard
// 86.67% chance in nightmare
if (!skill->value)
chance = 0;
else
chance = 1.0 - (0.5/(float)(skill->value));
if (random() > chance)
{
self->monsterinfo.attack_state = AS_STRAIGHT;
self->monsterinfo.currentmove = &floater_move_attack1;
}
else // circle strafe
{
if (random () <= 0.5) // switch directions
self->monsterinfo.lefty = 1 - self->monsterinfo.lefty;
self->monsterinfo.attack_state = AS_SLIDING;
self->monsterinfo.currentmove = &floater_move_attack1a;
}
}
void floater_melee(edict_t *self)
{
if (random() < 0.5)
self->monsterinfo.currentmove = &floater_move_attack3;
else
self->monsterinfo.currentmove = &floater_move_attack2;
}
void floater_pain (edict_t *self, edict_t *other, float kick, int damage)
{
int n;
if (self->health < (self->max_health / 2))
{
self->s.skinnum |= 1;
if (!(self->fogclip & 2)) // custom bloodtype flag check
self->blood_type = 3; // sparks and blood
}
if (level.time < self->pain_debounce_time)
return;
self->pain_debounce_time = level.time + 3;
if (skill->value == 3)
return; // no pain anims in nightmare
n = (rand() + 1) % 3;
if (n == 0)
{
gi.sound (self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0);
self->monsterinfo.currentmove = &floater_move_pain1;
}
else
{
gi.sound (self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0);
self->monsterinfo.currentmove = &floater_move_pain2;
}
}
void floater_dead (edict_t *self)
{
VectorSet (self->mins, -16, -16, -24);
VectorSet (self->maxs, 16, 16, -8);
self->movetype = MOVETYPE_TOSS;
self->svflags |= SVF_DEADMONSTER;
self->nextthink = 0;
gi.linkentity (self);
}
void floater_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
{
int n; //Knightmare added
for (n= 0; n < 4; n++)
ThrowGib (self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC);
for (n= 0; n < 10; n++)
ThrowGib (self, "models/objects/gibs/sm_metal/tris.md2", damage, GIB_METALLIC);
for (n= 0; n < 2; n++)
ThrowGib (self, "models/objects/gibs/gear/tris.md2", damage, GIB_METALLIC);
gi.sound (self, CHAN_VOICE, sound_death1, 1, ATTN_NORM, 0);
BecomeExplosion1(self);
}
//===========
//PGM
qboolean floater_blocked (edict_t *self, float dist)
{
if (blocked_checkshot (self, 0.25 + (0.05 * skill->value) ))
return true;
return false;
}
//PGM
//===========
/*QUAKED monster_floater (1 .5 0) (-24 -24 -24) (24 24 32) Ambush Trigger_Spawn Sight GoodGuy
*/
void SP_monster_floater (edict_t *self)
{
if (deathmatch->value)
{
G_FreeEdict (self);
return;
}
sound_attack2 = gi.soundindex ("floater/fltatck2.wav");
sound_attack3 = gi.soundindex ("floater/fltatck3.wav");
sound_death1 = gi.soundindex ("floater/fltdeth1.wav");
sound_idle = gi.soundindex ("floater/fltidle1.wav");
sound_pain1 = gi.soundindex ("floater/fltpain1.wav");
sound_pain2 = gi.soundindex ("floater/fltpain2.wav");
sound_sight = gi.soundindex ("floater/fltsght1.wav");
gi.soundindex ("floater/fltatck1.wav");
self->s.sound = gi.soundindex ("floater/fltsrch1.wav");
self->movetype = MOVETYPE_STEP;
self->solid = SOLID_BBOX;
// Lazarus: special purpose skins
if ( self->style )
{
PatchMonsterModel("models/monsters/float/tris.md2");
self->s.skinnum |= self->style * 2;
}
self->s.modelindex = gi.modelindex ("models/monsters/float/tris.md2");
//Knightmare- changed bbox, was z= 32, -24
VectorSet (self->mins, -24, -24, -16);
VectorSet (self->maxs, 24, 24, 40);
if (!self->health)
self->health = 200;
if (!self->gib_health)
self->gib_health = -80;
if (!self->mass)
self->mass = 300;
self->pain = floater_pain;
self->die = floater_die;
self->monsterinfo.stand = floater_stand;
self->monsterinfo.walk = floater_walk;
self->monsterinfo.run = floater_run;
// self->monsterinfo.dodge = floater_dodge;
self->monsterinfo.attack = floater_attack;
self->monsterinfo.melee = floater_melee;
self->monsterinfo.sight = floater_sight;
self->monsterinfo.idle = floater_idle;
self->monsterinfo.blocked = floater_blocked; // PGM
//Knightmare - sparks, not blood, on damage
if (!self->blood_type)
self->blood_type = 2; //sparks
else
self->fogclip |= 2; //custom bloodtype flag
// Lazarus
if (self->powerarmor)
{
if (self->powerarmortype == 1)
self->monsterinfo.power_armor_type = POWER_ARMOR_SCREEN;
else
self->monsterinfo.power_armor_type = POWER_ARMOR_SHIELD;
self->monsterinfo.power_armor_power = self->powerarmor;
}
self->common_name = "Technician";
self->class_id = ENTITY_MONSTER_FLOATER;
gi.linkentity (self);
if (random() <= 0.5)
self->monsterinfo.currentmove = &floater_move_stand1;
else
self->monsterinfo.currentmove = &floater_move_stand2;
self->monsterinfo.scale = MODEL_SCALE;
flymonster_start (self);
}