Esempio n. 1
0
        public override double TransferTo(PartResourceInfo destination, double amount)
        {
            SimplePartResource dest = (SimplePartResource)destination;

            amount = Math.Min(Math.Min(amount, Amount), dest.MaxAmount - dest.Amount);
            dest.resource.amount += amount;
            resource.amount      -= amount;
            return(amount);
        }
Esempio n. 2
0
        public override double TransferTo(PartResourceInfo destination, double amount)
        {
            RocketFuelResource dest = (RocketFuelResource)destination;
            double             liquidSpace = dest.liquidFuel.maxAmount - dest.liquidFuel.amount, oxidizerSpace = dest.oxidizer.maxAmount - dest.oxidizer.amount;

            amount = Math.Min(Math.Min(amount, Amount), Math.Min(liquidSpace * (10d / 9), oxidizerSpace * (10d / 11)));
            double fuel = amount * (9d / 10), oxygen = amount * (11d / 10);

            dest.liquidFuel.amount += fuel;
            liquidFuel.amount      -= fuel;
            dest.oxidizer.amount   += oxygen;
            oxidizer.amount        -= oxygen;
            return(amount);
        }
        private void BalanceResources(double maxFlow, List <ResourcePartMap> balanceParts)
        {
            if (balanceParts.Count < 2)
            {
                return;
            }

            // sort the parts by percent full and figure out what the desired percentage is
            PartResourceInfo[] resources = new PartResourceInfo[balanceParts.Count];
            double             totalAmount = 0, totalCapacity = 0;

            for (int i = 0; i < balanceParts.Count; i++)
            {
                resources[i]   = balanceParts[i].resource;
                totalAmount   += resources[i].Amount;
                totalCapacity += resources[i].MaxAmount;
            }
            Array.Sort(resources, (a, b) => a.PercentFull.CompareTo(b.PercentFull));
            double desiredPercentage = totalAmount / totalCapacity;

            // if the difference between the fullest and emptiest tank is small, we're done
            if (resources[resources.Length - 1].PercentFull - resources[0].PercentFull < PercentEpsilon)
            {
                return;
            }

            // work from both sides transferring from fuller tanks (near the end) to emptier tanks (near the beginning)
            for (int di = 0, si = resources.Length - 1; si > di && desiredPercentage - resources[di].PercentFull >= PercentEpsilon; di++)
            {
                PartResourceInfo dest   = resources[di];
                double           needed = (desiredPercentage - dest.PercentFull) * dest.MaxAmount;
                for (; si > di && resources[si].PercentFull - desiredPercentage >= PercentEpsilon; si--)
                {
                    PartResourceInfo src       = resources[si];
                    double           available = Math.Min(maxFlow, (src.PercentFull - desiredPercentage) * src.MaxAmount);
                    needed -= src.TransferTo(dest, Math.Min(available, needed));
                    if (needed < AmountEpsilon)
                    {
                        break;                         // if the dest tank became full enough, move to the next without advancing the source tank
                    }
                }
            }
        }
