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

FREE RotatingPickups : 0.2.2 0.2.2

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

namespace Oxide.Plugins
{
    [Info("RotatingPickups", "ReCoDeX", "0.2.2")]
    class RotatingPickups : RustPlugin
    {
        #region Fields  
        [PluginReference]
        Plugin Arena, ZoneManager;

        static RotatingPickups instance;
        static int[] layerTypes = new int[] { 4, 8, 16, 21, 23, 25, 26 };
        private bool initialized;

        private Dictionary<string, ZoneInfo> dropZones = new Dictionary<string, ZoneInfo>();
        private List<ulong> disabledPickup = new List<ulong>();

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

        #region Components      
        class ItemRotator : MonoBehaviour
        {            
            private BaseEntity entity;
            private Rigidbody rigidBody;
            private bool hasBegun;
            private bool collisionPickup;
            private bool isEventItem;

            private float secsToTake;
            void Awake()
            {
                entity = GetComponent<BaseEntity>();
                enabled = false;
                collisionPickup = instance.configData.CollisionPickup;
            }   
            void OnDestroy()
            {
                CancelInvoke();
                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 (layerTypes.Contains(collision.gameObject.layer) || collision.gameObject.name.Contains("junk_pile"))
                {
                    hasBegun = true;
                    Invoke("BeginRotation", instance.configData.RotateIn);
                }
            }
            void OnTriggerEnter(Collider col)
            {
                if (!collisionPickup) return;
                if (col?.gameObject?.layer != 17) return;
                var player = col.GetComponentInParent<BasePlayer>();
                if (player != null)
                {
                    if (!isEventItem && instance.disabledPickup.Contains(player.userID)) return;
                    if (instance.Arena && (bool)instance.Arena.Call("IsPlayerDead", player)) return;

                    if (entity is WorldItem)
                    {
                        Item item = (entity as WorldItem).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);
                            }
                        }
                    }
                    if (entity is DroppedItemContainer && instance.configData.CollisionPickupContainer)
                    {
                        instance.PickupContainer(player, entity as DroppedItemContainer);
                    }
                }
            } 
            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.TriggerRadius;

                string shortname = entity is DroppedItemContainer ? entity.ShortPrefabName : (entity as WorldItem).item.info.shortname;
                secsToTake = instance.configData.Speed;

                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;
                if (instance.configData.MonitorHeight)
                    InvokeRepeating("CheckHeight", 3f, 3f);
            }  
            private void CheckHeight()
            {
                RaycastHit hit;
                if (Physics.Raycast(new Ray(entity.transform.position, Vector3.down), out hit, 100f, LayerMask.GetMask("Terrain", "Construction", "Deployed", "Water", "Debris", "World")))
                {
                    var point = hit.point;
                    if (Vector3.Distance(point, entity.transform.position) > 1)
                    {
                        Vector3 adjustment = Vector3.up;
                        if (entity is WorldItem)
                        {
                            if ((entity as WorldItem).item.info.shortname.Contains("spear"))
                                adjustment = Vector3.up * 2;
                        }
                        entity.transform.position = point + adjustment;
                    }
                }
            }
            public void SetEventItem()
            {
                collisionPickup = true;
                isEventItem = true;
            }      
        }
        class ZoneInfo
        {
            public Vector3 Position;
            public float Radius;
            public bool IsBox;
            public Vector3 Size;
            public Vector3 Rotation;
        }
        #endregion

        #region Oxide Hooks   
        void Loaded()
        {
            permission.RegisterPermission("rotatingpickups.zones", this);
            lang.RegisterMessages(Messages, this);
        }    
        void OnServerInitialized()
        {
            initialized = true;
            instance = this;
            LoadVariables();

            if (configData.ZonesOnly)
                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.ActiveTypes.ContainsKey(item.info.category) && configData.ActiveTypes[item.info.category]) || configData.Overrides.Contains(item.info.shortname))
                    {
                        NextTick(() =>
                            {
                                if (worldItem != null)
                                    worldItem.gameObject.AddComponent<ItemRotator>();
                            });
                    }
                }
            }
            DroppedItemContainer itemContainer = entity.GetComponent<DroppedItemContainer>();
            if (itemContainer != null && configData.UseDroppedContainer)
            {
                if (!IsInZone(itemContainer)) return;
                NextTick(() =>
                {
                    if (itemContainer != null)
                        itemContainer.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 configData.Zones)            
                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(BaseEntity entity)
        {
            if (!configData.ZonesOnly) 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 target = colBuffer[i].GetComponentInParent<BaseEntity>();
                        colBuffer[i] = null;
                        if (target != null)                        
                            if (target == entity) return true;   
                    }
                }
            }           
            return false;
        }
        void PickupContainer(BasePlayer player, DroppedItemContainer source)
        {
            ItemContainer inventory = source.inventory;
            if (inventory != null)
            {                
                while(inventory.itemList.Count > 0)
                {
                    Item item = inventory.itemList[0];
                    if (!item.MoveToContainer(player.inventory.containerMain))                   
                        item.Drop(source.transform.position, Vector3.up);  
                    else player.Command("note.inv", new object[] { item.info.itemid, item.amount });
                }               
                source.Kill(BaseNetworkable.DestroyMode.None);
            }
        }
        void AddItemRotator(WorldItem worldItem)
        {
            NextTick(() =>
            {
                if (worldItem != null && !worldItem.GetComponent<ItemRotator>())
                {
                    ItemRotator rotator = worldItem.gameObject.AddComponent<ItemRotator>();
                    rotator.SetEventItem();
                }
            });
        }
        #endregion

        #region Commands
        [ChatCommand("ap")]
        void cmdAutoPickup(BasePlayer player, string command, string[] args)
        {
            if (!configData.CollisionPickup) return;

            if (disabledPickup.Contains(player.userID))
            {
                disabledPickup.Remove(player.userID);
                SendReply(player, msg("apEnabled", player.UserIDString));
            }
            else
            {
                disabledPickup.Add(player.userID);
                SendReply(player, msg("apDisabled", player.UserIDString));
            }
        }

        [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 set drop zones.");
                return;
            }
            if (args.Length == 1 && args[0].ToLower() == "list")
            {
                string zoneList = "--- Лист Ид зон ---";
                foreach (var zoneId in configData.Zones)
                    zoneList += $"\n{zoneId}";
                SendReply(player, zoneList);
                return;
            }
            if (args.Length != 2)
            {
                SendReply(player, $"{Title}  v.{Version} -- Registered Zones");
                SendReply(player, "/dropzone add <zoneid> - Add zone id to zone list");
                SendReply(player, "/dropzone remove <zoneid> - Remove zone id from zone list");
                SendReply(player, "/dropzone list - List of all registered zones");
                return;
            }
            switch (args[0].ToLower())
            {
                case "add":
                    object success = ZoneManager?.Call("CheckZoneID", args[1]);
                    if (success != null)
                    {
                        configData.Zones.Add(args[1]);
                        GetZoneInfo(args[1]);
                        SaveConfig(configData);
                        SendReply(player, "You have successfully added this zone to the zone list..");
                        return;
                    }
                    else SendReply(player, "This is wrong zone id");
                    return;
                case "remove":
                    if (configData.Zones.Contains(args[1]))
                    {
                        if (dropZones.ContainsKey(args[1]))
                            dropZones.Remove(args[1]);
                        configData.Zones.Remove(args[1]);
                        SaveConfig(configData);
                        SendReply(player, "You have successfully removed this zone from the zone list..");
                        return;
                        
                    }
                    else SendReply(player, "The specified zone id was not found in the zone list");
                    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 set drop zones.");
                return;
            }
            if (arg.Args.Length == 1 && arg.Args[0].ToLower() == "list")
            {
                string zoneList = "--- Zones ---";
                foreach (var zoneId in configData.Zones)
                    zoneList += $"\n{zoneId}";
                SendReply(arg, zoneList);
                return;
            }
            if (arg.Args.Length != 2)
            {
                SendReply(arg, $"{Title}  v.{Version} -- Registered Zones");
                SendReply(arg, "dropzone add <zoneid> - Add zone id to zone list");
                SendReply(arg, "dropzone remove <zoneid> - Remove zone id from zone list");
                SendReply(arg, "dropzone list - List of all registered zones");
                return;
            }
            switch (arg.Args[0].ToLower())
            {
                case "add":
                    object success = ZoneManager?.Call("CheckZoneID", arg.Args[1]);
                    if (success != null)
                    {
                        configData.Zones.Add(arg.Args[1]);
                        GetZoneInfo(arg.Args[1]);
                        SaveConfig(configData);
                        SendReply(arg, "You have successfully added this zone to the zone list.");
                        return;
                    }
                    else SendReply(arg, "This is wrong zone id");
                    return;
                case "remove":
                    if (configData.Zones.Contains(arg.Args[1]))
                    {
                        if (dropZones.ContainsKey(arg.Args[1]))
                            dropZones.Remove(arg.Args[1]);
                        configData.Zones.Remove(arg.Args[1]);
                        SaveConfig(configData);
                        SendReply(arg, "You have successfully removed this zone from the zone list.");
                        return;

                    }
                    else SendReply(arg, "The specified zone id was not found in the zone list");
                    return;
                default:
                    break;
            }
        }
        #endregion

        #region Config      
        private ConfigData configData;
        class ConfigData
        {
            [JsonProperty(PropertyName = "Allow collision pickup of items")]
            public bool CollisionPickup { get; set; }
            [JsonProperty(PropertyName = "Allow collision pickup of dropped item containers")]
            public bool CollisionPickupContainer { get; set; }
            [JsonProperty(PropertyName = "Rotate dropped item containers")]
            public bool UseDroppedContainer { get; set; }
            [JsonProperty(PropertyName = "Apply rotation in set zones only")]
            public bool ZonesOnly { get; set; }
            [JsonProperty(PropertyName = "Monitor height changes")]
            public bool MonitorHeight { get; set; }
            [JsonProperty(PropertyName = "Rotation speed")]
            public float Speed { get; set; }
            [JsonProperty(PropertyName = "Collision detection radius")]
            public float TriggerRadius { get; set; }
            [JsonProperty(PropertyName = "Time before rotation starts (seconds)")]
            public int RotateIn { get; set; }
            [JsonProperty(PropertyName = "Item types to rotate")]
            public Dictionary<ItemCategory, bool> ActiveTypes { get; set; }
            [JsonProperty(PropertyName = "Overrides - Items to rotate (ignores types)")]
            public List<string> Overrides { get; set; }
            [JsonProperty(PropertyName = "Zone IDs used for zone only rotation")]
            public List<string> Zones { get; set; }
        }
        private void LoadVariables()
        {
            LoadConfigVariables();
            SaveConfig();
        }
        protected override void LoadDefaultConfig()
        {
            var config = new ConfigData
            {
                CollisionPickup = true,
                CollisionPickupContainer = true,
                ZonesOnly = false,
                TriggerRadius = 0.5f,
                MonitorHeight = true,
                Speed = 5f,
                UseDroppedContainer = true,
                RotateIn = 1,
                ActiveTypes = 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 }
                },
                Overrides = new List<string>(),
                Zones = new List<string>()
            };
            SaveConfig(config);
        }
        private void LoadConfigVariables() => configData = Config.ReadObject<ConfigData>();
        void SaveConfig(ConfigData config) => Config.WriteObject(config, true);
        #endregion
                
        #region Localization
        string msg(string key, string playerId = null) => lang.GetMessage(key, this, playerId);

        Dictionary<string, string> Messages = new Dictionary<string, string>
        {
            ["apDisabled"] = "Auto-pickup is disabled.",
            ["apEnabled"] = "Auto-pickup enabled."
        };
        #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 оценок

Другие ресурсы пользователя 15FPS

Сверху