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

FREE TeleportMenu : 1.0.0 1.0.0

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

namespace Oxide.Plugins
{
    /// <summary>
    /// Определение класса CuiRawImageComponent для использования изображений по URL
    /// </summary>
    public class CuiRawImageComponent : ICuiComponent, ICuiColor
    {
        public string Type => "UnityEngine.UI.RawImage";

        [JsonProperty("sprite")]
        public string? Sprite { get; set; }

        public string? Color { get; set; }

        [JsonProperty("material")]
        public string? Material { get; set; }

        [JsonProperty("url")]
        public string? Url { get; set; }

        [JsonProperty("png")]
        public string? Png { get; set; }

        [JsonProperty("fadeIn")]
        public float FadeIn { get; set; }

        [JsonProperty("fitToParent")]
        public bool FitToParent { get; set; }
    }

    [Info("TeleportMenu", "YourName", "1.0.0")]
    [Description("Provides a UI teleport menu for players to teleport to different locations")]
    public class TeleportMenu : RustPlugin
    {
        #region Fields

        private const string UIMainPanel = "TeleportMenu.MainPanel";
        private const string UICloseButton = "TeleportMenu.CloseButton";
        private const string UIHomePanel = "TeleportMenu.HomePanel";
        private const string UIFriendsPanel = "TeleportMenu.FriendsPanel";
        private const string UIHomeButtonsPanel = "TeleportMenu.HomeButtonsPanel";
        private const string UITownButton = "TeleportMenu.TownButton";
        private const string UICampButton = "TeleportMenu.CampButton";
        private const string UIAcceptButton = "TeleportMenu.AcceptButton";
        private const string UIDeclineButton = "TeleportMenu.DeclineButton";

        private readonly Dictionary<ulong, Timer> pendingTeleports = new();
        private readonly Dictionary<ulong, Dictionary<string, Vector3>> homes;
        private readonly Dictionary<ulong, List<TeleportRequest>> teleportRequests = new();
        private readonly Dictionary<ulong, TeleportData> teleportData = new();

        private PluginConfig config;

        /// <summary>
        /// Добавляем словарь для хранения координат монументов
        /// </summary>
        private readonly Dictionary<string, Vector3> monumentPositions = new();
        private static readonly string[] stringArray = new[] { "дом1" };
        private static readonly string[] stringArray0 = new[] { "дом2" };

        #endregion Fields

        #region Configuration

        private sealed class PluginConfig
        {
            public float TeleportDelay { get; set; } = 5.0f;
            public float TeleportCooldown { get; set; } = 60.0f;
            public int MaxHomesPerPlayer { get; set; } = 999;
            public bool EnableTPToTown { get; set; } = true;
            public bool EnableTPToCamp { get; set; } = true;
            public bool EnableTPToFriends { get; set; } = true;
            public Vector3 TownLocation { get; set; } = new Vector3(0, 0, 0);
            public Vector3 CampLocation { get; set; } = new Vector3(0, 0, 0);
            public string MainColor { get; set; } = "0.4 0.34 0.6 0.98";
            public string BackgroundColor { get; set; } = "0.22 0.22 0.29 0.9";
            public string ButtonColor { get; set; } = "0.42 0.42 0.55 0.8";
            public string TextColor { get; set; } = "1 1 1 0.9";
            public string AcceptColor { get; set; } = "0.2 0.6 0.2 0.9";
            public string DeclineColor { get; set; } = "0.6 0.2 0.2 0.9";
            public bool AutoDetectMonuments { get; set; } = true;

            /// <summary>
            /// Настройки привилегий по телепортациям
            /// </summary>
            public Dictionary<string, TeleportLimits> PermissionLimits { get; set; } = new Dictionary<string, TeleportLimits>
            {
                ["default"] = new TeleportLimits { Home = 20, Town = 15, Camp = 15, Friend = 25 },
                ["vip"] = new TeleportLimits { Home = 30, Town = 25, Camp = 25, Friend = 35 },
                ["premium"] = new TeleportLimits { Home = 50, Town = 50, Camp = 50, Friend = 50 }
            };
        }

        public class TeleportLimits
        {
            public int Home { get; set; }
            public int Town { get; set; }
            public int Camp { get; set; }
            public int Friend { get; set; }
        }

        protected override void LoadDefaultConfig()
        {
            config = new PluginConfig();
            Config.WriteObject(config, true);
        }

        protected override void LoadConfig()
        {
            base.LoadConfig();
            try
            {
                config = Config.ReadObject<PluginConfig>();
                if (config == null)
                {
                    LoadDefaultConfig();
                }
            }
            catch (Exception ex)
            {
                PrintError($"Error loading config: {ex.Message}");
                LoadDefaultConfig();
            }
        }

        protected override void SaveConfig()
        {
            Config.WriteObject(config);
        }

        #endregion Configuration

        #region Data Models

        private sealed class TeleportData
        {
            public DateTime LastTeleport { get; set; } = DateTime.MinValue;
            public Dictionary<string, int> TeleportCounts { get; set; } = new Dictionary<string, int>
            {
                ["home"] = 0,
                ["town"] = 0,
                ["camp"] = 0,
                ["friend"] = 0
            };
            public int TeleportCount { get; set; }
        }

