]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/bot/default/waypoints.qc
Display hardwired waypoints purple
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / bot / default / waypoints.qc
index 9642bf3781d1895a0f2e770897392b92f1a6a158..1127a9d61873060c82fff14a983449d344ffc8b9 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <common/constants.qh>
 #include <common/net_linked.qh>
+#include <common/physics/player.qh>
 
 #include <lib/warpzone/common.qh>
 #include <lib/warpzone/util_server.qh>
@@ -23,7 +24,14 @@ void waypoint_unreachable(entity pl)
                it.colormod = '0.5 0.5 0.5';
                it.effects &= ~(EF_NODEPTHTEST | EF_RED | EF_BLUE);
        });
+
        entity e2 = navigation_findnearestwaypoint(pl, false);
+       if(!e2)
+       {
+               LOG_INFOF("Can't find any waypoint nearby\n");
+               return;
+       }
+
        navigation_markroutes(pl, e2);
 
        int j = 0;
@@ -160,6 +168,8 @@ void waypoint_setupmodel(entity wp)
                        wp.colormod = '1 0 0';
                else if (wp.wpflags & WAYPOINTFLAG_GENERATED)
                        wp.colormod = '1 1 0';
+               else if (wp.wphardwired)
+                       wp.colormod = '0.5 0 1';
                else
                        wp.colormod = '1 1 1';
        }
