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

FREE FixBlock : 1.0.1 1.0.1

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

namespace Oxide.Plugins
{
    [Info("FixBlock", "Night[EXE]", "1.0.1")]
    class FixBlock : RustPlugin
    {
        int waterLevel = 10;
        int maxHeight = 25;
        bool caveBuild = true;
        bool roadRestrict = true;
        bool adminIgnore = false;
        float treeRadius = 2f;
        
        private void LoadDefaultConfig()
        {
            GetConfig("Основные настройки", "Запрещать строительство глубже n метров", ref waterLevel);
            GetConfig("Основные настройки", "Запрещать строительство выше n метров", ref maxHeight);
            GetConfig("Основные настройки", "Разрешить строительство в пещерах", ref caveBuild);
            GetConfig("Основные настройки", "Запрещать строительство на дорогах", ref roadRestrict);
            
            GetConfig("Основные настройки", "Игнорировать админов", ref adminIgnore);
            GetConfig("Основные настройки", "Минимальный радиус от дерева", ref treeRadius);
            SaveConfig();
        }


        private void GetConfig<T>(string MainMenu, string Key, ref T var)
        {
            if (Config[MainMenu, Key] != null)
            {
                var = (T)Convert.ChangeType(Config[MainMenu, Key], typeof(T));
            }
            Config[MainMenu, Key] = var;
        }
        
        private int worldLayer = LayerMask.GetMask("World", "Default", "Terrain");

        private void OnEntityBuilt(Planner planner, GameObject gameObject)
        {
            if (planner == null || gameObject == null) return;
            BasePlayer player = planner.GetOwnerPlayer();
            if (player.IsAdmin && adminIgnore) return;
            if (player == null) return;
            
            int MaxHeight = -1;
            RaycastHit hitInfo;
            BaseEntity entity = gameObject.GetComponent<BaseEntity>();
            if (MaxHeight > 0 && Physics.Raycast(new Ray(entity.transform.position, Vector3.down), out hitInfo, float.PositiveInfinity, Rust.Layers.Terrain))
            {
                if (hitInfo.distance > MaxHeight)
                {
                    Refund(player, entity);
                    SendReply(player, "<color=#483D8B>[УВЕДОМЛЕНИЕ]:</color> Строение запрещенно!\nВаши ресурсы были возращенны!");
                    entity.Kill();
                    return;
                }
            }

            Vector3 pos = entity.GetNetworkPosition();
            if (roadRestrict)
            {
                RaycastHit hit;
                if (Physics.Raycast(pos , Vector3.down, out hit,  worldLayer))
                {
                    if (hit.transform.name == "Road Mesh")
                    {
                        Refund(player, entity);
                        SendReply(player, "<color=#483D8B>[УВЕДОМЛЕНИЕ]:</color> Строительство на дорогах запрещено!\nВаши ресурсы были возращенны!");
                        entity.Kill();
                        return;
                    }
                }
            }
            
            if (pos.y < -waterLevel) if (caveBuild) return; else
            {
                Refund(player, entity);
                SendReply(player,"<color=#483D8B>[УВЕДОМЛЕНИЕ]:</color> Строительство глубже {0} метров запрещено!\nВаши ресурсы были возращенны!", waterLevel);
                entity.Kill(); 
                return; 
            }
            
            if (TerrainMeta.WaterMap.GetHeight(pos) - pos.y > waterLevel)
            {
                Refund(player, entity);
                SendReply(player,"<color=#483D8B>[УВЕДОМЛЕНИЕ]:</color> Строительство глубже {0} метров запрещено!\nВаши ресурсы были возращенны!", waterLevel);
                entity.Kill();
                return;
            }
            
            if (pos.y - TerrainMeta.HeightMap.GetHeight(pos) > maxHeight)
            {
                Refund(player, entity);
                SendReply(player, "<color=#483D8B>[УВЕДОМЛЕНИЕ]:</color> Строительство выше {0} метров запрещено!\nВаши ресурсы были возращенны!", maxHeight);
                entity.Kill();
                return;
            }
            
            if (treeRadius > 0 && entity.ShortPrefabName.Contains("foundation"))
            {
                List<TreeEntity> treeList = new List<TreeEntity>();
                Vis.Entities(pos, treeRadius, treeList, LayerMask.GetMask("Tree"), QueryTriggerInteraction.Ignore);
                if (treeList.Count > 0)
                {
                    SendReply(player, "<color=#483D8B>[УВЕДОМЛЕНИЕ]:</color> Строительство рядом с деревьями в радиусе {0}м. запрещено!\nВаши ресурсы были возращенны!", (int)treeRadius);
                    Refund(player, entity);
                    entity.Kill();
                    return;
                }
            }
            
            CheckEntity(entity, player);
        }

