quake2-zaero/z_handler.c
1998-12-06 00:00:00 +00:00

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);
}