        private sealed class TeleportRequest
        {
            public ulong RequesterId { get; set; }
            public ulong TargetId { get; set; }
            public DateTime RequestTime { get; set; }
            public Timer? ExpiryTimer { get; set; }
        }

        #endregion Data Models

        #region Localization

        protected override void LoadDefaultMessages()
        {
            lang.RegisterMessages(new Dictionary<string, string>
            {
                ["TPHome"] = "ТП ДОМОЙ",
                ["TPToFriend"] = "ТП К ДРУГУ",
                ["Town"] = "В ГОРОД",
                ["Camp"] = "В ЛАГЕРЬ",
                ["Save"] = "Нажми, чтобы сохранить ДОМ",
                ["Empty"] = "ПУСТО",
                ["Accept"] = "ПРИНЯТЬ",
                ["Decline"] = "ОТКЛОНИТЬ",
                ["MenuTitle"] = "ТЕЛЕПОРТ МЕНЮ",
                ["CooldownMessage"] = "Подождите {0} секунд перед следующим телепортом",
                ["TeleportCountdown"] = "Телепортация через {0} секунд",
                ["TeleportSuccess"] = "Телепортация успешна!",
                ["TeleportFailed"] = "Телепортация отменена",
                ["NoPermission"] = "У вас нет разрешения на использование этой команды",
                ["HomeSet"] = "Дом {0} установлен",
                ["HomeLimitReached"] = "Вы достигли лимита домов ({0})",
                ["RequestSent"] = "Запрос на телепортацию отправлен игроку {0}",
                ["RequestReceived"] = "Игрок {0} хочет телепортироваться к вам",
                ["NoActiveRequests"] = "У вас нет активных запросов",
                ["TPRequestAccepted"] = "Запрос на телепортацию принят",
                ["TPRequestDeclined"] = "Запрос на телепортацию отклонен",
                ["RequestExpired"] = "Запрос на телепортацию истек",
                ["TooCloseToHostile"] = "Нельзя телепортироваться рядом с враждебной постройкой"
            }, this);
        }

        private string GetMsg(string key, string userId = null)
        {
            if (key == null)
            {
                return "MISSING_KEY";
            }

            string message = lang.GetMessage(key, this, userId);
            return message ?? key;
        }

        #endregion Localization

        #region Hooks

        private void Init()
        {
            LoadConfig();
            permission.RegisterPermission("teleportmenu.use", this);
            permission.RegisterPermission("teleportmenu.admin", this);
            permission.RegisterPermission("teleportmenu.default", this);
            permission.RegisterPermission("teleportmenu.vip", this);
            permission.RegisterPermission("teleportmenu.premium", this);
            cmd.AddChatCommand("tp", this, CmdTeleportMenu);
            cmd.AddChatCommand("home", this, CmdHome);
            cmd.AddChatCommand("town", this, CmdTown);
            cmd.AddChatCommand("camp", this, CmdCamp);
            cmd.AddChatCommand("tpr", this, CmdTeleportRequest);
            cmd.AddChatCommand("tpa", this, CmdAcceptTeleport);
            cmd.AddChatCommand("tpdecline", this, CmdDeclineTeleport);
            cmd.AddChatCommand("sethome", this, CmdSetHome);
            cmd.AddChatCommand("delhome", this, CmdDelHome);
            cmd.AddChatCommand("savehome", this, CmdSaveHome);
            cmd.AddChatCommand("savehome2", this, CmdSaveHome2);

            // Добавляем консольные команды для прямого вызова из UI без чата
            cmd.AddConsoleCommand("teleportmenu.sethome1", this, "ConSaveHome1");
            cmd.AddConsoleCommand("teleportmenu.sethome2", this, "ConSaveHome2");
            cmd.AddConsoleCommand("teleportmenu.sethome", this, "ConSetHome");
            cmd.AddConsoleCommand("teleportmenu.delhome", this, "ConDelHome");
            cmd.AddConsoleCommand("teleportmenu.home", this, "ConGoHome"); // Новая команда для телепортации к дому
            cmd.AddConsoleCommand("teleportmenu.close", this, "ConCloseMenu"); // Новая команда для закрытия интерфейса

            if (config.AutoDetectMonuments)
            {
                FindMonuments();
            }
        }

        private void OnServerSave()
        {
            SaveData();
        }

        private void Unload()
        {
            SaveData();
            foreach (BasePlayer? player in BasePlayer.activePlayerList)
            {
                DestroyUI(player);
            }
        }

        private void OnPlayerDisconnected(BasePlayer player)
        {
            DestroyUI(player);
            if (pendingTeleports.ContainsKey(player.userID))
            {
                pendingTeleports[player.userID]?.Destroy();
                _ = pendingTeleports.Remove(player.userID);
            }
        }

        #endregion Hooks

        #region Data Management

        private void SaveData()
        {
            Interface.Oxide.DataFileSystem.WriteObject($"{Name}/homes", homes);
        }

        private void LoadData()
        {
            // Ничего не делаем, так как поле инициализируется в конструкторе
        }

