Beispiel #1
0
        /// <summary>Check whether there are commands that can be removed from the flight computer command queue (when their delay time has elapsed).</summary>
        /// <remarks>This is done during the Update() phase of the game engine. <see cref="OnUpdate"/> method.</remarks>
        private void PopCommand()
        {
            // something in command queue?
            if (_commandQueue.Count <= 0)
            {
                return;
            }

            // Can come out of time warp even if ship is not powered; workaround for KSP 0.24 power consumption bug
            if (RTSettings.Instance.ThrottleTimeWarp && TimeWarp.CurrentRate > 4.0f)
            {
                var time = TimeWarp.deltaTime;
                foreach (var dc in _commandQueue.TakeWhile(c => c.TimeStamp <= RTUtil.GameTime + (2 * time + 1.0)))
                {
                    var message = new ScreenMessage(Localizer.Format("#RT_FC_msg1"), 4.0f, ScreenMessageStyle.UPPER_LEFT);                                //"[Flight Computer]: Throttling back time warp..."
                    while ((2 * TimeWarp.deltaTime + 1.0) > (Math.Max(dc.TimeStamp - RTUtil.GameTime, 0) + dc.ExtraDelay) && TimeWarp.CurrentRate > 1.0f) //
                    {
                        TimeWarp.SetRate(TimeWarp.CurrentRateIndex - 1, true);
                        ScreenMessages.PostScreenMessage(message);
                    }
                }
            }

            // Proceed the extraDelay for every command where the normal delay is over
            foreach (var dc in _commandQueue.Where(s => s.Delay == 0).ToList())
            {
                // Use time decrement instead of comparing scheduled time, in case we later want to
                //      reinstate event clocks stopping under certain conditions
                if (dc.ExtraDelay > 0)
                {
                    //issue: deltaTime is floating point -/+0.001, not great for long-term time-senitive operation
                    if (dc.ExtraDelayScheduledTimeStamp > RTUtil.GameTime)
                    {
                        dc.ExtraDelay = dc.ExtraDelayScheduledTimeStamp - RTUtil.GameTime;
                    }
                    else //fallback
                    {
                        dc.ExtraDelay -= TimeWarp.deltaTime;
                    }
                }
                else
                {
                    if (SignalProcessor.Powered)
                    {
                        // Note: depending on implementation, dc.Pop() may execute the event
                        if (dc.Pop(this))
                        {
                            _activeCommands[dc.Priority] = dc;
                            if (OnNewCommandPop != null)
                            {
                                OnNewCommandPop.Invoke();
                            }
                        }
                    }
                    else
                    {
                        string message = Localizer.Format("#RT_FC_msg2", dc.ShortName);//$"[Flight Computer]: Out of power, cannot run \"{}\" on schedule."
                        ScreenMessages.PostScreenMessage(new ScreenMessage(
                                                             message, 4.0f, ScreenMessageStyle.UPPER_LEFT));
                    }

                    _commandQueue.Remove(dc);
                    UpdateLastTarget();
                }
            }
        }
Beispiel #2
0
 private void Update()
 {
     safeDisplay     = display;
     ignoreChatInput = false;
     if (chatButtonHighlighted && display)
     {
         chatButtonHighlighted = false;
     }
     if (chatLocked && !display)
     {
         chatLocked = false;
         InputLockManager.RemoveControlLock(DMP_CHAT_LOCK);
     }
     if (workerEnabled)
     {
         //Handle leave event
         if (!leaveEventHandled)
         {
             if (selectedChannel != null)
             {
                 using (MessageWriter mw = new MessageWriter())
                 {
                     mw.Write <int>((int)ChatMessageType.LEAVE);
                     mw.Write <string>(Settings.fetch.playerName);
                     mw.Write <string>(selectedChannel);
                     NetworkWorker.fetch.SendChatMessage(mw.GetMessageBytes());
                 }
                 if (joinedChannels.Contains(selectedChannel))
                 {
                     joinedChannels.Remove(selectedChannel);
                 }
                 selectedChannel   = null;
                 selectedPMChannel = null;
             }
             if (selectedPMChannel != null)
             {
                 if (joinedPMChannels.Contains(selectedPMChannel))
                 {
                     joinedPMChannels.Remove(selectedPMChannel);
                 }
                 selectedChannel   = null;
                 selectedPMChannel = null;
             }
             leaveEventHandled = true;
         }
         //Handle send event
         if (!sendEventHandled)
         {
             if (sendText != "")
             {
                 if (!sendText.StartsWith("/") || sendText.StartsWith("//"))
                 {
                     if (sendText.StartsWith("//"))
                     {
                         sendText = sendText.Substring(1);
                     }
                     if (selectedChannel == null && selectedPMChannel == null)
                     {
                         //Sending a global chat message
                         using (MessageWriter mw = new MessageWriter())
                         {
                             mw.Write <int>((int)ChatMessageType.CHANNEL_MESSAGE);
                             mw.Write <string>(Settings.fetch.playerName);
                             //Global channel name is empty string.
                             mw.Write <string>("");
                             mw.Write <string>(sendText);
                             NetworkWorker.fetch.SendChatMessage(mw.GetMessageBytes());
                         }
                     }
                     if (selectedChannel != null)
                     {
                         using (MessageWriter mw = new MessageWriter())
                         {
                             mw.Write <int>((int)ChatMessageType.CHANNEL_MESSAGE);
                             mw.Write <string>(Settings.fetch.playerName);
                             mw.Write <string>(selectedChannel);
                             mw.Write <string>(sendText);
                             NetworkWorker.fetch.SendChatMessage(mw.GetMessageBytes());
                         }
                     }
                     if (selectedPMChannel != null)
                     {
                         using (MessageWriter mw = new MessageWriter())
                         {
                             mw.Write <int>((int)ChatMessageType.PRIVATE_MESSAGE);
                             mw.Write <string>(Settings.fetch.playerName);
                             mw.Write <string>(selectedPMChannel);
                             mw.Write <string>(sendText);
                             NetworkWorker.fetch.SendChatMessage(mw.GetMessageBytes());
                         }
                     }
                 }
                 else
                 {
                     //Handle command
                     if (sendText.StartsWith("/join ") && sendText.Length > 7)
                     {
                         string channelName = sendText.Substring(6);
                         if (channelName != "" || channelName != "Global")
                         {
                             DarkLog.Debug("Joining channel " + channelName);
                             joinedChannels.Add(channelName);
                             selectedChannel   = channelName;
                             selectedPMChannel = null;
                             using (MessageWriter mw = new MessageWriter())
                             {
                                 mw.Write <int>((int)ChatMessageType.JOIN);
                                 mw.Write <string>(Settings.fetch.playerName);
                                 mw.Write <string>(channelName);
                                 NetworkWorker.fetch.SendChatMessage(mw.GetMessageBytes());
                             }
                         }
                         else
                         {
                             ScreenMessages.PostScreenMessage("Couln't join '" + channelName + "', channel name not valid!", 5f, ScreenMessageStyle.UPPER_CENTER);
                         }
                     }
                     if (sendText.StartsWith("/query ") && sendText.Length > 8)
                     {
                         string playerName  = sendText.Substring(7);
                         bool   playerFound = false;
                         if (playerName != consoleIdentifier)
                         {
                             foreach (PlayerStatus ps in PlayerStatusWorker.fetch.playerStatusList)
                             {
                                 if (ps.playerName == playerName)
                                 {
                                     playerFound = true;
                                 }
                             }
                         }
                         else
                         {
                             //Make sure we can always query the server.
                             playerFound = true;
                         }
                         if (playerFound)
                         {
                             DarkLog.Debug("Starting query with " + playerName);
                             joinedPMChannels.Add(playerName);
                             selectedChannel   = null;
                             selectedPMChannel = playerName;
                         }
                         else
                         {
                             DarkLog.Debug("Couln't start query with '" + playerName + "', player not found!");
                             ScreenMessages.PostScreenMessage("Couln't start query with '" + playerName + "', player not found!", 5f, ScreenMessageStyle.UPPER_CENTER);
                         }
                     }
                     if (sendText == "/part" || sendText == "/leave")
                     {
                         leaveEventHandled = false;
                     }
                     if (sendText == "/ping")
                     {
                         NetworkWorker.fetch.SendPingRequest();
                     }
                     if (sendText == "/motd")
                     {
                         NetworkWorker.fetch.SendMotdRequest();
                     }
                 }
             }
             sendText         = "";
             sendEventHandled = true;
         }
         //Handle join messages
         while (newJoinMessages.Count > 0)
         {
             JoinLeaveMessage jlm = newJoinMessages.Dequeue();
             if (!playerChannels.ContainsKey(jlm.fromPlayer))
             {
                 playerChannels.Add(jlm.fromPlayer, new List <string>());
             }
             if (!playerChannels[jlm.fromPlayer].Contains(jlm.channel))
             {
                 playerChannels[jlm.fromPlayer].Add(jlm.channel);
             }
         }
         //Handle leave messages
         while (newLeaveMessages.Count > 0)
         {
             JoinLeaveMessage jlm = newLeaveMessages.Dequeue();
             if (playerChannels.ContainsKey(jlm.fromPlayer))
             {
                 if (playerChannels[jlm.fromPlayer].Contains(jlm.channel))
                 {
                     playerChannels[jlm.fromPlayer].Remove(jlm.channel);
                 }
                 if (playerChannels[jlm.fromPlayer].Count == 0)
                 {
                     playerChannels.Remove(jlm.fromPlayer);
                 }
             }
         }
         //Handle channel messages
         while (newChannelMessages.Count > 0)
         {
             ChannelEntry ce = newChannelMessages.Dequeue();
             if (!channelMessages.ContainsKey(ce.channel))
             {
                 channelMessages.Add(ce.channel, new List <string>());
             }
             //Highlight if the channel isn't selected.
             if (selectedChannel != null && ce.channel == "")
             {
                 if (!highlightChannel.Contains(ce.channel))
                 {
                     highlightChannel.Add(ce.channel);
                 }
             }
             if (ce.channel != selectedChannel && ce.channel != "")
             {
                 if (!highlightChannel.Contains(ce.channel))
                 {
                     highlightChannel.Add(ce.channel);
                 }
             }
             //Move the bar to the bottom on a new message
             if (selectedChannel == null && selectedPMChannel == null && ce.channel == "")
             {
                 chatScrollPos.y = float.PositiveInfinity;
             }
             if (selectedChannel != null && selectedPMChannel == null && ce.channel == selectedChannel)
             {
                 chatScrollPos.y = float.PositiveInfinity;
             }
             channelMessages[ce.channel].Add(ce.fromPlayer + ": " + ce.message);
         }
         //Handle private messages
         while (newPrivateMessages.Count > 0)
         {
             PrivateEntry pe = newPrivateMessages.Dequeue();
             if (pe.fromPlayer != Settings.fetch.playerName)
             {
                 if (!privateMessages.ContainsKey(pe.fromPlayer))
                 {
                     privateMessages.Add(pe.fromPlayer, new List <string>());
                 }
                 //Highlight if the player isn't selected
                 if (!joinedPMChannels.Contains(pe.fromPlayer))
                 {
                     joinedPMChannels.Add(pe.fromPlayer);
                 }
                 if (selectedPMChannel != pe.fromPlayer)
                 {
                     if (!highlightPM.Contains(pe.fromPlayer))
                     {
                         highlightPM.Add(pe.fromPlayer);
                     }
                 }
             }
             //Move the bar to the bottom on a new message
             if (selectedPMChannel != null && selectedChannel == null && (pe.fromPlayer == selectedPMChannel || pe.fromPlayer == Settings.fetch.playerName))
             {
                 chatScrollPos.y = float.PositiveInfinity;
             }
             if (pe.fromPlayer != Settings.fetch.playerName)
             {
                 privateMessages[pe.fromPlayer].Add(pe.fromPlayer + ": " + pe.message);
             }
             else
             {
                 privateMessages[pe.toPlayer].Add(pe.fromPlayer + ": " + pe.message);
             }
         }
         while (disconnectingPlayers.Count > 0)
         {
             string disconnectingPlayer = disconnectingPlayers.Dequeue();
             if (playerChannels.ContainsKey(disconnectingPlayer))
             {
                 playerChannels.Remove(disconnectingPlayer);
             }
             if (joinedPMChannels.Contains(disconnectingPlayer))
             {
                 joinedPMChannels.Remove(disconnectingPlayer);
             }
             if (highlightPM.Contains(disconnectingPlayer))
             {
                 highlightPM.Remove(disconnectingPlayer);
             }
             if (privateMessages.ContainsKey(disconnectingPlayer))
             {
                 privateMessages.Remove(disconnectingPlayer);
             }
         }
     }
 }
Beispiel #3
0
        public static void HUDMessage(string sMessage, float fDuration = 10f, int iStyle = 2)
        {
            ScreenMessageStyle smsStyle = (ScreenMessageStyle)iStyle;

            ScreenMessages.PostScreenMessage(sMessage, fDuration, smsStyle);
        }
        private void WarpdriveCharging()
        {
            double currentExoticMatter = 0;
            double maxExoticMatter     = 0;

            part.GetConnectedResourceTotals(exoticResourceDefinition.id, out currentExoticMatter, out maxExoticMatter);

            if (IsCharging)
            {
                double powerDraw = CheatOptions.InfiniteElectricity
                    ? (maxExoticMatter - currentExoticMatter) / 0.001
                    : Math.Max(minPowerRequirementForLightSpeed, Math.Min((maxExoticMatter - currentExoticMatter) / 0.001, getStableResourceSupply(FNResourceManager.FNRESOURCE_MEGAJOULES)));

                double power_returned = CheatOptions.InfiniteElectricity
                    ? powerDraw
                    : consumeFNResource(powerDraw * TimeWarp.fixedDeltaTime, FNResourceManager.FNRESOURCE_MEGAJOULES) / TimeWarp.fixedDeltaTime;

                if (power_returned < 0.99 * minPowerRequirementForLightSpeed)
                {
                    insufficientPowerTimeout--;
                }
                else
                {
                    insufficientPowerTimeout = 10;
                }

                if (insufficientPowerTimeout < 0)
                {
                    insufficientPowerTimeout--;
                    ScreenMessages.PostScreenMessage("Not enough MW power to initiate stable warp field!", 5.0f, ScreenMessageStyle.UPPER_CENTER);
                    StopCharging();
                    return;
                }

                if (currentExoticMatter < exotic_power_required)
                {
                    part.RequestResource(InterstellarResourcesConfiguration.Instance.ExoticMatter, -power_returned * 0.001 * TimeWarp.fixedDeltaTime);
                }

                if (!CheatOptions.IgnoreMaxTemperature)
                {
                    supplyFNResource(-power_returned * 0.999 * TimeWarp.fixedDeltaTime, FNResourceManager.FNRESOURCE_WASTEHEAT);
                }
            }

            if (!IsEnabled)
            {
                if (currentExoticMatter < exotic_power_required)
                {
                    double electrical_current_pct = 100.0 * currentExoticMatter / exotic_power_required;
                    DriveStatus = String.Format("Charging: ") + electrical_current_pct.ToString("0.00") + String.Format("%");
                }
                else
                {
                    DriveStatus = "Ready.";
                }

                warp_effect2_renderer.enabled = false;
                warp_effect1_renderer.enabled = false;
            }
            else
            {
                DriveStatus = "Active.";
                ;
                warp_effect2_renderer.enabled = true;
                warp_effect1_renderer.enabled = true;
            }
        }
