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

FREE VehicleLoot : 1.0.0 1.0.0

Нет прав для скачивания
C#:
using System;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
using Oxide.Core.Libraries;
using Oxide.Core;
using Oxide.Core.Configuration;
using Oxide.Core.Plugins;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.SceneManagement;
using Facepunch;
using Newtonsoft.Json;

namespace Oxide.Plugins
{
    [Info("VehicleLoot", "https://topplugin.ru/", "1.0.0")]
    internal class VehicleLoot : RustPlugin
    {																											

		#region Variables				
				
		private static bool Initialize = false;
		private static System.Random Rnd = new System.Random();
		private static LootContainer ToolContainer = null;
		private static int SpawnCounter = 0;
		private static List<bool> SpawnToolMap = new List<bool>();
				
		private static Dictionary<string, List<string>> PartNames = new Dictionary<string, List<string>>()
		{
			{ "low", new List<string>() 
				{
					"carburetor1",
					"crankshaft1",
					"piston1",
					"sparkplug1",
					"valve1"
				} 
			},
			{ "medium", new List<string>() 
				{
					"carburetor2",
					"crankshaft2",
					"piston2",
					"sparkplug2",
					"valve2"
				} 
			},
			{ "high", new List<string>() 
				{
					"carburetor3",
					"crankshaft3",
					"piston3",
					"sparkplug3",
					"valve3"
				} 
			}			
		};
		
		#endregion
	
		#region Hooks
	
		private void Init() 
		{
			SpawnCounter = 0;
			SpawnToolMap.Clear();
			LoadVariables();
			LoadData();
		}
		
		private void OnNewSave()
		{			
			Data.Clear();
			SaveData();
		}
		
		private void OnEntitySpawned(LootContainer loot) 
		{			
			if (!Initialize || loot == null) return;
			ChangeLoot(loot);
		}
		
		private void OnServerInitialized()
        {
			Initialize = true;
			var loots = BaseNetworkable.serverEntities.OfType<LootContainer>().ToList();			
			foreach(var loot in loots) ChangeLoot(loot);						
        }
		
		private void OnServerSave() => SaveData();
		
		private void Unload() => SaveData();
		
		#endregion
		
		#region Main
		
		private void SuppressRefresh(LootContainer container) 
		{			
            container.minSecondsBetweenRefresh = -1;
            container.maxSecondsBetweenRefresh = 0;
            container.GetComponent<FacepunchBehaviour>().CancelInvoke(new Action(container.SpawnLoot));
        }
		
		private static void GenSpawnToolMap()
		{
			SpawnToolMap.Clear();			
			
			for (int ii = 0; ii < configData.CrateToolPercent; ii++)
				SpawnToolMap.Add(true);
			
			for (int ii = configData.CrateToolPercent; ii < 100; ii++)
				SpawnToolMap.Add(false);
			
			SpawnToolMap = SpawnToolMap.OrderBy(x=> Rnd.Next()).ToList();
		}
		
		private void ChangeLoot(LootContainer loot)
		{
			if (loot == null || !loot.ShortPrefabName.Contains("vehicle_parts") || Data.Contains(loot.net.ID)) return;
			
			SuppressRefresh(loot);
			
			if (SpawnCounter % 100 == 0)
				GenSpawnToolMap();
			
			SpawnCounter++;
			
			// время спавнить содержимое ящика с инструментами
			if (SpawnToolMap[SpawnCounter % 100])
			{
				for (int ii=loot.inventory.itemList.ToList().Count-1; ii>=0; ii--)
				{
					var item = loot.inventory.itemList[ii];
					item.RemoveFromContainer();
					item.Remove(0f);
				}
				
				// добавляем инструменты
				var toolItems = GetToolItems();
				
				foreach (var item in toolItems)
				{
					if (loot.inventory.capacity < loot.inventory.itemList.Count+1)
						loot.inventory.capacity++;
					
					item.MoveToContainer(loot.inventory, -1, true);
				}
			}
			else // перезаполняем лут ящика с инструментами под улучшенный пак инструментов
			{
				// чистим все кроме скрапа
				Item scrap = null;
				for (int ii=loot.inventory.itemList.ToList().Count-1; ii>=0; ii--)
				{
					var item = loot.inventory.itemList[ii];
					
					if (item.info.shortname == "scrap")
					{
						item.RemoveFromContainer();
						scrap = item;						
						continue;
					}					
					
					item.RemoveFromContainer();
					item.Remove(0f);
				}
				
				// перемещаем скрап в первую позицию, иначе будет пустота в купе с финтом в конце loot.inventory.capacity = loot.inventory.itemList.Count();
				if (scrap != null)
					scrap.MoveToContainer(loot.inventory, -1, true);
				
				// добавляем запчасти
				int val = Rnd.Next(1, 101);
				int comp = 0;
				var type = "low";
				
				foreach (var pair in configData.SpawnLimit.OrderBy(x=> x.Value))
				{
					if (val <= comp + pair.Value)
					{
						type = pair.Key;
						break;
					}			
					comp += pair.Value;
				}
				
				var part = configData.Parts.FirstOrDefault(x=> x.Type == type);
				int amount = Rnd.Next(part.MinAmount, part.MaxAmount+1);
				
				for (int ii = 0; ii < amount; ii++)
				{
					int condition = Rnd.Next(part.MinCondition, part.MaxCondition+1);
					var itemName = (PartNames[type])[Rnd.Next(0, PartNames[type].Count)];
					var item = ItemManager.CreateByName(itemName, 1);
					item.condition = (item.maxCondition / 100f) * condition;
					
					if (loot.inventory.capacity < loot.inventory.itemList.Count+1)
						loot.inventory.capacity++;
					
					item.MoveToContainer(loot.inventory, -1, true);
				}
			}
						
			loot.inventory.capacity = loot.inventory.itemList.Count();
			Data.Add(loot.net.ID);
		}
		
