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

FREE TeamBattle : 1.2.3 1.2.3

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

namespace Oxide.Plugins
{
    [Info("TeamBattle", "YourName", "1.2.3")]
    [Description("Система комнат для командных сражений с таймером, снаряжением и респавном")]
    public class TeamBattle : RustPlugin
    {
        #region Конфигурация и данные

        private const int MAX_ROOMS = 4;
        private const int MAX_TEAM_PLAYERS = 5;
        private const int DEFAULT_COUNTDOWN = 60;
        private const int FAST_COUNTDOWN = 10;
        private const float RESPAWN_DELAY = 5f;

        private Dictionary<int, Dictionary<string, List<BasePlayer>>> Rooms = new Dictionary<int, Dictionary<string, List<BasePlayer>>>();
        private Dictionary<int, Timer> RoomTimers = new Dictionary<int, Timer>();
        private Dictionary<int, int> RoomCountdowns = new Dictionary<int, int>();
        private Dictionary<int, bool> RoomLocked = new Dictionary<int, bool>();

        private Dictionary<int, Dictionary<string, List<Vector3>>> ManualSpawnPoints = new Dictionary<int, Dictionary<string, List<Vector3>>>()
        {
            [1] = new Dictionary<string, List<Vector3>>
            {
                ["Team1"] = new List<Vector3>
                {
                    new Vector3(68.46f, 5.01f, 47.67f),
                    new Vector3(69f, 5.01f, 36.81f),
                    new Vector3(68.5f, 5.01f, 54.51f),
                    new Vector3(65.28f, 5.01f, 68.76f),
                    new Vector3(67.28f, 5.01f, 25.14f)
                },
                ["Team2"] = new List<Vector3>
                {
                    new Vector3(124.03f, 5f, 25.46f),
                    new Vector3(121.39f, 5f, 39.64f),
                    new Vector3(122.07f, 5f, 45.6f),
                    new Vector3(122.72f, 5f, 57.33f),
                    new Vector3(121.82f, 5f, 68.51f)
                }
            },
            [2] = new Dictionary<string, List<Vector3>>
            {
                ["Team1"] = new List<Vector3>
                {
                    new Vector3(628f, 10f, -106f),
                    new Vector3(630f, 10f, -104f),
                    new Vector3(632f, 10f, -106f),
                    new Vector3(630f, 10f, -108f),
                    new Vector3(634f, 10f, -106f)
                },
                ["Team2"] = new List<Vector3>
                {
                    new Vector3(608f, 10f, -106f),
                    new Vector3(610f, 10f, -104f),
                    new Vector3(612f, 10f, -106f),
                    new Vector3(610f, 10f, -108f),
                    new Vector3(614f, 10f, -106f)
                }
            },
            [3] = new Dictionary<string, List<Vector3>>
            {
                ["Team1"] = new List<Vector3>
                {
                    new Vector3(942f, 10f, -106f),
                    new Vector3(944f, 10f, -104f),
                    new Vector3(946f, 10f, -106f),
                    new Vector3(944f, 10f, -108f),
                    new Vector3(948f, 10f, -106f)
                },
                ["Team2"] = new List<Vector3>
                {
                    new Vector3(922f, 10f, -106f),
                    new Vector3(924f, 10f, -104f),
                    new Vector3(926f, 10f, -106f),
                    new Vector3(924f, 10f, -108f),
                    new Vector3(928f, 10f, -106f)
                }
            },
            [4] = new Dictionary<string, List<Vector3>>
            {
                ["Team1"] = new List<Vector3>
                {
                    new Vector3(1256f, 10f, -106f),
                    new Vector3(1258f, 10f, -104f),
                    new Vector3(1260f, 10f, -106f),
                    new Vector3(1258f, 10f, -108f),
                    new Vector3(1262f, 10f, -106f)
                },
                ["Team2"] = new List<Vector3>
                {
                    new Vector3(1236f, 10f, -106f),
                    new Vector3(1238f, 10f, -104f),
                    new Vector3(1240f, 10f, -106f),
                    new Vector3(1238f, 10f, -108f),
                    new Vector3(1242f, 10f, -106f)
                }
            }
        };

        private Dictionary<BasePlayer, Timer> RespawnTimers = new Dictionary<BasePlayer, Timer>();
        private Dictionary<BasePlayer, PlayerStatsData> PlayerStats = new Dictionary<BasePlayer, PlayerStatsData>();

