Exemple #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);
        }
Exemple #2
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);
        }
Exemple #3
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);
        }
Exemple #4
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;
			}
		}
Exemple #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);
        }
Exemple #6
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);
        }
Exemple #7
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);
        }
Exemple #8
0
        public Vessel_info(Vessel v, Guid vessel_id, UInt64 inc)
        {
            // NOTE: anything used here can't in turn use cache, unless you know what you are doing

            // NOTE: you can't cache vessel position
            // at any point in time all vessel/body positions are relative to a different frame of reference
            // so comparing the current position of a vessel, with the cached one of another make no sense

            // associate with an unique incremental id
            this.inc = inc;

            // determine if this is a valid vessel
            is_vessel = Lib.IsVessel(v);
            if (!is_vessel)
            {
                return;
            }

            // determine if this is a rescue mission vessel
            is_rescue = Misc.IsRescueMission(v);
            if (is_rescue)
            {
                return;
            }

            // dead EVA are not valid vessels
            if (EVA.IsDead(v))
            {
                return;
            }

            // shortcut for common tests
            is_valid = true;

            // generate id once
            id = vessel_id;

            // calculate crew info for the vessel
            crew_count    = Lib.CrewCount(v);
            crew_capacity = Lib.CrewCapacity(v);

            // get vessel position
            Vector3d position = Lib.VesselPosition(v);

            // this should never happen again
            if (Vector3d.Distance(position, v.mainBody.position) < 1.0)
            {
                throw new Exception("Shit hit the fan for vessel " + v.vesselName);
            }

            // determine if there is enough EC for a powered state
            powered = Lib.IsPowered(v);

            // determine if in sunlight, calculate sun direction and distance
            sunlight = Sim.RaytraceBody(v, position, FlightGlobals.Bodies[0], out sun_dir, out sun_dist) ? 1.0 : 0.0;

            // environment stuff
            atmo_factor        = Sim.AtmosphereFactor(v.mainBody, position, sun_dir);
            gamma_transparency = Sim.GammaTransparency(v.mainBody, v.altitude);
            underwater         = Sim.Underwater(v);
            breathable         = Sim.Breathable(v, underwater);
            landed             = Lib.Landed(v);
            zerog = !landed && (!v.mainBody.atmosphere || v.mainBody.atmosphereDepth < v.altitude);

            if (v.mainBody.flightGlobalsIndex != 0 && TimeWarp.CurrentRate > 1000.0f)
            {
                highspeedWarp(v);
            }

            // temperature at vessel position
            temperature = Sim.Temperature(v, position, sunlight, atmo_factor, out solar_flux, out albedo_flux, out body_flux, out total_flux);
            temp_diff   = Sim.TempDiff(temperature, v.mainBody, landed);

            // radiation
            radiation = Radiation.Compute(v, position, gamma_transparency, sunlight, out blackout, out magnetosphere, out inner_belt, out outer_belt, out interstellar);

            // extended atmosphere
            thermosphere = Sim.InsideThermosphere(v);
            exosphere    = Sim.InsideExosphere(v);

            // malfunction stuff
            malfunction = Reliability.HasMalfunction(v);
            critical    = Reliability.HasCriticalFailure(v);

            // communications info
            connection   = ConnectionInfo.Update(v, powered, blackout);
            transmitting = Science.Transmitting(v, connection.linked && connection.rate > double.Epsilon);

            // habitat data
            volume  = Habitat.Tot_volume(v);
            surface = Habitat.Tot_surface(v);

            if (Cache.HasVesselObjectsCache(v, "max_pressure"))
            {
                max_pressure = Cache.VesselObjectsCache <double>(v, "max_pressure");
            }
            pressure = Math.Min(max_pressure, Habitat.Pressure(v));

            evas            = (uint)(Math.Max(0, ResourceCache.Info(v, "Nitrogen").amount - 330) / PreferencesLifeSupport.Instance.evaAtmoLoss);
            poisoning       = Habitat.Poisoning(v);
            humidity        = Habitat.Humidity(v);
            shielding       = Habitat.Shielding(v);
            living_space    = Habitat.Living_space(v);
            volume_per_crew = Habitat.Volume_per_crew(v);
            comforts        = new Comforts(v, landed, crew_count > 1, connection.linked && connection.rate > double.Epsilon);

            // data about greenhouses
            greenhouses = Greenhouse.Greenhouses(v);

            // other stuff
            gravioli = Sim.Graviolis(v);

            Drive.GetCapacity(v, out free_capacity, out total_capacity);
        }