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

FREE PilotEject : 2.0.4 2.0.4

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

namespace Oxide.Plugins 
{
	[Info("PilotEject", "redBDGR", "2.0.4")] 
	[Description("A special helicopter event")]
	class PilotEject : RustPlugin 
	{
		[PluginReference] Plugin GUIAnnouncements;

		private bool useGUIAnnouncements; 
		private static PilotEject plugin; 
		private const string permissionName = "piloteject.admin"; 
		private float arrowHeight = 200f; 
		private float arrowLength = 120f;
		private float chanceOfOccuring = 0.20f;
		private bool changed;
		private bool inboundMessage = true;
		private bool killMSG = true;
		private float maxEventTime = 3600f;
		private float maxTimeToEvent = 600.0f;
		private float minEventTime = 1800f;
		private float minimumSpawnHeight = 20f; 
		private bool minimumSpawnHeightEnabled;
		private float minTimeToEvent = 300.0f;
		private bool pilotArrow = true; 
		private float pilotLifeLength = 600f; 
		private int customCratesToDrop = 3;
		private bool randomEventEnabled = true;
		private int minHelicoptersBeforeNextEvent = 0;
		private float pilotFallSpeed = 1;
		
		private Timer repeat;
		private StoredData storedData; 
		private DynamicConfigFile InventoryData;

		private float time;
		private bool timedEventEnabled = true; 
		private bool truePVEPilotDamageable;
		private int heliCount = 0;

		private Dictionary<string, PilotInfo> pilotData = new Dictionary<string, PilotInfo>();
		private List<BaseHelicopter> helis = new List<BaseHelicopter>();
		private List<EjectedPlayer> pilots = new List<EjectedPlayer>();

		private class StoredData 
		{
			public Dictionary<string, PilotInfo> pilotData = new Dictionary<string, PilotInfo>();
		}

		private class PilotInfo 
		{
			public string displayName;
			public List<ItemInfo> beltItems;
			public List<ItemInfo> clothingItems;
			public List<ItemInfo> inventoryItems;
			public float chance; 
			public float health; 
			public bool dropItems; 
			public bool wounded; 
		} 
		
		private class ItemInfo 
		{
			public int amount;
			public float chance;
			public string shortname;
			public ulong skinId;
		}

		private void SaveData() 
		{
			storedData.pilotData = pilotData;
			InventoryData.WriteObject(storedData);
		}

		private void LoadData() 
		{
			try 
			{
				storedData = InventoryData.ReadObject<StoredData>();
				pilotData = storedData.pilotData; 
			}
			catch 
			{
				Puts("Failed to load data, creating new file");
				storedData = new StoredData(); 
			} 
		} 
		
		private void LoadVariables() 
		{
			minTimeToEvent = Convert.ToSingle(GetConfig("Settings", "Min Time Until Pilot Eject", 300.0f));
			maxTimeToEvent = Convert.ToSingle(GetConfig("Settings", "Max Time Until Pilot Eject", 600.0f));
			killMSG = Convert.ToBoolean(GetConfig("Settings", "Pilot Death Message Enabled", true));
			pilotLifeLength = Convert.ToSingle(GetConfig("Settings", "Pilot Life Length", 600f)); 
			minimumSpawnHeight = Convert.ToSingle(GetConfig("Settings", "Pilot Minimum Spawn Height", 20f));
			minimumSpawnHeightEnabled = Convert.ToBoolean(GetConfig("Settings", "Min Spawn Height Enabled", false));
			inboundMessage = Convert.ToBoolean(GetConfig("Settings", "Inbound Message", true));
			customCratesToDrop = Convert.ToInt32(GetConfig("Settings", "Number of Crates to Spawn", 3));
			truePVEPilotDamageable = Convert.ToBoolean(GetConfig("Settings", "(TruePVP) Pilot Is Damageable", true));
			useGUIAnnouncements = Convert.ToBoolean(GetConfig("Settings", "Use GUIAnnouncements", false));
			pilotArrow = Convert.ToBoolean(GetConfig("Arrow Settings", "Arrow Above Pilot", true));
			arrowHeight = Convert.ToSingle(GetConfig("Arrow Settings", "Arrow Height", 200f));
			arrowLength = Convert.ToSingle(GetConfig("Arrow Settings", "Arrow Length (seconds)", 120f)); 
			timedEventEnabled = Convert.ToBoolean(GetConfig("Timed Event Settings", "Timed Helicopter Enabled", false));
			minEventTime = Convert.ToSingle(GetConfig("Timed Event Settings", "Min Time Until Next Event", 1800f)); 
			maxEventTime = Convert.ToSingle(GetConfig("Timed Event Settings", "Max Time Until Next Event", 3600f)); 
			randomEventEnabled = Convert.ToBoolean(GetConfig("Random Event Settings", "Chance of helicopter being event heli (external helicopters only)", true));
			chanceOfOccuring = Convert.ToSingle(GetConfig("Random Event Settings", "Chance Of Occuring", 0.20f));
			minHelicoptersBeforeNextEvent = Convert.ToInt32(GetConfig("Random Event Settings", "Min Helicopters Between Random Event", 0));

			if (!changed) return;
			SaveConfig();
			changed = false; 
		} 
		