        class PlayerStatsData
        {
            public int Kills { get; set; }
            public int Deaths { get; set; }
            public int Wins { get; set; }
        }

        #endregion

        #region Инициализация

        void Init()
        {
            for (int i = 1; i <= MAX_ROOMS; i++)
            {
                Rooms[i] = new Dictionary<string, List<BasePlayer>>
                {
                    ["Team1"] = new List<BasePlayer>(),
                    ["Team2"] = new List<BasePlayer>()
                };
                RoomCountdowns[i] = DEFAULT_COUNTDOWN;
                RoomLocked[i] = false;

                if (!ManualSpawnPoints.ContainsKey(i) || ManualSpawnPoints[i].Count == 0)
                {
                    Puts($"Внимание: для комнаты {i} не заданы координаты спавна!");
                }
            }

            permission.RegisterPermission("teambattle.admin", this);
            permission.RegisterPermission("teambattle.leave", this);
        }

        #endregion

        #region Основные команды

        [ChatCommand("play")]
        void PlayCommand(BasePlayer player, string command, string[] args)
        {
            ShowRoomSelection(player);
        }

        [ChatCommand("leave")]
        void LeaveCommand(BasePlayer player, string command, string[] args)
        {
            ProcessPlayerLeave(player, false);
        }

        [ChatCommand("tbleave")]
        void AdminLeaveCommand(BasePlayer admin, string command, string[] args)
        {
            if (!permission.UserHasPermission(admin.UserIDString, "teambattle.admin"))
            {
                admin.ChatMessage("<color=red>У вас нет прав на эту команду!</color>");
                return;
            }

            if (args.Length == 0)
            {
                admin.ChatMessage("Использование: /tbleave <ник игрока>");
                return;
            }

            var target = BasePlayer.Find(args[0]);
            if (target == null)
            {
                admin.ChatMessage("<color=red>Игрок не найден!</color>");
                return;
            }

            if (ProcessPlayerLeave(target, true))
            {
                admin.ChatMessage($"<color=green>Игрок {target.displayName} исключен из битвы!</color>");
            }
        }

        bool ProcessPlayerLeave(BasePlayer player, bool adminForced)
        {
            int roomId = FindPlayerRoom(player);
            if (roomId == -1)
            {
                if (adminForced)
                    player.ChatMessage("<color=yellow>Игрок не в битве!</color>");
                return false;
            }

            // Отменяем респавн
            if (RespawnTimers.TryGetValue(player, out Timer respawnTimer))
            {
                respawnTimer.Destroy();
                RespawnTimers.Remove(player);
            }

            // Удаляем из комнаты
            RemovePlayerFromAllRooms(player);
            
            // Телепорт и очистка
            player.Teleport(ConVar.Server.spawnpoint);
            player.inventory.Strip();
            player.health = player.MaxHealth();
            player.metabolism.bleeding.value = 0;

            // Эффекты и уведомления
            Effect.server.Run("assets/prefabs/misc/supply drop/effects/supply_drop_parachute.prefab", player.transform.position);
            CuiHelper.DestroyUi(player, "TeamSelectPanel");
            
            if (adminForced)
            {
                player.ChatMessage("<color=red>Администратор исключил вас из битвы!</color>");
            }
            else
            {
                player.ChatMessage("<color=green>Вы вышли из командной битвы!</color>");
            }

            // Обновляем UI и проверяем комнату
            UpdateRoomUI(roomId);
            if (Rooms[roomId]["Team1"].Count + Rooms[roomId]["Team2"].Count == 0)
            {
                ResetRoom(roomId);
            }

            // Статистика
            if (RoomLocked[roomId])
            {
                PlayerStats[player].Deaths++;
            }

            return true;
        }

        void OnPlayerDisconnected(BasePlayer player)
        {
            ProcessPlayerLeave(player, false);
        }

        #endregion

        #region Команды и UI

        [ChatCommand("play")]
        void PlayCommand(BasePlayer player, string command, string[] args)
        {
            ShowRoomSelection(player);
        }

