public override bool Update(float deltaSeconds) { // If the missile has outlived its thing, delete it. lifetime -= deltaSeconds; if (lifetime < 0) { Runner.DelSimObject(this); return(false); } // ideas: have certain missiles acquire a new target from owner if it disappears? have certain missiles explode when lacking a target? if (seek && lifetime < munition_arch.Lifetime - 1) { SimObject target = Runner.FindObject(target_objid); if (target == null) { target_objid = 0; target_subobjid = 0; seek = false; if (broadcast) { Runner.NotifyOnSetTarget(Objid, 0, 0); broadcast = false; } } else if (target.Position.DistSqr(Position) > seeker_range * seeker_range) { time_to_lock = munition_arch.TimeToLock; if (broadcast) { Runner.NotifyOnSetTarget(Objid, 0, 0); broadcast = false; } } else { Vector current_direction = Orientation * -Vector.Z(); Vector current_target_vector = target.ExtrapolatedPosition() - Position; Vector current_target_direction = current_target_vector.Normalize(); double target_cosine = current_target_direction.Dot(current_direction); double solid_angle = 1 / Math.Sqrt(Math.Pow(target.Arch.Radius / current_target_vector.Length(), 2) + 1); if (target_cosine < Math.Cos(seeker_fov / 2) - solid_angle) { time_to_lock = munition_arch.TimeToLock; if (broadcast) { Runner.NotifyOnSetTarget(Objid, 0, 0); broadcast = false; } } else if (time_to_lock > 0) { time_to_lock -= deltaSeconds; } else { if (!broadcast) { Runner.NotifyOnSetTarget(Objid, target_objid, target_subobjid); broadcast = true; } double max_cosine = Math.Cos(max_angular_velocity * deltaSeconds); if (max_cosine < target_cosine) { Vector cross = current_direction.Cross(current_target_direction); Matrix rotate = Matrix.CreateRotationAboutAxis(cross, max_cosine); Orientation *= rotate; velocity = rotate * velocity / 2 + velocity / 2; // need to ponder on this behavior } else { Orientation = Matrix.CreateLookAt(Position, target.ExtrapolatedPosition()); velocity = current_target_direction * velocity.Length() / 2 + velocity / 2; } } } } // Calculate any velocity changes if (motor_delay > 0) { motor_delay -= deltaSeconds; } else if (motor_lifetime > 0) { var linear_acceleration = new Vector(0, 0, -(motor_accel * deltaSeconds)); velocity += Orientation * linear_acceleration; motor_lifetime -= deltaSeconds; } // Move the object Position += velocity * deltaSeconds; UpdateTime += (float)deltaSeconds; Runner.NotifyOnObjUpdate(this); return(true); }