Example #1
0
        // return true if at least a component has malfunctioned or had a critical failure
        public static bool HasMalfunction(Vessel v)
        {
            if (v.loaded)
            {
                foreach (Reliability m in Lib.FindModules <Reliability>(v))
                {
                    if (m.broken)
                    {
                        return(true);
                    }
                }
            }
            else
            {
                foreach (ProtoPartModuleSnapshot m in Lib.FindModules(v.protoVessel, "Reliability"))
                {
                    if (Lib.Proto.GetBool(m, "broken"))
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
Example #2
0
		static void Render_environment(Panel p, Vessel v, Vessel_info vi)
		{
			// don't show env panel in eva kerbals
			if (v.isEVA) return;

			// get all sensor readings
			HashSet<string> readings = new HashSet<string>();
			if (v.loaded)
			{
				foreach (var s in Lib.FindModules<Sensor>(v))
				{
					readings.Add(s.type);
				}
			}
			else
			{
				foreach (ProtoPartModuleSnapshot m in Lib.FindModules(v.protoVessel, "Sensor"))
				{
					readings.Add(Lib.Proto.GetString(m, "type"));
				}
			}
			readings.Remove(string.Empty);

			p.AddSection("ENVIRONMENT");
			foreach (string type in readings)
			{
				p.AddContent(type, Sensor.Telemetry_content(v, vi, type), Sensor.Telemetry_tooltip(v, vi, type));
			}
			if (readings.Count == 0) p.AddContent("<i>no sensors installed</i>");
		}
Example #3
0
        // return total radiation emitted in a vessel
        public static double Total(Vessel v)
        {
            // get resource cache
            Resource_info ec = ResourceCache.Info(v, "ElectricCharge");

            double tot = 0.0;

            if (v.loaded)
            {
                foreach (var emitter in Lib.FindModules <Emitter>(v))
                {
                    if (ec.amount > double.Epsilon || emitter.ec_rate <= double.Epsilon)
                    {
                        tot += emitter.running ? emitter.radiation : 0.0;
                    }
                }
            }
            else
            {
                foreach (ProtoPartModuleSnapshot m in Lib.FindModules(v.protoVessel, "Emitter"))
                {
                    if (ec.amount > double.Epsilon || Lib.Proto.GetDouble(m, "ec_rate") <= double.Epsilon)
                    {
                        tot += Lib.Proto.GetBool(m, "running") ? Lib.Proto.GetDouble(m, "radiation") : 0.0;
                    }
                }
            }
            return(tot);
        }
Example #4
0
        // cause a part at random to malfunction
        public static void CauseMalfunction(Vessel v)
        {
            // if vessel is loaded
            if (v.loaded)
            {
                // choose a module at random
                var modules = Lib.FindModules <Reliability>(v).FindAll(k => !k.broken);
                if (modules.Count == 0)
                {
                    return;
                }
                var m = modules[Lib.RandomInt(modules.Count)];

                // break it
                m.Break();
            }
            // if vessel is not loaded
            else
            {
                // choose a module at random
                var modules = Lib.FindModules(v.protoVessel, "Reliability").FindAll(k => !Lib.Proto.GetBool(k, "broken"));
                if (modules.Count == 0)
                {
                    return;
                }
                var m = modules[Lib.RandomInt(modules.Count)];

                // find its part
                ProtoPartSnapshot p = v.protoVessel.protoPartSnapshots.Find(k => k.modules.Contains(m));

                // break it
                ProtoBreak(v, p, m);
            }
        }
Example #5
0
		// remove one experiment at random from the vessel
		public static void RemoveData(Vessel v)
		{
			// stock science system
			if (!Features.Science)
			{
				// if vessel is loaded
				if (v.loaded)
				{
					// get all science containers/experiments with data
					List<IScienceDataContainer> modules = Lib.FindModules<IScienceDataContainer>(v).FindAll(k => k.GetData().Length > 0);

					// remove a data sample at random
					if (modules.Count > 0)
					{
						IScienceDataContainer container = modules[Lib.RandomInt(modules.Count)];
						ScienceData[] data = container.GetData();
						container.DumpData(data[Lib.RandomInt(data.Length)]);
					}
				}
				// if not loaded
				else
				{
					// get all science containers/experiments with data
					var modules = new List<ProtoPartModuleSnapshot>();
					modules.AddRange(Lib.FindModules(v.protoVessel, "ModuleScienceContainer").FindAll(k => k.moduleValues.GetNodes("ScienceData").Length > 0));
					modules.AddRange(Lib.FindModules(v.protoVessel, "ModuleScienceExperiment").FindAll(k => k.moduleValues.GetNodes("ScienceData").Length > 0));

					// remove a data sample at random
					if (modules.Count > 0)
					{
						ProtoPartModuleSnapshot container = modules[Lib.RandomInt(modules.Count)];
						ConfigNode[] data = container.moduleValues.GetNodes("ScienceData");
						container.moduleValues.RemoveNode(data[Lib.RandomInt(data.Length)]);
					}
				}
			}
			// our own science system
			else
			{
				// select a file at random and remove it
				Drive drive = DB.Vessel(v).drive;
				if (drive.files.Count > 0) //< it should always be the case
				{
					string filename = string.Empty;
					int i = Lib.RandomInt(drive.files.Count);
					foreach (var pair in drive.files)
					{
						if (i-- == 0)
						{
							filename = pair.Key;
							break;
						}
					}
					drive.files.Remove(filename);
				}
			}
		}
Example #6
0
        internal void Update(Vessel v)
        {
            if (v == null || !v.loaded)
            {
                return;
            }

            if (habitats == null)
            {
                habitats    = Lib.FindModules <Habitat>(v);
                maxPressure = 1.0;
                foreach (var habitat in habitats)
                {
                    maxPressure = Math.Min(maxPressure, habitat.max_pressure);
                }
            }

            if (!Features.Radiation || habitats.Count == 0)
            {
                return;
            }

            // always do EVAs
            if (v.isEVA)
            {
                RaytraceToSun(v.rootPart);
                return;
            }

            if (habitatIndex < 0)
            {
                // first run, do them all
                foreach (var habitat in habitats)
                {
                    RaytraceToSun(habitat.part);
                }
                habitatIndex = 0;
            }
            else
            {
                // only do one habitat at a time to preserve some performance
                // and check that part still exists
                if (habitats[habitatIndex].part == null)
                {
                    habitats.RemoveAt(habitatIndex);
                }
                else
                {
                    RaytraceToSun(habitats[habitatIndex].part);
                }

                habitatIndex = (habitatIndex + 1) % habitats.Count;
            }
        }
Example #7
0
		public static void Update(Vessel v)
		{
			// do nothing if not an eva kerbal
			if (!v.isEVA) return;

			// get KerbalEVA module
			KerbalEVA kerbal = Lib.FindModules<KerbalEVA>(v)[0];

			Vessel_info vi = Cache.VesselInfo(v);

			// Stock KSP adds 5 units of monoprop to EVAs. We want to limit that amount
			// to whatever was available in the ship, so we don't magically create EVA prop out of nowhere
			if(Cache.HasVesselObjectsCache(v, "eva_prop"))
			{
				Lib.Log("### have eva_prop for " + v);
				var quantity = Cache.VesselObjectsCache<double>(v, "eva_prop");
				Cache.RemoveVesselObjectsCache(v, "eva_prop");
				Lib.Log("### adding " + quantity + " eva prop");
				Lib.SetResource(kerbal.part, Lib.EvaPropellantName(), quantity, Lib.EvaPropellantCapacity());
			}

			// get resource handler
			Resource_info ec = ResourceCache.Info(v, "ElectricCharge");

			// determine if headlamps need ec
			// - not required if there is no EC capacity in eva kerbal (no ec supply in profile)
			// - not required if no EC cost for headlamps is specified (set by the user)
			bool need_ec = ec.capacity > double.Epsilon && Settings.HeadLampsCost > double.Epsilon;

			// consume EC for the headlamps
			if (need_ec && kerbal.lampOn)
			{
				ec.Consume(Settings.HeadLampsCost * Kerbalism.elapsed_s, "headlamp");
			}

			// force the headlamps on/off
			HeadLamps(kerbal, kerbal.lampOn && (!need_ec || ec.amount > double.Epsilon));

			// if dead
			if (IsDead(v))
			{
				// enforce freezed state
				Freeze(kerbal);

				// disable modules
				DisableModules(kerbal);

				// remove plant flag action
				kerbal.flagItems = 0;
			}
		}
        // return total radiation emitted in a vessel
        public static double Total(Vessel v)
        {
            // get resource cache
            ResourceInfo ec = ResourceCache.GetResource(v, "ElectricCharge");

            double tot = 0.0;

            if (v.loaded)
            {
                foreach (var emitter in Lib.FindModules <Emitter>(v))
                {
                    if (ec.Amount > double.Epsilon || emitter.ec_rate <= double.Epsilon)
                    {
                        if (emitter.running)
                        {
                            if (emitter.radiation > 0)
                            {
                                tot += emitter.radiation * emitter.radiation_impact;
                            }
                            else
                            {
                                tot += emitter.radiation;                              // always account for full shielding effect
                            }
                        }
                    }
                }
            }
            else
            {
                foreach (ProtoPartModuleSnapshot m in Lib.FindModules(v.protoVessel, "Emitter"))
                {
                    if (ec.Amount > double.Epsilon || Lib.Proto.GetDouble(m, "ec_rate") <= double.Epsilon)
                    {
                        if (Lib.Proto.GetBool(m, "running"))
                        {
                            var rad = Lib.Proto.GetDouble(m, "radiation");
                            if (rad < 0)
                            {
                                tot += rad;
                            }
                            else
                            {
                                tot += rad * Lib.Proto.GetDouble(m, "radiation_factor");
                            }
                        }
                    }
                }
            }
            return(tot);
        }
Example #9
0
        static void Render_environment(Panel p, Vessel v, VesselData vd)
        {
            // don't show env panel in eva kerbals
            if (v.isEVA)
            {
                return;
            }

            // get all sensor readings
            HashSet <string> readings = new HashSet <string>();

            if (v.loaded)
            {
                foreach (var s in Lib.FindModules <Sensor>(v))
                {
                    readings.Add(s.type);
                }
            }
            else
            {
                foreach (ProtoPartModuleSnapshot m in Lib.FindModules(v.protoVessel, "Sensor"))
                {
                    readings.Add(Lib.Proto.GetString(m, "type"));
                }
            }
            readings.Remove(string.Empty);

            p.AddSection(Local.TELEMETRY_ENVIRONMENT);            //"ENVIRONMENT"

            if (vd.SolarPanelsAverageExposure >= 0.0)
            {
                var exposureString = vd.SolarPanelsAverageExposure.ToString("P1");
                if (vd.SolarPanelsAverageExposure < 0.2)
                {
                    exposureString = Lib.Color(exposureString, Lib.Kolor.Orange);
                }
                p.AddContent(Local.TELEMETRY_SolarPanelsAverageExposure, exposureString, "<b>" + Local.TELEMETRY_Exposureignoringbodiesocclusion + "</b>\n<i>" + Local.TELEMETRY_Exposureignoringbodiesocclusion_desc + "</i>");          //"solar panels average exposure""Exposure ignoring bodies occlusion""Won't change on unloaded vessels\nMake sure to optimize it before switching
            }

            foreach (string type in readings)
            {
                p.AddContent(type.ToLower().Replace('_', ' '), Sensor.Telemetry_content(v, vd, type), Sensor.Telemetry_tooltip(v, vd, type));
            }
            if (readings.Count == 0)
            {
                p.AddContent("<i>" + Local.TELEMETRY_nosensorsinstalled + "</i>");                              //no sensors installed
            }
        }
Example #10
0
        static void Incentive_redundancy(Vessel v, string redundancy)
        {
            if (v.loaded)
            {
                foreach (Reliability m in Lib.FindModules <Reliability>(v))
                {
                    if (m.redundancy == redundancy)
                    {
                        m.next += m.next - m.last;
                    }
                }
            }
            else
            {
                var PD = new Dictionary <string, Lib.Module_prefab_data>();

                foreach (ProtoPartSnapshot p in v.protoVessel.protoPartSnapshots)
                {
                    Part part_prefab    = PartLoader.getPartInfoByName(p.partName).partPrefab;
                    var  module_prefabs = part_prefab.FindModulesImplementing <PartModule>();
                    PD.Clear();

                    foreach (ProtoPartModuleSnapshot m in p.modules)
                    {
                        if (m.moduleName != "Reliability")
                        {
                            continue;
                        }

                        PartModule module_prefab = Lib.ModulePrefab(module_prefabs, m.moduleName, PD);
                        if (!module_prefab)
                        {
                            continue;
                        }

                        string r = Lib.Proto.GetString(m, "redundancy", string.Empty);
                        if (r == redundancy)
                        {
                            double last = Lib.Proto.GetDouble(m, "last");
                            double next = Lib.Proto.GetDouble(m, "next");
                            Lib.Proto.Set(m, "next", next + (next - last));
                        }
                    }
                }
            }
        }
Example #11
0
        public static Dictionary <uint, Drive> GetDriveParts(Vessel vessel)
        {
            Dictionary <uint, Drive> result = Cache.VesselObjectsCache <Dictionary <uint, Drive> >(vessel, "drives");

            if (result != null)
            {
                return(result);
            }
            result = new Dictionary <uint, Drive>();

            if (vessel.loaded)
            {
                foreach (var hd in vessel.FindPartModulesImplementing <HardDrive>())
                {
                    // Serenity/ModuleManager bug workaround (duplicate drives on EVAs)
                    if (result.ContainsKey(hd.part.flightID))
                    {
                        continue;
                    }

                    if (hd.hdId != 0 && DB.drives.ContainsKey(hd.hdId))
                    {
                        result.Add(hd.part.flightID, DB.drives[hd.hdId]);
                    }
                }
            }
            else
            {
                foreach (var p in vessel.protoVessel.protoPartSnapshots)
                {
                    foreach (var pm in Lib.FindModules(p, "HardDrive"))
                    {
                        var hdId = Lib.Proto.GetUInt(pm, "hdId", 0);
                        if (hdId != 0 && DB.drives.ContainsKey(hdId))
                        {
                            result.Add(p.flightID, DB.drives[hdId]);
                        }
                    }
                }
            }

            Cache.SetVesselObjectsCache(vessel, "drives", result);
            return(result);
        }
        /// <summary>
        /// get the total radiation emitted by nearby emitters (used for EVAs). only works for loaded vessels.
        /// </summary>
        public static double Nearby(Vessel v)
        {
            if (!v.loaded || !v.isEVA)
            {
                return(0.0);
            }
            var evaPosition = v.rootPart.transform.position;

            double result = 0.0;

            foreach (Vessel n in FlightGlobals.VesselsLoaded)
            {
                var vd = n.KerbalismData();
                if (!vd.IsSimulated)
                {
                    continue;
                }

                foreach (var emitter in Lib.FindModules <Emitter>(n))
                {
                    if (emitter.part == null || emitter.part.transform == null)
                    {
                        continue;
                    }
                    if (emitter.radiation <= 0)
                    {
                        continue;                                             // ignore shielding effects here
                    }
                    if (!emitter.running)
                    {
                        continue;
                    }

                    var emitterPosition = emitter.part.transform.position;
                    var vector          = evaPosition - emitterPosition;
                    var distance        = vector.magnitude;

                    result += Radiation.DistanceRadiation(emitter.radiation, distance);
                }
            }

            return(result);
        }
Example #13
0
        public static List <Data> Greenhouses(Vessel v)
        {
            List <Data> ret = new List <Data>();

            if (v.loaded)
            {
                foreach (Greenhouse greenhouse in Lib.FindModules <Greenhouse>(v))
                {
                    if (greenhouse.active)
                    {
                        Data gd = new Data
                        {
                            growth     = greenhouse.growth,
                            natural    = greenhouse.natural,
                            artificial = greenhouse.artificial,
                            tta        = greenhouse.tta,
                            issue      = greenhouse.issue
                        };
                        ret.Add(gd);
                    }
                }
            }
            else
            {
                foreach (ProtoPartModuleSnapshot m in Lib.FindModules(v.protoVessel, "Greenhouse"))
                {
                    if (Lib.Proto.GetBool(m, "active"))
                    {
                        Data gd = new Data
                        {
                            growth     = Lib.Proto.GetDouble(m, "growth"),
                            natural    = Lib.Proto.GetDouble(m, "natural"),
                            artificial = Lib.Proto.GetDouble(m, "artificial"),
                            tta        = Lib.Proto.GetDouble(m, "tta"),
                            issue      = Lib.Proto.GetString(m, "issue")
                        };
                        ret.Add(gd);
                    }
                }
            }
            return(ret);
        }
Example #14
0
        public static void Update(Vessel v)
        {
            // do nothing if not an eva kerbal
            if (!v.isEVA)
            {
                return;
            }

            // get KerbalEVA module
            KerbalEVA kerbal = Lib.FindModules <KerbalEVA>(v)[0];

            // get resource handler
            Resource_Info ec = ResourceCache.Info(v, "ElectricCharge");

            // determine if headlamps need ec
            // - not required if there is no EC capacity in eva kerbal (no ec supply in profile)
            // - not required if no EC cost for headlamps is specified (set by the user)
            bool need_ec = ec.capacity > double.Epsilon && Settings.HeadLampsCost > double.Epsilon;

            // consume EC for the headlamps
            if (need_ec && kerbal.lampOn)
            {
                ec.Consume(Settings.HeadLampsCost * Kerbalism.elapsed_s);
            }

            // force the headlamps on/off
            HeadLamps(kerbal, kerbal.lampOn && (!need_ec || ec.amount > double.Epsilon));

            // if dead
            if (IsDead(v))
            {
                // enforce freezed state
                Freeze(kerbal);

                // disable modules
                DisableModules(kerbal);

                // remove plant flag action
                kerbal.flagItems = 0;
            }
        }
Example #15
0
 private static void RestoreSampleMass(Vessel v, SubjectData filename, double restoredAmount)
 {
     if (v.loaded)            // loaded vessel
     {
         foreach (var experiment in v.FindPartModulesImplementing <Experiment>())
         {
             restoredAmount -= experiment.RestoreSampleMass(restoredAmount, filename.ExpInfo.ExperimentId);
         }
     }
     else             // unloaded vessel
     {
         foreach (ProtoPartModuleSnapshot m in Lib.FindModules(v.protoVessel, "Experiment"))
         {
             restoredAmount -= Experiment.RestoreSampleMass(restoredAmount, m, filename.ExpInfo.ExperimentId);
             if (restoredAmount < double.Epsilon)
             {
                 return;
             }
         }
     }
 }
Example #16
0
        static void Incentive_redundancy(Vessel v, string redundancy)
        {
            if (v.loaded)
            {
                foreach (Reliability m in Lib.FindModules <Reliability>(v))
                {
                    if (m.redundancy == redundancy)
                    {
                        m.next += m.next - m.last;
                    }
                }
            }
            else
            {
                foreach (ProtoPartModuleSnapshot m in Lib.FindModules(v.protoVessel, "Reliability"))
                {
                    // find part
                    ProtoPartSnapshot p = v.protoVessel.protoPartSnapshots.Find(k => k.modules.Contains(m));

                    // find module prefab
                    string      type        = Lib.Proto.GetString(m, "type", string.Empty);
                    Reliability reliability = p.partPrefab.FindModulesImplementing <Reliability>().Find(k => k.type == type);
                    if (reliability == null)
                    {
                        continue;
                    }

                    // double time to next failure
                    if (reliability.redundancy == redundancy)
                    {
                        double last = Lib.Proto.GetDouble(m, "last");
                        double next = Lib.Proto.GetDouble(m, "next");
                        Lib.Proto.Set(m, "next", next + (next - last));
                    }
                }
            }
        }
Example #17
0
 // return true if at least a component has a critical failure
 public static bool HasCriticalFailure(Vessel v)
 {
     if (v.loaded)
     {
         foreach (Reliability m in Lib.FindModules <Reliability>(v))
         {
             if (m.critical)
             {
                 return(true);
             }
         }
     }
     else
     {
         foreach (ProtoPartModuleSnapshot m in Lib.FindModules(v.protoVessel, "Reliability"))
         {
             if (Lib.Proto.GetBool(m, "critical"))
             {
                 return(true);
             }
         }
     }
     return(false);
 }
Example #18
0
        public void abort(Vessel v)
        {
            foreach (ScienceData data in queue)
            {
                foreach (ModuleScienceContainer container in Lib.FindModules <ModuleScienceContainer>(v))
                {
                    // add the data to the container
                    container.ReturnData(data);

                    // if, for some reasons, it wasn't possible to add the data, try the next container
                    // note: this also deal with multiple versions of same data in the entire vessel
                    if (!container.HasData(data))
                    {
                        continue;
                    }

                    // data was added, process the next data
                    break;
                }
            }

            queue.Clear();
            transmitted.Clear();
        }
Example #19
0
        private static void RestoreSampleMass(Vessel v, string filename, double restoredAmount)
        {
            int i  = filename.IndexOf('@');
            var id = i > 0 ? filename.Substring(0, i) : filename;

            if (v.loaded)            // loaded vessel
            {
                foreach (var experiment in v.FindPartModulesImplementing <Experiment>())
                {
                    restoredAmount -= experiment.RestoreSampleMass(restoredAmount, id);
                }
            }
            else             // unloaded vessel
            {
                foreach (ProtoPartModuleSnapshot m in Lib.FindModules(v.protoVessel, "Experiment"))
                {
                    restoredAmount -= Experiment.RestoreSampleMass(restoredAmount, m, id);
                    if (restoredAmount < double.Epsilon)
                    {
                        return;
                    }
                }
            }
        }
Example #20
0
        // return total radiation emitted in a vessel
        public static double Total(Vessel v)
        {
            // get resource cache
            ResourceInfo ec = ResourceCache.GetResource(v, "ElectricCharge");

            double total = 0.0;

            if (v.loaded)
            {
                foreach (var shield in Lib.FindModules <PassiveShield>(v))
                {
                    if (ec.Amount > 0 || shield.ec_rate <= 0)
                    {
                        if (shield.deployed)
                        {
                            total += shield.radiation;
                        }
                    }
                }
            }
            else
            {
                foreach (ProtoPartModuleSnapshot m in Lib.FindModules(v.protoVessel, "PassiveShield"))
                {
                    if (ec.Amount > 0 || Lib.Proto.GetDouble(m, "ec_rate") <= 0)
                    {
                        if (Lib.Proto.GetBool(m, "deployed"))
                        {
                            var rad = Lib.Proto.GetDouble(m, "radiation");
                            total += rad;
                        }
                    }
                }
            }
            return(total);
        }
Example #21
0
        // 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);
        }
Example #22
0
        public Comforts(Vessel v, bool firm_ground, bool not_alone, bool call_home)
        {
            // environment factors
            this.firm_ground = firm_ground;
            this.not_alone   = not_alone;
            this.call_home   = call_home;

            // if loaded
            if (v.loaded)
            {
                // scan parts for comfort
                foreach (Comfort c in Lib.FindModules <Comfort>(v))
                {
                    switch (c.bonus)
                    {
                    case "firm-ground": this.firm_ground = true; break;

                    case "not-alone":   this.not_alone = true;   break;

                    case "call-home":   this.call_home = true;   break;

                    case "exercise":    this.exercise = true;    break;

                    case "panorama":    this.panorama = true;    break;
                    }
                }

                // scan parts for gravity ring
                if (ResourceCache.Info(v, "ElectricCharge").amount >= 0.01)
                {
                    this.firm_ground |= Lib.HasModule <GravityRing>(v, k => k.deployed);
                }
            }
            // if not loaded
            else
            {
                // scan parts for comfort
                foreach (ProtoPartModuleSnapshot m in Lib.FindModules(v.protoVessel, "Comfort"))
                {
                    switch (Lib.Proto.GetString(m, "bonus"))
                    {
                    case "firm-ground": this.firm_ground = true; break;

                    case "not-alone":   this.not_alone = true;   break;

                    case "call-home":   this.call_home = true;   break;

                    case "exercise":    this.exercise = true;    break;

                    case "panorama":    this.panorama = true;    break;
                    }
                }

                // scan parts for gravity ring
                if (ResourceCache.Info(v, "ElectricCharge").amount >= 0.01)
                {
                    this.firm_ground |= Lib.HasModule(v.protoVessel, "GravityRing", k => Lib.Proto.GetBool(k, "deployed"));
                }
            }

            // calculate factor
            factor = 0.1;
            if (firm_ground)
            {
                factor += Settings.ComfortFirmGround;
            }
            if (not_alone)
            {
                factor += Settings.ComfortNotAlone;
            }
            if (call_home)
            {
                factor += Settings.ComfortCallHome;
            }
            if (exercise)
            {
                factor += Settings.ComfortExercise;
            }
            if (panorama)
            {
                factor += Settings.ComfortPanorama;
            }
            factor = Lib.Clamp(factor, 0.1, 1.0);
        }
Example #23
0
        public static List <ReliabilityInfo> BuildList(Vessel vessel)
        {
            var result = new List <ReliabilityInfo>();

            if (vessel.loaded)
            {
                foreach (var r in Lib.FindModules <Reliability>(vessel))
                {
                    result.Add(new ReliabilityInfo(r));
                }
            }
            else
            {
                var PD = new Dictionary <string, Lib.Module_prefab_data>();
                foreach (ProtoPartSnapshot p in vessel.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)
                    {
                        if (m.moduleName != "Reliability")
                        {
                            continue;
                        }

                        Reliability module_prefab = Lib.ModulePrefab(module_prefabs, m.moduleName, PD) as Reliability;
                        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;
                        }

                        result.Add(new ReliabilityInfo(p, m, module_prefab));
                    }
                }
            }

            result.Sort((a, b) => {
                if (a.group != b.group)
                {
                    return(string.Compare(a.group, b.group, StringComparison.Ordinal));
                }
                return(string.Compare(a.title, b.title));
            });

            return(result);
        }