        void ShowRoomSelection(BasePlayer player)
        {
            var elements = new CuiElementContainer();
            string panel = elements.Add(new CuiPanel
            {
                Image = { Color = "0.1 0.1 0.1 0.9" },
                RectTransform = { AnchorMin = "0.3 0.2", AnchorMax = "0.7 0.8" },
                CursorEnabled = true
            }, "Overlay", "RoomSelectPanel");

            elements.Add(new CuiLabel
            {
                Text = { Text = "Выберите комнату", FontSize = 18, Align = TextAnchor.MiddleCenter },
                RectTransform = { AnchorMin = "0.1 0.85", AnchorMax = "0.9 0.95" }
            }, panel, "Title");

            for (int i = 1; i <= MAX_ROOMS; i++)
            {
                int roomId = i;
                int playersCount = Rooms[roomId]["Team1"].Count + Rooms[roomId]["Team2"].Count;
                string status = RoomLocked[roomId] ? "[ЗАКРЫТО]" : $"[{playersCount}/{MAX_TEAM_PLAYERS * 2}]";

                elements.Add(new CuiButton
                {
                    Button = {
                        Command = $"teambattle.selectroom {roomId}",
                        Color = RoomLocked[roomId] ? "0.3 0.3 0.3 0.5" : "0.3 0.3 0.3 1",
                        Close = panel
                    },
                    RectTransform = { AnchorMin = $"0.1 {0.75 - (i * 0.15)}", AnchorMax = $"0.9 {0.85 - (i * 0.15)}" },
                    Text = { Text = $"Комната {roomId} {status}", FontSize = 14, Align = TextAnchor.MiddleCenter }
                }, panel, $"RoomBtn_{i}");
            }

            CuiHelper.AddUi(player, elements);
        }

        [ConsoleCommand("teambattle.selectroom")]
        void SelectRoomCMD(ConsoleSystem.Arg arg)
        {
            var player = arg.Player() as BasePlayer;
            if (player == null) return;

            if (!int.TryParse(arg.Args?[0], out int roomId) || roomId < 1 || roomId > MAX_ROOMS)
            {
                player.ChatMessage("Некорректный номер комнаты!");
                return;
            }

            if (RoomLocked[roomId])
            {
                player.ChatMessage("Комната уже в игре!");
                return;
            }

            CuiHelper.DestroyUi(player, "RoomSelectPanel");
            ShowTeamSelection(player, roomId);
        }

        void ShowTeamSelection(BasePlayer player, int roomId)
        {
            var elements = new CuiElementContainer();
            string panel = elements.Add(new CuiPanel
            {
                Image = { Color = "0.1 0.1 0.1 0.9" },
                RectTransform = { AnchorMin = "0.3 0.2", AnchorMax = "0.7 0.8" },
                CursorEnabled = true
            }, "Overlay", "TeamSelectPanel");

            elements.Add(new CuiLabel
            {
                Text = { Text = $"Комната {roomId} - Старт через: {RoomCountdowns[roomId]} сек", FontSize = 18, Align = TextAnchor.MiddleCenter },
                RectTransform = { AnchorMin = "0.1 0.85", AnchorMax = "0.9 0.95" }
            }, panel, "Title");

            CreateTeamButton(elements, panel, roomId, "Team1", "0.2 0.4 0.8 1", "0.1 0.6", "0.9 0.75");
            CreateTeamButton(elements, panel, roomId, "Team2", "0.8 0.2 0.2 1", "0.1 0.35", "0.9 0.5");

            elements.Add(new CuiButton
            {
                Button = { Command = "teambattle.leaveroom", Color = "0.8 0.2 0.2 1", Close = panel },
                RectTransform = { AnchorMin = "0.1 0.1", AnchorMax = "0.9 0.25" },
                Text = { Text = "Покинуть комнату", FontSize = 14, Align = TextAnchor.MiddleCenter }
            }, panel, "LeaveBtn");

            CuiHelper.AddUi(player, elements);
        }

        void CreateTeamButton(CuiElementContainer elements, string panel, int roomId, string team, string color, string min, string max)
        {
            bool isFull = Rooms[roomId][team].Count >= MAX_TEAM_PLAYERS;

            elements.Add(new CuiButton
            {
                Button = {
                    Command = isFull ? "" : $"teambattle.selectteam {roomId} {team}",
                    Color = isFull ? "0.3 0.3 0.3 0.5" : color,
                    Close = panel
                },
                RectTransform = { AnchorMin = min, AnchorMax = max },
                Text = { Text = $"{team} ({Rooms[roomId][team].Count}/{MAX_TEAM_PLAYERS})", FontSize = 14, Align = TextAnchor.MiddleCenter }
            }, panel, $"{team}Btn");
        }

