public void ToggleBVController() { shutdown = !shutdown; Events["ToggleBVController"].guiName = (!shutdown ? Localizer.Format("#LOC_BV_ContextMenu_Shutdown") : Localizer.Format("#LOC_BV_ContextMenu_Activate")); if (!HighLogic.LoadedSceneIsEditor) { Fields["vesselType"].guiActive = !shutdown; Fields["rotationVector"].guiActive = !shutdown; Events["BVControlPanel"].guiActive = !shutdown; if (shutdown) { if (active) { BVController controller = BonVoyage.Instance.GetControllerOfVessel(vessel); if (controller != null) { controller.Deactivate(); } } } BonVoyage.Instance.SetShutdownState(vessel.id, shutdown); } else { Fields["vesselType"].guiActiveEditor = !shutdown; } }
/// <summary> /// Toggle state of the control window dialog /// </summary> internal void ToggleControlWindow() { controlViewVisible = !controlViewVisible; if (controlViewVisible) { // Check if we are in flight, active vessel has full controll and BV controller and is not shutted down bool active = false; if (HighLogic.LoadedSceneIsFlight) { Vessel vessel = FlightGlobals.ActiveVessel; BVController controller = GetControllerOfVessel(FlightGlobals.ActiveVessel); if (controller != null) { active = (!controller.Shutdown && controller.CheckConnection()); } } if (active && (ControlView == null)) { ShowControlWindow(); } else { controlViewVisible = false; } } else { HideControlWindow(); } }
/// <summary> /// This will be called by Kerbalism. See https://github.com/Kerbalism/Kerbalism/wiki/TechGuide-~-C%23-API /// </summary> public static string BackgroundUpdate(Vessel v, ProtoPartSnapshot part_snapshot, ProtoPartModuleSnapshot module_snapshot, PartModule proto_part_module, Part proto_part, Dictionary <string, double> availableResources, List <KeyValuePair <string, double> > resourceChangeRequest, double elapsed_s) { BVController controller = BonVoyage.Instance.GetControllerOfVessel(v); if (controller == null) { return(""); } if (controller.Active) { double requiredPower = Proto.GetDouble(module_snapshot, "requiredPower", 0); resourceChangeRequest.Add(new KeyValuePair <string, double>("ElectricCharge", -requiredPower / 10.0)); } double availableEc; if (availableResources.TryGetValue("ElectricCharge", out availableEc)) { controller.batteries.CurrentEC = availableEc; } if (string.IsNullOrEmpty(localizedTitle)) { localizedTitle = Localizer.Format("#LOC_BV_Autopilot"); } return(localizedTitle); }
/// <summary> /// Constructor /// </summary> internal ControlWindowModel() { // Load from configuration CommonWindowProperties.ControlWindowPosition = Configuration.ControlWindowPosition; controllerActive = false; currentController = null; }
/// <summary> /// Move and rotate a rover or a ship /// Process resources /// </summary> /// <param name="vessel"></param> public void OnVesselGoOffRails(Vessel vessel) { if ((vessel.situation == Vessel.Situations.LANDED) || (vessel.situation == Vessel.Situations.SPLASHED)) { //if (vessel.isEVA) // Kerbals // return; if (vessel.packed) // No physics { return; } BVController controller = GetControllerOfVessel(vessel); if (controller != null) { // Move only a rover or landed Kerbal if ((controller is RoverController) || ((controller is KerbalController) && (vessel.situation == Vessel.Situations.LANDED))) { // Only rovers/Kerbals with active controller or rovers/Kerbals that just arrived at the destination if (controller.Active || controller.Arrived) { // Stabilize only if another stabilizer is not present if (!otherStabilizerPresent) { StabilizeVessel.AddVesselToStabilize(vessel, controller.RotationVector, Configuration.DisableRotation); } else // only rotate { if (!Configuration.DisableRotation) { StabilizeVessel.Rotate(vessel, controller.RotationVector); } } } } // Move only a ship or splashed Kerbal if ((controller is ShipController) || ((controller is KerbalController) && (vessel.situation == Vessel.Situations.SPLASHED))) { // Only ships/Kerbals with active controller or ships/Kerbals that just arrived at the destination if (controller.Active || controller.Arrived) { if (!Configuration.DisableRotation) { StabilizeVessel.Rotate(vessel, controller.RotationVector); } } } // Deduct resources if (!vessel.isEVA) { controller.ProcessResources(); } } } }
/// <summary> /// Move and rotate a rover /// </summary> /// <param name="vessel"></param> public void OnVesselGoOffRails(Vessel vessel) { if ((vessel.situation == Vessel.Situations.LANDED) || (vessel.situation == Vessel.Situations.SPLASHED)) { if (vessel.isEVA) // Kerbals { return; } if (vessel.packed) // No physics { return; } BVController controller = null; for (int i = 0; i < BVControllers.Count; i++) { if (BVControllers[i].vessel.id == vessel.id) { controller = BVControllers[i]; break; } } if (controller != null) { // Move only a rover if (controller is RoverController) { // Only rovers with active controller or rovers that just arrived at the destination if (controller.Active || controller.Arrived) { // Stabilize only if another stabilizer is not present if (!otherStabilizerPresent) { StabilizeVessel.AddVesselToStabilize(vessel, controller.RotationVector, Configuration.DisableRotation); } } } if (controller is ShipController) { // Only ships with active controller or ships that just arrived at the destination if (controller.Active || controller.Arrived) { if (!Configuration.DisableRotation) { StabilizeVessel.Rotate(vessel, controller.RotationVector); } } } // Deduct resources controller.ProcessResources(); } } }
/// <summary> /// Set current controller /// </summary> /// <param name="c"></param> internal void SetController(BVController controller) { currentController = controller; if (controller != null) { if (currentController.CheckConnection()) { controller.SystemCheck(); } controllerActive = controller.Active; } }
/// <summary> /// Get distance to a target of a vessel based on the index in list of controllers /// </summary> /// <param name="controllerIndex"></param> /// <returns></returns> private string GetDistanceToTarget(int controllerIndex) { string result = "-"; BVController controller = BonVoyage.Instance.BVControllers[controllerIndex]; if ((controller.GetVesselState() == VesselState.Moving) || (controller.GetVesselState() == VesselState.AwaitingSunlight)) { result = Tools.ConvertDistanceToText(controller.RemainingDistanceToTarget); } return(result); }
/// <summary> /// Get speed of a vessel based on the index in list of controllers /// </summary> /// <param name="controllerIndex"></param> /// <returns></returns> private string GetSpeed(int controllerIndex) { string result = "-"; BVController controller = BonVoyage.Instance.BVControllers[controllerIndex]; if ((controller.GetVesselState() == VesselState.Moving) || (controller.GetVesselState() == VesselState.AwaitingSunlight)) { result = controller.AverageSpeed.ToString("0.##") + " m/s"; } return(result); }
/// <summary> /// Load BV controllers from the config /// </summary> internal void LoadControllers() { Vessel vessel = null; ProtoPartSnapshot part = null; BVControllers.Clear(); for (int i = 0; i < FlightGlobals.Vessels.Count; i++) { vessel = FlightGlobals.Vessels[i]; ConfigNode vesselConfigNode = new ConfigNode(); vessel.protoVessel.Save(vesselConfigNode); for (int k = 0; k < vessel.protoVessel.protoPartSnapshots.Count; k++) { part = vessel.protoVessel.protoPartSnapshots[k]; ProtoPartModuleSnapshot module = part.FindModule("BonVoyageModule"); if (module != null) { ConfigNode BVModule = module.moduleValues; string vesselType = BVModule.GetValue("vesselType"); if (vessel.isActiveVessel) { BonVoyageModule m = vessel.FindPartModuleImplementing <BonVoyageModule>(); if (m != null) { vesselType = m.vesselType; } else { continue; } } BVController controller = null; switch (vesselType) { case "0": // rover controller = new RoverController(vessel, BVModule); break; case "1": // ship controller = new ShipController(vessel, BVModule); break; default: // default to rover controller = new RoverController(vessel, BVModule); break; } BVControllers.Add(controller); break; } } } }
/// <summary> /// Check if vessel has controller and is active /// </summary> /// <param name="v"></param> /// <returns></returns> internal bool CheckActiveControllerOfVessel(Vessel v) { bool active = false; if (HighLogic.LoadedSceneIsFlight) { BVController controller = GetControllerOfVessel(v); if (controller != null && !controller.Shutdown) { active = true; } } return(active); }
/// <summary> /// Get distance to a target of a vessel based on the index in list of controllers /// </summary> /// <param name="controllerIndex"></param> /// <returns></returns> private string GetDistanceToTarget(BVController controller) { string result = "-"; if (controller == null) { return(result); } if ((controller.GetVesselState() == VesselState.Moving) || (controller.GetVesselState() == VesselState.AwaitingSunlight)) { result = Tools.ConvertDistanceToText(controller.RemainingDistanceToTarget); } return(result); }
/// <summary> /// Get speed of a vessel based on the index in list of controllers /// </summary> /// <param name="controllerIndex"></param> /// <returns></returns> private string GetSpeed(BVController controller) { string result = "-"; if (controller == null) { return(result); } if ((controller.GetVesselState() == VesselState.Moving) || (controller.GetVesselState() == VesselState.AwaitingSunlight)) { result = controller.AverageSpeed.ToString("0.##") + " m/s"; } return(result); }
/// <summary> /// Load scenario details for each vessel with BV controller /// </summary> public void LoadScenario() { if (scenarioNode != null) { var controllers = BonVoyage.Instance.BVControllers; int count = controllers.Count; for (int i = 0; i < count; i++) { BVController controller = controllers[i]; if (controller.vessel != null) { ConfigNode controllerNode = scenarioNode.GetNode("CONTROLLER", "vesselId", controller.vessel.id.ToString()); if (controllerNode != null) { ConfigNode subNode = controllerNode.GetNode("BATTERIES"); if (subNode != null) { controller.batteries.UseBatteries = Convert.ToBoolean(subNode.GetValue("useBatteries")); controller.batteries.MaxUsedEC = Convert.ToDouble(subNode.GetValue("maxUsedEC")); controller.batteries.ECPerSecondConsumed = Convert.ToDouble(subNode.GetValue("ecPerSecondConsumed")); controller.batteries.ECPerSecondGenerated = Convert.ToDouble(subNode.GetValue("ecPerSecondGenerated")); controller.batteries.CurrentEC = Convert.ToDouble(subNode.GetValue("currentEC")); } subNode = controllerNode.GetNode("FUEL_CELLS"); if (subNode != null) { controller.fuelCells.Use = Convert.ToBoolean(subNode.GetValue("useFuelCells")); controller.fuelCells.OutputValue = Convert.ToDouble(subNode.GetValue("outputEC")); var resources = subNode.GetNodes("RESOURCE"); controller.fuelCells.InputResources.Clear(); for (int r = 0; r < resources.Length; r++) { Resource ir = new Resource(); ir.Name = resources[r].GetValue("name"); ir.Ratio = Convert.ToDouble(resources[r].GetValue("ratio")); ir.MaximumAmountAvailable = Convert.ToDouble(resources[r].GetValue("maximumAmount")); ir.CurrentAmountUsed = Convert.ToDouble(resources[r].GetValue("currentAmount")); controller.fuelCells.InputResources.Add(ir); } } } } } } }
/// <summary> /// Switch to vessel /// </summary> /// <param name="vesselId"></param> private void SwitchToVessel(Guid vesselId) { BVController controller = BonVoyage.Instance.GetControllerOfVessel(vesselId); if (controller == null) { return; } Vessel v = controller.vessel; if (v.loaded) { FlightGlobals.SetActiveVessel(v); } else { GamePersistence.SaveGame("persistent", HighLogic.SaveFolder, SaveMode.OVERWRITE); FlightDriver.StartAndFocusVessel("persistent", FlightGlobals.Vessels.IndexOf(v)); } }
/// <summary> /// Raised when rotationVector field was changed /// </summary> /// <param name="field"></param> /// <param name="oldValue"></param> private void RotationVectorChanged(BaseField field, object oldValue) { BVController controller = BonVoyage.Instance.GetControllerOfVessel(vessel); if (controller != null) { switch (rotationVector) { case "0": controller.RotationVector = Vector3d.up; break; case "1": controller.RotationVector = Vector3d.down; break; case "2": controller.RotationVector = Vector3d.forward; break; case "3": controller.RotationVector = Vector3d.back; break; case "4": controller.RotationVector = Vector3d.right; break; case "5": controller.RotationVector = Vector3d.left; break; default: controller.RotationVector = Vector3d.back; break; } } }
/// <summary> /// Stabilize vessel if there is some /// </summary> internal static void Stabilize() { if (vesselToStabilize == null) { return; } if (vesselTimer > 0) { Stabilize(vesselToStabilize); vesselTimer--; if (vesselTimer == 0) { BVController controller = BonVoyage.Instance.GetControllerOfVessel(vesselToStabilize); if (controller != null) { controller.Arrived = false; } vesselToStabilize = null; } } }
/// <summary> /// Create table row for controller /// </summary> /// <param name="controller"></param> /// <returns>DialogGUIHorizontalLayout row or null if controller state don't equals to selected filter</returns> private DialogGUIHorizontalLayout CreateListLayoutRow(BVController controller) { DialogGUIHorizontalLayout row = null; if ((activeControllersChecked && !controller.Shutdown) || (disabledControllersChecked && controller.Shutdown)) { UIStyle statusStyle; switch (controller.GetVesselState()) { case VesselState.Current: statusStyle = CommonWindowProperties.Style_Label_Normal_Center_White; break; case VesselState.Idle: statusStyle = CommonWindowProperties.Style_Label_Normal_Center_Grey; break; case VesselState.ControllerDisabled: statusStyle = CommonWindowProperties.Style_Label_Normal_Center_Red; break; case VesselState.AwaitingSunlight: statusStyle = CommonWindowProperties.Style_Label_Normal_Center_Yellow; break; case VesselState.Moving: statusStyle = CommonWindowProperties.Style_Label_Normal_Center_Green; break; default: statusStyle = CommonWindowProperties.Style_Label_Normal_Center_Grey; break; } row = new DialogGUIHorizontalLayout( new DialogGUILabel(controller.vessel.GetDisplayName(), 150f), new DialogGUISpace(10f), new DialogGUILabel(controller.GetVesselStateText(), 70f) { guiStyle = statusStyle }, new DialogGUISpace(10f), new DialogGUILabel(controller.vessel.mainBody.bodyDisplayName.Replace("^N", ""), 60f) { guiStyle = CommonWindowProperties.Style_Label_Normal_Center }, new DialogGUISpace(10f), new DialogGUILabel(delegate { return(GetSpeed(controller)); }, 60f) { guiStyle = CommonWindowProperties.Style_Label_Normal_Center }, new DialogGUISpace(10f), new DialogGUILabel(delegate { return(GetDistanceToTarget(controller)); }, 90f) { guiStyle = CommonWindowProperties.Style_Label_Normal_Center }, new DialogGUISpace(10f), ( !controller.vessel.isActiveVessel ? TooltipExtension.DeferTooltip(new DialogGUIButton("->", delegate { SwitchToVessel(controller.vessel.id); }, 22f, 16f, false) { tooltipText = (Localizer.Format("#LOC_BV_SwitchTo") + " " + controller.vessel.GetDisplayName()) }) : new DialogGUISpace(10f) ) ); row.SetOptionText(controller.vessel.id.ToString()); // ID of the row (vessel ID) controller.OnStateChanged += OnControllerStateChanged; // Register state changed event } return(row); }