]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Bot AI: grouped small health/armor: avoid multiple costly calls of path finding code...
authorterencehill <piuntn@gmail.com>
Thu, 28 Dec 2017 18:09:31 +0000 (19:09 +0100)
committerterencehill <piuntn@gmail.com>
Thu, 28 Dec 2017 18:09:31 +0000 (19:09 +0100)
qcsrc/common/t_items.qc
qcsrc/common/t_items.qh
qcsrc/server/bot/default/havocbot/havocbot.qc

index f4431eed2887f84e812e7bd61bcc46dac87eb6c7..7409a669b450a199f70b821bd7e8aa011ca3da4e 100644 (file)
@@ -1126,8 +1126,6 @@ float ammo_pickupevalfunc(entity player, entity item)
        return rating;
 }
 
-.int item_group;
-.int item_group_count;
 float healtharmor_pickupevalfunc(entity player, entity item)
 {
        float c = 0;
index 5ecbe548824bef246be9e2ccf45b5b95882df09d..fd1c9d248eba1b9aee5f11dcc41ab55bac6b2a86 100644 (file)
@@ -26,6 +26,8 @@ const int ISF_SIZE                            = BIT(7);
 
 #ifdef SVQC
 void StartItem(entity this, entity a);
+.int item_group;
+.int item_group_count;
 #endif
 
 #ifdef CSQC
index ceeee469764ccc0cb3a47c1b2736088c61297e92..2a0d0c8503f005c17d2156fd2871ebf216ac932d 100644 (file)
@@ -453,6 +453,34 @@ bool havocbot_checkgoaldistance(entity this, vector gco)
        return false;
 }
 
+entity havocbot_select_an_item_of_group(entity this, int gr)
+{
+       entity selected = NULL;
+       float selected_dist2 = 0;
+       // select farthest item of this group from bot's position
+       IL_EACH(g_items, it.item_group == gr && it.solid,
+       {
+               float dist2 = vlen2(this.origin - it.origin);
+               if (dist2 < 600 ** 2 && dist2 > selected_dist2)
+               {
+                       selected = it;
+                       selected_dist2 = vlen2(this.origin - selected.origin);
+               }
+       });
+
+       if (!selected)
+               return NULL;
+
+       set_tracewalk_dest(selected, this.origin, false);
+       if (!tracewalk(this, this.origin, STAT(PL_MIN, this), STAT(PL_MAX, this),
+               tracewalk_dest, tracewalk_dest_height, bot_navigation_movemode))
+       {
+               return NULL;
+       }
+
+       return selected;
+}
+
 void havocbot_movetogoal(entity this)
 {
        vector diff;
@@ -800,16 +828,34 @@ void havocbot_movetogoal(entity this)
                // optimize path finding by anticipating goalrating when bot is near a waypoint;
                // in this case path finding can start directly from a waypoint instead of
                // looking for all the reachable waypoints up to a certain distance
-               if (navigation_poptouchedgoals(this) && this.goalcurrent)
+               if (navigation_poptouchedgoals(this))
                {
-                       if (IS_MOVABLE(this.goalcurrent) && IS_DEAD(this.goalcurrent))
+                       if (this.goalcurrent)
                        {
-                               // remove even if not visible
-                               navigation_goalrating_timeout_force(this);
-                               return;
+                               if (IS_MOVABLE(this.goalcurrent) && IS_DEAD(this.goalcurrent))
+                               {
+                                       // remove even if not visible
+                                       navigation_goalrating_timeout_force(this);
+                                       return;
+                               }
+                               else if (navigation_goalrating_timeout_can_be_anticipated(this))
+                                       navigation_goalrating_timeout_force(this);
+                       }
+                       else
+                       {
+                               entity old_goal = this.goalcurrent_prev;
+                               if (old_goal.item_group && this.item_group != old_goal.item_group)
+                               {
+                                       // Avoid multiple costly calls of path finding code that selects one of the closest
+                                       // item of the group by telling the bot to head directly to the farthest item.
+                                       // Next time we let the bot select a goal as usual which can be another item
+                                       // of this group (the closest one) and so on
+                                       this.item_group = old_goal.item_group;
+                                       entity new_goal = havocbot_select_an_item_of_group(this, old_goal.item_group);
+                                       if (new_goal)
+                                               navigation_pushroute(this, new_goal);
+                               }
                        }
-                       else if (navigation_goalrating_timeout_can_be_anticipated(this))
-                               navigation_goalrating_timeout_force(this);
                }
        }