@@ -174,7 +184,14 @@ entity waypoint_spawn(vector m1, vector m2, float f)
 {
        if(!(f & WAYPOINTFLAG_PERSONAL))
        {
-               IL_EACH(g_waypoints, boxesoverlap(m1, m2, it.absmin, it.absmax),
+               vector em1 = m1;
+               vector em2 = m2;
+               if (m1 == m2)
+               {
+                       em1 = m1 - '8 8 8';
+                       em2 = m2 + '8 8 8';
+               }
+               IL_EACH(g_waypoints, boxesoverlap(em1, em2, it.absmin, it.absmax),
                {
                        return it;
                });
@@ -235,6 +252,21 @@ void waypoint_spawn_fromeditor(entity pl)
                ctf_flags = order;
        }
 
+       if(!PHYS_INPUT_BUTTON_CROUCH(pl))
+       {
+               // snap waypoint to item's origin if close enough
+               IL_EACH(g_items, true,
+               {
+                       vector item_org = (it.absmin + it.absmax) * 0.5;
+                       item_org.z = it.absmin.z - PL_MIN_CONST.z;
+                       if(vlen(item_org - org) < 30)
+                       {
+                               org = item_org;
+                               break;
+                       }
+               });
+       }
+
        LABEL(add_wp);
        e = waypoint_spawn(org, org, 0);
        waypoint_schedulerelink(e);
@@ -368,40 +400,99 @@ bool waypoint_islinked(entity from, entity to)
        return false;
 }
 
-// add a new link to the spawnfunc_waypoint, replacing the furthest link it already has
-void waypoint_addlink(entity from, entity to)
+void waypoint_updatecost_foralllinks()
 {
-       float c;
+       IL_EACH(g_waypoints, !(it.wpflags & WAYPOINTFLAG_TELEPORT),
+       {
+               if(it.wp00) it.wp00mincost = waypoint_getlinkcost(it, it.wp00);
+               if(it.wp01) it.wp01mincost = waypoint_getlinkcost(it, it.wp01);
+               if(it.wp02) it.wp02mincost = waypoint_getlinkcost(it, it.wp02);
+               if(it.wp03) it.wp03mincost = waypoint_getlinkcost(it, it.wp03);
+               if(it.wp04) it.wp04mincost = waypoint_getlinkcost(it, it.wp04);
+               if(it.wp05) it.wp05mincost = waypoint_getlinkcost(it, it.wp05);
+               if(it.wp06) it.wp06mincost = waypoint_getlinkcost(it, it.wp06);
+               if(it.wp07) it.wp07mincost = waypoint_getlinkcost(it, it.wp07);
+               if(it.wp08) it.wp08mincost = waypoint_getlinkcost(it, it.wp08);
+               if(it.wp09) it.wp09mincost = waypoint_getlinkcost(it, it.wp09);
+               if(it.wp10) it.wp10mincost = waypoint_getlinkcost(it, it.wp10);
+               if(it.wp11) it.wp11mincost = waypoint_getlinkcost(it, it.wp11);
+               if(it.wp12) it.wp12mincost = waypoint_getlinkcost(it, it.wp12);
+               if(it.wp13) it.wp13mincost = waypoint_getlinkcost(it, it.wp13);
+               if(it.wp14) it.wp14mincost = waypoint_getlinkcost(it, it.wp14);
+               if(it.wp15) it.wp15mincost = waypoint_getlinkcost(it, it.wp15);
+               if(it.wp16) it.wp16mincost = waypoint_getlinkcost(it, it.wp16);
+               if(it.wp17) it.wp17mincost = waypoint_getlinkcost(it, it.wp17);
+               if(it.wp18) it.wp18mincost = waypoint_getlinkcost(it, it.wp18);
+               if(it.wp19) it.wp19mincost = waypoint_getlinkcost(it, it.wp19);
+               if(it.wp20) it.wp20mincost = waypoint_getlinkcost(it, it.wp20);
+               if(it.wp21) it.wp21mincost = waypoint_getlinkcost(it, it.wp21);
+               if(it.wp22) it.wp22mincost = waypoint_getlinkcost(it, it.wp22);
+               if(it.wp23) it.wp23mincost = waypoint_getlinkcost(it, it.wp23);
+               if(it.wp24) it.wp24mincost = waypoint_getlinkcost(it, it.wp24);
+               if(it.wp25) it.wp25mincost = waypoint_getlinkcost(it, it.wp25);
+               if(it.wp26) it.wp26mincost = waypoint_getlinkcost(it, it.wp26);
+               if(it.wp27) it.wp27mincost = waypoint_getlinkcost(it, it.wp27);
+               if(it.wp28) it.wp28mincost = waypoint_getlinkcost(it, it.wp28);
+               if(it.wp29) it.wp29mincost = waypoint_getlinkcost(it, it.wp29);
+               if(it.wp30) it.wp30mincost = waypoint_getlinkcost(it, it.wp30);
+               if(it.wp31) it.wp31mincost = waypoint_getlinkcost(it, it.wp31);
+       });
+}
 
-       if (from == to)
-               return;
-       if (from.wpflags & WAYPOINTFLAG_NORELINK)
-               return;
+float waypoint_getlinearcost(float dist)
+{
+       if(skill >= autocvar_bot_ai_bunnyhop_skilloffset)
+               return dist / (autocvar_sv_maxspeed * 1.25);
+       return dist / autocvar_sv_maxspeed;
+}
 
-       if (waypoint_islinked(from, to))
-               return;
+float waypoint_gettravelcost(vector from, vector to)
+{
+       float c = waypoint_getlinearcost(vlen(to - from));
 
-       if (to.wpisbox || from.wpisbox)
+       float height = from.z - to.z;
+       if(height > jumpheight_vec.z && autocvar_sv_gravity > 0)
+       {
+               float height_cost = sqrt(height / (autocvar_sv_gravity / 2));
+               c = waypoint_getlinearcost(vlen(vec2(to - from))); // xy distance cost
+               if(height_cost > c)
+                       c = height_cost;
+       }
+       return c;
+}
+
+float waypoint_getlinkcost(entity from, entity to)
+{
+       vector v1 = from.origin;
+       vector v2 = to.origin;
+       if (from.wpisbox)
        {
-               // if either is a box we have to find the nearest points on them to
-               // calculate the distance properly
-               vector v1, v2, m1, m2;
-               v1 = from.origin;
-               m1 = to.absmin;
-               m2 = to.absmax;
+               vector m1 = to.absmin, m2 = to.absmax;
                v1_x = bound(m1_x, v1_x, m2_x);
                v1_y = bound(m1_y, v1_y, m2_y);
                v1_z = bound(m1_z, v1_z, m2_z);
-               v2 = to.origin;
-               m1 = from.absmin;
-               m2 = from.absmax;
+       }
+       if (to.wpisbox)
+       {
+               vector m1 = from.absmin, m2 = from.absmax;
                v2_x = bound(m1_x, v2_x, m2_x);
                v2_y = bound(m1_y, v2_y, m2_y);
                v2_z = bound(m1_z, v2_z, m2_z);
-               c = vlen(v2 - v1);
        }
-       else
-               c = vlen(to.origin - from.origin);
+       return waypoint_gettravelcost(v1, v2);
+}
+
+// add a new link to the spawnfunc_waypoint, replacing the furthest link it already has
+// if c == -1 automatically determine cost of the link
+void waypoint_addlink_customcost(entity from, entity to, float c)
+{
+       if (from == to || waypoint_islinked(from, to))
+               return;
+       if (c == -1 && (from.wpflags & WAYPOINTFLAG_NORELINK))
+               return;
+
+       if(c == -1)
+               c = waypoint_getlinkcost(from, to);
 
        if (from.wp31mincost < c) return;
        if (from.wp30mincost < c) {from.wp31 = to;from.wp31mincost = c;return;} from.wp31 = from.wp30;from.wp31mincost = from.wp30mincost;
@@ -438,6 +529,11 @@ void waypoint_addlink(entity from, entity to)
        from.wp00 = to;from.wp00mincost = c;return;
 }
 
+void waypoint_addlink(entity from, entity to)
+{
+       waypoint_addlink_customcost(from, to, -1);
+}
+
 // relink this spawnfunc_waypoint
 // (precompile a list of all reachable waypoints from this spawnfunc_waypoint)
 // (SLOW!)
@@ -484,6 +580,8 @@ void waypoint_think(entity this)
                                ++relink_lengthculled;
                                continue;
                        }
