public override bool SeekVolume(float targetVolume, int dir = 0)
        {
            BaseField field     = Fields[nameof(length)];
            float     orig      = (float)field.GetValue(this);
            float     maxLength = (field.uiControlEditor as UI_FloatEdit).maxValue;
            float     minLength = (field.uiControlEditor as UI_FloatEdit).minValue;
            float     precision = (field.uiControlEditor as UI_FloatEdit).incrementSlide;

            // Solve length directly, taken from AdjustDimensionBounds
            float targetLength = (-3f * (Pi - 4f) * Pi * diameter * pow(fillet, 2) + Pi * (3f * Pi - 10f) * pow(fillet, 3) + 24f * targetVolume) / (6f * Pi * pow(diameter, 2));

            targetLength = RoundToDirection(targetLength / precision, dir) * precision;
            float clampedTargetLength = Mathf.Clamp(targetLength, minLength, maxLength);
            bool  closeEnough         = Mathf.Abs((clampedTargetLength / targetLength) - 1) < 0.01;

            field.SetValue(targetLength, this);
            foreach (Part p in part.symmetryCounterparts)
            {
                // Propagate the change to other parts in symmetry group
                if (FindAbstractShapeModule(p, this) is ProceduralAbstractShape pm)
                {
                    field.SetValue(targetLength, pm);
                }
            }
            OnShapeDimensionChanged(field, orig);
            MonoUtilities.RefreshPartContextWindow(part);
            return(closeEnough);
        }
        private void onEditorVariantApplied(Part part, PartVariant variant)
        {
            // This should never be called in flight, but somehow it was, so just
            // have a check to be safe
            if (HighLogic.LoadedSceneIsFlight)
            {
                return;
            }
            if (part != base.part || part == null)
            {
                return;
            }

            if (variant == null || variant.DisplayName == null)
            {
                return;
            }
            ModSegSRBs.GetExtraInfo(variant, ref this.part.segmentHeight, ref this.part.segmentWidth);

            RecalculateFuelAndMass();
            var f = GetMaxThrust();

            if (baseEngine != null)
            {
                baseEngine.ScheduleSegmentUpdate("MSSRB_Fuel_Segment.onEditorVariantApplied", 5);
            }
#if true
            MonoUtilities.RefreshContextWindows(part);
#else
            MonoUtilities.RefreshPartContextWindow(part);
#endif
        }
 private void ClampFillet(BaseField f, object obj)
 {
     if (fillet > Mathf.Min(diameter, length))
     {
         fillet = Mathf.Min(diameter, length);
         MonoUtilities.RefreshPartContextWindow(part);
     }
 }
예제 #4
0
 private void ClampFillet(BaseField f, object obj)
 {
     if (fillet > Mathf.Min((outerDiameter - innerDiameter) / 2f, length) + 0.001f)
     {
         float oldFillet = fillet;
         fillet = Mathf.Min((outerDiameter - innerDiameter) / 2f, length);
         MonoUtilities.RefreshPartContextWindow(part);
     }
 }
예제 #5
0
 private void OnTankTypeChangedWithSymmetry(BaseField f, object obj)
 {
     OnTankTypeChanged(f, obj);
     foreach (Part p in part.symmetryCounterparts)
     {
         p.FindModuleImplementing <TankContentSwitcher>()?.OnTankTypeChanged(f, obj);
     }
     MonoUtilities.RefreshPartContextWindow(part);
 }
예제 #6
0
        private void UpdateMenu()
        {
            selectedRecipeName = _recipeOptions[selectedRecipeIndex].RecipeDisplayName;
            var nextRecipeName = _recipeOptions[_nextRecipeIndex].RecipeDisplayName;

            Events["SwapRecipe"].guiName = selectedRecipeName + " => " + nextRecipeName;

            MonoUtilities.RefreshPartContextWindow(part);
        }
        /// <summary>
        /// Used to toggle PAW items on or off based on conditions
        /// </summary>
        protected virtual void TogglePawItems()
        {
            Events[nameof(CancelRouteEvent)].active      = IsConnectedToOrigin;
            Events[nameof(ConnectToDepotEvent)].active   = IsConnectedToOrigin;
            Events[nameof(ConnectToOriginEvent)].active  = !IsConnectedToOrigin;
            Fields[nameof(OriginDepotDisplay)].guiActive = IsConnectedToOrigin && !string.IsNullOrEmpty(OriginDepotDisplay);
            Fields[nameof(RoutePayload)].guiActive       = IsConnectedToOrigin;
            Fields[nameof(RoutePayloadCost)].guiActive   = IsConnectedToOrigin;

            MonoUtilities.RefreshPartContextWindow(part);
        }
 public void OnShapeSelectionChanged(BaseField f, object obj)
 {
     if (CalculateVolume() > PPart.volumeMax)
     {
         UI_FloatEdit edt = Fields[nameof(length)].uiControlEditor as UI_FloatEdit;
         length = edt.minValue;
         AdjustDimensionBounds();
         length = Mathf.Max(length, edt.maxValue);
     }
     OnShapeDimensionChanged(f, obj);
     MonoUtilities.RefreshPartContextWindow(part);
 }