		private List<Item> GetToolItems()
		{
			if (ToolContainer == null)
			{
				var loot = GameManager.server.CreateEntity("assets/bundled/prefabs/radtown/crate_tools.prefab") as LootContainer;				
				loot.transform.position = new Vector3(0,-1f,0);
				loot.enableSaving = false;
				loot.Spawn();			
				loot.enableSaving = false;				
				ToolContainer = loot;
				SuppressRefresh(loot);
				PrintWarning("Заспавнен эталонный ящик с инструментами");
			}
			
			for (int ii=ToolContainer.inventory.itemList.ToList().Count-1; ii>=0; ii--)
			{
				var item = ToolContainer.inventory.itemList[ii];	
				item.RemoveFromContainer();
				item.Remove(0f);
			}
			
			ToolContainer.PopulateLoot();
			return ToolContainer.inventory.itemList.ToList();
		}
		
		#endregion
		
		#region Command		

		[Oxide.Plugins.ChatCommand("vl.tp")]
        private void TpCommand(BasePlayer player, string command, string[] args)
        {
			if (!player.IsAdmin) return;
			
			var loots = BaseNetworkable.serverEntities.OfType<LootContainer>().Where(b => b.ShortPrefabName.Contains("vehicle_parts")).ToList();
			
			if (loots == null || loots.Count == 0) 
			{
				SendReply(player, "Ящики с запчастями не найдены!");
				return;
			}	
			
            player.Teleport(loots.GetRandom().transform.position); 
        }				
		
		#endregion
		
		#region Config        				
		
        private static ConfigData configData;
		
        private class ConfigData
        {
			[JsonProperty(PropertyName = "Процент ящиков с запчастями, которые будут отданы под ящики с инструментами")]
			public int CrateToolPercent;
			[JsonProperty(PropertyName = "Шкала процентов, часть которой занимает группа запчастей (от 0 до 100)")]
			public Dictionary<string, int> SpawnLimit; 
			[JsonProperty(PropertyName = "Запчасти для машин")]
			public List<Part> Parts;
        }				
		
		private class Part
		{
			[JsonProperty(PropertyName = "Группа запчастей (low, medium, high)")]
			public string Type;
			[JsonProperty(PropertyName = "Минимальная целостность запчасти, в процентах")]
			public int MinCondition;
			[JsonProperty(PropertyName = "Максимальная целостность запчасти, в процентах")]
			public int MaxCondition;
			[JsonProperty(PropertyName = "Минимальное количество запчастей")]
			public int MinAmount;
			[JsonProperty(PropertyName = "Максимальное количество запчастей")]
			public int MaxAmount;
		}
		
        private void LoadVariables() => configData = Config.ReadObject<ConfigData>();        
		
        protected override void LoadDefaultConfig()
        {
            configData = new ConfigData
            {
				CrateToolPercent = 33,
				SpawnLimit = new Dictionary<string, int>()
				{
					{ "low", 60 },
					{ "medium", 30 },
					{ "high", 10 }
				},
				Parts = new List<Part>()
				{
					new Part()
					{
						Type = "low",
						MinCondition = 10,
						MaxCondition = 90,
						MinAmount = 2,
						MaxAmount = 2						
					},
					new Part()
					{
						Type = "medium",
						MinCondition = 10,
						MaxCondition = 70,
						MinAmount = 1,
						MaxAmount = 1						
					},
					new Part()
					{
						Type = "high",
						MinCondition = 10,
						MaxCondition = 70,
						MinAmount = 1,
						MaxAmount = 1						
					}
				}				
            };
            SaveConfig(configData);
			timer.Once(0.1f, ()=> SaveConfig(configData));
        }        
		
        private void SaveConfig(ConfigData config) => Config.WriteObject(config, true);
		
        #endregion				
		
		#region Data
		
		private static HashSet<uint> Data = new HashSet<uint>();
		
		private void LoadData() => Data = Interface.GetMod().DataFileSystem.ReadObject<HashSet<uint>>("VehicleLootData");		
		
		private static void SaveData() => Interface.GetMod().DataFileSystem.WriteObject("VehicleLootData", Data);				
		
		#endregion
		
	}
	
}

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