+void ctf_CalculatePassVelocity(entity flag, vector to, vector from, float turnrate)
+{
+ float current_distance = vlen((('1 0 0' * to_x) + ('0 1 0' * to_y)) - (('1 0 0' * from_x) + ('0 1 0' * from_y))); // for the sake of this check, exclude Z axis
+ float initial_height = min(autocvar_g_ctf_pass_arc_max, (flag.pass_distance * tanh(autocvar_g_ctf_pass_arc)));
+ float current_height = (initial_height * min(1, (current_distance / flag.pass_distance)));
+ print("current_height = ", ftos(current_height), ", initial_height = ", ftos(initial_height), ".\n");
+
+ vector targpos;
+ if(current_height) // make sure we can actually do this arcing path
+ {
+ vector arc_targpos = (to + ('0 0 1' * current_height));
+ WarpZone_TraceLine(flag.origin, arc_targpos, MOVE_NOMONSTERS, flag);
+ if(trace_fraction < 1)
+ {
+ //print("normal arc line failed, trying to find new pos...");
+ WarpZone_TraceLine(to, arc_targpos, MOVE_NOMONSTERS, flag);
+ arc_targpos = (trace_endpos + FLAG_PASS_ARC_OFFSET);
+
+ WarpZone_TraceLine(flag.origin, arc_targpos, MOVE_NOMONSTERS, flag);
+ if(trace_fraction < 1) { targpos = to; /* print(" ^1FAILURE^7, reverting to original direction.\n"); */ }
+ else { targpos = arc_targpos; /* print(" ^3SUCCESS^7, using new arc line.\n"); */ }
+ }
+ else { targpos = arc_targpos; }
+ }
+ else { targpos = to; }
+
+ //flag.angles = normalize(('0 1 0' * to_y) - ('0 1 0' * from_y));
+
+ vector desired_direction = normalize(targpos - from);
+ if(turnrate)
+ {
+ vector current_direction = normalize(flag.velocity);
+ flag.velocity = (normalize(current_direction + (desired_direction * autocvar_g_ctf_pass_turnrate)) * autocvar_g_ctf_pass_velocity);
+ }
+ else { flag.velocity = (desired_direction * autocvar_g_ctf_pass_velocity); }
+}
+