8 using namespace Orders;
50 return ( -v+sqrtf( temp ) )/accel;
78 float fourac = 2*accel*( (.5*v*v/decel)-v*
SIMULATION_ATOM*.5-l )/(1+accel/decel);
79 if (fourac > vsqr)
return FLT_MAX;
81 return ( -v+sqrtf( vsqr-fourac ) )/accel;
104 bool MoveToParent::OptimizeSpeed(
Unit *parent,
float v,
float &
a,
float max_speed )
107 if ( (!max_speed) || fabs( v ) <= max_speed )
110 a += (v > 0) ? -deltaa : deltaa;
115 bool MoveToParent::Done(
const Vector &ang_vel )
133 terminatingX += ( (local_vel.i > 0) != (last_velocity.i > 0) || (!local_vel.i) );
134 terminatingY += ( (local_vel.j > 0) != (last_velocity.j > 0) || (!local_vel.j) );
135 terminatingZ += ( (local_vel.k > 0) != (last_velocity.k > 0) || (!local_vel.k) );
137 last_velocity = local_vel;
143 Vector normheading = heading;
144 normheading.Normalize();
145 Vector max_velocity = max_speed*normheading;
146 max_velocity.Set( fabs( max_velocity.i ),
147 fabs( max_velocity.j ),
148 fabs( max_velocity.k ) );
149 if (done)
return done;
151 if (terminatingX > switchbacks
152 && terminatingY > switchbacks
153 && terminatingZ > switchbacks) {
154 if ( Done( last_velocity ) ) {
155 if (selfterminating) {
168 if (selfterminating && terminatingX > 8 && terminatingY > 8 && terminatingZ > 8) {
169 int tmp = (terminatingX-4);
170 if (terminatingY < terminatingX) tmp = terminatingY-4;
171 if (terminatingZ < terminatingX && terminatingZ < terminatingY) tmp = terminatingZ-4;
173 if (tmp > 30) tmp = 30;
174 vdiv = (
float) (1<<tmp);
194 OptimizeSpeed( parent, last_velocity.k, thrust.k, max_velocity.k/vdiv );
197 thrust.i = -thrust.i;
200 OptimizeSpeed( parent, last_velocity.i, thrust.i, max_velocity.i/vdiv );
203 thrust.j = -thrust.j;
206 OptimizeSpeed( parent, last_velocity.j, thrust.j, max_velocity.j/vdiv );
220 bool ChangeHeading::OptimizeAngSpeed(
float optimal_speed_pos,
float optimal_speed_neg,
float v,
float &a )
223 if ( (optimal_speed_pos == 0 && optimal_speed_neg == 0) || (v >= -optimal_speed_neg && v <= optimal_speed_pos) )
239 void ChangeHeading::TurnToward(
float atancalc,
float ang_veli,
float &torquei )
247 if (fabs( arrival_velocity ) <= max_arrival_speed && fabs( accel_needed ) < torquei/mass) {
248 torquei = accel_needed*mass;
255 torquei = fabs( torquei );
267 final_heading = target;
290 ( (local_heading.i > 0) != (last_velocity.i > 0) || (!local_heading.i) ) && last_velocity.i != 0 ? 1 : 0;
292 ( (local_heading.j > 0) != (last_velocity.j > 0) || (!local_heading.j) ) && last_velocity.j != 0 ? 1 : 0;
294 bool cheater =
false;
298 if (xswitch || yswitch) {
302 desiredR.Normalize();
304 if (desiredR.Dot( R ) > cheatpercent) {
305 P = Q.Cross( desiredR );
306 Q = desiredR.Cross( P );
308 xswitch = yswitch = 1;
311 local_velocity.j = .0f;
312 local_velocity.i = .0f;
316 local_velocity.i = .0f;
319 }
else if (yswitch) {
320 local_velocity.j = .0f;
324 ang_vel.k = local_velocity.k = 0;
329 terminatingX += xswitch;
330 terminatingY += yswitch;
331 last_velocity = local_velocity;
335 if (terminatingX > switchbacks && terminatingY > switchbacks) {
336 if (
Done( local_velocity ) ) {
337 if (this->terminating) {
347 TurnToward( atan2( local_heading.j, local_heading.k ), local_velocity.i, torque.i );
352 TurnToward( atan2( local_heading.i, local_heading.k ), -local_velocity.j, torque.j );
353 torque.j = -torque.j;
375 speed =
float(.00001);
393 if (target == NULL) {
397 if ( speed ==
float(.00001) ) {
401 if ( speed ==
float(.00001) )
420 if (target == NULL) {
443 deactivatewarp =
false;
444 StraightToTarget =
true;
445 inside_landing_zone =
false;
447 void AutoLongHaul::MakeLinearVelocityOrder()
450 static float combat_mode_mult =
455 max_combat_ab_speed ;
456 if (inside_landing_zone)
457 speed *= combat_mode_mult;
466 inside_landing_zone =
false;
467 MakeLinearVelocityOrder();
471 QVector AutoLongHaul::NewDestination(
const QVector &curnewdestination,
double magnitude )
473 return curnewdestination;
477 return a > b ? a :
b;
481 return a < b ? a :
b;
486 static float specInterdictionLimit =
494 static float accel_auto_limit =
496 static float speed_auto_limit =
498 if (minaccel < accel_auto_limit || parent->Velocity.MagnitudeSquared() > maxspeed*maxspeed*speed_auto_limit
503 bool AutoLongHaul::InsideLandingPort(
const Unit *obstacle )
const
505 static float landing_port_limit =
514 if (target == NULL) {
520 static bool compensate_for_interdiction =
522 static float enough_warp_for_cruise =
524 static float go_perpendicular_speed =
526 static float min_warp_orbit_radius =
528 static float warp_orbit_multiplier =
530 static float warp_behind_angle =
534 QVector destinationdirection = (destination-myposition);
535 double destinationdistance = destinationdirection.Magnitude();
536 destinationdirection = destinationdirection*(1./destinationdistance);
539 Unit *obstacle = NULL;
541 bool currently_inside_landing_zone =
false;
543 currently_inside_landing_zone = InsideLandingPort( obstacle );
544 if (currently_inside_landing_zone != inside_landing_zone) {
545 inside_landing_zone = currently_inside_landing_zone;
546 MakeLinearVelocityOrder();
548 if (maxmultiplier < enough_warp_for_cruise && obstacle != NULL && obstacle != target) {
551 double obstacledistance = obstacledirection.Magnitude();
553 obstacledirection = obstacledirection*(1./obstacledistance);
554 float angle = obstacledirection.Dot( destinationdirection );
555 if (obstacledistance-obstacle->
rSize() < destinationdistance-target->
rSize() && angle > warp_behind_angle) {
558 QVector planetme = -obstacledirection;
559 QVector planetperp = planetme.Cross( planetdest );
560 QVector detourvector = destinationdirection.Cross( planetperp );
561 double renormalizedetour = detourvector.Magnitude();
562 if (renormalizedetour > .01) detourvector = detourvector*(1./renormalizedetour);
563 double finaldetourdistance =
mymax( obstacle->
rSize()*warp_orbit_multiplier, min_warp_orbit_radius );
564 detourvector = detourvector*finaldetourdistance;
565 QVector newdestination = NewDestination( obstacle->
LocalPosition()+detourvector, finaldetourdistance );
566 float weight = (maxmultiplier-go_perpendicular_speed)/(enough_warp_for_cruise-go_perpendicular_speed);
568 if (maxmultiplier < go_perpendicular_speed) {
569 QVector perpendicular = myposition+planetme*( finaldetourdistance/planetme.Magnitude() );
570 weight = (go_perpendicular_speed-maxmultiplier)/go_perpendicular_speed;
571 destination = weight*perpendicular+(1-weight)*newdestination;
573 QVector olddestination = myposition+destinationdirection*finaldetourdistance;
574 destination = newdestination*(1-weight)+olddestination*weight;
576 StraightToTarget =
false;
578 StraightToTarget =
true;
581 StraightToTarget =
true;
584 deactivatewarp =
false;
585 float mass = parent->
GetMass();
588 if (mass) minaccel /= mass;
591 float speed = cfacing.Magnitude();
593 cfacing = cfacing*(1./
speed);
594 static float dotLimit =
596 "autopilot_spec_lining_up_angle",
598 if (cfacing.Dot( destinationdirection ) < dotLimit)
599 deactivatewarp =
true;
620 static float distance_to_stop =
622 static float enemy_distance_to_stop =
626 bool stopnow =
false;
629 float time_to_destination = dis/
speed;
630 float time_to_stop = speed*mass/parent->
limits.
retro;
631 if (time_to_destination <= time_to_stop)
635 && ( stopnow || dis < distance_to_stop || (target->
Target() == parent && dis < enemy_distance_to_stop) ) ) {
671 if (target == NULL) {
725 Unit *ownerDoNotDereference = NULL;
730 if (temp == un->
owner) {
731 ownerDoNotDereference = temp;
734 if (ownerDoNotDereference != NULL)