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

FREE RockBlock : 1.1.4 1.1.4

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

namespace Oxide.Plugins
{
    [Info("Rock Block", "Author Nogrod, Maintainer nivex", "1.1.4")]
    [Description("Blocks players from building in rocks")]
    class RockBlock : RustPlugin
    {
        private ConfigData config;
        private RaycastHit _hit;
        private const string permBypass = "rockblock.bypass";
        private readonly int worldLayer = LayerMask.GetMask("World", "Default");
        private Dictionary<string, string> _displayNames = new Dictionary<string, string>();

        private class ConfigData
        {
            public bool AllowCave { get; set; }
            public bool Logging { get; set; }
            public int MaxHeight { get; set; }
            public bool Kill { get; set; } = true;
        }

        protected override void LoadDefaultConfig()
        {
            config = new ConfigData
            {
                AllowCave = false,
                Logging = true,
                MaxHeight = -1,
                Kill = true
            };
            Config.WriteObject(config, true);
        }

        protected override void LoadDefaultMessages()
        {
            lang.RegisterMessages(new Dictionary<string, string>
            {
                ["DistanceTooHigh"] = "Distance to ground too high: {0}",
                ["PlayerSuspected"] = "{0} is suspected of building {1} inside a rock at {2}!"
            }, this);
        }

        protected override void LoadConfig()
        {
            base.LoadConfig();
            try { config = Config.ReadObject<ConfigData>(); } catch { }
            if (config == null) LoadDefaultConfig();
            Config.WriteObject(config, true);
        }

        private void Init()
        {            
            permission.RegisterPermission(permBypass, this);
            if (!config.Logging) Unsubscribe(nameof(OnServerInitialized));
        }

        private void OnServerInitialized()
        {
            foreach (var def in ItemManager.GetItemDefinitions())
            {
                var imd = def.GetComponent<ItemModDeployable>();
                if (imd == null || _displayNames.ContainsKey(imd.entityPrefab.resourcePath)) continue;
                _displayNames.Add(imd.entityPrefab.resourcePath, def.displayName.english);
            }
        }

        private void OnEntityBuilt(Planner planner, GameObject gameObject)
        {
            BasePlayer player = planner.GetOwnerPlayer();
            if (player == null || permission.UserHasPermission(player.UserIDString, permBypass))
            {
                return;
            }
            
            BaseEntity entity = gameObject.GetComponent<BaseEntity>();

            if (config.MaxHeight > 0)
            {
                RaycastHit hit;
                if (Physics.Raycast(new Ray(entity.transform.position, Vector3.down), out hit, float.PositiveInfinity, Rust.Layers.Terrain))
                {
                    if (hit.distance > config.MaxHeight)
                    {
                        SendReply(player, string.Format(lang.GetMessage("DistanceTooHigh", this, player.UserIDString), hit.distance));
                        entity.Invoke(entity.KillMessage, 0.1f);
                        return;
                    }
                }
            }

            CheckEntity(entity, player);
        }

        private void OnItemDeployed(Deployer deployer, BaseEntity entity)
        {
            BasePlayer player = deployer.GetOwnerPlayer();

            if (player != null && !permission.UserHasPermission(player.UserIDString, permBypass))
            {
                CheckEntity(entity, player);
            }
        }

        private void CheckEntity(BaseEntity entity, BasePlayer player)
        {
            if (entity == null)
            {
                return;
            }

            RaycastHit[] targets = Physics.RaycastAll(new Ray(entity.transform.position + Vector3.up * 200f, Vector3.down), 250, worldLayer);

            foreach (RaycastHit hit in targets)
            {
                if (hit.collider == null || !hit.collider.name.Contains("rock_") || !IsInside(hit.collider, entity) && !IsInCave(entity))
                {
                    continue;
                }

                if (config.Logging)
                {
                    string name;
                    if (!_displayNames.TryGetValue(entity.gameObject.name, out name))
                    {
                        name = entity.ShortPrefabName;
                    }

                    Puts(lang.GetMessage("PlayerSuspected", this), player.displayName, name, entity.transform.position);
                }

                if (config.Kill) entity.Invoke(entity.KillMessage, 0.1f);
                
                break;
            }
        }

        private bool IsInCave(BaseEntity entity)
        {
            if (!config.AllowCave)
            {
                return false;
            }

            RaycastHit[] targets = Physics.RaycastAll(new Ray(entity.transform.position, Vector3.up), 250, worldLayer);

            foreach (RaycastHit hit in targets)
            {
                if (hit.collider.name.Contains("rock_"))
                {
                    return true;
                }
            }

            return false;
        }

        private bool IsInside(Collider collider, BaseEntity entity)
        {
            var center = entity.WorldSpaceBounds().ToBounds().center;
            var rotation = entity.transform.rotation;
            var size = entity.bounds.extents;

            var points = new List<Vector3> // credits ZoneManger/k1lly0u
            {
                RotatePointAroundPivot(new Vector3(center.x + size.x, center.y + size.y, center.z + size.z), center, rotation),
                RotatePointAroundPivot(new Vector3(center.x + size.x, center.y - size.y, center.z + size.z), center, rotation),
                RotatePointAroundPivot(new Vector3(center.x + size.x, center.y + size.y, center.z - size.z), center, rotation),
                RotatePointAroundPivot(new Vector3(center.x + size.x, center.y - size.y, center.z - size.z), center, rotation),
                RotatePointAroundPivot(new Vector3(center.x - size.x, center.y + size.y, center.z + size.z), center, rotation),
                RotatePointAroundPivot(new Vector3(center.x - size.x, center.y - size.y, center.z + size.z), center, rotation),
                RotatePointAroundPivot(new Vector3(center.x - size.x, center.y + size.y, center.z - size.z), center, rotation),
                RotatePointAroundPivot(new Vector3(center.x - size.x, center.y - size.y, center.z - size.z), center, rotation)
            };

            Physics.queriesHitBackfaces = true;

            bool isInside = points.TrueForAll(point => IsInside(point));

            Physics.queriesHitBackfaces = false;

            return isInside;
        }

        private bool IsInside(Vector3 point)
        {
            if (Physics.Raycast(point, Vector3.up, out _hit, 20f, Layers.Mask.World, QueryTriggerInteraction.Ignore) && _hit.collider.name.Contains("rock_"))
            {
                var hits = Physics.RaycastAll(point + new Vector3(0f, 0.1f, 0f), Vector3.down, 50f, Layers.Mask.World | Layers.Mask.Terrain, QueryTriggerInteraction.Ignore);

                if (hits != null && hits.Length > 0)
                {
                    return hits.Last().collider.name.Contains("rock_");
                }

                return true;
            }

            return false;
        }

        private Vector3 RotatePointAroundPivot(Vector3 point, Vector3 pivot, Quaternion rotation) => rotation * (point - pivot) + pivot; // credits ZoneManger/k1lly0u
    }
}

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