コード例 #1
0
        public override void OnFixedUpdate()
        {
            if (scoopIsEnabled)
            {
                string atmospheric_resource_name = ORSAtmosphericResourceHandler.getAtmosphericResourceName(vessel.mainBody.flightGlobalsIndex, currentresource);
                if (atmospheric_resource_name != null)
                {
                    double resourcedensity = PartResourceLibrary.Instance.GetDefinition(atmospheric_resource_name).density;
                    double respcent        = ORSAtmosphericResourceHandler.getAtmosphericResourceContent(vessel.mainBody.flightGlobalsIndex, currentresource);
                    //double resourcedensity = PartResourceLibrary.Instance.GetDefinition(PluginHelper.atomspheric_resources_tocollect[currentresource]).density;
                    //double respcent = PluginHelper.getAtmosphereResourceContent(vessel.mainBody.flightGlobalsIndex, currentresource);

                    double airdensity        = part.vessel.atmDensity / 1000;
                    double powerrequirements = scoopair / 0.15f * 6f;

                    double airspeed = part.vessel.srf_velocity.magnitude + 40.0;
                    double air      = airspeed * airdensity * scoopair / resourcedensity;

                    if (respcent > 0 && vessel.altitude <= PluginHelper.getMaxAtmosphericAltitude(vessel.mainBody))
                    {
                        double scoopedAtm = air * respcent;

                        float powerreceived = Math.Max(consumeFNResource(powerrequirements * TimeWarp.fixedDeltaTime, FNResourceManager.FNRESOURCE_MEGAJOULES), 0);
                        float powerpcnt     = (float)(powerreceived / powerrequirements / TimeWarp.fixedDeltaTime);

                        //resflowf = (float)part.RequestResource(atmospheric_resource_name, -scoopedAtm * powerpcnt * TimeWarp.fixedDeltaTime);
                        resflowf = (float)ORSHelper.fixedRequestResource(part, atmospheric_resource_name, -scoopedAtm * powerpcnt * TimeWarp.fixedDeltaTime);
                        resflowf = -resflowf / TimeWarp.fixedDeltaTime;
                    }
                }
                else
                {
                }
            }
        }
コード例 #2
0
ファイル: VanAllen.cs プロジェクト: keichan34/KSPInterstellar
        public static double getRadiationLevel(int refBody, double altitude, double lat)
        {
            lat = lat / 180 * Math.PI;

            CelestialBody crefbody           = FlightGlobals.fetch.bodies[refBody];
            CelestialBody crefkerbin         = FlightGlobals.fetch.bodies[1];
            double        atmosphere         = FlightGlobals.getStaticPressure(altitude, crefbody);
            double        atmosphere_height  = PluginHelper.getMaxAtmosphericAltitude(crefbody);
            double        atmosphere_scaling = Math.Exp(-atmosphere);

            double mp    = crefbody.Mass;
            double rp    = crefbody.Radius;
            double rt    = crefbody.rotationPeriod;
            double relmp = mp / crefkerbin.Mass;
            double relrp = rp / crefkerbin.Radius;
            double relrt = rt / crefkerbin.rotationPeriod;

            double peakbelt      = 1.5 * crefkerbin.Radius * relrp;
            double peakbelt2     = 6 * crefkerbin.Radius * relrp;
            double altituded     = altitude;
            double a             = peakbelt / Math.Sqrt(2);
            double b             = peakbelt2 / Math.Sqrt(2);
            double beltparticles = Math.Sqrt(2 / Math.PI) * Math.Pow(altituded, 2) * Math.Exp(-Math.Pow(altituded, 2) / (2.0 * Math.Pow(a, 2))) / (Math.Pow(a, 3)) + 0.9 * Math.Sqrt(2 / Math.PI) * Math.Pow(altituded, 2) * Math.Exp(-Math.Pow(altituded, 2) / (2.0 * Math.Pow(b, 2))) / (Math.Pow(b, 3));

            beltparticles = beltparticles * relrp / relrt * 50.0;

            if (crefbody.flightGlobalsIndex == 0)
            {
                beltparticles = beltparticles / 1000;
            }

            beltparticles = beltparticles * Math.Abs(Math.Cos(lat)) * getSpecialMagneticFieldScaling(refBody) * atmosphere_scaling;

            return(beltparticles);
        }
コード例 #3
0
        protected override void pluginSpecificImpl()
        {
            if (resource_name == FNRESOURCE_CHARGED_PARTICLES)
            {
                flow_type = FNRESOURCE_FLOWTYPE_EVEN;
            }

            if (String.Equals(this.resource_name, FNResourceManager.FNRESOURCE_WASTEHEAT))   // passive dissip of waste heat - a little bit of this
            {
                double vessel_mass    = my_vessel.GetTotalMass();
                double passive_dissip = passive_temp_p4 * GameConstants.stefan_const * vessel_mass * 2.0;
                internl_power_extract += passive_dissip * TimeWarp.fixedDeltaTime;

                if (my_vessel.altitude <= PluginHelper.getMaxAtmosphericAltitude(my_vessel.mainBody))   // passive convection - a lot of this
                {
                    double pressure          = FlightGlobals.getStaticPressure(my_vessel.transform.position);
                    double delta_temp        = 20;
                    double conv_power_dissip = pressure * delta_temp * vessel_mass * 2.0 * GameConstants.rad_const_h / 1e6 * TimeWarp.fixedDeltaTime;
                    internl_power_extract += conv_power_dissip;
                }

                if (internl_power_extract < 0 && PluginHelper.isThermalDissipationDisabled())   // set buildup/dissip of waste heat to 0 if waste heat is disabled
                {
                    internl_power_extract = 0;
                }
            }
        }
コード例 #4
0
        public override void OnFixedUpdate()
        {
            if (FlightGlobals.fetch != null)
            {
                if (!bIsEnabled)
                {
                    strCollectingStatus = "Disabled";
                    strStarDist         = UpdateDistanceInGUI(); // passes the distance to the GUI
                    return;
                }

                if (vessel.altitude < (PluginHelper.getMaxAtmosphericAltitude(vessel.mainBody))) // won't collect in atmosphere
                {
                    ScreenMessages.PostScreenMessage("Solar wind collection not possible in atmosphere", 10.0f, ScreenMessageStyle.LOWER_CENTER);
                    strStarDist      = UpdateDistanceInGUI();
                    strSolarWindConc = "0";
                    DisableCollector();
                    return;
                }

                strStarDist = UpdateDistanceInGUI();

                // collect solar wind for a single frame
                CollectSolarWind(TimeWarp.fixedDeltaTime, false);

                // store current time in case vesel is unloaded
                fLastActiveTime = (float)Planetarium.GetUniversalTime();
            }
        }
コード例 #5
0
        public static double GetBeltAntiparticles(this CelestialBody body, double altitude, double lat)
        {
            lat = (lat / 180 * Math.PI);
            CelestialBody crefkerbin = FlightGlobals.fetch.bodies[PluginHelper.REF_BODY_KERBIN];

            double atmosphere_height = PluginHelper.getMaxAtmosphericAltitude(body);

            if (altitude <= atmosphere_height && body.flightGlobalsIndex != 0)
            {
                return(0);
            }

            double mp    = body.Mass;
            double rp    = body.Radius;
            double rt    = body.rotationPeriod;
            double relmp = mp / crefkerbin.Mass;
            double relrp = rp / crefkerbin.Radius;
            double relrt = rt / crefkerbin.rotationPeriod;

            double peakbelt      = 1.5 * crefkerbin.Radius * relrp;
            double altituded     = ((double)altitude);
            double a             = peakbelt / Math.Sqrt(2);
            double beltparticles = Math.Sqrt(2 / Math.PI) * Math.Pow(altituded, 2) * Math.Exp(-Math.Pow(altituded, 2) / (2.0 * Math.Pow(a, 2))) / (Math.Pow(a, 3));

            beltparticles = beltparticles * relmp * relrp / relrt * 50.0;

            if (body.flightGlobalsIndex == 0)
            {
                beltparticles = beltparticles / 1000;
            }

            beltparticles = beltparticles * Math.Abs(Math.Cos(lat)) * body.specialMagneticFieldScaling();
            return(beltparticles);
        }
