示例#1
0
        protected virtual List <ModuleDataTransmitter> GetTransmittersLoaded(Vessel v)
        {
            List <ModuleDataTransmitter> transmitters;

            if (!Cache.HasVesselObjectsCache(v, "commnet"))
            {
                // find transmitters
                transmitters = v.FindPartModulesImplementing <ModuleDataTransmitter>();
                if (transmitters == null)
                {
                    transmitters = new List <ModuleDataTransmitter>();
                }

                // Disable all stock buttons
                // TODO : moved from the update method (AntennaInfo()) to here to save performance, but maybe that is called too early and doesn't work
                foreach (ModuleDataTransmitter mdt in transmitters)
                {
                    mdt.Events["TransmitIncompleteToggle"].active = false;
                    mdt.Events["StartTransmission"].active        = false;
                    mdt.Events["StopTransmission"].active         = false;
                    mdt.Actions["StartTransmissionAction"].active = false;
                }

                Cache.SetVesselObjectsCache(v, "commnet", transmitters);
            }
            else
            {
                transmitters = Cache.VesselObjectsCache <List <ModuleDataTransmitter> >(v, "commnet");
            }

            return(transmitters);
        }
示例#2
0
        protected virtual List <KeyValuePair <ModuleDataTransmitter, ProtoPartSnapshot> > GetTransmittersUnloaded(Vessel v)
        {
            List <KeyValuePair <ModuleDataTransmitter, ProtoPartSnapshot> > transmitters;

            if (!Cache.HasVesselObjectsCache(v, "commnet_bg"))
            {
                transmitters = new List <KeyValuePair <ModuleDataTransmitter, ProtoPartSnapshot> >();

                // 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 (ModuleDataTransmitter t in part_prefab.FindModulesImplementing <ModuleDataTransmitter>())
                    {
                        transmitters.Add(new KeyValuePair <ModuleDataTransmitter, ProtoPartSnapshot>(t, p));
                    }
                }

                Cache.SetVesselObjectsCache(v, "commnet_bg", transmitters);
            }
            else
            {
                // cache transmitters
                transmitters = Cache.VesselObjectsCache <List <KeyValuePair <ModuleDataTransmitter, ProtoPartSnapshot> > >(v, "commnet_bg");
            }

            return(transmitters);
        }
示例#3
0
        public static void BackgroundUpdate(Vessel v, ProtoPartModuleSnapshot m, KerbalismProcess process, Resource_info ec, Vessel_resources resources, double elapsed_s)
        {
            if (!process.unloaded)
            {
                return;
            }

            List <KeyValuePair <string, double> > resourcesProduced;
            List <KeyValuePair <string, double> > resourcesConsumed;

            if (!Cache.HasVesselObjectsCache(v, "kerbalism_process_produced_" + process.part.flightID))
            {
                resourcesProduced = ParseResources(process.resources_produced, false);
                Cache.SetVesselObjectsCache <List <KeyValuePair <string, double> > >(v, "kerbalism_process_produced_" + process.part.flightID, resourcesProduced);
            }
            else
            {
                resourcesProduced = Cache.VesselObjectsCache <List <KeyValuePair <string, double> > >(v, "kerbalism_process_produced_" + process.part.flightID);
            }

            if (!Cache.HasVesselObjectsCache(v, "kerbalism_process_consumed_" + process.part.flightID))
            {
                resourcesConsumed = ParseResources(process.resources_produced, false);
                Cache.SetVesselObjectsCache <List <KeyValuePair <string, double> > >(v, "kerbalism_process_consumed_" + process.part.flightID, resourcesConsumed);
            }
            else
            {
                resourcesConsumed = Cache.VesselObjectsCache <List <KeyValuePair <string, double> > >(v, "kerbalism_process_consumed_" + process.part.flightID);
            }

            RunProcessTick(v, elapsed_s, process.ec_produced, resourcesProduced, process.ec_consumed, resourcesConsumed, ec, resources);
        }
示例#4
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>())
                {
                    if (DB.drives.ContainsKey(hd.part.flightID))
                    {
                        result.Add(hd.part.flightID, DB.drives[hd.part.flightID]);
                    }
                }
            }
            else
            {
                foreach (var hd in vessel.protoVessel.protoPartSnapshots)
                {
                    if (DB.drives.ContainsKey(hd.flightID))
                    {
                        result.Add(hd.flightID, DB.drives[hd.flightID]);
                    }
                }
            }

            Cache.SetVesselObjectsCache(vessel, "drives", result);
            return(result);
        }
