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

FREE FurnaceSorter : 2.0.1 2.0.1

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

namespace Oxide.Plugins
{
    [Info("Furnace Sorter", "Я и Я", "2.0.1")]
    [Description("Дерево автоматом")]
    public class FurnaceSorter : RustPlugin
    {
        #region Oxide Hooks

        private void Init()
        {
            cmd.AddConsoleCommand("furnacesort.toggle", this, "Command");
            LoadData();
        }

        private void Unload()
        {
            SaveData();
        }
        
        private void OnLootEntity(BasePlayer player, BaseOven oven)
        {
            CreateGUI(player);
        }
        
        private void OnLootEntityEnd(BasePlayer player, BaseOven entity)
        {
            DestroyGUI(player);   
        }

        #endregion

        #region Commands

        private void Command(ConsoleSystem.Arg arg)
        {
            var player = arg.Player();
            if (player != null)
            {
                var id = player.userID;
                if (disabled.Contains(id))
                {
                    disabled.Remove(id);
                }
                else
                {
                    disabled.Add(id);
                }
                
                CreateGUI(player);
            }
        }

        #endregion

        #region Data
        
        private List<ulong> disabled = new List<ulong>();
        
        private const string filename = "FurnaceSorter_playerData";

        private void LoadData()
        {
            try
            {
                disabled = Interface.Oxide.DataFileSystem.ReadObject<List<ulong>>(filename);
            }
            catch (Exception e)
            {
                PrintWarning(e.Message);
            }

            SaveData();
            timer.Every(600f, SaveData);
        }

        private void SaveData()
        {
            Interface.Oxide.DataFileSystem.WriteObject(filename, disabled);
        }

        #endregion

        #region GUI

        private const string elemHud = "furnacesorter.Hud";

        private void CreateGUI(BasePlayer player)
        {
            CuiHelper.DestroyUi(player, elemHud);
            CuiHelper.AddUi(player, GetUI(player));
        }

        private void DestroyGUI(BasePlayer player)
        {
            CuiHelper.DestroyUi(player, elemHud);
        }

        private CuiElementContainer GetUI(BasePlayer player)
        {
            var enabled = !disabled.Contains(player.userID);
            var text = enabled ? "Выключить сортировку" : "Включить сортировку";
            var color = enabled ? "0.8 0.28 0.2 1" : "0.44 0.52 0.29 0.6";
            
            return new CuiElementContainer
            {
                new CuiElement
                {
                    Name = elemHud,
                    Parent = "Hud.Menu",
                    Components =
                    {
                        new CuiImageComponent
                        {
                            Color  = "0.75 0.75 0.75 0.05"
                        },
                        new CuiRectTransformComponent
                        {
                            AnchorMin = "0.6505 0.022",
                            AnchorMax = "0.829 0.134"
                        }
                    }
                },
                {
                    new CuiButton
                    {
                        Text =
                        {
                            Text = text,
                            Color = "1 1 1 1",
                            Align = TextAnchor.MiddleCenter,
                            FontSize = 17
                        },
                        Button =
                        {
                            Command = "furnacesort.toggle",
                            Color = color,
                        },
                        RectTransform =
                        {
                            AnchorMin = "0.03 0.1",
                            AnchorMax = "0.97 0.9"
                        }
                    },
                    elemHud
                }
            };
        }

        #endregion

        #region Core
        
        private class OvenSlot
        {
            public Item Item;
            public int? Position;
            public int Index;
            public int DeltaAmount;
        }

        private bool IsSlotCompatible(Item item, BaseOven oven, ItemDefinition itemDefinition)
        {
            var cookable = item.info.GetComponent<ItemModCookable>();
            if (item.amount < item.info.stackable && item.info == itemDefinition) {return true;}
            if (oven.allowByproductCreation && oven.fuelType.GetComponent<ItemModBurnable>().byproductItem == item.info) {return true;}
            return cookable == null || cookable.becomeOnCooked == itemDefinition;
        }
        
        private object CanMoveItem(Item item, PlayerInventory inventory, uint targetContainer, int targetSlot)
        {
            var player = inventory.GetComponent<BasePlayer>();
            if (player == null) {return null;}
            if (disabled.Contains(player.userID)) {return null;}
            var container = inventory.FindContainer(targetContainer);
            if (container == null || container == item.GetRootContainer()) {return null;}
            var oven = container.entityOwner as BaseOven;
            if (oven == null) {return null;}
            var name = item.info.shortname;
            if (!name.EndsWith(".ore") && !name.EndsWith(".oil")){return null;}
            var totalSlots = oven.inventory.capacity - 3;
            MoveSplitItem(item, oven, totalSlots);
            return true;
        }