コード例 #6
0
        public static double GetProtonRadiationLevel(this CelestialBody body, CelestialBody homeworld, double altitude, double lat)
        {
            lat = lat / 180 * Math.PI;

            double atmosphere         = FlightGlobals.getStaticPressure(altitude, body) / 100;
            double atmosphere_height  = PluginHelper.getMaxAtmosphericAltitude(body);
            double atmosphere_scaling = Math.Exp(-atmosphere);

            double mp    = body.Mass;
            double rp    = body.Radius;
            double rt    = body.rotationPeriod;
            double relrp = rp / homeworld.Radius;
            double relrt = rt / homeworld.rotationPeriod;

            double peakbelt      = body.GetPeakProtonBeltAltitude(homeworld, altitude, lat);
            double altituded     = altitude;
            double a             = peakbelt / Math.Sqrt(2);
            double beltparticles = Math.Sqrt(2 / Math.PI) * Math.Pow(altituded, 2) * Math.Exp(-Math.Pow(altituded, 2) / (2 * Math.Pow(a, 2))) / (Math.Pow(a, 3));

            beltparticles = beltparticles * relrp / relrt * 50;

            if (body.flightGlobalsIndex == 0)
            {
                beltparticles = beltparticles / 1000;
            }

            beltparticles = beltparticles * Math.Abs(Math.Cos(lat)) * body.specialMagneticFieldScaling() * atmosphere_scaling;

            return(beltparticles);
        }
コード例 #7
0
        public static double GetElectronRadiationLevel(this CelestialBody body, double altitude, double lat)
        {
            lat = lat / 180 * Math.PI;
            CelestialBody crefkerbin         = FlightGlobals.fetch.bodies[PluginHelper.REF_BODY_KERBIN];
            double        atmosphere         = FlightGlobals.getStaticPressure(altitude, body) / 100;
            double        atmosphere_height  = PluginHelper.getMaxAtmosphericAltitude(body);
            double        atmosphere_scaling = Math.Exp(-atmosphere);

            double mp    = body.Mass;
            double rp    = body.Radius;
            double rt    = body.rotationPeriod;
            double relrp = rp / crefkerbin.Radius;
            double relrt = rt / crefkerbin.rotationPeriod;

            double peakbelt2     = body.GetPeakElectronBeltAltitude(altitude, lat);
            double altituded     = altitude;
            double b             = peakbelt2 / Math.Sqrt(2);
            double beltparticles = 0.9 * Math.Sqrt(2 / Math.PI) * Math.Pow(altituded, 2) * Math.Exp(-Math.Pow(altituded, 2) / (2.0 * Math.Pow(b, 2))) / (Math.Pow(b, 3));

            beltparticles = beltparticles * relrp / relrt * 50.0;

            if (body.flightGlobalsIndex == 0)
            {
                beltparticles = beltparticles / 1000;
            }

            beltparticles = beltparticles * Math.Abs(Math.Cos(lat)) * body.specialMagneticFieldScaling() * atmosphere_scaling;

            return(beltparticles);
        }
コード例 #8
0
        public override void OnUpdate()
        {
            Events["ActivateCollector"].active   = !bIsEnabled; // will activate the event (i.e. show the gui button) if the process is not enabled
            Events["DisableCollector"].active    = bIsEnabled;  // will show the button when the process IS enabled
            Fields["strReceivedPower"].guiActive = bIsEnabled;

            solarWindMolesPerSquareMeterPerSecond = CalculateSolarwindIonConcentration(part.vessel.solarFlux, solarCheatMultiplier, solarWindSpeed);
            interstellarDustMolesPerCubicMeter    = CalculateInterstellarIonConcentration(interstellarCheatMultiplier);

            var dAtmosphereConcentration = CalculateCurrentAtmosphereConcentration(vessel);

            var dHydrogenParticleConcentration = CalculateCurrentHydrogenParticleConcentration(vessel);
            var dHeliumParticleConcentration   = CalculateCurrentHeliumParticleConcentration(vessel);

            var dIonizedHydrogenConcentration = CalculateCurrentHydrogenIonsConcentration(vessel);
            var dIonizedHeliumConcentration   = CalculateCurrentHeliumIonsConcentration(vessel);

            hydrogenMolarMassConcentrationPerSquareMeterPerSecond = bIonizing ? dHydrogenParticleConcentration : dIonizedHydrogenConcentration;
            heliumMolarMassConcentrationPerSquareMeterPerSecond   = bIonizing ? dHeliumParticleConcentration: dIonizedHeliumConcentration;

            fSolarWindConcentrationPerSquareMeter       = (float)solarWindMolesPerSquareMeterPerSecond;
            fInterstellarIonsConcentrationPerCubicMeter = (float)interstellarDustMolesPerCubicMeter;
            fAtmosphereConcentration      = (float)dAtmosphereConcentration;
            fNeutralHydrogenConcentration = (float)dHydrogenParticleConcentration;
            fNeutralHeliumConcentration   = (float)dHeliumParticleConcentration;

            fIonizedHydrogenConcentration = (float)dIonizedHydrogenConcentration;
            fIonizedHeliumConcentration   = (float)dIonizedHeliumConcentration;

            magnetoSphereStrengthRatio = GetMagnetosphereRatio(vessel.altitude, PluginHelper.getMaxAtmosphericAltitude(vessel.mainBody));
            strMagnetoStrength         = UpdateMagnetoStrengthInGui();
        }
コード例 #9
0
        private void Window(int windowID)
        {
            bold_label           = new GUIStyle(GUI.skin.label);
            bold_label.fontStyle = FontStyle.Bold;
            if (GUI.Button(new Rect(windowPosition.width - 20, 2, 18, 18), "x"))
            {
                render_window = false;
            }

            GUILayout.BeginVertical();
            if (vessel.altitude < PluginHelper.getMaxAtmosphericAltitude(vessel.mainBody))
            {
                if (analysis_count > analysis_length)
                {
                    GUILayout.BeginHorizontal();
                    GUILayout.Label("Gas", bold_label, GUILayout.Width(150));
                    GUILayout.Label("Abundance", bold_label, GUILayout.Width(150));
                    GUILayout.EndHorizontal();
                    GUILayout.Space(5);
                    foreach (AtmosphericResource atmospheric_resource in AtmosphericResourceHandler.GetAtmosphericCompositionForBody(vessel.mainBody.flightGlobalsIndex).Values)
                    {
                        GUILayout.BeginHorizontal();
                        GUILayout.Label(atmospheric_resource.DisplayName, GUILayout.Width(150));
                        string resource_abundance_str;
                        if (atmospheric_resource.ResourceAbundance > 0.001)
                        {
                            resource_abundance_str = (atmospheric_resource.ResourceAbundance * 100.0).ToString() + "%";
                        }
                        else
                        {
                            if (atmospheric_resource.ResourceAbundance > 0.000001)
                            {
                                resource_abundance_str = (atmospheric_resource.ResourceAbundance * 1e6).ToString() + " ppm";
                            }
                            else
                            {
                                resource_abundance_str = (atmospheric_resource.ResourceAbundance * 1e9).ToString() + " ppb";
                            }
                        }
                        GUILayout.Label(resource_abundance_str, GUILayout.Width(150));
                        GUILayout.EndHorizontal();
                    }
                }
                else
                {
                    double percent_analysed = (double)analysis_count / analysis_length * 100;
                    GUILayout.BeginHorizontal();
                    GUILayout.Label("Analysing...", GUILayout.Width(150));
                    GUILayout.Label(percent_analysed.ToString("0.00") + "%", GUILayout.Width(150));
                    GUILayout.EndHorizontal();
                }
            }
            else
            {
                GUILayout.Label("--No Atmosphere to Sample--", GUILayout.ExpandWidth(true));
                analysis_count = 0;
            }
            GUILayout.EndVertical();
            GUI.DragWindow();
        }
