]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge remote-tracking branch 'origin/terencehill/bot_waypoints'
authorterencehill <piuntn@gmail.com>
Sat, 8 Dec 2018 12:25:04 +0000 (13:25 +0100)
committerterencehill <piuntn@gmail.com>
Sat, 8 Dec 2018 12:25:04 +0000 (13:25 +0100)
qcsrc/server/bot/api.qh
qcsrc/server/bot/default/waypoints.qc
qcsrc/server/bot/default/waypoints.qh
qcsrc/server/command/cmd.qc

index 4a0ede4e2acebe76a385a172403c9ad1caba9c2e..3f434dbecc7ab529dcc0794ba514e31c60e4eb68 100644 (file)
@@ -124,3 +124,6 @@ void waypoint_spawnforteleporter_wz(entity e, entity tracetest_ent);
 void waypoint_spawn_fromeditor(entity pl);
 entity waypoint_spawn(vector m1, vector m2, float f);
 void waypoint_unreachable(entity pl);
+
+void waypoint_getSymmetricalOrigin_cmd(entity caller, bool save, int arg_idx);
+void waypoint_getSymmetricalAxis_cmd(entity caller, bool save, int arg_idx);
index 8ef440deebfd67eed368bab3862c9d6018066a5f..8b0591099d3681254f54b06b507c3df0f5b1b2fb 100644 (file)
@@ -128,6 +128,108 @@ void waypoint_unreachable(entity pl)
        if (j) LOG_INFOF("%d items have no nearest waypoint and cannot be walked to (marked with blue light)\n", j);
 }
 
+void waypoint_getSymmetricalAxis_cmd(entity caller, bool save, int arg_idx)
+{
+       vector v1 = stov(argv(arg_idx++));
+       vector v2 = stov(argv(arg_idx++));
+       vector mid = (v1 + v2) / 2;
+
+       float diffy = (v2.y - v1.y);
+       float diffx = (v2.x - v1.x);
+       if (v1.y == v2.y)
+               diffy = 0.000001;
+       if (v1.x == v2.x)
+               diffx = 0.000001;
+       float m = - diffx / diffy;
+       float q = - m * mid.x + mid.y;
+       if (fabs(m) <= 0.000001) m = 0;
+       if (fabs(q) <= 0.000001) q = 0;
+
+       string axis_str =  strcat(ftos(m), " ", ftos(q));
+       if (save)
+               cvar_set("g_waypointeditor_symmetrical_axis", axis_str);
+       axis_str = strcat("\"", axis_str, "\"");
+       sprint(caller, strcat("Axis of symmetry based on input points: ", axis_str, "\n"));
+       if (save)
+               sprint(caller, sprintf(" ^3saved to %s\n", "g_waypointeditor_symmetrical_axis"));
+       if (save)
+       {
+               cvar_set("g_waypointeditor_symmetrical", "-2");
+               sprint(caller, strcat("g_waypointeditor_symmetrical", " has been set to ",
+                       cvar_string("g_waypointeditor_symmetrical"), "\n"));
+       }
+}
+
+void waypoint_getSymmetricalOrigin_cmd(entity caller, bool save, int arg_idx)
+{
+       vector org = '0 0 0';
+       int ctf_flags = 0;
+       for (int i = 0; i < 6; i++)
+       {
+               if (argv(arg_idx + i) != "")
+                       ctf_flags++;
+       }
+       if (ctf_flags < 2)
+       {
+               ctf_flags = 0;
+               org = vec2(havocbot_middlepoint);
+               if (argv(arg_idx) != "")
+                       sprint(caller, "WARNING: Ignoring single input point\n");
+               if (havocbot_middlepoint_radius == 0)
+               {
+                       sprint(caller, "Origin of symmetry can't be automatically determined\n");
+                       return;
+               }
+       }
+       else
+       {
+               vector v1, v2, v3, v4, v5, v6;
+               for (int i = 1; i <= ctf_flags; i++)
+               {
+                       if (i == 1) { v1 = stov(argv(arg_idx++)); org = v1 / ctf_flags; }
+                       else if (i == 2) { v2 = stov(argv(arg_idx++)); org += v2 / ctf_flags; }
+                       else if (i == 3) { v3 = stov(argv(arg_idx++)); org += v3 / ctf_flags; }
+                       else if (i == 4) { v4 = stov(argv(arg_idx++)); org += v4 / ctf_flags; }
+                       else if (i == 5) { v5 = stov(argv(arg_idx++)); org += v5 / ctf_flags; }
+                       else if (i == 6) { v6 = stov(argv(arg_idx++)); org += v6 / ctf_flags; }
+               }
+       }
+
+       if (fabs(org.x) <= 0.000001) org.x = 0;
+       if (fabs(org.y) <= 0.000001) org.y = 0;
+       string org_str = strcat(ftos(org.x), " ", ftos(org.y));
+       if (save)
+       {
+               cvar_set("g_waypointeditor_symmetrical_origin", org_str);
+               cvar_set("g_waypointeditor_symmetrical_order", ftos(ctf_flags));
+       }
+       org_str = strcat("\"", org_str, "\"");
+
+       if (ctf_flags < 2)
+               sprint(caller, strcat("Origin of symmetry based on flag positions: ", org_str, "\n"));
+       else
+               sprint(caller, strcat("Origin of symmetry based on input points: ", org_str, "\n"));
+       if (save)
+               sprint(caller, sprintf(" ^3saved to %s\n", "g_waypointeditor_symmetrical_origin"));
+
+       if (ctf_flags < 2)
+               sprint(caller, "Order of symmetry: 0 (autodetected)\n");
+       else
+               sprint(caller, strcat("Order of symmetry: ", ftos(ctf_flags), "\n"));
+       if (save)
+               sprint(caller, sprintf(" ^3saved to %s\n", "g_waypointeditor_symmetrical_order"));
+
+       if (save)
+       {
+               if (ctf_flags < 2)
+                       cvar_set("g_waypointeditor_symmetrical", "0");
+               else
+                       cvar_set("g_waypointeditor_symmetrical", "-1");
+               sprint(caller, strcat("g_waypointeditor_symmetrical", " has been set to ",
+                       cvar_string("g_waypointeditor_symmetrical"), "\n"));
+       }
+}
+
 vector waypoint_getSymmetricalPoint(vector org, int ctf_flags)
 {
        vector new_org = org;
@@ -1401,6 +1503,25 @@ void waypoint_showlinks_from(entity wp, int display_type)
        waypoint_showlink(wp.wp15, wp, display_type); waypoint_showlink(wp.wp31, wp, display_type);
 }
 
