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

FREE GChill : 1.8.1 1.8.1

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

namespace Oxide.Plugins
{
    [Info("GChill", "h1pex", "1.8.1")]
    [Description("Beach chair that perfectly matches player's Y-axis rotation")]
    class GChill : RustPlugin
    {
        private Dictionary<ulong, BaseEntity> playerChairs = new Dictionary<ulong, BaseEntity>();
        private Dictionary<ulong, float> lastRotationChecks = new Dictionary<ulong, float>();
        private Dictionary<BuildingPrivlidge, ulong> tcPlacedBy = new Dictionary<BuildingPrivlidge, ulong>();
        private Dictionary<ulong, float> lastSecurityChecks = new Dictionary<ulong, float>();
        
        private const float ROTATION_SPEED = 6.5f;
        private const float VIEW_THRESHOLD = 35f;
        private const float LERP_SPEED = 0.15f;
        private const float ROTATION_CHECK_INTERVAL = 0.033f;
        private const float SECURITY_CHECK_INTERVAL = 0.5f;

        void Init()
        {
            playerChairs.Clear();
            tcPlacedBy.Clear();
            lastRotationChecks.Clear();
            lastSecurityChecks.Clear();
            
            permission.RegisterPermission("gchill.use", this);
            timer.Every(SECURITY_CHECK_INTERVAL, CheckAllPlayerChairs);
            Subscribe("OnEntityBuilt");
        }

        void OnPlayerDisconnected(BasePlayer player) => CleanupChair(player?.userID ?? 0);
        void OnPlayerDie(BasePlayer player) => CleanupChair(player?.userID ?? 0);

        // Заменяем OnFrame на более эффективный таймер
        void OnTick()
        {
            float currentTime = Time.realtimeSinceStartup;

            foreach (var kvp in new Dictionary<ulong, BaseEntity>(playerChairs))
            {
                var playerId = kvp.Key;
                var chair = kvp.Value;

                // Проверяем время последней проверки поворота
                if (!lastRotationChecks.TryGetValue(playerId, out float lastCheck) || 
                    (currentTime - lastCheck) >= ROTATION_CHECK_INTERVAL)
                {
                    var player = BasePlayer.FindByID(playerId);
                    if (!IsValidPlayerAndChair(player, chair)) continue;
                    if (!(chair is BaseMountable mountable) || !mountable.IsMounted()) continue;

                    // Проверка безопасности с интервалом
                    if (!lastSecurityChecks.TryGetValue(playerId, out float lastSecurityCheck) || 
                        (currentTime - lastSecurityCheck) >= SECURITY_CHECK_INTERVAL)
                    {
                        if (IsPlayerOnForeignTerritory(player))
                        {
                            SendReply(player, "Вы находитесь на чужой территории.Лежак убран.");
                            DismountAndCleanupChair(playerId);
                            continue;
                        }
                        lastSecurityChecks[playerId] = currentTime;
                    }

                    // Обновляем поворот
                    UpdateChairRotation(player, chair);
                    lastRotationChecks[playerId] = currentTime;
                }
            }
        }

        private void UpdateChairRotation(BasePlayer player, BaseEntity chair)
        {
            float playerViewAngle = player.eyes.rotation.eulerAngles.y;
            float chairAngle = chair.transform.rotation.eulerAngles.y;
            float relativeAngle = Mathf.DeltaAngle(chairAngle, playerViewAngle);

            if (Mathf.Abs(relativeAngle) > VIEW_THRESHOLD)
            {
                float rotationDirection = Mathf.Sign(relativeAngle);
                
                // Убираем зависимость от Time.deltaTime для более стабильной скорости
                float targetRotation = ROTATION_SPEED * rotationDirection;
                
                // Применяем более прямой расчет нового угла
                float newAngle = Mathf.LerpAngle(chairAngle, playerViewAngle, LERP_SPEED);
                
                // Ограничиваем максимальное изменение угла за одно обновление
                float maxDelta = ROTATION_SPEED;
                float actualDelta = Mathf.DeltaAngle(chairAngle, newAngle);
                if (Mathf.Abs(actualDelta) > maxDelta)
                {
                    newAngle = chairAngle + (maxDelta * Mathf.Sign(actualDelta));
                }

                chair.transform.rotation = Quaternion.Euler(0f, newAngle, 0f);
                chair.TransformChanged();
                chair.SendNetworkUpdate();
            }
        }

