#include "havocbot.qh"
-#include "../../_all.qh"
#include "../aim.qh"
#include "../bot.qh"
#include "../waypoints.qh"
#include "../../../common/constants.qh"
+#include "../../../common/items/all.qh"
#include "../../../common/triggers/trigger/jumppads.qh"
-#include "../../../warpzonelib/common.qh"
+#include "../../../lib/warpzone/common.qh"
+
+.float speed;
void havocbot_ai()
{SELFPARAM();
if(self.weapons)
{
- WEP_ACTION(self.weapon, WR_AIM);
+ Weapon w = get_weaponinfo(self.weapon);
+ w.wr_aim(w);
if (autocvar_bot_nofire || IS_INDEPENDENT_PLAYER(self))
{
self.BUTTON_ATCK = false;
void havocbot_chooseenemy()
{SELFPARAM();
entity head, best, head2;
- float rating, bestrating, i, hf;
+ float rating, bestrating, hf;
vector eye, v;
if (autocvar_bot_nofire || IS_INDEPENDENT_PLAYER(self))
{
self.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_CORPSE;
- for(i = 0; ; ++i)
+ bool scan_transparent = false;
+ bool scan_secondary_targets = false;
+ bool have_secondary_targets = false;
+ while(true)
{
- while (head)
+ scan_secondary_targets = false;
+ :scan_targets
+ for( ; head; head = head.chain)
{
+ if(!scan_secondary_targets)
+ {
+ if(head.classname == "misc_breakablemodel")
+ {
+ have_secondary_targets = true;
+ continue;
+ }
+ }
+ else
+ {
+ if(head.classname != "misc_breakablemodel")
+ continue;
+ }
+
v = (head.absmin + head.absmax) * 0.5;
rating = vlen(v - eye);
if (rating<autocvar_bot_ai_enemydetectionradius)
bestrating = rating;
}
}
- head = head.chain;
+ }
+
+ if(!best && have_secondary_targets && !scan_secondary_targets)
+ {
+ scan_secondary_targets = true;
+ // restart the loop
+ head = head2;
+ bestrating = 100000000;
+ goto scan_targets;
}
// I want to do a second scan if no enemy was found or I don't have weapons
// TODO: Perform the scan when using the rifle (requires changes on the rifle code)
if(best || self.weapons) // || self.weapon == WEP_RIFLE.m_id
break;
- if(i)
+ if(scan_transparent)
break;
// Set flags to see through transparent objects
self.dphitcontentsmask |= DPCONTENTS_OPAQUE;
head = head2;
+ scan_transparent = true;
}
// Restore hit flags
self.enemy = best;
self.havocbot_stickenemy = true;
+ if(best && best.classname == "misc_breakablemodel")
+ self.havocbot_stickenemy = false;
}
float havocbot_chooseweapon_checkreload(int new_weapon)
float i, other_weapon_available = false;
for(i = WEP_FIRST; i <= WEP_LAST; ++i)
{
+ Weapon w = get_weaponinfo(i);
// if we are out of ammo for all other weapons, it's an emergency to switch to anything else
- if (WEP_ACTION(i, WR_CHECKAMMO1) + WEP_ACTION(i, WR_CHECKAMMO2))
+ if (w.wr_checkammo1(w) + w.wr_checkammo2(w))
other_weapon_available = true;
}
if(other_weapon_available)
int i;
// ;)
- if(g_weaponarena_weapons == WEPSET_TUBA)
+ if(g_weaponarena_weapons == WEPSET(TUBA))
{
self.switchweapon = WEP_TUBA.m_id;
return;
// Should it do a weapon combo?
float af, ct, combo_time, combo;
- af = ATTACK_FINISHED(self);
+ af = ATTACK_FINISHED(self, 0);
ct = autocvar_bot_ai_weapon_combo_threshold;
// Bots with no skill will be 4 times more slower than "godlike" bots when doing weapon combos
// Choose weapons for far distance
if ( distance > bot_distance_far ) {
- for(i=0; i < WEP_COUNT && bot_weapons_far[i] != -1 ; ++i){
+ for(i=0; i < Weapons_COUNT && bot_weapons_far[i] != -1 ; ++i){
w = bot_weapons_far[i];
if ( client_hasweapon(self, w, true, false) )
{
// Choose weapons for mid distance
if ( distance > bot_distance_close) {
- for(i=0; i < WEP_COUNT && bot_weapons_mid[i] != -1 ; ++i){
+ for(i=0; i < Weapons_COUNT && bot_weapons_mid[i] != -1 ; ++i){
w = bot_weapons_mid[i];
if ( client_hasweapon(self, w, true, false) )
{
}
// Choose weapons for close distance
- for(i=0; i < WEP_COUNT && bot_weapons_close[i] != -1 ; ++i){
+ for(i=0; i < Weapons_COUNT && bot_weapons_close[i] != -1 ; ++i){
w = bot_weapons_close[i];
if ( client_hasweapon(self, w, true, false) )
{