ew-progs/xsniperbot/xifight.qc
2011-09-06 00:00:00 +00:00

580 lines
13 KiB
C++

/*
=============================
xifight.qc
coded by
Michael Rogers a.k.a Xsniper
ssj_xsniper@yahoo.com
http://www.xsniper.net/
Description:
This file contains fighting code for Xsniper Bot.
=============================
*/
void() xsn_attack;
//========================================================================================================
//Fighting Styles Code Below
void() fs_standstill =
{
//very simple, stand still and fire
self.think = self.th_missile;
self.nextthink = time + 0.01;
};
void() fs_sidestep =
{
local float ofs;
// this is a cool strafing routine
if (self.lefty)
ofs = 90;
else
ofs = -90;
if (walkmove (self.angles_y + ofs, 20))
{
if (ofs == -90)
{
makevectors(self.angles);
self.flags = self.flags - (self.flags & FL_ONGROUND);
self.velocity = v_right * self.speed;
}
else
{
makevectors(self.angles);
self.flags = self.flags - (self.flags & FL_ONGROUND);
self.velocity = v_right * self.speed * -1;
}
return;
}
self.lefty = 1 - self.lefty;
walkmove (self.angles_y - ofs, 20);
if (ofs == -90)
{
makevectors(self.angles);
self.flags = self.flags - (self.flags & FL_ONGROUND);
self.velocity = v_right * self.speed;
}
else
{
makevectors(self.angles);
self.flags = self.flags - (self.flags & FL_ONGROUND);
self.velocity = v_right * self.speed * -1;
}
//lets fire our weapon now
self.think = self.th_missile;
self.nextthink = time + 0.01;
};
void() fs_charge =
{
//lets get as close to our enemy as possible
movetogoal(20);
makevectors(self.angles);
self.flags = self.flags - (self.flags & FL_ONGROUND);
self.velocity = v_forward * self.speed;
//shoot him up close and personal
self.think = self.th_missile;
self.nextthink = time + 0.01;
};
void() fs_back =
{
//if the enemy gets too close then back up
if (range(self.enemy) == RANGE_MELEE || range(self.enemy) == RANGE_NEAR)
ai_back(23);
//shoot from a distance
self.think = self.th_missile;
self.nextthink = time + 0.01;
};
void() fs_circle =
{
//circle around the enemy
if (vlen(self.enemy.origin - self.origin) < 80)
walkmove(self.angles_y - 180, 20);
if (vlen(self.enemy.origin - self.origin) > 110)
movetogoal(20);
else fs_sidestep();
//lets fire our weapon now
self.think = self.th_missile;
self.nextthink = time + 0.01;
};
/*
=============================
pick_fighting_style
Picks a fighting style based on
certain criteria.
Fighting Styles:
0: stand still
1: sidestep
2: charge towards opponent
3: keep your distance
4: circle around opponent
=============================
*/
void() pick_fighting_style =
{
local float r;
//set up random variable
r = random();
//for now lets pick a fighting style at random
if (r <= 0.2)
self.fstyle = 0;
else if (r <= 0.4)
self.fstyle = 1;
else if (r <= 0.6)
self.fstyle = 2;
else if (r <= 0.8)
self.fstyle = 3;
else
self.fstyle = 4;
//set up fstime
self.fstime = time + 5 + random();
};
/*
===============================
execute_fighting_style
Lets activate our fighting style.
Fighting Styles:
0: stand still
1: sidestep
2: charge towards opponent
3: keep your distance
4: circle around opponent
===============================
*/
void() execute_fighting_style =
{
//see if we need to get a new fighting style or not
if (time > self.fstime)
pick_fighting_style();
//when using melee weapons we need to charge forward for best results
if (self.weapon == IT_DAGGER)
self.fstyle = 2;
else if (self.weapon == IT_SWORD && self.wmode == 1)
self.fstyle = 2;
//execute our fighting style
if (self.fstyle == 0)
fs_standstill();
else if (self.fstyle == 1)
fs_sidestep();
else if (self.fstyle == 2)
fs_charge();
else if (self.fstyle == 3)
fs_back();
else
fs_circle();
};
//========================================================================================================
//Weapon Selection Code Below
/*
============================
have_weapon
Returns true or false if self has the weapon
referenced by wcode.
============================
*/
float(float wcode) have_weapon =
{
local float it;
//set up items
it = self.items;
//see if we have the weapon
if (it & wcode)
return TRUE;
else
return FALSE;
};
float() CheckPrimaryAmmo =
{
//check ammo for primary attacks
if(self.weapon == IT_CROSSBOW && self.currentammo >= 1)
return TRUE;
if(self.weapon == IT_TRINITY_BLAST && self.currentammo >= 1)
return TRUE;
if(self.weapon == IT_ICE_SHARDS && self.currentammo >= 2)
return TRUE;
if(self.weapon == IT_LIGHTNING_ARC && self.currentammo >= 1)
return TRUE;
if(self.weapon == IT_SMITE && self.currentammo >= 1)
return TRUE;
if(self.weapon == IT_SOUL_DISC && self.currentammo >= 2)
return TRUE;
if(self.weapon == IT_SWORD)
return TRUE;
if (self.weapon == IT_DAGGER)
return TRUE;
return FALSE;
};
float() CheckSecondaryAmmo =
{
//check ammo for secondary attacks
if(self.weapon == IT_CROSSBOW && self.currentammo >= 3)
return TRUE;
if(self.weapon == IT_TRINITY_BLAST && self.currentammo >= 3)
return TRUE;
if(self.weapon == IT_ICE_SHARDS && self.currentammo >= 4)
return TRUE;
if(self.weapon == IT_LIGHTNING_ARC && self.currentammo >= 10)
return TRUE;
if(self.weapon == IT_SMITE && self.currentammo >= 2)
return TRUE;
if(self.weapon == IT_SOUL_DISC && self.currentammo >= 2)
return TRUE;
if(self.weapon == IT_SWORD)
return TRUE;
if (self.weapon == IT_DAGGER)
return TRUE;
return FALSE;
};
/*
=================
have_ammo
Returns a 1 if they have enough ammo for primary attack only.
Returns a 2 if they have enough ammo for primary and secondary attack.
Returns a 0 if they don't have enough ammo for either attack.
=================
*/
float() have_ammo =
{
local float rvalue;
//initialize rvalue
rvalue = 0;
if (CheckPrimaryAmmo() == TRUE)
rvalue = rvalue + 1;
if (CheckSecondaryAmmo() == TRUE)
rvalue = rvalue + 1;
return rvalue;
};
void() print_ammo =
{
//debug msg
bprint("self.currentammo == ");
bprint(ftos(self.currentammo));
bprint("\n");
};
/*
=============================
enemies_nearby
Returns true or false if there are other
enemies near targ.
=============================
*/
float(entity targ) enemies_nearby =
{
local entity etemp;
local float ecount;
//initialize ecount
ecount = 0;
//check a radius around targ for other enemies
etemp = findradius(targ.origin, 300);
while(etemp)
{
//we don't want to count ourself
if (etemp != targ)
{
//only want to count monsters
if (etemp.monflag == "TRUE")
ecount = ecount + 1;
}
etemp = etemp.chain;
}
//return true or false based on ecount
if (ecount > 0)
return TRUE;
return FALSE;
};
string() get_weapon =
{
if (self.weapon == 4096) //IT_DAGGER
return "IT_DAGGER";
if (self.weapon == 1) //IT_CROSSBOW
return "IT_CROSSBOW";
if (self.weapon == 2) //IT_TRINITY_BLAST
return "IT_TRINITY_BLAST";
if (self.weapon == 4) //IT_ICE_SHARDS
return "IT_ICE_SHARDS";
if (self.weapon == 8) //IT_LIGHTNING_ARC
return "IT_LIGHTNING_ARC";
if (self.weapon == 16) //IT_SMITE
return "IT_SMITE";
if (self.weapon == 32) //IT_SOUL_DISC
return "IT_SOUL_DISC";
if (self.weapon == 64) //IT_SWORD
return "IT_SWORD";
if (self.weapon == 128) //IT_EXTRA_WEAPON
return "IT_EXTRA_WEAPON";
};
/*
=====================
set_weapon
Gives the best weapon possible with
w1 being the best and w8 being the worst.
If bot doesnt have any of these weapons then
it just returns.
=====================
*/
void(float w1, float w2,float w3,float w4,float w5,float w6,float w7,float w8) set_weapon =
{
if (have_weapon(w1))
{
self.weapon = w1;
//DebugMsg(3,"self.weapon == ",get_weapon(),"\n","");
//make sure we have enough ammo to do primary attack atleast
if (have_ammo() >= 1)
return;
}
if (have_weapon(w2))
{
self.weapon = w2;
//DebugMsg(3,"self.weapon == ",get_weapon(),"\n","");
//make sure we have enough ammo to do primary attack atleast
if (have_ammo() >= 1)
return;
}
if (have_weapon(w3))
{
self.weapon = w3;
//DebugMsg(3,"self.weapon == ",get_weapon(),"\n","");
//make sure we have enough ammo to do primary attack atleast
if (have_ammo() >= 1)
return;
}
if (have_weapon(w4))
{
self.weapon = w4;
//DebugMsg(3,"self.weapon == ",get_weapon(),"\n","");
//make sure we have enough ammo to do primary attack atleast
if (have_ammo() >= 1)
return;
}
if (have_weapon(w5))
{
self.weapon = w5;
//DebugMsg(3,"self.weapon == ",get_weapon(),"\n","");
//make sure we have enough ammo to do primary attack atleast
if (have_ammo() >= 1)
return;
}
if (have_weapon(w6))
{
self.weapon = w6;
//DebugMsg(3,"self.weapon == ",get_weapon(),"\n","");
//make sure we have enough ammo to do primary attack atleast
if (have_ammo() >= 1)
return;
}
if (have_weapon(w7))
{
self.weapon = w7;
//DebugMsg(3,"self.weapon == ",get_weapon(),"\n","");
//make sure we have enough ammo to do primary attack atleast
if (have_ammo() >= 1)
return;
}
if (have_weapon(w8))
{
self.weapon = w8;
//DebugMsg(3,"self.weapon == ",get_weapon(),"\n","");
//make sure we have enough ammo to do primary attack atleast
if (have_ammo() >= 1)
return;
}
};
/*
=====================
set_mode
Will put us into secondary attack mode
if possible and if our current weapon is
any of the weapons from w1 through w8
=====================
*/
void(float w1,float w2,float w3,float w4,float w5,float w6,float w7,float w8) set_mode =
{
if (self.weapon == w1 && have_ammo() == 2)
self.wmode = 2;
else if (self.weapon == w2 && have_ammo() == 2)
self.wmode = 2;
else if (self.weapon == w3 && have_ammo() == 2)
self.wmode = 2;
else if (self.weapon == w4 && have_ammo() == 2)
self.wmode = 2;
else if (self.weapon == w5 && have_ammo() == 2)
self.wmode = 2;
else if (self.weapon == w6 && have_ammo() == 2)
self.wmode = 2;
else if (self.weapon == w7 && have_ammo() == 2)
self.wmode = 2;
else if (self.weapon == w8 && have_ammo() == 2)
self.wmode = 2;
else
self.wmode = 1;
};
/*
=====================
choose_weapon
This function is called by the bot during combat
allowing him to choose the best weapon for
the situation based on range of enemy and number
of enemies around him.
=====================
*/
void() choose_weapon =
{
//get our current ammo set up
W_SetCurrentAmmo ();
//first check the range
if (range(self.enemy) == RANGE_MID) //Medium Range
{
//DebugMsg(2,"range == RANGE_MID", "\n", "", "");
//now check if more enemies are around self.enemy
if (enemies_nearby(self.enemy))
{
//DebugMsg(2,"enemies_nearby == TRUE", "\n", "", "");
//set our weapon appropriately
set_weapon(IT_SMITE,IT_ICE_SHARDS,IT_SOUL_DISC,IT_TRINITY_BLAST,IT_CROSSBOW,IT_SWORD,0,0);
//set weapon attack mode
set_mode(IT_ICE_SHARDS,IT_CROSSBOW,IT_SWORD,0,0,0,0,0);
//lets fire our weapon now
xsn_attack();
}
else //just one enemy
{
//DebugMsg(2,"enemies_nearby == FALSE", "\n", "", "");
//set our weapon appropriately
set_weapon(IT_SMITE,IT_ICE_SHARDS,IT_CROSSBOW,IT_TRINITY_BLAST,IT_SWORD,0,0,0);
//set weapon attack mode
set_mode(IT_CROSSBOW,IT_SWORD,0,0,0,0,0,0);
//lets fire our weapon now
xsn_attack();
}
}
else if (range(self.enemy) == RANGE_NEAR) //Closer but not melee yet
{
//DebugMsg(2,"range == RANGE_NEAR", "\n", "", "");
//now check if more enemies are around self.enemy
if (enemies_nearby(self.enemy))
{
//DebugMsg(2,"enemies_nearby == TRUE", "\n", "", "");
//set our weapon appropriately
set_weapon(IT_LIGHTNING_ARC,IT_SMITE,IT_ICE_SHARDS,IT_SOUL_DISC,IT_TRINITY_BLAST,IT_CROSSBOW,IT_SWORD,0);
//set weapon attack mode
set_mode(IT_LIGHTNING_ARC,IT_ICE_SHARDS,IT_TRINITY_BLAST,IT_CROSSBOW,IT_SWORD,0,0,0);
//lets fire our weapon now
xsn_attack();
}
else //just one enemy
{
//DebugMsg(2,"enemies_nearby == FALSE", "\n", "", "");
//set our weapon appropriately
set_weapon(IT_LIGHTNING_ARC,IT_SMITE,IT_SOUL_DISC,IT_CROSSBOW,IT_ICE_SHARDS,IT_TRINITY_BLAST,IT_SWORD,0);
//set weapon attack mode
set_mode(IT_CROSSBOW,IT_TRINITY_BLAST,IT_SWORD,0,0,0,0,0);
//lets fire our weapon now
xsn_attack();
}
}
else if (range(self.enemy) == RANGE_MELEE) //Hand to hand combat
{
//DebugMsg(2,"range == RANGE_MELEE", "\n", "", "");
//now check if more enemies are around self.enemy
if (enemies_nearby(self.enemy))
{
//DebugMsg(2,"enemies_nearby == TRUE", "\n", "", "");
//set our weapon appropriately
set_weapon(IT_LIGHTNING_ARC,IT_SMITE,IT_SOUL_DISC,IT_ICE_SHARDS,IT_CROSSBOW,IT_SWORD,IT_DAGGER,0);
//set weapon attack mode
set_mode(IT_LIGHTNING_ARC,IT_SMITE,IT_ICE_SHARDS,IT_CROSSBOW,0,0,0,0);
//lets fire our weapon now
xsn_attack();
}
else //just one enemy
{
//DebugMsg(2,"enemies_nearby == FALSE", "\n", "", "");
//set our weapon appropriately
set_weapon(IT_SWORD,IT_ICE_SHARDS,IT_DAGGER,0,0,0,0,0);
//set weapon attack mode
set_mode(0,0,0,0,0,0,0,0);
//lets fire our weapon now
xsn_attack();
}
}
};