/// <summary> /// GameEvent of any deployed science part changed in state /// </summary> protected void groundSciencePartStateChange(ModuleGroundSciencePart sciencePart) { if (sciencePart is ModuleGroundExpControl) { //toggle antenna module based on part enabled toggling Part controlStation = sciencePart.part; CNConstellationAntennaModule antennaMod = controlStation.FindModuleImplementing <CNConstellationAntennaModule>(); if (antennaMod != null) { antennaMod.InUse = sciencePart.Enabled; //Comment: Control Station has CanComm=false at this point -> require player action } this.rebuildFreqList(true); } else if (sciencePart is ModuleGroundCommsPart) { this.rebuildFreqList(true); } }
/// <summary> /// Find all Cargo parts within range, used to calculate power needs /// If firstTime is true, then also find the closest EVA'd kerbal and use that kerbal's stats for any adjustments /// The assumption is that the closest kerbal will be the one which dropped the part /// </summary> /// <param name="firstTime"></param> void GetCargoPartsInRange(bool firstTime = false) { numControllers = 0; numBatteries = 0; ModuleGroundExpControl closestModuleControl = null; totalPowerNeeded = 0f; totalPowerProduced = 0; totalSolarPowerProduced = 0; totalBatPowerProduced = 0; Vessel nearestVessel = null; float nearestVesselDistance = -1; foreach (Vessel v in FlightGlobals.Vessels) { if (v != null && v.Parts.Count == 1) { var moduleControl = v.FindPartModuleImplementing <ModuleGroundExpControl>(); if (moduleControl != null && moduleControl.part != null) { float num = Vector3.Distance(base.transform.position, moduleControl.part.transform.position); if (num <= moduleControl.controlUnitRange) { if (closestModuleControl == null) { closestModuleControl = moduleControl; } else { float num2 = Vector3.Distance(base.transform.position, closestModuleControl.part.transform.position); if (num2 < num) { closestModuleControl = moduleControl; } } numControllers++; Log.Info("Controller found, power needed: " + closestModuleControl.powerNeeded + ", experimentsConnected: " + closestModuleControl.experimentsConnected); int i = closestModuleControl.powerNeeded.IndexOf(' '); if (i > 0) { totalPowerNeeded += float.Parse(closestModuleControl.powerNeeded.Substring(0, closestModuleControl.powerNeeded.IndexOf(' '))); } else if (closestModuleControl.powerNeeded != null && closestModuleControl.powerNeeded != "") { totalPowerNeeded += float.Parse(closestModuleControl.powerNeeded); } } } if (v.isEVA) { if (nearestVessel == null) { nearestVessel = v; nearestVesselDistance = Vector3.Distance(base.transform.position, v.Parts[0].transform.position); } else { float num2 = Vector3.Distance(base.transform.position, v.Parts[0].transform.position); if (num2 < nearestVesselDistance) { nearestVessel = v; nearestVesselDistance = num2; } } } } } if (closestModuleControl != null) { foreach (Vessel v in FlightGlobals.Vessels) { if (v != null && v.Parts.Count == 1) { ModuleGroundSciencePart moduleSolar = v.FindPartModuleImplementing <ModuleGroundSciencePart>(); if (moduleSolar != null && moduleSolar.IsSolarPanel) { float num = Vector3.Distance(base.transform.position, moduleSolar.part.transform.position); if (num <= closestModuleControl.controlUnitRange) { Log.Info("vessel.directSunlight: " + moduleSolar.vessel.directSunlight + ", Solar found, PowerUnitsRequired: " + moduleSolar.PowerUnitsRequired + ", PowerUnitsProduced: " + moduleSolar.PowerUnitsProduced + ", ActualPowerUnitsProduced: " + moduleSolar.ActualPowerUnitsProduced); if (moduleSolar.Enabled) { // // The following is designed to work around a bug // https://bugs.kerbalspaceprogram.com/issues/24349 // if (TimeWarp.CurrentRate != 1) { if (moduleSolar.vessel.directSunlight) { moduleSolar.ActualPowerUnitsProduced = moduleSolar.PowerUnitsProduced; } else { moduleSolar.ActualPowerUnitsProduced = 0; } } totalSolarPowerProduced += moduleSolar.ActualPowerUnitsProduced; } } } else { ModuleDeployableBattery moduleBattery = v.FindPartModuleImplementing <ModuleDeployableBattery>(); if (moduleBattery != null && moduleBattery.IsBattery) { float num = Vector3.Distance(base.transform.position, moduleBattery.part.transform.position); if (num <= closestModuleControl.controlUnitRange) { numBatteries++; int batPowerProduced = (int)moduleBattery.maxPowerUnitsFlow; if (moduleBattery.availAmount < maxPUFlowPerDeltaTime) { batPowerProduced = 0; } totalBatPowerProduced += batPowerProduced; } } } } } } // There is no easy way to know which EVA'd kerbal dropped/placed this, so when created, // as part of the look of all vessels, find the kerbal nearest this part, and use that // kerbal's skill to get the effect if (firstTime) { if (nearestVessel != null && nearestVessel.isEVA && nearestVesselDistance < 2) { if (nearestVessel.parts[0].protoModuleCrew[0].HasEffect <DeployedSciencePowerSkill>()) { DeployedSciencePowerSkill effect = nearestVessel.parts[0].protoModuleCrew[0].GetEffect <DeployedSciencePowerSkill>(); if (effect != null) { kerbalEffectAdjustments = effect.GetValue(); invKerbalEffectAdjustments = 1f / kerbalEffectAdjustments; string msg1 = "Kerbal Effect Adjustment: " + kerbalEffectAdjustments + ", Description: " + Localizer.Format("#autoLOC_8002229", effect.GetValue()); string msg2 = ("MaxValue: " + ((solarPanelChargeRate / kerbalEffectAdjustments) * part.Resources[power].amount).ToString("F2")); Log.Info(msg1); Log.Info(msg2); ScreenMessages.PostScreenMessage(msg1, 10, ScreenMessageStyle.UPPER_CENTER); ScreenMessages.PostScreenMessage(msg2, 10, ScreenMessageStyle.UPPER_CENTER); } } } } Log.Info("totalPowerNeeded: " + totalPowerNeeded + ", totalPowerProduced: " + totalPowerProduced); }