// return set of devices on a vessel // - the list is only valid for a single simulation step public static Dictionary <uint, Device> Boot(Vessel v) { // store all devices var devices = new Dictionary <uint, Device>(); // store device being added Device dev; // loaded vessel if (v.loaded) { foreach (PartModule m in Lib.FindModules <PartModule>(v)) { switch (m.moduleName) { case "ProcessController": dev = new ProcessDevice(m as ProcessController); break; case "Greenhouse": dev = new GreenhouseDevice(m as Greenhouse); break; case "GravityRing": dev = new RingDevice(m as GravityRing); break; case "Emitter": dev = new EmitterDevice(m as Emitter); break; case "Laboratory": dev = new LaboratoryDevice(m as Laboratory); break; case "Experiment": dev = new ExperimentDevice(m as Experiment); break; case "ModuleDeployableSolarPanel": dev = new PanelDevice(m as ModuleDeployableSolarPanel); break; case "ModuleGenerator": dev = new GeneratorDevice(m as ModuleGenerator); break; case "ModuleResourceConverter": dev = new ConverterDevice(m as ModuleResourceConverter); break; case "ModuleKPBSConverter": dev = new ConverterDevice(m as ModuleResourceConverter); break; case "FissionReactor": dev = new ConverterDevice(m as ModuleResourceConverter); break; case "ModuleResourceHarvester": dev = new DrillDevice(m as ModuleResourceHarvester); break; case "ModuleLight": dev = new LightDevice(m as ModuleLight); break; case "ModuleColoredLensLight": dev = new LightDevice(m as ModuleLight); break; case "ModuleMultiPointSurfaceLight": dev = new LightDevice(m as ModuleLight); break; case "SCANsat": dev = new ScannerDevice(m); break; case "ModuleSCANresourceScanner": dev = new ScannerDevice(m); break; case "ModuleRTAntenna": dev = new RemoteTechAntennaDevice(m); break; case "ModuleRTAntennaPassive": dev = new RemoteTechAntennaDevice(m); break; default: continue; } // add the device // - multiple same-type components in the same part will have the same id, and are ignored if (!devices.ContainsKey(dev.Id())) { devices.Add(dev.Id(), dev); } } } // unloaded vessel else { // store data required to support multiple modules of same type in a part var PD = new Dictionary <string, Lib.Module_prefab_data>(); // for each part foreach (ProtoPartSnapshot p in v.protoVessel.protoPartSnapshots) { // get part prefab (required for module properties) Part part_prefab = PartLoader.getPartInfoByName(p.partName).partPrefab; // get all module prefabs var module_prefabs = part_prefab.FindModulesImplementing <PartModule>(); // clear module indexes PD.Clear(); // for each module foreach (ProtoPartModuleSnapshot m in p.modules) { // get the module prefab // if the prefab doesn't contain this module, skip it PartModule module_prefab = Lib.ModulePrefab(module_prefabs, m.moduleName, PD); if (!module_prefab) { continue; } // if the module is disabled, skip it // note: this must be done after ModulePrefab is called, so that indexes are right if (!Lib.Proto.GetBool(m, "isEnabled")) { continue; } // depending on module name switch (m.moduleName) { case "ProcessController": dev = new ProtoProcessDevice(m, module_prefab as ProcessController, p.flightID); break; case "Greenhouse": dev = new ProtoGreenhouseDevice(m, p.flightID); break; case "GravityRing": dev = new ProtoRingDevice(m, p.flightID); break; case "Emitter": dev = new ProtoEmitterDevice(m, p.flightID); break; case "Laboratory": dev = new ProtoLaboratoryDevice(m, p.flightID); break; case "Experiment": dev = new ProtoExperimentDevice(m, module_prefab as Experiment, p.flightID); break; case "ModuleDeployableSolarPanel": dev = new ProtoPanelDevice(m, module_prefab as ModuleDeployableSolarPanel, p.flightID); break; case "ModuleGenerator": dev = new ProtoGeneratorDevice(m, module_prefab as ModuleGenerator, p.flightID); break; case "ModuleResourceConverter": dev = new ProtoConverterDevice(m, module_prefab as ModuleResourceConverter, p.flightID); break; case "ModuleKPBSConverter": dev = new ProtoConverterDevice(m, module_prefab as ModuleResourceConverter, p.flightID); break; case "FissionReactor": dev = new ProtoConverterDevice(m, module_prefab as ModuleResourceConverter, p.flightID); break; case "ModuleResourceHarvester": dev = new ProtoDrillDevice(m, module_prefab as ModuleResourceHarvester, p.flightID); break; case "ModuleLight": dev = new ProtoLightDevice(m, p.flightID); break; case "ModuleColoredLensLight": dev = new ProtoLightDevice(m, p.flightID); break; case "ModuleMultiPointSurfaceLight": dev = new ProtoLightDevice(m, p.flightID); break; case "SCANsat": dev = new ProtoScannerDevice(m, part_prefab, v, p.flightID); break; case "ModuleSCANresourceScanner": dev = new ProtoScannerDevice(m, part_prefab, v, p.flightID); break; case "ModuleRTAntenna": dev = new ProtoRemoteTechAntennaDevice(m, module_prefab, v, p.flightID); break; case "ModuleRTAntennaPassive": dev = new ProtoRemoteTechAntennaDevice(m, module_prefab, v, p.flightID); break; default: continue; } // add the device // - multiple same-type components in the same part will have the same id, and are ignored if (!devices.ContainsKey(dev.Id())) { devices.Add(dev.Id(), dev); } } } } // return all devices found return(devices); }
//Used for orbital survey internal static DMCollectScience fetchSurveyScience(CelestialBody Body, DMScienceContainer DMScience) { ExperimentSituations targetSituation; ScienceSubject sub; AvailablePart aPart; string name; name = DMUtils.availableScience["All"].FirstOrDefault(n => n.Value == DMScience).Key; //Determine if the science part is available if applicable if (DMScience.SciPart != "None") { aPart = PartLoader.getPartInfoByName(DMScience.SciPart); if (aPart == null) { return(null); } if (!ResearchAndDevelopment.PartModelPurchased(aPart)) { return(null); } } //Make sure our experiment is OK if (DMScience.Exp == null) { return(null); } if (!Body.atmosphere && DMScience.Exp.requireAtmosphere) { return(null); } if (((ExperimentSituations)DMScience.SitMask & ExperimentSituations.InSpaceHigh) == ExperimentSituations.InSpaceHigh && ((ExperimentSituations)DMScience.SitMask & ExperimentSituations.InSpaceLow) == ExperimentSituations.InSpaceLow) { if (rand.Next(0, 2) == 0) { targetSituation = ExperimentSituations.InSpaceHigh; } else { targetSituation = ExperimentSituations.InSpaceLow; } } else if (((ExperimentSituations)DMScience.SitMask & ExperimentSituations.InSpaceHigh) == ExperimentSituations.InSpaceHigh) { targetSituation = ExperimentSituations.InSpaceHigh; } else { targetSituation = ExperimentSituations.InSpaceLow; } if (DMUtils.biomeRelevant(targetSituation, DMScience.BioMask)) { List <string> bList = DMUtils.fetchBiome(Body, DMScience.Exp, targetSituation); if (bList.Count == 0) { return(null); } } else { string subId = string.Format("{0}@{1}{2}", DMScience.Exp.id, Body.name, targetSituation); if (ResearchAndDevelopment.GetSubjects().Any(s => s.id == subId)) { sub = ResearchAndDevelopment.GetSubjectByID(subId); if (sub.scientificValue < 0.5f) { return(null); } } } return(new DMCollectScience(Body, targetSituation, "", name, 0)); }
private static List <BackgroundPM> Background_PMs(Vessel v) { var result = Cache.VesselObjectsCache <List <BackgroundPM> >(v, "background"); if (result != null) { return(result); } result = new List <BackgroundPM>(); // store data required to support multiple modules of same type in a part var PD = new Dictionary <string, Lib.Module_prefab_data>(); // for each part foreach (ProtoPartSnapshot p in v.protoVessel.protoPartSnapshots) { // get part prefab (required for module properties) Part part_prefab = PartLoader.getPartInfoByName(p.partName).partPrefab; // get all module prefabs var module_prefabs = part_prefab.FindModulesImplementing <PartModule>(); // clear module indexes PD.Clear(); // for each module foreach (ProtoPartModuleSnapshot m in p.modules) { // TODO : this is to migrate pre-3.1 saves using WarpFixer to the new SolarPanelFixer. At some point in the future we can remove this code. if (m.moduleName == "WarpFixer") { MigrateWarpFixer(v, part_prefab, p, m); } // get the module prefab // if the prefab doesn't contain this module, skip it PartModule module_prefab = Lib.ModulePrefab(module_prefabs, m.moduleName, PD); if (!module_prefab) { continue; } // if the module is disabled, skip it // note: this must be done after ModulePrefab is called, so that indexes are right if (!Lib.Proto.GetBool(m, "isEnabled")) { continue; } // get module type // if the type is unknown, skip it Module_type type = ModuleType(m.moduleName); if (type == Module_type.Unknown) { var backgroundDelegate = BackgroundDelegate.Instance(module_prefab); if (backgroundDelegate != null) { type = Module_type.APIModule; } else { continue; } } var entry = new BackgroundPM(); entry.p = p; entry.m = m; entry.module_prefab = module_prefab; entry.part_prefab = part_prefab; entry.type = type; result.Add(entry); } } Cache.SetVesselObjectsCache(v, "background", result); return(result); }
private void AddGrabModule(ConfigNode node) { foreach (ConfigNode grabNode in node.GetNodes("GRAB")) { // Check if the node has value if (!grabNode.HasValue("stockPartName")) { KAS_Shared.DebugWarning("AddGrabModule(AddModule) Missing stockPartName node !"); continue; } // Add and Retrieve the module string partName = grabNode.GetValue("stockPartName").Replace('_', '.'); AvailablePart aPart = PartLoader.getPartInfoByName(partName); if (aPart == null) { KAS_Shared.DebugError("AddModule(AddModule) - " + partName + " not found in partloader"); continue; } // get or add grab module KASModuleGrab grabModule = aPart.partPrefab.GetComponent <KASModuleGrab>(); if (grabModule) { KAS_Shared.DebugWarning("AddModule(AddModule) - KASModuleGrab already added to " + partName); } else { grabModule = aPart.partPrefab.AddModule("KASModuleGrab") as KASModuleGrab; if (!grabModule) { KAS_Shared.DebugError("AddGrabModule(AddModule) Error when adding module !"); continue; } } // Configure the module if (grabNode.HasValue("evaPartPos")) { grabModule.evaPartPos = KAS_Shared.ParseCfgVector3(grabNode.GetValue("evaPartPos")); } if (grabNode.HasValue("evaPartDir")) { grabModule.evaPartDir = KAS_Shared.ParseCfgVector3(grabNode.GetValue("evaPartDir")); } if (grabNode.HasValue("customGroundPos")) { grabModule.customGroundPos = bool.Parse(grabNode.GetValue("customGroundPos")); } if (grabNode.HasValue("dropPartPos")) { grabModule.dropPartPos = KAS_Shared.ParseCfgVector3(grabNode.GetValue("dropPartPos")); } if (grabNode.HasValue("dropPartRot")) { grabModule.dropPartRot = KAS_Shared.ParseCfgVector3(grabNode.GetValue("dropPartRot")); } if (grabNode.HasValue("physicJoint")) { grabModule.physicJoint = bool.Parse(grabNode.GetValue("physicJoint")); } if (grabNode.HasValue("addPartMass")) { grabModule.addPartMass = bool.Parse(grabNode.GetValue("addPartMass")); } if (grabNode.HasValue("storable")) { grabModule.storable = bool.Parse(grabNode.GetValue("storable")); } if (grabNode.HasValue("stateless")) { grabModule.stateless = bool.Parse(grabNode.GetValue("stateless")); } if (grabNode.HasValue("storedSize")) { grabModule.storedSize = int.Parse(grabNode.GetValue("storedSize")); } if (grabNode.HasValue("bayType")) { grabModule.bayType = grabNode.GetValue("bayType").ToString(); } if (grabNode.HasValue("bayNode")) { grabModule.bayNode = grabNode.GetValue("bayNode").ToString(); } if (grabNode.HasValue("bayRot")) { grabModule.bayRot = KAS_Shared.ParseCfgVector3(grabNode.GetValue("bayRot")); } if (grabNode.HasValue("grabSndPath")) { grabModule.grabSndPath = grabNode.GetValue("grabSndPath").ToString(); } if (grabNode.HasValue("attachMaxDist")) { grabModule.attachMaxDist = float.Parse(grabNode.GetValue("attachMaxDist")); } if (grabNode.HasValue("attachOnPart")) { grabModule.attachOnPart = bool.Parse(grabNode.GetValue("attachOnPart")); } if (grabNode.HasValue("attachOnEva")) { grabModule.attachOnEva = bool.Parse(grabNode.GetValue("attachOnEva")); } if (grabNode.HasValue("attachOnStatic")) { grabModule.attachOnStatic = bool.Parse(grabNode.GetValue("attachOnStatic")); } if (grabNode.HasValue("attachSendMsgOnly")) { grabModule.attachSendMsgOnly = bool.Parse(grabNode.GetValue("attachSendMsgOnly")); } if (grabNode.HasValue("attachPartSndPath")) { grabModule.attachPartSndPath = grabNode.GetValue("attachPartSndPath").ToString(); } if (grabNode.HasValue("attachStaticSndPath")) { grabModule.attachStaticSndPath = grabNode.GetValue("attachStaticSndPath").ToString(); } if (grabNode.HasValue("detachSndPath")) { grabModule.detachSndPath = grabNode.GetValue("detachSndPath").ToString(); } KAS_Shared.DebugLog("AddGrabModule(AddModule) Module successfully configured on " + partName); } }
public void Update() { this.enabled = true; AvailablePart intakePart = PartLoader.getPartInfoByName("CircularIntake"); if (intakePart != null) { if (intakePart.partPrefab.FindModulesImplementing <AtmosphericIntake>().Count <= 0 && PartLoader.Instance.IsReady()) { plugin_init = false; } } if (!resources_configured) { ConfigNode plugin_settings = GameDatabase.Instance.GetConfigNode("WarpPlugin/WarpPluginSettings/WarpPluginSettings"); if (plugin_settings != null) { if (plugin_settings.HasValue("ThermalMechanicsDisabled")) { PluginHelper.is_thermal_dissip_disabled = bool.Parse(plugin_settings.GetValue("ThermalMechanicsDisabled")); Debug.Log("[KSP Interstellar] ThermalMechanics set to enabled: " + !PluginHelper.is_thermal_dissip_disabled); } resources_configured = true; } else { showInstallationErrorMessage(); } } if (!plugin_init) { gdb = GameDatabase.Instance; plugin_init = true; AvailablePart kerbalRadiationPart = PartLoader.getPartInfoByName("kerbalEVA"); if (kerbalRadiationPart.partPrefab.Modules != null) { if (kerbalRadiationPart.partPrefab.FindModulesImplementing <FNModuleRadiation>().Count == 0) { kerbalRadiationPart.partPrefab.gameObject.AddComponent <FNModuleRadiation>(); } } else { kerbalRadiationPart.partPrefab.gameObject.AddComponent <FNModuleRadiation>(); } List <AvailablePart> available_parts = PartLoader.LoadedPartsList; foreach (AvailablePart available_part in available_parts) { Part prefab_available_part = available_part.partPrefab; try { if (prefab_available_part.Modules != null) { if (prefab_available_part.FindModulesImplementing <ModuleResourceIntake>().Count > 0) { ModuleResourceIntake intake = prefab_available_part.Modules["ModuleResourceIntake"] as ModuleResourceIntake; if (intake.resourceName == "IntakeAir") { Type type = AssemblyLoader.GetClassByName(typeof(PartModule), "AtmosphericIntake"); AtmosphericIntake pm = null; if (type != null) { pm = prefab_available_part.gameObject.AddComponent(type) as AtmosphericIntake; prefab_available_part.Modules.Add(pm); pm.area = intake.area * intake.unitScalar * intake.maxIntakeSpeed / 20; } PartResource intake_air_resource = prefab_available_part.Resources["IntakeAir"]; if (intake_air_resource != null && !prefab_available_part.Resources.Contains(InterstellarResourcesConfiguration.Instance.IntakeAtmosphere)) { ConfigNode node = new ConfigNode("RESOURCE"); node.AddValue("name", InterstellarResourcesConfiguration.Instance.IntakeAtmosphere); node.AddValue("maxAmount", intake_air_resource.maxAmount); node.AddValue("amount", intake_air_resource.amount); prefab_available_part.AddResource(node); } } } if (prefab_available_part.FindModulesImplementing <ModuleDeployableSolarPanel>().Count > 0) { ModuleDeployableSolarPanel panel = prefab_available_part.Modules["ModuleDeployableSolarPanel"] as ModuleDeployableSolarPanel; if (panel.chargeRate > 0) { Type type = AssemblyLoader.GetClassByName(typeof(PartModule), "FNSolarPanelWasteHeatModule"); FNSolarPanelWasteHeatModule pm = null; if (type != null) { pm = prefab_available_part.gameObject.AddComponent(type) as FNSolarPanelWasteHeatModule; prefab_available_part.Modules.Add(pm); } } if (!prefab_available_part.Resources.Contains("WasteHeat") && panel.chargeRate > 0) { ConfigNode node = new ConfigNode("RESOURCE"); node.AddValue("name", "WasteHeat"); node.AddValue("maxAmount", panel.chargeRate * 100); node.AddValue("amount", 0); PartResource pr = prefab_available_part.AddResource(node); if (available_part.resourceInfo != null && pr != null) { if (available_part.resourceInfo.Length == 0) { available_part.resourceInfo = pr.resourceName + ":" + pr.amount + " / " + pr.maxAmount; } else { available_part.resourceInfo = available_part.resourceInfo + "\n" + pr.resourceName + ":" + pr.amount + " / " + pr.maxAmount; } } } } if (prefab_available_part.FindModulesImplementing <ElectricEngineControllerFX>().Count() > 0) { available_part.moduleInfo = prefab_available_part.FindModulesImplementing <ElectricEngineControllerFX>().First().GetInfo(); available_part.moduleInfos.RemoveAll(modi => modi.moduleName == "Engine"); AvailablePart.ModuleInfo mod_info = available_part.moduleInfos.Where(modi => modi.moduleName == "Electric Engine Controller").First(); mod_info.moduleName = "Electric Engine"; } if (prefab_available_part.FindModulesImplementing <FNNozzleController>().Count() > 0) { available_part.moduleInfo = prefab_available_part.FindModulesImplementing <FNNozzleController>().First().GetInfo(); available_part.moduleInfos.RemoveAll(modi => modi.moduleName == "Engine"); AvailablePart.ModuleInfo mod_info = available_part.moduleInfos.Where(modi => modi.moduleName == "FNNozzle Controller").First(); mod_info.moduleName = "Thermal Nozzle"; } if (prefab_available_part.CrewCapacity > 0 || prefab_available_part.FindModulesImplementing <ModuleCommand>().Count > 0) { Type type = AssemblyLoader.GetClassByName(typeof(PartModule), "FNModuleRadiation"); FNModuleRadiation pm = null; if (type != null) { pm = prefab_available_part.gameObject.AddComponent(type) as FNModuleRadiation; prefab_available_part.Modules.Add(pm); double rad_hardness = prefab_available_part.mass / (Math.Max(prefab_available_part.CrewCapacity, 0.1)) * 7.5; pm.rad_hardness = rad_hardness; AvailablePart.ModuleInfo minfo = new AvailablePart.ModuleInfo(); minfo.moduleName = "Radiation Status"; minfo.info = pm.GetInfo(); available_part.moduleInfos.Add(minfo); } print("Adding ModuleRadiation to " + prefab_available_part.name); } } }catch (Exception ex) { if (prefab_available_part != null) { print("[KSP Interstellar] Exception caught adding to: " + prefab_available_part.name + " part: " + ex.ToString()); } else { print("[KSP Interstellar] Exception caught adding to unknown module"); } } } } //Destroy (this); }
public static void Update(Vessel v, Vessel_Info vi, VesselData vd, Vessel_Resources resources, double elapsed_s) { // get most used resource handlers Resource_Info ec = resources.Info(v, "ElectricCharge"); // store data required to support multiple modules of same type in a part var PD = new Dictionary <string, Lib.module_prefab_data>(); // for each part foreach (ProtoPartSnapshot p in v.protoVessel.protoPartSnapshots) { // get part prefab (required for module properties) Part part_prefab = PartLoader.getPartInfoByName(p.partName).partPrefab; // get all module prefabs var module_prefabs = part_prefab.FindModulesImplementing <PartModule>(); // clear module indexes PD.Clear(); // for each module foreach (ProtoPartModuleSnapshot m in p.modules) { // get module type // if the type is unknown, skip it Module_Type type = ModuleType(m.moduleName); if (type == Module_Type.Unknown) { continue; } // get the module prefab // if the prefab doesn't contain this module, skip it PartModule module_prefab = Lib.ModulePrefab(module_prefabs, m.moduleName, PD); if (!module_prefab) { continue; } // if the module is disabled, skip it // note: this must be done after ModulePrefab is called, so that indexes are right if (!Lib.Proto.GetBool(m, "isEnabled")) { continue; } // process modules // note: this should be a fast switch, possibly compiled to a jump table switch (type) { case Module_Type.Reliability: Reliability.BackgroundUpdate(v, p, m, module_prefab as Reliability); break; case Module_Type.Experiment: Experiment.BackgroundUpdate(v, m, module_prefab as Experiment, ec, elapsed_s); break; case Module_Type.Greenhouse: Greenhouse.BackgroundUpdate(v, m, module_prefab as Greenhouse, vi, resources, elapsed_s); break; case Module_Type.GravityRing: GravityRing.BackgroundUpdate(v, p, m, module_prefab as GravityRing, ec, elapsed_s); break; case Module_Type.Emitter: Emitter.BackgroundUpdate(v, p, m, module_prefab as Emitter, ec, elapsed_s); break; case Module_Type.Harvester: Harvester.BackgroundUpdate(v, m, module_prefab as Harvester, elapsed_s); break; case Module_Type.Laboratory: Laboratory.BackgroundUpdate(v, p, m, module_prefab as Laboratory, ec, elapsed_s); break; case Module_Type.Command: ProcessCommand(v, p, m, module_prefab as ModuleCommand, resources, elapsed_s); break; case Module_Type.Panel: ProcessPanel(v, p, m, module_prefab as ModuleDeployableSolarPanel, vi, ec, elapsed_s); break; case Module_Type.Generator: ProcessGenerator(v, p, m, module_prefab as ModuleGenerator, resources, elapsed_s); break; case Module_Type.Converter: ProcessConverter(v, p, m, module_prefab as ModuleResourceConverter, resources, elapsed_s); break; case Module_Type.Drill: ProcessHarvester(v, p, m, module_prefab as ModuleResourceHarvester, resources, elapsed_s); break; case Module_Type.AsteroidDrill: ProcessAsteroidDrill(v, p, m, module_prefab as ModuleAsteroidDrill, resources, elapsed_s); break; case Module_Type.StockLab: ProcessStockLab(v, p, m, module_prefab as ModuleScienceConverter, ec, elapsed_s); break; case Module_Type.Light: ProcessLight(v, p, m, module_prefab as ModuleLight, ec, elapsed_s); break; case Module_Type.Scanner: ProcessScanner(v, p, m, module_prefab, part_prefab, vd, ec, elapsed_s); break; case Module_Type.CurvedPanel: ProcessCurvedPanel(v, p, m, module_prefab, part_prefab, vi, ec, elapsed_s); break; case Module_Type.FissionGenerator: ProcessFissionGenerator(v, p, m, module_prefab, ec, elapsed_s); break; case Module_Type.RadioisotopeGenerator: ProcessRadioisotopeGenerator(v, p, m, module_prefab, ec, elapsed_s); break; case Module_Type.CryoTank: ProcessCryoTank(v, p, m, module_prefab, resources, elapsed_s); break; case Module_Type.AntennaDeploy: AntennaDeploy.BackgroundUpdate(v, p, m, vi, ec, elapsed_s); break; } } } }
public static string ReqValueFormat(Require req, object reqValue) { if (reqValue == null) { return(string.Empty); } switch (req) { case Require.OrbitMinEccentricity: case Require.OrbitMaxEccentricity: case Require.OrbitMinArgOfPeriapsis: case Require.OrbitMaxArgOfPeriapsis: case Require.AtmosphereAltMin: case Require.AtmosphereAltMax: return(((double)reqValue).ToString("F2")); case Require.SunAngleMin: case Require.SunAngleMax: case Require.OrbitMinInclination: case Require.OrbitMaxInclination: return(Lib.HumanReadableAngle((double)reqValue)); case Require.TemperatureMin: case Require.TemperatureMax: return(Lib.HumanReadableTemp((double)reqValue)); case Require.AltitudeMin: case Require.AltitudeMax: case Require.AltAboveGroundMin: case Require.AltAboveGroundMax: case Require.MaxAsteroidDistance: return(Lib.HumanReadableDistance((double)reqValue)); case Require.RadiationMin: case Require.RadiationMax: return(Lib.HumanReadableRadiation((double)reqValue)); case Require.VolumePerCrewMin: case Require.VolumePerCrewMax: return(Lib.HumanReadableVolume((double)reqValue)); case Require.SurfaceSpeedMin: case Require.SurfaceSpeedMax: case Require.VerticalSpeedMin: case Require.VerticalSpeedMax: case Require.SpeedMin: case Require.SpeedMax: return(Lib.HumanReadableSpeed((double)reqValue)); case Require.DynamicPressureMin: case Require.DynamicPressureMax: case Require.StaticPressureMin: case Require.StaticPressureMax: case Require.AtmDensityMin: case Require.AtmDensityMax: return(Lib.HumanReadablePressure((double)reqValue)); case Require.CrewMin: case Require.CrewMax: case Require.CrewCapacityMin: case Require.CrewCapacityMax: case Require.AstronautComplexLevelMin: case Require.AstronautComplexLevelMax: case Require.TrackingStationLevelMin: case Require.TrackingStationLevelMax: case Require.MissionControlLevelMin: case Require.MissionControlLevelMax: case Require.AdministrationLevelMin: case Require.AdministrationLevelMax: return(((int)reqValue).ToString()); case Require.Module: return(KSPUtil.PrintModuleName((string)reqValue)); case Require.Part: return(PartLoader.getPartInfoByName((string)reqValue)?.title ?? (string)reqValue); case Require.Sunlight: case Require.Shadow: return(((double)reqValue).ToString("P2")); default: return(string.Empty); } }
public AntennaInfoRT(Vessel v, bool powered, bool storm) { RemoteTech.SetPoweredDown(v.id, !powered); RemoteTech.SetCommsBlackout(v.id, storm); // if vessel is loaded, don't calculate ec, RT already handle it. if (v.loaded) { // find transmitters foreach (Part p in v.parts) { foreach (PartModule m in p.Modules) { // calculate internal (passive) transmitter ec usage @ 0.5W each if (m.moduleName == "ModuleRTAntennaPassive") { ec += 0.0005; } // calculate external transmitters else if (m.moduleName == "ModuleRTAntenna") { // only include data rate and ec cost if transmitter is active if (Lib.ReflectionValue <bool>(m, "IsRTActive")) { rate += (Lib.ReflectionValue <float>(m, "RTPacketSize") / Lib.ReflectionValue <float>(m, "RTPacketInterval")); } } } } } // if vessel is not loaded else { // find proto transmitters foreach (ProtoPartSnapshot p in v.protoVessel.protoPartSnapshots) { // get part prefab (required for module properties) Part part_prefab = PartLoader.getPartInfoByName(p.partName).partPrefab; foreach (ProtoPartModuleSnapshot m in p.modules) { // calculate internal (passive) transmitter ec usage @ 0.5W each if (m.moduleName == "ModuleRTAntennaPassive") { ec += 0.0005; } // calculate external transmitters else if (m.moduleName == "ModuleRTAntenna") { // only include data rate and ec cost if transmitter is active if (Lib.Proto.GetBool(m, "IsRTActive")) { bool mFound = false; // get all modules in prefab foreach (PartModule pm in part_prefab.Modules) { if (pm.moduleName == m.moduleName) { mFound = true; ModuleResource mResource = pm.resHandler.inputResources.Find(r => r.name == "ElectricCharge"); float? packet_size = Lib.SafeReflectionValue <float>(pm, "RTPacketSize"); float? packet_Interval = Lib.SafeReflectionValue <float>(pm, "RTPacketInterval"); // workaround for old savegames if (mResource == null || packet_size == null || packet_Interval == null) { Lib.DebugLog("Old SaveGame PartModule ModuleRTAntenna for part '{0}' on unloaded vessel '{1}', using default values as a workaround", p.partName, v.vesselName); Lib.DebugLog("ElectricCharge isNull: '{0}', RTPacketSize isNull: '{1}', RTPacketInterval isNull: '{2}'", mResource == null, packet_size == null, packet_Interval == null); rate += 6.6666; // 6.67 Mb/s in 100% factor ec += 0.025; // 25 W/s } else { rate += (float)packet_size / (float)packet_Interval; ec += mResource.rate; } } } if (!mFound) { Lib.DebugLog("Could not find PartModule ModuleRTAntenna for part {0} on unloaded vessel {1}, using default values as a workaround", p.partName, v.vesselName); rate += 6.6666; // 6.67 Mb/s in 100% factor ec += 0.025; // 25 W/s } } } } } } Init(v, powered, storm); }
// return set of devices on a vessel // - the list is only valid for a single simulation step public static List <Device> GetModuleDevices(Vessel v) { List <Device> moduleDevices = Cache.VesselObjectsCache <List <Device> >(v, "computer"); if (moduleDevices != null) { return(moduleDevices); } moduleDevices = new List <Device>(); // store device being added Device device; // loaded vessel if (v.loaded) { foreach (PartModule m in Lib.FindModules <PartModule>(v)) { switch (m.moduleName) { case "ProcessController": device = new ProcessDevice(m as ProcessController); break; case "Sickbay": device = new SickbayDevice(m as Sickbay); break; case "Greenhouse": device = new GreenhouseDevice(m as Greenhouse); break; case "GravityRing": device = new RingDevice(m as GravityRing); break; case "Emitter": device = new EmitterDevice(m as Emitter); break; case "Laboratory": device = new LaboratoryDevice(m as Laboratory); break; case "Experiment": device = new ExperimentDevice(m as Experiment); break; case "SolarPanelFixer": device = new PanelDevice(m as SolarPanelFixer); break; case "ModuleGenerator": device = new GeneratorDevice(m as ModuleGenerator); break; case "ModuleResourceConverter": device = new ConverterDevice(m as ModuleResourceConverter); break; case "ModuleKPBSConverter": device = new ConverterDevice(m as ModuleResourceConverter); break; case "FissionReactor": device = new ConverterDevice(m as ModuleResourceConverter); break; case "ModuleResourceHarvester": device = new DrillDevice(m as ModuleResourceHarvester); break; case "ModuleLight": device = new LightDevice(m as ModuleLight); break; case "ModuleColoredLensLight": device = new LightDevice(m as ModuleLight); break; case "ModuleMultiPointSurfaceLight": device = new LightDevice(m as ModuleLight); break; case "SCANsat": device = new ScannerDevice(m); break; case "ModuleSCANresourceScanner": device = new ScannerDevice(m); break; case "ModuleRTAntenna": case "ModuleDataTransmitter": device = new AntennaDevice(m, m.moduleName); break; case "ModuleRTAntennaPassive": device = new AntennaDevice(m, "ModuleRTAntenna"); break; default: continue; } // add the device moduleDevices.Add(device); } } // unloaded vessel else { // store data required to support multiple modules of same type in a part var PD = new Dictionary <string, Lib.Module_prefab_data>(); // for each part foreach (ProtoPartSnapshot p in v.protoVessel.protoPartSnapshots) { // get part prefab (required for module properties) Part part_prefab = PartLoader.getPartInfoByName(p.partName).partPrefab; // get all module prefabs var module_prefabs = part_prefab.FindModulesImplementing <PartModule>(); // clear module indexes PD.Clear(); // for each module foreach (ProtoPartModuleSnapshot m in p.modules) { // get the module prefab // if the prefab doesn't contain this module, skip it PartModule module_prefab = Lib.ModulePrefab(module_prefabs, m.moduleName, PD); if (!module_prefab) { continue; } // if the module is disabled, skip it // note: this must be done after ModulePrefab is called, so that indexes are right if (!Lib.Proto.GetBool(m, "isEnabled")) { continue; } // depending on module name switch (m.moduleName) { case "ProcessController": device = new ProtoProcessDevice(module_prefab as ProcessController, p, m); break; case "Sickbay": device = new ProtoSickbayDevice(module_prefab as Sickbay, p, m); break; case "Greenhouse": device = new ProtoGreenhouseDevice(module_prefab as Greenhouse, p, m); break; case "GravityRing": device = new ProtoRingDevice(module_prefab as GravityRing, p, m); break; case "Emitter": device = new ProtoEmitterDevice(module_prefab as Emitter, p, m); break; case "Laboratory": device = new ProtoLaboratoryDevice(module_prefab as Laboratory, p, m); break; case "Experiment": device = new ProtoExperimentDevice(module_prefab as Experiment, p, m, v); break; case "SolarPanelFixer": device = new ProtoPanelDevice(module_prefab as SolarPanelFixer, p, m); break; case "ModuleGenerator": device = new ProtoGeneratorDevice(module_prefab as ModuleGenerator, p, m); break; case "ModuleResourceConverter": case "ModuleKPBSConverter": case "FissionReactor": device = new ProtoConverterDevice(module_prefab as ModuleResourceConverter, p, m); break; case "ModuleResourceHarvester": device = new ProtoDrillDevice(module_prefab as ModuleResourceHarvester, p, m); break; case "ModuleLight": case "ModuleColoredLensLight": case "ModuleMultiPointSurfaceLight": device = new ProtoLightDevice(module_prefab as ModuleLight, p, m); break; case "SCANsat": device = new ProtoScannerDevice(module_prefab, p, m, v); break; case "ModuleSCANresourceScanner": device = new ProtoScannerDevice(module_prefab, p, m, v); break; case "ModuleRTAntenna": case "ModuleDataTransmitter": device = new ProtoAntennaDevice(module_prefab, p, m, m.moduleName); break; case "ModuleRTAntennaPassive": device = new ProtoAntennaDevice(module_prefab, p, m, "ModuleRTAntenna"); break; default: continue; } // add the device moduleDevices.Add(device); } } } // return all found module devices sorted by type, then by name // in reverse (the list will be presented from end to start in the UI) moduleDevices.Sort((b, a) => { int xdiff = a.DeviceType.CompareTo(b.DeviceType); if (xdiff != 0) { return(xdiff); } else { return(a.Name.CompareTo(b.Name)); } }); // now add vessel wide devices to the end of the list VesselData vd = v.KerbalismData(); moduleDevices.Add(new VesselDeviceTransmit(v, vd)); // vessel wide transmission toggle Cache.SetVesselObjectsCache(v, "computer", moduleDevices); return(moduleDevices); }
/// //////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// Post-load initialization. /// </summary> /// //////////////////////////////////////////////////////////////////////////////////////// public void load() { Util.log("++++ 'load()' ++++"); foreach (SkinnedMeshRenderer smr in Resources.FindObjectsOfTypeAll <SkinnedMeshRenderer>()) { if (skinningQuality != SkinQuality.Auto) { smr.quality = skinningQuality; } } foreach (Texture texture in Resources.FindObjectsOfTypeAll <Texture>()) { if (texture.filterMode == FilterMode.Bilinear) { texture.filterMode = FilterMode.Trilinear; } } foreach (GameDatabase.TextureInfo texInfo in GameDatabase.Instance.databaseTexture) { Texture2D texture = texInfo.texture; if (texture == null) { continue; } foreach (string path in Folders.DEFAULT) { if (!texture.name.StartsWith(path, StringComparison.Ordinal)) { continue; } string originalName = texture.name.Substring(path.Length); // Since we are merging multiple directories, we must expect conflicts. if (!mappedTextures.ContainsKey(originalName)) { if (originalName.StartsWith("GalaxyTex_", StringComparison.Ordinal)) { texture.wrapMode = TextureWrapMode.Clamp; } mappedTextures.Add(originalName, texture); } break; } } Shader headShader = Shader.Find("Bumped Diffuse"); Shader suitShader = Shader.Find("Bumped Diffuse"); Texture2D[] headNormalMaps = { null, null }; Texture2D ivaVisorTexture = null; if (mappedTextures.TryGetValue("kerbalHeadNRM", out headNormalMaps[0])) { mappedTextures.Remove("kerbalHeadNRM"); } if (mappedTextures.TryGetValue("kerbalGirl_06_BaseColorNRM", out headNormalMaps[1])) { mappedTextures.Remove("kerbalGirl_06_BaseColorNRM"); } if (mappedTextures.TryGetValue("kerbalVisor", out ivaVisorTexture)) { mappedTextures.Remove("kerbalVisor"); } // Fix female shaders, set normal-mapped shader for head and visor texture on proto-IVA and -EVA Kerbals. Kerbal[] kerbals = Resources.FindObjectsOfTypeAll <Kerbal>(); /*Util.log("++++++++++++++++++++++++++++++++++++ pouet+++++++++++++++++++++++++++++++++++++++++"); * foreach (Kerbal kerb in kerbals) * { * Util.log(kerb.name); * }*/ Kerbal maleIva = kerbals.First(k => k.transform.name == "kerbalMale"); Kerbal femaleIva = kerbals.First(k => k.transform.name == "kerbalFemale"); Part maleEva = PartLoader.getPartInfoByName("kerbalEVA").partPrefab; Part femaleEva = PartLoader.getPartInfoByName("kerbalEVAfemale").partPrefab; SkinnedMeshRenderer[][] maleMeshes = { maleIva.GetComponentsInChildren <SkinnedMeshRenderer>(true), maleEva.GetComponentsInChildren <SkinnedMeshRenderer>(true) }; SkinnedMeshRenderer[][] femaleMeshes = { femaleIva.GetComponentsInChildren <SkinnedMeshRenderer>(true), femaleEva.GetComponentsInChildren <SkinnedMeshRenderer>(true) }; // Male materials to be copied to females to fix tons of female issues (missing normal maps, non-bumpmapped // shaders, missing teeth texture ...) Material headMaterial = null; Material[] suitMaterials = { null, null }; Material[] helmetMaterials = { null, null }; Material[] visorMaterials = { null, null }; Material jetpackMaterial = null; for (int i = 0; i < 2; ++i) { foreach (SkinnedMeshRenderer smr in maleMeshes[i]) { // Many meshes share material, so it suffices to enumerate only one mesh for each material. switch (smr.name) { case "headMesh01": // Replace with bump-mapped shader so normal maps for heads will work. smr.sharedMaterial.shader = headShader; if (headNormalMaps[0] != null) { smr.sharedMaterial.SetTexture(Util.BUMPMAP_PROPERTY, headNormalMaps[0]); } headMaterial = smr.sharedMaterial; break; case "eyeballLeft": smr.sharedMaterial.shader = headShader; break; case "mesh_female_kerbalAstronaut01_kerbalGirl_mesh_eyeballLeft": smr.sharedMaterial.shader = headShader; break; case "eyeballRight": smr.sharedMaterial.shader = headShader; break; case "mesh_female_kerbalAstronaut01_kerbalGirl_mesh_eyeballRight": smr.sharedMaterial.shader = headShader; break; case "pupilLeft": smr.sharedMaterial.shader = headShader; break; case "pupilRight": smr.sharedMaterial.shader = headShader; break; case "mesh_female_kerbalAstronaut01_kerbalGirl_mesh_pupilLeft": smr.sharedMaterial.shader = headShader; break; case "mesh_female_kerbalAstronaut01_kerbalGirl_mesh_pupilRight": smr.sharedMaterial.shader = headShader; break; case "upTeeth01": smr.sharedMaterial.shader = headShader; break; case "mesh_female_kerbalAstronaut01_kerbalGirl_mesh_downTeeth01": smr.sharedMaterial.shader = headShader; break; case "mesh_female_kerbalAstronaut01_kerbalGirl_mesh_upTeeth02": smr.sharedMaterial.shader = headShader; break; case "mesh_female_kerbalAstronaut01_kerbalGirl_mesh_downTeeth02": smr.sharedMaterial.shader = headShader; break; case "downTeeth01": smr.sharedMaterial.shader = headShader; break; case "body01": // Also replace shader on EVA suits to match the one on IVA suits and to enable heat effects. smr.sharedMaterial.shader = suitShader; suitMaterials[i] = smr.sharedMaterial; break; case "helmet": // Also replace shader on EVA suits to match the one on IVA suits and to enable heat effects. smr.sharedMaterial.shader = suitShader; helmetMaterials[i] = smr.sharedMaterial; break; case "jetpack_base01": // Also replace shader on EVA suits to match the one on IVA suits and to enable heat effects. smr.sharedMaterial.shader = suitShader; jetpackMaterial = smr.sharedMaterial; break; case "visor": if (smr.transform.root == maleIva.transform && ivaVisorTexture != null) { smr.sharedMaterial.mainTexture = ivaVisorTexture; smr.sharedMaterial.color = Color.white; } visorMaterials[i] = smr.sharedMaterial; break; } } } for (int i = 0; i < 2; ++i) { foreach (SkinnedMeshRenderer smr in femaleMeshes[i]) { // Here we must enumerate all meshes wherever we are replacing the material. switch (smr.name) { case "headMesh": smr.sharedMaterial.shader = headShader; if (headNormalMaps[1] != null) { smr.sharedMaterial.SetTexture(Util.BUMPMAP_PROPERTY, headNormalMaps[1]); } break; case "mesh_female_kerbalAstronaut01_kerbalGirl_mesh_upTeeth01": case "mesh_female_kerbalAstronaut01_kerbalGirl_mesh_downTeeth01": case "upTeeth01": case "downTeeth01": // Females don't have textured teeth, they use the same material as for the eyeballs. Extending female // head material/texture to their teeth is not possible since teeth overlap with some ponytail sub texture. // However, female teeth map to the same texture coordinates as male teeth, so we fix this by applying // male head & teeth material for female teeth. smr.sharedMaterial = headMaterial; break; case "mesh_female_kerbalAstronaut01_body01": case "body01": smr.sharedMaterial = suitMaterials[i]; break; case "mesh_female_kerbalAstronaut01_helmet": case "helmet": smr.sharedMaterial = helmetMaterials[i]; break; case "jetpack_base01": smr.sharedMaterial = jetpackMaterial; break; case "mesh_female_kerbalAstronaut01_visor": case "visor": smr.sharedMaterial = visorMaterials[i]; break; } } } // Find NavBall replacement textures if available. if (mappedTextures.TryGetValue(HUD_NAVBALL, out hudNavBallTexture)) { mappedTextures.Remove(HUD_NAVBALL); if (hudNavBallTexture.mipmapCount != 1) { Util.log("HUDNavBall texture should not have mipmaps!"); } } if (mappedTextures.TryGetValue(IVA_NAVBALL, out ivaNavBallTexture)) { mappedTextures.Remove(IVA_NAVBALL); if (ivaNavBallTexture.mipmapCount != 1) { Util.log("IVANavBall texture should not have mipmaps!"); } } }
public TSGenericUpdater(Part part) { _part = part; _basePart = PartLoader.getPartInfoByName(part.partInfo.name).partPrefab; _ts = part.Modules.OfType <TweakScale>().First(); }
void boot_devices(Vessel v) { // store stuff string filename; Device device; // index counters int scrubber_i = 0; int recycler_i = 0; int greenhouse_i = 0; int ring_i = 0; int emitter_i = 0; int light_i = 0; int panel_i = 0; int generator_i = 0; int converter_i = 0; int drill_i = 0; // loaded vessel if (v.loaded) { foreach(PartModule m in v.FindPartModulesImplementing<PartModule>()) { switch(m.moduleName) { case "Scrubber": filename = Lib.BuildString("scrubber/", scrubber_i++.ToString()); device = new ScrubberDevice(m as Scrubber); break; case "Recycler": filename = Lib.BuildString("recycler/", recycler_i++.ToString()); device = new RecyclerDevice(m as Recycler); break; case "Greenhouse": filename = Lib.BuildString("greenhouse/", greenhouse_i++.ToString()); device = new GreenhouseDevice(m as Greenhouse); break; case "GravityRing": filename = Lib.BuildString("ring/", ring_i++.ToString()); device = new RingDevice(m as GravityRing); break; case "Emitter": if ((m as Emitter).ec_rate <= double.Epsilon) continue; //< skip non-tweakable emitters filename = Lib.BuildString("emitter/", emitter_i++.ToString()); device = new EmitterDevice(m as Emitter); break; case "ModuleDeployableSolarPanel": filename = Lib.BuildString("panel/", panel_i++.ToString()); device = new PanelDevice(m as ModuleDeployableSolarPanel); break; case "ModuleGenerator": filename = Lib.BuildString("generator/", generator_i++.ToString()); device = new GeneratorDevice(m as ModuleGenerator); break; case "ModuleResourceConverter": case "ModuleKPBSConverter": case "FissionReactor": filename = Lib.BuildString("converter/", converter_i++.ToString()); device = new ConverterDevice(m as ModuleResourceConverter); break; case "ModuleResourceHarvester": filename = Lib.BuildString("drill/", drill_i++.ToString()); device = new DrillDevice(m as ModuleResourceHarvester); break; case "ModuleLight": case "ModuleColoredLensLight": case "ModuleMultiPointSurfaceLight": filename = Lib.BuildString("light/", light_i++.ToString()); device = new LightDevice(m as ModuleLight); break; default: continue; } // add device file files.Add(filename, new File(device)); } } // unloaded vessel else { foreach(ProtoPartSnapshot p in v.protoVessel.protoPartSnapshots) { // a part can contain multiple resource converters int converter_index = 0; // get part prefab Part part_prefab = PartLoader.getPartInfoByName(p.partName).partPrefab; // for each modules foreach(ProtoPartModuleSnapshot m in p.modules) { // get the module prefab, skip if prefab doesn't contain the module PartModule module_prefab = Lib.FindModule(part_prefab, m.moduleName); if (!module_prefab) continue; // depending on module name switch(m.moduleName) { case "Scrubber": filename = Lib.BuildString("scrubber/", scrubber_i++.ToString()); device = new ProtoScrubberDevice(m); break; case "Recycler": filename = Lib.BuildString("recycler/", recycler_i++.ToString()); device = new ProtoRecyclerDevice(m); break; case "Greenhouse": filename = Lib.BuildString("greenhouse/", greenhouse_i++.ToString()); device = new ProtoGreenhouseDevice(m); break; case "GravityRing": filename = Lib.BuildString("ring/", ring_i++.ToString()); device = new ProtoRingDevice(m); break; case "Emitter": if ((module_prefab as Emitter).ec_rate <= double.Epsilon) continue; //< skip non-tweakable emitters filename = Lib.BuildString("emitter/", emitter_i++.ToString()); device = new ProtoEmitterDevice(m); break; case "ModuleDeployableSolarPanel": filename = Lib.BuildString("panel/", panel_i++.ToString()); device = new ProtoPanelDevice(m, module_prefab as ModuleDeployableSolarPanel); break; case "ModuleGenerator": filename = Lib.BuildString("generator/", generator_i++.ToString()); device = new ProtoGeneratorDevice(m, module_prefab as ModuleGenerator); break; case "ModuleResourceConverter": case "ModuleKPBSConverter": case "FissionReactor": var converter_prefabs = part_prefab.Modules.GetModules<ModuleResourceConverter>(); if (converter_index >= converter_prefabs.Count) continue; module_prefab = converter_prefabs[converter_index++]; filename = Lib.BuildString("converter/", converter_i++.ToString()); device = new ProtoConverterDevice(m, module_prefab as ModuleResourceConverter); break; case "ModuleResourceHarvester": ProtoPartModuleSnapshot deploy = p.modules.Find(k => k.moduleName == "ModuleAnimationGroup"); filename = Lib.BuildString("drill/", drill_i++.ToString()); device = new ProtoDrillDevice(m, module_prefab as ModuleResourceHarvester, deploy); break; case "ModuleLight": case "ModuleColoredLensLight": case "ModuleMultiPointSurfaceLight": filename = Lib.BuildString("light/", light_i++.ToString()); device = new ProtoLightDevice(m); break; default: continue; } // add device file files.Add(filename, new File(device)); } } } }
protected override bool Generate() { TSTTelescopeContract[] TSTTelescopeContracts = ContractSystem.Instance.GetCurrentContracts <TSTTelescopeContract>(); int offers = 0; int active = 0; for (int i = 0; i < TSTTelescopeContracts.Length; i++) { TSTTelescopeContract m = TSTTelescopeContracts[i]; if (m.ContractState == State.Offered) { offers++; } else if (m.ContractState == State.Active) { active++; } } Utilities.Log_Debug("Telescope Contracts check offers= {0} active= {1}", offers.ToString(), active.ToString()); if (offers >= 1) { return(false); } if (active >= 1) { return(false); } Utilities.Log_Debug("Generating Telescope Contract"); agent = AgentList.Instance.GetAgent("Tarsier Space Technology"); SetExpiry(); expiryType = DeadlineType.None; deadlineType = DeadlineType.None; Utilities.Log_Debug("Creating Parameter"); TSTTelescopeContractParam param = new TSTTelescopeContractParam(); AddParameter(param); string target_name = TSTProgressTracker.GetNextTelescopeTarget(); if (target_name == default(string)) { Utilities.Log_Debug("target body is default (not set), cannot generate"); return(false); } Utilities.Log_Debug("Target: {0}", target_name); AvailablePart ap2 = PartLoader.getPartInfoByName("tarsierAdvSpaceTelescope"); if (!ResearchAndDevelopment.PartTechAvailable(ap2) && !ResearchAndDevelopment.PartModelPurchased(ap2) && target_name == "Galaxy1") { Utilities.Log_Debug("Contracts for Planets completed and Galaxy contracts require advanced space telescope"); return(false); } Utilities.Log_Debug("Checking Celestial Bodies"); target = FlightGlobals.Bodies.Find(b => b.name == target_name); if (target == null) { Utilities.Log_Debug("Checking Galaxies"); target = TSTGalaxies.Galaxies.Find(g => g.name == target_name); } Utilities.Log_Debug("Using target: {0}", target.ToString()); param.target = target; Utilities.Log_Debug("Creating Science Param"); TSTScienceParam param2 = new TSTScienceParam(); param2.matchFields.Add("TarsierSpaceTech.SpaceTelescope"); param2.matchFields.Add("LookingAt" + target.name); AddParameter(param2); Utilities.Log_Debug("Created Science Param"); prestige = TSTProgressTracker.getTelescopePrestige(target); if (TSTProgressTracker.HasTelescopeCompleted(target)) { SetScience(TSTMstStgs.Instance.TSTsettings.scienceDiscoveredScope, target.type == typeof(TSTGalaxy) ? null : (CelestialBody)target.BaseObject); SetFunds(TSTMstStgs.Instance.TSTsettings.fundsdiscoveredScope * 0.75f, TSTMstStgs.Instance.TSTsettings.fundsdiscoveredScope, target.type == typeof(TSTGalaxy) ? null : (CelestialBody)target.BaseObject); SetReputation(TSTMstStgs.Instance.TSTsettings.repDiscoveredScope, target.type == typeof(TSTGalaxy) ? null : (CelestialBody)target.BaseObject); } else { SetScience(TSTMstStgs.Instance.TSTsettings.scienceUndiscoveredScope, target.type == typeof(TSTGalaxy) ? null : (CelestialBody)target.BaseObject); SetFunds(TSTMstStgs.Instance.TSTsettings.fundsUndiscoveredScope * 0.75f, TSTMstStgs.Instance.TSTsettings.fundsUndiscoveredScope, target.type == typeof(TSTGalaxy) ? null : (CelestialBody)target.BaseObject); SetReputation(TSTMstStgs.Instance.TSTsettings.repUndiscoveredScope, target.type == typeof(TSTGalaxy) ? null : (CelestialBody)target.BaseObject); } return(true); }
private AvailablePart getPartForExperiment(Experiment exp) { return(PartLoader.getPartInfoByName(exp.getPartName())); }
public static void ApplyDecals() { var textures = GameDatabase.Instance.databaseTexture; List <string[]> progs = ReadDecalCfg( Util.Combine("GameData", "SimpleSurvival", "Decals", "decals.txt")); string prevPartname = null; int prevVariant = -1; AvailablePart part = null; Texture2D result = null; foreach (string[] prog in progs) { if (prog.Length < 3) { Util.Warn($"Prog error: length {prog.Length}"); continue; } string partname = prog[0]; int variant = int.Parse(prog[1]); string progname = prog[2]; int tokenIndex = 3; Util.Log("Modifying part " + partname); Util.Log(" Prog: " + progname); if (partname != prevPartname || variant != prevVariant) { part = PartLoader.getPartInfoByName(partname); if (variant >= part.Variants.Count) { Util.Warn($"Variant #{variant} out of range; part has {part.Variants.Count} variants"); prevPartname = null; prevVariant = -1; continue; } string texname = part.Variants[variant].Materials[0].mainTexture.name; Util.Log(" Found texture: " + texname); Texture2D tex = textures.Find(a => a.name == texname).texture; result = MakeWritable(tex); prevPartname = partname; prevVariant = variant; } if (progname == C.PROG_APPLY_DECAL) { if (prog.Length < 9) { Util.Warn(" Fewer than 9 req'd tokens found; skipping"); continue; } string decal = prog[tokenIndex++]; int originX = int.Parse(prog[tokenIndex++]); int originY = int.Parse(prog[tokenIndex++]); int width = int.Parse(prog[tokenIndex++]); int height = int.Parse(prog[tokenIndex++]); int rotate = int.Parse(prog[tokenIndex++]); int flip = int.Parse(prog[tokenIndex++]); Texture2D overlay_orig = textures.Find(a => a.name.EndsWith('/' + decal)).texture; // Get original texture if (part.Variants == null) { Util.Warn(" Variants is null. Skipping " + partname); continue; } // Get resized decal Texture2D overlay = MakeWritable(overlay_orig, width, height); // Transform decal Util.Log($" Rotating CW {rotate} times"); Rotate(overlay, cycles: rotate); if (flip % 2 == 1) { Util.Log(" Flipping horizontally"); FlipHorizontal(overlay); } if (flip >= 2) { Util.Log(" Flipping vertically"); FlipVertical(overlay); } // Place decal on original texture for (int x = 0; x < Math.Min(result.width - originX, overlay.width); x++) { for (int y = 0; y < Math.Min(result.height - originY, overlay.height); y++) { Color overcol = overlay.GetPixel(x, y); if (overcol.a < 0.1f) { continue; } result.SetPixel(originX + x, originY + y, overcol); } } } else if (progname == C.PROG_COLORMULT) { float rfact = float.Parse(prog[tokenIndex++]); float gfact = float.Parse(prog[tokenIndex++]); float bfact = float.Parse(prog[tokenIndex++]); int originX = int.Parse(prog[tokenIndex++]); int originY = int.Parse(prog[tokenIndex++]); int width = int.Parse(prog[tokenIndex++]); int height = int.Parse(prog[tokenIndex++]); for (int x = originX; x < Math.Min(result.width, originX + width); x++) { for (int y = originY; y < Math.Min(result.height, originY + height); y++) { Color col = result.GetPixel(x, y); col.r *= rfact; col.g *= gfact; col.b *= bfact; result.SetPixel(x, y, col); } } } else if (progname == C.PROG_GRAYSCALE) { Color[] pixels = result.GetPixels(); for (int i = 0; i < pixels.Length; i++) { float gs = pixels[i].grayscale; pixels[i].r = gs; pixels[i].g = gs; pixels[i].b = gs; } result.SetPixels(pixels); } else { Util.Warn($" Program {progname} not recognized"); continue; } result.Apply(true); part.Variants[variant].Materials[0].mainTexture = result; // The 0th variant is the first to be selected, so this variant // should always be the icon presented in RnD if (variant == 0) { TechLoader.IconTextures[part] = result; } } Util.Log("Completed setup of EVA LifeSupport"); }
void FixKerbalModels() { mappedTextures.TryGetValue("eyeballLeft", out Texture2D eyeballLeft); mappedTextures.TryGetValue("eyeballRight", out Texture2D eyeballRight); mappedTextures.TryGetValue("pupilLeft", out Texture2D pupilLeft); mappedTextures.TryGetValue("pupilRight", out Texture2D pupilRight); mappedTextures.TryGetValue("kerbalVisor", out Texture2D ivaVisorTexture); mappedTextures.TryGetValue("EVAvisor", out Texture2D evaVisorTexture); // Shaders between male and female models are inconsistent, female models are missing normal maps and specular // lighting. So, we copy shaders from male materials to respective female materials. Kerbal[] kerbals = Resources.FindObjectsOfTypeAll <Kerbal>(); Kerbal maleIva = kerbals.First(k => k.transform.name == "kerbalMale"); Kerbal femaleIva = kerbals.First(k => k.transform.name == "kerbalFemale"); Part maleEva = PartLoader.getPartInfoByName("kerbalEVA").partPrefab; Part femaleEva = PartLoader.getPartInfoByName("kerbalEVAfemale").partPrefab; Part maleEvaVintage = PartLoader.getPartInfoByName("kerbalEVAVintage").partPrefab; Part femaleEvaVintage = PartLoader.getPartInfoByName("kerbalEVAfemaleVintage").partPrefab; if (logKerbalHierarchy) { LogHierarchies(maleIva, maleEva, maleEvaVintage, femaleIva, femaleEva, femaleEvaVintage); } SkinnedMeshRenderer[][] maleMeshes = { maleIva.GetComponentsInChildren <SkinnedMeshRenderer>(true), maleEva.GetComponentsInChildren <SkinnedMeshRenderer>(true), maleEvaVintage?.GetComponentsInChildren <SkinnedMeshRenderer>(true) }; SkinnedMeshRenderer[][] femaleMeshes = { femaleIva.GetComponentsInChildren <SkinnedMeshRenderer>(true), femaleEva.GetComponentsInChildren <SkinnedMeshRenderer>(true), femaleEvaVintage?.GetComponentsInChildren <SkinnedMeshRenderer>(true) }; // Male materials to be copied to females to fix tons of female issues (missing normal maps, non-bumpmapped // shaders, missing teeth texture ...) Material headMaterial = null; Material[] visorMaterials = { null, null, null }; for (int i = 0; i < 3; ++i) { if (maleMeshes[i] == null) { continue; } foreach (SkinnedMeshRenderer smr in maleMeshes[i]) { // Many meshes share the same material, so it suffices to enumerate only one mesh for each material. switch (smr.name) { case "eyeballLeft": smr.sharedMaterial.shader = EyeShader; smr.sharedMaterial.mainTexture = eyeballLeft; break; case "eyeballRight": smr.sharedMaterial.shader = EyeShader; smr.sharedMaterial.mainTexture = eyeballRight; break; case "pupilLeft": smr.sharedMaterial.shader = EyeShader; smr.sharedMaterial.mainTexture = pupilLeft; if (pupilLeft != null) { smr.sharedMaterial.color = Color.white; } break; case "pupilRight": smr.sharedMaterial.shader = EyeShader; smr.sharedMaterial.mainTexture = pupilRight; if (pupilRight != null) { smr.sharedMaterial.color = Color.white; } break; case "headMesh01": case "headMesh02": // Replace with bump-mapped shader so normal maps for heads will work. smr.sharedMaterial.shader = HeadShader; headMaterial = smr.sharedMaterial; break; case "visor": // It will be raplaced with reflective shader later, if reflections are enabled. switch (i) { case 0: // maleIva if (ivaVisorTexture != null) { smr.sharedMaterial.shader = TexturedVisorShader; smr.sharedMaterial.mainTexture = ivaVisorTexture; smr.sharedMaterial.color = Color.white; } break; case 1: // maleEva if (evaVisorTexture != null) { smr.sharedMaterial.shader = TexturedVisorShader; smr.sharedMaterial.mainTexture = evaVisorTexture; smr.sharedMaterial.color = Color.white; } break; case 2: // maleEvaVintage smr.sharedMaterial = visorMaterials[1]; break; } visorMaterials[i] = smr.sharedMaterial; break; } } } for (int i = 0; i < 3; ++i) { if (femaleMeshes[i] == null) { continue; } foreach (SkinnedMeshRenderer smr in femaleMeshes[i]) { // Here we must enumerate all meshes wherever we are replacing the material. switch (smr.name) { case "mesh_female_kerbalAstronaut01_kerbalGirl_mesh_eyeballLeft": smr.sharedMaterial.shader = EyeShader; smr.sharedMaterial.mainTexture = eyeballLeft; break; case "mesh_female_kerbalAstronaut01_kerbalGirl_mesh_eyeballRight": smr.sharedMaterial.shader = EyeShader; smr.sharedMaterial.mainTexture = eyeballRight; break; case "mesh_female_kerbalAstronaut01_kerbalGirl_mesh_pupilLeft": smr.sharedMaterial.shader = EyeShader; smr.sharedMaterial.mainTexture = pupilLeft; if (pupilLeft != null) { smr.sharedMaterial.color = Color.white; } break; case "mesh_female_kerbalAstronaut01_kerbalGirl_mesh_pupilRight": smr.sharedMaterial.shader = EyeShader; smr.sharedMaterial.mainTexture = pupilRight; if (pupilRight != null) { smr.sharedMaterial.color = Color.white; } break; case "mesh_female_kerbalAstronaut01_kerbalGirl_mesh_pCube1": case "mesh_female_kerbalAstronaut01_kerbalGirl_mesh_polySurface51": // Replace with bump-mapped shader so normal maps for heads will work. smr.sharedMaterial.shader = HeadShader; break; case "mesh_female_kerbalAstronaut01_kerbalGirl_mesh_upTeeth01": case "mesh_female_kerbalAstronaut01_kerbalGirl_mesh_downTeeth01": // Females don't have textured teeth, they use the same material as for the eyeballs. Extending female // head material/texture to their teeth is not possible since teeth overlap with some ponytail subtexture. // However, female teeth map to the same texture coordinates as male teeth, so we fix this by applying // male head & teeth material for female teeth. smr.sharedMaterial = headMaterial; break; case "visor": case "mesh_female_kerbalAstronaut01_visor": smr.sharedMaterial = visorMaterials[i]; break; } } } }
protected void processDeliveries() { if (!HighLogic.LoadedSceneIsFlight) { return; } //We're interested in resource and inventory deliveries... List <WBIResourceManifest> resourceManifests = WBIResourceManifest.GetManifestsForDestination(this.uniqueIdentifier); Log("Resource manifests count: " + resourceManifests.Count); //Distribute the resources throughout the vessel WBIResourceManifest resourceManifest; int totalManifests = resourceManifests.Count; string[] resourceKeys; string resourceName; double amount; for (int index = 0; index < totalManifests; index++) { //Get the manifest resourceManifest = resourceManifests[index]; //Go through all the resources and distribute them resourceKeys = resourceManifest.resourceAmounts.Keys.ToArray(); for (int keyIndex = 0; keyIndex < resourceKeys.Length; keyIndex++) { //Get the name resourceName = resourceKeys[keyIndex]; //Get the amount amount = resourceManifest.resourceAmounts[resourceName]; //Distribute the resource this.part.RequestResource(resourceName, -amount, ResourceFlowMode.ALL_VESSEL); Log("Added " + amount + " units of " + resourceName); } } //Deliver inventory items if (WBIKISWrapper.IsKISInstalled()) { //Get the inventory and available volume WBIKISInventoryWrapper inventory = WBIKISInventoryWrapper.GetInventory(this.part); List <WBIKISInventoryWrapper> inventories = WBIKISInventoryWrapper.GetInventories(this.part.vessel); int currentIndex = 0; float contentVolume = 0; float availableVolume = 0; //Grab the first available inventory if (inventory == null) { inventory = inventories[0]; if (inventory == null) { return; } } //Get available volume inventory.RefreshMassAndVolume(); contentVolume = inventory.GetContentVolume(); availableVolume = inventory.maxVolume - contentVolume; //Get all the manifests List <WBIKISInventoryManifest> inventoryManifests = WBIKISInventoryManifest.GetManifestsForDestination(this.uniqueIdentifier); Log("Inventory manifest count: " + inventoryManifests.Count); WBIKISInventoryManifest inventoryManifest; WBIInventoryManifestItem inventoryItem; totalManifests = inventoryManifests.Count; int totalItems; AvailablePart availablePart = null; int skippedItems = 0; for (int index = 0; index < totalManifests; index++) { //Get the manifest inventoryManifest = inventoryManifests[index]; //Get the total items in the manifest totalItems = inventoryManifest.inventoryItems.Count; for (int itemIndex = 0; itemIndex < totalItems; itemIndex++) { //Get the item inventoryItem = inventoryManifest.inventoryItems[itemIndex]; Log("Looking for enough room for " + inventoryItem.partName); //If the inventory has room, then add it. if (inventoryItem.volume < availableVolume) { Log("Current inventory has room."); //Decrease the available volume availableVolume -= inventoryItem.volume; //Get the part info availablePart = PartLoader.getPartInfoByName(inventoryItem.partName); //Add the part inventory.AddItem(availablePart, inventoryItem.partConfigNode, inventoryItem.quantity); Log("Added " + inventoryItem.partName); } //See if another inventory has room else { while (currentIndex < inventories.Count) { currentIndex += 1; inventory = inventories[currentIndex]; Log("New inventory found"); inventory.RefreshMassAndVolume(); contentVolume = inventory.GetContentVolume(); availableVolume = inventory.maxVolume - contentVolume; //If the inventory has room, then add it. if (inventoryItem.volume < availableVolume) { //Decrease the available volume availableVolume -= inventoryItem.volume; //Get the part info availablePart = PartLoader.getPartInfoByName(inventoryItem.partName); //Add the part inventory.AddItem(availablePart, inventoryItem.partConfigNode, inventoryItem.quantity); Log("Added " + inventoryItem.partName); break; } else { skippedItems += 1; } } } } } //Inform the player if we skipped some items if (skippedItems > 0) { ScreenMessages.PostScreenMessage(kItemSkippedMsg, kMessageDuration, ScreenMessageStyle.UPPER_CENTER); } } }
public override void OnUpdate() { base.OnUpdate(); MerillData.log(" research onUpdate " + part.name + " with info: " + part.partInfo); if (loaded && !change) { //evolve if we are researched (TODO: test when it's necessary to do this: only 1 time?) MerillData.log(" research onload " + part.name + " with info: " + part.partInfo); if (part.partInfo != null && ResearchAndDevelopment.PartTechAvailable(this.part.partInfo)) { MerillData.log(" research onload " + part.name + ", i'm researched for " + PartLoader.getPartInfoByName(initialPart)); AvailablePart partToEvolve = PartLoader.getPartInfoByName(initialPart); if (partToEvolve != null && partToEvolve.partPrefab != null) { evolve(partToEvolve); } } change = true; } }
// constructor /// <summary> Creates a <see cref="ConnectionInfo"/> object for the specified vessel from it's antenna modules</summary> public ConnectionInfo(Vessel v, bool powered, bool storm) { // set RemoteTech powered and storm state if (RemoteTech.Enabled) { RemoteTech.SetPoweredDown(v.id, !powered); RemoteTech.SetCommsBlackout(v.id, storm); } // return no connection if there is no ec left if (!powered) { // hysteresis delay if ((DB.Vessel(v).hyspos_signal >= 5.0)) { DB.Vessel(v).hyspos_signal = 5.0; DB.Vessel(v).hysneg_signal = 0.0; return; } DB.Vessel(v).hyspos_signal += 0.1; } else { // hysteresis delay DB.Vessel(v).hysneg_signal += 0.1; if (!(DB.Vessel(v).hysneg_signal >= 5.0)) { return; } DB.Vessel(v).hysneg_signal = 5.0; DB.Vessel(v).hyspos_signal = 0.0; } // CommNet or simple signal system if (!RemoteTech.Enabled) { List <ModuleDataTransmitter> transmitters; // if vessel is loaded if (v.loaded) { // find transmitters transmitters = v.FindPartModulesImplementing <ModuleDataTransmitter>(); if (transmitters != null) { foreach (ModuleDataTransmitter t in transmitters) { if (t.antennaType == AntennaType.INTERNAL) // do not include internal data rate, ec cost only { internal_cost += t.DataResourceCost * t.DataRate; } else { // do we have an animation ModuleDeployableAntenna animation = t.part.FindModuleImplementing <ModuleDeployableAntenna>(); if (animation != null) { // only include data rate and ec cost if transmitter is extended if (animation.deployState == ModuleDeployablePart.DeployState.EXTENDED) { rate += t.DataRate; external_cost += t.DataResourceCost * t.DataRate; } } // no animation else { rate += t.DataRate; external_cost += t.DataResourceCost * t.DataRate; } } } } } // if vessel is not loaded else { // find proto transmitters foreach (ProtoPartSnapshot p in v.protoVessel.protoPartSnapshots) { // get part prefab (required for module properties) Part part_prefab = PartLoader.getPartInfoByName(p.partName).partPrefab; transmitters = part_prefab.FindModulesImplementing <ModuleDataTransmitter>(); if (transmitters != null) { foreach (ModuleDataTransmitter t in transmitters) { if (t.antennaType == AntennaType.INTERNAL) // do not include internal data rate, ec cost only { internal_cost += t.DataResourceCost * t.DataRate; } else { // do we have an animation ProtoPartModuleSnapshot m = p.FindModule("ModuleDeployableAntenna"); if (m != null) { // only include data rate and ec cost if transmitter is extended string deployState = Lib.Proto.GetString(m, "deployState"); if (deployState == "EXTENDED") { rate += t.DataRate; external_cost += t.DataResourceCost * t.DataRate; } } // no animation else { rate += t.DataRate; external_cost += t.DataResourceCost * t.DataRate; } } } } } } // if CommNet is enabled if (HighLogic.fetch.currentGame.Parameters.Difficulty.EnableCommNet) { // are we connected to DSN if (v.connection != null) { if (v.connection.IsConnected) { linked = true; status = v.connection.ControlPath.First.hopType == CommNet.HopType.Home ? LinkStatus.direct_link : LinkStatus.indirect_link; strength = v.connection.SignalStrength; rate = rate * strength; target_name = Lib.Ellipsis(Localizer.Format(v.connection.ControlPath.First.end.displayName).Replace("Kerbin", "DSN"), 20); return; } // is loss of connection due to plasma blackout else if (Lib.ReflectionValue <bool>(v.connection, "inPlasma")) // calling InPlasma causes a StackOverflow :( { status = LinkStatus.plasma; rate = 0.0; internal_cost = 0.0; external_cost = 0.0; return; } } // no connection rate = 0.0; internal_cost = 0.0; external_cost = 0.0; return; } // the simple stupid always connected signal system linked = true; status = LinkStatus.direct_link; strength = 1; // 100 % target_name = "DSN: KSC"; return; } // RemoteTech signal system else { // if vessel is loaded if (v.loaded) { // find transmitters foreach (Part p in v.parts) { foreach (PartModule m in p.Modules) { // calculate internal (passive) transmitter ec usage @ 0.5W each if (m.moduleName == "ModuleRTAntennaPassive") { internal_cost += 0.0005; } // calculate external transmitters else if (m.moduleName == "ModuleRTAntenna") { // only include data rate and ec cost if transmitter is active if (Lib.ReflectionValue <bool>(m, "IsRTActive")) { rate += (Lib.ReflectionValue <float>(m, "RTPacketSize") / Lib.ReflectionValue <float>(m, "RTPacketInterval")); external_cost += m.resHandler.inputResources.Find(r => r.name == "ElectricCharge").rate; } } } } } // if vessel is not loaded else { // find proto transmitters foreach (ProtoPartSnapshot p in v.protoVessel.protoPartSnapshots) { // get part prefab (required for module properties) Part part_prefab = PartLoader.getPartInfoByName(p.partName).partPrefab; int index = 0; // module index foreach (ProtoPartModuleSnapshot m in p.modules) { // calculate internal (passive) transmitter ec usage @ 0.5W each if (m.moduleName == "ModuleRTAntennaPassive") { internal_cost += 0.0005; } // calculate external transmitters else if (m.moduleName == "ModuleRTAntenna") { // only include data rate and ec cost if transmitter is active skip if index is out of range if (Lib.Proto.GetBool(m, "IsRTActive") && index < part_prefab.Modules.Count) { // get module prefab PartModule pm = part_prefab.Modules.GetModule(index); if (pm != null) { rate += (Lib.ReflectionValue <float>(pm, "RTPacketSize") / Lib.ReflectionValue <float>(pm, "RTPacketInterval")); external_cost += pm.resHandler.inputResources.Find(r => r.name == "ElectricCharge").rate; } else { Lib.DebugLog(String.Format("ConnectionInfo: Could not find PartModule ModuleRTAntenna for part {0} on unloaded vessel {1}, using default values as a workaround", p.partName, v.vesselName)); rate += 6.6666; // 6.67 Mb/s external_cost += 0.025; // 25 W/s } } } index++; } } } // are we connected if (RemoteTech.Connected(v.id)) { linked = RemoteTech.ConnectedToKSC(v.id); status = RemoteTech.TargetsKSC(v.id) ? LinkStatus.direct_link : LinkStatus.indirect_link; strength = RemoteTech.GetSignalDelay(v.id); target_name = status == LinkStatus.direct_link ? Lib.Ellipsis("DSN: " + (RemoteTech.NameTargetsKSC(v.id) ?? ""), 20): Lib.Ellipsis(RemoteTech.NameFirstHopToKSC(v.id) ?? "", 20); return; } // is loss of connection due to a blackout else if (RemoteTech.GetCommsBlackout(v.id)) { status = storm ? LinkStatus.storm : LinkStatus.plasma; rate = 0.0; internal_cost = 0.0; external_cost = 0.0; return; } // no connection rate = 0.0; internal_cost = 0.0; external_cost = 0.0; return; } }
private void refreshExperimentalParts(GameEvents.HostTargetAction <RDTech, RDTech.OperationResult> data) { if (data.host.partsPurchased.Contains(part.partInfo)) { MerillData.log(" research done, and " + part.name + " is going to make an evolve on " + PartLoader.getPartInfoByName(initialPart)); AvailablePart partToEvolve = PartLoader.getPartInfoByName(initialPart); if (partToEvolve != null && partToEvolve.partPrefab != null) { evolve(partToEvolve); } } }
public override void OnStart(StartState state) { #if DEBUG print("========ModuleFuelTanks.OnStart( State == " + state.ToString() + ")======="); #endif if (basemass == 0 && part != null) { basemass = part.mass; } if (fuelList == null) { fuelList = new List <ModuleFuelTanks.FuelTank> (); } if (fuelList.Count == 0) { // when we get called from the editor, the fuelList won't be populated // because OnLoad() was never called. This is a hack to fix that. Part prefab = part.symmetryCounterparts.Find(pf => pf.Modules.Contains("ModuleFuelTanks") && ((ModuleFuelTanks)pf.Modules["ModuleFuelTanks"]).fuelList.Count > 0); if (prefab) { #if DEBUG print("ModuleFuelTanks.OnStart: copying from a symmetryCounterpart with a ModuleFuelTanks PartModule"); #endif } else { AvailablePart partData = PartLoader.getPartInfoByName(part.partInfo.name); if (partData == null) { print("ModuleFuelTanks.OnStart could not find AvailablePart for " + part.partInfo.name); } else if (partData.partPrefab == null) { print("ModuleFuelTanks.OnStart: AvailablePart.partPrefab is null."); } else { prefab = partData.partPrefab; if (!prefab.Modules.Contains("ModuleFuelTanks")) { print("ModuleFuelTanks.OnStart: AvailablePart.partPrefab does not contain a ModuleFuelTanks."); prefab = null; } } } if (prefab) { ModuleFuelTanks pModule = (ModuleFuelTanks)prefab.Modules["ModuleFuelTanks"]; if (pModule == this) { print("ModuleFuelTanks.OnStart: Copying from myself won't do any good."); } else { ConfigNode node = new ConfigNode("MODULE"); pModule.OnSave(node); #if DEBUG print("ModuleFuelTanks.OnStart node from prefab:" + node); #endif this.OnLoad(node); } } } foreach (FuelTank tank in fuelList) { tank.module = this; } if (radius > 0 && length > 0) { part.transform.localScale = new Vector3(rscale / radius, length, rscale / radius); foreach (AttachNode n in part.attachNodes) { if (n.nodeType == AttachNode.NodeType.Stack) { n.offset.y *= length; } } } part.mass = basemass + tank_mass; if (HighLogic.LoadedSceneIsEditor) { UpdateSymmetryCounterparts(); // if we detach and then re-attach a configured tank with symmetry on, make sure the copies are configured. } }
internal void Spawn() { KD kd = new KD(); Log.Info("Spawning a GeoCache"); // Set additional info for landed if (kd.landed) { Vector3d pos = kd.body.GetWorldSurfacePosition(kd.latitude, kd.longitude, kd.altitude); kd.orbit = new Orbit(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, kd.body); kd.orbit.UpdateFromStateVectors(pos, kd.body.getRFrmVel(pos), kd.body, Planetarium.GetUniversalTime()); } else { // Update the reference body in the orbit kd.orbit.referenceBody = kd.body; } uint flightId = ShipConstruction.GetUniqueFlightID(HighLogic.CurrentGame.flightState); kd.craftPart = PartLoader.getPartInfoByName("geocache"); // Create part nodes ConfigNode[] partNodes = new ConfigNode[1]; partNodes[0] = ProtoVessel.CreatePartNode(kd.craftPart.name, flightId, null); // Create additional nodes ConfigNode[] additionalNodes = new ConfigNode[0]; // Create the config node representation of the ProtoVessel ConfigNode protoVesselNode = ProtoVessel.CreateVesselNode(VesselName, VesselType.Probe, kd.orbit, 0, partNodes); // Additional seetings for a landed vessel if (kd.landed) { bool splashed = kd.altitude < 0.001 && kd.body.ocean; // Add a bit of height for landed if (!splashed) { kd.altitude += 40.2; Log.Info("Adding 40.2 to altitude"); } //Guid vesselId = vessel.id; // Figure out the appropriate rotation Vector3d norm = kd.body.GetRelSurfaceNVector(kd.latitude, kd.longitude); double terrainHeight = 0.0; if (kd.body.pqsController != null) { terrainHeight = kd.body.pqsController.GetSurfaceHeight(norm) - kd.body.pqsController.radius; } // Create the config node representation of the ProtoVessel protoVesselNode.SetValue("sit", (splashed ? Vessel.Situations.SPLASHED : Vessel.Situations.LANDED).ToString()); protoVesselNode.SetValue("landed", (!splashed).ToString()); protoVesselNode.SetValue("splashed", splashed.ToString()); protoVesselNode.SetValue("lat", kd.latitude); protoVesselNode.SetValue("lon", kd.longitude); protoVesselNode.SetValue("alt", kd.altitude); protoVesselNode.SetValue("landedAt", kd.body.name); float lowest = float.MaxValue; foreach (Collider collider in kd.craftPart.partPrefab.GetComponentsInChildren <Collider>()) { if (collider.gameObject.layer != 21 && collider.enabled) { lowest = Mathf.Min(lowest, collider.bounds.min.y); } } if (Mathf.Approximately(lowest, float.MaxValue)) { lowest = 0; } float hgt = kd.craftPart.partPrefab.localRoot.attPos0.y - lowest; hgt += 10; protoVesselNode.SetValue("hgt", hgt); // Set the normal vector relative to the surface Quaternion normal = Quaternion.LookRotation(new Vector3((float)norm.x, (float)norm.y, (float)norm.z)); Quaternion rotation = Quaternion.identity; rotation = rotation * Quaternion.FromToRotation(Vector3.up, Vector3.back); Vector3 nrm = (rotation * Vector3.forward); protoVesselNode.SetValue("prst", false.ToString()); protoVesselNode.SetValue("nrm", nrm.x + "," + nrm.y + "," + nrm.z); } ProtoVessel protoVessel = HighLogic.CurrentGame.AddVessel(protoVesselNode); //protoVessel.Load(HighLogic.CurrentGame.flightState); protoVessel.vesselName = VesselName; vessel = protoVessel.vesselRef; if (vessel != null) { //var mode = OrbitDriver.UpdateMode.UPDATE; //vessel.orbitDriver.SetOrbitMode(mode); vessel.Load(); launchPoint = vessel.GetWorldPos3D(); // Offset the position by 10m in y and z to have it created away from the current vessel launchPoint.y += 10; launchPoint.z += 10; StartCoroutine("SpawnCoRoutine"); } }
// called at every simulation step public void FixedUpdate() { // do nothing if paused if (Lib.IsPaused()) return; // do nothing if DB isn't ready if (!DB.Ready()) return; // for each vessel foreach(Vessel vessel in FlightGlobals.Vessels) { // skip invalid vessels if (!Lib.IsVessel(vessel)) continue; // skip loaded vessels if (vessel.loaded) continue; // get vessel data from the db vessel_data vd = DB.VesselData(vessel.id); // get vessel info from the cache vessel_info info = Cache.VesselInfo(vessel); // calculate atmospheric factor (proportion of flux not blocked by atmosphere) double atmo_factor = Sim.AtmosphereFactor(vessel.mainBody, info.position, info.sun_dir); // for each part foreach(ProtoPartSnapshot part in vessel.protoVessel.protoPartSnapshots) { // get part prefab (required for module properties) Part part_prefab = PartLoader.getPartInfoByName(part.partName).partPrefab; // store index of ModuleResourceConverter to process // rationale: a part can contain multiple resource converters int converter_index = 0; // for each module foreach(ProtoPartModuleSnapshot module in part.modules) { // something weird is going on, skip this if (!part_prefab.Modules.Contains(module.moduleName)) continue; // command module if (module.moduleName == "ModuleCommand") { // get module from prefab ModuleCommand command = part_prefab.Modules.GetModules<ModuleCommand>()[0]; // do not consume if this is a MCM with no crew // rationale: for consistency, the game doesn't consume resources for MCM without crew in loaded vessels // this make some sense: you left a vessel with some battery and nobody on board, you expect it to not consume EC if (command.minimumCrew == 0 || part.protoModuleCrew.Count > 0) { // for each input resource foreach(ModuleResource ir in command.inputResources) { // consume the resource Lib.RequestResource(vessel, ir.name, ir.rate * TimeWarp.fixedDeltaTime); } } } // solar panel else if (module.moduleName == "ModuleDeployableSolarPanel") { // determine if extended bool extended = module.moduleValues.GetValue("stateString") == ModuleDeployableSolarPanel.panelStates.EXTENDED.ToString(); // if in sunlight and extended if (info.sunlight && extended) { // get module from prefab ModuleDeployableSolarPanel panel = part_prefab.Modules.GetModules<ModuleDeployableSolarPanel>()[0]; // produce electric charge Lib.RequestResource(vessel, "ElectricCharge", -PanelOutput(vessel, part, panel, info.sun_dir, info.sun_dist, atmo_factor) * TimeWarp.fixedDeltaTime * Malfunction.Penalty(part)); } } // generator // note: assume generators require all input else if (module.moduleName == "ModuleGenerator") { // determine if active bool activated = Convert.ToBoolean(module.moduleValues.GetValue("generatorIsActive")); // if active if (activated) { // get module from prefab ModuleGenerator generator = part_prefab.Modules.GetModules<ModuleGenerator>()[0]; // determine if vessel is full of all output resources bool full = true; foreach(var or in generator.outputList) { double amount = Lib.GetResourceAmount(vessel, or.name); double capacity = Lib.GetResourceCapacity(vessel, or.name); double perc = capacity > 0.0 ? amount / capacity : 0.0; full &= (perc >= 1.0 - double.Epsilon); } // if not full if (!full) { // calculate worst required resource percentual double worst_input = 1.0; foreach(var ir in generator.inputList) { double required = ir.rate * TimeWarp.fixedDeltaTime; double amount = Lib.GetResourceAmount(vessel, ir.name); worst_input = Math.Min(worst_input, amount / required); } // for each input resource foreach(var ir in generator.inputList) { // consume the resource Lib.RequestResource(vessel, ir.name, ir.rate * worst_input * TimeWarp.fixedDeltaTime); } // for each output resource foreach(var or in generator.outputList) { // produce the resource Lib.RequestResource(vessel, or.name, -or.rate * worst_input * TimeWarp.fixedDeltaTime * Malfunction.Penalty(part)); } } } } // converter // note: support multiple resource converters // note: ignore stock temperature mechanic of converters // note: ignore autoshutdown // note: ignore crew experience bonus (seem that stock ignore it too) // note: 'undo' stock behaviour by forcing lastUpdateTime to now (to minimize overlapping calculations from this and stock post-facto simulation) // note: support PlanetaryBaseSystem converters // note: support NearFuture reactors else if (module.moduleName == "ModuleResourceConverter" || module.moduleName == "ModuleKPBSConverter" || module.moduleName == "FissionReactor") { // get module from prefab ModuleResourceConverter converter = part_prefab.Modules.GetModules<ModuleResourceConverter>()[converter_index++]; // determine if active bool activated = Convert.ToBoolean(module.moduleValues.GetValue("IsActivated")); // if active if (activated) { // determine if vessel is full of all output resources bool full = true; foreach(var or in converter.outputList) { double amount = Lib.GetResourceAmount(vessel, or.ResourceName); double capacity = Lib.GetResourceCapacity(vessel, or.ResourceName); double perc = capacity > 0.0 ? amount / capacity : 0.0; full &= (perc >= converter.FillAmount - double.Epsilon); } // if not full if (!full) { // calculate worst required resource percentual double worst_input = 1.0; foreach(var ir in converter.inputList) { double required = ir.Ratio * TimeWarp.fixedDeltaTime; double amount = Lib.GetResourceAmount(vessel, ir.ResourceName); worst_input = Math.Min(worst_input, amount / required); } // for each input resource foreach(var ir in converter.inputList) { // consume the resource Lib.RequestResource(vessel, ir.ResourceName, ir.Ratio * worst_input * TimeWarp.fixedDeltaTime); } // for each output resource foreach(var or in converter.outputList) { // produce the resource Lib.RequestResource(vessel, or.ResourceName, -or.Ratio * worst_input * TimeWarp.fixedDeltaTime * Malfunction.Penalty(part)); } } // undo stock behaviour by forcing last_update_time to now module.moduleValues.SetValue("lastUpdateTime", Planetarium.GetUniversalTime().ToString()); } } // drill // note: ignore stock temperature mechanic of harvesters // note: ignore autoshutdown // note: ignore depletion (stock seem to do the same) // note: 'undo' stock behaviour by forcing lastUpdateTime to now (to minimize overlapping calculations from this and stock post-facto simulation) else if (module.moduleName == "ModuleResourceHarvester") { // determine if active bool activated = Convert.ToBoolean(module.moduleValues.GetValue("IsActivated")); // if active if (activated) { // get module from prefab ModuleResourceHarvester harvester = part_prefab.Modules.GetModules<ModuleResourceHarvester>()[0]; // [disabled] reason: not working // deduce crew bonus /*double experience_bonus = 0.0; if (harvester.UseSpecialistBonus) { foreach(ProtoCrewMember c in vessel.protoVessel.GetVesselCrew()) { experience_bonus = Math.Max(experience_bonus, (c.trait == harvester.Specialty) ? (double)c.experienceLevel : 0.0); } }*/ const double crew_bonus = 1.0; //harvester.SpecialistBonusBase + (experience_bonus + 1.0) * harvester.SpecialistEfficiencyFactor; // detect amount of ore in the ground AbundanceRequest request = new AbundanceRequest { Altitude = vessel.altitude, BodyId = vessel.mainBody.flightGlobalsIndex, CheckForLock = false, Latitude = vessel.latitude, Longitude = vessel.longitude, ResourceType = (HarvestTypes)harvester.HarvesterType, ResourceName = harvester.ResourceName }; double abundance = ResourceMap.Instance.GetAbundance(request); // if there is actually something (should be if active when unloaded) if (abundance > harvester.HarvestThreshold) { // calculate worst required resource percentual double worst_input = 1.0; foreach(var ir in harvester.inputList) { double required = ir.Ratio * TimeWarp.fixedDeltaTime; double amount = Lib.GetResourceAmount(vessel, ir.ResourceName); worst_input = Math.Min(worst_input, amount / required); } // for each input resource foreach(var ir in harvester.inputList) { // consume the resource Lib.RequestResource(vessel, ir.ResourceName, ir.Ratio * worst_input * TimeWarp.fixedDeltaTime); } // determine resource produced double res = abundance * harvester.Efficiency * crew_bonus * worst_input * Malfunction.Penalty(part); // accumulate ore Lib.RequestResource(vessel, harvester.ResourceName, -res * TimeWarp.fixedDeltaTime); } // undo stock behaviour by forcing last_update_time to now module.moduleValues.SetValue("lastUpdateTime", Planetarium.GetUniversalTime().ToString()); } } // asteroid drill // note: untested // note: ignore stock temperature mechanic of asteroid drills // note: ignore autoshutdown // note: 'undo' stock behaviour by forcing lastUpdateTime to now (to minimize overlapping calculations from this and stock post-facto simulation) else if (module.moduleName == "ModuleAsteroidDrill") { // determine if active bool activated = Convert.ToBoolean(module.moduleValues.GetValue("IsActivated")); // if active if (activated) { // get module from prefab ModuleAsteroidDrill asteroid_drill = part_prefab.Modules.GetModules<ModuleAsteroidDrill>()[0]; // [disabled] reason: not working // deduce crew bonus /*double experience_bonus = 0.0; if (asteroid_drill.UseSpecialistBonus) { foreach(ProtoCrewMember c in vessel.protoVessel.GetVesselCrew()) { experience_bonus = Math.Max(experience_bonus, (c.trait == asteroid_drill.Specialty) ? (double)c.experienceLevel : 0.0); } }*/ const double crew_bonus = 1.0; //asteroid_drill.SpecialistBonusBase + (experience_bonus + 1.0) * asteroid_drill.SpecialistEfficiencyFactor; // get asteroid data ProtoPartModuleSnapshot asteroid_info = null; ProtoPartModuleSnapshot asteroid_resource = null; foreach(ProtoPartSnapshot p in vessel.protoVessel.protoPartSnapshots) { if (asteroid_info == null) asteroid_info = p.modules.Find(k => k.moduleName == "ModuleAsteroidInfo"); if (asteroid_resource == null) asteroid_resource = p.modules.Find(k => k.moduleName == "ModuleAsteroidResource"); } // if there is actually an asteroid attached to this active asteroid drill (it should) if (asteroid_info != null && asteroid_resource != null) { // get some data double mass_threshold = Convert.ToDouble(asteroid_info.moduleValues.GetValue("massThresholdVal")); double mass = Convert.ToDouble(asteroid_info.moduleValues.GetValue("currentMassVal")); double abundance = Convert.ToDouble(asteroid_resource.moduleValues.GetValue("abundance")); string res_name = asteroid_resource.moduleValues.GetValue("resourceName"); double res_density = PartResourceLibrary.Instance.GetDefinition(res_name).density; // if asteroid isn't depleted if (mass > mass_threshold && abundance > double.Epsilon) { // consume EC double ec_required = asteroid_drill.PowerConsumption * TimeWarp.fixedDeltaTime; double ec_consumed = Lib.RequestResource(vessel, "ElectricCharge", ec_required); double ec_ratio = ec_consumed / ec_required; // determine resource extracted double res_amount = abundance * asteroid_drill.Efficiency * crew_bonus * ec_ratio * TimeWarp.fixedDeltaTime; // produce mined resource Lib.RequestResource(vessel, res_name, -res_amount); // consume asteroid mass asteroid_info.moduleValues.SetValue("currentMassVal", (mass - res_density * res_amount).ToString()); } } // undo stock behaviour by forcing last_update_time to now module.moduleValues.SetValue("lastUpdateTime", Planetarium.GetUniversalTime().ToString()); } } // science lab // note: we are only simulating the EC consumption // note: there is no easy way to 'stop' the lab when there isn't enough EC else if (module.moduleName == "ModuleScienceConverter") { // get module from prefab ModuleScienceConverter lab = part_prefab.Modules.GetModules<ModuleScienceConverter>()[0]; // determine if active bool activated = Convert.ToBoolean(module.moduleValues.GetValue("IsActivated")); // if active if (activated) { Lib.RequestResource(vessel, "ElectricCharge", lab.powerRequirement * TimeWarp.fixedDeltaTime); } } // SCANSAT support else if (module.moduleName == "SCANsat" || module.moduleName == "ModuleSCANresourceScanner") { // get ec consumption rate PartModule scansat = part_prefab.Modules[module.moduleName]; double power = Lib.ReflectionValue<float>(scansat, "power"); double ec_required = power * TimeWarp.fixedDeltaTime; bool is_scanning = Lib.GetProtoValue<bool>(module, "scanning"); bool was_disabled = vd.scansat_id.Contains(part.flightID); // if its scanning if (Lib.GetProtoValue<bool>(module, "scanning")) { // consume ec double ec_consumed = Lib.RequestResource(vessel, "ElectricCharge", ec_required); // if there isn't enough ec if (ec_consumed < ec_required * 0.99 && ec_required > double.Epsilon) { // unregister scanner SCANsat.stopScanner(vessel, module, part_prefab); // remember disabled scanner vd.scansat_id.Add(part.flightID); // give the user some feedback if (DB.VesselData(vessel.id).cfg_ec == 1) Message.Post("SCANsat sensor was disabled on <b>" + vessel.vesselName + "</b>"); } } // if it was disabled else if (vd.scansat_id.Contains(part.flightID)) { // if there is enough ec double ec_amount = Lib.GetResourceAmount(vessel, "ElectricCharge"); double ec_capacity = Lib.GetResourceCapacity(vessel, "ElectricCharge"); if (ec_capacity > double.Epsilon && ec_amount / ec_capacity > 0.25) //< re-enable at 25% EC { // re-enable the scanner SCANsat.resumeScanner(vessel, module, part_prefab); // give the user some feedback if (DB.VesselData(vessel.id).cfg_ec == 1) Message.Post("SCANsat sensor resumed operations on <b>" + vessel.vesselName + "</b>"); } } // forget active scanners if (Lib.GetProtoValue<bool>(module, "scanning")) vd.scansat_id.Remove(part.flightID); } // NearFutureSolar support // note: we assume deployed, this is a current limitation else if (module.moduleName == "ModuleCurvedSolarPanel") { // if in sunlight if (info.sunlight) { PartModule curved_panel = part_prefab.Modules[module.moduleName]; double output = CurvedPanelOutput(vessel, part, part_prefab, curved_panel, info.sun_dir, info.sun_dist, atmo_factor) * Malfunction.Penalty(part); Lib.RequestResource(vessel, "ElectricCharge", -output * TimeWarp.fixedDeltaTime); } } // NearFutureElectrical support // note: fission generator ignore heat // note: radioisotope generator doesn't support easy mode else if (module.moduleName == "FissionGenerator") { PartModule generator = part_prefab.Modules[module.moduleName]; double power = Lib.ReflectionValue<float>(generator, "PowerGeneration"); // get fission reactor tweakable, will default to 1.0 for other modules var reactor = part.modules.Find(k => k.moduleName == "FissionReactor"); double tweakable = reactor == null ? 1.0 : Lib.ConfigValue(reactor.moduleValues, "CurrentPowerPercent", 100.0) * 0.01; Lib.RequestResource(vessel, "ElectricCharge", -power * tweakable * TimeWarp.fixedDeltaTime); } else if (module.moduleName == "ModuleRadioisotopeGenerator") { double mission_time = vessel.missionTime / (3600.0 * Lib.HoursInDay() * Lib.DaysInYear()); PartModule generator = part_prefab.Modules[module.moduleName]; double half_life = Lib.ReflectionValue<float>(generator, "HalfLife"); double remaining = Math.Pow(2.0, (-mission_time) / half_life); double power = Lib.ReflectionValue<float>(generator, "BasePower"); Lib.RequestResource(vessel, "ElectricCharge", -power * remaining * TimeWarp.fixedDeltaTime); } // KERBALISM modules else if (module.moduleName == "Scrubber") { Scrubber.BackgroundUpdate(vessel, part.flightID); } else if (module.moduleName == "Greenhouse") { Greenhouse.BackgroundUpdate(vessel, part.flightID); } else if (module.moduleName == "GravityRing") { GravityRing.BackgroundUpdate(vessel, part.flightID); } else if (module.moduleName == "Malfunction") { Malfunction.BackgroundUpdate(vessel, part.flightID); } } } } }
public static void DrawVessel(Vessel shipToDraw) { if (!vesselIsBuilt[shipToDraw]) { if (DistantObjectSettings.debugMode) { print("DistObj: Drawing vessel " + shipToDraw.vesselName); } vesselIsBuilt[shipToDraw] = true; List <ProtoPartSnapshot> partList = shipToDraw.protoVessel.protoPartSnapshots; foreach (ProtoPartSnapshot a in partList) { string partName; if (a.refTransformName.Contains(" ")) { partName = a.partName.Substring(0, a.refTransformName.IndexOf(" ")); } else { partName = a.partName; } AvailablePart avPart = PartLoader.getPartInfoByName(partName); if (a.modules.Find(n => n.moduleName == "LaunchClamp") != null) { if (DistantObjectSettings.debugMode) { print("Ignoring part " + partName); } continue; } if (!partModelNameLookup.ContainsKey(partName)) { partName = partName.Replace('.', '_'); if (!partModelNameLookup.ContainsKey(partName)) { if (DistantObjectSettings.debugMode) { print("DistObj ERROR: Could not find config definition for " + partName); } continue; } } GameObject clone = GameDatabase.Instance.GetModel(partModelNameLookup[partName]); if (clone == null) { if (DistantObjectSettings.debugMode) { print("DistObj ERROR: Could not load part model " + partModelNameLookup[partName]); } continue; } GameObject cloneMesh = Mesh.Instantiate(clone) as GameObject; clone.DestroyGameObject(); cloneMesh.transform.SetParent(shipToDraw.transform); cloneMesh.transform.localPosition = a.position; cloneMesh.transform.localRotation = a.rotation; VesselRanges.Situation situation = shipToDraw.vesselRanges.GetSituationRanges(shipToDraw.situation); if (Vector3d.Distance(cloneMesh.transform.position, FlightGlobals.ship_position) < situation.load) { Debug.LogError(Constants.DistantObject + " -- Tried to draw part " + partName + " within rendering distance of active vessel!"); continue; } cloneMesh.SetActive(true); foreach (Collider col in cloneMesh.GetComponentsInChildren <Collider>()) { col.enabled = false; } //check if part is a solar panel ProtoPartModuleSnapshot solarPanel = a.modules.Find(n => n.moduleName == "ModuleDeployableSolarPanel"); if (solarPanel != null) { if (solarPanel.moduleValues.GetValue("stateString") == "EXTENDED") { //grab the animation name specified in the part cfg string animName = avPart.partPrefab.GetComponent <ModuleDeployableSolarPanel>().animationName; //grab the actual animation istelf var animator = avPart.partPrefab.FindModelAnimators(); if (animator != null && animator.Length > 0) { AnimationClip animClip = animator[0].GetClip(animName); //grab the animation control module on the actual drawn model Animation anim = cloneMesh.GetComponentInChildren <Animation>(); //copy the animation over to the new part! anim.AddClip(animClip, animName); anim[animName].enabled = true; anim[animName].normalizedTime = 1f; } } } //check if part is a light ProtoPartModuleSnapshot light = a.modules.Find(n => n.moduleName == "ModuleLight"); if (light != null) { //Oddly enough the light already renders no matter what, so we'll kill the module if it's suppsed to be turned off if (light.moduleValues.GetValue("isOn") == "False") { Destroy(cloneMesh.GetComponentInChildren <Light>()); } } //check if part is a landing gear ProtoPartModuleSnapshot landingGear = a.modules.Find(n => n.moduleName == "ModuleWheelDeployment"); if (landingGear != null) { // MOARdV TODO: This wasn't really right to start with. // There is no field "savedAnimationTime". //if (landingGear.moduleValues.GetValue("savedAnimationTime") != "0") { //grab the animation name specified in the part cfg string animName = avPart.partPrefab.GetComponent <ModuleWheels.ModuleWheelDeployment>().animationStateName; var animator = avPart.partPrefab.FindModelAnimators(); if (animator != null && animator.Length > 0) { //grab the actual animation istelf AnimationClip animClip = animator[0].GetClip(animName); //grab the animation control module on the actual drawn model Animation anim = cloneMesh.GetComponentInChildren <Animation>(); //copy the animation over to the new part! anim.AddClip(animClip, animName); anim[animName].enabled = true; anim[animName].normalizedTime = 1f; } } } //check if part has a generic animation ProtoPartModuleSnapshot animGeneric = a.modules.Find(n => n.moduleName == "ModuleAnimateGeneric"); if (animGeneric != null) { if (animGeneric.moduleValues.GetValue("animTime") != "0") { //grab the animation name specified in the part cfg string animName = avPart.partPrefab.GetComponent <ModuleAnimateGeneric>().animationName; var animator = avPart.partPrefab.FindModelAnimators(); if (animator != null && animator.Length > 0) { //grab the actual animation istelf AnimationClip animClip = animator[0].GetClip(animName); //grab the animation control module on the actual drawn model Animation anim = cloneMesh.GetComponentInChildren <Animation>(); //copy the animation over to the new part! anim.AddClip(animClip, animName); anim[animName].enabled = true; anim[animName].normalizedTime = 1f; } } } referencePart.Add(cloneMesh, a); meshListLookup[shipToDraw].Add(cloneMesh); } } }
public IEnumerator pruning() { permapruneInProgress = true; Log.Info("PermaPrune.pruner"); renamedFilesList = FileOperations.Instance.loadRenamedFiles(); Log.Info("sizeof renamedFilesList: " + renamedFilesList.Count.ToString()); Log.Info("pruner, sizeof blacklist:" + JanitorsCloset.blackList.Count.ToString()); ShowRenamed.Instance.Show(); List <string> prunedParts = new List <string>(); foreach (blackListPart blp in JanitorsCloset.blackList.Values) { yield return(0); Log.Info("permapruneInProgress: " + permapruneInProgress.ToString()); if (!permapruneInProgress) { break; } if (blp.where != blackListType.ALL || blp.permapruned) { continue; } Log.Info("pruned part: " + blp.modName); //AvailablePart part = PartLoader.Instance.parts.Find(item => item.name.Equals(blp.modName)); AvailablePart part = PartLoader.getPartInfoByName(blp.modName); if (part == null) { continue; } prunedParts.Add(blp.modName); // Rename cfg file string s1 = part.configFileFullName.Substring(part.configFileFullName.IndexOf("GameData") + 9); RenameFile(s1, part.name); string partPath = part.partUrl; for (int x = 0; x < 1; x++) { int backslash = partPath.LastIndexOf('\\'); int slash = partPath.LastIndexOf('/'); int i = Math.Max(backslash, slash); partPath = partPath.Substring(0, i); } partPath += "/"; // rename resource file // Look for model = // model has complete path // Look for mesh = // with mesh, get patch from cfg file path Log.Info("searching for model"); Log.Info("Part: " + part.name); ConfigNode[] nodes = part.partConfig.GetNodes("MODEL"); ConfigNode[] nodes2; bool b; #if true if (nodes != null) { Log.Info("Nodes count: " + nodes.Length.ToString()); foreach (ConfigNode modelNode in nodes) { b = false; if (modelNode != null) { Log.Info("modelNode: " + modelNode.name); string model = GetModelURL(part, modelNode); Log.Info("ModelUrl: " + GetModelURL(part, modelNode)); if (model != null) { Log.Info("model: " + model); // Make sure it isn't being used in another part b = false; Log.Info("Part count: " + PartLoader.LoadedPartsList.Count.ToString()); string s; foreach (AvailablePart pSearch in PartLoader.LoadedPartsList) { Log.Info("pSearch: " + pSearch.name); if (part != pSearch && pSearch.partConfig != null) { nodes2 = pSearch.partConfig.GetNodes("MODEL"); if (nodes2 != null) { Log.Info("nodes2"); foreach (ConfigNode searchNode in nodes2) { if (searchNode != null) { Log.Info("searchNode"); if (model == GetModelURL(pSearch, searchNode)) { b = true; break; } } } } s = GetMeshURL(pSearch); Log.Info("Mesh URL: " + GetMeshURL(pSearch) + " ModelUrl: " + GetModelURL(part, modelNode)); if (GetMeshURL(pSearch) == model) { b = true; break; } } if (b) { break; } } } if (!b) { Log.Info("MODEL: " + model); string mURL = FindTexturePathFromModel.getModelURL(model); Log.Info("MODEL URL: " + mURL); model = model + ".mu"; RenameFile(model, part.name); } } } } #endif yield return(0); if (!permapruneInProgress) { break; } Log.Info("searching for meshes"); string mesh = GetMeshURL(part); if (mesh != null && mesh != "") { // Make sure it isn't being used in another part b = false; foreach (AvailablePart pSearch in PartLoader.LoadedPartsList) { if (part != pSearch) { string searchMesh = GetMeshURL(pSearch); if (searchMesh == mesh) { b = true; break; } if (pSearch.partConfig != null) { nodes2 = pSearch.partConfig.GetNodes("MODEL"); if (nodes2 != null) { foreach (ConfigNode searchNode in nodes2) { if (searchNode != null) { string model = GetModelURL(pSearch, searchNode); if (mesh == model) { b = true; break; } } } } } } } if (!b) { Log.Info("Renaming mesh: " + mesh + " partPath: " + partPath); string mURL = FindTexturePathFromModel.getModelURL(mesh); partPath = partPath.Substring(0, partPath.LastIndexOf("/")) + "/"; if (!(mesh.Contains("/") || mesh.Contains("\\"))) { mesh = partPath + mesh; } RenameFile(mesh, part.name); } } // this gets the model Log.Info("searching for model (INTERNAL)"); nodes = part.partConfig.GetNodes("INTERNAL"); if (nodes != null) { foreach (ConfigNode internalNode in nodes) { if (internalNode != null) { UrlDir.UrlConfig config; if (GetInternalSpaceConfigUrl.FindInternalSpaceConfigByName(internalNode.GetValue("name"), out config)) { // Make sure it isn't being used in another part b = false; foreach (AvailablePart pSearch in PartLoader.Instance.parts) { if (part != pSearch) { nodes2 = part.partConfig.GetNodes("INTERNAL"); if (nodes2 != null) { foreach (ConfigNode internalNodeSearch in nodes2) { UrlDir.UrlConfig configSearch; if (GetInternalSpaceConfigUrl.FindInternalSpaceConfigByName(internalNode.GetValue("name"), out configSearch)) { if (configSearch.url == config.url) { b = true; break; } } if (b) { break; } } } } if (b) { break; } } if (!b) { string s = config.url.Substring(0, config.url.LastIndexOf("/")) + ".cfg"; RenameFile(s, part.name); } } // // We aren't going to check to see if the different models inside the space are // used elsewhere. An assumption that the same model won't be used by multiple spaces // Log.Info("searching for internal space nodes"); ConfigNode cfgNode; bool b1 = GetInternalSpaceConfigUrl.FindInternalSpaceConfigNode(config.name, out cfgNode); if (b1) { nodes = cfgNode.GetNodes("MODEL"); if (nodes != null) { foreach (ConfigNode modelNode in nodes) { string model = modelNode.GetValue("model"); //Log.Info("MODEL: " + model); string mURL = FindTexturePathFromModel.getModelURL(model); // Log.Info("MODEL URL: " + mURL); model = model + ".mu"; RenameFile(model, part.name); } } } } } } } foreach (var s in prunedParts) { blackListPart blp = JanitorsCloset.blackList[s]; blp.permapruned = true; JanitorsCloset.blackList[s] = blp; } Log.Info("before saveRenamedFiles"); FileOperations.Instance.saveRenamedFiles(renamedFilesList); permapruneInProgress = false; yield break; //JanitorsCloset.Instance.clearBlackList(); }
public static Part CreatePart(string partname, Vector3 position, Quaternion rotation, Part flagFromPart) { AvailablePart avPart = PartLoader.getPartInfoByName(partname); return(CreatePart(avPart, position, rotation, flagFromPart)); }
//Used for initial orbital and surface survey parameter internal static DMCollectScience fetchSurveyScience(Contract.ContractPrestige c, List <CelestialBody> cR, List <CelestialBody> cUR, DMScienceContainer DMScience) { CelestialBody body; ExperimentSituations targetSituation; ScienceSubject sub; AvailablePart aPart; string name; string biome = ""; name = DMUtils.availableScience["All"].FirstOrDefault(n => n.Value == DMScience).Key; //Determine if the science part is available if applicable if (DMScience.SciPart != "None") { aPart = PartLoader.getPartInfoByName(DMScience.SciPart); if (aPart == null) { return(null); } if (!ResearchAndDevelopment.PartModelPurchased(aPart)) { return(null); } } body = DMUtils.nextTargetBody(c, cR, cUR); if (body == null) { return(null); } //Make sure our experiment is OK if (DMScience.Exp == null) { return(null); } if (!body.atmosphere && DMScience.Exp.requireAtmosphere) { return(null); } if (((ExperimentSituations)DMScience.SitMask & ExperimentSituations.InSpaceHigh) == ExperimentSituations.InSpaceHigh && ((ExperimentSituations)DMScience.SitMask & ExperimentSituations.InSpaceLow) == ExperimentSituations.InSpaceLow) { if (rand.Next(0, 2) == 0) { targetSituation = ExperimentSituations.InSpaceHigh; } else { targetSituation = ExperimentSituations.InSpaceLow; } } else if (((ExperimentSituations)DMScience.SitMask & ExperimentSituations.InSpaceHigh) == ExperimentSituations.InSpaceHigh) { targetSituation = ExperimentSituations.InSpaceHigh; } else { targetSituation = ExperimentSituations.InSpaceLow; } if (DMUtils.biomeRelevant(targetSituation, DMScience.BioMask) && targetSituation != ExperimentSituations.SrfSplashed) { List <string> bList = DMUtils.fetchBiome(body, DMScience.Exp, targetSituation); if (bList.Count == 0) { return(null); } else { biome = bList[rand.Next(0, bList.Count)]; } } //Make sure that our chosen science subject has science remaining to be gathered string subId = string.Format("{0}@{1}{2}{3}", DMScience.Exp.id, body.name, targetSituation, biome.Replace(" ", "")); if (ResearchAndDevelopment.GetSubjects().Any(s => s.id == subId)) { sub = ResearchAndDevelopment.GetSubjectByID(subId); if (sub.scientificValue < 0.5f) { return(null); } } return(new DMCollectScience(body, targetSituation, "", name, 0)); }
private static void UpdateVesselFilter() { vesselExpInfos.Clear(); bool hasROCScience = false; foreach (Part part in vesselParts) { foreach (PartModule partModule in part.Modules) { if (!partModule.enabled || !partModule.isEnabled) { continue; } if (partModule is Experiment experiment) { vesselExpInfos.Add(experiment.ExpInfo); } else if (partModule is ModuleScienceExperiment stockExperiment) { if (stockExperiment.experimentID == "ROCScience") { hasROCScience = true; } else { ExperimentInfo expInfo = ScienceDB.GetExperimentInfo(stockExperiment.experimentID); if (expInfo != null) { vesselExpInfos.Add(expInfo); } } } #if !KSP15_16 else if (partModule is ModuleInventoryPart inventory) { foreach (string inventoryPartName in inventory.InventoryPartsList) { Part groundPart = PartLoader.getPartInfoByName(inventoryPartName)?.partPrefab; if (groundPart == null) { continue; } foreach (PartModule groundmodule in groundPart.Modules) { if (groundmodule is ModuleGroundExperiment groundExp) { ExperimentInfo expInfo = ScienceDB.GetExperimentInfo(groundExp.experimentId); if (expInfo != null) { vesselExpInfos.Add(expInfo); } } } } } #endif } } if (hasROCScience) { foreach (ExperimentInfo experimentInfo in ScienceDB.ExperimentInfos) { if (experimentInfo.IsROC) { vesselExpInfos.Add(experimentInfo); } } } }
// Runs on start. public override void OnStart(StartState state) { using (PooledDebugLogger log = PooledDebugLogger.New(this)) { #if DEBUG try { #endif log.AppendFormat("{0}: starting up", this.ToString()); // Start up the underlying PartModule stuff. base.OnStart(state); log.Append("\n\tbase started up"); ModuleReactionWheel prefabModule; // Fetch the reaction wheel module. if (this.part.tryGetFirstModuleOfType <ModuleReactionWheel>(out this.reactionWheelModule)) { log.AppendFormat("\n\tFound ModuleReactionWheel {0}", this.reactionWheelModule); if (PartLoader.getPartInfoByName(this.part.partInfo.name).partPrefab .tryGetFirstModuleOfType <ModuleReactionWheel>(out prefabModule)) { log.AppendFormat("\n\tFound prefab module {0}", prefabModule); TweakableTools.InitializeTweakable <ModuleTweakableReactionWheel>( this.Fields["RollTorque"].uiControlCurrent(), ref this.RollTorque, ref this.reactionWheelModule.RollTorque, prefabModule.RollTorque ); log.Append("\n\tRollTorque setup"); TweakableTools.InitializeTweakable <ModuleTweakableReactionWheel>( this.Fields["PitchTorque"].uiControlCurrent(), ref this.PitchTorque, ref this.reactionWheelModule.PitchTorque, prefabModule.PitchTorque ); log.Append("\n\tPitchTorque setup"); TweakableTools.InitializeTweakable <ModuleTweakableReactionWheel>( this.Fields["YawTorque"].uiControlCurrent(), ref this.YawTorque, ref this.reactionWheelModule.YawTorque, prefabModule.YawTorque ); log.Append("\n\tYawTorque setup"); } } var torqueGainCtl = this.Fields["TorqueGain"].uiControlCurrent(); if (torqueGainCtl is UI_FloatRange) { var torqueGainSlider = torqueGainCtl as UI_FloatRange; torqueGainSlider.maxValue = 1f; torqueGainSlider.stepIncrement = 0.025f; } log.Append("\n\tStarted!"); #if DEBUG } finally { log.Print(); } #endif } }
/// <remarks> /// This code is based on KAS by KospY and the following license applies: /// http://kerbal.curseforge.com/ksp-mods/223900-kerbal-attachment-system-kas/license (link valid 03.09.2014) /// Usage of this code by me (marce) has been generously granted by KospY on 02.09.2014 per PM. /// </remarks> public static Part SpawnPartInFlight(string partName, Part referencePart, Vector3 referencePartOriginSpawnOffset, Quaternion spawnRotation, bool spawnLanded = true) { if (!HighLogic.LoadedSceneIsFlight) { Debug.Log(LogPrefix + " can only spawn in flight"); return(null); } var currentVessel = FlightGlobals.ActiveVessel; var avPart = PartLoader.getPartInfoByName(partName); var obj = UnityEngine.Object.Instantiate(avPart.partPrefab); if (obj == null) { Debug.Log(LogPrefix + " failed to instantiate part " + partName); return(null); } try { var newPart = (Part)obj; newPart.gameObject.SetActive(true); newPart.gameObject.name = avPart.name; newPart.partInfo = avPart; newPart.highlightRecurse = true; newPart.SetMirror(Vector3.one); var newShip = new ShipConstruct { newPart }; newShip.SaveShip(); newShip.shipName = avPart.title; var type = Convert.ChangeType(VesselType.Debris, VesselType.Debris.GetTypeCode()); if (type != null) { newShip.shipType = (int)type; } else { newShip.shipType = 1; } var v = newShip.parts[0].localRoot.gameObject.AddComponent <Vessel>(); v.id = Guid.NewGuid(); v.vesselName = newShip.shipName; v.Initialize(); v.Landed = spawnLanded; v.rootPart.flightID = ShipConstruction.GetUniqueFlightID(HighLogic.CurrentGame.flightState); v.rootPart.missionID = referencePart.missionID; v.rootPart.flagURL = referencePart.flagURL; FlightGlobals.SetActiveVessel(currentVessel); v.SetPosition(referencePart.transform.position + referencePartOriginSpawnOffset); v.SetRotation(spawnRotation); for (var i = 0; i < newPart.Modules.Count; i++) { var node = new ConfigNode(); node.AddValue("name", newPart.Modules[i].moduleName); var j = i; newPart.LoadModule(node, ref j); } return(newPart); } catch (NullReferenceException) { Debug.Log(LogPrefix + " part unknown"); return(null); } }