Example #24
0
        public Comforts(Vessel v, bool env_firm_ground, bool env_not_alone, bool env_call_home)
        {
            // environment factors
            firm_ground = env_firm_ground;
            not_alone   = env_not_alone;
            call_home   = env_call_home;

            // if loaded
            if (v.loaded)
            {
                // scan parts for comfort
                foreach (Comfort c in Lib.FindModules <Comfort>(v))
                {
                    switch (c.bonus)
                    {
                    case "firm-ground": firm_ground = true; break;

                    case "not-alone": not_alone = true; break;

                    case "call-home": call_home = true; break;

                    case "exercise": exercise = true; break;

                    case "panorama": panorama = true; break;

                    case "plants": plants = true; break;
                    }
                }

                // scan parts for gravity ring
                if (ResourceCache.Info(v, "ElectricCharge").amount >= 0.01)
                {
                    firm_ground |= Lib.HasModule <GravityRing>(v, k => k.deployed);
                }
            }
            // if not loaded
            else
            {
                // scan parts for comfort
                foreach (ProtoPartModuleSnapshot m in Lib.FindModules(v.protoVessel, "Comfort"))
                {
                    switch (Lib.Proto.GetString(m, "bonus"))
                    {
                    case "firm-ground": firm_ground = true; break;

                    case "not-alone": not_alone = true; break;

                    case "call-home": call_home = true; break;

                    case "exercise": exercise = true; break;

                    case "panorama": panorama = true; break;

                    case "plants": plants = true; break;
                    }
                }

                // scan parts for gravity ring
                if (ResourceCache.Info(v, "ElectricCharge").amount >= 0.01)
                {
                    firm_ground |= Lib.HasModule(v.protoVessel, "GravityRing", k => Lib.Proto.GetBool(k, "deployed"));
                }
            }

            // calculate factor
            factor = 0.1;
            if (firm_ground)
            {
                factor += PreferencesComfort.Instance.firmGround;
            }
            if (not_alone)
            {
                factor += PreferencesComfort.Instance.notAlone;
            }
            if (call_home)
            {
                factor += PreferencesComfort.Instance.callHome;
            }
            if (exercise)
            {
                factor += PreferencesComfort.Instance.exercise;
            }
            if (panorama)
            {
                factor += PreferencesComfort.Instance.panorama;
            }
            if (plants)
            {
                factor += PreferencesComfort.Instance.plants;
            }
            factor = Lib.Clamp(factor, 0.1, 1.0);
        }
