ew-progs/ew/monsters/hhound.qc
2011-09-06 00:00:00 +00:00

504 lines
16 KiB
C++

/*
==============================================================================
Hell Hound
coded by Michael Rogers a.k.a Xsniper
http://xsniper.virtualave.net/
some code done by iD software
==============================================================================
*/
$cd /models/enemies
$origin 0 0 24
$base base
$skin base
$frame idle101 idle102 idle103 idle104 idle105 idle106 idle107 idle108 idle109 idle110
$frame idle111 idle112 idle113 idle114 idle115 idle116 idle117 idle118 idle119 idle120
$frame idle121 idle122 idle123 idle124 idle125 idle126 idle127 idle128 idle129 idle130
$frame idle131 idle132 idle133 idle134 idle135 idle136 idle137 idle138 idle139 idle140
$frame idle201 idle202 idle203 idle204 idle205 idle206 idle207 idle208 idle209 idle210
$frame idle211 idle212 idle213 idle214 idle215 idle216 idle217 idle218 idle219 idle220
$frame idle221 idle222 idle223 idle224 idle225 idle226 idle227 idle228 idle229 idle230
$frame idle231 idle232 idle233 idle234 idle235 idle236 idle237 idle238 idle239 idle240
$frame bark1 bark2 bark3 bark4 bark5 bark6 bark7 bark8
$frame attack101 attack102 attack103 attack104 attack105 attack106
$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8
$frame run1 run2 run3 run4 run5 run6 run7 run8
$frame pain1 pain2 pain3 pain4
$frame death101 death102 death103 death104 death105 death106 death107 death108 death109 death110
$frame death111
$frame death201 death202 death203 death204 death205 death206 death207 death208 death209 death210
$frame death211 death212 death213 death214 death215 death216 death217 death218 death219 death220
$frame death221
$frame attack201 attack202 attack203 attack204 attack205 attack206 attack207 attack208
void() hhound_leap1;
void() hhound_run1;
void() hhound_idlesound;
/*
================
hhound_bite
================
*/
void() hhound_bite =
{
local vector delta;
local float ldmg;
if (!self.enemy)
return;
ai_charge(10);
if (!CanDamage (self.enemy, self))
return;
delta = self.enemy.origin - self.origin;
if (vlen(delta) > 100)
return;
ldmg = (random() + random() + random()) * 8;
T_Damage (self.enemy, self, self, ldmg);
};
void() hhound_JumpTouch =
{
local float ldmg;
if (self.health <= 0)
return;
if (other.takedamage)
{
if ( vlen(self.velocity) > 300 )
{
ldmg = 10 + 10*random();
T_Damage (other, self, self, ldmg);
}
}
if (!checkbottom(self))
{
if (self.flags & FL_ONGROUND)
{ // jump randomly to not get hung up
//dprint ("popjump\n");
self.touch = SUB_Null;
self.think = hhound_leap1;
self.nextthink = time + 0.1;
// self.velocity_x = (random() - 0.5) * 600;
// self.velocity_y = (random() - 0.5) * 600;
// self.velocity_z = 200;
// self.flags = self.flags - FL_ONGROUND;
}
return; // not on ground yet
}
self.touch = SUB_Null;
self.think = hhound_run1;
self.nextthink = time + 0.1;
};
//============================================================================
void() hhound_stand1 =[ $idle101, hhound_stand2 ] {ai_stand();hhound_idlesound();};
void() hhound_stand2 =[ $idle102, hhound_stand3 ] {ai_stand();};
void() hhound_stand3 =[ $idle103, hhound_stand4 ] {ai_stand();};
void() hhound_stand4 =[ $idle104, hhound_stand5 ] {ai_stand();};
void() hhound_stand5 =[ $idle105, hhound_stand6 ] {ai_stand();};
void() hhound_stand6 =[ $idle106, hhound_stand7 ] {ai_stand();};
void() hhound_stand7 =[ $idle107, hhound_stand8 ] {ai_stand();};
void() hhound_stand8 =[ $idle108, hhound_stand9 ] {ai_stand();};
void() hhound_stand9 =[ $idle109, hhound_stand10 ] {ai_stand();};
void() hhound_stand10 =[ $idle110, hhound_stand11 ] {ai_stand();};
void() hhound_stand11 =[ $idle111, hhound_stand12 ] {ai_stand();};
void() hhound_stand12 =[ $idle112, hhound_stand13 ] {ai_stand();};
void() hhound_stand13 =[ $idle113, hhound_stand14 ] {ai_stand();};
void() hhound_stand14 =[ $idle114, hhound_stand15 ] {ai_stand();};
void() hhound_stand15 =[ $idle115, hhound_stand16 ] {ai_stand();};
void() hhound_stand16 =[ $idle116, hhound_stand17 ] {ai_stand();};
void() hhound_stand17 =[ $idle117, hhound_stand18 ] {ai_stand();};
void() hhound_stand18 =[ $idle118, hhound_stand19 ] {ai_stand();};
void() hhound_stand19 =[ $idle119, hhound_stand20 ] {ai_stand();};
void() hhound_stand20 =[ $idle120, hhound_stand21 ] {ai_stand();};
void() hhound_stand21 =[ $idle121, hhound_stand22 ] {ai_stand();};
void() hhound_stand22 =[ $idle122, hhound_stand23 ] {ai_stand();};
void() hhound_stand23 =[ $idle123, hhound_stand24 ] {ai_stand();};
void() hhound_stand24 =[ $idle124, hhound_stand25 ] {ai_stand();};
void() hhound_stand25 =[ $idle125, hhound_stand26 ] {ai_stand();};
void() hhound_stand26 =[ $idle126, hhound_stand27 ] {ai_stand();};
void() hhound_stand27 =[ $idle127, hhound_stand28 ] {ai_stand();};
void() hhound_stand28 =[ $idle128, hhound_stand29 ] {ai_stand();};
void() hhound_stand29 =[ $idle129, hhound_stand30 ] {ai_stand();};
void() hhound_stand30 =[ $idle130, hhound_stand31 ] {ai_stand();};
void() hhound_stand31 =[ $idle131, hhound_stand32 ] {ai_stand();};
void() hhound_stand32 =[ $idle132, hhound_stand33 ] {ai_stand();};
void() hhound_stand33 =[ $idle133, hhound_stand34 ] {ai_stand();};
void() hhound_stand34 =[ $idle134, hhound_stand35 ] {ai_stand();};
void() hhound_stand35 =[ $idle135, hhound_stand36 ] {ai_stand();};
void() hhound_stand36 =[ $idle136, hhound_stand37 ] {ai_stand();};
void() hhound_stand37 =[ $idle137, hhound_stand38 ] {ai_stand();};
void() hhound_stand38 =[ $idle138, hhound_stand39 ] {ai_stand();};
void() hhound_stand39 =[ $idle139, hhound_stand40 ] {ai_stand();};
void() hhound_stand40 =[ $idle140, hhound_stand1 ] {ai_stand();};
//============================================================================
void() hhound_walk1 =[ $walk1 , hhound_walk2 ] {ai_walk(8);hhound_idlesound();};
void() hhound_walk2 =[ $walk2 , hhound_walk3 ] {ai_walk(8);};
void() hhound_walk3 =[ $walk3 , hhound_walk4 ] {ai_walk(8);};
void() hhound_walk4 =[ $walk4 , hhound_walk5 ] {ai_walk(8);};
void() hhound_walk5 =[ $walk5 , hhound_walk6 ] {ai_walk(8);};
void() hhound_walk6 =[ $walk6 , hhound_walk7 ] {ai_walk(8);};
void() hhound_walk7 =[ $walk7 , hhound_walk8 ] {ai_walk(8);};
void() hhound_walk8 =[ $walk8 , hhound_walk1 ] {ai_walk(8);};
//============================================================================
void() hhound_run1 =[ $walk1 , hhound_run2 ] {ai_run(24);hhound_idlesound();};
void() hhound_run2 =[ $walk2 , hhound_run3 ] {ai_run(24);};
void() hhound_run3 =[ $walk3 , hhound_run4 ] {ai_run(24);};
void() hhound_run4 =[ $walk4 , hhound_run5 ] {ai_run(24);};
void() hhound_run5 =[ $walk5 , hhound_run6 ] {ai_run(24);};
void() hhound_run6 =[ $walk6 , hhound_run7 ] {ai_run(24);};
void() hhound_run7 =[ $walk7 , hhound_run8 ] {ai_run(24);};
void() hhound_run8 =[ $walk8 , hhound_run1 ] {ai_run(24);};
//============================================================================
void() hhound_atta1 =[ $attack101, hhound_atta2 ] {ai_charge(10);};
void() hhound_atta2 =[ $attack102, hhound_atta3 ] {ai_charge(10);};
void() hhound_atta3 =[ $attack103, hhound_atta4 ] {ai_charge(10);};
void() hhound_atta4 =[ $attack104, hhound_atta5 ] {hhound_bite();};
void() hhound_atta5 =[ $attack105, hhound_atta6 ] {ai_charge(10);};
void() hhound_atta6 =[ $attack106, hhound_run1 ] {ai_charge(10);};
//============================================================================
void() hhound_attb1 =[ $attack201, hhound_attb2 ] {ai_charge(10);};
void() hhound_attb2 =[ $attack202, hhound_attb3 ] {ai_charge(10);};
void() hhound_attb3 =[ $attack203, hhound_attb4 ] {ai_charge(10);};
void() hhound_attb4 =[ $attack204, hhound_attb5 ] {hhound_bite();};
void() hhound_attb5 =[ $attack205, hhound_attb6 ] {ai_charge(10);};
void() hhound_attb6 =[ $attack206, hhound_attb7 ] {ai_charge(10);};
void() hhound_attb7 =[ $attack207, hhound_attb8 ] {ai_charge(10);};
void() hhound_attb8 =[ $attack208, hhound_run1 ] {ai_charge(10);};
void() hhound_melee =
{
if (random() > 0.5)
{
sound (self, CHAN_VOICE, "enemy/hhound/attack1.wav", 1, ATTN_NORM);
hhound_atta1 ();
}
else
{
sound (self, CHAN_VOICE, "enemy/hhound/attack2.wav", 1, ATTN_NORM);
hhound_attb1 ();
}
};
//============================================================================
void() hhound_leap1 =[ $run1, hhound_leap2 ] {ai_face();};
void() hhound_leap2 =[ $run2, hhound_leap3 ]
{
ai_face();
self.touch = hhound_JumpTouch;
makevectors (self.angles);
self.origin_z = self.origin_z + 1;
self.velocity = v_forward * 300 + '0 0 200';
if (self.flags & FL_ONGROUND)
self.flags = self.flags - FL_ONGROUND;
};
void() hhound_leap3 =[ $run3, hhound_leap4 ] {};
void() hhound_leap4 =[ $run4, hhound_leap5 ] {};
void() hhound_leap5 =[ $run5, hhound_leap6 ] {};
void() hhound_leap6 =[ $run6, hhound_leap7 ] {};
void() hhound_leap7 =[ $run7, hhound_leap8 ] {};
void() hhound_leap8 =[ $run8, hhound_leap8 ] {};
//============================================================================
void() hhound_pain1 =[ $pain1 , hhound_pain2 ] {};
void() hhound_pain2 =[ $pain2 , hhound_pain3 ] {};
void() hhound_pain3 =[ $pain3 , hhound_pain4 ] {};
void() hhound_pain4 =[ $pain4 , hhound_run1 ] {};
void() hhound_pain =
{
local float r;
//pick between 4 pain sounds
r = random();
if (r <= 0.25)
sound (self, CHAN_VOICE, "enemy/hhound/pain1.wav", 1, ATTN_NORM);
else if (r <= 0.5)
sound (self, CHAN_VOICE, "enemy/hhound/pain2.wav", 1, ATTN_NORM);
else if (r <= 0.75)
sound (self, CHAN_VOICE, "enemy/hhound/pain3.wav", 1, ATTN_NORM);
else
sound (self, CHAN_VOICE, "enemy/hhound/pain4.wav", 1, ATTN_NORM);
hhound_pain1 ();
};
//============================================================================
void() hhound_die1 =[ $death101, hhound_die2 ] {};
void() hhound_die2 =[ $death102, hhound_die3 ] {};
void() hhound_die3 =[ $death103, hhound_die4 ] {};
void() hhound_die4 =[ $death104, hhound_die5 ] {};
void() hhound_die5 =[ $death105, hhound_die6 ] {};
void() hhound_die6 =[ $death106, hhound_die7 ] {};
void() hhound_die7 =[ $death107, hhound_die8 ] {};
void() hhound_die8 =[ $death108, hhound_die9 ] {};
void() hhound_die9 =[ $death109, hhound_die10 ] {};
void() hhound_die10 =[ $death110, hhound_die11 ] {};
void() hhound_die11 =[ $death111, hhound_die11 ] {banish_monster();};
//============================================================================
void() hhound_dieb1 =[ $death201, hhound_dieb2 ] {};
void() hhound_dieb2 =[ $death202, hhound_dieb3 ] {};
void() hhound_dieb3 =[ $death203, hhound_dieb4 ] {};
void() hhound_dieb4 =[ $death204, hhound_dieb5 ] {};
void() hhound_dieb5 =[ $death205, hhound_dieb6 ] {};
void() hhound_dieb6 =[ $death206, hhound_dieb7 ] {};
void() hhound_dieb7 =[ $death207, hhound_dieb8 ] {};
void() hhound_dieb8 =[ $death208, hhound_dieb9 ] {};
void() hhound_dieb9 =[ $death209, hhound_dieb10 ] {};
void() hhound_dieb10 =[ $death210, hhound_dieb11 ] {};
void() hhound_dieb11 =[ $death211, hhound_dieb12 ] {};
void() hhound_dieb12 =[ $death212, hhound_dieb13 ] {};
void() hhound_dieb13 =[ $death213, hhound_dieb14 ] {};
void() hhound_dieb14 =[ $death214, hhound_dieb15 ] {};
void() hhound_dieb15 =[ $death215, hhound_dieb16 ] {};
void() hhound_dieb16 =[ $death216, hhound_dieb17 ] {};
void() hhound_dieb17 =[ $death217, hhound_dieb18 ] {};
void() hhound_dieb18 =[ $death218, hhound_dieb19 ] {};
void() hhound_dieb19 =[ $death219, hhound_dieb20 ] {};
void() hhound_dieb20 =[ $death220, hhound_dieb21 ] {};
void() hhound_dieb21 =[ $death221, hhound_dieb21 ] {banish_monster();};
void() hhound_die =
{
// regular death
sound (self, CHAN_VOICE, "enemy/hhound/death.wav", 1, ATTN_NORM);
self.solid = SOLID_NOT;
if (random() > 0.5)
hhound_die1 ();
else
hhound_dieb1 ();
};
//============================================================================
/*
==============
CheckhhoundMelee
Returns TRUE if a melee attack would hit right now
==============
*/
float() CheckhhoundMelee =
{
if (enemy_range == RANGE_MELEE)
{ // FIXME: check canreach
self.attack_state = AS_MELEE;
return TRUE;
}
return FALSE;
};
/*
==============
CheckhhoundJump
==============
*/
float() CheckhhoundJump =
{
local vector dist;
local float d;
if (self.origin_z + self.mins_z > self.enemy.origin_z + self.enemy.mins_z + 0.75 * self.enemy.size_z)
return FALSE;
if (self.origin_z + self.maxs_z < self.enemy.origin_z + self.enemy.mins_z + 0.25 * self.enemy.size_z)
return FALSE;
dist = self.enemy.origin - self.origin;
dist_z = 0;
d = vlen(dist);
if (d < 80)
return FALSE;
if (d > 150)
return FALSE;
return TRUE;
};
float() hhoundCheckAttack =
{
local vector vec;
// if close enough for slashing, go for it
if (CheckhhoundMelee ())
{
self.attack_state = AS_MELEE;
return TRUE;
}
if (CheckhhoundJump ())
{
self.attack_state = AS_MISSILE;
return TRUE;
}
return FALSE;
};
void() hhound_idlesound =
{
if (random() <= 0.2)
{
if (random() <= 0.5)
sound (self, CHAN_VOICE, "enemy/hhound/alert1.wav", 1, ATTN_NORM);
else
sound (self, CHAN_VOICE, "enemy/hhound/idle.wav", 1, ATTN_NORM);
}
};
//===========================================================================
/*QUAKED monster_hhound (1 0 0) (-32 -32 -24) (32 32 40) Ambush
*/
void() monster_hhound =
{
if (deathmatch)
{
remove(self);
return;
}
precache_model ("models/enemies/hhound.md2");
precache_sound ("enemy/hhound/alert1.wav");
precache_sound ("enemy/hhound/attack1.wav");
precache_sound ("enemy/hhound/attack2.wav");
precache_sound ("enemy/hhound/death.wav");
precache_sound ("enemy/hhound/idle.wav");
precache_sound ("enemy/hhound/pain1.wav");
precache_sound ("enemy/hhound/pain2.wav");
precache_sound ("enemy/hhound/pain3.wav");
precache_sound ("enemy/hhound/pain4.wav");
precache_sound ("enemy/hhound/rage.wav");
self.solid = SOLID_SLIDEBOX;
self.movetype = MOVETYPE_STEP;
setmodel (self, "models/enemies/hhound.md2");
setsize (self, '-32 -32 -24', '32 32 40');
// setsize (self, VEC_HULL2_MIN, VEC_HULL2_MAX);
self.health = set_health(30);
self.speed = set_speed(800);
self.dtype = 2; //dodge type forward_strafe
self.alpha = 1; //we aren't transparent
self.th_stand = hhound_stand1;
self.th_walk = hhound_walk1;
self.th_run = hhound_run1;
self.th_pain = hhound_pain;
self.th_die = hhound_die;
self.th_melee = hhound_melee;
self.th_missile = hhound_leap1;
//my new classname is?
self.classname = "monster_hhound";
//set up our monflag
self.monflag = "TRUE";
walkmonster_start();
};
/*
=================
create_hhoundbot
Creates a Hell Hound at the specified 'spot'.
This is used by the Captain, he summons Hell Hounds, Dwellers, and Axe Mercenaries.
=================
*/
void(vector spot) create_hhoundbot =
{
local entity bot;
// start entity and place it in world
bot = spawn();
bot.angles = self.angles;
setorigin (bot, spot);
bot.fixangle = TRUE;
spawn_tfog (bot.origin);
spawn_tdeath (bot.origin, bot);
// set size and shape
bot.solid = SOLID_SLIDEBOX;
bot.movetype = MOVETYPE_STEP;
setmodel (bot, "models/enemies/hhound.md2");
setsize (bot, '-32 -32 -24', '32 32 40');
bot.flags = bot.flags | FL_MONSTER;
bot.takedamage = DAMAGE_AIM;
// define his animation
bot.th_stand = hhound_stand1;
bot.th_walk = hhound_walk1;
bot.th_run = hhound_run1;
bot.th_die = hhound_die;
bot.th_melee = hhound_melee;
bot.th_missile = hhound_leap1;
bot.th_pain = hhound_pain;
bot.health = set_health(30);
bot.speed = set_speed(800);
bot.dtype = 2; //dodge type forward_strafe
bot.alpha = 1; //we aren't transparent
// polish him up
bot.classname = "monster_hhound";
bot.ideal_yaw = bot.angles * '0 1 0';
bot.yaw_speed = 120;
bot.view_ofs = '0 0 22';
//set up our monflag
bot.monflag = "TRUE";
// begin his thinking
bot.nextthink = time + 0.1 + random();
bot.think = th_stuck;
};