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

FREE Teleportation : 2.0.0 2.0.0

Нет прав для скачивания
C#:
using Oxide.Core;
using Oxide.Core.Plugins;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using ConVar;
using Newtonsoft.Json;
using Oxide.Game.Rust.Cui;
using Rust;
using UnityEngine;
using VLB;
using Color = UnityEngine.Color;
using Physics = UnityEngine.Physics;
using Time = UnityEngine.Time;
namespace Oxide.Plugins {
    [Info("Teleportation", "TopPlugin.ru", "2.0.0")]
    [Description("Teleportation")]
    class Teleportation : RustPlugin {
#region Classes
        private class ParentPosition {
            public static Vector3 GetOffsetPosition(Transform parent, Vector3 child) {
                return parent.InverseTransformPoint(child);
            }
            public static Vector3 GetFinalPosition(Transform parent, Vector3 offset) {
                return parent.TransformPoint(offset);
            }
        }
        private static class TimeHelper {
            public static string FormatTime(TimeSpan time, int maxSubstr = 5, string language = "ru") {
                string result = string.Empty;
                switch (language) {
                    case "ru" : int i = 0;
                    if (time.Days != 0 && i < maxSubstr) {
                        if (!string.IsNullOrEmpty(result)) result += " ";
                        result += $"{Format(time.Days, "д", "д", "д")}";
                        i++;
                    }
                    if (time.Hours != 0 && i < maxSubstr) {
                        if (!string.IsNullOrEmpty(result)) result += " ";
                        result += $"{Format(time.Hours, "ч", "ч", "ч")}";
                        i++;
                    }
                    if (time.Minutes != 0 && i < maxSubstr) {
                        if (!string.IsNullOrEmpty(result)) result += " ";
                        result += $"{Format(time.Minutes, "м", "м", "м")}";
                        i++;
                    }
                    if (time.Days == 0) {
                        if (time.Seconds != 0 && i < maxSubstr) {
                            if (!string.IsNullOrEmpty(result)) result += " ";
                            result += $"{Format(time.Seconds, "с", "с", "с")}";
                            i++;
                        }
                    }
                    break;
                    case "en" : int b = 0;
                    if (time.Days != 0 && b < maxSubstr) {
                        if (!string.IsNullOrEmpty(result)) result += " ";
                        result += $"{Format(time.Days, "d", "d", "d")}";
                        b++;
                    }
                    if (time.Hours != 0 && b < maxSubstr) {
                        if (!string.IsNullOrEmpty(result)) result += " ";
                        result += $"{Format(time.Hours, "h", "h", "h")}";
                        b++;
                    }
                    if (time.Minutes != 0 && b < maxSubstr) {
                        if (!string.IsNullOrEmpty(result)) result += " ";
                        result += $"{Format(time.Minutes, "m", "m", "m")}";
                        b++;
                    }
                    if (time.Days == 0) {
                        if (time.Seconds != 0 && b < maxSubstr) {
                            if (!string.IsNullOrEmpty(result)) result += " ";
                            result += $"{Format(time.Seconds, "s", "s", "s")}";
                            b++;
                        }
                    }
                    break;
                }
                return result;
            }
            private static string Format(int units, string form1, string form2, string form3) {
                var tmp = units % 10;
                if (units >= 5 && units <= 20 || tmp >= 5 && tmp <= 9) return $"{units}{form1}";
                if (tmp >= 2 && tmp <= 4) return $"{units}{form2}";
                return $"{units}{form3}";
            }
            private static DateTime Epoch = new DateTime(1970, 1, 1);
            public static double GetTimeStamp() {
                return DateTime.Now.Subtract(Epoch).TotalSeconds;
            }
        }
        private static class PlayerHelper {
            private static bool FindPlayerPredicate(BasePlayer player, string nameOrUserId) {
                return player.displayName.IndexOf(nameOrUserId, StringComparison.OrdinalIgnoreCase) != -1 || player.UserIDString == nameOrUserId;
            }
            public static bool Find(string nameOrUserId, out BasePlayer target) {
                nameOrUserId = nameOrUserId.ToLower();
                foreach (BasePlayer activePlayer in BasePlayer.activePlayerList) {
                    if (FindPlayerPredicate(activePlayer, nameOrUserId)) {
                        target = activePlayer;
                        return true;
                    }
                }
                foreach (BasePlayer sleepingPlayer in BasePlayer.sleepingPlayerList) {
                    if (FindPlayerPredicate(sleepingPlayer, nameOrUserId)) {
                        target = sleepingPlayer;
                        return true;
                    }
                }
                target = (BasePlayer) null;
                return false;
            }
            public static bool FindOnlineMultiple(string nameOrUserId, BasePlayer player, out BasePlayer target) {
                if (nameOrUserId == string.Empty) {
                    _plugin.SendMessage(player, "PLAYER.NOT.FOUND");
                    target = (BasePlayer) null;
                    return false;
                }
                List<BasePlayer> activePlayers = new List<BasePlayer>();
                nameOrUserId = nameOrUserId.ToLower();
                foreach (BasePlayer activePlayer in BasePlayer.activePlayerList) {
                    if (FindPlayerPredicate(activePlayer, nameOrUserId)) {
                        activePlayers.Add(activePlayer);
                    }
                }
                switch (activePlayers.Count) {
                    case 0 : _plugin.SendMessage(player, $"PLAYER.NOT.FOUND.PARAM", nameOrUserId);
                    target = null;
                    return false;
                    case 1 : target = activePlayers[0];
                    return true;
                    default : var text = "";
                    foreach (var activePlayer in activePlayers) {
                        text += $" {activePlayer.displayName},";
                    }
                    _plugin.SendMessage(player, "PLAYER.FIND.MULTIPLE");
                    target = null;
                    return false;
                }
            }
            public static bool FindOnline(string nameOrUserId, out BasePlayer target) {
                if (nameOrUserId == string.Empty) {
                    target = (BasePlayer) null;
                    return false;
                }
                nameOrUserId = nameOrUserId.ToLower();
                foreach (BasePlayer activePlayer in BasePlayer.activePlayerList) {
                    if (FindPlayerPredicate(activePlayer, nameOrUserId)) {
                        target = activePlayer;
                        return true;
                    }
                }
                target = (BasePlayer) null;
                return false;
            }
        }
        public class Request {
            public bool IsHome = false;
            public SettingMonument.AvailableMonument Monument;
            public BasePlayer Target = null;
            public BasePlayer Player = null;
            public Vector3 Position = Vector3.zero;
            public RealTimeSince RequestTimeout = 0;
            public bool RequestConfirmed = false;
            public Request(BasePlayer player, bool isHome, Vector3 position = default(Vector3), BasePlayer target = null, SettingMonument.AvailableMonument monument = null) {
                this.IsHome = isHome;
                this.Monument = monument;
                this.Target = target;
                this.Player = player;
                this.Position = position;
            }
        }
#endregion
#region Variables
        [PluginReference]
        private Plugin IQChat, ImageLibrary, Friends, Clans;
        private const string TeleportImage = "https://i.imgur.com/kTyCOMy.png";
        private static Teleportation _plugin;
        private const string Layer = "UI.Teleportation";
        private const string LayerBlur = "UI.Teleportation.Layer";
        private const string LayerNotification = "UI.Teleportation.Notification";
        private const string EffectPrefab = "assets/prefabs/locks/keypad/effects/lock.code.denied.prefab";
        private readonly int triggerLayer = LayerMask.GetMask("Trigger");
        private readonly int groundLayer = LayerMask.GetMask("Terrain", "World");
        private readonly int buildingLayer = LayerMask.GetMask("Terrain", "World", "Construction", "Deployed");
        private readonly int blockLayer = LayerMask.GetMask("Construction");
        private readonly int deployedLayer = LayerMask.GetMask("Deployed");
#endregion
#region OxideHooks
        void OnServerInitialized() {
            _plugin = this;
            StartPluginLoad();
        }
        void OnNewSave(string fileName) {
            if (_config.AutoWipe) {
                PrintWarning("Wipe detected! wiping data file...");
                _data.PlayersData = new Dictionary<ulong, PlayerData>();
                PluginData.SaveData();
            }
        }
        void OnServerSave() {
            PluginData.SaveData();
        }
        void Unload() {
            PluginData.SaveData();
            for (var i = 0; i < MarkerBag.MarkerBags.Count; i++) UnityEngine.Object.Destroy(MarkerBag.MarkerBags[i]);
            for (var i = 0; i < TeleportMgr.ManagersList.Count; i++) UnityEngine.Object.Destroy(TeleportMgr.ManagersList[i]);
            for (var i = 0; i < _config.SettingsMonument.AvailableMonuments.Count; i++) {
                var monument = _config.SettingsMonument.AvailableMonuments[i];
                if(monument.CreatedBag != null) monument.CreatedBag.Kill();
            }
        }
        void OnPlayerConnected(BasePlayer player) {
            if (player == null) return;
            if (player.HasPlayerFlag(BasePlayer.PlayerFlags.ReceivingSnapshot)) {
                timer.Once(2f, () => OnPlayerConnected(player));
                return;
            }
            if (!player.IsConnected) return;
            player.GetOrAddComponent<TeleportMgr>();
        }
        object CanRenameBed(BasePlayer player, SleepingBag bed, string bedName) {
            if (_config.SettingsMonument.AvailableMonuments.Exists(x => x.CreatedBag != null && x.CreatedBag == bed)) return false;
            return null;
        }
        object OnSleepingBagValidCheck(SleepingBag bag, ulong targetPlayerID, bool ignoreTimers) {
            if (_config.SettingsMonument.AvailableMonuments.Exists(x => x.CreatedBag != null && x.CreatedBag == bag)) return true;
            return null;
        }
#endregion
#region Commands
        [ChatCommand("tpc")]
        private void ChatCommandTpc(BasePlayer player, string command, string[] args) {
            var teleportMgr = TeleportMgr.GetManager(player);
            if (teleportMgr == null) return;
            if (teleportMgr.IncomingRequest != null && teleportMgr.IncomingRequest.Player != null) {
                var objTarget = TeleportMgr.GetManager(teleportMgr.IncomingRequest.Player);
                SendMessage(player, "TPR.PLAYER.CANCEL", teleportMgr.IncomingRequest.Player.displayName);
                SendMessage(teleportMgr.IncomingRequest.Player, "TPR.TARGET.CANCEL", player.displayName);
                objTarget.CancelTeleport();
                teleportMgr.CancelTeleport();
                return;
            }
            if (teleportMgr.Request != null && teleportMgr.Request.IsHome) {
                teleportMgr.CancelTeleport();
                SendMessage(player, "HOME.PLAYER.CANCEL");
            }
            if (teleportMgr.Request != null && teleportMgr.Request.Monument != null) {
                teleportMgr.CancelTeleport();
                SendMessage(player, "TPM.PLAYER.CANCEL");
            }
        }
        [ConsoleCommand("home")]
        void ConsoleCmdHome(ConsoleSystem.Arg arg) {
            var player = arg.Player();
            if (player == null) return;
            if (arg.HasArgs() == false) return;
            ChatCommandHome(player, "", arg.Args);
        }
        [ChatCommand("tp")]
        private void ChatCommandTp(BasePlayer player, string command, string[] args) {
            switch (args.Length) {
                case 0 : break;
                case 1 : if (!player.IsAdmin) return;
                string name = args[0];
                BasePlayer target = null;
                if(!PlayerHelper.FindOnlineMultiple(name, player, out target)) {
                    return;
                }
                if (target == null) {
                    Effect.server.Run(EffectPrefab, player, 0, Vector3.zero, Vector3.forward);
                    SendMessage(player, "PLAYER.NOT.FOUND");
                    return;
                }
                Teleport(player, target);
                break;
                case 2 : if (!player.IsAdmin) return;
                string name1 = args[0];
                string name2 = args[1];
                BasePlayer target1 = null;
                if(!PlayerHelper.FindOnlineMultiple(name1, player, out target1)) {
                    return;
                }
                BasePlayer target2 = null;
                if(!PlayerHelper.FindOnlineMultiple(name2, player, out target2)) {
                    return;
                }
                if (target1 == null || target2 == null) {
                    SendMessage(player, "PLAYER.NOT.FOUND");
                    return;
                }
                Teleport(target1, target2);
                break;
                case 3 : if (!player.IsAdmin) return;
                float x = float.Parse(args[0]);
                float y = float.Parse(args[1]);
                float z = float.Parse(args[2]);
                Teleport(player, x, y, z);
                break;
            }
        }
        [ConsoleCommand("UI_Teleportation")]
        private void ConsoleCommandTeleportation(ConsoleSystem.Arg arg) {
            var player = arg?.Connection?.player as BasePlayer;
            if (player == null) return;
            switch (arg.GetString(0)) {
                case "close" : CuiHelper.DestroyUi(player, Layer);
                CuiHelper.DestroyUi(player, LayerBlur);
                break;
            }
        }
        [ChatCommand("tpa")]
        private void ChatCommandTpa(BasePlayer player, string command, string[] args) {
            var teleportMgr = TeleportMgr.GetManager(player);
            if (teleportMgr == null) return;
            if (teleportMgr.IncomingRequest == null) {
                SendMessage(player, "TPA.ZERO.REQUEST");
                return;
            }
            var pendingPlayer = teleportMgr.IncomingRequest.Player;
            var pendingTeleportMgr = TeleportMgr.GetManager(pendingPlayer);
            if (pendingTeleportMgr == null) return;
            if (player.IsWounded() && _config.SettingsResolution.CantTeleportWounded) {
                Effect.server.Run(EffectPrefab, player, 0, Vector3.zero, Vector3.forward);
                SendMessage(player, "TP.CANCEL.BLOOD.OR.WOUNDED");
                return;
            }
            if (player.metabolism.bleeding.value > _config.SettingsResolution.SettingsBleeding.NeedBleedingAmount && _config.SettingsResolution.SettingsBleeding.CantTeleportBleeding) {
                Effect.server.Run(EffectPrefab, player, 0, Vector3.zero, Vector3.forward);
                SendMessage(player, "TP.CANCEL.BLOOD.OR.WOUNDED");
                return;
            }
            if (player.IsBuildingBlocked() && _config.SettingsResolution.CantTeleportInBuild) {
                Effect.server.Run(EffectPrefab, player, 0, Vector3.zero, Vector3.forward);
                SendMessage(player, "TP.CANCEL.BUILD.DONT.AUTH");
                return;
            }
            var ret = Interface.Call("CanTeleport", player) as string;
            if (ret != null) {
                SendMessageWithoutLang(player, ret);
                return;
            }
            SendMessage(player, "TPA.PLAYER.ACCEPT", pendingPlayer.displayName);
            SendMessage(pendingPlayer, "TPA.TARGET.ACCEPT");
            CuiHelper.DestroyUi(player, LayerNotification);
            teleportMgr.IncomingRequest = null;
            pendingTeleportMgr.AcceptRequest();
        }
        [ChatCommand("tpr")]
        private void ChatCommandTpr(BasePlayer player, string command, string[] args) {
            if (GetTeleportTimeTpr(player.userID) <= 0) return;
            if (args.Length < 1) {
                Effect.server.Run(EffectPrefab, player, 0, Vector3.zero, Vector3.forward);
                SendMessage(player, "TPR.HELP");
                return;
            }
            var ret = Interface.Call("CanTeleport", player) as string;
            if (ret != null) {
                SendMessageWithoutLang(player, ret);
                return;
            }
            var message = CanTeleportPlayer(player);
            if (string.IsNullOrEmpty(message) == false) {
                Effect.server.Run(EffectPrefab, player, 0, Vector3.zero, Vector3.forward);
                SendMessageWithoutLang(player, message);
                return;
            }
            var data = PluginData.GetForPlayer(player.userID);
            if (data == null) return;
            if (data.CooldownTeleport >= GetCurrentTime()) {
                SendMessage(player, "TPR.COOLDOWN", TimeHelper.FormatTime(TimeSpan.FromSeconds(data.CooldownTeleport - GetCurrentTime()), language : lang.GetLanguage(player.UserIDString)));
                return;
            }
            BasePlayer target = null;
            if(!PlayerHelper.FindOnlineMultiple(string.Join(" ", args), player, out target)) {
                return;
            }
            if (target == null) return;
            if (target == player) return;
            var teleportMgr = TeleportMgr.GetManager(player);
            if (teleportMgr == null) return;
            if (teleportMgr.Request != null) {
                SendMessage(player, "TPR.PLAYER.CANCEL.REQUEST");
                return;
            }
            var targetTeleportMgr = TeleportMgr.GetManager(target);
            if (targetTeleportMgr == null) return;
            if (targetTeleportMgr.IncomingRequest != null) {
                SendMessage(player, "TPR.TARGET.CANCEL.REQUEST");
                return;
            }
            teleportMgr.InitRequest(target.transform.position, false, target);
            targetTeleportMgr.IncomingRequest = teleportMgr.Request;
            SendMessage(player, "TPR.PLAYER.SEND", target.displayName);
            SendMessage(target, "TPR.TARGET.SEND", player.displayName);
            CuiElementContainer container = new CuiElementContainer();
            container.Add(new CuiPanel {
                CursorEnabled = false, RectTransform = {
                    AnchorMin = "0.5 0", AnchorMax = "0.5 0", OffsetMax = "0 0"
                }
                , Image = {
                    Color = GetColor("#FFFFFF", 0.4f)
                }
            }
            , "Hud", LayerNotification);
            container.Add(new CuiElement() {
                Parent = LayerNotification, Name = LayerNotification + ".Main", Components = {
                    new CuiRawImageComponent() {
                        Png = GetImage(TeleportImage)
                    }
                    , new CuiRectTransformComponent() {
                        AnchorMin = $"0 0", AnchorMax = $"1 1", OffsetMin = "-200 81", OffsetMax = "180 117.6"
                    }
                    ,
                }
            }
            );
            container.Add(new CuiPanel() {
                RectTransform = {
                    AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = "-151 81", OffsetMax = "132 117.6"
                }
                , Image = {
                    Color = "0.9686275 0.9215686 0.8823529 0.13529412"
                }
            }
            , LayerNotification);
            container.Add(new CuiLabel() {
                RectTransform = {
                    AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = "-151 81", OffsetMax = "132 117.6"
                }
                , Text = {
                    Text = GetMessage(player, "TPR.UI.REQUEST" , player.displayName), Font = "RobotoCondensed-Bold.ttf", Align = TextAnchor.MiddleCenter, FontSize = 16, Color = GetColor("#FFFFFFB2")
                }
                ,
            }
            , LayerNotification);
            container.Add(new CuiButton() {
                RectTransform = {
                    AnchorMin = "0.02 0", AnchorMax = "0 1", OffsetMax = "49 0"
                }
                , Button = {
                    Color = "0 0 0 0", Command = "chat.say /tpc"
                }
                , Text = {
                    Text = GetMessage(player, "TPR.UI.REQUEST.NO"), Align = TextAnchor.MiddleCenter, Color = GetColor("#D12C2C"), FontSize = 16
                }
            }
            , LayerNotification + ".Main");
            container.Add(new CuiButton() {
                RectTransform = {
                    AnchorMin = "0.98 0", AnchorMax = "1 1", OffsetMin = "-49 0"
                }
                , Button = {
                    Color = "0 0 0 0", Command = "chat.say /tpa"
                }
                , Text = {
                    Text = GetMessage(player, "TPR.UI.REQUEST.YES"), Align = TextAnchor.MiddleCenter, Color = GetColor("#C1FF9B"), FontSize = 16
                }
            }
            , LayerNotification + ".Main");
            CuiHelper.AddUi(target, container);
        }
        [ChatCommand("removehome")]
        private void СhatCommandRemoveHome(BasePlayer player, string command, string[] args) {
            if (args.Length < 1) {
                Effect.server.Run(EffectPrefab, player, 0, Vector3.zero, Vector3.forward);
                SendMessage(player, "REMOVE.HOME.HELP");
                return;
            }
            string homeName = string.Join(" ", args);
            var data = PluginData.GetForPlayer(player.userID);
            var home = data.GetHome(homeName);
            if (home == null) {
                SendMessage(player, "REMOVE.HOME.NONE");
                return;
            }
            if (home.SleepingBagId != 0) {
                var bag = BaseNetworkable.serverEntities.Find(home.SleepingBagId);
                if (bag != null) bag.Kill();
            }
            data.HomesList.Remove(home);
            SendMessage(player, "REMOVE.HOME.SUCCESS", homeName);
        }
        [ChatCommand("homelist")]
        private void СhatCommandHomeList(BasePlayer player, string command, string[] args) {
            var data = PluginData.GetForPlayer(player.userID);
            if (data == null) return;
            if (data.HomesList.Count < 1) {
                SendMessage(player, "HOMELIST.ZERO");
                return;
            }
            string homes = "";
            for (var i = data.HomesList.Count - 1; i >= 0; i--) {
                var home = data.HomesList[i];
                homes += $"{home.HomeName}";
                if (i != 0) homes += ", ";
            }
            SendMessage(player, "HOMELIST.FOUND", homes);
        }
        [ChatCommand("sethome")]
        private void ChatCommandSetHome(BasePlayer player, string command, string[] args) {
            if (GetHomeLimit(player.userID) <= 0) return;
            var foundationList = GetFoundation(player.ServerPosition);
            if (foundationList == null || foundationList.Count == 0) {
                SendMessage(player, "FOUNDATION.NOT.FOUND");
                return;
            }
            var foundation = foundationList?.First();
            if (foundation == null) {
                SendMessage(player, "FOUNDATION.NOT.FOUND");
                return;
            }
            string err = CheckFoundation(player.userID, player.ServerPosition);
            if (err != null) {
                SendMessage(player, err);
                return;
            }
            err = CheckInsideBlock(player.ServerPosition);
            if (err != null) {
                SendMessage(player, err);
                return;
            }
            if (player.GetBuildingPrivilege(player.WorldSpaceBounds()) != null && !player.GetBuildingPrivilege(player.WorldSpaceBounds()).authorizedPlayers.Select(p => p.userid).Contains(player.userID)) {
                Effect.server.Run(EffectPrefab, player, 0, Vector3.zero, Vector3.forward);
                SendMessage(player, "SETHOME.CANCEL.BUILD");
                return;
            }
            if (args.Length != 1) {
                SendMessage(player, "SETHOME.HELP");
                return;
            }
            if (player.IsWounded() && _config.SettingsResolution.CantTeleportWounded || player.metabolism.bleeding.value > _config.SettingsResolution.SettingsBleeding.NeedBleedingAmount && _config.SettingsResolution.SettingsBleeding.CantTeleportBleeding) {
                SendMessage(player, "BLOOD.OR.WOUNDED");
                return;
            }
            SetHome(player, args[0]);
        }
        [ChatCommand("home")]
        private void ChatCommandHome(BasePlayer player, string command, string[] args) {
            if (args.Length != 1) {
                Effect.server.Run(EffectPrefab, player, 0, Vector3.zero, Vector3.forward);
                SendMessage(player, "HOME.HELP");
                return;
            }
            if (GetTeleportTimeHome(player.userID) <= 0) return;
            var data = PluginData.GetForPlayer(player.userID);
            var homeName = string.Join(" ", args);
            var home = data.GetHome(homeName);
            if (home == null) {
                Effect.server.Run(EffectPrefab, player, 0, Vector3.zero, Vector3.forward);
                SendMessage(player, "HOME.NOT.FOUND.OR.REMOVED");
                return;
            }
            var ret = Interface.Call("CanTeleport", player) as string;
            if (ret != null) {
                SendMessageWithoutLang(player, ret);
                return;
            }
            if (_config.SettingsHome.EnableSleepingBags) {
                if (home.SleepingBagId == 0) {
                    data.HomesList.Remove(home);
                    Effect.server.Run(EffectPrefab, player, 0, Vector3.zero, Vector3.forward);
                    SendMessage(player, "HOME.NOT.FOUND.BAG");
                    return;
                }
                var bag = BaseNetworkable.serverEntities.Find(home.SleepingBagId);
                if (bag == null) {
                    data.HomesList.Remove(home);
                    Effect.server.Run(EffectPrefab, player, 0, Vector3.zero, Vector3.forward);
                    SendMessage(player, "HOME.NOT.FOUND.BAG");
                    return;
                }
            }
            if (data.CooldownHome > GetCurrentTime()) {
                Effect.server.Run(EffectPrefab, player, 0, Vector3.zero, Vector3.forward);
                SendMessage(player, "HOME.COOLDOWN", TimeHelper.FormatTime(TimeSpan.FromSeconds(data.CooldownHome - GetCurrentTime())));
                return;
            }
            var message = CanTeleportPlayer(player);
            if (!string.IsNullOrEmpty(message)) {
                Effect.server.Run(EffectPrefab, player, 0, Vector3.zero, Vector3.forward);
                SendMessageWithoutLang(player, message);
                return;
            }
            string err = CheckInsideBlock(home.HomePos);
            if (err != null) {
                SendMessage(player, "HOME.REMOVED.INSIDE.BLOCK", home.HomeName);
                data.HomesList.Remove(home);
                return;
            }
            var teleportMgr = TeleportMgr.GetManager(player);
            if (teleportMgr == null) return;
            if (teleportMgr.Request != null) {
                SendMessage(player, "TPR.PLAYER.CANCEL.REQUEST");
                return;
            }
            teleportMgr.InitRequest(home.HomePos, true);
            SendMessage(player, "HOME.TELEPORTATION", TimeHelper.FormatTime(TimeSpan.FromSeconds(GetTeleportTimeHome(player.userID)), language : lang.GetLanguage(player.UserIDString)));
        }
        [ChatCommand("tpm")]
        private void ChatCommandTpMonument(BasePlayer player, string command, string[] args) {
            if (args.Length < 1) {
                SendMessage(player, "TPM.HELP");
                return;
            }
            switch (args[0]) {
                case "add" : {
                    if (player.IsAdmin == false) break;
                    var closestMonument = FindClosestMonument(player.transform.position);
                    if (closestMonument == null) {
                        SendMessage(player, "TPM.ADMIN.CLOSEST.NOT.FOUND");
                        break;
                    }
                    var monumentInfo = _config.SettingsMonument.AvailableMonuments.Find(x => closestMonument.name.Contains(x.ShortPrefabName));
                    if (monumentInfo != null) {
                        SendMessage(player, "TPM.ADMIN.EXISTS");
                        break;
                    }
                    Vector3 positionOffset = ParentPosition.GetOffsetPosition(closestMonument.transform, player.transform.position);
                    string name = GetShortMonumentName(closestMonument.name);
                    SleepingBag bag = null;
                    if (_config.SettingsMonument.EnableSleepingBags) {
                        bag = CreateSleepingBag(null, ParentPosition.GetFinalPosition(closestMonument.transform, positionOffset) - new Vector3(0, 100f, 0), name);
                        bag.SetPublic(false);
                        bag.OwnerID = 0;
                        bag.deployerUserID = 0;
                        bag.spawnOffset += new Vector3(0, 100f, 0);
                        bag.unlockTime = Time.realtimeSinceStartup + 30f;
                        bag.secondsBetweenReuses = 30f;
                    }
                    monumentInfo = new SettingMonument.AvailableMonument() {
                        ShortPrefabName = name, CoolDown = 300f, CoolDownPublic = 30f, TeleportTime = 30f, Name = name, PositionOffset = positionOffset, ShortCutCommand = "", CreatedBag = bag, MonumentInfo = closestMonument,
                    }
                    ;
                    _config.SettingsMonument.AvailableMonuments.Add(monumentInfo);
                    SaveConfig();
                    SendMessage(player, "TPM.ADMIN.SUCCESS");
                    break;
                }
                case "remove" : {
                    if (player.IsAdmin == false) break;
                    if (args.Length < 2) break;
                    string name = string.Join(" ", args.Skip(1));
                    var monumentInfo = _config.SettingsMonument.AvailableMonuments.Find(x => x.Name == name);
                    if (monumentInfo == null) {
                        SendMessage(player, "TPM.ADMIN.REMOVE.NOT.FOUND");
                        break;
                    }
                    _config.SettingsMonument.AvailableMonuments.Remove(monumentInfo);
                    SaveConfig();
                    SendMessage(player, "TPM.ADMIN.REMOVE.SUCCESS");
                    break;
                }
                case "list" : {
                    if (_config.SettingsMonument.AvailableMonuments.Count < 1) {
                        SendMessage(player, "TPM.NO.AVAILABLE.MONUMENTS");
                        break;
                    }
                    string monuments = "";
                    for (var i = _config.SettingsMonument.AvailableMonuments.Count - 1; i >= 0; i--) {
                        var availableMonument = _config.SettingsMonument.AvailableMonuments[i];
                        monuments += $"\n/tpm {availableMonument.Name}" + (string.IsNullOrEmpty(availableMonument.ShortCutCommand) ? "" : $" (/{availableMonument.ShortCutCommand})");
                    }
                    SendMessage(player, "TPM.LIST.FOUND", monuments);
                    break;
                }
                default : {
                    if (args.Length < 1) {
                        SendMessage(player, "TPM.HELP");
                        break;
                    }
                    string name = string.Join(" ", args);
                    var monumentInfo = _config.SettingsMonument.AvailableMonuments.Find(x => x.Name == name);
                    if (monumentInfo == null) {
                        SendMessage(player, "TPM.NOT.FOUND");
                        break;
                    }
                    if (monumentInfo.MonumentInfo == null) {
                        SendMessage(player, "TPM.NOT.FOUND");
                        break;
                    }
                    var data = PluginData.GetForPlayer(player.userID);
                    if (data == null) break;
                    double cooldown = data.GetMonumentCooldown(monumentInfo.Name);
                    if (cooldown > GetCurrentTime()) {
                        SendMessage(player, "TPM.COOLDOWN", TimeHelper.FormatTime(TimeSpan.FromSeconds(cooldown - GetCurrentTime())));
                        break;
                    }
                    var teleportMgr = TeleportMgr.GetManager(player);
                    if (teleportMgr == null) break;
                    teleportMgr.InitRequest(ParentPosition.GetFinalPosition(monumentInfo.MonumentInfo.transform, monumentInfo.PositionOffset), false, null, monumentInfo);
                    SendMessage(player, "TPM.TP.SUCCESS", TimeHelper.FormatTime(TimeSpan.FromSeconds(monumentInfo.TeleportTime)));
                    break;
                }
            }
        }
        private MonumentInfo FindClosestMonument(Vector3 position) {
            MonumentInfo info = null;
            float minDistance = float.MaxValue;
            var monuments = TerrainMeta.Path.Monuments;
            foreach (var monument in monuments) {
                float distance = Vector3.Distance(position, monument.transform.position);
                if (distance > minDistance) continue;
                minDistance = distance;
                info = monument;
            }
            return info;
        }
        private MonumentInfo FindMonument(string shortPrefabName) {
            return TerrainMeta.Path.Monuments.Find(x => x.name.Contains(shortPrefabName));
        }
        private string GetShortMonumentName(string fullName) {
            var split = fullName.Split('/');
            return split[split.Length - 1].Replace(".prefab", string.Empty);
        }
#endregion
#region Lang
        private void SendMessage(BasePlayer player, string message, string arg1 = "", string arg2 = "", Chat.ChatChannel channel = Chat.ChatChannel.Global) {
            if (IQChat) IQChat?.Call("API_ALERT_PLAYER", player, GetMessage(player, message, arg1, arg2), GetMessage(player, "TELEPORTATION.TITLE"));
            else player.SendConsoleCommand("chat.add", channel, 0, GetMessage(player, message, arg1, arg2));
        }
        private void SendMessageWithoutLang(BasePlayer player, string message, Chat.ChatChannel channel = Chat.ChatChannel.Global) {
            if (IQChat) IQChat?.Call("API_ALERT_PLAYER", player, message, GetMessage(player, "TELEPORTATION.TITLE"));
            else player.SendConsoleCommand("chat.add", channel, 0, message);
        }
        private string GetMessage(BasePlayer player, string message, string arg1 = "", string arg2 = "") {
            return string.Format(lang.GetMessage(message, this, player.UserIDString), arg1, arg2);
        }
        protected override void LoadDefaultMessages() {
            lang.RegisterMessages(new Dictionary<string, string>() {
                ["TPM.ADMIN.REMOVE.NOT.FOUND"]
                = "Monument not found.", ["TPM.ADMIN.REMOVE.SUCCESS"] = "You successfuly removed the monument from config.", ["TPM.PLAYER.CANCEL"] = "Teleport to monument cancelled.", ["TPM.NO.AVAILABLE.MONUMENTS"] = "There is no available monuments.", ["TPM.LIST.FOUND"] = "Available monuments: {0}", ["TPM.HELP"] = "Usage: /tpm 'monument name'.\nUse: /tpm list - to see all available monuments.", ["TPM.NOT.FOUND"] = "Monument not found!", ["TPM.COOLDOWN"] = "Teleportation has been canceled! Reason: cooldown {0}", ["TPM.TP.SUCCESS"] = "You successfully teleport to monument.Time before teleporting {0}", ["TPM.SUCCESS"] = "You have successfully teleported to monument", ["TPM.ADMIN.SUCCESS"] = "Monument was successfully added into your config.", ["TPM.ADMIN.CLOSEST.NOT.FOUND"] = "The system could not find the nearest monument to you!", ["TPM.ADMIN.EXISTS"] = "Such a monument already exists!", ["TPR.PLAYER.CANCEL"] = "You have successfully canceled teleportation to player {0}", ["TPR.TARGET.CANCEL"] = "Player {0} has canceled teleportation to you!", ["HOME.PLAYER.CANCEL"] = "You canceled teleportation to your home!", ["PLAYER.NOT.FOUND"] = "Player not found", ["TPA.ZERO.REQUEST"] = "You have no pending teleport request!", ["TP.CANCEL.BLOOD.OR.WOUNDED"] = "Teleport canceled! You can't teleport while wounded!", ["TP.CANCEL.BUILD.DONT.AUTH"] = "You can't teleport while in a building blocked zone!", ["TPA.PLAYER.ACCEPT"] = "You've accepted the teleport request of {0}!", ["TPA.TARGET.ACCEPT"] = "Player has accepted your teleport request!! Teleportation has started!", ["TPR.HELP"] = "Use: /tpr nickname", ["TPR.COOLDOWN"] = "Your teleport requests are currently on cooldown.You'll have to wait {0} to send your next teleport request.", ["TELEPORTATION.TITLE"] = "[TELEPORTATION]", ["TPR.PLAYER.CANCEL.REQUEST"] = "You can't initiate another teleport while you have a teleport pending!", ["TPR.TARGET.CANCEL.REQUEST"] = "You can't request a teleport to someone who's about to teleport!", ["TPR.PLAYER.SEND"] = "Teleportation request to {0} was sent successfully", ["TPR.TARGET.SEND"] = "{0} sent you teleportation request\nTo accept type: /tpa\nTo refuse type: /tpc", ["REMOVE.HOME.HELP"] = "Use: /removehome name", ["REMOVE.HOME.NONE"] = "Couldn't find your home with that name!", ["REMOVE.HOME.SUCCESS"] = "You have removed your home {0}!", ["FOUNDATION.NOT.FOUND"] = "Foundation not found!", ["FOUNDATION.NOT.OWNED"] = "Foundation is not owned by you or your friends!", ["FOUNDATION.HOME.INSIDE.BLOCK"] = "You can't create home inside other blocks!", ["SETHOME.HELP"] = "Use: /sethome name", ["BLOOD.OR.WOUNDED"] = "You are bleeding or you wounded!", ["HOME.HELP"] = "Use: /home name", ["HOME.NOT.FOUND.OR.REMOVED"] = "Home location not found or has been deleted!", ["HOME.NOT.FOUND.BAG"] = "Teleportation is not possible! Sleeping bag not found!", ["HOME.COOLDOWN"] = "Teleportation has been canceled! Reason: cooldown {0}", ["HOME.REMOVED.INSIDE.BLOCK"] = "Your home '{0}' was removed because it was inside a foundation!", ["CAN.TP.SWIMMING"] = "Teleportation in water is prohibited!", ["CAN.TP.ALIVE"] = "You can't teleport while being dead!", ["CAN.TP.RADIATION"] = "You are irradiated! Teleportation has been canceled!", ["CAN.TP.BLEEDING"] = "You are bleeding! Teleportation canceled!", ["CAN.TP.TEMPERATURE"] = "You're too cold to teleport!", ["CAN.TP.WOUNDED"] = "You can't teleport while wounded!", ["CAN.TP.MOUNTED"] = "You can't teleport while mounting vehicle!", ["CAN.TP.BUILDINGBLOCK"] = "You can't teleport while in a building blocked zone!", ["SETHOME.ALREADY.EXISTS"] = "A location with this name already exists!", ["SETHOME.CANCEL.RADIUS"] = "You already have home location nearby!", ["SETHOME.CANCEL.MAXHOUSE"] = "Unable to set your home here, you have reached the maximum amount of homes!", ["SETHOME.SUCCESS"] = "You have saved the current location {0} as your home!", ["HOMELIST.ZERO"] = "You have no houses!", ["HOMELIST.FOUND"] = "Houses list: {0}", ["HOME.TELEPORTATION"] = "You successfully teleport to your home.Time before teleporting {0}", ["REQUEST.CHECK.DISCONNECT"] = "Teleport request has been canceled! Reason: player left server", ["REQUEST.CHECK.DEAD"] = "Teleport request has been canceled! Reason: player died!", ["REQUEST.CHECK.WOUNDED"] = "Teleport request has been canceled! Reason: player wounded!", ["REQUEST.CHECK.TIME.ENDED"] = "Teleport request has been canceled! Reason: time out!", ["TP.CHECK.BUILD"] = "Teleport request has been canceled! Reason: building blocked zone", ["TP.HOME.SUCCESS"] = "You teleported to your home!", ["TP.PLAYER.SUCCESS"] = "You have successfully teleported to {0}", ["TP.TARGET.SUCCESS"] = "Player {0} successfully teleported to you!", ["MARKER.BAG"] = "<size=24>{0}</size>\n<size=16>{1}</size>", ["MARKER.BAG.NAMEBAG"] = "{0}", ["MARKER.BAG.COOLDOWN"] = "COUNTDOWN: {0}", ["MARKER.BAG.NOTCOOLDOWN"] = "AVAILABLE FOR TELEPORTATION", ["TELEPORTATION.UI"] = "TIME LEFT BEFORE TELEPORT: {0}", ["PLAYER.NOT.FOUND.PARAM"] = "Player {0} not found", ["PLAYER.FIND.MULTIPLE"] = "Several players were found: {0}", ["TPR.UI.REQUEST"] = "REQUEST FROM PLAYER {0}", ["TPR.UI.REQUEST.YES"] = "YES", ["TPR.UI.REQUEST.NO"] = "NO", ["SETHOME.CANCEL.BUILD"] = "You cannot set your home location while in building blocked zone!"
            }
            , this);
            lang.RegisterMessages(new Dictionary<string, string>() {
                ["TPM.ADMIN.REMOVE.NOT.FOUND"]
                = "Монумент не найден.", ["TPM.ADMIN.REMOVE.SUCCESS"] = "Вы успешно удалили монумент из конфига.", ["TPM.PLAYER.CANCEL"] = "Телепорт на монумент был отменён.", ["TPM.NO.AVAILABLE.MONUMENTS"] = "Нет доступных монументов.", ["TPM.LIST.FOUND"] = "Доступные монументы: {0}", ["TPM.HELP"] = "Использование: /tpm 'название монумента'.\nИспользуйте: /tpm list - чтобы увидеть список доступных монументов.", ["TPM.NOT.FOUND"] = "Монумент не найден!", ["TPM.COOLDOWN"] = "Телепортация отменена! Причина: откат {0}", ["TPM.TP.SUCCESS"] = "Вы успешно телепортируетесь на монумент.Время перед телепортом {0}", ["TPM.SUCCESS"] = "Вы успешно телепортированы на монумент.", ["TPM.ADMIN.SUCCESS"] = "Вы успешно добавили новый монумент в конфиг.", ["TPM.ADMIN.CLOSEST.NOT.FOUND"] = "Система не смогла определить ближайший монумент к вам!", ["TPM.ADMIN.EXISTS"] = "Такой монумент уже есть в конфиге!", ["TPR.PLAYER.CANCEL"] = "Вы успешно отменили телепортацию к игроку {0}", ["TPR.TARGET.CANCEL"] = "Игрок {0} отменил телепортацию к Вам!", ["HOME.PLAYER.CANCEL"] = "Вы отменили телепортацию домой!", ["PLAYER.NOT.FOUND"] = "Игрок не найден", ["TPA.ZERO.REQUEST"] = "У вас нет входящих запросов на телепортацию!", ["TP.CANCEL.BLOOD.OR.WOUNDED"] = "Телепортация была отменена! Причина кровоток или вы упали!", ["TP.CANCEL.BUILD.DONT.AUTH"] = "В билдинг зоне телепортация запрещена!", ["TPA.PLAYER.ACCEPT"] = "Вы приняли запрос игрока {0}", ["TPA.TARGET.ACCEPT"] = "Игрок принял ваш запрос! Телепортация началась!", ["TPR.HELP"] = "Используйте: /tpr ник", ["TPR.COOLDOWN"] = "Телепортация невозможна! У вас кулдаун: {0}", ["TELEPORTATION.TITLE"] = "[TELEPORTATION]", ["TPR.PLAYER.CANCEL.REQUEST"] = "Телепортация невозможна! У Вас уже есть запрос!", ["TPR.TARGET.CANCEL.REQUEST"] = "Телепортация невозможна! У игрока уже есть запрос!", ["TPR.PLAYER.SEND"] = "Запрос к {0} был успешно отправлен", ["TPR.TARGET.SEND"] = "{0} отправил вам запрос на телепортацию\nЧтобы принять используйте /tpa\nЧтобы отказаться используйте /tpc", ["REMOVE.HOME.HELP"] = "Используйте: /removehome название", ["REMOVE.HOME.NONE"] = "Данного дома не существует", ["REMOVE.HOME.SUCCESS"] = "Вы удалили дом под названием {0}", ["FOUNDATION.NOT.FOUND"] = "Фундамент не найден!", ["FOUNDATION.NOT.OWNED"] = "Фундамент не пренадлежит вам или вашим друзьям!", ["FOUNDATION.HOME.INSIDE.BLOCK"] = "Вы не можете создавать дом внутри другого блока!", ["SETHOME.HELP"] = "Используйте: /sethome название", ["BLOOD.OR.WOUNDED"] = "У вас кровотечение или вы упали!", ["HOME.HELP"] = "Используйте: /home название", ["HOME.NOT.FOUND.OR.REMOVED"] = "Точка телепортации ненайдена или была удалена!", ["HOME.NOT.FOUND.BAG"] = "Телепортация невозможна! Спальник не обнаружен!", ["HOME.COOLDOWN"] = "Телепортация была отменена! Причина: кулдаун {0}", ["HOME.REMOVED.INSIDE.BLOCK"] = "Ваш дом '{0}' был удалён потому, что он был внутри фундамента!", ["CAN.TP.SWIMMING"] = "Телепортация в воде запрещена", ["CAN.TP.ALIVE"] = "Телепортация мертвым запрещена", ["CAN.TP.RADIATION"] = "Вы облучены! Телепортация была отменена!", ["CAN.TP.BLEEDING"] = "Вы истекаете кровью! Телепортация отменена!", ["CAN.TP.TEMPERATURE"] = "Вы замерзли! Телепортация отменена!", ["CAN.TP.WOUNDED"] = "Вы получили ранение! Телепортация отменена!", ["CAN.TP.MOUNTED"] = "Вы сидите! Телепортация отменена!", ["CAN.TP.CRAWLING"] = "Вы получили ранение! Телепортация отменена!", ["CAN.TP.BUILDINGBLOCK"] = "Вы находитесь в зоне действия шкафа! Телепортация отменена!", ["SETHOME.ALREADY.EXISTS"] = "Данный дом уже существует", ["SETHOME.CANCEL.RADIUS"] = "У вас уже установлен дом в этом месте!", ["SETHOME.CANCEL.MAXHOUSE"] = "Вы превысили максимальное количество сетхомов!", ["SETHOME.SUCCESS"] = "Вы успешно установили дом {0}", ["HOMELIST.ZERO"] = "У вас нет домов!", ["HOMELIST.FOUND"] = "Список ваших домов: {0}", ["HOME.TELEPORTATION"] = "Вы успешно телепортируетесь на дом.До телепортации {0}", ["REQUEST.CHECK.DISCONNECT"] = "Запрос на телепортацию был отменён! Причина: цель покинула сервер", ["REQUEST.CHECK.DEAD"] = "Запрос на телепортацию был отменён! Причина: цель погибла!", ["REQUEST.CHECK.WOUNDED"] = "Запрос на телепортацию был отменён! Причина: цель упала!", ["REQUEST.CHECK.CRAWLING"] = "Запрос на телепортацию был отменён! Причина: цель упала!", ["REQUEST.CHECK.TIME.ENDED"] = "Запрос на телепортацию был отменён! Причина: окончилось время ожидания!", ["TP.CHECK.BUILD"] = "Телепортация была отменена! Причина: зона шкафа", ["TP.HOME.SUCCESS"] = "Вы успешно были телепортированы домой!", ["TP.PLAYER.SUCCESS"] = "Вы успешно телепортировались к {0}", ["TP.TARGET.SUCCESS"] = "Игрок {0} успешно телепортировался к Вам!", ["MARKER.BAG"] = "<size=24>{0}</size>\n<size=16>{1}</size>", ["MARKER.BAG.NAMEBAG"] = "{0}", ["MARKER.BAG.COOLDOWN"] = "ОТКАТ: {0}", ["MARKER.BAG.NOTCOOLDOWN"] = "ДОСТУПЕН ДЛЯ ТЕЛЕПОРТАЦИИ", ["TELEPORTATION.UI"] = "ДО КОНЦА ТЕЛЕПОРТАЦИИ ОСТАЛОСЬ: {0}", ["PLAYER.NOT.FOUND.PARAM"] = "Игрок {0} был не найден", ["PLAYER.FIND.MULTIPLE"] = "Было найдено несколько игроков: {0}", ["TPR.UI.REQUEST"] = "ЗАПРОС ОТ ИГРОКА {0}", ["TPR.UI.REQUEST.YES"] = "ДА", ["TPR.UI.REQUEST.NO"] = "НЕТ", ["SETHOME.CANCEL.BUILD"] = "Вы не можете установить сетхом в билдинг зоне!"
            }
            , this, "ru");
        }
#endregion
#region Utils
        private string CanTeleportPlayer(BasePlayer player) {
            if (player.IsSwimming() && _config.SettingsResolution.CantTeleportSwimming) return GetMessage(player, "CAN.TP.SWIMMING");
            if (!player.IsAlive()) return GetMessage(player, "CAN.TP.ALIVE");
            if (player.isMounted) return 
// ... [Code preview truncated due to length. Full source in attached file] ...

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

Другие ресурсы пользователя 15FPS

Сверху