コード例 #10
0
        public override void OnFixedUpdate()
        {
            if (FlightGlobals.fetch != null)
            {
                if (!bIsEnabled)
                {
                    strCollectingStatus = "Disabled";
                    strStarDist         = UpdateDistanceInGUI(); // passes the distance to the GUI
                    return;
                }

                // won't collect in atmosphere
                if (IsCollectLegal() == false)
                {
                    DisableCollector();
                    return;
                }

                strStarDist = UpdateDistanceInGUI();

                // collect solar wind for a single frame
                CollectSolarWind(TimeWarp.fixedDeltaTime, false);

                // store current time in case vesel is unloaded
                dLastActiveTime = Planetarium.GetUniversalTime();

                // store current strength of the magnetic field in case vessel is unloaded
                dLastMagnetoStrength = GetMagnetosphereRatio(vessel.altitude, PluginHelper.getMaxAtmosphericAltitude(vessel.mainBody));

                // store current solar wind concentration in case vessel is unloaded
                dLastSolarConcentration = CalculateSolarWindConcentration(part.vessel.solarFlux);
            }
        }
コード例 #11
0
        public override void OnStart(PartModule.StartState state)
        {
            if (state == StartState.Editor)
            {
                return;                             // collecting won't work in editor
            }
            this.part.force_activate();

            localStar = GetCurrentStar();

            // get the part's animation
            anim = part.FindModelAnimators(animName).FirstOrDefault();

            // this bit goes through parts that contain animations and disables the "Status" field in GUI so that it's less crowded
            List <ModuleAnimateGeneric> MAGlist = part.FindModulesImplementing <ModuleAnimateGeneric>();

            foreach (ModuleAnimateGeneric MAG in MAGlist)
            {
                MAG.Fields["status"].guiActive       = false;
                MAG.Fields["status"].guiActiveEditor = false;
            }

            // verify collector was enabled
            if (!bIsEnabled)
            {
                return;
            }

            // verify a timestamp is available
            if (dLastActiveTime == 0)
            {
                return;
            }

            // verify any power was available in previous state
            if (dLastPowerPercentage < 0.01)
            {
                return;
            }

            // verify altitude is not too low
            if (vessel.altitude < (PluginHelper.getMaxAtmosphericAltitude(vessel.mainBody)))
            {
                ScreenMessages.PostScreenMessage("Solar Wind Collection Error, vessel in atmosphere", 10, ScreenMessageStyle.LOWER_CENTER);
                return;
            }

            // if the part should be extended (from last time), go to the extended animation
            if (bIsExtended == true && anim != null)
            {
                anim[animName].normalizedTime = 1;
            }

            // calculate time difference since last time the vessel was active
            double dTimeDifference = (Planetarium.GetUniversalTime() - dLastActiveTime) * 55;

            // collect solar wind for entire duration
            CollectSolarWind(dTimeDifference, true);
        }
コード例 #12
0
 public static bool IsInAtmosphere(this Vessel vessel)
 {
     if (vessel.altitude <= PluginHelper.getMaxAtmosphericAltitude(vessel.mainBody))
     {
         return(true);
     }
     return(false);
 }
コード例 #13
0
        public void FixedUpdate()
        {
            if (HighLogic.LoadedSceneIsFlight)
            {
                ElectricEngineControllerFX.getAllPropellants().ForEach(prop => part.Effect(prop.ParticleFXName, 0)); // set all FX to zero

                if (current_propellant != null && attachedEngine != null)
                {
                    updateISP();
                    List <ElectricEngineControllerFX> electric_engine_list = vessel.FindPartModulesImplementing <ElectricEngineControllerFX>();
                    int    engine_count      = electric_engine_list.Count;
                    double total_max_thrust  = evaluateMaxThrust();
                    double thrust_per_engine = total_max_thrust / (double)engine_count;
                    double power_per_engine  = Math.Min(0.5 * attachedEngine.currentThrottle * thrust_per_engine * current_propellant.IspMultiplier * baseISP / 1000.0 * 9.81, maxPower * current_propellant.Efficiency);
                    double power_received    = consumeFNResource(power_per_engine * TimeWarp.fixedDeltaTime / current_propellant.Efficiency, FNResourceManager.FNRESOURCE_MEGAJOULES) / TimeWarp.fixedDeltaTime;
                    double heat_to_produce   = power_received * (1.0 - current_propellant.Efficiency);
                    double heat_production   = supplyFNResource(heat_to_produce * TimeWarp.fixedDeltaTime, FNResourceManager.FNRESOURCE_WASTEHEAT) / TimeWarp.fixedDeltaTime;
                    // update GUI Values
                    electrical_consumption_f = (float)power_received;
                    heat_production_f        = (float)heat_production;
                    // thrust values
                    double thrust_ratio      = power_per_engine > 0 ? Math.Min(power_received / power_per_engine, 1.0) : 1;
                    double actual_max_thrust = current_propellant.Efficiency * 2000.0f * power_received / (current_propellant.IspMultiplier * baseISP * 9.81f * attachedEngine.currentThrottle);

                    if (attachedEngine.currentThrottle > 0)
                    {
                        if (!double.IsNaN(actual_max_thrust) && !double.IsInfinity(actual_max_thrust))
                        {
                            attachedEngine.maxThrust = Mathf.Max((float)actual_max_thrust, 0.00001f);
                        }
                        else
                        {
                            attachedEngine.maxThrust = 0.00001f;
                        }
                        float fx_ratio = Mathf.Min(electrical_consumption_f / maxPower, attachedEngine.finalThrust / attachedEngine.maxThrust);
                        part.Effect(current_propellant.ParticleFXName, fx_ratio);
                    }

                    if (isupgraded)
                    {
                        List <PartResource> vacuum_resources = part.GetConnectedResources("VacuumPlasma").ToList();
                        double vacuum_plasma_needed          = vacuum_resources.Sum(vc => vc.maxAmount - vc.amount);
                        double vacuum_plasma_current         = vacuum_resources.Sum(vc => vc.amount);
                        if (vessel.altitude < PluginHelper.getMaxAtmosphericAltitude(vessel.mainBody))
                        {
                            part.RequestResource("VacuumPlasma", vacuum_plasma_current);
                        }
                        else
                        {
                            part.RequestResource("VacuumPlasma", -vacuum_plasma_needed);
                        }
                    }
                }
            }
        }
コード例 #14
0
        public void ActivateWarpDrive()
        {
            if (IsEnabled)
            {
                return;
            }

            Vessel vess = this.part.vessel;

            //float atmosphere_height = vess.mainBody.maxAtmosphereAltitude;
            if (vess.altitude <= PluginHelper.getMaxAtmosphericAltitude(vess.mainBody) && vess.mainBody.flightGlobalsIndex != 0)
            {
                ScreenMessages.PostScreenMessage("Cannot activate warp drive within the atmosphere!", 5.0f, ScreenMessageStyle.UPPER_CENTER);
                return;
            }

            var resources = new List <PartResource>();

            part.GetConnectedResources(PartResourceLibrary.Instance.GetDefinition("ExoticMatter").id, resources);
            float electrical_current_available = 0;

            for (int i = 0; i < resources.Count; ++i)
            {
                electrical_current_available += (float)resources.ElementAt(i).amount;
            }
            if (electrical_current_available < megajoules_required * warp_factors[selected_factor])
            {
                ScreenMessages.PostScreenMessage("Warp drive charging!", 5.0f, ScreenMessageStyle.UPPER_CENTER);
                return;
            }
            part.RequestResource("ExoticMatter", megajoules_required * warp_factors[selected_factor]);
            warp_sound.Play();
            warp_sound.loop = true;


            //Orbit planetOrbit = vessel.orbit.referenceBody.orbit;
            Vector3d heading = part.transform.up;
            double   temp1   = heading.y;

            heading.y = heading.z;
            heading.z = temp1;

            Vector3d position = vessel.orbit.pos;

            heading              = heading * GameConstants.warpspeed * warp_factors[selected_factor];
            heading_act          = heading;
            serialisedwarpvector = ConfigNode.WriteVector(heading);

            vessel.GoOnRails();

            vessel.orbit.UpdateFromStateVectors(position, vessel.orbit.vel + heading, vessel.orbit.referenceBody, Planetarium.GetUniversalTime());
            vessel.GoOffRails();
            IsEnabled = true;
        }
