Иконка ресурса

FREE FurnaceSorter : 1.0.15 1.0.15

Нет прав для скачивания
C#:
using System.Collections.Generic;
using System.Linq;
using Oxide.Game.Rust.Cui;
using UnityEngine;

namespace Oxide.Plugins
{
    [Info("FurnaceSorter", "Absolut & PsychoTea", "1.0.15", ResourceId = 23)]
    class FurnaceSorter : RustPlugin
    {
        #region Declarations

        const string permAllow = "furnacesorter.allow";

        bool _debuggingMode = false;

        Dictionary<string, Timer> _timers = new Dictionary<string, Timer>();

        Dictionary<ulong, BaseOven> _uiInfo = new Dictionary<ulong, BaseOven>();

        string _panelSorter = "PanelSorter";

        string _panelOnScreen = "PanelOnScreen";

        List<ulong> _enabled = new List<ulong>();

        List<ItemContainer> _sorting = new List<ItemContainer>();

        #endregion

        #region Classes

        public class UI
        {
            public static CuiElementContainer CreateOverlayContainer(string panelName, string color, string aMin, string aMax, bool cursor = false)
            {
                return new CuiElementContainer()
                {
                    {
                        new CuiPanel
                        {
                            Image =
                            {
                                Color = color
                            },
                            RectTransform =
                            {
                                AnchorMin = aMin,
                                AnchorMax = aMax
                            },
                            CursorEnabled = cursor
                        },
                        new CuiElement().Parent = "Overlay",
                        panelName
                    }
                };
            }

            public static void CreateButton(ref CuiElementContainer container, string panel, string color, string text, int size, string aMin, string aMax, string command, TextAnchor align = TextAnchor.MiddleCenter)
            {
                container.Add(new CuiButton
                {
                    Button =
                    {
                        Color = color,
                        Command = command,
                        FadeIn = 1.0f
                    },
                    RectTransform =
                    {
                        AnchorMin = aMin,
                        AnchorMax = aMax
                    },
                    Text =
                    {
                        Text = text,
                        FontSize = size,
                        Align = align
                    }
                }, panel);
            }

            public static void CreateTextOutline(ref CuiElementContainer element, string panel, string colorText, string colorOutline, string text, int size, string aMin, string aMax, TextAnchor align = TextAnchor.MiddleCenter)
            {
                element.Add(new CuiElement
                {
                    Parent = panel,
                    Components =
                    {
                        new CuiTextComponent
                        {
                            Color = colorText,
                            FontSize = size,
                            Align = align,
                            Text = text
                        },
                        new CuiOutlineComponent
                        {
                            Distance = "1 1",
                            Color = colorOutline
                        },
                        new CuiRectTransformComponent
                        {
                            AnchorMin = aMin,
                            AnchorMax = aMax
                        }
                    }
                });
            }
        }

        #endregion

        #region Lang

        void RegisterLang() => lang.RegisterMessages(_messages, this);

        Dictionary<string, string> _messages = new Dictionary<string, string>()
        {
            { "Title", "FurnaceSorter: " },
            { "NoPerm","You do not have permission to use this command" },

            { "FurnaceSorterDisabled", "FurnaceSorter is now disabled." },
            { "FurnaceOnSorterDisabled", "FurnaceSorter cannot be used while the furnace is on." },
            { "FurnaceSorterEnabled", "FurnaceSorter is now enabled." },

            { "ToggleOff", "SORTER: Turn OFF" },
            { "ToggleOn", "SORTER: Turn ON" },

            { "OptimizationUnavailable", "You can not use the Optimizer while the furnace is on!" },
            { "NothingToOptimize", "There is nothing in the furnace to optimize.Optimization Failed!" },
            { "NoWood", "The furnace does not appear to have wood.Optimization Failed!" },
            { "NoAcceptableItems", "The furnace does not appear to have any valid items to optimize wood against.Optimization Failed!" },
            { "WoodRatioGood", "The wood to acceptable item ratio is correct.No Optimization Required!" },
            { "WoodNeeded", "Optimizing found you are short {0} wood" },
            { "ExtraWoodGiven", "Optimizing found you have {0} extra wood.This wood has been placed in your inventory!" },
            { "InventoryFull", "Your furnace has {0} extra wood but it will not fit in your inventory.Optimization Failed!" },
            { "FurnaceOptimized", "Your furnace has been optimized!" },
        };

        #endregion

        #region Config

        float _default_minX = 0.646f;

        float _default_minY = 0.1f;

        float _default_maxX = 0.81f;