        // Оптимизированная проверка территории
        private bool IsPlayerOnForeignTerritory(BasePlayer player)
        {
            if (player == null) return true;

            // Кэшируем результат проверки TC
            var nearestPrivilege = GetNearestBuildingPrivilege(player.transform.position);
            if (nearestPrivilege != null)
            {
                if (!nearestPrivilege.IsAuthed(player))
                {
                    // Проверяем, установил ли игрок этот TC
                    if (tcPlacedBy.TryGetValue(nearestPrivilege, out ulong placerId) && placerId != player.userID)
                    {
                        return true;
                    }
                }
            }

            // Проверка постройки под ногами
            RaycastHit hit;
            if (Physics.Raycast(player.transform.position + Vector3.up * 0.1f, Vector3.down, out hit, 3f, 
                LayerMask.GetMask("Construction", "Deployed")))
            {
                BaseEntity entity = hit.GetEntity();
                if (entity != null && entity.OwnerID != 0 && entity.OwnerID != player.userID)
                {
                    if (!AreInSameTeam(player.userID, entity.OwnerID))
                    {
                        return true;
                    }
                }
            }

            return false;
        }

        // Кэширующий метод получения ближайшего TC
        private BuildingPrivlidge GetNearestBuildingPrivilege(Vector3 position)
        {
            BuildingPrivlidge nearest = null;
            float nearestDistance = float.MaxValue;

            var privileges = UnityEngine.Object.FindObjectsOfType<BuildingPrivlidge>();
            foreach (var privilege in privileges)
            {
                if (privilege == null || privilege.IsDestroyed) continue;

                float distance = Vector3.Distance(position, privilege.transform.position);
                if (distance <= 30f && distance < nearestDistance)
                {
                    nearest = privilege;
                    nearestDistance = distance;
                }
            }

            return nearest;
        }

        // Новый метод для проверки всех активных лежаков
        private void CheckAllPlayerChairs()
        {
            // Копируем словарь для безопасного перебора
            foreach (var kvp in new Dictionary<ulong, BaseEntity>(playerChairs))
            {
                var playerId = kvp.Key;
                var chair = kvp.Value;
                var player = BasePlayer.FindByID(playerId);
                
                if (player == null || chair == null || chair.IsDestroyed) 
                {
                    CleanupChair(playerId);
                    continue;
                }
                
                // Проверяем нахождение на чужой территории
                if (IsPlayerOnForeignTerritory(player))
                {
                    // Принудительно убираем лежак
                    DismountAndCleanupChair(playerId);
                    SendReply(player, "Серверная проверка: вы находитесь на чужой территории.Лежак убран.");
                }
            }
        }

        // Отслеживаем установку шкафов
        void OnEntityBuilt(Planner plan, GameObject gameObject)
        {
            if (plan == null || gameObject == null) return;
            
            BasePlayer player = plan.GetOwnerPlayer();
            if (player == null) return;
            
            BaseEntity entity = gameObject.GetComponent<BaseEntity>();
            if (entity == null) return;
            
            // Если был установлен TC, записываем кто его установил
            if (entity is BuildingPrivlidge)
            {
                BuildingPrivlidge tc = entity as BuildingPrivlidge;
                tcPlacedBy[tc] = player.userID;
                
                // Сохраняем данные в хранилище для восстановления после перезагрузки сервера
                SaveTCData();
            }
        }
        
        // Сохраняем данные о TC в хранилище
        private void SaveTCData()
        {
            var data = new Dictionary<string, ulong>();
            foreach (var kvp in tcPlacedBy)
            {
                if (kvp.Key != null && !kvp.Key.IsDestroyed)
                {
                    // Используем сетевой ID TC как ключ
                    data[kvp.Key.net.ID.ToString()] = kvp.Value;
                }
            }
            
            // Сохраняем данные
            Interface.Oxide.DataFileSystem.WriteObject("GChill_TCData", data);
        }
        
        // Загружаем данные о TC при загрузке плагина
        void LoadTCData()
        {
            var data = Interface.Oxide.DataFileSystem.ReadObject<Dictionary<string, ulong>>("GChill_TCData");
            if (data == null) return;
            
            // Очищаем текущие данные
            tcPlacedBy.Clear();
            
            // Загружаем данные из хранилища
            foreach (var kvp in data)
            {
                try
                {
                    uint netID;
                    if (uint.TryParse(kvp.Key, out netID))
                    {
                        // Находим TC по его сетевому ID используя правильный класс
                        BaseNetworkable entity = null;
                        
                        // Пробуем найти напрямую по ID
                        foreach (var netEntity in BaseNetworkable.serverEntities)
                        {
                            if (netEntity.net.ID.Value == netID)
                            {
                                entity = netEntity;
                                break;
                            }
                        }
                        
                        if (entity != null && entity is BuildingPrivlidge)
                        {
                            tcPlacedBy[entity as BuildingPrivlidge] = kvp.Value;
                        }
                    }
                }
                catch {}
            }
        }
        