+void crosshair_trace_waypoints(entity pl)
+{
+       IL_EACH(g_waypoints, true, {
+               it.solid = SOLID_BSP;
+               if (!it.wpisbox)
+                       setsize(it, '-16 -16 -16', '16 16 16');
+       });
+
+       crosshair_trace(pl);
+
+       IL_EACH(g_waypoints, true, {
+               it.solid = SOLID_TRIGGER;
+               if (!it.wpisbox)
+                       setsize(it, '0 0 0', '0 0 0');
+       });
+       if (trace_ent.classname != "waypoint")
+               trace_ent = NULL;
+}
+
 void botframe_showwaypointlinks()
 {
        if (time < botframe_waypointeditorlightningtime)
@@ -1409,10 +1530,18 @@ void botframe_showwaypointlinks()
        FOREACH_CLIENT(IS_PLAYER(it) && !it.isbot,
        {
                int display_type = 0;
-               entity head = navigation_findnearestwaypoint(it, false);
+               if (wasfreed(it.wp_aimed))
+                       it.wp_aimed = NULL;
+               if (wasfreed(it.wp_locked))
+                       it.wp_locked = NULL;
+               if (PHYS_INPUT_BUTTON_USE(it))
+                       it.wp_locked = it.wp_aimed;
+               entity head = it.wp_locked;
+               if (!head)
+                       head = navigation_findnearestwaypoint(it, false);
                it.nearestwaypoint = head; // mainly useful for debug
                it.nearestwaypointtimeout = time + 2; // while I'm at it...
-               if (IS_ONGROUND(it) || it.waterlevel > WATERLEVEL_NONE)
+               if (IS_ONGROUND(it) || it.waterlevel > WATERLEVEL_NONE || it.wp_locked)
                        display_type = 1; // default
                else if(head && (head.wphardwired))
                        display_type = 2; // only hardwired
@@ -1431,6 +1560,29 @@ void botframe_showwaypointlinks()
                                        waypoint_showlinks_from(head, display_type);
                        }
                }
+               string str;
+               entity wp = NULL;
+               if (vdist(vec2(it.velocity), <, autocvar_sv_maxspeed * 1.1))
+               {
+                       crosshair_trace_waypoints(it);
+                       if (trace_ent)
+                       {
+                               wp = trace_ent;
+                               if (wp != it.wp_aimed)
+                               {
+                                       str = sprintf("\necho ^2WP info^7: entity: %d, flags: %d, origin: '%s'\n", etof(wp), wp.wpflags, vtos(wp.origin));
+                                       if (wp.wpisbox)
+                                               str = strcat(str, sprintf("echo \" absmin: '%s', absmax: '%s'\"\n", vtos(wp.absmin), vtos(wp.absmax)));
+                                       stuffcmd(it, str);
+                                       str = sprintf("entity: %d\nflags: %d\norigin: \'%s\'", etof(wp), wp.wpflags, vtos(wp.origin));
+                                       if (wp.wpisbox)
+                                               str = strcat(str, sprintf(" \nabsmin: '%s'\nabsmax: '%s'", vtos(wp.absmin), vtos(wp.absmax)));
+                                       debug_text_3d(wp.origin, str, 0, 7, '0 0 0');
+                               }
+                       }
+               }
+               if (it.wp_aimed != wp)
+                       it.wp_aimed = wp;
        });
 }
 
