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

FREE CorpseLocation : 2.2.3 2.2.3

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

namespace Oxide.Plugins
{
    [Info("Corpse Location", "shinnova", "2.2.3")]
    [Description("Allows users to locate their latest corpse")]

    class CorpseLocation : RustPlugin
    {
        #region Variable Declaration
        const string UsePerm = "corpselocation.use";
        const string TPPerm = "corpselocation.tp";
        const string VIPPerm = "corpselocation.vip";
        const string AdminPerm = "corpselocation.admin";
        const float calgon = 0.0066666666666667f;
        float WorldSize = (ConVar.Server.worldsize);
        Dictionary<string, Vector3> InternalGrid = new Dictionary<string, Vector3>();
        Dictionary<string, Timer> ActiveTimers = new Dictionary<string, Timer>();
        #endregion

        #region Config
        Configuration config;
        public class Configuration
        {
            [JsonProperty(PropertyName = "Show grid location")]
            public bool showGrid { get; set; } = true;
            [JsonProperty(PropertyName = "Track a corpse's location for x seconds")]
            public int trackTime { get; set; } = 30;
            [JsonProperty(PropertyName = "Allow teleporting to own corpse x times per day (0 for unlimited)")]
            public int tpAmount { get; set; } = 5;
            [JsonProperty(PropertyName = "Allow teleporting to own corpse x times per day (0 for unlimited), for VIPs")]
            public int viptpAmount { get; set; } = 10;
            [JsonProperty(PropertyName = "Reset players' remaining teleports at this time (HH:mm:ss format)")]
            public string resetTime { get; set; } = "00:00:00";
        }

        protected override void LoadConfig()
        {
            base.LoadConfig();
            try
            {
                config = Config.ReadObject<Configuration>();
                if (config == null)
                    LoadDefaultConfig();
            }
            catch
            {
                LoadDefaultConfig();
            }
            SaveConfig();
        }

        protected override void LoadDefaultConfig()
        {
            Puts("No or faulty config detected.Generating new configuration file");
            config = new Configuration();
        }

        protected override void SaveConfig() => Config.WriteObject(config);
        #endregion

        #region Data
        public class StoredData
        {
            public Dictionary<string, List<float>> deaths = new Dictionary<string, List<float>>();
            public Dictionary<string, int> teleportsRemaining = new Dictionary<string, int>();
            public Dictionary<string, Vector3> GridInfo = new Dictionary<string, Vector3>();
            public StoredData(){}
        }

        StoredData storedData;

        void SaveData() => Interface.Oxide.DataFileSystem.WriteObject("CorpseLocation", storedData);
        #endregion

        #region Hooks
        void OnNewSave(string filename)
        {
            NewData();
        }

        void OnServerInitialized()
        {
            permission.RegisterPermission(UsePerm, this);
            permission.RegisterPermission(TPPerm, this);
            permission.RegisterPermission(VIPPerm, this);
            permission.RegisterPermission(AdminPerm, this);
            storedData = Interface.Oxide.DataFileSystem.ReadObject<StoredData>("CorpseLocation");
            if (storedData == null || storedData.deaths == null)
            {
                Puts("Faulty data detected.Generating new data file");
                NewData();
            }
            if (storedData.GridInfo == null || storedData.GridInfo.Count == 0) CreateGrid();
            InternalGrid = storedData.GridInfo;
            timer.Every(1f, () => {
                if (System.DateTime.Now.ToString("HH:mm:ss") == config.resetTime)
                {
                    foreach (string PlayerID in storedData.teleportsRemaining.Keys)
                        if (permission.UserHasPermission(PlayerID, VIPPerm))
                            storedData.teleportsRemaining[PlayerID] = config.viptpAmount;
                        else
                            storedData.teleportsRemaining[PlayerID] = config.tpAmount;
                    SaveData();
                }
            });
        }
        new void LoadDefaultMessages()
        {
            lang.RegisterMessages(new Dictionary<string, string>
            {
                ["YouDied"] = "Your corpse was last seen {0} meters from here.",
                ["YouDiedGrid"] = "Your corpse was last seen {0} meters from here, in {1}.",
                ["ArrivedAtYourCorpse"] = "You have arrived at your corpse.",
                ["ArrivedAtTheCorpse"] = "You have arrived at the corpse of {0}.",
                ["OutOfTeleports"] = "You have no more teleports left today.",
                ["TeleportsRemaining"] = "You have {0} teleports remaining today.",
                ["UnknownLocation"] = "Your last death location is unknown.",
                ["UnknownLocationTarget"] = "{0}'s last death location is unknown.",
                ["NeedTarget"] = "You need to specify a player to teleport to the corpse of, using either their name or steam id.",
                ["InvalidPlayer"] = "{0} is not part of a known player's name/id.",
                ["NotAllowed"] = "You do not have permission to use that command.",
            }, this);
        }