Beispiel #5
0
        private void MainWindow(int id)
        {
            Trajectory traj      = Trajectory.fetch;
            var        lastPatch = traj.patches.LastOrDefault();

            GUILayout.BeginHorizontal();
            Settings.fetch.DisplayTrajectories = GUILayout.Toggle(Settings.fetch.DisplayTrajectories, "Display trajectory", GUILayout.Width(125));

            // check that we have patched conics. If not, apologize to the user and return.
            if (Settings.fetch.DisplayTrajectories && !isPatchedConicsAvailable())
            {
                ScreenMessages.PostScreenMessage(
                    "Can't show trajectory because patched conics are not available." +
                    " Please update your tracking station facility.");
                Settings.fetch.DisplayTrajectories = false;
                return;
            }

            if (Settings.fetch.DisplayTrajectories)
            {
                Settings.fetch.DisplayCompleteTrajectory = GUILayout.Toggle(Settings.fetch.DisplayCompleteTrajectory, "complete", GUILayout.Width(70));
            }
            GUILayout.EndHorizontal();

            Settings.fetch.BodyFixedMode = GUILayout.Toggle(Settings.fetch.BodyFixedMode, "Body-fixed mode");

            GUILayout.Label("Max G-force: " + (traj.MaxAccel / 9.81).ToString("0.00"));
            if (lastPatch != null && lastPatch.impactPosition.HasValue)
            {
                Vector3 up      = lastPatch.impactPosition.Value.normalized;
                Vector3 vel     = lastPatch.impactVelocity - lastPatch.startingState.referenceBody.getRFrmVel(lastPatch.impactPosition.Value + lastPatch.startingState.referenceBody.position);
                float   vVelMag = Vector3.Dot(vel, up);
                Vector3 vVel    = up * vVelMag;
                float   hVelMag = (vel - vVel).magnitude;
                GUILayout.Label("Impact: V = " + vVelMag.ToString("0.0") + "m/s, H = " + hVelMag.ToString("0.0") + "m/s");
            }
            else
            {
                GUILayout.Label("Impact velocity: -");
            }
            GUILayout.Space(10);

            if (Settings.fetch.DisplayTargetGUI = ToggleGroup(Settings.fetch.DisplayTargetGUI, "Target"))
            {
                GUI.enabled = traj.targetPosition.HasValue;
                if (GUILayout.Button("Unset target"))
                {
                    Trajectory.SetTarget();
                }
                GUI.enabled = true;

                GUILayout.BeginHorizontal();
                var patch = traj.patches.LastOrDefault();
                GUI.enabled = (patch != null && patch.impactPosition.HasValue);
                if (GUILayout.Button("Set current impact", GUILayout.Width(150)))
                {
                    Trajectory.SetTarget(patch.startingState.referenceBody, patch.impactPosition);
                }
                GUI.enabled = true;
                if (GUILayout.Button("Set KSC", GUILayout.Width(70)))
                {
                    var body = FlightGlobals.Bodies.SingleOrDefault(b => b.isHomeWorld);
                    if (body != null)
                    {
                        Vector3d worldPos = body.GetWorldSurfacePosition(-0.04860002, -74.72425635, 2.0);
                        Trajectory.SetTarget(body, worldPos - body.position);
                    }
                }
                GUILayout.EndHorizontal();

                GUILayout.BeginHorizontal();
                coords = GUILayout.TextField(coords, GUILayout.Width(170));
                if (GUILayout.Button(new GUIContent("Set", "Enter target latitude and longitude, separated by a comma"), GUILayout.Width(50)))
                {
                    string[] latLng = coords.Split(new char[] { ',', ';' });
                    var      body   = FlightGlobals.currentMainBody;
                    if (latLng.Length == 2 && body != null)
                    {
                        double lat, lng;
                        if (Double.TryParse(latLng[0].Trim(), out lat) && Double.TryParse(latLng[1].Trim(), out lng))
                        {
                            Vector3d worldPos = body.GetWorldSurfacePosition(lat, lng, 2.0);
                            Trajectory.SetTarget(body, worldPos - body.position);
                        }
                    }
                }
                GUILayout.EndHorizontal();
            }
            GUILayout.Space(10);

            GUILayout.BeginHorizontal();
            bool descentProfileGroup = Settings.fetch.DisplayDescentProfileGUI = ToggleGroup(Settings.fetch.DisplayDescentProfileGUI, "Descent profile", 120);

            DescentProfile.fetch.DoQuickControlsGUI();
            GUILayout.EndHorizontal();
            if (descentProfileGroup)
            {
                DescentProfile.fetch.DoGUI();
            }
            GUILayout.Space(10);

            if (Settings.fetch.DisplaySettingsGUI = ToggleGroup(Settings.fetch.DisplaySettingsGUI, "Settings"))
            {
                GUILayout.BeginHorizontal();
                GUILayout.Label("Max patches", GUILayout.Width(100));
                Settings.fetch.MaxPatchCount = Mathf.RoundToInt(GUILayout.HorizontalSlider((float)Settings.fetch.MaxPatchCount, 3, 10, GUILayout.Width(100)));
                GUILayout.Label(Settings.fetch.MaxPatchCount.ToString(), GUILayout.Width(15));
                GUILayout.EndHorizontal();

                GUILayout.BeginHorizontal();
                GUILayout.Label("Max frames per patch", GUILayout.Width(100));
                Settings.fetch.MaxFramesPerPatch = Mathf.RoundToInt(GUILayout.HorizontalSlider((float)Settings.fetch.MaxFramesPerPatch, 1, 50, GUILayout.Width(100)));
                GUILayout.Label(Settings.fetch.MaxFramesPerPatch.ToString(), GUILayout.Width(15));
                GUILayout.EndHorizontal();

                GUILayout.BeginHorizontal();
                Settings.fetch.AutoUpdateAerodynamicModel = GUILayout.Toggle(Settings.fetch.AutoUpdateAerodynamicModel, new GUIContent("Auto update", "Auto-update of the aerodynamic model. For example if a part is decoupled, the model needs to be updated. This is independent from trajectory update."));
                if (GUILayout.Button("Update now"))
                {
                    traj.InvalidateAerodynamicModel();
                }
                GUILayout.EndHorizontal();

                if (ToolbarManager.ToolbarAvailable)
                {
                    Settings.fetch.UseBlizzyToolbar = GUILayout.Toggle(Settings.fetch.UseBlizzyToolbar, new GUIContent("Use Blizzy's toolbar", "Will take effect after restart"));
                }

                //Settings.fetch.AutoPilotAvailable = GUILayout.Toggle(Settings.fetch.AutoPilotAvailable, new GUIContent("Unlock auto-pilot (EXPERIMENTAL)", "Enables the auto-pilot interface. This is experimental, subject to change, and might crash your spaceplanes more often than not."));
                Settings.fetch.AutoPilotAvailable = false; // auto-pilot disabled because it's incompatible with Remote Tech in its current implementation (and has some other bugs anyway)

                if (FlightGlobals.ActiveVessel != null)
                {
                    GUILayout.Label("Position:");
                    GUILayout.BeginHorizontal();
                    var body     = FlightGlobals.ActiveVessel.mainBody;
                    var worldPos = FlightGlobals.ActiveVessel.GetWorldPos3D();
                    GUILayout.Label("lat=" + body.GetLatitude(worldPos).ToString("000.000000"), GUILayout.Width(110));
                    GUILayout.Label("lng=" + body.GetLongitude(worldPos).ToString("000.000000"), GUILayout.Width(110));
                    GUILayout.EndHorizontal();
                }

                GUILayout.Label("Aerodynamic model: " + VesselAerodynamicModel.AerodynamicModelName);
                GUILayout.BeginHorizontal();
                GUILayout.Label("Perf: " + (traj.ComputationTime * 1000.0f).ToString("0.0") + "ms (" + (traj.ComputationTime / traj.GameFrameTime * 100.0f).ToString("0") + "%)", GUILayout.Width(120));
                GUILayout.Label(traj.ErrorCount + " error(s)", GUILayout.Width(80));
                GUILayout.EndHorizontal();
            }

            tooltip = GUI.tooltip;

            GUI.DragWindow();
        }
        public override void OnFixedUpdate()
        {
            if (myAttachedEngine.isOperational && myAttachedEngine.currentThrottle > 0 && myAttachedReactor != null)
            {
                if (!myAttachedReactor.isActive())
                {
                    myAttachedReactor.enableIfPossible();
                }
                updateIspEngineParams();
                float  curve_eval_point = (float)Math.Min(FlightGlobals.getStaticPressure(vessel.transform.position), 1.0);
                float  currentIsp       = myAttachedEngine.atmosphereCurve.Evaluate(curve_eval_point);
                double ispratio         = currentIsp / maxISP;
                this.current_isp = currentIsp;
                // scale down thrust if it's attached to the wrong sized reactor
                float heat_exchanger_thrust_divisor = 1;
                if (radius > myAttachedReactor.getRadius())
                {
                    heat_exchanger_thrust_divisor = myAttachedReactor.getRadius() * myAttachedReactor.getRadius() / radius / radius;
                }
                else
                {
                    heat_exchanger_thrust_divisor = radius * radius / myAttachedReactor.getRadius() / myAttachedReactor.getRadius();
                }

                if (myAttachedReactor.getRadius() == 0 || radius == 0)
                {
                    heat_exchanger_thrust_divisor = 1;
                }
                // get the flameout safety limit
                atmospheric_limit = getAtmosphericLimit();
                double thrust_limit = myAttachedEngine.thrustPercentage / 100;
                if (currentpropellant_is_jet)
                {
                    int    pre_coolers_active = vessel.FindPartModulesImplementing <FNModulePreecooler>().Where(prc => prc.isFunctional()).Count();
                    int    intakes_open       = vessel.FindPartModulesImplementing <ModuleResourceIntake>().Where(mre => mre.intakeEnabled).Count();
                    double proportion         = Math.Pow((double)(intakes_open - pre_coolers_active) / (double)intakes_open, 0.1);
                    if (double.IsNaN(proportion) || double.IsInfinity(proportion))
                    {
                        proportion = 1;
                    }
                    part.temperature = (float)Math.Max((Math.Sqrt(vessel.srf_velocity.magnitude) * 20.0 / GameConstants.atmospheric_non_precooled_limit) * part.maxTemp * proportion, 1);
                }
                double thermal_power_received = consumeFNResource(assThermalPower * TimeWarp.fixedDeltaTime * myAttachedEngine.currentThrottle, FNResourceManager.FNRESOURCE_THERMALPOWER) / TimeWarp.fixedDeltaTime;
                consumeFNResource(thermal_power_received * TimeWarp.fixedDeltaTime, FNResourceManager.FNRESOURCE_WASTEHEAT);
                float  power_ratio     = 0.0f;
                double engineMaxThrust = 0.01;
                if (assThermalPower > 0)
                {
                    power_ratio     = (float)(thermal_power_received / assThermalPower);
                    engineMaxThrust = Math.Max(thrust_limit * 2000.0 * thermal_power_received / maxISP / g0 * heat_exchanger_thrust_divisor * ispratio / myAttachedEngine.currentThrottle, 0.01);
                }
                //print ("B: " + engineMaxThrust);
                // set up TWR limiter if on
                //double additional_thrust_compensator = myAttachedEngine.finalThrust / (myAttachedEngine.maxThrust * myAttachedEngine.currentThrottle);
                double engine_thrust = engineMaxThrust;
                // engine thrust fixed
                //print ("A: " + engine_thrust*myAttachedEngine.velocityCurve.Evaluate((float)vessel.srf_velocity.magnitude));
                if (!double.IsInfinity(engine_thrust) && !double.IsNaN(engine_thrust))
                {
                    if (isLFO)
                    {
                        myAttachedEngine.maxThrust = (float)(2.0 * engine_thrust);
                    }
                    else
                    {
                        myAttachedEngine.maxThrust = (float)engine_thrust;
                    }
                }
                else
                {
                    myAttachedEngine.maxThrust = 0.000001f;
                }

                // amount of fuel being used at max throttle with no atmospheric limits
                if (current_isp > 0)
                {
                    double vcurve_at_current_velocity = 1;
                    if (myAttachedEngine.useVelocityCurve)
                    {
                        vcurve_at_current_velocity = myAttachedEngine.velocityCurve.Evaluate((float)vessel.srf_velocity.magnitude);
                    }
                    fuel_flow_rate = engine_thrust / current_isp / g0 / 0.005 * TimeWarp.fixedDeltaTime;
                    if (vcurve_at_current_velocity > 0)
                    {
                        fuel_flow_rate = fuel_flow_rate / vcurve_at_current_velocity;
                    }
                }
            }
            else
            {
                if (myAttachedEngine.realIsp > 0)
                {
                    atmospheric_limit = getAtmosphericLimit();
                    double vcurve_at_current_velocity = 1;
                    if (myAttachedEngine.useVelocityCurve)
                    {
                        vcurve_at_current_velocity = myAttachedEngine.velocityCurve.Evaluate((float)vessel.srf_velocity.magnitude);
                    }
                    fuel_flow_rate = myAttachedEngine.maxThrust / myAttachedEngine.realIsp / g0 / 0.005 * TimeWarp.fixedDeltaTime / vcurve_at_current_velocity;
                }
                else
                {
                    fuel_flow_rate = 0;
                }

                if (currentpropellant_is_jet)
                {
                    part.temperature = 1;
                }

                if (myAttachedReactor == null && myAttachedEngine.isOperational && myAttachedEngine.currentThrottle > 0)
                {
                    myAttachedEngine.Events ["Shutdown"].Invoke();
                    ScreenMessages.PostScreenMessage("Engine Shutdown: No reactor attached!", 5.0f, ScreenMessageStyle.UPPER_CENTER);
                }
            }
            //tell static helper methods we are currently updating things
            static_updating  = true;
            static_updating2 = true;
        }