index 1de3d449018d19cb4aae2cab101e864b595bf312..0b69dcbb8bca3e80fa9d543c5fcab6305e1f3b8c 100644 (file)
@@ -28,6 +28,8 @@ float botframe_cachedwaypointlinks;
 
 .float wpfire, wpcost, wpconsidered, wpisbox, wplinked, wphardwired;
 .int wpflags;
+.entity wp_aimed;
+.entity wp_locked;
 
 .vector wpnearestpoint;
 
index 80716d811c8e1da75124b95edb4a23b2e2ea5150..e39d5039dd8f4debe754d6487671416e401f5853 100644 (file)
@@ -188,6 +188,7 @@ void ClientCommand_wpeditor(entity caller, int request, int argc)
                                                sprint(caller, "ERROR: this command works only if you are player\n");
                                        else
                                                waypoint_spawn_fromeditor(caller);
+                                       return;
                                }
                                else if (argv(1) == "remove")
                                {
@@ -195,6 +196,7 @@ void ClientCommand_wpeditor(entity caller, int request, int argc)
                                                sprint(caller, "ERROR: this command works only if you are player\n");
                                        else
                                                waypoint_remove_fromeditor(caller);
+                                       return;
                                }
                                else if (argv(1) == "unreachable")
                                {
@@ -202,13 +204,34 @@ void ClientCommand_wpeditor(entity caller, int request, int argc)
                                                sprint(caller, "ERROR: this command works only if you are player\n");
                                        else
                                                waypoint_unreachable(caller);
+                                       return;
                                }
                                else if (argv(1) == "saveall")
+                               {
                                        waypoint_saveall();
+                                       return;
+                               }
                                else if (argv(1) == "relinkall")
+                               {
                                        waypoint_schedulerelinkall();
-
-                               return;
+                                       return;
+                               }
+                               else if (argv(1) == "symaxis")
+                               {
+                                       if (argv(2) == "set" || argv(2) == "get")
+                                       {
+                                               waypoint_getSymmetricalAxis_cmd(caller, (argv(2) == "set"), 3);
+                                               return;
+                                       }
+                               }
+                               else if (argv(1) == "symorigin")
+                               {
+                                       if (argv(2) == "set" || argv(2) == "get")
+                                       {
+                                               waypoint_getSymmetricalOrigin_cmd(caller, (argv(2) == "set"), 3);
+                                               return;
+                                       }
+                               }
                        }
                }
 
@@ -217,7 +240,13 @@ void ClientCommand_wpeditor(entity caller, int request, int argc)
                case CMD_REQUEST_USAGE:
                {
                        sprint(caller, "\nUsage:^3 cmd wpeditor action\n");
-                       sprint(caller, "  Where 'action' can be: spawn, remove, unreachable, saveall, relinkall\n");
+                       sprint(caller, "  Where 'action' can be: spawn, remove, unreachable, saveall, relinkall,\n");
+                       sprint(caller, "   symorigin get|set\n");
+                       sprint(caller, "   symorigin get|set p1 p2 ... pX\n");
+                       sprint(caller, "   symaxis get|set p1 p2\n");
+                       sprint(caller, "    where p1 p2 ... pX are positions \"x y z\" (z can be omitted)\n");
+                       sprint(caller, " symorigin and symaxis commands are useful to determine origin/axis of symmetry"
+                                                       " on maps without ctf flags or where flags aren't perfectly symmetrical\n");
                        return;
                }
        }