        void OnPlayerRespawned(BasePlayer player)
        {
            if (storedData.deaths.ContainsKey(player.UserIDString))
                SendCorpseLocation(player);
        }

        void OnEntityDeath(BaseCombatEntity entity, HitInfo info)
        {
            var player = entity as BasePlayer;
            if (player != null)
            {
                if (entity.IsNpc)
                    return;
                string UserID = player.UserIDString;
                Vector3 DeathPosition = entity.transform.position;
                List<float> ShortDeathPosition = new List<float> { DeathPosition.x, DeathPosition.y, DeathPosition.z };
                storedData.deaths[UserID] = ShortDeathPosition;
                SaveData();
                Puts(String.Format("{0} ({1}) died at {2}", player.displayName, UserID, DeathPosition));
            }
        }

        void OnEntitySpawned(BaseNetworkable entity)
        {
            BaseCorpse corpse = entity as BaseCorpse;
            if (corpse != null)
            {
                if (!corpse is PlayerCorpse || !corpse?.parentEnt?.ToPlayer() || corpse.parentEnt.ToPlayer().IsNpc)
                    return;
                BasePlayer player = corpse.parentEnt.ToPlayer();
                string UserID = player.UserIDString;
                if (ActiveTimers.ContainsKey(UserID))
                {
                    ActiveTimers[UserID].Destroy();
                    ActiveTimers.Remove(UserID);
                }
                Timer CorpseChecker = timer.Repeat(1, config.trackTime, () => {
                    if (!corpse.IsDestroyed)
                    {
                        Vector3 BodyLocation = corpse.transform.position;
                        List<float> ShortBodyLocation = new List<float> { BodyLocation.x, BodyLocation.y, BodyLocation.z };
                        storedData.deaths[UserID] = ShortBodyLocation;
                        SaveData();
                    }
                });
                ActiveTimers[UserID] = CorpseChecker;
            }
        }
        #endregion

        #region Functions
        void NewData()
        {
            storedData = new StoredData();
            SaveData();
            CreateGrid();
            InternalGrid = storedData.GridInfo;
        }

        float GetStepSize()
        {
            float GridWidth = (calgon * WorldSize);
            return WorldSize / GridWidth;
        }

        void CreateGrid()
        {
            if (storedData.GridInfo == null)
            {
                Dictionary<string, List<float>> DeathsBackup = storedData.deaths;
                storedData = new StoredData();
                storedData.deaths = DeathsBackup;
            }
            if (storedData.GridInfo.Count > 0) storedData.GridInfo.Clear();
            float offset = WorldSize / 2;
            float step = GetStepSize();
            string start = "";

            char letter = 'A';
            int number = 0;

            for (float zz = offset; zz > -offset; zz -= step)
            {
                for (float xx = -offset; xx < offset; xx += step)
                {
                    Vector3 GridStart = new Vector3(xx, 0, zz);
                    string GridReference = String.Format("{0}{1}{2}", start, letter, number);
                    storedData.GridInfo.Add(GridReference, GridStart);
                    if (letter.ToString().ToUpper() == "Z")
                    {
                        start = "A";
                        letter = 'A';
                    }
                    else
                    {
                        letter = (char)(((int)letter) + 1);
                    }


                }
                number++;
                start = "";
                letter = 'A';
            }
            SaveData();
        }

        string GetGrid(Vector3 DeathLocation)
        {
            string DeathGrid = "the unknown";
            foreach (var Grid in InternalGrid)
            {
                if (DeathLocation.x >= Grid.Value.x && DeathLocation.x < Grid.Value.x + GetStepSize() && DeathLocation.z <= Grid.Value.z && DeathLocation.z > Grid.Value.z - GetStepSize())
                {
                    DeathGrid = Grid.Key;
                    break;
                }
            }
            return DeathGrid;
        }

