474 lines
9.4 KiB
C
474 lines
9.4 KiB
C
/*
|
|
==============================================================================
|
|
|
|
handler handler
|
|
|
|
==============================================================================
|
|
*/
|
|
|
|
#include "g_local.h"
|
|
#include "z_handler.h"
|
|
|
|
|
|
|
|
|
|
void handler_standWhatNext (edict_t *self);
|
|
void handler_standSitWhatNext (edict_t *self);
|
|
void handler_stand (edict_t *self);
|
|
void handler_attack (edict_t *self);
|
|
void hound_createHound(edict_t *self, float healthPercent);
|
|
void handler_ConvertToInfantry(edict_t *self);
|
|
|
|
void hound_sight (edict_t *self, edict_t *other);
|
|
void infantry_sight (edict_t *self, edict_t *other);
|
|
|
|
static int sound_attack;
|
|
static int sound_scratch;
|
|
static int sound_sitdown;
|
|
static int sound_standup;
|
|
|
|
|
|
void handler_sight (edict_t *self, edict_t *other)
|
|
{
|
|
hound_sight(self, other);
|
|
infantry_sight(self, other);
|
|
}
|
|
|
|
//
|
|
// STAND
|
|
//
|
|
|
|
|
|
|
|
mframe_t handler_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
|
|
};
|
|
mmove_t handler_stand1 = {FRAME_stand1start, FRAME_stand1end, handler_frames_stand1, handler_standSitWhatNext};
|
|
|
|
|
|
void handler_scratch(edict_t *self)
|
|
{
|
|
// gi.sound (self, CHAN_VOICE, sound_scratch, 1, ATTN_NORM, 0);
|
|
}
|
|
|
|
|
|
|
|
mframe_t handler_frames_stand2 [] =
|
|
{
|
|
ai_stand, 0, handler_scratch,
|
|
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 handler_stand2 = {FRAME_stand2start, FRAME_stand2end, handler_frames_stand2, handler_standSitWhatNext};
|
|
|
|
|
|
|
|
|
|
mframe_t handler_frames_stand3 [] =
|
|
{
|
|
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 handler_stand3 = {FRAME_stand3start, FRAME_stand3end, handler_frames_stand3, handler_standWhatNext};
|
|
|
|
|
|
void handler_standup(edict_t *self)
|
|
{
|
|
// gi.sound (self, CHAN_VOICE, sound_standup, 1, ATTN_NORM, 0);
|
|
}
|
|
|
|
|
|
mframe_t handler_frames_stand4 [] =
|
|
{
|
|
ai_stand, 0, handler_standup,
|
|
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 handler_stand4 = {FRAME_stand4start, FRAME_stand4end, handler_frames_stand4, handler_standWhatNext};
|
|
|
|
|
|
|
|
void handler_sitdown(edict_t *self)
|
|
{
|
|
// gi.sound (self, CHAN_VOICE, sound_sitdown, 1, ATTN_NORM, 0);
|
|
}
|
|
|
|
|
|
mframe_t handler_frames_stand5 [] =
|
|
{
|
|
ai_stand, 0, handler_sitdown,
|
|
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 handler_stand5 = {FRAME_stand5start, FRAME_stand5end, handler_frames_stand5, handler_standSitWhatNext};
|
|
|
|
|
|
/*
|
|
00-30 Idle1 (sitting down)
|
|
31-59 Idle2 (pat on head)
|
|
60-89 Idle3 (standing)
|
|
90-100 Stand (standing up from sitting)
|
|
101-110 Sit (sitting down from standing)
|
|
111-128 Restrain (handler lets go)
|
|
*/
|
|
void handler_standWhatNext (edict_t *self)
|
|
{
|
|
float r = random();
|
|
|
|
if(r < 0.90)
|
|
{
|
|
self->monsterinfo.currentmove = &handler_stand3;
|
|
}
|
|
else
|
|
{
|
|
self->monsterinfo.currentmove = &handler_stand5;
|
|
}
|
|
}
|
|
|
|
|
|
void handler_standSitWhatNext (edict_t *self)
|
|
{
|
|
float r = random();
|
|
|
|
if(r < 0.70)
|
|
{
|
|
self->monsterinfo.currentmove = &handler_stand1;
|
|
}
|
|
else if(r < 0.85)
|
|
{
|
|
self->monsterinfo.currentmove = &handler_stand2;
|
|
}
|
|
else
|
|
{
|
|
self->monsterinfo.currentmove = &handler_stand4;
|
|
}
|
|
}
|
|
|
|
|
|
void handler_stand (edict_t *self)
|
|
{
|
|
float r = random();
|
|
|
|
if(self->monsterinfo.currentmove != &handler_stand1 &&
|
|
self->monsterinfo.currentmove != &handler_stand2 &&
|
|
self->monsterinfo.currentmove != &handler_stand3 &&
|
|
self->monsterinfo.currentmove != &handler_stand4 &&
|
|
self->monsterinfo.currentmove != &handler_stand5)
|
|
{
|
|
self->monsterinfo.currentmove = &handler_stand3;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
// PAIN
|
|
//
|
|
|
|
void handler_pain (edict_t *self, edict_t *other, float kick, int damage)
|
|
{
|
|
// if (self->health < (self->max_health / 2))
|
|
// self->s.skinnum = 1;
|
|
}
|
|
|
|
|
|
//
|
|
// ATTACK and MELEE
|
|
//
|
|
|
|
void handler_createHound(edict_t *self)
|
|
{
|
|
self->s.modelindex2 = 0;
|
|
hound_createHound(self, (self->health / 175.0));
|
|
}
|
|
|
|
|
|
void CheckIdleLoop(edict_t *self)
|
|
{
|
|
if(!self->powerarmor_time && self->spawnflags & 8)
|
|
{
|
|
self->powerarmor_time = level.time + (FRAMETIME * random() * 3);
|
|
}
|
|
|
|
if(self->powerarmor_time > level.time)
|
|
{
|
|
self->s.frame -= 2;
|
|
}
|
|
}
|
|
|
|
void CheckForEnemy(edict_t *self)
|
|
{
|
|
if(self->enemy && (self->enemy->client || (self->enemy->svflags & SVF_MONSTER)))
|
|
{
|
|
self->powerarmor_time = 0;
|
|
return;
|
|
}
|
|
|
|
if(self->powerarmor_time < level.time)
|
|
{
|
|
self->enemy = NULL;
|
|
handler_stand(self);
|
|
return;
|
|
}
|
|
|
|
self->s.frame--;
|
|
}
|
|
|
|
void StartCount(edict_t *self)
|
|
{
|
|
self->powerarmor_time = level.time + 3;
|
|
}
|
|
|
|
mframe_t handler_frames_attack1 [] =
|
|
{
|
|
ai_run, 0, StartCount,
|
|
ai_run, 0, CheckForEnemy,
|
|
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, CheckIdleLoop,
|
|
ai_charge, 0, NULL,
|
|
|
|
ai_charge, 0, NULL,
|
|
ai_charge, 0, handler_createHound,
|
|
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 handler_move_attack1 = {FRAME_attack1Start, FRAME_attack1End, handler_frames_attack1, handler_ConvertToInfantry};
|
|
|
|
|
|
void handler_attack (edict_t *self)
|
|
{
|
|
gi.sound (self, CHAN_VOICE, sound_attack, 1, ATTN_NORM, 0);
|
|
|
|
self->monsterinfo.currentmove = &handler_move_attack1;
|
|
|
|
self->powerarmor_time = 0;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
===
|
|
Death Stuff Starts
|
|
===
|
|
*/
|
|
|
|
void handler_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 handler_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
|
|
{
|
|
self->health = 1; // can't die while together...
|
|
}
|
|
|
|
|
|
/*
|
|
===
|
|
End Death Stuff
|
|
===
|
|
*/
|
|
|
|
void SP_monster_infantry_precache(void);
|
|
void SP_monster_hound_precache();
|
|
|
|
void SP_monster_handler_precache(void)
|
|
{
|
|
SP_monster_infantry_precache();
|
|
SP_monster_hound_precache();
|
|
|
|
sound_attack = gi.soundindex("monsters/guard/hhattack.wav");
|
|
/*
|
|
sound_scratch = gi.soundindex("monsters/guard/hhscratch.wav");
|
|
sound_sitdown = gi.soundindex("monsters/guard/hhsitdown.wav");
|
|
sound_standup = gi.soundindex("monsters/guard/hhstandup.wav");
|
|
*/
|
|
}
|
|
|
|
|
|
/*QUAKED monster_handler (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight
|
|
*/
|
|
void SP_monster_handler (edict_t *self)
|
|
{
|
|
if (deathmatch->value)
|
|
{
|
|
G_FreeEdict (self);
|
|
return;
|
|
}
|
|
|
|
SP_monster_handler_precache();
|
|
|
|
self->s.modelindex = gi.modelindex ("models/monsters/guard/handler/tris.md2");
|
|
self->s.modelindex2 = gi.modelindex ("models/monsters/guard/hound/tris.md2");
|
|
|
|
/*
|
|
Handler
|
|
X = -36 to 3
|
|
Y = -3 to 27
|
|
Z = -24 to 28
|
|
|
|
Hound
|
|
X = -12 to 11
|
|
Y = -30 to 30
|
|
Z = -24 to 8
|
|
*/
|
|
|
|
VectorSet (self->mins, -32, -32, -24);
|
|
VectorSet (self->maxs, 32, 32, 32);
|
|
self->movetype = MOVETYPE_STEP;
|
|
self->solid = SOLID_BBOX;
|
|
|
|
self->health = 175;
|
|
self->gib_health = -50;
|
|
self->mass = 250;
|
|
|
|
self->pain = handler_pain;
|
|
self->die = handler_die;
|
|
|
|
self->monsterinfo.stand = handler_stand;
|
|
self->monsterinfo.walk = handler_stand;
|
|
self->monsterinfo.run = handler_attack;
|
|
self->monsterinfo.attack = handler_attack;
|
|
self->monsterinfo.melee = NULL;
|
|
self->monsterinfo.sight = handler_sight;
|
|
self->monsterinfo.idle = NULL;
|
|
|
|
gi.linkentity (self);
|
|
|
|
self->monsterinfo.currentmove = &handler_stand1;
|
|
self->monsterinfo.scale = MODEL_SCALE;
|
|
|
|
if(!(self->spawnflags & 16))
|
|
{
|
|
level.total_monsters++; // add one for the hound which is created later :)
|
|
}
|
|
|
|
walkmonster_start (self);
|
|
}
|