X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;ds=sidebyside;f=qcsrc%2Fserver%2Fbot%2Fhavocbot%2Fhavocbot.qc;h=7c2f986346677e73b2cefc533cf45651ebd18cf0;hb=36f4b513fd7eac9b2dc37d393cebf3b7d98ac9af;hp=7463cfc6f0e9362f5bcdea43dddfb84b832ad7fa;hpb=6110f5b7f8b966f961eff44f0161e6b3cef2c1d9;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/server/bot/havocbot/havocbot.qc b/qcsrc/server/bot/havocbot/havocbot.qc index 7463cfc6f..7c2f98634 100644 --- a/qcsrc/server/bot/havocbot/havocbot.qc +++ b/qcsrc/server/bot/havocbot/havocbot.qc @@ -2,6 +2,8 @@ #include "role_ctf.qc" #include "role_onslaught.qc" #include "role_keyhunt.qc" +#include "role_freezetag.qc" +#include "role_keepaway.qc" #include "roles.qc" void havocbot_ai() @@ -146,27 +148,26 @@ void havocbot_ai() } 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; } } @@ -260,7 +261,7 @@ void havocbot_bunnyhop(vector dir) // 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") @@ -417,10 +418,11 @@ void havocbot_movetogoal() 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) @@ -654,9 +656,8 @@ void havocbot_movetogoal() 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; @@ -919,7 +920,7 @@ void havocbot_chooseenemy() // 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; @@ -940,6 +941,31 @@ void havocbot_chooseenemy() 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; @@ -1004,8 +1030,9 @@ void havocbot_chooseweapon() 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; @@ -1017,8 +1044,9 @@ void havocbot_chooseweapon() 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; @@ -1029,8 +1057,9 @@ void havocbot_chooseweapon() // 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; @@ -1112,9 +1141,8 @@ float havocbot_moveto(vector pos) } } - #ifdef DEBUG_BOT_GOALSTACK + if(autocvar_bot_debug_goalstack) debuggoalstack(); - #endif // Heading local vector dir = self.goalcurrent.origin - (self.origin + self.view_ofs);