        // Загружаем данные при загрузке плагина
        void OnServerInitialized()
        {
            LoadTCData();
        }
        
        // Сохраняем данные при выгрузке плагина
        void Unload()
        {
            SaveTCData();
        }

        // Проверка на членство в команде
        private bool AreInSameTeam(ulong playerID, ulong otherID)
        {
            if (playerID == otherID) return true;
            
            BasePlayer player = BasePlayer.FindByID(playerID);
            if (player == null) return false;
            
            RelationshipManager.PlayerTeam team = RelationshipManager.ServerInstance.FindPlayersTeam(playerID);
            if (team == null) return false;
            
            return team.members.Contains(otherID);
        }

        // Заменяем старый метод проверки позиции на новый
        private bool IsPositionSafe(Vector3 position, ulong playerID)
        {
            BasePlayer player = BasePlayer.FindByID(playerID);
            if (player == null) return false;
            
            // Временно перемещаем игрока на проверяемую позицию (только для проверки)
            Vector3 originalPosition = player.transform.position;
            player.transform.position = position;
            
            bool result = !IsPlayerOnForeignTerritory(player);
            
            // Возвращаем игрока на исходную позицию
            player.transform.position = originalPosition;
            
            return result;
        }

        // Заменяем старый метод проверки на новый
        private bool IsSafeToPlaceChair(BasePlayer player)
        {
            if (player == null) return false;
            return !IsPlayerOnForeignTerritory(player);
        }

        // Метод для принудительного снятия игрока с лежака и удаления
        private void DismountAndCleanupChair(ulong userId)
        {
            if (playerChairs.TryGetValue(userId, out var chair))
            {
                if (chair != null && !chair.IsDestroyed)
                {
                    var mountable = chair as BaseMountable;
                    if (mountable != null && mountable.IsMounted())
                    {
                        // Снимаем игрока
                        var player = BasePlayer.FindByID(userId);
                        if (player != null)
                        {
                            mountable.DismountPlayer(player);
                        }
                    }
                    
                    // Убиваем стул
                    chair.Kill();
                }
                playerChairs.Remove(userId);
            }
        }

        // Защита игрока на стуле от получения урона
        object OnEntityTakeDamage(BaseCombatEntity entity, HitInfo info)
        {
            if (entity == null || info == null) return null;

            // Проверяем, является ли цель игроком на стуле
            var targetPlayer = entity as BasePlayer;
            if (targetPlayer != null && playerChairs.ContainsKey(targetPlayer.userID))
            {
                var chair = playerChairs[targetPlayer.userID];
                if (chair != null && !chair.IsDestroyed && (chair as BaseMountable)?.IsMounted() == true)
                {
                    // Отменяем урон
                    return true;
                }
            }

            // Проверяем, является ли атакующий игроком на стуле
            var attackerPlayer = info.InitiatorPlayer;
            if (attackerPlayer != null && playerChairs.ContainsKey(attackerPlayer.userID))
            {
                var chair = playerChairs[attackerPlayer.userID];
                if (chair != null && !chair.IsDestroyed && (chair as BaseMountable)?.IsMounted() == true)
                {
                    // Отменяем урон от игрока на стуле
                    return true;
                }
            }

            return null;
        }

        // Предотвращение нанесения урона игроком на стуле
        object OnWeaponAttack(BaseProjectile projectile, HitInfo info)
        {
            if (projectile == null || info == null) return null;

            // Проверяем, является ли стреляющий игроком на стуле
            var attackerPlayer = info.InitiatorPlayer;
            if (attackerPlayer != null && playerChairs.ContainsKey(attackerPlayer.userID))
            {
                var chair = playerChairs[attackerPlayer.userID];
                if (chair != null && !chair.IsDestroyed && (chair as BaseMountable)?.IsMounted() == true)
                {
                    // Отменяем выстрел
                    return true;
                }
            }

            return null;
        }

