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

FREE RotatingPickups : 0.1.9 0.1.9

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

namespace Oxide.Plugins
{
    [Info("RotatingPickups", "k1lly0u", "0.1.9", ResourceId = 0)]
    class RotatingPickups : RustPlugin
    {
        #region Fields  
        StoredData storedData;
        private DynamicConfigFile data;

        [PluginReference]
        Plugin ZoneManager;

        static RotatingPickups instance;
        private bool initialized;
        private Dictionary<string, ZoneInfo> dropZones;

        private static readonly Collider[] colBuffer = (Collider[])typeof(Vis).GetField("colBuffer", (BindingFlags.Static | BindingFlags.NonPublic))?.GetValue(null);

        #endregion

        #region Components      
        class ItemRotator : MonoBehaviour
        {
            private WorldItem entity;
            private Rigidbody rigidBody;
            private bool hasBegun;

            private float secsToTake;
            void Awake()
            {
                entity = GetComponent<WorldItem>();
                enabled = false;                
            }   
            void OnDestroy()
            {
                if (entity == null) return;
                if (rigidBody != null)
                {
                    rigidBody.useGravity = true;
                    rigidBody.isKinematic = false;
                }
            }        
            void FixedUpdate()
            {
                entity.transform.RotateAround(entity.transform.position, Vector3.up, secsToTake);                
                entity.transform.hasChanged = true;
            }
            void OnCollisionEnter(Collision collision)
            {
                if (hasBegun || collision.gameObject == null) return;
                if (collision.gameObject.GetComponent<Terrain>() || collision.gameObject.name.Contains("junk_pile") || collision?.gameObject?.layer == (int)Layer.Construction)
                {
                    hasBegun = true;
                    Invoke("BeginRotation", instance.configData.TimeBeforeRotation);
                }
            }
            void OnTriggerEnter(Collider col)
            {
                if (!instance.configData.AllowContactPickup) return;
                if (col?.gameObject?.layer != 17) return;
                var player = col.GetComponentInParent<BasePlayer>();
                if (player != null)
                {
                    Item item = entity.item;
                    if (item != null)
                    {
                        if (player.inventory.containerBelt.itemList.Count < 6 || player.inventory.containerMain.itemList.Count < 24 || (player.inventory.containerWear.itemList.Count < 6 && item.info.category == ItemCategory.Attire))
                        {
                            player.GiveItem(item, BaseEntity.GiveItemReason.PickedUp);
                            Destroy(this);
                        }                        
                    }
                }
            } 
            private void BeginRotation()
            {
                gameObject.layer = (int)Layer.Reserved1;

                rigidBody = entity.GetComponent<Rigidbody>();
                rigidBody.useGravity = false;
                rigidBody.isKinematic = true;
                rigidBody.detectCollisions = true;
                rigidBody.collisionDetectionMode = CollisionDetectionMode.Discrete;

                var collider = gameObject.AddComponent<SphereCollider>();
                collider.isTrigger = true;
                collider.radius = instance.configData.ColliderTriggerRadius;

                string shortname = entity.item.info.shortname;
                secsToTake = instance.configData.RotationSpeed;

                entity.transform.transform.eulerAngles = new Vector3(instance.rotateList.ContainsKey(shortname) ? instance.rotateList[shortname] : 0, 0, 0);
                entity.transform.position = entity.transform.position + (shortname.Contains("spear") ? Vector3.up * 2 : Vector3.up);
                enabled = true;
            }          
        }
        class ZoneInfo
        {
            public Vector3 Position;
            public float Radius;
            public bool IsBox;
            public Vector3 Size;
            public Vector3 Rotation;
        }
        #endregion

        #region Oxide Hooks   
        void Loaded()
        {
            data = Interface.Oxide.DataFileSystem.GetFile("rotatingpickups_zonelist");
            dropZones = new Dictionary<string, ZoneInfo>();
            permission.RegisterPermission("rotatingpickups.zones", this);
        }    
        void OnServerInitialized()
        {
            initialized = true;
            instance = this;
            LoadVariables();
            LoadData();

            if (configData.AllowInZonesOnly)
                FindAllZones();
        }
        void OnEntitySpawned(BaseNetworkable entity)
        {
            if (!initialized) return;
            WorldItem worldItem = entity.GetComponent<WorldItem>();
            if (worldItem != null)
            {                
                if (!IsInZone(worldItem)) return;
                Item item = worldItem.item;
                if (item != null)
                {
                    if (configData.TypesToRotate.ContainsKey(item.info.category))
                    {
                        if (configData.TypesToRotate[item.info.category])
                        {
                            NextTick(() =>
                            {
                                if (worldItem != null)
                                    worldItem.gameObject.AddComponent<ItemRotator>();
                            });                            
                        }
                    }
                }
            }
        }
        void Unload()
        {
            var objects = UnityEngine.Object.FindObjectsOfType<ItemRotator>();
            if (objects != null)
                foreach (var obj in objects)
                    UnityEngine.Object.Destroy(obj);
        }
        #endregion