+                       float sv_deviation = 0;
+                       float ev_deviation = 0;
                        navigation_testtracewalk = 0;
                        if (!this.wpisbox)
                        {
@@ -491,6 +589,7 @@ void waypoint_think(entity this)
                                if (!trace_startsolid)
                                {
                                        //dprint("sv deviation", vtos(trace_endpos - sv), "\n");
+                                       sv_deviation = trace_endpos.z + 1 - sv.z;
                                        sv = trace_endpos + '0 0 1';
                                }
                        }
@@ -500,19 +599,37 @@ void waypoint_think(entity this)
                                if (!trace_startsolid)
                                {
                                        //dprint("ev deviation", vtos(trace_endpos - ev), "\n");
+                                       ev_deviation = trace_endpos.z + 1 - ev.z;
                                        ev = trace_endpos + '0 0 1';
                                }
                        }
                        //traceline(this.origin, it.origin, false, NULL);
                        //if (trace_fraction == 1)
-                       if (!this.wpisbox && tracewalk(this, sv, PL_MIN_CONST, PL_MAX_CONST, ev, MOVE_NOMONSTERS))
-                               waypoint_addlink(this, it);
-                       else
+                       if (this.wpisbox)
                                relink_walkculled += 0.5;
-                       if (!it.wpisbox && tracewalk(it, ev, PL_MIN_CONST, PL_MAX_CONST, sv, MOVE_NOMONSTERS))
-                               waypoint_addlink(it, this);
                        else
+                       {
+                               vector dest = ev;
+                               dest.z = em1.z + ev_deviation;
+                               float dest_height = em2.z - em1.z;
+                               if(tracewalk(this, sv, PL_MIN_CONST, PL_MAX_CONST, dest, dest_height, MOVE_NOMONSTERS))
+                                       waypoint_addlink(this, it);
+                               else
+                                       relink_walkculled += 0.5;
+                       }
+
+                       if (it.wpisbox)
                                relink_walkculled += 0.5;
+                       else
+                       {
+                               vector dest = sv;
+                               dest.z = sm1.z + sv_deviation;
+                               float dest_height = sm2.z - sm1.z;
+                               if(tracewalk(it, ev, PL_MIN_CONST, PL_MAX_CONST, dest, dest_height, MOVE_NOMONSTERS))
+                                       waypoint_addlink(it, this);
+                               else
+                                       relink_walkculled += 0.5;
+                       }
                }
        });
        navigation_testtracewalk = 0;
@@ -1025,6 +1142,35 @@ void waypoint_showlink(entity wp1, entity wp2, int display_type)
                te_lightning2(NULL, wp1.origin, wp2.origin);
 }
 
