]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge branch 'terencehill/bot_fixes' into 'master'
authorMario <zacjardine@y7mail.com>
Sat, 3 Oct 2015 06:52:42 +0000 (06:52 +0000)
committerMario <zacjardine@y7mail.com>
Sat, 3 Oct 2015 06:52:42 +0000 (06:52 +0000)
Bot fixes

* Make misc_breakablemodel entities secondary target for bots so they never prefer shooting at barrels over players
* While shooting at breakable objects, don't focus on them, be ready to choose another enemy
* Properly set bot_attack field in a few more situations (reset bot_attack field when going observer, and set/reset it properly when freezing/unfreezing somebody)

See merge request !197

qcsrc/server/bot/havocbot/havocbot.qc
qcsrc/server/cl_client.qc
qcsrc/server/g_damage.qc

index 7a3ac0561af3c6ec66917479cad1b6a2ab1756de..629009761fbcece18ce7d57a4f2094d6ef842eef 100644 (file)
@@ -856,7 +856,7 @@ 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 +908,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 +944,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,6 +974,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)
index b31d4d55666dc747c5bd8f24126874ce1f872f0a..da1a180d4c38dad14c8d1678b6edd6e2731ab8fc 100644 (file)
@@ -205,6 +205,7 @@ void PutObserverInServer (void)
        }
 
        self.frags = FRAGS_SPECTATOR;
+       self.bot_attack = false;
 
        MUTATOR_CALLHOOK(MakePlayerObserver);
 
index b5d87eed172cb27eafd02cec6d4af64a6dfd440e..2cc773b73f526b53a46b927692be1ba1069d9970 100644 (file)
@@ -560,6 +560,7 @@ void Freeze (entity targ, float freeze_time, float frozen_type, float show_waypo
        targ.revive_progress = ((frozen_type == 3) ? 1 : 0);
        targ.health = ((frozen_type == 3) ? targ_maxhealth : 1);
        targ.revive_speed = freeze_time;
+       self.bot_attack = false;
 
        entity ice, head;
        ice = spawn();
@@ -591,6 +592,9 @@ void Freeze (entity targ, float freeze_time, float frozen_type, float show_waypo
 
 void Unfreeze (entity targ)
 {
+       if(!targ.frozen)
+               return;
+
        if(targ.frozen && targ.frozen != 3) // only reset health if target was frozen
                targ.health = ((IS_PLAYER(targ)) ? start_health : targ.max_health);
 
@@ -598,6 +602,7 @@ void Unfreeze (entity targ)
        targ.frozen = 0;
        targ.revive_progress = 0;
        targ.revival_time = time;
+       self.bot_attack = true;
 
        WaypointSprite_Kill(targ.waypointsprite_attached);