コード例 #15
0
        public void ActivateWarpDrive()
        {
            if (IsEnabled)
            {
                return;
            }

            isDeactivatingWarpDrive = false;
            Vessel vess = this.part.vessel;

            //float atmosphere_height = vess.mainBody.maxAtmosphereAltitude;
            if (vess.altitude <= PluginHelper.getMaxAtmosphericAltitude(vess.mainBody) && vess.mainBody.flightGlobalsIndex != 0)
            {
                ScreenMessages.PostScreenMessage("Cannot activate warp drive within the atmosphere!", 5.0f, ScreenMessageStyle.UPPER_CENTER);
                return;
            }

            List <PartResource> resources = part.GetConnectedResources(InterstellarResourcesConfiguration.Instance.ExoticMatter).ToList();
            float exotic_matter_available = (float)resources.Sum(res => res.amount);
            var   powerRequiredForWarp    = megajoules_required * warp_factors[selected_factor];

            if (exotic_matter_available < powerRequiredForWarp)
            {
                ScreenMessages.PostScreenMessage("Warp drive isn't fully charged yet for Warp!", 5.0f, ScreenMessageStyle.UPPER_CENTER);
                return;
            }

            var totalConsumedPower = PluginHelper.LimitedWarpTravel
                ? (0.5 * powerRequiredForWarp) + (exotic_matter_available - powerRequiredForWarp)
                : powerRequiredForWarp;

            part.RequestResource(InterstellarResourcesConfiguration.Instance.ExoticMatter, totalConsumedPower);
            warp_sound.Play();
            warp_sound.loop = true;

            //Orbit planetOrbit = vessel.orbit.referenceBody.orbit;
            Vector3d heading = part.transform.up;
            double   temp1   = heading.y;

            heading.y = heading.z;
            heading.z = temp1;

            Vector3d position = vessel.orbit.pos;

            heading              = heading * GameConstants.warpspeed * warp_factors[selected_factor];
            heading_act          = heading;
            serialisedwarpvector = ConfigNode.WriteVector(heading);

            vessel.GoOnRails();
            vessel.orbit.UpdateFromStateVectors(position, vessel.orbit.vel + heading, vessel.orbit.referenceBody, Planetarium.GetUniversalTime());
            vessel.GoOffRails();
            IsEnabled = true;
        }
コード例 #16
0
        public void ActivateWarpDrive()
        {
            if (IsEnabled)
            {
                return;
            }

            isDeactivatingWarpDrive = false;

            if (warpToMassRatio < 1)
            {
                ScreenMessages.PostScreenMessage("Not enough warp power to warp vessel", 5.0f, ScreenMessageStyle.UPPER_CENTER);
                return;
            }

            Vessel vess = this.part.vessel;

            if (vess.altitude <= PluginHelper.getMaxAtmosphericAltitude(vess.mainBody) && vess.mainBody.flightGlobalsIndex != 0)
            {
                ScreenMessages.PostScreenMessage("Cannot activate warp drive within the atmosphere!", 5.0f, ScreenMessageStyle.UPPER_CENTER);
                return;
            }

            double exotic_matter_available;
            double total_exotic_matter_available;

            part.GetConnectedResourceTotals(exoticResourceDefinition.id, out exotic_matter_available, out total_exotic_matter_available);

            if (exotic_matter_available < exotic_power_required)
            {
                ScreenMessages.PostScreenMessage("Warp drive isn't fully charged yet for Warp!", 5.0f, ScreenMessageStyle.UPPER_CENTER);
                return;
            }

            if (maximumWarpSpeedFactor < selected_factor)
            {
                selected_factor = minimumPowerAllowedFactor;
            }

            float new_warpfactor = engine_throtle[selected_factor];

            currentPowerRequirementForWarp = GetPowerRequirementForWarp(new_warpfactor);

            if (!CheatOptions.InfiniteElectricity && currentPowerRequirementForWarp > getStableResourceSupply(FNResourceManager.FNRESOURCE_MEGAJOULES))
            {
                ScreenMessages.PostScreenMessage("Warp power requirement is higher that maximum power supply!", 5.0f, ScreenMessageStyle.UPPER_CENTER);
                return;
            }

            IsCharging          = false;
            initiateWarpTimeout = 10;
        }
コード例 #17
0
        public override void OnUpdate()
        {
            Events["ActivateCollector"].active = !bIsEnabled; // will activate the event (i.e. show the gui button) if the process is not enabled
            Events["DisableCollector"].active  = bIsEnabled;  // will show the button when the process IS enabled

            Fields["strReceivedPower"].guiActive = bIsEnabled;


            massConcentrationPerSquareMeterPerSecond = CalculateSolarWindConcentration(part.vessel.solarFlux);
            solarWindConcentration      = (float)massConcentrationPerSquareMeterPerSecond;
            dMagnetoSphereStrengthRatio = GetMagnetosphereRatio(vessel.altitude, PluginHelper.getMaxAtmosphericAltitude(vessel.mainBody));
            strMagnetoStrength          = UpdateMagnetoStrengthInGUI();
        }
コード例 #18
0
 // checks if the vessel is not in atmosphere and if it can therefore collect solar wind. Could incorporate other checks if needed.
 private bool IsCollectLegal()
 {
     if (vessel.altitude < (PluginHelper.getMaxAtmosphericAltitude(vessel.mainBody)) / 2) // won't collect in atmosphere
     {
         ScreenMessages.PostScreenMessage("Solar wind collection not possible in low atmosphere", 10, ScreenMessageStyle.LOWER_CENTER);
         distanceToLocalStar = UpdateDistanceInGui();
         fSolarWindConcentrationPerSquareMeter = 0;
         return(false);
     }
     else
     {
         return(true);
     }
 }
コード例 #19
0
        public void ActivateWarpDrive()
        {
            if (IsEnabled)
            {
                return;
            }

            isDeactivatingWarpDrive = false;

            if (warpToMassRatio < 1)
            {
                ScreenMessages.PostScreenMessage("Not enough warp power to warp vessel", 5.0f, ScreenMessageStyle.UPPER_CENTER);
                return;
            }

            Vessel vess = this.part.vessel;

            if (vess.altitude <= PluginHelper.getMaxAtmosphericAltitude(vess.mainBody) && vess.mainBody.flightGlobalsIndex != 0)
            {
                ScreenMessages.PostScreenMessage("Cannot activate warp drive within the atmosphere!", 5.0f, ScreenMessageStyle.UPPER_CENTER);
                return;
            }

            List <PartResource> resources = part.GetConnectedResources(InterstellarResourcesConfiguration.Instance.ExoticMatter).ToList();
            float exotic_matter_available = (float)resources.Sum(res => res.amount);

            if (exotic_matter_available < exotic_power_required)
            {
                ScreenMessages.PostScreenMessage("Warp drive isn't fully charged yet for Warp!", 5.0f, ScreenMessageStyle.UPPER_CENTER);
                return;
            }

            if (maximumWarpSpeedFactor < selected_factor)
            {
                selected_factor = minimumPowerAllowedFactor;
            }

            float new_warpfactor = engine_throtle[selected_factor];

            currentPowerRequirementForWarp = GetPowerRequirementForWarp(new_warpfactor);

            if (currentPowerRequirementForWarp > getStableResourceSupply(FNResourceManager.FNRESOURCE_MEGAJOULES))
            {
                ScreenMessages.PostScreenMessage("Warp power requirement is higher that maximum power supply!", 5.0f, ScreenMessageStyle.UPPER_CENTER);
                return;
            }

            IsCharging          = false;
            initiateWarpTimeout = 10;
        }
