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

FREE XDQuest : 8.6.7 8.6.7

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

namespace Oxide.Plugins.XDQuestExtensionMethods
{
	public static class ExtensionMethods
	{
		private static readonly Lang Lang = Interface.Oxide.GetLibrary<Lang>();

				
		public static string GetAdaptedMessage(this string langKey, in string userID, params object[] args)
		{
			string message = Lang.GetMessage(langKey, XDQuest.Instance, userID);
			
			StringBuilder stringBuilder = Pool.Get<StringBuilder>();
		
			try
			{
				return stringBuilder.AppendFormat(message, args).ToString();
			}
			finally
			{
				stringBuilder.Clear();
				Pool.FreeUnmanaged(ref stringBuilder);
			}
		}
		
		public static string GetAdaptedMessage(this string langKey, in string userID = null)
		{
			return Lang.GetMessage(langKey, XDQuest.Instance, userID);
		}
		
				
		
		public static IEnumerable<T> Page<T>(this List<T> source, int page, int pageSize)
		{
			int start = page * pageSize;
			int end = start + pageSize;
			for (int i = start; i < end && i < source.Count; i++)
			{
				yield return source[i];
			}
		}

			}
}
namespace Oxide.Plugins
{
	[Info("XDQuest", "DezLife", "8.6.7")]
	[Description("Расширенная квест система для вашего сервера!")]
	public class XDQuest : RustPlugin 
	{

		private void LoadQuestData()
		{
			List<Quest> questList = LoadQuestList();
			if (questList != null)
			{
				HashSet<long> currentQuestIds = new();
				foreach (Quest quest in questList)
				{
					currentQuestIds.Add(quest.QuestID);
					_questList.Add(quest.QuestID, quest);
					_questStatistics.TaskExecutionCounts.TryAdd(quest.QuestID, 0);
				}

				List<long> keysToRemove = new();
				foreach (long taskId in _questStatistics.TaskExecutionCounts.Keys)
					if (!currentQuestIds.Contains(taskId))
						keysToRemove.Add(taskId);
				
				foreach (long key in keysToRemove)
					_questStatistics.TaskExecutionCounts.Remove(key);
				SaveData();
			}
			else
			{
				_questList = new Dictionary<long, Quest>();
			}

			if (_questList.Count > 0)
			{
				foreach (Quest quest in _questList.Values)
				{
					if (!string.IsNullOrEmpty(quest.QuestPermission) && !permission.PermissionExists($"{Name}." + quest.QuestPermission, this))
					{
						permission.RegisterPermission($"{Name}." + quest.QuestPermission, this);
					}

					if (quest.QuestType == QuestType.EntityKill && !string.IsNullOrWhiteSpace(quest.Target) && quest.Target.Contains(","))
					{
						quest.IsMoreTarget = true;
						quest.Targets = quest.Target
							.Split(',')
							.Select(s => s.Trim())
							.Where(s => s.Length > 0)
							.ToArray();
					}
				}
			}
		}

		
		
		private void OpenMQL_CMD(BasePlayer player)
		{
			UIMiniQuestList(player);
		}

		private enum QuestType
		{
			IQPlagueSkill,
			IQHeadReward,
			IQCases,
			OreBonus,
			XDChinookIvent,
			Gather,
			EntityKill,
			Craft,
			Research,
			Loot,
			Grade,
			Swipe,
			Deploy,
			PurchaseFromNpc,
			HackCrate,
			RecycleItem,
			Growseedlings,
			RaidableBases,
			Fishing,
			BossMonster,
			HarborEvent,
			SatelliteDishEvent,
			Sputnik,
			AbandonedBases,
			Delivery,
			IQDronePatrol,
			GasStationEvent,
			Triangulation,
			FerryTerminalEvent,
			Convoy,
			Caravan,
			IQDefenderSupply
		}

		private void OnRecyclerToggle(Recycler recycler, BasePlayer player)
		{
			if (!recycler.IsOn())
			{
				if (!_recyclePlayer.TryAdd(recycler.net.ID.Value, player))
				{
					_recyclePlayer.Remove(recycler.net.ID.Value);
					_recyclePlayer.Add(recycler.net.ID.Value, player);
				}
			}
			else if (_recyclePlayer.ContainsKey(recycler.net.ID.Value))
			{
				_recyclePlayer.Remove(recycler.net.ID.Value);
			}
		}

		
		private static bool IsObjectNull(object obj) => ReferenceEquals(obj, null);
		

		private void InitializeNpc(Vector3 pos, Quaternion rot)
		{
			_npc = GameManager.server.CreateEntity(MISSIONPROVIDER_TEST, pos, rot) as NPCMissionProvider;
			if (_npc == null)
			{
				Debug.LogError($"Initializing NPC failed! NPCMissionProvider Component == null");
				return;
			}
			
			_npc.userID = 21;
			_npc.UserIDString = _npc.userID.ToString();
			_npc.displayName = Name;
			_npc.Spawn();
			_npc.inventory.containerWear.Clear();
			_npc.SendNetworkUpdate();
			
			
			if (_config.settingsNpc.Wear.Count > 0)
				foreach (Configuration.SettingsNpc.NPCOutfit t in _config.settingsNpc.Wear)
				{
					Item newItem = ItemManager.CreateByName(t.ShortName, 1, t.SkinId);
					if (newItem == null)
					{
						Debug.LogError($"Failed to create item! ({t.ShortName})");
						continue;
					}

					if (!newItem.MoveToContainer(_npc.inventory.containerWear))
					{
						newItem.Remove();
					}
				}

			
			if (_config.settingsNpc.soundUse)
			{
				InitializeBoomBox(_npc.transform);
			}
		}

		private void OnCollectiblePickedup(CollectibleEntity collectible, BasePlayer player, Item item)
		{
			if (player == null || item == null)
				return;
			
			QuestProgress(player.userID, QuestType.Gather, item.info.shortname, "", null, item.amount);
		}
		   		 		  						  	   		   					  			 		  		  		  				
		
		
		private void LoadDataCopyPaste()
		{
			string filePath = $"copypaste/{QUEST_BUILDING_NAME}";

			if (!Interface.Oxide.DataFileSystem.ExistsDatafile(filePath))
			{
				PrintError("XDQUEST_FileNotLoad".GetAdaptedMessage(null, QUEST_BUILDING_NAME));
				NextTick(() => { Interface.Oxide.UnloadPlugin(Name); });
				return;
			}

			ClearEnt();
		}
		private Configuration _config;

		private void OnSkillTreeHandleDispenser(BasePlayer player, BaseEntity entity, Item item)
		{
			if (player == null || item == null || item.info == null) return;
			QuestProgress(player.userID, QuestType.Gather, item.info.shortname, "", null, item.amount);
		}