        #endregion

        #region Логика игры

        [ConsoleCommand("teambattle.selectteam")]
        void SelectTeamCMD(ConsoleSystem.Arg arg)
        {
            var player = arg.Player() as BasePlayer;
            if (player == null) return;

            if (!int.TryParse(arg.Args?[0], out int roomId) || roomId < 1 || roomId > MAX_ROOMS)
            {
                player.ChatMessage("Ошибка выбора комнаты!");
                return;
            }

            if (RoomLocked[roomId])
            {
                player.ChatMessage("Игра уже началась!");
                return;
            }

            int currentRoom = FindPlayerRoom(player);
            if (currentRoom == roomId)
            {
                player.ChatMessage("Вы уже в этой комнате!");
                return;
            }

            string team = arg.Args?[1];
            if (string.IsNullOrEmpty(team) || !Rooms[roomId].ContainsKey(team))
            {
                player.ChatMessage("Ошибка выбора команды!");
                return;
            }

            if (Rooms[roomId][team].Count >= MAX_TEAM_PLAYERS)
            {
                player.ChatMessage("Команда заполнена!");
                return;
            }

            RemovePlayerFromAllRooms(player);
            Rooms[roomId][team].Add(player);

            if (!PlayerStats.ContainsKey(player))
            {
                PlayerStats[player] = new PlayerStatsData();
            }

            player.ChatMessage($"Вы в команде {team} (Комната {roomId})");

            UpdateRoomUI(roomId);
            ManageRoomTimer(roomId);

            Effect.server.Run("assets/prefabs/npc/patrol helicopter/effects/rocket_fire.prefab", player.transform.position);
        }

        [ConsoleCommand("teambattle.leaveroom")]
        void LeaveRoomCMD(ConsoleSystem.Arg arg)
        {
            var player = arg.Player() as BasePlayer;
            if (player == null) return;

            int roomId = FindPlayerRoom(player);
            if (roomId == -1) return;

            if (RespawnTimers.ContainsKey(player))
            {
                RespawnTimers[player].Destroy();
                RespawnTimers.Remove(player);
            }

            if (RoomLocked[roomId])
            {
                player.ChatMessage("Нельзя выйти во время игры!");
                return;
            }

            RemovePlayerFromAllRooms(player);
            CuiHelper.DestroyUi(player, "TeamSelectPanel");
            player.ChatMessage("Вы покинули комнату");
            ManageRoomTimer(roomId);
        }

        void RemovePlayerFromAllRooms(BasePlayer player)
        {
            foreach (var room in Rooms.Values)
            {
                foreach (var team in room.Values)
                {
                    team.Remove(player);
                }
            }
        }

        int FindPlayerRoom(BasePlayer player)
        {
            foreach (var kvp in Rooms)
            {
                foreach (var team in kvp.Value)
                {
                    if (team.Value.Contains(player))
                        return kvp.Key;
                }
            }
            return -1;
        }

        void UpdateRoomUI(int roomId)
        {
            foreach (var team in Rooms[roomId])
            {
                foreach (var player in team.Value)
                {
                    CuiHelper.DestroyUi(player, "TeamSelectPanel");
                    ShowTeamSelection(player, roomId);
                }
            }
        }

        void ManageRoomTimer(int roomId)
        {
            int playersCount = Rooms[roomId]["Team1"].Count + Rooms[roomId]["Team2"].Count;

            if (playersCount == 0)
            {
                ResetTimer(roomId);
                return;
            }

            RoomCountdowns[roomId] = playersCount >= MAX_TEAM_PLAYERS * 2 ? FAST_COUNTDOWN : DEFAULT_COUNTDOWN;

            if (!RoomTimers.ContainsKey(roomId))
            {
                StartRoomCountdown(roomId);
            }
        }