コード例 #20
0
        // checks if the vessel is not in atmosphere and if it can therefore collect solar wind. Could incorporate other checks if needed.
        private bool IsCollectLegal()
        {
            bool bCanCollect = false;

            if (vessel.altitude < (PluginHelper.getMaxAtmosphericAltitude(vessel.mainBody))) // won't collect in atmosphere
            {
                ScreenMessages.PostScreenMessage("Solar wind collection not possible in atmosphere", 10, ScreenMessageStyle.LOWER_CENTER);
                strStarDist            = UpdateDistanceInGUI();
                solarWindConcentration = 0;
                return(bCanCollect);
            }
            else
            {
                return(bCanCollect = true);
            }
        }
コード例 #21
0
ファイル: ISRUScoop.cs プロジェクト: Maeyanie/KSPInterstellar
        private void ScoopAthmosphere(double deltaTimeInSeconds, bool offlineCollecting)
        {
            string atmospheric_resource_name = ORSAtmosphericResourceHandler.getAtmosphericResourceName(vessel.mainBody.flightGlobalsIndex, currentresource);

            if (atmospheric_resource_name == null)
            {
                resflowf = 0.0f;
                return;
            }

            double resourcedensity = PartResourceLibrary.Instance.GetDefinition(atmospheric_resource_name).density;
            double respcent        = ORSAtmosphericResourceHandler.getAtmosphericResourceContent(vessel.mainBody.flightGlobalsIndex, currentresource);
            //double resourcedensity = PartResourceLibrary.Instance.GetDefinition(PluginHelper.atomspheric_resources_tocollect[currentresource]).density;
            //double respcent = PluginHelper.getAtmosphereResourceContent(vessel.mainBody.flightGlobalsIndex, currentresource);

            double airdensity        = (part.vessel.atmDensity + PluginHelper.MinAtmosphericAirDensity) / 1000.0;
            double powerrequirements = (scoopair / 0.15f) * 6f * (float)PluginHelper.PowerConsumptionMultiplier;

            double airspeed = part.vessel.srf_velocity.magnitude + 40.0;
            double air      = airspeed * airdensity * scoopair / resourcedensity;

            if (respcent == 0 || vessel.altitude > (PluginHelper.getMaxAtmosphericAltitude(vessel.mainBody) * PluginHelper.MaxAtmosphericAltitudeMult))
            {
                resflowf = 0.0f;
                return;
            }

            double scoopedAtm    = air * respcent;
            float  powerreceived = Math.Max(consumeFNResource(powerrequirements * TimeWarp.fixedDeltaTime, FNResourceManager.FNRESOURCE_MEGAJOULES), 0);

            last_power_percentage = offlineCollecting ? last_power_percentage : (float)(powerreceived / powerrequirements / TimeWarp.fixedDeltaTime);
            double resourceChange = scoopedAtm * last_power_percentage * deltaTimeInSeconds;

            if (offlineCollecting)
            {
                string numberformat = resourceChange > 100 ? "0" : "0.00";
                ScreenMessages.PostScreenMessage("Atmospheric Scoop collected " + resourceChange.ToString(numberformat) + " " + atmospheric_resource_name, 10.0f, ScreenMessageStyle.LOWER_CENTER);
            }

            //resflowf = (float)part.RequestResource(atmospheric_resource_name, -scoopedAtm * powerpcnt * TimeWarp.fixedDeltaTime);
            resflowf = (float)ORSHelper.fixedRequestResource(part, atmospheric_resource_name, -resourceChange);
            resflowf = -resflowf / TimeWarp.fixedDeltaTime;
        }
コード例 #22
0
        protected override void pluginSpecificImpl()
        {
            if (String.Equals(this.resource_name, FNResourceManager.FNRESOURCE_WASTEHEAT) && !PluginHelper.IsThermalDissipationDisabled)
            {
                // passive dissip of waste heat - a little bit of this
                double vessel_mass    = my_vessel.GetTotalMass();
                double passive_dissip = passive_temp_p4 * GameConstants.stefan_const * vessel_mass * 2;
                internl_power_extract_fixed += passive_dissip * TimeWarp.fixedDeltaTime;

                if (my_vessel.altitude <= PluginHelper.getMaxAtmosphericAltitude(my_vessel.mainBody))
                {
                    // passive convection - a lot of this
                    double pressure          = FlightGlobals.getStaticPressure(my_vessel.transform.position) / 100;
                    double delta_temp        = 20;
                    double conv_power_dissip = pressure * delta_temp * vessel_mass * 2.0 * GameConstants.rad_const_h / 1e6 * TimeWarp.fixedDeltaTime;
                    internl_power_extract_fixed += conv_power_dissip;
                }
            }
        }
コード例 #23
0
        public void FixedUpdate()
        {
            if (!HighLogic.LoadedSceneIsFlight)
            {
                return;
            }

            UpdateIonisationAnimation();

            if (FlightGlobals.fetch != null)
            {
                if (!bIsEnabled)
                {
                    strCollectingStatus = "Disabled";
                    distanceToLocalStar = UpdateDistanceInGui(); // passes the distance to the GUI
                    return;
                }

                // won't collect in atmosphere
                if (!IsCollectLegal())
                {
                    DisableCollector();
                    return;
                }

                distanceToLocalStar = UpdateDistanceInGui();

                // collect solar wind for a single frame
                CollectSolarWind(TimeWarp.fixedDeltaTime, false);

                // store current time in case vesel is unloaded
                dLastActiveTime = Planetarium.GetUniversalTime();

                // store current strength of the magnetic field in case vessel is unloaded
                dLastMagnetoStrength = GetMagnetosphereRatio(vessel.altitude, PluginHelper.getMaxAtmosphericAltitude(vessel.mainBody));

                // store current solar wind concentration in case vessel is unloaded
                dLastSolarConcentration    = solarWindMolesPerSquareMeterPerSecond; //CalculateSolarWindConcentration(part.vessel.solarFlux);
                dLastHydrogenConcentration = hydrogenMolarMassConcentrationPerSquareMeterPerSecond;
            }
        }
コード例 #24
0
        public override void OnStart(PartModule.StartState state)
        {
            if (state == StartState.Editor)
            {
                return;                             // collecting won't work in editor
            }
            this.part.force_activate();

            localStar = GetCurrentStar();

            // verify collector was enabled
            if (!bIsEnabled)
            {
                return;
            }

            // verify a timestamp is available
            if (fLastActiveTime == 0)
            {
                return;
            }

            // verify any power was available in previous state
            if (fLastPowerPercentage < 0.01)
            {
                return;
            }

            // verify altitude is not too low
            if (vessel.altitude < (PluginHelper.getMaxAtmosphericAltitude(vessel.mainBody)))
            {
                ScreenMessages.PostScreenMessage("Error, vessel is in atmosphere", 10.0f, ScreenMessageStyle.LOWER_CENTER);
                return;
            }

            // calculate time difference since last time the vessel was active
            double dTimeDifference = (Planetarium.GetUniversalTime() - fLastActiveTime) * 55;

            // collect solar wind for entire duration
            CollectSolarWind(dTimeDifference, true);
        }