		private bool IsClans(string userID, string targetID)
		{
			if (Clans)
			{
				string tagUserID = (string)Clans?.Call("GetClanOf", userID);
				string tagTargetID = (string)Clans?.Call("GetClanOf", targetID);
				if (tagUserID == null && tagTargetID == null)
				{
					return false;
				}

				return tagUserID == tagTargetID;
			}
			else
			{
				return false;
			}
		}
		private const string LAYERS = "UI_QuestMain";

		private string[] _gatherHooks =
		{
			"OnCollectiblePickedup",
			"OnDispenserGathered",
			"OnDispenserBonusReceived",
		};
		
		public static Timer QuestCooldownsTimer;

		
		
		private const bool RU = true;
		
		private readonly Dictionary<string, string> _headersDiscord = new()
		{
			{"Content-Type", "application/json"}
		};

		void OnNpcGiveSoldItem(NPCVendingMachine machine, Item soldItem, BasePlayer buyer)
		{
			if (CustomVendingSetup?.Call("API_IsCustomized", machine) is true)
				return;

			QuestProgress(buyer.userID, QuestType.PurchaseFromNpc, soldItem.info.shortname, "", null, soldItem.amount);
		}

		
		
		private void OnCrateHack(HackableLockedCrate crate)
		{
			if (crate.originalHackerPlayerId.IsSteamId())
			{
				QuestProgress(crate.originalHackerPlayerId, QuestType.HackCrate);
			}
		}

		private bool IsFriends(ulong userID, ulong targetID)
		{
			if (Friends is not null)
				return Friends.Call("HasFriend", userID, targetID) is true;
    
			return RelationshipManager.ServerInstance.playerToTeam.TryGetValue(userID, out RelationshipManager.PlayerTeam team) && team.members.Contains(targetID);
		}

		
		
		private void AddPageButton(string direction, string parentId, string command, CuiElementContainer container)
		{
			string buttonName = direction == "UP" ? "UPBTN" : "DOWNBTN";
			string imageName = direction == "UP" ? "3" : "4";
			string offsetMin = direction == "UP" ? "182.89 87.565" : "139.598 87.568";
			string offsetMax = direction == "UP" ? "221.51 114.635" : "178.326 114.632";
		   		 		  						  	   		   					  			 		  		  		  				
			container.Add(new CuiElement
			{
				Parent = parentId,
				Name = buttonName,
				Components =
				{
					new CuiRawImageComponent { Png = _imageUI.GetImage(imageName), Color = "1 1 1 1" },
					new CuiRectTransformComponent { AnchorMin = "0 0", AnchorMax = "0 0", OffsetMin = offsetMin, OffsetMax = offsetMax }
				}
			});

			container.Add(new CuiButton
			{
				RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1" },
				Button = { Color = "0 0 0 0", Command = command },
				Text = { Text = "" }
			}, buttonName);
		}
		
		private void OnItemRecycle(Item item, Recycler recycler)
		{
			BasePlayer value;
			if (_recyclePlayer.TryGetValue(recycler.net.ID.Value, out value))
			{
				int num2 = 1;
				if (item.amount > 1)
				{
					num2 = Mathf.CeilToInt(Mathf.Min(item.amount, item.info.stackable * 0.1f));
				}
				QuestProgress(value.userID, QuestType.RecycleItem, item.info.shortname, "", null, num2);
			}
		}

		private class SoundFileConverter : JsonConverter
		{
			public override bool CanConvert(Type objectType)
			{
				return objectType == typeof(byte[]);
			}

			public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
			{
				JToken value = JToken.Load(reader);
				return Convert.FromBase64String(value.ToString());
			}

			public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
			{
			}
		}

		
		
		private void OnHarborEventWinner(ulong winnerId)
		{
			QuestProgress(winnerId, QuestType.HarborEvent);
		}
		
		private void OnEntityDestroy(BaseEntity entity)
		{
			if (entity == null) return;
			ulong net = entity.net?.ID.Value ?? 0;
			if (Looted.Contains(net))
				Looted.Remove(net);
		}

		private void ClearPlayersData()
		{
			foreach (BasePlayer p in BasePlayer.activePlayerList)
			{
				CuiHelper.DestroyUi(p, MINI_QUEST_LIST);
				CuiHelper.DestroyUi(p, LAYERS);
			}
		}

		private readonly Dictionary<BasePlayer, Timer> _playerTimer = new Dictionary<BasePlayer, Timer>();

		
		
		private enum SpawnMode
		{
			Construction,
			NPC
		}

		private List<Quest> GetQuestsByCategory(UICategory category, ulong playerId)
		{
			List<Quest> result = new List<Quest>();

			PlayerData playerData = _playersInfo[playerId];
			if (playerData == null)
			{
				return result;
			}

			switch (category)
			{
				case UICategory.Available:
					foreach (Quest quest in _questList.Values)
					{
						if (!string.IsNullOrEmpty(quest.QuestPermission) && !permission.UserHasPermission(playerId.ToString(), $"{Name}." + quest.QuestPermission)) continue;

						bool isQuestAlreadyTaken = playerData.CurrentPlayerQuests.Exists(pq => pq.ParentQuestID == quest.QuestID);
						bool isQuestCd = playerData.PlayerQuestCooldowns.ContainsKey(quest.QuestID);
						bool isQuestAlreadyFinish = playerData.CompletedQuestIds.Contains(quest.QuestID);

						if (!isQuestAlreadyTaken && !isQuestAlreadyFinish && !isQuestCd)
						{
							result.Add(quest);
						}
					}

					break;

				case UICategory.Taken:
					foreach (PlayerQuest playerQuest in playerData.CurrentPlayerQuests)
					{
						Quest value;
						if (_questList.TryGetValue(playerQuest.ParentQuestID, out value))
						{
							result.Add(value);
						}
					}

					foreach (long questId in playerData.PlayerQuestCooldowns.Keys)
					{
						Quest value;
						if (_questList.TryGetValue(questId, out value))
						{
							result.Add(value);
						}
					}

					break;
			}

			return result;
		}
		   		 		  						  	   		   					  			 		  		  		  				
		
		
		private void OnDroneKilled(BasePlayer player, Drone drone, string KeyDrone)
		{
			if (player == null || drone == null)
				return;

			QuestProgress(player.userID, QuestType.IQDronePatrol, KeyDrone, "", null);
		}

		private Vector3 GetResultVector()
		{
			if (_config.spawnSettings.UseCustomPosition)
			{
				return _config.spawnSettings.CustomPosition.Position;
			}

			Transform transform = _monument.transform;
			return transform.position + transform.rotation * _config.spawnSettings.MonumentPosition.Position;
		}

        
				private List<Quest> LoadQuestList()
		{
			return Interface.Oxide.DataFileSystem.ExistsDatafile($"{Name}/{_config.settings.questListDataName}")
				? Interface.Oxide.DataFileSystem.ReadObject<List<Quest>>($"{Name}/{_config.settings.questListDataName}")
				: null;
		}