Esempio n. 4
0
        protected override void DrawWindowContents(int windowID)
        {
            headerScrollPosition = GUILayout.BeginScrollView(headerScrollPosition, GUILayout.ExpandHeight(false));
            GUILayout.BeginHorizontal();
            List <ResourceInfo> sortedResources = controller.GetResourceInfo().Values.ToList();

            sortedResources.Sort((a, b) => a.title.CompareTo(b.title));
            foreach (ResourceInfo resource in sortedResources)
            {
                bool toggled = GUILayout.Toggle(resource.isShowing, resource.title, buttonStyle) != resource.isShowing;
                if (toggled)
                {
                    SetResourceVisibility(resource, !resource.isShowing);
                    if (resource.isShowing && settings.OneTabOnly)
                    {
                        foreach (ResourceInfo otherResource in sortedResources)
                        {
                            if (otherResource != resource)
                            {
                                SetResourceVisibility(otherResource, false);
                            }
                        }
                    }
                }
            }
            GUILayout.EndHorizontal();
            GUILayout.EndScrollView();

            scrollPosition = GUILayout.BeginScrollView(scrollPosition);
            GUILayout.BeginVertical();

            // cache the value so we only do it once per call
            isControllable = controller.IsControllable();

            // avoid allocating new options and arrays for every cell
            GUILayoutOption[] width20 = new[] { GUILayout.Width(20) }, width46 = new[] { GUILayout.Width(46) }, width60 = new[] { GUILayout.Width(60) };
            foreach (ResourceInfo resource in sortedResources)
            {
                if (resource.isShowing)
                {
                    GUILayout.BeginHorizontal();
                    GUILayout.Space(20);
                    GUILayout.Label(resource.title, sectionStyle, GUILayout.Width(100));
                    if (resource.parts[0].resource.TransferMode == ResourceTransferMode.PUMP && isControllable)
                    {
                        resource.balance = GUILayout.Toggle(resource.balance, "Balance All", buttonStyle);
                    }
                    if (GUILayout.Button("Select All", buttonStyle))
                    {
                        bool ctrl = Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl);
                        SelectParts(resource, resource.parts, resource.parts.Any(p => !p.isSelected), ctrl);
                        ResetRangeSelection();
                    }
                    PopupWindow.Draw("Sort", windowPos, DrawSortMenu, buttonStyle, null);
                    GUILayout.EndHorizontal();

                    foreach (ResourcePartMap partInfo in resource.parts)
                    {
                        PartResourceInfo partResource = partInfo.resource;
                        double           percentFull  = partResource.PercentFull * 100.0;

                        if (percentFull < settings.FuelCriticalLevel)
                        {
                            labelStyle.normal.textColor = new Color(0.88f, 0.20f, 0.20f, 1.0f);
                        }
                        else if (percentFull < settings.FuelWarningLevel)
                        {
                            labelStyle.normal.textColor = Color.yellow;
                        }
                        else
                        {
                            labelStyle.normal.textColor = Color.white;
                        }

                        labelStyle.fontStyle = partInfo.isSelected ? FontStyle.Bold : FontStyle.Normal;

                        GUILayout.BeginHorizontal();
                        string partTitle = partInfo.part.partInfo.title;

                        if (GUILayout.Button(partTitle.Substring(0, Math.Min(30, partTitle.Length)), labelStyle)) // if the user clicked an item name...
                        {
                            bool shift = Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift);
                            bool ctrl  = Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl);
                            bool alt   = Input.GetKey(KeyCode.LeftAlt) || Input.GetKey(KeyCode.RightAlt);
                            if (alt) // alt-click selects either all parts on the same ship or all parts of the same type
                            {
                                List <ResourcePartMap> parts;
                                if (shift)
                                {
                                    parts = resource.parts.FindAll(p => p.part.partInfo.title == partTitle);
                                }
                                else
                                {
                                    parts = resource.parts.FindAll(p => p.shipId == partInfo.shipId);
                                }
                                SelectParts(resource, parts, parts.Any(p => !p.isSelected), ctrl); // select all those parts if any is unselected
                                ResetRangeSelection();
                            }
                            else // otherwise, select and deselect items normally
                            {
                                ICollection <ResourcePartMap> parts;
                                // shift-click selects a range of items in the view
                                if (shift && resource == lastResourceClicked && partInfo != lastPartClicked && lastPartClicked != null)
                                {
                                    int partIndex = resource.parts.IndexOf(partInfo), lastIndex = resource.parts.IndexOf(lastPartClicked);
                                    if (lastIndex < 0)
                                    {
                                        lastIndex = partIndex;
                                    }
                                    parts = resource.parts.GetRange(Math.Min(partIndex, lastIndex), Math.Abs(partIndex - lastIndex) + 1);
                                }
                                else
                                {
                                    parts = new ResourcePartMap[] { partInfo };
                                }
                                SelectParts(resource, parts, !partInfo.isSelected || !ctrl && resource.parts.Count(p => p.isSelected) > parts.Count, ctrl);
                                lastResourceClicked = resource;
                                lastPartClicked     = partInfo;
                            }
                        }

                        GUILayout.FlexibleSpace();
                        if (settings.ShowShipNumber)
                        {
                            GUILayout.Label(partInfo.shipId.ToString(), labelStyle, width20);
                        }
                        if (settings.ShowStageNumber)
                        {
                            GUILayout.Label(partInfo.part.inverseStage.ToString(), labelStyle, width20);
                        }
                        if (settings.ShowMaxAmount)
                        {
                            GUILayout.Label(partResource.MaxAmount.ToString("N1"), labelStyle, width60);
                        }
                        if (settings.ShowCurrentAmount)
                        {
                            GUILayout.Label(partResource.Amount.ToString("N1"), labelStyle, width60);
                        }
                        if (settings.ShowPercentFull)
                        {
                            GUILayout.Label(percentFull.ToString("N1") + "%", labelStyle, width46);
                        }
                        PopupWindow.Draw(GetControlText(partInfo), windowPos, DrawPopupContents, buttonStyle, partInfo, width20);

                        GUILayout.EndHorizontal();
                    }
                }
            }

            GUILayout.EndVertical();
            GUILayout.EndScrollView();

            GUILayout.BeginHorizontal();
            if (GUILayout.Toggle((settings.RateMultiplier == 100.0), "x100", buttonStyle))
            {
                settings.RateMultiplier = 100.0;
            }
            if (GUILayout.Toggle((settings.RateMultiplier == 10.0), "x10", buttonStyle))
            {
                settings.RateMultiplier = 10.0;
            }
            if (GUILayout.Toggle((settings.RateMultiplier == 1.0), "x1", buttonStyle))
            {
                settings.RateMultiplier = 1.0;
            }
            if (GUILayout.Toggle((settings.RateMultiplier == 0.1), "x0.1", buttonStyle))
            {
                settings.RateMultiplier = 0.1;
            }
            GUILayout.EndHorizontal();



            // Extra title bar buttons
            if (GUI.Button(new Rect(windowPos.width - 72, 4, 20, 20), resetContent, closeButtonStyle))
            {
                controller.RebuildActiveVesselLists( );
            }
            if (GUI.Button(new Rect(windowPos.width - 48, 4, 20, 20), settingsContent, closeButtonStyle))
            {
                settingsWindow.ToggleVisible( );
            }
            if (GUI.Button(new Rect(windowPos.width - 24, 4, 20, 20), helpContent, closeButtonStyle))
            {
                helpWindow.ToggleVisible( );
            }
        }