        [ChatCommand("gc")]
        void cmdGChill(BasePlayer player, string command, string[] args)
        {
            if (player == null) return;

            // Проверяем нахождение на чужой территории
            if (IsPlayerOnForeignTerritory(player))
            {
                SendReply(player, "Вы не можете использовать лежак на чужой территории!");
                return;
            }

            if (!permission.UserHasPermission(player.UserIDString, "gchill.use"))
            {
                SendReply(player, "У вас нет разрешения на использование этой команды!");
                return;
            }

            // Проверка и очистка старых лежаков
            if (playerChairs.TryGetValue(player.userID, out var existingChair))
            {
                if (existingChair != null && !existingChair.IsDestroyed)
                {
                    SendReply(player, "У вас уже есть лежак!");
                    return;
                }
                playerChairs.Remove(player.userID);
            }

            // Получаем чистый Y-ротационный вектор игрока
            Quaternion playerRotation = Quaternion.Euler(0, player.transform.eulerAngles.y, 0);
            
            // Создаем лежак
            CreateChairForPlayer(player, playerRotation);
        }

        void CreateChairForPlayer(BasePlayer player, Quaternion rotation)
        {
            // Проверяем нахождение на чужой территории
            if (IsPlayerOnForeignTerritory(player))
            {
                SendReply(player, "Вы не можете использовать лежак на чужой территории!");
                return;
            }

            // УПРОЩЕННОЕ РАЗМЕЩЕНИЕ - без сложных проверок коллизий
            Vector3 chairPosition = Vector3.zero; // Инициализируем переменную
            RaycastHit hit;
            
            // Выполняем рейкаст чтобы проверить препятствия впереди игрока
            bool hasObstacle = Physics.Raycast(player.eyes.position, player.eyes.HeadForward(), out hit, 3f, LayerMask.GetMask("Construction", "World", "Deployed"));
            
            if (hasObstacle)
            {
                // Если на пути есть препятствие, проверяем расстояние до него
                float distToObstacle = Vector3.Distance(player.eyes.position, hit.point);
                
                if (distToObstacle < 1.5f)
                {
                    SendReply(player, "Недостаточно места для размещения лежака.Отойдите от препятствия!");
                    return;
                }
                
                // Размещаем лежак перед препятствием
                chairPosition = hit.point - player.eyes.HeadForward() * 0.5f;
                
                // Убеждаемся, что лежак не пройдет сквозь препятствие
                Vector3 finalPos = chairPosition;
                finalPos.y += 0.2f; // Небольшая подстраховка по высоте
                
                // Проверяем, не будет ли стул пересекать стену/препятствие
                Collider[] colliders = Physics.OverlapBox(
                    finalPos,
                    new Vector3(1f, 0.3f, 0.4f), // Половина размеров лежака
                    rotation,
                    LayerMask.GetMask("Construction", "World", "Deployed")
                );
                
                if (colliders.Length > 0)
                {
                    SendReply(player, "Лежак будет пересекать препятствие.Измените позицию!");
                    return;
                }
                
                // Если прошли все проверки, спавним лежак
                SpawnChair(player, chairPosition, player.transform.rotation);
                return;
            }
            else
            {
                // Проверяем, на чем стоит игрок
                bool isOnBuildingOrFoundation = false;
                if (Physics.Raycast(player.transform.position, Vector3.down, out hit, 3f, LayerMask.GetMask("Construction", "World", "Deployed")))
                {
                    BaseEntity entity = hit.GetEntity();
                    if (entity != null)
                    {
                        // Проверяем, является ли это фундаментом или частью постройки
                        BuildingBlock block = entity as BuildingBlock;
                        if (block != null)
                        {
                            // Это фундамент или часть постройки
                            isOnBuildingOrFoundation = true;
                            
                            // Проверяем принадлежность или доступ
                            if (block.OwnerID == player.userID || HasBuildingAccess(player, block))
                            {
                                // Размещаем лежак перед игроком с проверкой на коллизии
                                Vector3 potentialPos = new Vector3(
                                    player.transform.position.x + player.transform.forward.x * 1.8f,
                                    hit.point.y + 0.4f, // Немного выше поверхности
                                    player.transform.position.z + player.transform.forward.z * 1.8f
                                );
                                
                                // Проверяем линию от игрока до потенциальной позиции лежака
                                if (!Physics.Linecast(player.eyes.position, potentialPos, LayerMask.GetMask("Construction", "World", "Deployed")))
                                {
                                    // Проверяем, не будет ли стул пересекать стену/препятствие
                                    Collider[] colliders = Physics.OverlapBox(
                                        potentialPos,
                                        new Vector3(1f, 0.3f, 0.4f), // Половина размеров лежака
                                        rotation,
                                        LayerMask.GetMask("Construction", "World", "Deployed")
                                    );
                                    
                                    if (colliders.Length == 0)
                                    {
                                        chairPosition = potentialPos;
                                        SpawnChair(player, chairPosition, player.transform.rotation);
                                        return;
                                    }
                                    else
                                    {
                                        SendReply(player, "Лежак будет пересекать препятствие.Измените позицию!");
                                        return;
                                    }
                                }
                                else
                                {
                                    SendReply(player, "На пути к месту размещения есть препятствие!");
                                    return;
                                }
                            }
                        }
                    }
                }
                
                // Если игрок не на фундаменте или у него нет доступа, пробуем обычное размещение
                if (!isOnBuildingOrFoundation)
                {
                    // Пробуем разные позиции рядом с игроком
                    bool foundValidPos = false;
                    
                    // Используем круговой поиск для проверки разных позиций
                    for (float angle = 0; angle < 360; angle += 45)
                    {
                        float radians = angle * Mathf.Deg2Rad;
                        Vector3 direction = new Vector3(Mathf.Sin(radians), 0, Mathf.Cos(radians));
                        
                        for (float distance = 1.5f; distance <= 2.5f; distance += 0.5f)
                        {
                            Vector3 testPos = player.transform.position + direction * distance;
                            
                            // Проверка высоты поверхности
                            if (Physics.Raycast(testPos + Vector3.up * 2f, Vector3.down, out hit, 4f, LayerMask.GetMask("Terrain", "World", "Construction")))
                            {
                                Vector3 potentialPos = new Vector3(testPos.x, hit.point.y + 0.4f, testPos.z);
                                
                                // Проверяем линию видимости от игрока до позиции
                                if (!Physics.Linecast(player.eyes.position, potentialPos, LayerMask.GetMask("Construction", "World", "Deployed")))
                                {
                                    // Проверяем, не будет ли стул пересекать препятствие
                                    Collider[] colliders = Physics.OverlapBox(
                                        potentialPos,
                                        new Vector3(1f, 0.3f, 0.4f), // Половина размеров лежака
                                        rotation,
                                        LayerMask.GetMask("Construction", "World", "Deployed")
                                    );
                                    
                                    if (colliders.Length == 0)
                                    {
                                        chairPosition = potentialPos;
                                        foundValidPos = true;
                                        break;
                                    }
                                }
                            }
                        }
                        
                        if (foundValidPos) break;
                    }
                    
                    if (foundValidPos)
                    {
                        SpawnChair(player, chairPosition, player.transform.rotation);
                        return;
                    }
                    else
                    {
                        SendReply(player, "Не удалось найти подходящее место для лежака!");
                        return;
                    }
                }
            }
            
            // Если все проверки не прошли, сообщаем об ошибке
            SendReply(player, "Не удалось создать лежак.Попробуйте в другом месте.");
        }