        void SendCorpseLocation(BasePlayer player)
        {
            List<float> ShortDeathLocation = storedData.deaths[player.UserIDString];
            Vector3 DeathLocation = new Vector3(ShortDeathLocation[0], ShortDeathLocation[1], ShortDeathLocation[2]);
            int DistanceToCorpse = (int)Vector3.Distance(player.transform.position, DeathLocation);
            string DeathGrid = GetGrid(DeathLocation);
            if (config.showGrid)
                SendReply(player, String.Format(lang.GetMessage("YouDiedGrid", this, player.UserIDString), DistanceToCorpse, DeathGrid));
            else
                SendReply(player, String.Format(lang.GetMessage("YouDied", this, player.UserIDString), DistanceToCorpse));
        }

        Dictionary<ulong, string> GetPlayers(string NameOrID)
        {
            var pl = covalence.Players.FindPlayers(NameOrID).ToList();
            return pl.Select(p => new KeyValuePair<ulong, string>(ulong.Parse(p.Id), p.Name)).ToDictionary(x => x.Key, x => x.Value);
        }
        #endregion

        #region Commands
        [ChatCommand("where")]
        void whereCommand(BasePlayer player, string command, string[] args)
        {
            string PlayerID = player.UserIDString;
            if (args.Length > 0 && args[0] == "tp" && permission.UserHasPermission(PlayerID, TPPerm))
            {
                int TPAllowed = config.tpAmount;
                if (permission.UserHasPermission(PlayerID, VIPPerm))
                    TPAllowed = config.viptpAmount;
                if (!storedData.teleportsRemaining.ContainsKey(PlayerID) || storedData.teleportsRemaining[PlayerID] > TPAllowed)
                {
                    storedData.teleportsRemaining[PlayerID] = TPAllowed;
                    SaveData();
                }
                List<float> TargetCorpse = storedData.deaths[PlayerID];
                Vector3 destination = new Vector3(TargetCorpse[0], TargetCorpse[1], TargetCorpse[2]);
                if (TPAllowed == 0)
                {
                    player.Teleport(destination);
                    SendReply(player, String.Format(lang.GetMessage("ArrivedAtYourCorpse", this, PlayerID)));
                }
                else
                {
                    if (storedData.teleportsRemaining[PlayerID] > 0)
                    {
                        player.Teleport(destination);
                        storedData.teleportsRemaining[PlayerID]--;
                        SaveData();
                        SendReply(player, String.Format(lang.GetMessage("ArrivedAtYourCorpse", this, PlayerID)));
                        SendReply(player, String.Format(lang.GetMessage("TeleportsRemaining", this, PlayerID), storedData.teleportsRemaining[PlayerID]));
                    }
                    else
                        SendReply(player, String.Format(lang.GetMessage("OutOfTeleports", this, PlayerID)));   
                }
                return; 
            }
            if (permission.UserHasPermission(PlayerID, UsePerm))
            {
                if (storedData.deaths.ContainsKey(player.UserIDString))
                    SendCorpseLocation(player);
                else
                    SendReply(player, String.Format(lang.GetMessage("UnknownLocation", this, PlayerID)));
            }
            else
                SendReply(player, String.Format(lang.GetMessage("NotAllowed", this, PlayerID)));
        }

        [ChatCommand("tpcorpse")]
        void tpCommand(BasePlayer player, string command, string[] args)
        {
            string PlayerID = player.UserIDString;
            if (permission.UserHasPermission(PlayerID, AdminPerm))
            {
                if (args.Length == 0)
                {
                    SendReply(player, String.Format(lang.GetMessage("NeedTarget", this, PlayerID)));
                    return;
                }
                Dictionary<ulong, string> FoundPlayers = GetPlayers(args[0]);
                if (FoundPlayers.Count == 0)
                {
                    SendReply(player, String.Format(lang.GetMessage("InvalidPlayer", this, PlayerID), args[0]));
                    return;
                }
                string TargetID = FoundPlayers.First().Key.ToString();
                if (storedData.deaths.ContainsKey(TargetID))
                {
                    List<float> TargetCorpse = storedData.deaths[TargetID];
                    Vector3 destination = new Vector3(TargetCorpse[0], TargetCorpse[1], TargetCorpse[2]);
                    player.Teleport(destination);
                    SendReply(player, String.Format(lang.GetMessage("ArrivedAtTheCorpse", this, PlayerID), FoundPlayers.First().Value));
                }
                else
                    SendReply(player, String.Format(lang.GetMessage("UnknownLocationTarget", this, PlayerID), FoundPlayers.First().Value));
            }
            else
                SendReply(player, String.Format(lang.GetMessage("NotAllowed", this, PlayerID)));
        }
        #endregion
    }
}

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