        float _defeault_maxY = 0.14f;

        ConfigData _configData;

        class ConfigData
        {
            public float minx { get; set; }

            public float miny { get; set; }

            public float maxx { get; set; }

            public float maxy { get; set; }
        }

        void LoadConfigData()
        {
            LoadConfigVariables();

            if (_configData == null) LoadDefaultConfig();

            SaveConfig();

            if (_configData.maxx == default(float) &&
                _configData.maxy == default(float) &&
                _configData.minx == default(float) &&
                _configData.miny == default(float))
            {
                _configData.minx = _default_minX;
                _configData.miny = _default_minY;
                _configData.maxx = _default_maxX;
                _configData.maxy = _defeault_maxY;

                SaveConfig(_configData);
            }
        }

        void LoadConfigVariables() => _configData = Config.ReadObject<ConfigData>();

        void SaveConfig(ConfigData config) => Config.WriteObject(config, true);

        protected override void LoadDefaultConfig()
        {
            SaveConfig(new ConfigData
            {
                minx = _default_minX,
                miny = _default_minY,
                maxx = _default_maxX,
                maxy = _defeault_maxY,
            });
        }

        #endregion

        #region Hooks

        void Init()
        {
            RegisterLang();

            permission.RegisterPermission(permAllow, this);

            LoadConfigData();

            if (ConVar.Server.hostname == "PsychoTea's Testing Server")
            {
                _debuggingMode = true;
            }
        }

        void Unload()
        {
            BasePlayer.activePlayerList.ToList().ForEach(x => CloseUI(x));

            foreach (var entry in _timers)
            {
                entry.Value.Destroy();
            }

            _timers.Clear();
        }

        void OnPlayerInit(BasePlayer player)
        {
            if (!_enabled.Contains(player.userID))
            {
                _enabled.Add(player.userID);
            }
        }

        void OnPlayerDisconnected(BasePlayer player)
        {
            CloseUI(player);
        }

        void OnPlayerRespawned(BasePlayer player)
        {
            CuiHelper.DestroyUi(player, _panelOnScreen);
            CuiHelper.DestroyUi(player, _panelSorter);
        }

        void OnLootEntity(BasePlayer player, BaseEntity entity)
        {
            if (player == null || entity == null) return;

            if (!HasPerm(player)) return;

            BaseOven oven = entity as BaseOven;
            if (oven == null) return;

            if (!_uiInfo.ContainsKey(player.userID))
            {
                _uiInfo.Add(player.userID, oven);
            }

            _uiInfo[player.userID] = oven;

            SorterUI(player);
        }

        void OnPlayerLootEnd(PlayerLoot looter)
        {
            if (looter?.entitySource == null) return;

            if (!(looter.entitySource is BaseOven)) return;

            BasePlayer player = looter.GetComponent<BasePlayer>();
            if (player == null) return;

            if (_uiInfo.ContainsKey(player.userID))
            {
                _uiInfo[player.userID] = null;
            }

            CuiHelper.DestroyUi(player, _panelSorter);
        }

        object CanAcceptItem(ItemContainer container, Item item)
        {
            if (container == null ||
                container.entityOwner == null ||
                container.entityOwner.GetComponent<BaseOven>() == null ||
                item == null ||
                item.parent == container ||
                _sorting.Contains(container))
            {
                return null;
            }

            BasePlayer player = item.GetOwnerPlayer();
            if (player == null)
            {
                DebugMessage("No player");
                return null;
            }

            if (!HasPerm(player))
            {
                DebugMessage("No permission");
                return null;
            }

            if (!_enabled.Contains(player.userID))
            {
                DebugMessage("Not enabled");
                return null;
            }

            List<string> AcceptableItems = new List<string>();

            BaseOven oven = container.entityOwner.GetComponent<BaseOven>();
            string ovenName = oven.ShortPrefabName;

            if (ovenName.Contains("campfire") ||
                ovenName.Contains("hobobarrel") ||
                ovenName.Contains("bbq"))
            {
                AcceptableItems = new List<string>
                {
                    "bearmeat",
                    "deermeat.raw",
                    "humanmeat.raw",
                    "meat.boar",
                    "wolfmeat.raw",
                    "can.beans.empty",
                    "can.tuna.empty",
                    "chicken.raw",
                    "fish.raw"
                };
            }
            else if (ovenName.Contains("furnace"))
            {
                AcceptableItems = new List<string>
                {
                    "hq.metal.ore",
                    "metal.ore",
                    "sulfur.ore",
                    "can.beans.empty",
                    "can.tuna.empty"
               };
            }
            else if (ovenName.Contains("refinery"))
            {
                AcceptableItems = new List<string>
                {
                    "crude.oil"
                };
            }

