internal override string GetLabel(Vessel vessel, EvaluationContext context, SubRequirementState state) { string targetName = context?.targetBody?.displayName ?? "target"; ObserveBodyState losState = (ObserveBodyState)state; if (!losState.requirementMet) { if (losState.occluder != null) { return(Localizer.Format("Occluded by <<1>>", Lib.Color(losState.occluder.displayName, Lib.Kolor.Red))); } if (losState.distance > 0) { return(Localizer.Format("Distance <<1>>", Lib.Color(Lib.HumanReadableDistance(losState.distance), Lib.Kolor.Red))); } if (!losState.angularRequirementMet && (minAngularVelocity != 0 || maxAngularVelocity != 0)) { string angularVelocityStr = Lib.Color(losState.angularVelocity.ToString("F1") + " °/m", Lib.Kolor.Red); return(Localizer.Format("Angular velocity <<1>>", angularVelocityStr)); } return(Localizer.Format("<<1>> is <<2>>", targetName, Lib.Color("not visible", Lib.Kolor.Red))); } string result = Localizer.Format("<<1>> is <<2>>", targetName, Lib.Color("visible", Lib.Kolor.Green)); if (losState.angularRequirementMet) { string angularVelocityStr = Lib.Color(losState.angularVelocity.ToString("F1") + " °/m", Lib.Kolor.Green); result += ", " + Localizer.Format("angular velocity: <<1>>", angularVelocityStr); } return(result); }
internal override string GetLabel(Vessel vessel, EvaluationContext context, SubRequirementState state) { string targetName = context?.targetBody?.displayName.LocalizeRemoveGender() ?? Localizer.Format("#KerCon_ABody"); ObserveBodyState losState = (ObserveBodyState)state; if (!losState.requirementMet) { if (losState.occluder != null) { return(Localizer.Format("#KerCon_OccludedByX", Lib.Color(losState.occluder.displayName.LocalizeRemoveGender(), Lib.Kolor.Red))); // Occluded by <<1>> } if (losState.distance > 0) { return(Localizer.Format("#KerCon_DistanceX", Lib.Color(Lib.HumanReadableDistance(losState.distance), Lib.Kolor.Red))); } if (!losState.angularRequirementMet && (minAngularVelocity != 0 || maxAngularVelocity != 0)) { string angularVelocityStr = Lib.Color(losState.angularVelocity.ToString("F1") + " °/m", Lib.Kolor.Red); return(Localizer.Format("#KerCon_AngularVelX", angularVelocityStr)); } return(Localizer.Format("#KerCon_XisY", targetName, Lib.Color(Localizer.Format("#KerCon_NotVisible"), Lib.Kolor.Red))); } string result = Localizer.Format("#KerCon_XisY", targetName, Lib.Color(Localizer.Format("#KerCon_Visible"), Lib.Kolor.Green)); if (losState.angularRequirementMet) { string angularVelocityStr = Lib.Color(losState.angularVelocity.ToString("F1") + " °/m", Lib.Kolor.Green); result += ", " + Localizer.Format("#KerCon_AngularVelX", angularVelocityStr); } return(result); }
internal override SubRequirementState VesselMeetsCondition(Vessel vessel, EvaluationContext context) { ObserveBodyState state = new ObserveBodyState(); var body = context.targetBody; // generate ray parameters var vesselPosition = context.VesselPosition(vessel); var bodyDir = context.BodyPosition(body) - vesselPosition; state.distance = bodyDir.magnitude; bodyDir /= state.distance; state.distance -= body.Radius; double distance = maxDistance; if (distance == 0 && maxDistanceAU != 0) { distance = Sim.AU * maxDistanceAU; } if (distance != 0 && state.distance > distance) { state.requirementMet = false; return(state); } if (minAngularVelocity > 0 || maxAngularVelocity > 0) { var elevation = AboveWaypoint.GetElevation(vessel, 0, 0, context.targetBody, context); var elevation10s = AboveWaypoint.GetElevation(vessel, 0, 0, context.targetBody, context, 10); state.angularVelocity = Math.Abs((elevation10s - elevation) * 6.0); // radial velocity is in degrees/minute state.angularRequirementMet = true; if (minAngularVelocity > 0) { state.angularRequirementMet &= state.angularVelocity >= minAngularVelocity; } if (maxAngularVelocity > 0) { state.angularRequirementMet &= state.angularVelocity <= maxAngularVelocity; } state.requirementMet &= state.angularRequirementMet; } VesselData vd; if (!vessel.TryGetVesselData(out vd)) { state.requirementMet = false; return(state); } // check if the ray intersects with an occluder foreach (CelestialBody occludingBody in vd.EnvVisibleBodies) { if (occludingBody == body) { continue; } if (!Sim.RayAvoidBody(vesselPosition, bodyDir, state.distance, occludingBody)) { state.occluder = occludingBody; state.requirementMet = false; return(state); } } state.requirementMet = true; return(state); }