/* ============================================================================== 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); }