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

FREE QuickSmelt : 4.0.5 4.0.5

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using Facepunch.Extend;
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Configuration;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEngine;

namespace Oxide.Plugins
{
    [Info("QuickSmelt", "Wulf/Jake-Rich", "4.0.5", ResourceId = 1067)]
    [Description("Increases the speed of the furnace smelting")]

    class QuickSmelt : RustPlugin
    {
        public static QuickSmelt _plugin;
        public static JSONFile<ConfigData> _settingsFile;
        public static ConfigData Settings { get { return _settingsFile.Instance; } }
        public static MethodInfo ConsumeFuelMethod;

        public const string permAllow = "quicksmelt.allow";

        public class ConfigData
        {
            public int SmeltSpeed = 1;
            public int WoodRate = 1;
            public float CharcoalRate = 0.70f;
            public bool CanCookFoodInFurnace = false;
            public bool UsePermissions = false;

            [JsonProperty(PropertyName = "Large Furnace Multiplier")]
            public float LargeFurnaceMultiplier = 1.0f;
            [JsonProperty(PropertyName = "Campfire Multiplier")]
            public float CampFireMultiplier = 1.0f;
            [JsonProperty(PropertyName = "Oil Refinery Multiplier")]
            public float OilRefineryMultiplier = 1.0f;
            [JsonProperty(PropertyName = "Water Purifier Multiplier")]
            public float WaterPurifierMultiplier = 1.0f;
            //public float Efficency = 1f;


            public int GetSmeltRate(BaseEntity entity)
            {
                switch (entity.ShortPrefabName)
                {
                    default: { return SmeltSpeed; }
                    case "furnace_static": { return (int)(SmeltSpeed * LargeFurnaceMultiplier); }
                    case "hobobarrel_static": { return (int)(SmeltSpeed * CampFireMultiplier); }
                    case "furnace": { return SmeltSpeed; }
                    case "BBQ.Deployed": { return (int)(SmeltSpeed * CampFireMultiplier); }
                    case "campfire_static": { return (int)(SmeltSpeed * CampFireMultiplier); }
                    case "campfire": { return (int)(SmeltSpeed * CampFireMultiplier); }
                    case "small_refinery_static": { return (int)(SmeltSpeed * OilRefineryMultiplier); }
                    case "refinery_small_deployed": { return (int)(SmeltSpeed * OilRefineryMultiplier); }
                    case "fireplace.deployed": { return (int)(SmeltSpeed * CampFireMultiplier); }
                }
            }
        }

        public List<string> FurnaceTypes = new List<string>();

        private static HashSet<string> RawMeatNames = new HashSet<string>()
        {
            "bearmeat",
            "meat.boar",
            "wolfmeat.raw",
            "humanmeat.raw",
            "fish.raw",
            "chicken.raw",
            "deermeat.raw",
            "horsemeat.raw",
        };

        void Init()
        {
            _plugin = this;
            permission.RegisterPermission(permAllow, this);
        }
		