        // Новый метод для прямого создания стула без лишних проверок
        private void SpawnChair(BasePlayer player, Vector3 position, Quaternion rotation)
        {
            // Создаем сущность лежака
            var beachChair = GameManager.server.CreateEntity(
                "assets/prefabs/misc/summer_dlc/beach_chair/beachchair.deployed.prefab", 
                position, 
                rotation);

            if (beachChair == null)
            {
                SendReply(player, "Не удалось создать лежак.");
                return;
            }

            // Принудительно устанавливаем позицию и вращение
            beachChair.transform.position = position;
            beachChair.transform.rotation = rotation;
            
            // Спавним и регистрируем
            beachChair.Spawn();
            playerChairs[player.userID] = beachChair;

            // Сажаем игрока с задержкой
            timer.Once(0.2f, () =>
            {
                if (IsValidPlayerAndChair(player, beachChair))
                {
                    try
                    {
                        (beachChair as BaseMountable).MountPlayer(player);
                        SendReply(player, "Лежак создан!");
                    }
                    catch
                    {
                        // Если не удалось посадить игрока, удаляем лежак и пробуем еще раз с увеличенной высотой
                        Vector3 newPosition = position;
                        newPosition.y += 0.3f;
                        
                        beachChair.Kill();
                        playerChairs.Remove(player.userID);
                        
                        var newChair = GameManager.server.CreateEntity(
                            "assets/prefabs/misc/summer_dlc/beach_chair/beachchair.deployed.prefab", 
                            newPosition, 
                            rotation);
                            
                        if (newChair != null)
                        {
                            newChair.Spawn();
                            playerChairs[player.userID] = newChair;
                            
                            timer.Once(0.2f, () =>
                            {
                                if (IsValidPlayerAndChair(player, newChair))
                                {
                                    try
                                    {
                                        (newChair as BaseMountable).MountPlayer(player);
                                        SendReply(player, "Лежак создан!");
                                    }
                                    catch
                                    {
                                        newChair.Kill();
                                        playerChairs.Remove(player.userID);
                                        SendReply(player, "Не удалось сесть на лежак.");
                                    }
                                }
                            });
                        }
                        else
                        {
                            SendReply(player, "Не удалось создать лежак.");
                        }
                    }
                }
            });
        }