            if (!AcceptableItems.Contains(item.info.shortname))
            {
                DebugMessage($"not acceptable item {item.info.shortname}");
                return null;
            }

            if (container.entityOwner.GetComponent<BaseOven>().IsOn())
            {
                _enabled.Remove(player.userID);
                OnScreen(player, "FurnaceOnSorterDisabled");
                SorterUI(player);
                return null;
            }

            var totalAmount = item.amount;

            DebugMessage($"TotalAmount = {totalAmount}");

            List<Item> lessThanMax = new List<Item>();
            List<Item> items = new List<Item>();

            bool containsCharcoal = false;

            foreach (var entry in container.itemList)
            {
                if (entry.info.displayName.english == "Charcoal")
                {
                    DebugMessage($"Contains Charcoal");

                    containsCharcoal = true;
                }

                if (entry.info.shortname == item.info.shortname)
                {
                    items.Add(entry);
                    totalAmount += entry.amount;

                    if (entry.amount < item.MaxStackable())
                    {
                        lessThanMax.Add(entry);
                    }

                    DebugMessage($"TotalAmount = {totalAmount}");
                }
            }

            var newSlots = container.capacity - container.itemList.Count();
            
            if (lessThanMax.Count == 0)
            {
                if (containsCharcoal && newSlots <= 1)
                {
                    return ItemContainer.CanAcceptResult.CannotAccept;
                }

                if (!containsCharcoal && newSlots <= 2)
                {
                    return ItemContainer.CanAcceptResult.CannotAccept;
                }
            }

            if (ovenName.Contains("refinery"))
            {
                newSlots -= 2;
            }
            else
            {
                newSlots -= containsCharcoal ? 1 : 2;
            }

            if (newSlots > totalAmount) newSlots = totalAmount;

            DebugMessage($"{newSlots} - Available Slots");

            var totalSlots = items.Count();

            if (totalSlots == 0)
            {
                totalSlots += newSlots;
            }
            else
            {
                newSlots = 0;
            }

            if (totalSlots > totalAmount)
            {
                totalSlots = totalAmount;
            }

            var remainder = totalAmount % totalSlots;

            DebugMessage($"Remainder: {remainder}");

            var SplitableAmount = totalAmount - remainder;

            DebugMessage($"SplitAmount: {SplitableAmount}");

            var eachStack = SplitableAmount / totalSlots;

            DebugMessage($"EachStack: {eachStack}");

            if (eachStack > item.MaxStackable())
            {
                eachStack = item.MaxStackable();

                remainder = totalAmount - (eachStack * totalSlots);
            }

            SortFurnace(player, container, item, eachStack, items, item.info.shortname, remainder, newSlots);

            return ItemContainer.CanAcceptResult.CannotAccept;
        }

        private Item FindBurnable(BaseOven oven)
        {
            foreach (var item in oven.inventory.itemList)
            {
                if (item.info.GetComponent<ItemModBurnable>() == null)
                {
                    continue;
                }

                if (oven.fuelType == null)
                {
                    continue;
                }

                if (oven.fuelType != item.info)
                {
                    continue;
                }

                return item;
            }

            return null;
        }

        #endregion

        #region Commands

        [ConsoleCommand("UI_ToggleSorter")]
        void UIToggleSorterConsoleCommand(ConsoleSystem.Arg arg)
        {
            var player = arg.Connection.player as BasePlayer;
            if (player == null) return;

            if (!HasPerm(player)) return;

            if (!_enabled.Contains(player.userID))
            {
                _enabled.Add(player.userID);

                OnScreen(player, "FurnaceSorterEnabled");
                SorterUI(player);

                return;
            }

            _enabled.Remove(player.userID);

            OnScreen(player, "FurnaceSorterDisabled");
            SorterUI(player);
        }

        #endregion

        #region GUI

        void SorterUI(BasePlayer player)
        {
            CuiHelper.DestroyUi(player, _panelSorter);

            var element = UI.CreateOverlayContainer(_panelSorter, "0 0 0 0", $"{_configData.minx} {_configData.miny}", $"{_configData.maxx} {_configData.maxy}");

            if (_enabled.Contains(player.userID)) UI.CreateButton(ref element, _panelSorter, "0.584 0.29 0.211 1.0", GetMessage("ToggleOff", player), 12, "0 0", "0.6 1", $"UI_ToggleSorter {3}");

            else UI.CreateButton(ref element, _panelSorter, "0.439 0.509 0.294 1.0", GetMessage("ToggleOn", player), 12, "0 0", "0.6 1", $"UI_ToggleSorter {3}");

            CuiHelper.AddUi(player, element);
        }

