From: terencehill Date: Sun, 29 Dec 2019 21:20:53 +0000 (+0100) Subject: Dinamically test and create links from waypoints to items every time a bot heads... X-Git-Tag: xonotic-v0.8.5~1164 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=a2f0b94d4b69d2009c8bac03be0783a63c9458bb;p=xonotic%2Fxonotic-data.pk3dir.git Dinamically test and create links from waypoints to items every time a bot heads to an item since creating all the links for all items when a bot joins is very expensive; it fixes #2048 "Adding bots causes a server spike" --- diff --git a/qcsrc/server/bot/default/navigation.qc b/qcsrc/server/bot/default/navigation.qc index 5457211d8..5ee889d16 100644 --- a/qcsrc/server/bot/default/navigation.qc +++ b/qcsrc/server/bot/default/navigation.qc @@ -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 (;;) diff --git a/qcsrc/server/bot/default/navigation.qh b/qcsrc/server/bot/default/navigation.qh index 026d326b9..073a98cf4 100644 --- a/qcsrc/server/bot/default/navigation.qh +++ b/qcsrc/server/bot/default/navigation.qh @@ -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)) diff --git a/qcsrc/server/bot/default/waypoints.qc b/qcsrc/server/bot/default/waypoints.qc index c09d8f81d..da407cbbc 100644 --- a/qcsrc/server/bot/default/waypoints.qc +++ b/qcsrc/server/bot/default/waypoints.qc @@ -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) diff --git a/qcsrc/server/bot/default/waypoints.qh b/qcsrc/server/bot/default/waypoints.qh index 25356446a..e9aa1ee12 100644 --- a/qcsrc/server/bot/default/waypoints.qh +++ b/qcsrc/server/bot/default/waypoints.qh @@ -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);