		protected override void LoadDefaultConfig() 
		{
			Config.Clear(); 
			LoadVariables(); 
		} 
		
		private void Init() 
		{
			plugin = this;
			LoadVariables();
			InventoryData = Interface.Oxide.DataFileSystem.GetFile("PilotEject");
			LoadData(); 
			
			permission.RegisterPermission(permissionName, this);
			if (timedEventEnabled) timer.Repeat(Random.Range(minEventTime, maxEventTime), 0, CallBrokenHeli);

			lang.RegisterMessages(new Dictionary<string, string> 
			{
                ["Heli Malfunctioned"] = "Патрульный вертолёт вышел из строя! Пилоту пришлось спрыгнуть с вертолёта на парашюте.Найди его и забери его лут!",
                ["No Permission"] = "У вас нет доступа к этой команде.",
                ["Pilot Killed"] = "Пилот был убит игроком <color=#ffd479>{0}</color>",
                ["Pilot Inventory Set"] = "Инвентарь пилота успешно сохранён.",
                ["Malfunction Timer Warning (Console)"] = "Патрульный вертолёт выйдет из строя через {0} секунд",
                ["Broken Heli Inbound"] = "Вертолёт сильно повреждён!",
				["setpilot Invalid Syntax"] = "Неправильный синтаксис!\nДоступная команда:\n/setpilot <add/remove/set> <name>"
			}, this);

			foreach (BasePlayer player in BasePlayer.activePlayerList)
			if (permission.UserHasPermission(player.UserIDString, "playerwake.notify")) player.ChatMessage("msg"); 
		} 
		
		private void Unload() { } 
		private void OnServerSave() 
		{
			SaveData(); 
		}

		private void OnEntityDeath(BaseCombatEntity entity, HitInfo info) 
		{
			if (!entity || info == null) return;
			BaseHelicopter heli = entity.GetComponent<BaseHelicopter>();
			if (heli) 
			{
				if (helis.Contains(heli)) helis.Remove(heli); 
				return; 
			} 
			EjectedPlayer pilot = entity.GetComponent<EjectedPlayer>(); 
			if (pilot == null) return;
			BasePlayer player = info.InitiatorPlayer;
			if (player) 
				if (killMSG) 
				{
					if (useGUIAnnouncements) 
						SendGlobaGUIAnnouncement(string.Format(msg("Pilot Killed"), player.displayName));
					else 
						rust.BroadcastChat(null, string.Format(msg("Pilot Killed"), player.displayName)); 
				} 
		} 
		