Beispiel #7
0
        private void MainWindow(int id)
        {
            Trajectory traj = Trajectory.fetch;

            GUILayout.BeginHorizontal();

            Settings.fetch.DisplayTrajectories = GUILayout.Toggle(Settings.fetch.DisplayTrajectories, "Show trajectory", GUILayout.Width(125));

            Settings.fetch.DisplayTrajectoriesInFlight = GUILayout.Toggle(Settings.fetch.DisplayTrajectoriesInFlight, "In-Flight");

            // check that we have patched conics. If not, apologize to the user and return.
            if (Settings.fetch.DisplayTrajectories && !Util.IsPatchedConicsAvailable)
            {
                ScreenMessages.PostScreenMessage(
                    "Can't show trajectory because patched conics are not available." +
                    " Please update your tracking station facility.");
                Settings.fetch.DisplayTrajectories = false;
                return;
            }

            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal();

            Settings.fetch.BodyFixedMode = GUILayout.Toggle(Settings.fetch.BodyFixedMode, "Body-fixed mode");

            if (Settings.fetch.DisplayTrajectories)
            {
                Settings.fetch.DisplayCompleteTrajectory = GUILayout.Toggle(Settings.fetch.DisplayCompleteTrajectory, "complete", GUILayout.Width(70));
            }

            GUILayout.EndHorizontal();

            GUILayout.Label("Max G-force: " + guistring_gForce);

            GUILayout.Label(guistring_impactVelocity);
            GUILayout.Space(10);


            if (Settings.fetch.DisplayTargetGUI = ToggleGroup(Settings.fetch.DisplayTargetGUI, "Target"))
            {
                GUI.enabled = Trajectory.Target.WorldPosition.HasValue;

                GUILayout.Label(guistring_targetDistance);

                if (GUILayout.Button("Unset target"))
                {
                    Trajectory.Target.Set();
                }
                GUI.enabled = true;

                GUILayout.BeginHorizontal();
                var patch = traj.Patches.LastOrDefault();
                GUI.enabled = (patch != null && patch.ImpactPosition.HasValue);
                if (GUILayout.Button("Set current impact", GUILayout.Width(150)))
                {
                    Trajectory.Target.Set(patch.StartingState.ReferenceBody, patch.ImpactPosition);
                }
                GUI.enabled = true;
                if (GUILayout.Button("Set KSC", GUILayout.Width(70)))
                {
                    var body = FlightGlobals.Bodies.SingleOrDefault(b => b.isHomeWorld);
                    if (body != null)
                    {
                        Vector3d worldPos = body.GetWorldSurfacePosition(-0.04860002, -74.72425635, 2.0);
                        Trajectory.Target.Set(body, worldPos - body.position);
                    }
                }
                GUILayout.EndHorizontal();

                GUILayout.BeginHorizontal();

                Vessel targetVessel = FlightGlobals.fetch.VesselTarget?.GetVessel();
                GUI.enabled = (patch != null && targetVessel != null && targetVessel.Landed
                               // && targetVessel.lastBody == patch.startingState.referenceBody
                               );
                if (GUILayout.Button("Target vessel"))
                {
                    Trajectory.Target.Set(targetVessel.lastBody, targetVessel.GetWorldPos3D() - targetVessel.lastBody.position);
                    ScreenMessages.PostScreenMessage("Targeting vessel " + targetVessel.GetName());
                }

                FinePrint.Waypoint navigationWaypoint = FlightGlobals.ActiveVessel?.navigationWaypoint;
                GUI.enabled = (navigationWaypoint != null);
                if (GUILayout.Button("Active waypoint"))
                {
                    Trajectory.Target.Set(navigationWaypoint.celestialBody,
                                          navigationWaypoint.celestialBody.GetRelSurfacePosition(navigationWaypoint.latitude, navigationWaypoint.longitude, navigationWaypoint.altitude));
                    ScreenMessages.PostScreenMessage("Targeting waypoint " + navigationWaypoint.name);
                }
                GUILayout.EndHorizontal();

                GUI.enabled = true;

                GUILayout.BeginHorizontal();
                coords = GUILayout.TextField(Trajectory.Target.ManualText, GUILayout.Width(170));
                if (coords != Trajectory.Target.ManualText)
                {
                    Trajectory.Target.ManualText = coords;
                    Trajectory.Target.Save();
                }
                if (GUILayout.Button(new GUIContent("Set",
                                                    "Enter target latitude and longitude, separated by a comma, in decimal format (with a dot for decimal separator)"),
                                     GUILayout.Width(50)))
                {
                    string[] latLng = coords.Split(new char[] { ',', ';' });
                    var      body   = FlightGlobals.currentMainBody;
                    if (latLng.Length == 2 && body != null)
                    {
                        double lat;
                        double lng;
                        if (double.TryParse(latLng[0].Trim(), out lat) && double.TryParse(latLng[1].Trim(), out lng))
                        {
                            Vector3d relPos   = body.GetWorldSurfacePosition(lat, lng, 2.0) - body.position;
                            double   altitude = Trajectory.GetGroundAltitude(body, relPos) + body.Radius;
                            Trajectory.Target.Set(body, relPos * (altitude / relPos.magnitude));
                        }
                    }
                }
                GUILayout.EndHorizontal();
            }

            GUILayout.Space(10);

            GUILayout.BeginHorizontal();
            bool descentProfileGroup = Settings.fetch.DisplayDescentProfileGUI = ToggleGroup(Settings.fetch.DisplayDescentProfileGUI, "Descent profile", 120);

            DescentProfile.fetch.DoQuickControlsGUI();
            GUILayout.EndHorizontal();
            if (descentProfileGroup)
            {
                DescentProfile.fetch.DoGUI();
            }
            GUILayout.Space(10);

            if (Settings.fetch.DisplaySettingsGUI = ToggleGroup(Settings.fetch.DisplaySettingsGUI, "Settings"))
            {
                GUILayout.BeginHorizontal();
                GUILayout.Label("Max patches", GUILayout.Width(100));
                Settings.fetch.MaxPatchCount = Mathf.RoundToInt(GUILayout.HorizontalSlider((float)Settings.fetch.MaxPatchCount, 3, 10, GUILayout.Width(100)));
                GUILayout.Label(Settings.fetch.MaxPatchCount.ToString(), GUILayout.Width(15));
                GUILayout.EndHorizontal();

                GUILayout.BeginHorizontal();
                GUILayout.Label("Max frames per patch", GUILayout.Width(100));
                Settings.fetch.MaxFramesPerPatch = Mathf.RoundToInt(GUILayout.HorizontalSlider((float)Settings.fetch.MaxFramesPerPatch, 1, 50, GUILayout.Width(100)));
                GUILayout.Label(Settings.fetch.MaxFramesPerPatch.ToString(), GUILayout.Width(15));
                GUILayout.EndHorizontal();

                GUILayout.BeginHorizontal();
                Settings.fetch.UseCache = GUILayout.Toggle(Settings.fetch.UseCache, new GUIContent("Use Cache", "Toggle cache usage. Trajectory will be more precise when cache disabled, but computation time will be higher. It's not recommended to keep it unchecked, unless your CPU can handle the load."), GUILayout.Width(80));
                GUILayout.EndHorizontal();

                GUILayout.BeginHorizontal();
                Settings.fetch.AutoUpdateAerodynamicModel = GUILayout.Toggle(Settings.fetch.AutoUpdateAerodynamicModel, new GUIContent("Auto update", "Auto-update of the aerodynamic model. For example if a part is decoupled, the model needs to be updated. This is independent from trajectory update."));
                if (GUILayout.Button("Update now"))
                {
                    traj.InvalidateAerodynamicModel();
                }
                GUILayout.EndHorizontal();

                if (ToolbarManager.ToolbarAvailable)
                {
                    Settings.fetch.UseBlizzyToolbar = GUILayout.Toggle(Settings.fetch.UseBlizzyToolbar, new GUIContent("Use Blizzy's toolbar", "Will take effect after restart"));
                }

                if (FlightGlobals.ActiveVessel != null)
                {
                    GUILayout.Label("Position:");
                    GUILayout.BeginHorizontal();
                    GUILayout.Label("lat=" + guistring_Latitude, GUILayout.Width(110));
                    GUILayout.Label("lng=" + guistring_Longitude, GUILayout.Width(110));
                    GUILayout.EndHorizontal();
                }

                GUILayout.Label("Aerodynamic model: " + traj.AerodynamicModelName);
                GUILayout.BeginHorizontal();
                GUILayout.Label(String.Format("Perf: {0,5:F1}ms ({1,4:F1})%",
                                              traj.ComputationTime * 1000.0f,
                                              traj.ComputationTime / traj.GameFrameTime * 100.0f
                                              ), GUILayout.Width(130));
                GUILayout.Label(traj.ErrorCount + " error(s)", GUILayout.Width(80));
                GUILayout.EndHorizontal();

                GUILayout.BeginHorizontal();
                if (GUILayout.Toggle(Settings.fetch.NewGui, new GUIContent("New Gui", "Swap to the New Gui")))
                {
                    Settings.fetch.NewGui         = true;
                    Settings.fetch.MainGUIEnabled = true;
                    Settings.fetch.GUIEnabled     = false;
                    InputLockManager.RemoveControlLock("TrajectoriesFlightLock");
                    clickThroughLocked = false;
                }
                else
                {
                    Settings.fetch.NewGui         = false;
                    Settings.fetch.MainGUIEnabled = false;
                    Settings.fetch.GUIEnabled     = true;
                }
                GUILayout.EndHorizontal();
            }

            tooltip = GUI.tooltip;

            GUI.DragWindow();
        }
        public override void OnFixedUpdate()
        {
            base.OnFixedUpdate();
            if (IsEnabled && myAttachedReactor != null && FNRadiator.hasRadiatorsForVessel(vessel))
            {
                updateGeneratorPower();

                // check if MaxStableMegaWattPower is changed
                var maxStableMegaWattPower = MaxStableMegaWattPower;
                if (maxStableMegaWattPower != _previousMaxStableMegaWattPower)
                {
                    _powerState = PowerStates.powerChange;
                }

                _previousMaxStableMegaWattPower = maxStableMegaWattPower;

                if (maxStableMegaWattPower > 0 && (TimeWarp.fixedDeltaTime != previousTimeWarp || _powerState != PowerStates.powerOnline))
                {
                    _powerState = PowerStates.powerOnline;

                    var powerBufferingBonus      = myAttachedReactor.PowerBufferBonus * maxStableMegaWattPower;
                    var requiredMegawattCapacity = Math.Max(0.0001, TimeWarp.fixedDeltaTime * maxStableMegaWattPower + powerBufferingBonus);
                    var previousMegawattCapacity = Math.Max(0.0001, previousTimeWarp * maxStableMegaWattPower + powerBufferingBonus);

                    if (megajouleResource != null)
                    {
                        megajouleResource.maxAmount = requiredMegawattCapacity;

                        if (maxStableMegaWattPower > 0.1)
                        {
                            megajouleResource.amount = requiredMegawattCapacity > previousMegawattCapacity
                                    ? Math.Max(0, Math.Min(requiredMegawattCapacity, megajouleResource.amount + requiredMegawattCapacity - previousMegawattCapacity))
                                    : Math.Max(0, Math.Min(requiredMegawattCapacity, (megajouleResource.amount / megajouleResource.maxAmount) * requiredMegawattCapacity));
                        }
                    }

                    //PartResource wasteheatResource = part.Resources.list.FirstOrDefault(r => r.resourceName == FNResourceManager.FNRESOURCE_WASTEHEAT);
                    //if (wasteheatResource != null)
                    //{
                    //    var previousMaxAmount = wasteheatResource.maxAmount;
                    //    wasteheatResource.maxAmount = TimeWarp.fixedDeltaTime * part.mass * 1000;
                    //    this.part.RequestResource(FNResourceManager.FNRESOURCE_WASTEHEAT, previousTimeWarp > TimeWarp.fixedDeltaTime ? previousMaxAmount - wasteheatResource.maxAmount : 0);
                    //}

                    PartResource electricChargeResource = part.Resources.list.FirstOrDefault(r => r.resourceName == "ElectricCharge");
                    if (electricChargeResource != null)
                    {
                        //if (maxStableMegaWattPower <= 0)
                        electricChargeResource.maxAmount = requiredMegawattCapacity;
                        electricChargeResource.amount    = maxStableMegaWattPower <= 0 ? 0 : Math.Min(electricChargeResource.maxAmount, electricChargeResource.amount);
                    }
                }
                previousTimeWarp = TimeWarp.fixedDeltaTime;

                // don't produce any power when our reactor has stopped
                if (maxStableMegaWattPower <= 0)
                {
                    PowerDown();
                    return;
                }
                else
                {
                    powerDownFraction = 1;
                }

                double electrical_power_currently_needed;

                if (myAttachedReactor.ShouldApplyBalance(chargedParticleMode ? ElectricGeneratorType.charged_particle : ElectricGeneratorType.thermal))
                {
                    var chargedPowerPerformance = myAttachedReactor.EfficencyConnectedChargedEnergyGenrator * myAttachedReactor.ChargedPowerRatio;
                    var thermalPowerPerformance = myAttachedReactor.EfficencyConnectedThermalEnergyGenrator * (1 - myAttachedReactor.ChargedPowerRatio);

                    var totalPerformance        = chargedPowerPerformance + thermalPowerPerformance;
                    var balancePerformanceRatio = (chargedParticleMode ? chargedPowerPerformance / totalPerformance : thermalPowerPerformance / totalPerformance);

                    electrical_power_currently_needed = (getCurrentUnfilledResourceDemand(FNResourceManager.FNRESOURCE_MEGAJOULES) + getSpareResourceCapacity(FNResourceManager.FNRESOURCE_MEGAJOULES)) * balancePerformanceRatio;
                }
                else
                {
                    electrical_power_currently_needed = getCurrentUnfilledResourceDemand(FNResourceManager.FNRESOURCE_MEGAJOULES) + getSpareResourceCapacity(FNResourceManager.FNRESOURCE_MEGAJOULES);
                }


                double electricdt       = 0;
                double electricdtps     = 0;
                double max_electricdtps = 0;

                if (!chargedParticleMode) // thermal mode
                {
                    double carnotEff = 1.0 - coldBathTemp / hotBathTemp;
                    _totalEff = carnotEff * pCarnotEff * myAttachedReactor.ThermalEnergyEfficiency;

                    myAttachedReactor.NotifyActiveThermalEnergyGenrator(_totalEff, ElectricGeneratorType.thermal);

                    if (_totalEff <= 0 || coldBathTemp <= 0 || hotBathTemp <= 0 || maxThermalPower <= 0)
                    {
                        return;
                    }

                    double thermal_power_currently_needed = electrical_power_currently_needed / _totalEff; // _totalEff;

                    double thermal_power_requested = Math.Max(Math.Min(maxThermalPower, thermal_power_currently_needed) * TimeWarp.fixedDeltaTime, 0.0);

                    requestedPower_f = (float)thermal_power_requested / TimeWarp.fixedDeltaTime;

                    double input_power = consumeFNResource(thermal_power_requested, FNResourceManager.FNRESOURCE_THERMALPOWER);

                    if (!(myAttachedReactor.EfficencyConnectedChargedEnergyGenrator > 0) && input_power < thermal_power_requested)
                    {
                        input_power += consumeFNResource(thermal_power_requested - input_power, FNResourceManager.FNRESOURCE_CHARGED_PARTICLES);
                    }

                    double wastedt = input_power * _totalEff;

                    consumeFNResource(wastedt, FNResourceManager.FNRESOURCE_WASTEHEAT);
                    electricdt       = input_power * _totalEff;
                    electricdtps     = Math.Max(electricdt / TimeWarp.fixedDeltaTime, 0.0);
                    max_electricdtps = maxThermalPower * _totalEff;
                }
                else // charged particle mode
                {
                    _totalEff = isupgraded ? upgradedDirectConversionEff : directConversionEff;

                    myAttachedReactor.NotifyActiveChargedEnergyGenrator(_totalEff, ElectricGeneratorType.charged_particle);

                    if (_totalEff <= 0)
                    {
                        return;
                    }

                    double charged_power_currently_needed = electrical_power_currently_needed; // _totalEff / ;

                    var charged_power_requested = Math.Max(Math.Min(maxChargedPower, charged_power_currently_needed) * TimeWarp.fixedDeltaTime, 0.0);

                    requestedPower_f = (float)charged_power_requested / TimeWarp.fixedDeltaTime;

                    double input_power = consumeFNResource(charged_power_requested, FNResourceManager.FNRESOURCE_CHARGED_PARTICLES);

                    electricdt   = input_power * _totalEff;
                    electricdtps = Math.Max(electricdt / TimeWarp.fixedDeltaTime, 0.0);
                    double wastedt = input_power * _totalEff;
                    max_electricdtps = maxChargedPower * _totalEff;
                    consumeFNResource(wastedt, FNResourceManager.FNRESOURCE_WASTEHEAT);
                }
                outputPower = -(float)supplyFNResourceFixedMax(electricdtps * TimeWarp.fixedDeltaTime, max_electricdtps * TimeWarp.fixedDeltaTime, FNResourceManager.FNRESOURCE_MEGAJOULES) / TimeWarp.fixedDeltaTime;
            }
            else
            {
                previousTimeWarp = TimeWarp.fixedDeltaTime;
                if (IsEnabled && !vessel.packed)
                {
                    if (!FNRadiator.hasRadiatorsForVessel(vessel))
                    {
                        IsEnabled = false;
                        Debug.Log("[WarpPlugin] Generator Shutdown: No radiators available!");
                        ScreenMessages.PostScreenMessage("Generator Shutdown: No radiators available!", 5.0f, ScreenMessageStyle.UPPER_CENTER);
                        PowerDown();
                    }

                    if (myAttachedReactor == null)
                    {
                        IsEnabled = false;
                        Debug.Log("[WarpPlugin] Generator Shutdown: No reactor available!");
                        ScreenMessages.PostScreenMessage("Generator Shutdown: No reactor available!", 5.0f, ScreenMessageStyle.UPPER_CENTER);
                        PowerDown();
                    }
                }
                else
                {
                    PowerDown();
                }
            }
        }
