]> git.rm.cloudns.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Dinamically test and create links from waypoints to items every time a bot heads...
authorterencehill <piuntn@gmail.com>
Sun, 29 Dec 2019 21:20:53 +0000 (22:20 +0100)
committerterencehill <piuntn@gmail.com>
Sun, 29 Dec 2019 21:20:53 +0000 (22:20 +0100)
qcsrc/server/bot/default/navigation.qc
qcsrc/server/bot/default/navigation.qh
qcsrc/server/bot/default/waypoints.qc
qcsrc/server/bot/default/waypoints.qh

index 5457211d84d2305bfa70ba1cd74a694a61239fbe..5ee889d169605d4f0c373b6d331682a903595563 100644 (file)
@@ -943,10 +943,7 @@ entity navigation_findnearestwaypoint_withdist_except(entity ent, float walkfrom
                        if(boxesoverlap(pm1, pm2, it.absmin, it.absmax))
                        {
                                if(walkfromwp && !ent.navigation_dynamicgoal)
-                               {
                                        waypoint_clearlinks(ent); // initialize wpXXmincost fields
-                                       navigation_item_addlink(it, ent);
-                               }
                                return it;
                        }
                });
@@ -965,24 +962,6 @@ entity navigation_findnearestwaypoint_withdist_except(entity ent, float walkfrom
                org.z = ent.origin.z + ent.mins.z - PL_MIN_CONST.z; // player height
        }
 
-       if(!autocvar_g_waypointeditor && walkfromwp && !ent.navigation_dynamicgoal)
-       {
-               waypoint_clearlinks(ent); // initialize wpXXmincost fields
-               IL_EACH(g_waypoints, it != ent,
-               {
-                       if (walkfromwp && (it.wpflags & WPFLAGMASK_NORELINK))
-                               continue;
-
-                       set_tracewalk_dest(ent, it.origin, false);
-                       if (vdist(tracewalk_dest - it.origin, <, 1050)
-                               && tracewalk(ent, it.origin, PL_MIN_CONST, PL_MAX_CONST,
-                               tracewalk_dest, tracewalk_dest_height, bot_navigation_movemode))
-                       {
-                               navigation_item_addlink(it, ent);
-                       }
-               });
-       }
-
        // box check failed, try walk
        IL_EACH(g_waypoints, it != ent,
        {
@@ -1507,7 +1486,7 @@ bool navigation_routetogoal(entity this, entity e, vector startposition)
        if(e == NULL)
                return false;
 
-       if(nearest_wp && nearest_wp.enemy)
+       if(nearest_wp && nearest_wp.enemy && !(nearest_wp.enemy.wpflags & WPFLAGMASK_NORELINK))
        {
                // often path can be optimized by not adding the nearest waypoint
                if (this.goalentity.navigation_dynamicgoal || autocvar_g_waypointeditor)
@@ -1529,8 +1508,35 @@ bool navigation_routetogoal(entity this, entity e, vector startposition)
                                }
                        }
                }
-               else if(navigation_item_islinked(nearest_wp.enemy, this.goalentity))
-                       e = nearest_wp.enemy;
+               else
+               {
+                       // NOTE unlike waypoints, items hold incoming links
+                       navigation_item_initlinks_ifneeded(this.goalentity);
+                       int link_num = navigation_item_getlinknum(this.goalentity, nearest_wp.enemy);
+                       if (link_num >= 0)
+                       {
+                               if (navigation_item_iswalkablelink(this.goalentity, link_num))
+                                       e = nearest_wp.enemy;
+                       }
+                       else // untested link
+                       {
+                               entity wp = nearest_wp.enemy;
+                               entity goal = this.goalentity;
+                               bool walkable = false;
+                               if (checkpvs(wp.origin, goal))
+                               {
+                                       set_tracewalk_dest(goal, wp.origin, false);
+                                       if (vdist(tracewalk_dest - wp.origin, <, 1050)
+                                               && tracewalk(goal, wp.origin, PL_MIN_CONST, PL_MAX_CONST,
+                                               tracewalk_dest, tracewalk_dest_height, bot_navigation_movemode))
+                                       {
+                                               walkable = true;
+                                               e = nearest_wp.enemy;
+                                       }
+                               }
+                               navigation_item_add_link(wp, goal, walkable);
+                       }
+               }
        }
 
        for (;;)