        #endregion Data Management

        #region Commands

        private void CmdTeleportMenu(BasePlayer player, string command, string[] args)
        {
            if (!permission.UserHasPermission(player.UserIDString, "teleportmenu.use"))
            {
                player.ChatMessage(GetMsg("NoPermission", player.UserIDString));
                return;
            }

            ShowTeleportMenu(player);
        }

        private void CmdHome(BasePlayer player, string command, string[] args)
        {
            if (!permission.UserHasPermission(player.UserIDString, "teleportmenu.use"))
            {
                player.ChatMessage(GetMsg("NoPermission", player.UserIDString));
                return;
            }

            if (args.Length == 0)
            {
                ShowTeleportMenu(player);
                return;
            }

            string homeName = args[0];
            if (!homes.ContainsKey(player.userID) || !homes[player.userID].TryGetValue(homeName, out Vector3 value))
            {
                player.ChatMessage($"Дом '{homeName}' не найден");
                return;
            }

            InitiateTeleport(player, value, "home");
        }

        private void CmdTown(BasePlayer player, string command, string[] args)
        {
            if (!permission.UserHasPermission(player.UserIDString, "teleportmenu.use"))
            {
                player.ChatMessage(GetMsg("NoPermission", player.UserIDString));
                return;
            }

            if (!config.EnableTPToTown)
            {
                player.ChatMessage("Телепортация в город отключена");
                return;
            }

            InitiateTeleport(player, config.TownLocation, "town");
        }

        private void CmdCamp(BasePlayer player, string command, string[] args)
        {
            if (!permission.UserHasPermission(player.UserIDString, "teleportmenu.use"))
            {
                player.ChatMessage(GetMsg("NoPermission", player.UserIDString));
                return;
            }

            if (!config.EnableTPToCamp)
            {
                player.ChatMessage("Телепортация в лагерь отключена");
                return;
            }

            InitiateTeleport(player, config.CampLocation, "camp");
        }

        private void CmdTeleportRequest(BasePlayer player, string command, string[] args)
        {
            if (!permission.UserHasPermission(player.UserIDString, "teleportmenu.use"))
            {
                player.ChatMessage(GetMsg("NoPermission", player.UserIDString));
                return;
            }

            if (!config.EnableTPToFriends)
            {
                player.ChatMessage("Телепортация к друзьям отключена");
                return;
            }

            if (args.Length == 0)
            {
                player.ChatMessage("Укажите имя игрока или ID");
                return;
            }

            BasePlayer target = FindPlayer(args[0], player);
            if (target == null)
            {
                player.ChatMessage($"Игрок '{args[0]}' не найден");
                return;
            }

            if (target == player)
            {
                player.ChatMessage("Вы не можете телепортироваться к себе");
                return;
            }

            SendTeleportRequest(player, target);
        }

        private void CmdAcceptTeleport(BasePlayer player, string command, string[] args)
        {
            if (!permission.UserHasPermission(player.UserIDString, "teleportmenu.use"))
            {
                player.ChatMessage(GetMsg("NoPermission", player.UserIDString));
                return;
            }

            if (!teleportRequests.ContainsKey(player.userID) || teleportRequests[player.userID].Count == 0)
            {
                player.ChatMessage(GetMsg("NoActiveRequests", player.UserIDString));
                return;
            }

            TeleportRequest request = teleportRequests[player.userID][0];
            BasePlayer requester = BasePlayer.FindByID(request.RequesterId);
            if (requester == null)
            {
                player.ChatMessage("Игрок оффлайн");
                RemoveTeleportRequest(player.userID, request);
                return;
            }

            // Проверка лимитов телепортации для запрашивающего
            if (!CheckTeleportLimits(requester, "friend"))
            {
                requester.ChatMessage("Вы достигли лимита телепортаций к друзьям");
                player.ChatMessage($"Игрок {requester.displayName} достиг лимита телепортаций");
                RemoveTeleportRequest(player.userID, request);
                return;
            }

            player.ChatMessage(GetMsg("TPRequestAccepted", player.UserIDString));
            requester.ChatMessage(GetMsg("TPRequestAccepted", requester.UserIDString));

            InitiateTeleport(requester, player.transform.position, "friend");
            RemoveTeleportRequest(player.userID, request);
        }

        private void CmdDeclineTeleport(BasePlayer player, string command, string[] args)
        {
            if (!permission.UserHasPermission(player.UserIDString, "teleportmenu.use"))
            {
                player.ChatMessage(GetMsg("NoPermission", player.UserIDString));
                return;
            }

            if (!teleportRequests.ContainsKey(player.userID) || teleportRequests[player.userID].Count == 0)
            {
                player.ChatMessage(GetMsg("NoActiveRequests", player.UserIDString));
                return;
            }

            TeleportRequest request = teleportRequests[player.userID][0];
            BasePlayer requester = BasePlayer.FindByID(request.RequesterId);

            player.ChatMessage(GetMsg("TPRequestDeclined", player.UserIDString));
            requester?.ChatMessage(GetMsg("TPRequestDeclined", requester.UserIDString));

            RemoveTeleportRequest(player.userID, request);
        }