Example #25
0
        public static void BackgroundUpdate(Vessel vessel, ProtoPartSnapshot p, ProtoPartModuleSnapshot m, KerbalismScansat kerbalismScansat,
                                            Part part_prefab, VesselData vd, Resource_info ec, double elapsed_s)
        {
            List <ProtoPartModuleSnapshot> scanners = Cache.VesselObjectsCache <List <ProtoPartModuleSnapshot> >(vessel, "scansat_" + p.flightID);

            if (scanners == null)
            {
                scanners = Lib.FindModules(p, "SCANsat");
                if (scanners.Count == 0)
                {
                    scanners = Lib.FindModules(p, "ModuleSCANresourceScanner");
                }
                Cache.SetVesselObjectsCache(vessel, "scansat_" + p.flightID, scanners);
            }

            if (scanners.Count == 0)
            {
                return;
            }
            var scanner = scanners[0];

            bool is_scanning = Lib.Proto.GetBool(scanner, "scanning");

            if (is_scanning && kerbalismScansat.ec_rate > double.Epsilon)
            {
                ec.Consume(kerbalismScansat.ec_rate * elapsed_s, "scanner");
            }

            if (!Features.Science)
            {
                if (is_scanning && ec.amount < double.Epsilon)
                {
                    SCANsat.StopScanner(vessel, scanner, part_prefab);
                    is_scanning = false;

                    // remember disabled scanner
                    vd.scansat_id.Add(p.flightID);

                    // give the user some feedback
                    if (vd.cfg_ec)
                    {
                        Message.Post(Lib.BuildString("SCANsat sensor was disabled on <b>", vessel.vesselName, "</b>"));
                    }
                }
                else if (vd.scansat_id.Contains(p.flightID))
                {
                    // if there is enough ec
                    // note: comparing against amount in previous simulation step
                    // re-enable at 25% EC
                    if (ec.level > 0.25)
                    {
                        // re-enable the scanner
                        SCANsat.ResumeScanner(vessel, m, part_prefab);
                        is_scanning = true;

                        // give the user some feedback
                        if (vd.cfg_ec)
                        {
                            Message.Post(Lib.BuildString("SCANsat sensor resumed operations on <b>", vessel.vesselName, "</b>"));
                        }
                    }
                }

                // forget active scanners
                if (is_scanning)
                {
                    vd.scansat_id.Remove(p.flightID);
                }

                return;
            }             // if(!Feature.Science)

            string body_name     = Lib.Proto.GetString(m, "body_name");
            int    sensorType    = (int)Lib.Proto.GetUInt(m, "sensorType");
            double body_coverage = Lib.Proto.GetDouble(m, "body_coverage");
            double warp_buffer   = Lib.Proto.GetDouble(m, "warp_buffer");

            double new_coverage = SCANsat.Coverage(sensorType, vessel.mainBody);

            if (body_name == vessel.mainBody.name && new_coverage < body_coverage)
            {
                // SCANsat sometimes reports a coverage of 0, which is wrong
                new_coverage = body_coverage;
            }

            if (vessel.mainBody.name != body_name)
            {
                body_name     = vessel.mainBody.name;
                body_coverage = new_coverage;
            }
            else
            {
                double coverage_delta = new_coverage - body_coverage;
                body_coverage = new_coverage;

                if (is_scanning)
                {
                    Science.Generate_subject(kerbalismScansat.experimentType, vessel);
                    var    subject_id = Science.Generate_subject_id(kerbalismScansat.experimentType, vessel);
                    var    exp        = Science.Experiment(subject_id);
                    double size       = exp.max_amount * coverage_delta / 100.0;               // coverage is 0-100%
                    size += warp_buffer;

                    if (size > double.Epsilon)
                    {
                        // store what we can
                        foreach (var d in Drive.GetDrives(vessel))
                        {
                            var available = d.FileCapacityAvailable();
                            var chunk     = Math.Min(size, available);
                            if (!d.Record_file(subject_id, chunk, true))
                            {
                                break;
                            }
                            size -= chunk;

                            if (size < double.Epsilon)
                            {
                                break;
                            }
                        }
                    }

                    if (size > double.Epsilon)
                    {
                        // we filled all drives up to the brim but were unable to store everything
                        if (warp_buffer < double.Epsilon)
                        {
                            // warp buffer is empty, so lets store the rest there
                            warp_buffer = size;
                            size        = 0;
                        }
                        else
                        {
                            // warp buffer not empty. that's ok if we didn't get new data
                            if (coverage_delta < double.Epsilon)
                            {
                                size = 0;
                            }
                            // else we're scanning too fast. stop.
                        }
                    }

                    // we filled all drives up to the brim but were unable to store everything
                    // cancel scanning and annoy the user
                    if (size > double.Epsilon || ec.amount < double.Epsilon)
                    {
                        warp_buffer = 0;
                        SCANsat.StopScanner(vessel, scanner, part_prefab);
                        vd.scansat_id.Add(p.flightID);
                        if (vd.cfg_ec)
                        {
                            Message.Post(Lib.BuildString("SCANsat sensor was disabled on <b>", vessel.vesselName, "</b>"));
                        }
                    }
                }
                else if (vd.scansat_id.Contains(p.flightID))
                {
                    var vi = Cache.VesselInfo(vessel);
                    if (ec.level >= 0.25 && (vi.free_capacity / vi.total_capacity > 0.9))
                    {
                        SCANsat.ResumeScanner(vessel, scanner, part_prefab);
                        vd.scansat_id.Remove(p.flightID);
                        if (vd.cfg_ec)
                        {
                            Message.Post(Lib.BuildString("SCANsat sensor resumed operations on <b>", vessel.vesselName, "</b>"));
                        }
                    }
                }
            }

            Lib.Proto.Set(m, "warp_buffer", warp_buffer);
            Lib.Proto.Set(m, "body_coverage", body_coverage);
            Lib.Proto.Set(m, "body_name", body_name);
        }