		private void OnEntitySpawned(BaseNetworkable entity) 
		{
			BaseHelicopter heli = entity.GetComponent<BaseHelicopter>();
			if (!heli) 
			{
				PlayerCorpse corpse = entity.GetComponent<PlayerCorpse>();
				if (!corpse) return; 
				if (corpse.playerSteamID.ToString().StartsWith("76561198")) return;
				PilotInfo data = null; 
				try 
				{
					if (!pilotData.TryGetValue(corpse.playerName, out data)) return; 
				} 
				catch(Exception e) 
				{
					Puts($"Pilot {corpse.playerName} tried to spawn it's inventory but no inventory was found!"); 
					return; 
				} 
				timer.Once(0.5f, () => GiveItems(corpse, data)); 
				return; 
			} 
			
			if (heliCount != minHelicoptersBeforeNextEvent) 
			{
				heliCount++; 
				return; 
			} 
			timer.Once(0.1f, () => 
			{
				if (heli == null) return;
				if (helis.Contains(heli)) return; 
				if (randomEventEnabled) 
				{
					float rng = Random.Range(0f, 1f);
					if (rng > chanceOfOccuring) return;
					TriggerEventStart(heli);
					return; 
				}
				else 
				{
					TriggerEventStart(heli); 
				} 
			}); 
		} 
		
		private object CanEntityTakeDamage(BaseCombatEntity entity, HitInfo info) 
		{
			if (!truePVEPilotDamageable) return null;
			EjectedPlayer player = entity.GetComponent<EjectedPlayer>();
			if (player == null) return null;
			info.damageTypes.Scale(Rust.DamageType.Heat, 0);
			if (pilots.Contains(player)) return true;
			return null; 
		}

		object OnNpcPlayerResume(NPCPlayerApex player) 
		{
			EjectedPlayer pilot = player.GetComponent<EjectedPlayer>();
			if (!pilot) return null;
			if (pilot.isGrounded) return null;
			return false; 
		}

		private class EjectHelicopter : FacepunchBehaviour 
		{
			private BaseHelicopter heli;
			private List<Scientist> pilots = new List<Scientist>();
			private float eventTime;
			private bool eventTriggered;
			private bool isOverWater = true;
			private bool spawnHeightEnabled = plugin.minimumSpawnHeightEnabled;
			private float minSpawnHeight = plugin.minimumSpawnHeight;
			private void Awake() 
			{
				heli = GetComponent<BaseHelicopter>();
				eventTime = UnityEngine.Time.time + Random.Range(plugin.minTimeToEvent, plugin.maxTimeToEvent);
				plugin.Puts(string.Format(plugin.msg("Malfunction Timer Warning (Console)"), eventTime - UnityEngine.Time.time));
				if (plugin.inboundMessage) 
				{
					if (plugin.useGUIAnnouncements) 
						plugin.SendGlobaGUIAnnouncement(plugin.msg("Broken Heli Inbound"));
					else
						plugin.rust.BroadcastChat(null, plugin.msg("Broken Heli Inbound")); 
				}
				InvokeRepeating(UpdateWaterCheck, 10f, 1f); 
			}

			private void Update() 
			{
				if (eventTriggered == false) 
					if (UnityEngine.Time.time >= eventTime) 
					{
						if (isOverWater) return; StartEvent(); 
					} 
			} 
			
			private void OnDestroy() 
			{
				CancelInvoke(UpdateWaterCheck);
				foreach (Scientist pilot in pilots) 
				pilot.GetComponent<EjectedPlayer>().heliCrashPos = new Vector3(transform.position.x + UnityEngine.Random.Range(-5f, 5f), TerrainMeta.HeightMap.GetHeight(transform.position), transform.position.z + UnityEngine.Random.Range(-5f, 5f)); 
			}

			private void StartEvent() 
			{
				eventTriggered = true;
				if (heli) 
				{
					if (plugin.useGUIAnnouncements) 
						plugin.SendGlobaGUIAnnouncement(plugin.msg("Heli Malfunctioned")); 
					else 
						plugin.rust.BroadcastChat(null, plugin.msg("Heli Malfunctioned"));

					heli.Hurt(heli.health - 10.0f);
					heli.maxCratesToSpawn = plugin.customCratesToDrop;
					SpawnNPCs();
					heli.Hurt(heli.health);
				} 
			} 
			
			private void UpdateWaterCheck() 
			{
				bool x = WaterLevel.GetWaterInfo(new Vector3(transform.position.x, TerrainMeta.HeightMap.GetHeight(transform.position), transform.position.z)).isValid;
				if (isOverWater == true && x == false) 
					if (UnityEngine.Time.time >= eventTime) 
						eventTime = UnityEngine.Time.time + 10f;
					isOverWater = x; 
			} 
			