        private void CmdSetHome(BasePlayer player, string command, string[] args)
        {
            if (!permission.UserHasPermission(player.UserIDString, "teleportmenu.use"))
            {
                player.ChatMessage(GetMsg("NoPermission", player.UserIDString));
                return;
            }

            // Проверяем, указал ли игрок название дома
            if (args.Length == 0)
            {
                player.ChatMessage("Ошибка: Вы должны указать название дома. Использование: /sethome [название]");
                return;
            }

            string homeName = args[0];

            // Проверяем, находится ли игрок на фундаменте
            bool onFoundation = IsPlayerOnFoundation(player);
            if (!onFoundation)
            {
                player.ChatMessage("Дом можно сохранить только стоя на фундаменте!");
                return;
            }

            // Проверяем, находится ли игрок в зоне своего шкафа (имеет права строительства)
            bool hasBuildingPrivilege = HasBuildingPrivilege(player);
            if (!hasBuildingPrivilege)
            {
                player.ChatMessage("Дом можно сохранить только в зоне действия вашего шкафа!");
                return;
            }

            // Сохраняем дом
            if (!homes.ContainsKey(player.userID))
            {
                homes[player.userID] = new Dictionary<string, Vector3>();
            }

            // Сохраняем позицию дома
            homes[player.userID][homeName] = player.transform.position;
            SaveData();
            player.ChatMessage($"Дом '{homeName}' установлен");

            // Перезапускаем интерфейс, чтобы отобразить новый дом
            if (player.IsReceivingSnapshot)
            {
                // Показываем UI только если игрок не в процессе загрузки
                _ = timer.Once(0.5f, () => ShowTeleportMenu(player));
            }
            else
            {
                ShowTeleportMenu(player);
            }
        }

        /// <summary>
        /// Новая чат-команда для сохранения дома с именем "дом1"
        /// </summary>
        private void CmdSaveHome(BasePlayer player, string command, string[] args)
        {
            if (!permission.UserHasPermission(player.UserIDString, "teleportmenu.use"))
            {
                player.ChatMessage(GetMsg("NoPermission", player.UserIDString));
                return;
            }

            // Вызываем существующий метод с предопределенным именем дома
            CmdSetHome(player, "sethome", stringArray);
        }

        /// <summary>
        /// Команда для сохранения второго дома
        /// </summary>
        private void CmdSaveHome2(BasePlayer player, string command, string[] args)
        {
            if (!permission.UserHasPermission(player.UserIDString, "teleportmenu.use"))
            {
                player.ChatMessage(GetMsg("NoPermission", player.UserIDString));
                return;
            }

            // Вызываем существующий метод с именем для второго дома
            CmdSetHome(player, "sethome", stringArray0);
        }

        /// <summary>
        /// Команда для удаления дома по имени
        /// </summary>
        private void CmdDelHome(BasePlayer player, string command, string[] args)
        {
            if (!permission.UserHasPermission(player.UserIDString, "teleportmenu.use"))
            {
                player.ChatMessage(GetMsg("NoPermission", player.UserIDString));
                return;
            }

            if (args.Length == 0)
            {
                player.ChatMessage("Укажите название дома для удаления. Использование: /delhome [название]");
                return;
            }

            string homeName = args[0];
            if (!homes.ContainsKey(player.userID) || !homes[player.userID].ContainsKey(homeName))
            {
                player.ChatMessage($"Дом '{homeName}' не найден");
                return;
            }

            _ = homes[player.userID].Remove(homeName);
            SaveData();
            player.ChatMessage($"Дом '{homeName}' удален");

            // Обновляем интерфейс после удаления дома
            ShowTeleportMenu(player);
        }

        #endregion Commands

        #region UI Methods