示例#5
0
        protected virtual List <KeyValuePair <ModuleDataTransmitter, ProtoPartModuleSnapshot> > GetTransmittersUnloaded(Vessel v)
        {
            List <KeyValuePair <ModuleDataTransmitter, ProtoPartModuleSnapshot> > transmitters;

            if (!Cache.HasVesselObjectsCache(v, "commnet_bg"))
            {
                transmitters = new List <KeyValuePair <ModuleDataTransmitter, ProtoPartModuleSnapshot> >();

                // find proto transmitters
                foreach (ProtoPartSnapshot pps in v.protoVessel.protoPartSnapshots)
                {
                    // get part prefab (required for module properties)
                    Part part_prefab = pps.partInfo.partPrefab;

                    for (int i = 0; i < part_prefab.Modules.Count; i++)
                    {
                        if (part_prefab.Modules[i] is ModuleDataTransmitter mdt)
                        {
                            ProtoPartModuleSnapshot ppms;
                            // We want to also get a possible ModuleDataTransmitter derivative but type checking isn't available
                            // so we check a specific value present on the base class (See ModuleDataTransmitter.OnSave())
                            if (pps.modules[i].moduleValues.HasValue("canComm"))
                            {
                                ppms = pps.modules[i];
                            }
                            // fallback in case the module indexes are messed up
                            else
                            {
                                ppms = pps.FindModule("ModuleDataTransmitter");
                                Lib.LogDebug($"Could not find a ModuleDataTransmitter or derivative at index {i} on part {pps.partName} on vessel {v.protoVessel.vesselName}", Lib.LogLevel.Warning);
                            }

                            if (ppms != null)
                            {
                                transmitters.Add(new KeyValuePair <ModuleDataTransmitter, ProtoPartModuleSnapshot>(mdt, ppms));
                            }
                        }
                    }
                }

                Cache.SetVesselObjectsCache(v, "commnet_bg", transmitters);
            }
            else
            {
                // cache transmitters
                transmitters = Cache.VesselObjectsCache <List <KeyValuePair <ModuleDataTransmitter, ProtoPartModuleSnapshot> > >(v, "commnet_bg");
            }

            return(transmitters);
        }
示例#6
0
        public static ConnectionInfo Update(Vessel v, bool powered, bool storm)
        {
            var result = Cache.VesselObjectsCache <ConnectionInfo>(v, "connection_info");
            var ts     = Cache.VesselObjectsCache <double>(v, "connection_info_ts");
            var maxAge = Math.Max(2, Kerbalism.elapsed_s * 2);

            if (result == null || Planetarium.GetUniversalTime() > ts + maxAge)
            {
                result = new ConnectionInfo(v, powered, storm);
                Cache.SetVesselObjectsCache(v, "connection_info", result);
                Cache.SetVesselObjectsCache(v, "connection_info_ts", Planetarium.GetUniversalTime());
            }

            return(result);
        }
示例#7
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);
        }
示例#8
0
        protected virtual List <ModuleDataTransmitter> GetTransmittersLoaded(Vessel v)
        {
            List <ModuleDataTransmitter> transmitters;

            if (!Cache.HasVesselObjectsCache(v, "commnet"))
            {
                // find transmitters
                transmitters = v.FindPartModulesImplementing <ModuleDataTransmitter>();
                if (transmitters == null)
                {
                    transmitters = new List <ModuleDataTransmitter>();
                }
                Cache.SetVesselObjectsCache(v, "commnet", transmitters);
            }
            else
            {
                transmitters = Cache.VesselObjectsCache <List <ModuleDataTransmitter> >(v, "commnet");
            }

            return(transmitters);
        }