Example #26
0
        public bool TestRequirements(Vessel v, out RequireResult[] results, bool testAll = false)
        {
            UnityEngine.Profiling.Profiler.BeginSample("Kerbalism.ExperimentRequirements.TestRequirements");
            VesselData vd = v.KerbalismData();

            results = new RequireResult[Requires.Length];

            bool good = true;

            for (int i = 0; i < Requires.Length; i++)
            {
                results[i] = new RequireResult(Requires[i]);
                switch (Requires[i].require)
                {
                case Require.OrbitMinInclination: TestReq((c, r) => c >= r, v.orbit.inclination, (double)Requires[i].value, results[i]); break;

                case Require.OrbitMaxInclination: TestReq((c, r) => c <= r, v.orbit.inclination, (double)Requires[i].value, results[i]); break;

                case Require.OrbitMinEccentricity: TestReq((c, r) => c >= r, v.orbit.eccentricity, (double)Requires[i].value, results[i]); break;

                case Require.OrbitMaxEccentricity: TestReq((c, r) => c <= r, v.orbit.eccentricity, (double)Requires[i].value, results[i]); break;

                case Require.OrbitMinArgOfPeriapsis: TestReq((c, r) => c >= r, v.orbit.argumentOfPeriapsis, (double)Requires[i].value, results[i]); break;

                case Require.OrbitMaxArgOfPeriapsis: TestReq((c, r) => c <= r, v.orbit.argumentOfPeriapsis, (double)Requires[i].value, results[i]); break;

                case Require.TemperatureMin: TestReq((c, r) => c >= r, vd.EnvTemperature, (double)Requires[i].value, results[i]); break;

                case Require.TemperatureMax: TestReq((c, r) => c <= r, vd.EnvTemperature, (double)Requires[i].value, results[i]); break;

                case Require.AltitudeMin: TestReq((c, r) => c >= r, v.altitude, (double)Requires[i].value, results[i]); break;

                case Require.AltitudeMax: TestReq((c, r) => c <= r, v.altitude, (double)Requires[i].value, results[i]); break;

                case Require.RadiationMin: TestReq((c, r) => c >= r, vd.EnvRadiation, (double)Requires[i].value, results[i]); break;

                case Require.RadiationMax: TestReq((c, r) => c <= r, vd.EnvRadiation, (double)Requires[i].value, results[i]); break;

                case Require.VolumePerCrewMin: TestReq((c, r) => c >= r, vd.VolumePerCrew, (double)Requires[i].value, results[i]); break;

                case Require.VolumePerCrewMax: TestReq((c, r) => c <= r, vd.VolumePerCrew, (double)Requires[i].value, results[i]); break;

                case Require.SunAngleMin: TestReq((c, r) => c >= r, vd.EnvSunBodyAngle, (double)Requires[i].value, results[i]); break;

                case Require.SunAngleMax: TestReq((c, r) => c <= r, vd.EnvSunBodyAngle, (double)Requires[i].value, results[i]); break;

                case Require.SurfaceSpeedMin: TestReq((c, r) => c >= r, v.srfSpeed, (double)Requires[i].value, results[i]); break;

                case Require.SurfaceSpeedMax: TestReq((c, r) => c <= r, v.srfSpeed, (double)Requires[i].value, results[i]); break;

                case Require.VerticalSpeedMin: TestReq((c, r) => c >= r, v.verticalSpeed, (double)Requires[i].value, results[i]); break;

                case Require.VerticalSpeedMax: TestReq((c, r) => c <= r, v.verticalSpeed, (double)Requires[i].value, results[i]); break;

                case Require.SpeedMin: TestReq((c, r) => c >= r, v.speed, (double)Requires[i].value, results[i]); break;

                case Require.SpeedMax: TestReq((c, r) => c <= r, v.speed, (double)Requires[i].value, results[i]); break;

                case Require.DynamicPressureMin: TestReq((c, r) => c >= r, v.dynamicPressurekPa, (double)Requires[i].value, results[i]); break;

                case Require.DynamicPressureMax: TestReq((c, r) => c <= r, v.dynamicPressurekPa, (double)Requires[i].value, results[i]); break;

                case Require.StaticPressureMin: TestReq((c, r) => c >= r, v.staticPressurekPa, (double)Requires[i].value, results[i]); break;

                case Require.StaticPressureMax: TestReq((c, r) => c <= r, v.staticPressurekPa, (double)Requires[i].value, results[i]); break;

                case Require.AtmDensityMin: TestReq((c, r) => c >= r, v.atmDensity, (double)Requires[i].value, results[i]); break;

                case Require.AtmDensityMax: TestReq((c, r) => c <= r, v.atmDensity, (double)Requires[i].value, results[i]); break;

                case Require.AltAboveGroundMin: TestReq((c, r) => c >= r, v.heightFromTerrain, (double)Requires[i].value, results[i]); break;

                case Require.AltAboveGroundMax: TestReq((c, r) => c <= r, v.heightFromTerrain, (double)Requires[i].value, results[i]); break;

                case Require.MaxAsteroidDistance: TestReq((c, r) => c <= r, TestAsteroidDistance(v), (double)Requires[i].value, results[i]); break;

                case Require.AtmosphereAltMin: TestReq((c, r) => c >= r, v.mainBody.atmosphere ? v.altitude / v.mainBody.atmosphereDepth : double.NaN, (double)Requires[i].value, results[i]); break;

                case Require.AtmosphereAltMax: TestReq((c, r) => c <= r, v.mainBody.atmosphere ? v.altitude / v.mainBody.atmosphereDepth : double.NaN, (double)Requires[i].value, results[i]); break;

                case Require.CrewMin: TestReq((c, r) => c >= r, vd.CrewCount, (int)Requires[i].value, results[i]); break;

                case Require.CrewMax: TestReq((c, r) => c <= r, vd.CrewCount, (int)Requires[i].value, results[i]); break;

                case Require.CrewCapacityMin: TestReq((c, r) => c >= r, vd.CrewCapacity, (int)Requires[i].value, results[i]); break;

                case Require.CrewCapacityMax: TestReq((c, r) => c <= r, vd.CrewCapacity, (int)Requires[i].value, results[i]); break;

                case Require.AstronautComplexLevelMin: TestReq((c, r) => c >= r, GetFacilityLevel(SpaceCenterFacility.AstronautComplex), (int)Requires[i].value, results[i]); break;

                case Require.AstronautComplexLevelMax: TestReq((c, r) => c <= r, GetFacilityLevel(SpaceCenterFacility.AstronautComplex), (int)Requires[i].value, results[i]); break;

                case Require.TrackingStationLevelMin: TestReq((c, r) => c >= r, GetFacilityLevel(SpaceCenterFacility.TrackingStation), (int)Requires[i].value, results[i]); break;

                case Require.TrackingStationLevelMax: TestReq((c, r) => c <= r, GetFacilityLevel(SpaceCenterFacility.TrackingStation), (int)Requires[i].value, results[i]); break;

                case Require.MissionControlLevelMin: TestReq((c, r) => c >= r, GetFacilityLevel(SpaceCenterFacility.MissionControl), (int)Requires[i].value, results[i]); break;

                case Require.MissionControlLevelMax: TestReq((c, r) => c <= r, GetFacilityLevel(SpaceCenterFacility.MissionControl), (int)Requires[i].value, results[i]); break;

                case Require.AdministrationLevelMin: TestReq((c, r) => c >= r, GetFacilityLevel(SpaceCenterFacility.Administration), (int)Requires[i].value, results[i]); break;

                case Require.AdministrationLevelMax: TestReq((c, r) => c <= r, GetFacilityLevel(SpaceCenterFacility.Administration), (int)Requires[i].value, results[i]); break;

                case Require.Shadow: TestReq(() => vd.EnvInFullShadow, results[i]); break;

                case Require.Sunlight: TestReq(() => vd.EnvInSunlight, results[i]); break;

                case Require.Greenhouse: TestReq(() => vd.Greenhouses.Count > 0, results[i]); break;

                case Require.AbsoluteZero: TestReq(() => vd.EnvTemperature < 30.0, results[i]); break;

                case Require.InnerBelt: TestReq(() => vd.EnvInnerBelt, results[i]); break;

                case Require.OuterBelt: TestReq(() => vd.EnvOuterBelt, results[i]); break;

                case Require.MagneticBelt: TestReq(() => vd.EnvInnerBelt || vd.EnvOuterBelt, results[i]); break;

                case Require.Magnetosphere: TestReq(() => vd.EnvMagnetosphere, results[i]); break;

                case Require.InterStellar: TestReq(() => Lib.IsSun(v.mainBody) && vd.EnvInterstellar, results[i]); break;

                case Require.Part: TestReq(() => Lib.HasPart(v, (string)Requires[i].value), results[i]); break;

                case Require.Module: TestReq(() => Lib.FindModules(v.protoVessel, (string)Requires[i].value).Count > 0, results[i]); break;

                default: results[i].isValid = true; break;
                }

                if (!testAll && !results[i].isValid)
                {
                    UnityEngine.Profiling.Profiler.EndSample();
                    return(false);
                }

                good &= results[i].isValid;
            }

            UnityEngine.Profiling.Profiler.EndSample();
            return(good);
        }