コード例 #25
0
        public override void OnUpdate()
        {
            Events["ActivateCollector"].active = !bIsEnabled; // will activate the event (i.e. show the gui button) if the process is not enabled
            Events["DisableCollector"].active  = bIsEnabled;  // will show the button when the process IS enabled

            Fields["strReceivedPower"].guiActive = bIsEnabled;

            UpdateIonisationAnimation();

            var dSolarWindConcentration = CalculateSolarwindIonConcentration(part.vessel.solarFlux, solarCheatMultiplier);

            solarWindCollected = (float)dSolarWindConcentration;

            orbitalSpeed = part.vessel.obt_speed;
            var dInterstellarHydrogenConcentration = CalculateInterstellarIonConcentration(orbitalSpeed, interstellarCheatMultiplier);

            interstellarHydrogenCollected = (float)dInterstellarHydrogenConcentration;
            molarMassConcentrationPerSquareMeterPerSecond = dSolarWindConcentration + dInterstellarHydrogenConcentration;

            dMagnetoSphereStrengthRatio = GetMagnetosphereRatio(vessel.altitude, PluginHelper.getMaxAtmosphericAltitude(vessel.mainBody));
            strMagnetoStrength          = UpdateMagnetoStrengthInGUI();
        }
コード例 #26
0
ファイル: VanAllen.cs プロジェクト: keichan34/KSPInterstellar
        public static float getBeltAntiparticles(int refBody, float altitude, float lat)
        {
            lat = (float)(lat / 180 * Math.PI);
            CelestialBody crefbody   = FlightGlobals.fetch.bodies[refBody];
            CelestialBody crefkerbin = FlightGlobals.fetch.bodies[1];

            double atmosphere_height = PluginHelper.getMaxAtmosphericAltitude(crefbody);

            if (altitude <= atmosphere_height && crefbody.flightGlobalsIndex != 0)
            {
                return(0);
            }

            double mp    = crefbody.Mass;
            double rp    = crefbody.Radius;
            double rt    = crefbody.rotationPeriod;
            double relmp = mp / crefkerbin.Mass;
            double relrp = rp / crefkerbin.Radius;
            double relrt = rt / crefkerbin.rotationPeriod;

            double peakbelt      = 1.5 * crefkerbin.Radius * relrp;
            double altituded     = ((double)altitude);
            double a             = peakbelt / Math.Sqrt(2);
            double beltparticles = Math.Sqrt(2 / Math.PI) * Math.Pow(altituded, 2) * Math.Exp(-Math.Pow(altituded, 2) / (2.0 * Math.Pow(a, 2))) / (Math.Pow(a, 3));

            beltparticles = beltparticles * relmp * relrp / relrt * 50.0;

            if (crefbody.flightGlobalsIndex == 0)
            {
                beltparticles = beltparticles / 1000;
            }

            beltparticles = beltparticles * Math.Abs(Math.Cos(lat)) * getSpecialMagneticFieldScaling(refBody);

            return((float)beltparticles);
        }
コード例 #27
0
        private void ScoopAthmosphere(double deltaTimeInSeconds, bool offlineCollecting)
        {
            string ors_atmospheric_resource_name = AtmosphericResourceHandler.getAtmosphericResourceName(vessel.mainBody.flightGlobalsIndex, currentresource);
            string resourceDisplayName           = AtmosphericResourceHandler.getAtmosphericResourceDisplayName(vessel.mainBody.flightGlobalsIndex, currentresource);

            if (ors_atmospheric_resource_name == null)
            {
                resflowf      = 0;
                recievedPower = "error";
                densityFractionOfUpperAthmosphere = "error";
                return;
            }

            // map ors resource to kspi resource
            if (PluginHelper.OrsResourceMappings == null || !PluginHelper.OrsResourceMappings.TryGetValue(ors_atmospheric_resource_name, out resourceStoragename))
            {
                resourceStoragename = ors_atmospheric_resource_name;
            }
            else if (!PartResourceLibrary.Instance.resourceDefinitions.Contains(resourceStoragename))
            {
                resourceStoragename = ors_atmospheric_resource_name;
            }

            var definition = PartResourceLibrary.Instance.GetDefinition(resourceStoragename);

            if (definition == null)
            {
                return;
            }

            double resourcedensity       = definition.density;
            double maxAltitudeAtmosphere = PluginHelper.getMaxAtmosphericAltitude(vessel.mainBody);

            double upperAtmospherFraction = Math.Max(0, (vessel.altitude - maxAltitudeAtmosphere) / Math.Max(0.000001, maxAltitudeAtmosphere * PluginHelper.MaxAtmosphericAltitudeMult - maxAltitudeAtmosphere));
            double upperatmosphereDensity = 1 - upperAtmospherFraction;

            double airDensity = part.vessel.atmDensity + (PluginHelper.MinAtmosphericAirDensity * upperatmosphereDensity);

            atmosphericDensity = airDensity.ToString("0.00000000");

            var hydrogenTax = 0.4 * Math.Sin(upperAtmospherFraction * Math.PI * 0.5);
            var heliumTax   = 0.2 * Math.Sin(upperAtmospherFraction * Math.PI);

            double rescourceFraction = (1.0 - hydrogenTax - heliumTax) * AtmosphericResourceHandler.getAtmosphericResourceContent(vessel.mainBody.flightGlobalsIndex, currentresource);

            // increase density hydrogen
            if (resourceDisplayName == "Hydrogen")
            {
                rescourceFraction += hydrogenTax;
            }
            else if (resourceDisplayName == "Helium")
            {
                rescourceFraction += heliumTax;
            }

            densityFractionOfUpperAthmosphere = (upperatmosphereDensity * 100).ToString("0.000") + "%";
            rescourcePercentage = rescourceFraction * 100;
            if (rescourceFraction <= 0 || vessel.altitude > (PluginHelper.getMaxAtmosphericAltitude(vessel.mainBody) * PluginHelper.MaxAtmosphericAltitudeMult))
            {
                resflowf      = 0;
                recievedPower = "off";
                densityFractionOfUpperAthmosphere = "too high";
                rescourcePercentage = 0;
                return;
            }

            double airspeed            = part.vessel.srf_velocity.magnitude + 40;
            double air                 = airspeed * (airDensity / 1000) * scoopair / resourcedensity;
            double scoopedAtm          = air * rescourceFraction;
            double powerrequirementsMW = (scoopair / 0.15) * 6 * PluginHelper.PowerConsumptionMultiplier * powerReqMult;

            if (scoopedAtm > 0 && part.GetResourceSpareCapacity(resourceStoragename) > 0)
            {
                var powerRequest = powerrequirementsMW * TimeWarp.fixedDeltaTime;

                // calculate available power
                double powerreceivedMW = CheatOptions.InfiniteElectricity
                    ? powerRequest
                    : Math.Max(consumeFNResource(powerRequest, ResourceManager.FNRESOURCE_MEGAJOULES, TimeWarp.fixedDeltaTime), 0);

                double normalisedRevievedPowerMW = powerreceivedMW / TimeWarp.fixedDeltaTime;

                // if power requirement sufficiently low, retreive power from KW source
                if (powerrequirementsMW < 2 && normalisedRevievedPowerMW <= powerrequirementsMW)
                {
                    var requiredKW = (powerrequirementsMW - normalisedRevievedPowerMW) * 1000;
                    var recievedKW = part.RequestResource(ResourceManager.STOCK_RESOURCE_ELECTRICCHARGE, requiredKW * TimeWarp.fixedDeltaTime);
                    powerreceivedMW += (recievedKW / 1000);
                }

                last_power_percentage = offlineCollecting ? last_power_percentage : powerreceivedMW / powerrequirementsMW / TimeWarp.fixedDeltaTime;
            }
            else
            {
                last_power_percentage = 0;
                powerrequirementsMW   = 0;
            }

            recievedPower = powerrequirementsMW < 2
                ? (last_power_percentage * powerrequirementsMW * 1000).ToString("0.0") + " KW / " + (powerrequirementsMW * 1000).ToString("0.0") + " KW"
                : (last_power_percentage * powerrequirementsMW).ToString("0.0") + " MW / " + powerrequirementsMW.ToString("0.0") + " MW";

            double resourceChange = scoopedAtm * last_power_percentage * deltaTimeInSeconds;

            if (offlineCollecting)
            {
                string numberformat = resourceChange > 100 ? "0" : "0.00";
                ScreenMessages.PostScreenMessage("Atmospheric Scoop collected " + resourceChange.ToString(numberformat) + " " + resourceStoragename, 10.0f, ScreenMessageStyle.LOWER_CENTER);
            }

            resflowf = part.RequestResource(resourceStoragename, -resourceChange);
            resflowf = -resflowf / TimeWarp.fixedDeltaTime;
            UpdateResourceFlow();
        }