        bool IsValidPlayerAndChair(BasePlayer player, BaseEntity chair)
        {
            return player != null && !player.IsDead() && 
                   chair != null && !chair.IsDestroyed &&
                   playerChairs.ContainsKey(player.userID) && 
                   playerChairs[player.userID] == chair;
        }

        private void CleanupChair(ulong userId)
        {
            if (playerChairs.TryGetValue(userId, out var chair))
            {
                if (chair != null && !chair.IsDestroyed)
                    chair.Kill();
                playerChairs.Remove(userId);
            }
        }

        void OnEntityDismounted(BaseMountable entity, BasePlayer player)
        {
            if (player == null || !playerChairs.TryGetValue(player.userID, out var chair))
                return;

            if (chair == entity)
            {
                player.SendConsoleCommand("cursor.visible", false);
                player.SendConsoleCommand("cursor.lock", true);
                timer.Once(0.5f, () => CleanupChair(player.userID));
            }
        }

        // Метод для проверки доступа к постройке
        private bool HasBuildingAccess(BasePlayer player, BaseEntity entity)
        {
            // Проверка прямого владения объектом
            if (entity.OwnerID == player.userID)
            {
                return true;
            }
            
            // Проверяем является ли объект частью здания
            BuildingBlock block = entity as BuildingBlock;
            if (block != null)
            {
                // Проверяем владельца блока
                if (block.OwnerID == player.userID)
                {
                    return true;
                }
                
                // Проверяем авторизацию в ближайших TC
                var cupboards = UnityEngine.Object.FindObjectsOfType<BuildingPrivlidge>();
                foreach (var cupboard in cupboards)
                {
                    if (cupboard == null || cupboard.IsDestroyed) continue;
                    
                    float distance = Vector3.Distance(block.transform.position, cupboard.transform.position);
                    if (distance <= 30f && cupboard.IsAuthed(player))
                    {
                        return true;
                    }
                }
            }
            
            // Проверка авторизации в шкафе привилегий напрямую
            BuildingPrivlidge privilege = entity as BuildingPrivlidge;
            if (privilege != null)
            {
                return privilege.IsAuthed(player);
            }
            
            // Проверка доступа через кодовый замок
            var lockable = entity.GetComponent<BaseLock>();
            if (lockable != null)
            {
                if (!lockable.IsLocked())
                {
                    return true; // Если замок не заперт, считаем что есть доступ
                }
                
                CodeLock codeLock = lockable as CodeLock;
                if (codeLock != null)
                {
                    // Проверяем авторизацию в кодовом замке
                    return codeLock.whitelistPlayers.Contains(player.userID) || 
                           codeLock.guestPlayers.Contains(player.userID);
                }
            }
            
            // Проверяем наличие шкафа привилегий в радиусе
            var cupboardsNearby = UnityEngine.Object.FindObjectsOfType<BuildingPrivlidge>();
            foreach (var cupboard in cupboardsNearby)
            {
                if (Vector3.Distance(entity.transform.position, cupboard.transform.position) <= 30f)
                {
                    if (cupboard.IsAuthed(player))
                    {
                        return true;
                    }
                }
            }
            
            return false;
        }
        
        // Метод для проверки привилегий игрока к постройке
        private bool HasBuildingPrivilege(BasePlayer player, BuildingBlock block)
        {
            if (block == null) return false;
            
            // Проверяем все шкафы привилегий вокруг блока
            var cupboards = UnityEngine.Object.FindObjectsOfType<BuildingPrivlidge>();
            foreach (var cupboard in cupboards)
            {
                if (cupboard == null || cupboard.IsDestroyed) continue;
                
                float distance = Vector3.Distance(block.transform.position, cupboard.transform.position);
                if (distance <= 30f && cupboard.IsAuthed(player))
                {
                    return true;
                }
            }
            
            return false;
        }
    }
}

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