Example #27
0
        public AntennaInfo(Vessel v)
        {
            // initialize data
            type       = new List <AntennaType>();
            cost       = new List <double>();
            rate       = new List <double>();
            dist       = new List <double>();
            relay      = new List <bool>();
            no_antenna = true;

            // get ec available
            // - this is the amount available at previous simulation step
            bool ec_available = ResourceCache.Info(v, "ElectricCharge").amount > double.Epsilon;

            // if the vessel is loaded
            if (v.loaded)
            {
                // get all antennas data
                foreach (Antenna a in Lib.FindModules <Antenna>(v))
                {
                    if (!Settings.ExtendedAntenna || a.extended)
                    {
                        type.Add(a.type);
                        cost.Add(a.cost);
                        rate.Add(a.rate);
                        dist.Add(a.dist);
                        relay.Add(ec_available && a.relay);
                        is_relay    |= ec_available && a.relay;
                        direct_cost += a.cost;
                        if (a.type == AntennaType.low_gain)
                        {
                            indirect_cost += a.cost;
                        }
                    }
                    no_antenna = false;
                }
            }
            // if the vessel isn't loaded
            // - we don't support multiple antenna modules per-part
            else
            {
                // 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 module prefab
                    Antenna a = part_prefab.FindModuleImplementing <Antenna>();

                    // if there is none, skip the part
                    if (a == null)
                    {
                        continue;
                    }

                    // for each module
                    foreach (ProtoPartModuleSnapshot m in p.modules)
                    {
                        // we are only interested in antennas
                        if (m.moduleName != "Antenna")
                        {
                            continue;
                        }

                        // if the module is disabled, skip it
                        if (!Lib.Proto.GetBool(m, "isEnabled"))
                        {
                            continue;
                        }

                        // get antenna data
                        if (!Settings.ExtendedAntenna || Lib.Proto.GetBool(m, "extended"))
                        {
                            bool antenna_is_relay = Lib.Proto.GetBool(m, "relay");
                            type.Add(a.type);
                            cost.Add(a.cost);
                            rate.Add(a.rate);
                            dist.Add(a.dist);
                            relay.Add(ec_available && antenna_is_relay);
                            is_relay    |= ec_available && antenna_is_relay;
                            direct_cost += a.cost;
                            if (a.type == AntennaType.low_gain)
                            {
                                indirect_cost += a.cost;
                            }
                        }
                        no_antenna = false;
                    }
                }
            }
        }
