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

FREE OneTimeSpawn : 1.0.1 1.0.1

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

namespace Oxide.Plugins
{
    [Info("OneTimeSpawn", "codeboy", "1.0.1")]
    class OneTimeSpawn : RustPlugin
    {
        #region Classes

        class MonumentAdapter
        {
            public MonoBehaviour Object => (MonoBehaviour)_monumentInfo["Object"];
            public string PrefabName => (string)_monumentInfo["PrefabName"];
            public string ShortName => (string)_monumentInfo["ShortName"];
            public string Alias => (string)_monumentInfo["Alias"];
            public Vector3 Position => (Vector3)_monumentInfo["Position"];
            public Quaternion Rotation => (Quaternion)_monumentInfo["Rotation"];
            public OBB[] BoundingBoxes => (OBB[])_monumentInfo["BoundingBoxes"];

            private Dictionary<string, object> _monumentInfo;

            public MonumentAdapter(Dictionary<string, object> monumentInfo)
            {
                _monumentInfo = monumentInfo;
            }

            public Vector3 TransformPoint(Vector3 localPosition) =>
                ((Func<Vector3, Vector3>)_monumentInfo["TransformPoint"]).Invoke(localPosition);

            public Vector3 InverseTransformPoint(Vector3 worldPosition) =>
                ((Func<Vector3, Vector3>)_monumentInfo["InverseTransformPoint"]).Invoke(worldPosition);

            public Vector3 ClosestPointOnBounds(Vector3 position) =>
                ((Func<Vector3, Vector3>)_monumentInfo["ClosestPointOnBounds"]).Invoke(position);

            public bool IsInBounds(Vector3 position) =>
                ((Func<Vector3, bool>)_monumentInfo["IsInBounds"]).Invoke(position);
        }

        #endregion
        
        #region Fields

        private const string PermissionToUse = "onetimespawn.use";
        
        private MonumentAdapter _cachedMonument;
        
        private List<ulong> _alreadySpawned;
        private BasePlayer.SpawnPoint cachedSpawnpoint = null;

        [PluginReference] private Plugin MonumentFinder;
        #endregion
        
        #region Hooks

        private void OnServerInitialized()
        {
            permission.RegisterPermission(PermissionToUse, this);
            
            LoadData();
            if (cfg.Position == Vector3.zero)
            {
                PrintError("Spawn position is (0, 0, 0). Please install position via command /spawnpos when you have ownerid");
                PrintError("Spawn position is (0, 0, 0). Please install position via command /spawnpos when you have ownerid");
                PrintError("Spawn position is (0, 0, 0). Please install position via command /spawnpos when you have ownerid");
                PrintError("Spawn position is (0, 0, 0). Please install position via command /spawnpos when you have ownerid");
                PrintError("Spawn position is (0, 0, 0). Please install position via command /spawnpos when you have ownerid");
                return;
            }

            if (HasLinkedMonument() && !MonumentFinder)
            {
                PrintError("MonumentFinder plugin is not installed. Please install it or remove link to monument in config");
                PrintError("MonumentFinder plugin is not installed. Please install it or remove link to monument in config");
                PrintError("MonumentFinder plugin is not installed. Please install it or remove link to monument in config");
                
                Interface.Oxide.UnloadPlugin(Title);
                return;
            }

            SetupSpawnpoint(isServerStart:true);
        }

        private void OnNewSave()
        {
            if (cfg.WipeData)
            {
                PrintWarning("Players data was successfully wiped with server wipe!");
                _alreadySpawned.Clear();
                SaveData();
            }

            if (cfg.DeleteSpawnPositionOnMapWipe)
            {
                PrintWarning("Spawnpoint was wiped with server wipe! Please, install new position with command /spawnpos and reload plugin");
                cfg.Position = Vector3.zero;
                SaveConfig();
                cachedSpawnpoint = null;
            }
        }
        
        private void Unload() => SaveData();
        private void OnServerSave() => SaveData();
        
        private object OnPlayerRespawn(BasePlayer player, BasePlayer.SpawnPoint spawnPoint)
        {
            if (cachedSpawnpoint == null)
                return null;