        private void ShowTeleportMenu(BasePlayer player)
        {
            DestroyUI(player);

            CuiElementContainer container = new();

            // Панель-подложка
            _ = container.Add(new CuiPanel
            {
                RectTransform = { AnchorMin = "0.25 0.3", AnchorMax = "0.75 0.8" },
                Image = { Color = "0 0 0 0" },
                CursorEnabled = true
            }, "Overlay", UIMainPanel);

            // Фоновое изображение для главной панели
            container.Add(new CuiElement
            {
                Parent = UIMainPanel,
                Components =
                {
                    new CuiRawImageComponent
                    {
                        Url = "https://i.imgur.com/qvVhltR.png",
                        Color = "1 1 1 1",
                        FitToParent = true
                    },
                    new CuiRectTransformComponent { AnchorMin = "0 0", AnchorMax = "1 1" }
                }
            });

            // Кнопка закрытия интерфейса
            _ = container.Add(new CuiButton
            {
                Button = { Color = "0.0 0.0 0.0 0.0", Command = "teleportmenu.close" },
                RectTransform = { AnchorMin = "0.95 0.94", AnchorMax = "1 1" },
                Text = { Text = "", Align = TextAnchor.MiddleCenter, Color = config.TextColor, FontSize = 18 }
            }, UIMainPanel);

            // Добавляем кнопки принять/отклонить телепортацию в верхней части интерфейса
            _ = container.Add(new CuiButton
            {
                Button = { Color = "0.0 0.0 0.0 0.0", Command = "chat.say /tpa", FadeIn = 0.2f },
                RectTransform = { AnchorMin = "0.75 0.8", AnchorMax = "0.9 0.88" },
                Text = { Text = "", Align = TextAnchor.MiddleCenter, Color = config.TextColor, FontSize = 14 }
            }, UIMainPanel, "AcceptTpButton");

            _ = container.Add(new CuiButton
            {
                Button = { Color = "0.0 0.0 0.0 0.0", Command = "chat.say /tpdecline", FadeIn = 0.2f },
                RectTransform = { AnchorMin = "0.519 0.275", AnchorMax = "0.703 0.325" },
                Text = { Text = "", Align = TextAnchor.MiddleCenter, Color = config.TextColor, FontSize = 14 }
            }, UIMainPanel, "DeclineTpButton");

            // Пустая нижняя панель (только для сохранения структуры и корректной работы)
            _ = container.Add(new CuiPanel
            {
                RectTransform = { AnchorMin = "0 0.1", AnchorMax = "1 0.63" },
                Image = { Color = "0 0 0 0" } // Полностью прозрачная
            }, UIMainPanel, "HomesPanel");

            // Получаем информацию о телепортациях для отображения в нижней части меню
            string townLimitText = GetTeleportLimitText(player, "town");
            string homeLimitText = GetTeleportLimitText(player, "home");
            string campLimitText = GetTeleportLimitText(player, "camp");
            string friendLimitText = GetTeleportLimitText(player, "friend");

            // Добавляем кнопку телепортации в город (Outpost)
            const string townPanelName = "TownButton";
            CuiPanel townPanel = new()
            {
                RectTransform = { AnchorMin = "0.295 0.60", AnchorMax = "0.485 0.65" },
                Image = { Color = "0 0 0 0" },
                CursorEnabled = true
            };
            _ = container.Add(townPanel, UIMainPanel, townPanelName);

            // Добавляем прозрачную кнопку для обработки клика в город с подсветкой
            _ = container.Add(new CuiButton
            {
                Button = { Color = "0.0 0.0 0.0 0.0", Command = "chat.say /town", FadeIn = 0.2f },
                RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1" },
                Text = { Text = "", Align = TextAnchor.MiddleCenter, Color = config.TextColor, FontSize = 14 }
            }, townPanelName);

            // Добавляем кнопку телепортации в лагерь бандитов (Bandit Camp)
            const string campPanelName = "CampButton";
            CuiPanel campPanel = new()
            {
                RectTransform = { AnchorMin = "0.519 0.60", AnchorMax = "0.704 0.65" },
                Image = { Color = "0 0 0 0" },
                CursorEnabled = true
            };
            _ = container.Add(campPanel, UIMainPanel, campPanelName);

            // Добавляем прозрачную кнопку для обработки клика в лагерь с подсветкой
            _ = container.Add(new CuiButton
            {
                Button = { Color = "0.0 0.0 0.0 0.0", Command = "chat.say /camp", FadeIn = 0.2f },
                RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1" },
                Text = { Text = "", Align = TextAnchor.MiddleCenter, Color = config.TextColor, FontSize = 14 }
            }, campPanelName);

            // Создаем кнопки быстрого доступа к домам с фиксированным положением
            if (homes.ContainsKey(player.userID) && homes[player.userID].Count > 0)
            {
                int count = 0;

                foreach (KeyValuePair<string, Vector3> home in homes[player.userID])
                {
                    if (count >= 10)
                    {
                        break; // Увеличиваем лимит с 3 до 10
                    }

                    // Используем фиксированные координаты для кнопок, расположенных вертикально
                    string anchorMin, anchorMax;
                    if (count == 0)
                    {
                        // Первая кнопка на месте "Сохранить текущее место как дом"
                        anchorMin = "0.06 0.70";
                        anchorMax = "0.265 0.77";
                    }
                    else if (count == 1)
                    {
                        // Вторая кнопка ниже первой
                        anchorMin = "0.06 0.62";
                        anchorMax = "0.265 0.69";
                    }
                    else if (count == 2)
                    {
                        // Третья кнопка еще ниже
                        anchorMin = "0.06 0.54";
                        anchorMax = "0.265 0.61";
                    }
                    else if (count == 3)
                    {
                        // Четвертая кнопка
                        anchorMin = "0.06 0.46";
                        anchorMax = "0.265 0.53";
                    }
                    else if (count == 4)
                    {
                        // Пятая кнопка
                        anchorMin = "0.06 0.38";
                        anchorMax = "0.265 0.45";
                    }
                    else if (count == 5)
                    {
                        // Шестая кнопка
                        anchorMin = "0.06 0.30";
                        anchorMax = "0.265 0.37";
                    }
                    else if (count == 6)
                    {
                        // Седьмая кнопка
                        anchorMin = "0.06 0.22";
                        anchorMax = "0.265 0.29";
                    }
                    else if (count == 7)
                    {
                        // Восьмая кнопка
                        anchorMin = "0.06 0.14";
                        anchorMax = "0.265 0.21";
                    }
                    else if (count == 8)
                    {
                        // Девятая кнопка
                        anchorMin = "0.39 0.70";
                        anchorMax = "0.59 0.77";
                    }
                    else // count == 9
                    {
                        // Десятая кнопка
                        anchorMin = "0.39 0.62";
                        anchorMax = "0.59 0.69";
                    }

                    string panelName = $"QuickHome_{count}";

                    // Создаем кнопку телепортации к дому
                    CuiPanel homePanel = new()
                    {
                        RectTransform = { AnchorMin = anchorMin, AnchorMax = anchorMax },
                        Image = { Color = "0 0 0 0" }
                    };
                    _ = container.Add(homePanel, UIMainPanel, panelName);

                    // Добавляем фоновое изображение
                    container.Add(new CuiElement
                    {
                        Parent = panelName,
                        Components =
                        {
                            new CuiRawImageComponent
                            {
                                Url = "https://i.imgur.com/rNv8SmY.png",
                                Color = "1 1 1 1",
                                FitToParent = true
                            },
                            new CuiRectTransformComponent { AnchorMin = "0 0", AnchorMax = "1 1" }
                        }
                    });

                    // Добавляем текст кнопки
                    container.Add(new CuiElement
                    {
                        Parent = panelName,
                        Components =
                        {
                            new CuiTextComponent
                            {
                                Text = $"Телепорт: {home.Key}",
                                Font = "robotocondensed-bold.ttf",
                                FontSize = 14,
                                Align = TextAnchor.MiddleCenter,
                                Color = config.TextColor
                            },
                            new CuiRectTransformComponent { AnchorMin = "0.05 0.1", AnchorMax = "0.95 0.9" }
                        }
                    });

                    // Добавляем прозрачную кнопку для обработки клика
                    _ = container.Add(new CuiButton
                    {
                        Button = { Color = "0 0 0 0", Command = $"teleportmenu.home {home.Key}" },
                        RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1" },
                        Text = { Text = "" }
                    }, panelName);

                    // Создаем кнопку удаления дома справа от кнопки телепортации
                    string deleteAnchorMin, deleteAnchorMax;
                    if (count == 0)
                    {
                        deleteAnchorMin = "0.27 0.70";
                        deleteAnchorMax = "0.37 0.77";
                    }
                    else if (count == 1)
                    {
                        deleteAnchorMin = "0.27 0.62";
                        deleteAnchorMax = "0.37 0.69";
                    }
                    else if (count == 2)
                    {
                        deleteAnchorMin = "0.27 0.54";
                        deleteAnchorMax = "0.37 0.61";
                    }
                    else if (count == 3)
                    {
                        deleteAnchorMin = "0.27 0.46";
                        deleteAnchorMax = "0.37 0.53";
                    }
                    else if (count == 4)
                    {
                        deleteAnchorMin = "0.27 0.38";
                        deleteAnchorMax = "0.37 0.45";
                    }
                    else if (count == 5)
                    {
                        deleteAnchorMin = "0.27 0.30";
                        deleteAnchorMax = "0.37 0.37";
                    }
                    else if (count == 6)
                    {
                        deleteAnchorMin = "0.27 0.22";
                        deleteAnchorMax = "0.37 0.29";
                    }
                    else if (count == 7)
                    {
                        deleteAnchorMin = "0.27 0.14";
                        deleteAnchorMax = "0.37 0.21";
                    }
                    else if (count == 8)
                    {
                        deleteAnchorMin = "0.39 0.70";
                        deleteAnchorMax = "0.49 0.77";
                    }
                    else // count == 9
                    {
                        deleteAnchorMin = "0.39 0.62";
                        deleteAnchorMax = "0.49 0.69";
                    }

                    // Добавляем кнопку удаления
                    _ = container.Add(new CuiButton
                    {
                        Button = { Color = "0.6 0.2 0.2 0.8", Command = $"teleportmenu.delhome {home.Key}", FadeIn = 0.2f },
                        RectTransform = { AnchorMin = deleteAnchorMin, AnchorMax = deleteAnchorMax },
                        Text = { Text = "X", Align = TextAnchor.MiddleCenter, Color = config.TextColor, FontSize = 14 }
                    }, UIMainPanel, $"DeleteHome_{count}");

                    count++;
                }

                // Определяем позицию для кнопки создания дома - всегда ниже последней кнопки телепортации
                string saveButtonAnchorMin, saveButtonAnchorMax;

                // В зависимости от количества домов, смещаем вниз
                if (count == 0)
                {
                    saveButtonAnchorMin = "0.06 0.70";
                    saveButtonAnchorMax = "0.265 0.77";
                }
                else if (count == 1)
                {
                    saveButtonAnchorMin = "0.06 0.62";
                    saveButtonAnchorMax = "0.265 0.69";
                }
                else if (count == 2)
                {
                    saveButtonAnchorMin = "0.06 0.54";
                    saveButtonAnchorMax = "0.265 0.61";
                }
                else if (count == 3)
                {
                    saveButtonAnchorMin = "0.06 0.46";
                    saveButtonAnchorMax = "0.265 0.53";
                }
                else if (count == 4)
                {
                    saveButtonAnchorMin = "0.06 0.38";
                    saveButtonAnchorMax = "0.265 0.45";
                }
                else if (count == 5)
                {
                    saveButtonAnchorMin = "0.06 0.30";
                    saveButtonAnchorMax = "0.265 0.37";
                }
                else if (count == 6)
                {
                    saveButtonAnchorMin = "0.06 0.22";
                    saveButtonAnchorMax = "0.265 0.29";
                }
                else if (count == 7)
                {
                    saveButtonAnchorMin = "0.06 0.14";
                    saveButtonAnchorMax = "0.265 0.21";
                }
                else if (count == 8)
                {
                    saveButtonAnchorMin = "0.39 0.70";
                    saveButtonAnchorMax = "0.59 0.77";
                }
                else // count == 9
                {
                    saveButtonAnchorMin = "0.39 0.62";
                    saveButtonAnchorMax = "0.59 0.69";
                }

                // Создаем кнопку "Сохранить текущее место как дом" на новой позиции
                CuiPanel saveHomePanel = new()
                {
                    RectTransform = { AnchorMin = saveButtonAnchorMin, AnchorMax = saveButtonAnchorMax },
                    Image = { Color = "0 0 0 0" },
                    CursorEnabled = true
                };
                _ = container.Add(saveHomePanel, UIMainPanel, "SaveHomePanel");

                // Добавляем фоновое изображение для кнопки
                container.Add(new CuiElement
                {
                    Parent = "SaveHomePanel",
                    Components =
                    {
                        new CuiRawImageComponent
                        {
                            Url = "https://i.imgur.com/rNv8SmY.png",
                            Color = "1 1 1 1",
                            FitToParent = true
                        },
                        new CuiRectTransformComponent { AnchorMin = "0 0", AnchorMax = "1 1" }
                    }
                });

                // Добавляем текст
                container.Add(new CuiElement
                {
                    Parent = "SaveHomePanel",
                    Components =
                    {
                        new CuiTextComponent
                        {
                            Text = "Сохранить текущее место как дом",
                            Font = "robotocondensed-bold.ttf",
                            FontSize = 14,
                            Align = TextAnchor.MiddleCenter,
                            Color = config.TextColor
                        },
                        new CuiRectTransformComponent { AnchorMin = "0.05 0.1", AnchorMax = "0.95 0.9" }
                    }
                });

                // Генерируем уникальное имя для нового дома
                string newHomeName = $"дом_{DateTime.Now:HHmmss}";

                // Добавляем кнопку поверх (прозрачную, только для обработки клика)
                _ = container.Add(new CuiButton
                {
                    Button = { Color = "0.4 0.4 0.4 0.1", Command = $"teleportmenu.sethome {newHomeName}", FadeIn = 0.2f },
                    RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1" },
                    Text = { Text = "" }
                }, "SaveHomePanel");
            }
            else
            {
                // Если нет домов, размещаем кнопку создания дома на стандартной позиции
                CuiPanel saveHomePanel = new()
                {
                    RectTransform = { AnchorMin = "0.06 0.70", AnchorMax = "0.265 0.77" },
                    Image = { Color = "0 0 0 0" }
                };
                _ = container.Add(saveHomePanel, UIMainPanel, "SaveHomePanel");

                // Добавляем фоновое изображение для кнопки
                container.Add(new CuiElement
                {
                    Parent = "SaveHomePanel",
                    Components =
                    {
                        new CuiRawImageComponent
                        {
                            Url = "https://i.imgur.com/rNv8SmY.png",
                            Color = "1 1 1 1",
                            FitToParent = true
                        },
                        new CuiRectTransformComponent { AnchorMin = "0 0", AnchorMax = "1 1" }
                    }
                });

                // Добавляем текст
                container.Add(new CuiElement
                {
                    Parent = "SaveHomePanel",
                    Components =
                    {
                        new CuiTextComponent
                        {
                            Text = "Сохранить текущее место как дом",
                            Font = "robotocondensed-bold.ttf",
                            FontSize = 14,
                            Align = TextAnchor.MiddleCenter,
                            Color = config.TextColor
                        },
                        new CuiRectTransformComponent { AnchorMin = "0.05 0.1", AnchorMax = "0.95 0.9" }
                    }
                });

                // Генерируем уникальное имя для нового дома
                string newHomeName = $"дом_{DateTime.Now:HHmmss}";

                // Добавляем кнопку поверх (прозрачную, только для обработки клика)
                _ = container.Add(new CuiButton
                {
                    Button = { Color = "0 0 0 0", Command = $"teleportmenu.sethome {newHomeName}" },
                    RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1" },
                    Text = { Text = "" }
                }, "SaveHomePanel");
            }

            // Отображение запросов телепортации
            if (teleportRequests.ContainsKey(player.userID) && teleportRequests[player.userID].Count > 0)
            {
                TeleportRequest request = teleportRequests[player.userID][0];
                BasePlayer requester = BasePlayer.FindByID(request.RequesterId);
                if (requester != null)
                {
                    // Панель запроса - делаем полупрозрачной
                    _ = container.Add(new CuiPanel
                    {
                        RectTransform = { AnchorMin = "0.2 0.4", AnchorMax = "0.8 0.7" },
                        Image = { Color = "0.1 0.1 0.1 0.9" }
                    }, UIMainPanel, "RequestPanel");

                    // Текст запроса
                    container.Add(new CuiElement
                    {
                        Parent = "RequestPanel",
                        Components =
                        {
                            new CuiTextComponent
                            {
                                Text = $"Игрок {requester.displayName} хочет телепортироваться к вам",
                                Font = "robotocondensed-regular.ttf",
                                FontSize = 14,
                                Align = TextAnchor.MiddleCenter,
                                Color = config.TextColor
                            },
                            new CuiRectTransformComponent { AnchorMin = "0.1 0.6", AnchorMax = "0.9 0.9" }
                        }
                    });

                    // Кнопки принять/отклонить - делаем полупрозрачными
                    _ = container.Add(new CuiButton
                    {
                        Button = { Color = "0.2 0.6 0.2 0.8", Command = "tpa" },
                        RectTransform = { AnchorMin = "0.1 0.2", AnchorMax = "0.45 0.4" },
                        Text = { Text = "ПРИНЯТЬ", Align = TextAnchor.MiddleCenter, Color = config.TextColor, FontSize = 14 }
                    }, "RequestPanel", UIAcceptButton);

                    _ = container.Add(new CuiButton
                    {
                        Button = { Color = "0.6 0.2 0.2 0.8", Command = "tpdecline" },
                        RectTransform = { AnchorMin = "0.55 0.2", AnchorMax = "0.9 0.4" },
                        Text = { Text = "ОТКЛОНИТЬ", Align = TextAnchor.MiddleCenter, Color = config.TextColor, FontSize = 14 }
                    }, "RequestPanel", UIDeclineButton);
                }
            }

            // Добавляем информационную панель внизу меню с лимитами телепортаций
            // Создаем 4 панели для отображения лимитов телепортаций
            // Панель для лимита телепортаций в город
            const string townLimitPanelName = "TownLimitPanel";
            CuiPanel townLimitPanel = new()
            {
                RectTransform = { AnchorMin = "0.43 0.112", AnchorMax = "0.47 0.162" },
                Image = { Color = "0.0 0.0 0.0 0.0" }
            };
            _ = container.Add(townLimitPanel, UIMainPanel, townLimitPanelName);

            // Добавляем текст с информацией о лимитах телепортаций в город
            container.Add(new CuiElement
            {
                Parent = townLimitPanelName,
                Components =
                {
                    new CuiTextComponent
                    {
                        Text = $" {townLimitText}",
                        Font = "robotocondensed-bold.ttf",
                        FontSize = 16,
                        Align = TextAnchor.MiddleCenter,
                        Color = "1 1 1 0.9"
                    },
                    new CuiRectTransformComponent { AnchorMin = "0 0", AnchorMax = "1 1" }
                }
            });

            // Панель для лимита телепортаций домой
            const string homeLimitPanelName = "HomeLimitPanel";
            CuiPanel homeLimitPanel = new()
            {
                RectTransform = { AnchorMin = "0.625 0.112", AnchorMax = "0.675 0.162" },
                Image = { Color = "0.0 0.0 0.0 0.0" }
            };
            _ = container.Add(homeLimitPanel, UIMainPanel, homeLimitPanelName);

            // Добавляем текст с информацией о лимитах телепортаций домой
            container.Add(new CuiElement
            {
                Parent = homeLimitPanelName,
                Components =
                {
                    new CuiTextComponent
                    {
                        Text = $" {homeLimitText}",
                        Font = "robotocondensed-bold.ttf",
                        FontSize = 16,
                        Align = TextAnchor.MiddleCenter,
                        Color = "1 1 1 0.9"
                    },
                    new CuiRectTransformComponent { AnchorMin = "0 0", AnchorMax = "1 1" }
                }
            });

            // Панель для лимита телепортаций в лагерь
            const string campLimitPanelName = "CampLimitPanel";
            CuiPanel campLimitPanel = new()
            {
                RectTransform = { AnchorMin = "0.43 0.025", AnchorMax = "0.47 0.075" },
                Image = { Color = "0.0 0.0 0.0 0.0" }
            };
            _ = container.Add(campLimitPanel, UIMainPanel, campLimitPanelName);

            // Добавляем текст с информацией о лимитах телепортаций в лагерь
            container.Add(new CuiElement
            {
                Parent = campLimitPanelName,
                Components =
                {
                    new CuiTextComponent
                    {
                        Text = $" {campLimitText}",
                        Font = "robotocondensed-bold.ttf",
                        FontSize = 16,
                        Align = TextAnchor.MiddleCenter,
                        Color = "1 1 1 0.9"
                    },
                    new CuiRectTransformComponent { AnchorMin = "0 0", AnchorMax = "1 1" }
                }
            });

            // Панель для лимита телепортаций к другу
            const string friendLimitPanelName = "FriendLimitPanel";
            CuiPanel friendLimitPanel = new()
            {
                RectTransform = { AnchorMin = "0.625 0.025", AnchorMax = "0.675
// ... [Code preview truncated due to length. Full source in attached file] ...

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