hexen2/H2MP/hcode/ravenai.hc
2000-11-10 00:00:00 +00:00

349 lines
8.2 KiB
C++

/*
* $Header: /H2 Mission Pack/HCode/ravenai.hc 2 2/12/98 5:55p Jmonroe $
*/
float() LocateTarget =
{
return FindTarget(TRUE);
};
float MA_SUCCESSFUL = 0;
float MA_BLOCKED = -1;
float MA_CROSSED = -2;
float MA_NOWEAPON = -3;
float MA_TOOSOON = -4;
float MA_TOOFAR = -5;
float MA_NOATTACK = -6;
float MA_MELEE = 1;
float MA_MISSILE = 2;
float MA_BOTH = 3;
float MA_FAR_MELEE = 4;
float MA_SHORT_MISSILE = 8;
// You must perform the following call sometime before calling this function:
// enemy_range = range (self.enemy);
float(float AttackType, float ChanceModifier) CheckMonsterAttack =
{
local vector spot1, spot2;
local entity targ;
local float chance;
targ = self.enemy;
if (self.classname == "monster_hydra")
if (self.enemy.watertype != CONTENT_WATER)
{
if (self.search_time < time)
{
self.monster_stage = 0;
self.enemy = world;
return 0;
}
return 0;
}
else self.search_time = time + 5;
// see if any entities are in the way of the shot
spot1 = self.origin + self.view_ofs;
spot2 = targ.origin + targ.view_ofs;
traceline (spot1, spot2, FALSE, self);
if(trace_ent.thingtype>=THINGTYPE_WEBS)
traceline (trace_endpos, spot2, FALSE, trace_ent);
if (trace_ent != targ)
if(trace_ent.health>25||!trace_ent.takedamage||(trace_ent.flags&FL_MONSTER&&trace_ent.classname!="player_sheep"))
return MA_BLOCKED; // don't have a clear shot
if (trace_inopen && trace_inwater)
return MA_CROSSED; // sight line crossed contents
if (enemy_range == RANGE_MELEE)
{ // melee attack
if (AttackType & MA_SHORT_MISSILE)
{
if (random() < 0.5)
{
self.th_missile ();
return MA_SUCCESSFUL;
}
}
if (self.th_melee)
{
if (AttackType & MA_MELEE)
{
self.th_melee ();
return MA_SUCCESSFUL;
}
else
return MA_NOWEAPON;
}
}
// missile attack
if (!self.th_missile || !(AttackType & (MA_MISSILE | MA_FAR_MELEE)))
{
return MA_NOWEAPON;
}
if (time < self.attack_finished)
return MA_TOOSOON;
if (enemy_range == RANGE_FAR)
return MA_TOOFAR;
if (enemy_range == RANGE_MELEE)
{
chance = 0.9;
self.attack_finished = 0;
}
else if (enemy_range == RANGE_NEAR)
{
if (self.th_melee)
chance = 0.2;
else
chance = 0.4;
}
else if (enemy_range == RANGE_MID)
{
if (self.th_melee)
chance = 0.05;
else
chance = 0.1;
}
else
chance = 0;
chance = chance * ChanceModifier;
if (chance > 0.95) chance = 0.95;
if (random () < chance)
{
if (self.th_melee)
{ // quake c wouldn't allow me to put this in on if!!!
if (AttackType & MA_FAR_MELEE)
{
self.th_melee ();
}
else
{
self.th_missile ();
}
}
else
{
self.th_missile ();
}
// SUB_AttackFinished (random(2,0));
SUB_AttackFinished (random(8,0));
return MA_SUCCESSFUL;
}
return MA_NOATTACK;
};
float (vector offset, vector to_where)monster_checkpos =
{
// This function will trace 2 lines - the first line will go from the origin to the offset from the origin.
// If this could be done atleast half way, then a 2nd trace is done from the end point of the first trace
// to the final destination. If this was mostly successful, then the function will return true, otherwise
// false. You would use this function in a situation where you want to see if the enemy is visibile from
// your right side, so you first see if you can go do the right side, then go forward from there to the enemy.
local vector start;
local float length;
start = self.origin + offset;
traceline (self.origin, start, FALSE, self);
if (trace_fraction < 0.5)
{ // Couldn't get to the offset
return FALSE;
}
length = vlen(self.origin-start) * trace_fraction;
start = trace_endpos;
traceline (start,to_where, FALSE, self);
if (trace_ent == self.enemy || trace_fraction > 0.98)
{ // We found the enemy!
length = length + vlen(start-self.enemy.origin) * trace_fraction;
return length;
}
return FALSE;
};
void (float l, float r, float u, float d, float last_move, vector where) find_path =
{
// This function will check to see if an enemy can be located from the top, bottom, left, and right sides.
// The l, r, u, d parameters specify the order for which the search should be done. If it couldn't find
// the enemy, then it will try the last seen position of the enemy. last_move indicates that the previous
// move was successful (i.e. the monster could move forward). where is the position to check for.
local float length;
local float newyaw;
local float newz;
local float c;
local float retval;
// local vector a, b;
makevectors (self.angles);
length = 99999;
newyaw = self.ideal_yaw;
newz = self.velocity_z;
c = 0;
while(c<=4)
{ // We have 5 checks to do
if (c == 0 && last_move)
{ // Try checking forward
retval = monster_checkpos(v_forward*300,where);
if (retval && retval < length)
{
//dprint("found you to the forward\n");
self.monster_duration = 18 + 5;
length = retval;
}
}
if (c == l)
{ // Try checking to the left
retval = monster_checkpos(v_right*-200,where);
if (retval && retval < length)
{
//dprint("found you to the left\n");
newyaw = self.angles_y + 90;
self.monster_duration = 18 + 5;
length = retval;
}
}
else if (c == r)
{ // Try checking to the right
retval = monster_checkpos(v_right*200,where);
if (retval && retval < length)
{
//dprint("found you to the right\n");
newyaw = self.angles_y - 90;
self.monster_duration = 18 + 5;
length = retval;
}
}
else if (c == u)
{ // Try checking to the top
retval = monster_checkpos(v_up*200,where);
if (retval && retval < length)
{
//dprint("found you to the up\n");
newz = 30;
self.monster_duration = 18 + 5;
length = retval;
}
}
else if (c == d)
{ // Try checking to the bottom
retval = monster_checkpos(v_up*-200,where);
if (retval && retval < length)
{
//dprint("found you to the down\n");
newz = -30;
self.monster_duration = 18 + 5;
length = retval;
}
}
c = c + 1;
}
if (length == 99999 && self.monster_last_seen != where)
{ // If we didn't find a direction, and we haven't done this, try looking where the enemy
// was last seen
find_path(l,r,u,d,0,self.monster_last_seen);
//dprint("Using last seen\n");
}
else
{
self.ideal_yaw = newyaw;
self.velocity_z = newz;
}
};
/*
float () FindDir =
{ // Monster couldn't go in the direction it is pointed to, so find one it can go to
local vector a,b,c;
local float inc,step;
if (random() < 0.5) inc = 45;
else inc = -45;
c = '0 0 0';
c_y = c_y + inc;
step = 0;
while(step < 6)
{ // 7 directions to check (45 degrees each)
makevectors (self.angles + c);
a = self.origin + self.view_ofs;
b = a + v_forward*100;
traceline (a, b, FALSE, self);
if (trace_fraction > 0.9)
{ // We can mostly go this direction
return self.angles_y + c_y;
//dprint(" found\n");
}
c_y = c_y + inc;
step = step + 1;
}
return self.angles_y;
};
*/
/*
* $Log: /H2 Mission Pack/HCode/ravenai.hc $
*
* 2 2/12/98 5:55p Jmonroe
* remove unreferenced funcs
*
* 18 10/28/97 1:01p Mgummelt
* Massive replacement, rewrote entire code... just kidding. Added
* support for 5th class.
*
* 16 9/03/97 9:14p Mgummelt
* Fixing targetting AI
*
* 15 8/26/97 2:26a Mgummelt
*
* 14 8/14/97 10:28p Bgokey
*
* 13 8/14/97 7:32p Bgokey
*
* 12 8/14/97 7:05p Bgokey
*
* 11 8/12/97 6:10p Mgummelt
*
* 10 7/21/97 4:04p Mgummelt
*
* 9 7/21/97 4:02p Mgummelt
*
* 8 6/18/97 5:40p Mgummelt
*
* 7 6/16/97 12:03p Rjohnson
* Removed imp stuff
*
* 6 5/31/97 4:00p Mgummelt
*
* 5 5/30/97 10:04p Mgummelt
*
* 4 2/26/97 3:14p Rlove
* Changes to basic monster ai
*
* 3 1/09/97 1:48p Rjohnson
* Made FindDir() return a direction instead of just setting it
*
* 2 1/02/97 11:20a Rjohnson
* Christmas Changes
*
* 1 12/17/96 10:38a Rjohnson
* Initial Version
*/