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

FREE RandomSpawns : 1.1.0 1.1.0

Нет прав для скачивания
C#:
using System;
using System.Collections.Generic;
using UnityEngine;
using System.Reflection;
using System.Linq;

namespace Oxide.Plugins
{
    [Info("RandomSpawns", "S1m0n", "1.1.0")]
    class RandomSpawns : RustPlugin
    {
        #region Fields
        private bool Disabled;
        private int spawnCount;
        private Hash<string, List<Vector3>> spawnPoints = new Hash<string, List<Vector3>>();
        private static readonly Collider[] colBuffer = (Collider[])typeof(Vis).GetField("colBuffer", (BindingFlags.Static | BindingFlags.NonPublic))?.GetValue(null);
        System.Random random = new System.Random();
        #endregion

        #region Oxide Hooks
        [ChatCommand("showspawns")]
        void cmdShowSpawns(BasePlayer player, string command, string[] args)
        {
            if (!player.IsAdmin) return;           
            SendReply(player, "Total spawn count: " + spawnCount);
            foreach (var list in spawnPoints.Values)
            {
                foreach (var position in list)
                    player.SendConsoleCommand("ddraw.box", 30f, Color.magenta, position, 1f);
            }
        }
        
        void OnServerInitialized()
        {           
            Disabled = true;
            LoadVariables();
            GenerateSpawnpoints();
        }
        BasePlayer.SpawnPoint OnFindSpawnPoint()
        {
            if (Disabled) return null;
            if (BasePlayer.activePlayerList.Count < configData.MinimumPlayersToActivate)
                return null;

            string biome = configData.SpawnAreas.Where(x => x.Value == true).ToList().GetRandom().Key.ToLower();
            var targetpos = GetSpawnPoint(biome);
            if (targetpos == null)
                return null;

            BasePlayer.SpawnPoint spawnPoint1 = new BasePlayer.SpawnPoint();
            spawnPoint1.pos = (Vector3)targetpos;
            spawnPoint1.rot = new Quaternion(0f, 0f, 0f, 1f);
            return spawnPoint1;
        }
        string GetMajorityBiome(Vector3 position)
        {
            Dictionary<string, float> biomes = new Dictionary<string, float>
            {
                {"arctic", TerrainMeta.BiomeMap.GetBiome(position, TerrainBiome.ARCTIC) },
                {"arid", TerrainMeta.BiomeMap.GetBiome(position, TerrainBiome.ARID) },
                {"temperate", TerrainMeta.BiomeMap.GetBiome(position, TerrainBiome.TEMPERATE) },
                {"tundra", TerrainMeta.BiomeMap.GetBiome(position, TerrainBiome.TUNDRA) }
            };
            return biomes.OrderByDescending(x => x.Value).ToArray()[0].Key;           
        }
        #endregion

        #region Functions
        private object GetSpawnPoint(string biome = "")
        {            
            if (string.IsNullOrEmpty(biome))
                biome = spawnPoints.ElementAt(random.Next(0, 3)).Key;

            Vector3 targetPos = spawnPoints[biome.ToLower()].GetRandom();

