X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fserver%2Fbot%2Fhavocbot%2Fhavocbot.qc;h=dd111d9f00400f376eedd8ea6462ec90c3caaddd;hb=9a2efec7718c9dd4805a8982f475f86f05509979;hp=f6a5d50a39f793191e0e4f918662fc03f9ff938a;hpb=fdb8fddad19ce594e98563dd156fa349c0a834c6;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/server/bot/havocbot/havocbot.qc b/qcsrc/server/bot/havocbot/havocbot.qc index f6a5d50a3..dd111d9f0 100644 --- a/qcsrc/server/bot/havocbot/havocbot.qc +++ b/qcsrc/server/bot/havocbot/havocbot.qc @@ -145,6 +145,31 @@ void havocbot_ai() bot_aimdir(v, -1); } havocbot_movetogoal(); + + // 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) // 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 + { + for(i = WEP_FIRST; i <= WEP_LAST; ++i) + { + e = get_weaponinfo(i); + if ((e.spawnflags & WEP_FLAG_RELOADABLE) && (self.weapon_load[i] < cvar(strcat("g_balance_", e.netname, "_reload_ammo")))) + self.switchweapon = i; + } + } + } }; void havocbot_keyboard_movement(vector destorg) @@ -170,7 +195,7 @@ void havocbot_keyboard_movement(vector destorg) local float trigger, trigger1; blend = bound(0,sk*0.1,1); - trigger = autocvar_bot_ai_keyboard_treshold; + trigger = autocvar_bot_ai_keyboard_threshold; trigger1 = 0 - trigger; // categorize forward movement @@ -234,7 +259,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") @@ -391,10 +416,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) @@ -628,9 +654,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; @@ -893,7 +918,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; @@ -914,6 +939,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; @@ -978,8 +1028,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; @@ -991,8 +1042,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; @@ -1003,8 +1055,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; @@ -1086,9 +1139,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);