Beispiel #9
0
        private void GenerateTrustFromReactorHeat()
        {
            if (!myAttachedReactor.IsActive)
            {
                myAttachedReactor.enableIfPossible();
            }

            // determine ISP
            if (currentpropellant_is_jet)
            {
                updateIspEngineParams();
                this.current_isp = myAttachedEngine.atmosphereCurve.Evaluate((float)Math.Min(FlightGlobals.getStaticPressure(vessel.transform.position), 1.0));
            }
            else
            {
                maxISP          = (float)(Math.Sqrt((double)myAttachedReactor.CoreTemperature) * (PluginHelper.IspCoreTempMult + IspTempMultOffset) * GetIspPropellantModifier());
                assThermalPower = myAttachedReactor is InterstellarFusionReactor ? myAttachedReactor.MaximumPower * 0.95f : myAttachedReactor.MaximumPower;
            }

            // get the flameout safety limit
            if (currentpropellant_is_jet)
            {
                int pre_coolers_active = vessel.FindPartModulesImplementing <FNModulePreecooler>().Where(prc => prc.isFunctional()).Count();
                int intakes_open       = vessel.FindPartModulesImplementing <ModuleResourceIntake>().Where(mre => mre.intakeEnabled).Count();

                double proportion = Math.Pow((double)(intakes_open - pre_coolers_active) / (double)intakes_open, 0.1);
                if (double.IsNaN(proportion) || double.IsInfinity(proportion))
                {
                    proportion = 1;
                }

                float temp = (float)Math.Max((Math.Sqrt(vessel.srf_velocity.magnitude) * 20.0 / GameConstants.atmospheric_non_precooled_limit) * part.maxTemp * proportion, 1);
                if (temp > part.maxTemp - 10.0f)
                {
                    ScreenMessages.PostScreenMessage("Engine Shutdown: Catastrophic overheating was imminent!", 5.0f, ScreenMessageStyle.UPPER_CENTER);
                    myAttachedEngine.Shutdown();
                    part.temperature = 1;
                }
                else
                {
                    part.temperature = temp;
                }
            }

            double thermal_consume_total  = assThermalPower * TimeWarp.fixedDeltaTime * myAttachedEngine.currentThrottle * GetAtmosphericLimit();
            double thermal_power_received = consumeFNResource(thermal_consume_total, FNResourceManager.FNRESOURCE_THERMALPOWER) / TimeWarp.fixedDeltaTime;

            if (thermal_power_received * TimeWarp.fixedDeltaTime < thermal_consume_total)
            {
                thermal_power_received += consumeFNResource(thermal_consume_total - thermal_power_received * TimeWarp.fixedDeltaTime, FNResourceManager.FNRESOURCE_CHARGED_PARTICLES) / TimeWarp.fixedDeltaTime;
            }

            consumeFNResource(thermal_power_received * TimeWarp.fixedDeltaTime, FNResourceManager.FNRESOURCE_WASTEHEAT);

            // calculate max thrust
            double engineMaxThrust = 0.01;

            if (assThermalPower > 0)
            {
                double ispRatio     = currentpropellant_is_jet ? this.current_isp / maxISP : 1;
                double thrust_limit = myAttachedEngine.thrustPercentage / 100.0;
                engineMaxThrust = Math.Max(thrust_limit * GetPowerTrustModifier() * GetHeatTrustModifier() * thermal_power_received / maxISP / PluginHelper.GravityConstant * heatExchangerThrustDivisor * ispRatio / myAttachedEngine.currentThrottle, 0.01);
            }

            double max_thrust_in_space = engineMaxThrust / myAttachedEngine.thrustPercentage * 100.0;
            double engine_thrust       = max_thrust_in_space;

            // update engine thrust/ISP for thermal noozle
            if (!currentpropellant_is_jet)
            {
                pressureTreshold = exitArea * (float)GameConstants.EarthAthmospherePresureAtSeaLevel * (float)FlightGlobals.getStaticPressure(vessel.transform.position);
                engine_thrust    = Math.Max(max_thrust_in_space - pressureTreshold, 0.00001);
                var thrustAtmosphereRatio  = engine_thrust / Math.Max(max_thrust_in_space, 0.000001);
                var isp_reduction_fraction = thrustAtmosphereRatio * heatExchangerThrustDivisor;
                updateIspEngineParams(isp_reduction_fraction, max_thrust_in_space);
                this.current_isp = maxISP * isp_reduction_fraction;
            }

            if (!double.IsInfinity(engine_thrust) && !double.IsNaN(engine_thrust))
            {
                myAttachedEngine.maxThrust = thrustPropellantMultiplier == 1f ? (float)engine_thrust : (float)(engine_thrust * thrustPropellantMultiplier);
            }
            else
            {
                myAttachedEngine.maxThrust = 0.000001f;
            }

            // amount of fuel being used at max throttle with no atmospheric limits
            if (current_isp > 0)
            {
                double vcurve_at_current_velocity = 1;

                if (myAttachedEngine.useVelocityCurve && myAttachedEngine.velocityCurve != null)
                {
                    vcurve_at_current_velocity = myAttachedEngine.velocityCurve.Evaluate((float)vessel.srf_velocity.magnitude);
                }

                fuel_flow_rate = engine_thrust / current_isp / PluginHelper.GravityConstant / 0.005 * TimeWarp.fixedDeltaTime;
                if (vcurve_at_current_velocity > 0 && !double.IsInfinity(vcurve_at_current_velocity) && !double.IsNaN(vcurve_at_current_velocity))
                {
                    this.fuel_flow_rate = fuel_flow_rate / vcurve_at_current_velocity;
                }

                if (atmospheric_limit > 0 && !double.IsInfinity(atmospheric_limit) && !double.IsNaN(atmospheric_limit))
                {
                    this.fuel_flow_rate = fuel_flow_rate / atmospheric_limit;
                }
            }
        }
        private void Update()
        {
            safeDisplay = display;
            if (workerEnabled)
            {
                while (craftAddQueue.Count > 0)
                {
                    CraftChangeEntry cce = craftAddQueue.Dequeue();
                    AddCraftEntry(cce.playerName, cce.craftType, cce.craftName);
                }

                while (craftDeleteQueue.Count > 0)
                {
                    CraftChangeEntry cce = craftDeleteQueue.Dequeue();
                    DeleteCraftEntry(cce.playerName, cce.craftType, cce.craftName);
                }

                while (craftResponseQueue.Count > 0)
                {
                    CraftResponseEntry cre = craftResponseQueue.Dequeue();
                    SaveCraftFile(cre.craftType, cre.craftName, cre.craftData);
                }

                if (uploadCraftName != null)
                {
                    UploadCraftFile(uploadCraftType, uploadCraftName);
                    uploadCraftName = null;
                    uploadCraftType = CraftType.VAB;
                }

                if (downloadCraftName != null)
                {
                    DownloadCraftFile(selectedPlayer, downloadCraftType, downloadCraftName);
                    downloadCraftName = null;
                    downloadCraftType = CraftType.VAB;
                }

                if (deleteCraftName != null)
                {
                    DeleteCraftEntry(Settings.fetch.playerName, deleteCraftType, deleteCraftName);
                    using (MessageWriter mw = new MessageWriter())
                    {
                        mw.Write <int>((int)CraftMessageType.DELETE_FILE);
                        mw.Write <string>(Settings.fetch.playerName);
                        mw.Write <int>((int)deleteCraftType);
                        mw.Write <string>(deleteCraftName);
                        NetworkWorker.fetch.SendCraftLibraryMessage(mw.GetMessageBytes());
                    }
                    deleteCraftName = null;
                    deleteCraftType = CraftType.VAB;
                }

                if (displayCraftUploadingMessage && ((UnityEngine.Time.realtimeSinceStartup - lastCraftMessageCheck) > CRAFT_MESSAGE_CHECK_INTERVAL))
                {
                    lastCraftMessageCheck = UnityEngine.Time.realtimeSinceStartup;
                    if (craftUploadMessage != null)
                    {
                        craftUploadMessage.duration = 0f;
                    }
                    if (finishedUploadingCraft)
                    {
                        displayCraftUploadingMessage = false;
                        craftUploadMessage           = ScreenMessages.PostScreenMessage("Craft uploaded!", 2f, ScreenMessageStyle.UPPER_CENTER);
                    }
                    else
                    {
                        craftUploadMessage = ScreenMessages.PostScreenMessage("Uploading craft...", 1f, ScreenMessageStyle.UPPER_CENTER);
                    }
                }
            }
        }
        public void onVesselAboutToBeDestroyed(EventReport report)
        {
            Debug.Log("[KSPI] - Handling Impactor");

            ConfigNode config;
            ConfigNode science_node;

            Vessel vessel = report.origin.vessel;
            float  vesselMass;
            int    science_experiment_number = 0;

            string vessel_impact_node_string  = string.Concat("IMPACT_", vessel.id.ToString());
            string vessel_seismic_node_string = string.Concat("SEISMIC_SCIENCE_", vessel.mainBody.name.ToUpper());

            // Do nothing if we don't have a vessel.  This seems improbable, but who knows.
            if (vessel == null)
            {
                Debug.Log("[KSPI] - Impactor: Ignored because the vessel is undefined.");
                return;
            }

            // Do nothing if we have recorded an impact less than 10 physics updates ago.  This probably means this call
            // is a duplicate of a previous call.
            if (Planetarium.GetUniversalTime() - this.lastImpactTime < TimeWarp.fixedDeltaTime * 10f)
            {
                Debug.Log("[KSPI] - Impactor: Ignored because we've just recorded an impact.");
                return;
            }

            // Do nothing if we are a debris item less than ten physics-updates old.  That probably means we were
            // generated by a recently-recorded impact.
            if (vessel.vesselType == VesselType.Debris && vessel.missionTime < Time.fixedDeltaTime * 10f)
            {
                Debug.Log("[KSPI] - Impactor: Ignored due to vessel being brand-new debris.");
                return;
            }

            vesselMass = vessel.GetTotalMass();

            // Do nothing if we aren't very near the terrain.  Note that using heightFromTerrain probably allows
            // impactors against the ocean floor... good luck.
            float vesselDimension = vessel.MOI.magnitude / vesselMass;

            if (vessel.heightFromSurface > Mathf.Max(vesselDimension, 0.75f))
            {
                Debug.Log("[KSPI] - Impactor: Ignored due to vessel altitude being too high.");
                return;
            }

            // Do nothing if we aren't impacting the surface.
            if (!(
                    report.other.ToLower().Contains(string.Intern("surface")) ||
                    report.other.ToLower().Contains(string.Intern("terrain")) ||
                    report.other.ToLower().Contains(vessel.mainBody.name.ToLower())
                    ))
            {
                Debug.Log("[KSPI] - Impactor: Ignored due to not impacting the surface.");
                return;
            }

            /*
             * NOTE: This is a deviation from current KSPI behavior.  KSPI currently registers an impact over 40 m/s
             * regardless of its mass; this means that trivially light impactors (single instruments, even) could
             * trigger the experiment.
             *
             * The guard below requires that the impactor have at least as much vertical impact energy as a 1 Mg
             * object traveling at 40 m/s.  This means that nearly-tangential impacts or very light impactors will need
             * to be much faster, but that heavier impactors may be slower.
             *
             * */
            if ((Math.Pow(vessel.verticalSpeed, 2d) * vesselMass / 2d < 800d) && vessel.verticalSpeed > 20d)
            {
                Debug.Log("[KSPI] - Impactor: Ignored due to vessel imparting too little impact energy.");
                return;
            }

            config = PluginHelper.getPluginSaveFile();
            if (config.HasNode(vessel_seismic_node_string))
            {
                science_node = config.GetNode(vessel_seismic_node_string);
                science_experiment_number = science_node.nodes.Count;

                if (science_node.HasNode(vessel_impact_node_string))
                {
                    Debug.Log("[KSPI] - Impactor: Ignored because this vessel's impact has already been recorded.");
                    return;
                }
            }
            else
            {
                science_node = config.AddNode(vessel_seismic_node_string);
                science_node.AddValue("name", "interstellarseismicarchive");
            }

            int      body                = vessel.mainBody.flightGlobalsIndex;
            Vector3d net_vector          = Vector3d.zero;
            bool     first               = true;
            double   distribution_factor = 0;

            foreach (Vessel conf_vess in FlightGlobals.Vessels)
            {
                String vessel_probe_node_string = string.Concat("VESSEL_SEISMIC_PROBE_", conf_vess.id.ToString());

                if (config.HasNode(vessel_probe_node_string))
                {
                    ConfigNode probe_node = config.GetNode(vessel_probe_node_string);

                    // If the seismometer is inactive, skip it.
                    bool is_active = false;
                    if (probe_node.HasValue("is_active"))
                    {
                        bool.TryParse(probe_node.GetValue("is_active"), out is_active);
                        if (!is_active)
                        {
                            continue;
                        }
                    }

                    // If the seismometer is on another planet, skip it.
                    int planet = -1;
                    if (probe_node.HasValue("celestial_body"))
                    {
                        int.TryParse(probe_node.GetValue("celestial_body"), out planet);
                        if (planet != body)
                        {
                            continue;
                        }
                    }

                    // do sciency stuff
                    Vector3d surface_vector = (conf_vess.transform.position - FlightGlobals.Bodies[body].transform.position);
                    surface_vector = surface_vector.normalized;
                    if (first)
                    {
                        first               = false;
                        net_vector          = surface_vector;
                        distribution_factor = 1;
                    }
                    else
                    {
                        distribution_factor += 1.0 - Vector3d.Dot(surface_vector, net_vector.normalized);
                        net_vector           = net_vector + surface_vector;
                    }
                }
            }

            distribution_factor = Math.Min(distribution_factor, 3.5); // no more than 3.5x boost to science by using multiple detectors
            if (distribution_factor > 0 && !double.IsInfinity(distribution_factor) && !double.IsNaN(distribution_factor))
            {
                ScreenMessages.PostScreenMessage("Impact Recorded, science report can now be accessed from one of your accelerometers deployed on this body.", 5f, ScreenMessageStyle.UPPER_CENTER);
                this.lastImpactTime = Planetarium.GetUniversalTime();
                Debug.Log("[KSPI] - Impactor: Impact registered!");

                ConfigNode impact_node = new ConfigNode(vessel_impact_node_string);
                impact_node.AddValue(string.Intern("transmitted"), bool.FalseString);
                impact_node.AddValue(string.Intern("vesselname"), vessel.vesselName);
                impact_node.AddValue(string.Intern("distribution_factor"), distribution_factor);
                science_node.AddNode(impact_node);

                config.Save(PluginHelper.PluginSaveFilePath);
            }
        }