+void waypoint_showlinks_to(entity wp, int display_type)
+{
+       IL_EACH(g_waypoints, it != wp,
+       {
+               if (waypoint_islinked(it, wp))
+                       waypoint_showlink(it, wp, display_type);
+       });
+}
+
+void waypoint_showlinks_from(entity wp, int display_type)
+{
+       waypoint_showlink(wp.wp00, wp, display_type); waypoint_showlink(wp.wp16, wp, display_type);
+       waypoint_showlink(wp.wp01, wp, display_type); waypoint_showlink(wp.wp17, wp, display_type);
+       waypoint_showlink(wp.wp02, wp, display_type); waypoint_showlink(wp.wp18, wp, display_type);
+       waypoint_showlink(wp.wp03, wp, display_type); waypoint_showlink(wp.wp19, wp, display_type);
+       waypoint_showlink(wp.wp04, wp, display_type); waypoint_showlink(wp.wp20, wp, display_type);
+       waypoint_showlink(wp.wp05, wp, display_type); waypoint_showlink(wp.wp21, wp, display_type);
+       waypoint_showlink(wp.wp06, wp, display_type); waypoint_showlink(wp.wp22, wp, display_type);
+       waypoint_showlink(wp.wp07, wp, display_type); waypoint_showlink(wp.wp23, wp, display_type);
+       waypoint_showlink(wp.wp08, wp, display_type); waypoint_showlink(wp.wp24, wp, display_type);
+       waypoint_showlink(wp.wp09, wp, display_type); waypoint_showlink(wp.wp25, wp, display_type);
+       waypoint_showlink(wp.wp10, wp, display_type); waypoint_showlink(wp.wp26, wp, display_type);
+       waypoint_showlink(wp.wp11, wp, display_type); waypoint_showlink(wp.wp27, wp, display_type);
+       waypoint_showlink(wp.wp12, wp, display_type); waypoint_showlink(wp.wp28, wp, display_type);
+       waypoint_showlink(wp.wp13, wp, display_type); waypoint_showlink(wp.wp29, wp, display_type);
+       waypoint_showlink(wp.wp14, wp, display_type); waypoint_showlink(wp.wp30, wp, display_type);
+       waypoint_showlink(wp.wp15, wp, display_type); waypoint_showlink(wp.wp31, wp, display_type);
+}
+
 void botframe_showwaypointlinks()
 {
        if (time < botframe_waypointeditorlightningtime)
@@ -1047,38 +1193,10 @@ void botframe_showwaypointlinks()
                        if (head)
                        {
                                te_lightning2(NULL, head.origin, it.origin);
-                               waypoint_showlink(head.wp00, head, display_type);
-                               waypoint_showlink(head.wp01, head, display_type);
-                               waypoint_showlink(head.wp02, head, display_type);
-                               waypoint_showlink(head.wp03, head, display_type);
-                               waypoint_showlink(head.wp04, head, display_type);
-                               waypoint_showlink(head.wp05, head, display_type);
-                               waypoint_showlink(head.wp06, head, display_type);
-                               waypoint_showlink(head.wp07, head, display_type);
-                               waypoint_showlink(head.wp08, head, display_type);
-                               waypoint_showlink(head.wp09, head, display_type);
-                               waypoint_showlink(head.wp10, head, display_type);
-                               waypoint_showlink(head.wp11, head, display_type);
-                               waypoint_showlink(head.wp12, head, display_type);
-                               waypoint_showlink(head.wp13, head, display_type);
-                               waypoint_showlink(head.wp14, head, display_type);
-                               waypoint_showlink(head.wp15, head, display_type);
-                               waypoint_showlink(head.wp16, head, display_type);
-                               waypoint_showlink(head.wp17, head, display_type);
-                               waypoint_showlink(head.wp18, head, display_type);
-                               waypoint_showlink(head.wp19, head, display_type);
-                               waypoint_showlink(head.wp20, head, display_type);
-                               waypoint_showlink(head.wp21, head, display_type);
-                               waypoint_showlink(head.wp22, head, display_type);
-                               waypoint_showlink(head.wp23, head, display_type);
-                               waypoint_showlink(head.wp24, head, display_type);
-                               waypoint_showlink(head.wp25, head, display_type);
-                               waypoint_showlink(head.wp26, head, display_type);
-                               waypoint_showlink(head.wp27, head, display_type);
-                               waypoint_showlink(head.wp28, head, display_type);
-                               waypoint_showlink(head.wp29, head, display_type);
-                               waypoint_showlink(head.wp30, head, display_type);
-                               waypoint_showlink(head.wp31, head, display_type);
+                               if(PHYS_INPUT_BUTTON_CROUCH(it))
+                                       waypoint_showlinks_to(head, display_type);
+                               else
+                                       waypoint_showlinks_from(head, display_type);
                        }
                }
        });