        void StartRoomCountdown(int roomId)
        {
            RoomTimers[roomId] = timer.Every(1f, () =>
            {
                RoomCountdowns[roomId]--;
                UpdateRoomUI(roomId);

                if (RoomCountdowns[roomId] <= 0)
                {
                    StartGame(roomId);
                    return;
                }

                if (Rooms[roomId]["Team1"].Count + Rooms[roomId]["Team2"].Count == 0)
                {
                    ResetTimer(roomId);
                }
            });
        }

        void ResetTimer(int roomId)
        {
            if (RoomTimers.TryGetValue(roomId, out Timer roomTimer))
            {
                roomTimer.Destroy();
                RoomTimers.Remove(roomId);
            }
            RoomCountdowns[roomId] = DEFAULT_COUNTDOWN;
        }

        void StartGame(int roomId)
        {
            RoomLocked[roomId] = true;
            Puts($"Игра началась в комнате {roomId}");

            TeleportTeams(roomId);
            GiveStarterKits(roomId);

            foreach (var team in Rooms[roomId])
            {
                foreach (var player in team.Value)
                {
                    player.ChatMessage($"<color=green>Игра началась! Вы в {team.Key}</color>");
                    CuiHelper.DestroyUi(player, "TeamSelectPanel");
                    Effect.server.Run("assets/prefabs/misc/xmas/presents/effects/gift_open.prefab", player.transform.position);
                }
            }

            timer.Once(300f, () => EndGame(roomId));
        }

        void TeleportTeams(int roomId)
        {
            if (!ManualSpawnPoints.ContainsKey(roomId))
            {
                Puts($"Ошибка: для комнаты {roomId} не заданы координаты спавна!");
                return;
            }

            for (int i = 0; i < Rooms[roomId]["Team1"].Count; i++)
            {
                if (i < ManualSpawnPoints[roomId]["Team1"].Count)
                {
                    BasePlayer player = Rooms[roomId]["Team1"][i];
                    player.Teleport(ManualSpawnPoints[roomId]["Team1"][i]);
                    PlayTeleportEffect(player);
                }
                else
                {
                    Puts($"Не хватает координат спавна для Team1 в комнате {roomId}!");
                }
            }

            for (int i = 0; i < Rooms[roomId]["Team2"].Count; i++)
            {
                if (i < ManualSpawnPoints[roomId]["Team2"].Count)
                {
                    BasePlayer player = Rooms[roomId]["Team2"][i];
                    player.Teleport(ManualSpawnPoints[roomId]["Team2"][i]);
                    PlayTeleportEffect(player);
                }
                else
                {
                    Puts($"Не хватает координат спавна для Team2 в комнате {roomId}!");
                }
            }
        }

        void PlayTeleportEffect(BasePlayer player)
        {
            if (player == null || !player.IsConnected) return;

            Effect.server.Run("assets/prefabs/misc/particle_teleport.prefab", player.transform.position);
            Effect.server.Run("assets/prefabs/misc/sound_teleport.prefab", player.transform.position);
        }

        void GiveStarterKits(int roomId)
        {
            foreach (var team in Rooms[roomId])
            {
                foreach (var player in team.Value)
                {
                    player.inventory.Strip();
                    GiveWeapon(player, "rifle.ak");
                    GiveItem(player, "ammo.rifle", 100);
                    GiveItem(player, "medkit", 3);
                    GiveItem(player, "bandage", 5);
                }
            }
        }

        void GiveWeapon(BasePlayer player, string itemName)
        {
            var item = ItemManager.CreateByName(itemName, 1);
            if (item != null)
            {
                if (!item.MoveToContainer(player.inventory.containerBelt))
                {
                    item.Remove();
                }
            }
        }

        void GiveItem(BasePlayer player, string itemName, int amount)
        {
            var item = ItemManager.CreateByName(itemName, amount);
            if (item != null)
            {
                if (!item.MoveToContainer(player.inventory.containerBelt))
                {
                    item.Remove();
                }
            }
        }

        void OnEntityDeath(BaseCombatEntity entity, HitInfo info)
        {
            var player = entity as BasePlayer;
            if (player == null) return;

            int roomId = FindPlayerRoom(player);
            if (roomId == -1 || !RoomLocked[roomId]) return;

            player.inventory.Strip();
            player.ChatMessage($"<color=red>Вы погибли! Возрождение через {RESPAWN_DELAY} сек.</color>");

            if (RespawnTimers.ContainsKey(player))
            {
                RespawnTimers[player].Destroy();
                RespawnTimers.Remove(player);
            }

            RespawnTimers[player] = timer.Once(RESPAWN_DELAY, () => RespawnPlayer(player, roomId));
        }