コード例 #28
0
        public override void OnStart(PartModule.StartState state)
        {
            Actions["ToggleToggleResourceAction"].guiName = Events["ToggleResource"].guiName = String.Format("Toggle Resource");

            if (state == StartState.Editor)
            {
                return;
            }

            this.part.force_activate();

            // verify if body has atmosphere at all
            if (!vessel.mainBody.atmosphere)
            {
                return;
            }

            // verify scoop was enabled
            if (!scoopIsEnabled)
            {
                return;
            }

            // verify a timestamp is available
            if (last_active_time == 0)
            {
                return;
            }

            // verify any power was avaialble in previous save
            if (last_power_percentage < 0.01)
            {
                return;
            }

            // verify altitude is not too high
            if (vessel.altitude > (PluginHelper.getMaxAtmosphericAltitude(vessel.mainBody) * PluginHelper.MaxAtmosphericAltitudeMult))
            {
                ScreenMessages.PostScreenMessage("Vessel is too high for resource accumulation", 10, ScreenMessageStyle.LOWER_CENTER);
                return;
            }

            // verify altitude is not too low
            if (vessel.altitude < (PluginHelper.getMaxAtmosphericAltitude(vessel.mainBody)))
            {
                ScreenMessages.PostScreenMessage("Vessel is too low for resource accumulation", 10, ScreenMessageStyle.LOWER_CENTER);
                return;
            }

            // verify eccentricity
            if (vessel.orbit.eccentricity > 0.1)
            {
                string message = "Eccentricity of " + vessel.orbit.eccentricity.ToString("0.0000") + " is too High for resource accumulations";
                ScreenMessages.PostScreenMessage(message, 10.0f, ScreenMessageStyle.LOWER_CENTER);
                return;
            }

            // verify that an electric or Thermal engine is available with high enough ISP
            var highIspEngine = part.vessel.parts.Find(p =>
                                                       p.FindModulesImplementing <ElectricEngineControllerFX>().Any(e => e.baseISP > 4200) ||
                                                       p.FindModulesImplementing <ThermalNozzleController>().Any(e => e.AttachedReactor.CoreTemperature > 40000));

            if (highIspEngine == null)
            {
                ScreenMessages.PostScreenMessage("No engine available, with high enough Isp and propelant switch ability to compensate for atmospheric drag", 10, ScreenMessageStyle.LOWER_CENTER);
                return;
            }

            // calcualte time past since last frame
            double time_diff = (Planetarium.GetUniversalTime() - last_active_time) * 55;

            // scoop athmosphere for entire durration
            ScoopAthmosphere(time_diff, true);
        }