        private void MoveSplitItem(Item item, BaseOven oven, int totalSlots)
        {
            var player = item.GetOwnerPlayer();
            var container = oven.inventory;
            var invalidItemsCount = container.itemList.Count(slotItem => !IsSlotCompatible(slotItem, oven, item.info));
            var numOreSlots = Math.Min(container.capacity - invalidItemsCount, totalSlots);
            var totalMoved = 0;
            var totalAmount = Math.Min(item.amount + container.itemList.Where(slotItem => slotItem.info == item.info).Take(numOreSlots).Sum(slotItem => slotItem.amount), item.info.stackable * numOreSlots);
            if (numOreSlots <= 0) {return;}
            var totalStackSize = Math.Min(totalAmount / numOreSlots, item.info.stackable);
            var remaining = totalAmount - totalAmount / numOreSlots * numOreSlots;
            var addedSlots = new List<int>();
            var ovenSlots = new List<OvenSlot>();

            for (var i = 0; i < numOreSlots; ++i)
            {
                Item existingItem;
                var slot = FindMatchingSlotIndex(container, out existingItem, item.info, addedSlots);
                if (slot == -1)
                {
                    return;
                }
                addedSlots.Add(slot);
                var ovenSlot = new OvenSlot
                {
                    Position = existingItem?.position,
                    Index = slot,
                    Item = existingItem
                };
                var currentAmount = existingItem?.amount ?? 0;
                var missingAmount = totalStackSize - currentAmount + (i < remaining ? 1 : 0);
                ovenSlot.DeltaAmount = missingAmount;
                if (currentAmount + missingAmount <= 0) {continue;}
                ovenSlots.Add(ovenSlot);
            }

            foreach (var slot in ovenSlots)
            {
                if (slot.Item == null)
                {
                    if (slot.DeltaAmount > 0)
                    {
                        var newItem = ItemManager.Create(item.info, slot.DeltaAmount, item.skin);
                        slot.Item = newItem;
                        newItem.MoveToContainer(container, slot.Position ?? slot.Index);
                    }
                }
                else
                {
                    slot.Item.amount += slot.DeltaAmount;
                }

                totalMoved += slot.DeltaAmount;
            }

            container.MarkDirty();

            if (totalMoved >= item.amount)
            {
                item.Remove();
                item.GetRootContainer()?.MarkDirty();
            }
            else
            {
                item.amount -= totalMoved;
                item.GetRootContainer()?.MarkDirty();
            }
            
            AddFuel(player, oven);
        }

        private int FindMatchingSlotIndex(ItemContainer container, out Item existingItem, ItemDefinition itemType, List<int> indexBlacklist)
        {
            existingItem = null;
            var firstIndex = -1;
            var existingItems = new Dictionary<int, Item>();

            for (var i = 0; i < container.capacity; ++i)
            {
                if (indexBlacklist.Contains(i)) {continue;}
                var itemSlot = container.GetSlot(i);
                if (itemSlot == null || itemType != null && itemSlot.info == itemType)
                {
                    if (itemSlot != null)
                        existingItems.Add(i, itemSlot);

                    if (firstIndex == -1)
                    {
                        existingItem = itemSlot;
                        firstIndex = i;
                    }
                }
            }

            if (existingItems.Count <= 0 && firstIndex != -1)
            {
                return firstIndex;
            }
            else if (existingItems.Count > 0)
            {
                var largestStackItem = existingItems.OrderByDescending(kv => kv.Value.amount).First();
                existingItem = largestStackItem.Value;
                return largestStackItem.Key;
            }

            existingItem = null;
            return -1;
        }

        private void AddFuel(BasePlayer player, BaseOven oven)
        {
            if (oven.inventory.capacity - oven.inventory.itemList.Count == 0) {return;}
            var existing = oven.inventory.GetAmount(-151838493, false);
            var hqmWood = 10;
            var metalWood = 5;
            var sulfurWood = 3;
            var crudeOil = 7;
            var wood = GetItems("wood", player.inventory.AllItems().ToList());
            
            foreach (var item in oven.inventory.itemList.ToList())
            {
                var need = 0;
                var amount = item.amount;
                
                switch (item.info.shortname)
                {
                    case "hq.metal.ore":
                        need = amount * hqmWood - existing;
                        break;
                    
                    case "metal.ore":
                        need = amount * metalWood - existing;
                        break;
                    
                    case "sulfur.ore":
                        need = amount * sulfurWood - existing;
                        break;
                    
                    default:
                        continue;
                }

                if (need > 0)
                {
                    TakeItemAmount(wood, need, oven.inventory);
                    existing += need;
                }
            }
        }
        
        private List<Item> GetItems(string name, List<Item> itemList)
        {
            var items = new List<Item>();

            foreach (var obj in itemList)
            {
                if (obj.info.shortname == name && !obj.IsBusy())
                {
                    items.Add(obj);
                }
            }

            return items;
        }
        
        private void TakeItemAmount(List<Item> moveFrom, int amount, ItemContainer moveTO)
        {
            foreach (var item in moveFrom.ToList())
            {
                if (item.amount > amount && amount > 0)
                {
                    item.MarkDirty();
                    item.amount -= amount;
                    var newItem = ItemManager.Create(item.info, amount);
                    newItem.MoveToContainer(moveTO);
                    return;
                }

                amount -= item.amount;
                item.MoveToContainer(moveTO);
            }
        }

        #endregion
    }
}

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