Beispiel #12
0
        private void DrawButtonsBlock(float widthOffset)
        {
            if (GUI.Button(new Rect(widthOffset, 36, ButtonSize, ButtonSize), "↻"))
            {
                //_camObject.transform.Rotate(new Vector3(0, 0, 180f));
                _camObject.transform.Rotate(new Vector3(0, 0, 90f));
                _isUpsideDown = !_isUpsideDown;
                _alignment++;
                if ((int)_alignment > 3)
                {
                    _alignment = Alignment.up;
                }
            }
            if (GUI.RepeatButton(new Rect(widthOffset + ButtonSize, 36, ButtonSize, ButtonSize), "↑"))
            {
                switch (_alignment)
                {
                case Alignment.up: RotateY += _rotateStep; break;

                case Alignment.right: RotateZ -= _rotateStep; break;

                case Alignment.down: RotateY -= _rotateStep; break;

                case Alignment.left: RotateZ += _rotateStep; break;
                }
            }
            if (GUI.Button(new Rect(widthOffset + ButtonSize * 2, 36, ButtonSize, ButtonSize), "⦿"))
            {
                if (ThisPart.vessel.Equals(FlightGlobals.ActiveVessel))
                {
                    if (!TargetHelper.IsTargetSelect)
                    {
                        ScreenMessages.PostScreenMessage("NO TARGET FOR SCANNING", 3f, ScreenMessageStyle.UPPER_CENTER);
                    }
                    else
                    {
                        if (Hits <= 0)
                        {
                            ScreenMessages.PostScreenMessage("BULLETS DEPLETED", 3f, ScreenMessageStyle.UPPER_CENTER);
                        }
                        else
                        {
                            var    id = PartResourceLibrary.Instance.GetDefinition(_resourceName).id;
                            double amount;
                            double maxAmount;
                            ThisPart.GetConnectedResourceTotals(id, out amount, out maxAmount);
                            if (amount > _resourceUsage)
                            {
                                ThisPart.RequestResource(id, (double)_resourceUsage);
                                var hit = PartGameObject.GetChild($"{_bulletName}{Hits:000}");
                                Object.Destroy(hit);
                                Hits--;
                                _isRayEnabled      = true;
                                IsWaitForRay       = true;
                                _isScienceActivate = false;
                            }
                            else
                            {
                                ScreenMessages.PostScreenMessage("NOT ENOUGH ELECTRICITY FOR SCAN", 3f, ScreenMessageStyle.UPPER_CENTER);
                            }
                        }
                        //if (HitCounter() && UseResourceForScanning())
                        //{
                        //    _isRayEnabled = true;
                        //    IsWaitForRay = true;
                        //    _isScienceActivate = false;
                        //}
                    }
                }
                else
                {
                    ScreenMessages.PostScreenMessage("Camera not on active vessel", 3f, ScreenMessageStyle.UPPER_CENTER);
                }
            }
            if (GUI.RepeatButton(new Rect(widthOffset, 36 + ButtonSize, ButtonSize, ButtonSize), "←"))
            {
                switch (_alignment)
                {
                case Alignment.up: RotateZ -= _rotateStep; break;

                case Alignment.right: RotateY -= _rotateStep; break;

                case Alignment.down: RotateZ += _rotateStep; break;

                case Alignment.left: RotateY += _rotateStep; break;
                }
            }
            if (GUI.Button(new Rect(widthOffset + ButtonSize, 36 + ButtonSize, ButtonSize, ButtonSize), "o"))
            {
                IsToZero = true;
            }
            if (GUI.RepeatButton(new Rect(widthOffset + ButtonSize * 2, 36 + ButtonSize, ButtonSize, ButtonSize), "→"))
            {
#if false
                if (!_isUpsideDown)
                {
                    RotateZ += _rotateStep;
                }
                else
                {
                    RotateZ -= _rotateStep;
                }
#endif
                switch (_alignment)
                {
                case Alignment.up: RotateZ += _rotateStep; break;

                case Alignment.right: RotateY += _rotateStep; break;

                case Alignment.down: RotateZ -= _rotateStep; break;

                case Alignment.left: RotateY -= _rotateStep; break;
                }
            }
            if (GUI.Button(new Rect(widthOffset, 36 + ButtonSize * 2, ButtonSize, ButtonSize), "-"))
            {
                CurrentZoom += 0.5f;
                if (CurrentZoom > MaxZoom)
                {
                    CurrentZoom = MaxZoom;
                }
            }
            if (GUI.RepeatButton(new Rect(widthOffset + ButtonSize, 36 + ButtonSize * 2, ButtonSize, ButtonSize), "↓"))
            {
#if false
                if (_rotateYbuffer > 0)
                {
                    if (!_isUpsideDown)
                    {
                        RotateY -= _rotateStep;
                    }
                    else
                    {
                        RotateY += _rotateStep;
                    }
                }
#endif
                switch (_alignment)
                {
                case Alignment.up: RotateY -= _rotateStep; break;

                case Alignment.right: RotateZ += _rotateStep; break;

                case Alignment.down: RotateY += _rotateStep; break;

                case Alignment.left: RotateZ -= _rotateStep; break;
                }
            }
            if (GUI.Button(new Rect(widthOffset + ButtonSize * 2, 36 + ButtonSize * 2, ButtonSize, ButtonSize), "+"))
            {
                CurrentZoom -= 0.5f;
                if (CurrentZoom < MinZoom)
                {
                    CurrentZoom = MinZoom;
                }
            }
        }
Beispiel #13
0
        public override void OnStart(StartState state)
        {
            base.OnStart(state);
            if (state == StartState.Editor || state == StartState.None)
            {
                return;
            }
            //Loading texture
            texStrut = GameDatabase.Instance.GetTexture(tubeTexPath, false);
            if (!texStrut)
            {
                KAS_Shared.DebugError("tube texture loading error !");
                ScreenMessages.PostScreenMessage(
                    string.Format(
                        "Texture file : {0} has not been found, please check your KAS installation !",
                        tubeTexPath),
                    10, ScreenMessageStyle.UPPER_CENTER);
            }
            // loading sounds
            KAS_Shared.createFXSound(this.part, fxSndLink, sndLinkPath, false);
            KAS_Shared.createFXSound(this.part, fxSndUnlink, sndUnlinkPath, false);
            KAS_Shared.createFXSound(this.part, fxSndBroke, sndBrokePath, false);

            // loading strut renderer
            strutRenderer = this.part.gameObject.AddComponent <KAS_Tube>();
            strutRenderer.tubeTexTilingOffset = textureTiling;
            strutRenderer.tubeScale           = tubeScale;
            strutRenderer.sphereScale         = jointScale;
            strutRenderer.tubeTexture         = texStrut;
            strutRenderer.sphereTexture       = texStrut;
            strutRenderer.tubeJoinedTexture   = texStrut;
            strutRenderer.srcNode             = strutTransform;

            // loading tube type
            switch (tubeSrcType)
            {
            case "None":
                strutRenderer.srcJointType = KAS_Tube.tubeJointType.None;
                break;

            case "Rounded":
                strutRenderer.srcJointType = KAS_Tube.tubeJointType.Rounded;
                break;

            case "ShiftedAndRounded":
                strutRenderer.srcJointType = KAS_Tube.tubeJointType.ShiftedAndRounded;
                break;

            case "Joined":
                strutRenderer.srcJointType = KAS_Tube.tubeJointType.Joined;
                break;

            default:
                strutRenderer.srcJointType = KAS_Tube.tubeJointType.Joined;
                break;
            }
            switch (tubeTgtType)
            {
            case "None":
                strutRenderer.tgtJointType = KAS_Tube.tubeJointType.None;
                break;

            case "Rounded":
                strutRenderer.tgtJointType = KAS_Tube.tubeJointType.Rounded;
                break;

            case "ShiftedAndRounded":
                strutRenderer.tgtJointType = KAS_Tube.tubeJointType.ShiftedAndRounded;
                break;

            case "Joined":
                strutRenderer.tgtJointType = KAS_Tube.tubeJointType.Joined;
                break;

            default:
                strutRenderer.tgtJointType = KAS_Tube.tubeJointType.Joined;
                break;
            }

            // Reset link if docked
            if (attachMode.Docked && !linked)
            {
                KAS_Shared.DebugLog("OnStart(strut) Docked strut detected from save, relinking...");
                KASModuleStrut linkedStrutModuleSavedD = dockedAttachModule.GetComponent <KASModuleStrut>();
                LinkTo(linkedStrutModuleSavedD, false, true);
            }

            // Loading onVesselWasModified KSP event
            GameEvents.onVesselWasModified.Add(new EventData <Vessel> .OnEvent(this.OnVesselWasModified));
        }
