+void waypoint_spawn_fromeditor(entity pl)
+{
+ entity e;
+ vector org = pl.origin;
+ int ctf_flags = havocbot_symmetryaxis_equation.z;
+ bool sym = ((autocvar_g_waypointeditor_symmetrical > 0 && ctf_flags >= 2)
+ || (autocvar_g_waypointeditor_symmetrical < 0));
+ int order = ctf_flags;
+ if(autocvar_g_waypointeditor_symmetrical_order >= 2)
+ {
+ order = autocvar_g_waypointeditor_symmetrical_order;
+ 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);
+ if(!e)
+ {
+ LOG_INFOF("Couldn't spawn waypoint at %v\n", org);
+ return;
+ }
+ waypoint_schedulerelink(e);
+ bprint(strcat("Waypoint spawned at ", vtos(e.origin), "\n"));
+ if(sym)
+ {
+ org = waypoint_getSymmetricalOrigin(e.origin, ctf_flags);
+ if (vdist(org - pl.origin, >, 32))
+ {
+ if(order > 2)
+ order--;
+ else
+ sym = false;
+ goto add_wp;
+ }
+ }
+}
+
+void waypoint_remove(entity wp)
+{
+ // tell all waypoints linked to wp that they need to relink
+ IL_EACH(g_waypoints, it != wp,
+ {
+ if (waypoint_islinked(it, wp))
+ waypoint_removelink(it, wp);
+ });
+ delete(wp);
+}
+
+void waypoint_remove_fromeditor(entity pl)
+{
+ entity e = navigation_findnearestwaypoint(pl, false);
+
+ int ctf_flags = havocbot_symmetryaxis_equation.z;
+ bool sym = ((autocvar_g_waypointeditor_symmetrical > 0 && ctf_flags >= 2)
+ || (autocvar_g_waypointeditor_symmetrical < 0));
+ int order = ctf_flags;
+ if(autocvar_g_waypointeditor_symmetrical_order >= 2)
+ {
+ order = autocvar_g_waypointeditor_symmetrical_order;
+ ctf_flags = order;
+ }
+
+ LABEL(remove_wp);
+ if (!e) return;
+ if (e.wpflags & WAYPOINTFLAG_GENERATED) return;
+
+ if (e.wphardwired)
+ {
+ LOG_INFO("^1Warning: ^7Removal of hardwired waypoints is not allowed in the editor. Please remove links from/to this waypoint (", vtos(e.origin), ") by hand from maps/", mapname, ".waypoints.hardwired\n");
+ return;
+ }
+
+ entity wp_sym = NULL;
+ if (sym)
+ {
+ vector org = waypoint_getSymmetricalOrigin(e.origin, ctf_flags);
+ FOREACH_ENTITY_CLASS("waypoint", !(it.wpflags & WAYPOINTFLAG_GENERATED), {
+ if(vdist(org - it.origin, <, 3))
+ {
+ wp_sym = it;
+ break;
+ }
+ });
+ }
+
+ bprint(strcat("Waypoint removed at ", vtos(e.origin), "\n"));
+ waypoint_remove(e);
+
+ if (sym && wp_sym)
+ {
+ e = wp_sym;
+ if(order > 2)
+ order--;
+ else
+ sym = false;
+ goto remove_wp;
+ }
+}
+
+void waypoint_removelink(entity from, entity to)
+{
+ if (from == to || (from.wpflags & WAYPOINTFLAG_NORELINK))
+ return;
+
+ bool found = false;
+ if (!found && from.wp00 == to) found = true; if (found) {from.wp00 = from.wp01; from.wp00mincost = from.wp01mincost;}
+ if (!found && from.wp01 == to) found = true; if (found) {from.wp01 = from.wp02; from.wp01mincost = from.wp02mincost;}
+ if (!found && from.wp02 == to) found = true; if (found) {from.wp02 = from.wp03; from.wp02mincost = from.wp03mincost;}
+ if (!found && from.wp03 == to) found = true; if (found) {from.wp03 = from.wp04; from.wp03mincost = from.wp04mincost;}
+ if (!found && from.wp04 == to) found = true; if (found) {from.wp04 = from.wp05; from.wp04mincost = from.wp05mincost;}
+ if (!found && from.wp05 == to) found = true; if (found) {from.wp05 = from.wp06; from.wp05mincost = from.wp06mincost;}
+ if (!found && from.wp06 == to) found = true; if (found) {from.wp06 = from.wp07; from.wp06mincost = from.wp07mincost;}
+ if (!found && from.wp07 == to) found = true; if (found) {from.wp07 = from.wp08; from.wp07mincost = from.wp08mincost;}
+ if (!found && from.wp08 == to) found = true; if (found) {from.wp08 = from.wp09; from.wp08mincost = from.wp09mincost;}
+ if (!found && from.wp09 == to) found = true; if (found) {from.wp09 = from.wp10; from.wp09mincost = from.wp10mincost;}
+ if (!found && from.wp10 == to) found = true; if (found) {from.wp10 = from.wp11; from.wp10mincost = from.wp11mincost;}
+ if (!found && from.wp11 == to) found = true; if (found) {from.wp11 = from.wp12; from.wp11mincost = from.wp12mincost;}
+ if (!found && from.wp12 == to) found = true; if (found) {from.wp12 = from.wp13; from.wp12mincost = from.wp13mincost;}
+ if (!found && from.wp13 == to) found = true; if (found) {from.wp13 = from.wp14; from.wp13mincost = from.wp14mincost;}
+ if (!found && from.wp14 == to) found = true; if (found) {from.wp14 = from.wp15; from.wp14mincost = from.wp15mincost;}
+ if (!found && from.wp15 == to) found = true; if (found) {from.wp15 = from.wp16; from.wp15mincost = from.wp16mincost;}
+ if (!found && from.wp16 == to) found = true; if (found) {from.wp16 = from.wp17; from.wp16mincost = from.wp17mincost;}
+ if (!found && from.wp17 == to) found = true; if (found) {from.wp17 = from.wp18; from.wp17mincost = from.wp18mincost;}
+ if (!found && from.wp18 == to) found = true; if (found) {from.wp18 = from.wp19; from.wp18mincost = from.wp19mincost;}
+ if (!found && from.wp19 == to) found = true; if (found) {from.wp19 = from.wp20; from.wp19mincost = from.wp20mincost;}
+ if (!found && from.wp20 == to) found = true; if (found) {from.wp20 = from.wp21; from.wp20mincost = from.wp21mincost;}
+ if (!found && from.wp21 == to) found = true; if (found) {from.wp21 = from.wp22; from.wp21mincost = from.wp22mincost;}
+ if (!found && from.wp22 == to) found = true; if (found) {from.wp22 = from.wp23; from.wp22mincost = from.wp23mincost;}
+ if (!found && from.wp23 == to) found = true; if (found) {from.wp23 = from.wp24; from.wp23mincost = from.wp24mincost;}
+ if (!found && from.wp24 == to) found = true; if (found) {from.wp24 = from.wp25; from.wp24mincost = from.wp25mincost;}
+ if (!found && from.wp25 == to) found = true; if (found) {from.wp25 = from.wp26; from.wp25mincost = from.wp26mincost;}
+ if (!found && from.wp26 == to) found = true; if (found) {from.wp26 = from.wp27; from.wp26mincost = from.wp27mincost;}
+ if (!found && from.wp27 == to) found = true; if (found) {from.wp27 = from.wp28; from.wp27mincost = from.wp28mincost;}
+ if (!found && from.wp28 == to) found = true; if (found) {from.wp28 = from.wp29; from.wp28mincost = from.wp29mincost;}
+ if (!found && from.wp29 == to) found = true; if (found) {from.wp29 = from.wp30; from.wp29mincost = from.wp30mincost;}
+ if (!found && from.wp30 == to) found = true; if (found) {from.wp30 = from.wp31; from.wp30mincost = from.wp31mincost;}
+ if (found) {from.wp31 = NULL; from.wp31mincost = 10000000;}
+}
+