示例#9
0
        void ToEVA(GameEvents.FromToAction <Part, Part> data)
        {
            OnVesselModified(data.from.vessel);
            OnVesselModified(data.to.vessel);

            // get total crew in the origin vessel
            double tot_crew = Lib.CrewCount(data.from.vessel) + 1.0;

            // get vessel resources handler
            VesselResources resources = ResourceCache.Get(data.from.vessel);

            // setup supply resources capacity in the eva kerbal
            Profile.SetupEva(data.to);

            String prop_name = Lib.EvaPropellantName();

            // for each resource in the kerbal
            for (int i = 0; i < data.to.Resources.Count; ++i)
            {
                // get the resource
                PartResource res = data.to.Resources[i];

                // eva prop is handled differently
                if (res.resourceName == prop_name)
                {
                    continue;
                }

                double quantity = Math.Min(resources.GetResource(data.from.vessel, res.resourceName).Amount / tot_crew, res.maxAmount);
                // remove resource from vessel
                quantity = data.from.RequestResource(res.resourceName, quantity);

                // add resource to eva kerbal
                data.to.RequestResource(res.resourceName, -quantity);
            }

            // take as much of the propellant as possible. just imagine: there are 1.3 units left, and 12 occupants
            // in the ship. you want to send out an engineer to fix the chemical plant that produces monoprop,
            // and have to get from one end of the station to the other with just 0.1 units in the tank...
            // nope.
            double evaPropQuantity = data.from.RequestResource(prop_name, Lib.EvaPropellantCapacity());

            // We can't just add the monoprop here, because that doesn't always work. It might be related
            // to the fact that stock KSP wants to add 5 units of monoprop to new EVAs. Instead of fighting KSP here,
            // we just let it do it's thing and set our amount later in EVA.cs - which seems to work just fine.
            // don't put that into Cache.VesselInfo because that can be deleted before we get there
            Cache.SetVesselObjectsCache(data.to.vessel, "eva_prop", evaPropQuantity);

            // Airlock loss
            resources.Consume(data.from.vessel, "Nitrogen", Settings.LifeSupportAtmoLoss, ResourceBroker.Generic);

            // show warning if there is little or no EVA propellant in the suit
            if (evaPropQuantity <= 0.05 && !Lib.Landed(data.from.vessel))
            {
                Message.Post(Severity.danger,
                             Local.CallBackMsg_EvaNoMP.Format("<b>" + prop_name + "</b>"), Local.CallBackMsg_EvaNoMP2);       //Lib.BuildString("There isn't any <<1>> in the EVA suit")"Don't let the ladder go!"
            }

            // turn off headlamp light, to avoid stock bug that show them for a split second when going on eva
            KerbalEVA kerbal = data.to.FindModuleImplementing <KerbalEVA>();

            EVA.HeadLamps(kerbal, false);

            // execute script
            data.from.vessel.KerbalismData().computer.Execute(data.from.vessel, ScriptType.eva_out);
        }
示例#10
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);
        }
示例#11
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)
        {
            var devices = Cache.VesselObjectsCache <Dictionary <uint, Device> >(v, "computer");

            if (devices != null)
            {
                return(devices);
            }

            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 "Sickbay":                      dev = new SickbayDevice(m as Sickbay);                           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":
                    case "ModuleDataTransmitter":        dev = new Antenna(m, m.moduleName);                              break;

                    case "ModuleRTAntennaPassive":       dev = new Antenna(m, "ModuleRTAntenna"); 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>();

                var experiments = new List <KeyValuePair <Experiment, ProtoPartModuleSnapshot> >();

                // 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 "Sickbay":                      dev = new ProtoSickbayDevice(m, module_prefab as Sickbay, 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":
                            experiments.Add(new KeyValuePair <Experiment, ProtoPartModuleSnapshot>(module_prefab as Experiment, m));
                            dev = new ProtoExperimentDevice(m, module_prefab as Experiment, p.flightID, experiments);
                            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":
                        case "ModuleDataTransmitter":        dev = new ProtoPartAntenna(m, p, v, m.moduleName, p.flightID);                                   break;

                        case "ModuleRTAntennaPassive":       dev = new ProtoPartAntenna(m, p, v, "ModuleRTAntenna", 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);
                        }
                    }
                }
            }

            devices = devices.OrderBy(k => k.Value.Name()).ToDictionary(pair => pair.Key, pair => pair.Value);
            //return all found devices sorted by name

            Cache.SetVesselObjectsCache(v, "computer", devices);
            return(devices);
        }