예제 #9
0
 private void ResetModel()
 {
     panelLength = coreModule.definition.panelLength;
     panelWidth  = coreModule.definition.panelWidth;
     panelScale  = coreModule.definition.panelScale;
     SetUIVisibleFields();
     ModelChangedHandler(true);
     prevLength = panelLength;
     prevWidth  = panelWidth;
     prevScale  = panelScale;
     MonoUtilities.RefreshPartContextWindow(part);
 }
예제 #10
0
        private void UpdateLabels()
        {
            Fields[nameof(EconomyBerths)].guiActive       = !IsLuxury;
            Fields[nameof(EconomyBerths)].guiActiveEditor = !IsLuxury;
            Fields[nameof(LuxuryBerths)].guiActive        = IsLuxury;
            Fields[nameof(LuxuryBerths)].guiActiveEditor  = IsLuxury;

            Events[nameof(ToggleBerthTypeEvent)].guiName = IsLuxury ?
                                                           _switchToEconomyLabel :
                                                           _switchToLuxuryLabel;

            MonoUtilities.RefreshPartContextWindow(part);
        }
        private void onEditorVariantApplied(Part part, PartVariant variant)
        {
            if (part != base.part)
            {
                return;
            }
            ModSegSRBs.GetExtraInfo(variant, ref this.part.segmentHeight, ref this.part.segmentWidth);

            ScheduleSegmentUpdate("onEditorVariantApplied");
#if true
            MonoUtilities.RefreshContextWindows(part);
#else
            MonoUtilities.RefreshPartContextWindow(part);
#endif
        }
예제 #12
0
        public void ResetModel()
        {
            if (lengthWidth)
            {
                return;
            }

            currentDiameter = coreModule.definition.diameter;
            currentVScale   = 0;

            this.ROLupdateUIFloatEditControl(nameof(currentDiameter), minDiameter, maxDiameter, diameterLargeStep, diameterSmallStep, diameterSlideStep);
            this.ROLupdateUIFloatEditControl(nameof(currentVScale), -1, 1, 0.25f, 0.05f, 0.001f);
            ModelChangedHandlerWithSymmetry(true, true);
            MonoUtilities.RefreshPartContextWindow(part);
        }
예제 #13
0
        public void OnShapeChanged(BaseField f, object obj, bool forceRefresh = false)
        {
            float v = CalculateVolume();

            if (v > PPart.volumeMax || v < PPart.volumeMin)
            {
                UI_FloatEdit edt = Fields[nameof(length)].uiControlEditor as UI_FloatEdit;
                length = edt.minValue;
                AdjustDimensionBounds();
                length = Mathf.Clamp(length, edt.minValue, edt.maxValue);
            }
            OnShapeDimensionChanged(f, obj);
            if (forceRefresh)
            {
                MonoUtilities.RefreshPartContextWindow(part);
            }
        }