        private void OnItemDeployed(Deployer deployer, BaseEntity entity)
        {
            BasePlayer player = deployer.GetOwnerPlayer();
            if (player != null)
            {
                CheckEntity(entity, player);
            }
        }

        private void CheckEntity(BaseEntity entity, BasePlayer player)
        {
            if (entity != null)
            {
                RaycastHit[] targets = Physics.RaycastAll(new Ray(entity.transform.position + Vector3.up * 200f, Vector3.down), 250, worldLayer);
                foreach (RaycastHit hit in targets)
                {
                    MeshCollider collider = hit.collider.GetComponent<MeshCollider>();
                    if (collider == null || !collider.sharedMesh.name.StartsWith("rock_") || !IsInside(hit.collider, entity) && (false|| !IsInCave(entity))) continue;
                    Refund(player, entity);
                    SendReply(player, "<color=#483D8B>[УВЕДОМЛЕНИЕ]:</color> Строение запрещенно!\nВаши ресурсы были возращенны!");
                    entity.Kill();
                    break;
                }
            }
        }

        private bool IsInCave(BaseEntity entity)
        {
            RaycastHit[] targets = Physics.RaycastAll(new Ray(entity.transform.position, Vector3.up), 250, worldLayer);
            foreach (RaycastHit hit in targets)
            {
                if (hit.collider.name.StartsWith("rock_")) return true;
            }
            return false;
        }

        private static bool IsInside(Collider collider, BaseEntity entity)
        {
            Vector3 point = entity.WorldSpaceBounds().ToBounds().max;
            Vector3 center = collider.bounds.center;
            Vector3 direction = center - point;
            Ray ray = new Ray(point, direction);
            RaycastHit hitInfo;
            return !collider.Raycast(ray, out hitInfo, direction.magnitude + 1);
        }
        
        void Refund(BasePlayer player, BaseEntity entity)
        {
            RefundHelper.Refund(player, entity);
        }
        
        public static class RefundHelper
        {
            private static Dictionary<uint, Dictionary<ItemDefinition, int>> refundItems =
                new Dictionary<uint, Dictionary<ItemDefinition, int>>();

            public static void Refund(BasePlayer player, BaseEntity entity, float percent = 1)
            {
                StorageContainer storage = entity as StorageContainer;
                if (storage)
                {
                    for (int i = storage.inventory.itemList.Count - 1; i >= 0; i--)
                    {
                        var item = storage.inventory.itemList[i];
                        if (item == null) continue;
                        item.amount = (int)(item.amount * percent);
                        float single = 20f;
                        Vector3 vector32 = Quaternion.Euler(UnityEngine.Random.Range(-single * 0.5f, single * 0.5f), UnityEngine.Random.Range(-single * 0.5f, single * 0.5f), UnityEngine.Random.Range(-single * 0.5f, single * 0.5f)) * Vector3.up;
                        BaseEntity baseEntity = item.Drop(storage.transform.position + (Vector3.up * 1f), vector32 * UnityEngine.Random.Range(5f, 10f), UnityEngine.Random.rotation);
                        baseEntity.SetAngularVelocity(UnityEngine.Random.rotation.eulerAngles * 5f);
                    }
                }

                BuildingBlock block = entity as BuildingBlock;
                if (block != null)
                {
                    try
                    {
                        if (block.currentGrade == null) return;
                        foreach (var item in block.currentGrade.costToBuild)
                        {
                            var amount = (int)(item.amount * (Mathf.Approximately(percent, -1) ? 0.5f : percent));
                            if (amount < 1) amount = 1;
                            player.GiveItem(ItemManager.Create(item.itemDef, amount, 0));
                        }

                    }
                    catch
                    {

                    }
                    return;
                }

                Dictionary<ItemDefinition, int> items;
                if (refundItems.TryGetValue(entity.prefabID, out items))
                {
                    foreach (var item in items)
                        if (item.Value > 0)
                            player.GiveItem(ItemManager.Create(item.Key, (int)(item.Value)));
                }
            }

            private static void InitRefundItems()
            {
                foreach (var item in ItemManager.itemList)
                {
                    var deployable = item.GetComponent<ItemModDeployable>();
                    if (deployable != null)
                    {
                        if (item.Blueprint == null || deployable.entityPrefab == null) continue;
                        
                        refundItems.Add(deployable.entityPrefab.resourceID, item.Blueprint.ingredients.ToDictionary(p => p.itemDef, p => ((int)p.amount)));
                    }
                }
            }
        }
    }
}

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