			private void SpawnNPCs() 
			{
				foreach (var entry in plugin.pilotData) 
				CreatePilot(entry.Value); 
			} 
			
			private void CreatePilot(PilotInfo data) 
			{
				Vector3 pos = transform.position;
				pos = new Vector3(pos.x + UnityEngine.Random.Range(-5f, 5f), pos.y, pos.z + UnityEngine.Random.Range(-5f, 5f));
				if (spawnHeightEnabled) 
					if (pos.y < minSpawnHeight) 
						pos = new Vector3(pos.x, minSpawnHeight, pos.z);
					Scientist pilot = GameManager.server.CreateEntity("assets/prefabs/npc/scientist/scientist.prefab", pos).GetComponent<Scientist>();
					pilot.Pause();
					pilot.CommunicationRadius = 0f;
					pilot.Spawn();
					pilot.GetComponent<NPCPlayer>().enabled = false;
					pilots.Add(pilot);
					pilot.displayName = data.displayName;
					pilot.health = data.health;
					pilot.SendNetworkUpdateImmediate();
					GiveItems(pilot.GetComponent<BasePlayer>(), data);
					EjectedPlayer ep = pilot.gameObject.AddComponent<EjectedPlayer>();
					ep.data = data; 
			} 
			
			private void GiveItems(BasePlayer player, PilotInfo data) 
			{
				foreach (var item in data.clothingItems) 
				if (Random.Range(0f, 1f) < item.chance) 
				{
					var newitem = ItemManager.CreateByName(item.shortname, item.amount, item.skinId);
					if (newitem == null) continue;
					newitem.MoveToContainer(player.inventory.containerWear); 
				} 
			} 
		} 
		
		private class EjectedPlayer : FacepunchBehaviour 
		{
			private BasePlayer player;
			public NPCPlayerApex npc;
			public PilotInfo data;
			public bool isGrounded;
			public Vector3 groundPos;
			private BaseEntity chute;
			private float deathTime;
			public Vector3 heliCrashPos;
			private bool doDraws = plugin.pilotArrow;
			private float lifeLength = plugin.pilotLifeLength;
			private void Awake() 
			{
				player = GetComponent<BasePlayer>();
				npc = player.GetComponent<NPCPlayerApex>();
				plugin.pilots.Add(this);
				groundPos = new Vector3(transform.position.x, TerrainMeta.HeightMap.GetHeight(transform.position), transform.position.z);
				deathTime = UnityEngine.Time.time + lifeLength;
				InitChute();
			}
			private void Update() 
			{
				if (isGrounded == false) 
				{
					transform.position = new Vector3(transform.position.x, transform.position.y - 0.015f * plugin.pilotFallSpeed, transform.position.z);
					npc?.SendNetworkUpdateImmediate();
					if (Vector3.Distance(transform.position, groundPos) < 0.15f) 
					{
						OnLanded(); 
					} 
				} 
				else 
				{
					if (heliCrashPos != null && heliCrashPos != Vector3.zero) 
					{
						if (Vector3.Distance(transform.position, heliCrashPos) < 0.5f) 
						{
							CancelInvoke(() => npc.SetDestination(heliCrashPos)); 
						} 
						else 
							if (Vector3.Distance(transform.position, heliCrashPos) > 10f) 
							{
								heliCrashPos = new Vector3(transform.position.x + UnityEngine.Random.Range(-5f, 5f), TerrainMeta.HeightMap.GetHeight(transform.position), transform.position.z + UnityEngine.Random.Range(-5f, 5f));
								InvokeRepeating(() => npc.SetDestination(heliCrashPos), 0.2f, 5f); 
							} 
					} 
					if (UnityEngine.Time.time >= deathTime) 
					{
						KillPilot();
						return; 
					} 
				} 
			} 
			
			private void OnDestroy() 
			{
				if (chute) 
					chute.Kill();
				if (plugin.pilots.Contains(this)) 
					plugin.pilots.Remove(this);
				if (npc) 
					npc.displayName = data.displayName; 
			} 
			
