public void Update(List <IMyEntity> missileCollection) { if (SafetyTimerIsOver()) { ModDebugger.Launch(); // if (Missile.Physics.Flags != RigidBodyFlag.RBF_BULLET) Missile.Physics.Flags = RigidBodyFlag.RBF_BULLET; // float TURNING_SPEED = 0.1f; // float FACTOR = 2f; // Log.Info("Missile.Physics.Flags"); //BLEH Vector3 targetPoint = Vector3.Zero; try { Vector3 boundingBoxCenter = (Target.WorldAABB.Max + Target.WorldAABB.Min) * 0.5; if (boundingBoxCenter == Vector3.Zero) { boundingBoxCenter = Target.GetPosition(); } if (_hasPhysicsSteering) { Ray positiveVelocityRay = new Ray(Missile.GetPosition(), Missile.Physics.LinearVelocity); Ray negativeVelocityRay = new Ray(Missile.GetPosition(), -1f * Missile.Physics.LinearVelocity); Plane targetPlane = new Plane(boundingBoxCenter, Vector3.Normalize(Missile.Physics.LinearVelocity)); float?intersectionDist = positiveVelocityRay.Intersects(targetPlane); // Vector3 reverseVector; if (intersectionDist != null) { targetPoint = positiveVelocityRay.Position + (float)intersectionDist * positiveVelocityRay.Direction; // reverseVector = Target.GetPosition() - targetPoint; targetPoint = 2 * boundingBoxCenter - targetPoint; // targetPoint = targetPoint + reverseVector; } else { intersectionDist = negativeVelocityRay.Intersects(targetPlane); if (intersectionDist != null) { if ((_isOvershooting == false) && (_finishedOvershooting == false)) { _overshootDistance = Missile.Physics.LinearVelocity.Length() * (360 / _turningSpeed) / 10000 + 0; _isOvershooting = true; } // targetPoint = negativeVelocityRay.Position + (float)intersectionDist * negativeVelocityRay.Direction; if (_isOvershooting && !_finishedOvershooting) { if (intersectionDist > _overshootDistance) { targetPoint = boundingBoxCenter; _finishedOvershooting = true; // Log.Info("we finished overshooting, returning to target."); } else { targetPoint = Missile.GetPosition() + Missile.WorldMatrix.Forward; // Log.Info("we overshot, we keep heading forward."); // Log.Info(" current Distance: " + intersectionDist + " and overshootCorr " + _overshootDistance); } } else if (_isOvershooting && _finishedOvershooting) { targetPoint = boundingBoxCenter; } } } Vector3 diffVelocity = Target.GetTopMostParent().Physics.LinearVelocity - Missile.Physics.LinearVelocity; if (targetPoint == Vector3.Zero) { targetPoint = boundingBoxCenter - diffVelocity; } } else { targetPoint = boundingBoxCenter; } } catch (Exception e) { Log.Info("Caught exception during MissileData Update! " + e); if (Target != null) { targetPoint = Target.GetPosition(); } } Vector3 targetDirection = Vector3.Normalize(targetPoint - Missile.GetPosition()); float maxRadVelocity = MathHelper.ToRadians(_turningSpeed); float angle = MyUtils.GetAngleBetweenVectorsAndNormalise(Missile.WorldMatrix.Forward, targetDirection); // Log.Info("angle = " + MathHelper.ToDegrees(angle)); float turnPercent; if (Math.Abs(angle) < Double.Epsilon) { turnPercent = 0f; } else if (Math.Abs(angle) > maxRadVelocity) { turnPercent = maxRadVelocity / Math.Abs(angle); } else { turnPercent = 1f; } Matrix targetMatrix = Matrix.CreateWorld(Missile.GetPosition(), targetDirection, Vector3D.CalculatePerpendicularVector(targetDirection)); //Matrix.CreateFromYawPitchRoll(0f, (float)Math.PI*0.5f, 0f))); var slerpMatrix = Matrix.Slerp(Missile.WorldMatrix, targetMatrix, turnPercent); RayD nextTargetLineD = new RayD(Missile.GetPosition(), slerpMatrix.Forward); bool iswait = false; foreach (var othermissile in missileCollection) { if (othermissile.EntityId == Missile.EntityId) { continue; } if (nextTargetLineD.Intersects(othermissile.WorldVolume) != null) { iswait = true; } } if (iswait == false) { Missile.SetWorldMatrix(slerpMatrix); if (_hasPhysicsSteering) { var linVel = Missile.Physics.LinearVelocity; var linSpeed = linVel.Length(); Missile.Physics.LinearVelocity = 0.98f * linVel + 0.02f * Missile.WorldMatrix.Forward * linSpeed; } else { Vector3 linVel = Missile.Physics.LinearVelocity; Missile.Physics.LinearVelocity = Vector3.Normalize(Missile.WorldMatrix.Forward) * linVel.Length(); } } } else { // if (Missile.Physics.Flags == RigidBodyFlag.RBF_BULLET) Missile.Physics.Flags = RigidBodyFlag.RBF_BULLET & RigidBodyFlag.RBF_DISABLE_COLLISION_RESPONSE; } Tick(); }