}
else if (fabs(autocvar_g_waypointeditor_symmetrical) == 2)
{
- float m = havocbot_symmetryaxis_equation.x;
- float q = havocbot_symmetryaxis_equation.y;
+ float m = havocbot_symmetry_axis_m;
+ float q = havocbot_symmetry_axis_q;
if (autocvar_g_waypointeditor_symmetrical == -2)
{
m = autocvar_g_waypointeditor_symmetrical_axis.x;
return it;
});
}
+ // spawn only one destination waypoint for teleports teleporting player to the exact same spot
+ // otherwise links loaded from file would be applied only to the first destination
+ // waypoint since link format doesn't specify waypoint entities but just positions
+ if((f & WAYPOINTFLAG_GENERATED) && !(f & WAYPOINTFLAG_NORELINK) && m1 == m2)
+ {
+ IL_EACH(g_waypoints, boxesoverlap(m1, m2, it.absmin, it.absmax),
+ {
+ return it;
+ });
+ }
entity w = new(waypoint);
IL_PUSH(g_waypoints, w);
{
entity e;
vector org = pl.origin;
- int ctf_flags = havocbot_symmetryaxis_equation.z;
+ int ctf_flags = havocbot_symmetry_origin_order;
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;
- }
+ ctf_flags = autocvar_g_waypointeditor_symmetrical_order;
+ if (sym && ctf_flags < 2)
+ ctf_flags = 2;
+ int wp_num = ctf_flags;
if(!PHYS_INPUT_BUTTON_CROUCH(pl))
{
{
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)
+ if (vlen(item_org - org) < 20)
{
org = item_org;
break;
org = waypoint_getSymmetricalOrigin(e.origin, ctf_flags);
if (vdist(org - pl.origin, >, 32))
{
- if(order > 2)
- order--;
+ if(wp_num > 2)
+ wp_num--;
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))
{
entity e = navigation_findnearestwaypoint(pl, false);
- int ctf_flags = havocbot_symmetryaxis_equation.z;
+ int ctf_flags = havocbot_symmetry_origin_order;
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;
- }
+ ctf_flags = autocvar_g_waypointeditor_symmetrical_order;
+ if (sym && ctf_flags < 2)
+ ctf_flags = 2;
+ int wp_num = ctf_flags;
LABEL(remove_wp);
if (!e) return;
if (sym && wp_sym)
{
e = wp_sym;
- if(order > 2)
- order--;
+ if(wp_num > 2)
+ wp_num--;
else
sym = false;
goto remove_wp;
}
float waypoint_getlinearcost_underwater(float dist)
{
- // NOTE: this value is hardcoded on the engine too, see SV_WaterMove
+ // NOTE: underwater speed factor is hardcoded in the engine too, see SV_WaterMove
return dist / (autocvar_sv_maxspeed * 0.7);
}
bot_calculate_stepheightvec();
+ int dphitcontentsmask_save = this.dphitcontentsmask;
+ this.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP | DPCONTENTS_BOTCLIP;
+
bot_navigation_movemode = ((autocvar_bot_navigation_ignoreplayers) ? MOVE_NOMONSTERS : MOVE_NORMAL);
//dprint("waypoint_think wpisbox = ", ftos(this.wpisbox), "\n");
relink_walkculled += 0.5;
else
{
- if (tracewalk(it, ev, PL_MIN_CONST, PL_MAX_CONST, sv2, sv2_height, MOVE_NOMONSTERS))
+ if (tracewalk(this, ev, PL_MIN_CONST, PL_MAX_CONST, sv2, sv2_height, MOVE_NOMONSTERS))
waypoint_addlink(it, this);
else
relink_walkculled += 0.5;
});
navigation_testtracewalk = 0;
this.wplinked = true;
+ this.dphitcontentsmask = dphitcontentsmask_save;
}
void waypoint_clearlinks(entity wp)
bool parse_comments = true;
float ver = 0;
+ string links_time = string_null;
while ((s = fgets(file)))
{
{
if(substring(s, 2, 17) == "WAYPOINT_VERSION ")
ver = stof(substring(s, 19, -1));
+ else if(substring(s, 2, 14) == "WAYPOINT_TIME ")
+ links_time = substring(s, 16, -1);
continue;
}
else
{
- if(ver < WAYPOINT_VERSION)
+ if(ver < WAYPOINT_VERSION || links_time != waypoint_time)
{
- LOG_TRACE("waypoint links for this map are outdated.");
+ if (links_time != waypoint_time)
+ LOG_TRACE("waypoint links for this map are not made for these waypoints.");
+ else
+ LOG_TRACE("waypoint links for this map are outdated.");
if (g_assault)
{
LOG_TRACE("Assault waypoint links need to be manually updated in the editor");
}
fputs(file, strcat("//", "WAYPOINT_VERSION ", ftos_decimals(WAYPOINT_VERSION, 2), "\n"));
+ if (waypoint_time != "")
+ fputs(file, strcat("//", "WAYPOINT_TIME ", waypoint_time, "\n"));
int c = 0;
IL_EACH(g_waypoints, true,
// (they are read as a waypoint with origin '0 0 0' and flag 0 though)
fputs(file, strcat("//", "WAYPOINT_VERSION ", ftos_decimals(WAYPOINT_VERSION, 2), "\n"));
fputs(file, strcat("//", "WAYPOINT_SYMMETRY ", sym_str, "\n"));
- fputs(file, strcat("//", "\n"));
+
+ strcpy(waypoint_time, strftime(true, "%Y-%m-%d %H:%M:%S"));
+ fputs(file, strcat("//", "WAYPOINT_TIME ", waypoint_time, "\n"));
+ //fputs(file, strcat("//", "\n"));
+ //fputs(file, strcat("//", "\n"));
+ //fputs(file, strcat("//", "\n"));
int c = 0;
IL_EACH(g_waypoints, true,
if (tokens > 2) { sym_param2 = stof(argv(2)); }
if (tokens > 3) { sym_param3 = stof(argv(3)); }
}
+ else if(substring(s, 2, 14) == "WAYPOINT_TIME ")
+ strcpy(waypoint_time, substring(s, 16, -1));
continue;
}
else
{
int display_type = 0;
entity 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)
display_type = 1; // default
else if(head && (head.wphardwired))