mirror of
https://github.com/id-Software/quake2-rerelease-dll.git
synced 2025-02-14 15:51:42 +00:00
692 lines
17 KiB
C++
692 lines
17 KiB
C++
// Copyright (c) ZeniMax Media Inc.
|
|
// Licensed under the GNU General Public License 2.0.
|
|
/*
|
|
==============================================================================
|
|
|
|
insane
|
|
|
|
==============================================================================
|
|
*/
|
|
|
|
#include "g_local.h"
|
|
#include "m_insane.h"
|
|
|
|
constexpr spawnflags_t SPAWNFLAG_INSANE_CRAWL = 4_spawnflag;
|
|
constexpr spawnflags_t SPAWNFLAG_INSANE_CRUCIFIED = 8_spawnflag;
|
|
constexpr spawnflags_t SPAWNFLAG_INSANE_STAND_GROUND = 16_spawnflag;
|
|
constexpr spawnflags_t SPAWNFLAG_INSANE_ALWAYS_STAND = 32_spawnflag;
|
|
constexpr spawnflags_t SPAWNFLAG_INSANE_QUIET = 64_spawnflag;
|
|
|
|
static int sound_fist;
|
|
static int sound_shake;
|
|
static int sound_moan;
|
|
static int sound_scream[8];
|
|
|
|
void insane_fist(edict_t *self)
|
|
{
|
|
gi.sound(self, CHAN_VOICE, sound_fist, 1, ATTN_IDLE, 0);
|
|
}
|
|
|
|
void insane_shake(edict_t *self)
|
|
{
|
|
if (!self->spawnflags.has(SPAWNFLAG_INSANE_QUIET))
|
|
gi.sound(self, CHAN_VOICE, sound_shake, 1, ATTN_IDLE, 0);
|
|
}
|
|
|
|
extern const mmove_t insane_move_cross, insane_move_struggle_cross;
|
|
|
|
void insane_moan(edict_t *self)
|
|
{
|
|
if (self->spawnflags.has(SPAWNFLAG_INSANE_QUIET))
|
|
return;
|
|
|
|
// Paril: don't moan every second
|
|
if (self->monsterinfo.attack_finished < level.time)
|
|
{
|
|
gi.sound(self, CHAN_VOICE, sound_moan, 1, ATTN_IDLE, 0);
|
|
self->monsterinfo.attack_finished = level.time + random_time(1_sec, 3_sec);
|
|
}
|
|
}
|
|
|
|
void insane_scream(edict_t *self)
|
|
{
|
|
if (self->spawnflags.has(SPAWNFLAG_INSANE_QUIET))
|
|
return;
|
|
|
|
// Paril: don't moan every second
|
|
if (self->monsterinfo.attack_finished < level.time)
|
|
{
|
|
gi.sound(self, CHAN_VOICE, random_element(sound_scream), 1, ATTN_IDLE, 0);
|
|
self->monsterinfo.attack_finished = level.time + random_time(1_sec, 3_sec);
|
|
}
|
|
}
|
|
|
|
void insane_stand(edict_t *self);
|
|
void insane_dead(edict_t *self);
|
|
void insane_cross(edict_t *self);
|
|
void insane_walk(edict_t *self);
|
|
void insane_run(edict_t *self);
|
|
void insane_checkdown(edict_t *self);
|
|
void insane_checkup(edict_t *self);
|
|
void insane_onground(edict_t *self);
|
|
|
|
// Paril: unused atm because it breaks N64.
|
|
// may fix later
|
|
void insane_shrink(edict_t *self)
|
|
{
|
|
self->maxs[2] = 0;
|
|
self->svflags |= SVF_DEADMONSTER;
|
|
gi.linkentity(self);
|
|
}
|
|
|
|
mframe_t insane_frames_stand_normal[] = {
|
|
{ ai_stand },
|
|
{ ai_stand },
|
|
{ ai_stand },
|
|
{ ai_stand },
|
|
{ ai_stand },
|
|
{ ai_stand, 0, insane_checkdown }
|
|
};
|
|
MMOVE_T(insane_move_stand_normal) = { FRAME_stand60, FRAME_stand65, insane_frames_stand_normal, insane_stand };
|
|
|
|
mframe_t insane_frames_stand_insane[] = {
|
|
{ ai_stand, 0, insane_shake },
|
|
{ ai_stand },
|
|
{ ai_stand },
|
|
{ ai_stand },
|
|
{ ai_stand },
|
|
{ ai_stand },
|
|
{ ai_stand },
|
|
{ ai_stand },
|
|
{ ai_stand },
|
|
{ ai_stand },
|
|
{ ai_stand },
|
|
{ ai_stand },
|
|
{ ai_stand },
|
|
{ ai_stand },
|
|
{ ai_stand },
|
|
{ ai_stand },
|
|
{ ai_stand },
|
|
{ ai_stand },
|
|
{ ai_stand },
|
|
{ ai_stand },
|
|
{ ai_stand },
|
|
{ ai_stand },
|
|
{ ai_stand },
|
|
{ ai_stand },
|
|
{ ai_stand },
|
|
{ ai_stand },
|
|
{ ai_stand },
|
|
{ ai_stand },
|
|
{ ai_stand },
|
|
{ ai_stand, 0, insane_checkdown }
|
|
};
|
|
MMOVE_T(insane_move_stand_insane) = { FRAME_stand65, FRAME_stand94, insane_frames_stand_insane, insane_stand };
|
|
|
|
mframe_t insane_frames_uptodown[] = {
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move, 0, insane_moan },
|
|
{ ai_move },//, 0, monster_duck_down },
|
|
{ ai_move },
|
|
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
|
|
{ ai_move, 2.7f },
|
|
{ ai_move, 4.1f },
|
|
{ ai_move, 6 },
|
|
{ ai_move, 7.6f },
|
|
{ ai_move, 3.6f },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move, 0, insane_fist },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move, 0, insane_fist },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move }
|
|
};
|
|
MMOVE_T(insane_move_uptodown) = { FRAME_stand1, FRAME_stand40, insane_frames_uptodown, insane_onground };
|
|
|
|
mframe_t insane_frames_downtoup[] = {
|
|
{ ai_move, -0.7f }, // 41
|
|
{ ai_move, -1.2f }, // 42
|
|
{ ai_move, -1.5f }, // 43
|
|
{ ai_move, -4.5f }, // 44
|
|
{ ai_move, -3.5f }, // 45
|
|
{ ai_move, -0.2f }, // 46
|
|
{ ai_move }, // 47
|
|
{ ai_move, -1.3f }, // 48
|
|
{ ai_move, -3 }, // 49
|
|
{ ai_move, -2 }, // 50
|
|
{ ai_move },//, 0, monster_duck_up }, // 51
|
|
{ ai_move }, // 52
|
|
{ ai_move }, // 53
|
|
{ ai_move, -3.3f }, // 54
|
|
{ ai_move, -1.6f }, // 55
|
|
{ ai_move, -0.3f }, // 56
|
|
{ ai_move }, // 57
|
|
{ ai_move }, // 58
|
|
{ ai_move } // 59
|
|
};
|
|
MMOVE_T(insane_move_downtoup) = { FRAME_stand41, FRAME_stand59, insane_frames_downtoup, insane_stand };
|
|
|
|
mframe_t insane_frames_jumpdown[] = {
|
|
{ ai_move, 0.2f },
|
|
{ ai_move, 11.5f },
|
|
{ ai_move, 5.1f },
|
|
{ ai_move, 7.1f },
|
|
{ ai_move }
|
|
};
|
|
MMOVE_T(insane_move_jumpdown) = { FRAME_stand96, FRAME_stand100, insane_frames_jumpdown, insane_onground };
|
|
|
|
mframe_t insane_frames_down[] = {
|
|
{ ai_move }, // 100
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move }, // 110
|
|
{ ai_move, -1.7f },
|
|
{ ai_move, -1.6f },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move, 0, insane_fist },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move }, // 120
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move }, // 130
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move, 0, insane_moan },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move }, // 140
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move }, // 150
|
|
{ ai_move, 0.5f },
|
|
{ ai_move },
|
|
{ ai_move, -0.2f, insane_scream },
|
|
{ ai_move },
|
|
{ ai_move, 0.2f },
|
|
{ ai_move, 0.4f },
|
|
{ ai_move, 0.6f },
|
|
{ ai_move, 0.8f },
|
|
{ ai_move, 0.7f },
|
|
{ ai_move, 0, insane_checkup } // 160
|
|
};
|
|
MMOVE_T(insane_move_down) = { FRAME_stand100, FRAME_stand160, insane_frames_down, insane_onground };
|
|
|
|
mframe_t insane_frames_walk_normal[] = {
|
|
{ ai_walk, 0, insane_scream },
|
|
{ ai_walk, 2.5f },
|
|
{ ai_walk, 3.5f },
|
|
{ ai_walk, 1.7f },
|
|
{ ai_walk, 2.3f },
|
|
{ ai_walk, 2.4f },
|
|
{ ai_walk, 2.2f, monster_footstep },
|
|
{ ai_walk, 4.2f },
|
|
{ ai_walk, 5.6f },
|
|
{ ai_walk, 3.3f },
|
|
{ ai_walk, 2.4f },
|
|
{ ai_walk, 0.9f },
|
|
{ ai_walk, 0, monster_footstep }
|
|
};
|
|
MMOVE_T(insane_move_walk_normal) = { FRAME_walk27, FRAME_walk39, insane_frames_walk_normal, insane_walk };
|
|
MMOVE_T(insane_move_run_normal) = { FRAME_walk27, FRAME_walk39, insane_frames_walk_normal, insane_run };
|
|
|
|
mframe_t insane_frames_walk_insane[] = {
|
|
{ ai_walk, 0, insane_scream }, // walk 1
|
|
{ ai_walk, 3.4f }, // walk 2
|
|
{ ai_walk, 3.6f }, // 3
|
|
{ ai_walk, 2.9f }, // 4
|
|
{ ai_walk, 2.2f }, // 5
|
|
{ ai_walk, 2.6f, monster_footstep }, // 6
|
|
{ ai_walk }, // 7
|
|
{ ai_walk, 0.7f }, // 8
|
|
{ ai_walk, 4.8f }, // 9
|
|
{ ai_walk, 5.3f }, // 10
|
|
{ ai_walk, 1.1f }, // 11
|
|
{ ai_walk, 2, monster_footstep }, // 12
|
|
{ ai_walk, 0.5f }, // 13
|
|
{ ai_walk }, // 14
|
|
{ ai_walk }, // 15
|
|
{ ai_walk, 4.9f }, // 16
|
|
{ ai_walk, 6.7f }, // 17
|
|
{ ai_walk, 3.8f }, // 18
|
|
{ ai_walk, 2, monster_footstep }, // 19
|
|
{ ai_walk, 0.2f }, // 20
|
|
{ ai_walk }, // 21
|
|
{ ai_walk, 3.4f }, // 22
|
|
{ ai_walk, 6.4f }, // 23
|
|
{ ai_walk, 5 }, // 24
|
|
{ ai_walk, 1.8f, monster_footstep }, // 25
|
|
{ ai_walk } // 26
|
|
};
|
|
MMOVE_T(insane_move_walk_insane) = { FRAME_walk1, FRAME_walk26, insane_frames_walk_insane, insane_walk };
|
|
MMOVE_T(insane_move_run_insane) = { FRAME_walk1, FRAME_walk26, insane_frames_walk_insane, insane_run };
|
|
|
|
mframe_t insane_frames_stand_pain[] = {
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move, 0, monster_footstep },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move, 0, monster_footstep }
|
|
};
|
|
MMOVE_T(insane_move_stand_pain) = { FRAME_st_pain2, FRAME_st_pain12, insane_frames_stand_pain, insane_run };
|
|
|
|
mframe_t insane_frames_stand_death[] = {
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move, 0, monster_footstep },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move, 0, monster_footstep },
|
|
{ ai_move },
|
|
{ ai_move, 0, monster_footstep },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move }
|
|
};
|
|
MMOVE_T(insane_move_stand_death) = { FRAME_st_death2, FRAME_st_death18, insane_frames_stand_death, insane_dead };
|
|
|
|
mframe_t insane_frames_crawl[] = {
|
|
{ ai_walk, 0, insane_scream },
|
|
{ ai_walk, 1.5f },
|
|
{ ai_walk, 2.1f },
|
|
{ ai_walk, 3.6f },
|
|
{ ai_walk, 2, monster_footstep },
|
|
{ ai_walk, 0.9f },
|
|
{ ai_walk, 3 },
|
|
{ ai_walk, 3.4f },
|
|
{ ai_walk, 2.4f, monster_footstep }
|
|
};
|
|
MMOVE_T(insane_move_crawl) = { FRAME_crawl1, FRAME_crawl9, insane_frames_crawl, nullptr };
|
|
MMOVE_T(insane_move_runcrawl) = { FRAME_crawl1, FRAME_crawl9, insane_frames_crawl, nullptr };
|
|
|
|
mframe_t insane_frames_crawl_pain[] = {
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move }
|
|
};
|
|
MMOVE_T(insane_move_crawl_pain) = { FRAME_cr_pain2, FRAME_cr_pain10, insane_frames_crawl_pain, insane_run };
|
|
|
|
mframe_t insane_frames_crawl_death[] = {
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move }
|
|
};
|
|
MMOVE_T(insane_move_crawl_death) = { FRAME_cr_death10, FRAME_cr_death16, insane_frames_crawl_death, insane_dead };
|
|
|
|
mframe_t insane_frames_cross[] = {
|
|
{ ai_move, 0, insane_moan },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move }
|
|
};
|
|
MMOVE_T(insane_move_cross) = { FRAME_cross1, FRAME_cross15, insane_frames_cross, insane_cross };
|
|
|
|
mframe_t insane_frames_struggle_cross[] = {
|
|
{ ai_move, 0, insane_scream },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move },
|
|
{ ai_move }
|
|
};
|
|
MMOVE_T(insane_move_struggle_cross) = { FRAME_cross16, FRAME_cross30, insane_frames_struggle_cross, insane_cross };
|
|
|
|
void insane_cross(edict_t *self)
|
|
{
|
|
if (frandom() < 0.8f)
|
|
M_SetAnimation(self, &insane_move_cross);
|
|
else
|
|
M_SetAnimation(self, &insane_move_struggle_cross);
|
|
}
|
|
|
|
MONSTERINFO_WALK(insane_walk) (edict_t *self) -> void
|
|
{
|
|
if (self->spawnflags.has(SPAWNFLAG_INSANE_STAND_GROUND)) // Hold Ground?
|
|
if (self->s.frame == FRAME_cr_pain10)
|
|
{
|
|
M_SetAnimation(self, &insane_move_down);
|
|
//monster_duck_down(self);
|
|
return;
|
|
}
|
|
if (self->spawnflags.has(SPAWNFLAG_INSANE_CRAWL))
|
|
M_SetAnimation(self, &insane_move_crawl);
|
|
else if (frandom() <= 0.5f)
|
|
M_SetAnimation(self, &insane_move_walk_normal);
|
|
else
|
|
M_SetAnimation(self, &insane_move_walk_insane);
|
|
}
|
|
|
|
MONSTERINFO_RUN(insane_run) (edict_t *self) -> void
|
|
{
|
|
if (self->spawnflags.has(SPAWNFLAG_INSANE_STAND_GROUND)) // Hold Ground?
|
|
if (self->s.frame == FRAME_cr_pain10)
|
|
{
|
|
M_SetAnimation(self, &insane_move_down);
|
|
//monster_duck_down(self);
|
|
return;
|
|
}
|
|
if (self->spawnflags.has(SPAWNFLAG_INSANE_CRAWL) || (self->s.frame >= FRAME_cr_pain2 && self->s.frame <= FRAME_cr_pain10) || (self->s.frame >= FRAME_crawl1 && self->s.frame <= FRAME_crawl9) ||
|
|
(self->s.frame >= FRAME_stand99 && self->s.frame <= FRAME_stand160)) // Crawling?
|
|
M_SetAnimation(self, &insane_move_runcrawl);
|
|
else if (frandom() <= 0.5f) // Else, mix it up
|
|
{
|
|
M_SetAnimation(self, &insane_move_run_normal);
|
|
//monster_duck_up(self);
|
|
}
|
|
else
|
|
{
|
|
M_SetAnimation(self, &insane_move_run_insane);
|
|
//monster_duck_up(self);
|
|
}
|
|
}
|
|
|
|
PAIN(insane_pain) (edict_t *self, edict_t *other, float kick, int damage, const mod_t &mod) -> void
|
|
{
|
|
int l, r;
|
|
|
|
if (level.time < self->pain_debounce_time)
|
|
return;
|
|
|
|
self->pain_debounce_time = level.time + 3_sec;
|
|
|
|
r = 1 + brandom();
|
|
if (self->health < 25)
|
|
l = 25;
|
|
else if (self->health < 50)
|
|
l = 50;
|
|
else if (self->health < 75)
|
|
l = 75;
|
|
else
|
|
l = 100;
|
|
gi.sound(self, CHAN_VOICE, gi.soundindex(G_Fmt("player/male/pain{}_{}.wav", l, r).data()), 1, ATTN_IDLE, 0);
|
|
|
|
// Don't go into pain frames if crucified.
|
|
if (self->spawnflags.has(SPAWNFLAG_INSANE_CRUCIFIED))
|
|
{
|
|
M_SetAnimation(self, &insane_move_struggle_cross);
|
|
return;
|
|
}
|
|
|
|
if (((self->s.frame >= FRAME_crawl1) && (self->s.frame <= FRAME_crawl9)) || ((self->s.frame >= FRAME_stand99) && (self->s.frame <= FRAME_stand160)) || ((self->s.frame >= FRAME_stand1 && self->s.frame <= FRAME_stand40)))
|
|
{
|
|
M_SetAnimation(self, &insane_move_crawl_pain);
|
|
}
|
|
else
|
|
{
|
|
M_SetAnimation(self, &insane_move_stand_pain);
|
|
//monster_duck_up(self);
|
|
}
|
|
}
|
|
|
|
void insane_onground(edict_t *self)
|
|
{
|
|
M_SetAnimation(self, &insane_move_down);
|
|
//monster_duck_down(self);
|
|
}
|
|
|
|
void insane_checkdown(edict_t *self)
|
|
{
|
|
// if ( (self->s.frame == FRAME_stand94) || (self->s.frame == FRAME_stand65) )
|
|
if (self->spawnflags.has(SPAWNFLAG_INSANE_ALWAYS_STAND)) // Always stand
|
|
return;
|
|
if (frandom() < 0.3f)
|
|
{
|
|
if (frandom() < 0.5f)
|
|
M_SetAnimation(self, &insane_move_uptodown);
|
|
else
|
|
M_SetAnimation(self, &insane_move_jumpdown);
|
|
}
|
|
}
|
|
|
|
void insane_checkup(edict_t *self)
|
|
{
|
|
// If Hold_Ground and Crawl are set
|
|
if (self->spawnflags.has_all(SPAWNFLAG_INSANE_CRAWL | SPAWNFLAG_INSANE_STAND_GROUND))
|
|
return;
|
|
if (frandom() < 0.5f)
|
|
{
|
|
M_SetAnimation(self, &insane_move_downtoup);
|
|
//monster_duck_up(self);
|
|
}
|
|
}
|
|
|
|
MONSTERINFO_STAND(insane_stand) (edict_t *self) -> void
|
|
{
|
|
if (self->spawnflags.has(SPAWNFLAG_INSANE_CRUCIFIED)) // If crucified
|
|
{
|
|
M_SetAnimation(self, &insane_move_cross);
|
|
self->monsterinfo.aiflags |= AI_STAND_GROUND;
|
|
}
|
|
// If Hold_Ground and Crawl are set
|
|
else if (self->spawnflags.has_all(SPAWNFLAG_INSANE_CRAWL | SPAWNFLAG_INSANE_STAND_GROUND))
|
|
{
|
|
M_SetAnimation(self, &insane_move_down);
|
|
//monster_duck_down(self);
|
|
}
|
|
else if (frandom() < 0.5f)
|
|
M_SetAnimation(self, &insane_move_stand_normal);
|
|
else
|
|
M_SetAnimation(self, &insane_move_stand_insane);
|
|
}
|
|
|
|
void insane_dead(edict_t *self)
|
|
{
|
|
if (self->spawnflags.has(SPAWNFLAG_INSANE_CRUCIFIED))
|
|
{
|
|
self->flags |= FL_FLY;
|
|
}
|
|
else
|
|
{
|
|
self->mins = { -16, -16, -24 };
|
|
self->maxs = { 16, 16, -8 };
|
|
self->movetype = MOVETYPE_TOSS;
|
|
}
|
|
monster_dead(self);
|
|
}
|
|
|
|
DIE(insane_die) (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, const vec3_t &point, const mod_t &mod) -> void
|
|
{
|
|
if (M_CheckGib(self, mod))
|
|
{
|
|
gi.sound(self, CHAN_VOICE, gi.soundindex("misc/udeath.wav"), 1, ATTN_IDLE, 0);
|
|
ThrowGibs(self, damage, {
|
|
{ 2, "models/objects/gibs/bone/tris.md2" },
|
|
{ 4, "models/objects/gibs/sm_meat/tris.md2" },
|
|
{ "models/objects/gibs/head2/tris.md2", GIB_HEAD }
|
|
});
|
|
self->deadflag = true;
|
|
return;
|
|
}
|
|
|
|
if (self->deadflag)
|
|
return;
|
|
|
|
gi.sound(self, CHAN_VOICE, gi.soundindex(G_Fmt("player/male/death{}.wav", irandom(1, 5)).data()), 1, ATTN_IDLE, 0);
|
|
|
|
self->deadflag = true;
|
|
self->takedamage = true;
|
|
|
|
if (self->spawnflags.has(SPAWNFLAG_INSANE_CRUCIFIED))
|
|
{
|
|
insane_dead(self);
|
|
}
|
|
else
|
|
{
|
|
if (((self->s.frame >= FRAME_crawl1) && (self->s.frame <= FRAME_crawl9)) || ((self->s.frame >= FRAME_stand99) && (self->s.frame <= FRAME_stand160)))
|
|
M_SetAnimation(self, &insane_move_crawl_death);
|
|
else
|
|
M_SetAnimation(self, &insane_move_stand_death);
|
|
}
|
|
}
|
|
|
|
/*QUAKED misc_insane (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn CRAWL CRUCIFIED STAND_GROUND ALWAYS_STAND QUIET
|
|
*/
|
|
void SP_misc_insane(edict_t *self)
|
|
{
|
|
// static int skin = 0; //@@
|
|
|
|
if ( !M_AllowSpawn( self ) ) {
|
|
G_FreeEdict( self );
|
|
return;
|
|
}
|
|
|
|
sound_fist = gi.soundindex("insane/insane11.wav");
|
|
if (!self->spawnflags.has(SPAWNFLAG_INSANE_QUIET))
|
|
{
|
|
sound_shake = gi.soundindex("insane/insane5.wav");
|
|
sound_moan = gi.soundindex("insane/insane7.wav");
|
|
sound_scream[0] = gi.soundindex("insane/insane1.wav");
|
|
sound_scream[1] = gi.soundindex("insane/insane2.wav");
|
|
sound_scream[2] = gi.soundindex("insane/insane3.wav");
|
|
sound_scream[3] = gi.soundindex("insane/insane4.wav");
|
|
sound_scream[4] = gi.soundindex("insane/insane6.wav");
|
|
sound_scream[5] = gi.soundindex("insane/insane8.wav");
|
|
sound_scream[6] = gi.soundindex("insane/insane9.wav");
|
|
sound_scream[7] = gi.soundindex("insane/insane10.wav");
|
|
}
|
|
|
|
self->movetype = MOVETYPE_STEP;
|
|
self->solid = SOLID_BBOX;
|
|
self->s.modelindex = gi.modelindex("models/monsters/insane/tris.md2");
|
|
|
|
self->mins = { -16, -16, -24 };
|
|
self->maxs = { 16, 16, 32 };
|
|
|
|
self->health = 100 * st.health_multiplier;
|
|
self->gib_health = -50;
|
|
self->mass = 300;
|
|
|
|
self->pain = insane_pain;
|
|
self->die = insane_die;
|
|
|
|
self->monsterinfo.stand = insane_stand;
|
|
self->monsterinfo.walk = insane_walk;
|
|
self->monsterinfo.run = insane_run;
|
|
self->monsterinfo.dodge = nullptr;
|
|
self->monsterinfo.attack = nullptr;
|
|
self->monsterinfo.melee = nullptr;
|
|
self->monsterinfo.sight = nullptr;
|
|
self->monsterinfo.aiflags |= AI_GOOD_GUY;
|
|
|
|
//@@
|
|
// self->s.skinnum = skin;
|
|
// skin++;
|
|
// if (skin > 12)
|
|
// skin = 0;
|
|
|
|
gi.linkentity(self);
|
|
|
|
if (self->spawnflags.has(SPAWNFLAG_INSANE_STAND_GROUND)) // Stand Ground
|
|
self->monsterinfo.aiflags |= AI_STAND_GROUND;
|
|
|
|
M_SetAnimation(self, &insane_move_stand_normal);
|
|
|
|
self->monsterinfo.scale = MODEL_SCALE;
|
|
|
|
if (self->spawnflags.has(SPAWNFLAG_INSANE_CRUCIFIED)) // Crucified ?
|
|
{
|
|
self->flags |= FL_NO_KNOCKBACK | FL_STATIONARY;
|
|
stationarymonster_start(self);
|
|
}
|
|
else
|
|
walkmonster_start(self);
|
|
|
|
self->s.skinnum = irandom(3);
|
|
}
|