        void Loaded()
        {
            _settingsFile = new JSONFile<ConfigData>("QuickSmelt", ConfigLocation.Config, extension: ".json");
            ConsumeFuelMethod = typeof(BaseOven).GetMethod("ConsumeFuel", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
        }

		void Unload()
		{
            //Make sure to always return things to their vanilla state
		    foreach(var oven in BaseNetworkable.serverEntities.OfType<BaseOven>())
            {
                oven.allowByproductCreation = true;

                var data = oven.GetComponent<FurnaceData>();

                if (oven.IsOn())
                {
                    //Stop the modded smelting, resume the vanilla smelting
                    StopCooking(oven);
                    oven.StartCooking();
                }

                //Get rid of those monobehaviors
                UnityEngine.Object.Destroy(data);
            }
		}

		void OnServerInitialized()
        {
		    foreach(var oven in BaseNetworkable.serverEntities.OfType<BaseOven>().Where(x=>x.IsOn()))
            {
                NextFrame(() =>
                {
                    if (oven == null || oven.IsDestroyed)
                    {
                        return;
                    }
                    //So invokes are actually removed at the end of a frame, meaning you can get multiple invokes at once after reloading plugin
                    StopCooking(oven);
                    StartCooking(oven);
                });
            }
        }

		object OnOvenToggle(BaseOven oven, BasePlayer player)
		{
            if (oven is BaseFuelLightSource || (oven.needsBuildingPrivilegeToUse && !player.CanBuild()))
            {
                return null;
            }
			if (!oven.HasFlag(BaseEntity.Flags.On))
			{
				StartCooking(oven);
			}
            else
            {
                StopCooking(oven);
            }
            return false;
		}
		
        public Item FindBurnable(BaseOven oven)
        {
            return oven.inventory.itemList.FirstOrDefault(x => //TIL you can declare Linq over multiple lines
            {
                var comp = x.info.GetComponent<ItemModBurnable>();
                if (comp != null && (oven.fuelType == null || x.info == oven.fuelType))
                {
                    return true;
                }
                return false;
            });
        }

        //Overwriting Oven.StartCooking
		void StartCooking(BaseOven oven)
		{
            if ((Settings.UsePermissions && !permission.UserHasPermission(oven.OwnerID.ToString(), permAllow)))
            {
                oven.StartCooking();
                return;
            }
            if (FindBurnable(oven) == null)
            {
                return;
            }
            oven.UpdateAttachmentTemperature();
            var data = oven.transform.GetOrAddComponent<FurnaceData>();
            oven.CancelInvoke(oven.Cook);
            oven.InvokeRepeating(data.CookOverride, 0.5f, 0.5f);
            oven.SetFlag(BaseEntity.Flags.On, true, false);
        }
		
        void StopCooking(BaseOven oven)
        {
            var data = oven.transform.GetOrAddComponent<FurnaceData>();
            oven.CancelInvoke(data.CookOverride);
            oven.StopCooking();
        }

		void OnConsumeFuel(BaseOven oven, Item fuel, ItemModBurnable burnable)
        {
            BaseEntity slot = oven.GetSlot(BaseEntity.Slot.FireMod);
            if (slot != null)
            {
                //Usually 0.5f for cook tick, fuel is only consumed twice per second
                slot.SendMessage("Cook", 2f * Settings.SmeltSpeed * Settings.WaterPurifierMultiplier, SendMessageOptions.DontRequireReceiver);
            }

            if (oven == null || oven is BaseFuelLightSource)
            {
                return;
            }

            // Check if permissions are enabled and player has permission
            if (Settings.UsePermissions && !permission.UserHasPermission(oven.OwnerID.ToString(), permAllow)) return;

            var data = oven.transform.GetOrAddComponent<FurnaceData>();

            #region Charcoal Modifier

            if (burnable.byproductItem != null)
            {
                oven.allowByproductCreation = false;

                int charcoalAmount = 0;

                float modifiedRate = Settings.CharcoalRate * Settings.WoodRate;
                
                charcoalAmount += (int)(Settings.CharcoalRate * Settings.WoodRate);

                modifiedRate -= charcoalAmount;

                if (modifiedRate > 0 && modifiedRate <= 1f)
                {
                    if (UnityEngine.Random.Range(0f, 1f) < modifiedRate)
                    {
                        charcoalAmount += 1;
                    }
                }

                if (charcoalAmount > 0)
                {
                    TryAddItem(oven.inventory, burnable.byproductItem, Mathf.Min(charcoalAmount, fuel.amount));
                }
            }

            #endregion

            // Modify the amount of fuel to use
            fuel.UseItem(Settings.WoodRate - 1);
        }

        public static int TakeFromInventorySlot(ItemContainer container, int itemId, int amount, Item item)
        {
            if (item.info.itemid != itemId) return 0;

            if (item.amount > amount)
            {
                item.UseItem(amount);
                return amount;
            }

            amount = item.amount;
            item.Remove();
            return amount;
        }

        public static void TryAddItem(ItemContainer container, ItemDefinition definition, int amount)
        {
            int amountLeft = amount;
            foreach (var item in container.itemList)
            {
                if (item.info != definition)
                {
                    continue;
                }
                if (amountLeft <= 0)
                {
                    return;
                }
                if (item.amount < item.MaxStackable())
                {
                    int amountToAdd = Mathf.Min(amountLeft, item.MaxStackable() - item.amount);
                    item.amount += amountToAdd;
                    item.MarkDirty();
                    amountLeft -= amountToAdd;
                }
            }
            if (amountLeft <= 0)
            {
                return;
            }
            var smeltedItem = ItemManager.Create(definition, amountLeft);
            if (!smeltedItem.MoveToContainer(container))
            {
                smeltedItem.Drop(container.dropPosition, container.dropVelocity);
                var oven = container.entityOwner as BaseOven;
                if (oven != null)
                {
                    _plugin.StopCooking(oven);
                    //oven.OvenFull();
                }
            }
        }

        public class FurnaceData : MonoBehaviour
        {
            private BaseOven _oven;
            public BaseOven Furnace { get { if (_oven == null) { _oven = GetComponent<BaseOven>(); } return _oven; } } //One line bullshit right here

            public int SmeltTicks = 0;
            public Dictionary<string, float> ItemLeftovers = new Dictionary<string, float>();

            public void CookOverride()
            {
                SmeltTicks++;
                if (SmeltTicks % 2 == 0)
                {
                    TrySmeltItems();
                }
                var burnable = _plugin.FindBurnable(Furnace);
                if (burnable == null)
                {
                    _plugin.StopCooking(Furnace);
                    return;
                }
                ItemModBurnable component = burnable.info.GetComponent<ItemModBurnable>();
                burnable.fuel -= 0.5f * Furnace.cookingTemperature / 200f;
                if (!burnable.HasFlag(global::Item.Flag.OnFire))
                {
                    burnable.SetFlag(global::Item.Flag.OnFire, true);
                    burnable.MarkDirty();
                }
                if (burnable.fuel <= 0f)
                {
                    var array = ArrayPool.Get(2);
                    array[0] = burnable;
                    array[1] = component;
                    ConsumeFuelMethod.Invoke(Furnace, array);
                    ArrayPool.Free(array);
                }
            }

            void TrySmeltItems()
            {
                #region Smelt Modifier

                int smeltLoops = Mathf.Max(1, Settings.GetSmeltRate(Furnace));

                if (smeltLoops > 0)
                {
                    //Took from QuickSmelt and modified
                    // Loop through furance inventory slots
                    for (var i = 0; i < Furnace.inventory.itemList.Count; i++)
                    {
                        // Check for and ignore invalid items
                        var slotItem = Furnace.inventory.itemList[i];
                        if (slotItem == null || !slotItem.IsValid())
                        {
                            continue;
                        }

                        // Check for and ignore non-cookables
                        var cookable = slotItem.info.GetComponent<ItemModCookable>();
                        if (cookable == null)
                        {
                            continue;
                        }

                        //Make sure oil refinery only cooks oil, fireplace cooks food, furnace cooks ore
                        if (cookable.lowTemp > Furnace.cookingTemperature || cookable.highTemp < Furnace.cookingTemperature)
                        {
                            if (Settings.CanCookFoodInFurnace == true)
                            {
                                //Allow food to be cooked in furnaces
                                if (!RawMeatNames.Contains(slotItem.info.shortname))
                                {
                                    continue;
                                }
                            }
                            else
                            {
                                continue;
                            }
                        }

                        //_plugin.Puts($"{SmeltTicks} {(int)(cookable.cookTime)}");

                        //We do probability over time to see if we should cook instead of keeping track of item smelt time
                        //Will change this back to linear smelting once we expose ItemModCookable.OnCycle()
                        if ((int)cookable.cookTime != 0 && (SmeltTicks / 2) % (int)(cookable.cookTime) != 0)
                        {
                            continue;
                        }

                        // Skip already cooked food items
                        if (slotItem.info.shortname.EndsWith(".cooked"))
                        {
                            continue;
                        }

                        // Set consumption to however many we can pull from this actual stack
                        var consumptionAmount = TakeFromInventorySlot(Furnace.inventory, slotItem.info.itemid, Settings.SmeltSpeed, slotItem);

                        // If we took nothing, then...we can't create any
                        if (consumptionAmount <= 0)
                        {
                            continue;
                        }

                        //Will be used for efficency
                        int extraLoops = 1;

                        // Create the item(s) that are now cooked
                        TryAddItem(Furnace.inventory, cookable.becomeOnCooked, (cookable.amountOfBecome * consumptionAmount * extraLoops));
                    }
                }

                #endregion

                ItemManager.DoRemoves();
            }

            void Destroy()
            { 
                Furnace.CancelInvoke(CookOverride);
            }
        }

        [ConsoleCommand("quicksmelt.smelt")]
        void ChangeSmeltSpeed_ConsoleCommand(ConsoleSystem.Arg args)
        {
            if (!args.IsAdmin)
            {
                return;
            }
            if (args.HasArgs(1))
            {
                Settings.SmeltSpeed = args.GetInt(0, 1);
            }
            args.ReplyWith($"Smelt Speed: {Settings.SmeltSpeed}x (Default: 1)");
            _settingsFile.Save();
        }

        [ConsoleCommand("quicksmelt.wood")]
        void ChangeWoodRate_ConsoleCommand(ConsoleSystem.Arg args)
        {
            if (!args.IsAdmin)
            {
                return;
            }
            if (args.HasArgs(1))
            {
                Settings.WoodRate = args.GetInt(0, 1);
            }
            args.ReplyWith($"Wood Rate: {Settings.WoodRate} (Default: 1)");
            _settingsFile.Save();
        }

        [ConsoleCommand("quicksmelt.charcoal")]
        void ChangeCharcoal_ConsoleCommand(ConsoleSystem.Arg args)
        {
            if (!args.IsAdmin)
            {
                return;
            }
            if (args.HasArgs(1))
            {
                Settings.CharcoalRate = args.GetFloat(0, 1);
            }
            args.ReplyWith($"Charcoal Rate: {Settings.CharcoalRate.ToString("0.0")} (Default: 0.7)");
            _settingsFile.Save();
        }

        [ConsoleCommand("quicksmelt.food")]
        void ChangeFood_ConsoleCommand(ConsoleSystem.Arg args)
        {
            if (!args.IsAdmin)
            {
                return;
            }
            Settings.CanCookFoodInFurnace = !Settings.CanCookFoodInFurnace;
            args.ReplyWith($"Food will now {(Settings.CanCookFoodInFurnace ? "" : "not ")}cook in Furnaces.");
            _settingsFile.Save();
        }

        [ConsoleCommand("quicksmelt")]
        void QuickSmeltInfoCommand(ConsoleSystem.Arg args)
        {
            if (!args.IsAdmin)
            {
                return;
            }
            TextTable table = new TextTable();
            table.AddColumns("Description", "Setting", "Console Command");
            table.AddRow("", "");
            table.AddRow($"Smelt Speed", $"{Settings.SmeltSpeed}x", "quicksmelt.smelt");
            table.AddRow($"Charcoal Rate", $"{Settings.CharcoalRate.ToString("0.0")}x", "quicksmelt.charcoal");
            table.AddRow($"Wood Rate", $"{Settings.WoodRate}x", "quicksmelt.wood");
            table.AddRow($"Will Food Cook In Furnace", $"{Settings.CanCookFoodInFurnace}", "quicksmelt.food");
            args.ReplyWith(table.ToString());
        }

        #region Configuration Files

        public enum ConfigLocation
        {
            Data = 0,
            Config = 1,
            Logs = 2,
            Plugins = 3,
            Lang = 4,
            Custom = 5,
        }

        public class JSONFile<Type> where Type : class
        {
            private DynamicConfigFile _file;
            public string _name { get; set; }
            public Type Instance { get; set; }
            private ConfigLocation _location { get; set; }
            private string _path { get; set; }

            public JSONFile(string name, ConfigLocation location = ConfigLocation.Data, string path = null, string extension = ".json")
            {
                _name = name.Replace(".json", "");
                _location = location;
                switch (location)
                {
                    case ConfigLocation.Data:
                        {
                            _path = $"{Oxide.Core.Interface.Oxide.DataDirectory}/{name}{extension}";
                            break;
                        }
                    case ConfigLocation.Config:
                        {
                            _path = $"{Oxide.Core.Interface.Oxide.ConfigDirectory}/{name}{extension}";
                            break;
                        }
                    case ConfigLocation.Logs:
                        {
                            _path = $"{Oxide.Core.Interface.Oxide.LogDirectory}/{name}{extension}";
                            break;
                        }
                    case ConfigLocation.Lang:
                        {
                            _path = $"{Oxide.Core.Interface.Oxide.LangDirectory}/{name}{extension}";
                            break;
                        }
                    case ConfigLocation.Custom:
                        {
                            _path = $"{path}/{name}{extension}";
                            break;
                        }
                }
                _file = new DynamicConfigFile(_path);
                _file.Settings = new JsonSerializerSettings() { ReferenceLoopHandling = ReferenceLoopHandling.Ignore };
                Init();
            }

            public virtual void Init()
            {
                Load();
                Save();
                Load();
            }

            public virtual void Load()
            {

                if (!_file.Exists())
                {
                    Save();
                }
                Instance = _file.ReadObject<Type>();
                if (Instance == null)
                {
                    Instance = Activator.CreateInstance<Type>();
                    Save();
                }
                return;
            }

            public virtual void Save()
            {
                _file.WriteObject(Instance);
                return;
            }

            public virtual void Reload()
            {
                Load();
            }
        }

        #endregion
    }
}

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