Beispiel #14
0
        private bool LinkTo(KASModuleStrut tgtModule, bool checkCondition = true,
                            bool setJointOrDock = true)
        {
            //Check condition if needed
            if (checkCondition)
            {
                if (!CheckLink(this.strutTransform, tgtModule.strutTransform, true))
                {
                    ScreenMessages.PostScreenMessage("Max angle or length reached, cannot link!",
                                                     5, ScreenMessageStyle.UPPER_CENTER);
                    return(false);
                }

                if (tgtModule == this)
                {
                    ScreenMessages.PostScreenMessage(
                        string.Format("{0} cannot be linked to itself!", part.partInfo.title),
                        5, ScreenMessageStyle.UPPER_CENTER);
                    return(false);
                }

                if (tgtModule.type != this.type)
                {
                    ScreenMessages.PostScreenMessage(
                        string.Format("{0} cannot be linked to {1} because they are not compatible!",
                                      part.partInfo.title, tgtModule.part.partInfo.title),
                        5, ScreenMessageStyle.UPPER_CENTER);
                    return(false);
                }

                if (tgtModule.vessel != vessel && !allowDock)
                {
                    ScreenMessages.PostScreenMessage(
                        string.Format("{0} cannot be linked to another vessel!", part.partInfo.title),
                        5, ScreenMessageStyle.UPPER_CENTER);
                    return(false);
                }
            }

            // Load tube renderer in this module
            this.StopEvaLink();
            this.strutRenderer.tgtNode    = tgtModule.strutTransform;
            this.strutRenderer.shaderName = "Diffuse";
            this.strutRenderer.color      = Color.white;
            this.strutRenderer.color.a    = 1f;
            this.strutRenderer.Load();

            // Set references for the current module
            this.Events["ContextMenuUnlink"].guiActiveUnfocused = true;
            this.Events["ContextMenuLink"].guiActiveUnfocused   = false;
            this.linkedStrutModule = tgtModule;
            this.linked            = true;

            // Set references for the target module
            tgtModule.linkedStrutModule = this;
            tgtModule.Events["ContextMenuUnlink"].guiActiveUnfocused = true;
            tgtModule.Events["ContextMenuLink"].guiActiveUnfocused   = false;
            tgtModule.linked = true;
            tgtStrutPartID   = tgtModule.part.flightID.ToString();
            tgtStrutVesselID = tgtModule.part.vessel.id.ToString();

            KAS_Shared.InvalidateContextMenu(this.part);
            KAS_Shared.InvalidateContextMenu(tgtModule.part);

            if (setJointOrDock)
            {
                // Create joint or dock part
                if (tgtModule.vessel == vessel)
                {
                    if (tgtModule.part.parent != part && part.parent != tgtModule.part)
                    {
                        KAS_Shared.DebugLog("LinkTo(Strut) Parts are from the same vessel but are not connected,"
                                            + " setting joint...");
                        if (part.parent && tgtModule.part.parent)
                        {
                            KAS_Shared.DebugLog("LinkTo(Strut) Set joint on struts parents");
                            AttachFixed(part.parent, tgtModule.part.parent, breakForce);
                        }
                        else
                        {
                            KAS_Shared.DebugLog("LinkTo(Strut) Set joint on struts");
                            AttachFixed(part, tgtModule.part, breakForce);
                        }
                    }
                }
                else
                {
                    KAS_Shared.DebugLog("LinkTo(Strut) Parts are from a different vessel, docking...");
                    AttachDocked(tgtModule);
                }
            }
            else
            {
                KAS_Shared.DebugLog("LinkTo(Strut) setJointOrDock = false, ignoring dock and creating joint");
            }

            // Connect fuel flow when appropriate
            bool both_attached =
                this.part.srfAttachNode.attachedPart && tgtModule.part.srfAttachNode.attachedPart;

            this.Events["ContextMenuTogglePump"].active = this.allowPumpFuel && both_attached;
            if (this.pumpFuel)
            {
                this.StartPump(checkCondition);
            }

            tgtModule.Events["ContextMenuTogglePump"].active = tgtModule.allowPumpFuel && both_attached;
            if (tgtModule.pumpFuel)
            {
                tgtModule.StartPump(checkCondition);
            }

            return(true);
        }
 // Repair the reactor to max Repair percent
 public void DoReactorRepair()
 {
     this.CoreIntegrity = MaxRepairPercent;
     ScreenMessages.PostScreenMessage(new ScreenMessage(Localizer.Format("#LOC_NFElectrical_ModuleFissionReactor_Message_Repair_RepairSuccess", MaxRepairPercent.ToString("F0")), 5.0f, ScreenMessageStyle.UPPER_CENTER));
 }
Beispiel #16
0
        ////////////////////////////

        private void ScreenMsg(string msg)
        {
            ScreenMessages.PostScreenMessage(new ScreenMessage(msg, 4, ScreenMessageStyle.UPPER_CENTER));
        }
Beispiel #17
0
        public void OnGUI()
        {
            if (siteLocations.Count < 1)
            {
                return;
            }

            if (Event.current.type == EventType.Repaint || Event.current.isMouse)
            {
                OnDraw();
            }
            GUI.skin = HighLogic.Skin;
            if (bStyle == null)
            {
                bStyle = new GUIStyle(GUI.skin.button)
                {
                    padding       = new RectOffset(),
                    contentOffset = new Vector2()
                };
            }
            if (oldButton)
            {
                if (GUI.Button(new Rect(Screen.width - 100, 45, 100, 30), "Launch Sites"))
                {
                    showWindow = !showWindow;
                }
            }
            else
            {
                if (GUI.Button(new Rect(Screen.width - 33, 45, 28, 28), (showWindow ? lsButtonHighlight : lsButtonNormal), bStyle))
                {
                    showWindow = !showWindow;
                }
            }
            if (GUI.Button(new Rect(Screen.width - 33, 78, 28, 28), (showSites ? eyeButtonHighlight : eyeButtonNormal), bStyle))
            {
                showSites = !showSites;
            }
            if (showWindow)
            {
                if (oldButton)
                {
                    GUILayout.BeginArea(new Rect(Screen.width - 333, 75, 300, 400));
                }
                else
                {
                    GUILayout.BeginArea(new Rect(Screen.width - 333, 45, 300, 400));
                }
                scrollPosition = GUILayout.BeginScrollView(scrollPosition, GUILayout.Width(300), GUILayout.Height(400));
                Color defColor = GUI.color;
                foreach (KeyValuePair <string, LaunchSite> kvp in siteLocations)
                {
                    bool isActiveSite = kvp.Value.name.Equals(activeSite);
                    GUILayout.BeginHorizontal();
                    if (GUILayout.Button(magButtonNormal, bStyle, GUILayout.MaxWidth(28)))
                    {
                        FocusOnSite(kvp.Value.geographicLocation);
                    }
                    if (isActiveSite)
                    {
                        GUI.contentColor = XKCDColors.ElectricLime;
                    }
                    if (GUILayout.Button(new GUIContent(kvp.Value.displayName, kvp.Value.description)))
                    {
                        if (isActiveSite)
                        {
                            ScreenMessages.PostScreenMessage("Cannot set launch site to active site.", 2.5f, ScreenMessageStyle.LOWER_CENTER);
                        }
                        else
                        {
                            SetSite(kvp.Value);
                        }
                    }
                    GUI.contentColor = defColor;
                    GUILayout.EndHorizontal();
                }
                GUILayout.EndScrollView();
                GUILayout.EndArea();

                GUI.backgroundColor = XKCDColors.AlmostBlack;
                if (curTooltip != "")
                {
                    if (oldButton)
                    {
                        GUI.Label(new Rect(Screen.width - 633, 75, 300, 400), GUI.tooltip, infoLabel);
                    }
                    else
                    {
                        GUI.Label(new Rect(Screen.width - 633, 45, 300, 400), GUI.tooltip, infoLabel);
                    }
                }
                if (Event.current.type == EventType.Repaint)
                {
                    curTooltip = GUI.tooltip;
                }
            }
        }
Beispiel #18
0
        // FixedUpdate is also called while not staged
        public void FixedUpdate()
        {
            var cryostat_resource = part.Resources[resourceName];

            if (cryostat_resource == null || double.IsPositiveInfinity(currentPowerReq))
            {
                boiloff = 0;
                return;
            }

            var fixedDeltaTime = (double)(decimal)Math.Round(TimeWarp.fixedDeltaTime, 7);

            if (!isDisabled && currentPowerReq > 0)
            {
                UpdateElectricChargeBuffer(Math.Max(currentPowerReq, 0.1 * powerReqKW));

                var fixedPowerReqKW = currentPowerReq * fixedDeltaTime;

                var fixedRecievedChargeKW = CheatOptions.InfiniteElectricity
                    ? fixedPowerReqKW
                    : consumeFNResource(fixedPowerReqKW / 1000, ResourceManager.FNRESOURCE_MEGAJOULES) * 1000;

                if (fixedRecievedChargeKW <= fixedPowerReqKW)
                {
                    fixedRecievedChargeKW += part.RequestResource(ResourceManager.FNRESOURCE_MEGAJOULES, (fixedPowerReqKW - fixedRecievedChargeKW) / 1000) * 1000;
                }

                if (currentPowerReq < 1000 && fixedRecievedChargeKW <= fixedPowerReqKW)
                {
                    fixedRecievedChargeKW += part.RequestResource(ResourceManager.STOCK_RESOURCE_ELECTRICCHARGE, fixedPowerReqKW - fixedRecievedChargeKW);
                }

                recievedPowerKW = fixedRecievedChargeKW / fixedDeltaTime;
            }
            else
            {
                recievedPowerKW = 0;
            }

            bool hasExtraBoiloff = initializationCountdown == 0 && powerReqKW > 0 && currentPowerReq > 0 && recievedPowerKW < currentPowerReq && previousRecievedPowerKW < previousPowerReq;

            var boiloffReducuction = !hasExtraBoiloff ? boilOffRate : boilOffRate + (boilOffAddition * (1 - recievedPowerKW / currentPowerReq));

            boiloff = CheatOptions.IgnoreMaxTemperature || boiloffReducuction <= 0 ? 0 : boiloffReducuction * environmentBoiloff;

            if (boiloff > 0.0000000001)
            {
                var boilOffAmount = boiloff * fixedDeltaTime;

                cryostat_resource.amount = Math.Max(0, cryostat_resource.amount - boilOffAmount);

                boiloffStr = boiloff.ToString("0.0000000") + " L/s " + cryostat_resource.resourceName;

                if (hasExtraBoiloff && part.vessel.isActiveVessel && !warningShown)
                {
                    warningShown = true;
                    var message = "Warning: " + boiloffStr + " Boiloff";
                    Debug.LogWarning("[KSPI] - FNModuleCryostat: " + message);
                    ScreenMessages.PostScreenMessage(message, 5, ScreenMessageStyle.UPPER_CENTER);
                }
            }
            else
            {
                warningShown = false;
                boiloffStr   = "0.0000000 L/s " + cryostat_resource.resourceName;
            }

            previousPowerReq        = currentPowerReq;
            previousRecievedPowerKW = recievedPowerKW;
        }
Beispiel #19
0
        // Physics update
        public override void OnFixedUpdate()
        {
            if (FlightGlobals.fetch == null || !isEnabled)
            {
                return;
            }

            totalMassFlow = this.requestedMassFlow;

            // retreive ratios
            var propellant_ratio = hydrogenPropellant.ratio;
            var deuterium_ratio  = deuteriumPropellant.ratio;
            var tritium_ratio    = tritiumPropellant.ratio;
            var sumOfRatios      = propellant_ratio + deuterium_ratio + tritium_ratio;

            // Resource demand
            float demandReqPropellant = ((propellant_ratio / sumOfRatios) * this.requestedMassFlow) / densityHydrogen;
            float demandReqDeuterium  = ((deuterium_ratio / sumOfRatios) * this.requestedMassFlow) / densityDeuterium;
            float demandReqTritium    = ((tritium_ratio / sumOfRatios) * this.requestedMassFlow) / densityTritium;

            // Realtime mode
            if (!this.vessel.packed)
            {
                // Resource demand
                propellantUsed = demandReqPropellant;
                deuteriumUsed  = demandReqDeuterium;
                tritiumUsed    = demandReqTritium;

                // if not transitioning from warp to real
                // Update values to use during timewarp
                if (!warpToReal) //&& vessel.ctrlState.mainThrottle == previousThrottle)
                {
                    IspPersistent      = realIsp;
                    ThrottlePersistent = vessel.ctrlState.mainThrottle;

                    this.CalculateThrust();
                    // verify we have thrust
                    if ((vessel.ctrlState.mainThrottle > 0 && finalThrust > 0) || (vessel.ctrlState.mainThrottle == 0 && finalThrust == 0))
                    {
                        ThrustPersistent = finalThrust;
                    }
                }
            }
            else if (part.vessel.situation != Vessel.Situations.SUB_ORBITAL)
            {
                // Timewarp mode: perturb orbit using thrust
                warpToReal = true;                          // Set to true for transition to realtime
                double UT = Planetarium.GetUniversalTime(); // Universal time

                propellantUsed = (float)part.RequestResource(InterstellarResourcesConfiguration.Instance.Hydrogen, demandReqPropellant * TimeWarp.fixedDeltaTime) / TimeWarp.fixedDeltaTime;
                deuteriumUsed  = (float)part.RequestResource(InterstellarResourcesConfiguration.Instance.Deuterium, demandReqDeuterium * TimeWarp.fixedDeltaTime) / TimeWarp.fixedDeltaTime;
                tritiumUsed    = (float)part.RequestResource(InterstellarResourcesConfiguration.Instance.Tritium, demandReqTritium * TimeWarp.fixedDeltaTime) / TimeWarp.fixedDeltaTime;

                // Calculate thrust and deltaV if demand output > 0
                if (propellantUsed > 0 && deuteriumUsed > 0 && tritiumUsed > 0)
                {
                    double vesselMass = this.vessel.GetTotalMass();                                      // Current mass
                    double m1         = vesselMass - (this.requestedMassFlow * TimeWarp.fixedDeltaTime); // Mass at end of burn

                    if (m1 <= 0 || vesselMass <= 0)
                    {
                        return;
                    }

                    double deltaV = IspPersistent * PluginHelper.GravityConstant * Math.Log(vesselMass / m1); // Delta V from burn

                    Vector3d thrustV = this.part.transform.up;                                                // Thrust direction
                    Vector3d deltaVV = deltaV * thrustV;                                                      // DeltaV vector
                    vessel.orbit.Perturb(deltaVV, UT, TimeWarp.fixedDeltaTime);                               // Update vessel orbit
                }
                // Otherwise, if throttle is turned on, and demand out is 0, show warning
                else if (ThrottlePersistent > 0)
                {
                    ScreenMessages.PostScreenMessage("Out of resource", 5.0f);
                }
            }
            else //if (vessel.ctrlState.mainThrottle > 0)
            {
                ScreenMessages.PostScreenMessage("Cannot accelerate and timewarp durring sub orbital spaceflight!", 5.0f, ScreenMessageStyle.UPPER_CENTER);
            }


            // Update display numbers
            thrust_d         = ThrustPersistent;
            isp_d            = IspPersistent;
            throttle_d       = ThrottlePersistent;
            previousThrottle = vessel.ctrlState.mainThrottle;
        }