            var entities = Physics.OverlapSphereNonAlloc(targetPos, 10f, colBuffer, LayerMask.GetMask("Construction"));
            if (entities > 0)
            {
                spawnPoints[biome].Remove(targetPos);
                -- spawnCount;
                if (spawnCount < 10)
                {
                    PrintWarning("All current spawnpoints have been overrun by buildings and such.Disabling custom spawnpoints");
                    Disabled = true;
                    return null;
                }
                return GetSpawnPoint();
            }
            return targetPos;
        }
        private void GenerateSpawnpoints()
        {
            PrintWarning("Generating spawnpoints.This may take a moment");
            for (int i = 0; i < 1500; i++)
            {
                float max = TerrainMeta.Size.x / 2;
                var success = FindNewPosition(new Vector3(0,0,0), max);
                if (success is Vector3)
                {
                    Vector3 spawnPoint = (Vector3)success;
                    float height = TerrainMeta.HeightMap.GetHeight(spawnPoint);
                    if (spawnPoint.y >= height && !(spawnPoint.y - height > 1))
                    {
                        string biome = GetMajorityBiome(spawnPoint);
                        if (!spawnPoints.ContainsKey(biome))
                            spawnPoints.Add(biome, new List<Vector3>());
                        spawnPoints[biome].Add(spawnPoint);
                    }
                }
            }            
            foreach (var biome in spawnPoints)
                spawnCount += biome.Value.Count;
            PrintWarning($"{spawnCount} spawn points generated!");
            Disabled = false;
        }
        Vector3 CalculatePoint(Vector3 position, float max)
        {
            var angle = Math.PI * 2.0f * random.NextDouble();
            var radius = Math.Sqrt(random.NextDouble()) * max;
            var x = position.x + radius * Math.Cos(angle);
            var y = position.y + radius * Math.Sin(angle);
            return new Vector3((float)x, 300, (float)y);
        }
        object FindNewPosition(Vector3 position, float max, bool failed = false)
        {
            var targetPos = UnityEngine.Random.insideUnitCircle * max;
            var sourcePos = new Vector3(position.x + targetPos.x, 300, position.z + targetPos.y);
            var hitInfo = RayPosition(sourcePos);
            var success = ProcessRay(hitInfo);
            if (success == null)
            {
                if (failed) return null;
                else return FindNewPosition(position, max, true);
            }
            else if (success is Vector3)
            {
                if (failed) return null;
                else return FindNewPosition(new Vector3(sourcePos.x, ((Vector3)success).y, sourcePos.y), max, true);
            }
            else
            {
                sourcePos.y = Mathf.Max((float)success, TerrainMeta.HeightMap.GetHeight(sourcePos));
                return sourcePos;
            }
        }
        private object ProcessRay(RaycastHit hitInfo)
        {
            if (hitInfo.collider != null)
            {
                if (hitInfo.collider?.gameObject.layer == UnityEngine.LayerMask.NameToLayer("Water"))
                    return null;
                if (hitInfo.collider?.gameObject.layer == UnityEngine.LayerMask.NameToLayer("Prevent Building"))
                    return null;
                if (hitInfo.GetEntity() != null)
                {
                    return hitInfo.point.y;
                }
                if (hitInfo.collider?.name == "areaTrigger")
                    return null;
                if (hitInfo.collider?.GetComponentInParent<SphereCollider>() || hitInfo.collider?.GetComponentInParent<BoxCollider>())
                {
                    return hitInfo.collider.transform.position + new Vector3(0, -1, 0);
                }               
            }
            return hitInfo.point.y;
        }

        RaycastHit RayPosition(Vector3 sourcePos)
        {
            RaycastHit hitInfo;
            Physics.Raycast(sourcePos, Vector3.down, out hitInfo);//, LayerMask.GetMask("Terrain", "World", "Construction"));

            return hitInfo;
        }
        #endregion

        #region Config        
        private ConfigData configData;
        class ConfigData
        {
            public Dictionary<string, bool> SpawnAreas { get; set; }
            public int MinimumPlayersToActivate { get; set; }
        }
        private void LoadVariables()
        {
            LoadConfigVariables();
            SaveConfig();
        }
        protected override void LoadDefaultConfig()
        {
            var config = new ConfigData
            {
                SpawnAreas = new Dictionary<string, bool>
                {
                    { "Arid", true },
                    { "Arctic", true },
                    { "Temperate", true },
                    { "Tundra", true },
                },
                MinimumPlayersToActivate = 1
            };
            SaveConfig(config);
        }
        private void LoadConfigVariables() => configData = Config.ReadObject<ConfigData>();
        void SaveConfig(ConfigData config) => Config.WriteObject(config, true);
        #endregion
    }
}

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

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

Сверху