        #region Functions
        void FindAllZones()
        {
            if (!ZoneManager) return;
            foreach(var zoneId in storedData.zoneIds)
            {
                GetZoneInfo(zoneId);
            }
        }
        void GetZoneInfo(string zoneId)
        {
            object success = ZoneManager?.Call("GetZoneLocation", zoneId);
            if (success is Vector3)
            {
                Vector3 position = (Vector3)success;
                success = ZoneManager?.Call("GetZoneSize", zoneId);
                if (success is Vector3 && (Vector3)success != Vector3.zero)
                {
                    Vector3 size = (Vector3)success;
                    success = ZoneManager.Call("ZoneFieldList", zoneId);
                    if (success == null) return;
                    Dictionary<string, string> fieldList = (Dictionary<string, string>)success;
                    if (fieldList.ContainsKey("rotation"))
                    {
                        string rotString = fieldList["rotation"];
                        dropZones.Add(zoneId, new ZoneInfo { Position = position, IsBox = true, Size = size, Rotation = ParseV3String(rotString) });                        
                    }
                    return;
                }
                else success = ZoneManager?.Call("GetZoneRadius", zoneId);
                if (success is float && (float)success != 0)
                    dropZones.Add(zoneId, new ZoneInfo { Position = position, Radius = (float)success });                
            }
        }
        Vector3 ParseV3String(string source)
        {
            string outString = source.Substring(1, source.Length - 2);
            string[] splitString = outString.Split("," [0]);
            return new Vector3(float.Parse(splitString[0]), float.Parse(splitString[1]), float.Parse(splitString[2]));
        }
        bool IsInZone(WorldItem entity)
        {
            if (!configData.AllowInZonesOnly) return true;
            foreach(var zone in dropZones)
            {
                if (!zone.Value.IsBox)
                {
                    if (Vector3.Distance(zone.Value.Position, entity.transform.position) < zone.Value.Radius)
                        return true;
                }
                else
                {
                    int entities = 0;
                    if (zone.Value.Size != Vector3.zero)
                        entities = Physics.OverlapBoxNonAlloc(zone.Value.Position, new Vector3(zone.Value.Size.x /2, zone.Value.Size.y / 2, zone.Value.Size.z / 2), colBuffer, Quaternion.Euler(zone.Value.Rotation));
                    for (var i = 0; i < entities; i++)
                    {
                        var item = colBuffer[i].GetComponentInParent<WorldItem>();
                        colBuffer[i] = null;
                        if (item != null)
                        {
                            if (item == entity) return true;                            
                        }
                    }
                }
            }           
            return false;
        }
        #endregion