		private List<BaseEntity> _houseNpc = new();

		
		private void MainUi(BasePlayer player)
		{
			CuiElementContainer container = new CuiElementContainer
			{
				{
					new CuiPanel
					{
						CursorEnabled = true,
						Image = { Color = "1 1 1 0" },
						RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1" }
					},
					"OverlayNonScaled",
					LAYERS
				},


				new CuiElement
				{
					Name = LAYER_MAIN_BACKGROUND,
					Parent = LAYERS,
					Components =
					{
						new CuiRawImageComponent { Color = "1 1 1 1", Png = _imageUI.GetImage("1") },
						new CuiRectTransformComponent { AnchorMin = "0 0", AnchorMax = "1 1" }
					}
				},

				new CuiElement
				{
					Name = "CloseUIImage",
					Parent = LAYER_MAIN_BACKGROUND,
					Components =
					{
						new CuiRawImageComponent { Color = "1 1 1 1", Png = _imageUI.GetImage("2") },
						new CuiRectTransformComponent { AnchorMin = "0 0", AnchorMax = "0 0", OffsetMin = "96.039 87.558", OffsetMax = "135.315 114.647" }
					}
				},

				{
					new CuiButton
					{
						Button = { Color = "1 1 1 0", Command = "CloseMainUI" },
						Text = { Text = "", Font = "robotocondensed-regular.ttf", FontSize = 14, Align = TextAnchor.MiddleCenter, Color = "0 0 0 1" },
						RectTransform = { AnchorMin = "0 0", AnchorMax = "0 0", OffsetMin = "96.039 87.558", OffsetMax = "135.315 114.647" }
					},
					LAYER_MAIN_BACKGROUND,
					"BtnCloseUI"
				},

				{
					new CuiLabel
					{
						RectTransform = { AnchorMin = "0 0.5", AnchorMax = "0 0.5", OffsetMin = "96.227 191.4", OffsetMax = "208.973 211.399" },
						Text =
						{
							Text = "XDQUEST_UI_TASKLIST".GetAdaptedMessage(player.UserIDString), Font = "robotocondensed-regular.ttf", FontSize = 14, Align = TextAnchor.MiddleLeft,
							Color = "0.7169812 0.7169812 0.7169812 1"
						}
					},
					LAYER_MAIN_BACKGROUND,
					"LabelQuestList"
				},

				{
					new CuiLabel
					{
						RectTransform = { AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-269.184 -102.227", OffsetMax = "-197.242 -72.373" },
						Text =
						{
							Text = "XDQUEST_UI_Awards".GetAdaptedMessage(player.UserIDString), Font = "robotocondensed-regular.ttf", FontSize = 14, Align = TextAnchor.MiddleCenter, Color = "1 1 1 1"
						}
					},
					LAYER_MAIN_BACKGROUND,
					"PrizeTitle"
				},

				{
					new CuiLabel
					{
						RectTransform = { AnchorMin = "0 0.5", AnchorMax = "0 0.5", OffsetMin = "250.187 191.399", OffsetMax = "350.187 211.401" },
						Text =
						{
							Text = "XDQUEST_UI_TASKCount".GetAdaptedMessage(player.UserIDString, 0), Font = "robotocondensed-regular.ttf", FontSize = 14, Align = TextAnchor.MiddleRight,
							Color = "1 1 1 1"
						}
					},
					LAYER_MAIN_BACKGROUND,
					"LabelQuestCount", "LabelQuestCount"
				}
			};

			CuiHelper.DestroyUi(player, "UI_QuestMain");
			CuiHelper.AddUi(player, container);
			Category(player, UICategory.Available);
			QuestListUI(player, UICategory.Available);
			QuestInfo(player, 0, UICategory.Available);
		}

		
		
		private void OnConvoyEventWin(ulong userID)
		{
			QuestProgress(userID, QuestType.Convoy);
		}


		
		
		private void OnItemCraftFinished(ItemCraftTask task, Item item, ItemCrafter crafter)
		{
			QuestProgress(crafter.owner.userID, QuestType.Craft, task.blueprint.targetItem.shortname, "", null, item.amount);
		}
		private class QuestStatistics
		{
			public int CompletedTasks, TakenTasks, DeclinedTasks;

			public Dictionary<long, int> TaskExecutionCounts = new();

						public void GatherTaskStatistics(TaskType taskType, long? taskId = null)
			{
				switch (taskType)
				{
					case TaskType.Completed:
						CompletedTasks += 1;
						break;
					case TaskType.Taken:
						TakenTasks += 1;
						break;
					case TaskType.Declined:
						DeclinedTasks += 1;
						break;
					case TaskType.TaskExecution:
						if (taskId.HasValue)
						{
							if (!TaskExecutionCounts.TryAdd(taskId.Value, 1))
							{
								TaskExecutionCounts[taskId.Value] += 1;
							}
						}
						else
						{
							throw new ArgumentNullException("For TaskExecution type, taskId must be provided.");
						}

						break;
					default:
						throw new ArgumentException("Unknown task type");
				}
			}
            
			public Dictionary<long, int> GetTop5MostExecutedTasks()
			{
				List<KeyValuePair<long, int>> topTasks = new List<KeyValuePair<long, int>>();
    
				foreach (KeyValuePair<long, int> task in TaskExecutionCounts)
				{
					if (topTasks.Count < 5)
					{
						topTasks.Add(task);
						topTasks.Sort((a, b) => b.Value.CompareTo(a.Value));
					}
					else
					{
						if (task.Value > topTasks[4].Value)
						{
							topTasks[4] = task;
							topTasks.Sort((a, b) => b.Value.CompareTo(a.Value));
						}
					}
				}

				Dictionary<long, int> result = new Dictionary<long, int>();
				foreach (KeyValuePair<long, int> kvp in topTasks)
				{
					result[kvp.Key] = kvp.Value;
				}

				return result;
			}
        
			public Dictionary<long, int> GetTop5LeastExecutedTasks()
			{
				List<KeyValuePair<long, int>> leastTasks = new List<KeyValuePair<long, int>>();
    
				foreach (KeyValuePair<long, int> task in TaskExecutionCounts)
				{
					if (leastTasks.Count < 5)
					{
						leastTasks.Add(task);
						leastTasks.Sort((a, b) => a.Value.CompareTo(b.Value));
					}
					else
					{
						if (task.Value < leastTasks[4].Value)
						{
							leastTasks[4] = task;
							leastTasks.Sort((a, b) => a.Value.CompareTo(b.Value));
						}
					}
				}

				Dictionary<long, int> result = new Dictionary<long, int>();
				foreach (KeyValuePair<long, int> kvp in leastTasks)
				{
					result[kvp.Key] = kvp.Value;
				}

				return result;
			}

					}

		
		
		private void OnAbandonedBaseEnded(Vector3 center, bool allowPVP, List<BasePlayer> intruders)
		{
			if (intruders.Count <= 0)
				return;

			foreach (BasePlayer player in intruders)
			{
				QuestProgress(player.userID, QuestType.AbandonedBases);
			}
		}

		private void SendChat(BasePlayer player, string message, ConVar.Chat.ChatChannel channel = ConVar.Chat.ChatChannel.Global)
		{
			if (IQChat)
				if (_config.settingsIQChat.UIAlertUse)
					IQChat?.Call("API_ALERT_PLAYER_UI", player, message);
				else IQChat?.Call("API_ALERT_PLAYER", player, message, _config.settingsIQChat.CustomPrefix, _config.settingsIQChat.CustomAvatar);
			else player.SendConsoleCommand("chat.add", channel, 0, message);
		}

		
				
		private void OnCaravanEventWin(ulong userID)
		{
			QuestProgress(userID, QuestType.Caravan);
		}

		private void OnItemResearched(ResearchTable table, int amountToConsume)
		{
			QuestProgress(table.LastLootedBy, QuestType.Research, table.GetTargetItem().info.shortname);
		}

		private bool TakeItemsNeededForQuest(BasePlayer player, Quest globalQuest)
		{
			ItemDefinition idItem = ItemManager.FindItemDefinition(globalQuest.Target);
			int? item = null;
			if (player != null && player.inventory != null)
				item = player.inventory.GetAmount(idItem.itemid);
			
			if (item is 0 or null)
			{
				UINottice(player, "XDQUEST_UI_InsufficientResources".GetAdaptedMessage(player.UserIDString, idItem.displayName.english));
				return false;
			}

			if (item < globalQuest.ActionCount)
			{
				UINottice(player, "XDQUEST_UI_NotResourcesAmount".GetAdaptedMessage(player.UserIDString, idItem.displayName.english, globalQuest.ActionCount));
				return false;
			}

			if (item >= globalQuest.ActionCount)
			{
				player.inventory.Take(null, idItem.itemid, globalQuest.ActionCount);
			}

			return true;
		}

		
				
		private void OnPlayerDeath(BasePlayer player, HitInfo info)
		{
			if (player == null || info == null || !player.userID.IsSteamId())
				return;
			BasePlayer attacker = info.InitiatorPlayer;
			if (attacker == null)
				return;

			if (IsFriends(player.userID.Get(), attacker.userID.Get()) || IsClans(player.UserIDString, attacker.UserIDString) || IsDuel(attacker.userID.Get()) || player.userID == attacker.userID)
				return;

			QuestProgress(attacker.userID, QuestType.EntityKill, "player");
		}

		
		
		private void OnEntityBuilt(Planner plan, GameObject go)
		{
			if(plan == null) return;
			BasePlayer player = plan.GetOwnerPlayer();
			if (player == null || go == null || plan.GetItem() == null)
			{
				return;
			}
			BaseEntity ent = go.ToBaseEntity();
			if (ent == null || ent.skinID == 11543256361)
			{
				return;
			}
			
			QuestProgress(player.userID, QuestType.Deploy, plan.GetItem().info.shortname);
		}

		private void Category(BasePlayer player, UICategory category)
		{
			string color1 = category == UICategory.Available ? "0.4509804 0.5529412 0.2705882 0.8392157" : "0.6431373 0.6509804 0.654902 0.4";
			string color2 = category == UICategory.Taken ? "0.4509804 0.5529412 0.2705882 0.8392157" : "0.6431373 0.6509804 0.654902 0.4";
			string img = _imageUI.GetImage("16");
			CuiElementContainer container = new CuiElementContainer();
		   		 		  						  	   		   					  			 		  		  		  				
			container.Add(new CuiPanel
			{
				CursorEnabled = false,
				Image = { Color = "1 1 1 0" },
				RectTransform = { AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-541.65 234.6", OffsetMax = "-284.33 337.6" }
			}, LAYER_MAIN_BACKGROUND, XDQUEST_CATEGORY_MAIN, XDQUEST_CATEGORY_MAIN);

			container.Add(new CuiElement
			{
				Name = "XDQUEST_CATEGORY_SPRITE",
				Parent = XDQUEST_CATEGORY_MAIN,
				Components =
				{
					new CuiRawImageComponent { Color = "0.7529412 0.5137255 0.04705882 1", Sprite = "assets/icons/Favourite_active.png", Material = "assets/icons/iconmaterial.mat", },
					new CuiRectTransformComponent { AnchorMin = "0 1", AnchorMax = "0 1", OffsetMin = "1.3 -22.5", OffsetMax = "21.3 -2.5" }
				}
			});

			container.Add(new CuiLabel
			{
				RectTransform = { AnchorMin = "0.5 1", AnchorMax = "0.5 1", OffsetMin = "-103.66 -25", OffsetMax = "125.915 0" },
				Text =
				{
					Text = "XDQUEST_UI_CATEGORY".GetAdaptedMessage(player.UserIDString), Font = "robotocondensed-bold.ttf", FontSize = 12, Align = TextAnchor.MiddleLeft,
					Color = "0.7169812 0.7169812 0.7169812 1"
				}
			}, XDQUEST_CATEGORY_MAIN, "XDQUEST_CATEGORY_TITLE");


			container.Add(new CuiElement
			{
				Name = "XDQUEST_CATEGORY_BTN_1",
				Parent = XDQUEST_CATEGORY_MAIN,
				Components =
				{
					new CuiRawImageComponent { Color = color1, Png = img },
					new CuiRectTransformComponent { AnchorMin = "0 0.5", AnchorMax = "0 0.5", OffsetMin = "0 4.8", OffsetMax = "150 22.8" }
				}
			});

			container.Add(new CuiButton
			{
				RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1" },
				Button = { Color = "0 0 0 0", Command = category == UICategory.Available ? "" : $"UI_Handler category {UICategory.Available.ToString()}" },
				Text =
				{
					Text = "XDQUEST_UI_CATEGORY_ONE".GetAdaptedMessage(player.UserIDString), Font = "robotocondensed-regular.ttf", FontSize = 12, Align = TextAnchor.MiddleCenter, Color = "1 1 1 1"
				}
			}, "XDQUEST_CATEGORY_BTN_1");

			container.Add(new CuiElement
			{
				Name = "XDQUEST_CATEGORY_BTN_2",
				Parent = XDQUEST_CATEGORY_MAIN,
				Components =
				{
					new CuiRawImageComponent { Color = color2, Png = img },
					new CuiRectTransformComponent { AnchorMin = "0 0.5", AnchorMax = "0 0.5", OffsetMin = "0 -17.2", OffsetMax = "150 0.8" }
				}
			});

			container.Add(new CuiButton
			{
				RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1" },
				Button = { Color = "0 0 0 0", Command = category == UICategory.Taken ? "" : $"UI_Handler category {UICategory.Taken.ToString()}" },
				Text =
				{
					Text = "XDQUEST_UI_CATEGORY_TWO".GetAdaptedMessage(player.UserIDString), Font = "robotocondensed-regular.ttf", FontSize = 12, Align = TextAnchor.MiddleCenter, Color = "1 1 1 1"
				}
			}, "XDQUEST_CATEGORY_BTN_2");

			CuiHelper.DestroyUi(player, XDQUEST_CATEGORY_MAIN);
			CuiHelper.AddUi(player, container);
		}

		
		
		private void CreateMapMarker(Vector3 pos)
		{
			Interface.CallHook("API_CreateMarker", pos, Name, 0, 3f, 0.2f, _config.mapSettings.nameMarkerMap, _config.mapSettings.colorMarker, _config.mapSettings.colorOutline);
		}


		private void Init()
		{
			Instance = this;
			LoadPlayerData();
			LoadQuestStatisticsData();
			LoadQuestData();
		}

				
		
        public class FancyMessage
        {
            [JsonProperty("content")] public string Content;
		   		 		  						  	   		   					  			 		  		  		  				
            [JsonProperty("username")] public string Username;

            [JsonProperty("avatar_url")] public string AvatarUrl;

            [JsonProperty("embeds")] public List<Embed> Embeds;

            public FancyMessage(string content, List<Embed> embeds)
            {
                Content = content;
                Username = "XDQuest Statistics";
                AvatarUrl = "https://i.imgur.com/RxgzxNW.jpg";
                Embeds = embeds;
            }

            public string ToJson() => JsonConvert.SerializeObject(this);

            public class Embed
            {
                [JsonProperty("title")] public string Title { get; }
                [JsonProperty("description")] public string Description { get; }
                [JsonProperty("color")] public int Color { get; }
                [JsonProperty("timestamp")] public string Timestamp { get; }

                public Embed(string title, string description = "")
                {
                    Title = title;
                    Description = description;
                    Color = 16689937;
                    Timestamp = DateTime.UtcNow.ToString("o");
                }
            }
            
        }
		   		 		  						  	   		   					  			 		  		  		  				
		private void OnServerShutdown() => Unload();
		
		[ConsoleCommand("xdquest.stat")]
		private void StatisticsPost (ConsoleSystem.Arg arg)
		{
			BasePlayer player = arg.Player();
			if (player != null && !player.IsAdmin)
			{
				player.ConsoleMessage("XDQUEST_INSUFFICIENT_PERMISSIONS_ERROR".GetAdaptedMessage(player.UserIDString));
				return;
			}
			
			if (!_config.statisticsCollectionSettings.useStatistics)
			{
				SendConsoleMessage(player, "XDQUEST_STAT_CMD_1".GetAdaptedMessage(PlayerOrNull(player)));
				return;
			}

			if (string.IsNullOrEmpty(_config.statisticsCollectionSettings.discordWebhookUrl))
			{
				SendConsoleMessage(player, "XDQUEST_STAT_CMD_2".GetAdaptedMessage(PlayerOrNull(player)));
				return;
			}
			
			GrabAndPostStatistics();
		}

		private void STCanReceiveYield(BasePlayer player, GrowableEntity entity, Item item)
		{
			if (player == null || item == null || item.info == null) return;
			QuestProgress(player.userID, QuestType.Gather, item.info.shortname, "", null, item.amount);
		}
		
		private void DestroyUnneededComponents(BaseEntity entity)
		{
			UnityEngine.Object.Destroy(entity.GetComponent<DestroyOnGroundMissing>());
			UnityEngine.Object.Destroy(entity.GetComponent<GroundWatch>());
		}

		
		
		private void UINottice(BasePlayer player, string msg, string sprite = "assets/icons/warning.png", string color = "0.76 0.34 0.10 1.00")
		{
			CuiElementContainer container = new CuiElementContainer
			{
				new CuiElement
				{
					FadeOut = 0.30f,
					Name = "QuestUiNotice",
					Parent = LAYER_MAIN_BACKGROUND,
					Components =
					{
						new CuiRawImageComponent { Color = "1 1 1 1", Png = _imageUI.GetImage("12"), FadeIn = 0.30f },
						new CuiRectTransformComponent { AnchorMin = "0 1", AnchorMax = "0 1", OffsetMin = "315 -110", OffsetMax = "610 -43" }
					}
				},

				new CuiElement
				{
					FadeOut = 0.30f,
					Name = "NoticeFeed",
					Parent = "QuestUiNotice",
					Components =
					{
						new CuiRawImageComponent { Color = color, Png = _imageUI.GetImage("13"), FadeIn = 0.30f },
						new CuiRectTransformComponent { AnchorMin = "0 0.5", AnchorMax = "0 0.5", OffsetMin = "0.276 -33.458", OffsetMax = "12.692 33.459" }
					}
				},
				//container.Add(new CuiElement
				//{
				//    Parent = "QuestUi",
				//    Components = {
				//        new CuiRawImageComponent { Color = HexToRustFormat(color), Png = GetImage("16"), FadeIn = 0.30f },
				//        new CuiRectTransformComponent { AnchorMin = "0 0", AnchorMax = "0 0", OffsetMin = "0.451 -23.243", OffsetMax = "1.60543422 12.543" }
				//    }
				//});

				new CuiElement
				{
					FadeOut = 0.30f,
					Name = "NoticeSprite",
					Parent = "QuestUiNotice",
					Components =
					{
						new CuiImageComponent { Color = "1 1 1 1", Sprite = sprite, FadeIn = 0.30f },
						new CuiRectTransformComponent { AnchorMin = "0 0.5", AnchorMax = "0 0.5", OffsetMin = "23.5 -15.5", OffsetMax = "54.5 15.5" }
					}
				},
		   		 		  						  	   		   					  			 		  		  		  				
				{
					new CuiLabel
					{
						RectTransform = { AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-78.262 -33.458", OffsetMax = "143.522 33.459" },
						Text = { Text = msg, Font = "robotocondensed-regular.ttf", FontSize = 11, Align = TextAnchor.MiddleLeft, Color = "1 1 1 1", FadeIn = 0.30f }
					},
					"QuestUiNotice",
					"NoticeText"
				}
			};

			CuiHelper.DestroyUi(player, "NoticeText");
			CuiHelper.DestroyUi(player, "NoticeSprite");
			CuiHelper.DestroyUi(player, "NoticeFeed");
			CuiHelper.DestroyUi(player, "QuestUiNotice");
			CuiHelper.AddUi(player, container);

			DeleteNotification(player);
		}

		
		
		private object OnEntityGroundMissing(BaseEntity ent)
		{
			if (ent == null) return null;
			if (ent.OwnerID == QUEST_BUILDING_OWNER) return false;
			return null;
		}
		private QuestStatistics _questStatistics = new();
		private const string SPHERE_PREFAB = "assets/prefabs/visualization/sphere.prefab";

		private void LoadDataSounds()
		{
			string[] files = Interface.Oxide.DataFileSystem.GetFiles($"{Name}/Sounds/");
			foreach (string filePath in files)
			{
				string fileName = GetFileNameWithoutExtension(filePath);
				try
				{
					NpcSound data = Interface.Oxide.DataFileSystem.ReadObject<NpcSound>($"{Name}/Sounds/{fileName}");
					if (data.voiceData != null && data.voiceData.Length > 0)
					{
						_cachedSounds.Add(fileName, data);
					}
					else
					{
						PrintError($"File {fileName} is corrupted and cannot be loaded!");
					}
				}
				catch (Exception ex)
				{
					PrintError($"Error loading file {fileName}: {ex.Message}");
				}
			}
		}
		private float RadianToDegree(float radians)
		{
			return (float)(radians * 180.0f / Math.PI);
		}
		private const string XDQUEST_CATEGORY_MAIN = "XDQUEST_CATEGORY_MAIN";

		private void ClearEnt()
		{
			List<BaseEntity> entities = Pool.Get<List<BaseEntity>>();

			Vis.Entities(GetResultVector(), 20f, entities, LayerMask.GetMask("Construction", "Deployable", "Deployed", "Debris", "Default", "Player (Server)"));

			foreach (BaseEntity entity in entities)
			{
				if(entity == null || entity.IsDestroyed || (entity.OwnerID != QUEST_BUILDING_OWNER && !entity.PrefabName.Contains("missionprovider_test")))
					continue;
				entity.Kill();
			}
			
			Pool.FreeUnmanaged(ref entities);

			timer.Once(5f, HandleSpawn);
		}

		
		
		
		private static class ObjectCache
		{
			private static readonly object True = true;
			private static readonly object False = false;

			private static class StaticObjectCache<T>
			{
				private static readonly Dictionary<T, object> CacheByValue = new Dictionary<T, object>();

				public static object Get(T value)
				{
					object cachedObject;
					if (!CacheByValue.TryGetValue(value, out cachedObject))
					{
						cachedObject = value;
						CacheByValue[value] = cachedObject;
					}

					return cachedObject;
				}
			}
		   		 		  						  	   		   					  			 		  		  		  				
			public static object Get<T>(T value)
			{
				return StaticObjectCache<T>.Get(value);
			}

			public static object Get(bool value)
			{
				return value ? True : False;
			}
		}

		
		
		private enum UICategory
		{
			Available,
			Taken,
		}

		[ConsoleCommand("CloseMiniQuestList")]
		void CloseMiniQuestList(ConsoleSystem.Arg arg)
		{
			CuiHelper.DestroyUi(arg.Player(), MINI_QUEST_LIST);
			if (_openMiniQuestListPlayers.Contains(arg.Player().userID))
			{
				_openMiniQuestListPlayers.Remove(arg.Player().userID);
			}
		}

		protected override void LoadDefaultConfig()
		{
			_config = new Configuration();
		}
		private AudioZoneController _audioZoneController;

		
		
		private void QuestProgress(ulong playerUserID, QuestType questType, string entName = "", string skinId = "", List<Item> items = null, int count = 1)
		{
			if (!_playersInfo.TryGetValue(playerUserID, out PlayerData playerData))
				return;

			List<PlayerQuest> playerQuests = playerData.CurrentPlayerQuests.FindAll(x => x.ParentQuestType == questType && !x.Finished);

			foreach (PlayerQuest quest in playerQuests)
			{
				Quest parentQuest = _questList[quest.ParentQuestID];
				if (string.IsNullOrEmpty(entName) && items == null)
				{
					quest.AddCount(count);
					return;
				}
				
				if (items != null)
				{
					bool isSkinID = ulong.TryParse(parentQuest.Target, out ulong skinIditem);
					foreach (Item item in items)
					{
						if(item.info.shortname.Equals(parentQuest.Target, StringComparison.OrdinalIgnoreCase) || (isSkinID && item.skin.Equals(skinIditem)))
							quest.AddCount(item.amount);
					}
					continue;
				}
				
				switch (questType)
				{
					case QuestType.IQCases:
					case QuestType.HarborEvent:
					case QuestType.SatelliteDishEvent:
					case QuestType.Sputnik:
					case QuestType.Caravan:
					case QuestType.Convoy:
					case QuestType.GasStationEvent:
					case QuestType.FerryTerminalEvent:
					case QuestType.Triangulation:
					case QuestType.AbandonedBases:
					case QuestType.IQDronePatrol:
					case QuestType.IQDefenderSupply:
					case QuestType.IQHeadReward:
					{
						if (parentQuest.Target.Equals(entName) || parentQuest.Target.Equals("0") || parentQuest.Target.Equals("999"))
							quest.AddCount(count);
						break;
					}
					case QuestType.Swipe:
					{
						if (parentQuest.Target.Equals(entName))
							quest.AddCount(count);
						break;
					}
					case QuestType.EntityKill:
					{
						if (parentQuest.IsMoreTarget)
						{
							foreach (string target in parentQuest.Targets)
							{
								if (entName.Equals(target, StringComparison.OrdinalIgnoreCase))
									quest.AddCount(count);
							}
						}
						else
						{
							if (entName.Equals(parentQuest.Target, StringComparison.OrdinalIgnoreCase))
								quest.AddCount(count);
						}
						break;
					}
					default:
					{
						if (entName.Equals(parentQuest.Target, StringComparison.OrdinalIgnoreCase) || skinId.Equals(parentQuest.Target))
							quest.AddCount(count);
						break;
					}
				}
			}
			
			Interface.CallHook("OnQuestProgress", playerUserID, (int)questType, entName, skinId, items, count);
		}

		private Dictionary<long, Quest> _questList = new();

		private void SaveData()
		{
			Interface.Oxide.DataFileSystem.WriteObject(this.Name + $"/PlayerInfo", _playersInfo);
			Interface.Oxide.DataFileSystem.WriteObject(this.Name + $"/QuestStatistics", _questStatistics);
		}
		private const ulong QUEST_BUILDING_OWNER = 3774732;
		
		private void OnServerInitialized()
		{
			_monument = TerrainMeta.Path.Monuments.FirstOrDefault(p => p.name.ToLower().Contains("compound") && p.IsSafeZone);

			if (!CopyPaste)
			{
				UnloadWithMessage("Check if you have the 'Copy Paste' plugin installed");
				return;
			}

			if (CopyPaste.Version < new VersionNumber(4, 2, 5))
			{
				UnloadWithMessage("You have an old version of Copy Paste!\nplease update the plugin to the latest version (4.2.5 or higher) - https://umod.org/plugins/copy-paste");
				return;
			}

			if (_monument == null && !_config.spawnSettings.UseCustomPosition)
			{
				UnloadWithMessage("XDQUEST_MissingOutPost".GetAdaptedMessage());
				return;
			}

			if (_questList.Count == 0)
			{
				PrintError("XDQUEST_MissingQuests".GetAdaptedMessage());
				return;
			}

			foreach (string cmds in _config.settings.questListProgress)
				cmd.AddChatCommand(cmds, this, nameof(OpenMQL_CMD));

			LoadDataCopyPaste();
			LoadDataSounds();
			GatherHooksSub();

			_imageUI = new ImageUI();
			_imageUI.DownloadImage();

			foreach (BasePlayer player in BasePlayer.activePlayerList)
				OnPlayerConnected(player);
            
			QuestCooldownsTimer = timer.Every(70f, CheckQuestCooldowns);

			if (_config.statisticsCollectionSettings.useStatistics && !string.IsNullOrEmpty(_config.statisticsCollectionSettings.discordWebhookUrl))
			{
				timer.Every(_config.statisticsCollectionSettings.publishFrequency, GrabAndPostStatistics);
			}
		}

		
		
		private void OnOpenedCase(BasePlayer player, string name)
		{
			QuestProgress(player.userID, QuestType.IQCases, name);
		}

		private static double CurrentTime()
		{
			return Facepunch.Math.Epoch.Current;
		}
		
		[PluginReference] Plugin CopyPaste, IQChat, Friends, Clans, EventHelper, Battles, Duel, Duelist, ArenaTournament, Notify, SkillTree, CustomVendingSetup;

		private void Unload()
		{
			if (IsObjectNull(Instance))
				return;

			if (!IsObjectNull(QuestCooldownsTimer))
			{
				QuestCooldownsTimer.Destroy();
			}

			if (_config.mapSettings.mapUse)
				DeleteMapMarker();
			if (_imageUI != null)
			{
				_imageUI.UnloadImages();
				_imageUI = null;
			}

			Instance = null;
			QuestCooldownsTimer = null;
			SaveData();
			DestroyObjects();
			RemoveHouseNpCs();
			if (_npc != null)
				_npc.KillMessage();
			
			ClearPlayersData();
		}
		
		private void InitializeBoomBox(Transform npcTransform)
		{
			DeployableBoomBox boomBox = null;
			try
			{
				Vector3 pos = npcTransform.position + new Vector3(0, 1.4f, 0);
				Quaternion rot = npcTransform.rotation;

				boomBox = GameManager.server.CreateEntity(BOOM_BOX_PREFAB, pos, rot) as DeployableBoomBox;
				if (boomBox == null)
				{
					Debug.LogError("Unable to create DeployableBoomBox entity.");
					return;
				}

				boomBox.enableSaving = false;
				boomBox.OwnerID = QUEST_BUILDING_OWNER;
				boomBox.Spawn();

				UnityEngine.Object.Destroy(boomBox.GetComponent<GroundWatch>());
				UnityEngine.Object.Destroy(boomBox.GetComponent<DestroyOnGroundMissing>());
				

				boomBox.BoxController.SetFlag(BaseEntity.Flags.Reserved8, true);
				boomBox.BoxController.SetFlag(BaseEntity.Flags.Busy, true);
				boomBox.BoxController.ConditionLossRate = 0;
				
				boomBox.networkEntityScale = true;
				boomBox.transform.localScale = new Vector3(0.01f, 0.01f, 0.01f);;
				boomBox.SendNetworkUpdate();
				
				NextTick(() =>
				{
					_houseNpc.Add(boomBox);
				});
				
				_audioZoneController = new GameObject().AddComponent<AudioZoneController>();
				_audioZoneController.Activate(pos, boomBox, 3.2f);
			}
			catch (Exception e)
			{
				Debug.LogError("An error occurred while initializing BoomBox: " + e);
				if (boomBox != null && !boomBox.IsDestroyed)
					boomBox.Kill();
			}
		}
		private const string LAYER_MAIN_BACKGROUND = "UI_QuestMainBackground";
		
		public static XDQuest? Instance;
		
		
		
		private void OnDispenserGathered(ResourceDispenser dispenser, BasePlayer player, Item item)
		{
			if(player == null) return;
			QuestProgress(player.userID, QuestType.Gather, item.info.shortname, "", null, item.amount);
		}

		private void DeleteMapMarker()
		{
			Interface.CallHook("API_RemoveMarker", Name);
		}
		
		private void SpawnNPCs(Vector3 position, float rotationNpc)
		{
			Quaternion rotation = Quaternion.Euler(0, RadianToDegree(rotationNpc), 0);
		   		 		  						  	   		   					  			 		  		  		  				
			InitializeNpc(position, rotation);
		}
		
		private void OnPasteFinished(List<BaseEntity> pastedEntities, string fileName)
		{
			if (!string.Equals(fileName, QUEST_BUILDING_NAME, StringComparison.CurrentCultureIgnoreCase))
				return;

			_houseNpc = pastedEntities;
			try
			{
				foreach (BaseEntity item in _houseNpc)
				{
					if (item == null || item.IsDestroyed || item.transform == null)
						continue;
					
					item.OwnerID = QUEST_BUILDING_OWNER;

					if (item is CeilingLight or SimpleLight or BaseOven or DigitalClock)
						item.SetFlag(BaseEntity.Flags.On, true);
					if (item is ElectricalHeater)
						item.SetFlag(BaseEntity.Flags.Reserved8, true);
					if (item is WeaponRack weaponRack)
						foreach (BaseEntity child in weaponRack.children)
						{
							if (child != null && !child.IsDestroyed)
							{
								child.enableSaving = false;
								BaseEntity.saveList.Remove(child);
							}
						}

					if (item is CCTV_RC cctvRc)
					{
						cctvRc.UpdateIdentifier(_config.settings.CameraId);
						cctvRc.SetFlag(BaseEntity.Flags.Reserved8, true);
						cctvRc.UpdateRCAccess(true);
					}
					
					if (item is NeonSign neonSign)
					{
						neonSign.SetFlag(BaseEntity.Flags.Reserved8, true);
						neonSign.isAnimating = true;
						if (neonSign.isAnimating)
						{
							neonSign.CancelInvoke(neonSign.animationLoopAction);
							neonSign.InvokeRepeating(neonSign.animationLoopAction, 2f, 2f);
						}
						
						DestroyUnneededComponents(neonSign);
						neonSign.SendNetworkUpdate();
					}
					
					if (item.prefabID == 1447082346)
					{
						item.transform.GetPositionAndRotation(out Vector3 positionCopy, out Quaternion rotationCopy);
                        InitializeNpc(positionCopy, rotationCopy);
						
                        item.Kill();
                        continue;
					}

					if (item is DeployableBoomBox boomBox)
					{
						if (_config.settings.useRadio)
						{
							NextTick(() =>
							{
								boomBox.BoxController.CurrentRadioIp = _config.settings.RadioStation;
								boomBox.BoxController.ConditionLossRate = 0;
								boomBox.BoxController.baseEntity.ClientRPC(RpcTarget.NetworkGroup("OnRadioIPChanged"), boomBox.BoxController.CurrentRadioIp);
								if (!boomBox.BoxController.IsOn())
								{
									boomBox.BoxController.ServerTogglePlay(true);
								}

								boomBox.BoxController.baseEntity.SendNetworkUpdate();
							});
						}
					}
		   		 		  						  	   		   					  			 		  		  		  				
					if (item is BuildingBlock buildingBlock)
						buildingBlock.StopBeingRotatable();
					
					if (item is DecayEntity decayEntity)
					{
						decayEntity.decay = null;
						decayEntity.decayVariance = 0;
						decayEntity.ResetUpkeepTime();
						decayEntity.DecayTouch();
						decayEntity.CancelInvoke(nameof(DecayEntity.DecayTick));
						BuildingManager.server.decayEntities.Remove(decayEntity);
					}

					if (item is BaseCombatEntity combatEntity)
					{
						combatEntity.pickup.enabled = false;
					}

					if (item is Door door)
					{
						door.pickup.enabled = false;
						door.canTakeLock = false;
						door.canTakeCloser = false;
					}

					if (!IsIgnoreClass(item))
					{
						item.SetFlag(BaseEntity.Flags.Busy, true);
						item.SetFlag(BaseEntity.Flags.Locked, true);
					}
				}

				PrintWarning("XDQUEST_CopyPasteSuccessfully".GetAdaptedMessage());
			}
			catch (Exception ex)
			{
				PrintError("XDQUEST_BuildingPasteError".GetAdaptedMessage());
				Log(ex.ToString(), "LogError");
			}
		}
		
		
		protected override void LoadDefaultMessages()
		{
			lang.RegisterMessages(new Dictionary<string, string>
			{
				["XDQUEST_CopyPasteError"] = "There was a problem with CopyPaste! Contact the Developer!\nDiscord: @DezLife\nnvk.com/dezlife",
				["XDQUEST_CopyPasteSuccessfully"] = "The building has spawned successfully!",
				["XDQUEST_BuildingPasteError"] = "There was a problem with spawning the Building! Contact the Developer!\nDiscord: @DezLife\nvk.com/dezlife",
				["XDQUEST_MissingOutPost"] = "Your map doesnt have an Outpost Monument. Please use a custom spawn point.",
				["XDQUEST_MissingQuests"]
					= "You do not have a file with tasks, the plugin will not work correctly! Create one on the Website - https://xdquest.skyplugins.ru/ or use the included one.",
				["XDQUEST_FileNotLoad"] = "The construction file was not found : {0}. Move it to the copy paste folder",
				["XDQUEST_UI_TASKLIST"] = "Quest List",
				["XDQUEST_UI_Awards"] = "Rewards",
				["XDQUEST_UI_TASKCount"] = "<color=#42a1f5>{0}</color> QUESTS",
				["XDQUEST_UI_CHIPperformed"] = "Completed",
				["XDQUEST_UI_CHIPInProgress"] = "In progress",
				["XDQUEST_UI_QUESTREPEATCAN"] = "Yes",
				["XDQUEST_UI_QUESTREPEATfForbidden"] = "No",
				["XDQUEST_UI_Missing"] = "Missing",
				["XDQUEST_UI_InfoRepeatInCD"] = "Repeat {0}  |  Cooldown {1}  |  Hand in {2}",
				["XDQUEST_UI_QuestNecessary"] = "Needed",
				["XDQUEST_UI_QuestNotNecessary"] = "Not needed",
				["XDQUEST_UI_QuestBtnPerformed"] = "COMPLETED",
				["XDQUEST_UI_QuestBtnTake"] = "TAKE",
				["XDQUEST_UI_QuestBtnPass"] = "COMPLETE",
				["XDQUEST_UI_QuestBtnDelivery"] = "DELIVER",
				["XDQUEST_UI_QuestBtnRefuse"] = "REFUSE",
				["XDQUEST_UI_ACTIVEOBJECTIVES"] = "Objective: {0}",
				["XDQUEST_UI_MiniQLInfo"] = "{0}\nProgress: {1} / {2}\nQuest: {3}",
				["XDQUEST_UI_MiniQLInfoDelivery"] = "{0}\nQuest: {3}",
				["XDQUEST_UI_CMDPosChange"]
					= "You have successfully changed the position for building within the Outpost.\n(You need to reload the plugin)\nYou can configure the building's rotation in the config",
				["XDQUEST_UI_CMDCustomPosAdd"]
					= "You have successfully added a custom building position.\n(You need to reload the plugin)\nYou can rotate the building in the config!\nRemember to enable the option to spawn a building on a custom position in the config.",
				["XDQUEST_UI_QuestLimit"] = "You have to many <color=#4286f4>unfinished</color> Quests",
				["XDQUEST_UI_AlreadyTaken"] = "You have already <color=#4286f4>taken</color> this Quest!",
				["XDQUEST_UI_NotPerm"] = "You do not have the rights to perform this Quest.",
				["XDQUEST_UI_AlreadyDone"] = "You have already <color=#4286f4>completed</color> this Quest!",
				["XDQUEST_UI_TookTasks"] = "You have <color=#4286f4>successfully</color> accepted the Quest {0}",
				["XDQUEST_UI_ACTIVECOLDOWN"] = "This Quest is on Cooldown.",
				["XDQUEST_UI_LackOfSpace"] = "Your inventory is full! Clear some space and try again!",
				["XDQUEST_UI_QuestsCompleted"] = "Quest Completed! Enjoy your reward!",
				["XDQUEST_UI_PassedTasks"] = "So this Quest was to much for you? \n Try again later!",
				["XDQUEST_UI_ActiveQuestCount"] = "You have no active Quests.",
				["XDQUEST_Finished_QUEST"] = "You have completed the task: <color=#4286f4>{0}</color>",
				["XDQUEST_Finished_QUEST_ALL"] = "Player <color=#4286f4>{0}</color> just completed a task: <color=#4286f4>{1}</color> and got a reward!",
				["XDQUEST_UI_InsufficientResources"] = "You don't have {0}, you should definitely bring this to Sidorovich",
				["XDQUEST_UI_InsufficientResourcesSkin"] = "You don’t have the required item, you need to bring it to Sidorovich",
				["XDQUEST_UI_NotResourcesAmount"] = "You don't have enough {0}, you need {1}",
				["XDQUEST_SoundLoadErrorExt"] = "The voice file {0} is missing, upload it using this path - (/data/XDQuest/Sounds). Or remove it from the configuration",
				["XDQUEST_UI_CATEGORY"] = "CATEGORIES",
				["XDQUEST_UI_CATEGORY_ONE"] = "Available tasks",
				["XDQUEST_UI_CATEGORY_TWO"] = "Active tasks",
				["XDQUEST_UI_TASKS_LIST_EMPTY"] = "Quest list is empty",
				["XDQUEST_UI_TASKS_INFO_EMPTY"] = "Select a task to see information about it",
				["XDQUEST_REPEATABLE_QUEST_AVAILABLE_AGAIN"] = "You can participate in the quest \"<color=#4286f4>{0}</color>\" again! \nDon't miss your chance!",
				["XDQUEST_STAT_1"] = "Main Statistics",
				["XDQUEST_STAT_2"] = "**Tasks Completed:** {0}\n\n**Total Tasks Taken:** {1}\n\n**Tasks Declined:** {
// ... [Code preview truncated due to length. Full source in attached file] ...

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