示例#12
0
        public AntennaInfoCommNet(Vessel v, bool powered, bool storm, bool transmitting)
        {
            int transmitterCount = 0;

            rate = 1;
            double ec_transmitter = 0;

            // if vessel is loaded
            if (v.loaded)
            {
                List <ModuleDataTransmitter> transmitters;

                if (!Cache.HasVesselObjectsCache(v, "commnet"))
                {
                    // find transmitters
                    transmitters = v.FindPartModulesImplementing <ModuleDataTransmitter>();
                    if (transmitters == null)
                    {
                        transmitters = new List <ModuleDataTransmitter>();
                    }
                    Cache.SetVesselObjectsCache(v, "commnet", transmitters);
                }
                else
                {
                    transmitters = Cache.VesselObjectsCache <List <ModuleDataTransmitter> >(v, "commnet");
                }

                foreach (ModuleDataTransmitter t in transmitters)
                {
                    // Disable all stock buttons
                    t.Events["TransmitIncompleteToggle"].active = false;
                    t.Events["StartTransmission"].active        = false;
                    t.Events["StopTransmission"].active         = false;
                    t.Actions["StartTransmissionAction"].active = false;

                    if (t.antennaType == AntennaType.INTERNAL)                     // do not include internal data rate, ec cost only
                    {
                        ec += t.DataResourceCost * t.DataRate;
                    }
                    else
                    {
                        // do we have an animation
                        ModuleDeployableAntenna animation        = t.part.FindModuleImplementing <ModuleDeployableAntenna>();
                        ModuleAnimateGeneric    animationGeneric = t.part.FindModuleImplementing <ModuleAnimateGeneric>();
                        if (animation != null)
                        {
                            // only include data rate and ec cost if transmitter is extended
                            if (animation.deployState == ModuleDeployablePart.DeployState.EXTENDED)
                            {
                                rate *= t.DataRate;
                                transmitterCount++;
                                var e = t.DataResourceCost * t.DataRate;
                                ec_transmitter += e;
                            }
                        }
                        else if (animationGeneric != null)
                        {
                            // only include data rate and ec cost if transmitter is extended
                            if (animationGeneric.animSpeed > 0)
                            {
                                rate *= t.DataRate;
                                transmitterCount++;
                                var e = t.DataResourceCost * t.DataRate;
                                ec_transmitter += e;
                            }
                        }
                        // no animation
                        else
                        {
                            rate *= t.DataRate;
                            transmitterCount++;
                            var e = t.DataResourceCost * t.DataRate;
                            ec_transmitter += e;
                        }
                    }
                }
            }
            // if vessel is not loaded
            else
            {
                List <KeyValuePair <ModuleDataTransmitter, ProtoPartSnapshot> > transmitters;
                if (!Cache.HasVesselObjectsCache(v, "commnet_bg"))
                {
                    transmitters = new List <KeyValuePair <ModuleDataTransmitter, ProtoPartSnapshot> >();
                    // 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 (ModuleDataTransmitter t in part_prefab.FindModulesImplementing <ModuleDataTransmitter>())
                        {
                            transmitters.Add(new KeyValuePair <ModuleDataTransmitter, ProtoPartSnapshot>(t, p));
                        }
                    }

                    Cache.SetVesselObjectsCache(v, "commnet_bg", transmitters);
                }
                else
                {
                    // cache transmitters
                    transmitters = Cache.VesselObjectsCache <List <KeyValuePair <ModuleDataTransmitter, ProtoPartSnapshot> > >(v, "commnet_bg");
                }

                foreach (var pair in transmitters)
                {
                    ModuleDataTransmitter t = pair.Key;
                    ProtoPartSnapshot     p = pair.Value;

                    if (t.antennaType == AntennaType.INTERNAL)                     // do not include internal data rate, ec cost only
                    {
                        ec += t.DataResourceCost * t.DataRate;
                    }
                    else
                    {
                        // do we have an animation
                        ProtoPartModuleSnapshot m = p.FindModule("ModuleDeployableAntenna") ?? p.FindModule("ModuleAnimateGeneric");
                        if (m != null)
                        {
                            // only include data rate and ec cost if transmitter is extended
                            string deployState = Lib.Proto.GetString(m, "deployState");
                            float  animSpeed   = Lib.Proto.GetFloat(m, "animSpeed");
                            if (deployState == "EXTENDED" || animSpeed > 0)
                            {
                                rate *= t.DataRate;
                                transmitterCount++;
                                ec_transmitter += t.DataResourceCost * t.DataRate;
                            }
                        }
                        // no animation
                        else
                        {
                            rate *= t.DataRate;
                            transmitterCount++;
                            ec_transmitter += t.DataResourceCost * t.DataRate;
                        }
                    }
                }
            }

            if (transmitterCount > 1)
            {
                rate = Math.Pow(rate, 1.0 / transmitterCount);
            }
            else if (transmitterCount == 0)
            {
                rate = 0;
            }

            // when transmitting, transmitters need more EC for the signal amplifiers.
            // while not transmitting, transmitters only use 10-20% of that
            ec_transmitter *= transmitting ? Settings.TransmitterActiveEcFactor : Settings.TransmitterPassiveEcFactor;

            ec += ec_transmitter;

            Init(v, powered, storm);
        }
示例#13
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);
        }
示例#14
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);
        }