}
havocbot_movetogoal();
- // if the bot is not attacking, go through all weapons that aren't fully loaded and reload them to keep them ready
+ // if the bot is not attacking, consider reloading weapons
if not(self.aistatus & AI_STATUS_ATTACKING)
{
float i;
entity e;
// we are currently holding a weapon that's not fully loaded, reload it
- if(skill > 2.5) // bots can only reload held weapons on purpose past this skill
- if(self.clip_load < self.clip_size && self.weapon)
+ if(skill >= 2) // bots can only reload the held weapon on purpose past this skill
+ if(self.clip_load < self.clip_size)
self.impulse = 20; // "press" the reload button, not sure if this is done right
// if we're not reloading a weapon, switch to any weapon in our invnetory that's not fully loaded to reload it next
// the code above executes next frame, starting the reloading then
if(skill >= 5) // bots can only look for unloaded weapons past this skill
if(self.clip_load >= 0) // only if we're not reloading a weapon already
- if not(self.clip_load < self.clip_size && self.weapon) // we're already holding a weapon we can reload, don't look for another
{
for(i = WEP_FIRST; i <= WEP_LAST; ++i)
{
e = get_weaponinfo(i);
- if(self.weapon_load[i] < cvar(strcat("g_balance_", e.netname, "_reload_ammo")))
+ if ((e.spawnflags & WEP_FLAG_RELOADABLE) && (self.weapon_load[i] < cvar(strcat("g_balance_", e.netname, "_reload_ammo"))))
self.switchweapon = i;
}
}
// Don't jump when using some weapons
/*
if(self.aistatus & AI_STATUS_ATTACKING)
- if(self.weapon == WEP_SNIPERRIFLE)
+ if(self.weapon == WEP_RIFLE)
return;
if(self.goalcurrent.classname == "player")
if(self.goalcurrent==self.navigation_jetpack_goal)
if(self.ammo_fuel)
{
- #ifdef DEBUG_BOT_GOALSTACK
+ if(autocvar_bot_debug_goalstack)
+ {
debuggoalstack();
te_wizspike(self.navigation_jetpack_point);
- #endif
+ }
// Take off
if not(self.aistatus & AI_STATUS_JETPACK_FLYING)
return;
}
-#ifdef DEBUG_BOT_GOALSTACK
- debuggoalstack();
-#endif
+ if(autocvar_bot_debug_goalstack)
+ debuggoalstack();
m1 = self.goalcurrent.origin + self.goalcurrent.mins;
m2 = self.goalcurrent.origin + self.goalcurrent.maxs;
// 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_SNIPERRIFLE
+ if(best || self.weapons) // || self.weapon == WEP_RIFLE
break;
if(i)
break;
self.havocbot_stickenemy = TRUE;
};
+float havocbot_chooseweapon_checkreload(float new_weapon)
+{
+ // bots under this skill cannot find unloaded weapons to reload idly when not in combat,
+ // so skip this for them, or they'll never get to reload their weapons at all.
+ // this also allows bots under this skill to be more stupid, and reload more often during combat :)
+ if(skill < 5)
+ return FALSE;
+
+ // if this weapon is scheduled for reloading, don't switch to it during combat
+ if (self.weapon_load[new_weapon] < 0)
+ {
+ local float i, other_weapon_available;
+ for(i = WEP_FIRST; i <= WEP_LAST; ++i)
+ {
+ // if we are out of ammo for all other weapons, it's an emergency to switch to anything else
+ if (weapon_action(i, WR_CHECKAMMO1) + weapon_action(i, WR_CHECKAMMO2))
+ other_weapon_available = TRUE;
+ }
+ if(other_weapon_available)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
void havocbot_chooseweapon()
{
local float i;
return;
}
- // Do not change weapon while reloading. If we do, the bot risks switching betwen empty weapons
- // before getting to reload them, shooting none of them at all, giving lower overall performance
- if(self.weapon && self.clip_load < 1)
- return;
-
// Do not change weapon during the next second after a combo
i = time - self.lastcombotime;
if(i < 1)
if ( distance > bot_distance_far ) {
for(i=0; i < WEP_COUNT && bot_weapons_far[i] != -1 ; ++i){
w = bot_weapons_far[i];
- if ( client_hasweapon(self, w, TRUE, FALSE) ){
- if ( self.weapon == w && combo)
+ if ( client_hasweapon(self, w, TRUE, FALSE) )
+ {
+ if ((self.weapon == w && combo) || havocbot_chooseweapon_checkreload(w))
continue;
self.switchweapon = w;
return;
if ( distance > bot_distance_close) {
for(i=0; i < WEP_COUNT && bot_weapons_mid[i] != -1 ; ++i){
w = bot_weapons_mid[i];
- if ( client_hasweapon(self, w, TRUE, FALSE) ){
- if ( self.weapon == w && combo)
+ if ( client_hasweapon(self, w, TRUE, FALSE) )
+ {
+ if ((self.weapon == w && combo) || havocbot_chooseweapon_checkreload(w))
continue;
self.switchweapon = w;
return;
// Choose weapons for close distance
for(i=0; i < WEP_COUNT && bot_weapons_close[i] != -1 ; ++i){
w = bot_weapons_close[i];
- if ( client_hasweapon(self, w, TRUE, FALSE) ){
- if ( self.weapon == w && combo)
+ if ( client_hasweapon(self, w, TRUE, FALSE) )
+ {
+ if ((self.weapon == w && combo) || havocbot_chooseweapon_checkreload(w))
continue;
self.switchweapon = w;
return;
}
}
- #ifdef DEBUG_BOT_GOALSTACK
+ if(autocvar_bot_debug_goalstack)
debuggoalstack();
- #endif
// Heading
local vector dir = self.goalcurrent.origin - (self.origin + self.view_ofs);