Beispiel #20
0
 public override void PrintMissingResources()
 {
     ScreenMessages.PostScreenMessage(Localizer.Format("#LOC_KSPIE_HeavyWaterElectroliser_Postmsg") + " " + _waterHeavyResourceName, 3.0f, ScreenMessageStyle.UPPER_CENTER);//Missing
 }
        private void InitiateWarp()
        {
            if (maximumWarpSpeedFactor < selected_factor)
            {
                selected_factor = minimumPowerAllowedFactor;
            }

            float new_warp_factor = engine_throtle[selected_factor];

            currentPowerRequirementForWarp = GetPowerRequirementForWarp(new_warp_factor);

            float power_returned = CheatOptions.InfiniteElectricity
                ? currentPowerRequirementForWarp
                : consumeFNResource(currentPowerRequirementForWarp * TimeWarp.fixedDeltaTime, FNResourceManager.FNRESOURCE_MEGAJOULES) / TimeWarp.fixedDeltaTime;

            if (power_returned < 0.99 * currentPowerRequirementForWarp)
            {
                initiateWarpTimeout--;

                if (initiateWarpTimeout == 1)
                {
                    while (selected_factor != minimum_selected_factor)
                    {
                        ReduceWarpPower();
                        new_warp_factor = engine_throtle[selected_factor];
                        currentPowerRequirementForWarp = GetPowerRequirementForWarp(new_warp_factor);
                        if (power_returned >= currentPowerRequirementForWarp)
                        {
                            return;
                        }
                    }
                }
                if (initiateWarpTimeout == 0)
                {
                    ScreenMessages.PostScreenMessage("Not enough power to initiate warp " + power_returned + " " + currentPowerRequirementForWarp, 5.0f, ScreenMessageStyle.UPPER_CENTER);
                    IsCharging = true;
                    return;
                }
            }

            initiateWarpTimeout   = 0; // stop initiating to warp
            vesselWasInOuterspace = (this.vessel.altitude > this.vessel.mainBody.atmosphereDepth * 10);

            // consume all exotic matter to create warp field
            part.RequestResource(InterstellarResourcesConfiguration.Instance.ExoticMatter, exotic_power_required);

            warp_sound.Play();
            warp_sound.loop = true;

            active_part_heading = new Vector3d(part.transform.up.x, part.transform.up.z, part.transform.up.y);

            heading_act          = active_part_heading * GameConstants.warpspeed * new_warp_factor;
            serialisedwarpvector = ConfigNode.WriteVector(heading_act);

            vessel.GoOnRails();
            vessel.orbit.UpdateFromStateVectors(vessel.orbit.pos, vessel.orbit.vel + heading_act, vessel.orbit.referenceBody, Planetarium.GetUniversalTime());
            vessel.GoOffRails();

            IsEnabled = true;

            existing_warpfactor    = new_warp_factor;
            previous_Frame_heading = active_part_heading;
        }
Beispiel #22
0
        private void scienceReceive(float sci, ScienceSubject sub, ProtoVessel pv, bool reverse)
        {
            if (this.Root.ContractState != Contract.State.Active)
            {
                return;
            }

            if (sub == null)
            {
                return;
            }

            if (type == 0 || type == 2)
            {
                if (!string.IsNullOrEmpty(biomeName))
                {
                    if (sub.id == subject)
                    {
                        if (HighLogic.LoadedScene == GameScenes.SPACECENTER || HighLogic.LoadedScene == GameScenes.TRACKSTATION)
                        {
                            base.SetComplete();
                        }
                        else
                        {
                            returnedScience += sci;
                            if (returnedScience >= scienceContainer.Exp.baseValue * scienceContainer.Transmit * sub.subjectValue * 0.3f)
                            {
                                ScreenMessages.PostScreenMessage("DMagic Orbital Science Survey Parameter Complete", 4f, ScreenMessageStyle.UPPER_CENTER);
                                base.SetComplete();
                            }
                            else
                            {
                                ScreenMessages.PostScreenMessage("This area has already been studied, try investigating another region to complete the contract", 6f, ScreenMessageStyle.UPPER_CENTER);
                            }
                        }
                    }
                }
                else
                {
                    if (sub.id.Contains(subject))
                    {
                        if (HighLogic.LoadedScene == GameScenes.SPACECENTER || HighLogic.LoadedScene == GameScenes.TRACKSTATION)
                        {
                            base.SetComplete();
                        }
                        else
                        {
                            returnedScience += sci;
                            if (returnedScience >= scienceContainer.Exp.baseValue * scienceContainer.Transmit * sub.subjectValue * 0.3f)
                            {
                                ScreenMessages.PostScreenMessage("DMagic Orbital Science Survey Parameter Complete", 4f, ScreenMessageStyle.UPPER_CENTER);
                                base.SetComplete();
                            }
                            else
                            {
                                if (DMUtils.biomeRelevant(this.Situation, (int)this.Container.Exp.biomeMask))
                                {
                                    ScreenMessages.PostScreenMessage("This area has already been studied, try investigating another region to complete the contract", 6f, ScreenMessageStyle.UPPER_CENTER);
                                }
                                else
                                {
                                    ScreenMessages.PostScreenMessage("Not enough science remaining; this experiment may need to be returned to Kerbin for credit", 6f, ScreenMessageStyle.UPPER_CENTER);
                                }
                            }
                        }
                    }
                }
            }
            else if (type == 1)
            {
                if (sub.id.Contains(subject))
                {
                    base.SetComplete();
                }
            }
        }
        public void UpdateWarpSpeed()
        {
            if (!IsEnabled || exotic_power_required <= 0)
            {
                return;
            }

            float new_warp_factor = engine_throtle[selected_factor];

            currentPowerRequirementForWarp = GetPowerRequirementForWarp(new_warp_factor);

            float available_power = CheatOptions.InfiniteElectricity
                ? currentPowerRequirementForWarp
                : (float)getStableResourceSupply(FNResourceManager.FNRESOURCE_MEGAJOULES);

            float power_returned;

            if (CheatOptions.InfiniteElectricity)
            {
                power_returned = currentPowerRequirementForWarp;
            }
            else
            {
                power_returned = consumeFNResource(currentPowerRequirementForWarp * TimeWarp.fixedDeltaTime, FNResourceManager.FNRESOURCE_MEGAJOULES) / TimeWarp.fixedDeltaTime;

                if (!CheatOptions.IgnoreMaxTemperature)
                {
                    supplyFNResource(-power_returned * TimeWarp.fixedDeltaTime, FNResourceManager.FNRESOURCE_WASTEHEAT);
                }
            }

            // retreive vessel heading
            Vector3d new_part_heading = new Vector3d(part.transform.up.x, part.transform.up.z, part.transform.up.y);

            // detect any changes in vessel heading and heading stability
            magnitudeDiff          = (float)(active_part_heading - new_part_heading).magnitude;
            magnitudeChange        = (float)(previous_Frame_heading - new_part_heading).magnitude;
            previous_Frame_heading = new_part_heading;

            // detect power shortage
            if (currentPowerRequirementForWarp > available_power)
            {
                insufficientPowerTimeout = -1;
            }
            else if (power_returned < 0.99 * currentPowerRequirementForWarp)
            {
                insufficientPowerTimeout--;
            }
            else
            {
                insufficientPowerTimeout = 10;
            }


            if (this.vessel.altitude < this.vessel.mainBody.atmosphereDepth * 2)
            {
                if (vesselWasInOuterspace)
                {
                    DeactivateWarpDrive();
                    return;
                }
            }
            else
            {
                vesselWasInOuterspace = true;
            }

            // determine if we need to change speed and heading
            var hasPowerShortage       = insufficientPowerTimeout < 0;
            var hasHeadingChanged      = magnitudeDiff > 0.05 && magnitudeChange < 0.0001;
            var hasWarpFactorChange    = existing_warpfactor != new_warp_factor;
            var hasGavityPullInbalance = maximumWarpSpeedFactor < selected_factor;

            if (hasGavityPullInbalance)
            {
                selected_factor = maximumWarpSpeedFactor;
            }

            if (!CheatOptions.InfiniteElectricity && hasPowerShortage)
            {
                if (selected_factor == minimumPowerAllowedFactor || selected_factor == minimum_selected_factor || power_returned < 0.99 * PowerRequirementForMaximumAllowedLightSpeed)
                {
                    ScreenMessages.PostScreenMessage("Critical Power shortage, deactivating warp");
                    DeactivateWarpDrive();
                    return;
                }

                ScreenMessages.PostScreenMessage("Insufficient Power " + power_returned.ToString("0.0") + " / " + currentPowerRequirementForWarp.ToString("0.0") + ", reducing power drain");
                ReduceWarpPower();
            }

            if (hasWarpFactorChange || hasPowerShortage || hasHeadingChanged || hasGavityPullInbalance)
            {
                new_warp_factor     = engine_throtle[selected_factor];
                existing_warpfactor = new_warp_factor;

                Vector3d reverse_heading = new Vector3d(-heading_act.x, -heading_act.y, -heading_act.z);

                heading_act          = new_part_heading * GameConstants.warpspeed * new_warp_factor;
                active_part_heading  = new_part_heading;
                serialisedwarpvector = ConfigNode.WriteVector(heading_act);

                vessel.GoOnRails();
                vessel.orbit.UpdateFromStateVectors(vessel.orbit.pos, vessel.orbit.vel + reverse_heading + heading_act, vessel.orbit.referenceBody, Planetarium.GetUniversalTime());
                vessel.GoOffRails();
            }
        }
Beispiel #24
0
 private void DoSimulationNotification()
 {
     Log.Info("DoSimulationNotification   simNotification: " + simNotification);
     ScreenMessages.PostScreenMessage(simNotification, 1.0f, ScreenMessageStyle.UPPER_CENTER);
 }
Beispiel #25
0
        private void EaseLoadingForExtendedRange()
        {
            if (!_loading)
            {
                return;
            }

            if (!FlightGlobals.currentMainBody.pqsController.isBuildingMaps)
            {
                --_reset;
            }
            if (_reset > 0)
            {
                return;
            }
            _reset = VesLoad;

            switch (_stage)
            {
            case 0:
                _vesEnume = FlightGlobals.VesselsLoaded.ToList().GetEnumerator();
                _tvel     = FlightGlobals.ActiveVessel;
                ++_stage;
                break;

            case 1:
                if (_vesEnume.Current != null)
                {
                    _vesEnume.Current.OnFlyByWire -= Thratlarasat;
                }
                if (_vesEnume.MoveNext())
                {
                    if (SortaLanded(_vesEnume.Current))
                    {
                        FlightGlobals.ForceSetActiveVessel(_vesEnume.Current);
                    }
                    _vesEnume.Current.OnFlyByWire += Thratlarasat;
                }
                else
                {
                    _vesEnume.Dispose();
                    ++_stage;
                    FlightGlobals.ForceSetActiveVessel(_tvel);
                }

                ScreenMessages.PostScreenMessage(
                    "[PhysicsRangeExtender]Extending terrain distance: entangling.", 3f,
                    ScreenMessageStyle.UPPER_CENTER);
                Debug.LogError($"Black Spell entangling {_vesEnume.Current?.vesselName}");
                break;

            case 2:
                ScreenMessages.PostScreenMessage(
                    "[PhysicsRangeExtender]Extending terrain distance: condensing.", 3f,
                    ScreenMessageStyle.UPPER_CENTER);
                ++_stage;
                break;

            case 3:
                ScreenMessages.PostScreenMessage(
                    "[PhysicsRangeExtender]Extending terrain distance: releasing energies.", 3f,
                    ScreenMessageStyle.UPPER_CENTER);
                _reset = 100;
                ++_stage;
                break;

            case 4:
                CheatOptions.NoCrashDamage     = _crashDamage;
                CheatOptions.UnbreakableJoints = _joints;
                _loading = false;
                ScreenMessages.PostScreenMessage(
                    "[PhysicsRangeExtender]Extending terrain distance: complete.", 3f,
                    ScreenMessageStyle.UPPER_CENTER);
                break;
            }
        }
        private void ApplyEVAEffect(LifeSupportStatus kStat, ProtoCrewMember crew, Vessel v, int effectId)
        {
            /*
             *  SIDE EFFECTS:
             *
             *  0 = No Effect (The feature is effectively turned off
             *  1 = Grouchy (they become a Tourist until rescued)
             *  2 = Mutinous (A tourist, but destroys a part of a nearby vessel...)
             *  3 = Instantly 'wander' back to the KSC - don't ask us how!
             *  4 = M.I.A. (will eventually respawn)
             *  5 = K.I.A.
             *
             */

            var msg = "";

            switch (effectId)
            {
            case 1:     //Grouchy
                if (crew.type != ProtoCrewMember.KerbalType.Tourist)
                {
                    msg            = string.Format("{0} refuses to work", crew.name);
                    kStat.OldTrait = crew.experienceTrait.Title;
                    crew.type      = ProtoCrewMember.KerbalType.Tourist;
                    KerbalRoster.SetExperienceTrait(crew, "Tourist");
                    kStat.IsGrouchy = true;
                    LifeSupportManager.Instance.TrackKerbal(kStat);
                }
                break;

            case 2:      //Mutinous
            {
                msg            = string.Format("{0} has become mutinous", crew.name);
                kStat.OldTrait = crew.experienceTrait.Title;
                crew.type      = ProtoCrewMember.KerbalType.Tourist;
                KerbalRoster.SetExperienceTrait(crew, "Tourist");
                kStat.IsGrouchy = true;
                LifeSupportManager.Instance.TrackKerbal(kStat);
                DestroyRandomPart(v);
            }
            break;

            case 3:     //Return to KSC
                msg = string.Format("{0} gets fed up and wanders back to the KSC", crew.name);
                LifeSupportManager.Instance.UntrackKerbal(crew.name);
                crew.rosterStatus = ProtoCrewMember.RosterStatus.Available;
                DestroyVessel(v);
                break;

            case 4:     //Despawn
                msg = string.Format("{0} has gone missing", crew.name);
                LifeSupportManager.Instance.UntrackKerbal(crew.name);
                crew.rosterStatus = ProtoCrewMember.RosterStatus.Missing;
                DestroyVessel(v);
                break;

            case 5:     //Kill
                msg = string.Format("{0} has died", crew.name);
                LifeSupportManager.Instance.UntrackKerbal(crew.name);
                crew.rosterStatus = ProtoCrewMember.RosterStatus.Dead;
                DestroyVessel(v);
                break;
            }

            ScreenMessages.PostScreenMessage(msg, 5f, ScreenMessageStyle.UPPER_CENTER);
        }