        #region Commands
        [ChatCommand("dropzone")]
        void cmdDropZone(BasePlayer player, string command, string[] args)
        {
            if (!player.IsAdmin && !permission.UserHasPermission(player.UserIDString, "rotatingpickups.zones")) return;
            if (!ZoneManager)
            {
                SendReply(player, "ZoneManager is not installed! Unable to register zones for item drops");
                return;
            }
            if (args.Length == 1 && args[0].ToLower() == "list")
            {
                string zoneList = "--- Registered Zone IDs ---";
                foreach (var zoneId in storedData.zoneIds)
                    zoneList += $"\n{zoneId}";
                SendReply(player, zoneList);
                return;
            }
            if (args.Length != 2)
            {
                SendReply(player, $"{Title}  v.{Version} -- Registered Zones");
                SendReply(player, "/dropzone add <zoneid> - Adds the zone ID to the list zones");
                SendReply(player, "/dropzone remove <zoneid> - Removes the zone ID from the list of zones");
                SendReply(player, "/dropzone list - List all registered zone IDs");
                return;
            }
            switch (args[0].ToLower())
            {
                case "add":
                    object success = ZoneManager?.Call("CheckZoneID", args[1]);
                    if (success != null)
                    {
                        storedData.zoneIds.Add(args[1]);
                        GetZoneInfo(args[1]);
                        SaveData();
                        SendReply(player, "You have successfully added this zone to the zone list");
                        return;
                    }
                    else SendReply(player, "That is a invalid Zone ID");
                    return;
                case "remove":
                    if (storedData.zoneIds.Contains(args[1]))
                    {
                        if (dropZones.ContainsKey(args[1]))
                            dropZones.Remove(args[1]);
                        storedData.zoneIds.Remove(args[1]);
                        SaveData();
                        SendReply(player, "You have successfully removed this zone from the zone list");
                        return;
                        
                    }
                    else SendReply(player, "The specified zone ID is not in the list of registered zones");
                    return;
                default:
                    break;
            }
        }
        [ConsoleCommand("dropzone")]
        void ccmdDropZone(ConsoleSystem.Arg arg)
        {
            if (arg.Connection != null) return;
            if (!ZoneManager)
            {
                SendReply(arg, "ZoneManager is not installed! Unable to register zones for item drops");
                return;
            }
            if (arg.Args.Length == 1 && arg.Args[0].ToLower() == "list")
            {
                string zoneList = "--- Registered Zone IDs ---";
                foreach (var zoneId in storedData.zoneIds)
                    zoneList += $"\n{zoneId}";
                SendReply(arg, zoneList);
                return;
            }
            if (arg.Args.Length != 2)
            {
                SendReply(arg, $"{Title}  v.{Version} -- Registered Zones");
                SendReply(arg, "dropzone add <zoneid> - Adds the zone ID to the list zones");
                SendReply(arg, "dropzone remove <zoneid> - Removes the zone ID from the list of zones");
                SendReply(arg, "dropzone list - List all registered zone IDs");
                return;
            }
            switch (arg.Args[0].ToLower())
            {
                case "add":
                    object success = ZoneManager?.Call("CheckZoneID", arg.Args[1]);
                    if (success != null)
                    {
                        storedData.zoneIds.Add(arg.Args[1]);
                        GetZoneInfo(arg.Args[1]);
                        SaveData();
                        SendReply(arg, "You have successfully added this zone to the zone list");
                        return;
                    }
                    else SendReply(arg, "That is a invalid Zone ID");
                    return;
                case "remove":
                    if (storedData.zoneIds.Contains(arg.Args[1]))
                    {
                        if (dropZones.ContainsKey(arg.Args[1]))
                            dropZones.Remove(arg.Args[1]);
                        storedData.zoneIds.Remove(arg.Args[1]);
                        SaveData();
                        SendReply(arg, "You have successfully removed this zone from the zone list");
                        return;

                    }
                    else SendReply(arg, "The specified zone ID is not in the list of registered zones");
                    return;
                default:
                    break;
            }
        }
        #endregion

        #region Config      
        private ConfigData configData;
        class ConfigData
        {
            public bool AllowContactPickup { get; set; }
            public bool AllowInZonesOnly { get; set; }
            public float RotationSpeed { get; set; }
            public float ColliderTriggerRadius { get; set; }
            public int TimeBeforeRotation { get; set; }
            public Dictionary<ItemCategory, bool> TypesToRotate { get; set; }
        }
        private void LoadVariables()
        {
            LoadConfigVariables();
            SaveConfig();
        }
        protected override void LoadDefaultConfig()
        {
            var config = new ConfigData
            {
                AllowContactPickup = true,
                AllowInZonesOnly = true,
                ColliderTriggerRadius = 0.5f,
                RotationSpeed = 5f,
                TimeBeforeRotation = 1,
                TypesToRotate = new Dictionary<ItemCategory, bool>
                {
                    {ItemCategory.Ammunition, true },
                    {ItemCategory.Attire, true },
                    {ItemCategory.Component, false },
                    {ItemCategory.Construction, false },
                    {ItemCategory.Food, true },
                    {ItemCategory.Items, false },
                    {ItemCategory.Medical, true },
                    {ItemCategory.Misc, false },
                    {ItemCategory.Resources, true },
                    {ItemCategory.Tool, true },
                    {ItemCategory.Traps, false },
                    {ItemCategory.Weapon, true },
                    {ItemCategory.Common, false }
                }
            };
            SaveConfig(config);
        }
        private void LoadConfigVariables() => configData = Config.ReadObject<ConfigData>();
        void SaveConfig(ConfigData config) => Config.WriteObject(config, true);
        #endregion

        #region Data Management
        void SaveData() => data.WriteObject(storedData);
        void LoadData()
        {
            try
            {
                storedData = data.ReadObject<StoredData>();
            }
            catch
            {
                storedData = new StoredData();
            }
        }
        class StoredData
        {
            public List<string> zoneIds = new List<string>();
        }
        #endregion

        Dictionary<string, int> rotateList = new Dictionary<string, int>
        {
            { "knife.bone", 270 },
            { "rifle.ak", 90 },
            { "smg.2", 270 },
            { "shotgun.double", 90 },
            { "spear.wooden", 270 },
            { "spear.stone", 270 },
            { "smg.thompson", 270 },
            { "shotgun.waterpipe", 90 },
            { "building.planner", 270 },
            { "map", 270 },
            { "mask.bandana", 270 },
            { "hat.beenie", 270 },
            { "coffeecan.helmet", 270 },
            { "hammer.salvaged", 270 },
            { "axe.salvaged", 270 },
        };
    }
}

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