コード例 #29
0
        // the main collecting function
        private void CollectSolarWind(double deltaTimeInSeconds, bool offlineCollecting)
        {
            var ionizationPowerCost  = bIonizing ? ionRequirements * Math.Pow(powerPercentage * 0.01, 2) : 0;
            var magneticPowerCost    = mwRequirements * Math.Pow(powerPercentage * 0.01, 2);
            var dPowerRequirementsMw = PluginHelper.PowerConsumptionMultiplier * (magneticPowerCost + ionizationPowerCost); // change the mwRequirements number in part config to change the power consumption

            // checks for free space in solar wind 'tanks'
            dSolarWindSpareCapacity = part.GetResourceSpareCapacity(solarWindResourceDefinition.name);
            dHydrogenSpareCapacity  = part.GetResourceSpareCapacity(hydrogenResourceDefinition.name);

            if (offlineCollecting)
            {
                solarWindMolesPerSquareMeterPerSecond = dLastSolarConcentration; // if resolving offline collection, pass the saved value, because OnStart doesn't resolve the function at line 328
                hydrogenMolarMassConcentrationPerSquareMeterPerSecond = dLastHydrogenConcentration;
            }

            if ((solarWindMolesPerSquareMeterPerSecond > 0 || hydrogenMolarMassConcentrationPerSquareMeterPerSecond > 0)) // && (dSolarWindSpareCapacity > 0 || dHydrogenSpareCapacity > 0))
            {
                var requiredHeliumMass = TimeWarp.fixedDeltaTime * heliumRequirementTonPerSecond;

                var heliumGasRequired     = requiredHeliumMass / helium4GasResourceDefinition.density;
                var receivedHeliumGas     = part.RequestResource(helium4GasResourceDefinition.id, heliumGasRequired);
                var receivedHeliumGasMass = receivedHeliumGas * helium4GasResourceDefinition.density;

                var massHeliumMassShortage = (requiredHeliumMass - receivedHeliumGasMass);

                var lqdHeliumRequired     = massHeliumMassShortage / lqdHelium4ResourceDefinition.density;
                var receivedLqdHelium     = part.RequestResource(lqdHelium4ResourceDefinition.id, lqdHeliumRequired);
                var receiverLqdHeliumMass = receivedLqdHelium * lqdHelium4ResourceDefinition.density;

                var heliumRatio = Math.Min(1, requiredHeliumMass > 0 ? (receivedHeliumGasMass + receiverLqdHeliumMass) / requiredHeliumMass : 0);

                // calculate available power
                var revievedPowerMw = consumeFNResourcePerSecond(dPowerRequirementsMw * heliumRatio, ResourceManager.FNRESOURCE_MEGAJOULES);

                // if power requirement sufficiently low, retreive power from KW source
                if (dPowerRequirementsMw < 2 && revievedPowerMw <= dPowerRequirementsMw)
                {
                    var requiredKw = (dPowerRequirementsMw - revievedPowerMw) * 1000;
                    var receivedKw = part.RequestResource(ResourceManager.STOCK_RESOURCE_ELECTRICCHARGE, heliumRatio * requiredKw * TimeWarp.fixedDeltaTime) / TimeWarp.fixedDeltaTime;
                    revievedPowerMw += (receivedKw * 0.001);
                }

                dLastPowerPercentage = offlineCollecting ? dLastPowerPercentage : (dPowerRequirementsMw > 0 ? revievedPowerMw / dPowerRequirementsMw : 0);

                // show in GUI
                strCollectingStatus = "Collecting solar wind";
            }
            else
            {
                dLastHydrogenConcentration = 0;
                dLastPowerPercentage       = 0;
                dPowerRequirementsMw       = 0;
            }

            // set the GUI string to state the number of KWs received if the MW requirements were lower than 2, otherwise in MW
            strReceivedPower = dPowerRequirementsMw < 2
                ? (dLastPowerPercentage * dPowerRequirementsMw * 1000).ToString("0.0") + " KW / " + (dPowerRequirementsMw * 1000).ToString("0.0") + " KW"
                : (dLastPowerPercentage * dPowerRequirementsMw).ToString("0.0") + " MW / " + dPowerRequirementsMw.ToString("0.0") + " MW";

            // get the shielding effect provided by the magnetosphere
            magnetoSphereStrengthRatio = GetMagnetosphereRatio(vessel.altitude, PluginHelper.getMaxAtmosphericAltitude(vessel.mainBody));

            // if online collecting, get the old values instead (simplification for the time being)
            if (offlineCollecting)
            {
                magnetoSphereStrengthRatio = dLastMagnetoStrength;
            }

            if (Math.Abs(magnetoSphereStrengthRatio) < float.Epsilon)
            {
                dShieldedEffectiveness = 1;
            }
            else
            {
                dShieldedEffectiveness = (1 - magnetoSphereStrengthRatio);
            }

            effectiveSurfaceAreaInSquareMeter     = surfaceArea + (magneticArea * powerPercentage * 0.01);
            effectiveSurfaceAreaInSquareKiloMeter = effectiveSurfaceAreaInSquareMeter * 1e-6;
            effectiveDiamterInKilometer           = 2 * Math.Sqrt(effectiveSurfaceAreaInSquareKiloMeter / Math.PI);

            Vector3d solarDirectionVector = localStar.transform.position - vessel.transform.position;

            solarWindFactor = Math.Max(0, Vector3d.Dot(part.transform.up, solarDirectionVector.normalized));
            solarwindProductionModifiers = collectMultiplier * effectiveness * dShieldedEffectiveness * dLastPowerPercentage * solarWindFactor;

            var solarWindGramCollectedPerSecond = solarWindMolesPerSquareMeterPerSecond * solarwindProductionModifiers * effectiveSurfaceAreaInSquareMeter * 1.9;

            var interstellarIonsConcentrationPerSquareMeter = vessel.obt_speed * interstellarDustMolesPerCubicMeter;

            var interstellarGramCollectedPerSecond = interstellarIonsConcentrationPerSquareMeter * effectiveSurfaceAreaInSquareMeter * 1.9;

            /** The first important bit.
             * This determines how much solar wind will be collected. Can be tweaked in part configs by changing the collector's effectiveness.
             * */
            var dSolarDustResourceChange = (solarWindGramCollectedPerSecond + interstellarGramCollectedPerSecond) * deltaTimeInSeconds * 1e-6 / solarWindResourceDefinition.density;

            // if the vessel has been out of focus, print out the collected amount for the player
            if (offlineCollecting)
            {
                var strNumberFormat = dSolarDustResourceChange > 100 ? "0" : "0.000";
                // let the player know that offline collecting worked
                ScreenMessages.PostScreenMessage("We collected " + dSolarDustResourceChange.ToString(strNumberFormat) + " units of " + solarWindResourceDefinition.name, 10, ScreenMessageStyle.LOWER_CENTER);
            }

            // this is the second important bit - do the actual change of the resource amount in the vessel
            dWindResourceFlow = -part.RequestResource(solarWindResourceDefinition.id, -dSolarDustResourceChange);

            var dHydrogenCollectedPerSecond = hydrogenMolarMassConcentrationPerSquareMeterPerSecond * effectiveSurfaceAreaInSquareMeter;
            var dHydrogenResourceChange     = dHydrogenCollectedPerSecond * 1e-6 / hydrogenResourceDefinition.density;

            dHydrogenResourceFlow = -part.RequestResource(hydrogenResourceDefinition.id, -dHydrogenResourceChange);

            if (offlineCollecting)
            {
                var strNumberFormat = dHydrogenResourceChange > 100 ? "0" : "0.000";
                // let the player know that offline collecting worked
                ScreenMessages.PostScreenMessage("We collected " + dHydrogenResourceChange.ToString(strNumberFormat) + " units of " + hydrogenResourceDefinition.name, 10, ScreenMessageStyle.LOWER_CENTER);
            }

            var dHeliumCollectedPerSecond = heliumMolarMassConcentrationPerSquareMeterPerSecond * effectiveSurfaceAreaInSquareMeter;
            var dHeliumResourceChange     = dHeliumCollectedPerSecond * 1e-6 / helium4GasResourceDefinition.density;

            dHeliumResourceFlow = -part.RequestResource(helium4GasResourceDefinition.id, -dHeliumResourceChange);

            if (offlineCollecting)
            {
                var strNumberFormat = dHeliumResourceChange > 100 ? "0" : "0.000";
                // let the player know that offline collecting worked
                ScreenMessages.PostScreenMessage("We collected " + dHeliumResourceFlow.ToString(strNumberFormat) + " units of " + helium4GasResourceDefinition.name, 10, ScreenMessageStyle.LOWER_CENTER);
            }

            var atmosphericGasKgPerSquareMeter      = GetAtmosphericGasDensityKgPerCubicMeter();
            var solarDustKgPerSquareMeter           = solarWindMolesPerSquareMeterPerSecond * 1e-3 * 1.9;
            var interstellarDustKgPerSquareMeter    = interstellarDustMolesPerCubicMeter * 1e-3 * 1.9;
            var atmosphericDragInNewton             = vessel.obt_speed * atmosphericGasKgPerSquareMeter;
            var interstellarDustDragInNewton        = vessel.obt_speed * interstellarDustKgPerSquareMeter;
            var maxOrbitalVesselDragInNewton        = effectiveSurfaceAreaInSquareMeter * (atmosphericDragInNewton + interstellarDustDragInNewton);
            var dEffectiveOrbitalVesselDragInNewton = maxOrbitalVesselDragInNewton * (bIonizing ? 1 : 0.001);
            var solarwindDragInNewtonPerSquareMeter = solarWindSpeed * solarDustKgPerSquareMeter;
            var dSolarWindVesselForceInNewton       = solarwindDragInNewtonPerSquareMeter * effectiveSurfaceAreaInSquareMeter;

            fSolarWindCollectedGramPerHour = (float)(solarWindGramCollectedPerSecond * 3600);
            fInterstellarIonsConcentrationPerSquareMeter = (float)interstellarIonsConcentrationPerSquareMeter;
            fInterstellarIonsCollectedGramPerHour        = (float)interstellarGramCollectedPerSecond * 3600;
            fHydrogenCollectedGramPerHour        = (float)dHydrogenCollectedPerSecond * 3600;
            fHeliumCollectedGramPerHour          = (float)dHeliumCollectedPerSecond * 3600;
            fAtmosphereIonsKgPerSquareMeter      = (float)atmosphericGasKgPerSquareMeter;
            fSolarWindKgPerSquareMeter           = (float)solarDustKgPerSquareMeter;
            fInterstellarIonsKgPerSquareMeter    = (float)interstellarDustKgPerSquareMeter;
            fAtmosphericDragInNewton             = (float)atmosphericDragInNewton;
            fInterstellarDustDragInNewton        = (float)interstellarDustDragInNewton;
            fMaxOrbitalVesselDragInNewton        = (float)maxOrbitalVesselDragInNewton;
            fEffectiveOrbitalVesselDragInNewton  = (float)dEffectiveOrbitalVesselDragInNewton;
            fSolarWindDragInNewtonPerSquareMeter = (float)solarwindDragInNewtonPerSquareMeter;
            fSolarWindVesselForceInNewton        = (float)dSolarWindVesselForceInNewton;

            if (vessel.packed)
            {
                var totalVesselMassInKg = part.vessel.GetTotalMass() * 1000;
                if (totalVesselMassInKg <= 0)
                {
                    return;
                }

                var universalTime = Planetarium.GetUniversalTime();
                if (universalTime <= 0)
                {
                    return;
                }

                var orbitalDragDeltaVv = TimeWarp.fixedDeltaTime * part.vessel.obt_velocity.normalized * -dEffectiveOrbitalVesselDragInNewton / totalVesselMassInKg;
                vessel.orbit.Perturb(orbitalDragDeltaVv, universalTime);

                var solarPushDeltaVv = TimeWarp.fixedDeltaTime * solarDirectionVector.normalized * -fSolarWindVesselForceInNewton / totalVesselMassInKg;
                vessel.orbit.Perturb(solarPushDeltaVv, universalTime);
            }
            else
            {
                var vesselRegitBody = part.vessel.GetComponent <Rigidbody>();
                vesselRegitBody.AddForce(part.vessel.velocityD.normalized * -dEffectiveOrbitalVesselDragInNewton * 1e-3, ForceMode.Force);
                vesselRegitBody.AddForce(solarDirectionVector.normalized * -dSolarWindVesselForceInNewton * 1e-3, ForceMode.Force);
            }
        }
コード例 #30
0
 private string UpdateMagnetoStrengthInGui()
 {
     return((GetMagnetosphereRatio(vessel.altitude, PluginHelper.getMaxAtmosphericAltitude(vessel.mainBody)) * 100).ToString("F1"));
 }