Beispiel #27
0
        public override void OnFixedUpdate()
        {
            base.OnFixedUpdate();
            if (IsEnabled && myAttachedReactor != null && FNRadiator.hasRadiatorsForVessel(vessel))
            {
                updateGeneratorPower();
                double electricdt       = 0;
                double electricdtps     = 0;
                double max_electricdtps = 0;
                double input_power      = 0;

                double currentmegajoulesSpareCapacity = TimeWarp.fixedDeltaTime > 1 || !PluginHelper.MatchDemandWithSupply
                    ? getSpareResourceCapacity(FNResourceManager.FNRESOURCE_MEGAJOULES) / TimeWarp.fixedDeltaTime
                    : getTotalResourceCapacity(FNResourceManager.FNRESOURCE_MEGAJOULES);

                double electrical_power_currently_needed = (getCurrentUnfilledResourceDemand(FNResourceManager.FNRESOURCE_MEGAJOULES) + currentmegajoulesSpareCapacity);
                if (!chargedParticleMode)
                {
                    double carnotEff = 1.0 - coldBathTemp / hotBathTemp;
                    totalEff = carnotEff * pCarnotEff;
                    if (totalEff <= 0 || coldBathTemp <= 0 || hotBathTemp <= 0 || maxThermalPower <= 0)
                    {
                        return;
                    }

                    double thermal_power_currently_needed = electrical_power_currently_needed / totalEff;
                    double thermaldt = Math.Max(Math.Min(maxThermalPower, thermal_power_currently_needed) * TimeWarp.fixedDeltaTime, 0.0);
                    input_power = consumeFNResource(thermaldt, FNResourceManager.FNRESOURCE_THERMALPOWER);
                    if (input_power < thermaldt)
                    {
                        input_power += consumeFNResource(thermaldt - input_power, FNResourceManager.FNRESOURCE_CHARGED_PARTICLES);
                    }

                    double wastedt = input_power * totalEff;
                    consumeFNResource(wastedt, FNResourceManager.FNRESOURCE_WASTEHEAT);
                    electricdt       = input_power * totalEff;
                    electricdtps     = Math.Max(electricdt / TimeWarp.fixedDeltaTime, 0.0);
                    max_electricdtps = maxThermalPower * totalEff;
                }
                else
                {
                    totalEff = 0.85;
                    double charged_power_currently_needed = electrical_power_currently_needed / totalEff;
                    input_power  = consumeFNResource(Math.Max(charged_power_currently_needed * TimeWarp.fixedDeltaTime, 0), FNResourceManager.FNRESOURCE_CHARGED_PARTICLES);
                    electricdt   = input_power * totalEff;
                    electricdtps = Math.Max(electricdt / TimeWarp.fixedDeltaTime, 0.0);
                    double wastedt = input_power * totalEff;
                    max_electricdtps = maxChargedPower * totalEff;
                    consumeFNResource(wastedt, FNResourceManager.FNRESOURCE_WASTEHEAT);
                    //supplyFNResource(wastedt, FNResourceManager.FNRESOURCE_WASTEHEAT);
                }
                outputPower = -(float)supplyFNResourceFixedMax(electricdtps * TimeWarp.fixedDeltaTime, max_electricdtps * TimeWarp.fixedDeltaTime, FNResourceManager.FNRESOURCE_MEGAJOULES) / TimeWarp.fixedDeltaTime;
            }
            else
            {
                if (IsEnabled && !vessel.packed)
                {
                    if (!FNRadiator.hasRadiatorsForVessel(vessel))
                    {
                        IsEnabled = false;
                        Debug.Log("[WarpPlugin] Generator Shutdown: No radiators available!");
                        ScreenMessages.PostScreenMessage("Generator Shutdown: No radiators available!", 5.0f, ScreenMessageStyle.UPPER_CENTER);
                    }

                    if (myAttachedReactor == null)
                    {
                        IsEnabled = false;
                        Debug.Log("[WarpPlugin] Generator Shutdown: No reactor available!");
                        ScreenMessages.PostScreenMessage("Generator Shutdown: No reactor available!", 5.0f, ScreenMessageStyle.UPPER_CENTER);
                    }
                }
            }
        }
Beispiel #28
0
        public void GenerateModControlFile(bool whitelistMode)
        {
            string gameDataDir = Client.dmpClient.gameDataDir;

            string[] topLevelFiles  = Directory.GetFiles(gameDataDir);
            string[] modDirectories = Directory.GetDirectories(gameDataDir);

            List <string> requiredFiles = new List <string>();
            List <string> optionalFiles = new List <string>();
            List <string> partsList     = Common.GetStockParts();

            //If whitelisting, add top level dll's to required (It's usually things like modulemanager)
            foreach (string dllFile in topLevelFiles)
            {
                if (Path.GetExtension(dllFile).ToLower() == ".dll")
                {
                    requiredFiles.Add(Path.GetFileName(dllFile));
                }
            }

            foreach (string modDirectory in modDirectories)
            {
                string lowerDirectoryName = modDirectory.Substring(modDirectory.ToLower().IndexOf("gamedata") + 9).ToLower();
                if (lowerDirectoryName.StartsWith("squad"))
                {
                    continue;
                }
                if (lowerDirectoryName.StartsWith("nasamission"))
                {
                    continue;
                }
                if (lowerDirectoryName.StartsWith("darkmultiplayer"))
                {
                    continue;
                }
                bool          modIsRequired   = false;
                string[]      partFiles       = Directory.GetFiles(Path.Combine(gameDataDir, modDirectory), "*", SearchOption.AllDirectories);
                List <string> modDllFiles     = new List <string>();
                List <string> modPartCfgFiles = new List <string>();
                foreach (string partFile in partFiles)
                {
                    bool   fileIsPartFile   = false;
                    string relativeFileName = partFile.Substring(partFile.ToLower().IndexOf("gamedata") + 9).Replace(@"\", "/");
                    if (Path.GetExtension(partFile).ToLower() == ".cfg")
                    {
                        ConfigNode cn = ConfigNode.Load(partFile);
                        if (cn == null)
                        {
                            continue;
                        }
                        foreach (ConfigNode partNode in cn.GetNodes("PART"))
                        {
                            string partName = partNode.GetValue("name");
                            if (partName != null)
                            {
                                DarkLog.Debug("Part detected in " + relativeFileName + " , name: " + partName);
                                partName       = partName.Replace('_', '.');
                                modIsRequired  = true;
                                fileIsPartFile = true;
                                partsList.Add(partName);
                            }
                        }
                    }
                    if (fileIsPartFile)
                    {
                        modPartCfgFiles.Add(relativeFileName);
                    }
                    if (Path.GetExtension(partFile).ToLower() == ".dll")
                    {
                        modDllFiles.Add(relativeFileName);
                    }
                }

                if (modIsRequired)
                {
                    if (modDllFiles.Count > 0)
                    {
                        //If the mod as a plugin, just require that. It's clear enough.
                        requiredFiles.AddRange(modDllFiles);
                    }
                    else
                    {
                        //If the mod does *not* have a plugin (Scoop-o-matic is an example), add the part files to required instead.
                        requiredFiles.AddRange(modPartCfgFiles);
                    }
                }
                else
                {
                    if (whitelistMode)
                    {
                        optionalFiles.AddRange(modDllFiles);
                    }
                }
            }
            string modFileData = Common.GenerateModFileStringData(requiredFiles.ToArray(), optionalFiles.ToArray(), whitelistMode, new string[0], partsList.ToArray());
            string saveModFile = Path.Combine(Client.dmpClient.kspRootPath, "DMPModControl.txt");

            using (StreamWriter sw = new StreamWriter(saveModFile, false))
            {
                sw.Write(modFileData);
            }
            ScreenMessages.PostScreenMessage("DMPModFile.txt file generated in your KSP folder", 5f, ScreenMessageStyle.UPPER_CENTER);
        }
Beispiel #29
0
 public static void checkPrice(string refBodyName, double SMA)
 {
     ScreenMessages.PostScreenMessage(refBodyName, 5.0f, ScreenMessageStyle.UPPER_CENTER);
     if (refBodyName == "Kerbin")
     {
         setPriceKer();
     }
     if (refBodyName == "Mun")
     {
         setPriceMun();
     }
     if (refBodyName == "Minmus")
     {
         setPriceMinmus();
     }
     if (refBodyName == "Duna")
     {
         setPriceDuna();
     }
     if (refBodyName == "Ike")
     {
         setPriceIke();
     }
     if (refBodyName == "Eve")
     {
         setPriceEve();
     }
     if (refBodyName == "Gilly")
     {
         setPriceGilly();
     }
     if (refBodyName == "Moho")
     {
         setPriceMoho();
     }
     if (refBodyName == "Dres")
     {
         setPriceDres();
     }
     if (refBodyName == "Eeloo")
     {
         setPriceEeloo();
     }
     if (refBodyName == "Jool")
     {
         setPriceJool();
     }
     if (refBodyName == "Laythe")
     {
         setPriceLaythe();
     }
     if (refBodyName == "Vall")
     {
         setPriceVall();
     }
     if (refBodyName == "Bop")
     {
         setPriceBop();
     }
     if (refBodyName == "Tylo")
     {
         setPriceTylo();
     }
     if (refBodyName == "Pol")
     {
         setPricePol();
     }
     if (refBodyName == "Sun" && SMA > 1000000000)
     {
         setPriceSunHigh();
     }
     if (refBodyName == "Sun" && SMA < 1000000000)
     {
         setPriceSunLow();
     }
 }
Beispiel #30
0
        public override void OnUpdate()
        {
            if (!CheatOptions.InfiniteElectricity && !isChargingForJumpstart && !isSwappingFuelMode && getCurrentResourceDemand(ResourceManager.FNRESOURCE_MEGAJOULES) > getStableResourceSupply(ResourceManager.FNRESOURCE_MEGAJOULES) && getResourceBarRatio(ResourceManager.FNRESOURCE_MEGAJOULES) < 0.1 && IsEnabled && !fusion_alert)
            {
                ScreenMessages.PostScreenMessage("Warning: Fusion Reactor plasma heating cannot be guaranteed, reducing power requirements is recommended.", 10.0f, ScreenMessageStyle.UPPER_CENTER);
                fusion_alert = true;
            }
            else
            {
                fusion_alert = false;
            }

            if (isChargingField.guiActive)
            {
                accumulatedChargeStr = PluginHelper.getFormattedPowerString(accumulatedElectricChargeInMW, "0.0", "0.000")
                                       + " / " + PluginHelper.getFormattedPowerString(StartupPower, "0.0", "0.000");
            }
            else if (part.vessel.geeForce > startupMaximumGeforce)
            {
                accumulatedChargeStr = part.vessel.geeForce.ToString("0.000") + "g > " + startupMaximumGeforce + "g";
            }
            else
            {
                accumulatedChargeStr = String.Empty;
            }

            Fields["accumulatedChargeStr"].guiActive = plasma_ratio < 1;

            electricPowerMaintenance = PluginHelper.getFormattedPowerString(power_consumed) + " / " + PluginHelper.getFormattedPowerString(LaserPowerRequirements);

            if (startupAnimation != null && !initialized)
            {
                if (IsEnabled)
                {
                    //animationScalar = startupAnimation.GetScalar;
                    if (animationStarted == 0)
                    {
                        startupAnimation.ToggleAction(new KSPActionParam(KSPActionGroup.Custom01, KSPActionType.Activate));
                        animationStarted = Planetarium.GetUniversalTime();
                    }
                    else if (!startupAnimation.IsMoving())
                    {
                        startupAnimation.ToggleAction(new KSPActionParam(KSPActionGroup.Custom01, KSPActionType.Deactivate));
                        animationStarted = 0;
                        initialized      = true;
                        isDeployed       = true;
                    }
                }
                else // Not Enabled
                {
                    // continiously start
                    startupAnimation.ToggleAction(new KSPActionParam(KSPActionGroup.Custom01, KSPActionType.Activate));
                    startupAnimation.ToggleAction(new KSPActionParam(KSPActionGroup.Custom01, KSPActionType.Deactivate));
                }
            }
            else if (startupAnimation == null)
            {
                isDeployed = true;
            }

            // call base class
            base.OnUpdate();
        }