Esempio n. 5
0
 public ResourcePartMap(PartResourceInfo resource, Part part, int shipId)
 {
     this.resource = resource;
     this.part     = part;
     this.shipId   = shipId;
 }
Esempio n. 6
0
 /// <summary>Attempts to transfer the given amount of resource to another <see cref="PartResourceInfo"/> object,
 /// which must be of the same type.
 /// </summary>
 /// <returns>Returns the amount actually transferred, which may be less if the destination became full or
 /// otherwise cannot accept more resources, or the source doesn't have enough.
 /// </returns>
 public abstract double TransferTo(PartResourceInfo destination, double amount);
Esempio n. 7
0
        protected override void DrawWindowContents(int windowID)
        {
            headerScrollPosition = GUILayout.BeginScrollView(headerScrollPosition, GUILayout.ExpandHeight(false));
            GUILayout.BeginHorizontal();
            List <ResourceInfo> sortedResources = controller.GetResourceInfo().Values.ToList();

            sortedResources.Sort((a, b) => a.title.CompareTo(b.title));
            foreach (ResourceInfo resource in sortedResources)
            {
                if (HighLogic.CurrentGame.Parameters.CustomParams <TacSettings_1>().hideNontransferableResources&&
                    (resource.parts[0].resource.TransferMode != ResourceTransferMode.PUMP || !isControllable)
                    )
                {
                    continue;
                }

                bool toggled = (GUILayout.Toggle(resource.isShowing, resource.title, buttonStyle) != resource.isShowing);
                if (toggled)
                {
                    SetResourceVisibility(resource, !resource.isShowing);
                    if (resource.isShowing && settings.OneTabOnly)
                    {
                        foreach (ResourceInfo otherResource in sortedResources)
                        {
                            if (otherResource != resource)
                            {
                                SetResourceVisibility(otherResource, false);
                            }
                        }
                    }
                }
            }
            GUILayout.EndHorizontal();
            GUILayout.EndScrollView();

            scrollPosition = GUILayout.BeginScrollView(scrollPosition);
            GUILayout.BeginVertical();

            // cache the value so we only do it once per call
            isControllable = controller.IsControllable();

            // avoid allocating new options and arrays for every cell
            //GUILayoutOption[] width20 = new[] { GUILayout.Width(20) }, width46 = new[] { GUILayout.Width(46) }, width60 = new[] { GUILayout.Width(60) };
            foreach (ResourceInfo resource in sortedResources)
            {
                if (resource.isShowing)
                {
                    if (HighLogic.CurrentGame.Parameters.CustomParams <TacSettings_1>().hideNontransferableResources&&
                        (resource.parts[0].resource.TransferMode != ResourceTransferMode.PUMP || !isControllable)
                        )
                    {
                        continue;
                    }

                    GUILayout.BeginHorizontal();
                    GUILayout.Space(20);
                    GUILayout.Label(resource.title, sectionStyle, GUILayout.Width(100));
                    if (resource.parts[0].resource.TransferMode == ResourceTransferMode.PUMP && isControllable)
                    {
                        resource.balance = GUILayout.Toggle(resource.balance, "Balance All", buttonStyle);
                    }
                    if (GUILayout.Button("Select All", buttonStyle))
                    {
                        bool ctrl = Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl);
                        SelectParts(resource, resource.parts, resource.parts.Any(p => !p.isSelected), ctrl);
                        ResetRangeSelection();
                    }
                    PopupWindow.Draw("Sort", windowPos, DrawSortMenu, buttonStyle, null);


                    GUILayout.EndHorizontal();

                    foreach (ResourcePartMap partInfo in resource.parts)
                    {
                        PartResourceInfo partResource = partInfo.resource;
                        double           percentFull  = partResource.PercentFull * 100.0;

                        if (percentFull < settings.FuelCriticalLevel)
                        {
                            labelStyle.normal.textColor = new Color(0.88f, 0.20f, 0.20f, 1.0f);
                        }
                        else if (percentFull < settings.FuelWarningLevel)
                        {
                            labelStyle.normal.textColor = Color.yellow;
                        }
                        else
                        {
                            labelStyle.normal.textColor = Color.white;
                        }

                        labelStyle.fontStyle = partInfo.isSelected ? FontStyle.Bold : FontStyle.Normal;

                        GUILayout.BeginHorizontal();
                        string partTitle = partInfo.part.partInfo.title;

                        if (GUILayout.Button(partTitle.Substring(0, Math.Min(30, partTitle.Length)), labelStyle)) // if the user clicked an item name...
                        {
                            bool shift = Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift);
                            bool ctrl  = Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl);
                            bool alt   = Input.GetKey(KeyCode.LeftAlt) || Input.GetKey(KeyCode.RightAlt);
                            if (alt) // alt-click selects either all parts on the same ship or all parts of the same type
                            {
                                List <ResourcePartMap> parts;
                                if (shift)
                                {
                                    parts = resource.parts.FindAll(p => p.part.partInfo.title == partTitle);
                                }
                                else
                                {
                                    parts = resource.parts.FindAll(p => p.shipId == partInfo.shipId);
                                }
                                SelectParts(resource, parts, parts.Any(p => !p.isSelected), ctrl); // select all those parts if any is unselected
                                ResetRangeSelection();
                            }
                            else // otherwise, select and deselect items normally
                            {
                                ICollection <ResourcePartMap> parts;
                                // shift-click selects a range of items in the view
                                if (shift && resource == lastResourceClicked && partInfo != lastPartClicked && lastPartClicked != null)
                                {
                                    int partIndex = resource.parts.IndexOf(partInfo), lastIndex = resource.parts.IndexOf(lastPartClicked);
                                    if (lastIndex < 0)
                                    {
                                        lastIndex = partIndex;
                                    }
                                    parts = resource.parts.GetRange(Math.Min(partIndex, lastIndex), Math.Abs(partIndex - lastIndex) + 1);
                                }
                                else
                                {
                                    parts = new ResourcePartMap[] { partInfo };
                                }
                                SelectParts(resource, parts, !partInfo.isSelected || !ctrl && resource.parts.Count(p => p.isSelected) > parts.Count, ctrl);
                                lastResourceClicked = resource;
                                lastPartClicked     = partInfo;
                            }
                        }

                        GUILayout.FlexibleSpace();
                        if (settings.ShowShipNumber)
                        {
                            GUILayout.Label(partInfo.shipId.ToString(), labelStyle, width20);
                        }
                        if (settings.ShowStageNumber)
                        {
                            GUILayout.Label(partInfo.part.inverseStage.ToString(), labelStyle, width20);
                        }
                        if (settings.ShowMaxAmount)
                        {
                            GUILayout.Label(partResource.MaxAmount.ToString("N1"), labelStyle, width60);
                        }
                        if (settings.ShowCurrentAmount)
                        {
                            GUILayout.Label(partResource.Amount.ToString("N1"), labelStyle, width60);
                        }
                        if (settings.ShowPercentFull)
                        {
                            GUILayout.Label(percentFull.ToString("N1") + "%", labelStyle, width46);
                        }

                        GUILayout.Space(10);
                        //  Lock, Transfer In, Transfer Out, Balance, Dump, Highlight, then maybe Edit...??

                        if (settings.ShowToggles)
                        {
                            List <ResourcePartMap> selectedParts = partInfo.isSelected ? EnumerateSelectedParts().ToList() : new List <ResourcePartMap>(1)
                            {
                                partInfo
                            };
                            bool canPump = true, allHighlighted = true;
                            foreach (ResourcePartMap part in selectedParts)
                            {
                                canPump        &= part.resource.TransferMode == ResourceTransferMode.PUMP;
                                allHighlighted &= part.isHighlighted;
                            }
                            for (int toggleNum = 1; toggleNum < 6; toggleNum++)
                            {
                                if (canPump && isControllable)
                                {
                                    if (HighLogic.CurrentGame.Parameters.CustomParams <TacSettings_3>().lockedPos == toggleNum)
                                    {
                                        DrawToggleButton(partInfo, TransferDirection.LOCKED, "L", "Lock");
                                    }
                                    if (HighLogic.CurrentGame.Parameters.CustomParams <TacSettings_3>().transferInPos == toggleNum)
                                    {
                                        DrawToggleButton(partInfo, TransferDirection.IN, "I", "Transfer In");
                                    }
                                    if (HighLogic.CurrentGame.Parameters.CustomParams <TacSettings_3>().transferOutPos == toggleNum)
                                    {
                                        DrawToggleButton(partInfo, TransferDirection.OUT, "O", "Transfer Out");
                                    }
                                    if (HighLogic.CurrentGame.Parameters.CustomParams <TacSettings_3>().balancePos == toggleNum)
                                    {
                                        DrawToggleButton(partInfo, TransferDirection.BALANCE, "B", "Balance");
                                    }
                                    if (HighLogic.CurrentGame.Parameters.CustomParams <TacSettings_3>().dumpPos == toggleNum)
                                    {
                                        DrawToggleButton(partInfo, TransferDirection.DUMP, "D", "Dump");
                                    }
                                }
                                if (HighLogic.CurrentGame.Parameters.CustomParams <TacSettings_3>().lockedPos == toggleNum)
                                {
                                    bool highlight = GUILayout.Toggle(allHighlighted, new GUIContent("H", "Highlight"), buttonStyle, width20);
                                    if (highlight != allHighlighted)
                                    {
                                        foreach (ResourcePartMap part in selectedParts)
                                        {
                                            if (!highlight && part.isHighlighted && !part.isSelected)
                                            {
                                                part.part.SetHighlightDefault();
                                            }
                                            part.isHighlighted = highlight;
                                        }
                                        //guiChanged = true;
                                    }
                                }
                            }
                        }
                        if (HighLogic.CurrentGame.Parameters.CustomParams <TacSettings_1>().popupMenu)
                        {
                            PopupWindow.Draw(GetControlText(partInfo), windowPos, DrawPopupContents, coloredButtonStyle, partInfo, width20);
                        }

                        GUILayout.EndHorizontal();
                    }
                }
            }

            GUILayout.EndVertical();
            GUILayout.EndScrollView();

            GUILayout.BeginHorizontal();
            if (GUILayout.Toggle((settings.RateMultiplier == 100.0), "x100", buttonStyle))
            {
                settings.RateMultiplier = 100.0;
            }
            if (GUILayout.Toggle((settings.RateMultiplier == 10.0), "x10", buttonStyle))
            {
                settings.RateMultiplier = 10.0;
            }
            if (GUILayout.Toggle((settings.RateMultiplier == 1.0), "x1", buttonStyle))
            {
                settings.RateMultiplier = 1.0;
            }
            if (GUILayout.Toggle((settings.RateMultiplier == 0.1), "x0.1", buttonStyle))
            {
                settings.RateMultiplier = 0.1;
            }
            GUILayout.EndHorizontal();



            // Extra title bar buttons
#if false
            if (GUI.Button(new Rect(windowPos.width - 72, 4, 20, 20), resetContent, closeButtonStyle))
#else
            if (GUI.Button(new Rect(windowPos.width - 48, 4, 20, 20), resetContent, closeButtonStyle))
#endif
            {
                controller.RebuildActiveVesselLists();
            }
#if false
            if (!HighLogic.CurrentGame.Parameters.CustomParams <TacSettings_3>().disableOldSettings)
            {
                if (GUI.Button(new Rect(windowPos.width - 48, 4, 20, 20), settingsContent, closeButtonStyle))
                {
                    settingsWindow.ToggleVisible();
                }
            }
#endif
            if (GUI.Button(new Rect(windowPos.width - 24, 4, 20, 20), helpContent, closeButtonStyle))
            {
                helpWindow.ToggleVisible();
            }
        }