Example #28
0
        // 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 "Harvester":                     dev = new HarvesterDevice(m as Harvester);                break;

                    case "Laboratory":                    dev = new LaboratoryDevice(m as Laboratory);              break;

                    case "Antenna":                       dev = new AntennaDevice(m as Antenna);                    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;

                    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 "Harvester":                     dev = new ProtoHarvesterDevice(m, module_prefab as Harvester, p.flightID);                break;

                        case "Laboratory":                    dev = new ProtoLaboratoryDevice(m, p.flightID);                                           break;

                        case "Antenna":                       dev = new ProtoAntennaDevice(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;

                        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);
        }
Example #29
0
        public static string TestRequirements(string experiment_id, string requirements, Vessel v)
        {
            CelestialBody body = v.mainBody;
            Vessel_info   vi   = Cache.VesselInfo(v);

            List <string> list = Lib.Tokenize(requirements, ',');

            foreach (string s in list)
            {
                var parts = Lib.Tokenize(s, ':');

                var    condition = parts[0];
                string value     = string.Empty;
                if (parts.Count > 1)
                {
                    value = parts[1];
                }

                bool good = true;
                switch (condition)
                {
                case "OrbitMinInclination": good = Math.Abs(v.orbit.inclination) >= double.Parse(value); break;

                case "OrbitMaxInclination": good = Math.Abs(v.orbit.inclination) <= double.Parse(value); break;

                case "OrbitMinEccentricity": good = v.orbit.eccentricity >= double.Parse(value); break;

                case "OrbitMaxEccentricity": good = v.orbit.eccentricity <= double.Parse(value); break;

                case "OrbitMinArgOfPeriapsis": good = v.orbit.argumentOfPeriapsis >= double.Parse(value); break;

                case "OrbitMaxArgOfPeriapsis": good = v.orbit.argumentOfPeriapsis <= double.Parse(value); break;

                case "TemperatureMin": good = vi.temperature >= double.Parse(value); break;

                case "TemperatureMax": good = vi.temperature <= double.Parse(value); break;

                case "AltitudeMin": good = v.altitude >= double.Parse(value); break;

                case "AltitudeMax": good = v.altitude <= double.Parse(value); break;

                case "RadiationMin": good = vi.radiation >= double.Parse(value); break;

                case "RadiationMax": good = vi.radiation <= double.Parse(value); break;

                case "Microgravity": good = vi.zerog; break;

                case "Body": good = TestBody(v.mainBody.name, value); break;

                case "Shadow": good = vi.sunlight < double.Epsilon; break;

                case "Sunlight": good = vi.sunlight > 0.5; break;

                case "CrewMin": good = vi.crew_count >= int.Parse(value); break;

                case "CrewMax": good = vi.crew_count <= int.Parse(value); break;

                case "CrewCapacityMin": good = vi.crew_capacity >= int.Parse(value); break;

                case "CrewCapacityMax": good = vi.crew_capacity <= int.Parse(value); break;

                case "VolumePerCrewMin": good = vi.volume_per_crew >= double.Parse(value); break;

                case "VolumePerCrewMax": good = vi.volume_per_crew <= double.Parse(value); break;

                case "Greenhouse": good = vi.greenhouses.Count > 0; break;

                case "Surface": good = Lib.Landed(v); break;

                case "Atmosphere": good = body.atmosphere && v.altitude < body.atmosphereDepth; break;

                case "AtmosphereBody": good = body.atmosphere; break;

                case "AtmosphereAltMin": good = body.atmosphere && (v.altitude / body.atmosphereDepth) >= double.Parse(value); break;

                case "AtmosphereAltMax": good = body.atmosphere && (v.altitude / body.atmosphereDepth) <= double.Parse(value); break;

                case "BodyWithAtmosphere": good = body.atmosphere; break;

                case "BodyWithoutAtmosphere": good = !body.atmosphere; break;

                case "SunAngleMin": good = Lib.IsSun(v.mainBody) || Lib.SunBodyAngle(v) >= double.Parse(value); break;

                case "SunAngleMax": good = Lib.IsSun(v.mainBody) || Lib.SunBodyAngle(v) <= double.Parse(value); break;

                case "Vacuum": good = !body.atmosphere || v.altitude > body.atmosphereDepth; break;

                case "Ocean": good = body.ocean && v.altitude < 0.0; break;

                case "PlanetarySpace": good = body.flightGlobalsIndex != 0 && !Lib.Landed(v) && v.altitude > body.atmosphereDepth; break;

                case "AbsoluteZero": good = vi.temperature < 30.0; break;

                case "InnerBelt": good = vi.inner_belt; break;

                case "OuterBelt": good = vi.outer_belt; break;

                case "MagneticBelt": good = vi.inner_belt || vi.outer_belt; break;

                case "Magnetosphere": good = vi.magnetosphere; break;

                case "Thermosphere": good = vi.thermosphere; break;

                case "Exosphere": good = vi.exosphere; break;

                case "InterPlanetary": good = body.flightGlobalsIndex == 0 && !vi.interstellar; break;

                case "InterStellar": good = body.flightGlobalsIndex == 0 && vi.interstellar; break;

                case "SurfaceSpeedMin": good = v.srfSpeed >= double.Parse(value); break;

                case "SurfaceSpeedMax": good = v.srfSpeed <= double.Parse(value); break;

                case "VerticalSpeedMin": good = v.verticalSpeed >= double.Parse(value); break;

                case "VerticalSpeedMax": good = v.verticalSpeed <= double.Parse(value); break;

                case "SpeedMin": good = v.speed >= double.Parse(value); break;

                case "SpeedMax": good = v.speed <= double.Parse(value); break;

                case "DynamicPressureMin": good = v.dynamicPressurekPa >= double.Parse(value); break;

                case "DynamicPressureMax": good = v.dynamicPressurekPa <= double.Parse(value); break;

                case "StaticPressureMin": good = v.staticPressurekPa >= double.Parse(value); break;

                case "StaticPressureMax": good = v.staticPressurekPa <= double.Parse(value); break;

                case "AtmDensityMin": good = v.atmDensity >= double.Parse(value); break;

                case "AtmDensityMax": good = v.atmDensity <= double.Parse(value); break;

                case "AltAboveGroundMin": good = v.heightFromTerrain >= double.Parse(value); break;

                case "AltAboveGroundMax": good = v.heightFromTerrain <= double.Parse(value); break;

                case "Part": good = Lib.HasPart(v, value); break;

                case "Module": good = Lib.FindModules(v.protoVessel, value).Count > 0; break;

                case "AstronautComplexLevelMin":
                    good = (ScenarioUpgradeableFacilities.Instance == null) || ScenarioUpgradeableFacilities.GetFacilityLevel(SpaceCenterFacility.AstronautComplex) >= (double.Parse(value) - 1) / 2.0;
                    break;

                case "AstronautComplexLevelMax":
                    good = (ScenarioUpgradeableFacilities.Instance == null) || ScenarioUpgradeableFacilities.GetFacilityLevel(SpaceCenterFacility.AstronautComplex) <= (double.Parse(value) - 1) / 2.0;
                    break;

                case "TrackingStationLevelMin":
                    good = (ScenarioUpgradeableFacilities.Instance == null) || ScenarioUpgradeableFacilities.GetFacilityLevel(SpaceCenterFacility.TrackingStation) >= (double.Parse(value) - 1) / 2.0;
                    break;

                case "TrackingStationLevelMax":
                    good = (ScenarioUpgradeableFacilities.Instance == null) || ScenarioUpgradeableFacilities.GetFacilityLevel(SpaceCenterFacility.TrackingStation) <= (double.Parse(value) - 1) / 2.0;
                    break;

                case "MissionControlLevelMin":
                    good = (ScenarioUpgradeableFacilities.Instance == null) || ScenarioUpgradeableFacilities.GetFacilityLevel(SpaceCenterFacility.MissionControl) >= (double.Parse(value) - 1) / 2.0;
                    break;

                case "MissionControlLevelMax":
                    good = (ScenarioUpgradeableFacilities.Instance == null) || ScenarioUpgradeableFacilities.GetFacilityLevel(SpaceCenterFacility.MissionControl) <= (double.Parse(value) - 1) / 2.0;
                    break;

                case "AdministrationLevelMin":
                    good = (ScenarioUpgradeableFacilities.Instance == null) || ScenarioUpgradeableFacilities.GetFacilityLevel(SpaceCenterFacility.Administration) >= (double.Parse(value) - 1) / 2.0;
                    break;

                case "AdministrationLevelMax":
                    good = (ScenarioUpgradeableFacilities.Instance == null) || ScenarioUpgradeableFacilities.GetFacilityLevel(SpaceCenterFacility.Administration) <= (double.Parse(value) - 1) / 2.0;
                    break;

                case "MaxAsteroidDistance": good = AsteroidDistance(v) <= double.Parse(value); break;
                }

                if (!good)
                {
                    return(s);
                }
            }

            var subject_id = Science.Generate_subject_id(experiment_id, v);

            var exp = Science.Experiment(subject_id);
            var sit = GetExperimentSituation(v);

            if (!v.loaded && sit.AtmosphericFlight())
            {
                return("Background flight");
            }

            if (!sit.IsAvailable(exp))
            {
                return("Invalid situation");
            }


            // At this point we know the situation is valid and the experiment can be done
            // create it in R&D
            Science.Generate_subject(experiment_id, v);

            return(string.Empty);
        }
        static bool Prefix(ref ProtoVessel pv, ref bool quick)
        {
            if (pv == null)
            {
                return(true);
            }

            // get a hard drive. any hard drive will do, no need to find a specific one.
            ProtoPartModuleSnapshot protoHardDrive = null;

            foreach (var p in pv.protoPartSnapshots)
            {
                foreach (var pm in Lib.FindModules(p, "HardDrive"))
                {
                    protoHardDrive = pm;
                    break;
                }
                if (protoHardDrive != null)
                {
                    break;
                }
            }

            if (protoHardDrive == null)
            {
                return(true);                // no drive on the vessel - nothing to do.
            }
            double scienceToCredit = 0.0;

            List <DialogGUIBase> labels = new List <DialogGUIBase>();

            foreach (Drive drive in Drive.GetDrives(pv, true))
            {
                foreach (File file in drive.files.Values)
                {
                    double subjectValue = file.subjectData.ScienceValue(file.size);
                    file.subjectData.RemoveScienceCollectedInFlight(subjectValue);

                    if (file.useStockCrediting)
                    {
                        file.ConvertToStockData().Save(protoHardDrive.moduleValues.AddNode("ScienceData"));

                        if (!file.subjectData.ExistsInRnD)
                        {
                            file.subjectData.CreateSubjectInRnD();
                        }

                        file.subjectData.SetAsPersistent();
                        file.subjectData.UpdateSubjectCompletion(subjectValue);
                    }
                    else
                    {
                        scienceToCredit += file.subjectData.RetrieveScience(subjectValue, false, pv);

                        labels.Add(new DialogGUILabel(Lib.BuildString(
                                                          Lib.Color("+ " + subjectValue.ToString("F1"), Lib.Kolor.Science),
                                                          " (",
                                                          Lib.Color(file.subjectData.ScienceRetrievedInKSC.ToString("F1"), Lib.Kolor.Science, true),
                                                          " / ",
                                                          Lib.Color(file.subjectData.ScienceMaxValue.ToString("F1"), Lib.Kolor.Science, true),
                                                          ") : ",
                                                          file.subjectData.FullTitle
                                                          )));
                    }
                }

                foreach (Sample sample in drive.samples.Values)
                {
                    double subjectValue = sample.subjectData.ScienceValue(sample.size);
                    sample.subjectData.RemoveScienceCollectedInFlight(subjectValue);

                    if (sample.useStockCrediting)
                    {
                        sample.ConvertToStockData().Save(protoHardDrive.moduleValues.AddNode("ScienceData"));

                        if (!sample.subjectData.ExistsInRnD)
                        {
                            sample.subjectData.CreateSubjectInRnD();
                        }

                        sample.subjectData.SetAsPersistent();
                        sample.subjectData.UpdateSubjectCompletion(subjectValue);
                    }
                    else
                    {
                        scienceToCredit += sample.subjectData.RetrieveScience(subjectValue, false, pv);

                        labels.Add(new DialogGUILabel(Lib.BuildString(
                                                          Lib.Color("+ " + subjectValue.ToString("F1"), Lib.Kolor.Science),
                                                          " (",
                                                          Lib.Color(sample.subjectData.ScienceRetrievedInKSC.ToString("F1"), Lib.Kolor.Science, true),
                                                          " / ",
                                                          Lib.Color(sample.subjectData.ScienceMaxValue.ToString("F1"), Lib.Kolor.Science, true),
                                                          ") : ",
                                                          sample.subjectData.FullTitle
                                                          )));
                    }
                }
            }

            protoHardDrive.moduleName = "ModuleScienceContainer";

            if (scienceToCredit > 0.0)
            {
                // ideally we should hack the stock dialog to add the little science widgets to it but I'm lazy
                // plus it looks like crap anyway
                PopupDialog.SpawnPopupDialog
                (
                    new MultiOptionDialog
                    (
                        "scienceResults", "", pv.vesselName + " " + Local.VesselRecovery_title, HighLogic.UISkin, new Rect(0.3f, 0.5f, 350f, 100f),                      //" recovery"
                        new DialogGUIVerticalLayout
                        (
                            new DialogGUIBox(Local.VesselRecovery_info + " : " + Lib.Color(scienceToCredit.ToString("F1") + " " + Local.VesselRecovery_CREDITS, Lib.Kolor.Science, true), 340f, 30f),                            //"SCIENCE RECOVERED"" CREDITS"
                            new DialogGUIScrollList
                            (
                                new Vector2(340f, 250f), false, true,
                                new DialogGUIVerticalLayout(labels.ToArray())
                            ),
                            new DialogGUIButton(Local.VesselRecovery_OKbutton, null, 340f, 30f, true, HighLogic.UISkin.button)                            //"OK"
                        )
                    ),
                    false, HighLogic.UISkin
                );
            }

            return(true);            // continue to the original code
        }