]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/bot/havocbot/havocbot.qc
Merge branch 'terencehill/quickmenu_file_example' into 'master'
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / bot / havocbot / havocbot.qc
index 5796fe60163346a5023ede6a39b4b560dc6bfa88..696de21dcad230f8f95a42ecd9fe49df82d5b479 100644 (file)
@@ -1,5 +1,4 @@
 #include "havocbot.qh"
-#include "../../_all.qh"
 
 #include "../aim.qh"
 #include "../bot.qh"
@@ -8,13 +7,16 @@
 #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.draggedby)
                return;
 
@@ -102,7 +104,8 @@ void havocbot_ai()
 
                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;
@@ -179,7 +182,7 @@ void havocbot_ai()
 }
 
 void havocbot_keyboard_movement(vector destorg)
-{
+{SELFPARAM();
        vector keyboard;
        float blend, maxspeed;
        float sk;
@@ -254,7 +257,7 @@ void havocbot_keyboard_movement(vector destorg)
 }
 
 void havocbot_bunnyhop(vector dir)
-{
+{SELFPARAM();
        float bunnyhopdistance;
        vector deviation;
        float maxspeed;
@@ -397,7 +400,7 @@ void havocbot_bunnyhop(vector dir)
 }
 
 void havocbot_movetogoal()
-{
+{SELFPARAM();
        vector destorg;
        vector diff;
        vector dir;
@@ -854,9 +857,9 @@ void havocbot_movetogoal()
 }
 
 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))
        {
@@ -908,10 +911,29 @@ void havocbot_chooseenemy()
 
        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)
@@ -925,20 +947,29 @@ void havocbot_chooseenemy()
                                        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
@@ -946,10 +977,12 @@ 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)
-{
+{SELFPARAM();
        // 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 :)
@@ -962,8 +995,9 @@ 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)
@@ -974,11 +1008,11 @@ float havocbot_chooseweapon_checkreload(int new_weapon)
 }
 
 void havocbot_chooseweapon()
-{
+{SELFPARAM();
        int i;
 
        // ;)
-       if(g_weaponarena_weapons == WEPSET_TUBA)
+       if(g_weaponarena_weapons == WEPSET(TUBA))
        {
                self.switchweapon = WEP_TUBA.m_id;
                return;
@@ -1011,7 +1045,7 @@ void havocbot_chooseweapon()
        // 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
@@ -1035,7 +1069,7 @@ void havocbot_chooseweapon()
 
                // 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) )
                                {
@@ -1049,7 +1083,7 @@ void havocbot_chooseweapon()
 
                // 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) )
                                {
@@ -1062,7 +1096,7 @@ void havocbot_chooseweapon()
                }
 
                // 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) )
                        {
@@ -1076,7 +1110,7 @@ void havocbot_chooseweapon()
 }
 
 void havocbot_aim()
-{
+{SELFPARAM();
        vector selfvel, enemyvel;
 //     if(self.flags & FL_INWATER)
 //             return;
@@ -1098,7 +1132,7 @@ void havocbot_aim()
 }
 
 float havocbot_moveto_refresh_route()
-{
+{SELFPARAM();
        // Refresh path to goal if necessary
        entity wp;
        wp = self.havocbot_personal_waypoint;
@@ -1109,7 +1143,7 @@ float havocbot_moveto_refresh_route()
 }
 
 float havocbot_moveto(vector pos)
-{
+{SELFPARAM();
        entity wp;
 
        if(self.aistatus & AI_STATUS_WAYPOINT_PERSONAL_GOING)
@@ -1231,7 +1265,7 @@ float havocbot_resetgoal()
 }
 
 void havocbot_setupbot()
-{
+{SELFPARAM();
        self.bot_ai = havocbot_ai;
        self.cmd_moveto = havocbot_moveto;
        self.cmd_resetgoal = havocbot_resetgoal;
@@ -1240,7 +1274,7 @@ void havocbot_setupbot()
 }
 
 vector havocbot_dodge()
-{
+{SELFPARAM();
        // LordHavoc: disabled because this is too expensive
        return '0 0 0';
 #if 0