]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/bot/havocbot/havocbot.qc
Merge branch 'master' into terencehill/bot_fixes
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / bot / havocbot / havocbot.qc
index 139926b7e4a844e7080b14c11445716a94ffbb05..7b7c6474307a9c81db7cceaaa5eac771420db6c1 100644 (file)
@@ -1,9 +1,18 @@
 #include "havocbot.qh"
-#include "role_onslaught.qc"
-#include "role_keyhunt.qc"
-#include "roles.qc"
+#include "../../_all.qh"
+
+#include "../aim.qh"
+#include "../bot.qh"
+#include "../navigation.qh"
+#include "../scripting.qh"
+#include "../waypoints.qh"
+
+#include "../../../common/constants.qh"
+
 #include "../../../common/triggers/trigger/jumppads.qh"
 
+#include "../../../warpzonelib/common.qh"
+
 void havocbot_ai()
 {
        if(self.draggedby)
@@ -149,9 +158,6 @@ void havocbot_ai()
        // if the bot is not attacking, consider reloading weapons
        if (!(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)
@@ -162,9 +168,9 @@ void havocbot_ai()
                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)
+                       for (int i = WEP_FIRST; i <= WEP_LAST; ++i)
                        {
-                               e = get_weaponinfo(i);
+                               entity e = get_weaponinfo(i);
                                if ((self.weapons & WepSet_FromWeapon(i)) && (e.spawnflags & WEP_FLAG_RELOADABLE) && (self.weapon_load[i] < e.reloading_ammo))
                                        self.switchweapon = i;
                        }
@@ -594,7 +600,7 @@ void havocbot_movetogoal()
                else if(self.health>WEP_CVAR(devastator, damage)*0.5)
                {
                        if(self.velocity.z < 0)
-                       if(client_hasweapon(self, WEP_DEVASTATOR, true, false))
+                       if(client_hasweapon(self, WEP_DEVASTATOR.m_id, true, false))
                        {
                                self.movement_x = maxspeed;
 
@@ -608,7 +614,7 @@ void havocbot_movetogoal()
                                        return;
                                }
 
-                               self.switchweapon = WEP_DEVASTATOR;
+                               self.switchweapon = WEP_DEVASTATOR.m_id;
                                self.v_angle_x = 90;
                                self.BUTTON_ATCK = true;
                                self.rocketjumptime = time + WEP_CVAR(devastator, detonatedelay);
@@ -850,7 +856,7 @@ void havocbot_movetogoal()
 void havocbot_chooseenemy()
 {
        entity head, best, head2;
-       float rating, bestrating, i, hf;
+       float rating, bestrating, hf;
        vector eye, v;
        if (autocvar_bot_nofire || IS_INDEPENDENT_PLAYER(self))
        {
@@ -902,10 +908,24 @@ void havocbot_chooseenemy()
 
        self.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_CORPSE;
 
-       for(i = 0; ; ++i)
+       bool scan_transparent = false;
+       bool scan_secondary_targets = false;
+       while(true)
        {
-               while (head)
+               scan_secondary_targets = false;
+               for ( ; head; head = head.chain)
                {
+                       if(!scan_secondary_targets)
+                       {
+                               if(head.classname == "misc_breakablemodel")
+                                       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)
@@ -919,20 +939,27 @@ void havocbot_chooseenemy()
                                        bestrating = rating;
                                }
                        }
-                       head = head.chain;
+
+                       if(!best && !scan_secondary_targets)
+                       {
+                               scan_secondary_targets = true;
+                               head = head2;
+                               bestrating = 100000000;
+                       }
                }
 
                // 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
+               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
@@ -940,6 +967,8 @@ void havocbot_chooseenemy()
 
        self.enemy = best;
        self.havocbot_stickenemy = true;
+       if(best && best.classname == "misc_breakablemodel")
+               self.havocbot_stickenemy = false;
 }
 
 float havocbot_chooseweapon_checkreload(int new_weapon)
@@ -974,7 +1003,7 @@ void havocbot_chooseweapon()
        // ;)
        if(g_weaponarena_weapons == WEPSET_TUBA)
        {
-               self.switchweapon = WEP_TUBA;
+               self.switchweapon = WEP_TUBA.m_id;
                return;
        }
 
@@ -983,7 +1012,7 @@ void havocbot_chooseweapon()
        {
                // If no weapon was chosen get the first available weapon
                if(self.weapon==0)
-               for(i = WEP_FIRST; i <= WEP_LAST; ++i) if(i != WEP_BLASTER)
+               for(i = WEP_FIRST; i <= WEP_LAST; ++i) if(i != WEP_BLASTER.m_id)
                {
                        if(client_hasweapon(self, i, true, false))
                        {