			private void OnLanded() 
			{
				isGrounded = true;
				npc.Resume();
				transform.position = groundPos;
				chute?.Kill();
				if (data.wounded) 
					npc.StartWounded();
				else 
				{
					if (heliCrashPos != null && heliCrashPos != Vector3.zero) 
						InvokeRepeating(() => npc.SetDestination(heliCrashPos), 0.05f, 5f); 
				} 
				if (doDraws) 
					foreach (BasePlayer player in BasePlayer.activePlayerList) 
				plugin.DoDraws(player, transform.position); 
			} 
			
			public void KillPilot() 
			{
				if (player) 
					player.Kill(); 
			} 
			
			private void InitChute() 
			{
				chute = GameManager.server.CreateEntity("assets/prefabs/misc/parachute/parachute.prefab", new Vector3(0, 0, 0));
				chute.SetParent(player); 
				chute.Spawn(); 
			} 
		} 
		
		[ChatCommand("callbrokenheli")] 
		private void CallBrokenHeliCMD(BasePlayer player, string command, string[] args) 
		{
			if (!permission.UserHasPermission(player.UserIDString, permissionName)) 
			{
				player.ChatMessage(msg("No Permission", player.UserIDString)); 
				return; 
			} 
			CallBrokenHeli(); 
		}

		[ConsoleCommand("callbrokenheli")] 
		private void CallBrokeHeliCONSOLECMD(ConsoleSystem.Arg args) 
		{
			if (args.Connection != null) return; 
			CallBrokenHeli(); 
			Puts("Broken heli inbound");
		} 
		
		[ChatCommand("setpilot")] 
		private void SetpilotinventoryCMD(BasePlayer player, string command, string[] args) 
		{
			if (!permission.UserHasPermission(player.UserIDString, permissionName)) 
			{
				player.ChatMessage(msg("No Permission", player.UserIDString)); 
				return; 
			}
			if (args.Length != 2) 
			{
				player.ChatMessage(msg("setpilot Invalid Syntax", player.UserIDString));
				return; 
			}
			
			switch (args[0]) 
			{
				case "add": 
				if (pilotData.ContainsKey(args[1])) 
				{
					player.ChatMessage($"This pilot already exists.Use \"/setpilot set {args[1]}\" to change this pilots inventory"); 
					break; 
				} 
				pilotData.Add(args[1], new PilotInfo() 
				{
					chance = 1f,
					displayName = args[1],
					health = 100f,
					dropItems = true,
					beltItems = new List<ItemInfo>(),
					clothingItems = new List<ItemInfo>(),
					inventoryItems = new List<ItemInfo>(),
					wounded = false 
				});
				AddItemsToData(args[1], player);
				player.ChatMessage($"{args[1]} has been added!");
				break;

				case "remove": 
				if (!pilotData.ContainsKey(args[1])) 
				{
					player.ChatMessage($"{args[1]} does not exist!");
					break; 
				} 
				pilotData.Remove(args[1]); 
				player.ChatMessage($"{args[1]} has been removed!");
				break; 
				
				case "set":
				PilotInfo data;
				if (!pilotData.TryGetValue(args[1], out data)) 
				{
					player.ChatMessage($"{args[1]} does not exist!"); 
					break; 
				} 
				AddItemsToData(args[1], player);
				player.ChatMessage($"{args[1]}'s inventory has been set!");
				break; 
				default: 
				player.ChatMessage(msg("setpilot Invalid Syntax", player.UserIDString)); 
				break; 
			} 
			
			SaveData();
			LoadData(); 
		}

		private void SendGlobaGUIAnnouncement(string msg) 
		{
			foreach(BasePlayer player in BasePlayer.activePlayerList) 
			if (player.IsConnected) 
				GUIAnnouncements?.Call("CreateAnnouncement", msg, "Grey", "White", player); 
		} 
		