        void RespawnPlayer(BasePlayer player, int roomId)
        {
            if (player == null || !player.IsConnected) return;

            string playerTeam = Rooms[roomId]["Team1"].Contains(player) ? "Team1" : "Team2";
            Vector3 spawnPos = FindAvailableSpawnPoint(roomId, playerTeam);

            player.Respawn();
            timer.Once(0.1f, () =>
            {
                if (player.IsConnected)
                {
                    player.Teleport(spawnPos);
                    GiveStarterKitsToPlayer(player);
                    PlayTeleportEffect(player);
                }
            });

            if (RespawnTimers.ContainsKey(player))
            {
                RespawnTimers.Remove(player);
            }
        }

        Vector3 FindAvailableSpawnPoint(int roomId, string team)
        {
            if (ManualSpawnPoints.ContainsKey(roomId) && ManualSpawnPoints[roomId].ContainsKey(team))
            {
                foreach (var point in ManualSpawnPoints[roomId][team])
                {
                    if (IsSpawnPointFree(point))
                        return point;
                }
            }

            float offsetX = team == "Team1" ? 10f : -10f;
            float randomZ = UnityEngine.Random.Range(-5f, 5f);

            Vector3 basePos = ManualSpawnPoints.ContainsKey(roomId) &&
                              ManualSpawnPoints[roomId].ContainsKey(team) &&
                              ManualSpawnPoints[roomId][team].Count > 0
                ? ManualSpawnPoints[roomId][team][0]
                : new Vector3(314 * roomId, 10, -106);

            return basePos + new Vector3(offsetX, 0, randomZ);
        }

        bool IsSpawnPointFree(Vector3 point)
        {
            var entities = new List<BaseEntity>();
            Vis.Entities(point, 1f, entities);
            return !entities.Any(e => e is BasePlayer);
        }

        void GiveStarterKitsToPlayer(BasePlayer player)
        {
            player.inventory.Strip();
            GiveWeapon(player, "rifle.ak");
            GiveItem(player, "ammo.rifle", 100);
            GiveItem(player, "medkit", 3);
            GiveItem(player, "bandage", 5);
        }

        void EndGame(int roomId)
        {
            foreach (var kvp in RespawnTimers.ToList())
            {
                if (kvp.Value != null && !kvp.Value.Destroyed)
                {
                    kvp.Value.Destroy();
                }
            }
            RespawnTimers.Clear();

            // Здесь можно добавить логику определения победителя
            // Пока просто отправим всем сообщение о завершении игры

            foreach (var team in Rooms[roomId])
            {
                foreach (var player in team.Value)
                {
                    player.ChatMessage("<color=blue>Игра окончена!</color>");
                }
            }

            ResetRoom(roomId);
        }

        void ResetRoom(int roomId)
        {
            Rooms[roomId]["Team1"].Clear();
            Rooms[roomId]["Team2"].Clear();
            RoomLocked[roomId] = false;
            RoomCountdowns[roomId] = DEFAULT_COUNTDOWN;
            Puts($"Комната {roomId} сброшена");
        }

        #endregion

        #region Админ-команды

        [ChatCommand("tbreset")]
        void AdminResetCommand(BasePlayer player, string command, string[] args)
        {
            if (!permission.UserHasPermission(player.UserIDString, "teambattle.admin"))
            {
                player.ChatMessage("У вас нет прав на эту команду!");
                return;
            }

            if (args.Length == 0)
            {
                player.ChatMessage("Использование: /tbreset [номер комнаты или all]");
                return;
            }

            if (args[0] == "all")
            {
                for (int i = 1; i <= MAX_ROOMS; i++)
                {
                    ResetRoom(i);
                }
                player.ChatMessage("Все комнаты сброшены!");
            }
            else if (int.TryParse(args[0], out int roomId) && roomId >= 1 && roomId <= MAX_ROOMS)
            {
                ResetRoom(roomId);
                player.ChatMessage($"Комната {roomId} сброшена!");
            }
            else
            {
                player.ChatMessage("Некорректный номер комнаты!");
            }
        }

        #endregion
    }
}

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