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

FREE TreeLimit : 1.0.5 1.0.5

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

namespace Oxide.Plugins
{
    [Info("TreeLimit", "Nimant", "1.0.5")]    
    public class TreeLimit : RustPlugin
    {						
		
		#region Variables
		
		private static float MinDistance = 6f * 6f;
		private static bool WasRestart = false;
		
		private static Dictionary<string, int> SaveTreeLimit = new Dictionary<string, int>()
		{
			{ "v2_temp_forest", 10000 },
			{ "v2_temp_forest_small", 10000 },
			{ "v2_tundra_forest", 10000 },
			{ "v2_tundra_forest_small", 2000 },
			{ "v2_arctic_forest", 1500 },
			{ "v2_arctic_forest_snow", 3500 },
			{ "v2_arid_cactus", 2000 },
			{ "v2_arid_palms_dense", 3000 },
			{ "v2_arid_palms_light", 600 },
			{ "v2_arid_palms_superdense", 10000 },
			{ "v2_temp_beachforest_small", 5000 },
			{ "v2_temp_field_small", 1750 },
			{ "v2_arid_palm_beach", 8000 },
			{ "v2_temp_field_large", 100 },
			{ "v2_temp_forest_deciduous", 10000 },
			{ "v2_temp_forest_small_deciduous", 10000 }		
		};
		
		private class TreeInfo
		{
			public TreeEntity tree;
			public Vector2 pos;
			public bool isNeedDel;
		}
		
		#endregion
		
		#region Hooks
	
		private void Init() 
		{
			LoadVariables();
			MinDistance = configData.MinDistance * configData.MinDistance;
		}

		private void OnTerrainInitialized() => WasRestart = true;		
		
		private void OnServerInitialized() 
		{				
			if (!WasRestart) return;
			WasRestart = false;
			timer.Once(configData.StartClearTime, ()=> ReFillTree());
		}
		
		#endregion
		
		#region Main
		
		private void ReFillTree() => ServerMgr.Instance.StartCoroutine(SpawnFill());
		
		private IEnumerator SpawnFill()
        {
			Puts($"Поиск близко стоящих деревьев");
			
            var allSpawnPopulations = SpawnHandler.Instance.AllSpawnPopulations;
            SpawnHandler.Instance.StopCoroutine("SpawnTick");            
                        			
			SpawnDistribution[] spawndists = SpawnHandler.Instance.SpawnDistributions;
			for (int i = 0; i < allSpawnPopulations.Length; i++)
			{
				if (!(allSpawnPopulations[i] == null) && allSpawnPopulations[i].name.Contains("v2_"))
				{
					if (allSpawnPopulations[i]._targetDensity <= 1f && SaveTreeLimit.ContainsKey(allSpawnPopulations[i].name))
						allSpawnPopulations[i]._targetDensity = SaveTreeLimit[allSpawnPopulations[i].name];
					
					allSpawnPopulations[i]._targetDensity = (float)Math.Round((configData.DensityPercent/100f) * allSpawnPopulations[i]._targetDensity);					
					SpawnHandler.Instance.SpawnInitial(allSpawnPopulations[i], spawndists[i]);					
				}
			}			
            
            SpawnHandler.Instance.StartCoroutine("SpawnTick");						
			
			var trees_ = BaseNetworkable.serverEntities.OfType<TreeEntity>().ToList();	
			var trees = trees_.Select(x=> new TreeInfo() { tree = x, isNeedDel = false, pos = new Vector2(x.transform.position.x, x.transform.position.z) }).ToList();
			int tCount = trees.Count, gIndex = 0;
			int lastPerc = -1;
						
			for (int ii = 0; ii < tCount; ii++)
			{
				if (trees[ii].tree != null && !trees[ii].isNeedDel)
				{
					for (int jj = ii + 1; jj < tCount; jj++)
					{
						if (trees[ii].tree == null || trees[ii].isNeedDel || trees[jj].tree == null || trees[jj].isNeedDel) continue; 
						
						if ((trees[ii].pos - trees[jj].pos).sqrMagnitude <= MinDistance)
							trees[jj].isNeedDel = true;
						
						gIndex++;
						
						if (gIndex % 150000 == 0)
							yield return new WaitForEndOfFrame();
					}
				}
				
				var perc = (int)Math.Round((100f * ii) / tCount);
					
				if (lastPerc != perc)
				{
					if (perc % 10 == 0)
						Puts($"обработано {perc}%");
					
					lastPerc = perc;					
				}
			}
			
			Puts($"Поиск близко стоящих деревьев завершен");
			Puts($"Удаление близко стоящих деревьев [было {trees_.Count()} шт]");	
			
			gIndex = 0;
			foreach(var info in trees.Where(x=> x.isNeedDel && x.tree != null && !x.tree.IsDestroyed))
			{
				info.tree.Kill();
				
				if (gIndex % 150 == 0)
					yield return new WaitForEndOfFrame();
				
				gIndex++;
			}						

			trees_ = BaseNetworkable.serverEntities.OfType<TreeEntity>().ToList();	
			Puts($"Удаление близко стоящих деревьев завершено [стало {trees_.Count()} шт]");
        }
		
		#endregion
		
		#region Commands
		
		[ConsoleCommand("tl.count")] 
		private void CmdTreeCount(ConsoleSystem.Arg arg)
        {
            if (arg.Player() != null) return;        
			var trees = BaseNetworkable.serverEntities.OfType<TreeEntity>().ToList();	
			Puts($"Всего деревьев на сервере: {trees.Count()}");
        }
		
		[ConsoleCommand("tl.refill")] 
		private void CmdReFillTree(ConsoleSystem.Arg arg)
        {
            if (arg.Player() != null) return;  
			ReFillTree();
        }
		
		#endregion
		
		#region Config        				
		
        private static ConfigData configData;
		
        private class ConfigData
        {
			[JsonProperty(PropertyName = "Задержка запуска чистки после старта сервера (секунды)")]
			public float StartClearTime;
			[JsonProperty(PropertyName = "Минимальное расстояние между деревьями (метры)")]
			public float MinDistance;
			[JsonProperty(PropertyName = "Какой процент деревьев от оригинала оставить")]
			public float DensityPercent;
        }
		
        private void LoadVariables() => configData = Config.ReadObject<ConfigData>();        
		
        protected override void LoadDefaultConfig()
        {
            configData = new ConfigData
            {
				StartClearTime = 30f,
                MinDistance = 6f,
				DensityPercent = 30f
            };
            SaveConfig(configData);
			timer.Once(0.1f, ()=> SaveConfig(configData));
        }        
		
        private void SaveConfig(ConfigData config) => Config.WriteObject(config, true);
		
        #endregion				
		
    }
}

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