            if (!_alreadySpawned.Contains(player.userID))
            {
                _alreadySpawned.Add(player.userID);
                return cachedSpawnpoint;
            }
            return null;
        }
        private bool HasLinkedMonument() => !string.IsNullOrEmpty(cfg.LinkToMonument);

        private bool IsValidLinkedMonument()
        {
            if (string.IsNullOrEmpty(cfg.LinkToMonument))
                return true;
            return GetLinkedMonument() != null;
        }

        private Vector3 SetupSpawnpoint(Vector3 pos = default, BasePlayer reply = null, bool isServerStart = false)
        {
            Vector3 toSave = pos;
    
            if (isServerStart)
            {
                toSave = cfg.Position;
        
                if (HasLinkedMonument() && IsValidLinkedMonument())
                {
                    var mon = GetLinkedMonument();
                    pos = mon.TransformPoint(toSave);
                }
                else
                {
                    pos = toSave;
                }
            }
            else
            {
                if (HasLinkedMonument())
                {
                    if (!IsValidLinkedMonument())
                    {
                        PrintError("Linked monument is not found. Please, check monument name in config");
                        return default;
                    }

                    var mon = GetLinkedMonument();
                    toSave = mon.InverseTransformPoint(pos);
                }
                else
                {
                    if (pos == default)
                        pos = cfg.Position;
                }
            }
    
            cachedSpawnpoint = new()
            {
                pos = pos,
                rot = default
            };
    
            if (reply != null)
                reply.ChatMessage($"Spawnpoint was successfully installed! Position: {pos.ToString()}. {(HasLinkedMonument() ? "Linked monument" : "No Linked monument")}");
            else
                PrintWarning($"Spawnpoint was successfully installed! Position: {pos.ToString()}. {(HasLinkedMonument() ? "Linked monument" : "No Linked monument")}");
    
            return toSave;
        }
        
        private MonumentAdapter? GetLinkedMonument()
        {
            if (_cachedMonument != null)
                return _cachedMonument;
            
            if (string.IsNullOrEmpty(cfg.LinkToMonument))
                return null;
            
            var monument = (List<Dictionary<string, object>>)MonumentFinder?.Call("API_Find", cfg.LinkToMonument)!;
            if (monument.IsNullOrEmpty())
                return null;
            
            _cachedMonument = new(monument[0]);
            return _cachedMonument;
        }
        #endregion

        #region Commands
        
        [ChatCommand("spawnpos")]
        private void cmdSpawnPos(BasePlayer player)
        {
            if (player == null)
                return;
            if (!player.IsAdmin && !permission.UserHasPermission(player.UserIDString, PermissionToUse))
                return;

            cfg.Position = SetupSpawnpoint(player.GetNetworkPosition(), player, false);
            SaveConfig(cfg);
        }
        #endregion

        #region Config

        private ConfigData cfg;

        public class ConfigData
        {
            [JsonProperty("Spawn position")] public Vector3 Position;

            [JsonProperty("Wipe already spawned players on map wipe?")]
            public bool WipeData;

            [JsonProperty("Delete spawn position on map wipe?")]
            public bool DeleteSpawnPositionOnMapWipe;

            [JsonProperty("Link to monument (requires MonumentFinder plugin). If not empty, Spawn position will be set as offset from monument center")]
            public string LinkToMonument;
        }

        protected override void LoadDefaultConfig()
        {
            var config = new ConfigData()
            {
                Position = Vector3.zero,
                WipeData = false,
                DeleteSpawnPositionOnMapWipe = false,
                LinkToMonument = ""
            };
            SaveConfig(config);
        }

        protected override void LoadConfig()
        {
            base.LoadConfig();
            cfg = Config.ReadObject<ConfigData>();
            SaveConfig(cfg);
        }

        private void SaveConfig(object config)
        {
            Config.WriteObject(config, true);
        }
        #endregion

        #region Data

        private void SaveData()
        {
            Interface.Oxide.DataFileSystem.WriteObject($"{Title}/alreadySpawned", _alreadySpawned);
        }

        void LoadData()
        {
            _alreadySpawned = Interface.Oxide?.DataFileSystem?.ReadObject<List<ulong>>($"{Title}/alreadySpawned")
                      ?? new();
        }

        #endregion
    }
}

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