예제 #14
0
 private void TextureButton(string sTarget, float gap)
 {
     GUILayout.BeginHorizontal();
     if (gap > 0)
     {
         GUILayout.Space(gap);
     }
     if (GUILayout.Button(sTarget))
     {
         PartModule kspTextureSwitchPM = parent.part.Modules["KSPTextureSwitch"];
         string     prev        = CurrentTextureField.GetValue(CurrentTextureField.host) as string;
         var        tuContainer = KSPTextureSwitchType.GetField("textureSets", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(kspTextureSwitchPM);
         var        recolorData = TUTextureContainerType.GetField("customColors", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(tuContainer) as Array;
         CurrentTextureField.SetValue(sTarget, CurrentTextureField.host);
         CurrentTextureField.uiControlEditor.onFieldChanged.Invoke(CurrentTextureField, prev);
         TUSetRecoloringMethod.Invoke(kspTextureSwitchPM, new object[] { string.Empty, recolorData });
         MonoUtilities.RefreshPartContextWindow(parent.part);
     }
     GUILayout.FlexibleSpace();
     GUILayout.EndHorizontal();
 }
예제 #15
0
 public static void UpdatePartMenu(this Part part)
 {
     MonoUtilities.RefreshPartContextWindow(part);
     UpdateEditorGUI();
 }
        void UpdateSegments()
        {
            if (part == null)
            {
                Log.Info("UpdateSegments, part is null");
                return;
            }
            Log.Info("UpdateSegments, updateSegmentsIn: " + updateSegmentsIn);

            // Get a list of all the attached fuel segments, following the nodes from the top node
            // of the engine to the bottom node of the attached segment, and then the top node of the segment, etc
            // Stop when a part does not have the correct fuel resource

            totalMaxThrust     = 0;
            totalSegmentHeight = 0;
            totalFuelMass      = 0;
            segments.Clear();
            Part curPart = this.part;
            Part nextPart;

            AttachNode topAttachNode = this.part.FindAttachNode("top");

            CheckPartResources(this.part as MSSRB_Part);

            while (topAttachNode.attachedPart != null)
            {
                nextPart = topAttachNode.attachedPart;

                // Make sure that the part attached to this part's topNode is that part's bottom node
                AttachNode nextPartBottomNode = nextPart.FindAttachNode("bottom");
                if (nextPartBottomNode == null || nextPartBottomNode.attachedPart != curPart)
                {
                    Log.Info("nextPartBottomNode == null");
                    break;
                }
                if (!CheckPartResources(nextPart as MSSRB_Part))
                {
                    Log.Info("CheckPartResources returns false");
                    break;
                }
                curPart       = nextPart;
                topAttachNode = nextPart.FindAttachNode("top");
                if (topAttachNode == null)
                {
                    break;
                }
            }

            for (int i = 0; i < segments.Count; i++)
            {
                Segment          s   = segments[i];
                PartResourceList prl = s.part.Resources;
                s.ratio = prl[ModSegSRBs.Propellant].maxAmount / totalFuelMass;
                Log.Info("UpdateSegments, segment[" + i + "]: " + s.part.partInfo.title + ", resources: " + prl[ModSegSRBs.Propellant].maxAmount);
            }
            Log.Info("UpdateSegments, totalFuelMass: " + totalFuelMass);

            maxThrust        = (float)totalMaxThrust * thrustModifier;
            maxFuelFlow      = (float)/*Planetarium.fetch.fixedDeltaTime* */ (maxThrust /*  * mixtureDensityRecip  */) / (atmosphereCurve.Evaluate(0f) * g);
            origMaxThrust    = maxThrust;
            maxDisplayThrust = maxThrust;
            PartResource pr = part.Resources[ModSegSRBs.BurnablePropellant];

            if (CoM != null || HighLogic.LoadedSceneIsFlight)
            {
                Log.Info("(1) BurnablePropellant Setting part.amount = 0");
                pr.amount    = 0;
                pr.maxAmount = maxFuelFlow;
            }
            else

            {
                Log.Info("(1) BurnablePropellant Setting part.amount = " + totalFuelMass);
                pr.amount    = totalFuelMass;
                pr.maxAmount = totalFuelMass;
            }

            if (part.segmentWidth > 0)
            {
                float lengthToWidthRatio = totalSegmentHeight / part.segmentWidth;
                heatProduction = baseHeatProduction + 5 * lengthToWidthRatio;

                if (lengthToWidthRatio > HighLogic.CurrentGame.Parameters.CustomParams <MSSRB_1>().maxSafeWidthToLengthRatio)
                {
                    float excess = totalSegmentHeight - part.segmentWidth * HighLogic.CurrentGame.Parameters.CustomParams <MSSRB_1>().maxSafeWidthToLengthRatio;
                    failureChance = Math.Max(failureChance, excess * invTotalSegmentHeight / (50 * 60));
                    if (HighLogic.LoadedSceneIsEditor)
                    {
                        if (HighLogic.CurrentGame.Parameters.CustomParams <MSSRB_1>().warnOnExcessiveHeight)
                        {
                            ScreenMessages.PostScreenMessage("* Warning *  SRB length exceeds safe limits by " + (100 * excess * invTotalSegmentHeight).ToString("F1") + "%", 5);
                        }

                        HighlightStack();
                    }
                }
                else
                {
                    UnHighlightStack();
                    failureChance = HighLogic.CurrentGame.Parameters.CustomParams <MSSRB_1>().failureChance;
                }
            }
            else
            {
                heatProduction = 0;
            }

            totalFuelFlow = maxFuelFlow / Planetarium.fetch.fixedDeltaTime;

#if true
            MonoUtilities.RefreshContextWindows(part);
#else
            MonoUtilities.RefreshPartContextWindow(part);
#endif
            GameEvents.onChangeEngineDVIncludeState.Fire(this);
        }