		private void AddItemsToData(string pilotName, BasePlayer player) 
		{
			PilotInfo data; 
			if (!pilotData.TryGetValue(pilotName, out data)) return; 
			data.inventoryItems.Clear();
			data.clothingItems.Clear();
			data.beltItems.Clear();
			foreach (var item in player.inventory.containerMain.itemList) 
			data.inventoryItems.Add(new ItemInfo 
			{
				shortname = item.info.shortname,
				amount = item.amount,
				chance = 1f,
				skinId = item.skin 
			});

			foreach (var item in player.inventory.containerBelt.itemList) 
			data.beltItems.Add(new ItemInfo 
			{
				shortname = item.info.shortname,
				amount = item.amount,
				chance = 1f,
				skinId = item.skin 
			});

			foreach (var item in player.inventory.containerWear.itemList) 
			data.clothingItems.Add(new ItemInfo 
			{
				shortname = item.info.shortname,
				amount = item.amount,
				chance = 1f,
				skinId = item.skin 
			}); 
		} 
		
		private void DoDraws(BasePlayer player, Vector3 startPos) 
		{
			if (player.IsAdmin) 
			{
				player.SendConsoleCommand("ddraw.arrow", arrowLength, Color.red, startPos + new Vector3(0f, 25f + arrowHeight, 0f), startPos + new Vector3(0f, 25f, 0f), 4.0f); 
			} 
			else 
			{
				player.SetPlayerFlag(BasePlayer.PlayerFlags.IsAdmin, true);
				player.SendNetworkUpdateImmediate();
				player.SendConsoleCommand("ddraw.arrow", arrowLength, Color.red, startPos + new Vector3(0f, 25f + arrowHeight, 0f), startPos + new Vector3(0f, 25f, 0f), 4.0f);
				player.SetPlayerFlag(BasePlayer.PlayerFlags.IsAdmin, false);
				player.SendNetworkUpdateImmediate(); 
			} 
		} 
		
		private void GiveItems(PlayerCorpse corpse, PilotInfo data) 
		{
			foreach (ItemContainer container in corpse.containers) 
			container.Clear(); 
			foreach (var item in data.inventoryItems) 
			if (Random.Range(0f, 1f) < item.chance) 
			{
				var newitem = ItemManager.CreateByName(item.shortname, item.amount, item.skinId);
				if (newitem == null) continue; 
				newitem.MoveToContainer(corpse.containers[0]); 
			} 
			foreach (var item in data.beltItems) 
			if (Random.Range(0f, 1f) < item.chance) 
			{
				var newitem = ItemManager.CreateByName(item.shortname, item.amount, item.skinId); 
				if (newitem == null) continue; 
				newitem.MoveToContainer(corpse.containers[2]); 
			} 
			foreach (var item in data.clothingItems) 
			if (Random.Range(0f, 1f) < item.chance) 
			{
				var newitem = ItemManager.CreateByName(item.shortname, item.amount, item.skinId);
				if (newitem == null) continue; 
				newitem.MoveToContainer(corpse.containers[1]); 
			} 
		}

		private void TriggerEventStart(BaseHelicopter heli) 
		{
			heli.gameObject.AddComponent<EjectHelicopter>();
			helis.Add(heli);
			heliCount = 0; 
		} 
		
		private void CallBrokenHeli() 
		{
			BaseEntity ent = GameManager.server.CreateEntity("assets/prefabs/npc/patrol helicopter/patrolhelicopter.prefab", new Vector3(0, 50f, 0));
			ent.GetComponent<PatrolHelicopterAI>().enabled = false;
			ent.transform.position = new Vector3(0, 50, 0);
			ent.GetComponent<PatrolHelicopterAI>().enabled = true;
			helis.Add((BaseHelicopter)ent);
			ent.Spawn();
			ent.gameObject.AddComponent<EjectHelicopter>();
		} 
		
		private object GetConfig(string menu, string datavalue, object defaultValue) 
		{
			var data = Config[menu] as Dictionary<string, object>;
			if (data == null) 
			{
				data = new Dictionary<string, object>();
				Config[menu] = data;
				changed = true; 
			} 
			object value; 
			if (data.TryGetValue(datavalue, out value)) return value; 
			value = defaultValue;
			data[datavalue] = value;
			changed = true;
			return value; 
		} 
		
		private string msg(string key, string id = null) 
		{
			return lang.GetMessage(key, this, id); 
		} 
		
		private bool IsDamagedHeli(BaseHelicopter heli) 
		{
			return helis.Contains(heli); 
		} 
	} 
}

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