        void OnScreen(BasePlayer player, string msg)
        {
            if (_timers.ContainsKey(player.userID.ToString()))
            {
                _timers[player.userID.ToString()].Destroy();
                _timers.Remove(player.userID.ToString());
            }
            CuiHelper.DestroyUi(player, _panelOnScreen);
            var element = UI.CreateOverlayContainer(_panelOnScreen, "0.0 0.0 0.0 0.0", "0.3 0.5", "0.7 0.8");
            UI.CreateTextOutline(ref element, _panelOnScreen, string.Empty, "0 0 0 1", GetMessage(msg, player), 32, "0.0 0.0", "1.0 1.0");
            CuiHelper.AddUi(player, element);
            _timers.Add(player.userID.ToString(), timer.Once(4, () => CuiHelper.DestroyUi(player, _panelOnScreen)));
        }

        void CloseUI(BasePlayer player)
        {
            if (player == null) return;

            if (_uiInfo.ContainsKey(player.userID))
            {
                _uiInfo.Remove(player.userID);
            }

            if (_timers.ContainsKey(player.userID.ToString()))
            {
                _timers[player.userID.ToString()].Destroy();
                _timers.Remove(player.userID.ToString());
            }

            if (_enabled.Contains(player.userID))
            {
                _enabled.Remove(player.userID);
            }

            CuiHelper.DestroyUi(player, _panelOnScreen);

            CuiHelper.DestroyUi(player, _panelSorter);
        }

        #endregion

        #region Functions

        void SortFurnace(BasePlayer player, ItemContainer container, Item originalItem, int stackAmount, List<Item> existingItems, string shortname, int remainder, int newSlots)
        {
            _sorting.Add(container);

            DebugMessage("Starting Sort");

            ItemDefinition def = ItemManager.FindItemDefinition(shortname);

            foreach (var entry in existingItems.Where(x => x != null))
            {
                entry.amount = stackAmount;
            }

            while (newSlots > 0)
            {
                var newItem = ItemManager.Create(def, stackAmount);
                newItem.MoveToContainer(container, -1, false);

                newSlots--;
            }

            if (remainder > 0)
            {
                foreach (var entry in container.itemList.Where(k => k.info.shortname == originalItem.info.shortname))
                {
                    DebugMessage($"Amount: {entry.amount} - Remainder Amount: {remainder}");

                    if (entry.amount != entry.MaxStackable())
                    {
                        entry.amount++;
                        remainder--;

                        DebugMessage($"Amount: {entry.amount} - Remainder Amount: {remainder}");
                    }

                    if (remainder == 0)
                    {
                        DebugMessage($"Remainder = 0");

                        originalItem.RemoveFromContainer();
                        originalItem.Remove(0f);

                        break;
                    }

                    DebugMessage("Continuing...");
                }

                DebugMessage($"Remainder > 0 - Remainder Amount: {remainder}");
                DebugMessage($"OriginalItem Amount - {originalItem.amount}");

                originalItem.amount = remainder;

                DebugMessage($"OriginalItem Amount - {originalItem.amount}");

                originalItem.MarkDirty();
            }
            else
            {
                DebugMessage($"Remainder = 0");

                originalItem.RemoveFromContainer();
                originalItem.Remove(0f);
            }

            _sorting.Remove(container);
            container.MarkDirty();
        }

        #endregion

        #region Helpers

        void SendMessage(BasePlayer player, string key, params object[] args)
        {
            string message = GetMessage(key, player, args);

            SendReply(player, $"<color=orange>{GetMessage("Title", player)}</color><color=#A9A9A9>{message}</color>");
        }

        string GetMessage(string key, BasePlayer player = null, params object[] args)
        {
            return string.Format(lang.GetMessage(key, this, player?.UserIDString), args);
        }

        void DebugMessage(string message)
        {
            if (!_debuggingMode) return;

            Puts(message);
        }

        bool HasPerm(BasePlayer player, string perm = permAllow) => player.IsAdmin || permission.UserHasPermission(player.UserIDString, perm);

        #endregion
    }
}

Автор
15FPS
Скачиваний
0
Просмотры
1
Первый выпуск
Обновление
Оценка
0.00 звёзд 0 оценок
Сверху