mirror of
https://github.com/blendogames/thirtyflightsofloving.git
synced 2025-01-18 14:31:55 +00:00
d16b46e3cf
Overhauled child entity movement in default Lazarus DLL. Added bbox versions of various triggers to default Lazarus DLL. Added level.maptype field to default Lazarus DLL. Added entity class IDs to default Lazarus DLL. Incremented savegame version for default Lazarus DLL.
666 lines
16 KiB
C
666 lines
16 KiB
C
/*
|
|
===========================================================================
|
|
Copyright (C) 1997-2001 Id Software, Inc.
|
|
Copyright (C) 2000-2002 Mr. Hyde and Mad Dog
|
|
|
|
This file is part of Lazarus Quake 2 Mod source code.
|
|
|
|
Lazarus Quake 2 Mod source code is free software; you can redistribute it
|
|
and/or modify it under the terms of the GNU General Public License as
|
|
published by the Free Software Foundation; either version 2 of the License,
|
|
or (at your option) any later version.
|
|
|
|
Lazarus Quake 2 Mod source code is distributed in the hope that it will be
|
|
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with Lazarus Quake 2 Mod source code; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
===========================================================================
|
|
*/
|
|
|
|
/*
|
|
==============================================================================
|
|
|
|
flyer
|
|
|
|
==============================================================================
|
|
*/
|
|
|
|
#include "g_local.h"
|
|
#include "m_flyer.h"
|
|
|
|
qboolean visible (edict_t *self, edict_t *other);
|
|
|
|
static int nextmove; // Used for start/stop frames
|
|
|
|
static int sound_sight;
|
|
static int sound_idle;
|
|
static int sound_pain1;
|
|
static int sound_pain2;
|
|
static int sound_slash;
|
|
static int sound_sproing;
|
|
static int sound_die;
|
|
|
|
|
|
void flyer_check_melee(edict_t *self);
|
|
void flyer_loop_melee (edict_t *self);
|
|
void flyer_melee (edict_t *self);
|
|
void flyer_setstart (edict_t *self);
|
|
void flyer_stand (edict_t *self);
|
|
void flyer_nextmove (edict_t *self);
|
|
|
|
|
|
void flyer_sight (edict_t *self, edict_t *other)
|
|
{
|
|
gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0);
|
|
}
|
|
|
|
void flyer_idle (edict_t *self)
|
|
{
|
|
// if (!(self->spawnflags & SF_MONSTER_AMBUSH))
|
|
gi.sound (self, CHAN_VOICE, sound_idle, 1, ATTN_IDLE, 0);
|
|
}
|
|
|
|
void flyer_pop_blades (edict_t *self)
|
|
{
|
|
gi.sound (self, CHAN_VOICE, sound_sproing, 1, ATTN_NORM, 0);
|
|
}
|
|
|
|
|
|
mframe_t flyer_frames_stand [] =
|
|
{
|
|
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 flyer_move_stand = {FRAME_stand01, FRAME_stand45, flyer_frames_stand, NULL};
|
|
|
|
|
|
mframe_t flyer_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
|
|
};
|
|
mmove_t flyer_move_walk = {FRAME_stand01, FRAME_stand45, flyer_frames_walk, NULL};
|
|
|
|
mframe_t flyer_frames_run [] =
|
|
{
|
|
ai_run, 10, NULL,
|
|
ai_run, 10, NULL,
|
|
ai_run, 10, NULL,
|
|
ai_run, 10, NULL,
|
|
ai_run, 10, NULL,
|
|
ai_run, 10, NULL,
|
|
ai_run, 10, NULL,
|
|
ai_run, 10, NULL,
|
|
ai_run, 10, NULL,
|
|
ai_run, 10, NULL,
|
|
ai_run, 10, NULL,
|
|
ai_run, 10, NULL,
|
|
ai_run, 10, NULL,
|
|
ai_run, 10, NULL,
|
|
ai_run, 10, NULL,
|
|
ai_run, 10, NULL,
|
|
ai_run, 10, NULL,
|
|
ai_run, 10, NULL,
|
|
ai_run, 10, NULL,
|
|
ai_run, 10, NULL,
|
|
ai_run, 10, NULL,
|
|
ai_run, 10, NULL,
|
|
ai_run, 10, NULL,
|
|
ai_run, 10, NULL,
|
|
ai_run, 10, NULL,
|
|
ai_run, 10, NULL,
|
|
ai_run, 10, NULL,
|
|
ai_run, 10, NULL,
|
|
ai_run, 10, NULL,
|
|
ai_run, 10, NULL,
|
|
ai_run, 10, NULL,
|
|
ai_run, 10, NULL,
|
|
ai_run, 10, NULL,
|
|
ai_run, 10, NULL,
|
|
ai_run, 10, NULL,
|
|
ai_run, 10, NULL,
|
|
ai_run, 10, NULL,
|
|
ai_run, 10, NULL,
|
|
ai_run, 10, NULL,
|
|
ai_run, 10, NULL,
|
|
ai_run, 10, NULL,
|
|
ai_run, 10, NULL,
|
|
ai_run, 10, NULL,
|
|
ai_run, 10, NULL,
|
|
ai_run, 10, NULL
|
|
};
|
|
mmove_t flyer_move_run = {FRAME_stand01, FRAME_stand45, flyer_frames_run, NULL};
|
|
|
|
void flyer_run (edict_t *self)
|
|
{
|
|
if (self->monsterinfo.aiflags & AI_STAND_GROUND)
|
|
self->monsterinfo.currentmove = &flyer_move_stand;
|
|
else
|
|
self->monsterinfo.currentmove = &flyer_move_run;
|
|
}
|
|
|
|
void flyer_walk (edict_t *self)
|
|
{
|
|
self->monsterinfo.currentmove = &flyer_move_walk;
|
|
}
|
|
|
|
void flyer_stand (edict_t *self)
|
|
{
|
|
self->monsterinfo.currentmove = &flyer_move_stand;
|
|
}
|
|
|
|
mframe_t flyer_frames_start [] =
|
|
{
|
|
ai_move, 0, NULL,
|
|
ai_move, 0, NULL,
|
|
ai_move, 0, NULL,
|
|
ai_move, 0, NULL,
|
|
ai_move, 0, NULL,
|
|
ai_move, 0, flyer_nextmove
|
|
};
|
|
mmove_t flyer_move_start = {FRAME_start01, FRAME_start06, flyer_frames_start, NULL};
|
|
|
|
mframe_t flyer_frames_stop [] =
|
|
{
|
|
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, flyer_nextmove
|
|
};
|
|
mmove_t flyer_move_stop = {FRAME_stop01, FRAME_stop07, flyer_frames_stop, NULL};
|
|
|
|
void flyer_stop (edict_t *self)
|
|
{
|
|
self->monsterinfo.currentmove = &flyer_move_stop;
|
|
}
|
|
|
|
void flyer_start (edict_t *self)
|
|
{
|
|
self->monsterinfo.currentmove = &flyer_move_start;
|
|
}
|
|
|
|
|
|
mframe_t flyer_frames_rollright [] =
|
|
{
|
|
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 flyer_move_rollright = {FRAME_rollr01, FRAME_rollr09, flyer_frames_rollright, NULL};
|
|
|
|
mframe_t flyer_frames_rollleft [] =
|
|
{
|
|
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 flyer_move_rollleft = {FRAME_rollf01, FRAME_rollf09, flyer_frames_rollleft, NULL};
|
|
|
|
mframe_t flyer_frames_pain3 [] =
|
|
{
|
|
ai_move, 0, NULL,
|
|
ai_move, 0, NULL,
|
|
ai_move, 0, NULL,
|
|
ai_move, 0, NULL
|
|
};
|
|
mmove_t flyer_move_pain3 = {FRAME_pain301, FRAME_pain304, flyer_frames_pain3, flyer_run};
|
|
|
|
mframe_t flyer_frames_pain2 [] =
|
|
{
|
|
ai_move, 0, NULL,
|
|
ai_move, 0, NULL,
|
|
ai_move, 0, NULL,
|
|
ai_move, 0, NULL
|
|
};
|
|
mmove_t flyer_move_pain2 = {FRAME_pain201, FRAME_pain204, flyer_frames_pain2, flyer_run};
|
|
|
|
mframe_t flyer_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,
|
|
ai_move, 0, NULL,
|
|
ai_move, 0, NULL
|
|
};
|
|
mmove_t flyer_move_pain1 = {FRAME_pain101, FRAME_pain109, flyer_frames_pain1, flyer_run};
|
|
|
|
mframe_t flyer_frames_defense [] =
|
|
{
|
|
ai_move, 0, NULL,
|
|
ai_move, 0, NULL,
|
|
ai_move, 0, NULL, // Hold this frame
|
|
ai_move, 0, NULL,
|
|
ai_move, 0, NULL,
|
|
ai_move, 0, NULL
|
|
};
|
|
mmove_t flyer_move_defense = {FRAME_defens01, FRAME_defens06, flyer_frames_defense, NULL};
|
|
|
|
mframe_t flyer_frames_bankright [] =
|
|
{
|
|
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 flyer_move_bankright = {FRAME_bankr01, FRAME_bankr07, flyer_frames_bankright, NULL};
|
|
|
|
mframe_t flyer_frames_bankleft [] =
|
|
{
|
|
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 flyer_move_bankleft = {FRAME_bankl01, FRAME_bankl07, flyer_frames_bankleft, NULL};
|
|
|
|
|
|
void flyer_fire (edict_t *self, int flash_number)
|
|
{
|
|
vec3_t start;
|
|
vec3_t forward, right;
|
|
vec3_t end;
|
|
vec3_t dir;
|
|
int effect;
|
|
|
|
if ((self->s.frame == FRAME_attak204) || (self->s.frame == FRAME_attak207) || (self->s.frame == FRAME_attak210))
|
|
effect = EF_HYPERBLASTER;
|
|
else
|
|
effect = 0;
|
|
AngleVectors (self->s.angles, forward, right, NULL);
|
|
G_ProjectSource (self->s.origin, monster_flash_offset[flash_number], 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, flash_number, effect, BLASTER_ORANGE);
|
|
}
|
|
|
|
void flyer_fireleft (edict_t *self)
|
|
{
|
|
flyer_fire (self, MZ2_FLYER_BLASTER_1);
|
|
}
|
|
|
|
void flyer_fireright (edict_t *self)
|
|
{
|
|
flyer_fire (self, MZ2_FLYER_BLASTER_2);
|
|
}
|
|
|
|
|
|
mframe_t flyer_frames_attack2 [] =
|
|
{
|
|
ai_charge, 0, NULL,
|
|
ai_charge, 0, NULL,
|
|
ai_charge, 0, NULL,
|
|
ai_charge, -10, flyer_fireleft, // left gun
|
|
ai_charge, -10, flyer_fireright, // right gun
|
|
ai_charge, -10, flyer_fireleft, // left gun
|
|
ai_charge, -10, flyer_fireright, // right gun
|
|
ai_charge, -10, flyer_fireleft, // left gun
|
|
ai_charge, -10, flyer_fireright, // right gun
|
|
ai_charge, -10, flyer_fireleft, // left gun
|
|
ai_charge, -10, flyer_fireright, // right gun
|
|
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 flyer_move_attack2 = {FRAME_attak201, FRAME_attak217, flyer_frames_attack2, flyer_run};
|
|
|
|
|
|
void flyer_slash_left (edict_t *self)
|
|
{
|
|
vec3_t aim;
|
|
|
|
VectorSet (aim, MELEE_DISTANCE, self->mins[0], 0);
|
|
fire_hit (self, aim, 5, 0);
|
|
gi.sound (self, CHAN_WEAPON, sound_slash, 1, ATTN_NORM, 0);
|
|
}
|
|
|
|
void flyer_slash_right (edict_t *self)
|
|
{
|
|
vec3_t aim;
|
|
|
|
VectorSet (aim, MELEE_DISTANCE, self->maxs[0], 0);
|
|
fire_hit (self, aim, 5, 0);
|
|
gi.sound (self, CHAN_WEAPON, sound_slash, 1, ATTN_NORM, 0);
|
|
}
|
|
|
|
mframe_t flyer_frames_start_melee [] =
|
|
{
|
|
ai_charge, 0, flyer_pop_blades,
|
|
ai_charge, 0, NULL,
|
|
ai_charge, 0, NULL,
|
|
ai_charge, 0, NULL,
|
|
ai_charge, 0, NULL,
|
|
ai_charge, 0, NULL
|
|
};
|
|
mmove_t flyer_move_start_melee = {FRAME_attak101, FRAME_attak106, flyer_frames_start_melee, flyer_loop_melee};
|
|
|
|
mframe_t flyer_frames_end_melee [] =
|
|
{
|
|
ai_charge, 0, NULL,
|
|
ai_charge, 0, NULL,
|
|
ai_charge, 0, NULL
|
|
};
|
|
mmove_t flyer_move_end_melee = {FRAME_attak119, FRAME_attak121, flyer_frames_end_melee, flyer_run};
|
|
|
|
|
|
mframe_t flyer_frames_loop_melee [] =
|
|
{
|
|
ai_charge, 0, NULL, // Loop Start
|
|
ai_charge, 0, NULL,
|
|
ai_charge, 0, flyer_slash_left, // Left Wing Strike
|
|
ai_charge, 0, NULL,
|
|
ai_charge, 0, NULL,
|
|
ai_charge, 0, NULL,
|
|
ai_charge, 0, NULL,
|
|
ai_charge, 0, flyer_slash_right, // Right Wing Strike
|
|
ai_charge, 0, NULL,
|
|
ai_charge, 0, NULL,
|
|
ai_charge, 0, NULL,
|
|
ai_charge, 0, NULL // Loop Ends
|
|
|
|
};
|
|
mmove_t flyer_move_loop_melee = {FRAME_attak107, FRAME_attak118, flyer_frames_loop_melee, flyer_check_melee};
|
|
|
|
void flyer_loop_melee (edict_t *self)
|
|
{
|
|
/* if (random() <= 0.5)
|
|
self->monsterinfo.currentmove = &flyer_move_attack1;
|
|
else */
|
|
self->monsterinfo.currentmove = &flyer_move_loop_melee;
|
|
}
|
|
|
|
|
|
|
|
void flyer_attack (edict_t *self)
|
|
{
|
|
/* if (random() <= 0.5)
|
|
self->monsterinfo.currentmove = &flyer_move_attack1;
|
|
else */
|
|
self->monsterinfo.currentmove = &flyer_move_attack2;
|
|
}
|
|
|
|
void flyer_setstart (edict_t *self)
|
|
{
|
|
nextmove = ACTION_run;
|
|
self->monsterinfo.currentmove = &flyer_move_start;
|
|
}
|
|
|
|
void flyer_nextmove (edict_t *self)
|
|
{
|
|
if (nextmove == ACTION_attack1)
|
|
self->monsterinfo.currentmove = &flyer_move_start_melee;
|
|
else if (nextmove == ACTION_attack2)
|
|
self->monsterinfo.currentmove = &flyer_move_attack2;
|
|
else if (nextmove == ACTION_run)
|
|
self->monsterinfo.currentmove = &flyer_move_run;
|
|
}
|
|
|
|
void flyer_melee (edict_t *self)
|
|
{
|
|
// flyer.nextmove = ACTION_attack1;
|
|
// self->monsterinfo.currentmove = &flyer_move_stop;
|
|
self->monsterinfo.currentmove = &flyer_move_start_melee;
|
|
}
|
|
|
|
void flyer_check_melee(edict_t *self)
|
|
{
|
|
if (range (self, self->enemy) == RANGE_MELEE)
|
|
if (random() <= 0.8)
|
|
self->monsterinfo.currentmove = &flyer_move_loop_melee;
|
|
else
|
|
self->monsterinfo.currentmove = &flyer_move_end_melee;
|
|
else
|
|
self->monsterinfo.currentmove = &flyer_move_end_melee;
|
|
}
|
|
|
|
void flyer_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 (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() % 3;
|
|
if (n == 0)
|
|
{
|
|
gi.sound (self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0);
|
|
self->monsterinfo.currentmove = &flyer_move_pain1;
|
|
}
|
|
else if (n == 1)
|
|
{
|
|
gi.sound (self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0);
|
|
self->monsterinfo.currentmove = &flyer_move_pain2;
|
|
}
|
|
else
|
|
{
|
|
gi.sound (self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0);
|
|
self->monsterinfo.currentmove = &flyer_move_pain3;
|
|
}
|
|
}
|
|
|
|
|
|
void flyer_die(edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
|
|
{
|
|
int n;
|
|
// Knightmare- gibs!
|
|
for (n= 0; n < 4; n++)
|
|
ThrowGib (self, "models/objects/gibs/sm_metal/tris.md2", damage, GIB_METALLIC);
|
|
for (n= 0; n < 2; n++)
|
|
ThrowGib (self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC);
|
|
gi.sound (self, CHAN_VOICE, sound_die, 1, ATTN_NORM, 0);
|
|
BecomeExplosion1(self);
|
|
}
|
|
|
|
|
|
/*QUAKED monster_flyer (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight
|
|
*/
|
|
void SP_monster_flyer (edict_t *self)
|
|
{
|
|
if (deathmatch->value)
|
|
{
|
|
G_FreeEdict (self);
|
|
return;
|
|
}
|
|
|
|
// fix a map bug in jail5.bsp
|
|
if (!Q_stricmp(level.mapname, "jail5") && (self->s.origin[2] == -104))
|
|
{
|
|
self->targetname = self->target;
|
|
self->target = NULL;
|
|
}
|
|
|
|
sound_sight = gi.soundindex ("flyer/flysght1.wav");
|
|
sound_idle = gi.soundindex ("flyer/flysrch1.wav");
|
|
sound_pain1 = gi.soundindex ("flyer/flypain1.wav");
|
|
sound_pain2 = gi.soundindex ("flyer/flypain2.wav");
|
|
sound_slash = gi.soundindex ("flyer/flyatck2.wav");
|
|
sound_sproing = gi.soundindex ("flyer/flyatck1.wav");
|
|
sound_die = gi.soundindex ("flyer/flydeth1.wav");
|
|
|
|
gi.soundindex ("flyer/flyatck3.wav");
|
|
|
|
// Lazarus: special purpose skins
|
|
if ( self->style )
|
|
{
|
|
PatchMonsterModel("models/monsters/flyer/tris.md2");
|
|
self->s.skinnum = self->style * 2;
|
|
}
|
|
|
|
self->s.modelindex = gi.modelindex ("models/monsters/flyer/tris.md2");
|
|
VectorSet (self->mins, -16, -16, -24);
|
|
VectorSet (self->maxs, 16, 16, 16);
|
|
self->movetype = MOVETYPE_STEP;
|
|
self->solid = SOLID_BBOX;
|
|
|
|
self->s.sound = gi.soundindex ("flyer/flyidle1.wav");
|
|
|
|
// Lazarus: mapper-configurable health
|
|
if (!self->health)
|
|
self->health = 50;
|
|
if (!self->mass)
|
|
self->mass = 50;
|
|
|
|
self->pain = flyer_pain;
|
|
self->die = flyer_die;
|
|
|
|
self->monsterinfo.stand = flyer_stand;
|
|
self->monsterinfo.walk = flyer_walk;
|
|
self->monsterinfo.run = flyer_run;
|
|
self->monsterinfo.attack = flyer_attack;
|
|
self->monsterinfo.melee = flyer_melee;
|
|
self->monsterinfo.sight = flyer_sight;
|
|
self->monsterinfo.idle = flyer_idle;
|
|
|
|
// Knightmare- added sparks and blood type
|
|
if (!self->blood_type)
|
|
self->blood_type = 3; //sparks and blood
|
|
|
|
// Lazarus
|
|
if (self->powerarmor) {
|
|
self->monsterinfo.power_armor_type = POWER_ARMOR_SHIELD;
|
|
self->monsterinfo.power_armor_power = self->powerarmor;
|
|
}
|
|
self->common_name = "Flyer";
|
|
self->class_id = ENTITY_MONSTER_FLYER;
|
|
|
|
gi.linkentity (self);
|
|
|
|
self->monsterinfo.currentmove = &flyer_move_stand;
|
|
self->monsterinfo.scale = MODEL_SCALE;
|
|
|
|
flymonster_start (self);
|
|
}
|