index 026d326b9e6fba8524b95a73862eb284e3f06d86..073a98cf4e725544eab16f9e84a2f180285f30a2 100644 (file)
@@ -41,6 +41,9 @@ entity navigation_bestgoal;
 /*
 // item it is linked from waypoint it.wpXX (INCOMING link)
 // links are sorted by their cost (wpXXmincost)
+// one of these links is added in game every time a bot heads to an item
+// even links that are not walkable are added (marked with a high cost)
+// so that bots next time know if they can walk it or not saving a tracewalk call
 .entity wp00, wp01, wp02, wp03, wp04, wp05, wp06, wp07, wp08, wp09, wp10, wp11, wp12, wp13, wp14, wp15;
 .entity wp16, wp17, wp18, wp19, wp20, wp21, wp22, wp23, wp24, wp25, wp26, wp27, wp28, wp29, wp30, wp31;
 
@@ -50,9 +53,12 @@ entity navigation_bestgoal;
 .float wp24mincost, wp25mincost, wp26mincost, wp27mincost, wp28mincost, wp29mincost, wp30mincost, wp31mincost;
 */
 
-#define navigation_item_islinked(from_wp, to_item) waypoint_islinked(to_item, from_wp)
-#define navigation_item_addlink(from_wp, to_item) \
-       waypoint_addlink_customcost(to_item, from_wp, waypoint_getlinkcost(from_wp, to_item))
+#define navigation_item_initlinks_ifneeded(e) MACRO_BEGIN if (!e.wp00) waypoint_clearlinks(e); MACRO_END // initialize wpXXmincost fields
+#define navigation_item_getlinknum(to_item, from_wp) waypoint_getlinknum(to_item, from_wp)
+#define navigation_item_iswalkablelink(to_item, from_wp) (waypoint_get_assigned_link_cost(to_item, from_wp) < 999)
+
+#define navigation_item_add_link(from_wp, to_item, walkable) \
+       waypoint_addlink_customcost(to_item, from_wp, (walkable ? waypoint_getlinkcost(from_wp, to_item) : 999))
 
 #define TELEPORT_USED(pl, tele_wp) \
        boxesoverlap(tele_wp.absmin, tele_wp.absmax, pl.lastteleport_origin + STAT(PL_MIN, pl), pl.lastteleport_origin + STAT(PL_MAX, pl))
index c09d8f81d4fc927bdabe934b27ac86a9e0f3dcab..da407cbbc8673d7cfd2be4603898c0bf5aa1f120 100644 (file)
@@ -1572,6 +1572,46 @@ void waypoint_load_hardwiredlinks()
        LOG_TRACE("loaded ", ftos(c), " waypoint links from maps/", mapname, ".waypoints.hardwired");
 }
 
+float waypoint_get_assigned_link_cost(entity w, float i)
+{
+       switch(i)
+       {
+               case  0: return w.wp00mincost;
+               case  1: return w.wp01mincost;
+               case  2: return w.wp02mincost;
+               case  3: return w.wp03mincost;
+               case  4: return w.wp04mincost;
+               case  5: return w.wp05mincost;
+               case  6: return w.wp06mincost;
+               case  7: return w.wp07mincost;
+               case  8: return w.wp08mincost;
+               case  9: return w.wp09mincost;
+               case 10: return w.wp10mincost;
+               case 11: return w.wp11mincost;
+               case 12: return w.wp12mincost;
+               case 13: return w.wp13mincost;
+               case 14: return w.wp14mincost;
+               case 15: return w.wp15mincost;
+               case 16: return w.wp16mincost;
+               case 17: return w.wp17mincost;
+               case 18: return w.wp18mincost;
+               case 19: return w.wp19mincost;
+               case 20: return w.wp20mincost;
+               case 21: return w.wp21mincost;
+               case 22: return w.wp22mincost;
+               case 23: return w.wp23mincost;
+               case 24: return w.wp24mincost;
+               case 25: return w.wp25mincost;
+               case 26: return w.wp26mincost;
+               case 27: return w.wp27mincost;
+               case 28: return w.wp28mincost;
+               case 29: return w.wp29mincost;
+               case 30: return w.wp30mincost;
+               case 31: return w.wp31mincost;
+               default: return -1;
+       }
+}
+
 entity waypoint_get_link(entity w, float i)
 {
        switch(i)
index 25356446a4d1c05d40ece80c5e6f81f64cbfab7e..e9aa1ee12a64213aa9fb8af5feb11347495ba02e 100644 (file)
@@ -67,6 +67,8 @@ void waypoint_think(entity this);
 void waypoint_clearlinks(entity wp);
 void waypoint_schedulerelink(entity wp);
 
+float waypoint_get_assigned_link_cost(entity w, float i);
+
 float waypoint_getlinkcost(entity from, entity to);
 float waypoint_gettravelcost(vector from, vector to, entity from_ent, entity to_ent);
 float waypoint_getlinearcost(float dist);